@thi.ng/hiccup-markdown 3.2.1 → 3.2.3

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/parser.d.ts DELETED
@@ -1,65 +0,0 @@
1
- import type { Fn3, IObjectOf } from "@thi.ng/api";
2
- import type { ILogger } from "@thi.ng/logger";
3
- import type { ContextOpts, ParseScope } from "@thi.ng/parse";
4
- export declare const GRAMMAR: import("@thi.ng/parse").Language | undefined;
5
- export declare const parseRaw: (src: string, opts?: Partial<ContextOpts>) => {
6
- result: boolean;
7
- ctx: import("@thi.ng/parse").ParseContext<string>;
8
- };
9
- export interface TagTransforms {
10
- bold(ctx: MDParseContext, body: string): any;
11
- bquote(ctx: MDParseContext, body: any[], meta?: any): any;
12
- code(ctx: MDParseContext, body: string): any;
13
- codeblock(ctx: MDParseContext, lang: string, head: string, body: string, meta?: any): any;
14
- custom(ctx: MDParseContext, kind: string, body: string, meta?: any): any;
15
- emoji(ctx: MDParseContext, id: string): any;
16
- footnote(ctx: MDParseContext, id: string, body: any[], meta?: any): any;
17
- footnoteRef(ctx: MDParseContext, id: string): any;
18
- footnoteWrapper(ctx: MDParseContext, notes: IObjectOf<any>): any;
19
- hd(ctx: MDParseContext, level: number, body: any[], meta?: any): any;
20
- hr(ctx: MDParseContext, length: number): any;
21
- img(ctx: MDParseContext, src: string, alt: string): any;
22
- italic(ctx: MDParseContext, body: string): any;
23
- link(ctx: MDParseContext, target: string, body: any[]): any;
24
- linkRef(ctx: MDParseContext, refID: string, body: any[]): any;
25
- meta(ctx: MDParseContext, body: string): any;
26
- ol(ctx: MDParseContext, items: any[], meta?: any): any;
27
- olitem(ctx: MDParseContext, attribs: TodoAttribs, index: number, ...body: any[]): any;
28
- para(ctx: MDParseContext, body: any[], meta?: any): any;
29
- strike(ctx: MDParseContext, body: string): any;
30
- table(ctx: MDParseContext, align: ColumnAlign[], head: any[], rows: any[], meta?: any): any;
31
- tableCell(ctx: MDParseContext, body: any[]): any;
32
- tableRow(ctx: MDParseContext, cells: any[]): any;
33
- ul(ctx: MDParseContext, items: any[], meta?: any): any;
34
- ulitem(ctx: MDParseContext, attribs: TodoAttribs, ...body: any[]): any;
35
- }
36
- export interface MDParseContext {
37
- logger?: ILogger;
38
- tags: TagTransforms;
39
- linkRefs: IObjectOf<string>;
40
- footnotes: IObjectOf<any>;
41
- headings: {
42
- level: number;
43
- body: any[];
44
- }[];
45
- hasFootnotes: boolean;
46
- meta?: any;
47
- opts: MDParseOpts;
48
- }
49
- export interface MDParseOpts {
50
- /**
51
- * Line break representation in blockquotes. E.g. Use `["br",{}]` for actual
52
- * line breaks.
53
- *
54
- * @defaultValue `" "`
55
- */
56
- bqLineBreak: any;
57
- }
58
- export type TodoAttribs = Partial<{
59
- __todo: true;
60
- __done: boolean;
61
- }>;
62
- export type ColumnAlign = "center" | "left" | "right";
63
- export declare const defMDContext: (tags?: Partial<TagTransforms>, opts?: Partial<MDParseOpts>) => MDParseContext;
64
- export declare const walk: Fn3<ParseScope<string>, MDParseContext, any[], void>;
65
- //# sourceMappingURL=parser.d.ts.map
package/parser.js DELETED
@@ -1,379 +0,0 @@
1
- // thing:no-export
2
- import { peek } from "@thi.ng/arrays/peek";
3
- import { delay } from "@thi.ng/compose/delay";
4
- import { DEFAULT, defmulti } from "@thi.ng/defmulti";
5
- import { EMOJI } from "@thi.ng/emoji/emoji";
6
- import { defContext } from "@thi.ng/parse/context";
7
- import { defGrammar } from "@thi.ng/parse/grammar";
8
- export const GRAMMAR = defGrammar(`
9
- DNL1: <DNL>+ => discard ;
10
- DNL2: <NL>{2,} ;
11
- inlinedelim: ( "![" | '[' | "**" | '_' | "~~" | '\`' | " :" ) ;
12
- delim: ( <inlinedelim> | <DNL2> ) ;
13
- delim1: ( <inlinedelim> | <NL> ) ;
14
- body: .(?-<delim>!) => join ;
15
- body1: .(?-<delim1>!) => join ;
16
-
17
- ref: "[["! .(?+"]]"!) => join ;
18
- fnref: "[^"! <label> ;
19
- fnote: <LSTART> "[^"! <fnlabel> <WS1> <para> ;
20
- fnlabel: .(?+"]:"!) => join ;
21
- label: .(?+']'!) => join ;
22
- target: .(?+')'!) => join ;
23
- link: '['! <label> '('! <target> ;
24
- linkref: '['! <label> '['! <label> ;
25
- linkdef: <LSTART> '['! <label> ':'! <WS1> <ldtarget> ;
26
- ldtarget: .(?+<DNL1>) => join ;
27
- img: "!["! <label> '('! <target> ;
28
- bold: "**"! .(?+"**"!) => join ;
29
- italic: "_"! .(?+"_"!) => join ;
30
- code: '\`'! .(?+'\`'!) => join ;
31
- strike: "~~"! .(?+"~~"!) => join ;
32
- emoji: ' '? ':'! <ALPHA_NUM>(?+':'!) => join ;
33
- para: (<ref> | <img> | <fnref> | <linkref> | <link> | <bold> | <italic> | <strike> | <code> | <emoji> | <body>)* <DNL2>! ;
34
-
35
- hdlevel: '#'+ => count ;
36
- hd: <LSTART> <hdlevel> <WS0>
37
- (<ref> | <img> | <fnref> | <link> | <bold> | <italic> | <strike> | <code> | <emoji> | <body1> )* <DNL1> ;
38
-
39
- lilevel: ' '* => count ;
40
- uint: <DIGIT>+ => int ;
41
- ulid: <DNL> <WS0> '-'! ;
42
- olid: <DNL> <WS0> <DIGIT>+! '.'! ;
43
- lidelim: ( <delim> | <ulid> | <olid> ) ;
44
- libody: .(?-<lidelim>!) => join ;
45
- todo: '['! [ xX] ']'! <WS1> => hoistR ;
46
- ulitem: <LSTART> <lilevel> "- "! <todo>?
47
- (<ref> | <img> | <fnref> | <link> | <bold> | <italic> | <strike> | <code> | <emoji> | <libody> )* <DNL> ;
48
- olitem: <LSTART> <lilevel> <uint> ". "! <todo>?
49
- (<ref> | <img> | <fnref> | <link> | <bold> | <italic> | <strike> | <code> | <emoji> | <libody> )* <DNL> ;
50
- list: (<ulitem> | <olitem>)+ <DNL1> ;
51
-
52
- cbdelim: <LSTART> "\`\`\`"! ;
53
- codeblock: <cbdelim>! <codemeta> <codebody> <DNL1> ;
54
- codemeta: .(?+<NL>!) => join ;
55
- codebody: .(?+<cbdelim>) => join ;
56
-
57
- customdelim: <LSTART> ":::"! ;
58
- customblock: <customdelim>! <custommeta> <custombody> <DNL1> ;
59
- custommeta: .(?+<NL>!) => join ;
60
- custombody: .(?+<customdelim>) => join ;
61
-
62
- metablock: <LSTART> "{{{"! <metabody> <DNL1> ;
63
- metabody: .(?+<metaend>!) => join ;
64
- metaend: "}}}" <LEND> ;
65
-
66
- bqline: <LSTART> "> "!
67
- (<ref> | <img> | <fnref> | <link> | <bold> | <italic> | <strike> | <code> | <emoji> | <body1>)* <DNL> ;
68
- bquote: <bqline>+ <DNL1> ;
69
-
70
- tdelim: (<inlinedelim> | '|' ) ;
71
- tbody: .(?-<tdelim>!) => join ;
72
- tcell: <WS0> (<ref> | <img> | <fnref> | <link> | <bold> | <italic> | <strike> | <code> | <emoji> | <tbody> )* '|'! ;
73
- trow: <LSTART> '|'! <tcell>(?+<DNL>) ;
74
- table: <trow>+ <DNL1> ;
75
-
76
- hr: "--" ('-'(?-<NL>!))* <DNL1> => join ;
77
-
78
- main: <WS0> (<hd> | <list> | <bquote> | <codeblock> | <customblock> | <metablock> | <table> | <hr> | <fnote> | <linkdef> | <para>)* ;
79
- `);
80
- export const parseRaw = (src, opts) => {
81
- const ctx = defContext(src, opts);
82
- return { result: GRAMMAR.rules.main(ctx), ctx };
83
- };
84
- export const defMDContext = (tags, opts) => ({
85
- footnotes: {},
86
- headings: [],
87
- linkRefs: {},
88
- hasFootnotes: false,
89
- meta: null,
90
- opts: {
91
- bqLineBreak: " ",
92
- ...opts,
93
- },
94
- tags: {
95
- bold: (_, body) => ["strong", {}, body],
96
- bquote: (_, body, meta) => [
97
- "blockquote",
98
- __withMeta({}, meta),
99
- ...body,
100
- ],
101
- code: (_, body) => ["code", {}, body],
102
- codeblock: (_, lang, __head, body, meta) => [
103
- "pre",
104
- __withMeta({ data: { lang }, __head }, meta),
105
- ["code", {}, body],
106
- ],
107
- custom: (_, kind, body, meta) => [kind, __withMeta({}, meta), body],
108
- emoji: (_, id) => EMOJI[id] || id,
109
- footnote: (_, id, body, meta) => [
110
- "li",
111
- __withMeta({ id: `fn-${id}` }, meta),
112
- ["sup", {}, `[${id}] `],
113
- ...body,
114
- " ",
115
- ["a", { href: `#fnref-${id}` }, "⏎"],
116
- ],
117
- footnoteRef: (_, id) => [
118
- "sup",
119
- {},
120
- ["a", { id: `fnref-${id}`, href: `#fn-${id}` }, `[${id}]`],
121
- ],
122
- footnoteWrapper: (_, notes) => [
123
- "ul",
124
- { id: "footnotes" },
125
- ...Object.keys(notes)
126
- .sort()
127
- .map((id) => notes[id]),
128
- ],
129
- hd: (_, level, body, meta) => [
130
- level < 7 ? `h${level}` : "p",
131
- __withMeta({}, meta),
132
- ...body,
133
- ],
134
- hr: (_, __length) => ["hr", { __length }],
135
- img: (_, src, alt) => ["img", { src, alt }],
136
- italic: (_, body) => ["em", {}, body],
137
- link: (_, href, body) => ["a", { href }, ...body],
138
- linkRef: (ctx, refID, body) => [
139
- "a",
140
- { href: delay(() => ctx.linkRefs[refID]) },
141
- ...body,
142
- ],
143
- meta: (_, body) => body,
144
- olitem: (_, attribs, index, body) => [
145
- "li",
146
- { ...attribs, __index: index },
147
- ...body,
148
- ],
149
- ol: (_, items, meta) => ["ol", __withMeta({}, meta), ...items],
150
- para: (_, body, meta) => ["p", __withMeta({}, meta), ...body],
151
- strike: (_, body) => ["s", {}, body],
152
- table: (_, __align, head, rows, meta) => [
153
- "table",
154
- __withMeta({ __align }, meta),
155
- ["thead", {}, head],
156
- ["tbody", {}, ...rows],
157
- ],
158
- tableCell: (_, body) => ["td", {}, ...body],
159
- tableRow: (_, cells) => ["tr", {}, ...cells],
160
- ul: (_, items, meta) => ["ul", __withMeta({}, meta), ...items],
161
- ulitem: (_, attribs, body) => ["li", attribs, ...body],
162
- ...tags,
163
- },
164
- });
165
- export const walk = defmulti((x, ctx) => {
166
- ctx.logger && ctx.logger.debug(x);
167
- return x.id;
168
- }, {
169
- body1: "body",
170
- bqline: "repeat0",
171
- label: "body",
172
- libody: "body",
173
- main: "root",
174
- repeat1: "repeat0",
175
- tbody: "body",
176
- }, {
177
- [DEFAULT]: (scope, ctx) => {
178
- throw new Error(`unknown ID: ${scope.id}, ctx: ${JSON.stringify(ctx)}`);
179
- },
180
- root: ({ children }, ctx, acc) => {
181
- walk(children[0], ctx, acc);
182
- if (ctx.hasFootnotes) {
183
- __collect(acc, ctx.tags.footnoteWrapper(ctx, ctx.footnotes));
184
- }
185
- },
186
- main: ({ children }, ctx, acc) => walk(children[0], ctx, acc),
187
- repeat0: ({ children }, ctx, acc) => {
188
- for (let c of children)
189
- walk(c, ctx, acc);
190
- },
191
- body: ({ result }, _, acc) => __collect(acc, result),
192
- bold: ({ result }, ctx, acc) => __collect(acc, ctx.tags.bold(ctx, result)),
193
- bquote: (scope, ctx, acc) => {
194
- const body = [];
195
- const children = scope.children[0].children;
196
- for (let i = 0, n = children.length - 1; i <= n; i++) {
197
- walk(children[i].children[0], ctx, body);
198
- if (i < n)
199
- body.push(ctx.opts.bqLineBreak);
200
- }
201
- __collect(acc, ctx.tags.bquote(ctx, body, ctx.meta));
202
- ctx.meta = null;
203
- },
204
- code: ({ result }, ctx, acc) => __collect(acc, ctx.tags.code(ctx, result)),
205
- codeblock: ({ children }, ctx, acc) => {
206
- const [lang, ...head] = children[0].result.split(" ");
207
- __collect(acc, ctx.tags.codeblock(ctx, lang, head, children[1].result.trim(), ctx.meta));
208
- ctx.meta = null;
209
- },
210
- customblock: ({ children }, ctx, acc) => {
211
- __collect(acc, ctx.tags.custom(children[0].result, children[1].result.trim(), ctx.meta));
212
- ctx.meta = null;
213
- },
214
- emoji: ({ result }, ctx, acc) => {
215
- if (result[0] === " ") {
216
- __collect(acc, " ");
217
- result = result.substring(1);
218
- }
219
- __collect(acc, ctx.tags.emoji(ctx, result));
220
- },
221
- fnote: ({ children }, ctx) => {
222
- const body = [];
223
- const id = children[0].result;
224
- walk(children[1].children[0], ctx, body);
225
- const res = ctx.tags.footnote(ctx, id, body, ctx.meta);
226
- if (res != null) {
227
- ctx.hasFootnotes = true;
228
- ctx.footnotes[id] = res;
229
- }
230
- ctx.meta = null;
231
- },
232
- fnref: ({ children }, ctx, acc) => __collect(acc, ctx.tags.footnoteRef(ctx, children[0].result)),
233
- hd: ({ children }, ctx, acc) => {
234
- const body = [];
235
- const level = children[0].result;
236
- walk(children[1], ctx, body);
237
- ctx.headings.push({ level, body });
238
- __collect(acc, ctx.tags.hd(ctx, level, body, ctx.meta));
239
- ctx.meta = null;
240
- },
241
- hr: ({ result }, ctx, acc) => __collect(acc, ctx.tags.hr(ctx, result.length)),
242
- img: ({ children }, ctx, acc) => __collect(acc, ctx.tags.img(ctx, children[1].result, children[0].result)),
243
- italic: ({ result }, ctx, acc) => __collect(acc, ctx.tags.italic(ctx, result)),
244
- link: ({ children }, ctx, acc) => {
245
- const body = [];
246
- walk(children[0], ctx, body);
247
- __collect(acc, ctx.tags.link(ctx, children[1].result, body));
248
- },
249
- linkdef: ({ children }, ctx) => {
250
- ctx.linkRefs[children[0].result] = children[1].result;
251
- },
252
- linkref: ({ children }, ctx, acc) => {
253
- const body = [];
254
- walk(children[0], ctx, body);
255
- __collect(acc, ctx.tags.linkRef(ctx, children[1].result, body));
256
- },
257
- list: (scope, ctx, acc) => {
258
- const children = scope.children[0].children;
259
- const stack = [
260
- [children[0].id === "ulitem" ? "ul" : "ol"],
261
- ];
262
- const levels = [0];
263
- for (let item of children) {
264
- const currLevel = item.children[0].result;
265
- if (currLevel > peek(levels)) {
266
- const sublist = [item.id === "ulitem" ? "ul" : "ol"];
267
- const parent = peek(stack);
268
- parent.length > 1
269
- ? peek(parent).push(sublist)
270
- : parent.push([
271
- parent[0] === "ul" ? "ulitem" : "olitem",
272
- {},
273
- sublist,
274
- ]);
275
- stack.push(sublist);
276
- levels.push(currLevel);
277
- }
278
- else if (currLevel < peek(levels)) {
279
- while (currLevel < peek(levels)) {
280
- stack.pop();
281
- levels.pop();
282
- }
283
- }
284
- walk(item, ctx, peek(stack));
285
- }
286
- const $list = (root, isRoot = false) => ctx.tags[root[0]](ctx, root.slice(1).map($item), isRoot ? ctx.meta : null);
287
- const $item = (item) => {
288
- let last = item[item.length - 1];
289
- if (last[0] === "ul" || last[0] === "ol")
290
- item[item.length - 1] = $list(last);
291
- return item[0] === "ulitem"
292
- ? ctx.tags.ulitem(ctx, item[1], item.slice(2))
293
- : ctx.tags.olitem(ctx, item[1], item[2], item.slice(3));
294
- };
295
- __collect(acc, $list(stack[0], true));
296
- ctx.meta = null;
297
- },
298
- metablock: ({ children }, ctx) => {
299
- ctx.meta = ctx.tags.meta(ctx, children[0].result.trim());
300
- },
301
- olitem: ({ children }, ctx, acc) => {
302
- const body = [];
303
- walk(children[3], ctx, body);
304
- __collect(acc, [
305
- "olitem",
306
- __listItemAttribs(children[2]),
307
- children[1].result,
308
- ...body,
309
- ]);
310
- },
311
- para: ({ children }, ctx, acc) => {
312
- const body = [];
313
- for (let c of children)
314
- walk(c, ctx, body);
315
- __collect(acc, ctx.tags.para(ctx, body, ctx.meta));
316
- ctx.meta = null;
317
- },
318
- strike: ({ result }, ctx, acc) => __collect(acc, ctx.tags.strike(ctx, result)),
319
- table: (scope, ctx, acc) => {
320
- const children = scope.children[0].children;
321
- const head = [];
322
- const rows = [];
323
- walk(children[0], ctx, head);
324
- let align = [];
325
- if (children.length > 1) {
326
- for (let c of children[1].children[0].children) {
327
- const raw = (c.children[0].children[0].result.trim());
328
- align.push(raw.startsWith(":-")
329
- ? raw.endsWith("-:")
330
- ? "center"
331
- : "left"
332
- : raw.endsWith("-:")
333
- ? "right"
334
- : "left");
335
- }
336
- for (let c of children.slice(2))
337
- walk(c, ctx, rows);
338
- }
339
- else {
340
- align = new Array(children[0].children[0].children.length).fill("left");
341
- }
342
- __collect(acc, ctx.tags.table(ctx, align, head[0], rows, ctx.meta));
343
- ctx.meta = null;
344
- },
345
- tcell: ({ children }, ctx, acc) => {
346
- const body = [];
347
- for (let c of children)
348
- walk(c, ctx, body);
349
- __collect(acc, ctx.tags.tableCell(ctx, body));
350
- },
351
- trow: ({ children }, ctx, acc) => {
352
- const cols = [];
353
- for (let c of children[0].children)
354
- walk(c, ctx, cols);
355
- __collect(acc, ctx.tags.tableRow(ctx, cols));
356
- },
357
- ulitem: ({ children }, ctx, acc) => {
358
- const body = [];
359
- walk(children[2], ctx, body);
360
- __collect(acc, [
361
- "ulitem",
362
- __listItemAttribs(children[1]),
363
- ...body,
364
- ]);
365
- },
366
- });
367
- const __collect = (acc, x) => x != null && acc.push(x);
368
- const __withMeta = (target, meta) => {
369
- if (meta != null) {
370
- target.__meta = meta;
371
- }
372
- return target;
373
- };
374
- const __listItemAttribs = (scope) => scope?.id === "todo"
375
- ? {
376
- __todo: true,
377
- __done: scope.result === "x",
378
- }
379
- : {};