@dogsbay/format-asciidoc 0.2.0-beta.48
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 +40 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +239 -0
- package/dist/cli.js.map +1 -0
- package/dist/detect.d.ts +42 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/detect.js +56 -0
- package/dist/detect.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/inline-walker.d.ts +17 -0
- package/dist/inline-walker.d.ts.map +1 -0
- package/dist/inline-walker.js +167 -0
- package/dist/inline-walker.js.map +1 -0
- package/dist/loaders/antora.d.ts +3 -0
- package/dist/loaders/antora.d.ts.map +1 -0
- package/dist/loaders/antora.js +254 -0
- package/dist/loaders/antora.js.map +1 -0
- package/dist/loaders/asciibinder.d.ts +3 -0
- package/dist/loaders/asciibinder.d.ts.map +1 -0
- package/dist/loaders/asciibinder.js +206 -0
- package/dist/loaders/asciibinder.js.map +1 -0
- package/dist/loaders/master-adoc.d.ts +3 -0
- package/dist/loaders/master-adoc.d.ts.map +1 -0
- package/dist/loaders/master-adoc.js +168 -0
- package/dist/loaders/master-adoc.js.map +1 -0
- package/dist/loaders/plain.d.ts +3 -0
- package/dist/loaders/plain.d.ts.map +1 -0
- package/dist/loaders/plain.js +61 -0
- package/dist/loaders/plain.js.map +1 -0
- package/dist/loaders/types.d.ts +88 -0
- package/dist/loaders/types.d.ts.map +1 -0
- package/dist/loaders/types.js +2 -0
- package/dist/loaders/types.js.map +1 -0
- package/dist/loaders/util.d.ts +15 -0
- package/dist/loaders/util.d.ts.map +1 -0
- package/dist/loaders/util.js +49 -0
- package/dist/loaders/util.js.map +1 -0
- package/dist/parse.d.ts +110 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +116 -0
- package/dist/parse.js.map +1 -0
- package/dist/tree.d.ts +2 -0
- package/dist/tree.d.ts.map +1 -0
- package/dist/tree.js +2 -0
- package/dist/tree.js.map +1 -0
- package/dist/walker.d.ts +8 -0
- package/dist/walker.d.ts.map +1 -0
- package/dist/walker.js +193 -0
- package/dist/walker.js.map +1 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# @dogsbay/format-asciidoc
|
|
2
|
+
|
|
3
|
+
AsciiDoc format plugin for Dogsbay. Imports `.adoc` sources into `TreeNode[]` via a three-stage pipeline:
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
AsciiDoc source
|
|
7
|
+
→ @dogsbay/adoc2md-modular (per-file engine; AsciiDoc → Markdown + Minja directives)
|
|
8
|
+
→ @dogsbay/minja (resolve {{ vars }} / {% if %} / {% include %} against an attribute context)
|
|
9
|
+
→ markdown-it + walker (Markdown → Token[] → TreeNode[])
|
|
10
|
+
TreeNode[]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Each stage is independently testable. The pipeline preserves unresolved directives (via Minja's `undefinedBehavior: "preserve"`) so a downstream pass can finish substitution when more context becomes available.
|
|
14
|
+
|
|
15
|
+
## API
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import MarkdownIt from "markdown-it";
|
|
19
|
+
import { parseAsciidocToTree } from "@dogsbay/format-asciidoc";
|
|
20
|
+
|
|
21
|
+
const md = new MarkdownIt({ html: true, linkify: true });
|
|
22
|
+
const { tree, env } = await parseAsciidocToTree(md, adocSource, {
|
|
23
|
+
filePath: "/path/to/source.adoc", // base for include resolution
|
|
24
|
+
attributes: { product: "AAP", version: "2.5" },
|
|
25
|
+
envOverrides: { /* ... merged into env returned */ },
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Async — Minja's renderer is async (I/O for includes, timeout enforcement).
|
|
30
|
+
|
|
31
|
+
## Position in the platform
|
|
32
|
+
|
|
33
|
+
- **Each format owns its parse pipeline.** format-asciidoc does not depend on format-mkdocs; the convention in this repo is "every format converges on `TreeNode` independently" (see [`plans/format-asciidoc-import.md`](../../plans/format-asciidoc-import.md) Phase 6).
|
|
34
|
+
- Walker bootstrapped from format-mkdocs's walker as a starting reference. Diverges independently from there.
|
|
35
|
+
|
|
36
|
+
## Roadmap
|
|
37
|
+
|
|
38
|
+
- **Phase 7 (this package, current):** scaffold + `parseAsciidocToTree` + smoke tests.
|
|
39
|
+
- **Phase 8:** wire into the `dogsbay` CLI's `from:` enum + validate against AAP fixtures end-to-end.
|
|
40
|
+
- **Corpus loaders:** per-source-shape loaders (AsciiBinder topic maps, Antora playbooks, AAP master.adoc walk, plain .adoc) — see [`plans/asciidoc-corpus-loaders.md`](../../plans/asciidoc-corpus-loaders.md).
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,YAAY,EAMb,MAAM,gBAAgB,CAAC;AAqNxB,eAAO,MAAM,MAAM,EAAE,YAmBpB,CAAC"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FormatPlugin for AsciiDoc as a source format.
|
|
3
|
+
*
|
|
4
|
+
* Phase 9a — refactored to use the CorpusLoader registry. Topology
|
|
5
|
+
* discovery lives in `loaders/{plain,master-adoc,...}.ts`; this file
|
|
6
|
+
* orchestrates loader pick → enumerate → parse-per-file → assemble
|
|
7
|
+
* ExportPage[] + NavItem[] for the CLI.
|
|
8
|
+
*
|
|
9
|
+
* The plain loader is the default fallback (matches Phase 8a
|
|
10
|
+
* behaviour byte-for-byte). The master-adoc loader picks up AAP-style
|
|
11
|
+
* `master.adoc`-rooted titles. AsciiBinder (`_topic_map.yml`) and
|
|
12
|
+
* Antora (`antora-playbook.yml`) loaders ship in Phase 9b/9c per
|
|
13
|
+
* plans/asciidoc-corpus-loaders.md.
|
|
14
|
+
*
|
|
15
|
+
* Callers can override the auto-detected loader by passing
|
|
16
|
+
* `opts.loader = "<name>"` (CLI: `--loader <name>`).
|
|
17
|
+
*/
|
|
18
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
19
|
+
import { basename } from "node:path";
|
|
20
|
+
import MarkdownIt from "markdown-it";
|
|
21
|
+
import { parseAsciidocToTree } from "./parse.js";
|
|
22
|
+
import { pickLoader, ALL_LOADERS } from "./detect.js";
|
|
23
|
+
function prettifyName(slug) {
|
|
24
|
+
return slug
|
|
25
|
+
.split(/[-_]/)
|
|
26
|
+
.filter(Boolean)
|
|
27
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
28
|
+
.join(" ");
|
|
29
|
+
}
|
|
30
|
+
function slugify(text) {
|
|
31
|
+
return text
|
|
32
|
+
.toLowerCase()
|
|
33
|
+
.replace(/[^\w\s-]/g, "")
|
|
34
|
+
.trim()
|
|
35
|
+
.replace(/\s+/g, "-");
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* markdown-it-attrs syntax for explicit heading anchors, trailing the
|
|
39
|
+
* heading text. AsciiDoc `[id="welcome-index"]` block anchors come
|
|
40
|
+
* through the engine as `{id="welcome-index"}`; an AsciiDoc anchor
|
|
41
|
+
* macro `[[welcome-index]]` becomes `{#welcome-index}`. Either form
|
|
42
|
+
* is valid markdown-it-attrs that an Astro render-time pass would
|
|
43
|
+
* later consume — we just need to honour it during migration so the
|
|
44
|
+
* canonical Dogsbay-MD output carries the id as `props.slug` instead
|
|
45
|
+
* of leaving a literal `{id="…"}` string in the heading text (which
|
|
46
|
+
* the dogsbay-md serializer's auto-slug step would then duplicate as
|
|
47
|
+
* a second `{#auto-slug}` block — breaking md-attrs' rule that only
|
|
48
|
+
* the *last* `{…}` block wins).
|
|
49
|
+
*
|
|
50
|
+
* Matches at end of text, capturing the id from either form:
|
|
51
|
+
* { id="foo" } → "foo"
|
|
52
|
+
* {#foo} → "foo"
|
|
53
|
+
* Tolerant of optional whitespace inside the braces.
|
|
54
|
+
*/
|
|
55
|
+
const HEADING_ID_RE = /\s*\{\s*(?:id\s*=\s*"([^"]+)"|#([^\s{}]+))\s*\}\s*$/;
|
|
56
|
+
/**
|
|
57
|
+
* Strip a trailing `{id="…"}` / `{#…}` from the last text inline of a
|
|
58
|
+
* heading and return the captured id. Mutates the inline array in
|
|
59
|
+
* place — emptied text spans are dropped so the serializer doesn't
|
|
60
|
+
* emit dangling spaces. Returns `undefined` if no marker is present.
|
|
61
|
+
*/
|
|
62
|
+
function extractHeadingId(node) {
|
|
63
|
+
const inline = node.inline;
|
|
64
|
+
if (!Array.isArray(inline) || inline.length === 0)
|
|
65
|
+
return undefined;
|
|
66
|
+
// Scan from the end for the last text span — md-attrs anchors are
|
|
67
|
+
// always at end-of-line, but trailing inline formatting (a link
|
|
68
|
+
// marker, an icon, etc.) shouldn't block detection.
|
|
69
|
+
for (let i = inline.length - 1; i >= 0; i--) {
|
|
70
|
+
const span = inline[i];
|
|
71
|
+
if (span.type !== "text")
|
|
72
|
+
continue;
|
|
73
|
+
const m = span.text.match(HEADING_ID_RE);
|
|
74
|
+
if (!m)
|
|
75
|
+
return undefined;
|
|
76
|
+
const id = m[1] ?? m[2];
|
|
77
|
+
const stripped = span.text.slice(0, span.text.length - m[0].length);
|
|
78
|
+
if (stripped.length > 0) {
|
|
79
|
+
span.text = stripped;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
inline.splice(i, 1);
|
|
83
|
+
}
|
|
84
|
+
return id;
|
|
85
|
+
}
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Read inline text from a heading node, cross-shape tolerant.
|
|
90
|
+
* format-asciidoc's parse.ts flattens prose wrappers (so we get the
|
|
91
|
+
* flat shape via `node.inline`), but this stays tolerant of the
|
|
92
|
+
* wrapped shape too — defence in depth in case the pipeline changes.
|
|
93
|
+
*/
|
|
94
|
+
function headingText(node) {
|
|
95
|
+
let inline;
|
|
96
|
+
if (Array.isArray(node.inline)) {
|
|
97
|
+
inline = node.inline;
|
|
98
|
+
}
|
|
99
|
+
else if (Array.isArray(node.children)) {
|
|
100
|
+
for (const child of node.children) {
|
|
101
|
+
if (child &&
|
|
102
|
+
child.type === "prose" &&
|
|
103
|
+
Array.isArray(child.inline)) {
|
|
104
|
+
inline = child.inline;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (!inline)
|
|
110
|
+
return "";
|
|
111
|
+
return inline
|
|
112
|
+
.map((n) => (n.type === "text" ? n.text : ""))
|
|
113
|
+
.join("")
|
|
114
|
+
.trim();
|
|
115
|
+
}
|
|
116
|
+
function extractHeadings(tree) {
|
|
117
|
+
const headings = [];
|
|
118
|
+
const seen = new Map();
|
|
119
|
+
for (const node of tree) {
|
|
120
|
+
if (node.type !== "heading")
|
|
121
|
+
continue;
|
|
122
|
+
// Honour an explicit `{id="…"}` / `{#…}` marker FIRST — strips
|
|
123
|
+
// it from inline so subsequent text reads (and the serializer's
|
|
124
|
+
// round-trip via inline) don't see the literal marker text.
|
|
125
|
+
let slug = node.props?.slug;
|
|
126
|
+
if (!slug) {
|
|
127
|
+
const explicitId = extractHeadingId(node);
|
|
128
|
+
if (explicitId) {
|
|
129
|
+
if (!node.props)
|
|
130
|
+
node.props = { level: 1 };
|
|
131
|
+
node.props.slug = explicitId;
|
|
132
|
+
slug = explicitId;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const text = headingText(node);
|
|
136
|
+
if (!slug) {
|
|
137
|
+
const baseSlug = slugify(text);
|
|
138
|
+
const count = seen.get(baseSlug) ?? 0;
|
|
139
|
+
slug = count === 0 ? baseSlug : `${baseSlug}-${count}`;
|
|
140
|
+
seen.set(baseSlug, count + 1);
|
|
141
|
+
if (!node.props)
|
|
142
|
+
node.props = { level: 1 };
|
|
143
|
+
node.props.slug = slug;
|
|
144
|
+
}
|
|
145
|
+
headings.push({
|
|
146
|
+
depth: node.props?.level ?? 1,
|
|
147
|
+
slug,
|
|
148
|
+
text,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
return headings;
|
|
152
|
+
}
|
|
153
|
+
async function importAsciidoc(source, opts) {
|
|
154
|
+
if (!existsSync(source)) {
|
|
155
|
+
throw new Error(`Source directory not found: ${source}`);
|
|
156
|
+
}
|
|
157
|
+
// Phase 9a: pick a loader by topology detection (or explicit override).
|
|
158
|
+
const loaderName = typeof opts.loader === "string" ? opts.loader : undefined;
|
|
159
|
+
const loader = pickLoader(source, loaderName);
|
|
160
|
+
const attributes = opts.attributes && typeof opts.attributes === "object"
|
|
161
|
+
? opts.attributes
|
|
162
|
+
: {};
|
|
163
|
+
const hrefPrefix = typeof opts.hrefPrefix === "string" ? opts.hrefPrefix : "";
|
|
164
|
+
const { pages: pageSources, nav } = await loader.load(source, { hrefPrefix });
|
|
165
|
+
const md = new MarkdownIt({ html: true, linkify: true });
|
|
166
|
+
const pages = [];
|
|
167
|
+
// Per-page fail-soft. A 20k-page corpus migration can't tolerate a
|
|
168
|
+
// single broken page (filesystem race, malformed AsciiDoc construct
|
|
169
|
+
// the engine doesn't recognise, etc.) crashing the entire run. Log
|
|
170
|
+
// the failure with its slug and source path, drop the page, keep
|
|
171
|
+
// going. At the end report a one-line summary so the user sees
|
|
172
|
+
// exactly how many pages didn't make it. Note: parseAsciidocToTree
|
|
173
|
+
// already swallows Minja-stage errors and falls back to the raw
|
|
174
|
+
// engine output (preserves directives verbatim), so anything that
|
|
175
|
+
// reaches *this* catch is a hard failure earlier in the pipeline
|
|
176
|
+
// (engine throw, markdown-it crash, etc.) — rare but real.
|
|
177
|
+
let failed = 0;
|
|
178
|
+
for (const ps of pageSources) {
|
|
179
|
+
try {
|
|
180
|
+
const content = readFileSync(ps.filePath, "utf-8");
|
|
181
|
+
const pageAttrs = ps.attributes
|
|
182
|
+
? { ...attributes, ...ps.attributes }
|
|
183
|
+
: attributes;
|
|
184
|
+
const { tree, intermediateMd } = await parseAsciidocToTree(md, content, {
|
|
185
|
+
filePath: ps.filePath,
|
|
186
|
+
attributes: pageAttrs,
|
|
187
|
+
});
|
|
188
|
+
const headings = extractHeadings(tree);
|
|
189
|
+
const h1 = headings.find((h) => h.depth === 1);
|
|
190
|
+
const title = h1?.text || prettifyName(basename(ps.slug));
|
|
191
|
+
pages.push({
|
|
192
|
+
slug: ps.slug,
|
|
193
|
+
title,
|
|
194
|
+
tree,
|
|
195
|
+
headings,
|
|
196
|
+
frontmatter: {},
|
|
197
|
+
meta: {},
|
|
198
|
+
// `bodyMarkdown` is what migrate-asciidoc writes to disk —
|
|
199
|
+
// engine output + Minja preserve, paragraph structure of
|
|
200
|
+
// the source `.adoc` intact. Bypasses the markdown-it →
|
|
201
|
+
// format-dogsbay-md round-trip that would otherwise fold
|
|
202
|
+
// adjacent non-blank lines into one squashed paragraph.
|
|
203
|
+
// The TreeNode + headings stay as canonical for the runtime
|
|
204
|
+
// path (format-astro emit). See plans/multi-variant-builds.md
|
|
205
|
+
// for the broader migration-vs-runtime split.
|
|
206
|
+
bodyMarkdown: intermediateMd,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
failed += 1;
|
|
211
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
212
|
+
console.warn(`asciidoc import: failed to convert ${ps.filePath} (slug "${ps.slug}"), skipping: ${msg}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (failed > 0) {
|
|
216
|
+
console.warn(`asciidoc import: ${failed} of ${pageSources.length} page(s) failed to convert and were skipped`);
|
|
217
|
+
}
|
|
218
|
+
return { pages, nav };
|
|
219
|
+
}
|
|
220
|
+
export const plugin = {
|
|
221
|
+
name: "asciidoc",
|
|
222
|
+
canImport: true,
|
|
223
|
+
canExport: false,
|
|
224
|
+
detectSource: (path) => {
|
|
225
|
+
// The plugin's overall detect = any registered loader detects.
|
|
226
|
+
return ALL_LOADERS.some((l) => l.detect(path));
|
|
227
|
+
},
|
|
228
|
+
importOptions: [
|
|
229
|
+
{
|
|
230
|
+
flags: "--loader <name>",
|
|
231
|
+
description: "Force a specific corpus loader (plain, master-adoc). Auto-detected when omitted.",
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
exportOptions: [],
|
|
235
|
+
async import(source, opts) {
|
|
236
|
+
return importAsciidoc(source, opts);
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/detect.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loader detection + selection.
|
|
3
|
+
*
|
|
4
|
+
* Ordered most-specific first: Antora → AsciiBinder → master.adoc
|
|
5
|
+
* → plain. First loader whose `detect()` returns true wins.
|
|
6
|
+
*
|
|
7
|
+
* Callers can override via the `loader` option (CLI: `--loader <name>`)
|
|
8
|
+
* — useful when the precedence list silently picks the wrong loader
|
|
9
|
+
* (e.g. a repo with both a master.adoc and a _topic_map.yml).
|
|
10
|
+
*
|
|
11
|
+
* Phase 9a ships plain + master-adoc. Phase 9b adds asciibinder.
|
|
12
|
+
* Phase 9c adds antora. Until they ship, this list contains only
|
|
13
|
+
* the loaders that exist; detection still works — the absent ones
|
|
14
|
+
* just never claim a corpus.
|
|
15
|
+
*/
|
|
16
|
+
import type { CorpusLoader } from "./loaders/types.js";
|
|
17
|
+
/**
|
|
18
|
+
* Loaders in detection-precedence order (most specific first).
|
|
19
|
+
* The plain loader is the catch-all and stays last.
|
|
20
|
+
*/
|
|
21
|
+
export declare const ALL_LOADERS: CorpusLoader[];
|
|
22
|
+
export declare class LoaderNotFoundError extends Error {
|
|
23
|
+
readonly requested: string;
|
|
24
|
+
readonly available: string[];
|
|
25
|
+
constructor(requested: string, available: string[]);
|
|
26
|
+
}
|
|
27
|
+
export declare class NoLoaderMatchedError extends Error {
|
|
28
|
+
readonly sourceDir: string;
|
|
29
|
+
constructor(sourceDir: string);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Pick the loader to use for a given source dir.
|
|
33
|
+
*
|
|
34
|
+
* - `override` (CLI `--loader <name>`) always wins; throws
|
|
35
|
+
* LoaderNotFoundError if the name doesn't match a registered loader.
|
|
36
|
+
* - Otherwise runs each loader's `detect()` in precedence order;
|
|
37
|
+
* first match wins.
|
|
38
|
+
* - Throws NoLoaderMatchedError if nothing detects (sourceDir likely
|
|
39
|
+
* isn't an AsciiDoc corpus at all).
|
|
40
|
+
*/
|
|
41
|
+
export declare function pickLoader(sourceDir: string, override?: string): CorpusLoader;
|
|
42
|
+
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAMvD;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,YAAY,EAKrC,CAAC;AAEF,qBAAa,mBAAoB,SAAQ,KAAK;aAChB,SAAS,EAAE,MAAM;aAAkB,SAAS,EAAE,MAAM,EAAE;gBAAtD,SAAS,EAAE,MAAM,EAAkB,SAAS,EAAE,MAAM,EAAE;CAKnF;AAED,qBAAa,oBAAqB,SAAQ,KAAK;aACjB,SAAS,EAAE,MAAM;gBAAjB,SAAS,EAAE,MAAM;CAO9C;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAChB,YAAY,CAcd"}
|
package/dist/detect.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { plainLoader } from "./loaders/plain.js";
|
|
2
|
+
import { masterAdocLoader } from "./loaders/master-adoc.js";
|
|
3
|
+
import { asciibinderLoader } from "./loaders/asciibinder.js";
|
|
4
|
+
import { antoraLoader } from "./loaders/antora.js";
|
|
5
|
+
/**
|
|
6
|
+
* Loaders in detection-precedence order (most specific first).
|
|
7
|
+
* The plain loader is the catch-all and stays last.
|
|
8
|
+
*/
|
|
9
|
+
export const ALL_LOADERS = [
|
|
10
|
+
antoraLoader,
|
|
11
|
+
asciibinderLoader,
|
|
12
|
+
masterAdocLoader,
|
|
13
|
+
plainLoader,
|
|
14
|
+
];
|
|
15
|
+
export class LoaderNotFoundError extends Error {
|
|
16
|
+
requested;
|
|
17
|
+
available;
|
|
18
|
+
constructor(requested, available) {
|
|
19
|
+
super(`Unknown asciidoc loader "${requested}". Available: ${available.join(", ")}.`);
|
|
20
|
+
this.requested = requested;
|
|
21
|
+
this.available = available;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export class NoLoaderMatchedError extends Error {
|
|
25
|
+
sourceDir;
|
|
26
|
+
constructor(sourceDir) {
|
|
27
|
+
super(`No asciidoc loader matched the source at ${sourceDir}. ` +
|
|
28
|
+
`Tried ${ALL_LOADERS.map((l) => l.name).join(", ")}. ` +
|
|
29
|
+
`Pass --loader <name> to force a specific loader.`);
|
|
30
|
+
this.sourceDir = sourceDir;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Pick the loader to use for a given source dir.
|
|
35
|
+
*
|
|
36
|
+
* - `override` (CLI `--loader <name>`) always wins; throws
|
|
37
|
+
* LoaderNotFoundError if the name doesn't match a registered loader.
|
|
38
|
+
* - Otherwise runs each loader's `detect()` in precedence order;
|
|
39
|
+
* first match wins.
|
|
40
|
+
* - Throws NoLoaderMatchedError if nothing detects (sourceDir likely
|
|
41
|
+
* isn't an AsciiDoc corpus at all).
|
|
42
|
+
*/
|
|
43
|
+
export function pickLoader(sourceDir, override) {
|
|
44
|
+
if (override) {
|
|
45
|
+
const match = ALL_LOADERS.find((l) => l.name === override);
|
|
46
|
+
if (!match) {
|
|
47
|
+
throw new LoaderNotFoundError(override, ALL_LOADERS.map((l) => l.name));
|
|
48
|
+
}
|
|
49
|
+
return match;
|
|
50
|
+
}
|
|
51
|
+
const match = ALL_LOADERS.find((l) => l.detect(sourceDir));
|
|
52
|
+
if (!match)
|
|
53
|
+
throw new NoLoaderMatchedError(sourceDir);
|
|
54
|
+
return match;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAmB;IACzC,YAAY;IACZ,iBAAiB;IACjB,gBAAgB;IAChB,WAAW;CACZ,CAAC;AAEF,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAChB;IAAmC;IAA/D,YAA4B,SAAiB,EAAkB,SAAmB;QAChF,KAAK,CACH,4BAA4B,SAAS,iBAAiB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC9E,CAAC;QAHwB,cAAS,GAAT,SAAS,CAAQ;QAAkB,cAAS,GAAT,SAAS,CAAU;IAIlF,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACjB;IAA5B,YAA4B,SAAiB;QAC3C,KAAK,CACH,4CAA4C,SAAS,IAAI;YACvD,SAAS,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YACtD,kDAAkD,CACrD,CAAC;QALwB,cAAS,GAAT,SAAS,CAAQ;IAM7C,CAAC;CACF;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CACxB,SAAiB,EACjB,QAAiB;IAEjB,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;QAC3D,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,mBAAmB,CAC3B,QAAQ,EACR,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAC/B,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IAC3D,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,oBAAoB,CAAC,SAAS,CAAC,CAAC;IACtD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @dogsbay/format-asciidoc
|
|
3
|
+
*
|
|
4
|
+
* AsciiDoc format plugin — imports `.adoc` sources into `TreeNode[]`.
|
|
5
|
+
* See plans/format-asciidoc-import.md for the full architecture.
|
|
6
|
+
*/
|
|
7
|
+
export { parseAsciidocToTree, type ParseAsciidocOptions } from "./parse.js";
|
|
8
|
+
export { tokensToTree } from "./walker.js";
|
|
9
|
+
export type { TreeNode } from "./tree.js";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,mBAAmB,EAAE,KAAK,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @dogsbay/format-asciidoc
|
|
3
|
+
*
|
|
4
|
+
* AsciiDoc format plugin — imports `.adoc` sources into `TreeNode[]`.
|
|
5
|
+
* See plans/format-asciidoc-import.md for the full architecture.
|
|
6
|
+
*/
|
|
7
|
+
export { parseAsciidocToTree } from "./parse.js";
|
|
8
|
+
export { tokensToTree } from "./walker.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,mBAAmB,EAA6B,MAAM,YAAY,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline token walker — converts markdown-it inline tokens into InlineNode[].
|
|
3
|
+
*
|
|
4
|
+
* Walks tokens left-to-right maintaining an annotation stack (bold/italic/
|
|
5
|
+
* strikethrough) and a container stack for links. Emits InlineNode spans
|
|
6
|
+
* as it encounters content tokens.
|
|
7
|
+
*
|
|
8
|
+
* Formatting is flat annotations on text spans (Notion model), not nested
|
|
9
|
+
* elements. `{ bold: true, italic: true }` instead of `<strong><em>`.
|
|
10
|
+
*/
|
|
11
|
+
import type Token from "markdown-it/lib/token.mjs";
|
|
12
|
+
import type { InlineNode } from "@dogsbay/types";
|
|
13
|
+
/**
|
|
14
|
+
* Convert markdown-it inline token children into structured InlineNode[].
|
|
15
|
+
*/
|
|
16
|
+
export declare function walkInlineTokens(tokens: Token[] | null): InlineNode[];
|
|
17
|
+
//# sourceMappingURL=inline-walker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inline-walker.d.ts","sourceRoot":"","sources":["../src/inline-walker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,KAAK,MAAM,2BAA2B,CAAC;AACnD,OAAO,KAAK,EACV,UAAU,EAWX,MAAM,gBAAgB,CAAC;AAQxB;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,GAAG,UAAU,EAAE,CA2KrE"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert markdown-it inline token children into structured InlineNode[].
|
|
3
|
+
*/
|
|
4
|
+
export function walkInlineTokens(tokens) {
|
|
5
|
+
if (!tokens || tokens.length === 0)
|
|
6
|
+
return [];
|
|
7
|
+
const result = [];
|
|
8
|
+
const annotations = { bold: false, italic: false, strikethrough: false };
|
|
9
|
+
// Stack for container elements (links)
|
|
10
|
+
// When inside a link, spans are pushed to the link's children instead of result
|
|
11
|
+
const containerStack = [];
|
|
12
|
+
function target() {
|
|
13
|
+
if (containerStack.length > 0) {
|
|
14
|
+
return containerStack[containerStack.length - 1].node.children;
|
|
15
|
+
}
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
function pushNode(node) {
|
|
19
|
+
target().push(node);
|
|
20
|
+
}
|
|
21
|
+
function makeText(text) {
|
|
22
|
+
const span = { type: "text", text };
|
|
23
|
+
if (annotations.bold)
|
|
24
|
+
span.bold = true;
|
|
25
|
+
if (annotations.italic)
|
|
26
|
+
span.italic = true;
|
|
27
|
+
if (annotations.strikethrough)
|
|
28
|
+
span.strikethrough = true;
|
|
29
|
+
return span;
|
|
30
|
+
}
|
|
31
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
32
|
+
const token = tokens[i];
|
|
33
|
+
switch (token.type) {
|
|
34
|
+
// ── Annotation open/close ──
|
|
35
|
+
case "strong_open":
|
|
36
|
+
annotations.bold = true;
|
|
37
|
+
break;
|
|
38
|
+
case "strong_close":
|
|
39
|
+
annotations.bold = false;
|
|
40
|
+
break;
|
|
41
|
+
case "em_open":
|
|
42
|
+
annotations.italic = true;
|
|
43
|
+
break;
|
|
44
|
+
case "em_close":
|
|
45
|
+
annotations.italic = false;
|
|
46
|
+
break;
|
|
47
|
+
case "s_open":
|
|
48
|
+
annotations.strikethrough = true;
|
|
49
|
+
break;
|
|
50
|
+
case "s_close":
|
|
51
|
+
annotations.strikethrough = false;
|
|
52
|
+
break;
|
|
53
|
+
// ── Link container ──
|
|
54
|
+
case "link_open": {
|
|
55
|
+
const href = token.attrGet("href") || "";
|
|
56
|
+
const title = token.attrGet("title") || undefined;
|
|
57
|
+
const linkNode = { type: "link", href, children: [] };
|
|
58
|
+
if (title)
|
|
59
|
+
linkNode.title = title;
|
|
60
|
+
containerStack.push({ type: "link", node: linkNode });
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
case "link_close": {
|
|
64
|
+
const container = containerStack.pop();
|
|
65
|
+
if (container) {
|
|
66
|
+
// Push the completed link to the parent target
|
|
67
|
+
target().push(container.node);
|
|
68
|
+
}
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
// ── Text ──
|
|
72
|
+
case "text": {
|
|
73
|
+
if (token.content) {
|
|
74
|
+
pushNode(makeText(token.content));
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
// ── Inline code ──
|
|
79
|
+
case "code_inline": {
|
|
80
|
+
const codeNode = { type: "code", text: token.content };
|
|
81
|
+
pushNode(codeNode);
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
// ── Image ──
|
|
85
|
+
case "image": {
|
|
86
|
+
const src = token.attrGet("src") || "";
|
|
87
|
+
const alt = token.content || token.attrGet("alt") || undefined;
|
|
88
|
+
const title = token.attrGet("title") || undefined;
|
|
89
|
+
const imgNode = { type: "image", src };
|
|
90
|
+
if (alt)
|
|
91
|
+
imgNode.alt = alt;
|
|
92
|
+
if (title)
|
|
93
|
+
imgNode.title = title;
|
|
94
|
+
pushNode(imgNode);
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
// ── Footnote reference (custom rule) ──
|
|
98
|
+
case "footnote_ref": {
|
|
99
|
+
const label = token.meta?.label || "";
|
|
100
|
+
const fnNode = { type: "footnote-ref", label };
|
|
101
|
+
pushNode(fnNode);
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
// ── Line breaks ──
|
|
105
|
+
case "softbreak": {
|
|
106
|
+
// Soft break is just whitespace (newline within a paragraph)
|
|
107
|
+
pushNode(makeText(" "));
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case "hardbreak": {
|
|
111
|
+
const brNode = { type: "break" };
|
|
112
|
+
pushNode(brNode);
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
// ── Inline math ──
|
|
116
|
+
case "math_inline": {
|
|
117
|
+
const mathNode = { type: "math", latex: token.content || token.meta?.latex || "" };
|
|
118
|
+
pushNode(mathNode);
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
// ── Icon/emoji shortcode ──
|
|
122
|
+
case "icon_shortcode": {
|
|
123
|
+
const meta = token.meta || {};
|
|
124
|
+
const iconNode = {
|
|
125
|
+
type: "icon",
|
|
126
|
+
name: meta.name || meta.raw || "",
|
|
127
|
+
library: meta.library,
|
|
128
|
+
};
|
|
129
|
+
if (meta.variant)
|
|
130
|
+
iconNode.variant = meta.variant;
|
|
131
|
+
if (meta.size)
|
|
132
|
+
iconNode.size = meta.size;
|
|
133
|
+
if (meta.attrs)
|
|
134
|
+
iconNode.attrs = meta.attrs;
|
|
135
|
+
pushNode(iconNode);
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
// ── Raw HTML inline (escape hatch) ──
|
|
139
|
+
case "html_inline": {
|
|
140
|
+
// Try to detect <kbd> patterns from keys plugin
|
|
141
|
+
const kbdMatch = token.content.match(/^<kbd>([^<]+)<\/kbd>(?:\+<kbd>([^<]+)<\/kbd>)*$/);
|
|
142
|
+
if (kbdMatch) {
|
|
143
|
+
const keys = token.content
|
|
144
|
+
.match(/<kbd>([^<]+)<\/kbd>/g)
|
|
145
|
+
.map((m) => m.replace(/<\/?kbd>/g, ""));
|
|
146
|
+
const kbdNode = { type: "kbd", keys };
|
|
147
|
+
pushNode(kbdNode);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
const htmlNode = { type: "html-inline", html: token.content };
|
|
151
|
+
pushNode(htmlNode);
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
// ── Fallback: anything else becomes html-inline ──
|
|
156
|
+
default: {
|
|
157
|
+
if (token.content) {
|
|
158
|
+
const htmlNode = { type: "html-inline", html: token.content };
|
|
159
|
+
pushNode(htmlNode);
|
|
160
|
+
}
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=inline-walker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inline-walker.js","sourceRoot":"","sources":["../src/inline-walker.ts"],"names":[],"mappings":"AA+BA;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAsB;IACrD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAE9C,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,MAAM,WAAW,GAAgB,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;IAEtF,uCAAuC;IACvC,gFAAgF;IAChF,MAAM,cAAc,GAAyC,EAAE,CAAC;IAEhE,SAAS,MAAM;QACb,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,OAAO,cAAc,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;QACjE,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,SAAS,QAAQ,CAAC,IAAgB;QAChC,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAED,SAAS,QAAQ,CAAC,IAAY;QAC5B,MAAM,IAAI,GAAe,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAChD,IAAI,WAAW,CAAC,IAAI;YAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACvC,IAAI,WAAW,CAAC,MAAM;YAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QAC3C,IAAI,WAAW,CAAC,aAAa;YAAE,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QAExB,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,8BAA8B;YAC9B,KAAK,aAAa;gBAChB,WAAW,CAAC,IAAI,GAAG,IAAI,CAAC;gBACxB,MAAM;YACR,KAAK,cAAc;gBACjB,WAAW,CAAC,IAAI,GAAG,KAAK,CAAC;gBACzB,MAAM;YACR,KAAK,SAAS;gBACZ,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC;gBAC1B,MAAM;YACR,KAAK,UAAU;gBACb,WAAW,CAAC,MAAM,GAAG,KAAK,CAAC;gBAC3B,MAAM;YACR,KAAK,QAAQ;gBACX,WAAW,CAAC,aAAa,GAAG,IAAI,CAAC;gBACjC,MAAM;YACR,KAAK,SAAS;gBACZ,WAAW,CAAC,aAAa,GAAG,KAAK,CAAC;gBAClC,MAAM;YAER,uBAAuB;YACvB,KAAK,WAAW,CAAC,CAAC,CAAC;gBACjB,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;gBACzC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC;gBAClD,MAAM,QAAQ,GAAe,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;gBAClE,IAAI,KAAK;oBAAE,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;gBAClC,cAAc,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACtD,MAAM;YACR,CAAC;YACD,KAAK,YAAY,CAAC,CAAC,CAAC;gBAClB,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,EAAE,CAAC;gBACvC,IAAI,SAAS,EAAE,CAAC;oBACd,+CAA+C;oBAC/C,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBAChC,CAAC;gBACD,MAAM;YACR,CAAC;YAED,aAAa;YACb,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;oBAClB,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;gBACpC,CAAC;gBACD,MAAM;YACR,CAAC;YAED,oBAAoB;YACpB,KAAK,aAAa,CAAC,CAAC,CAAC;gBACnB,MAAM,QAAQ,GAAe,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;gBACnE,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACnB,MAAM;YACR,CAAC;YAED,cAAc;YACd,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBACvC,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC;gBAC/D,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC;gBAClD,MAAM,OAAO,GAAgB,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;gBACpD,IAAI,GAAG;oBAAE,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC;gBAC3B,IAAI,KAAK;oBAAE,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;gBACjC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBAClB,MAAM;YACR,CAAC;YAED,yCAAyC;YACzC,KAAK,cAAc,CAAC,CAAC,CAAC;gBACpB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;gBACtC,MAAM,MAAM,GAAsB,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;gBAClE,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACjB,MAAM;YACR,CAAC;YAED,oBAAoB;YACpB,KAAK,WAAW,CAAC,CAAC,CAAC;gBACjB,6DAA6D;gBAC7D,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;gBACxB,MAAM;YACR,CAAC;YACD,KAAK,WAAW,CAAC,CAAC,CAAC;gBACjB,MAAM,MAAM,GAAgB,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;gBAC9C,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACjB,MAAM;YACR,CAAC;YAED,oBAAoB;YACpB,KAAK,aAAa,CAAC,CAAC,CAAC;gBACnB,MAAM,QAAQ,GAAe,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,EAAE,CAAC;gBAC/F,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACnB,MAAM;YACR,CAAC;YAED,6BAA6B;YAC7B,KAAK,gBAAgB,CAAC,CAAC,CAAC;gBACtB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;gBAC9B,MAAM,QAAQ,GAAe;oBAC3B,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,IAAI,EAAE;oBACjC,OAAO,EAAE,IAAI,CAAC,OAAO;iBACtB,CAAC;gBACF,IAAI,IAAI,CAAC,OAAO;oBAAE,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;gBAClD,IAAI,IAAI,CAAC,IAAI;oBAAE,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;gBACzC,IAAI,IAAI,CAAC,KAAK;oBAAE,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;gBAC5C,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACnB,MAAM;YACR,CAAC;YAED,uCAAuC;YACvC,KAAK,aAAa,CAAC,CAAC,CAAC;gBACnB,gDAAgD;gBAChD,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAClC,iDAAiD,CAClD,CAAC;gBACF,IAAI,QAAQ,EAAE,CAAC;oBACb,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO;yBACvB,KAAK,CAAC,sBAAsB,CAAE;yBAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC;oBAC1C,MAAM,OAAO,GAAc,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;oBACjD,QAAQ,CAAC,OAAO,CAAC,CAAC;gBACpB,CAAC;qBAAM,CAAC;oBACN,MAAM,QAAQ,GAAe,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;oBAC1E,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACrB,CAAC;gBACD,MAAM;YACR,CAAC;YAED,oDAAoD;YACpD,OAAO,CAAC,CAAC,CAAC;gBACR,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;oBAClB,MAAM,QAAQ,GAAe,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;oBAC1E,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACrB,CAAC;gBACD,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"antora.d.ts","sourceRoot":"","sources":["../../src/loaders/antora.ts"],"names":[],"mappings":"AA4DA,OAAO,KAAK,EACV,YAAY,EAIb,MAAM,YAAY,CAAC;AAsJpB,eAAO,MAAM,YAAY,EAAE,YA2F1B,CAAC"}
|