@pretextbook/ptxast-util-to-mdast 0.0.4 → 0.0.6

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 CHANGED
@@ -28,7 +28,19 @@ Converts a `PtxRoot` tree to an mdast `Root` tree with directive nodes for PreTe
28
28
 
29
29
  ### `ptxastToMarkdown(root: PtxRoot): string`
30
30
 
31
- Converts a `PtxRoot` tree to a Markdown string. Theorem-like environments render as `:::theorem` directive fences; divisions render as ATX headings (`##`).
31
+ Converts a `PtxRoot` tree to a Markdown string. Theorem-like environments render as `:::theorem` directive fences; divisions render as ATX headings, relative to the document's actual outermost division (a depth-1 heading is whatever that division is — `chapter`, `section`, `part`, ...).
32
+
33
+ When the outermost division isn't `chapter` (the default a depth-1 heading is assumed to mean by [`@pretextbook/remark-pretext`](../remark-pretext)), a `division:` frontmatter block is prepended so the markdown can be converted back to PreTeXt unambiguously:
34
+
35
+ ```
36
+ ---
37
+ division: section
38
+ ---
39
+
40
+ # Top-level section
41
+
42
+ ## A subsection
43
+ ```
32
44
 
33
45
  ## License
34
46
 
package/dist/index.cjs CHANGED
@@ -1,2 +1,7 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("@pretextbook/ptxast"),k=require("mdast-util-to-markdown"),x=require("mdast-util-directive"),v=require("mdast-util-math"),b=new Set(["chapter","section","subsection","subsubsection","paragraphs","appendix"]),T={chapter:1,section:2,subsection:3,subsubsection:4,paragraphs:5,appendix:1},w=new Set(["pretext","book","article","frontmatter","backmatter","part"]),P=new Map([["theorem",{name:"theorem",category:"theorem-like"}],["lemma",{name:"lemma",category:"theorem-like"}],["corollary",{name:"corollary",category:"theorem-like"}],["proposition",{name:"proposition",category:"theorem-like"}],["claim",{name:"claim",category:"theorem-like"}],["fact",{name:"fact",category:"theorem-like"}],["conjecture",{name:"conjecture",category:"theorem-like"}],["axiom",{name:"axiom",category:"theorem-like"}],["principle",{name:"principle",category:"theorem-like"}],["hypothesis",{name:"hypothesis",category:"theorem-like"}],["algorithm",{name:"algorithm",category:"theorem-like"}],["definition",{name:"definition",category:"definition-like"}],["notation",{name:"notation",category:"definition-like"}],["remark",{name:"remark",category:"remark-like"}],["note",{name:"note",category:"remark-like"}],["observation",{name:"observation",category:"remark-like"}],["warning",{name:"warning",category:"remark-like"}],["insight",{name:"insight",category:"remark-like"}],["assemblage",{name:"assemblage",category:"remark-like"}],["example",{name:"example",category:"example-like"}],["question",{name:"question",category:"example-like"}],["problem",{name:"problem",category:"example-like"}],["exercise",{name:"exercise",category:"example-like"}],["activity",{name:"activity",category:"example-like"}],["exploration",{name:"exploration",category:"example-like"}],["investigation",{name:"investigation",category:"example-like"}],["project",{name:"project",category:"example-like"}],["proof",{name:"proof",category:"proof-like"}],["case",{name:"case",category:"proof-like"}],["solution",{name:"solution",category:"solution-like"}],["hint",{name:"hint",category:"solution-like"}],["answer",{name:"answer",category:"solution-like"}]]),M=new Set(["theorem-like","definition-like"]);function g(e){return{type:"root",children:d(e.children,2)}}function d(e,t){const n=[];for(const r of e){if(r.type!=="element")continue;const o=r;if(w.has(o.name))n.push(...d(o.children,t));else if(b.has(o.name)){const l=T[o.name]??t;n.push(...E(o,l))}else{const l=u(o);l!==null&&n.push(l)}}return n}function E(e,t){const n=[],r=e.attributes??{},o=e.children,l=o.find(a=>a.type==="element"&&a.name==="title"),s=o.filter(a=>!(a.type==="element"&&a.name==="title")),i={type:"heading",depth:t,children:l?l.children.map(h).filter(m):[],...r["xml:id"]?{data:{id:r["xml:id"],hProperties:{id:r["xml:id"]}}}:{}};n.push(i);const c=Math.min(t+1,6);return n.push(...d(s,c)),n}function u(e){switch(e.name){case"p":return S(e);case"blockquote":return C(e);case"ol":return y(e,!0);case"ul":return y(e,!1);case"program":return D(e);case"me":case"men":case"md":case"mdn":return I(e);default:{const t=P.get(e.name);return t?j(e,t):null}}}function S(e){return{type:"paragraph",children:e.children.map(h).filter(m)}}function C(e){return{type:"blockquote",children:e.children.filter(t=>t.type==="element").map(t=>u(t)).filter(m)}}function y(e,t){return{type:"list",ordered:t,spread:!1,children:e.children.filter(n=>n.type==="element").map(n=>q(n))}}function q(e){return{type:"listItem",spread:!1,children:e.children.filter(t=>t.type==="element").map(t=>u(t)).filter(m)}}function D(e){return{type:"code",lang:(e.attributes??{}).language??null,value:p.getPtxTextContent(e)}}function I(e){const t=e.children;return t.length>0&&t[0].type==="text"?{type:"math",value:p.getPtxTextContent(e)}:{type:"math",value:t.filter(r=>r.type==="element"&&r.name==="mrow").map(r=>p.getPtxTextContent(r)).join(` \\\\
2
- `)}}function j(e,t){const n=e.attributes??{},r=e.children,o={};n["xml:id"]&&(o.id=n["xml:id"]);for(const[i,c]of Object.entries(n))i==="xml:id"||c==null||(o[i]=c);const l=r.find(i=>i.type==="element"&&i.name==="title"),s=[];if(l){const i={type:"paragraph",data:{directiveLabel:!0},children:l.children.map(h).filter(m)};s.push(i)}if(M.has(t.category))for(const i of r){if(i.type!=="element")continue;const c=i;if(c.name!=="title")if(c.name==="statement")for(const a of c.children){if(a.type!=="element")continue;const f=u(a);f&&s.push(f)}else{const a=u(c);a&&s.push(a)}}else for(const i of r){if(i.type!=="element")continue;const c=i;if(c.name==="title")continue;const a=u(c);a&&s.push(a)}return{type:"containerDirective",name:t.name,attributes:Object.keys(o).length>0?o:void 0,children:s}}function h(e){if(e.type==="text")return{type:"text",value:e.value??""};if(e.type!=="element")return null;const t=e;switch(t.name){case"em":return{type:"emphasis",children:t.children.map(h).filter(m)};case"alert":return{type:"strong",children:t.children.map(h).filter(m)};case"c":return{type:"inlineCode",value:p.getPtxTextContent(t)};case"m":return{type:"inlineMath",value:p.getPtxTextContent(t)};default:return null}}function m(e){return e!==null}function N(e){const t=g(e);return k.toMarkdown(t,{extensions:[x.directiveToMarkdown(),v.mathToMarkdown()]})}exports.ptxastToMarkdown=N;exports.ptxastToMdast=g;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("@pretextbook/ptxast"),T=require("mdast-util-to-markdown"),I=require("mdast-util-directive"),S=require("mdast-util-math"),g=new Set([...c.DIVISION_HIERARCHY,...c.EXTRA_DIVISION_TYPES.filter(e=>!c.isTitlelessDivisionType(e))]),k=new Set(c.TITLELESS_DIVISION_TYPES),x=new Set(["pretext","book","article","frontmatter","backmatter"]),E=new Map([["theorem",{name:"theorem",category:"theorem-like"}],["lemma",{name:"lemma",category:"theorem-like"}],["corollary",{name:"corollary",category:"theorem-like"}],["proposition",{name:"proposition",category:"theorem-like"}],["claim",{name:"claim",category:"theorem-like"}],["fact",{name:"fact",category:"theorem-like"}],["conjecture",{name:"conjecture",category:"theorem-like"}],["axiom",{name:"axiom",category:"theorem-like"}],["principle",{name:"principle",category:"theorem-like"}],["hypothesis",{name:"hypothesis",category:"theorem-like"}],["algorithm",{name:"algorithm",category:"theorem-like"}],["definition",{name:"definition",category:"definition-like"}],["notation",{name:"notation",category:"definition-like"}],["remark",{name:"remark",category:"remark-like"}],["note",{name:"note",category:"remark-like"}],["observation",{name:"observation",category:"remark-like"}],["warning",{name:"warning",category:"remark-like"}],["insight",{name:"insight",category:"remark-like"}],["assemblage",{name:"assemblage",category:"remark-like"}],["example",{name:"example",category:"example-like"}],["question",{name:"question",category:"example-like"}],["problem",{name:"problem",category:"example-like"}],["exercise",{name:"exercise",category:"example-like"}],["activity",{name:"activity",category:"example-like"}],["exploration",{name:"exploration",category:"example-like"}],["investigation",{name:"investigation",category:"example-like"}],["project",{name:"project",category:"example-like"}],["proof",{name:"proof",category:"proof-like"}],["case",{name:"case",category:"proof-like"}],["solution",{name:"solution",category:"solution-like"}],["hint",{name:"hint",category:"solution-like"}],["answer",{name:"answer",category:"solution-like"}]]),P=new Set(["theorem-like","definition-like"]);function v(e){return{type:"root",children:h(e.children,1)}}function b(e){for(const t of e){if(t.type!=="element")continue;const i=t;if(g.has(i.name)||k.has(i.name)){const n=i.attributes??{},r={};return n["xml:id"]&&(r.xmlid=n["xml:id"]),n.label&&(r.label=n.label),n.component&&(r.component=n.component),{name:i.name,attributes:r}}if(x.has(i.name)){const n=b(i.children);if(n)return n}}}function h(e,t){const i=[];for(const n of e){if(n.type!=="element")continue;const r=n;if(x.has(r.name)||k.has(r.name))i.push(...h(r.children,t));else if(g.has(r.name))i.push(...w(r,Math.min(t,6)));else{const s=p(r);s!==null&&i.push(s)}}return i}function w(e,t){const i=[],n=e.attributes??{},r=e.children,s=r.find(a=>a.type==="element"&&a.name==="title"),m=r.filter(a=>!(a.type==="element"&&a.name==="title")),o={type:"heading",depth:t,children:s?s.children.map(f).filter(u):[],...n["xml:id"]?{data:{id:n["xml:id"],hProperties:{id:n["xml:id"]}}}:{}};i.push(o);const l=Math.min(t+1,6);return i.push(...h(m,l)),i}function p(e){switch(e.name){case"p":return M(e);case"blockquote":return D(e);case"ol":return y(e,!0);case"ul":return y(e,!1);case"program":return N(e);case"me":case"men":case"md":case"mdn":return C(e);default:{const t=E.get(e.name);return t?j(e,t):null}}}function M(e){return{type:"paragraph",children:e.children.map(f).filter(u)}}function D(e){return{type:"blockquote",children:e.children.filter(t=>t.type==="element").map(t=>p(t)).filter(u)}}function y(e,t){return{type:"list",ordered:t,spread:!1,children:e.children.filter(i=>i.type==="element").map(i=>_(i))}}function _(e){return{type:"listItem",spread:!1,children:e.children.filter(t=>t.type==="element").map(t=>p(t)).filter(u)}}function N(e){return{type:"code",lang:(e.attributes??{}).language??null,value:c.getPtxTextContent(e)}}function C(e){const t=e.children;return t.length>0&&t[0].type==="text"?{type:"math",value:c.getPtxTextContent(e)}:{type:"math",value:t.filter(n=>n.type==="element"&&n.name==="mrow").map(n=>c.getPtxTextContent(n)).join(` \\\\
2
+ `)}}function j(e,t){const i=e.attributes??{},n=e.children,r={};i["xml:id"]&&(r.id=i["xml:id"]);for(const[o,l]of Object.entries(i))o==="xml:id"||l==null||(r[o]=l);const s=n.find(o=>o.type==="element"&&o.name==="title"),m=[];if(s){const o={type:"paragraph",data:{directiveLabel:!0},children:s.children.map(f).filter(u)};m.push(o)}if(P.has(t.category))for(const o of n){if(o.type!=="element")continue;const l=o;if(l.name!=="title")if(l.name==="statement")for(const a of l.children){if(a.type!=="element")continue;const d=p(a);d&&m.push(d)}else{const a=p(l);a&&m.push(a)}}else for(const o of n){if(o.type!=="element")continue;const l=o;if(l.name==="title")continue;const a=p(l);a&&m.push(a)}return{type:"containerDirective",name:t.name,attributes:Object.keys(r).length>0?r:void 0,children:m}}function f(e){if(e.type==="text")return{type:"text",value:e.value??""};if(e.type!=="element")return null;const t=e;switch(t.name){case"em":return{type:"emphasis",children:t.children.map(f).filter(u)};case"alert":return{type:"strong",children:t.children.map(f).filter(u)};case"c":return{type:"inlineCode",value:c.getPtxTextContent(t)};case"m":return{type:"inlineMath",value:c.getPtxTextContent(t)};default:return null}}function u(e){return e!==null}function q(e){const t=v(e),i=T.toMarkdown(t,{extensions:[I.directiveToMarkdown(),S.mathToMarkdown()]}),n=b(e.children);if(!n)return i;const r=[];return n.name!=="chapter"&&r.push(`division: ${n.name}`),n.attributes.xmlid&&r.push(`xmlid: ${n.attributes.xmlid}`),n.attributes.label&&r.push(`label: ${n.attributes.label}`),n.attributes.component&&r.push(`component: ${n.attributes.component}`),r.length===0?i:`---
3
+ ${r.join(`
4
+ `)}
5
+ ---
6
+
7
+ ${i}`}exports.ptxastToMarkdown=q;exports.ptxastToMdast=v;
package/dist/index.js CHANGED
@@ -1,30 +1,17 @@
1
- import { getPtxTextContent as u } from "@pretextbook/ptxast";
2
- import { toMarkdown as g } from "mdast-util-to-markdown";
3
- import { directiveToMarkdown as k } from "mdast-util-directive";
4
- import { mathToMarkdown as v } from "mdast-util-math";
5
- const x = /* @__PURE__ */ new Set([
6
- "chapter",
7
- "section",
8
- "subsection",
9
- "subsubsection",
10
- "paragraphs",
11
- // appendix is division-like at the same level as chapter
12
- "appendix"
13
- ]), b = {
14
- chapter: 1,
15
- section: 2,
16
- subsection: 3,
17
- subsubsection: 4,
18
- paragraphs: 5,
19
- appendix: 1
20
- }, T = /* @__PURE__ */ new Set([
1
+ import { DIVISION_HIERARCHY as b, EXTRA_DIVISION_TYPES as T, isTitlelessDivisionType as I, TITLELESS_DIVISION_TYPES as S, getPtxTextContent as p } from "@pretextbook/ptxast";
2
+ import { toMarkdown as E } from "mdast-util-to-markdown";
3
+ import { directiveToMarkdown as w } from "mdast-util-directive";
4
+ import { mathToMarkdown as _ } from "mdast-util-math";
5
+ const g = /* @__PURE__ */ new Set([
6
+ ...b,
7
+ ...T.filter((e) => !I(e))
8
+ ]), k = new Set(S), v = /* @__PURE__ */ new Set([
21
9
  "pretext",
22
10
  "book",
23
11
  "article",
24
12
  "frontmatter",
25
- "backmatter",
26
- "part"
27
- ]), w = /* @__PURE__ */ new Map([
13
+ "backmatter"
14
+ ]), P = /* @__PURE__ */ new Map([
28
15
  // theorem-like
29
16
  ["theorem", { name: "theorem", category: "theorem-like" }],
30
17
  ["lemma", { name: "lemma", category: "theorem-like" }],
@@ -63,78 +50,91 @@ const x = /* @__PURE__ */ new Set([
63
50
  ["solution", { name: "solution", category: "solution-like" }],
64
51
  ["hint", { name: "hint", category: "solution-like" }],
65
52
  ["answer", { name: "answer", category: "solution-like" }]
66
- ]), E = /* @__PURE__ */ new Set(["theorem-like", "definition-like"]);
67
- function P(e) {
53
+ ]), D = /* @__PURE__ */ new Set(["theorem-like", "definition-like"]);
54
+ function N(e) {
68
55
  return {
69
56
  type: "root",
70
- children: f(e.children, 2)
57
+ children: h(e.children, 1)
71
58
  };
72
59
  }
73
- function f(e, t) {
74
- const n = [];
75
- for (const r of e) {
76
- if (r.type !== "element") continue;
77
- const o = r;
78
- if (T.has(o.name))
79
- n.push(...f(o.children, t));
80
- else if (x.has(o.name)) {
81
- const l = b[o.name] ?? t;
82
- n.push(...M(o, l));
83
- } else {
84
- const l = p(o);
85
- l !== null && n.push(l);
60
+ function x(e) {
61
+ for (const t of e) {
62
+ if (t.type !== "element") continue;
63
+ const i = t;
64
+ if (g.has(i.name) || k.has(i.name)) {
65
+ const n = i.attributes ?? {}, r = {};
66
+ return n["xml:id"] && (r.xmlid = n["xml:id"]), n.label && (r.label = n.label), n.component && (r.component = n.component), { name: i.name, attributes: r };
67
+ }
68
+ if (v.has(i.name)) {
69
+ const n = x(i.children);
70
+ if (n) return n;
71
+ }
72
+ }
73
+ }
74
+ function h(e, t) {
75
+ const i = [];
76
+ for (const n of e) {
77
+ if (n.type !== "element") continue;
78
+ const r = n;
79
+ if (v.has(r.name) || k.has(r.name))
80
+ i.push(...h(r.children, t));
81
+ else if (g.has(r.name))
82
+ i.push(...M(r, Math.min(t, 6)));
83
+ else {
84
+ const c = u(r);
85
+ c !== null && i.push(c);
86
86
  }
87
87
  }
88
- return n;
88
+ return i;
89
89
  }
90
90
  function M(e, t) {
91
- const n = [], r = e.attributes ?? {}, o = e.children, l = o.find(
91
+ const i = [], n = e.attributes ?? {}, r = e.children, c = r.find(
92
92
  (a) => a.type === "element" && a.name === "title"
93
- ), s = o.filter(
93
+ ), m = r.filter(
94
94
  (a) => !(a.type === "element" && a.name === "title")
95
- ), i = {
95
+ ), o = {
96
96
  type: "heading",
97
97
  depth: t,
98
- children: l ? l.children.map(h).filter(m) : [],
99
- ...r["xml:id"] ? { data: { id: r["xml:id"], hProperties: { id: r["xml:id"] } } } : {}
98
+ children: c ? c.children.map(f).filter(s) : [],
99
+ ...n["xml:id"] ? { data: { id: n["xml:id"], hProperties: { id: n["xml:id"] } } } : {}
100
100
  };
101
- n.push(i);
102
- const c = Math.min(t + 1, 6);
103
- return n.push(...f(s, c)), n;
101
+ i.push(o);
102
+ const l = Math.min(t + 1, 6);
103
+ return i.push(...h(m, l)), i;
104
104
  }
105
- function p(e) {
105
+ function u(e) {
106
106
  switch (e.name) {
107
107
  case "p":
108
- return I(e);
108
+ return L(e);
109
109
  case "blockquote":
110
- return S(e);
110
+ return A(e);
111
111
  case "ol":
112
112
  return y(e, !0);
113
113
  case "ul":
114
114
  return y(e, !1);
115
115
  case "program":
116
- return N(e);
116
+ return j(e);
117
117
  case "me":
118
118
  case "men":
119
119
  case "md":
120
120
  case "mdn":
121
- return j(e);
121
+ return R(e);
122
122
  default: {
123
- const t = w.get(e.name);
124
- return t ? _(e, t) : null;
123
+ const t = P.get(e.name);
124
+ return t ? Y(e, t) : null;
125
125
  }
126
126
  }
127
127
  }
128
- function I(e) {
128
+ function L(e) {
129
129
  return {
130
130
  type: "paragraph",
131
- children: e.children.map(h).filter(m)
131
+ children: e.children.map(f).filter(s)
132
132
  };
133
133
  }
134
- function S(e) {
134
+ function A(e) {
135
135
  return {
136
136
  type: "blockquote",
137
- children: e.children.filter((t) => t.type === "element").map((t) => p(t)).filter(m)
137
+ children: e.children.filter((t) => t.type === "element").map((t) => u(t)).filter(s)
138
138
  };
139
139
  }
140
140
  function y(e, t) {
@@ -142,76 +142,76 @@ function y(e, t) {
142
142
  type: "list",
143
143
  ordered: t,
144
144
  spread: !1,
145
- children: e.children.filter((n) => n.type === "element").map((n) => D(n))
145
+ children: e.children.filter((i) => i.type === "element").map((i) => O(i))
146
146
  };
147
147
  }
148
- function D(e) {
148
+ function O(e) {
149
149
  return {
150
150
  type: "listItem",
151
151
  spread: !1,
152
- children: e.children.filter((t) => t.type === "element").map((t) => p(t)).filter(m)
152
+ children: e.children.filter((t) => t.type === "element").map((t) => u(t)).filter(s)
153
153
  };
154
154
  }
155
- function N(e) {
155
+ function j(e) {
156
156
  return {
157
157
  type: "code",
158
158
  lang: (e.attributes ?? {}).language ?? null,
159
- value: u(e)
159
+ value: p(e)
160
160
  };
161
161
  }
162
- function j(e) {
162
+ function R(e) {
163
163
  const t = e.children;
164
- return t.length > 0 && t[0].type === "text" ? { type: "math", value: u(e) } : { type: "math", value: t.filter((r) => r.type === "element" && r.name === "mrow").map((r) => u(r)).join(` \\\\
164
+ return t.length > 0 && t[0].type === "text" ? { type: "math", value: p(e) } : { type: "math", value: t.filter((n) => n.type === "element" && n.name === "mrow").map((n) => p(n)).join(` \\\\
165
165
  `) };
166
166
  }
167
- function _(e, t) {
168
- const n = e.attributes ?? {}, r = e.children, o = {};
169
- n["xml:id"] && (o.id = n["xml:id"]);
170
- for (const [i, c] of Object.entries(n))
171
- i === "xml:id" || c == null || (o[i] = c);
172
- const l = r.find(
173
- (i) => i.type === "element" && i.name === "title"
174
- ), s = [];
175
- if (l) {
176
- const i = {
167
+ function Y(e, t) {
168
+ const i = e.attributes ?? {}, n = e.children, r = {};
169
+ i["xml:id"] && (r.id = i["xml:id"]);
170
+ for (const [o, l] of Object.entries(i))
171
+ o === "xml:id" || l == null || (r[o] = l);
172
+ const c = n.find(
173
+ (o) => o.type === "element" && o.name === "title"
174
+ ), m = [];
175
+ if (c) {
176
+ const o = {
177
177
  type: "paragraph",
178
178
  data: { directiveLabel: !0 },
179
- children: l.children.map(h).filter(m)
179
+ children: c.children.map(f).filter(s)
180
180
  };
181
- s.push(i);
181
+ m.push(o);
182
182
  }
183
- if (E.has(t.category))
184
- for (const i of r) {
185
- if (i.type !== "element") continue;
186
- const c = i;
187
- if (c.name !== "title")
188
- if (c.name === "statement")
189
- for (const a of c.children) {
183
+ if (D.has(t.category))
184
+ for (const o of n) {
185
+ if (o.type !== "element") continue;
186
+ const l = o;
187
+ if (l.name !== "title")
188
+ if (l.name === "statement")
189
+ for (const a of l.children) {
190
190
  if (a.type !== "element") continue;
191
- const d = p(a);
192
- d && s.push(d);
191
+ const d = u(a);
192
+ d && m.push(d);
193
193
  }
194
194
  else {
195
- const a = p(c);
196
- a && s.push(a);
195
+ const a = u(l);
196
+ a && m.push(a);
197
197
  }
198
198
  }
199
199
  else
200
- for (const i of r) {
201
- if (i.type !== "element") continue;
202
- const c = i;
203
- if (c.name === "title") continue;
204
- const a = p(c);
205
- a && s.push(a);
200
+ for (const o of n) {
201
+ if (o.type !== "element") continue;
202
+ const l = o;
203
+ if (l.name === "title") continue;
204
+ const a = u(l);
205
+ a && m.push(a);
206
206
  }
207
207
  return {
208
208
  type: "containerDirective",
209
209
  name: t.name,
210
- attributes: Object.keys(o).length > 0 ? o : void 0,
211
- children: s
210
+ attributes: Object.keys(r).length > 0 ? r : void 0,
211
+ children: m
212
212
  };
213
213
  }
214
- function h(e) {
214
+ function f(e) {
215
215
  if (e.type === "text")
216
216
  return { type: "text", value: e.value ?? "" };
217
217
  if (e.type !== "element") return null;
@@ -220,31 +220,38 @@ function h(e) {
220
220
  case "em":
221
221
  return {
222
222
  type: "emphasis",
223
- children: t.children.map(h).filter(m)
223
+ children: t.children.map(f).filter(s)
224
224
  };
225
225
  case "alert":
226
226
  return {
227
227
  type: "strong",
228
- children: t.children.map(h).filter(m)
228
+ children: t.children.map(f).filter(s)
229
229
  };
230
230
  case "c":
231
- return { type: "inlineCode", value: u(t) };
231
+ return { type: "inlineCode", value: p(t) };
232
232
  case "m":
233
- return { type: "inlineMath", value: u(t) };
233
+ return { type: "inlineMath", value: p(t) };
234
234
  default:
235
235
  return null;
236
236
  }
237
237
  }
238
- function m(e) {
238
+ function s(e) {
239
239
  return e !== null;
240
240
  }
241
- function O(e) {
242
- const t = P(e);
243
- return g(t, {
244
- extensions: [k(), v()]
245
- });
241
+ function H(e) {
242
+ const t = N(e), i = E(t, {
243
+ extensions: [w(), _()]
244
+ }), n = x(e.children);
245
+ if (!n) return i;
246
+ const r = [];
247
+ return n.name !== "chapter" && r.push(`division: ${n.name}`), n.attributes.xmlid && r.push(`xmlid: ${n.attributes.xmlid}`), n.attributes.label && r.push(`label: ${n.attributes.label}`), n.attributes.component && r.push(`component: ${n.attributes.component}`), r.length === 0 ? i : `---
248
+ ${r.join(`
249
+ `)}
250
+ ---
251
+
252
+ ${i}`;
246
253
  }
247
254
  export {
248
- O as ptxastToMarkdown,
249
- P as ptxastToMdast
255
+ H as ptxastToMarkdown,
256
+ N as ptxastToMdast
250
257
  };
@@ -1,4 +1,36 @@
1
1
  import { Root as MdastRoot } from 'mdast';
2
- import { Root } from '@pretextbook/ptxast';
2
+ import { Root, ElementContent } from '@pretextbook/ptxast';
3
+ export declare const DIVISION_TYPE_NAMES: Set<string>;
4
+ export declare const TITLELESS_DIVISION_TYPES: Set<string>;
5
+ /**
6
+ * Structural container types whose content should be recursed into
7
+ * without emitting a heading, and without changing the current depth.
8
+ * This handles full ptxast trees that include a `pretext > book > chapter`
9
+ * hierarchy.
10
+ */
11
+ export declare const TRANSPARENT_TYPES: Set<string>;
3
12
  /** Convert an xast Root (PreTeXt document) to an mdast Root. */
4
13
  export declare function ptxastToMdast(root: Root): MdastRoot;
14
+ /** The outermost division's name plus the subset of its attributes that
15
+ * round-trip through markdown frontmatter (`xmlid`, `label`, `component`). */
16
+ export interface TopLevelDivisionInfo {
17
+ name: string;
18
+ attributes: {
19
+ xmlid?: string;
20
+ label?: string;
21
+ component?: string;
22
+ };
23
+ }
24
+ /**
25
+ * Find the outermost division in a ptxast tree (skipping transparent
26
+ * structural wrappers), i.e. the division a depth-1 heading would represent
27
+ * if this tree were flattened to markdown — along with its `xml:id`/
28
+ * `label`/`component` attributes, for round-tripping into frontmatter.
29
+ */
30
+ export declare function findTopLevelDivisionInfo(nodes: ElementContent[]): TopLevelDivisionInfo | undefined;
31
+ /**
32
+ * Find the name of the outermost division in a ptxast tree (skipping
33
+ * transparent structural wrappers), i.e. the division a depth-1 heading
34
+ * would represent if this tree were flattened to markdown.
35
+ */
36
+ export declare function findTopLevelDivision(nodes: ElementContent[]): string | undefined;
@@ -3,5 +3,11 @@ export { ptxastToMdast } from './ptxast-to-mdast.js';
3
3
  /**
4
4
  * Convert an xast Root (PreTeXt document) to a markdown string using the directive
5
5
  * syntax for PreTeXt block environments.
6
+ *
7
+ * A leading frontmatter block is prepended when the outermost division
8
+ * carries information that markdown can't otherwise represent: a
9
+ * `division:` field when it isn't `chapter` (the default a depth-1 heading
10
+ * is assumed to mean), and `xmlid:`/`label:`/`component:` fields mirroring
11
+ * that division's `xml:id`/`label`/`component` attributes.
6
12
  */
7
13
  export declare function ptxastToMarkdown(root: Root): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pretextbook/ptxast-util-to-mdast",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "Convert ptxast to mdast (markdown AST) and markdown strings",
5
5
  "author": "Oscar Levin",
6
6
  "license": "GPL-3.0-or-later",
@@ -39,7 +39,7 @@
39
39
  "test": "vitest run"
40
40
  },
41
41
  "dependencies": {
42
- "@pretextbook/ptxast": "^0.0.4",
42
+ "@pretextbook/ptxast": "^0.0.6",
43
43
  "@types/mdast": "^4.0.0",
44
44
  "mdast-util-directive": "^3.0.0",
45
45
  "mdast-util-math": "^3.0.0",