@uniweb/press 0.4.8 → 0.4.10
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 +1 -1
- package/src/adapters/docx.js +8 -2
- package/src/adapters/epub.js +2 -0
- package/src/adapters/math-css.js +45 -0
- package/src/adapters/pagedjs.js +3 -0
- package/src/adapters/typst.js +2 -1
- package/src/ir/parser.js +16 -0
package/package.json
CHANGED
package/src/adapters/docx.js
CHANGED
|
@@ -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:
|
|
618
|
-
link:
|
|
623
|
+
children: children.length ? children : [new TextRun({ text: destination })],
|
|
624
|
+
link: destination,
|
|
619
625
|
})
|
|
620
626
|
}
|
|
621
627
|
|
package/src/adapters/epub.js
CHANGED
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
import JSZip from 'jszip'
|
|
32
32
|
import { parseFragment } from 'parse5'
|
|
33
33
|
import { fetchAssets } from '../assets/fetch.js'
|
|
34
|
+
import { MATH_CSS } from './math-css.js'
|
|
34
35
|
|
|
35
36
|
// ============================================================================
|
|
36
37
|
// Public API
|
|
@@ -625,4 +626,5 @@ pre {
|
|
|
625
626
|
overflow: auto;
|
|
626
627
|
white-space: pre-wrap;
|
|
627
628
|
}
|
|
629
|
+
${MATH_CSS}
|
|
628
630
|
`
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The CSS a Temml-produced MathML document needs to lay out.
|
|
3
|
+
*
|
|
4
|
+
* Math arrives as MathML, which browsers render natively — so it is tempting
|
|
5
|
+
* to conclude, as this pipeline's own comments once did, that it carries no
|
|
6
|
+
* CSS dependency at all. It does, for two separate reasons:
|
|
7
|
+
*
|
|
8
|
+
* 1. **Temml emits class hooks and expects a stylesheet to define them.**
|
|
9
|
+
* `tml-left` / `tml-right` carry the `&` column alignment of an `aligned`
|
|
10
|
+
* environment, and `tml-jot` carries its extra row spacing. With nothing
|
|
11
|
+
* defining them, a derivation's `=` signs do not line up and its rows sit
|
|
12
|
+
* flush against each other. The declarations below are Temml's own, from
|
|
13
|
+
* `Temml-Local.css`.
|
|
14
|
+
*
|
|
15
|
+
* 2. **`mtd` gets no vertical padding from the browser.** Temml's stylesheet
|
|
16
|
+
* only *adjusts* row spacing for jot and small, on the stated assumption
|
|
17
|
+
* that "default mtd top padding is 0.5ex per MathML-Core and user-agent
|
|
18
|
+
* CSS". Measured in Chrome 2026-07, a pristine `mtd` gets 0px — so a
|
|
19
|
+
* `pmatrix` or `cases`, which carries no `tml-*` class at all, renders with
|
|
20
|
+
* its rows touching. Shipping Temml's stylesheet verbatim fixes the
|
|
21
|
+
* derivation and leaves the matrix broken; the `math mtd` rule below is the
|
|
22
|
+
* part Temml does not have.
|
|
23
|
+
*
|
|
24
|
+
* ── Why this is a string and not an imported stylesheet ──
|
|
25
|
+
*
|
|
26
|
+
* These adapters run in browser hosts as well as Node ones (see the host-
|
|
27
|
+
* supplied asset loaders in `assets/fetch.js`), so press cannot read a file at
|
|
28
|
+
* runtime, and it does not depend on `@uniweb/kit`. The same declarations
|
|
29
|
+
* therefore live in `kit/src/prose-tokens.css` for the browser lane.
|
|
30
|
+
*
|
|
31
|
+
* That is a duplicate, and duplicates drift — so it is pinned mechanically
|
|
32
|
+
* rather than by comment: `framework/_contracts/math-css-parity.test.js`
|
|
33
|
+
* parses both and fails when they disagree. Change one, change the other, or
|
|
34
|
+
* the contract test names it.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
export const MATH_CSS = `/* Temml's own class hooks — without these an aligned environment neither
|
|
38
|
+
aligns nor breathes. */
|
|
39
|
+
.tml-right { text-align: right; }
|
|
40
|
+
.tml-left { text-align: left; }
|
|
41
|
+
.tml-sml-pad { padding-left: 0.05em; }
|
|
42
|
+
/* Row spacing. The browser gives mtd no vertical padding, so state the
|
|
43
|
+
MathML-Core default here; Temml's own CSS only adjusts it for jot. */
|
|
44
|
+
math mtd { padding-top: 0.5ex; padding-bottom: 0.5ex; }
|
|
45
|
+
math mtable.tml-jot mtd { padding-top: 0.7ex; padding-bottom: 0.7ex; }`
|
package/src/adapters/pagedjs.js
CHANGED
|
@@ -231,6 +231,8 @@ export const DEFAULT_POLYFILL_URL =
|
|
|
231
231
|
* book PDF without a custom foundation stylesheet. Foundations override by
|
|
232
232
|
* passing `options.stylesheet`.
|
|
233
233
|
*/
|
|
234
|
+
import { MATH_CSS } from './math-css.js'
|
|
235
|
+
|
|
234
236
|
export const DEFAULT_STYLESHEET = `
|
|
235
237
|
/* Hidden metadata block — the DOM carries it for CSS string-set / string() */
|
|
236
238
|
[data-pagedjs-metadata] { display: none; }
|
|
@@ -292,4 +294,5 @@ blockquote {
|
|
|
292
294
|
}
|
|
293
295
|
ul, ol { margin: 0.5em 0 0.75em 1.5em; }
|
|
294
296
|
figure { break-inside: avoid; }
|
|
297
|
+
${MATH_CSS}
|
|
295
298
|
`
|
package/src/adapters/typst.js
CHANGED
|
@@ -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') {
|