update mistune

This commit is contained in:
thomas girod 2024-07-01 17:33:05 +02:00
parent 8bcf59aaf0
commit 3c2dcfbfa2
6 changed files with 278 additions and 312 deletions

View File

@ -12,161 +12,125 @@
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# #
from __future__ import annotations
import os import os
import re import re
from typing import TYPE_CHECKING
import mistune
from django.urls import reverse from django.urls import reverse
from mistune import InlineGrammar, InlineLexer, Markdown, Renderer, escape, escape_link from mistune import HTMLRenderer, Markdown
if TYPE_CHECKING:
from mistune import InlineParser, InlineState
# match __text__, without linebreak in the text, nor backslash prepending an underscore
# Examples :
# - "__text__" : OK
# - "__te xt__" : OK
# - "__te_xt__" : nope (underscore in the middle)
# - "__te\_xt__" : Ok (the middle underscore is escaped)
# - "__te\nxt__" : nope (there is a linebreak in the text)
# - "\__text__" : nope (one of the underscores have a backslash prepended)
# - "\\__text__" : Ok (the backslash is ignored, because there is another backslash before)
UNDERLINED_RE = (
r"(?<!\\)(?:\\{2})*" # ignore if there is an odd number of backslashes before
r"_{2}" # two underscores
r"(?P<underlined>([^\\_]|\\.)+)" # the actual text
r"_{2}" # closing underscores
)
SITH_LINK_RE = (
r"\[(?P<page_name>[\w\s]+)\]" # [nom du lien]
r"\(page:\/\/" # (page://
r"(?P<page_slug>[a-zA-Z0-9][a-zA-Z0-9.-]*[a-zA-Z0-9])" # actual page name
r"\)" # )
)
CUSTOM_DIMENSIONS_IMAGE_RE = (
r"\[(?P<img_name>[\w\s]+)\]" # [nom du lien]
r"\(img:\/\/" # (img://
r"(?P<img_slug>[a-zA-Z0-9][a-zA-Z0-9.-]*[a-zA-Z0-9])" # actual page name
r"\)" # )
)
class SithRenderer(Renderer): def parse_underline(_inline: InlineParser, m: re.Match, state: InlineState):
def file_link(self, pk, suffix): state.append_token({"type": "underline", "raw": m.group("underlined")})
return reverse("core:file_detail", kwargs={"file_id": pk}) + suffix return m.end()
def exposant(self, text):
return """<sup>%s</sup>""" % text
def indice(self, text): def underline(md_instance: Markdown):
return """<sub>%s</sub>""" % text md_instance.inline.register(
"underline",
UNDERLINED_RE,
parse_underline,
before="emphasis",
)
md_instance.renderer.register("underline", lambda _, text: f"<u>{text}</u>")
def underline(self, text):
return """<u>%s</u>""" % text
def image(self, original_src, title, text): def parse_sith_link(_inline: InlineParser, m: re.Match, state: InlineState):
"""Rendering a image with title and text. page_name = m.group("page_name")
:param src: source link of the image. page_slug = m.group("page_slug")
:param title: title text of the image. state.append_token(
:param text: alt text of the image. {
""" "type": "link",
style = None "children": [{"type": "text", "raw": page_name}],
if "?" in original_src: "attrs": {"url": reverse("core:page", kwargs={"page_name": page_slug})},
src, params = original_src.rsplit("?", maxsplit=1) }
m = re.search(r"(\d+%?)(x(\d+%?))?", params) )
return m.end()
def sith_link(md_instance: Markdown):
md_instance.inline.register(
"sith_link",
SITH_LINK_RE,
parse_sith_link,
before="emphasis",
)
# no custom renderer here.
# we just add another parsing rule, but render it as if it was
# a regular markdown link
class SithRenderer(HTMLRenderer):
def image(self, text: str, url: str, title=None) -> str:
if "?" not in url:
return super().image(text, url, title)
new_url, params = url.rsplit("?", maxsplit=1)
m = re.match(r"^(?P<width>\d+(%|px)?)(x(?P<height>\d+(%|px)?))?$", params)
if not m: if not m:
src = original_src return super().image(text, url, title)
else:
width = m.group(1) width, height = m.group("width"), m.group("height")
if not width.endswith("%"): if not width.endswith(("%", "px")):
width += "px" width += "px"
style = "width: %s; " % width style = f"width:{width};"
height = m.group(3)
if height is not None: if height is not None:
if not height.endswith("%"): if not height.endswith(("%", "px")):
height += "px" height += "px"
style += "height: %s; " % height style += f"height:{height};"
else: return super().image(text, new_url, title).replace("/>", f'style="{style}" />')
params = None
src = original_src
src = escape_link(src)
text = escape(text, quote=True)
if title:
title = escape(title, quote=True)
html = '<img src="%s" alt="%s" title="%s"' % (src, text, title)
else:
html = '<img src="%s" alt="%s"' % (src, text)
if style:
html = '%s style="%s"' % (html, style)
if self.options.get("use_xhtml"):
return "%s />" % html
return "%s>" % html
class SithInlineGrammar(InlineGrammar): markdown = mistune.create_markdown(
double_emphasis = re.compile(r"^\*{2}([\s\S]+?)\*{2}(?!\*)") # **word** renderer=SithRenderer(escape=True),
emphasis = re.compile(r"^\*((?:\*\*|[^\*])+?)\*(?!\*)") # *word* plugins=[
underline = re.compile(r"^_{2}([\s\S]+?)_{2}(?!_)") # __word__ underline,
exposant = re.compile(r"^<sup>([\s\S]+?)</sup>") # <sup>text</sup> sith_link,
indice = re.compile(r"^<sub>([\s\S]+?)</sub>") # <sub>text</sub>
class SithInlineLexer(InlineLexer):
grammar_class = SithInlineGrammar
default_rules = [
"escape",
# 'inline_html',
"autolink",
"url",
"footnote",
"link",
"reflink",
"nolink",
"exposant",
"double_emphasis",
"emphasis",
"underline",
"indice",
"code",
"linebreak",
"strikethrough", "strikethrough",
"text", "footnotes",
] "table",
inline_html_rules = [ "spoiler",
"escape", "subscript",
"autolink", "superscript",
"url", "url",
"link", ],
"reflink", )
"nolink",
"exposant",
"double_emphasis",
"emphasis",
"underline",
"indice",
"code",
"linebreak",
"strikethrough",
"text",
]
def output_underline(self, m):
text = m.group(1)
return self.renderer.underline(text)
def output_exposant(self, m):
text = m.group(1)
return self.renderer.exposant(text)
def output_indice(self, m):
text = m.group(1)
return self.renderer.indice(text)
# Double emphasis rule changed
def output_double_emphasis(self, m):
text = m.group(1)
text = self.output(text)
return self.renderer.double_emphasis(text)
# Emphasis rule changed
def output_emphasis(self, m):
text = m.group(1)
text = self.output(text)
return self.renderer.emphasis(text)
def _process_link(self, m, link, title=None):
try: # Add page:// support for links
page = re.compile(r"^page://(\S*)") # page://nom_de_ma_page
match = page.search(link)
page = match.group(1) or ""
link = reverse("core:page", kwargs={"page_name": page})
except:
pass
try: # Add file:// support for links
file_link = re.compile(r"^file://(\d*)/?(\S*)?") # file://4000/download
match = file_link.search(link)
pk = match.group(1)
suffix = match.group(2) or ""
link = reverse("core:file_detail", kwargs={"file_id": id}) + suffix
except:
pass
return super()._process_link(m, link, title)
renderer = SithRenderer(escape=True)
inline = SithInlineLexer(renderer)
markdown = Markdown(renderer, inline=inline)
if __name__ == "__main__": if __name__ == "__main__":
root_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) root_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

View File

@ -13,8 +13,8 @@
# #
# #
import os
from datetime import date, timedelta from datetime import date, timedelta
from pathlib import Path
import freezegun import freezegun
import pytest import pytest
@ -22,7 +22,7 @@ from django.core.cache import cache
from django.test import TestCase from django.test import TestCase
from django.urls import reverse from django.urls import reverse
from django.utils.timezone import now from django.utils.timezone import now
from pytest_django.asserts import assertRedirects from pytest_django.asserts import assertInHTML, assertRedirects
from club.models import Membership from club.models import Membership
from core.markdown import markdown from core.markdown import markdown
@ -108,12 +108,51 @@ class TestUserLogin:
assertRedirects(response, reverse("core:index")) assertRedirects(response, reverse("core:index"))
@pytest.mark.parametrize(
("md", "html"),
[
(
"[nom du lien](page://nomDeLaPage)",
'<a href="/page/nomDeLaPage/">nom du lien</a>',
),
("__texte__", "<u>texte</u>"),
("~~***__texte__***~~", "<del><em><strong><u>texte</u></strong></em></del>"),
(
'![tst_alt](/img.png?50% "tst_title")',
'<img src="/img.png" alt="tst_alt" title="tst_title" style="width:50%;" />',
),
(
"[texte](page://tst-page)",
'<a href="/page/tst-page/">texte</a>',
),
(
"![](/img.png?50x450)",
'<img src="/img.png" alt="" style="width:50px;height:450px;" />',
),
("![](/img.png)", '<img src="/img.png" alt="" />'),
(
"![](/img.png?50%x120%)",
'<img src="/img.png" alt="" style="width:50%;height:120%;" />',
),
("![](/img.png?50px)", '<img src="/img.png" alt="" style="width:50px;" />'),
(
"![](/img.png?50pxx120%)",
'<img src="/img.png" alt="" style="width:50px;height:120%;" />',
),
# when the image dimension has a wrong format, don't touch the url
("![](/img.png?50pxxxxxxxx)", '<img src="/img.png?50pxxxxxxxx" alt="" />'),
("![](/img.png?azerty)", '<img src="/img.png?azerty" alt="" />'),
],
)
def test_custom_markdown_syntax(md, html):
"""Test the homemade markdown syntax"""
assert markdown(md) == f"<p>{html}</p>\n"
def test_full_markdown_syntax(): def test_full_markdown_syntax():
root_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) doc_path = Path(settings.BASE_DIR) / "doc"
with open(os.path.join(root_path) + "/doc/SYNTAX.md", "r") as md_file: md = (doc_path / "SYNTAX.md").read_text()
md = md_file.read() html = (doc_path / "SYNTAX.html").read_text()
with open(os.path.join(root_path) + "/doc/SYNTAX.html", "r") as html_file:
html = html_file.read()
result = markdown(md) result = markdown(md)
assert result == html assert result == html
@ -218,12 +257,15 @@ http://git.an
) )
response = self.client.get(reverse("core:page", kwargs={"page_name": "guy"})) response = self.client.get(reverse("core:page", kwargs={"page_name": "guy"}))
assert response.status_code == 200 assert response.status_code == 200
assert ( print(response.content.decode())
'<p>Guy <em>bibou</em></p>\\n<p><a href="http://git.an">http://git.an</a></p>\\n' expected = """
+ "<h1>Swag</h1>\\n&lt;guy&gt;Bibou&lt;/guy&gt;" <p>Guy <em>bibou</em></p>
+ "&lt;script&gt;alert(\\'Guy\\');&lt;/script&gt;" <p><a href="http://git.an">http://git.an</a></p>
in str(response.content) <h1>Swag</h1>
) <p>&lt;guy&gt;Bibou&lt;/guy&gt;</p>
<p>&lt;script&gt;alert('Guy');&lt;/script&gt;</p>
"""
assertInHTML(expected, response.content.decode())
class UserToolsTest: class UserToolsTest:

View File

@ -1,29 +1,22 @@
<p>Cette page vise à documenter la syntaxe <em>Markdown</em> utilisée sur le site.</p> <p>Cette page vise à documenter la syntaxe <em>Markdown</em> utilisée sur le site.</p>
<h1>Markdown-AE Documentation</h1> <h1>Markdown-AE Documentation</h1>
<p>Le Markdown le plus standard se trouve documenté ici: <p>Le Markdown le plus standard se trouve documenté ici:
<a href="https://daringfireball.net/projects/markdown/syntax">https://daringfireball.net/projects/markdown/syntax</a> .<br> <a href="https://www.markdownguide.org/basic-syntax">https://www.markdownguide.org/basic-syntax</a>.<br />
Si cette page n'est pas exhaustive vis à vis de la syntaxe du site AE, Si cette page n'est pas exhaustive vis à vis de la syntaxe du site AE,
elle a au moins le mérite de bien documenter le Markdown original.</p> elle a au moins le mérite de bien documenter le Markdown original.</p>
<p>Le réel parseur du site AE est une version tunée de <a href="https://github.com/lepture/mistune">mistune</a>.<br> <p>Le réel parseur du site AE est une version tunée de <a href="https://github.com/lepture/mistune">mistune</a>.<br />
Les plus aventureux pourront aller lire ses <a href="https://github.com/lepture/mistune/blob/master/tests/fixtures">tests</a> Les plus aventureux pourront aller lire ses <a href="https://github.com/lepture/mistune/blob/master/tests/fixtures">tests</a>
afin d'en connaître la syntaxe le plus finement possible.<br> afin d'en connaître la syntaxe le plus finement possible.<br />
En pratique, cette page devrait déjà résumer une bonne partie.</p> En pratique, cette page devrait déjà résumer une bonne partie.</p>
<h2>Basique</h2> <h2>Basique</h2>
<ul> <ul>
<li><p>Mettre le texte en <strong>gras</strong> : <code>**texte**</code></p> <li>Mettre le texte en <strong>gras</strong> : <code>**texte**</code></li>
</li> <li>Mettre le texte en <em>italique</em> : <code>*texte*</code></li>
<li><p>Mettre le texte en <em>italique</em> : <code>*texte*</code></p> <li><u>Souligner</u> le texte : <code>__texte__</code></li>
</li> <li><del>Barrer du texte</del> : <code>~~texte~~</code></li>
<li><p><u>Souligner</u> le texte : <code>__texte__</code></p> <li>On peut bien sûr tout <del><em><strong><u>combiner</u></strong></em></del> : <code>~~***__texte__***~~</code></li>
</li> <li>Mettre du texte^en exposant^ : <code>&lt;sup&gt;texte&lt;/sup&gt;</code></li>
<li><p><del>Barrer du texte</del> : <code>~~texte~~</code></p> <li>Mettre du texte~en indice~ : <code>&lt;sub&gt;texte&lt;/sub&gt;</code></li>
</li>
<li><p>On peut bien sûr tout <del><strong><em><u>combiner</u></em></strong></del> : <code>~~***__texte__***~~</code></p>
</li>
<li><p><sup>Mettre du texte</sup> en exposant : <code>&lt;sup&gt;texte&lt;/sup&gt;</code></p>
</li>
<li><p><sub>Mettre du texte</sub> en indice : <code>&lt;sub&gt;texte&lt;/sub&gt;</code></p>
</li>
</ul> </ul>
<h2>Liens</h2> <h2>Liens</h2>
<ul> <ul>
@ -43,7 +36,7 @@ l'adresse complète d'une page : <code>[nom du lien](page://nomDeLaPage)</code><
<li>On peut également utiliser une image pour les liens : <li>On peut également utiliser une image pour les liens :
<code>[nom du lien]![images/imageDuSiteAE.png](/chemin/vers/image.png titre optionnel)(options)</code></li> <code>[nom du lien]![images/imageDuSiteAE.png](/chemin/vers/image.png titre optionnel)(options)</code></li>
</ul> </ul>
<p>[nom du lien]<img src="/chemin/vers/image.png titre optionnel" alt="images/imageDuSiteAE.png">(options)</p> <p>[nom du lien]![images/imageDuSiteAE.png](/chemin/vers/image.png titre optionnel)(options)</p>
<h2>Titres</h2> <h2>Titres</h2>
<ul> <ul>
<li>Plusieurs niveaux de titres sont possibles</li> <li>Plusieurs niveaux de titres sont possibles</li>
@ -56,17 +49,12 @@ etc...
<h1>Titre de niveau 1</h1> <h1>Titre de niveau 1</h1>
<h2>Titre de niveau 2</h2> <h2>Titre de niveau 2</h2>
<h3>Titre de niveau 3</h3> <h3>Titre de niveau 3</h3>
<p>Si le titre de votre section commence par un tilde (~) alors le texte sous la section est
affiché par défaut caché et il est consultable grace à un bouton +/-</p>
<h2>~Test</h2>
<h2>Paragraphes et sauts de ligne</h2> <h2>Paragraphes et sauts de ligne</h2>
<p>Un nouveau paragraphe se fait avec deux retours à la ligne.</p> <p>Un nouveau paragraphe se fait avec deux retours à la ligne.</p>
<p>Un saut de ligne se force avec au moins deux espaces en fin de ligne.</p> <p>Un saut de ligne se force avec au moins deux espaces en fin de ligne.</p>
<h2>Listes</h2> <h2>Listes</h2>
<p>Il est possible de créer des listes :</p> <p>Il est possible de créer des listes :</p>
<ul> <h3>ordonnées :</h3>
<li>ordonnées :</li>
</ul>
<pre><code>1. élément <pre><code>1. élément
2. élément 2. élément
3. élément 3. élément
@ -86,12 +74,10 @@ affiché par défaut caché et il est consultable grace à un bouton +/-</p>
<li>élément</li> <li>élément</li>
<li>élément</li> <li>élément</li>
</ol> </ol>
<ul> <h3>non ordonnées :</h3>
<li>non ordonnées :</li> <pre><code>- élément
</ul> - élément
<pre><code> * élément - élément
* élément
* élément
</code></pre> </code></pre>
<ul> <ul>
<li>élément</li> <li>élément</li>
@ -106,7 +92,8 @@ affiché par défaut caché et il est consultable grace à un bouton +/-</p>
| test | test | test | | test | test | test |
</code></pre> </code></pre>
<table> <table>
<thead><tr> <thead>
<tr>
<th>Titre</th> <th>Titre</th>
<th>Titre2</th> <th>Titre2</th>
<th>Titre3</th> <th>Titre3</th>
@ -131,7 +118,8 @@ affiché par défaut caché et il est consultable grace à un bouton +/-</p>
| gauche | centre | droite | | gauche | centre | droite |
</code></pre> </code></pre>
<table> <table>
<thead><tr> <thead>
<tr>
<th style="text-align:left">Titre</th> <th style="text-align:left">Titre</th>
<th style="text-align:center">Titre2</th> <th style="text-align:center">Titre2</th>
<th style="text-align:right">Titre3</th> <th style="text-align:right">Titre3</th>
@ -146,18 +134,18 @@ affiché par défaut caché et il est consultable grace à un bouton +/-</p>
</tbody> </tbody>
</table> </table>
<h2>Images et contenus</h2> <h2>Images et contenus</h2>
<p>Une image est insérée ainsi : <code>![texte alternatif](/chemin/vers/image.png "titre optionnel")</code> <p>Une image est insérée ainsi : <code>![texte alternatif](/chemin/vers/image.png &quot;titre optionnel&quot;)</code>
<img src="/static/core/img/logo.png" alt="texte alternatif" title="titre optionnel"></p> <img src="/static/core/img/logo.png" alt="texte alternatif" title="titre optionnel" /></p>
<p>On peut lui spécifier ses dimensions de plusieurs manières :</p> <p>On peut lui spécifier ses dimensions de plusieurs manières :</p>
<pre><code>![image à 50%](/static/core/img/logo.png?50% "Image à 50%") <pre><code>![image à 50%](/static/core/img/logo.png?50% &quot;Image à 50%&quot;)
![image de 350 pixels de large](/static/core/img/logo.png?350 "Image de 350 pixels") ![image de 350 pixels de large](/static/core/img/logo.png?350 &quot;Image de 350 pixels&quot;)
![image de 350x100 pixels](/static/core/img/logo.png?350x100 "Image de 350x100 pixels") ![image de 350x100 pixels](/static/core/img/logo.png?350x100 &quot;Image de 350x100 pixels&quot;)
</code></pre> </code></pre>
<p><img src="/static/core/img/logo.png" alt="image à 50%" title="Image à 50%" style="width: 50%; "><br> <p><img src="/static/core/img/logo.png" alt="image à 50%" title="Image à 50%" style="width:50%;" /><br />
Image à 50% de la largeur de la page.</p> Image à 50% de la largeur de la page.</p>
<p><img src="/static/core/img/logo.png" alt="image de 350 pixels de large" title="Image de 350 pixels" style="width: 350px; "><br> <p><img src="/static/core/img/logo.png" alt="image de 350 pixels de large" title="Image de 350 pixels" style="width:350px;" /><br />
Image de 350 pixels de large.</p> Image de 350 pixels de large.</p>
<p><img src="/static/core/img/logo.png" alt="image de 350x100 pixels" title="Image de 350x100 pixels" style="width: 350px; height: 100px; "><br> <p><img src="/static/core/img/logo.png" alt="image de 350x100 pixels" title="Image de 350x100 pixels" style="width:350px;height:100px;" /><br />
Image de 350x100 pixels.</p> Image de 350x100 pixels.</p>
<p>(devrait pouvoir détecter si vidéo ou non)</p> <p>(devrait pouvoir détecter si vidéo ou non)</p>
<h2>Blocs de citations</h2> <h2>Blocs de citations</h2>
@ -166,41 +154,34 @@ Image de 350x100 pixels.</p>
&gt; un bloc de &gt; un bloc de
&gt; citation &gt; citation
</code></pre> </code></pre>
<blockquote><p>Ceci est <blockquote>
<p>Ceci est
un bloc de un bloc de
citation</p> citation</p>
</blockquote> </blockquote>
<p>Il est possible d'intégrer de la syntaxe Markdown-AE dans un tel bloc.</p> <p>Il est possible d'intégrer de la syntaxe Markdown-AE dans un tel bloc.</p>
<h2>Note de bas de page</h2> <h2>Note de bas de page</h2>
<p>On les créer comme ça<sup class="footnote-ref" id="fnref-key"><a href="#fn-key">1</a></sup>:</p> <p>On les crée comme ça<sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup>:</p>
<h2>échapper des caractères</h2> <pre><code>Je fais une note[^clef].
[^clef]: je note ensuite où je veux le contenu de ma clef qui apparaîtra quand même en bas
</code></pre>
<p>Vous pouvez aussi utiliser des numéros pour nommer vos clefs.</p>
<pre><code>Note plus complexe[^1]
[^1]:
je peux même faire des blocs
sur plusieurs lignes, comme d'habitude!
</code></pre>
<h2>Échapper des caractères</h2>
<ul> <ul>
<li>Il est possible d'ignorer un caractère spécial en l'échappant à l'aide d'un \</li> <li>Il est possible d'ignorer un caractère spécial en l'échappant à l'aide d'un \</li>
<li>L'échappement de blocs de codes complet se fera à l'aide de balises &lt;nosyntax&gt;&lt;/nosyntax&gt;</li> <li>L'échappement de blocs de codes complet se fera à l'aide de balises &lt;nosyntax&gt;&lt;/nosyntax&gt;</li>
</ul> </ul>
<h2>Autres (hérité de l'ancien wiki)</h2> <h2>Autres (hérité de l'ancien wiki)</h2>
<ul> <p>Une ligne peut être créée avec une ligne contenant 4 tirets (<code>----</code>).</p>
<li>Une ligne peut être crée avec une ligne contenant 4 tirets ( - ).</li> <section class="footnotes">
<li>Une barre de progression est crée ainsi :<blockquote><p>[[[70]]]</p> <ol>
</blockquote> <li id="fn-1"><p>ceci est le contenu de ma clef<a href="#fnref-1" class="footnote">&#8617;</a></p></li>
</li>
<li>Notes en pied de page :<blockquote><p>((note))</p>
</blockquote>
</li>
</ul>
<div class="footnotes">
<hr>
<ol><li id="fn-key"><p>ceci est le contenu de ma clef</p>
<pre><code>Je fais une note[^clef].
[^clef]: je note ensuite ou je veux le contenu de ma clef qui apparaîtra quand même en bas
</code></pre>
<p>Vous pouvez utiliser des numéros pour nommer vos clef si vous avez la flemme.</p>
<pre><code>Note plus complexe[^1]
[^1]:
je peux même faire des blocks
sur plusieurs lignes, comme d'habitude!
</code></pre><p><a href="#fnref-key" class="footnote">&#8617;</a></p></li>
</ol> </ol>
</div> </section>

View File

@ -3,7 +3,7 @@ Cette page vise à documenter la syntaxe *Markdown* utilisée sur le site.
# Markdown-AE Documentation # Markdown-AE Documentation
Le Markdown le plus standard se trouve documenté ici: Le Markdown le plus standard se trouve documenté ici:
https://daringfireball.net/projects/markdown/syntax . https://www.markdownguide.org/basic-syntax.
Si cette page n'est pas exhaustive vis à vis de la syntaxe du site AE, Si cette page n'est pas exhaustive vis à vis de la syntaxe du site AE,
elle a au moins le mérite de bien documenter le Markdown original. elle a au moins le mérite de bien documenter le Markdown original.
@ -14,37 +14,31 @@ En pratique, cette page devrait déjà résumer une bonne partie.
## Basique ## Basique
* Mettre le texte en **gras** : `**texte**` - Mettre le texte en **gras** : `**texte**`
- Mettre le texte en *italique* : `*texte*`
* Mettre le texte en *italique* : `*texte*` - __Souligner__ le texte : `__texte__`
- ~~Barrer du texte~~ : `~~texte~~`
* __Souligner__ le texte : `__texte__` - On peut bien sûr tout ~~***__combiner__***~~ : `~~***__texte__***~~`
- Mettre du texte^en exposant^ : `<sup>texte</sup>`
* ~~Barrer du texte~~ : `~~texte~~` - Mettre du texte~en indice~ : `<sub>texte</sub>`
* On peut bien sûr tout ~~***__combiner__***~~ : `~~***__texte__***~~`
* <sup>Mettre du texte</sup> en exposant : `<sup>texte</sup>`
* <sub>Mettre du texte</sub> en indice : `<sub>texte</sub>`
## Liens ## Liens
* Les liens simples sont détectés automatiquement : `http://www.site.com` - Les liens simples sont détectés automatiquement : `http://www.site.com`
http://www.site.com http://www.site.com
* Il est possible de nommer son lien : `[nom du lien](http://www.site.com)` - Il est possible de nommer son lien : `[nom du lien](http://www.site.com)`
[nom du lien](http://www.site.com) [nom du lien](http://www.site.com)
* Les liens peuvent être internes au site de l'AE, on peut dès lors éviter d'entrer - Les liens peuvent être internes au site de l'AE, on peut dès lors éviter d'entrer
l'adresse complète d'une page : `[nom du lien](page://nomDeLaPage)` l'adresse complète d'une page : `[nom du lien](page://nomDeLaPage)`
[nom du lien](page://nomDeLaPage) [nom du lien](page://nomDeLaPage)
* On peut également utiliser une image pour les liens : - On peut également utiliser une image pour les liens :
`[nom du lien]![images/imageDuSiteAE.png](/chemin/vers/image.png titre optionnel)(options)` `[nom du lien]![images/imageDuSiteAE.png](/chemin/vers/image.png titre optionnel)(options)`
[nom du lien]![images/imageDuSiteAE.png](/chemin/vers/image.png titre optionnel)(options) [nom du lien]![images/imageDuSiteAE.png](/chemin/vers/image.png titre optionnel)(options)
@ -53,7 +47,7 @@ l'adresse complète d'une page : `[nom du lien](page://nomDeLaPage)`
## Titres ## Titres
* Plusieurs niveaux de titres sont possibles - Plusieurs niveaux de titres sont possibles
``` ```
# Titre de niveau 1 # Titre de niveau 1
@ -65,11 +59,6 @@ etc...
## Titre de niveau 2 ## Titre de niveau 2
### Titre de niveau 3 ### Titre de niveau 3
Si le titre de votre section commence par un tilde (~) alors le texte sous la section est
affiché par défaut caché et il est consultable grace à un bouton +/-
## ~Test
## Paragraphes et sauts de ligne ## Paragraphes et sauts de ligne
Un nouveau paragraphe se fait avec deux retours à la ligne. Un nouveau paragraphe se fait avec deux retours à la ligne.
@ -81,7 +70,7 @@ Un saut de ligne se force avec au moins deux espaces en fin de ligne.
Il est possible de créer des listes : Il est possible de créer des listes :
* ordonnées : ### ordonnées :
``` ```
1. élément 1. élément
@ -104,16 +93,16 @@ Vous pouvez marquer plus simplement comme suit, les numéros se faisant tout seu
1. élément 1. élément
* non ordonnées : ### non ordonnées :
``` ```
* élément - élément
* élément - élément
* élément - élément
``` ```
* élément - élément
* élément - élément
* élément - élément
## Tableaux ## Tableaux
@ -185,39 +174,29 @@ Il est possible d'intégrer de la syntaxe Markdown-AE dans un tel bloc.
## Note de bas de page ## Note de bas de page
On les créer comme ça[^key]: On les crée comme ça[^key]:
[^key]: ceci est le contenu de ma clef [^key]: ceci est le contenu de ma clef
``` ```
Je fais une note[^clef]. Je fais une note[^clef].
[^clef]: je note ensuite ou je veux le contenu de ma clef qui apparaîtra quand même en bas [^clef]: je note ensuite où je veux le contenu de ma clef qui apparaîtra quand même en bas
``` ```
Vous pouvez utiliser des numéros pour nommer vos clef si vous avez la flemme. Vous pouvez aussi utiliser des numéros pour nommer vos clefs.
``` ```
Note plus complexe[^1] Note plus complexe[^1]
[^1]: [^1]:
je peux même faire des blocks je peux même faire des blocs
sur plusieurs lignes, comme d'habitude! sur plusieurs lignes, comme d'habitude!
``` ```
## échapper des caractères ## Échapper des caractères
* Il est possible d'ignorer un caractère spécial en l'échappant à l'aide d'un \
* L'échappement de blocs de codes complet se fera à l'aide de balises <nosyntax></nosyntax>
- Il est possible d'ignorer un caractère spécial en l'échappant à l'aide d'un \
- L'échappement de blocs de codes complet se fera à l'aide de balises <nosyntax></nosyntax>
## Autres (hérité de l'ancien wiki) ## Autres (hérité de l'ancien wiki)
* Une ligne peut être crée avec une ligne contenant 4 tirets ( - ). Une ligne peut être créée avec une ligne contenant 4 tirets (`----`).
* Une barre de progression est crée ainsi :
> [[[70]]]
* Notes en pied de page :
> ((note))

14
poetry.lock generated
View File

@ -888,13 +888,13 @@ traitlets = "*"
[[package]] [[package]]
name = "mistune" name = "mistune"
version = "0.8.4" version = "3.0.2"
description = "The fastest markdown parser in pure Python" description = "A sane and fast Markdown parser with useful plugins and renderers"
optional = false optional = false
python-versions = "*" python-versions = ">=3.7"
files = [ files = [
{file = "mistune-0.8.4-py2.py3-none-any.whl", hash = "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"}, {file = "mistune-3.0.2-py3-none-any.whl", hash = "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205"},
{file = "mistune-0.8.4.tar.gz", hash = "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e"}, {file = "mistune-3.0.2.tar.gz", hash = "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8"},
] ]
[[package]] [[package]]
@ -1865,5 +1865,5 @@ filelock = ">=3.4"
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.10,<3.12" python-versions = "^3.10"
content-hash = "c33378496709848054a8e4ecd1ebf74df12f15a1bb66ab61d2958e6a3c40f812" content-hash = "e01f649e4ed95bc01a4a72a3ea90dc13a83e6e21d6e77d84b7adcdb2ca68dec8"

View File

@ -20,10 +20,10 @@ homepage = "https://ae.utbm.fr/"
license = "GPL-3.0-only" license = "GPL-3.0-only"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.10,<3.12" # Version is held back by mistune python = "^3.10"
Django = "^4.2.13" Django = "^4.2.13"
Pillow = "^10.4.0" Pillow = "^10.4.0"
mistune = "^0.8.4" mistune = "^3.0.2"
django-jinja = "^2.11" django-jinja = "^2.11"
cryptography = "^42.0.8" cryptography = "^42.0.8"
pytz = "^2021.1" pytz = "^2021.1"