From 0d5595c683fc48c97b94e877a644ebc10fced978 Mon Sep 17 00:00:00 2001 From: Skia Date: Thu, 24 Aug 2017 16:29:40 +0200 Subject: [PATCH] core: add test for Markdown syntax Signed-off-by: Skia --- README.md | 8 ++ core/apps.py | 4 +- core/management/commands/markdown.py | 37 +++++ core/markdown.py | 43 +----- core/tests.py | 12 ++ doc/SYNTAX.html | 206 +++++++++++++++++++++++++++ doc/SYNTAX.md | 91 ++++++++++-- sith/settings.py | 5 +- 8 files changed, 350 insertions(+), 56 deletions(-) create mode 100644 core/management/commands/markdown.py create mode 100644 doc/SYNTAX.html diff --git a/README.md b/README.md index 654d37d7..98e8495f 100644 --- a/README.md +++ b/README.md @@ -71,5 +71,13 @@ appropriate group fields, or the right method to check user permissions. $ cloc --exclude-dir=doc,env . ``` +#### Updating doc/SYNTAX.md + +If you make an update in the Markdown syntax parser, it's good to document +update the syntax reference page in `doc/SYNTAX.md`. But updating this file will +break the tests if you don't update the corresponding `doc/SYNTAX.html` file at +the same time. +To do that, simply run `./manage.py markdown > doc/SYNTAX.html`, +and the tests should pass again. diff --git a/core/apps.py b/core/apps.py index 8eb1cf65..75643556 100644 --- a/core/apps.py +++ b/core/apps.py @@ -22,6 +22,8 @@ # # +import sys + from django.apps import AppConfig from django.core.signals import request_started @@ -44,7 +46,7 @@ class SithConfig(AppConfig): Club._memberships = {} Forum._club_memberships = {} - print("Connecting signals!") + print("Connecting signals!", file=sys.stderr) request_started.connect(clear_cached_groups, weak=False, dispatch_uid="clear_cached_groups") request_started.connect(clear_cached_memberships, weak=False, dispatch_uid="clear_cached_memberships") # TODO: there may be a need to add more cache clearing diff --git a/core/management/commands/markdown.py b/core/management/commands/markdown.py new file mode 100644 index 00000000..d0fad56f --- /dev/null +++ b/core/management/commands/markdown.py @@ -0,0 +1,37 @@ +# -*- coding:utf-8 -* +# +# Copyright 2017 +# - Skia +# +# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, +# http://ae.utbm.fr. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License a published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple +# Place - Suite 330, Boston, MA 02111-1307, USA. +# +# + +import os +from django.core.management.base import BaseCommand + +from core.markdown import markdown + +class Command(BaseCommand): + help = "Output the fully rendered doc/SYNTAX.md file" + + def handle(self, *args, **options): + root_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) + with open(os.path.join(root_path) + '/doc/SYNTAX.md', 'r') as md: + result = markdown(md.read()) + print(result, end='') diff --git a/core/markdown.py b/core/markdown.py index 991ab439..e9ce814c 100644 --- a/core/markdown.py +++ b/core/markdown.py @@ -22,6 +22,7 @@ # # +import os import re from mistune import Renderer, InlineGrammar, InlineLexer, Markdown, escape, escape_link from django.core.urlresolvers import reverse @@ -192,41 +193,7 @@ inline = SithInlineLexer(renderer) markdown = Markdown(renderer, inline=inline) if __name__ == "__main__": - print(markdown.inline.default_rules) - print(markdown.inline.inline_html_rules) - text = """ -## Basique - -* Mettre le texte en **gras** : `**texte**` - -* Mettre le texte en *italique* : `*texte*` - -* __Souligner__ le texte : `__texte__` - -* ~~Barrer du texte~~ : `~~texte~~` - -* Mettre ^du texte^ en ^exposant^ : `^mot` ou `^texte^` - -* _Mettre du texte_ en _indice_ : `_mot` ou `_texte_` - -* Pied de page [^en pied de page] - -## Blocs de citations - -Un bloc de citation se crée ainsi : -``` -> Ceci est -> un bloc de -> citation -``` - -> Ceci est -> un bloc de -> citation - -Il est possible d'intégrer de la syntaxe Markdown-AE dans un tel bloc. - -Petit *test* _sur_ ^une^ **seule** ^ligne pour voir^ - -""" - print(markdown(text)) + root_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + with open(os.path.join(root_path) + '/doc/SYNTAX.md', 'r') as md: + result = markdown(md.read()) + print(result, end='') diff --git a/core/tests.py b/core/tests.py index 86520153..69fa50aa 100644 --- a/core/tests.py +++ b/core/tests.py @@ -22,11 +22,14 @@ # # +import os + from django.test import Client, TestCase from django.core.urlresolvers import reverse from django.core.management import call_command from core.models import User, Group, Page +from core.markdown import markdown """ to run these tests : @@ -185,6 +188,15 @@ class UserRegistrationTest(TestCase): self.assertTrue(response.status_code == 200) self.assertTrue("""

Votre nom d\\'utilisateur et votre mot de passe ne correspondent pas. Merci de r\\xc3\\xa9essayer.

""" in str(response.content)) +class MarkdownTest(TestCase): + def test_full_markdown_syntax(self): + root_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + with open(os.path.join(root_path) + '/doc/SYNTAX.md', 'r') as md_file: + md = md_file.read() + with open(os.path.join(root_path) + '/doc/SYNTAX.html', 'r') as html_file: + html = html_file.read() + result = markdown(md) + self.assertTrue(result == html) class PageHandlingTest(TestCase): def setUp(self): diff --git a/doc/SYNTAX.html b/doc/SYNTAX.html new file mode 100644 index 00000000..d6b998e9 --- /dev/null +++ b/doc/SYNTAX.html @@ -0,0 +1,206 @@ +

Cette page vise à documenter la syntaxe Markdown utilisée sur le site.

+

Markdown-AE Documentation

+

Le Markdown le plus standard se trouve documenté ici: +https://daringfireball.net/projects/markdown/syntax .
+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.

+

Le réel parseur du site AE est une version tunée de mistune.
+Les plus aventureux pourront aller lire ses tests +afin d'en connaître la syntaxe le plus finement possible.
+En pratique, cette page devrait déjà résumer une bonne partie.

+

Basique

+
    +
  • Mettre le texte en gras : **texte**

    +
  • +
  • Mettre le texte en italique : *texte*

    +
  • +
  • Souligner le texte : __texte__

    +
  • +
  • Barrer du texte : ~~texte~~

    +
  • +
  • On peut bien sûr tout combiner : ~~***__texte__***~~

    +
  • +
  • Mettre du texte en exposant : <sup>texte</sup>

    +
  • +
  • Mettre du texte en indice : <sub>texte</sub>

    +
  • +
+

Liens

+
    +
  • Les liens simples sont détectés automatiquement : http://www.site.com
  • +
+

http://www.site.com

+
    +
  • Il est possible de nommer son lien : [nom du lien](http://www.site.com)
  • +
+

nom du lien

+
    +
  • 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)
  • +
+

nom du lien

+
    +
  • 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(options)

+

Titres

+
    +
  • Plusieurs niveaux de titres sont possibles
  • +
+
# Titre de niveau 1
+## Titre de niveau 2
+### Titre de niveau 3
+etc...
+
+

Titre de niveau 1

+

Titre de niveau 2

+

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

+

Un nouveau paragraphe se fait avec deux retours à la ligne.

+

Un saut de ligne se force avec au moins deux espaces en fin de ligne.

+

Listes

+

Il est possible de créer des listes :

+
    +
  • ordonnées :
  • +
+
1. élément
+2. élément
+3. élément
+
+
    +
  1. élément
  2. +
  3. élément
  4. +
  5. élément
  6. +
+

Vous pouvez marquer plus simplement comme suit, les numéros se faisant tout seuls:

+
1. élément
+1. élément
+1. élément
+
+
    +
  1. élément
  2. +
  3. élément
  4. +
  5. élément
  6. +
+
    +
  • non ordonnées :
  • +
+
 * élément
+ * élément
+ * élément
+
+
    +
  • élément
  • +
  • élément
  • +
  • élément
  • +
+

Tableaux

+

Un tableau est obtenu en respectant la syntaxe suivante :

+
| Titre | Titre2 | Titre3 |
+|-------|--------|--------|
+| test  | test   |   test |
+| test  | test   |   test |
+
+ + + + + + + + + + + + + + + + + + + +
TitreTitre2Titre3
testtesttest
testtesttest
+

L'alignement dans les cellules est géré comme suit, avec les ':' sur la ligne en dessous du titre:

+
|  Titre | Titre2 | Titre3 |
+|:-------|:------:|-------:|
+| gauche | centre | droite |
+
+ + + + + + + + + + + + + + +
TitreTitre2Titre3
gauchecentredroite
+

Images et contenus

+

Une image est insérée ainsi : ![texte alternatif](/chemin/vers/image.png "titre optionnel") +texte alternatif

+

On peut lui spécifier ses dimensions de plusieurs manières:

+
![image à 50%](/static/core/img/logo.png?50% "Image à 50%")
+![image de  350 pixels de large](/static/core/img/logo.png?350 "Image de 350 pixels")
+![image de 350x100 pixels](/static/core/img/logo.png?350x100 "Image de 350x100 pixels")
+
+

image à 50%
+Image à 50% de la largeur de la page.

+

image de 350 pixels de large
+Image de 350 pixels de large.

+

image de 350x100 pixels
+Image de 350x100 pixels.

+

( devrait pouvoir détecter si vidéo ou non )

+

Blocs de citations

+

Un bloc de citation se crée ainsi :

+
> Ceci est
+> un bloc de
+> citation
+
+

Ceci est +un bloc de +citation

+
+

Il est possible d'intégrer de la syntaxe Markdown-AE dans un tel bloc.

+

Note de bas de page

+

On les créer comme ça1:

+

é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>
  • +
+

Autres ( hérité de l'ancien wiki )

+
    +
  • 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))

    +
    +
  • +
+
+
+
  1. ceci est le contenu de ma 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
    +
    +

    Vous pouvez utiliser des numéros pour nommer vos clef si vous avez la flemme.

    +
    Note plus complexe[^1]
    +
    +[^1]:
    +    je peux même faire des blocks   
    +    sur plusieurs lignes, comme d'habitude!
    +

  2. +
+
diff --git a/doc/SYNTAX.md b/doc/SYNTAX.md index e2e7d6a4..0515f05c 100644 --- a/doc/SYNTAX.md +++ b/doc/SYNTAX.md @@ -2,6 +2,15 @@ Cette page vise à documenter la syntaxe *Markdown* utilisée sur le site. # Markdown-AE Documentation +Le Markdown le plus standard se trouve documenté ici: +https://daringfireball.net/projects/markdown/syntax . +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. + +Le réel parseur du site AE est une version tunée de [mistune](https://github.com/lepture/mistune). +Les plus aventureux pourront aller lire ses [tests](https://github.com/lepture/mistune/blob/master/tests/fixtures) +afin d'en connaître la syntaxe le plus finement possible. +En pratique, cette page devrait déjà résumer une bonne partie. ## Basique @@ -13,10 +22,11 @@ Cette page vise à documenter la syntaxe *Markdown* utilisée sur le site. * ~~Barrer du texte~~ : `~~texte~~` -* ^Mettre du texte^ en ^exposant : `^mot` ou `^texte^` +* On peut bien sûr tout ~~***__combiner__***~~ : `~~***__texte__***~~` -* _Mettre du texte_ en _indice : `_mot` ou `_texte_` +* Mettre du texte en exposant : `texte` +* Mettre du texte en indice : `texte` ## Liens @@ -30,9 +40,9 @@ 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 -l'adresse complète d'une page : `[nom du lien](article://nomDeLaPage)` +l'adresse complète d'une page : `[nom du lien](page://nomDeLaPage)` -[nom du lien](article://nomDeLaPage) +[nom du lien](page://nomDeLaPage) * On peut également utiliser une image pour les liens : `[nom du lien]![images/imageDuSiteAE.png](/chemin/vers/image.png titre optionnel)(options)` @@ -58,6 +68,14 @@ etc... 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 + +Un nouveau paragraphe se fait avec deux retours à la ligne. + +Un saut de ligne se force avec au moins deux espaces en fin de ligne. + ## Listes @@ -81,7 +99,13 @@ Vous pouvez marquer plus simplement comme suit, les numéros se faisant tout seu 1. élément ``` +1. élément +1. élément +1. élément + + * non ordonnées : + ``` * élément * élément @@ -94,7 +118,7 @@ Vous pouvez marquer plus simplement comme suit, les numéros se faisant tout seu ## Tableaux -Un tableau est obtenu en respectant la syntax suivante : +Un tableau est obtenu en respectant la syntaxe suivante : ``` | Titre | Titre2 | Titre3 | @@ -107,25 +131,42 @@ Un tableau est obtenu en respectant la syntax suivante : | test | test | test | | test | test | test | -L'alignement dans les cellules est géré en mettant des espaces à droite ou a gauche des chaines de caractères contenues dans chaque case. +L'alignement dans les cellules est géré comme suit, avec les ':' sur la ligne en dessous du titre: ``` -| Titre | Titre2 | Titre3 | -|-------|--------|--------| -|gauche | centre | droite| +| Titre | Titre2 | Titre3 | +|:-------|:------:|-------:| +| gauche | centre | droite | ``` -| Titre | Titre2 | Titre3 | -|-------|--------|--------| -|gauche | centre | droite| +| Titre | Titre2 | Titre3 | +|:-------|:------:|-------:| +| gauche | centre | droite | ## Images et contenus -Une image est insérée ainsi : `![texte alternatif](/chemin/vers/image.png "titre optionnel")(options)` -![texte alternatif](/static/core/img/logo.png "titre optionnel")(options) +Une image est insérée ainsi : `![texte alternatif](/chemin/vers/image.png "titre optionnel")` +![texte alternatif](/static/core/img/logo.png "titre optionnel") + +On peut lui spécifier ses dimensions de plusieurs manières: + +``` +![image à 50%](/static/core/img/logo.png?50% "Image à 50%") +![image de 350 pixels de large](/static/core/img/logo.png?350 "Image de 350 pixels") +![image de 350x100 pixels](/static/core/img/logo.png?350x100 "Image de 350x100 pixels") +``` + + +![image à 50%](/static/core/img/logo.png?50% "Image à 50%") +Image à 50% de la largeur de la page. + +![image de 350 pixels de large](/static/core/img/logo.png?350 "Image de 350 pixels") +Image de 350 pixels de large. + +![image de 350x100 pixels](/static/core/img/logo.png?350x100 "Image de 350x100 pixels") +Image de 350x100 pixels. ( devrait pouvoir détecter si vidéo ou non ) -( TODO : parametres ) ## Blocs de citations @@ -142,7 +183,26 @@ Un bloc de citation se crée ainsi : Il est possible d'intégrer de la syntaxe Markdown-AE dans un tel bloc. +## Note de bas de page +On les créer comme ça[^key]: + +[^key]: ceci est le contenu de ma 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 + ``` + Vous pouvez utiliser des numéros pour nommer vos clef si vous avez la flemme. + + ``` + Note plus complexe[^1] + + [^1]: + je peux même faire des blocks + sur plusieurs lignes, comme d'habitude! + + ``` ## échapper des caractères @@ -160,3 +220,4 @@ Il est possible d'intégrer de la syntaxe Markdown-AE dans un tel bloc. > ((note)) + diff --git a/sith/settings.py b/sith/settings.py index 5d53c6ea..bbeb59ad 100644 --- a/sith/settings.py +++ b/sith/settings.py @@ -36,6 +36,7 @@ https://docs.djangoproject.com/en/1.8/ref/settings/ # Build paths inside the project like this: os.path.join(BASE_DIR, ...) import os +import sys import binascii from django.utils.translation import ugettext_lazy as _ @@ -569,9 +570,9 @@ SITH_MAILING_FETCH_KEY = 'IloveMails' try: from .settings_custom import * - print("Custom settings imported") + print("Custom settings imported", file=sys.stderr) except: - print("Custom settings failed") + print("Custom settings failed", file=sys.stderr) if DEBUG: INSTALLED_APPS += ("debug_toolbar",)