mirror of
https://github.com/laurent22/joplin.git
synced 2024-11-24 08:12:24 +02:00
All: Also support $ as delimiter for Katex expressoins
This commit is contained in:
parent
d25d9b3f44
commit
727ba7300e
18
ElectronClient/app/package-lock.json
generated
18
ElectronClient/app/package-lock.json
generated
@ -2852,6 +2852,24 @@
|
||||
"uc.micro": "1.0.3"
|
||||
}
|
||||
},
|
||||
"markdown-it-katex": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-katex/-/markdown-it-katex-2.0.3.tgz",
|
||||
"integrity": "sha1-17hqGuoLnWSW+rTnkZoY/e9YnDk=",
|
||||
"requires": {
|
||||
"katex": "0.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"katex": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/katex/-/katex-0.6.0.tgz",
|
||||
"integrity": "sha1-EkGOCRIcBckgQbazuftrqyE8tvM=",
|
||||
"requires": {
|
||||
"match-at": "0.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"match-at": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/match-at/-/match-at-0.1.1.tgz",
|
||||
|
@ -70,6 +70,7 @@
|
||||
"levenshtein": "^1.0.5",
|
||||
"lodash": "^4.17.4",
|
||||
"markdown-it": "^8.4.0",
|
||||
"markdown-it-katex": "^2.0.3",
|
||||
"md5": "^2.2.1",
|
||||
"mime": "^2.0.3",
|
||||
"moment": "^2.19.1",
|
||||
|
10
README.md
10
README.md
@ -150,19 +150,19 @@ Joplin uses and renders [Github-flavoured Markdown](https://github.com/adam-p/ma
|
||||
|
||||
## Math notation
|
||||
|
||||
Math expressions can be added using the [Katex notation](https://khan.github.io/KaTeX/). To add an inline equation, wrap the expression in `` `{.katex}EXPRESSION` ``, eg. `` `{.katex}\sqrt{3x-1}+(1+x)^2` ``. To create an expression block, wrap it as follow:
|
||||
Math expressions can be added using the [Katex notation](https://khan.github.io/KaTeX/). To add an inline equation, wrap the expression in `$EXPRESSION$`, eg. `$\sqrt{3x-1}+(1+x)^2$`. To create an expression block, wrap it as follow:
|
||||
|
||||
```katex
|
||||
$$
|
||||
EXPRESSION
|
||||
```
|
||||
$$
|
||||
|
||||
For example:
|
||||
|
||||
```katex
|
||||
$$
|
||||
f(x) = \int_{-\infty}^\infty
|
||||
\hat f(\xi)\,e^{2 \pi i \xi x}
|
||||
\,d\xi
|
||||
```
|
||||
$$
|
||||
|
||||
Here is an example with the Markdown and rendered result side by side:
|
||||
|
||||
|
@ -157,7 +157,7 @@ class MdToHtml {
|
||||
}
|
||||
}
|
||||
|
||||
customCodeHandler_(language) {
|
||||
rendererPlugin_(language) {
|
||||
if (!language) return null;
|
||||
|
||||
const handlers = {};
|
||||
@ -196,9 +196,10 @@ class MdToHtml {
|
||||
const isCodeBlock = tag === 'code' && t.block;
|
||||
const isInlineCode = t.type === 'code_inline';
|
||||
const codeBlockLanguage = t && t.info ? t.info : null;
|
||||
let codeBlockHandler = null;
|
||||
let rendererPlugin = null;
|
||||
let rendererPluginOptions = { tagType: 'inline' };
|
||||
|
||||
if (isCodeBlock) codeBlockHandler = this.customCodeHandler_(codeBlockLanguage);
|
||||
if (isCodeBlock) rendererPlugin = this.rendererPlugin_(codeBlockLanguage);
|
||||
|
||||
if (previousToken && previousToken.tag === 'li' && tag === 'p') {
|
||||
// Markdown-it render list items as <li><p>Text<p></li> which makes it
|
||||
@ -216,7 +217,7 @@ class MdToHtml {
|
||||
} else if (t.type === 'link_open') {
|
||||
openTag = 'a';
|
||||
} else if (isCodeBlock) {
|
||||
if (codeBlockHandler) {
|
||||
if (rendererPlugin) {
|
||||
openTag = null;
|
||||
} else {
|
||||
openTag = 'pre';
|
||||
@ -235,25 +236,30 @@ class MdToHtml {
|
||||
|
||||
if (isCodeBlock) {
|
||||
const codeAttrs = ['code'];
|
||||
if (!codeBlockHandler) {
|
||||
if (!rendererPlugin) {
|
||||
if (codeBlockLanguage) codeAttrs.push(t.info); // t.info contains the language when the token is a codeblock
|
||||
output.push('<code class="' + codeAttrs.join(' ') + '">');
|
||||
}
|
||||
} else if (isInlineCode) {
|
||||
const result = this.parseInlineCodeLanguage_(tokenContent);
|
||||
if (result) {
|
||||
codeBlockHandler = this.customCodeHandler_(result.language);
|
||||
rendererPlugin = this.rendererPlugin_(result.language);
|
||||
tokenContent = result.newContent;
|
||||
}
|
||||
|
||||
if (!codeBlockHandler) {
|
||||
if (!rendererPlugin) {
|
||||
output.push('<code>');
|
||||
}
|
||||
}
|
||||
|
||||
if (codeBlockHandler) {
|
||||
codeBlockHandler.loadAssets().catch((error) => {
|
||||
console.warn('MdToHtml: Error loading assets for ' + codeBlockHandler.name() + ': ', error.message);
|
||||
if (t.type === 'math_inline' || t.type === 'math_block') {
|
||||
rendererPlugin = this.rendererPlugin_('katex');
|
||||
rendererPluginOptions = { tagType: t.type === 'math_block' ? 'block' : 'inline' };
|
||||
}
|
||||
|
||||
if (rendererPlugin) {
|
||||
rendererPlugin.loadAssets().catch((error) => {
|
||||
console.warn('MdToHtml: Error loading assets for ' + rendererPlugin.name() + ': ', error.message);
|
||||
});
|
||||
}
|
||||
|
||||
@ -270,8 +276,10 @@ class MdToHtml {
|
||||
output = output.concat(parsedChildren);
|
||||
} else {
|
||||
if (tokenContent) {
|
||||
if ((isCodeBlock || isInlineCode) && codeBlockHandler) {
|
||||
output = codeBlockHandler.processContent(output, tokenContent, isCodeBlock ? 'block' : 'inline');
|
||||
if ((isCodeBlock || isInlineCode) && rendererPlugin) {
|
||||
output = rendererPlugin.processContent(output, tokenContent, isCodeBlock ? 'block' : 'inline');
|
||||
} else if (rendererPlugin) {
|
||||
output = rendererPlugin.processContent(output, tokenContent, rendererPluginOptions.tagType);
|
||||
} else {
|
||||
output.push(htmlentities(tokenContent));
|
||||
}
|
||||
@ -286,15 +294,15 @@ class MdToHtml {
|
||||
} else if (tag && t.type.indexOf('inline') >= 0) {
|
||||
closeTag = openTag;
|
||||
} else if (isCodeBlock) {
|
||||
if (!codeBlockHandler) closeTag = openTag;
|
||||
if (!rendererPlugin) closeTag = openTag;
|
||||
}
|
||||
|
||||
if (isCodeBlock) {
|
||||
if (!codeBlockHandler) {
|
||||
if (!rendererPlugin) {
|
||||
output.push('</code>');
|
||||
}
|
||||
} else if (isInlineCode) {
|
||||
if (!codeBlockHandler) {
|
||||
if (!rendererPlugin) {
|
||||
output.push('</code>');
|
||||
}
|
||||
}
|
||||
@ -307,9 +315,9 @@ class MdToHtml {
|
||||
}
|
||||
}
|
||||
|
||||
if (codeBlockHandler) {
|
||||
const extraCss = codeBlockHandler.extraCss();
|
||||
const name = codeBlockHandler.name();
|
||||
if (rendererPlugin) {
|
||||
const extraCss = rendererPlugin.extraCss();
|
||||
const name = rendererPlugin.name();
|
||||
if (extraCss && !(name in extraCssBlocks)) {
|
||||
extraCssBlocks[name] = extraCss;
|
||||
}
|
||||
@ -345,6 +353,13 @@ class MdToHtml {
|
||||
linkify: true,
|
||||
});
|
||||
|
||||
// This is currently used only so that the $expression$ and $$\nexpression\n$$ blocks are translated
|
||||
// to math_inline and math_block blocks. These blocks are then processed directly with the Katex
|
||||
// library. It is better this way as then it is possible to conditionally load the CSS required by
|
||||
// Katex and use an up-to-date version of Katex (as of 2018, the plugin is still using 0.6, which is
|
||||
// buggy instead of 0.9).
|
||||
md.use(require('markdown-it-katex'));
|
||||
|
||||
// Hack to make checkboxes clickable. Ideally, checkboxes should be parsed properly in
|
||||
// renderTokens_(), but for now this hack works. Marking it with HORRIBLE_HACK so
|
||||
// that it can be removed and replaced later on.
|
||||
|
18
ReactNativeClient/package-lock.json
generated
18
ReactNativeClient/package-lock.json
generated
@ -3666,6 +3666,24 @@
|
||||
"uc.micro": "1.0.3"
|
||||
}
|
||||
},
|
||||
"markdown-it-katex": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-katex/-/markdown-it-katex-2.0.3.tgz",
|
||||
"integrity": "sha1-17hqGuoLnWSW+rTnkZoY/e9YnDk=",
|
||||
"requires": {
|
||||
"katex": "0.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"katex": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/katex/-/katex-0.6.0.tgz",
|
||||
"integrity": "sha1-EkGOCRIcBckgQbazuftrqyE8tvM=",
|
||||
"requires": {
|
||||
"match-at": "0.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"match-at": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/match-at/-/match-at-0.1.1.tgz",
|
||||
|
@ -17,6 +17,7 @@
|
||||
"html-entities": "^1.2.1",
|
||||
"katex": "^0.9.0-beta1",
|
||||
"markdown-it": "^8.4.0",
|
||||
"markdown-it-katex": "^2.0.3",
|
||||
"md5": "^2.2.1",
|
||||
"moment": "^2.18.1",
|
||||
"prop-types": "^15.6.0",
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
@ -331,16 +331,16 @@ sudo ln -s ~/.joplin-bin/bin/joplin /usr/bin/joplin
|
||||
<h1 id="markdown">Markdown</h1>
|
||||
<p>Joplin uses and renders <a href="https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet">Github-flavoured Markdown</a> with a few variations and additions. In particular:</p>
|
||||
<h2 id="math-notation">Math notation</h2>
|
||||
<p>Math expressions can be added using the <a href="https://khan.github.io/KaTeX/">Katex notation</a>. To add an inline equation, wrap the expression in <code>`{.katex}EXPRESSION` </code>, eg. <code>`{.katex}\sqrt{3x-1}+(1+x)^2` </code>. To create an expression block, wrap it as follow:</p>
|
||||
<pre><code>```katex
|
||||
<p>Math expressions can be added using the <a href="https://khan.github.io/KaTeX/">Katex notation</a>. To add an inline equation, wrap the expression in <code>$EXPRESSION$</code>, eg. <code>$\sqrt{3x-1}+(1+x)^2$</code>. To create an expression block, wrap it as follow:</p>
|
||||
<pre><code>$$
|
||||
EXPRESSION
|
||||
```
|
||||
$$
|
||||
</code></pre><p>For example:</p>
|
||||
<pre><code>```katex
|
||||
<pre><code>$$
|
||||
f(x) = \int_{-\infty}^\infty
|
||||
\hat f(\xi)\,e^{2 \pi i \xi x}
|
||||
\,d\xi
|
||||
```
|
||||
$$
|
||||
</code></pre><p>Here is an example with the Markdown and rendered result side by side:</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/Katex.png" style="max-width: 100%; max-height: 35em;"></p>
|
||||
<h2 id="checkboxes">Checkboxes</h2>
|
||||
@ -378,14 +378,14 @@ f(x) = \int_{-\infty}^\infty
|
||||
<td><img src="https://raw.githubusercontent.com/stevenrskelton/flag-icon/master/png/16/country-4x3/hr.png" alt=""></td>
|
||||
<td>Croatian</td>
|
||||
<td>hr_HR</td>
|
||||
<td>Hrvoje Mandić <a href="mailto:trbuhom@net.hr">trbuhom@net.hr</a></td>
|
||||
<td>Hrvoje Mandić <a href="mailto:trbuhom@net.hr">trbuhom@net.hr</a></td>
|
||||
<td>72%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://raw.githubusercontent.com/stevenrskelton/flag-icon/master/png/16/country-4x3/de.png" alt=""></td>
|
||||
<td>Deutsch</td>
|
||||
<td>de_DE</td>
|
||||
<td>Tobias Strobel <a href="mailto:git@strobeltobias.de">git@strobeltobias.de</a></td>
|
||||
<td>Tobias Strobel <a href="mailto:git@strobeltobias.de">git@strobeltobias.de</a></td>
|
||||
<td>92%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -441,14 +441,14 @@ f(x) = \int_{-\infty}^\infty
|
||||
<td><img src="https://raw.githubusercontent.com/stevenrskelton/flag-icon/master/png/16/country-4x3/ru.png" alt=""></td>
|
||||
<td>Русский</td>
|
||||
<td>ru_RU</td>
|
||||
<td>Artyom Karlov <a href="mailto:artyom.karlov@gmail.com">artyom.karlov@gmail.com</a></td>
|
||||
<td>Artyom Karlov <a href="mailto:artyom.karlov@gmail.com">artyom.karlov@gmail.com</a></td>
|
||||
<td>96%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://raw.githubusercontent.com/stevenrskelton/flag-icon/master/png/16/country-4x3/cn.png" alt=""></td>
|
||||
<td>中文 (简体)</td>
|
||||
<td>zh_CN</td>
|
||||
<td>RCJacH <a href="mailto:RCJacH@outlook.com">RCJacH@outlook.com</a></td>
|
||||
<td>RCJacH <a href="mailto:RCJacH@outlook.com">RCJacH@outlook.com</a></td>
|
||||
<td>76%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
Loading…
Reference in New Issue
Block a user