Skip to content

Commit

Permalink
Version 0.8
Browse files Browse the repository at this point in the history
  • Loading branch information
goessner committed Jul 22, 2020
1 parent badd8cd commit 4202e2f
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 78 deletions.
4 changes: 2 additions & 2 deletions package.json
@@ -1,6 +1,6 @@
{
"name": "markdown-it-texmath",
"version": "0.7.2",
"version": "0.8.0",
"description": "markdown-it extension for rendering TeX Math",
"keywords": [
"TeX",
Expand All @@ -21,7 +21,7 @@
"license": "MIT",
"dependencies": {},
"devDependencies": {
"katex": "^0.11.1",
"katex": "^0.12.0",
"markdown-it": "^11.0.0"
}
}
13 changes: 6 additions & 7 deletions readme.md
Expand Up @@ -107,13 +107,7 @@ Use following links for `texmath.js` and `texmath.css`
* Inline syntax of display math with `dollars` mode is supported starting from version "0.7.0". So `'This formula $$a+b=c$$ will result in display math presentation'`, i.e. gets displayed on a separate line. For *true* inline math use `$..$` mode like before.

* __Multiline diplay math in `blockquote` block possible ?__
* Display math inside of `blockquote` blocks is able to span multiple lines with version "0.6.8". Every single display math line **must** begin with a `>` character then, as in
```
> $$ a +
> b
> = c
> $$
```
* Display math inside of `blockquote` blocks is able to span multiple lines with version "0.7.3".

* __`markdown-it-texmath` with React Native does not work, why ?__
* `markdown-it-texmath` is using regular expressions with `y` [(sticky) property](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky) and cannot avoid this. The use of the `y` flag in regular expressions means the plugin is not compatible with React Native (which as of now doesn't support it and throws an error `Invalid flags supplied to RegExp constructor`).
Expand All @@ -125,6 +119,11 @@ Use following links for `texmath.js` and `texmath.css`

## CHANGELOG

### [0.8.0] on July 10, 2020
* Infinite loop bug with `gitlab` mode and display math inside `blockquote` section removed.
* Fundamental redesign of display math implementation.
* Update to KaTeX version 0.12.0.

### [0.7.2] on June 22, 2020
* Regex bug with `gitlab` mode removed.

Expand Down
59 changes: 31 additions & 28 deletions test/blockquote-bug.html
Expand Up @@ -12,37 +12,40 @@
<body>
<div id="out"></div>
<script>
const str = `
> *Hi*
> > He $\`5 +\\pi\`$
> >
> > \`\`\`math
> > c^2 =
> > a^2 + \\phi
> > \\sqrt{b^2}
> > \`\`\` (2)
>
> ahsgahg
Ho xyz \`\`\`math\\psi+\\phi \`\`\` abcdef ashagsh
abcdefghi
\`\`\`math a + b = \\pi \`\`\` (3)
x

>\`\`\`math
>\\frac{1}{2}
>\`\`\`
> \`\`\`math
const str = `
hello$a+b=c$with
>$$
> \\frac{1}{2}
> \`\`\`
`
document.addEventListener("DOMContentLoaded", () => {
const md = markdownit().use(texmath, {engine:katex, delimiters:'gitlab',macros:{"\\RR": "\\mathbb{R}"}});
> $$ (4)
> hello`
/*
const str = `
hello
>
> \`\`\`math
x = \\frac{1}{2}
\`\`\` (4)
hartnäckig
hello`
*/
document.addEventListener("DOMContentLoaded", () => {
const md = markdownit().use(texmath, {engine:katex, delimiters:'dollars',macros:{"\\RR": "\\mathbb{R}"}});
// const md = markdownit().use(texmath, {engine:katex, delimiters:'gitlab',macros:{"\\RR": "\\mathbb{R}"}});
out.innerHTML = md.render(str);
//console.log(out.innerHTML)
//console.log(md)
/*
md.block.ruler.disable(texmath.blockRuleNames, true);
md.inline.ruler.disable(texmath.inlineRuleNames, true);
*/
//console.log(md.render(str))
/*
md.block.ruler.enable(texmath.blockRuleNames, true);
md.inline.ruler.enable(texmath.inlineRuleNames, true);
console.log(md.render(str))
*/
})
</script>
</body>
Expand Down
89 changes: 48 additions & 41 deletions texmath.js
Expand Up @@ -16,7 +16,7 @@ function texmath(md, options) {
else if (typeof module === "object")
texmath.katex = require('katex');
else // artifical error object.
texmath.katex = { renderToString() { return 'No math renderer found.' }};
texmath.katex = { renderToString() { return 'No math renderer found.' } };
}

if (delimiters in texmath.rules) {
Expand All @@ -26,76 +26,79 @@ function texmath(md, options) {
}

for (const rule of texmath.rules[delimiters].block) {
md.block.ruler.before('fence', rule.name, texmath.block(rule));
md.block.ruler.before('fence', rule.name, texmath.block(rule)); // ! important for ```math delimiters
md.renderer.rules[rule.name] = (tokens, idx) => rule.tmpl.replace(/\$2/,tokens[idx].info) // equation number .. ?
.replace(/\$1/,texmath.render(tokens[idx].content,true,katexOptions));
}
}
}

// texmath.inline = (rule) => dollar; // just for testing ..
// texmath.inline = (rule) => dollar; // just for debugging/testing ..

texmath.inline = (rule) =>
function(state, silent) {
const pos = state.pos;
const str = state.src;
const pre = str.startsWith(rule.tag, rule.rex.lastIndex = pos) && (!rule.pre || rule.pre(str, pos)); // valid pre-condition ...
const match = pre && rule.rex.exec(str);
const lastPos = match && (rule.rex.lastIndex - 1);
const res = !!match && pos < rule.rex.lastIndex && (!rule.post || rule.post(str, rule.rex.lastIndex - 1));

if (match && (!rule.post || rule.post(str, lastPos))) { // match && valid post-condition
if (res) {
if (!silent) {
const token = state.push(rule.name, 'math', 0);
token.content = match[1];
token.markup = rule.tag;
}
state.pos = rule.rex.lastIndex;
}
rule.rex.lastIndex = 0;
return !!match;
return res;
}

texmath.block = (rule) =>
function block(state, begLine, endLine, silent) {
texmath.inBlockquote(state.tokens); // cache current blockquote level ...

const pos = state.bMarks[begLine] + state.tShift[begLine];
const str = state.src;
const pre = str.startsWith(rule.tag, rule.rex.lastIndex = pos) && (!rule.pre || rule.pre(str, pos)); // valid pre-condition ....
const match = pre && rule.rex.exec(str);
const lastPos = match && (rule.rex.lastIndex - 1);
const res = !!match
&& pos < rule.rex.lastIndex
&& (!rule.post || rule.post(str, rule.rex.lastIndex - 1));

if (match && (!rule.post || rule.post(str, lastPos))) { // match and valid post-condition ...
if (match[1].includes('\n') && texmath.inBlockquote.level) // multiline display math inside of blockquote block.
match[1] = match[1].replace(/(^(?:\s*>)+)/gm,'\n'); // so remove all leading '>' inside of display math !
if (!silent) {
const token = state.push(rule.name, 'math', 0);
token.block = true;
token.content = match[1];
token.info = match[match.length-1];
token.markup = rule.tag;
}
for (let line=begLine, endpos=lastPos; line < endLine; line++)
if (endpos >= state.bMarks[line] && endpos <= state.eMarks[line]) { // line for end of block math found ...
state.line = line+1;
if (res && !silent) { // match and valid post-condition ...
const endpos = rule.rex.lastIndex - 1;
let curline;

for (curline = begLine; curline < endLine; curline++)
if (endpos >= state.bMarks[curline] + state.tShift[curline] && endpos <= state.eMarks[curline]) // line for end of block math found ...
break;
}
}
rule.rex.lastIndex = 0;
return !!match;
}

texmath.inBlockquote = function(tokens) {
if (tokens && tokens.length) {
const len = tokens.length;
texmath.inBlockquote.level = tokens[len-1].type === 'blockquote_open' ? tokens[len-1].level + 1
: tokens[len-1].type === 'blockquote_close' ? tokens[len-1].level
: texmath.inBlockquote.level;
// "this will prevent lazy continuations from ever going past our end marker"
// s. https://github.com/markdown-it/markdown-it-container/blob/master/index.js
const lineMax = state.lineMax;
const parentType = state.parentType;
state.lineMax = curline;
state.parentType = 'math';

if (parentType === 'blockquote') // remove all leading '>' inside multiline formula
match[1] = match[1].replace(/(\n*?^(?:\s*>)+)/gm,'');
// begin token
let token = state.push(rule.name, 'math', 1); // 'math_block'
token.block = true;
token.markup = rule.tag;
token.content = match[1];
token.info = match[match.length-1]; // eq.no
token.map = [ begLine, curline ];
// end token
token = state.push(rule.name+'_end', 'math', -1);
token.block = true;
token.markup = rule.tag;

state.parentType = parentType;
state.lineMax = lineMax;
state.line = curline+1;
}
return res;
}
else
texmath.inBlockquote.level = 0;
}
texmath.inBlockquote.level = 0;

texmath.render = function(tex,displayMode,options) {
options.displayMode = displayMode;
Expand Down Expand Up @@ -157,6 +160,10 @@ function dollar(state, silent) {
};
*/

// used for enable/disable math rendering by `markdown-it`
texmath.inlineRuleNames = ['math_inline','math_inline_double'];
texmath.blockRuleNames = ['math_block','math_block_eqno'];

texmath.$_pre = (str,beg) => {
const prv = beg > 0 ? str[beg-1].charCodeAt(0) : false;
return !prv || prv !== 0x5c // no backslash,
Expand Down Expand Up @@ -197,14 +204,14 @@ texmath.rules = {
tag: '$`'
}
],
block: [
block: [
{ name: 'math_block_eqno',
rex: /`{3}math\s*?([^`]+?)\s*?`{3}\s*?\(([^)$\r\n]+?)\)/gmy,
rex: /`{3}math\s*([^`]+?)\s*?`{3}\s*\(([^)\r\n]+?)\)/gm,
tmpl: '<section class="eqno"><eqn>$1</eqn><span>($2)</span></section>',
tag: '```math'
},
{ name: 'math_block',
rex: /`{3}math\s*?([^`]*?)\s*?`{3}/gmy,
rex: /`{3}math\s*([^`]*?)\s*`{3}/gm,
tmpl: '<section><eqn>$1</eqn></section>',
tag: '```math'
}
Expand Down

0 comments on commit 4202e2f

Please sign in to comment.