@cobapen/markdown 0.4.1 → 0.4.2

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.
@@ -0,0 +1,8 @@
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
+ export declare function fence_custom(tokens: Token[], idx: number, options: Options, env: Env, slf: Renderer): string;
8
+ export {};
@@ -0,0 +1,41 @@
1
+ import { escapeHtml, unescapeAll } from "markdown-it/lib/common/utils.mjs";
2
+ import { InfoString } from "./info-string.js";
3
+ export function fence_custom(tokens, idx, options, env, slf) {
4
+ const token = tokens[idx];
5
+ const info_str = token.info ? unescapeAll(token.info).trim() : "";
6
+ const info = new InfoString(info_str);
7
+ const langName = info.lang;
8
+ const langAttrs = info.attrs.join(" ");
9
+ let highlighted;
10
+ if (options.highlight) {
11
+ highlighted = options.highlight(token.content, langName, langAttrs) || escapeHtml(token.content);
12
+ }
13
+ else {
14
+ highlighted = escapeHtml(token.content);
15
+ }
16
+ if (highlighted.indexOf("<pre") === 0) {
17
+ return highlighted + "\n";
18
+ }
19
+ if (info.hasLang) {
20
+ const i = token.attrIndex("class");
21
+ const tmpAttrs = token.attrs ? token.attrs.slice() : [];
22
+ if (i < 0) {
23
+ tmpAttrs.push(["class", options.langPrefix + langName]);
24
+ }
25
+ else {
26
+ tmpAttrs[i] = tmpAttrs[i].slice();
27
+ tmpAttrs[i][1] += " " + options.langPrefix + langName;
28
+ }
29
+ const tmpToken = {
30
+ attrs: tmpAttrs
31
+ };
32
+ if (info.title.length > 0) {
33
+ const style = (env.showCodeTitleByDefault === true)
34
+ ? ""
35
+ : " style=\"visibility:hidden;\"";
36
+ return `<pre><code${slf.renderAttrs(tmpToken)}>${highlighted}</code><span class="title"${style}>${info.title}</span></pre>\n`;
37
+ }
38
+ return `<pre><code${slf.renderAttrs(tmpToken)}>${highlighted}</code></pre>\n`;
39
+ }
40
+ return `<pre><code${slf.renderAttrs(token)}>${highlighted}</code></pre>\n`;
41
+ }
@@ -0,0 +1,2 @@
1
+ export declare function highlightWithLineNumber(code: string, lang: string, linestart?: number): string;
2
+ export declare function highlighterForMarkdownIt(str: string, lang: string, attrs: string): string;
@@ -0,0 +1,45 @@
1
+ import hljs from "highlight.js";
2
+ import { InfoString } from "./info-string.js";
3
+ function _debuglog(..._args) {
4
+ }
5
+ function numDigits(n) {
6
+ return Math.floor(n).toString().length;
7
+ }
8
+ function niceDec(n) {
9
+ return n.toFixed(3);
10
+ }
11
+ export function highlightWithLineNumber(code, lang, linestart) {
12
+ try {
13
+ if (lang && hljs.getLanguage(lang)) {
14
+ let htmlLines = hljs.highlight(code, { language: lang }).value;
15
+ if (linestart !== undefined) {
16
+ const lines = htmlLines.split("\n");
17
+ const elWidth = numDigits(linestart + lines.length) * 0.8;
18
+ const elStyle = "display:inline-block;" +
19
+ "user-select:none;" +
20
+ `width: ${niceDec(elWidth)}em;`;
21
+ lines.forEach((line, i, lines) => {
22
+ lines[i] =
23
+ "<div class=\"line\">" +
24
+ `<span class="line-no" style="${elStyle}">${linestart + i}</span>${line}` +
25
+ "</div>";
26
+ });
27
+ _debuglog(lines);
28
+ htmlLines = lines.join("");
29
+ }
30
+ return htmlLines;
31
+ }
32
+ else {
33
+ return "";
34
+ }
35
+ }
36
+ catch (_) {
37
+ return "";
38
+ }
39
+ }
40
+ export function highlighterForMarkdownIt(str, lang, attrs) {
41
+ _debuglog(lang ? lang : "(lang is empty or undefined)");
42
+ const info = new InfoString(lang + " " + attrs);
43
+ _debuglog(info);
44
+ return highlightWithLineNumber(str, info.lang, info.linestart);
45
+ }
@@ -0,0 +1,19 @@
1
+ export declare class InfoString {
2
+ private readonly _lang;
3
+ private readonly _attrs;
4
+ private readonly _title;
5
+ private readonly _linestart;
6
+ constructor(info: string);
7
+ get lang(): string;
8
+ get attrs(): string[];
9
+ get title(): string;
10
+ get linestart(): number | undefined;
11
+ get hasLang(): boolean;
12
+ static parseInfoString(info: string): string[];
13
+ static parseMetaNotation(text: string): {
14
+ filename: string;
15
+ line: number;
16
+ } | undefined;
17
+ static getTitle(attr: string[]): string;
18
+ static getLineStart(attr: string[]): number | undefined;
19
+ }
@@ -0,0 +1,100 @@
1
+ export class InfoString {
2
+ _lang;
3
+ _attrs;
4
+ _title;
5
+ _linestart;
6
+ constructor(info) {
7
+ if (info.length > 0) {
8
+ const arr = InfoString.parseInfoString(info);
9
+ this._lang = arr[0];
10
+ this._attrs = arr.slice(1);
11
+ this._title = InfoString.getTitle(this._attrs);
12
+ this._linestart = InfoString.getLineStart(this._attrs);
13
+ }
14
+ else {
15
+ this._lang = "";
16
+ this._attrs = [];
17
+ this._title = "";
18
+ this._linestart = undefined;
19
+ }
20
+ }
21
+ get lang() {
22
+ return this._lang;
23
+ }
24
+ get attrs() {
25
+ return this._attrs;
26
+ }
27
+ get title() {
28
+ return this._title;
29
+ }
30
+ get linestart() {
31
+ return this._linestart;
32
+ }
33
+ get hasLang() {
34
+ return this._lang.length > 0;
35
+ }
36
+ static parseInfoString(info) {
37
+ const dq = "[^\"\\\\]*(?:\\\\.|[^\"\\\\]*)*";
38
+ const sq = "[^\'\\\\]*(?:\\\\.|[^\'\\\\]*)*";
39
+ const ptn = `([^\\s]+=)?(?:"(${dq})"|'(${sq})'|([^\\s]+))`;
40
+ const regex = new RegExp(ptn, "g");
41
+ const result = [];
42
+ let match;
43
+ while ((match = regex.exec(info)) !== null) {
44
+ let text = (match[1] || "") + (match[2] || match[3] || match[4] || "");
45
+ text = unescape(text).trim();
46
+ result.push(text);
47
+ }
48
+ return result;
49
+ }
50
+ static parseMetaNotation(text) {
51
+ const match = text.match(/^\{\s*([^:]+):(\d+)\s*\}$/);
52
+ if (match) {
53
+ return {
54
+ filename: match[1],
55
+ line: parseInt(match[2], 10),
56
+ };
57
+ }
58
+ return undefined;
59
+ }
60
+ static getTitle(attr) {
61
+ const titleAttr = attr.find(x => x.startsWith("title=")) ?? "";
62
+ if (titleAttr.length > 0) {
63
+ const match = titleAttr.match(/^title=(.*)$/);
64
+ if (match) {
65
+ let value = match[1].trim();
66
+ if (value.startsWith("\"") && value.endsWith("\"")) {
67
+ value = value.slice(1, -1);
68
+ value = unescape(value).trim();
69
+ }
70
+ return value;
71
+ }
72
+ else {
73
+ throw new Error("Must not fail. Check impl.");
74
+ }
75
+ }
76
+ if (attr.length > 0) {
77
+ const meta = InfoString.parseMetaNotation(attr[0]);
78
+ if (meta && meta.filename.length > 0) {
79
+ return meta.filename;
80
+ }
81
+ }
82
+ return "";
83
+ }
84
+ static getLineStart(attr) {
85
+ const lineAttr = attr.find(x => x.startsWith("linestart=")) ?? "";
86
+ if (lineAttr.length > 0) {
87
+ return parseInt(lineAttr.split("=")[1].trim());
88
+ }
89
+ if (attr.length > 0) {
90
+ const meta = InfoString.parseMetaNotation(attr[0]);
91
+ if (meta && meta.line > 0) {
92
+ return meta.line;
93
+ }
94
+ }
95
+ return undefined;
96
+ }
97
+ }
98
+ function unescape(text) {
99
+ return text.replaceAll(/\\\"/g, "\"").replaceAll(/\\\'/g, "'");
100
+ }
package/lib/index.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ import markdownIt, { Options as MarkdownOptions } from "markdown-it";
2
+ import { Options as MathOptions } from "./math/mathjax.js";
3
+ export interface Config {
4
+ showCodeTitleByDefault: boolean;
5
+ markdown: Partial<MarkdownOptions>;
6
+ math: Partial<MathOptions>;
7
+ }
8
+ export type Options = Partial<Config>;
9
+ export declare class CMarkdown {
10
+ private readonly _config;
11
+ private readonly _mj;
12
+ private readonly _md;
13
+ constructor(option?: Options);
14
+ setup(md: markdownIt): void;
15
+ render(text: string): string;
16
+ mathcss(): string;
17
+ }
package/lib/index.js ADDED
@@ -0,0 +1,61 @@
1
+ import markdownIt from "markdown-it";
2
+ import advTable from "markdown-it-adv-table";
3
+ import anchor from "markdown-it-anchor";
4
+ import cjkbreaks from "markdown-it-cjk-breaks";
5
+ import deflist from "markdown-it-deflist";
6
+ import footnote from "markdown-it-footnote";
7
+ import toc from "markdown-it-table-of-contents";
8
+ import { fence_custom } from "./code/fence-custom.js";
9
+ import { highlighterForMarkdownIt } from "./code/highlight.js";
10
+ import { replacelink } from "./link/replacelink.js";
11
+ import { MathjaxEngine } from "./math/mathjax.js";
12
+ import { mdmath } from "./math/mdmath.js";
13
+ const defaultOptions = {
14
+ showCodeTitleByDefault: false,
15
+ markdown: {
16
+ html: true,
17
+ linkify: true,
18
+ highlight: highlighterForMarkdownIt,
19
+ },
20
+ math: {
21
+ tex: {
22
+ macros: {
23
+ bm: ["\\boldsymbol{#1}", 1],
24
+ },
25
+ },
26
+ }
27
+ };
28
+ export class CMarkdown {
29
+ _config;
30
+ _mj;
31
+ _md;
32
+ constructor(option) {
33
+ const config = { ...defaultOptions, ...option };
34
+ const mj = new MathjaxEngine(config.math);
35
+ const md = markdownIt(config.markdown);
36
+ this._config = config;
37
+ this._mj = mj;
38
+ this._md = md;
39
+ this.setup(md);
40
+ }
41
+ setup(md) {
42
+ md.renderer.rules.fence = fence_custom;
43
+ md.use(anchor)
44
+ .use(cjkbreaks)
45
+ .use(footnote)
46
+ .use(deflist)
47
+ .use(replacelink)
48
+ .use(advTable)
49
+ .use(mdmath(this._mj))
50
+ .use(toc, {
51
+ includeLevel: [2, 3],
52
+ });
53
+ }
54
+ render(text) {
55
+ const env = { ...this._config };
56
+ return this._md.render(text, env);
57
+ }
58
+ mathcss() {
59
+ return this._mj.stylesheet();
60
+ }
61
+ }
@@ -0,0 +1,8 @@
1
+ import type { PluginWithOptions } from "markdown-it";
2
+ import type 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;
@@ -0,0 +1,39 @@
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;
@@ -0,0 +1,67 @@
1
+ import { type LiteDocument } from "mathjax-full/js/adaptors/lite/Document.js";
2
+ import { LiteElement } from "mathjax-full/js/adaptors/lite/Element.js";
3
+ import { type LiteText } from "mathjax-full/js/adaptors/lite/Text.js";
4
+ import { type LiteAdaptor } from "mathjax-full/js/adaptors/liteAdaptor.js";
5
+ import { type MathDocument } from "mathjax-full/js/core/MathDocument.js";
6
+ import { TeX } from "mathjax-full/js/input/tex.js";
7
+ import { CHTML } from "mathjax-full/js/output/chtml.js";
8
+ type N = LiteElement;
9
+ type T = LiteText;
10
+ type D = LiteDocument;
11
+ interface AnyObject {
12
+ [x: string]: any;
13
+ }
14
+ interface TexConfig {
15
+ packages: string | [string] | AnyObject;
16
+ inlineMath: [[string, string]];
17
+ displayMath: [[string, string]];
18
+ processEscapes: boolean;
19
+ processEnvironments: boolean;
20
+ processRefs: boolean;
21
+ digits: RegExp;
22
+ tags: string;
23
+ tagSide: string;
24
+ tagIndent: string;
25
+ useLabelIds: boolean;
26
+ multlineWidth: string;
27
+ maxMacros: number;
28
+ maxBuffer: number;
29
+ baseURL: string;
30
+ formatError: (jax: object, err: Error) => void;
31
+ macros: AnyObject;
32
+ }
33
+ interface CHTMLConfig {
34
+ scale: number;
35
+ minScale: number;
36
+ matchFontHeight: boolean;
37
+ mtextInheritFont: boolean;
38
+ merrorInheritFont: boolean;
39
+ mtextFont: string;
40
+ merrorFont: string;
41
+ mathmlspacing: boolean;
42
+ skipAttributes: AnyObject;
43
+ exFactor: number;
44
+ displayAlign: string;
45
+ displayIndent: number | string;
46
+ fontURL: string;
47
+ adaptiveCSS: boolean;
48
+ }
49
+ export interface Options {
50
+ inline: boolean;
51
+ em: number;
52
+ ex: number;
53
+ width: number;
54
+ tex?: Partial<TexConfig>;
55
+ chtml?: Partial<CHTMLConfig>;
56
+ }
57
+ export declare class MathjaxEngine {
58
+ option: Options;
59
+ adaptor: LiteAdaptor;
60
+ tex: TeX<N, T, D>;
61
+ chtml: CHTML<N, T, D>;
62
+ html: MathDocument<N, T, D>;
63
+ constructor(option?: Partial<Options>);
64
+ convert(tex: string, override?: Partial<Options>): string;
65
+ stylesheet(): string;
66
+ }
67
+ export {};
@@ -0,0 +1,79 @@
1
+ import { merge } from "lodash-es";
2
+ import { LiteElement } from "mathjax-full/js/adaptors/lite/Element.js";
3
+ import { liteAdaptor } from "mathjax-full/js/adaptors/liteAdaptor.js";
4
+ import { RegisterHTMLHandler } from "mathjax-full/js/handlers/html.js";
5
+ import { AllPackages } from "mathjax-full/js/input/tex/AllPackages.js";
6
+ import { TeX } from "mathjax-full/js/input/tex.js";
7
+ import { mathjax } from "mathjax-full/js/mathjax.js";
8
+ import { CHTML } from "mathjax-full/js/output/chtml.js";
9
+ const MATHJAX_DEFAULT_FONT_URL = "https://cdn.jsdelivr.net/npm/mathjax-full@3/es5/output/chtml/fonts/woff-v2";
10
+ const defaultOption = {
11
+ inline: false,
12
+ em: 16,
13
+ ex: 8,
14
+ width: 80 * 16,
15
+ tex: {
16
+ packages: AllPackages,
17
+ },
18
+ chtml: {
19
+ scale: 1.21,
20
+ fontURL: MATHJAX_DEFAULT_FONT_URL,
21
+ adaptiveCSS: true,
22
+ exFactor: 5,
23
+ },
24
+ };
25
+ export class MathjaxEngine {
26
+ option;
27
+ adaptor;
28
+ tex;
29
+ chtml;
30
+ html;
31
+ constructor(option) {
32
+ this.option = merge({}, defaultOption, option);
33
+ if (typeof this.option.tex?.packages === "string") {
34
+ this.option.tex.packages = this.option.tex.packages.split(/\s*,\s*/);
35
+ }
36
+ this.adaptor = liteAdaptor();
37
+ RegisterHTMLHandler(this.adaptor);
38
+ const tex = new TeX(this.option.tex);
39
+ const chtml = new CHTML(this.option.chtml);
40
+ const html = mathjax.document("", {
41
+ InputJax: tex,
42
+ OutputJax: chtml,
43
+ });
44
+ html.addRenderAction("typeset", 155, renderDoc, renderMath);
45
+ this.tex = tex;
46
+ this.chtml = chtml;
47
+ this.html = html;
48
+ function renderDoc(_doc) { }
49
+ function renderMath(math, doc) {
50
+ const adaptor = doc.adaptor;
51
+ const text = adaptor.node("mjx-copytext", { "aria-hidden": true }, [
52
+ adaptor.text(math.math),
53
+ ]);
54
+ adaptor.setStyle(text, "position", "absolute");
55
+ adaptor.setStyle(text, "display", "none");
56
+ adaptor.setStyle(text, "width", "0");
57
+ adaptor.setStyle(math.typesetRoot, "position", "relative");
58
+ adaptor.append(math.typesetRoot, text);
59
+ }
60
+ }
61
+ convert(tex, override) {
62
+ const node = this.html.convert(tex, {
63
+ display: !(override?.inline ?? this.option.inline),
64
+ em: override?.em ?? this.option.em,
65
+ ex: override?.ex ?? this.option.ex,
66
+ containerWidth: override?.width ?? this.option.width,
67
+ scale: 1.0,
68
+ });
69
+ if (node instanceof LiteElement) {
70
+ return this.adaptor.outerHTML(node);
71
+ }
72
+ else {
73
+ return "ERROR";
74
+ }
75
+ }
76
+ stylesheet() {
77
+ return this.adaptor.textContent(this.chtml.styleSheet(this.html));
78
+ }
79
+ }
@@ -0,0 +1,3 @@
1
+ import type { PluginSimple } from "markdown-it";
2
+ import { MathjaxEngine } from "./mathjax.js";
3
+ export declare function mdmath(math: MathjaxEngine): PluginSimple;
@@ -0,0 +1,48 @@
1
+ import katex from "katex";
2
+ import { math_block, math_inline } from "./mdparser.js";
3
+ function getRenderers(mathjax) {
4
+ function renderInlineMath(tex) {
5
+ return katex.renderToString(tex, {
6
+ throwOnError: false,
7
+ strict: (code, _msg, _token) => {
8
+ switch (code) {
9
+ case "unicodeTextInMathMode":
10
+ return "ignore";
11
+ default:
12
+ return "warn";
13
+ }
14
+ },
15
+ });
16
+ }
17
+ function renderBlockMath(tex) {
18
+ try {
19
+ const math = mathjax.convert(tex);
20
+ return "<p>" + math + "</p>";
21
+ }
22
+ catch (err) {
23
+ console.error(err);
24
+ return tex;
25
+ }
26
+ }
27
+ function inlineRenderer(tokens, index) {
28
+ return renderInlineMath(tokens[index].content);
29
+ }
30
+ function blockRenderer(tokens, index) {
31
+ return renderBlockMath(tokens[index].content + "\n");
32
+ }
33
+ return {
34
+ inlineRenderer,
35
+ blockRenderer,
36
+ };
37
+ }
38
+ export function mdmath(math) {
39
+ const renderer = getRenderers(math);
40
+ return (md) => {
41
+ md.inline.ruler.after("escape", "math_inline", math_inline);
42
+ md.block.ruler.after("blockquote", "math_block", math_block, {
43
+ alt: ["paragraph", "reference", "blockquote", "list"],
44
+ });
45
+ md.renderer.rules.math_inline = renderer.inlineRenderer;
46
+ md.renderer.rules.math_block = renderer.blockRenderer;
47
+ };
48
+ }
@@ -0,0 +1,4 @@
1
+ import StateBlock from "markdown-it/lib/rules_block/state_block.mjs";
2
+ import StateInline from "markdown-it/lib/rules_inline/state_inline.mjs";
3
+ export declare function math_inline(state: StateInline, silent: boolean): boolean;
4
+ export declare function math_block(state: StateBlock, start: number, end: number, silent: boolean): boolean;
@@ -0,0 +1,124 @@
1
+ function isValidDelim(state, pos) {
2
+ const max = state.posMax;
3
+ let can_open = true;
4
+ let can_close = true;
5
+ const prevChar = pos > 0 ? state.src.charCodeAt(pos - 1) : -1;
6
+ const nextChar = pos + 1 <= max ? state.src.charCodeAt(pos + 1) : -1;
7
+ if (prevChar === 0x20 ||
8
+ prevChar === 0x09 ||
9
+ (nextChar >= 0x30 && nextChar <= 0x39)) {
10
+ can_close = false;
11
+ }
12
+ if (nextChar === 0x20 || nextChar === 0x09) {
13
+ can_open = false;
14
+ }
15
+ return {
16
+ can_open: can_open,
17
+ can_close: can_close,
18
+ };
19
+ }
20
+ export function math_inline(state, silent) {
21
+ let match, token, res, pos;
22
+ if (state.src[state.pos] !== "$") {
23
+ return false;
24
+ }
25
+ res = isValidDelim(state, state.pos);
26
+ if (!res.can_open) {
27
+ if (!silent) {
28
+ state.pending += "$";
29
+ }
30
+ state.pos += 1;
31
+ return true;
32
+ }
33
+ const start = state.pos + 1;
34
+ match = start;
35
+ while ((match = state.src.indexOf("$", match)) !== -1) {
36
+ pos = match - 1;
37
+ while (state.src[pos] === "\\") {
38
+ pos -= 1;
39
+ }
40
+ if ((match - pos) % 2 == 1) {
41
+ break;
42
+ }
43
+ match += 1;
44
+ }
45
+ if (match === -1) {
46
+ if (!silent) {
47
+ state.pending += "$";
48
+ }
49
+ state.pos = start;
50
+ return true;
51
+ }
52
+ if (match - start === 0) {
53
+ if (!silent) {
54
+ state.pending += "$$";
55
+ }
56
+ state.pos = start + 1;
57
+ return true;
58
+ }
59
+ res = isValidDelim(state, match);
60
+ if (!res.can_close) {
61
+ if (!silent) {
62
+ state.pending += "$";
63
+ }
64
+ state.pos = start;
65
+ return true;
66
+ }
67
+ if (!silent) {
68
+ token = state.push("math_inline", "math", 0);
69
+ token.markup = "$";
70
+ token.content = state.src.slice(start, match);
71
+ }
72
+ state.pos = match + 1;
73
+ return true;
74
+ }
75
+ export function math_block(state, start, end, silent) {
76
+ let firstLine;
77
+ let lastLine;
78
+ let next;
79
+ let lastPos;
80
+ let found = false;
81
+ let pos = state.bMarks[start] + state.tShift[start];
82
+ let max = state.eMarks[start];
83
+ if (pos + 2 > max) {
84
+ return false;
85
+ }
86
+ if (state.src.slice(pos, pos + 2) !== "$$") {
87
+ return false;
88
+ }
89
+ pos += 2;
90
+ firstLine = state.src.slice(pos, max);
91
+ if (silent) {
92
+ return true;
93
+ }
94
+ if (firstLine.trim().slice(-2) === "$$") {
95
+ firstLine = firstLine.trim().slice(0, -2);
96
+ found = true;
97
+ }
98
+ for (next = start; !found;) {
99
+ next++;
100
+ if (next >= end) {
101
+ break;
102
+ }
103
+ pos = state.bMarks[next] + state.tShift[next];
104
+ max = state.eMarks[next];
105
+ if (pos < max && state.tShift[next] < state.blkIndent) {
106
+ break;
107
+ }
108
+ if (state.src.slice(pos, max).trim().slice(-2) === "$$") {
109
+ lastPos = state.src.slice(0, max).lastIndexOf("$$");
110
+ lastLine = state.src.slice(pos, lastPos);
111
+ found = true;
112
+ }
113
+ }
114
+ state.line = next + 1;
115
+ const token = state.push("math_block", "math", 0);
116
+ token.block = true;
117
+ token.content =
118
+ (firstLine && firstLine.trim() ? firstLine + "\n" : "") +
119
+ state.getLines(start + 1, next, state.tShift[start], true) +
120
+ (lastLine && lastLine.trim() ? lastLine : "");
121
+ token.map = [start, state.line];
122
+ token.markup = "$$";
123
+ return true;
124
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cobapen/markdown",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "A markdown converter for cobapen website",
5
5
  "keywords": [
6
6
  "markdown"
@@ -8,8 +8,8 @@
8
8
  "license": "MIT",
9
9
  "author": "yamavol",
10
10
  "type": "module",
11
- "main": "dist/index.js",
12
- "types": "dist/index.d.ts",
11
+ "main": "lib/index.js",
12
+ "types": "lib/index.d.ts",
13
13
  "homepage": "https://github.com/cobapen/markdown#readme",
14
14
  "bugs": {
15
15
  "url": "https://github.com/cobapen/markdown/issues"
@@ -19,8 +19,8 @@
19
19
  "url": "git+https://github.com/cobapen/markdown.git"
20
20
  },
21
21
  "files": [
22
- "dist/**/*.js",
23
- "dist/**/*.d.ts"
22
+ "lib/**/*.js",
23
+ "lib/**/*.d.ts"
24
24
  ],
25
25
  "engines": {
26
26
  "node": ">=20.11.0 <21 || >=21.2.0"