@p-buddy/parkdown 0.0.5 → 0.0.7
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 +26 -10
- package/dist/cli.js +8 -8
- package/dist/index.js +127 -113
- package/dist/index.umd.cjs +12 -11
- package/package.json +3 -5
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ populateMarkdownInclusions(file, writeFile);
|
|
|
44
44
|
|
|
45
45
|
[](./.assets/authoring.md)
|
|
46
46
|
<!-- p↓ BEGIN -->
|
|
47
|
-
<!-- p↓ length lines:
|
|
47
|
+
<!-- p↓ length lines: 574 chars: 17955 -->
|
|
48
48
|
## Authoring
|
|
49
49
|
|
|
50
50
|
You author inclusions in your markdown files using a link with no text i.e. `[](<url>)`, where `<url>` points to some local or remote text resource (e.g.`./other.md`, `https://example.com/remote.md`).
|
|
@@ -55,6 +55,8 @@ These links can be rendered either [inline](#inline) or [block](#block), dependi
|
|
|
55
55
|
|
|
56
56
|
Inline inclusions occur when your _text-less_ link has 1 or more siblings (meaning it's **not** the only node in a [paragraph](https://www.markdownguide.org/basic-syntax/#paragraphs-1)).
|
|
57
57
|
|
|
58
|
+
> **CAUTION:** [parkdown](https://www.npmjs.com/package/@p-buddy/parkdown) will not protect you from authoring inline inclusions that should actually be [block](#block) inclusions to be valid markdown.
|
|
59
|
+
|
|
58
60
|
There are two equivalent ways to author inline inclusions, [single-line](#single-line) or [multi-line](#multi-line), and which you choose depends solely on how you want your raw markdown to look (it will **not** affect the rendered output).
|
|
59
61
|
|
|
60
62
|
#### Single-line
|
|
@@ -254,7 +256,7 @@ Before...
|
|
|
254
256
|
|
|
255
257
|
[](.assets/query.md?heading=-1)
|
|
256
258
|
<!-- p↓ BEGIN -->
|
|
257
|
-
<!-- p↓ length lines:
|
|
259
|
+
<!-- p↓ length lines: 361 chars: 13249 -->
|
|
258
260
|
### Query parameters
|
|
259
261
|
|
|
260
262
|
You can pass query parameters to your inclusion links to control how their content is processed and included within your markdown.
|
|
@@ -294,6 +296,8 @@ Below is the currently supported API for the `region` query parameter, where eac
|
|
|
294
296
|
- `[](<url>?region=remove(some-specifier))`
|
|
295
297
|
- `[](<url>?region=replace(some-specifier,replacement-content))`
|
|
296
298
|
|
|
299
|
+
If no value(s) are included (e.g. `[](<url>?region)`), then simply all comments that contain `parkdown:` or `p↓:` will be stripped (as is done as a post-processing step for all other `region` functionality).
|
|
300
|
+
|
|
297
301
|
[](.assets/api-note.md?wrap=quote)
|
|
298
302
|
<!-- p↓ BEGIN -->
|
|
299
303
|
<!-- p↓ length lines: 9 chars: 352 -->
|
|
@@ -355,7 +359,7 @@ Skip the default processing behavior for the given type of file.
|
|
|
355
359
|
|
|
356
360
|
[](src/include.ts?wrap=dropdown(See-default-processing-behavior.)®ion=extract(Default-Behavior),replace(...))
|
|
357
361
|
<!-- p↓ BEGIN -->
|
|
358
|
-
<!-- p↓ length lines:
|
|
362
|
+
<!-- p↓ length lines: 21 chars: 525 -->
|
|
359
363
|
|
|
360
364
|
<details>
|
|
361
365
|
<summary>
|
|
@@ -364,11 +368,15 @@ See default processing behavior.
|
|
|
364
368
|
|
|
365
369
|
```ts
|
|
366
370
|
if (extension === "md") {
|
|
367
|
-
|
|
368
|
-
|
|
371
|
+
|
|
372
|
+
const getContent = extendGetRelativePathContent(getRelativePathContent, target);
|
|
373
|
+
const relative = basePath ? join(basePath, dir) : dir;
|
|
374
|
+
const depth = clampHeadingSum(headingDepth, Number(headingModfiier));
|
|
375
|
+
|
|
376
|
+
content = recursivelyPopulateInclusions(content, depth, getContent, path, relative);
|
|
369
377
|
}
|
|
370
378
|
else if (/^(js|ts)x?|svelte$/i.test(extension))
|
|
371
|
-
content = wrap(content, "code",
|
|
379
|
+
content = wrap(content, "code", { extension, inline });
|
|
372
380
|
```
|
|
373
381
|
|
|
374
382
|
</details>
|
|
@@ -422,6 +430,14 @@ If we instead wanted the included heading to remain a `h1` / `#` heading, we'd m
|
|
|
422
430
|
[](./to-be-included.md?heading=-1)
|
|
423
431
|
```
|
|
424
432
|
|
|
433
|
+
which would result in the following:
|
|
434
|
+
|
|
435
|
+
```md
|
|
436
|
+
# Heading
|
|
437
|
+
|
|
438
|
+
# Included Heading
|
|
439
|
+
```
|
|
440
|
+
|
|
425
441
|
</details>
|
|
426
442
|
|
|
427
443
|
#### `inline` (Advanced)
|
|
@@ -496,7 +512,7 @@ const definitions = [
|
|
|
496
512
|
|
|
497
513
|
[](.assets/api.md?heading=-1)
|
|
498
514
|
<!-- p↓ BEGIN -->
|
|
499
|
-
<!-- p↓ length lines: 104 chars:
|
|
515
|
+
<!-- p↓ length lines: 104 chars: 4973 -->
|
|
500
516
|
#### Query Parameters with Function-like APIs
|
|
501
517
|
|
|
502
518
|
Some query parameters have more complex APIs, which are defined by a collection of typescript function singatures (limited to only `string`, `boolean`, and `number` arguments), like:
|
|
@@ -570,7 +586,7 @@ const urlCharacters = {
|
|
|
570
586
|
|
|
571
587
|
[](src/utils.ts?region=extract(sanitize))
|
|
572
588
|
<!-- p↓ BEGIN -->
|
|
573
|
-
<!-- p↓ length lines: 29 chars:
|
|
589
|
+
<!-- p↓ length lines: 29 chars: 771 -->
|
|
574
590
|
|
|
575
591
|
```ts
|
|
576
592
|
type Replacement = [from: RegExp | string, to: string];
|
|
@@ -591,8 +607,8 @@ const replacements: Record<string, Replacement[]> = {
|
|
|
591
607
|
const applyReplacement = (accumulator: string, [from, to]: Replacement) =>
|
|
592
608
|
accumulator.replaceAll(from, to);
|
|
593
609
|
|
|
594
|
-
export const sanitize = (
|
|
595
|
-
const sanitized = replacements.static.reduce(applyReplacement,
|
|
610
|
+
export const sanitize = (content: string, space: string = DEFAULT_SPACE) => {
|
|
611
|
+
const sanitized = replacements.static.reduce(applyReplacement, content)
|
|
596
612
|
return replacements.url
|
|
597
613
|
.map(([key, to]) => ([space + key + space, to] satisfies Replacement))
|
|
598
614
|
.reduce(applyReplacement, sanitized)
|
package/dist/cli.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command as t } from "@commander-js/extra-typings";
|
|
3
|
-
import { populateMarkdownInclusions as
|
|
4
|
-
const
|
|
3
|
+
import { populateMarkdownInclusions as l, depopulateMarkdownInclusions as r } from "@p-buddy/parkdown";
|
|
4
|
+
const f = "0.0.7", p = new t().version(f).option("--nw, --no-write", "Do NOT write result to file (defaults to false)", !1).option("--ni, --no-inclusions", "Do NOT process file inclusions (defaults to false)", !1).option("-d, --depopulate", "Remove populated inclusions from the file", !1).option("-f, --file <flag>", "The file(s) to process", (s, o) => (o.push(s), o), new Array()).parse(), { inclusions: c, depopulate: u, file: n, write: i } = p.opts();
|
|
5
5
|
n.length === 0 && n.push("README.md");
|
|
6
|
-
const
|
|
7
|
-
[
|
|
8
|
-
[
|
|
6
|
+
const a = [
|
|
7
|
+
[l, !c],
|
|
8
|
+
[r, u]
|
|
9
9
|
];
|
|
10
|
-
for (const [
|
|
10
|
+
for (const [s] of a.filter(([o, e]) => e))
|
|
11
11
|
for (const o of n) {
|
|
12
|
-
const
|
|
13
|
-
i && console.log(
|
|
12
|
+
const e = s(o, !i);
|
|
13
|
+
i && console.log(e);
|
|
14
14
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,31 +1,29 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { writeFileSync as
|
|
5
|
-
import { basename as
|
|
6
|
-
import { URLSearchParams as
|
|
7
|
-
import { unified as
|
|
8
|
-
import
|
|
9
|
-
import { visit as
|
|
10
|
-
import
|
|
11
|
-
import { dedent as T } from "ts-dedent";
|
|
12
|
-
import we from "extract-comments";
|
|
1
|
+
var me = Object.defineProperty;
|
|
2
|
+
var ue = (e, t, n) => t in e ? me(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
|
|
3
|
+
var L = (e, t, n) => ue(e, typeof t != "symbol" ? t + "" : t, n);
|
|
4
|
+
import { writeFileSync as V, readFileSync as he } from "node:fs";
|
|
5
|
+
import { basename as ge, dirname as M, join as S, resolve as J } from "node:path";
|
|
6
|
+
import { URLSearchParams as fe } from "node:url";
|
|
7
|
+
import { unified as de } from "unified";
|
|
8
|
+
import we from "remark-parse";
|
|
9
|
+
import { visit as ve } from "unist-util-visit";
|
|
10
|
+
import { dedent as j } from "ts-dedent";
|
|
13
11
|
const g = (e, t) => e.position.start.offset - t.position.start.offset;
|
|
14
12
|
g.reverse = (e, t) => g(t, e);
|
|
15
|
-
const D = (e) => e.position !== void 0 && e.position.start.offset !== void 0 && e.position.end.offset !== void 0, $e =
|
|
13
|
+
const D = (e) => e.position !== void 0 && e.position.start.offset !== void 0 && e.position.end.offset !== void 0, $e = de().use(we), I = {
|
|
16
14
|
md: (e) => $e.parse(e)
|
|
17
|
-
},
|
|
15
|
+
}, N = (e, t) => {
|
|
18
16
|
const n = [];
|
|
19
|
-
return
|
|
17
|
+
return ve(e, (s, o, r) => {
|
|
20
18
|
if (s.type !== "root") {
|
|
21
19
|
if (t && s.type !== t) return;
|
|
22
20
|
if (D(s)) {
|
|
23
|
-
const i =
|
|
24
|
-
n.push({ ...s,
|
|
21
|
+
const i = ((r == null ? void 0 : r.children.length) ?? 0) - 1;
|
|
22
|
+
n.push({ ...s, siblingIndex: o, siblingCount: i });
|
|
25
23
|
}
|
|
26
24
|
}
|
|
27
25
|
}), n;
|
|
28
|
-
}, Ce = (e) => e.children.length === 0,
|
|
26
|
+
}, Ce = (e) => e.children.length === 0, Z = (e, t, ...n) => {
|
|
29
27
|
if (n.length === 0) throw new Error("No nodes to replace content from");
|
|
30
28
|
n.sort(g);
|
|
31
29
|
const s = n.at(0), o = n.at(-1);
|
|
@@ -37,10 +35,10 @@ const D = (e) => e.position !== void 0 && e.position.start.offset !== void 0 &&
|
|
|
37
35
|
`), Se = (e) => {
|
|
38
36
|
const t = e.split("?");
|
|
39
37
|
return t.length > 1 ? [t.slice(0, -1).join("?"), t.at(-1)] : [e, ""];
|
|
40
|
-
},
|
|
38
|
+
}, Ne = (e) => Se(e)[0];
|
|
41
39
|
class d {
|
|
42
40
|
constructor() {
|
|
43
|
-
|
|
41
|
+
L(this, "intervals", []);
|
|
44
42
|
}
|
|
45
43
|
push(t, n) {
|
|
46
44
|
this.intervals.push([Math.min(t, n), Math.max(t, n)]);
|
|
@@ -78,7 +76,7 @@ class d {
|
|
|
78
76
|
return this.intervals = o;
|
|
79
77
|
}
|
|
80
78
|
}
|
|
81
|
-
const
|
|
79
|
+
const q = /,\s*(?![^()]*\))/, B = {
|
|
82
80
|
reserved: {
|
|
83
81
|
semi: ";",
|
|
84
82
|
slash: "/",
|
|
@@ -104,7 +102,7 @@ const L = /,\s*(?![^()]*\))/, W = {
|
|
|
104
102
|
unsquare: "]",
|
|
105
103
|
tick: "`"
|
|
106
104
|
}
|
|
107
|
-
},
|
|
105
|
+
}, xe = "-", F = {
|
|
108
106
|
static: [
|
|
109
107
|
["'''", '"'],
|
|
110
108
|
["''", "'"],
|
|
@@ -112,24 +110,24 @@ const L = /,\s*(?![^()]*\))/, W = {
|
|
|
112
110
|
[/p↓:\s+/g, ""]
|
|
113
111
|
],
|
|
114
112
|
url: [
|
|
115
|
-
...Object.entries(
|
|
116
|
-
...Object.entries(
|
|
113
|
+
...Object.entries(B.unsafe),
|
|
114
|
+
...Object.entries(B.reserved)
|
|
117
115
|
]
|
|
118
|
-
},
|
|
119
|
-
const n =
|
|
120
|
-
return
|
|
121
|
-
}, ke = ["string", "number", "boolean"],
|
|
122
|
-
const t = e.match(
|
|
116
|
+
}, U = (e, [t, n]) => e.replaceAll(t, n), K = (e, t = xe) => {
|
|
117
|
+
const n = F.static.reduce(U, e);
|
|
118
|
+
return F.url.map(([s, o]) => [t + s + t, o]).reduce(U, n).replaceAll(t, " ");
|
|
119
|
+
}, ke = ["string", "number", "boolean"], be = (e) => ke.includes(e), _e = /^([a-zA-Z0-9_-]+)(?:\(([^)]*)\))?$/, Te = (e) => {
|
|
120
|
+
const t = e.match(_e);
|
|
123
121
|
if (!t) throw new Error(`Invalid invocation: ${e}`);
|
|
124
122
|
const [, n, s = ""] = t;
|
|
125
123
|
if (!s.trim()) return { name: n, parameters: [] };
|
|
126
|
-
const o =
|
|
124
|
+
const o = Me(s);
|
|
127
125
|
return { name: n, parameters: o };
|
|
128
126
|
}, Oe = (e, t) => {
|
|
129
127
|
for (let n = t + 1; n < e.length; n++)
|
|
130
128
|
if (e[n] !== void 0) return !1;
|
|
131
129
|
return !0;
|
|
132
|
-
},
|
|
130
|
+
}, Me = (e) => {
|
|
133
131
|
const t = [];
|
|
134
132
|
let n = "", s = !1;
|
|
135
133
|
for (let o = 0; o < e.length; o++) {
|
|
@@ -139,11 +137,11 @@ const L = /,\s*(?![^()]*\))/, W = {
|
|
|
139
137
|
s = !s, n += c ? "'''" : "''", o += c ? 2 : 1;
|
|
140
138
|
} else i ? (s = !s, n += r) : r === "," && !s ? (t.push(n.trim()), n = "") : n += r;
|
|
141
139
|
}
|
|
142
|
-
return t.push(n.trim()), t.map((o) => o === "" ? void 0 : o ?
|
|
143
|
-
},
|
|
140
|
+
return t.push(n.trim()), t.map((o) => o === "" ? void 0 : o ? je(o) : void 0).filter((o, r, i) => o !== void 0 || !Oe(i, r));
|
|
141
|
+
}, je = (e) => {
|
|
144
142
|
const t = e.length >= 2 && e[0] === "'" && e.at(-1) === "'", n = t && e.length >= 4 && e[1] === "'" && e.at(-2) === "'";
|
|
145
143
|
return !t || n ? e : e.slice(1, -1);
|
|
146
|
-
},
|
|
144
|
+
}, De = (e) => {
|
|
147
145
|
const t = /^(\w+)(?:\(([^)]*)\))?/, n = e.match(t);
|
|
148
146
|
if (!n) return { name: e };
|
|
149
147
|
const [, s, o] = n;
|
|
@@ -152,17 +150,17 @@ const L = /,\s*(?![^()]*\))/, W = {
|
|
|
152
150
|
let c;
|
|
153
151
|
for (; (c = r.exec(o)) !== null; ) {
|
|
154
152
|
const [, l, a, p] = c, m = p.trim();
|
|
155
|
-
if (!
|
|
153
|
+
if (!be(m)) throw new Error(`Unsupported type: ${m}`);
|
|
156
154
|
i.push({ name: l, optional: a === "?", type: m });
|
|
157
155
|
}
|
|
158
156
|
return { name: s, parameters: i };
|
|
159
|
-
},
|
|
160
|
-
const t = e.map(
|
|
157
|
+
}, Y = (e) => {
|
|
158
|
+
const t = e.map(De).reduce(
|
|
161
159
|
(n, { name: s, parameters: o }) => n.set(s, o),
|
|
162
160
|
/* @__PURE__ */ new Map()
|
|
163
161
|
);
|
|
164
162
|
return (n) => {
|
|
165
|
-
const { name: s, parameters: o } =
|
|
163
|
+
const { name: s, parameters: o } = Te(n);
|
|
166
164
|
if (!t.has(s))
|
|
167
165
|
throw new Error(`Unknown method: ${s}`);
|
|
168
166
|
const r = t.get(s);
|
|
@@ -192,7 +190,7 @@ const L = /,\s*(?![^()]*\))/, W = {
|
|
|
192
190
|
return i;
|
|
193
191
|
}, { name: s });
|
|
194
192
|
};
|
|
195
|
-
},
|
|
193
|
+
}, G = (e) => Object.entries(e).filter(([t]) => t !== "name" && !isNaN(Number(t))).map(([t, n]) => n), Ie = [
|
|
196
194
|
/**
|
|
197
195
|
* Wraps the content in a markdown-formatted code block.
|
|
198
196
|
* @param lang The language of the code block (defaults to the file extension).
|
|
@@ -222,9 +220,9 @@ const L = /,\s*(?![^()]*\))/, W = {
|
|
|
222
220
|
* @example [](<url>?wrap=dropdown(hello_world,,_))
|
|
223
221
|
*/
|
|
224
222
|
"dropdown(summary: string, open?: boolean, space?: string)"
|
|
225
|
-
], Re =
|
|
223
|
+
], Re = Y(Ie), f = (e, t = 1) => `
|
|
226
224
|
`.repeat(t) + e + `
|
|
227
|
-
`.repeat(t),
|
|
225
|
+
`.repeat(t), O = (e, t, n) => `<${t}${n ? ` ${n}` : ""}>${f(e)}</${t}>`, H = (e, t, n) => {
|
|
228
226
|
const s = Re(t);
|
|
229
227
|
switch (s.name) {
|
|
230
228
|
case "code":
|
|
@@ -235,13 +233,21 @@ const L = /,\s*(?![^()]*\))/, W = {
|
|
|
235
233
|
case "quote":
|
|
236
234
|
return n != null && n.inline && !e.includes(`
|
|
237
235
|
|
|
238
|
-
`) ? `> ${e}` : f(
|
|
236
|
+
`) ? `> ${e}` : f(O(f(e), "blockquote"));
|
|
239
237
|
case "dropdown":
|
|
240
|
-
const c =
|
|
241
|
-
return f(
|
|
238
|
+
const c = O(K(s.summary), "summary");
|
|
239
|
+
return f(O([c, e].join(`
|
|
242
240
|
`), "details", s.open ? "open" : void 0));
|
|
243
241
|
}
|
|
244
|
-
},
|
|
242
|
+
}, R = (e) => {
|
|
243
|
+
const t = /(\/\/[^\n]*|\/\*[\s\S]*?\*\/|<!--[\s\S]*?-->)/gm, n = [];
|
|
244
|
+
let s;
|
|
245
|
+
for (; (s = t.exec(e)) !== null; ) {
|
|
246
|
+
const o = [s.index, s.index + s[0].length], r = Ae(s[0]).trim();
|
|
247
|
+
n.push({ range: o, value: r });
|
|
248
|
+
}
|
|
249
|
+
return n;
|
|
250
|
+
}, Ae = (e) => e.startsWith("//") ? e.slice(2) : e.startsWith("/*") ? e.slice(2, -2) : e.startsWith("<!--") ? e.slice(4, -3) : e, Pe = [
|
|
245
251
|
/**
|
|
246
252
|
* Extract regions from the retrieved content between comments that INCLUDE the specified ids.
|
|
247
253
|
* @param id The id of the comment to extract.
|
|
@@ -272,24 +278,24 @@ const L = /,\s*(?![^()]*\))/, W = {
|
|
|
272
278
|
* @example [](<url>?region=replace(specifier,new_content,_)
|
|
273
279
|
*/
|
|
274
280
|
"replace(id: string, with?: string, space?: string)"
|
|
275
|
-
],
|
|
281
|
+
], We = Y(Pe), x = (e, t) => R(e).filter(({ value: n }) => n.includes(t)).sort((n, s) => n.range[0] - s.range[0]), Le = (e, ...t) => {
|
|
276
282
|
if (t.length === 0) return e;
|
|
277
|
-
const n = ([i, c]) => e.slice(i, c), s =
|
|
283
|
+
const n = ([i, c]) => e.slice(i, c), s = R(e), o = new d(), r = new d();
|
|
278
284
|
for (const i of t) {
|
|
279
285
|
const c = s.filter(({ value: l }) => l.includes(i)).sort((l, a) => l.range[0] - a.range[0]);
|
|
280
286
|
for (let l = 0; l < c.length - 1; l += 2) {
|
|
281
287
|
const a = c[l], p = c[l + 1];
|
|
282
288
|
o.push(a.range[1], p.range[0]);
|
|
283
|
-
const [m, ...y] = n([a.range[1], p.range[0]]),
|
|
284
|
-
r.push(a.range[0], a.range[1] + (m.trim() ? 0 : 1)), r.push(p.range[0], p.range[1] + (
|
|
289
|
+
const [m, ...y] = n([a.range[1], p.range[0]]), w = y[y.length - 1];
|
|
290
|
+
r.push(a.range[0], a.range[1] + (m.trim() ? 0 : 1)), r.push(p.range[0], p.range[1] + (w.trim() ? 0 : 1));
|
|
285
291
|
}
|
|
286
292
|
}
|
|
287
|
-
return o.collapse(), r.collapse(),
|
|
293
|
+
return o.collapse(), r.collapse(), j(
|
|
288
294
|
o.subtract(r).map(n).filter(Boolean).join("")
|
|
289
295
|
).trim();
|
|
290
|
-
},
|
|
296
|
+
}, qe = (e, ...t) => {
|
|
291
297
|
if (t.length === 0) return e;
|
|
292
|
-
const n = ([i, c]) => e.slice(i, c), s =
|
|
298
|
+
const n = ([i, c]) => e.slice(i, c), s = R(e), o = new d();
|
|
293
299
|
for (const i of t) {
|
|
294
300
|
const c = s.filter(({ value: l }) => l.includes(i)).sort((l, a) => l.range[0] - a.range[0]);
|
|
295
301
|
for (let l = 0; l < c.length - 1; l += 2) {
|
|
@@ -300,40 +306,48 @@ const L = /,\s*(?![^()]*\))/, W = {
|
|
|
300
306
|
}
|
|
301
307
|
o.collapse();
|
|
302
308
|
const r = new d();
|
|
303
|
-
return r.push(0, e.length), r.subtract(o),
|
|
309
|
+
return r.push(0, e.length), r.subtract(o), j(
|
|
304
310
|
r.collapse().map(n).filter(Boolean).join("")
|
|
305
311
|
).trim();
|
|
306
|
-
},
|
|
312
|
+
}, Be = (e, t, n, s) => {
|
|
307
313
|
if (!t) return e;
|
|
308
|
-
const o =
|
|
314
|
+
const o = x(e, t);
|
|
309
315
|
if (o.length < 2) return e;
|
|
310
316
|
let r = "", i = 0;
|
|
311
317
|
for (let l = 0; l < o.length - 1; l += 2) {
|
|
312
318
|
const a = o[l], p = o[l + 1];
|
|
313
|
-
r += e.slice(i, a.range[1]), r +=
|
|
319
|
+
r += e.slice(i, a.range[1]), r += K(n ?? a.value, s), i = p.range[0];
|
|
314
320
|
}
|
|
315
321
|
r += e.slice(i);
|
|
316
322
|
const c = new d();
|
|
317
323
|
return c.push(0, r.length), c.subtract(
|
|
318
|
-
|
|
319
|
-
),
|
|
324
|
+
x(r, t).reduce((l, { range: a }) => (l.push(...a), l), new d())
|
|
325
|
+
), j(
|
|
320
326
|
c.collapse().map(([l, a]) => r.slice(l, a)).filter(Boolean).join("")
|
|
321
327
|
).trim();
|
|
322
|
-
},
|
|
323
|
-
|
|
328
|
+
}, Q = (e) => ({ isSpace: e === " ", isNewline: e === `
|
|
329
|
+
` || e === void 0 }), z = (e) => [
|
|
330
|
+
...x(e, "p↓:"),
|
|
331
|
+
...x(e, "parkdown:")
|
|
332
|
+
].sort((t, n) => t.range[0] - n.range[0]).reverse().reduce((t, { range: [n, s], value: o }) => {
|
|
333
|
+
const r = (a, p) => t.slice(0, a) + t.slice(p), i = Q(t[n - 1]), c = Q(t[s]), l = s === t.length;
|
|
334
|
+
return i.isNewline && c.isNewline ? r(n - (l ? 1 : 0), s + 1) : i.isNewline ? r(n, s + (c.isSpace ? 1 : 0)) : r(n - (i.isSpace ? 1 : 0), s);
|
|
335
|
+
}, e), Fe = (e, t) => {
|
|
336
|
+
if (!t) return z(e);
|
|
337
|
+
const n = We(t);
|
|
324
338
|
switch (n.name) {
|
|
325
339
|
case "extract":
|
|
326
|
-
e =
|
|
340
|
+
e = Le(e, n.id, ...G(n));
|
|
327
341
|
break;
|
|
328
342
|
case "remove":
|
|
329
|
-
e =
|
|
343
|
+
e = qe(e, n.id, ...G(n));
|
|
330
344
|
break;
|
|
331
345
|
case "replace":
|
|
332
|
-
e =
|
|
346
|
+
e = Be(e, n.id, n.with, n.space);
|
|
333
347
|
break;
|
|
334
348
|
}
|
|
335
|
-
return e;
|
|
336
|
-
},
|
|
349
|
+
return z(e);
|
|
350
|
+
}, Ue = ["http", "./", "../"], Ge = ({ url: e }) => Ue.some((t) => e.startsWith(t)), He = (e) => D(e) && Ce(e) && Ge(e), ee = ({ url: e }, t) => `[](${t ? S(t, e) : e})`, u = {
|
|
337
351
|
_open: "<!--",
|
|
338
352
|
_close: "-->",
|
|
339
353
|
_flag: "p↓",
|
|
@@ -348,14 +362,14 @@ const L = /,\s*(?![^()]*\))/, W = {
|
|
|
348
362
|
`).length}`, n = `chars: ${e.length}`;
|
|
349
363
|
return E(u._open, u._flag, "length", t, n, u._close);
|
|
350
364
|
}
|
|
351
|
-
},
|
|
352
|
-
|
|
365
|
+
}, X = (e) => (t) => D(t) && t.value === u[e], Qe = ({ position: e, url: t, siblingCount: n }, s) => ({ position: e, url: t, headingDepth: s, inline: n >= 1 }), ze = ({ position: { start: e }, url: t, siblingCount: n }, { position: { end: s } }, o) => ({ position: { start: e, end: s }, url: t, headingDepth: o, inline: n >= 1 }), Xe = (e, t, n) => (e.inline ? E : Ee)(
|
|
366
|
+
ee(e, n),
|
|
353
367
|
u.begin,
|
|
354
368
|
u.lengthOf(t),
|
|
355
369
|
t,
|
|
356
370
|
u.end
|
|
357
|
-
),
|
|
358
|
-
const t =
|
|
371
|
+
), Ve = (e) => {
|
|
372
|
+
const t = N(e, "heading").reduce((n, { position: s, depth: o }) => n.set(s.start.line, o), /* @__PURE__ */ new Map());
|
|
359
373
|
return (n) => {
|
|
360
374
|
for (let s = n.position.start.line; s >= 1; s--) {
|
|
361
375
|
const o = t.get(s);
|
|
@@ -363,7 +377,7 @@ const L = /,\s*(?![^()]*\))/, W = {
|
|
|
363
377
|
}
|
|
364
378
|
return 0;
|
|
365
379
|
};
|
|
366
|
-
},
|
|
380
|
+
}, k = {
|
|
367
381
|
openingCommentDoesNotFollowLink: ({ position: { start: e } }) => new Error(`Opening comment (@${e.line}:${e.column}) does not follow link`),
|
|
368
382
|
closingCommentNotMatchedToOpening: ({ position: { start: e } }) => new Error(`Closing comment (@${e.line}:${e.column}) does not match to opening comment`),
|
|
369
383
|
openingCommentNotClosed: ({ position: { start: e } }) => new Error(`Opening comment (@${e.line}:${e.column}) is not followed by a closing comment`)
|
|
@@ -377,96 +391,96 @@ const L = /,\s*(?![^()]*\))/, W = {
|
|
|
377
391
|
else {
|
|
378
392
|
const i = r.node;
|
|
379
393
|
if (o.length === 0)
|
|
380
|
-
throw
|
|
394
|
+
throw k.closingCommentNotMatchedToOpening(i);
|
|
381
395
|
const c = o.pop().node;
|
|
382
396
|
if (o.length > 0) continue;
|
|
383
397
|
n.push({ open: c, close: i });
|
|
384
398
|
}
|
|
385
399
|
if (o.length > 0)
|
|
386
|
-
throw
|
|
400
|
+
throw k.openingCommentNotClosed(o[0].node);
|
|
387
401
|
return n;
|
|
388
|
-
},
|
|
402
|
+
}, Ze = (e, t, n) => {
|
|
389
403
|
const s = [...t].sort(g), o = [];
|
|
390
404
|
return [...n].sort((r, i) => g.reverse(r.open, i.open)).forEach((r) => {
|
|
391
405
|
for (; s.length > 0; ) {
|
|
392
406
|
const i = s.pop();
|
|
393
407
|
if (i.position.start.offset < r.open.position.start.offset) {
|
|
394
408
|
if (ye(e, i, r.open).trim() !== "")
|
|
395
|
-
throw
|
|
409
|
+
throw k.openingCommentDoesNotFollowLink(r.open);
|
|
396
410
|
return o.push([i, r]);
|
|
397
411
|
}
|
|
398
412
|
o.push(i);
|
|
399
413
|
}
|
|
400
|
-
throw
|
|
414
|
+
throw k.openingCommentDoesNotFollowLink(r.open);
|
|
401
415
|
}), o.push(...s.reverse()), o.reverse();
|
|
402
|
-
},
|
|
416
|
+
}, te = (e, t) => {
|
|
403
417
|
t ?? (t = I.md(e));
|
|
404
|
-
const n =
|
|
405
|
-
return
|
|
406
|
-
},
|
|
418
|
+
const n = Ve(t), s = N(t, "link").filter(He), o = N(t, "html").sort(g), r = o.filter(X("begin")), i = o.filter(X("end")), c = Je(r, i);
|
|
419
|
+
return Ze(e, s, c).map((a) => Array.isArray(a) ? ze(a[0], a[1].close, n(a[0])) : Qe(a, n(a)));
|
|
420
|
+
}, Ke = (e, { url: t }) => (n) => e(S(M(t), n)), ne = (...e) => {
|
|
407
421
|
const t = e.reduce((n, s) => n + s, 0);
|
|
408
422
|
return Math.min(Math.max(t, 1), 6);
|
|
409
|
-
},
|
|
423
|
+
}, Ye = (e, t, n) => {
|
|
410
424
|
if (t === 0) return e;
|
|
411
425
|
n ?? (n = I.md(e));
|
|
412
|
-
const s =
|
|
426
|
+
const s = N(n, "heading"), o = e.split(`
|
|
413
427
|
`);
|
|
414
428
|
for (const r of s) {
|
|
415
|
-
const { depth: i, position: { start: c, end: l } } = r, a =
|
|
429
|
+
const { depth: i, position: { start: c, end: l } } = r, a = ne(i, t), p = o[c.line - 1].slice(i, l.column), m = "#".repeat(a) + p;
|
|
416
430
|
o[c.line - 1] = m, r.depth = a;
|
|
417
431
|
}
|
|
418
432
|
return o.join(`
|
|
419
433
|
`);
|
|
420
|
-
},
|
|
434
|
+
}, se = (e) => te(e).reverse().sort(g.reverse).reduce((t, n) => Z(t, ee(n), n), e), oe = (e, t, n, s, o) => {
|
|
421
435
|
try {
|
|
422
|
-
e =
|
|
436
|
+
e = se(e), e = Ye(e, t);
|
|
423
437
|
const r = I.md(e);
|
|
424
|
-
return
|
|
425
|
-
var
|
|
426
|
-
const { url: c, headingDepth: l } = i, [a, ...p] =
|
|
438
|
+
return te(e, r).sort(g).reverse().map((i) => {
|
|
439
|
+
var P, W;
|
|
440
|
+
const { url: c, headingDepth: l } = i, [a, ...p] = ge(c).split("?"), m = a.split(".").pop() ?? "", y = p.join("?"), w = M(c), A = S(w, a);
|
|
427
441
|
if (c.startsWith("./") || c.startsWith("../")) {
|
|
428
|
-
let h = n(
|
|
429
|
-
const
|
|
430
|
-
h = (
|
|
431
|
-
const
|
|
432
|
-
let { inline:
|
|
433
|
-
if (
|
|
442
|
+
let h = n(A);
|
|
443
|
+
const v = new fe(y), b = (P = v.get("region")) == null ? void 0 : P.split(q);
|
|
444
|
+
h = (b == null ? void 0 : b.reduce(($, C) => Fe($, C), h)) ?? h;
|
|
445
|
+
const ce = v.has("skip"), le = v.get("heading") ?? 0, ae = v.has("inline");
|
|
446
|
+
let { inline: _ } = i;
|
|
447
|
+
if (ae && (_ = !0), !ce)
|
|
434
448
|
if (m === "md") {
|
|
435
|
-
const $ =
|
|
436
|
-
h =
|
|
449
|
+
const $ = Ke(n, i), C = o ? S(o, w) : w, pe = ne(l, Number(le));
|
|
450
|
+
h = oe(
|
|
437
451
|
h,
|
|
438
452
|
/** p↓: ... */
|
|
439
|
-
|
|
453
|
+
pe,
|
|
440
454
|
$,
|
|
441
|
-
|
|
455
|
+
A,
|
|
442
456
|
C
|
|
443
457
|
/** p↓: ... */
|
|
444
458
|
);
|
|
445
|
-
} else /^(js|ts)x?|svelte$/i.test(m) && (h =
|
|
459
|
+
} else /^(js|ts)x?|svelte$/i.test(m) && (h = H(
|
|
446
460
|
h,
|
|
447
461
|
"code",
|
|
448
462
|
/** p↓: ... */
|
|
449
|
-
{ extension: m, inline:
|
|
463
|
+
{ extension: m, inline: _ }
|
|
450
464
|
/** p↓: ... */
|
|
451
465
|
));
|
|
452
|
-
const
|
|
453
|
-
return h = (
|
|
466
|
+
const T = (W = v.get("wrap")) == null ? void 0 : W.split(q);
|
|
467
|
+
return h = (T == null ? void 0 : T.reduce(($, C) => H($, C, { extension: m, inline: _ }), h)) ?? h, { target: i, content: Xe(i, h, o) };
|
|
454
468
|
} else throw c.startsWith("http") ? new Error("External web links are not implemented yet") : new Error(`Unsupported link type: ${c}`);
|
|
455
|
-
}).reduce((i, { target: c, content: l }) =>
|
|
469
|
+
}).reduce((i, { target: c, content: l }) => Z(i, l, c), e);
|
|
456
470
|
} catch (r) {
|
|
457
|
-
throw new Error(`Error populating inclusions in file ${s}: ${r}`);
|
|
471
|
+
throw new Error(`Error populating inclusions in file ${s ?? "(unknown)"}: ${r}`);
|
|
458
472
|
}
|
|
459
|
-
},
|
|
460
|
-
const t =
|
|
461
|
-
return { markdown:
|
|
473
|
+
}, re = (e) => he(e, "utf-8"), ie = (e) => {
|
|
474
|
+
const t = J(e), n = M(t);
|
|
475
|
+
return { markdown: re(t), dir: n, path: t };
|
|
476
|
+
}, lt = (e, t = !0) => {
|
|
477
|
+
const { dir: n, path: s, markdown: o } = ie(e), i = oe(o, 0, (c) => re(J(n, Ne(c))), s);
|
|
478
|
+
return t && V(s, i), i;
|
|
462
479
|
}, at = (e, t = !0) => {
|
|
463
|
-
const {
|
|
464
|
-
return t &&
|
|
465
|
-
}, pt = (e, t = !0) => {
|
|
466
|
-
const { path: n, markdown: s } = se(e), o = te(s);
|
|
467
|
-
return t && z(n, o), o;
|
|
480
|
+
const { path: n, markdown: s } = ie(e), o = se(s);
|
|
481
|
+
return t && V(n, o), o;
|
|
468
482
|
};
|
|
469
483
|
export {
|
|
470
|
-
|
|
471
|
-
|
|
484
|
+
at as depopulateMarkdownInclusions,
|
|
485
|
+
lt as populateMarkdownInclusions
|
|
472
486
|
};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
(function(
|
|
2
|
-
`),
|
|
3
|
-
`.repeat(
|
|
4
|
-
`.repeat(
|
|
5
|
-
`))return`\`${e}\``;const r=
|
|
1
|
+
(function(u,d){typeof exports=="object"&&typeof module<"u"?d(exports,require("node:fs"),require("node:path"),require("node:url"),require("unified"),require("remark-parse"),require("unist-util-visit"),require("ts-dedent")):typeof define=="function"&&define.amd?define(["exports","node:fs","node:path","node:url","unified","remark-parse","unist-util-visit","ts-dedent"],d):(u=typeof globalThis<"u"?globalThis:u||self,d(u.index={},u.node_fs,u.node_path,u.node_url,u.unified,u.remarkParse,u.unistUtilVisit,u.tsDedent))})(this,function(u,d,h,ie,ce,le,ae,j){"use strict";var Xe=Object.defineProperty;var Je=(u,d,h)=>d in u?Xe(u,d,{enumerable:!0,configurable:!0,writable:!0,value:h}):u[d]=h;var re=(u,d,h)=>Je(u,typeof d!="symbol"?d+"":d,h);const v=(e,n)=>e.position.start.offset-n.position.start.offset;v.reverse=(e,n)=>v(n,e);const M=e=>e.position!==void 0&&e.position.start.offset!==void 0&&e.position.end.offset!==void 0,pe=ce.unified().use(le),O={md:e=>pe.parse(e)},k=(e,n)=>{const t=[];return ae.visit(e,(s,o,r)=>{if(s.type!=="root"){if(n&&s.type!==n)return;if(M(s)){const i=((r==null?void 0:r.children.length)??0)-1;t.push({...s,siblingIndex:o,siblingCount:i})}}}),t},ue=e=>e.children.length===0,D=(e,n,...t)=>{if(t.length===0)throw new Error("No nodes to replace content from");t.sort(v);const s=t.at(0),o=t.at(-1);return e.slice(0,s.position.start.offset)+n+e.slice(o.position.end.offset)},me=(e,n,t)=>{const s=Math.min(n.position.end.offset,t.position.end.offset),o=Math.max(n.position.start.offset,t.position.start.offset);return e.slice(s,o)},N=(...e)=>e.join(" "),de=(...e)=>e.join(`
|
|
2
|
+
`),he=e=>{const n=e.split("?");return n.length>1?[n.slice(0,-1).join("?"),n.at(-1)]:[e,""]},fe=e=>he(e)[0];class w{constructor(){re(this,"intervals",[])}push(n,t){this.intervals.push([Math.min(n,t),Math.max(n,t)])}combine(n){this.intervals.push(...n.intervals)}collapse(){const{intervals:n}=this;if(!n.length)return this.intervals=[];n.sort((r,i)=>r[0]-i[0]);const t=[];let[s,o]=n[0];for(let r=1;r<n.length;r++){const[i,c]=n[r];i<=o?o=Math.max(o,c):(t.push([s,o]),s=i,o=c)}return t.push([s,o]),this.intervals=t}subtract(n){const{intervals:t}=this,{intervals:s}=n;if(!t.length||!s.length)return t;let o=[...t];for(const[r,i]of s){const c=[];for(const[l,a]of o){if(i<=l||r>=a){c.push([l,a]);continue}r>l&&c.push([l,r]),i<a&&c.push([i,a])}o=c}return this.intervals=o}}const W=/,\s*(?![^()]*\))/,_={reserved:{semi:";",slash:"/",question:"?",colon:":",at:"@",equal:"=",and:"&"},unsafe:{quote:'"',angle:"<",unangle:">",hash:"#",percent:"%",curly:"{",uncurly:"}",pipe:"|",back:"\\",carrot:"^",tilde:"~",square:"[",unsquare:"]",tick:"`"}},ge="-",L={static:[["'''",'"'],["''","'"],[/parkdown:\s+/g,""],[/p↓:\s+/g,""]],url:[...Object.entries(_.unsafe),...Object.entries(_.reserved)]},B=(e,[n,t])=>e.replaceAll(n,t),F=(e,n=ge)=>{const t=L.static.reduce(B,e);return L.url.map(([s,o])=>[n+s+n,o]).reduce(B,t).replaceAll(n," ")},ve=["string","number","boolean"],we=e=>ve.includes(e),$e=/^([a-zA-Z0-9_-]+)(?:\(([^)]*)\))?$/,Ce=e=>{const n=e.match($e);if(!n)throw new Error(`Invalid invocation: ${e}`);const[,t,s=""]=n;if(!s.trim())return{name:t,parameters:[]};const o=Se(s);return{name:t,parameters:o}},ye=(e,n)=>{for(let t=n+1;t<e.length;t++)if(e[t]!==void 0)return!1;return!0},Se=e=>{const n=[];let t="",s=!1;for(let o=0;o<e.length;o++){const r=e[o],i=r==="'";if(i&&e.at(o+1)==="'"){const c=e.at(o+2)==="'";s=!s,t+=c?"'''":"''",o+=c?2:1}else i?(s=!s,t+=r):r===","&&!s?(n.push(t.trim()),t=""):t+=r}return n.push(t.trim()),n.map(o=>o===""?void 0:o?Ee(o):void 0).filter((o,r,i)=>o!==void 0||!ye(i,r))},Ee=e=>{const n=e.length>=2&&e[0]==="'"&&e.at(-1)==="'",t=n&&e.length>=4&&e[1]==="'"&&e.at(-2)==="'";return!n||t?e:e.slice(1,-1)},ke=e=>{const n=/^(\w+)(?:\(([^)]*)\))?/,t=e.match(n);if(!t)return{name:e};const[,s,o]=t;if(!o)return{name:s};const r=/(\w+)(\?)?:\s*([^,]+)/g,i=[];let c;for(;(c=r.exec(o))!==null;){const[,l,a,p]=c,m=p.trim();if(!we(m))throw new Error(`Unsupported type: ${m}`);i.push({name:l,optional:a==="?",type:m})}return{name:s,parameters:i}},U=e=>{const n=e.map(ke).reduce((t,{name:s,parameters:o})=>t.set(s,o),new Map);return t=>{const{name:s,parameters:o}=Ce(t);if(!n.has(s))throw new Error(`Unknown method: ${s}`);const r=n.get(s);if(r===void 0)return{name:s};if(o.length>r.length){const i=r.filter(({optional:l})=>!l).length,c=i===r.length?i.toString():`${i} - ${r.length}`;throw new Error(`Too many parameters: ${o.length} for method '${s}' (expected: ${c})`)}return r.reduce((i,{name:c,optional:l,type:a},p)=>{const m=o[p];if(m===void 0){if(l)return i;throw new Error(`Missing required parameter: ${c} for method '${s}'`)}switch(a){case"string":i[c]=m;break;case"number":case"boolean":i[c]=JSON.parse(m);break}if(typeof i[c]!==a)throw new Error(`Invalid type: ${c} must be ${a}, got ${typeof i[c]} for method '${s}'`);return i},{name:s})}},G=e=>Object.entries(e).filter(([n])=>n!=="name"&&!isNaN(Number(n))).map(([n,t])=>t),Ne=U(["code(lang?: string, meta?: string)","quote()","dropdown(summary: string, open?: boolean, space?: string)"]),$=(e,n=1)=>`
|
|
3
|
+
`.repeat(n)+e+`
|
|
4
|
+
`.repeat(n),q=(e,n,t)=>`<${n}${t?` ${t}`:""}>${$(e)}</${n}>`,H=(e,n,t)=>{const s=Ne(n);switch(s.name){case"code":if(!s.lang&&!s.meta&&(t==null?void 0:t.inline)&&!e.includes(`
|
|
5
|
+
`))return`\`${e}\``;const r=s.lang??(t==null?void 0:t.extension)??"",i=s.meta?` ${s.meta}`:"";return $(`\`\`\`${r}${i}${$(e)}\`\`\``);case"quote":return t!=null&&t.inline&&!e.includes(`
|
|
6
6
|
|
|
7
|
-
`)?`> ${e}`:$(
|
|
8
|
-
`),"details",
|
|
9
|
-
`?
|
|
10
|
-
|
|
11
|
-
`);for(const
|
|
12
|
-
`)
|
|
7
|
+
`)?`> ${e}`:$(q($(e),"blockquote"));case"dropdown":const c=q(F(s.summary),"summary");return $(q([c,e].join(`
|
|
8
|
+
`),"details",s.open?"open":void 0))}},I=e=>{const n=/(\/\/[^\n]*|\/\*[\s\S]*?\*\/|<!--[\s\S]*?-->)/gm,t=[];let s;for(;(s=n.exec(e))!==null;){const o=[s.index,s.index+s[0].length],r=xe(s[0]).trim();t.push({range:o,value:r})}return t},xe=e=>e.startsWith("//")?e.slice(2):e.startsWith("/*")?e.slice(2,-2):e.startsWith("<!--")?e.slice(4,-3):e,Te=U(["extract(id: string, 0?: string, 1?: string, 2?: string)","remove(id: string, 0?: string, 1?: string, 2?: string)","replace(id: string, with?: string, space?: string)"]),x=(e,n)=>I(e).filter(({value:t})=>t.includes(n)).sort((t,s)=>t.range[0]-s.range[0]),be=(e,...n)=>{if(n.length===0)return e;const t=([i,c])=>e.slice(i,c),s=I(e),o=new w,r=new w;for(const i of n){const c=s.filter(({value:l})=>l.includes(i)).sort((l,a)=>l.range[0]-a.range[0]);for(let l=0;l<c.length-1;l+=2){const a=c[l],p=c[l+1];o.push(a.range[1],p.range[0]);const[m,...b]=t([a.range[1],p.range[0]]),C=b[b.length-1];r.push(a.range[0],a.range[1]+(m.trim()?0:1)),r.push(p.range[0],p.range[1]+(C.trim()?0:1))}}return o.collapse(),r.collapse(),j.dedent(o.subtract(r).map(t).filter(Boolean).join("")).trim()},je=(e,...n)=>{if(n.length===0)return e;const t=([i,c])=>e.slice(i,c),s=I(e),o=new w;for(const i of n){const c=s.filter(({value:l})=>l.includes(i)).sort((l,a)=>l.range[0]-a.range[0]);for(let l=0;l<c.length-1;l+=2){const a=c[l],p=c[l+1],m=t([p.range[1],p.range[1]+1]).at(-1);o.push(a.range[0],m===`
|
|
9
|
+
`?p.range[1]+1:p.range[1])}}o.collapse();const r=new w;return r.push(0,e.length),r.subtract(o),j.dedent(r.collapse().map(t).filter(Boolean).join("")).trim()},Me=(e,n,t,s)=>{if(!n)return e;const o=x(e,n);if(o.length<2)return e;let r="",i=0;for(let l=0;l<o.length-1;l+=2){const a=o[l],p=o[l+1];r+=e.slice(i,a.range[1]),r+=F(t??a.value,s),i=p.range[0]}r+=e.slice(i);const c=new w;return c.push(0,r.length),c.subtract(x(r,n).reduce((l,{range:a})=>(l.push(...a),l),new w)),j.dedent(c.collapse().map(([l,a])=>r.slice(l,a)).filter(Boolean).join("")).trim()},Q=e=>({isSpace:e===" ",isNewline:e===`
|
|
10
|
+
`||e===void 0}),z=e=>[...x(e,"p↓:"),...x(e,"parkdown:")].sort((n,t)=>n.range[0]-t.range[0]).reverse().reduce((n,{range:[t,s],value:o})=>{const r=(a,p)=>n.slice(0,a)+n.slice(p),i=Q(n[t-1]),c=Q(n[s]),l=s===n.length;return i.isNewline&&c.isNewline?r(t-(l?1:0),s+1):i.isNewline?r(t,s+(c.isSpace?1:0)):r(t-(i.isSpace?1:0),s)},e),Oe=(e,n)=>{if(!n)return z(e);const t=Te(n);switch(t.name){case"extract":e=be(e,t.id,...G(t));break;case"remove":e=je(e,t.id,...G(t));break;case"replace":e=Me(e,t.id,t.with,t.space);break}return z(e)},qe=["http","./","../"],Ie=({url:e})=>qe.some(n=>e.startsWith(n)),Pe=e=>M(e)&&ue(e)&&Ie(e),V=({url:e},n)=>`[](${n?h.join(n,e):e})`,f={_open:"<!--",_close:"-->",_flag:"p↓",get begin(){return N(f._open,f._flag,"BEGIN",f._close)},get end(){return N(f._open,f._flag,"END",f._close)},lengthOf(e){const n=`lines: ${e.split(`
|
|
11
|
+
`).length}`,t=`chars: ${e.length}`;return N(f._open,f._flag,"length",n,t,f._close)}},X=e=>n=>M(n)&&n.value===f[e],Re=({position:e,url:n,siblingCount:t},s)=>({position:e,url:n,headingDepth:s,inline:t>=1}),Ae=({position:{start:e},url:n,siblingCount:t},{position:{end:s}},o)=>({position:{start:e,end:s},url:n,headingDepth:o,inline:t>=1}),De=(e,n,t)=>(e.inline?N:de)(V(e,t),f.begin,f.lengthOf(n),n,f.end),We=e=>{const n=k(e,"heading").reduce((t,{position:s,depth:o})=>t.set(s.start.line,o),new Map);return t=>{for(let s=t.position.start.line;s>=1;s--){const o=n.get(s);if(o)return o}return 0}},T={openingCommentDoesNotFollowLink:({position:{start:e}})=>new Error(`Opening comment (@${e.line}:${e.column}) does not follow link`),closingCommentNotMatchedToOpening:({position:{start:e}})=>new Error(`Closing comment (@${e.line}:${e.column}) does not match to opening comment`),openingCommentNotClosed:({position:{start:e}})=>new Error(`Opening comment (@${e.line}:${e.column}) is not followed by a closing comment`)},_e=(e,n)=>{const t=[],s=[...e.map(r=>({node:r,type:"open"})),...n.map(r=>({node:r,type:"close"}))].sort((r,i)=>v(r.node,i.node)),o=[];for(const r of s)if(r.type==="open")o.push(r);else{const i=r.node;if(o.length===0)throw T.closingCommentNotMatchedToOpening(i);const c=o.pop().node;if(o.length>0)continue;t.push({open:c,close:i})}if(o.length>0)throw T.openingCommentNotClosed(o[0].node);return t},Le=(e,n,t)=>{const s=[...n].sort(v),o=[];return[...t].sort((r,i)=>v.reverse(r.open,i.open)).forEach(r=>{for(;s.length>0;){const i=s.pop();if(i.position.start.offset<r.open.position.start.offset){if(me(e,i,r.open).trim()!=="")throw T.openingCommentDoesNotFollowLink(r.open);return o.push([i,r])}o.push(i)}throw T.openingCommentDoesNotFollowLink(r.open)}),o.push(...s.reverse()),o.reverse()},J=(e,n)=>{n??(n=O.md(e));const t=We(n),s=k(n,"link").filter(Pe),o=k(n,"html").sort(v),r=o.filter(X("begin")),i=o.filter(X("end")),c=_e(r,i);return Le(e,s,c).map(a=>Array.isArray(a)?Ae(a[0],a[1].close,t(a[0])):Re(a,t(a)))},Be=(e,{url:n})=>t=>e(h.join(h.dirname(n),t)),Z=(...e)=>{const n=e.reduce((t,s)=>t+s,0);return Math.min(Math.max(n,1),6)},Fe=(e,n,t)=>{if(n===0)return e;t??(t=O.md(e));const s=k(t,"heading"),o=e.split(`
|
|
12
|
+
`);for(const r of s){const{depth:i,position:{start:c,end:l}}=r,a=Z(i,n),p=o[c.line-1].slice(i,l.column),m="#".repeat(a)+p;o[c.line-1]=m,r.depth=a}return o.join(`
|
|
13
|
+
`)},K=e=>J(e).reverse().sort(v.reverse).reduce((n,t)=>D(n,V(t),t),e),Y=(e,n,t,s,o)=>{try{e=K(e),e=Fe(e,n);const r=O.md(e);return J(e,r).sort(v).reverse().map(i=>{var se,oe;const{url:c,headingDepth:l}=i,[a,...p]=h.basename(c).split("?"),m=a.split(".").pop()??"",b=p.join("?"),C=h.dirname(c),te=h.join(C,a);if(c.startsWith("./")||c.startsWith("../")){let g=t(te);const y=new ie.URLSearchParams(b),P=(se=y.get("region"))==null?void 0:se.split(W);g=(P==null?void 0:P.reduce((S,E)=>Oe(S,E),g))??g;const He=y.has("skip"),Qe=y.get("heading")??0,ze=y.has("inline");let{inline:R}=i;if(ze&&(R=!0),!He)if(m==="md"){const S=Be(t,i),E=o?h.join(o,C):C,Ve=Z(l,Number(Qe));g=Y(g,Ve,S,te,E)}else/^(js|ts)x?|svelte$/i.test(m)&&(g=H(g,"code",{extension:m,inline:R}));const A=(oe=y.get("wrap"))==null?void 0:oe.split(W);return g=(A==null?void 0:A.reduce((S,E)=>H(S,E,{extension:m,inline:R}),g))??g,{target:i,content:De(i,g,o)}}else throw c.startsWith("http")?new Error("External web links are not implemented yet"):new Error(`Unsupported link type: ${c}`)}).reduce((i,{target:c,content:l})=>D(i,l,c),e)}catch(r){throw new Error(`Error populating inclusions in file ${s??"(unknown)"}: ${r}`)}},ee=e=>d.readFileSync(e,"utf-8"),ne=e=>{const n=h.resolve(e),t=h.dirname(n);return{markdown:ee(n),dir:t,path:n}},Ue=(e,n=!0)=>{const{dir:t,path:s,markdown:o}=ne(e),i=Y(o,0,c=>ee(h.resolve(t,fe(c))),s);return n&&d.writeFileSync(s,i),i},Ge=(e,n=!0)=>{const{path:t,markdown:s}=ne(e),o=K(s);return n&&d.writeFileSync(t,o),o};u.depopulateMarkdownInclusions=Ge,u.populateMarkdownInclusions=Ue,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@p-buddy/parkdown",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"private": false,
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.7",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"bin": "./dist/cli.js",
|
|
8
8
|
"files": [
|
|
@@ -24,10 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@commander-js/extra-typings": "^13.1.0",
|
|
27
|
-
"@flex-development/import-regex": "^3.0.0",
|
|
28
|
-
"extract-comments": "^1.1.0",
|
|
29
27
|
"remark-parse": "^11.0.0",
|
|
30
|
-
"stable-hash": "^0.0.4",
|
|
31
28
|
"ts-dedent": "^2.2.0",
|
|
32
29
|
"unified": "^11.0.5",
|
|
33
30
|
"unist-util-visit": "^5.0.0"
|
|
@@ -37,7 +34,8 @@
|
|
|
37
34
|
"build:cli": "vite build --config vite.cli.config.ts",
|
|
38
35
|
"build": "pnpm run build:lib && pnpm run build:cli",
|
|
39
36
|
"test": "vitest",
|
|
40
|
-
"test:run": "vitest run"
|
|
37
|
+
"test:run": "vitest run",
|
|
38
|
+
"cli": "npx tsx src/cli.ts"
|
|
41
39
|
},
|
|
42
40
|
"typings": "./dist/index.d.ts",
|
|
43
41
|
"exports": {
|