@uniweb/press 0.4.8 → 0.4.9

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/press",
3
- "version": "0.4.8",
3
+ "version": "0.4.9",
4
4
  "description": "Press your React components into downloadable files — Word, Excel, PDF. Registration-based pattern with lazy-loaded format adapters.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -510,6 +510,9 @@ function irToInlineChildren(node) {
510
510
  // a TextRun so the OOXML parent is <w:r>.
511
511
  return [new TextRun({ children: [new DocxTab()] })]
512
512
  case 'externalHyperlink':
513
+ // A plain <a href> from same-source JSX — same destination, same
514
+ // emitter. See the href note in ir/parser.js.
515
+ case 'a':
513
516
  return [irToExternalHyperlink(node)]
514
517
  case 'internalHyperlink':
515
518
  return [irToInternalHyperlink(node)]
@@ -612,10 +615,13 @@ function irToTextRunPair(node) {
612
615
  }
613
616
 
614
617
  function irToExternalHyperlink(node) {
618
+ // `link` is the data-* spelling (data-link); `href` arrives from a plain
619
+ // <a href>. Same destination either way.
620
+ const destination = node.link || node.href || ''
615
621
  const children = (node.children || []).flatMap(irToInlineChildren)
616
622
  return new ExternalHyperlink({
617
- children: children.length ? children : [new TextRun({ text: node.link || '' })],
618
- link: node.link || '',
623
+ children: children.length ? children : [new TextRun({ text: destination })],
624
+ link: destination,
619
625
  })
620
626
  }
621
627
 
@@ -374,6 +374,7 @@ function blockNodeToTypst(node) {
374
374
  return inlineNodeToTypst(node)
375
375
 
376
376
  case 'link':
377
+ case 'a':
377
378
  return inlineNodeToTypst(node)
378
379
 
379
380
  case 'math':
@@ -526,7 +527,7 @@ function inlineNodeToTypst(node) {
526
527
  return text
527
528
  }
528
529
 
529
- if (node.type === 'link') {
530
+ if (node.type === 'link' || node.type === 'a') {
530
531
  const href = node.href || ''
531
532
  const inner = inlineChildrenToTypst(node.children || [])
532
533
  return `#link(${quoteTypstString(href)})[${inner}]`
package/src/ir/parser.js CHANGED
@@ -103,6 +103,22 @@ function nodeToIR(node) {
103
103
  const properties = attributesToProperties(node.attrs || [])
104
104
  const children = collectChildren(node)
105
105
 
106
+ // A plain <a href> carries its destination in a normal HTML attribute, not
107
+ // a data-* one, so attributesToProperties drops it. Foundations reach this
108
+ // shape by writing an ordinary anchor in JSX that serves both the browser
109
+ // preview and the compile input — the same-source property principles.md
110
+ // §8 asks us to pursue. Without the href the adapters still emit the link
111
+ // TEXT and silently lose the destination, which is precisely the
112
+ // preview/output drift that principle exists to eliminate.
113
+ //
114
+ // Only `href` is lifted, and only for an anchor: it is the one plain
115
+ // attribute whose document meaning is unambiguous. The IR stays data-*
116
+ // driven everywhere else.
117
+ if (type === 'a' && properties.href === undefined) {
118
+ const href = getAttr(node, 'href')
119
+ if (href) properties.href = href
120
+ }
121
+
106
122
  const obj = { type, ...properties }
107
123
 
108
124
  if (type === 'text') {