info_overlay: Render Markdown help with frontend Markdown library.

Fixes #15375.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2021-03-10 18:09:13 -08:00 committed by Tim Abbott
parent 31e865d9ed
commit 7f30e5f9df
5 changed files with 167 additions and 164 deletions

View File

@ -1,16 +1,153 @@
import render_markdown_help from "../templates/markdown_help.hbs";
import * as common from "./common"; import * as common from "./common";
import * as components from "./components"; import * as components from "./components";
import * as hashchange from "./hashchange"; import * as hashchange from "./hashchange";
import * as keydown_util from "./keydown_util"; import * as keydown_util from "./keydown_util";
import * as markdown from "./markdown";
import * as overlays from "./overlays"; import * as overlays from "./overlays";
import * as popovers from "./popovers"; import * as popovers from "./popovers";
import * as rendered_markdown from "./rendered_markdown";
import * as ui from "./ui"; import * as ui from "./ui";
import * as util from "./util";
// Make it explicit that our toggler is undefined until // Make it explicit that our toggler is undefined until
// set_up_toggler is called. // set_up_toggler is called.
export let toggler; export let toggler;
const markdown_help_rows = [
{
markdown: "*italic*",
usage_html: "(or <kbd>Ctrl</kbd>+<kbd>I</kbd>)",
},
{
markdown: "**bold**",
usage_html: "(or <kbd>Ctrl</kbd>+<kbd>B</kbd>)",
},
{
markdown: "~~strikethrough~~",
},
{
markdown: "[Zulip website](https://zulip.org)",
usage_html: "(or <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>L</kbd>)",
},
{
markdown: `\
* Milk
* Tea
* Green tea
* Black tea
* Oolong tea
* Coffee`,
},
{
markdown: `\
1. Milk
1. Tea
1. Coffee`,
},
{
markdown: ":heart:",
usage_html:
'(and <a href="https://www.webfx.com/tools/emoji-cheat-sheet/" target="_blank" rel="noopener noreferrer">many others</a>, from the <a href="https://code.google.com/p/noto/" target="_blank" rel="noopener noreferrer">Noto Project</a>)',
},
{
markdown: "@**Joe Smith**",
usage_html: "(autocompletes from @joe)",
output_html: '<p><span class="user-mention">@Joe Smith</span></p>',
effect_html: "(notifies Joe Smith)",
},
{
markdown: "@_**Joe Smith**",
usage_html: "(autocompletes from @_joe)",
output_html: '<p><span class="user-mention">Joe Smith</span></p>',
effect_html: "(links to profile but doesn't notify Joe Smith)",
},
{
markdown: "@**all**",
effect_html: "(notifies all recipients)",
},
{
markdown: "#**streamName**",
output_html: "<p><a>#streamName</a></p>",
effect_html: "(links to a stream)",
},
{
markdown: "/me is busy working",
output_html: '<p><span class="sender_name-in-status">Iago</span> is busy working</p>',
usage_html: "(send a status message as user Iago)",
},
{
markdown: "Some inline `code`",
},
{
markdown: `\
\`\`\`
def zulip():
print "Zulip"
\`\`\``,
},
{
markdown: `\
\`\`\`python
def zulip():
print "Zulip"
\`\`\``,
output_html: `\
<div class="codehilite"><pre><span class="k">def</span> <span class="nf">zulip</span><span class="p">():</span>
<span class="k">print</span> <span class="s">"Zulip"</span></pre></div>`,
},
{
note_html: i18n.t(
'To add syntax highlighting to a multi-line code block, add the language\'s <b>first</b> <a target="_blank" rel="noopener noreferrer" href="https://pygments.org/docs/lexers/">Pygments short name</a> after the first set of back-ticks. You can also make a code block by indenting each line with 4 spaces.',
),
},
{
markdown: "> Quoted",
},
{
markdown: `\
\`\`\`quote
Quoted block
\`\`\``,
},
{
markdown: `\
\`\`\`spoiler Always visible heading
This text won't be visible until the user clicks.
\`\`\``,
},
{
markdown: "Some inline math $$ e^{i \\pi} + 1 = 0 $$",
},
{
markdown: `\
\`\`\`math
\\int_{0}^{1} f(x) dx
\`\`\``,
},
{
note_html: i18n.t(
'You can also make <a target="_blank" rel="noopener noreferrer" href="https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#wiki-tables">tables</a> with this <a target="_blank" rel="noopener noreferrer" href="https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#wiki-tables">Markdown-ish table syntax</a>.',
),
},
];
export function set_up_toggler() { export function set_up_toggler() {
for (const row of markdown_help_rows) {
if (row.markdown && !row.output_html) {
const message = {raw_content: row.markdown};
markdown.apply_markdown(message);
row.output_html = util.clean_user_content_links(message.content);
}
}
const $markdown_help = $(render_markdown_help({markdown_help_rows}));
$markdown_help.find(".rendered_markdown").each(function () {
rendered_markdown.update_elements($(this));
});
$(".informational-overlays .overlay-body").append($markdown_help);
const opts = { const opts = {
selected: 0, selected: 0,
child_wants_focus: true, child_wants_focus: true,

View File

@ -0,0 +1,30 @@
<div class="overlay-modal hide" id="message-formatting" tabindex="-1" role="dialog"
aria-label="{{t "Message formatting" }}">
<div class="modal-body" data-simplebar data-simplebar-auto-hide="false">
<div id="markdown-instructions">
<table class="table table-striped table-condensed table-rounded table-bordered help-table">
<thead>
<tr>
<th>{{t "You type" }}</th>
<th>{{t "You get" }}</th>
</tr>
</thead>
<tbody>
{{#each markdown_help_rows}}
<tr>
{{#if note_html}}
<td colspan="2">{{{note_html}}}</td>
{{else}}
<td><div class="preserve_spaces">{{markdown}}</div> {{{usage_html}}}</td>
<td class="rendered_markdown">{{{output_html}}} {{{effect_html}}}</td>
{{/if}}
</tr>
{{/each}}
</tbody>
</table>
</div>
<hr>
<a href="/help/format-your-message-using-markdown" target="_blank" rel="noopener noreferrer">{{t "Detailed message formatting documentation" }}</a>
</div>
</div>

View File

@ -137,7 +137,6 @@
<div class="overlay-body"> <div class="overlay-body">
{% include "zerver/app/keyboard_shortcuts.html" %} {% include "zerver/app/keyboard_shortcuts.html" %}
{% include "zerver/app/search_operators.html" %} {% include "zerver/app/search_operators.html" %}
{% include "zerver/app/markdown_help.html" %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -11,160 +11,6 @@
</thead> </thead>
<tbody> <tbody>
<tr>
<td>*italic* (or <kbd>Ctrl + I</kbd>)</td>
<td class="rendered_markdown"><i>italic</i></td>
</tr>
<tr>
<td>**bold** (or <kbd>Ctrl + B</kbd>)</td>
<td class="rendered_markdown"><b>bold</b></td>
</tr>
<tr>
<td>~~strikethrough~~</td>
<td class="rendered_markdown"><del>strikethrough</del></td>
</tr>
<tr>
<td>[Zulip website](https://zulip.org) (or <kbd>Ctrl + Shift + L</kbd>)</td>
<td class="rendered_markdown"><a href="https://zulip.org" target="_blank" rel="noopener noreferrer">Zulip website</a></td>
</tr>
<tr>
<td>* Milk<br>
* Tea<br>
&nbsp;&nbsp;* Green tea<br>
&nbsp;&nbsp;* Black tea<br>
&nbsp;&nbsp;* Oolong tea<br>
* Coffee
</td>
<td class="rendered_markdown">
<ul>
<li>Milk</li>
<li>Tea
<ul>
<li>Green tea</li>
<li>Black tea</li>
<li>Oolong tea</li>
</ul>
</li>
<li>Coffee</li>
</ul>
</td>
</tr>
<tr>
<td>1. Milk<br>
1. Tea<br>
1. Coffee
</td>
<td class="rendered_markdown">1. Milk<br>
2. Tea<br>
3. Coffee
</td>
</tr>
<tr>
<td>:heart: (and <a href="https://www.webfx.com/tools/emoji-cheat-sheet/" target="_blank" rel="noopener noreferrer">many others</a>, from the <a href="https://code.google.com/p/noto/" target="_blank" rel="noopener noreferrer">Noto Project</a>)</td>
<td class="rendered_markdown"><img alt=":heart:" class="emoji" src="/static/generated/emoji/images/emoji/heart.png" title=":heart:" /></td>
</tr>
<tr>
<td>@**Joe Smith**<br>
(autocompletes from @joe)</td>
<td class="rendered_markdown"><span class="user-mention">@Joe Smith</span> (notifies Joe Smith)</td>
</tr>
<tr>
<td>@_**Joe Smith**<br>
(autocompletes from @_joe)</td>
<td class="rendered_markdown"><span class="user-mention">Joe Smith</span> (links to profile but doesn't notify Joe Smith)</td>
</tr>
<tr>
<td>@**all**</td>
<td class="rendered_markdown"><span class="user-mention">@all</span> (notifies all recipients)</td>
</tr>
<tr>
<td>#**streamName**</td>
<td class="rendered_markdown"><a>#streamName</a> (links to a stream)</td>
</tr>
<tr>
<td>/me is busy working<br>
(send a status message as user Iago)</td>
<td class="rendered_markdown"><span class="sender_name-in-status">Iago</span> is busy working</td>
</tr>
<tr>
<td>Some inline `code`</td>
<td class="rendered_markdown">Some inline <code>code</code></td>
</tr>
<tr>
<td class="preserve_spaces">```
def zulip():
print "Zulip"
```</td>
<td class="rendered_markdown">
<div class="codehilite"><pre>def zulip():
print "Zulip"</pre></div>
</td>
</tr>
<tr>
<td class="preserve_spaces">```python
def zulip():
print "Zulip"
```</td>
<td class="rendered_markdown">
<div class="codehilite"><pre><span class="k">def</span> <span class="nf">zulip</span><span class="p">():</span>
<span class="k">print</span> <span class="s">"Zulip"</span></pre></div>
</td>
</tr>
<tr>
<td colspan="2">{% trans %}To add syntax highlighting to a multi-line code block,
add the language's <b>first</b> <a target="_blank" rel="noopener noreferrer" href="https://pygments.org/docs/lexers/">Pygments short name</a>
after the first set of back-ticks.
You can also make a code block by indenting each line with 4 spaces.{% endtrans %}</td>
</tr>
<tr>
<td>&gt; Quoted</td>
<td class="rendered_markdown"><blockquote>Quoted</blockquote></td>
</tr>
<tr>
<td class="preserve_spaces">```quote
Quoted block
```</td>
<td class="rendered_markdown"><blockquote><p>Quoted block</p></blockquote></td>
</tr>
<tr>
<td class="preserve_spaces">```spoiler Always visible heading
This text won't be visible until the user clicks.
```</td>
<td class="rendered_markdown">
<div class="spoiler-block">
<div class="spoiler-header"><span class="spoiler-button"><span class="spoiler-arrow"></span></span>
<p>Always visible heading</p>
</div>
<div class="spoiler-content">
<p>This text won't be visible until the user clicks.</p>
</div>
</div>
</td>
</tr>
<tr>
<td>Some inline math $$ e^{i \pi } + 1 = 0 $$</td>
<td class="rendered_markdown">
Some inline math <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msup><mi>e</mi><mrow><mi>i</mi><mi>π</mi></mrow></msup><mo>+</mo><mn>1</mn><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">e^{i\pi} + 1 = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height: 0.874664em;"></span><span class="strut bottom" style="height: 0.957994em; vertical-align: -0.08333em;"></span><span class="base"><span class="mord"><span class="mord mathit">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height: 0.874664em;"><span class="" style="top: -3.113em; margin-right: 0.05em;"><span class="pstrut" style="height: 2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathit mtight">i</span><span class="mord mathit mtight" style="margin-right: 0.03588em;">π</span></span></span></span></span></span></span></span></span><span class="mbin">+</span><span class="mord mathrm">1</span><span class="mrel">=</span><span class="mord mathrm">0</span></span></span></span>
</td>
</tr>
<tr>
<td class="preserve_spaces">```math
\int_{0}^{1} f(x) dx
```</td>
<td>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><msubsup><mo></mo><mn>0</mn><mn>1</mn></msubsup><mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo><mi>d</mi><mi>x</mi></mrow><annotation encoding="application/x-tex">\int_{0}^{1} f(x) dx</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height: 1.56401em;"></span><span class="strut bottom" style="height: 2.47596em; vertical-align: -0.91195em;"></span><span class="base"><span class="mop"><span class="mop op-symbol large-op" style="margin-right: 0.44445em; position: relative; top: -0.001125em;"></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height: 1.56401em;"><span class="" style="top: -1.78805em; margin-left: -0.44445em; margin-right: 0.05em;"><span class="pstrut" style="height: 2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathrm mtight">0</span></span></span></span><span class="" style="top: -3.8129em; margin-right: 0.05em;"><span class="pstrut" style="height: 2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathrm mtight">1</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height: 0.91195em;"></span></span></span></span></span><span class="mord mathit" style="margin-right: 0.10764em;">f</span><span class="mopen">(</span><span class="mord mathit">x</span><span class="mclose">)</span><span class="mord mathit">d</span><span class="mord mathit">x</span></span></span></span></span>
</td>
</tr>
<tr>
<td class="rendered_markdown" colspan="2">{% trans %}You can also make <a target="_blank" rel="noopener noreferrer"
href="https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#wiki-tables">tables</a>
with this <a target="_blank" rel="noopener noreferrer"
href="https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#wiki-tables">Markdown-ish
table syntax</a>.{% endtrans %}</td>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>

View File

@ -630,12 +630,6 @@ html_rules: List["Rule"] = [
}, },
{ {
"pattern": r'title="[^{\:]', "pattern": r'title="[^{\:]',
"exclude_line": {
(
"templates/zerver/app/markdown_help.html",
'<td class="rendered_markdown"><img alt=":heart:" class="emoji" src="/static/generated/emoji/images/emoji/heart.png" title=":heart:" /></td>',
),
},
"exclude": { "exclude": {
"templates/zerver/emails", "templates/zerver/emails",
"templates/analytics/realm_details.html", "templates/analytics/realm_details.html",
@ -649,7 +643,6 @@ html_rules: List["Rule"] = [
"exclude": { "exclude": {
"static/templates/settings/display_settings.hbs", "static/templates/settings/display_settings.hbs",
"templates/zerver/app/keyboard_shortcuts.html", "templates/zerver/app/keyboard_shortcuts.html",
"templates/zerver/app/markdown_help.html",
}, },
"good_lines": ['<img src="{{source_url}}" alt="{{ _(name) }}" />', '<img alg="" />'], "good_lines": ['<img src="{{source_url}}" alt="{{ _(name) }}" />', '<img alg="" />'],
"bad_lines": ['<img alt="Foo Image" />'], "bad_lines": ['<img alt="Foo Image" />'],
@ -679,8 +672,6 @@ html_rules: List["Rule"] = [
+ "'" + "'"
+ "](display: ?none|background: {{|color: {{|background-color: {{).*", + "](display: ?none|background: {{|color: {{|background-color: {{).*",
"exclude": { "exclude": {
# KaTeX output uses style attribute
"templates/zerver/app/markdown_help.html",
# 5xx page doesn't have external CSS # 5xx page doesn't have external CSS
"static/html/5xx.html", "static/html/5xx.html",
# exclude_pattern above handles color, but have other issues: # exclude_pattern above handles color, but have other issues: