marked-katex-extension 2.1.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  Render [katex](https://katex.org/) code in marked
4
4
 
5
- Note: Block level katex requires at least 2 `$` at the beginning and end.
6
-
7
5
  ```markdown
8
6
  This is inline katex: $c = \\pm\\sqrt{a^2 + b^2}$
9
7
 
@@ -17,7 +15,7 @@ $$
17
15
  You will still need to include the css in your html document to allow katex styles.
18
16
 
19
17
  ```html
20
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.2/dist/katex.min.css" integrity="sha384-bYdxxUwYipFNohQlHt0bjN/LCpueqWz13HufFEV1SUatKs1cm4L6fFgCi1jT643X" crossorigin="anonymous">
18
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css" integrity="sha384-GvrOXuhMATgEsSwCs4smul74iXGOixntILdUW9XmUC6+HX0sLNAK3q71HotJqlAn" crossorigin="anonymous">
21
19
  ```
22
20
 
23
21
  # Usage
@@ -41,6 +39,25 @@ marked.parse("katex: $c = \\pm\\sqrt{a^2 + b^2}$");
41
39
 
42
40
  ![image](https://user-images.githubusercontent.com/97994/188899567-e6e8268c-209e-4067-8f44-0ada16caacdd.png)
43
41
 
42
+ ## Block level
43
+
44
+ You can include newlines in block level katex. Block level katex must contain starting and ending delimiters on their own line.
45
+
46
+ ```js
47
+ marked.parse(`
48
+ $$
49
+ \\begin{array}{cc}
50
+ a & b \\\\
51
+ c & d
52
+ \\end{array}
53
+ $$
54
+ `);
55
+ ```
56
+
57
+ ## DisplayMode
58
+
59
+ [`displayMode`](https://katex.org/docs/options.html) will be on by default when using two dollar signs (`$$`) in inline or block katex. And it will be off by default for a single dollar sign (`$`) in inline or block katex.
60
+
44
61
  ## `options`
45
62
 
46
- Options are sent directly to [`katex.renderToString`](https://katex.org/docs/api.html#server-side-rendering-or-rendering-to-a-string)
63
+ Options are sent directly to [`katex`](https://katex.org/docs/options.html)
package/lib/index.cjs CHANGED
@@ -2,54 +2,71 @@
2
2
 
3
3
  var katex = require('katex');
4
4
 
5
+ const inlineStartRule = /(?<=\s|^)\${1,2}(?!\$)/;
6
+ const inlineRule = /^(\${1,2})(?!\$)((?:\\.|[^\\\n])+?)(?<!\$)\1(?=\s|$)/;
7
+ const blockRule = /^(\${1,2})\n((?:\\[^]|[^\\])+?)\n\1(?:\n|$)/;
8
+
5
9
  function index(options = {}) {
6
10
  return {
7
11
  extensions: [
8
- inlineKatex(options),
9
- blockKatex(options)
12
+ inlineKatex(options, createRenderer(options, false)),
13
+ blockKatex(options, createRenderer(options, true))
10
14
  ]
11
15
  };
12
16
  }
13
17
 
14
- function inlineKatex(options) {
18
+ function createRenderer(options, newlineAfter) {
19
+ return (token) => katex.renderToString(token.text, { ...options, displayMode: token.displayMode }) + (newlineAfter ? '\n' : '');
20
+ }
21
+
22
+ function inlineKatex(options, renderer) {
15
23
  return {
16
24
  name: 'inlineKatex',
17
25
  level: 'inline',
18
- start(src) { return src.indexOf('$'); },
26
+ start(src) {
27
+ const match = src.match(inlineStartRule);
28
+ if (!match) {
29
+ return;
30
+ }
31
+
32
+ const possibleKatex = src.substring(match.index);
33
+
34
+ if (possibleKatex.match(inlineRule)) {
35
+ return match.index;
36
+ }
37
+ },
19
38
  tokenizer(src, tokens) {
20
- const match = src.match(/^\$+([^$\n]+?)\$+/);
39
+ const match = src.match(inlineRule);
21
40
  if (match) {
22
41
  return {
23
42
  type: 'inlineKatex',
24
43
  raw: match[0],
25
- text: match[1].trim()
44
+ text: match[2].trim(),
45
+ displayMode: match[1].length === 2
26
46
  };
27
47
  }
28
48
  },
29
- renderer(token) {
30
- return katex.renderToString(token.text, options);
31
- }
49
+ renderer
32
50
  };
33
51
  }
34
52
 
35
- function blockKatex(options) {
53
+ function blockKatex(options, renderer) {
36
54
  return {
37
55
  name: 'blockKatex',
38
56
  level: 'block',
39
- start(src) { return src.indexOf('\n$$'); },
57
+ start(src) { return src.indexOf('\n$'); },
40
58
  tokenizer(src, tokens) {
41
- const match = src.match(/^\$\$+\n([^$]+?)\n\$\$+\n/);
59
+ const match = src.match(blockRule);
42
60
  if (match) {
43
61
  return {
44
62
  type: 'blockKatex',
45
63
  raw: match[0],
46
- text: match[1].trim()
64
+ text: match[2].trim(),
65
+ displayMode: match[1].length === 2
47
66
  };
48
67
  }
49
68
  },
50
- renderer(token) {
51
- return `<p>${katex.renderToString(token.text, options)}</p>`;
52
- }
69
+ renderer
53
70
  };
54
71
  }
55
72
 
package/lib/index.umd.js CHANGED
@@ -18409,54 +18409,71 @@
18409
18409
  }
18410
18410
  };
18411
18411
 
18412
+ const inlineStartRule = /(?<=\s|^)\${1,2}(?!\$)/;
18413
+ const inlineRule = /^(\${1,2})(?!\$)((?:\\.|[^\\\n])+?)(?<!\$)\1(?=\s|$)/;
18414
+ const blockRule = /^(\${1,2})\n((?:\\[^]|[^\\])+?)\n\1(?:\n|$)/;
18415
+
18412
18416
  function index(options = {}) {
18413
18417
  return {
18414
18418
  extensions: [
18415
- inlineKatex(options),
18416
- blockKatex(options)
18419
+ inlineKatex(options, createRenderer(options, false)),
18420
+ blockKatex(options, createRenderer(options, true))
18417
18421
  ]
18418
18422
  };
18419
18423
  }
18420
18424
 
18421
- function inlineKatex(options) {
18425
+ function createRenderer(options, newlineAfter) {
18426
+ return (token) => katex.renderToString(token.text, { ...options, displayMode: token.displayMode }) + (newlineAfter ? '\n' : '');
18427
+ }
18428
+
18429
+ function inlineKatex(options, renderer) {
18422
18430
  return {
18423
18431
  name: 'inlineKatex',
18424
18432
  level: 'inline',
18425
- start(src) { return src.indexOf('$'); },
18433
+ start(src) {
18434
+ const match = src.match(inlineStartRule);
18435
+ if (!match) {
18436
+ return;
18437
+ }
18438
+
18439
+ const possibleKatex = src.substring(match.index);
18440
+
18441
+ if (possibleKatex.match(inlineRule)) {
18442
+ return match.index;
18443
+ }
18444
+ },
18426
18445
  tokenizer(src, tokens) {
18427
- const match = src.match(/^\$+([^$\n]+?)\$+/);
18446
+ const match = src.match(inlineRule);
18428
18447
  if (match) {
18429
18448
  return {
18430
18449
  type: 'inlineKatex',
18431
18450
  raw: match[0],
18432
- text: match[1].trim()
18451
+ text: match[2].trim(),
18452
+ displayMode: match[1].length === 2
18433
18453
  };
18434
18454
  }
18435
18455
  },
18436
- renderer(token) {
18437
- return katex.renderToString(token.text, options);
18438
- }
18456
+ renderer
18439
18457
  };
18440
18458
  }
18441
18459
 
18442
- function blockKatex(options) {
18460
+ function blockKatex(options, renderer) {
18443
18461
  return {
18444
18462
  name: 'blockKatex',
18445
18463
  level: 'block',
18446
- start(src) { return src.indexOf('\n$$'); },
18464
+ start(src) { return src.indexOf('\n$'); },
18447
18465
  tokenizer(src, tokens) {
18448
- const match = src.match(/^\$\$+\n([^$]+?)\n\$\$+\n/);
18466
+ const match = src.match(blockRule);
18449
18467
  if (match) {
18450
18468
  return {
18451
18469
  type: 'blockKatex',
18452
18470
  raw: match[0],
18453
- text: match[1].trim()
18471
+ text: match[2].trim(),
18472
+ displayMode: match[1].length === 2
18454
18473
  };
18455
18474
  }
18456
18475
  },
18457
- renderer(token) {
18458
- return `<p>${katex.renderToString(token.text, options)}</p>`;
18459
- }
18476
+ renderer
18460
18477
  };
18461
18478
  }
18462
18479
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marked-katex-extension",
3
- "version": "2.1.1",
3
+ "version": "3.0.0",
4
4
  "description": "MarkedJS extesion to render katex",
5
5
  "main": "./lib/index.cjs",
6
6
  "module": "./src/index.js",
@@ -27,7 +27,8 @@
27
27
  "test:cover": "jest --coverage",
28
28
  "test:types": "tsd -f spec/index.test-d.ts -t src/index.d.ts",
29
29
  "lint": "eslint .",
30
- "build": "rollup -c rollup.config.js"
30
+ "build": "rollup -c rollup.config.js",
31
+ "update-specs": "node ./update-specs.js"
31
32
  },
32
33
  "repository": {
33
34
  "type": "git",
@@ -43,26 +44,28 @@
43
44
  "marked": "^4 || ^5"
44
45
  },
45
46
  "devDependencies": {
46
- "@babel/core": "^7.22.5",
47
- "@babel/preset-env": "^7.22.5",
47
+ "@babel/core": "^7.22.6",
48
+ "@babel/preset-env": "^7.22.6",
48
49
  "@rollup/plugin-node-resolve": "^15.1.0",
49
50
  "@semantic-release/changelog": "^6.0.3",
50
51
  "@semantic-release/commit-analyzer": "^10.0.1",
51
52
  "@semantic-release/git": "^10.0.1",
52
53
  "@semantic-release/github": "^9.0.3",
53
54
  "@semantic-release/npm": "^10.0.4",
54
- "@semantic-release/release-notes-generator": "^11.0.3",
55
+ "@semantic-release/release-notes-generator": "^11.0.4",
55
56
  "@types/marked": "^5.0.0",
56
- "babel-jest": "^29.5.0",
57
- "eslint": "^8.43.0",
57
+ "babel-jest": "^29.6.0",
58
+ "cheerio": "^1.0.0-rc.12",
59
+ "eslint": "^8.44.0",
58
60
  "eslint-config-standard": "^17.1.0",
59
61
  "eslint-plugin-import": "^2.27.5",
60
62
  "eslint-plugin-n": "^16.0.1",
61
63
  "eslint-plugin-promise": "^6.1.1",
62
- "jest-cli": "^29.5.0",
63
- "marked": "^5.0.4",
64
- "rollup": "^3.25.3",
65
- "semantic-release": "^21.0.5",
64
+ "jest-cli": "^29.6.0",
65
+ "marked": "^5.1.0",
66
+ "node-fetch": "^3.3.1",
67
+ "rollup": "^3.26.1",
68
+ "semantic-release": "^21.0.7",
66
69
  "tsd": "^0.28.1"
67
70
  },
68
71
  "dependencies": {
package/src/index.js CHANGED
@@ -1,52 +1,69 @@
1
1
  import katex from 'katex';
2
2
 
3
+ const inlineStartRule = /(?<=\s|^)\${1,2}(?!\$)/;
4
+ const inlineRule = /^(\${1,2})(?!\$)((?:\\.|[^\\\n])+?)(?<!\$)\1(?=\s|$)/;
5
+ const blockRule = /^(\${1,2})\n((?:\\[^]|[^\\])+?)\n\1(?:\n|$)/;
6
+
3
7
  export default function(options = {}) {
4
8
  return {
5
9
  extensions: [
6
- inlineKatex(options),
7
- blockKatex(options)
10
+ inlineKatex(options, createRenderer(options, false)),
11
+ blockKatex(options, createRenderer(options, true))
8
12
  ]
9
13
  };
10
14
  }
11
15
 
12
- function inlineKatex(options) {
16
+ function createRenderer(options, newlineAfter) {
17
+ return (token) => katex.renderToString(token.text, { ...options, displayMode: token.displayMode }) + (newlineAfter ? '\n' : '');
18
+ }
19
+
20
+ function inlineKatex(options, renderer) {
13
21
  return {
14
22
  name: 'inlineKatex',
15
23
  level: 'inline',
16
- start(src) { return src.indexOf('$'); },
24
+ start(src) {
25
+ const match = src.match(inlineStartRule);
26
+ if (!match) {
27
+ return;
28
+ }
29
+
30
+ const possibleKatex = src.substring(match.index);
31
+
32
+ if (possibleKatex.match(inlineRule)) {
33
+ return match.index;
34
+ }
35
+ },
17
36
  tokenizer(src, tokens) {
18
- const match = src.match(/^\$+([^$\n]+?)\$+/);
37
+ const match = src.match(inlineRule);
19
38
  if (match) {
20
39
  return {
21
40
  type: 'inlineKatex',
22
41
  raw: match[0],
23
- text: match[1].trim()
42
+ text: match[2].trim(),
43
+ displayMode: match[1].length === 2
24
44
  };
25
45
  }
26
46
  },
27
- renderer(token) {
28
- return katex.renderToString(token.text, options);
29
- }
47
+ renderer
30
48
  };
31
49
  }
32
50
 
33
- function blockKatex(options) {
51
+ function blockKatex(options, renderer) {
34
52
  return {
35
53
  name: 'blockKatex',
36
54
  level: 'block',
37
- start(src) { return src.indexOf('\n$$'); },
55
+ start(src) { return src.indexOf('\n$'); },
38
56
  tokenizer(src, tokens) {
39
- const match = src.match(/^\$\$+\n([^$]+?)\n\$\$+\n/);
57
+ const match = src.match(blockRule);
40
58
  if (match) {
41
59
  return {
42
60
  type: 'blockKatex',
43
61
  raw: match[0],
44
- text: match[1].trim()
62
+ text: match[2].trim(),
63
+ displayMode: match[1].length === 2
45
64
  };
46
65
  }
47
66
  },
48
- renderer(token) {
49
- return `<p>${katex.renderToString(token.text, options)}</p>`;
50
- }
67
+ renderer
51
68
  };
52
69
  }