From 43f7d7816ad1f3c39ec75eed40b6ac9ae1f359b3 Mon Sep 17 00:00:00 2001
From: "J.-S. Caux" <J.S.Caux@uva.nl>
Date: Sat, 8 Jun 2019 22:14:01 +0200
Subject: [PATCH] Include markup help pages. Still very incomplete.

---
 markup/constants.py                           | 308 ++++++++++++++++++
 markup/forms.py                               |   7 +-
 markup/templates/markup/base.html             |  13 +
 markup/templates/markup/help.html             | 111 +++++++
 markup/templates/markup/markdown_help.html    | 166 ++++++++++
 markup/templates/markup/plaintext_help.html   |  62 ++++
 .../markup/restructuredtext_help.html         |  58 ++++
 markup/templatetags/process_markup.py         |  22 +-
 markup/urls.py                                |  20 ++
 markup/views.py                               |  46 ++-
 .../static/scipost/assets/css/_general.scss   |   6 +
 11 files changed, 805 insertions(+), 14 deletions(-)
 create mode 100644 markup/constants.py
 create mode 100644 markup/templates/markup/base.html
 create mode 100644 markup/templates/markup/help.html
 create mode 100644 markup/templates/markup/markdown_help.html
 create mode 100644 markup/templates/markup/plaintext_help.html
 create mode 100644 markup/templates/markup/restructuredtext_help.html

diff --git a/markup/constants.py b/markup/constants.py
new file mode 100644
index 000000000..73b658f9f
--- /dev/null
+++ b/markup/constants.py
@@ -0,0 +1,308 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+BLEACH_ALLOWED_TAGS = [
+    'a', 'abbr', 'acronym', 'b', 'blockquote', 'br', 'code', 'em',
+    'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'li', 'ol',
+    'p', 'pre', 'strong', 'table', 'td', 'th', 'tr', 'ul',
+]
+
+
+MathSnippets = (
+    {
+        'title': 'Inline and online equations',
+        'raw':
+r"""Some say $e^{i\pi} + 1 = 0$ is the most beautiful equation there is.
+
+Do you know this famous Hamiltonian?
+\[
+H = \sum_j {\boldsymbol S}_j \cdot {\boldsymbol S}_{j+1}
+\]
+
+What about this one?
+$$
+H = \int dx \left[ \partial_x \Psi^\dagger \partial_x \Psi
++ c \Psi^\dagger \Psi^\dagger \Psi \Psi \right]
+$$
+""",
+    },
+    {
+        'title': 'Multiline equations',
+        'raw':
+r"""
+Maxwell's equations:
+\[
+\begin{align*}
+\nabla \cdot {\boldsymbol E} &= \frac{\rho}{\epsilon_0}, &
+\nabla \times {\boldsymbol E} + \frac{\partial \boldsymbol B}{\partial t} &= 0, \\
+\nabla \cdot {\boldsymbol B} &= 0, &
+\nabla \times {\boldsymbol B} - \frac{1}{c^2} \frac{\partial \boldsymbol E}{\partial t}
+&= \mu_0 {\boldsymbol J}
+\end{align*}
+\]
+
+$$
+\begin{align}
+\nabla \cdot {\boldsymbol E} &= \frac{\rho}{\epsilon_0}, &
+\nabla \times {\boldsymbol E} + \frac{\partial \boldsymbol B}{\partial t} &= 0, \\
+\nabla \cdot {\boldsymbol B} &= 0, &
+\nabla \times {\boldsymbol B} - \frac{1}{c^2} \frac{\partial \boldsymbol E}{\partial t}
+&= \mu_0 {\boldsymbol J}
+\end{align}
+$$
+
+$$
+\begin{align}
+\nabla \cdot {\boldsymbol E} = \frac{\rho}{\epsilon_0},
+\nabla \times {\boldsymbol E} + \frac{\partial \boldsymbol B}{\partial t} = 0, \\
+\nabla \cdot {\boldsymbol B} = 0,
+\nabla \times {\boldsymbol B} - \frac{1}{c^2} \frac{\partial \boldsymbol E}{\partial t}
+= \mu_0 {\boldsymbol J}
+\label{eq:Maxwell}
+\end{align}
+$$
+"""
+        },
+)
+
+
+PlainTextSnippets = {
+    'maths_inline_online':
+r"""Some say $e^{i\pi} + 1 = 0$ is the most beautiful equation of all.
+
+Do you know this famous Hamiltonian?
+\[
+H = \sum_j {\boldsymbol S}_j \cdot {\boldsymbol S}_{j+1}
+\]
+
+What about this one?
+$$
+H = \int dx \left[ \partial_x \Psi^\dagger \partial_x \Psi
++ c \Psi^\dagger \Psi^\dagger \Psi \Psi \right]
+$$
+""",
+
+    'maths_multiple_lines':
+"""
+Equations on multiple lines:
+\[
+\nabla \cdot {\boldsymbol E} = \frac{\rho}{\epsilon_0}, \qquad
+\nabla \times {\boldsymbol E} + \frac{\partial \boldsymbol B}{\partial t}= 0 \\\\
+\nabla \cdot {\boldsymbol B} = 0, \qquad
+\nabla \times {\boldsymbol B} - \frac{1}{c^2} \frac{\partial \boldsymbol E}{\partial t}
+= \mu_0 {\boldsymbol J}
+\]
+
+\[
+\begin{eqnarray*}
+\nabla \cdot {\boldsymbol E} &=& \frac{\rho}{\epsilon_0}, \qquad
+\nabla \times {\boldsymbol E} + \frac{\partial \boldsymbol B}{\partial t} &=& 0 \\\\
+\nabla \cdot {\boldsymbol B} &=& 0, \qquad
+\nabla \times {\boldsymbol B} - \frac{1}{c^2} \frac{\partial \boldsymbol E}{\partial t}
+&=& \mu_0 {\boldsymbol J}
+\end{eqnarray*}
+\]
+"""
+}
+
+
+MarkdownSnippets = {
+    'paragraphs':
+"""Including an empty line between two blocks of text separates those into
+
+two different paragraphs.
+
+Typing text on consecutive lines separated
+by linebreaks
+will merge the lines into one
+paragraph.
+
+However if you explicitly end a line with two spaces
+then a linebreak will be forced.""",
+
+    'headers':
+"""# Level 1 (html h1)
+Topmost headline
+
+## Level 2 (h2)
+two
+
+### Level 3 (h3)
+three
+
+#### Level 4 (h4)
+four
+
+##### Level 5 (h5)
+five
+
+###### Level 6 (h6)
+six, lowest level available.""",
+
+    'emphasis':
+"""You can obtain italics with *asterisks* or _single underscores_,
+and boldface using **double asterisks** or __double underscores__.
+
+If you need to explicitly use these characters (namely \* and \_),
+you can escape them with a backslash.""",
+
+    'blockquotes':
+"""> This is a blockquote with two paragraphs. You should begin
+> each line with a ">" (greater than) symbol.
+>
+> Here is the second paragraph. The same wrapup rules
+> apply as per
+> normal paragraphs.
+
+A line of normal text will separate blockquotes.
+
+> Otherwise
+
+> multiple blockquotes
+
+> will be merged into one.
+
+You can be lazy and simply put a single ">" in front of
+a hard-wrapped paragraph, and all the
+text will be included in a single wrapped-up blockquote.
+
+> This is especially handy if you are copy and pasting e.g.
+a referee's comment which you want to respond to, and
+which spans
+multiple
+lines.
+
+Finally,
+
+> you can
+>> nest
+>>> many levels
+>>>> of blockquotes
+
+>>> and come back to a lower level by putting a blank line
+
+>> to indicate a "terminated" level.
+""",
+
+    'lists':
+"""Markdown supports unordered (bulleted) and ordered (numbered) lists.
+
+Unordered list items are marked with asterisk, plus or hyphen, which
+can be used interchangeable (even within a single list):
+
+* first item
++ second item
+- third item
+
+Ordered list items are marked by a number (it does not matter which,
+they will be automatically recomputed anyway) followed by a period:
+
+1. first item
+7. second item
+123. third item
+42. fourth item
+1. fifth item
+
+If you separate list items by blank lines, an HTML paragraph will
+be wrapped around each item, giving more padding around the items:
+
+1. first item
+
+1. second item
+
+Nested lists can be obtained by four-space (or tab) indentation:
+
+1. First mainlist item
+    1. first sublist item
+    1. second sublist item
+1. Second mainlist item""",
+
+    'code':
+"""An inline code span, to mention simple things like the
+`print()` function, is obtained by wrapping it with single backticks.
+
+A code block is obtained by indenting the code by 4 spaces or a tab:
+
+    from django import forms
+
+    class MarkupTextForm(forms.Form):
+        markup_text = forms.CharField()
+
+        def get_processed_markup(self):
+            text = self.cleaned_data['markup_text']""",
+
+    'hr':
+"""A horizontal rule (HTML hr) can be obtained by writing three or
+more asterisks, hyphens or underscores on a line by themselves:
+
+text
+
+***
+
+more text
+
+-----
+
+more text
+_______
+
+Be careful to include an empty line before hyphens,
+otherwise the system might
+
+confuse the preceding text for a headline
+-------
+""",
+
+    'links':
+"""### Inline-style hyperlinks
+
+Here is an example of an inline link to the [SciPost homepage](https://scipost.org/).
+
+For example, one can also link to
+a specific [Submission](https://scipost.org/submissions/1509.04230v5/)
+or a specific [Report](https://scipost.org/submissions/1509.04230v4/#report_2).
+
+### Reference-style hyperlinks
+
+You can also use reference-style links when citing this [resource][md],
+which you need to cite [again][md] and [again][md]
+and [again][md].
+
+The reference will be resolved provided you define the link label somewhere
+in your text.
+
+[md]: https://daringfireball.net/projects/markdown/syntax""",
+
+    'maths_inline_online':
+r"""### Inline maths
+
+You can have simple inline equations like this: $E = mc^2$ by enclosing them with
+dollar signs.
+
+### Online maths
+
+For online maths, you need to enclose the equations with double dollar signs:
+
+$$
+H = \sum_j S^x_j S^x_{j+1} + S^y_j S^y_{j+1} + \Delta S^z_j S^z_{j+1}
+$$
+"""
+}
+
+
+ReStructuredTextSnippets = {
+    'maths_inline_online':
+r"""Inline maths
+============
+
+For inline equations, you must use the :code:`math` role, for example :math:`E = mc^2`.
+
+On-line maths
+=============
+
+For on-line display of equations, the :code:`math` directive must be used:
+
+.. math::
+  H = \sum_j {\boldsymbol S}_j \cdot {\boldsymbol S}_{j+1}"""
+}
diff --git a/markup/forms.py b/markup/forms.py
index eca1fcfdd..8dcc56976 100644
--- a/markup/forms.py
+++ b/markup/forms.py
@@ -11,6 +11,7 @@ from django import forms
 from django.utils.encoding import force_text
 from django.utils.safestring import mark_safe
 
+from .constants import BLEACH_ALLOWED_TAGS
 from .utils import detect_markup_language
 
 
@@ -60,11 +61,7 @@ class MarkupTextForm(forms.Form):
                 #'processed_markup': markdown.markdown(escape(text), output_format='html5')
                 'processed_markup': bleach.clean(
                     markdown.markdown(text, output_format='html5'),
-                    tags=['a', 'abbr', 'acronym', 'b', 'blockquote', 'code', 'em',
-                          'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'i', 'li', 'ol',
-                          'p', 'pre', 'strong', 'ul',
-                          ])
-                # 'processed_markup': markdown.markdown(text, output_format='html5')
+                    tags=BLEACH_ALLOWED_TAGS)
                 }
 
         # at this point, language is assumed to be plain text
diff --git a/markup/templates/markup/base.html b/markup/templates/markup/base.html
new file mode 100644
index 000000000..1e4b463f7
--- /dev/null
+++ b/markup/templates/markup/base.html
@@ -0,0 +1,13 @@
+{% extends 'scipost/base.html' %}
+
+{% block breadcrumb %}
+  <div class="container-outside header">
+    <div class="container">
+      <nav class="breadcrumb hidden-sm-down">
+        {% block breadcrumb_items %}
+          <a href="{% url 'markup:help' %}" class="breadcrumb-item">Markup</a>
+        {% endblock %}
+      </nav>
+    </div>
+  </div>
+{% endblock %}
diff --git a/markup/templates/markup/help.html b/markup/templates/markup/help.html
new file mode 100644
index 000000000..a2bc522b3
--- /dev/null
+++ b/markup/templates/markup/help.html
@@ -0,0 +1,111 @@
+{% extends 'markup/base.html' %}
+
+{% block pagetitle %}: Markup help{% endblock pagetitle %}
+
+{% block breadcrumb_items %}
+  {{ block.super }}
+  <span class="breadcrumb-item">Help</span>
+{% endblock %}
+
+{% block content %}
+
+  <div class="row">
+    <div class="col-12">
+      <h2 class="highlight">Markup help</h2>
+
+      <p>
+	On many occasions while contributing to SciPost,
+	one has to fill in a text-based field in a web form.
+	For many reasons, it is desirable to give <em>structure</em> to what one writes.
+	We offer <strong>markup facilities</strong> to enable you to do this.
+      </p>
+
+      <p>
+	We support three options:
+	<ul>
+	  <li>plain text</li>
+	  <li>Markdown</li>
+	  <li>reStructuredText</li>
+	</ul>
+	Each of these supports LaTeX via <a href="https://www.mathjax.org">MathJax</a>,
+	though the precise semantics varies from one option to the other.
+      </p>
+
+      <p>
+	Which should you choose? This is mostly a question of personal preference.
+	To help you decide, here is a quick summary of main points to bear in mind:
+	<table class="table table-bordered">
+	  <tr>
+	    <th>Option</th><th>Advantages</th><th>Disadvantages</th>
+	  </tr>
+	  <tr>
+	    <td>Plain text</td>
+	    <td>
+	      <ul>
+		<li>Simplicity</li>
+	      </ul>
+	    </td>
+	    <td>
+	      <ul>
+		<li>No markup!</li>
+	      </ul>
+	    </td>
+	  </tr>
+	  <tr>
+	    <td>Markdown</td>
+	    <td>
+	      <ul>
+		<li>ease of use</li>
+		<li>
+		  provides more or less all the markup you'll ever need,
+		  at least for small snippets
+		</li>
+	      </ul>
+	    </td>
+	    <td>
+	      <ul>
+		<li>non-standardized: many dozen "dialects" exist</li>
+		<li>not really meant for large, complex documents</li>
+	      </ul>
+	    </td>
+	  </tr>
+	  <tr>
+	    <td>reStructuredText</td>
+	    <td>
+	      <ul>
+		<li>relative ease of use</li>
+		<li>standardized: the language is well-defined and stable</li>
+		<li>
+		  it's the standard documentation language for Python;
+		  <a href="http://www.sphinx-doc.org/">Sphinx</a> uses ReST
+		  files as input
+		</li>
+		<li>ReST files are easily exportable to other formats such
+		  as HTML, LaTeX etc.
+		</li>
+	      </ul>
+	    </td>
+	    <td>
+	      <ul>
+		<li>support for maths is good, but remains less extensive than in LaTeX</li>
+	      </ul>
+	    </td>
+	  </tr>
+	</table>
+      </p>
+
+      <p>
+	Which option you choose is completely up to you. Our system will determine
+	which one you are using and render your input accordingly.
+      </p>
+
+      <h3 class="highlight" id="Plain">Plain text</h3>
+      <p>See our <a href="{% url 'markup:plaintext_help' %}">plain text-specific</a> help page</p>
+      <h3 class="highlight" id="Markdown">Markdown</h3>
+      <p>See our <a href="{% url 'markup:markdown_help' %}">Markdown-specific</a> help page</p>
+      <h3 class="highlight" id="reStructuredText">reStructuredText</h3>
+      <p>See our <a href="{% url 'markup:restructuredtext_help' %}">reStructuredText-specific</a> help page</p>
+    </div>
+  </div>
+
+{% endblock content %}
diff --git a/markup/templates/markup/markdown_help.html b/markup/templates/markup/markdown_help.html
new file mode 100644
index 000000000..bf65bdabc
--- /dev/null
+++ b/markup/templates/markup/markdown_help.html
@@ -0,0 +1,166 @@
+{% extends 'markup/base.html' %}
+
+{% block pagetitle %}: Markup help{% endblock pagetitle %}
+
+{% block breadcrumb_items %}
+  {{ block.super }}
+  <span class="breadcrumb-item"><a href="{% url 'markup:help' %}">Help</a></span>
+    <span class="breadcrumb-item">Markdown</span>
+{% endblock %}
+
+{% load process_markup %}
+
+{% block content %}
+
+  <div class="row">
+    <div class="col-12">
+      <h2 class="highlight">Markdown help</h2>
+
+      <p>You will find below a quick summary of Markdown basics, as enabled here at SciPost.</p>
+      <p>You can find more details about Markdown's syntax at <a href="https://daringfireball.net/projects/markdown/syntax">this page</a>.</p>
+
+      <h3>Quick links</h3>
+      <ul>
+	<li><a href="#Paragraphs">Paragraphs and line breaks</a></li>
+	<li><a href="#Headlines">Headlines</a></li>
+	<li><a href="Emphasis">Emphasis</a></li>
+	<li><a href="#Blockquotes">Blockquotes</a></li>
+	<li><a href="#Lists">Lists</a></li>
+	<li><a href="#Code">Code blocks</a></li>
+	<li><a href="#HR">Horizontal rules</a></li>
+	<li><a href="#Links">Links</a></li>
+	<li><a href="#Mathematics">Mathematics</a></li>
+      </ul>
+
+      <h3 class="highlight" id="Paragraphs">Paragraphs and line breaks</h3>
+      <div class="row">
+	<div class="col-6">
+	  <h3><strong>If you write:</strong></h3>
+	  <pre>{{ snippets.paragraphs }}</pre>
+	</div>
+	<div class="col-6">
+	  <h3><strong>You will get:</strong></h3>
+	  {{ snippets.paragraphs|safe|process_markup:'Markdown' }}
+	</div>
+      </div>
+
+      <h3 class="highlight" id="Headlines">Headlines</h3>
+      <div class="row">
+	<div class="col-6">
+	  <h3><strong>If you write:</strong></h3>
+	  <pre>{{ snippets.headers }}</pre>
+	</div>
+	<div class="col-6">
+	  <h3><strong>You will get:</strong></h3>
+	  {{ snippets.headers|process_markup:'Markdown' }}
+	</div>
+      </div>
+
+      <h3 class="highlight" id="Emphasis">Emphasis</h3>
+      <div class="row">
+	<div class="col-6">
+	  <h3><strong>If you write:</strong></h3>
+	  <pre>{{ snippets.emphasis }}</pre>
+	</div>
+	<div class="col-6">
+	  <h3><strong>You will get:</strong></h3>
+	  {{ snippets.emphasis|process_markup:'Markdown' }}
+	</div>
+      </div>
+
+      <h3 class="highlight" id="Blockquotes">Blockquotes</h3>
+      <div class="row">
+	<div class="col-6">
+	  <h3><strong>If you write:</strong></h3>
+	  <pre>{{ snippets.blockquotes }}</pre>
+	</div>
+	<div class="col-6">
+	  <h3><strong>You will get:</strong></h3>
+	  {{ snippets.blockquotes|safe|process_markup:'Markdown' }}
+	</div>
+      </div>
+
+      <h3 class="highlight" id="Lists">Lists</h3>
+      <div class="row">
+	<div class="col-6">
+	  <h3><strong>If you write:</strong></h3>
+	  <pre>{{ snippets.lists }}</pre>
+	</div>
+	<div class="col-6">
+	  <h3><strong>You will get:</strong></h3>
+	  {{ snippets.lists|safe|process_markup:'Markdown' }}
+	</div>
+      </div>
+
+      <h3 class="highlight" id="Code">Code</h3>
+      <div class="row">
+	<div class="col-6">
+	  <h3><strong>If you write:</strong></h3>
+	  <pre>{{ snippets.code }}</pre>
+	</div>
+	<div class="col-6">
+	  <h3><strong>You will get:</strong></h3>
+	  {{ snippets.code|safe|process_markup:'Markdown' }}
+	</div>
+      </div>
+
+      <h3 class="highlight" id="HR">Horizontal rules</h3>
+      <div class="row">
+	<div class="col-6">
+	  <h3><strong>If you write:</strong></h3>
+	  <pre>{{ snippets.hr }}</pre>
+	</div>
+	<div class="col-6">
+	  <h3><strong>You will get:</strong></h3>
+	  {{ snippets.hr|safe|process_markup:'Markdown' }}
+	</div>
+      </div>
+
+      <h3 class="highlight" id="Links">Links</h3>
+      <div class="row">
+	<div class="col-6">
+	  <h3><strong>If you write:</strong></h3>
+	  <pre>{{ snippets.links }}</pre>
+	</div>
+	<div class="col-6">
+	  <h3><strong>You will get:</strong></h3>
+	  {{ snippets.links|safe|process_markup:'Markdown' }}
+	</div>
+      </div>
+
+      <h3 class="highlight" id="Mathematics">Mathematics</h3>
+      <div class="row">
+	<div class="col-6">
+	  <h3><strong>If you write:</strong></h3>
+	  <pre>{{ snippets.maths_inline_online }}</pre>
+	</div>
+	<div class="col-6">
+	  <h3><strong>You will get:</strong></h3>
+	  {{ snippets.maths_inline_online|safe|process_markup:'Markdown' }}
+	</div>
+      </div>
+
+    </div>
+  </div>
+
+  {% with language='Markdown' %}
+    <div class="row">
+      <div class="col-12">
+	<h3 class="highlight">Math snippets</h3>
+	{{ math_snippets.length }}
+	{% for snippet in math_snippets %}
+	  <h4>{{ snippet.title }}</h4>
+	  <div class="row">
+	    <div class="col-lg-6">
+	      <pre>{{ snippet.raw }}</pre>
+	    </div>
+	    <div class="col-lg-6">
+	      {{ snippet.raw|safe|process_markup:language }}
+	    </div>
+	  </div>
+	{% endfor %}
+      </div>
+    </div>
+  {% endwith %}
+
+{% endblock content %}
diff --git a/markup/templates/markup/plaintext_help.html b/markup/templates/markup/plaintext_help.html
new file mode 100644
index 000000000..ff5de32ef
--- /dev/null
+++ b/markup/templates/markup/plaintext_help.html
@@ -0,0 +1,62 @@
+{% extends 'markup/base.html' %}
+
+{% block pagetitle %}: Markup help{% endblock pagetitle %}
+
+{% block breadcrumb_items %}
+  {{ block.super }}
+  <span class="breadcrumb-item"><a href="{% url 'markup:help' %}">Help</a></span>
+  <span class="breadcrumb-item">Plain text</span>
+{% endblock %}
+
+{% load process_markup %}
+
+{% block content %}
+
+  <div class="row">
+    <div class="col-12">
+      <h2 class="highlight">Plain text help</h2>
+
+      <h3 class="highlight" id="Mathematics">Mathematics</h3>
+
+      <p>
+	You can delimit inline maths using dollar signs like this: <code>&#36; ... &#36;</code>.
+      </p>
+      <p>
+	For on-line maths, use escaped angular brackets
+	<code>&#92;&#91; ... &#92;&#93;</code> or
+	double-dollar delimiters <code>$$ ... $$</code>.
+      </p>
+      <div class="row">
+	<div class="col-6">
+	  <h4><strong>If you write:</strong></h4>
+	  <pre>{{ snippets.maths_inline_online }}</pre>
+	</div>
+	<div class="col-6">
+	  <h4><strong>You will get:</strong></h4>
+	  {{ snippets.maths_inline_online|safe|process_markup:'plain' }}
+	</div>
+      </div>
+    </div>
+  </div>
+
+  {% with language='plain' %}
+    <div class="row">
+      <div class="col-12">
+	<h3 class="highlight">Math snippets</h3>
+	{{ math_snippets.length }}
+	{% for snippet in math_snippets %}
+	  <h4>{{ snippet.title }}</h4>
+	  <div class="row">
+	    <div class="col-lg-6">
+	      <pre>{{ snippet.raw }}</pre>
+	    </div>
+	    <div class="col-lg-6">
+	      {{ snippet.raw|safe|process_markup:language }}
+	    </div>
+	  </div>
+	{% endfor %}
+      </div>
+    </div>
+  {% endwith %}
+
+{% endblock content %}
diff --git a/markup/templates/markup/restructuredtext_help.html b/markup/templates/markup/restructuredtext_help.html
new file mode 100644
index 000000000..d92733245
--- /dev/null
+++ b/markup/templates/markup/restructuredtext_help.html
@@ -0,0 +1,58 @@
+{% extends 'markup/base.html' %}
+
+{% block pagetitle %}: Markup help{% endblock pagetitle %}
+
+{% block breadcrumb_items %}
+  {{ block.super }}
+  <span class="breadcrumb-item"><a href="{% url 'markup:help' %}">Help</a></span>
+  <span class="breadcrumb-item">reStructuredText</span>
+{% endblock %}
+
+{% load process_markup %}
+
+{% block content %}
+
+  <div class="row">
+    <div class="col-12">
+      <h2 class="highlight">reStructuredText help</h2>
+
+      <h3 class="highlight" id="Mathematics">Mathematics</h3>
+
+      <p>
+	For mathematics in reStructuredText, you must use the <code>math</code>
+	directive/role.
+      </p>
+      <div class="row">
+	<div class="col-6">
+	  <h4><strong>If you write:</strong></h4>
+	  <pre>{{ snippets.maths_inline_online }}</pre>
+	</div>
+	<div class="col-6">
+	  <h4><strong>You will get:</strong></h4>
+	  {{ snippets.maths_inline_online|safe|process_markup:'reStructuredText' }}
+	</div>
+      </div>
+    </div>
+  </div>
+
+  {% with language='reStructuredText' %}
+    <div class="row">
+      <div class="col-12">
+	<h3 class="highlight">Math snippets</h3>
+	{{ math_snippets.length }}
+	{% for snippet in math_snippets %}
+	  <h4>{{ snippet.title }}</h4>
+	  <div class="row">
+	    <div class="col-lg-6">
+	      <pre>{{ snippet.raw }}</pre>
+	    </div>
+	    <div class="col-lg-6">
+	      {{ snippet.raw|safe|process_markup:language }}
+	    </div>
+	  </div>
+	{% endfor %}
+      </div>
+    </div>
+  {% endwith %}
+
+{% endblock content %}
diff --git a/markup/templatetags/process_markup.py b/markup/templatetags/process_markup.py
index 70de66695..c73702410 100644
--- a/markup/templatetags/process_markup.py
+++ b/markup/templatetags/process_markup.py
@@ -2,32 +2,39 @@ __copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
 __license__ = "AGPL v3"
 
 
+import bleach
 from docutils.core import publish_parts
 from io import StringIO
 import markdown
-from markupsafe import escape
 
 from django import template
 from django.template.defaultfilters import linebreaksbr
 from django.utils.encoding import force_text
 from django.utils.safestring import mark_safe
 
+from ..constants import BLEACH_ALLOWED_TAGS
 from ..utils import detect_markup_language
 
+
 register = template.Library()
 
 
 @register.filter(name='process_markup')
-def process_markup(text):
+def process_markup(text, language_forced=None):
     if not text:
         return ''
 
     markup_detector = detect_markup_language(text)
+    print('language detected: %s' % markup_detector['language'])
 
     if markup_detector['errors']:
         return markup_detector['errors']
 
-    if markup_detector['language'] == 'reStructuredText':
+    language = markup_detector['language']
+    if language_forced:
+        language = language_forced
+
+    if language == 'reStructuredText':
         warnStream = StringIO()
         try:
             parts = publish_parts(
@@ -45,8 +52,11 @@ def process_markup(text):
         except:
             return warnStream.getvalue()
 
-    elif markup_detector['language'] == 'Markdown':
-        return mark_safe(markdown.markdown(escape(text), output_format='html5'))
-
+    elif language == 'Markdown':
+        return mark_safe(
+            bleach.clean(
+                markdown.markdown(text, output_format='html5'),
+                tags=BLEACH_ALLOWED_TAGS)
+        )
     else:
         return linebreaksbr(text)
diff --git a/markup/urls.py b/markup/urls.py
index 3e014641c..dd40e7598 100644
--- a/markup/urls.py
+++ b/markup/urls.py
@@ -15,4 +15,24 @@ urlpatterns = [
         views.process,
         name='process'
     ),
+    url(
+        r'^help/$',
+        views.markup_help,
+        name='help'
+    ),
+    url(
+        r'^help/plaintext$',
+        views.plaintext_help,
+        name='plaintext_help'
+    ),
+    url(
+        r'^help/Markdown$',
+        views.markdown_help,
+        name='markdown_help'
+    ),
+    url(
+        r'^help/reStructuredText$',
+        views.restructuredtext_help,
+        name='restructuredtext_help'
+    ),
 ]
diff --git a/markup/views.py b/markup/views.py
index 72d1579e6..507e1adbd 100644
--- a/markup/views.py
+++ b/markup/views.py
@@ -5,13 +5,14 @@ __license__ = "AGPL v3"
 from django.http import JsonResponse
 from django.shortcuts import render
 
-from markup.forms import MarkupTextForm
-
+from .constants import MathSnippets, PlainTextSnippets,\
+    MarkdownSnippets, ReStructuredTextSnippets
+from .forms import MarkupTextForm
 
 
 def process(request):
     """
-    Process the POSTed text.
+    API call to process the POSTed text.
 
     This returns a JSON dict containing
 
@@ -22,3 +23,42 @@ def process(request):
     if form.is_valid():
         return JsonResponse(form.get_processed_markup())
     return JsonResponse({})
+
+
+def markup_help(request):
+    """
+    General help page about markup facilities at SciPost.
+    """
+    return render(request, 'markup/help.html')
+
+
+def plaintext_help(request):
+    """
+    Help page for plain text.
+    """
+    context = {
+        'math_snippets': MathSnippets,
+        'snippets': PlainTextSnippets,
+    }
+    return render(request, 'markup/plaintext_help.html', context)
+
+def markdown_help(request):
+    """
+    Help page for Markdown.
+    """
+    context = {
+        'math_snippets': MathSnippets,
+        'snippets': MarkdownSnippets,
+    }
+    return render(request, 'markup/markdown_help.html', context)
+
+
+def restructuredtext_help(request):
+    """
+    Help page for reStructuredText.
+    """
+    context = {
+        'math_snippets': MathSnippets,
+        'snippets': ReStructuredTextSnippets,
+    }
+    return render(request, 'markup/restructuredtext_help.html', context)
diff --git a/scipost/static/scipost/assets/css/_general.scss b/scipost/static/scipost/assets/css/_general.scss
index a76c5a9e1..5de4f5179 100644
--- a/scipost/static/scipost/assets/css/_general.scss
+++ b/scipost/static/scipost/assets/css/_general.scss
@@ -13,6 +13,12 @@
     background-color: transparent;
 }
 
+blockquote {
+    margin-left: 0.5rem;
+    padding-left: 0.5rem;
+    border-left: 2px solid grey;
+}
+
 body #MathJax_Message {
     left: 1rem;
     bottom: 1rem;
-- 
GitLab