@cobapen/markdown 0.3.1 → 0.4.1
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 +1 -1
- package/package.json +12 -7
- package/dist/code/fence-custom.d.ts +0 -13
- package/dist/code/fence-custom.js +0 -51
- package/dist/code/highlight.d.ts +0 -18
- package/dist/code/highlight.js +0 -91
- package/dist/code/info-string.d.ts +0 -26
- package/dist/code/info-string.js +0 -129
- package/dist/index.d.ts +0 -42
- package/dist/index.js +0 -79
- package/dist/link/replacelink.d.ts +0 -8
- package/dist/link/replacelink.js +0 -40
- package/dist/math/mathjax.d.ts +0 -97
- package/dist/math/mathjax.js +0 -110
- package/dist/math/mdmath.d.ts +0 -14
- package/dist/math/mdmath.js +0 -67
- package/dist/math/mdparser.d.ts +0 -9
- package/dist/math/mdparser.js +0 -148
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cobapen/markdown",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "A markdown converter for cobapen website",
|
|
5
|
-
"keywords": [
|
|
5
|
+
"keywords": [
|
|
6
|
+
"markdown"
|
|
7
|
+
],
|
|
6
8
|
"license": "MIT",
|
|
7
9
|
"author": "yamavol",
|
|
8
10
|
"type": "module",
|
|
@@ -20,20 +22,24 @@
|
|
|
20
22
|
"dist/**/*.js",
|
|
21
23
|
"dist/**/*.d.ts"
|
|
22
24
|
],
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=20.11.0 <21 || >=21.2.0"
|
|
27
|
+
},
|
|
23
28
|
"scripts": {
|
|
24
29
|
"build": "tsc",
|
|
25
|
-
"build:
|
|
30
|
+
"build:dev": "tsc --build tsconfig.dev.json",
|
|
31
|
+
"build:doc": "npm run build && node docs/build.js",
|
|
26
32
|
"test": "vitest",
|
|
27
33
|
"coverage": "vitest run --coverage",
|
|
28
34
|
"lint": "eslint src",
|
|
29
|
-
"lint:fix": "eslint src --fix"
|
|
30
|
-
"lint:dist": "eslint dist --fix"
|
|
35
|
+
"lint:fix": "eslint src --fix"
|
|
31
36
|
},
|
|
32
37
|
"dependencies": {
|
|
33
38
|
"highlight.js": "^11.11.1",
|
|
34
39
|
"katex": "^0.16.22",
|
|
35
40
|
"lodash-es": "^4.17.21",
|
|
36
41
|
"markdown-it": "^14.1.0",
|
|
42
|
+
"markdown-it-adv-table": "^0.1.1",
|
|
37
43
|
"markdown-it-anchor": "^9.2.0",
|
|
38
44
|
"markdown-it-cjk-breaks": "^2.0.0",
|
|
39
45
|
"markdown-it-deflist": "^3.0.0",
|
|
@@ -42,7 +48,7 @@
|
|
|
42
48
|
"mathjax-full": "^3.2.2"
|
|
43
49
|
},
|
|
44
50
|
"devDependencies": {
|
|
45
|
-
"@
|
|
51
|
+
"@cobapen/eslint-config": "^0.4.0",
|
|
46
52
|
"@types/katex": "^0.16.7",
|
|
47
53
|
"@types/lodash-es": "^4.17.12",
|
|
48
54
|
"@types/markdown-it": "^14.1.2",
|
|
@@ -52,7 +58,6 @@
|
|
|
52
58
|
"eslint": "^9.24.0",
|
|
53
59
|
"mustache": "^4.2.0",
|
|
54
60
|
"typescript": "^5.8.3",
|
|
55
|
-
"typescript-eslint": "^8.29.1",
|
|
56
61
|
"vitest": "^3.1.1"
|
|
57
62
|
}
|
|
58
63
|
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Options } from "markdown-it/index.mjs";
|
|
2
|
-
import Renderer from "markdown-it/lib/renderer.mjs";
|
|
3
|
-
import Token from "markdown-it/lib/token.mjs";
|
|
4
|
-
interface Env {
|
|
5
|
-
showCodeTitleByDefault?: boolean;
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Custom fence renderer for markdown-it.
|
|
9
|
-
*
|
|
10
|
-
* see: markdown-it/lib/renderer.mjs
|
|
11
|
-
*/
|
|
12
|
-
export declare function fence_custom(tokens: Token[], idx: number, options: Options, env: Env, slf: Renderer): string;
|
|
13
|
-
export {};
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { escapeHtml, unescapeAll } from "markdown-it/lib/common/utils.mjs";
|
|
2
|
-
import { InfoString } from "./info-string.js";
|
|
3
|
-
/**
|
|
4
|
-
* Custom fence renderer for markdown-it.
|
|
5
|
-
*
|
|
6
|
-
* see: markdown-it/lib/renderer.mjs
|
|
7
|
-
*/
|
|
8
|
-
export function fence_custom(tokens, idx, options, env, slf) {
|
|
9
|
-
const token = tokens[idx];
|
|
10
|
-
const info_str = token.info ? unescapeAll(token.info).trim() : "";
|
|
11
|
-
const info = new InfoString(info_str);
|
|
12
|
-
const langName = info.lang;
|
|
13
|
-
const langAttrs = info.attrs.join(" ");
|
|
14
|
-
let highlighted;
|
|
15
|
-
if (options.highlight) {
|
|
16
|
-
highlighted = options.highlight(token.content, langName, langAttrs) || escapeHtml(token.content);
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
highlighted = escapeHtml(token.content);
|
|
20
|
-
}
|
|
21
|
-
if (highlighted.indexOf("<pre") === 0) {
|
|
22
|
-
return highlighted + "\n";
|
|
23
|
-
}
|
|
24
|
-
// If language exists, inject class gently, without modifying original token.
|
|
25
|
-
// May be, one day we will add .deepClone() for token and simplify this part, but
|
|
26
|
-
// now we prefer to keep things local.
|
|
27
|
-
if (info.hasLang) {
|
|
28
|
-
const i = token.attrIndex("class");
|
|
29
|
-
const tmpAttrs = token.attrs ? token.attrs.slice() : [];
|
|
30
|
-
if (i < 0) {
|
|
31
|
-
tmpAttrs.push(["class", options.langPrefix + langName]);
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
tmpAttrs[i] = tmpAttrs[i].slice();
|
|
35
|
-
tmpAttrs[i][1] += " " + options.langPrefix + langName;
|
|
36
|
-
}
|
|
37
|
-
// Fake token just to render attributes
|
|
38
|
-
const tmpToken = {
|
|
39
|
-
attrs: tmpAttrs
|
|
40
|
-
};
|
|
41
|
-
if (info.title.length > 0) {
|
|
42
|
-
const style = (env.showCodeTitleByDefault === true)
|
|
43
|
-
? ""
|
|
44
|
-
: " style=\"visibility:hidden;\"";
|
|
45
|
-
return `<pre><code${slf.renderAttrs(tmpToken)}>${highlighted}</code><span class="title"${style}>${info.title}</span></pre>\n`;
|
|
46
|
-
}
|
|
47
|
-
return `<pre><code${slf.renderAttrs(tmpToken)}>${highlighted}</code></pre>\n`;
|
|
48
|
-
}
|
|
49
|
-
return `<pre><code${slf.renderAttrs(token)}>${highlighted}</code></pre>\n`;
|
|
50
|
-
}
|
|
51
|
-
//# sourceMappingURL=fence-custom.js.map
|
package/dist/code/highlight.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Highlight function with line number support
|
|
3
|
-
*
|
|
4
|
-
* @param code
|
|
5
|
-
* @param lang
|
|
6
|
-
* @param linestart
|
|
7
|
-
* @returns
|
|
8
|
-
*/
|
|
9
|
-
export declare function highlightWithLineNumber(code: string, lang: string, linestart?: number): string;
|
|
10
|
-
/**
|
|
11
|
-
* Exported function for markdown-it
|
|
12
|
-
*
|
|
13
|
-
* @param str
|
|
14
|
-
* @param lang
|
|
15
|
-
* @param attrs
|
|
16
|
-
* @returns
|
|
17
|
-
*/
|
|
18
|
-
export declare function highlighterForMarkdownIt(str: string, lang: string, attrs: string): string;
|
package/dist/code/highlight.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* highlight.ts
|
|
3
|
-
* 2023-11-20
|
|
4
|
-
* provides a custom highlighter for MarkdownIt
|
|
5
|
-
*/
|
|
6
|
-
import hljs from "highlight.js";
|
|
7
|
-
import { InfoString } from "./info-string.js";
|
|
8
|
-
function _debuglog(..._args) {
|
|
9
|
-
// if (_debuglog.caller.name !== "") return;
|
|
10
|
-
// console.log(...args);
|
|
11
|
-
}
|
|
12
|
-
/** Get digits of the number. e.g. 1000 => 4 */
|
|
13
|
-
function numDigits(n) {
|
|
14
|
-
return Math.floor(n).toString().length;
|
|
15
|
-
}
|
|
16
|
-
/** Print a decimal nicely */
|
|
17
|
-
function niceDec(n) {
|
|
18
|
-
return n.toFixed(3);
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Highlight function with line number support
|
|
22
|
-
*
|
|
23
|
-
* @param code
|
|
24
|
-
* @param lang
|
|
25
|
-
* @param linestart
|
|
26
|
-
* @returns
|
|
27
|
-
*/
|
|
28
|
-
export function highlightWithLineNumber(code, lang, linestart) {
|
|
29
|
-
try {
|
|
30
|
-
/** convert if lang is specified + supported by highlight.js */
|
|
31
|
-
if (lang && hljs.getLanguage(lang)) {
|
|
32
|
-
/** do conversion */
|
|
33
|
-
let htmlLines = hljs.highlight(code, { language: lang }).value;
|
|
34
|
-
/**
|
|
35
|
-
* Attach the line number if specified.
|
|
36
|
-
*
|
|
37
|
-
* The given code is rendered in <pre><code>, so each line is terminated by '\n'.
|
|
38
|
-
* Split the input, wrap them by <div class="line">.
|
|
39
|
-
* At the beginning of each line, <span class="line-no"> is added.
|
|
40
|
-
*
|
|
41
|
-
* default styles are embedded so that the text is readable
|
|
42
|
-
* even if css was not applied.
|
|
43
|
-
*
|
|
44
|
-
* default-styles:
|
|
45
|
-
* - display: inline-block
|
|
46
|
-
* - user-select: none
|
|
47
|
-
* - width: ${numDigits}em
|
|
48
|
-
*/
|
|
49
|
-
if (linestart !== undefined) {
|
|
50
|
-
const lines = htmlLines.split("\n");
|
|
51
|
-
const elWidth = numDigits(linestart + lines.length) * 0.8;
|
|
52
|
-
const elStyle = "display:inline-block;" +
|
|
53
|
-
"user-select:none;" +
|
|
54
|
-
`width: ${niceDec(elWidth)}em;`;
|
|
55
|
-
lines.forEach((line, i, lines) => {
|
|
56
|
-
lines[i] =
|
|
57
|
-
"<div class=\"line\">" +
|
|
58
|
-
`<span class="line-no" style="${elStyle}">${linestart + i}</span>${line}` +
|
|
59
|
-
"</div>";
|
|
60
|
-
});
|
|
61
|
-
_debuglog(lines);
|
|
62
|
-
htmlLines = lines.join("");
|
|
63
|
-
}
|
|
64
|
-
return htmlLines;
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
// no language , no highlighting.
|
|
68
|
-
// If you want line numbers without highlighting, set language to
|
|
69
|
-
// "nohighlight" or "text"
|
|
70
|
-
return "";
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
catch (_) {
|
|
74
|
-
return "";
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Exported function for markdown-it
|
|
79
|
-
*
|
|
80
|
-
* @param str
|
|
81
|
-
* @param lang
|
|
82
|
-
* @param attrs
|
|
83
|
-
* @returns
|
|
84
|
-
*/
|
|
85
|
-
export function highlighterForMarkdownIt(str, lang, attrs) {
|
|
86
|
-
_debuglog(lang ? lang : "(lang is empty or undefined)");
|
|
87
|
-
const info = new InfoString(lang + " " + attrs);
|
|
88
|
-
_debuglog(info);
|
|
89
|
-
return highlightWithLineNumber(str, info.lang, info.linestart);
|
|
90
|
-
}
|
|
91
|
-
//# sourceMappingURL=highlight.js.map
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* InfoString parses info_string from fenced code block.
|
|
3
|
-
*/
|
|
4
|
-
export declare class InfoString {
|
|
5
|
-
private readonly _lang;
|
|
6
|
-
private readonly _attrs;
|
|
7
|
-
private readonly _title;
|
|
8
|
-
private readonly _linestart;
|
|
9
|
-
constructor(info: string);
|
|
10
|
-
get lang(): string;
|
|
11
|
-
get attrs(): string[];
|
|
12
|
-
get title(): string;
|
|
13
|
-
get linestart(): number | undefined;
|
|
14
|
-
get hasLang(): boolean;
|
|
15
|
-
/** Parse info_string into an array of strings. All quotes are removed*/
|
|
16
|
-
static parseInfoString(info: string): string[];
|
|
17
|
-
/** Parse metadata notation "{filename:line, ...}"" */
|
|
18
|
-
static parseMetaNotation(text: string): {
|
|
19
|
-
filename: string;
|
|
20
|
-
line: number;
|
|
21
|
-
} | undefined;
|
|
22
|
-
/** From attributes list, return title metadata */
|
|
23
|
-
static getTitle(attr: string[]): string;
|
|
24
|
-
/** From attributes list, return line number if defined */
|
|
25
|
-
static getLineStart(attr: string[]): number | undefined;
|
|
26
|
-
}
|
package/dist/code/info-string.js
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* InfoString parses info_string from fenced code block.
|
|
3
|
-
*/
|
|
4
|
-
export class InfoString {
|
|
5
|
-
_lang;
|
|
6
|
-
_attrs;
|
|
7
|
-
_title;
|
|
8
|
-
_linestart;
|
|
9
|
-
constructor(info) {
|
|
10
|
-
if (info.length > 0) {
|
|
11
|
-
const arr = InfoString.parseInfoString(info);
|
|
12
|
-
this._lang = arr[0];
|
|
13
|
-
this._attrs = arr.slice(1);
|
|
14
|
-
this._title = InfoString.getTitle(this._attrs);
|
|
15
|
-
this._linestart = InfoString.getLineStart(this._attrs);
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
this._lang = "";
|
|
19
|
-
this._attrs = [];
|
|
20
|
-
this._title = "";
|
|
21
|
-
this._linestart = undefined;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
get lang() {
|
|
25
|
-
return this._lang;
|
|
26
|
-
}
|
|
27
|
-
get attrs() {
|
|
28
|
-
return this._attrs;
|
|
29
|
-
}
|
|
30
|
-
get title() {
|
|
31
|
-
return this._title;
|
|
32
|
-
}
|
|
33
|
-
get linestart() {
|
|
34
|
-
return this._linestart;
|
|
35
|
-
}
|
|
36
|
-
get hasLang() {
|
|
37
|
-
return this._lang.length > 0;
|
|
38
|
-
}
|
|
39
|
-
/** Parse info_string into an array of strings. All quotes are removed*/
|
|
40
|
-
static parseInfoString(info) {
|
|
41
|
-
// There are 4 possible tokens, but it can be reduced to 2 patterns.
|
|
42
|
-
// arg, "arg quoted", key=value, key="value quoted"
|
|
43
|
-
//
|
|
44
|
-
// This function returns a quote-removed string.
|
|
45
|
-
//
|
|
46
|
-
// const regex = /([^\s]+=)?(?:"([^"]*)"|'([^']*)'|([^\s]+))/g;
|
|
47
|
-
// ~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
48
|
-
// key= "value" 'value' value
|
|
49
|
-
//
|
|
50
|
-
// The regex above does not support escape letters. The next regex
|
|
51
|
-
// is escape char aware.
|
|
52
|
-
//
|
|
53
|
-
// NOTE: This class is designed to handle escape letters. However, tools
|
|
54
|
-
// might decide to unescape info_string before used (e.g. markdown-it).
|
|
55
|
-
// In such case, you might need to use double-escaped quotes.
|
|
56
|
-
//
|
|
57
|
-
const dq = "[^\"\\\\]*(?:\\\\.|[^\"\\\\]*)*"; // [^"]*
|
|
58
|
-
const sq = "[^\'\\\\]*(?:\\\\.|[^\'\\\\]*)*"; // [^']*
|
|
59
|
-
// ~~~~~~~~~~ ~~~~~ ~~~~~~~~~~
|
|
60
|
-
// char seq ( escape char seq )*
|
|
61
|
-
//
|
|
62
|
-
const ptn = `([^\\s]+=)?(?:"(${dq})"|'(${sq})'|([^\\s]+))`;
|
|
63
|
-
// ~~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~
|
|
64
|
-
// key= "value" 'value' value
|
|
65
|
-
const regex = new RegExp(ptn, "g");
|
|
66
|
-
const result = [];
|
|
67
|
-
let match;
|
|
68
|
-
while ((match = regex.exec(info)) !== null) {
|
|
69
|
-
let text = (match[1] || "") + (match[2] || match[3] || match[4] || "");
|
|
70
|
-
text = unescape(text).trim();
|
|
71
|
-
result.push(text);
|
|
72
|
-
}
|
|
73
|
-
return result;
|
|
74
|
-
}
|
|
75
|
-
/** Parse metadata notation "{filename:line, ...}"" */
|
|
76
|
-
static parseMetaNotation(text) {
|
|
77
|
-
const match = text.match(/^\{\s*([^:]+):(\d+)\s*\}$/);
|
|
78
|
-
if (match) {
|
|
79
|
-
return {
|
|
80
|
-
filename: match[1],
|
|
81
|
-
line: parseInt(match[2], 10),
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
return undefined;
|
|
85
|
-
}
|
|
86
|
-
/** From attributes list, return title metadata */
|
|
87
|
-
static getTitle(attr) {
|
|
88
|
-
const titleAttr = attr.find(x => x.startsWith("title=")) ?? "";
|
|
89
|
-
if (titleAttr.length > 0) {
|
|
90
|
-
const match = titleAttr.match(/^title=(.*)$/);
|
|
91
|
-
if (match) {
|
|
92
|
-
let value = match[1].trim();
|
|
93
|
-
if (value.startsWith("\"") && value.endsWith("\"")) {
|
|
94
|
-
value = value.slice(1, -1);
|
|
95
|
-
value = unescape(value).trim();
|
|
96
|
-
}
|
|
97
|
-
return value;
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
throw new Error("Must not fail. Check impl.");
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
if (attr.length > 0) {
|
|
104
|
-
const meta = InfoString.parseMetaNotation(attr[0]);
|
|
105
|
-
if (meta && meta.filename.length > 0) {
|
|
106
|
-
return meta.filename;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return "";
|
|
110
|
-
}
|
|
111
|
-
/** From attributes list, return line number if defined */
|
|
112
|
-
static getLineStart(attr) {
|
|
113
|
-
const lineAttr = attr.find(x => x.startsWith("linestart=")) ?? "";
|
|
114
|
-
if (lineAttr.length > 0) {
|
|
115
|
-
return parseInt(lineAttr.split("=")[1].trim());
|
|
116
|
-
}
|
|
117
|
-
if (attr.length > 0) {
|
|
118
|
-
const meta = InfoString.parseMetaNotation(attr[0]);
|
|
119
|
-
if (meta && meta.line > 0) {
|
|
120
|
-
return meta.line;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
return undefined;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
function unescape(text) {
|
|
127
|
-
return text.replaceAll(/\\\"/g, "\"").replaceAll(/\\\'/g, "'");
|
|
128
|
-
}
|
|
129
|
-
//# sourceMappingURL=info-string.js.map
|
package/dist/index.d.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import markdownIt, { Options as MarkdownOptions } from "markdown-it";
|
|
2
|
-
import { Options as MathOptions } from "./math/mathjax.js";
|
|
3
|
-
export interface Config {
|
|
4
|
-
/**
|
|
5
|
-
* Set "true" to display the title (if specified) of the fenced code block.
|
|
6
|
-
* The title is hidden by default, and user must explicitly override the style.
|
|
7
|
-
*/
|
|
8
|
-
showCodeTitleByDefault: boolean;
|
|
9
|
-
/**
|
|
10
|
-
* MarkdownIt options
|
|
11
|
-
*/
|
|
12
|
-
markdown: Partial<MarkdownOptions>;
|
|
13
|
-
/**
|
|
14
|
-
* MathJax options
|
|
15
|
-
*/
|
|
16
|
-
math: Partial<MathOptions>;
|
|
17
|
-
}
|
|
18
|
-
export type Options = Partial<Config>;
|
|
19
|
-
export declare class CMarkdown {
|
|
20
|
-
private readonly _config;
|
|
21
|
-
private readonly _mj;
|
|
22
|
-
private readonly _md;
|
|
23
|
-
constructor(option?: Options);
|
|
24
|
-
/**
|
|
25
|
-
* Install plugins and renderers to the markdown-it instance.
|
|
26
|
-
*
|
|
27
|
-
* @param md The instance
|
|
28
|
-
*/
|
|
29
|
-
setup(md: markdownIt): void;
|
|
30
|
-
/**
|
|
31
|
-
* Render html from markdown.
|
|
32
|
-
*
|
|
33
|
-
* @param text markdown text
|
|
34
|
-
* @returns html text
|
|
35
|
-
*/
|
|
36
|
-
render(text: string): string;
|
|
37
|
-
/**
|
|
38
|
-
* Returns the MathJax CSS.
|
|
39
|
-
* @returns
|
|
40
|
-
*/
|
|
41
|
-
mathcss(): string;
|
|
42
|
-
}
|
package/dist/index.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import markdownIt from "markdown-it";
|
|
2
|
-
import { highlighterForMarkdownIt } from "./code/highlight.js";
|
|
3
|
-
import anchor from "markdown-it-anchor";
|
|
4
|
-
// @ts-ignore
|
|
5
|
-
import cjkbreaks from "markdown-it-cjk-breaks";
|
|
6
|
-
// @ts-ignore
|
|
7
|
-
import deflist from "markdown-it-deflist";
|
|
8
|
-
// @ts-ignore
|
|
9
|
-
import toc from "markdown-it-table-of-contents";
|
|
10
|
-
// @ts-ignore
|
|
11
|
-
import footnote from "markdown-it-footnote";
|
|
12
|
-
import { MathjaxEngine } from "./math/mathjax.js";
|
|
13
|
-
import { mdmath } from "./math/mdmath.js";
|
|
14
|
-
import { fence_custom } from "./code/fence-custom.js";
|
|
15
|
-
import { replacelink } from "./link/replacelink.js";
|
|
16
|
-
const defaultOptions = {
|
|
17
|
-
showCodeTitleByDefault: false,
|
|
18
|
-
markdown: {
|
|
19
|
-
html: true,
|
|
20
|
-
linkify: true,
|
|
21
|
-
highlight: highlighterForMarkdownIt,
|
|
22
|
-
},
|
|
23
|
-
math: {
|
|
24
|
-
tex: {
|
|
25
|
-
macros: {
|
|
26
|
-
bm: ["\\boldsymbol{#1}", 1],
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
export class CMarkdown {
|
|
32
|
-
_config;
|
|
33
|
-
_mj;
|
|
34
|
-
_md;
|
|
35
|
-
constructor(option) {
|
|
36
|
-
const config = { ...defaultOptions, ...option };
|
|
37
|
-
const mj = new MathjaxEngine(config.math);
|
|
38
|
-
const md = markdownIt(config.markdown);
|
|
39
|
-
this._config = config;
|
|
40
|
-
this._mj = mj;
|
|
41
|
-
this._md = md;
|
|
42
|
-
this.setup(md);
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Install plugins and renderers to the markdown-it instance.
|
|
46
|
-
*
|
|
47
|
-
* @param md The instance
|
|
48
|
-
*/
|
|
49
|
-
setup(md) {
|
|
50
|
-
md.renderer.rules.fence = fence_custom;
|
|
51
|
-
md.use(anchor)
|
|
52
|
-
.use(cjkbreaks)
|
|
53
|
-
.use(footnote)
|
|
54
|
-
.use(deflist)
|
|
55
|
-
.use(replacelink)
|
|
56
|
-
.use(mdmath(this._mj))
|
|
57
|
-
.use(toc, {
|
|
58
|
-
includeLevel: [2, 3],
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Render html from markdown.
|
|
63
|
-
*
|
|
64
|
-
* @param text markdown text
|
|
65
|
-
* @returns html text
|
|
66
|
-
*/
|
|
67
|
-
render(text) {
|
|
68
|
-
const env = { ...this._config }; // env object must s
|
|
69
|
-
return this._md.render(text, env);
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Returns the MathJax CSS.
|
|
73
|
-
* @returns
|
|
74
|
-
*/
|
|
75
|
-
mathcss() {
|
|
76
|
-
return this._mj.stylesheet();
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { PluginWithOptions } from "markdown-it";
|
|
2
|
-
import Token from "markdown-it/lib/token.mjs";
|
|
3
|
-
type ReplaceHandler = (link: string, env: any, token: Token) => string;
|
|
4
|
-
interface Options {
|
|
5
|
-
replace: ReplaceHandler;
|
|
6
|
-
}
|
|
7
|
-
export declare const replacelink: PluginWithOptions<Options>;
|
|
8
|
-
export default replacelink;
|
package/dist/link/replacelink.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
function defaultHandler(link, _env, _token) {
|
|
2
|
-
if (!link.startsWith("http") && link.endsWith(".md")) {
|
|
3
|
-
return link.replace(/\.md$/, ".html");
|
|
4
|
-
}
|
|
5
|
-
else {
|
|
6
|
-
return link;
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
function replaceAttr(token, attrName, handler, env) {
|
|
10
|
-
token.attrs?.forEach(attr => {
|
|
11
|
-
if (attr[0] === attrName) {
|
|
12
|
-
attr[1] = handler(attr[1], env, token);
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
function getHandler(option) {
|
|
17
|
-
const replaceFn = option?.replace || defaultHandler;
|
|
18
|
-
function handler(state) {
|
|
19
|
-
state.tokens.forEach(token => {
|
|
20
|
-
if (token.type === "inline" && token.children !== null) {
|
|
21
|
-
token.children.forEach(childToken => {
|
|
22
|
-
if (childToken.type == "link_open") {
|
|
23
|
-
replaceAttr(childToken, "href", replaceFn, state.env);
|
|
24
|
-
}
|
|
25
|
-
else if (childToken.type == "image") {
|
|
26
|
-
replaceAttr(childToken, "src", replaceFn, state.env);
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
;
|
|
33
|
-
return handler;
|
|
34
|
-
}
|
|
35
|
-
export const replacelink = (md, option) => {
|
|
36
|
-
const handler = getHandler(option);
|
|
37
|
-
md.core.ruler.after("linkify", "replace_link", handler);
|
|
38
|
-
};
|
|
39
|
-
export default replacelink;
|
|
40
|
-
//# sourceMappingURL=replacelink.js.map
|
package/dist/math/mathjax.d.ts
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* mathjax.ts
|
|
3
|
-
*
|
|
4
|
-
* Server-Side Mathjax converter from TeX input to CommonHTML.
|
|
5
|
-
*
|
|
6
|
-
* see official examples for more information
|
|
7
|
-
* https://github.com/mathjax/mathjax-v3
|
|
8
|
-
* https://github.com/mathjax/MathJax-demos-node/blob/master/direct/tex2chtml
|
|
9
|
-
*/
|
|
10
|
-
import { type LiteAdaptor } from "mathjax-full/js/adaptors/liteAdaptor.js";
|
|
11
|
-
import { LiteElement } from "mathjax-full/js/adaptors/lite/Element.js";
|
|
12
|
-
import { type LiteText } from "mathjax-full/js/adaptors/lite/Text.js";
|
|
13
|
-
import { type LiteDocument } from "mathjax-full/js/adaptors/lite/Document.js";
|
|
14
|
-
import { type MathDocument } from "mathjax-full/js/core/MathDocument.js";
|
|
15
|
-
import { TeX } from "mathjax-full/js/input/tex.js";
|
|
16
|
-
import { CHTML } from "mathjax-full/js/output/chtml.js";
|
|
17
|
-
type N = LiteElement;
|
|
18
|
-
type T = LiteText;
|
|
19
|
-
type D = LiteDocument;
|
|
20
|
-
interface AnyObject {
|
|
21
|
-
[x: string]: any;
|
|
22
|
-
}
|
|
23
|
-
interface TexConfig {
|
|
24
|
-
packages: string | [string] | AnyObject;
|
|
25
|
-
inlineMath: [[string, string]];
|
|
26
|
-
displayMath: [[string, string]];
|
|
27
|
-
processEscapes: boolean;
|
|
28
|
-
processEnvironments: boolean;
|
|
29
|
-
processRefs: boolean;
|
|
30
|
-
digits: RegExp;
|
|
31
|
-
tags: string;
|
|
32
|
-
tagSide: string;
|
|
33
|
-
tagIndent: string;
|
|
34
|
-
useLabelIds: boolean;
|
|
35
|
-
multlineWidth: string;
|
|
36
|
-
maxMacros: number;
|
|
37
|
-
maxBuffer: number;
|
|
38
|
-
baseURL: string;
|
|
39
|
-
formatError: (jax: object, err: Error) => void;
|
|
40
|
-
macros: AnyObject;
|
|
41
|
-
}
|
|
42
|
-
interface CHTMLConfig {
|
|
43
|
-
scale: number;
|
|
44
|
-
minScale: number;
|
|
45
|
-
matchFontHeight: boolean;
|
|
46
|
-
mtextInheritFont: boolean;
|
|
47
|
-
merrorInheritFont: boolean;
|
|
48
|
-
mtextFont: string;
|
|
49
|
-
merrorFont: string;
|
|
50
|
-
mathmlspacing: boolean;
|
|
51
|
-
skipAttributes: AnyObject;
|
|
52
|
-
exFactor: number;
|
|
53
|
-
displayAlign: string;
|
|
54
|
-
displayIndent: number | string;
|
|
55
|
-
fontURL: string;
|
|
56
|
-
adaptiveCSS: boolean;
|
|
57
|
-
}
|
|
58
|
-
export interface Options {
|
|
59
|
-
inline: boolean;
|
|
60
|
-
em: number;
|
|
61
|
-
ex: number;
|
|
62
|
-
width: number;
|
|
63
|
-
tex?: Partial<TexConfig>;
|
|
64
|
-
chtml?: Partial<CHTMLConfig>;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Initialize and encapsulates mathjax instances to generate
|
|
68
|
-
* CommonHTML from TeX input.
|
|
69
|
-
*
|
|
70
|
-
* There are 2 important methods. One converts the input.
|
|
71
|
-
* The other returns a stylesheet document. The stylesheet must be included
|
|
72
|
-
* in your HTML document to render the equation properly.
|
|
73
|
-
*/
|
|
74
|
-
export declare class MathjaxEngine {
|
|
75
|
-
option: Options;
|
|
76
|
-
adaptor: LiteAdaptor;
|
|
77
|
-
tex: TeX<N, T, D>;
|
|
78
|
-
chtml: CHTML<N, T, D>;
|
|
79
|
-
html: MathDocument<N, T, D>;
|
|
80
|
-
constructor(option?: Partial<Options>);
|
|
81
|
-
/**
|
|
82
|
-
* convert TeX input to CHTML.
|
|
83
|
-
*
|
|
84
|
-
* @param tex input string
|
|
85
|
-
* @param override parameter to override the defaults, if you wish to
|
|
86
|
-
* @returns
|
|
87
|
-
*/
|
|
88
|
-
convert(tex: string, override?: Partial<Options>): string;
|
|
89
|
-
/**
|
|
90
|
-
* returns adaptive css (stylesheet for the processed equations only),
|
|
91
|
-
* or the full mathjax css (if configured)
|
|
92
|
-
*
|
|
93
|
-
* @returns css content
|
|
94
|
-
*/
|
|
95
|
-
stylesheet(): string;
|
|
96
|
-
}
|
|
97
|
-
export {};
|
package/dist/math/mathjax.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* mathjax.ts
|
|
3
|
-
*
|
|
4
|
-
* Server-Side Mathjax converter from TeX input to CommonHTML.
|
|
5
|
-
*
|
|
6
|
-
* see official examples for more information
|
|
7
|
-
* https://github.com/mathjax/mathjax-v3
|
|
8
|
-
* https://github.com/mathjax/MathJax-demos-node/blob/master/direct/tex2chtml
|
|
9
|
-
*/
|
|
10
|
-
import { liteAdaptor } from "mathjax-full/js/adaptors/liteAdaptor.js";
|
|
11
|
-
import { LiteElement } from "mathjax-full/js/adaptors/lite/Element.js"; /* N */
|
|
12
|
-
import { RegisterHTMLHandler } from "mathjax-full/js/handlers/html.js";
|
|
13
|
-
import { TeX } from "mathjax-full/js/input/tex.js";
|
|
14
|
-
import { mathjax } from "mathjax-full/js/mathjax.js";
|
|
15
|
-
import { CHTML } from "mathjax-full/js/output/chtml.js";
|
|
16
|
-
import { AllPackages } from "mathjax-full/js/input/tex/AllPackages.js";
|
|
17
|
-
import { merge } from "lodash-es";
|
|
18
|
-
const MATHJAX_DEFAULT_FONT_URL = "https://cdn.jsdelivr.net/npm/mathjax-full@3/es5/output/chtml/fonts/woff-v2";
|
|
19
|
-
const defaultOption = {
|
|
20
|
-
inline: false,
|
|
21
|
-
em: 16,
|
|
22
|
-
ex: 8,
|
|
23
|
-
width: 80 * 16,
|
|
24
|
-
tex: {
|
|
25
|
-
packages: AllPackages,
|
|
26
|
-
},
|
|
27
|
-
chtml: {
|
|
28
|
-
scale: 1.21, // magic # chosen which look nice for me
|
|
29
|
-
fontURL: MATHJAX_DEFAULT_FONT_URL,
|
|
30
|
-
adaptiveCSS: true,
|
|
31
|
-
exFactor: 5,
|
|
32
|
-
},
|
|
33
|
-
};
|
|
34
|
-
/**
|
|
35
|
-
* Initialize and encapsulates mathjax instances to generate
|
|
36
|
-
* CommonHTML from TeX input.
|
|
37
|
-
*
|
|
38
|
-
* There are 2 important methods. One converts the input.
|
|
39
|
-
* The other returns a stylesheet document. The stylesheet must be included
|
|
40
|
-
* in your HTML document to render the equation properly.
|
|
41
|
-
*/
|
|
42
|
-
export class MathjaxEngine {
|
|
43
|
-
option;
|
|
44
|
-
adaptor;
|
|
45
|
-
tex;
|
|
46
|
-
chtml;
|
|
47
|
-
html;
|
|
48
|
-
constructor(option) {
|
|
49
|
-
this.option = merge({}, defaultOption, option);
|
|
50
|
-
if (typeof this.option.tex?.packages === "string") {
|
|
51
|
-
this.option.tex.packages = this.option.tex.packages.split(/\s*,\s*/);
|
|
52
|
-
}
|
|
53
|
-
this.adaptor = liteAdaptor();
|
|
54
|
-
RegisterHTMLHandler(this.adaptor);
|
|
55
|
-
const tex = new TeX(this.option.tex);
|
|
56
|
-
const chtml = new CHTML(this.option.chtml);
|
|
57
|
-
const html = mathjax.document("", {
|
|
58
|
-
InputJax: tex,
|
|
59
|
-
OutputJax: chtml,
|
|
60
|
-
});
|
|
61
|
-
html.addRenderAction("typeset", 155, renderDoc, renderMath);
|
|
62
|
-
this.tex = tex;
|
|
63
|
-
this.chtml = chtml;
|
|
64
|
-
this.html = html;
|
|
65
|
-
function renderDoc(_doc) { }
|
|
66
|
-
function renderMath(math, doc) {
|
|
67
|
-
const adaptor = doc.adaptor;
|
|
68
|
-
const text = adaptor.node("mjx-copytext", { "aria-hidden": true }, [
|
|
69
|
-
adaptor.text(math.math),
|
|
70
|
-
]);
|
|
71
|
-
adaptor.setStyle(text, "position", "absolute");
|
|
72
|
-
adaptor.setStyle(text, "display", "none");
|
|
73
|
-
adaptor.setStyle(text, "width", "0");
|
|
74
|
-
adaptor.setStyle(math.typesetRoot, "position", "relative");
|
|
75
|
-
adaptor.append(math.typesetRoot, text);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* convert TeX input to CHTML.
|
|
80
|
-
*
|
|
81
|
-
* @param tex input string
|
|
82
|
-
* @param override parameter to override the defaults, if you wish to
|
|
83
|
-
* @returns
|
|
84
|
-
*/
|
|
85
|
-
convert(tex, override) {
|
|
86
|
-
const node = this.html.convert(tex, {
|
|
87
|
-
display: !(override?.inline ?? this.option.inline),
|
|
88
|
-
em: override?.em ?? this.option.em,
|
|
89
|
-
ex: override?.ex ?? this.option.ex,
|
|
90
|
-
containerWidth: override?.width ?? this.option.width,
|
|
91
|
-
scale: 1.0,
|
|
92
|
-
});
|
|
93
|
-
if (node instanceof LiteElement) {
|
|
94
|
-
return this.adaptor.outerHTML(node);
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
return "ERROR";
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* returns adaptive css (stylesheet for the processed equations only),
|
|
102
|
-
* or the full mathjax css (if configured)
|
|
103
|
-
*
|
|
104
|
-
* @returns css content
|
|
105
|
-
*/
|
|
106
|
-
stylesheet() {
|
|
107
|
-
return this.adaptor.textContent(this.chtml.styleSheet(this.html));
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
//# sourceMappingURL=mathjax.js.map
|
package/dist/math/mdmath.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* mdmath.ts
|
|
3
|
-
*
|
|
4
|
-
* MarkdownIt extension for math equation processing
|
|
5
|
-
*/
|
|
6
|
-
import { PluginSimple } from "markdown-it";
|
|
7
|
-
import { MathjaxEngine } from "./mathjax.js";
|
|
8
|
-
/**
|
|
9
|
-
* returns a Markdown-It plugin
|
|
10
|
-
*
|
|
11
|
-
* @param math mathjax Engine to use
|
|
12
|
-
* @returns
|
|
13
|
-
*/
|
|
14
|
-
export declare function mdmath(math: MathjaxEngine): PluginSimple;
|
package/dist/math/mdmath.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* mdmath.ts
|
|
3
|
-
*
|
|
4
|
-
* MarkdownIt extension for math equation processing
|
|
5
|
-
*/
|
|
6
|
-
import katex from "katex";
|
|
7
|
-
import { math_block, math_inline } from "./mdparser.js";
|
|
8
|
-
/**
|
|
9
|
-
* Returns a MarkdownIt renderer to render inline/block TeX into HTML.
|
|
10
|
-
* `KaTeX` is used for inline math, `MathJax` is used for block math.
|
|
11
|
-
*
|
|
12
|
-
* @param mathjax mathjax engine (used for block math processing)
|
|
13
|
-
* @returns
|
|
14
|
-
*/
|
|
15
|
-
function getRenderers(mathjax) {
|
|
16
|
-
function renderInlineMath(tex) {
|
|
17
|
-
return katex.renderToString(tex, {
|
|
18
|
-
throwOnError: false,
|
|
19
|
-
strict: (code, _msg, _token) => {
|
|
20
|
-
switch (code) {
|
|
21
|
-
case "unicodeTextInMathMode":
|
|
22
|
-
return "ignore";
|
|
23
|
-
default:
|
|
24
|
-
return "warn";
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
function renderBlockMath(tex) {
|
|
30
|
-
try {
|
|
31
|
-
const math = mathjax.convert(tex);
|
|
32
|
-
return "<p>" + math + "</p>";
|
|
33
|
-
}
|
|
34
|
-
catch (err) {
|
|
35
|
-
console.error(err);
|
|
36
|
-
return tex;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
function inlineRenderer(tokens, index) {
|
|
40
|
-
return renderInlineMath(tokens[index].content);
|
|
41
|
-
}
|
|
42
|
-
function blockRenderer(tokens, index) {
|
|
43
|
-
return renderBlockMath(tokens[index].content + "\n");
|
|
44
|
-
}
|
|
45
|
-
return {
|
|
46
|
-
inlineRenderer,
|
|
47
|
-
blockRenderer,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* returns a Markdown-It plugin
|
|
52
|
-
*
|
|
53
|
-
* @param math mathjax Engine to use
|
|
54
|
-
* @returns
|
|
55
|
-
*/
|
|
56
|
-
export function mdmath(math) {
|
|
57
|
-
const renderer = getRenderers(math);
|
|
58
|
-
return (md) => {
|
|
59
|
-
md.inline.ruler.after("escape", "math_inline", math_inline);
|
|
60
|
-
md.block.ruler.after("blockquote", "math_block", math_block, {
|
|
61
|
-
alt: ["paragraph", "reference", "blockquote", "list"],
|
|
62
|
-
});
|
|
63
|
-
md.renderer.rules.math_inline = renderer.inlineRenderer;
|
|
64
|
-
md.renderer.rules.math_block = renderer.blockRenderer;
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
//# sourceMappingURL=mdmath.js.map
|
package/dist/math/mdparser.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* mdparser.ts
|
|
3
|
-
*
|
|
4
|
-
* provides methods to parse MarkdownIt token stream and extract math equations.
|
|
5
|
-
*/
|
|
6
|
-
import StateBlock from "markdown-it/lib/rules_block/state_block.mjs";
|
|
7
|
-
import StateInline from "markdown-it/lib/rules_inline/state_inline.mjs";
|
|
8
|
-
export declare function math_inline(state: StateInline, silent: boolean): boolean;
|
|
9
|
-
export declare function math_block(state: StateBlock, start: number, end: number, silent: boolean): boolean;
|
package/dist/math/mdparser.js
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* mdparser.ts
|
|
3
|
-
*
|
|
4
|
-
* provides methods to parse MarkdownIt token stream and extract math equations.
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Tests if potential opening or closing delimieter
|
|
8
|
-
* Assumes that there is a "$" at state.src[pos]
|
|
9
|
-
*/
|
|
10
|
-
function isValidDelim(state, pos) {
|
|
11
|
-
const max = state.posMax;
|
|
12
|
-
let can_open = true;
|
|
13
|
-
let can_close = true;
|
|
14
|
-
const prevChar = pos > 0 ? state.src.charCodeAt(pos - 1) : -1;
|
|
15
|
-
const nextChar = pos + 1 <= max ? state.src.charCodeAt(pos + 1) : -1;
|
|
16
|
-
// Check non-whitespace conditions for opening and closing, and
|
|
17
|
-
// check that closing delimeter isn't followed by a number
|
|
18
|
-
if (prevChar === 0x20 /* " " */ ||
|
|
19
|
-
prevChar === 0x09 /* \t */ ||
|
|
20
|
-
(nextChar >= 0x30 /* "0" */ && nextChar <= 0x39) /* "9" */) {
|
|
21
|
-
can_close = false;
|
|
22
|
-
}
|
|
23
|
-
if (nextChar === 0x20 /* " " */ || nextChar === 0x09 /* \t */) {
|
|
24
|
-
can_open = false;
|
|
25
|
-
}
|
|
26
|
-
return {
|
|
27
|
-
can_open: can_open,
|
|
28
|
-
can_close: can_close,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
export function math_inline(state, silent) {
|
|
32
|
-
let match, token, res, pos;
|
|
33
|
-
if (state.src[state.pos] !== "$") {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
res = isValidDelim(state, state.pos);
|
|
37
|
-
if (!res.can_open) {
|
|
38
|
-
if (!silent) {
|
|
39
|
-
state.pending += "$";
|
|
40
|
-
}
|
|
41
|
-
state.pos += 1;
|
|
42
|
-
return true;
|
|
43
|
-
}
|
|
44
|
-
// First check for and bypass all properly escaped delimieters
|
|
45
|
-
// This loop will assume that the first leading backtick can not
|
|
46
|
-
// be the first character in state.src, which is known since
|
|
47
|
-
// we have found an opening delimieter already.
|
|
48
|
-
const start = state.pos + 1;
|
|
49
|
-
match = start;
|
|
50
|
-
while ((match = state.src.indexOf("$", match)) !== -1) {
|
|
51
|
-
// Found potential $, look for escapes, pos will point to
|
|
52
|
-
// first non escape when complete
|
|
53
|
-
pos = match - 1;
|
|
54
|
-
while (state.src[pos] === "\\") {
|
|
55
|
-
pos -= 1;
|
|
56
|
-
}
|
|
57
|
-
// Even number of escapes, potential closing delimiter found
|
|
58
|
-
if ((match - pos) % 2 == 1) {
|
|
59
|
-
break;
|
|
60
|
-
}
|
|
61
|
-
match += 1;
|
|
62
|
-
}
|
|
63
|
-
// No closing delimter found. Consume $ and continue.
|
|
64
|
-
if (match === -1) {
|
|
65
|
-
if (!silent) {
|
|
66
|
-
state.pending += "$";
|
|
67
|
-
}
|
|
68
|
-
state.pos = start;
|
|
69
|
-
return true;
|
|
70
|
-
}
|
|
71
|
-
// Check if we have empty content, ie: $$. Do not parse.
|
|
72
|
-
if (match - start === 0) {
|
|
73
|
-
if (!silent) {
|
|
74
|
-
state.pending += "$$";
|
|
75
|
-
}
|
|
76
|
-
state.pos = start + 1;
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
79
|
-
// Check for valid closing delimiter
|
|
80
|
-
res = isValidDelim(state, match);
|
|
81
|
-
if (!res.can_close) {
|
|
82
|
-
if (!silent) {
|
|
83
|
-
state.pending += "$";
|
|
84
|
-
}
|
|
85
|
-
state.pos = start;
|
|
86
|
-
return true;
|
|
87
|
-
}
|
|
88
|
-
if (!silent) {
|
|
89
|
-
token = state.push("math_inline", "math", 0);
|
|
90
|
-
token.markup = "$";
|
|
91
|
-
token.content = state.src.slice(start, match);
|
|
92
|
-
}
|
|
93
|
-
state.pos = match + 1;
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
export function math_block(state, start, end, silent) {
|
|
97
|
-
let firstLine;
|
|
98
|
-
let lastLine;
|
|
99
|
-
let next;
|
|
100
|
-
let lastPos;
|
|
101
|
-
let found = false;
|
|
102
|
-
let pos = state.bMarks[start] + state.tShift[start];
|
|
103
|
-
let max = state.eMarks[start];
|
|
104
|
-
if (pos + 2 > max) {
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
if (state.src.slice(pos, pos + 2) !== "$$") {
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
pos += 2;
|
|
111
|
-
firstLine = state.src.slice(pos, max);
|
|
112
|
-
if (silent) {
|
|
113
|
-
return true;
|
|
114
|
-
}
|
|
115
|
-
if (firstLine.trim().slice(-2) === "$$") {
|
|
116
|
-
// Single line expression
|
|
117
|
-
firstLine = firstLine.trim().slice(0, -2);
|
|
118
|
-
found = true;
|
|
119
|
-
}
|
|
120
|
-
for (next = start; !found;) {
|
|
121
|
-
next++;
|
|
122
|
-
if (next >= end) {
|
|
123
|
-
break;
|
|
124
|
-
}
|
|
125
|
-
pos = state.bMarks[next] + state.tShift[next];
|
|
126
|
-
max = state.eMarks[next];
|
|
127
|
-
if (pos < max && state.tShift[next] < state.blkIndent) {
|
|
128
|
-
// non-empty line with negative indent should stop the list:
|
|
129
|
-
break;
|
|
130
|
-
}
|
|
131
|
-
if (state.src.slice(pos, max).trim().slice(-2) === "$$") {
|
|
132
|
-
lastPos = state.src.slice(0, max).lastIndexOf("$$");
|
|
133
|
-
lastLine = state.src.slice(pos, lastPos);
|
|
134
|
-
found = true;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
state.line = next + 1;
|
|
138
|
-
const token = state.push("math_block", "math", 0);
|
|
139
|
-
token.block = true;
|
|
140
|
-
token.content =
|
|
141
|
-
(firstLine && firstLine.trim() ? firstLine + "\n" : "") +
|
|
142
|
-
state.getLines(start + 1, next, state.tShift[start], true) +
|
|
143
|
-
(lastLine && lastLine.trim() ? lastLine : "");
|
|
144
|
-
token.map = [start, state.line];
|
|
145
|
-
token.markup = "$$";
|
|
146
|
-
return true;
|
|
147
|
-
}
|
|
148
|
-
//# sourceMappingURL=mdparser.js.map
|