markdown-codec 4.1.0 → 5.0.0

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.
Files changed (40) hide show
  1. package/README.md +3 -4
  2. package/dist/block/block.d.cts +1 -1
  3. package/dist/block/block.d.ts +1 -1
  4. package/dist/block/definitions.d.cts +1 -1
  5. package/dist/block/definitions.d.ts +1 -1
  6. package/dist/diagnostics/diagnostics.cjs +0 -1
  7. package/dist/diagnostics/diagnostics.d.cts +1 -1
  8. package/dist/diagnostics/diagnostics.d.ts +1 -1
  9. package/dist/diagnostics/diagnostics.js +0 -1
  10. package/dist/{diagnostics-CUMLtGHJ.d.cts → diagnostics-CkcSYZf1.d.cts} +0 -1
  11. package/dist/{diagnostics-CUMLtGHJ.d.ts → diagnostics-CkcSYZf1.d.ts} +0 -1
  12. package/dist/emit/inline.cjs +20 -10
  13. package/dist/emit/inline.d.cts +1 -1
  14. package/dist/emit/inline.d.ts +1 -1
  15. package/dist/emit/inline.js +20 -10
  16. package/dist/emit/table.d.cts +1 -1
  17. package/dist/emit/table.d.ts +1 -1
  18. package/dist/index.cjs +0 -1
  19. package/dist/index.d.cts +3 -3
  20. package/dist/index.d.ts +3 -3
  21. package/dist/index.js +2 -2
  22. package/dist/lower/front-matter.d.cts +1 -1
  23. package/dist/lower/front-matter.d.ts +1 -1
  24. package/dist/lower/inline.cjs +10 -6
  25. package/dist/lower/inline.d.cts +2 -2
  26. package/dist/lower/inline.d.ts +2 -2
  27. package/dist/lower/inline.js +11 -7
  28. package/dist/lower/lower.cjs +4 -4
  29. package/dist/lower/lower.js +4 -4
  30. package/dist/lower/table.cjs +1 -1
  31. package/dist/lower/table.js +1 -1
  32. package/dist/options/options.d.cts +1 -1
  33. package/dist/options/options.d.ts +1 -1
  34. package/dist/read.d.cts +1 -1
  35. package/dist/read.d.ts +1 -1
  36. package/dist/shared/style-constants.cjs +0 -2
  37. package/dist/shared/style-constants.d.cts +1 -2
  38. package/dist/shared/style-constants.d.ts +1 -2
  39. package/dist/shared/style-constants.js +1 -2
  40. package/package.json +1 -1
package/README.md CHANGED
@@ -69,7 +69,7 @@ pnpm add markdown-codec
69
69
  npm install markdown-codec
70
70
  ```
71
71
 
72
- Published to [npmjs.org](https://www.npmjs.com/package/markdown-codec) via OIDC trusted publishing. `dist/` is committed rather than gitignored a holdover from a pre-publish period when a git-tarball install needed a working build; now a known cleanup.
72
+ Published to [npmjs.org](https://www.npmjs.com/package/markdown-codec) via OIDC trusted publishing. `dist/` is gitignored like every other package's build output: the published tarball carries the release build, and a workspace consumer gets `dist/` from turbo's `^_build` ordering, never from the repository.
73
73
 
74
74
  ## Usage
75
75
 
@@ -200,7 +200,6 @@ Every construct `src/lower`/`src/emit` cannot represent losslessly is a document
200
200
  - **`md/raw-html-preserved-as-text`** — see the raw-HTML entry above.
201
201
  - **`md/table-cell-formatting-dropped`** / **`md/table-cell-multi-paragraph-joined`** — GFM cells have no rich-formatting or multi-paragraph representation.
202
202
  - **`md/duplicate-footnote-definition`** — two definitions share a label; every reference resolves to the first, both are kept as written.
203
- - **`md/footnote-reference-preserved-as-text`** — a reference site is a marked run, not an `anchor` construct; see [Footnotes](#footnotes).
204
203
  - **`md/footnote-body-heading-flattened`** — a heading inside a definition body is carried as literal ATX text, since a construct extent may not open or close a heading scope.
205
204
  - **`md/construct-unrepresented`** — a construct kind markdown has no syntax for renders transparently: its extent still appears, the construct itself does not.
206
205
  - **`md/package-table-dropped`** — `writeMarkdown` only, ahead of flattening: a `DocumentPackage`'s own `definitions`/`layers`/`attachments`/`destinations`/`pages` table has no flat-`ContentDocument` home (`flattenPackage`'s own envelope carries forward only `metadata` and `symbolTable`); fires once per non-empty table present.
@@ -209,10 +208,10 @@ Every construct `src/lower`/`src/emit` cannot represent losslessly is a document
209
208
 
210
209
  GitHub's footnote extension (`[^label]` markers, `[^label]: body` definitions) is on by default, alongside the four GFM toggles — switch it off with `footnotes: false`. Neither CommonMark nor the GFM spec document defines footnotes, so both spellings are ordinary text with it off.
211
210
 
212
- The two halves of a footnote map onto **two different mechanisms**, and that split is structural rather than a choice:
211
+ The two halves of a footnote map onto the **same `anchor` construct at two different scopes**, and that split is structural rather than a choice:
213
212
 
214
213
  - **A definition becomes an `anchor` construct.** Lowering emits document-schema.js's construct boundary markers — a `constructStart` carrying `{ kind: 'anchor', anchorType: 'footnote', name }`, the definition's own lowered body blocks, and a `constructEnd` — which is what `readMarkdownContent` returns in its block flow, and what `decompose` promotes to a construct group of its own in the `DocumentPackage` `readMarkdown` returns (the descriptor rides the group's `node`, the body blocks its `children`). The body rides the construct's extent rather than `AnchorDescriptor.definition`, which names a key in a package-level definitions table: `DocumentPackage` does carry that table as a root (unlike the flat `ContentDocument`), but a table entry there is a flat descriptor record, not a container for block content, so a body that is genuinely several paragraphs, a code block, or a list still has nowhere to live as a table value either way — the construct's own bracketed extent is the one shape in this schema built to hold real block content. A bodyless `[^1]:` lowers to the point anchor the same descriptor describes: a pair with nothing between it.
215
- - **A reference site stays a marked run.** A construct's extent is block-scoped by document-schema.js's own definition, and a reference sits between two runs inside a paragraph, so no block-level boundary marker can bracket it without splitting the paragraph in two. The schema names this gap itself and parks the inline-anchor case on a run-level extent mechanism it has not shipped. Until it does, the reference is a `ContentRun` keeping its own `[^label]` spelling and carrying `FOOTNOTE_REFERENCE_FONT_MARKER`, reported through `md/footnote-reference-preserved-as-text`.
214
+ - **A reference site becomes a point run-level `anchor` extent.** A reference sits between two runs inside a paragraph, so no block-level boundary marker can bracket it without splitting the paragraph in two — but a run-level construct extent (`RunConstructExtent` on `ContentParagraph.constructs`, document-schema.js 4.5.0) names exactly that shape. Lowering emits an ordinary text run keeping the reference's own `[^label]` spelling (the materialised rendering, so a consumer that ignores constructs still shows `[^1]`) plus a point extent `{ kind: 'anchor', anchorType: 'footnote', name }` at `startRun === endRun` naming that run, the same wiring ooxml.js's docx reader mints for a `w:footnoteReference` carried through `decompose`/`flattenPackage` verbatim, exactly the way a table cell's own markers are. The writer spells `[^label]` back out from the covering extent rather than from anything about the run's text (which is what still distinguishes a genuine reference from a deliberately-escaped literal `\[^1\]`), gated by the same label grammar as the definition marker: a foreign name that grammar cannot spell degrades to the run's own escaped text plus `md/construct-unrepresented`.
216
215
 
217
216
  Definitions are recognised only at the document's own top level. Inside a block quote or a list item, the pair's extent would sit inside a scope the enclosing container had already opened, which the marker contract forbids a producer from emitting — so the text stays an ordinary paragraph there. A heading inside a definition body is flattened to literal ATX text for the same reason.
218
217
 
@@ -1,6 +1,6 @@
1
1
  import { s as MarkdownDocumentNode } from "../ast-8XCbjRQT.cjs";
2
2
  import { r as FootnoteLabelSet } from "../footnote-CKk4JbLk.cjs";
3
- import { i as MarkdownDiagnosticSink } from "../diagnostics-CUMLtGHJ.cjs";
3
+ import { i as MarkdownDiagnosticSink } from "../diagnostics-CkcSYZf1.cjs";
4
4
  import { LinkReferenceMap } from "../inline/link.cjs";
5
5
  import { t as InlineParseOptions } from "../inline-CoS1JzxI.cjs";
6
6
  //#region src/block/block.d.ts
@@ -1,6 +1,6 @@
1
1
  import { s as MarkdownDocumentNode } from "../ast-8XCbjRQT.js";
2
2
  import { r as FootnoteLabelSet } from "../footnote-CKk4JbLk.js";
3
- import { i as MarkdownDiagnosticSink } from "../diagnostics-CUMLtGHJ.js";
3
+ import { i as MarkdownDiagnosticSink } from "../diagnostics-CkcSYZf1.js";
4
4
  import { LinkReferenceMap } from "../inline/link.js";
5
5
  import { t as InlineParseOptions } from "../inline-OGXVE6hB.js";
6
6
  //#region src/block/block.d.ts
@@ -1,4 +1,4 @@
1
- import { i as MarkdownDiagnosticSink } from "../diagnostics-CUMLtGHJ.cjs";
1
+ import { i as MarkdownDiagnosticSink } from "../diagnostics-CkcSYZf1.cjs";
2
2
  import { LinkReferenceDefinition } from "../inline/link.cjs";
3
3
  //#region src/block/definitions.d.ts
4
4
  declare function extractDefinitions(content: string, references: Map<string, LinkReferenceDefinition>, sink?: MarkdownDiagnosticSink, startLine?: number): string;
@@ -1,4 +1,4 @@
1
- import { i as MarkdownDiagnosticSink } from "../diagnostics-CUMLtGHJ.js";
1
+ import { i as MarkdownDiagnosticSink } from "../diagnostics-CkcSYZf1.js";
2
2
  import { LinkReferenceDefinition } from "../inline/link.js";
3
3
  //#region src/block/definitions.d.ts
4
4
  declare function extractDefinitions(content: string, references: Map<string, LinkReferenceDefinition>, sink?: MarkdownDiagnosticSink, startLine?: number): string;
@@ -19,7 +19,6 @@ const MarkdownDiagnosticCodes = {
19
19
  RAW_HTML_DROPPED: "md/raw-html-dropped",
20
20
  MATH_INLINE_PRESERVED_AS_TEXT: "md/math-inline-preserved-as-text",
21
21
  FRONT_MATTER_KEY_UNMAPPED: "md/front-matter-key-unmapped",
22
- FOOTNOTE_REFERENCE_PRESERVED_AS_TEXT: "md/footnote-reference-preserved-as-text",
23
22
  FOOTNOTE_BODY_HEADING_FLATTENED: "md/footnote-body-heading-flattened",
24
23
  CONSTRUCT_UNREPRESENTED: "md/construct-unrepresented",
25
24
  PACKAGE_TABLE_DROPPED: "md/package-table-dropped",
@@ -1,2 +1,2 @@
1
- import { a as MarkdownInputTooLargeError, c as MarkdownNestingLimitExceededError, d as MarkdownUnbalancedConstructMarkersError, f as MarkdownUnsupportedDocumentKindError, i as MarkdownDiagnosticSink, l as MarkdownPackageFlattenError, m as NOOP_MARKDOWN_DIAGNOSTIC_SINK, n as MarkdownDiagnosticCodes, o as MarkdownInvalidRunConstructExtentError, p as MarkdownWriteError, r as MarkdownDiagnosticSeverity, s as MarkdownInvalidUtf8Error, t as MarkdownDiagnostic, u as MarkdownParseError } from "../diagnostics-CUMLtGHJ.cjs";
1
+ import { a as MarkdownInputTooLargeError, c as MarkdownNestingLimitExceededError, d as MarkdownUnbalancedConstructMarkersError, f as MarkdownUnsupportedDocumentKindError, i as MarkdownDiagnosticSink, l as MarkdownPackageFlattenError, m as NOOP_MARKDOWN_DIAGNOSTIC_SINK, n as MarkdownDiagnosticCodes, o as MarkdownInvalidRunConstructExtentError, p as MarkdownWriteError, r as MarkdownDiagnosticSeverity, s as MarkdownInvalidUtf8Error, t as MarkdownDiagnostic, u as MarkdownParseError } from "../diagnostics-CkcSYZf1.cjs";
2
2
  export { MarkdownDiagnostic, MarkdownDiagnosticCodes, MarkdownDiagnosticSeverity, MarkdownDiagnosticSink, MarkdownInputTooLargeError, MarkdownInvalidRunConstructExtentError, MarkdownInvalidUtf8Error, MarkdownNestingLimitExceededError, MarkdownPackageFlattenError, MarkdownParseError, MarkdownUnbalancedConstructMarkersError, MarkdownUnsupportedDocumentKindError, MarkdownWriteError, NOOP_MARKDOWN_DIAGNOSTIC_SINK };
@@ -1,2 +1,2 @@
1
- import { a as MarkdownInputTooLargeError, c as MarkdownNestingLimitExceededError, d as MarkdownUnbalancedConstructMarkersError, f as MarkdownUnsupportedDocumentKindError, i as MarkdownDiagnosticSink, l as MarkdownPackageFlattenError, m as NOOP_MARKDOWN_DIAGNOSTIC_SINK, n as MarkdownDiagnosticCodes, o as MarkdownInvalidRunConstructExtentError, p as MarkdownWriteError, r as MarkdownDiagnosticSeverity, s as MarkdownInvalidUtf8Error, t as MarkdownDiagnostic, u as MarkdownParseError } from "../diagnostics-CUMLtGHJ.js";
1
+ import { a as MarkdownInputTooLargeError, c as MarkdownNestingLimitExceededError, d as MarkdownUnbalancedConstructMarkersError, f as MarkdownUnsupportedDocumentKindError, i as MarkdownDiagnosticSink, l as MarkdownPackageFlattenError, m as NOOP_MARKDOWN_DIAGNOSTIC_SINK, n as MarkdownDiagnosticCodes, o as MarkdownInvalidRunConstructExtentError, p as MarkdownWriteError, r as MarkdownDiagnosticSeverity, s as MarkdownInvalidUtf8Error, t as MarkdownDiagnostic, u as MarkdownParseError } from "../diagnostics-CkcSYZf1.js";
2
2
  export { MarkdownDiagnostic, MarkdownDiagnosticCodes, MarkdownDiagnosticSeverity, MarkdownDiagnosticSink, MarkdownInputTooLargeError, MarkdownInvalidRunConstructExtentError, MarkdownInvalidUtf8Error, MarkdownNestingLimitExceededError, MarkdownPackageFlattenError, MarkdownParseError, MarkdownUnbalancedConstructMarkersError, MarkdownUnsupportedDocumentKindError, MarkdownWriteError, NOOP_MARKDOWN_DIAGNOSTIC_SINK };
@@ -18,7 +18,6 @@ const MarkdownDiagnosticCodes = {
18
18
  RAW_HTML_DROPPED: "md/raw-html-dropped",
19
19
  MATH_INLINE_PRESERVED_AS_TEXT: "md/math-inline-preserved-as-text",
20
20
  FRONT_MATTER_KEY_UNMAPPED: "md/front-matter-key-unmapped",
21
- FOOTNOTE_REFERENCE_PRESERVED_AS_TEXT: "md/footnote-reference-preserved-as-text",
22
21
  FOOTNOTE_BODY_HEADING_FLATTENED: "md/footnote-body-heading-flattened",
23
22
  CONSTRUCT_UNREPRESENTED: "md/construct-unrepresented",
24
23
  PACKAGE_TABLE_DROPPED: "md/package-table-dropped",
@@ -26,7 +26,6 @@ declare const MarkdownDiagnosticCodes: {
26
26
  readonly RAW_HTML_DROPPED: "md/raw-html-dropped";
27
27
  readonly MATH_INLINE_PRESERVED_AS_TEXT: "md/math-inline-preserved-as-text";
28
28
  readonly FRONT_MATTER_KEY_UNMAPPED: "md/front-matter-key-unmapped";
29
- readonly FOOTNOTE_REFERENCE_PRESERVED_AS_TEXT: "md/footnote-reference-preserved-as-text";
30
29
  readonly FOOTNOTE_BODY_HEADING_FLATTENED: "md/footnote-body-heading-flattened";
31
30
  readonly CONSTRUCT_UNREPRESENTED: "md/construct-unrepresented";
32
31
  readonly PACKAGE_TABLE_DROPPED: "md/package-table-dropped";
@@ -26,7 +26,6 @@ declare const MarkdownDiagnosticCodes: {
26
26
  readonly RAW_HTML_DROPPED: "md/raw-html-dropped";
27
27
  readonly MATH_INLINE_PRESERVED_AS_TEXT: "md/math-inline-preserved-as-text";
28
28
  readonly FRONT_MATTER_KEY_UNMAPPED: "md/front-matter-key-unmapped";
29
- readonly FOOTNOTE_REFERENCE_PRESERVED_AS_TEXT: "md/footnote-reference-preserved-as-text";
30
29
  readonly FOOTNOTE_BODY_HEADING_FLATTENED: "md/footnote-body-heading-flattened";
31
30
  readonly CONSTRUCT_UNREPRESENTED: "md/construct-unrepresented";
32
31
  readonly PACKAGE_TABLE_DROPPED: "md/package-table-dropped";
@@ -1,4 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_inline_footnote = require("../inline/footnote.cjs");
2
3
  const require_diagnostics_diagnostics = require("../diagnostics/diagnostics.cjs");
3
4
  require("../shared/style-constants.cjs");
4
5
  //#region src/emit/inline.ts
@@ -67,7 +68,10 @@ function renderCodeSpan(text) {
67
68
  const wouldBeStrippedOnReparse = !isAllSpaces && text.startsWith(" ") && text.endsWith(" ");
68
69
  return risksFenceCollision || wouldBeStrippedOnReparse ? `${fence} ${text} ${fence}` : `${fence}${text}${fence}`;
69
70
  }
70
- function renderLeaf(run, context) {
71
+ function footnoteReferenceAt(constructs, index) {
72
+ for (const extent of constructs ?? []) if (extent.descriptor.kind === "anchor" && extent.descriptor.anchorType === "footnote" && extent.startRun === index && extent.endRun === index) return extent.descriptor;
73
+ }
74
+ function renderLeaf(run, context, index, constructs) {
71
75
  if (run.source?.format === "markdown") return run.source.xml;
72
76
  if (run.fontFamily === "Courier New") {
73
77
  context.sink({
@@ -77,7 +81,13 @@ function renderLeaf(run, context) {
77
81
  });
78
82
  return renderCodeSpan(run.text);
79
83
  }
80
- if (run.fontFamily === "Footnote Reference") return run.text;
84
+ const footnote = footnoteReferenceAt(constructs, index);
85
+ if (footnote !== void 0 && require_inline_footnote.isValidFootnoteLabel(footnote.name)) return `[^${footnote.name}]`;
86
+ if (footnote !== void 0) context.sink({
87
+ code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.CONSTRUCT_UNREPRESENTED,
88
+ severity: "info",
89
+ message: `a footnote reference anchor's own name "${footnote.name}" cannot be spelled as a "[^label]" marker (whitespace or "]" would reparse as something else); the run's own text renders escaped in its place, but the reference itself is not represented`
90
+ });
81
91
  if (run.fontFamily === "Cambria Math") return `\\(${run.text}\\)`;
82
92
  return escapeMarkdownText(run.text);
83
93
  }
@@ -110,8 +120,8 @@ function wrapForStyle(body, key, context, precedingText) {
110
120
  const delimiter = key === "bold" ? marker.repeat(2) : marker;
111
121
  return `${delimiter}${body}${delimiter}`;
112
122
  }
113
- function renderNestedStyles(runs, depth, context) {
114
- if (depth >= STYLE_KEYS.length) return runs.map((run) => renderLeaf(run, context)).join("");
123
+ function renderNestedStyles(runs, depth, context, base, constructs) {
124
+ if (depth >= STYLE_KEYS.length) return runs.map((run, local) => renderLeaf(run, context, base + local, constructs)).join("");
115
125
  const key = STYLE_KEYS[depth];
116
126
  let out = "";
117
127
  let index = 0;
@@ -121,14 +131,14 @@ function renderNestedStyles(runs, depth, context) {
121
131
  const active = styleActive(current, key);
122
132
  let end = index + 1;
123
133
  while (end < runs.length && styleActive(runs[end], key) === active) end += 1;
124
- const inner = renderNestedStyles(runs.slice(index, end), depth + 1, context);
134
+ const inner = renderNestedStyles(runs.slice(index, end), depth + 1, context, base + index, constructs);
125
135
  out += active ? wrapForStyle(inner, key, context, out) : inner;
126
136
  index = end;
127
137
  }
128
138
  return out;
129
139
  }
130
- function isPlainAutolink(run) {
131
- if (run.hyperlink === void 0 || run.hyperlink.length === 0 || run.bold === true || run.italic === true || run.strike === true || run.fontFamily === "Courier New" || run.fontFamily === "Cambria Math" || run.fontFamily === "Footnote Reference") return false;
140
+ function isPlainAutolink(run, footnoteReference) {
141
+ if (run.hyperlink === void 0 || run.hyperlink.length === 0 || run.bold === true || run.italic === true || run.strike === true || run.fontFamily === "Courier New" || run.fontFamily === "Cambria Math" || footnoteReference !== void 0) return false;
132
142
  return run.text === run.hyperlink || run.hyperlink === `mailto:${run.text}`;
133
143
  }
134
144
  function escapeLinkDestination(destination) {
@@ -157,7 +167,7 @@ function emitRuns(runs, context, constructs = void 0) {
157
167
  if (run.hyperlink === void 0) {
158
168
  let end = index + 1;
159
169
  while (end < runs.length && runs[end]?.hyperlink === void 0) end += 1;
160
- out += renderNestedStyles(runs.slice(index, end), 0, context);
170
+ out += renderNestedStyles(runs.slice(index, end), 0, context, index, constructs);
161
171
  index = end;
162
172
  continue;
163
173
  }
@@ -171,9 +181,9 @@ function emitRuns(runs, context, constructs = void 0) {
171
181
  message: `${String(group.length)} adjacent runs share the hyperlink "${hyperlink}"; markdown has no way to place two link boundaries back to back, so they render as one link spanning their combined text`
172
182
  });
173
183
  const title = linkTitleCovering(constructs, index, groupEnd);
174
- if (title === void 0 && group.length === 1 && isPlainAutolink(group[0])) out += `<${group[0].text}>`;
184
+ if (title === void 0 && group.length === 1 && isPlainAutolink(group[0], footnoteReferenceAt(constructs, index))) out += `<${group[0].text}>`;
175
185
  else {
176
- const linkText = renderNestedStyles(group, 0, context);
186
+ const linkText = renderNestedStyles(group, 0, context, index, constructs);
177
187
  out += `[${linkText}](${escapeLinkDestination(hyperlink)}${title === void 0 ? "" : ` "${renderLinkTitle(title)}"`})`;
178
188
  }
179
189
  index = groupEnd;
@@ -1,4 +1,4 @@
1
- import { i as MarkdownDiagnosticSink } from "../diagnostics-CUMLtGHJ.cjs";
1
+ import { i as MarkdownDiagnosticSink } from "../diagnostics-CkcSYZf1.cjs";
2
2
  import { ContentRun, RunConstructExtent } from "document-schema.js";
3
3
  //#region src/emit/inline.d.ts
4
4
  interface InlineEmitContext {
@@ -1,4 +1,4 @@
1
- import { i as MarkdownDiagnosticSink } from "../diagnostics-CUMLtGHJ.js";
1
+ import { i as MarkdownDiagnosticSink } from "../diagnostics-CkcSYZf1.js";
2
2
  import { ContentRun, RunConstructExtent } from "document-schema.js";
3
3
  //#region src/emit/inline.d.ts
4
4
  interface InlineEmitContext {
@@ -1,3 +1,4 @@
1
+ import { isValidFootnoteLabel } from "../inline/footnote.js";
1
2
  import { MarkdownDiagnosticCodes } from "../diagnostics/diagnostics.js";
2
3
  import "../shared/style-constants.js";
3
4
  //#region src/emit/inline.ts
@@ -66,7 +67,10 @@ function renderCodeSpan(text) {
66
67
  const wouldBeStrippedOnReparse = !isAllSpaces && text.startsWith(" ") && text.endsWith(" ");
67
68
  return risksFenceCollision || wouldBeStrippedOnReparse ? `${fence} ${text} ${fence}` : `${fence}${text}${fence}`;
68
69
  }
69
- function renderLeaf(run, context) {
70
+ function footnoteReferenceAt(constructs, index) {
71
+ for (const extent of constructs ?? []) if (extent.descriptor.kind === "anchor" && extent.descriptor.anchorType === "footnote" && extent.startRun === index && extent.endRun === index) return extent.descriptor;
72
+ }
73
+ function renderLeaf(run, context, index, constructs) {
70
74
  if (run.source?.format === "markdown") return run.source.xml;
71
75
  if (run.fontFamily === "Courier New") {
72
76
  context.sink({
@@ -76,7 +80,13 @@ function renderLeaf(run, context) {
76
80
  });
77
81
  return renderCodeSpan(run.text);
78
82
  }
79
- if (run.fontFamily === "Footnote Reference") return run.text;
83
+ const footnote = footnoteReferenceAt(constructs, index);
84
+ if (footnote !== void 0 && isValidFootnoteLabel(footnote.name)) return `[^${footnote.name}]`;
85
+ if (footnote !== void 0) context.sink({
86
+ code: MarkdownDiagnosticCodes.CONSTRUCT_UNREPRESENTED,
87
+ severity: "info",
88
+ message: `a footnote reference anchor's own name "${footnote.name}" cannot be spelled as a "[^label]" marker (whitespace or "]" would reparse as something else); the run's own text renders escaped in its place, but the reference itself is not represented`
89
+ });
80
90
  if (run.fontFamily === "Cambria Math") return `\\(${run.text}\\)`;
81
91
  return escapeMarkdownText(run.text);
82
92
  }
@@ -109,8 +119,8 @@ function wrapForStyle(body, key, context, precedingText) {
109
119
  const delimiter = key === "bold" ? marker.repeat(2) : marker;
110
120
  return `${delimiter}${body}${delimiter}`;
111
121
  }
112
- function renderNestedStyles(runs, depth, context) {
113
- if (depth >= STYLE_KEYS.length) return runs.map((run) => renderLeaf(run, context)).join("");
122
+ function renderNestedStyles(runs, depth, context, base, constructs) {
123
+ if (depth >= STYLE_KEYS.length) return runs.map((run, local) => renderLeaf(run, context, base + local, constructs)).join("");
114
124
  const key = STYLE_KEYS[depth];
115
125
  let out = "";
116
126
  let index = 0;
@@ -120,14 +130,14 @@ function renderNestedStyles(runs, depth, context) {
120
130
  const active = styleActive(current, key);
121
131
  let end = index + 1;
122
132
  while (end < runs.length && styleActive(runs[end], key) === active) end += 1;
123
- const inner = renderNestedStyles(runs.slice(index, end), depth + 1, context);
133
+ const inner = renderNestedStyles(runs.slice(index, end), depth + 1, context, base + index, constructs);
124
134
  out += active ? wrapForStyle(inner, key, context, out) : inner;
125
135
  index = end;
126
136
  }
127
137
  return out;
128
138
  }
129
- function isPlainAutolink(run) {
130
- if (run.hyperlink === void 0 || run.hyperlink.length === 0 || run.bold === true || run.italic === true || run.strike === true || run.fontFamily === "Courier New" || run.fontFamily === "Cambria Math" || run.fontFamily === "Footnote Reference") return false;
139
+ function isPlainAutolink(run, footnoteReference) {
140
+ if (run.hyperlink === void 0 || run.hyperlink.length === 0 || run.bold === true || run.italic === true || run.strike === true || run.fontFamily === "Courier New" || run.fontFamily === "Cambria Math" || footnoteReference !== void 0) return false;
131
141
  return run.text === run.hyperlink || run.hyperlink === `mailto:${run.text}`;
132
142
  }
133
143
  function escapeLinkDestination(destination) {
@@ -156,7 +166,7 @@ function emitRuns(runs, context, constructs = void 0) {
156
166
  if (run.hyperlink === void 0) {
157
167
  let end = index + 1;
158
168
  while (end < runs.length && runs[end]?.hyperlink === void 0) end += 1;
159
- out += renderNestedStyles(runs.slice(index, end), 0, context);
169
+ out += renderNestedStyles(runs.slice(index, end), 0, context, index, constructs);
160
170
  index = end;
161
171
  continue;
162
172
  }
@@ -170,9 +180,9 @@ function emitRuns(runs, context, constructs = void 0) {
170
180
  message: `${String(group.length)} adjacent runs share the hyperlink "${hyperlink}"; markdown has no way to place two link boundaries back to back, so they render as one link spanning their combined text`
171
181
  });
172
182
  const title = linkTitleCovering(constructs, index, groupEnd);
173
- if (title === void 0 && group.length === 1 && isPlainAutolink(group[0])) out += `<${group[0].text}>`;
183
+ if (title === void 0 && group.length === 1 && isPlainAutolink(group[0], footnoteReferenceAt(constructs, index))) out += `<${group[0].text}>`;
174
184
  else {
175
- const linkText = renderNestedStyles(group, 0, context);
185
+ const linkText = renderNestedStyles(group, 0, context, index, constructs);
176
186
  out += `[${linkText}](${escapeLinkDestination(hyperlink)}${title === void 0 ? "" : ` "${renderLinkTitle(title)}"`})`;
177
187
  }
178
188
  index = groupEnd;
@@ -1,4 +1,4 @@
1
- import { i as MarkdownDiagnosticSink } from "../diagnostics-CUMLtGHJ.cjs";
1
+ import { i as MarkdownDiagnosticSink } from "../diagnostics-CkcSYZf1.cjs";
2
2
  import { InlineEmitContext } from "./inline.cjs";
3
3
  import { ContentTable } from "document-schema.js";
4
4
  //#region src/emit/table.d.ts
@@ -1,4 +1,4 @@
1
- import { i as MarkdownDiagnosticSink } from "../diagnostics-CUMLtGHJ.js";
1
+ import { i as MarkdownDiagnosticSink } from "../diagnostics-CkcSYZf1.js";
2
2
  import { InlineEmitContext } from "./inline.js";
3
3
  import { ContentTable } from "document-schema.js";
4
4
  //#region src/emit/table.d.ts
package/dist/index.cjs CHANGED
@@ -6,7 +6,6 @@ const require_read = require("./read.cjs");
6
6
  const require_write = require("./write.cjs");
7
7
  const require_codec = require("./codec.cjs");
8
8
  exports.CODE_BLOCK_STYLE_ID = require_shared_style_constants.CODE_BLOCK_STYLE_ID;
9
- exports.FOOTNOTE_REFERENCE_FONT_MARKER = require_shared_style_constants.FOOTNOTE_REFERENCE_FONT_MARKER;
10
9
  exports.HORIZONTAL_RULE_STYLE_ID = require_shared_style_constants.HORIZONTAL_RULE_STYLE_ID;
11
10
  exports.HTML_PREFORMATTED_STYLE_ID = require_shared_style_constants.HTML_PREFORMATTED_STYLE_ID;
12
11
  exports.MAX_HEADING_STYLE_LEVEL = require_shared_style_constants.MAX_HEADING_STYLE_LEVEL;
package/dist/index.d.cts CHANGED
@@ -1,9 +1,9 @@
1
- import { a as MarkdownInputTooLargeError, c as MarkdownNestingLimitExceededError, d as MarkdownUnbalancedConstructMarkersError, f as MarkdownUnsupportedDocumentKindError, i as MarkdownDiagnosticSink, m as NOOP_MARKDOWN_DIAGNOSTIC_SINK, n as MarkdownDiagnosticCodes, o as MarkdownInvalidRunConstructExtentError, p as MarkdownWriteError, r as MarkdownDiagnosticSeverity, s as MarkdownInvalidUtf8Error, t as MarkdownDiagnostic, u as MarkdownParseError } from "./diagnostics-CUMLtGHJ.cjs";
1
+ import { a as MarkdownInputTooLargeError, c as MarkdownNestingLimitExceededError, d as MarkdownUnbalancedConstructMarkersError, f as MarkdownUnsupportedDocumentKindError, i as MarkdownDiagnosticSink, m as NOOP_MARKDOWN_DIAGNOSTIC_SINK, n as MarkdownDiagnosticCodes, o as MarkdownInvalidRunConstructExtentError, p as MarkdownWriteError, r as MarkdownDiagnosticSeverity, s as MarkdownInvalidUtf8Error, t as MarkdownDiagnostic, u as MarkdownParseError } from "./diagnostics-CkcSYZf1.cjs";
2
2
  import { MarkdownBytesSchema, markdownCodec, markdownContentCodec } from "./codec.cjs";
3
3
  import { n as MarkdownImageResolver, r as MarkdownResolvedImageBytes, t as MarkdownImageResolveContext } from "./image-C4KYmz_L.cjs";
4
4
  import { MarkdownBulletListMarker, MarkdownCodeFenceChar, MarkdownEmphasisMarker, MarkdownHeadingStyle, MarkdownLineEnding, MarkdownOrderedListDelimiter, MarkdownThematicBreakChar, ReadMarkdownOptions, WriteMarkdownOptions, WriteMarkdownStyleOptions } from "./options/options.cjs";
5
5
  import { ReadMarkdownContentResult, ReadMarkdownResult, readMarkdown, readMarkdownContent } from "./read.cjs";
6
6
  import { writeMarkdown, writeMarkdownContent } from "./write.cjs";
7
7
  import { ListNumIdInfo, ListNumIdMintOptions, NumIdMintState, createNumIdMintState, mintListNumId, mintedListType, parseListNumId } from "./shared/list-id.cjs";
8
- import { CODE_BLOCK_STYLE_ID, FOOTNOTE_REFERENCE_FONT_MARKER, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, QUOTE_INDENT_PT, QUOTE_STYLE_ID, headingStyleId, parseHeadingStyleId } from "./shared/style-constants.cjs";
9
- export { CODE_BLOCK_STYLE_ID, FOOTNOTE_REFERENCE_FONT_MARKER, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, type ListNumIdInfo, type ListNumIdMintOptions, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, type MarkdownBulletListMarker, MarkdownBytesSchema, type MarkdownCodeFenceChar, type MarkdownDiagnostic, MarkdownDiagnosticCodes, type MarkdownDiagnosticSeverity, type MarkdownDiagnosticSink, type MarkdownEmphasisMarker, type MarkdownHeadingStyle, type MarkdownImageResolveContext, type MarkdownImageResolver, MarkdownInputTooLargeError, MarkdownInvalidRunConstructExtentError, MarkdownInvalidUtf8Error, type MarkdownLineEnding, MarkdownNestingLimitExceededError, type MarkdownOrderedListDelimiter, MarkdownParseError, type MarkdownResolvedImageBytes, type MarkdownThematicBreakChar, MarkdownUnbalancedConstructMarkersError, MarkdownUnsupportedDocumentKindError, MarkdownWriteError, NOOP_MARKDOWN_DIAGNOSTIC_SINK, type NumIdMintState, QUOTE_INDENT_PT, QUOTE_STYLE_ID, type ReadMarkdownContentResult, type ReadMarkdownOptions, type ReadMarkdownResult, type WriteMarkdownOptions, type WriteMarkdownStyleOptions, createNumIdMintState, headingStyleId, markdownCodec, markdownContentCodec, mintListNumId, mintedListType, parseHeadingStyleId, parseListNumId, readMarkdown, readMarkdownContent, writeMarkdown, writeMarkdownContent };
8
+ import { CODE_BLOCK_STYLE_ID, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, QUOTE_INDENT_PT, QUOTE_STYLE_ID, headingStyleId, parseHeadingStyleId } from "./shared/style-constants.cjs";
9
+ export { CODE_BLOCK_STYLE_ID, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, type ListNumIdInfo, type ListNumIdMintOptions, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, type MarkdownBulletListMarker, MarkdownBytesSchema, type MarkdownCodeFenceChar, type MarkdownDiagnostic, MarkdownDiagnosticCodes, type MarkdownDiagnosticSeverity, type MarkdownDiagnosticSink, type MarkdownEmphasisMarker, type MarkdownHeadingStyle, type MarkdownImageResolveContext, type MarkdownImageResolver, MarkdownInputTooLargeError, MarkdownInvalidRunConstructExtentError, MarkdownInvalidUtf8Error, type MarkdownLineEnding, MarkdownNestingLimitExceededError, type MarkdownOrderedListDelimiter, MarkdownParseError, type MarkdownResolvedImageBytes, type MarkdownThematicBreakChar, MarkdownUnbalancedConstructMarkersError, MarkdownUnsupportedDocumentKindError, MarkdownWriteError, NOOP_MARKDOWN_DIAGNOSTIC_SINK, type NumIdMintState, QUOTE_INDENT_PT, QUOTE_STYLE_ID, type ReadMarkdownContentResult, type ReadMarkdownOptions, type ReadMarkdownResult, type WriteMarkdownOptions, type WriteMarkdownStyleOptions, createNumIdMintState, headingStyleId, markdownCodec, markdownContentCodec, mintListNumId, mintedListType, parseHeadingStyleId, parseListNumId, readMarkdown, readMarkdownContent, writeMarkdown, writeMarkdownContent };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { a as MarkdownInputTooLargeError, c as MarkdownNestingLimitExceededError, d as MarkdownUnbalancedConstructMarkersError, f as MarkdownUnsupportedDocumentKindError, i as MarkdownDiagnosticSink, m as NOOP_MARKDOWN_DIAGNOSTIC_SINK, n as MarkdownDiagnosticCodes, o as MarkdownInvalidRunConstructExtentError, p as MarkdownWriteError, r as MarkdownDiagnosticSeverity, s as MarkdownInvalidUtf8Error, t as MarkdownDiagnostic, u as MarkdownParseError } from "./diagnostics-CUMLtGHJ.js";
1
+ import { a as MarkdownInputTooLargeError, c as MarkdownNestingLimitExceededError, d as MarkdownUnbalancedConstructMarkersError, f as MarkdownUnsupportedDocumentKindError, i as MarkdownDiagnosticSink, m as NOOP_MARKDOWN_DIAGNOSTIC_SINK, n as MarkdownDiagnosticCodes, o as MarkdownInvalidRunConstructExtentError, p as MarkdownWriteError, r as MarkdownDiagnosticSeverity, s as MarkdownInvalidUtf8Error, t as MarkdownDiagnostic, u as MarkdownParseError } from "./diagnostics-CkcSYZf1.js";
2
2
  import { MarkdownBytesSchema, markdownCodec, markdownContentCodec } from "./codec.js";
3
3
  import { n as MarkdownImageResolver, r as MarkdownResolvedImageBytes, t as MarkdownImageResolveContext } from "./image-Cm3hT5PS.js";
4
4
  import { MarkdownBulletListMarker, MarkdownCodeFenceChar, MarkdownEmphasisMarker, MarkdownHeadingStyle, MarkdownLineEnding, MarkdownOrderedListDelimiter, MarkdownThematicBreakChar, ReadMarkdownOptions, WriteMarkdownOptions, WriteMarkdownStyleOptions } from "./options/options.js";
5
5
  import { ReadMarkdownContentResult, ReadMarkdownResult, readMarkdown, readMarkdownContent } from "./read.js";
6
6
  import { writeMarkdown, writeMarkdownContent } from "./write.js";
7
7
  import { ListNumIdInfo, ListNumIdMintOptions, NumIdMintState, createNumIdMintState, mintListNumId, mintedListType, parseListNumId } from "./shared/list-id.js";
8
- import { CODE_BLOCK_STYLE_ID, FOOTNOTE_REFERENCE_FONT_MARKER, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, QUOTE_INDENT_PT, QUOTE_STYLE_ID, headingStyleId, parseHeadingStyleId } from "./shared/style-constants.js";
9
- export { CODE_BLOCK_STYLE_ID, FOOTNOTE_REFERENCE_FONT_MARKER, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, type ListNumIdInfo, type ListNumIdMintOptions, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, type MarkdownBulletListMarker, MarkdownBytesSchema, type MarkdownCodeFenceChar, type MarkdownDiagnostic, MarkdownDiagnosticCodes, type MarkdownDiagnosticSeverity, type MarkdownDiagnosticSink, type MarkdownEmphasisMarker, type MarkdownHeadingStyle, type MarkdownImageResolveContext, type MarkdownImageResolver, MarkdownInputTooLargeError, MarkdownInvalidRunConstructExtentError, MarkdownInvalidUtf8Error, type MarkdownLineEnding, MarkdownNestingLimitExceededError, type MarkdownOrderedListDelimiter, MarkdownParseError, type MarkdownResolvedImageBytes, type MarkdownThematicBreakChar, MarkdownUnbalancedConstructMarkersError, MarkdownUnsupportedDocumentKindError, MarkdownWriteError, NOOP_MARKDOWN_DIAGNOSTIC_SINK, type NumIdMintState, QUOTE_INDENT_PT, QUOTE_STYLE_ID, type ReadMarkdownContentResult, type ReadMarkdownOptions, type ReadMarkdownResult, type WriteMarkdownOptions, type WriteMarkdownStyleOptions, createNumIdMintState, headingStyleId, markdownCodec, markdownContentCodec, mintListNumId, mintedListType, parseHeadingStyleId, parseListNumId, readMarkdown, readMarkdownContent, writeMarkdown, writeMarkdownContent };
8
+ import { CODE_BLOCK_STYLE_ID, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, QUOTE_INDENT_PT, QUOTE_STYLE_ID, headingStyleId, parseHeadingStyleId } from "./shared/style-constants.js";
9
+ export { CODE_BLOCK_STYLE_ID, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, type ListNumIdInfo, type ListNumIdMintOptions, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, type MarkdownBulletListMarker, MarkdownBytesSchema, type MarkdownCodeFenceChar, type MarkdownDiagnostic, MarkdownDiagnosticCodes, type MarkdownDiagnosticSeverity, type MarkdownDiagnosticSink, type MarkdownEmphasisMarker, type MarkdownHeadingStyle, type MarkdownImageResolveContext, type MarkdownImageResolver, MarkdownInputTooLargeError, MarkdownInvalidRunConstructExtentError, MarkdownInvalidUtf8Error, type MarkdownLineEnding, MarkdownNestingLimitExceededError, type MarkdownOrderedListDelimiter, MarkdownParseError, type MarkdownResolvedImageBytes, type MarkdownThematicBreakChar, MarkdownUnbalancedConstructMarkersError, MarkdownUnsupportedDocumentKindError, MarkdownWriteError, NOOP_MARKDOWN_DIAGNOSTIC_SINK, type NumIdMintState, QUOTE_INDENT_PT, QUOTE_STYLE_ID, type ReadMarkdownContentResult, type ReadMarkdownOptions, type ReadMarkdownResult, type WriteMarkdownOptions, type WriteMarkdownStyleOptions, createNumIdMintState, headingStyleId, markdownCodec, markdownContentCodec, mintListNumId, mintedListType, parseHeadingStyleId, parseListNumId, readMarkdown, readMarkdownContent, writeMarkdown, writeMarkdownContent };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { MarkdownDiagnosticCodes, MarkdownInputTooLargeError, MarkdownInvalidRunConstructExtentError, MarkdownInvalidUtf8Error, MarkdownNestingLimitExceededError, MarkdownParseError, MarkdownUnbalancedConstructMarkersError, MarkdownUnsupportedDocumentKindError, MarkdownWriteError, NOOP_MARKDOWN_DIAGNOSTIC_SINK } from "./diagnostics/diagnostics.js";
2
2
  import { createNumIdMintState, mintListNumId, mintedListType, parseListNumId } from "./shared/list-id.js";
3
- import { CODE_BLOCK_STYLE_ID, FOOTNOTE_REFERENCE_FONT_MARKER, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, QUOTE_INDENT_PT, QUOTE_STYLE_ID, headingStyleId, parseHeadingStyleId } from "./shared/style-constants.js";
3
+ import { CODE_BLOCK_STYLE_ID, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, QUOTE_INDENT_PT, QUOTE_STYLE_ID, headingStyleId, parseHeadingStyleId } from "./shared/style-constants.js";
4
4
  import { readMarkdown, readMarkdownContent } from "./read.js";
5
5
  import { writeMarkdown, writeMarkdownContent } from "./write.js";
6
6
  import { MarkdownBytesSchema, markdownCodec, markdownContentCodec } from "./codec.js";
7
- export { CODE_BLOCK_STYLE_ID, FOOTNOTE_REFERENCE_FONT_MARKER, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, MarkdownBytesSchema, MarkdownDiagnosticCodes, MarkdownInputTooLargeError, MarkdownInvalidRunConstructExtentError, MarkdownInvalidUtf8Error, MarkdownNestingLimitExceededError, MarkdownParseError, MarkdownUnbalancedConstructMarkersError, MarkdownUnsupportedDocumentKindError, MarkdownWriteError, NOOP_MARKDOWN_DIAGNOSTIC_SINK, QUOTE_INDENT_PT, QUOTE_STYLE_ID, createNumIdMintState, headingStyleId, markdownCodec, markdownContentCodec, mintListNumId, mintedListType, parseHeadingStyleId, parseListNumId, readMarkdown, readMarkdownContent, writeMarkdown, writeMarkdownContent };
7
+ export { CODE_BLOCK_STYLE_ID, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, MarkdownBytesSchema, MarkdownDiagnosticCodes, MarkdownInputTooLargeError, MarkdownInvalidRunConstructExtentError, MarkdownInvalidUtf8Error, MarkdownNestingLimitExceededError, MarkdownParseError, MarkdownUnbalancedConstructMarkersError, MarkdownUnsupportedDocumentKindError, MarkdownWriteError, NOOP_MARKDOWN_DIAGNOSTIC_SINK, QUOTE_INDENT_PT, QUOTE_STYLE_ID, createNumIdMintState, headingStyleId, markdownCodec, markdownContentCodec, mintListNumId, mintedListType, parseHeadingStyleId, parseListNumId, readMarkdown, readMarkdownContent, writeMarkdown, writeMarkdownContent };
@@ -1,4 +1,4 @@
1
- import { i as MarkdownDiagnosticSink } from "../diagnostics-CUMLtGHJ.cjs";
1
+ import { i as MarkdownDiagnosticSink } from "../diagnostics-CkcSYZf1.cjs";
2
2
  import { LayoutMetadata } from "document-schema.js";
3
3
  //#region src/lower/front-matter.d.ts
4
4
  interface FrontMatterResult {
@@ -1,4 +1,4 @@
1
- import { i as MarkdownDiagnosticSink } from "../diagnostics-CUMLtGHJ.js";
1
+ import { i as MarkdownDiagnosticSink } from "../diagnostics-CkcSYZf1.js";
2
2
  import { LayoutMetadata } from "document-schema.js";
3
3
  //#region src/lower/front-matter.d.ts
4
4
  interface FrontMatterResult {
@@ -72,12 +72,16 @@ function lowerInlineNodeInto(node, style, context, runs, extents) {
72
72
  runs.push(buildRun(node.literal, style, require_shared_style_constants.MATH_INLINE_FONT_MARKER));
73
73
  return;
74
74
  case "footnoteReference":
75
- context.sink({
76
- code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.FOOTNOTE_REFERENCE_PRESERVED_AS_TEXT,
77
- severity: "info",
78
- message: `footnote reference "[^${node.label}]" is preserved as a marked text run rather than an anchor construct: a construct's extent is block-scoped, and a reference site sits between two runs inside a paragraph, which no block-level boundary marker can bracket`
75
+ runs.push(buildRun(`[^${node.label}]`, style));
76
+ extents.push({
77
+ descriptor: {
78
+ kind: "anchor",
79
+ anchorType: "footnote",
80
+ name: node.label
81
+ },
82
+ startRun: runs.length - 1,
83
+ endRun: runs.length - 1
79
84
  });
80
- runs.push(buildRun(`[^${node.label}]`, style, require_shared_style_constants.FOOTNOTE_REFERENCE_FONT_MARKER));
81
85
  return;
82
86
  case "autolink": {
83
87
  const destination = node.email ? `mailto:${node.destination}` : node.destination;
@@ -140,7 +144,7 @@ function lowerInlineNodes(nodes, context) {
140
144
  lowerNodesInto(nodes, {}, context, runs, extents);
141
145
  return {
142
146
  runs,
143
- linkTitleExtents: extents
147
+ runConstructExtents: extents
144
148
  };
145
149
  }
146
150
  function lowerCodeBlockRun(literal) {
@@ -1,5 +1,5 @@
1
1
  import { v as MarkdownInlineNode } from "../ast-8XCbjRQT.cjs";
2
- import { i as MarkdownDiagnosticSink } from "../diagnostics-CUMLtGHJ.cjs";
2
+ import { i as MarkdownDiagnosticSink } from "../diagnostics-CkcSYZf1.cjs";
3
3
  import { ContentRun, RunConstructExtent } from "document-schema.js";
4
4
  //#region src/lower/inline.d.ts
5
5
  interface InlineLowerContext {
@@ -8,7 +8,7 @@ interface InlineLowerContext {
8
8
  }
9
9
  interface InlineLowerResult {
10
10
  readonly runs: ContentRun[];
11
- readonly linkTitleExtents: readonly RunConstructExtent[];
11
+ readonly runConstructExtents: readonly RunConstructExtent[];
12
12
  }
13
13
  declare function lowerInlineNodes(nodes: readonly MarkdownInlineNode[], context: InlineLowerContext): InlineLowerResult;
14
14
  declare function lowerCodeBlockRun(literal: string): ContentRun;
@@ -1,5 +1,5 @@
1
1
  import { v as MarkdownInlineNode } from "../ast-8XCbjRQT.js";
2
- import { i as MarkdownDiagnosticSink } from "../diagnostics-CUMLtGHJ.js";
2
+ import { i as MarkdownDiagnosticSink } from "../diagnostics-CkcSYZf1.js";
3
3
  import { ContentRun, RunConstructExtent } from "document-schema.js";
4
4
  //#region src/lower/inline.d.ts
5
5
  interface InlineLowerContext {
@@ -8,7 +8,7 @@ interface InlineLowerContext {
8
8
  }
9
9
  interface InlineLowerResult {
10
10
  readonly runs: ContentRun[];
11
- readonly linkTitleExtents: readonly RunConstructExtent[];
11
+ readonly runConstructExtents: readonly RunConstructExtent[];
12
12
  }
13
13
  declare function lowerInlineNodes(nodes: readonly MarkdownInlineNode[], context: InlineLowerContext): InlineLowerResult;
14
14
  declare function lowerCodeBlockRun(literal: string): ContentRun;
@@ -1,5 +1,5 @@
1
1
  import { MarkdownDiagnosticCodes } from "../diagnostics/diagnostics.js";
2
- import { FOOTNOTE_REFERENCE_FONT_MARKER, MATH_INLINE_FONT_MARKER, MONOSPACE_FONT_FAMILY } from "../shared/style-constants.js";
2
+ import { MATH_INLINE_FONT_MARKER, MONOSPACE_FONT_FAMILY } from "../shared/style-constants.js";
3
3
  //#region src/lower/inline.ts
4
4
  function buildRun(text, style, fontFamily) {
5
5
  return {
@@ -71,12 +71,16 @@ function lowerInlineNodeInto(node, style, context, runs, extents) {
71
71
  runs.push(buildRun(node.literal, style, MATH_INLINE_FONT_MARKER));
72
72
  return;
73
73
  case "footnoteReference":
74
- context.sink({
75
- code: MarkdownDiagnosticCodes.FOOTNOTE_REFERENCE_PRESERVED_AS_TEXT,
76
- severity: "info",
77
- message: `footnote reference "[^${node.label}]" is preserved as a marked text run rather than an anchor construct: a construct's extent is block-scoped, and a reference site sits between two runs inside a paragraph, which no block-level boundary marker can bracket`
74
+ runs.push(buildRun(`[^${node.label}]`, style));
75
+ extents.push({
76
+ descriptor: {
77
+ kind: "anchor",
78
+ anchorType: "footnote",
79
+ name: node.label
80
+ },
81
+ startRun: runs.length - 1,
82
+ endRun: runs.length - 1
78
83
  });
79
- runs.push(buildRun(`[^${node.label}]`, style, FOOTNOTE_REFERENCE_FONT_MARKER));
80
84
  return;
81
85
  case "autolink": {
82
86
  const destination = node.email ? `mailto:${node.destination}` : node.destination;
@@ -139,7 +143,7 @@ function lowerInlineNodes(nodes, context) {
139
143
  lowerNodesInto(nodes, {}, context, runs, extents);
140
144
  return {
141
145
  runs,
142
- linkTitleExtents: extents
146
+ runConstructExtents: extents
143
147
  };
144
148
  }
145
149
  function lowerCodeBlockRun(literal) {
@@ -29,17 +29,17 @@ function decorateParagraph(paragraph, context) {
29
29
  };
30
30
  return result;
31
31
  }
32
- function paragraphWithConstructs(runs, linkTitleExtents) {
32
+ function paragraphWithConstructs(runs, runConstructExtents) {
33
33
  return {
34
34
  runs,
35
- ...linkTitleExtents.length > 0 ? { constructs: [...linkTitleExtents] } : {}
35
+ ...runConstructExtents.length > 0 ? { constructs: [...runConstructExtents] } : {}
36
36
  };
37
37
  }
38
38
  function lowerHeading(node, context) {
39
39
  const inline = require_lower_inline.lowerInlineNodes(node.children, inlineContext(context));
40
40
  return [decorateParagraph({
41
41
  kind: "paragraph",
42
- ...paragraphWithConstructs(inline.runs, inline.linkTitleExtents),
42
+ ...paragraphWithConstructs(inline.runs, inline.runConstructExtents),
43
43
  styleId: require_shared_style_constants.headingStyleId(node.level),
44
44
  headingLevel: node.level
45
45
  }, context)];
@@ -53,7 +53,7 @@ function lowerParagraph(node, context) {
53
53
  const inline = require_lower_inline.lowerInlineNodes(segment, inlineCtx);
54
54
  blocks.push(decorateParagraph({
55
55
  kind: "paragraph",
56
- ...paragraphWithConstructs(inline.runs, inline.linkTitleExtents)
56
+ ...paragraphWithConstructs(inline.runs, inline.runConstructExtents)
57
57
  }, context));
58
58
  segment = [];
59
59
  };
@@ -28,17 +28,17 @@ function decorateParagraph(paragraph, context) {
28
28
  };
29
29
  return result;
30
30
  }
31
- function paragraphWithConstructs(runs, linkTitleExtents) {
31
+ function paragraphWithConstructs(runs, runConstructExtents) {
32
32
  return {
33
33
  runs,
34
- ...linkTitleExtents.length > 0 ? { constructs: [...linkTitleExtents] } : {}
34
+ ...runConstructExtents.length > 0 ? { constructs: [...runConstructExtents] } : {}
35
35
  };
36
36
  }
37
37
  function lowerHeading(node, context) {
38
38
  const inline = lowerInlineNodes(node.children, inlineContext(context));
39
39
  return [decorateParagraph({
40
40
  kind: "paragraph",
41
- ...paragraphWithConstructs(inline.runs, inline.linkTitleExtents),
41
+ ...paragraphWithConstructs(inline.runs, inline.runConstructExtents),
42
42
  styleId: headingStyleId(node.level),
43
43
  headingLevel: node.level
44
44
  }, context)];
@@ -52,7 +52,7 @@ function lowerParagraph(node, context) {
52
52
  const inline = lowerInlineNodes(segment, inlineCtx);
53
53
  blocks.push(decorateParagraph({
54
54
  kind: "paragraph",
55
- ...paragraphWithConstructs(inline.runs, inline.linkTitleExtents)
55
+ ...paragraphWithConstructs(inline.runs, inline.runConstructExtents)
56
56
  }, context));
57
57
  segment = [];
58
58
  };
@@ -11,7 +11,7 @@ function lowerTableCell(cell, alignment, context) {
11
11
  return { blocks: [{
12
12
  kind: "paragraph",
13
13
  runs: inline.runs,
14
- ...inline.linkTitleExtents.length > 0 ? { constructs: [...inline.linkTitleExtents] } : {},
14
+ ...inline.runConstructExtents.length > 0 ? { constructs: [...inline.runConstructExtents] } : {},
15
15
  ...paragraphAlignment === void 0 ? {} : { alignment: paragraphAlignment }
16
16
  }] };
17
17
  }
@@ -10,7 +10,7 @@ function lowerTableCell(cell, alignment, context) {
10
10
  return { blocks: [{
11
11
  kind: "paragraph",
12
12
  runs: inline.runs,
13
- ...inline.linkTitleExtents.length > 0 ? { constructs: [...inline.linkTitleExtents] } : {},
13
+ ...inline.runConstructExtents.length > 0 ? { constructs: [...inline.runConstructExtents] } : {},
14
14
  ...paragraphAlignment === void 0 ? {} : { alignment: paragraphAlignment }
15
15
  }] };
16
16
  }
@@ -1,4 +1,4 @@
1
- import { i as MarkdownDiagnosticSink } from "../diagnostics-CUMLtGHJ.cjs";
1
+ import { i as MarkdownDiagnosticSink } from "../diagnostics-CkcSYZf1.cjs";
2
2
  import { n as MarkdownImageResolver } from "../image-C4KYmz_L.cjs";
3
3
  import { Margins, PageSize } from "document-schema.js";
4
4
  //#region src/options/options.d.ts
@@ -1,4 +1,4 @@
1
- import { i as MarkdownDiagnosticSink } from "../diagnostics-CUMLtGHJ.js";
1
+ import { i as MarkdownDiagnosticSink } from "../diagnostics-CkcSYZf1.js";
2
2
  import { n as MarkdownImageResolver } from "../image-Cm3hT5PS.js";
3
3
  import { Margins, PageSize } from "document-schema.js";
4
4
  //#region src/options/options.d.ts
package/dist/read.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as MarkdownDiagnostic } from "./diagnostics-CUMLtGHJ.cjs";
1
+ import { t as MarkdownDiagnostic } from "./diagnostics-CkcSYZf1.cjs";
2
2
  import { ReadMarkdownOptions } from "./options/options.cjs";
3
3
  import { ContentDocument, DocumentPackage } from "document-schema.js";
4
4
  //#region src/read.d.ts
package/dist/read.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as MarkdownDiagnostic } from "./diagnostics-CUMLtGHJ.js";
1
+ import { t as MarkdownDiagnostic } from "./diagnostics-CkcSYZf1.js";
2
2
  import { ReadMarkdownOptions } from "./options/options.js";
3
3
  import { ContentDocument, DocumentPackage } from "document-schema.js";
4
4
  //#region src/read.d.ts
@@ -19,13 +19,11 @@ const HTML_PREFORMATTED_STYLE_ID = "HTMLPreformatted";
19
19
  const MATH_BLOCK_STYLE_ID = "MathBlock";
20
20
  const MONOSPACE_FONT_FAMILY = "Courier New";
21
21
  const MATH_INLINE_FONT_MARKER = "Cambria Math";
22
- const FOOTNOTE_REFERENCE_FONT_MARKER = "Footnote Reference";
23
22
  const QUOTE_INDENT_PT = 36;
24
23
  const TASK_CHECKBOX_UNCHECKED = "☐";
25
24
  const TASK_CHECKBOX_CHECKED = "☒";
26
25
  //#endregion
27
26
  exports.CODE_BLOCK_STYLE_ID = CODE_BLOCK_STYLE_ID;
28
- exports.FOOTNOTE_REFERENCE_FONT_MARKER = FOOTNOTE_REFERENCE_FONT_MARKER;
29
27
  exports.HORIZONTAL_RULE_STYLE_ID = HORIZONTAL_RULE_STYLE_ID;
30
28
  exports.HTML_PREFORMATTED_STYLE_ID = HTML_PREFORMATTED_STYLE_ID;
31
29
  exports.MATH_BLOCK_STYLE_ID = MATH_BLOCK_STYLE_ID;
@@ -9,9 +9,8 @@ declare const HTML_PREFORMATTED_STYLE_ID = "HTMLPreformatted";
9
9
  declare const MATH_BLOCK_STYLE_ID = "MathBlock";
10
10
  declare const MONOSPACE_FONT_FAMILY = "Courier New";
11
11
  declare const MATH_INLINE_FONT_MARKER = "Cambria Math";
12
- declare const FOOTNOTE_REFERENCE_FONT_MARKER = "Footnote Reference";
13
12
  declare const QUOTE_INDENT_PT = 36;
14
13
  declare const TASK_CHECKBOX_UNCHECKED = "☐";
15
14
  declare const TASK_CHECKBOX_CHECKED = "☒";
16
15
  //#endregion
17
- export { CODE_BLOCK_STYLE_ID, FOOTNOTE_REFERENCE_FONT_MARKER, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, MATH_BLOCK_STYLE_ID, MATH_INLINE_FONT_MARKER, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, QUOTE_INDENT_PT, QUOTE_STYLE_ID, TASK_CHECKBOX_CHECKED, TASK_CHECKBOX_UNCHECKED, headingStyleId, parseHeadingStyleId };
16
+ export { CODE_BLOCK_STYLE_ID, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, MATH_BLOCK_STYLE_ID, MATH_INLINE_FONT_MARKER, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, QUOTE_INDENT_PT, QUOTE_STYLE_ID, TASK_CHECKBOX_CHECKED, TASK_CHECKBOX_UNCHECKED, headingStyleId, parseHeadingStyleId };
@@ -9,9 +9,8 @@ declare const HTML_PREFORMATTED_STYLE_ID = "HTMLPreformatted";
9
9
  declare const MATH_BLOCK_STYLE_ID = "MathBlock";
10
10
  declare const MONOSPACE_FONT_FAMILY = "Courier New";
11
11
  declare const MATH_INLINE_FONT_MARKER = "Cambria Math";
12
- declare const FOOTNOTE_REFERENCE_FONT_MARKER = "Footnote Reference";
13
12
  declare const QUOTE_INDENT_PT = 36;
14
13
  declare const TASK_CHECKBOX_UNCHECKED = "☐";
15
14
  declare const TASK_CHECKBOX_CHECKED = "☒";
16
15
  //#endregion
17
- export { CODE_BLOCK_STYLE_ID, FOOTNOTE_REFERENCE_FONT_MARKER, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, MATH_BLOCK_STYLE_ID, MATH_INLINE_FONT_MARKER, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, QUOTE_INDENT_PT, QUOTE_STYLE_ID, TASK_CHECKBOX_CHECKED, TASK_CHECKBOX_UNCHECKED, headingStyleId, parseHeadingStyleId };
16
+ export { CODE_BLOCK_STYLE_ID, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, MATH_BLOCK_STYLE_ID, MATH_INLINE_FONT_MARKER, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, QUOTE_INDENT_PT, QUOTE_STYLE_ID, TASK_CHECKBOX_CHECKED, TASK_CHECKBOX_UNCHECKED, headingStyleId, parseHeadingStyleId };
@@ -18,9 +18,8 @@ const HTML_PREFORMATTED_STYLE_ID = "HTMLPreformatted";
18
18
  const MATH_BLOCK_STYLE_ID = "MathBlock";
19
19
  const MONOSPACE_FONT_FAMILY = "Courier New";
20
20
  const MATH_INLINE_FONT_MARKER = "Cambria Math";
21
- const FOOTNOTE_REFERENCE_FONT_MARKER = "Footnote Reference";
22
21
  const QUOTE_INDENT_PT = 36;
23
22
  const TASK_CHECKBOX_UNCHECKED = "☐";
24
23
  const TASK_CHECKBOX_CHECKED = "☒";
25
24
  //#endregion
26
- export { CODE_BLOCK_STYLE_ID, FOOTNOTE_REFERENCE_FONT_MARKER, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, MATH_BLOCK_STYLE_ID, MATH_INLINE_FONT_MARKER, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, QUOTE_INDENT_PT, QUOTE_STYLE_ID, TASK_CHECKBOX_CHECKED, TASK_CHECKBOX_UNCHECKED, headingStyleId, parseHeadingStyleId };
25
+ export { CODE_BLOCK_STYLE_ID, HORIZONTAL_RULE_STYLE_ID, HTML_PREFORMATTED_STYLE_ID, MATH_BLOCK_STYLE_ID, MATH_INLINE_FONT_MARKER, MAX_HEADING_STYLE_LEVEL, MONOSPACE_FONT_FAMILY, QUOTE_INDENT_PT, QUOTE_STYLE_ID, TASK_CHECKBOX_CHECKED, TASK_CHECKBOX_UNCHECKED, headingStyleId, parseHeadingStyleId };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markdown-codec",
3
- "version": "4.1.0",
3
+ "version": "5.0.0",
4
4
  "description": "Hand-written CommonMark+GFM <-> DocumentPackage codec, built on document-schema.js",
5
5
  "type": "module",
6
6
  "repository": {