@uniweb/semantic-parser 1.1.13 → 1.1.15

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniweb/semantic-parser",
3
- "version": "1.1.13",
3
+ "version": "1.1.15",
4
4
  "description": "Semantic parser for ProseMirror/TipTap content structures",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -378,7 +378,7 @@ function processGroupContent(elements) {
378
378
  });
379
379
  break;
380
380
 
381
- case "math_display":
381
+ case "math":
382
382
  // Block-level math from $$...$$ on its own line or ```math
383
383
  // fence. The mathml string is pre-compiled at parse time;
384
384
  // foundations render it by setting dangerouslySetInnerHTML
@@ -388,6 +388,11 @@ function processGroupContent(elements) {
388
388
  // `content.sequence` — this flat collection is convenience
389
389
  // sugar when order doesn't matter. Allocate lazily so
390
390
  // pages without math pay nothing.
391
+ //
392
+ // Inline math doesn't reach the groups walker — it's
393
+ // wrapped inside paragraph HTML strings — so checking
394
+ // the `display` flag is unnecessary here. If that ever
395
+ // changes, gate this branch on `element.display === true`.
391
396
  (body.math ||= []).push({
392
397
  id: element.id || null,
393
398
  latex: element.latex || '',
@@ -11,6 +11,23 @@ import { parse as parseYaml } from "yaml";
11
11
  * @param {Object} attrs - Code block attributes (language, tag, data)
12
12
  * @returns {*} Parsed data or raw text
13
13
  */
14
+ /**
15
+ * HTML-attribute encoding for values placed inside double-quoted
16
+ * attributes. Backslashes and braces (common in LaTeX) pass through
17
+ * unchanged; only the four characters that are unsafe in this context
18
+ * need replacing.
19
+ *
20
+ * @param {string} s
21
+ * @returns {string}
22
+ */
23
+ function escapeAttr(s) {
24
+ return String(s)
25
+ .replace(/&/g, "&")
26
+ .replace(/"/g, """)
27
+ .replace(/</g, "&lt;")
28
+ .replace(/>/g, "&gt;");
29
+ }
30
+
14
31
  function getCodeBlockData(text, attrs) {
15
32
  const { language, tag, data } = attrs || {};
16
33
 
@@ -174,8 +191,15 @@ function createSequenceElement(node, options = {}) {
174
191
  // renderers. Foundations can read el.mathml from content.sequence.
175
192
  // The optional id enables numbered cross-references via
176
193
  // @uniweb/scholar/math's <EquationRef>.
194
+ //
195
+ // Element type is `math` with `display: true`. Inline math
196
+ // (math_inline inside paragraphs) reaches downstream as the
197
+ // same `math` IR node with `display: false`. PM-schema names
198
+ // (math_display / math_inline) stay put — they're the
199
+ // content-writer roundtrip contract.
177
200
  return {
178
- type: "math_display",
201
+ type: "math",
202
+ display: true,
179
203
  id: node.attrs?.id || null,
180
204
  latex: node.attrs?.latex || "",
181
205
  mathml: node.attrs?.mathml || "",
@@ -399,11 +423,21 @@ function getTextContent(content, options = {}) {
399
423
 
400
424
  return prev + styledText;
401
425
  } else if (type === "math_inline") {
402
- // Pre-compiled MathML string rides straight into the
403
- // paragraph's HTML and reaches kit's Text via
404
- // dangerouslySetInnerHTML. The HTML5 parser handles <math>
405
- // as MathML natively — zero runtime math library needed.
406
- return prev + (curr.attrs?.mathml || "");
426
+ // Inline math is a non-text inline atom. The mathml is
427
+ // pre-compiled at parse time (content-reader) and rides
428
+ // inline so kit's Text (dangerouslySetInnerHTML) renders
429
+ // it natively in the browser. Wrapping in a span carries
430
+ // the LaTeX source as `data-latex` so Press's print
431
+ // adapters (typst, latex, etc.) have a structured handle
432
+ // when their Paragraph builder walks the styled string.
433
+ // The wrapper is visually invisible; the inner <math>
434
+ // still renders as MathML in the browser.
435
+ const latex = escapeAttr(curr.attrs?.latex || "");
436
+ const mathml = curr.attrs?.mathml || "";
437
+ return (
438
+ prev +
439
+ `<span data-type="math" data-latex="${latex}" data-display="false">${mathml}</span>`
440
+ );
407
441
  } else if (type === "inset_placeholder") {
408
442
  // Inline inset (e.g. a `[@key]{...}` cite). Emit a marker
409
443
  // tag the renderer can split on; the actual inset is
@@ -572,6 +606,8 @@ function parseImgBlock(itemAttrs) {
572
606
  theme,
573
607
  role,
574
608
  credit = "",
609
+ id, // {#fig-id} cross-reference label — preserved so Press
610
+ // adapters can emit \label{id} (LaTeX) / <id> (Typst).
575
611
  } = itemAttrs;
576
612
 
577
613
  let { contentType, viewType, contentId, identifier } = imgInfo || {};
@@ -605,6 +641,7 @@ function parseImgBlock(itemAttrs) {
605
641
  theme,
606
642
  role,
607
643
  credit,
644
+ id: id || undefined,
608
645
  };
609
646
  }
610
647