@cobapen/markdown 0.7.0 → 0.8.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/lib/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import { Options as MathOptions } from "@cobapen/math";
2
2
  import markdownIt, { Options as MarkdownOptions } from "markdown-it";
3
- import { ReplaceHandler } from "./link/replacelink.js";
3
+ import { RewriteHandler } from "./plugins/rewritelink.js";
4
4
  export interface Config {
5
5
  showCodeTitleByDefault: boolean;
6
- linkRewrite?: ReplaceHandler;
6
+ rewriteLink?: RewriteHandler;
7
+ tocLevel: number | [number, number];
7
8
  markdown: Partial<MarkdownOptions>;
8
9
  math: Partial<MathOptions>;
9
10
  }
package/lib/index.js CHANGED
@@ -5,11 +5,12 @@ import anchor from "markdown-it-anchor";
5
5
  import deflist from "markdown-it-deflist";
6
6
  import footnote from "markdown-it-footnote";
7
7
  import toc from "markdown-it-table-of-contents";
8
- import { cjk_break } from "./cjk-break/cjk-break.js";
9
- import { fence_custom } from "./code/fence-custom.js";
10
- import { highlighterForMarkdownIt } from "./code/highlight.js";
11
- import { replacelink } from "./link/replacelink.js";
12
- import { mdmath } from "./math/mdmath.js";
8
+ import { cjk_break } from "./plugins/cjk-break.js";
9
+ import { fence_custom } from "./plugins/code/fence-custom.js";
10
+ import { highlighterForMarkdownIt } from "./plugins/code/highlight.js";
11
+ import { mdmath } from "./plugins/math/mdmath.js";
12
+ import { mermaidPlugin } from "./plugins/mermaid.js";
13
+ import { rewritelink } from "./plugins/rewritelink.js";
13
14
  await MathJaxEngine.loadExtensions();
14
15
  const defaultOptions = {
15
16
  showCodeTitleByDefault: false,
@@ -18,6 +19,7 @@ const defaultOptions = {
18
19
  linkify: true,
19
20
  highlight: highlighterForMarkdownIt,
20
21
  },
22
+ tocLevel: [2, 3],
21
23
  math: {
22
24
  output: {
23
25
  font: "mathjax-newcm"
@@ -48,13 +50,15 @@ export class CMarkdown {
48
50
  .use(cjk_break)
49
51
  .use(footnote)
50
52
  .use(deflist)
51
- .use(replacelink, {
52
- replace: this._config.linkRewrite,
53
+ .use(rewritelink, {
54
+ rewrite: this._config.rewriteLink,
53
55
  })
54
56
  .use(advTable)
55
57
  .use(mdmath(this._mj))
58
+ .use(mermaidPlugin)
56
59
  .use(toc, {
57
- includeLevel: [2, 3],
60
+ markderPattern: /^\[\[(toc|_toc_)\]\]/im,
61
+ includeLevel: fmtTocLevel(this._config.tocLevel),
58
62
  });
59
63
  }
60
64
  render(text, opt) {
@@ -65,3 +69,11 @@ export class CMarkdown {
65
69
  return this._mj.stylesheet();
66
70
  }
67
71
  }
72
+ function fmtTocLevel(level) {
73
+ if (typeof level === "number") {
74
+ return [2, Math.max(2, level)];
75
+ }
76
+ else {
77
+ return level;
78
+ }
79
+ }
package/lib/merge.d.ts ADDED
@@ -0,0 +1,37 @@
1
+ type Primitive = string | number | boolean | symbol | bigint | null | undefined;
2
+ export type DeepPartial<T> = {
3
+ [P in keyof T]?: T[P] extends Array<infer U> ? Array<DeepPartial<U>> : T[P] extends object ? T[P] extends Function ? T[P] : DeepPartial<T[P]> : T[P];
4
+ };
5
+ type BuiltinObject = Date | RegExp | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any> | Promise<any> | Error | ArrayBuffer | DataView | Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
6
+ type IsPlainObject<T> = T extends object ? T extends BuiltinObject ? false : T extends Function ? false : T extends readonly any[] ? false : true : false;
7
+ type NonUndefined<T> = Exclude<T, undefined>;
8
+ type DeepMergeProp<TValue, UValue> = [
9
+ NonUndefined<UValue>
10
+ ] extends [never] ? TValue : IsPlainObject<TValue> extends true ? IsPlainObject<NonUndefined<UValue>> extends true ? DeepMerged<TValue, NonUndefined<UValue>> : NonUndefined<UValue> : NonUndefined<UValue>;
11
+ type DeepMergedObject<T extends object, U extends object> = {
12
+ [K in keyof T | keyof U]: K extends keyof U ? K extends keyof T ? DeepMergeProp<T[K], U[K]> : U[K] : K extends keyof T ? T[K] : never;
13
+ };
14
+ type DeepMerged<T, U> = [
15
+ U
16
+ ] extends [undefined] ? T : U extends Primitive ? U : U extends Function ? U : U extends BuiltinObject ? U : U extends ReadonlyArray<infer UItem> ? T extends ReadonlyArray<infer TItem> ? Array<DeepMerged<TItem, UItem>> : Array<DeepMerged<unknown, UItem>> : U extends Map<infer UKey, infer UValue> ? T extends Map<infer TKey, infer TValue> ? Map<UKey | TKey, DeepMerged<TValue, UValue>> : Map<UKey, UValue> : U extends Set<infer UItem> ? T extends Set<infer TItem> ? Set<UItem | TItem> : Set<UItem> : IsPlainObject<U> extends true ? IsPlainObject<T> extends true ? DeepMergedObject<T & object, U & object> : U : U;
17
+ export declare function isPrimitive(value: unknown): value is Primitive;
18
+ export declare function isFunction(value: unknown): value is Function;
19
+ export declare function isObject(value: unknown): value is object;
20
+ export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
21
+ export type ArrayMergeStrategy = "replace" | "concat" | "merge" | "deepmerge" | "atomic";
22
+ export type MapMergeStrategy = "atomic" | "merge" | "deepmerge";
23
+ export type SetMergeStrategy = "atomic" | "merge";
24
+ export interface MergeOptions {
25
+ array?: ArrayMergeStrategy;
26
+ map?: MapMergeStrategy;
27
+ set?: SetMergeStrategy;
28
+ }
29
+ export declare function merge<T, U>(target: Partial<T>, source?: Partial<U>, options?: MergeOptions): DeepMerged<T, U>;
30
+ export interface CloneOptions {
31
+ array?: boolean;
32
+ map?: boolean;
33
+ set?: boolean;
34
+ buffer?: boolean;
35
+ }
36
+ export declare function clone<T>(source: T, options?: CloneOptions): T;
37
+ export {};
package/lib/merge.js ADDED
@@ -0,0 +1,289 @@
1
+ export function isPrimitive(value) {
2
+ return (value === null
3
+ || typeof value === "string"
4
+ || typeof value === "number"
5
+ || typeof value === "boolean"
6
+ || typeof value === "symbol"
7
+ || typeof value === "bigint"
8
+ || typeof value === "undefined");
9
+ }
10
+ export function isFunction(value) {
11
+ return typeof value === "function";
12
+ }
13
+ export function isObject(value) {
14
+ return typeof value === "object" && value !== null;
15
+ }
16
+ export function isPlainObject(value) {
17
+ if (!isObject(value)) {
18
+ return false;
19
+ }
20
+ const proto = Object.getPrototypeOf(value);
21
+ return proto === Object.prototype || proto === null;
22
+ }
23
+ export function merge(target, source, options) {
24
+ const seen = new WeakMap();
25
+ const arrayStrategy = options?.array ?? "replace";
26
+ const mapStrategy = options?.map ?? "atomic";
27
+ const setStrategy = options?.set ?? "atomic";
28
+ function _merge(target, source) {
29
+ if (isPrimitive(source) || isFunction(source)) {
30
+ return source;
31
+ }
32
+ else if (!isObject(source)) {
33
+ throw new Error("never");
34
+ }
35
+ else if (seen.has(source)) {
36
+ return seen.get(source);
37
+ }
38
+ else if (Array.isArray(source)) {
39
+ const srcArray = source;
40
+ const dstArray = Array.isArray(target) ? target : [];
41
+ switch (arrayStrategy) {
42
+ case "atomic": {
43
+ return source;
44
+ }
45
+ case "concat": {
46
+ const result = [];
47
+ seen.set(source, result);
48
+ for (const item of dstArray) {
49
+ result.push(_merge(undefined, item));
50
+ }
51
+ for (const item of srcArray) {
52
+ result.push(_merge(undefined, item));
53
+ }
54
+ return result;
55
+ }
56
+ case "merge": {
57
+ const result = [];
58
+ seen.set(source, result);
59
+ for (const item of dstArray) {
60
+ result.push(_merge(undefined, item));
61
+ }
62
+ for (let i = 0; i < srcArray.length; i++) {
63
+ if (srcArray[i] !== undefined) {
64
+ result[i] = _merge(undefined, srcArray[i]);
65
+ }
66
+ }
67
+ return result;
68
+ }
69
+ case "deepmerge": {
70
+ const result = [];
71
+ seen.set(source, result);
72
+ for (const item of dstArray) {
73
+ result.push(_merge(undefined, item));
74
+ }
75
+ for (let i = 0; i < srcArray.length; i++) {
76
+ const merged = _merge(result[i], srcArray[i]);
77
+ if (merged !== undefined) {
78
+ result[i] = merged;
79
+ }
80
+ }
81
+ return result;
82
+ }
83
+ case "replace":
84
+ default: {
85
+ const result = [];
86
+ seen.set(source, result);
87
+ for (const item of srcArray) {
88
+ result.push(_merge(undefined, item));
89
+ }
90
+ return result;
91
+ }
92
+ }
93
+ }
94
+ else if (isPlainObject(source)) {
95
+ const targetIsPlain = isPlainObject(target);
96
+ const resultProto = targetIsPlain
97
+ ? Object.getPrototypeOf(target)
98
+ : Object.getPrototypeOf(source);
99
+ const result = Object.create(resultProto);
100
+ if (targetIsPlain) {
101
+ Object.assign(result, target);
102
+ }
103
+ seen.set(source, result);
104
+ for (const key of Object.keys(source)) {
105
+ if (key === "__proto__" || key === "constructor" || key === "prototype") {
106
+ continue;
107
+ }
108
+ const value = source[key];
109
+ const merged = _merge(result[key], value);
110
+ if (merged !== undefined) {
111
+ result[key] = merged;
112
+ }
113
+ }
114
+ return result;
115
+ }
116
+ else if (source instanceof Map) {
117
+ const srcMap = source;
118
+ const dstMap = target instanceof Map ? target : undefined;
119
+ switch (mapStrategy) {
120
+ case "deepmerge": {
121
+ const result = new Map();
122
+ seen.set(source, result);
123
+ if (dstMap) {
124
+ for (const [key, value] of dstMap) {
125
+ result.set(key, value);
126
+ }
127
+ }
128
+ for (const [key, value] of srcMap) {
129
+ if (value === undefined) {
130
+ continue;
131
+ }
132
+ const merged = _merge(result.get(key), value);
133
+ if (merged !== undefined) {
134
+ result.set(key, merged);
135
+ }
136
+ }
137
+ return result;
138
+ }
139
+ case "merge": {
140
+ const result = new Map();
141
+ seen.set(source, result);
142
+ if (dstMap) {
143
+ for (const [key, value] of dstMap) {
144
+ result.set(key, value);
145
+ }
146
+ }
147
+ for (const [key, value] of srcMap) {
148
+ if (value === undefined) {
149
+ continue;
150
+ }
151
+ const merged = _merge(undefined, value);
152
+ if (merged !== undefined) {
153
+ result.set(key, merged);
154
+ }
155
+ }
156
+ return result;
157
+ }
158
+ case "atomic":
159
+ default: {
160
+ return source;
161
+ }
162
+ }
163
+ }
164
+ else if (source instanceof Set) {
165
+ const srcSet = source;
166
+ const dstSet = target instanceof Set ? target : undefined;
167
+ switch (setStrategy) {
168
+ case "merge": {
169
+ const result = new Set();
170
+ seen.set(source, result);
171
+ if (dstSet) {
172
+ for (const item of dstSet) {
173
+ result.add(item);
174
+ }
175
+ }
176
+ for (const item of srcSet) {
177
+ result.add(item === source ? result : item);
178
+ }
179
+ return result;
180
+ }
181
+ case "atomic":
182
+ default: {
183
+ return source;
184
+ }
185
+ }
186
+ }
187
+ else {
188
+ return source;
189
+ }
190
+ }
191
+ let merged = _merge(target, source);
192
+ if (merged === undefined) {
193
+ merged = _merge(undefined, target);
194
+ }
195
+ return merged === undefined
196
+ ? target
197
+ : merged;
198
+ }
199
+ export function clone(source, options) {
200
+ const seen = new WeakMap();
201
+ const cloneArray = options?.array ?? true;
202
+ const cloneMap = options?.map ?? true;
203
+ const cloneSet = options?.set ?? true;
204
+ const cloneBuffer = options?.buffer ?? true;
205
+ function _clone(source) {
206
+ if (isPrimitive(source) || isFunction(source)) {
207
+ return source;
208
+ }
209
+ else if (!isObject(source)) {
210
+ throw new Error("never");
211
+ }
212
+ else if (seen.has(source)) {
213
+ return seen.get(source);
214
+ }
215
+ else if (Array.isArray(source) && cloneArray) {
216
+ const result = [];
217
+ seen.set(source, result);
218
+ for (const item of source) {
219
+ result.push(_clone(item));
220
+ }
221
+ return result;
222
+ }
223
+ else if (isPlainObject(source)) {
224
+ const proto = Object.getPrototypeOf(source);
225
+ const result = Object.create(proto);
226
+ seen.set(source, result);
227
+ for (const key of Object.keys(source)) {
228
+ if (key === "__proto__" || key === "constructor" || key === "prototype") {
229
+ continue;
230
+ }
231
+ const value = source[key];
232
+ const cloned = _clone(value);
233
+ if (cloned !== undefined) {
234
+ result[key] = cloned;
235
+ }
236
+ }
237
+ return result;
238
+ }
239
+ else if (source instanceof Date) {
240
+ const result = new Date(source.getTime());
241
+ seen.set(source, result);
242
+ return result;
243
+ }
244
+ else if (source instanceof RegExp) {
245
+ const result = new RegExp(source.source, source.flags);
246
+ seen.set(source, result);
247
+ return result;
248
+ }
249
+ else if (source instanceof Map && cloneMap) {
250
+ const result = new Map();
251
+ seen.set(source, result);
252
+ for (const [key, value] of source) {
253
+ result.set(key, _clone(value));
254
+ }
255
+ return result;
256
+ }
257
+ else if (source instanceof Set && cloneSet) {
258
+ const result = new Set();
259
+ seen.set(source, result);
260
+ for (const item of source) {
261
+ result.add(_clone(item));
262
+ }
263
+ return result;
264
+ }
265
+ else if (source instanceof ArrayBuffer && cloneBuffer) {
266
+ const src = source;
267
+ const result = src.slice(0);
268
+ seen.set(source, result);
269
+ return result;
270
+ }
271
+ else if (ArrayBuffer.isView(source) && cloneBuffer) {
272
+ if (source instanceof DataView) {
273
+ const src = source;
274
+ const sliced = src.buffer.slice(src.byteOffset, src.byteOffset + src.byteLength);
275
+ const result = new DataView(sliced);
276
+ seen.set(source, result);
277
+ return result;
278
+ }
279
+ const ctor = source.constructor;
280
+ const result = new ctor(source);
281
+ seen.set(source, result);
282
+ return result;
283
+ }
284
+ else {
285
+ return source;
286
+ }
287
+ }
288
+ return _clone(source);
289
+ }
@@ -0,0 +1,3 @@
1
+ import type { PluginSimple } from "markdown-it/lib/index.mjs";
2
+ export declare function mermaidPlugin(): PluginSimple;
3
+ export default mermaidPlugin;
@@ -0,0 +1,36 @@
1
+ function hashCode(str) {
2
+ let hash = 0;
3
+ for (let i = 0; i < str.length; i++) {
4
+ const char = str.charCodeAt(i);
5
+ hash = (hash << 5) - hash + char;
6
+ hash = hash & hash;
7
+ }
8
+ return hash.toString(36);
9
+ }
10
+ ;
11
+ function getHashCodeId(code) {
12
+ return `mermaid-${hashCode(code)}`;
13
+ }
14
+ ;
15
+ function mermaidChart(id, code) {
16
+ return `<pre id="${id}" class="mermaid">${code}</pre>`;
17
+ }
18
+ ;
19
+ export function mermaidPlugin() {
20
+ return (md) => {
21
+ const original = md.renderer.rules.fence ||
22
+ function (tokens, idx, options, _env, self) {
23
+ return self.renderToken(tokens, idx, options);
24
+ };
25
+ md.renderer.rules.fence = (tokens, idx, options, env, self) => {
26
+ const token = tokens[idx];
27
+ if (token.info === "mermaid") {
28
+ const code = token.content.trim();
29
+ const id = getHashCodeId(code);
30
+ return mermaidChart(id, code);
31
+ }
32
+ return original(tokens, idx, options, env, self);
33
+ };
34
+ };
35
+ }
36
+ export default mermaidPlugin;
@@ -1,9 +1,9 @@
1
1
  import type { PluginWithOptions } from "markdown-it";
2
2
  import type Token from "markdown-it/lib/token.mjs";
3
- export type ReplaceHandler = (link: string, env: any, token: Token) => string;
3
+ export type RewriteHandler = (link: string, env: any, token: Token) => string;
4
4
  export interface Options {
5
- replace: ReplaceHandler;
5
+ rewrite: RewriteHandler;
6
6
  }
7
7
  export declare function defaultHandler(link: string, _env: any, _token: Token): string;
8
- export declare const replacelink: PluginWithOptions<Options>;
9
- export default replacelink;
8
+ export declare const rewritelink: PluginWithOptions<Options>;
9
+ export default rewritelink;
@@ -0,0 +1,69 @@
1
+ export 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 replaceHtmlAttr(token, handler, env) {
17
+ const attrs = [
18
+ "href", "src", "action", "formaction", "poster", "cite", "data",
19
+ "manifest", "srcset", "imgsrcset", "ping", "content", "usemap"
20
+ ].join("|");
21
+ const regex = new RegExp(`(${attrs})\\s*=\\s*["']([^"']+)["']`, "g");
22
+ const rewriteFn = (_match, attr, value) => {
23
+ if (attr === "srcset" || attr === "imgsrcset") {
24
+ const replaced = value.split(",")
25
+ .map(part => part
26
+ .split(" ")
27
+ .map(text => handler(text, env, token))
28
+ .join(" "))
29
+ .join(",");
30
+ return `${attr}="${replaced}"`;
31
+ }
32
+ else {
33
+ const replaced = handler(value, env, token);
34
+ return `${attr}="${replaced}"`;
35
+ }
36
+ };
37
+ const content = token.content.replace(regex, rewriteFn);
38
+ token.content = content;
39
+ }
40
+ function getHandler(option) {
41
+ const rewriteFn = option?.rewrite || defaultHandler;
42
+ function handler(state) {
43
+ state.tokens.forEach(token => {
44
+ if (token.type === "inline" && token.children !== null) {
45
+ token.children.forEach(childToken => {
46
+ if (childToken.type == "link_open") {
47
+ replaceAttr(childToken, "href", rewriteFn, state.env);
48
+ }
49
+ else if (childToken.type == "image") {
50
+ replaceAttr(childToken, "src", rewriteFn, state.env);
51
+ }
52
+ else if (childToken.type == "html_inline") {
53
+ replaceHtmlAttr(childToken, rewriteFn, state.env);
54
+ }
55
+ });
56
+ }
57
+ else if (token.type === "html_block") {
58
+ replaceHtmlAttr(token, rewriteFn, state.env);
59
+ }
60
+ });
61
+ }
62
+ ;
63
+ return handler;
64
+ }
65
+ export const rewritelink = (md, option) => {
66
+ const handler = getHandler(option);
67
+ md.core.ruler.after("linkify", "rewrite_link", handler);
68
+ };
69
+ export default rewritelink;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cobapen/markdown",
3
- "version": "0.7.0",
3
+ "version": "0.8.1",
4
4
  "description": "A markdown converter for cobapen website",
5
5
  "keywords": [
6
6
  "markdown"
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@cobapen/math": "^0.1.2",
39
- "@mathjax/src": "^4.1.0",
39
+ "@mathjax/src": "^4.1.1",
40
40
  "highlight.js": "^11.11.1",
41
41
  "markdown-it": "^14.1.1",
42
42
  "markdown-it-adv-table": "^0.2.3",
@@ -50,7 +50,7 @@
50
50
  "@cobapen/eslint-config": "^0.5.1",
51
51
  "@types/markdown-it": "^14.1.2",
52
52
  "@types/mustache": "^4.2.6",
53
- "@types/node": "^25.2.3",
53
+ "@types/node": "^25.3.5",
54
54
  "@vitest/coverage-v8": "^4.0.18",
55
55
  "eslint": "^9.39.2",
56
56
  "mustache": "^4.2.0",
@@ -1,57 +0,0 @@
1
- export 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 replaceHtmlAttr(token, handler, env) {
17
- const regex = /(href|src)\s*=\s*["']([^"']+)["']/g;
18
- let content = token.content;
19
- let match = regex.exec(content);
20
- while (match !== null) {
21
- const before = match[2];
22
- const replaced = handler(before, env, token);
23
- content = content.replace(before, replaced);
24
- match = regex.exec(content);
25
- }
26
- token.content = content;
27
- }
28
- function getHandler(option) {
29
- const replaceFn = option?.replace || defaultHandler;
30
- function handler(state) {
31
- state.tokens.forEach(token => {
32
- if (token.type === "inline" && token.children !== null) {
33
- token.children.forEach(childToken => {
34
- if (childToken.type == "link_open") {
35
- replaceAttr(childToken, "href", replaceFn, state.env);
36
- }
37
- else if (childToken.type == "image") {
38
- replaceAttr(childToken, "src", replaceFn, state.env);
39
- }
40
- else if (childToken.type == "html_inline") {
41
- replaceHtmlAttr(childToken, replaceFn, state.env);
42
- }
43
- });
44
- }
45
- else if (token.type === "html_block") {
46
- replaceHtmlAttr(token, replaceFn, state.env);
47
- }
48
- });
49
- }
50
- ;
51
- return handler;
52
- }
53
- export const replacelink = (md, option) => {
54
- const handler = getHandler(option);
55
- md.core.ruler.after("linkify", "replace_link", handler);
56
- };
57
- export default replacelink;
@@ -1,151 +0,0 @@
1
- import { type LiteDocument } from "@mathjax/src/js/adaptors/lite/Document.js";
2
- import { LiteElement } from "@mathjax/src/js/adaptors/lite/Element.js";
3
- import { type LiteText } from "@mathjax/src/js/adaptors/lite/Text.js";
4
- import { type LiteAdaptor } from "@mathjax/src/js/adaptors/liteAdaptor.js";
5
- import { type MathDocument } from "@mathjax/src/js/core/MathDocument.js";
6
- import { TeX } from "@mathjax/src/js/input/tex.js";
7
- import { CHTML } from "@mathjax/src/js/output/chtml.js";
8
- import { type DeepPartial } from "../utils/merge.js";
9
- import "@mathjax/src/js/input/tex/base/BaseConfiguration.js";
10
- import "@mathjax/src/js/input/tex/ams/AmsConfiguration.js";
11
- import "@mathjax/src/js/input/tex/newcommand/NewcommandConfiguration.js";
12
- import "@mathjax/src/js/input/tex/noundefined/NoUndefinedConfiguration.js";
13
- import "@mathjax/src/js/input/tex/action/ActionConfiguration.js";
14
- import "@mathjax/src/js/input/tex/ams/AmsConfiguration.js";
15
- import "@mathjax/src/js/input/tex/amscd/AmsCdConfiguration.js";
16
- import "@mathjax/src/js/input/tex/autoload/AutoloadConfiguration.js";
17
- import "@mathjax/src/js/input/tex/base/BaseConfiguration.js";
18
- import "@mathjax/src/js/input/tex/bbm/BbmConfiguration.js";
19
- import "@mathjax/src/js/input/tex/bboldx/BboldxConfiguration.js";
20
- import "@mathjax/src/js/input/tex/bbox/BboxConfiguration.js";
21
- import "@mathjax/src/js/input/tex/begingroup/BegingroupConfiguration.js";
22
- import "@mathjax/src/js/input/tex/boldsymbol/BoldsymbolConfiguration.js";
23
- import "@mathjax/src/js/input/tex/braket/BraketConfiguration.js";
24
- import "@mathjax/src/js/input/tex/bussproofs/BussproofsConfiguration.js";
25
- import "@mathjax/src/js/input/tex/cancel/CancelConfiguration.js";
26
- import "@mathjax/src/js/input/tex/cases/CasesConfiguration.js";
27
- import "@mathjax/src/js/input/tex/centernot/CenternotConfiguration.js";
28
- import "@mathjax/src/js/input/tex/color/ColorConfiguration.js";
29
- import "@mathjax/src/js/input/tex/colortbl/ColortblConfiguration.js";
30
- import "@mathjax/src/js/input/tex/colorv2/ColorV2Configuration.js";
31
- import "@mathjax/src/js/input/tex/configmacros/ConfigMacrosConfiguration.js";
32
- import "@mathjax/src/js/input/tex/dsfont/DsfontConfiguration.js";
33
- import "@mathjax/src/js/input/tex/empheq/EmpheqConfiguration.js";
34
- import "@mathjax/src/js/input/tex/enclose/EncloseConfiguration.js";
35
- import "@mathjax/src/js/input/tex/extpfeil/ExtpfeilConfiguration.js";
36
- import "@mathjax/src/js/input/tex/gensymb/GensymbConfiguration.js";
37
- import "@mathjax/src/js/input/tex/html/HtmlConfiguration.js";
38
- import "@mathjax/src/js/input/tex/mathtools/MathtoolsConfiguration.js";
39
- import "@mathjax/src/js/input/tex/mhchem/MhchemConfiguration.js";
40
- import "@mathjax/src/js/input/tex/newcommand/NewcommandConfiguration.js";
41
- import "@mathjax/src/js/input/tex/noerrors/NoErrorsConfiguration.js";
42
- import "@mathjax/src/js/input/tex/noundefined/NoUndefinedConfiguration.js";
43
- import "@mathjax/src/js/input/tex/physics/PhysicsConfiguration.js";
44
- import "@mathjax/src/js/input/tex/require/RequireConfiguration.js";
45
- import "@mathjax/src/js/input/tex/setoptions/SetOptionsConfiguration.js";
46
- import "@mathjax/src/js/input/tex/tagformat/TagFormatConfiguration.js";
47
- import "@mathjax/src/js/input/tex/texhtml/TexHtmlConfiguration.js";
48
- import "@mathjax/src/js/input/tex/textcomp/TextcompConfiguration.js";
49
- import "@mathjax/src/js/input/tex/textmacros/TextMacrosConfiguration.js";
50
- import "@mathjax/src/js/input/tex/unicode/UnicodeConfiguration.js";
51
- import "@mathjax/src/js/input/tex/units/UnitsConfiguration.js";
52
- import "@mathjax/src/js/input/tex/upgreek/UpgreekConfiguration.js";
53
- import "@mathjax/src/js/input/tex/verb/VerbConfiguration.js";
54
- type N = LiteElement;
55
- type T = LiteText;
56
- type D = LiteDocument;
57
- declare const fontNames: readonly ["mathjax-newcm"];
58
- type FontName = typeof fontNames[number];
59
- interface AnyObject {
60
- [x: string]: any;
61
- }
62
- export interface Options extends DeepPartial<EngineOptions> {
63
- loader?: DeepPartial<LoaderOptions>;
64
- tex?: DeepPartial<TexInputOptions>;
65
- output?: DeepPartial<OutputOptions>;
66
- chtml?: DeepPartial<CHTMLOptions>;
67
- }
68
- interface EngineOptions {
69
- noAsyncLoad: boolean;
70
- }
71
- interface LoaderOptions {
72
- load: string[];
73
- paths: {
74
- mathjax?: {
75
- [x: string]: string;
76
- };
77
- fonts?: string;
78
- };
79
- }
80
- interface TexInputOptions {
81
- packages: string | [string] | AnyObject;
82
- inlineMath: [[string, string]];
83
- displayMath: [[string, string]];
84
- processEscapes: boolean;
85
- processEnvironments: boolean;
86
- processRefs: boolean;
87
- digits: RegExp;
88
- tags: string;
89
- tagSide: string;
90
- tagIndent: string;
91
- useLabelIds: boolean;
92
- multlineWidth: string;
93
- maxMacros: number;
94
- maxBuffer: number;
95
- baseURL: string;
96
- formatError: (jax: object, err: Error) => void;
97
- macros: AnyObject;
98
- }
99
- interface OutputOptions {
100
- scale: number;
101
- minScale: number;
102
- matchFontHeight: boolean;
103
- mtextInheritFont: boolean;
104
- merrorInheritFont: boolean;
105
- mtextFont: string;
106
- merrorFont: string;
107
- mathmlspacing: boolean;
108
- skipAttributes: AnyObject;
109
- exFactor: number;
110
- displayAlign: string;
111
- displayIndent: number | string;
112
- linebreaks: {
113
- inline: boolean;
114
- width: number | string;
115
- lineleading: number;
116
- };
117
- font: FontName;
118
- fontPath: string;
119
- fontExtensions: string[];
120
- htmlHDW: "auto" | "use" | "force" | "ignore";
121
- preFilters: string[];
122
- postFilters: string[];
123
- fontData: object;
124
- [x: string]: any;
125
- }
126
- interface CHTMLOptions {
127
- matchFontHeight: boolean;
128
- fontURL: string;
129
- dynamicPrefix: string;
130
- adaptiveCSS: boolean;
131
- }
132
- export interface ConvertOptions {
133
- inline: boolean;
134
- em: number;
135
- ex: number;
136
- width: number;
137
- }
138
- export declare class MathjaxEngine {
139
- private _initStatus;
140
- option: Options;
141
- adaptor: LiteAdaptor;
142
- tex: TeX<N, T, D>;
143
- chtml: CHTML<N, T, D>;
144
- html: MathDocument<N, T, D>;
145
- constructor(option?: Partial<Options>);
146
- private asyncInit;
147
- waitInit(): Promise<void>;
148
- convert(tex: string, option?: Partial<ConvertOptions>): string;
149
- stylesheet(): string;
150
- }
151
- export {};
@@ -1,198 +0,0 @@
1
- import { MathJaxNewcmFont } from "@mathjax/mathjax-newcm-font/mjs/chtml.js";
2
- import { source as mjsource } from "@mathjax/src/components/mjs/source.js";
3
- import { LiteElement } from "@mathjax/src/js/adaptors/lite/Element.js";
4
- import { liteAdaptor } from "@mathjax/src/js/adaptors/liteAdaptor.js";
5
- import { RegisterHTMLHandler } from "@mathjax/src/js/handlers/html.js";
6
- import { TeX } from "@mathjax/src/js/input/tex.js";
7
- import { mathjax } from "@mathjax/src/js/mathjax.js";
8
- import { CHTML } from "@mathjax/src/js/output/chtml.js";
9
- import { merge } from "../utils/merge.js";
10
- import "@mathjax/src/js/input/tex/base/BaseConfiguration.js";
11
- import "@mathjax/src/js/input/tex/ams/AmsConfiguration.js";
12
- import "@mathjax/src/js/input/tex/newcommand/NewcommandConfiguration.js";
13
- import "@mathjax/src/js/input/tex/noundefined/NoUndefinedConfiguration.js";
14
- import "@mathjax/src/js/input/tex/action/ActionConfiguration.js";
15
- import "@mathjax/src/js/input/tex/ams/AmsConfiguration.js";
16
- import "@mathjax/src/js/input/tex/amscd/AmsCdConfiguration.js";
17
- import "@mathjax/src/js/input/tex/autoload/AutoloadConfiguration.js";
18
- import "@mathjax/src/js/input/tex/base/BaseConfiguration.js";
19
- import "@mathjax/src/js/input/tex/bbm/BbmConfiguration.js";
20
- import "@mathjax/src/js/input/tex/bboldx/BboldxConfiguration.js";
21
- import "@mathjax/src/js/input/tex/bbox/BboxConfiguration.js";
22
- import "@mathjax/src/js/input/tex/begingroup/BegingroupConfiguration.js";
23
- import "@mathjax/src/js/input/tex/boldsymbol/BoldsymbolConfiguration.js";
24
- import "@mathjax/src/js/input/tex/braket/BraketConfiguration.js";
25
- import "@mathjax/src/js/input/tex/bussproofs/BussproofsConfiguration.js";
26
- import "@mathjax/src/js/input/tex/cancel/CancelConfiguration.js";
27
- import "@mathjax/src/js/input/tex/cases/CasesConfiguration.js";
28
- import "@mathjax/src/js/input/tex/centernot/CenternotConfiguration.js";
29
- import "@mathjax/src/js/input/tex/color/ColorConfiguration.js";
30
- import "@mathjax/src/js/input/tex/colortbl/ColortblConfiguration.js";
31
- import "@mathjax/src/js/input/tex/colorv2/ColorV2Configuration.js";
32
- import "@mathjax/src/js/input/tex/configmacros/ConfigMacrosConfiguration.js";
33
- import "@mathjax/src/js/input/tex/dsfont/DsfontConfiguration.js";
34
- import "@mathjax/src/js/input/tex/empheq/EmpheqConfiguration.js";
35
- import "@mathjax/src/js/input/tex/enclose/EncloseConfiguration.js";
36
- import "@mathjax/src/js/input/tex/extpfeil/ExtpfeilConfiguration.js";
37
- import "@mathjax/src/js/input/tex/gensymb/GensymbConfiguration.js";
38
- import "@mathjax/src/js/input/tex/html/HtmlConfiguration.js";
39
- import "@mathjax/src/js/input/tex/mathtools/MathtoolsConfiguration.js";
40
- import "@mathjax/src/js/input/tex/mhchem/MhchemConfiguration.js";
41
- import "@mathjax/src/js/input/tex/newcommand/NewcommandConfiguration.js";
42
- import "@mathjax/src/js/input/tex/noerrors/NoErrorsConfiguration.js";
43
- import "@mathjax/src/js/input/tex/noundefined/NoUndefinedConfiguration.js";
44
- import "@mathjax/src/js/input/tex/physics/PhysicsConfiguration.js";
45
- import "@mathjax/src/js/input/tex/require/RequireConfiguration.js";
46
- import "@mathjax/src/js/input/tex/setoptions/SetOptionsConfiguration.js";
47
- import "@mathjax/src/js/input/tex/tagformat/TagFormatConfiguration.js";
48
- import "@mathjax/src/js/input/tex/texhtml/TexHtmlConfiguration.js";
49
- import "@mathjax/src/js/input/tex/textcomp/TextcompConfiguration.js";
50
- import "@mathjax/src/js/input/tex/textmacros/TextMacrosConfiguration.js";
51
- import "@mathjax/src/js/input/tex/unicode/UnicodeConfiguration.js";
52
- import "@mathjax/src/js/input/tex/units/UnitsConfiguration.js";
53
- import "@mathjax/src/js/input/tex/upgreek/UpgreekConfiguration.js";
54
- import "@mathjax/src/js/input/tex/verb/VerbConfiguration.js";
55
- const fontNames = [
56
- "mathjax-newcm",
57
- ];
58
- const defaultFontName = fontNames[0];
59
- function isFontName(name) {
60
- return fontNames.includes(name);
61
- }
62
- const fontDataMap = {
63
- "mathjax-newcm": MathJaxNewcmFont,
64
- };
65
- const texExtensions = Object.keys(mjsource)
66
- .filter(name => name.substring(0, 6) === "[tex]/")
67
- .map(name => name.substring(6))
68
- .sort();
69
- const packageList = [
70
- "base",
71
- "ams",
72
- "newcommand",
73
- "noundefined",
74
- ].concat(texExtensions);
75
- const MATHJAX_DEFAULT_FONT_URL = (name) => `https://cdn.jsdelivr.net/npm/@mathjax/${name}-font@4/chtml/woff2`;
76
- const defaultMathOption = {
77
- noAsyncLoad: true,
78
- tex: {
79
- packages: packageList,
80
- },
81
- output: {
82
- scale: 1.21,
83
- exFactor: 5,
84
- font: defaultFontName,
85
- },
86
- chtml: {
87
- adaptiveCSS: true,
88
- },
89
- };
90
- const defaultConvertOption = {
91
- inline: false,
92
- em: 16,
93
- ex: 8,
94
- width: 80 * 16,
95
- };
96
- export class MathjaxEngine {
97
- _initStatus = null;
98
- option;
99
- adaptor;
100
- tex;
101
- chtml;
102
- html;
103
- constructor(option) {
104
- this.option = initOption(option);
105
- this.adaptor = liteAdaptor();
106
- RegisterHTMLHandler(this.adaptor);
107
- const tex = new TeX(this.option.tex);
108
- const chtml = new CHTML({
109
- ...this.option.output,
110
- ...this.option.chtml,
111
- });
112
- if (this.option.noAsyncLoad !== true) {
113
- this._initStatus = this.asyncInit(chtml);
114
- }
115
- const html = mathjax.document("", {
116
- InputJax: tex,
117
- OutputJax: chtml,
118
- });
119
- html.addRenderAction("typeset", 155, renderDoc, renderMath);
120
- this.tex = tex;
121
- this.chtml = chtml;
122
- this.html = html;
123
- function renderDoc(_doc) { }
124
- function renderMath(math, doc) {
125
- const adaptor = doc.adaptor;
126
- const text = adaptor.node("mjx-copytext", { "aria-hidden": true }, [
127
- adaptor.text(math.math),
128
- ]);
129
- adaptor.setStyle(text, "position", "absolute");
130
- adaptor.setStyle(text, "display", "none");
131
- adaptor.setStyle(text, "width", "0");
132
- adaptor.setStyle(math.typesetRoot, "position", "relative");
133
- adaptor.append(math.typesetRoot, text);
134
- }
135
- }
136
- async asyncInit(chtml) {
137
- await import("@mathjax/src/js/util/asyncLoad/esm.js");
138
- await chtml.font.loadDynamicFiles();
139
- }
140
- ;
141
- async waitInit() {
142
- if (this._initStatus) {
143
- await this._initStatus;
144
- this._initStatus = null;
145
- }
146
- }
147
- convert(tex, option) {
148
- const node = this.html.convert(tex, convOption(option));
149
- if (node instanceof LiteElement) {
150
- return this.adaptor.outerHTML(node);
151
- }
152
- else {
153
- return "ERROR";
154
- }
155
- }
156
- stylesheet() {
157
- return this.adaptor.textContent(this.chtml.styleSheet(this.html));
158
- }
159
- }
160
- function initOption(opt) {
161
- const option = merge(defaultMathOption, opt);
162
- const packages = option?.tex?.packages;
163
- if (typeof packages === "string") {
164
- option.tex = option.tex ?? {};
165
- option.tex.packages = packages.split(/\s*,\s*/);
166
- }
167
- if (option.output?.font !== undefined && typeof option.output.font === "string") {
168
- let name = option.output.font.trim();
169
- if (name === "default") {
170
- name = defaultFontName;
171
- }
172
- if (isFontName(name)) {
173
- if (option.output.fontData === undefined) {
174
- option.output.fontData = fontDataMap[name];
175
- }
176
- if (option.chtml?.fontURL === undefined) {
177
- option.chtml = option.chtml ?? {};
178
- option.chtml.fontURL = MATHJAX_DEFAULT_FONT_URL(name);
179
- }
180
- }
181
- }
182
- if (option.chtml?.adaptiveCSS !== true) {
183
- if (option.noAsyncLoad) {
184
- console.warn("[MathjaxEngine] adaptiveCSS is disabled, so noAsyncLoad is forced to false.");
185
- }
186
- option.noAsyncLoad = false;
187
- }
188
- return option;
189
- }
190
- function convOption(option) {
191
- return {
192
- display: !(option?.inline ?? defaultConvertOption.inline),
193
- em: option?.em ?? defaultConvertOption.em,
194
- ex: option?.ex ?? defaultConvertOption.ex,
195
- containerWidth: option?.width ?? defaultConvertOption.width,
196
- scale: 1.0,
197
- };
198
- }
@@ -1,12 +0,0 @@
1
- type Primitive = string | number | boolean | symbol | BigInt | null | undefined;
2
- export type DeepPartial<T> = {
3
- [P in keyof T]?: T[P] extends Array<infer U> ? Array<DeepPartial<U>> : T[P] extends object ? T[P] extends Function ? T[P] : DeepPartial<T[P]> : T[P];
4
- };
5
- type IsPlainObject<T> = T extends object ? T extends Function ? false : T extends any[] ? false : true : false;
6
- type DeepMerged<T, U> = {
7
- [K in keyof T | keyof U]: K extends keyof T ? K extends keyof U ? U[K] extends undefined ? T[K] : IsPlainObject<T[K]> extends true ? IsPlainObject<U[K]> extends true ? DeepMerged<T[K], U[K]> : U[K] : U[K] : T[K] : never;
8
- };
9
- export declare function isPrimitive(value: unknown): value is Primitive;
10
- export declare function isFunction(value: unknown): value is Function;
11
- export declare function merge<T, U>(target: Partial<T>, source?: Partial<U>): DeepMerged<T, U>;
12
- export {};
@@ -1,50 +0,0 @@
1
- export function isPrimitive(value) {
2
- return (value === null
3
- || typeof value === "string"
4
- || typeof value === "number"
5
- || typeof value === "boolean"
6
- || typeof value === "symbol"
7
- || typeof value === "bigint"
8
- || typeof value === "undefined");
9
- }
10
- export function isFunction(value) {
11
- return typeof value === "function";
12
- }
13
- export function merge(target, source) {
14
- const seen = new WeakMap();
15
- function _merge(target, source) {
16
- if (seen.has(source)) {
17
- return seen.get(source);
18
- }
19
- else if (isPrimitive(source) || isFunction(source)) {
20
- return source;
21
- }
22
- else if (Array.isArray(source)) {
23
- const result = source.map(item => _merge(undefined, item));
24
- seen.set(source, result);
25
- return result;
26
- }
27
- else if (typeof source === "object") {
28
- const result = { ...target };
29
- seen.set(source, result);
30
- for (const key of Object.keys(source)) {
31
- if (key === "__proto__" || key === "constructor" || key === "prototype") {
32
- continue;
33
- }
34
- const value = source[key];
35
- const merged = _merge(result[key], value);
36
- if (merged !== undefined) {
37
- result[key] = merged;
38
- }
39
- }
40
- return result;
41
- }
42
- else {
43
- return undefined;
44
- }
45
- }
46
- const merged = _merge(target, source);
47
- return merged === undefined
48
- ? target
49
- : merged;
50
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes