@dogsbay/adoc2md-modular 0.2.0-beta.101

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,209 @@
1
+ /**
2
+ * @dogsbay/adoc2md-modular
3
+ *
4
+ * AsciiDoc → Markdown converter optimised for modular-content
5
+ * patterns (includes, leveloffset, conditionals, attributes).
6
+ *
7
+ * Ported from the `~/dev/md2md` prototype's `src/downdoc.js` — a
8
+ * modified fork of Dan Allen's downdoc with adjustments for
9
+ * modular-content workflows (AAP, OpenShift, Antora-style content).
10
+ * See LINEAGE.md for the upstream fork point and the local
11
+ * modifications enumerated.
12
+ *
13
+ * This is the **per-file** converter. Corpus discovery (which files
14
+ * to convert, what order, what attribute context to apply) lives in
15
+ * the loaders in `@dogsbay/format-asciidoc` per
16
+ * `plans/asciidoc-corpus-loaders.md`. Variable / include
17
+ * resolution happens downstream in `@dogsbay/minja` per Phase 2 of
18
+ * `plans/format-asciidoc-import.md`.
19
+ *
20
+ * Phase 3 status: stub. The public API is shaped but the body is a
21
+ * pass-through that returns the input unchanged so the package
22
+ * loads and the wiring tests pass. Phase 4 ports the actual
23
+ * converter.
24
+ */
25
+ /**
26
+ * Options for `asciidocToMarkdown`. Names and semantics mirror the
27
+ * md2md CLI flags (`-a name=value`, `-d`, `-A`, `--inline-includes`)
28
+ * so existing automation can drop in with no translation.
29
+ */
30
+ export interface AsciidocToMarkdownOptions {
31
+ /**
32
+ * AsciiDoc attribute values known at convert time. These do NOT
33
+ * substitute into `{name}` slots here — the engine always emits
34
+ * `{{ name }}` Minja variables for attribute refs and lets the
35
+ * downstream `@dogsbay/minja` pass do the actual substitution
36
+ * with a runtime context. Same shape for `ifdef::` conditionals:
37
+ * always preserved as `{% if name %}` for Minja to evaluate.
38
+ *
39
+ * What this option DOES do: suppresses any in-document
40
+ * `:name: value` attribute entry from emitting a corresponding
41
+ * `{% set name = "value" %}` directive (because the value is
42
+ * being supplied externally). Equivalent to repeating
43
+ * `-a name=value` on md2md's CLI.
44
+ *
45
+ * The clean two-stage pipeline:
46
+ * AsciiDoc → adoc2md-modular → Markdown with `{{ vars }}` + `{% if %}`
47
+ * → @dogsbay/minja(context) → final Markdown
48
+ */
49
+ attributes?: Record<string, unknown>;
50
+ /**
51
+ * Whether to inline `include::` directives during the AsciiDoc →
52
+ * Markdown pass.
53
+ *
54
+ * - `false` (default) — emit `{% include "path" %}` directives in
55
+ * the output markdown. Downstream Minja resolution expands them
56
+ * with the correct basePath tracking.
57
+ * - `true` — read each included file at convert time and splice
58
+ * its content directly into the output. Equivalent to md2md's
59
+ * `--inline-includes` flag. Loses round-trip fidelity but
60
+ * produces a fully self-contained markdown artifact.
61
+ */
62
+ inlineIncludes?: boolean;
63
+ /**
64
+ * Definition list output format.
65
+ * - `'markdown'` (default) — `Term\n: Definition` (CommonMark).
66
+ * - `'html'` — `<dl><dt>Term</dt><dd>Definition</dd></dl>`.
67
+ * - `'pandoc'` — Pandoc's definition-list extension shape.
68
+ */
69
+ dlistFormat?: "markdown" | "html" | "pandoc";
70
+ /**
71
+ * Admonition output format. Only `[NOTE]` / `[WARNING]` /
72
+ * `[TIP]` block-form admonitions respect this option. The
73
+ * line-form (`NOTE: …`) always emits the html-like
74
+ * `**📌 NOTE**\` prefix shape regardless.
75
+ *
76
+ * - `'html'` (default) — `<dl><dt><strong>📌 NOTE</strong></dt><dd>…</dd></dl>`
77
+ * for universal compatibility (Pandoc, GFM, MkDocs).
78
+ * - `'mkdocs'` — `!!! note` blocks (Material).
79
+ * - `'docusaurus'` — `:::note` directive blocks.
80
+ * - `'github'` — `> [!NOTE]` GFM-style alerts.
81
+ */
82
+ admonitionFormat?: "html" | "mkdocs" | "docusaurus" | "github";
83
+ /**
84
+ * Base path for resolving `include::` directives at convert
85
+ * time. Used both for inline includes (`inlineIncludes: true`)
86
+ * AND for the smart-indentation pass that `inlineIncludes: false`
87
+ * runs against the filesystem — without a basePath the engine
88
+ * silently drops include lines instead of emitting the
89
+ * `{% include "./<path>.md" %}` directive.
90
+ *
91
+ * Defaults to `process.cwd()` so includes always emit. Pass
92
+ * the source file's directory when converting a file that uses
93
+ * relative include paths.
94
+ */
95
+ basePath?: string;
96
+ /**
97
+ * Emit AsciiDoc block roles (`[role="x"]` / `[.x]`) as markdown-it-attrs
98
+ * classes (`{.x}`) on the block, instead of dropping them.
99
+ *
100
+ * - `false` (default) — drop roles (legacy behavior). Safe for consumers
101
+ * that do NOT run markdown-it-attrs at parse time (e.g. the
102
+ * `from: asciidoc` direct path), where a `{.x}` trailer would otherwise
103
+ * leak as literal text.
104
+ * - `true` — emit `{.x}`. Use when the downstream parser runs
105
+ * markdown-it-attrs (the migrate → `dogsbay-md` flow), so the class
106
+ * becomes a real HTML class. Currently applied on section headings
107
+ * (`## Title {id="…" .role}`).
108
+ *
109
+ * See plans/adoc2md-block-metadata.md (#384).
110
+ */
111
+ blockRoles?: boolean;
112
+ /**
113
+ * Containment root for include reads at CONVERT time (issue #027).
114
+ * When set, any file the engine reads to resolve an include —
115
+ * tag-filtered splices (`include::x[tags=…]`), smart-indentation
116
+ * probes, and `inlineIncludes` full splices — must resolve (after
117
+ * symlinks) inside this directory, or conversion fails with a named
118
+ * `IncludeContainmentError`. Unset = uncontained (trusted input,
119
+ * backward compatible). The downstream Minja stage enforces its own
120
+ * containment for the `{% include %}` directives the engine emits.
121
+ */
122
+ includeRoot?: string;
123
+ /**
124
+ * Docroot-relative slug of the source page (e.g. `"architecture/admission-plug-ins"`).
125
+ *
126
+ * When provided, cross-doc xref hrefs are resolved against this slug and
127
+ * emitted as root-relative paths (`/<resolved>`) rather than file-relative
128
+ * (`../<path>`). The latter is correct for *file*-style URLs but off by one
129
+ * under Astro's default `build.format: 'directory'` (trailing-slash URLs),
130
+ * so multi-depth pages get broken cross-refs without this resolution.
131
+ *
132
+ * Internal-anchor xrefs (`xref:my-section[]` -> `#my-section`) and external
133
+ * URLs are untouched. Absent `sourcePath` falls back to the legacy
134
+ * file-relative emit so standalone unit-test callers keep working.
135
+ *
136
+ * See plans/xref-absolute-hrefs.md.
137
+ */
138
+ sourcePath?: string;
139
+ /**
140
+ * Antora corpus mode. Activates Antora-specific resolution that would be
141
+ * wrong (or ambiguous) for other corpus shapes, so it's opt-in:
142
+ *
143
+ * - `xref:module:page[…]` / `xref:component:module:page[…]` coordinates
144
+ * translate to root-relative hrefs (`/module/page`; `ROOT` collapses;
145
+ * a `version@` prefix is dropped). Without this flag a module
146
+ * coordinate looks like a URL scheme and leaks verbatim.
147
+ * - `include::[module:]family$rel[…]` resource IDs (partial$, example$,
148
+ * page$, attachment$, image$) resolve to the module's family directory
149
+ * (`modules/<mod>/partials/…`). Cross-component targets warn and drop.
150
+ * - Emitted `{% include %}` paths are relativized against `sourcePath`
151
+ * (the document's OUTPUT position) instead of the raw source-relative
152
+ * path, because migrated pages live at their slug path while fragments
153
+ * mirror the source layout.
154
+ * - `tag=` / `tags=` include attributes are honoured (tag slices are
155
+ * inlined at convert time). This also applies outside Antora mode.
156
+ *
157
+ * The module context is derived from the source file's own path (the
158
+ * nearest `modules/<name>/` ancestor of `basePath`).
159
+ *
160
+ * See plans/antora-support-gaps.md.
161
+ */
162
+ antora?: boolean;
163
+ /**
164
+ * Antora PLAYBOOK mode (#067): the slug prefix under which this file's
165
+ * component was mounted (`guides/`, `server-admin/server-4.9/`, `` for the
166
+ * root component). Include output paths target `<prefix>modules/…` so a
167
+ * page or fragment under the prefix finds fragments mirrored beside it.
168
+ * Omit for single-component corpora; when omitted the engine infers the
169
+ * prefix for PAGES from `sourcePath` and uses `''` for fragments.
170
+ */
171
+ antoraSlugPrefix?: string;
172
+ /**
173
+ * Antora PLAYBOOK mode (#067): every loaded component by name → its
174
+ * root directory and slug prefix, so an include/xref naming ANOTHER
175
+ * loaded component (`include::guides:ROOT:partial$x.adoc[]` from inside
176
+ * `reference`) resolves against that component instead of being warned
177
+ * as unresolvable. Omit for single-component corpora.
178
+ */
179
+ antoraComponents?: Record<string, {
180
+ dir: string;
181
+ prefix: string;
182
+ }>;
183
+ /**
184
+ * Attribute names the caller KNOWS are false — e.g. the corpus's other
185
+ * distro flags in a single-distro migrate. Drives conditional STATE
186
+ * tracking only (a provably-dropped branch's lists/dlists cannot anchor
187
+ * later content); never drops output text. Names may be given in either
188
+ * hyphen or underscore form.
189
+ */
190
+ falseAttributes?: string[];
191
+ /**
192
+ * Clamp over-declared rowspans (`.6+|` over five sub-rows) to the rows
193
+ * that actually fit, instead of letting the span swallow the next
194
+ * row's first cell (issue #031 — upstream openshift-docs bugs;
195
+ * asciidoctor renders them broken too). OPT-IN: default false keeps
196
+ * pure garbage-in-garbage-out parity. Set by `migrate-asciidoc`.
197
+ */
198
+ clampRowspans?: boolean;
199
+ }
200
+ /**
201
+ * Convert AsciiDoc source to Markdown.
202
+ *
203
+ * Wraps the engine (Phase 4 port of md2md/src/downdoc.js) and
204
+ * exposes the documented public options shape. Output is Markdown
205
+ * with embedded Minja directives for unresolved variables and
206
+ * includes — resolve them downstream with `@dogsbay/minja`.
207
+ */
208
+ export declare function asciidocToMarkdown(src: string, opts?: AsciidocToMarkdownOptions): string;
209
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC;;;;;;;;;;;;;;;;;OAiBG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAErC;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;IAE7C;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,YAAY,GAAG,QAAQ,CAAC;IAE/D;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAEnE;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAQD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,yBAA8B,GACnC,MAAM,CAqBR"}
package/dist/index.js ADDED
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @dogsbay/adoc2md-modular
3
+ *
4
+ * AsciiDoc → Markdown converter optimised for modular-content
5
+ * patterns (includes, leveloffset, conditionals, attributes).
6
+ *
7
+ * Ported from the `~/dev/md2md` prototype's `src/downdoc.js` — a
8
+ * modified fork of Dan Allen's downdoc with adjustments for
9
+ * modular-content workflows (AAP, OpenShift, Antora-style content).
10
+ * See LINEAGE.md for the upstream fork point and the local
11
+ * modifications enumerated.
12
+ *
13
+ * This is the **per-file** converter. Corpus discovery (which files
14
+ * to convert, what order, what attribute context to apply) lives in
15
+ * the loaders in `@dogsbay/format-asciidoc` per
16
+ * `plans/asciidoc-corpus-loaders.md`. Variable / include
17
+ * resolution happens downstream in `@dogsbay/minja` per Phase 2 of
18
+ * `plans/format-asciidoc-import.md`.
19
+ *
20
+ * Phase 3 status: stub. The public API is shaped but the body is a
21
+ * pass-through that returns the input unchanged so the package
22
+ * loads and the wiring tests pass. Phase 4 ports the actual
23
+ * converter.
24
+ */
25
+ // Engine ported from md2md/src/downdoc.js — see engine.js,
26
+ // engine.d.ts, and LINEAGE.md. Imported here as the only call
27
+ // site; everything in this file translates the public options
28
+ // shape into the engine's raw shape.
29
+ import engine from "./engine.js";
30
+ /**
31
+ * Convert AsciiDoc source to Markdown.
32
+ *
33
+ * Wraps the engine (Phase 4 port of md2md/src/downdoc.js) and
34
+ * exposes the documented public options shape. Output is Markdown
35
+ * with embedded Minja directives for unresolved variables and
36
+ * includes — resolve them downstream with `@dogsbay/minja`.
37
+ */
38
+ export function asciidocToMarkdown(src, opts = {}) {
39
+ // Translate the public options to engine option names. The only
40
+ // delta is `inlineIncludes` (public) → `nunjucksIncludes` (engine),
41
+ // which is the inverse boolean: inlineIncludes=true means inline
42
+ // at convert time, which the engine expresses as
43
+ // nunjucksIncludes=false.
44
+ return engine(src, {
45
+ attributes: opts.attributes ?? {},
46
+ basePath: opts.basePath ?? process.cwd(),
47
+ nunjucksIncludes: opts.inlineIncludes === true ? false : true,
48
+ dlistFormat: opts.dlistFormat ?? "markdown",
49
+ clampRowspans: opts.clampRowspans ?? false,
50
+ admonitionFormat: opts.admonitionFormat ?? "html",
51
+ blockRoles: opts.blockRoles ?? false,
52
+ sourcePath: opts.sourcePath ?? null,
53
+ antora: opts.antora ?? false,
54
+ antoraSlugPrefix: opts.antoraSlugPrefix ?? null,
55
+ antoraComponents: opts.antoraComponents ?? null,
56
+ falseAttributes: opts.falseAttributes ?? [],
57
+ includeRoot: opts.includeRoot ?? null,
58
+ });
59
+ }
60
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAwLH,2DAA2D;AAC3D,8DAA8D;AAC9D,8DAA8D;AAC9D,qCAAqC;AACrC,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,GAAW,EACX,OAAkC,EAAE;IAEpC,gEAAgE;IAChE,oEAAoE;IACpE,iEAAiE;IACjE,iDAAiD;IACjD,0BAA0B;IAC1B,OAAO,MAAM,CAAC,GAAG,EAAE;QACjB,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE;QACjC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE;QACxC,gBAAgB,EAAE,IAAI,CAAC,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;QAC7D,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,UAAU;QAC3C,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,KAAK;QAC1C,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,IAAI,MAAM;QACjD,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,KAAK;QACpC,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI;QACnC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK;QAC5B,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,IAAI,IAAI;QAC/C,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,IAAI,IAAI;QAC/C,eAAe,EAAE,IAAI,CAAC,eAAe,IAAI,EAAE;QAC3C,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI;KACtC,CAAC,CAAC;AACL,CAAC"}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@dogsbay/adoc2md-modular",
3
+ "version": "0.2.0-beta.101",
4
+ "description": "AsciiDoc → Markdown converter optimised for modular-content patterns (includes, leveloffset, conditionals, attributes). Ported from the md2md prototype; emits Markdown with embedded Minja directives for downstream variable / include resolution.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "bin": {
15
+ "adoc2md": "./bin/adoc2md.js",
16
+ "adoc2md-modular": "./bin/adoc2md.js"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "bin",
21
+ "README.md",
22
+ "LINEAGE.md"
23
+ ],
24
+ "devDependencies": {
25
+ "@types/node": "^25.9.5",
26
+ "typescript": "^5.9.3",
27
+ "vitest": "^4.1.10"
28
+ },
29
+ "license": "MIT",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/dogsbay/dogsbay.git",
33
+ "directory": "packages/adoc2md-modular"
34
+ },
35
+ "homepage": "https://github.com/dogsbay/dogsbay/tree/main/packages/adoc2md-modular",
36
+ "bugs": {
37
+ "url": "https://github.com/dogsbay/dogsbay/issues"
38
+ },
39
+ "scripts": {
40
+ "build": "tsc",
41
+ "test": "vitest run",
42
+ "test:watch": "vitest"
43
+ }
44
+ }