Skip to content

Commit 9e1c5b9

Browse files
committed
Version 0.7.0
1 parent 0c26060 commit 9e1c5b9

File tree

7 files changed

+128
-92
lines changed

7 files changed

+128
-92
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "markdown-it-texmath",
3-
"version": "0.6.9",
3+
"version": "0.7.0",
44
"description": "markdown-it extension for rendering TeX Math",
55
"keywords": [
66
"TeX",

readme.md

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ This extension is a comfortable tool for scientists, engineers and students with
1616
* Inline math with tables, lists and blockquote.
1717
* User setting delimiters:
1818
* `'dollars'` (default)
19-
* inline: `$...$`
19+
* inline: `$...$` or `$$...$$`
2020
* display: `$$...$$`
2121
* display + equation number: `$$...$$ (1)`
2222
* `'brackets'`
@@ -35,10 +35,6 @@ This extension is a comfortable tool for scientists, engineers and students with
3535
* inline: ``$$...$$``
3636
* display: `$$...$$`
3737
* display + equation number: `$$...$$ (1)`
38-
* `'pandoc'`
39-
* inline: `$...$` or `$$...$$`
40-
* display: `$$...$$`
41-
* display + equation number: `$$...$$ (1)`
4238

4339
## Show me
4440

@@ -107,7 +103,11 @@ Use following links for `texmath.js` and `texmath.css`
107103

108104
## FAQ
109105

110-
* 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
106+
* __Support of inline syntax of display math ?__
107+
* 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.
108+
109+
* __Multiline diplay math in `blockquote` block possible ?__
110+
* 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
111111
```
112112
> $$ a +
113113
> b
@@ -118,13 +118,19 @@ Use following links for `texmath.js` and `texmath.css`
118118
* __`markdown-it-texmath` with React Native does not work, why ?__
119119
* `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`).
120120

121-
* __Why doesn't `markdown-it-texmath` work with mathjax ?__
122-
* `markdown-it-texmath` is a personal project of mine. As it does very well what I want it to do, I offer it to the public as an open source plugin. I do not have time or interest to integrate other math engines.
121+
* __Why doesn't `markdown-it-texmath` work with other engines ?__
122+
* `markdown-it-texmath` is a personal project of mine. As it does very well with KaTeX what I want it to do, I offer it to the public as an open source plugin. I do not have time or interest to integrate other math engines.
123123
But if someone wants to help here out, pull requests are always welcome.
124124

125125

126126
## CHANGELOG
127127

128+
### [0.7.0] on June 14, 2020
129+
* Experimental `pandoc` mode removed. Enhanced `dollars` mode now does, what `pandoc` mode was requiring.
130+
* With `dollars` mode inline math expression `$$..$$` will result in display math presentation now. Adding equation numbers `$$..$$(1)` is not supported in inline syntax.
131+
* Significant code redesign and regular expression optimization results in more compact code and performance gain ... not measured though.
132+
* Bug with display math inside of `blockquote` blocks removed.
133+
128134
### [0.6.9] on June 11, 2020
129135
* Now display math inside of `blockquote` blocks can span multiple lines, provided that every line starts with a `>` character.
130136
* Possible cause of [blockquote bug(https://github.com/goessner/mdmath/issues/50)] presumably eliminated.

test/blockquote-bug.html

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset='utf-8'>
5+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex/dist/katex.min.css">
6+
<link rel="stylesheet" href="../css/texmath.css">
7+
<style>blockquote { background-color:#eee;} </style>
8+
<script src="https://cdn.jsdelivr.net/npm/markdown-it/dist/markdown-it.min.js"></script>
9+
<script src="https://cdn.jsdelivr.net/npm/katex/dist/katex.min.js"></script>
10+
<script src="../texmath.js"></script>
11+
</head>
12+
<body>
13+
<div id="out"></div>
14+
<script>
15+
const str = `
16+
> *Hi*
17+
> > He $5 +\\pi$
18+
> >
19+
> > $$c^2 =
20+
> > a^2 + \\phi
21+
> > \\sqrt{b^2}$$ (2)
22+
>
23+
> ahsgahg
24+
25+
Ho xyz $$\\psi+\\phi$$ abcdef ashagsh
26+
27+
abcdefghi
28+
29+
$$a + b = \\pi$$ (3)
30+
x
31+
`
32+
document.addEventListener("DOMContentLoaded", () => {
33+
const md = markdownit().use(texmath, {engine:katex, delimiters:'dollars',macros:{"\\RR": "\\mathbb{R}"}});
34+
out.innerHTML = md.render(str);
35+
})
36+
</script>
37+
</body>
38+
</html>

test/blockquote-bug.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
const tm = require('../texmath.js');
44
//const md = require('markdown-it')({html:true}).use(tm,{engine:require('katex'), delimiters:'dollars'});
5-
const md = require('markdown-it')({html:true}).use(tm,{engine:require('katex'), delimiters:'gitlab'});
5+
const md = require('markdown-it')({html:true}).use(tm,{engine:require('katex'), delimiters:'dollars'});
66
const str = `
77
With
88
9-
> \`\`\`math
9+
> $$
1010
> x
11-
> \`\`\`
11+
> $$
1212
`;
1313

1414
// overwrite texmath render function (suppressing katex)

test/bugtest.html

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,20 @@
2626
2727
with
2828
29-
$$
30-
{\\bold e}_\\alpha = \\begin{pmatrix}\\cos\\alpha\\\\ \\sin\\alpha\\end{pmatrix} \\quad and \\quad {\\tilde\\bold e}_\\alpha = \\begin{pmatrix}-\\sin\\alpha\\\\ \\cos\\alpha\\end{pmatrix}
31-
$$
29+
> hello
30+
> world
31+
32+
> $$c^2 =
33+
> a^2 +
34+
> b^2$$ (2)
35+
36+
37+
>
38+
>$$
39+
>{\\bold e}_\\alpha = \\begin{pmatrix}\\cos\\alpha\\\\ \\sin\\alpha\\end{pmatrix} \\quad and
40+
>\\quad {\\tilde\\bold e}_\\alpha = \\begin{pmatrix}-\\sin\\alpha\\\\ \\cos\\alpha\\end{pmatrix}
41+
> $$
42+
>
3243
3344
Resolving for the hypothenuse part $c{\\bold e}_x$ and $c{\\bold e}_\\varphi$ as well as $u$ in the loop closure equation (1)
3445
@@ -41,7 +52,7 @@
4152
finally results in the Pythagorean theorem (2)
4253
4354
$$
44-
c^2 = a^2 + b^2
55+
c^2 = a^2 + b^2 + \pi
4556
$$ (3)
4657
`
4758
document.addEventListener("DOMContentLoaded", () => {

test/pandoc-bug.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
str = `# Triangle
2020
Let the right triangle hypothenuse be aligned with the coordinate system *x-axis*.
2121
The vector loop closure equation then reads
22-
2322
$$
2423
a{\\bold e}_\\alpha + b\\tilde{\\bold e}_\\alpha + c{\\bold e}_x = \\bold 0
2524
$$ (1)
@@ -45,7 +44,7 @@
4544
$$ (3)
4645
`
4746
document.addEventListener("DOMContentLoaded", () => {
48-
md = markdownit().use(texmath, {engine:katex, delimiters:'pandoc',macros:{"\\RR": "\\mathbb{R}"}});
47+
md = markdownit().use(texmath, {engine:katex, delimiters:'dollars',macros:{"\\RR": "\\mathbb{R}"}});
4948
out.innerHTML = md.render(str);
5049
})
5150
</script>

texmath.js

Lines changed: 56 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function texmath(md, options) {
2222
if (delimiters in texmath.rules) {
2323
for (const rule of texmath.rules[delimiters].inline) {
2424
md.inline.ruler.before('escape', rule.name, texmath.inline(rule)); // ! important
25-
md.renderer.rules[rule.name] = (tokens, idx) => rule.tmpl.replace(/\$1/,texmath.render(tokens[idx].content,false,katexOptions));
25+
md.renderer.rules[rule.name] = (tokens, idx) => rule.tmpl.replace(/\$1/,texmath.render(tokens[idx].content,!!rule.displayMode,katexOptions));
2626
}
2727

2828
for (const rule of texmath.rules[delimiters].block) {
@@ -33,60 +33,69 @@ function texmath(md, options) {
3333
}
3434
}
3535

36-
texmath.applyRule = function(rule, str, beg, inBlockquote) {
37-
let pre, match, post;
38-
rule.rex.lastIndex = beg;
39-
40-
pre = str.startsWith(rule.tag,beg) && (!rule.pre || rule.pre(str,beg)); // pre-condition ...
41-
match = pre && rule.rex.exec(str);
42-
if (match) {
43-
match.lastIndex = rule.rex.lastIndex;
44-
post = (!rule.post || rule.post(str, match.lastIndex-1)) // valid post-condition ...
45-
&& (!inBlockquote || !match[1].includes('\n') || !/\n[^>]/gm.test(match[1])); // not in blockquote || on single line || every bol == '>'
46-
if (post && inBlockquote)
47-
match[1] = match[1].replace(/\n>/gm,'\n'); // remove '>' at bol inside of display math !
48-
}
49-
rule.rex.lastIndex = 0;
50-
51-
return post && match; // returning match object ... !
52-
}
53-
5436
// texmath.inline = (rule) => dollar; // just for testing ..
5537

5638
texmath.inline = (rule) =>
5739
function(state, silent) {
58-
const res = texmath.applyRule(rule, state.src, state.pos);
59-
if (res) {
40+
const pos = state.pos;
41+
const str = state.src;
42+
const pre = str.startsWith(rule.tag, rule.rex.lastIndex = pos) && (!rule.pre || rule.pre(str, pos)); // valid pre-condition ...
43+
const match = pre && rule.rex.exec(str);
44+
const lastPos = match && (rule.rex.lastIndex - 1);
45+
46+
if (match && (!rule.post || rule.post(str, lastPos))) { // match && valid post-condition
6047
if (!silent) {
6148
const token = state.push(rule.name, 'math', 0);
62-
token.content = res[1]; // group 1 from regex ..
49+
token.content = match[1];
6350
token.markup = rule.tag;
6451
}
65-
state.pos = res.lastIndex;
52+
state.pos = rule.rex.lastIndex;
6653
}
67-
return !!res;
54+
rule.rex.lastIndex = 0;
55+
return !!match;
6856
}
6957

7058
texmath.block = (rule) =>
71-
function(state, begLine, endLine, silent) {
72-
const res = texmath.applyRule(rule, state.src, state.bMarks[begLine] + state.tShift[begLine], state.parentType==='blockquote');
73-
if (res) {
59+
function block(state, begLine, endLine, silent) {
60+
texmath.inBlockquote(state.tokens); // cache current blockquote level ...
61+
62+
const pos = state.bMarks[begLine] + state.tShift[begLine];
63+
const str = state.src;
64+
const pre = str.startsWith(rule.tag, rule.rex.lastIndex = pos) && (!rule.pre || rule.pre(str, pos)); // valid pre-condition ....
65+
const match = pre && rule.rex.exec(str);
66+
const lastPos = match && (rule.rex.lastIndex - 1);
67+
68+
if (match && (!rule.post || rule.post(str, lastPos))) { // match and valid post-condition ...
69+
if (match[1].includes('\n') && texmath.inBlockquote.level) // multiline display math inside of blockquote block.
70+
match[1] = match[1].replace(/\n(\s*?>)+/gm,'\n'); // remove all leading '>' inside of display math !
7471
if (!silent) {
7572
const token = state.push(rule.name, 'math', 0);
7673
token.block = true;
77-
token.content = res[1];
78-
token.info = res[res.length-1];
74+
token.content = match[1];
75+
token.info = match[match.length-1];
7976
token.markup = rule.tag;
8077
}
81-
for (let line=begLine, endpos=res.lastIndex-1; line < endLine; line++)
78+
for (let line=begLine, endpos=lastPos; line < endLine; line++)
8279
if (endpos >= state.bMarks[line] && endpos <= state.eMarks[line]) { // line for end of block math found ...
8380
state.line = line+1;
8481
break;
8582
}
86-
state.pos = res.lastIndex;
8783
}
88-
return !!res;
84+
rule.rex.lastIndex = 0;
85+
return !!match;
86+
}
87+
88+
texmath.inBlockquote = function(tokens) {
89+
if (tokens && tokens.length) {
90+
const len = tokens.length;
91+
texmath.inBlockquote.level = tokens[len-1].type === 'blockquote_open' ? tokens[len-1].level + 1
92+
: tokens[len-1].type === 'blockquote_close' ? tokens[len-1].level
93+
: texmath.inBlockquote.level;
8994
}
95+
else
96+
texmath.inBlockquote.level = 0;
97+
}
98+
texmath.inBlockquote.level = 0;
9099

91100
texmath.render = function(tex,displayMode,options) {
92101
options.displayMode = displayMode;
@@ -208,15 +217,8 @@ texmath.rules = {
208217
tmpl: '<eq>$1</eq>',
209218
tag: '``'
210219
},
211-
{ name: 'math_inline',
212-
rex: /\$(\S[^$\r\n]*?[^\s\\]{1}?)\$/gy,
213-
tmpl: '<eq>$1</eq>',
214-
tag: '$',
215-
pre: texmath.$_pre,
216-
post: texmath.$_post
217-
},
218-
{ name: 'math_single',
219-
rex: /\$([^$\s\\]{1}?)\$/gy,
220+
{ name: 'math_inline',
221+
rex: /\$((?:\S?)|(?:\S.*?\S))\$/gy,
220222
tmpl: '<eq>$1</eq>',
221223
tag: '$',
222224
pre: texmath.$_pre,
@@ -239,56 +241,36 @@ texmath.rules = {
239241
kramdown: {
240242
inline: [
241243
{ name: 'math_inline',
242-
rex: /\${2}([^$\r\n]*?)\${2}/gy,
244+
rex: /\${2}(.+?)\${2}/gy,
243245
tmpl: '<eq>$1</eq>',
244246
tag: '$$'
245247
}
246248
],
247249
block: [
248250
{ name: 'math_block_eqno',
249-
rex: /\${2}([^$]*?)\${2}\s*?\(([^)$\r\n]+?)\)/gmy,
250-
tmpl: '<section class="eqno"><eqn>$1</eqn><span>($2)</span></section>',
251-
tag: '$$'
252-
},
253-
{ name: 'math_block',
254-
rex: /\${2}([^$]*?)\${2}/gmy,
255-
tmpl: '<section><eqn>$1</eqn></section>',
256-
tag: '$$'
257-
}
258-
]
259-
},
260-
pandoc: {
261-
inline: [
262-
{ name: 'math_block',
263-
rex: /\${2}([^$]*?)\${2}/gy,
264-
tmpl: '<section><eqn>$1</eqn></section>',
265-
tag: '$$'
266-
}
267-
],
268-
block: [
269-
{ name: 'math_block_eqno',
270-
rex: /\${2}([^$]*?)\${2}\s*?\(([^)$\r\n]+?)\)/gmy,
251+
rex: /\${2}([^$]+?)\${2}\s*?\(([^)\s]+?)\)/gmy,
271252
tmpl: '<section class="eqno"><eqn>$1</eqn><span>($2)</span></section>',
272253
tag: '$$'
273254
},
274255
{ name: 'math_block',
275-
rex: /\${2}([^$]*?)\${2}/gmy,
256+
rex: /\${2}([^$]+?)\${2}/gmy,
276257
tmpl: '<section><eqn>$1</eqn></section>',
277258
tag: '$$'
278259
}
279260
]
280261
},
281262
dollars: {
282-
inline: [
283-
{ name: 'math_inline',
284-
rex: /\$(\S[^$\r\n]*?[^\s\\]{1}?)\$/gy,
285-
tmpl: '<eq>$1</eq>',
286-
tag: '$',
263+
inline: [
264+
{ name: 'math_inline_double',
265+
rex: /\${2}((?:\S)|(?:\S.*?\S))\${2}/gy,
266+
tmpl: '<section><eqn>$1</eqn></section>',
267+
tag: '$$',
268+
displayMode: true,
287269
pre: texmath.$_pre,
288270
post: texmath.$_post
289271
},
290-
{ name: 'math_single',
291-
rex: /\$([^$\s\\]{1}?)\$/gy,
272+
{ name: 'math_inline',
273+
rex: /\$((?:\S)|(?:\S.*?\S))\$/gy,
292274
tmpl: '<eq>$1</eq>',
293275
tag: '$',
294276
pre: texmath.$_pre,
@@ -297,12 +279,12 @@ texmath.rules = {
297279
],
298280
block: [
299281
{ name: 'math_block_eqno',
300-
rex: /\${2}([^$]*?)\${2}\s*?\(([^)$\r\n]+?)\)/gmy,
282+
rex: /\${2}([^$]+?)\${2}\s*?\(([^)\s]+?)\)/gmy,
301283
tmpl: '<section class="eqno"><eqn>$1</eqn><span>($2)</span></section>',
302284
tag: '$$'
303285
},
304286
{ name: 'math_block',
305-
rex: /\${2}([^$]*?)\${2}/gmy,
287+
rex: /\${2}([^$]+?)\${2}/gmy,
306288
tmpl: '<section><eqn>$1</eqn></section>',
307289
tag: '$$'
308290
}

0 commit comments

Comments
 (0)