rapier-markdown-kit 1.2.32 → 1.2.40
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 +16 -10
- package/dist/agent/vendor/pretext/NOTICE +2 -2
- package/dist/agent/vendor/pretext/SOURCE.json +62 -78
- package/dist/agent/vendor/pretext/analysis.js +24 -6
- package/dist/agent/vendor/pretext/gecko-line-breaks.js +1 -1
- package/dist/agent/vendor/pretext/generated/engine-break-data.js +1 -1
- package/dist/agent/vendor/pretext/generated/webkit-generic-families.js +1 -1
- package/dist/agent/vendor/pretext/graphemes.js +1 -1
- package/dist/agent/vendor/pretext/han-kerning.js +1 -1
- package/dist/agent/vendor/pretext/layout.js +14 -11
- package/dist/agent/vendor/pretext/line-break.js +170 -195
- package/dist/agent/vendor/pretext/line-breaks.js +1 -7
- package/dist/agent/vendor/pretext/line-text.js +2 -2
- package/dist/agent/vendor/pretext/measurement.js +454 -113
- package/dist/agent/vendor/pretext/prepare.js +164 -244
- package/dist/agent/vendor/pretext/rich-inline.js +57 -37
- package/dist/agent/will.mjs +73 -0
- package/dist/kit/ledger/data.mjs +2 -2
- package/dist/kit/ledger/format.mjs +86 -42
- package/dist/kit/ledger/hash.mjs +43 -2
- package/dist/kit/ledger/history.mjs +6 -0
- package/dist/kit/ledger/inverse-source.mjs +6 -2
- package/dist/kit/ledger/journal-records.mjs +4 -2
- package/dist/kit/ledger/merge.mjs +3 -17
- package/dist/kit/ledger/text-merge.mjs +191 -28
- package/dist/kit/rapier-ledger.mjs +2 -2
- package/dist/kit/render-markdown.mjs +133 -10
- package/dist/kit/render-print.mjs +3 -3
- package/dist/kit/render-sanitize.mjs +66 -23
- package/dist/kit/render.mjs +10 -10
- package/dist/kit/wiki.mjs +34 -0
- package/dist/kit/will.d.mts +3 -0
- package/dist/layout/hyphenation.mjs +6 -4
- package/dist/layout/line-plan.mjs +96 -0
- package/dist/layout/model.mjs +2 -1
- package/dist/layout/paragraph-fit.mjs +4 -4
- package/dist/layout/prepared-paragraph.mjs +19 -2
- package/dist/layout/typography.mjs +57 -63
- package/dist/spec/document-fonts.mjs +1 -0
- package/dist/spec/document-settings.mjs +1 -0
- package/dist/spec/html-blocks.mjs +10 -7
- package/dist/spec/md-assets.mjs +52 -12
- package/package.json +1 -1
- package/style.css +37 -28
- package/dist/agent/vendor/pretext/entry-geometry.js +0 -183
package/README.md
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
# rapier-markdown-kit
|
|
2
2
|
|
|
3
|
-
Read, render and write Self-contained Markdown
|
|
4
|
-
|
|
3
|
+
Read, render and write Self-contained Markdown: one `.md` file with its pictures, drawings and layout.
|
|
4
|
+
|
|
5
|
+
<picture>
|
|
6
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/jackskip22/rapier-plugins/main/assets/diagram-390-dark.png">
|
|
7
|
+
<img src="https://raw.githubusercontent.com/jackskip22/rapier-plugins/main/assets/diagram-390-light.png" alt="A Rapier document on a phone with an editable diagram of connected boxes" width="320">
|
|
8
|
+
</picture>
|
|
9
|
+
|
|
10
|
+
Try it: open a `.md` file at [rapier.website](https://rapier.website).
|
|
11
|
+
Install: `npm install rapier-markdown-kit`.
|
|
12
|
+
|
|
13
|
+
The kit works in browsers and Node: pictures, editable SVG drawings, layout and precise inline typography. Build portable documents for people and agents. Will/1 regions mark what an agent
|
|
5
14
|
may edit, append to or preserve. MIT, no dependencies.
|
|
6
15
|
|
|
7
16
|
- Typography uses ordinary inline HTML spans with validated size, color and family. Comments and references
|
|
@@ -9,16 +18,13 @@ may edit, append to or preserve. MIT, no dependencies.
|
|
|
9
18
|
- One stylesheet renders the document as the editor and its exported page do.
|
|
10
19
|
- The line planner flows text around a picture's real shape; a conformance suite of thirteen documents runs
|
|
11
20
|
any implementation against it.
|
|
12
|
-
-
|
|
13
|
-
- MIT, no dependencies, Node 22 or newer.
|
|
21
|
+
- Node 22 or newer.
|
|
14
22
|
|
|
15
23
|
To show documents in your app without writing a renderer, frame the read-only reader with
|
|
16
24
|
`npm install rapier-embed` (`build: 'reader'`). To hand a person the whole editor around their document as one
|
|
17
25
|
offline file, run `npx rapier-html notes.md`.
|
|
18
26
|
|
|
19
|
-
|
|
20
|
-
the person taps a change to see what was there before and undoes anything. `show {target:"comparison"}` lets the agent
|
|
21
|
-
deliberately show a diff. The kit supplies the portable source and history those tools use.
|
|
27
|
+
The kit supplies the portable source and history Rapier's agent tools use.
|
|
22
28
|
|
|
23
29
|
```sh
|
|
24
30
|
npm install rapier-markdown-kit
|
|
@@ -57,7 +63,7 @@ import {parseAssets} from 'rapier-markdown-kit/assets'; // the picture appendi
|
|
|
57
63
|
## Choose a Rapier workflow
|
|
58
64
|
|
|
59
65
|
Rapier is a phone-first Markdown editor for notes, diagrams, drawing and watercolor painting. It runs offline
|
|
60
|
-
as one HTML file on Android, Web and
|
|
66
|
+
as one HTML file on Android, Web, Windows and Linux.
|
|
61
67
|
|
|
62
68
|
1. **Work together live.** Connect to `https://mcp.rapier.website/door/mcp`, then call `open` to share one document with the person.
|
|
63
69
|
2. **Deliver an offline editor.** Run `npx rapier-html notes.md` to put the document and editor in one HTML file ([rapier-html](https://github.com/jackskip22/rapier-plugins/tree/main/npm/rapier-html)).
|
|
@@ -550,8 +556,8 @@ tolerance.
|
|
|
550
556
|
## License
|
|
551
557
|
|
|
552
558
|
MIT, the full text in `LICENSE`; Rapier-owned modules and the stylesheet keep their MIT line. Pretext's complete license,
|
|
553
|
-
notice and pinned source inventory are in `dist/agent/vendor/pretext/`. The selected upstream is
|
|
554
|
-
`
|
|
559
|
+
notice and pinned source inventory are in `dist/agent/vendor/pretext/`. The selected upstream is main
|
|
560
|
+
`0d102a5cd933611e86a7e60bda7b4baa5995c6b0`: Pretext 1.0.0 plus the commits of main through pull request #525. Its upstream license includes
|
|
555
561
|
Chromium/WebKit BSD, Unicode and ICU notices for derived code and generated data; those notices travel with the kit
|
|
556
562
|
and the exported wrapping runtime. The history projection uses the MIT diff core;
|
|
557
563
|
its full grant is in `dist/packages/rapier-diff/LICENSE`. The Rapier editor is AGPL-3.0-only and
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
Pretext
|
|
2
|
-
Package metadata version: 0.0
|
|
1
|
+
Pretext 1.0.0 plus main to #525 at 0d102a5cd933611e86a7e60bda7b4baa5995c6b0 (2026-10-15T10:02:17-07:00)
|
|
2
|
+
Package metadata version: 1.0.0; this snapshot is the 1.0.0 release (4a98f37b) plus the 16 commits of main through pull request #525.
|
|
3
3
|
Copyright (c) 2026 Pretext contributors
|
|
4
4
|
https://github.com/chenglou/pretext
|
|
5
5
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"package": "@chenglou/pretext",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"release": "
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"release": "1.0.0 plus main to #525",
|
|
5
5
|
"repository": "https://github.com/chenglou/pretext",
|
|
6
|
-
"commit": "
|
|
7
|
-
"commitDate": "2026-10-
|
|
8
|
-
"sourceTree": "
|
|
9
|
-
"packageSha256": "
|
|
6
|
+
"commit": "0d102a5cd933611e86a7e60bda7b4baa5995c6b0",
|
|
7
|
+
"commitDate": "2026-10-15T10:02:17-07:00",
|
|
8
|
+
"sourceTree": "fc987521e1fab1b6c1bedcc7a2e1912ca06bb166",
|
|
9
|
+
"packageSha256": "adf65e4df509df3cb3acef2cc4dd6179591f72bc9a2c351012d9d62d15552d2a",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"thirdPartyLicenses": [
|
|
12
12
|
"BSD-3-Clause",
|
|
@@ -15,19 +15,19 @@
|
|
|
15
15
|
"ICU"
|
|
16
16
|
],
|
|
17
17
|
"licenseSha256": "b0bc6870efb4e667f911d5f6b52fc9b321d634a0469a17464e35da244c28f128",
|
|
18
|
-
"noticeSha256": "
|
|
18
|
+
"noticeSha256": "c0867f4217303fa447f1932581335903d1082a4e350bcb6d15fedbe6f796af76",
|
|
19
19
|
"exports": {
|
|
20
20
|
".": "./layout.js",
|
|
21
21
|
"./rich-inline": "./rich-inline.js"
|
|
22
22
|
},
|
|
23
23
|
"compiler": {
|
|
24
|
-
"runtime": "
|
|
25
|
-
"amaro": "1.1.
|
|
24
|
+
"runtime": "v22.22.0",
|
|
25
|
+
"amaro": "1.1.4",
|
|
26
26
|
"api": "node:module.stripTypeScriptTypes",
|
|
27
27
|
"mode": "strip",
|
|
28
28
|
"sourceMap": false,
|
|
29
29
|
"importParser": "Acorn 8.19.0",
|
|
30
|
-
"toolSha256": "
|
|
30
|
+
"toolSha256": "53f6030b37a0a2a29e0957ffc93706cabbfc14de689f79b53ec056160d2082e8"
|
|
31
31
|
},
|
|
32
32
|
"changes": "Node TypeScript erasure and attribution header; rich-inline.js and prepare.js additionally carry rapier-paragraph-segments-v2 (direct legal source facts and explicit projected hyphen-minus). This local runtime extension is not byte-exact upstream. Source hashes, unchanged-upstream output hash and patched output hash are recorded. Default wrapping and the single measurement graph are preserved.",
|
|
33
33
|
"generatedData": [
|
|
@@ -57,18 +57,18 @@
|
|
|
57
57
|
"sourceBytes": 35140,
|
|
58
58
|
"sourceSha256": "b8782c423a8d192f1d5c69c8ed2422bc8d55526c9aa18010e70348252285455e",
|
|
59
59
|
"output": "generated/engine-break-data.js",
|
|
60
|
-
"outputBytes":
|
|
61
|
-
"outputSha256": "
|
|
60
|
+
"outputBytes": 35264,
|
|
61
|
+
"outputSha256": "71006713e3383564b5c7348c736c2dba6a59e04c05693a6a62e6367b45abbc7a",
|
|
62
62
|
"imports": []
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
65
|
"source": "src/line-breaks.ts",
|
|
66
|
-
"sourceGitBlob": "
|
|
67
|
-
"sourceBytes":
|
|
68
|
-
"sourceSha256": "
|
|
66
|
+
"sourceGitBlob": "ec09b58611c8251d583bab2893f57dec78082a33",
|
|
67
|
+
"sourceBytes": 38127,
|
|
68
|
+
"sourceSha256": "4b3b654234a175e06ea672ff903c544e00ae7626698bfa8f83616c84fa0aaee4",
|
|
69
69
|
"output": "line-breaks.js",
|
|
70
|
-
"outputBytes":
|
|
71
|
-
"outputSha256": "
|
|
70
|
+
"outputBytes": 38251,
|
|
71
|
+
"outputSha256": "cbc65ed7232d1bfc241787a3d99986e062c74bbb30d3fbf738cf7c59c2196ccf",
|
|
72
72
|
"imports": [
|
|
73
73
|
"./generated/engine-break-data.js"
|
|
74
74
|
]
|
|
@@ -79,8 +79,8 @@
|
|
|
79
79
|
"sourceBytes": 4663,
|
|
80
80
|
"sourceSha256": "2f99310f195889177675edd7e0fbd00ee1a59286f243a9a8b13085bcb12b89f3",
|
|
81
81
|
"output": "graphemes.js",
|
|
82
|
-
"outputBytes":
|
|
83
|
-
"outputSha256": "
|
|
82
|
+
"outputBytes": 4787,
|
|
83
|
+
"outputSha256": "88bf8f7575ad7e888b4d7223130ab4cbe6c559cb83e35672cbe1ca94d3f86d01",
|
|
84
84
|
"imports": [
|
|
85
85
|
"./line-breaks.js"
|
|
86
86
|
]
|
|
@@ -91,8 +91,8 @@
|
|
|
91
91
|
"sourceBytes": 33564,
|
|
92
92
|
"sourceSha256": "cf67f7eecaf6c9849acfa9958575070597cb5e6f3a1a17bb2027cef828340248",
|
|
93
93
|
"output": "gecko-line-breaks.js",
|
|
94
|
-
"outputBytes":
|
|
95
|
-
"outputSha256": "
|
|
94
|
+
"outputBytes": 33688,
|
|
95
|
+
"outputSha256": "4551c550d9658572d00470099ab843c588a3a63b3ad3baf825ccebfc6983336e",
|
|
96
96
|
"imports": [
|
|
97
97
|
"./generated/engine-break-data.js",
|
|
98
98
|
"./graphemes.js",
|
|
@@ -101,12 +101,12 @@
|
|
|
101
101
|
},
|
|
102
102
|
{
|
|
103
103
|
"source": "src/analysis.ts",
|
|
104
|
-
"sourceGitBlob": "
|
|
105
|
-
"sourceBytes":
|
|
106
|
-
"sourceSha256": "
|
|
104
|
+
"sourceGitBlob": "a994b67226c90e39fbd25e3b8fdfa63249b55527",
|
|
105
|
+
"sourceBytes": 41259,
|
|
106
|
+
"sourceSha256": "bf6fbab9ab2f32b92573ad982d8485ca7d2ee8de1886a8bdcc435b7bdca15241",
|
|
107
107
|
"output": "analysis.js",
|
|
108
|
-
"outputBytes":
|
|
109
|
-
"outputSha256": "
|
|
108
|
+
"outputBytes": 41383,
|
|
109
|
+
"outputSha256": "c3595e80fc013ed6424f78e204e45a06b5a9d1c02d335b344782199edcfc369f",
|
|
110
110
|
"imports": [
|
|
111
111
|
"./gecko-line-breaks.js",
|
|
112
112
|
"./graphemes.js",
|
|
@@ -119,59 +119,45 @@
|
|
|
119
119
|
"sourceBytes": 5190,
|
|
120
120
|
"sourceSha256": "16ffba2832197e189a5ddf7e745304a3c5faacc82858a51808c3744991b11614",
|
|
121
121
|
"output": "generated/webkit-generic-families.js",
|
|
122
|
-
"outputBytes":
|
|
123
|
-
"outputSha256": "
|
|
122
|
+
"outputBytes": 5314,
|
|
123
|
+
"outputSha256": "8df335194a5e28fe8b94da13b7c64f6eeafd2ee6e4ca82e47de97b50bef8c7e6",
|
|
124
124
|
"imports": []
|
|
125
125
|
},
|
|
126
126
|
{
|
|
127
127
|
"source": "src/measurement.ts",
|
|
128
|
-
"sourceGitBlob": "
|
|
129
|
-
"sourceBytes":
|
|
130
|
-
"sourceSha256": "
|
|
128
|
+
"sourceGitBlob": "0ab3ebaa2802088fb2ac7b5dcc10d35a3440b36f",
|
|
129
|
+
"sourceBytes": 93605,
|
|
130
|
+
"sourceSha256": "245707d4090bcb74f0c796e074680e798d5eaf2c19e1ba66f06bcc2390132253",
|
|
131
131
|
"output": "measurement.js",
|
|
132
|
-
"outputBytes":
|
|
133
|
-
"outputSha256": "
|
|
132
|
+
"outputBytes": 93729,
|
|
133
|
+
"outputSha256": "bdb161e112ace0b15d3d072620d709e439a3c0d53d853922cc16ae6fcc00fbda",
|
|
134
134
|
"imports": [
|
|
135
135
|
"./generated/webkit-generic-families.js",
|
|
136
136
|
"./graphemes.js",
|
|
137
137
|
"./line-breaks.js"
|
|
138
138
|
]
|
|
139
139
|
},
|
|
140
|
-
{
|
|
141
|
-
"source": "src/entry-geometry.ts",
|
|
142
|
-
"sourceGitBlob": "c7f139c1f6234329fffa30678f5005c7b1468afb",
|
|
143
|
-
"sourceBytes": 9321,
|
|
144
|
-
"sourceSha256": "271d975afceb141c10406de5923decc61c9f45b9229dff421ff4355c46611899",
|
|
145
|
-
"output": "entry-geometry.js",
|
|
146
|
-
"outputBytes": 9443,
|
|
147
|
-
"outputSha256": "d526d143bd6eb4432295f2e6551090088fa72f4de36c6c2d32af0f8f46979065",
|
|
148
|
-
"imports": [
|
|
149
|
-
"./graphemes.js",
|
|
150
|
-
"./measurement.js"
|
|
151
|
-
]
|
|
152
|
-
},
|
|
153
140
|
{
|
|
154
141
|
"source": "src/line-break.ts",
|
|
155
|
-
"sourceGitBlob": "
|
|
156
|
-
"sourceBytes":
|
|
157
|
-
"sourceSha256": "
|
|
142
|
+
"sourceGitBlob": "4ddb69de1eca351f0d0023cad5eb7758bf98359d",
|
|
143
|
+
"sourceBytes": 68368,
|
|
144
|
+
"sourceSha256": "5f45ad068f266eff920cd1df6f0a9784e888d6c0e990631cd9ac6b3c8e77ee30",
|
|
158
145
|
"output": "line-break.js",
|
|
159
|
-
"outputBytes":
|
|
160
|
-
"outputSha256": "
|
|
146
|
+
"outputBytes": 68492,
|
|
147
|
+
"outputSha256": "cc0c4c9f0cb76765ee78cda536e5df9dafa8fdc1a845acabee1fe4e4377c5a31",
|
|
161
148
|
"imports": [
|
|
162
149
|
"./analysis.js",
|
|
163
|
-
"./entry-geometry.js",
|
|
164
150
|
"./measurement.js"
|
|
165
151
|
]
|
|
166
152
|
},
|
|
167
153
|
{
|
|
168
154
|
"source": "src/line-text.ts",
|
|
169
|
-
"sourceGitBlob": "
|
|
170
|
-
"sourceBytes":
|
|
171
|
-
"sourceSha256": "
|
|
155
|
+
"sourceGitBlob": "ece66351037a8c11e2504700dd1452ab3fcd873e",
|
|
156
|
+
"sourceBytes": 3759,
|
|
157
|
+
"sourceSha256": "d79e792a052baba6d50658e45dcd60d4c9c57720200682e41852f4e1f9186bd5",
|
|
172
158
|
"output": "line-text.js",
|
|
173
|
-
"outputBytes":
|
|
174
|
-
"outputSha256": "
|
|
159
|
+
"outputBytes": 3883,
|
|
160
|
+
"outputSha256": "cf0d621bd2496a0376a985139356d7bf49f75e549743eaab06a74aaef06303af",
|
|
175
161
|
"imports": [
|
|
176
162
|
"./analysis.js",
|
|
177
163
|
"./graphemes.js",
|
|
@@ -185,8 +171,8 @@
|
|
|
185
171
|
"sourceBytes": 13202,
|
|
186
172
|
"sourceSha256": "0fd39a11777abf2a8af12c7a8450903140d336ae6cdc58b4fb4bb033cc46ff3b",
|
|
187
173
|
"output": "han-kerning.js",
|
|
188
|
-
"outputBytes":
|
|
189
|
-
"outputSha256": "
|
|
174
|
+
"outputBytes": 13326,
|
|
175
|
+
"outputSha256": "7eabac3539df0ac2a753315cddd3a70a1e4e53100f955cb81304eece5dc43071",
|
|
190
176
|
"imports": [
|
|
191
177
|
"./analysis.js",
|
|
192
178
|
"./line-breaks.js",
|
|
@@ -195,32 +181,31 @@
|
|
|
195
181
|
},
|
|
196
182
|
{
|
|
197
183
|
"source": "src/prepare.ts",
|
|
198
|
-
"sourceGitBlob": "
|
|
199
|
-
"sourceBytes":
|
|
200
|
-
"sourceSha256": "
|
|
184
|
+
"sourceGitBlob": "c9185214686fbe9f4dd00c860f29cac8be790fb3",
|
|
185
|
+
"sourceBytes": 43095,
|
|
186
|
+
"sourceSha256": "4fc8ab0f7f61c9ba9bf7c451347936fbdf703c0096fecc3d9260180798e70909",
|
|
201
187
|
"output": "prepare.js",
|
|
202
|
-
"outputBytes":
|
|
203
|
-
"outputSha256": "
|
|
188
|
+
"outputBytes": 43266,
|
|
189
|
+
"outputSha256": "0301c86ac74bc8395007d1b3d27e364de7da795f528501da98ed0adfb2230deb",
|
|
204
190
|
"imports": [
|
|
205
191
|
"./analysis.js",
|
|
206
|
-
"./entry-geometry.js",
|
|
207
192
|
"./generated/engine-break-data.js",
|
|
208
193
|
"./graphemes.js",
|
|
209
194
|
"./han-kerning.js",
|
|
210
195
|
"./line-breaks.js",
|
|
211
196
|
"./measurement.js"
|
|
212
197
|
],
|
|
213
|
-
"upstreamOutputSha256": "
|
|
198
|
+
"upstreamOutputSha256": "a42bda210a756435b42c5cf9e853133ff2c27a93e9792b20f26e58aa2262cc9f",
|
|
214
199
|
"localPatch": "rapier-paragraph-segments-v2"
|
|
215
200
|
},
|
|
216
201
|
{
|
|
217
202
|
"source": "src/layout.ts",
|
|
218
|
-
"sourceGitBlob": "
|
|
219
|
-
"sourceBytes":
|
|
220
|
-
"sourceSha256": "
|
|
203
|
+
"sourceGitBlob": "02fa8cb7b2b67c54a4e8a2c1f9694e6cc0c9e37d",
|
|
204
|
+
"sourceBytes": 14339,
|
|
205
|
+
"sourceSha256": "e2d88979f449c0416342377a2a8e7e98bd57f20539737ea5bcfab9d1b6ad2b22",
|
|
221
206
|
"output": "layout.js",
|
|
222
|
-
"outputBytes":
|
|
223
|
-
"outputSha256": "
|
|
207
|
+
"outputBytes": 14463,
|
|
208
|
+
"outputSha256": "48922fbb39c1f0a9a62199ee7e51ea9baff421f5c03f0a8cca33ca57dee01a5b",
|
|
224
209
|
"imports": [
|
|
225
210
|
"./analysis.js",
|
|
226
211
|
"./line-break.js",
|
|
@@ -232,21 +217,20 @@
|
|
|
232
217
|
},
|
|
233
218
|
{
|
|
234
219
|
"source": "src/rich-inline.ts",
|
|
235
|
-
"sourceGitBlob": "
|
|
236
|
-
"sourceBytes":
|
|
237
|
-
"sourceSha256": "
|
|
220
|
+
"sourceGitBlob": "c39ef17092fcea7915d7a28de9328ecfc2ed2e7f",
|
|
221
|
+
"sourceBytes": 75016,
|
|
222
|
+
"sourceSha256": "f030adb3c32fd96742741970d9b75efe239b00317137d18560eaf369f53e5687",
|
|
238
223
|
"output": "rich-inline.js",
|
|
239
|
-
"outputBytes":
|
|
240
|
-
"outputSha256": "
|
|
224
|
+
"outputBytes": 75768,
|
|
225
|
+
"outputSha256": "47e675a12f59c622a154e6f2009055679cfa03e3e4d0f623dcd85fb3d3576304",
|
|
241
226
|
"imports": [
|
|
242
227
|
"./analysis.js",
|
|
243
|
-
"./entry-geometry.js",
|
|
244
228
|
"./line-break.js",
|
|
245
229
|
"./line-text.js",
|
|
246
230
|
"./measurement.js",
|
|
247
231
|
"./prepare.js"
|
|
248
232
|
],
|
|
249
|
-
"upstreamOutputSha256": "
|
|
233
|
+
"upstreamOutputSha256": "28e12e027b0448c27126f6c525936e94ce457712ee4447c67842115e313ca636",
|
|
250
234
|
"localPatch": "rapier-paragraph-segments-v2"
|
|
251
235
|
}
|
|
252
236
|
]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Pretext
|
|
1
|
+
/*! Pretext 1.0.0 + main (0d102a5cd) | MIT; BSD/Unicode/ICU notices in LICENSE | Copyright (c) 2026 Pretext contributors */
|
|
2
2
|
import { getGeckoLineBreaks, isDiscardable, isEastAsianSegmentBreak, isJapaneseOrChinese, isSpaceCombiningSequenceTail, isSpaceOrTabOrSegmentBreak } from './gecko-line-breaks.js'
|
|
3
3
|
import { isBidiControl, } from './graphemes.js'
|
|
4
4
|
import { BREAK, CLUSTER_START, FORCED_BREAK, ITEM_START, SOFT_HYPHEN_BREAK, getBlinkLineBreaks, getWebKitBreakBetweenItems, getWebKitLineBreaks } from './line-breaks.js'
|
|
@@ -49,6 +49,12 @@ export const RETURNABLE = 0x40
|
|
|
49
49
|
// The engine's clusters don't split the segment, so no emergency break splits it
|
|
50
50
|
// either. Measurement clears it.
|
|
51
51
|
export const ONE_CLUSTER = 0x80
|
|
52
|
+
// In its place on a prepared handle: the zero-width break is a soft hyphen, which the Gecko scan
|
|
53
|
+
// makes one where its break draws no hyphen (classifySegmentUnit). Firefox's text run drops it,
|
|
54
|
+
// so it is a break with nothing there: it stays with the line that ends at it and no line starts
|
|
55
|
+
// with it, where a zero-width space is content (walkPreparedComplexLines in src/line-break.ts).
|
|
56
|
+
// Measurement sets it.
|
|
57
|
+
export const DROPPED = 0x80
|
|
52
58
|
|
|
53
59
|
|
|
54
60
|
// Each kind's name by its code, as prepareWithSegments() gives them.
|
|
@@ -62,7 +68,8 @@ export const SEGMENT_KINDS = [
|
|
|
62
68
|
// flags byte: its kind, UNBROKEN where the engine's scan gives no break before text, zero-width
|
|
63
69
|
// glue or a control, other than at a line start, and where tabs don't hang before a tab or
|
|
64
70
|
// the spaces after one, RETURNABLE at the other segments of text with such a boundary, which
|
|
65
|
-
// `hasUnbroken` tells, and ONE_CLUSTER where the scan has clusters of its own.
|
|
71
|
+
// `hasUnbroken` tells, and ONE_CLUSTER where the scan has clusters of its own. A zero-width
|
|
72
|
+
// space right after another is UNBROKEN too, which `hasUnbroken` leaves out.
|
|
66
73
|
|
|
67
74
|
|
|
68
75
|
|
|
@@ -268,9 +275,9 @@ function mapSourceLineBreaks(source , normalizedLength , sourceBre
|
|
|
268
275
|
|
|
269
276
|
// A FORCED_BREAK after U+2028 or U+2029 makes the separator a hard break in every white-space
|
|
270
277
|
// mode, and a SOFT_HYPHEN_BREAK makes a soft hyphen a zero-width break: the line can end there
|
|
271
|
-
// without a hyphen
|
|
272
|
-
//
|
|
273
|
-
//
|
|
278
|
+
// without a hyphen, and Firefox, which drops soft hyphens from its text runs, has nothing there
|
|
279
|
+
// (DROPPED). One with only soft hyphens before it on its chunk stays a soft hyphen: no line ends
|
|
280
|
+
// at a chunk's start, and a line's start leaves either out.
|
|
274
281
|
function classifySegmentUnit(normalized , breaks , i , code , whiteSpace , scan ) {
|
|
275
282
|
if ((code === 0x2028 || code === 0x2029) && (breaks[i + 1] & FORCED_BREAK) !== 0) return HARD_BREAK
|
|
276
283
|
if (code === 0x00AD && (breaks[i + 1] & SOFT_HYPHEN_BREAK) !== 0 && followsChunkContent(normalized, i)) return ZERO_WIDTH_BREAK
|
|
@@ -303,7 +310,8 @@ function isControlSegmentCode(code ) {
|
|
|
303
310
|
// closing bracket, or under keep-all, is zero-width glue: it stays its own zero-width
|
|
304
311
|
// segment, takes no letter spacing and doesn't end a line.
|
|
305
312
|
// Combining marks right after it, or after a control, stay apart from the text after
|
|
306
|
-
// them,
|
|
313
|
+
// them, a segment of their own that measurement measures alone, as it does any text
|
|
314
|
+
// (ENGINE_FOLLOWUPS.md, Canvas answers that differ from the page). Where the Gecko
|
|
307
315
|
// scan marks cluster starts, a segment is ONE_CLUSTER unless one falls inside it.
|
|
308
316
|
//
|
|
309
317
|
// Firefox leaves soft hyphens and bidi controls out of the text run it breaks and maps a line end
|
|
@@ -394,6 +402,15 @@ function segmentAtLineBreaks(normalized , spaceSources
|
|
|
394
402
|
// white space ends the line: Gecko breaks only after the whole run (nsLineBreaker.cpp:
|
|
395
403
|
// 318-330). A soft hyphen before the tab keeps its break (GetHyphenationBreaks,
|
|
396
404
|
// nsTextFrame.cpp:4409-4457).
|
|
405
|
+
//
|
|
406
|
+
// No break comes between two zero-width spaces either (UAX #14 LB7), so the second is
|
|
407
|
+
// marked too: a line that goes back to its last break, as Gecko's does from a tab that
|
|
408
|
+
// doesn't fit, goes back past both, where the second would hold a line of its own (`M`,
|
|
409
|
+
// two of them, a tab and `is` in pre-wrap at 24px are three lines in Firefox 157, the
|
|
410
|
+
// tab on the second). It isn't counted in `hasUnbroken`, which takes a text off the
|
|
411
|
+
// simple walkers: the second fits wherever the first does, so no line of theirs ends
|
|
412
|
+
// between the two, and none goes back to a break from it. A soft hyphen that is a
|
|
413
|
+
// zero-width break (classifySegmentUnit) is left as it was.
|
|
397
414
|
let hasUnbroken = false
|
|
398
415
|
const count = flags.length
|
|
399
416
|
for (let j = count - 2; j >= 0; j--) {
|
|
@@ -405,6 +422,7 @@ function segmentAtLineBreaks(normalized , spaceSources
|
|
|
405
422
|
} else if (next === TEXT || next === ZERO_WIDTH_GLUE || next === CONTROL) {
|
|
406
423
|
if (kind === ZERO_WIDTH_BREAK || kind === SOFT_HYPHEN) flags[j] = flags[j] & ~KIND_BITS | ZERO_WIDTH_GLUE
|
|
407
424
|
} else {
|
|
425
|
+
if (next === ZERO_WIDTH_BREAK && kind === ZERO_WIDTH_BREAK && normalized.charCodeAt(starts[j + 1] ) === 0x200B) flags[j + 1] = flags[j + 1] | UNBROKEN
|
|
408
426
|
continue
|
|
409
427
|
}
|
|
410
428
|
flags[j + 1] = flags[j + 1] | UNBROKEN
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Pretext
|
|
1
|
+
/*! Pretext 1.0.0 + main (0d102a5cd) | MIT; BSD/Unicode/ICU notices in LICENSE | Copyright (c) 2026 Pretext contributors */
|
|
2
2
|
// Break opportunities as Firefox finds them: a port of how Gecko transforms a text node's
|
|
3
3
|
// white space, sets up its text run and breaks its words with nsLineBreaker over ICU4X's
|
|
4
4
|
// line iterator, with Firefox's baked line data and the Unicode properties Gecko reads,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Pretext
|
|
1
|
+
/*! Pretext 1.0.0 + main (0d102a5cd) | MIT; BSD/Unicode/ICU notices in LICENSE | Copyright (c) 2026 Pretext contributors */
|
|
2
2
|
// Generated by scripts/generate-engine-break-data.ts from scripts/engine-data/.
|
|
3
3
|
// Do not edit by hand. Regenerate with `bun run generate:engine-break-data`.
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Pretext
|
|
1
|
+
/*! Pretext 1.0.0 + main (0d102a5cd) | MIT; BSD/Unicode/ICU notices in LICENSE | Copyright (c) 2026 Pretext contributors */
|
|
2
2
|
// Generated by scripts/generate-webkit-generic-families.ts from scripts/engine-data/safari-27.0/.
|
|
3
3
|
// Do not edit by hand. Regenerate with `bun run generate:webkit-generic-families`.
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Pretext
|
|
1
|
+
/*! Pretext 1.0.0 + main (0d102a5cd) | MIT; BSD/Unicode/ICU notices in LICENSE | Copyright (c) 2026 Pretext contributors */
|
|
2
2
|
// Grapheme clusters as each engine's Intl.Segmenter finds them: ICU's character rules
|
|
3
3
|
// (char.brk) as Chrome and libicucore ship them, which scripts/generate-engine-break-data.ts
|
|
4
4
|
// writes to src/generated/engine-break-data.ts. Firefox's ICU4X data gives the same clusters
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Pretext
|
|
1
|
+
/*! Pretext 1.0.0 + main (0d102a5cd) | MIT; BSD/Unicode/ICU notices in LICENSE | Copyright (c) 2026 Pretext contributors */
|
|
2
2
|
// Blink's HanKerning under the default text-spacing-trim: normal (han_kerning.cc/.h,
|
|
3
3
|
// han_kerning_char_type.h and shaping_line_breaker.cc at Chrome 153). Blink halts a fullwidth
|
|
4
4
|
// opening mark after an opening, middle, closing or narrow opening mark, and a closing mark
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Pretext
|
|
1
|
+
/*! Pretext 1.0.0 + main (0d102a5cd) | MIT; BSD/Unicode/ICU notices in LICENSE | Copyright (c) 2026 Pretext contributors */
|
|
2
2
|
// Prepare text with engine segmentation rules and cached Canvas measurements, then
|
|
3
3
|
// lay it out with arithmetic. Preparation touches the DOM in three places: the emoji
|
|
4
4
|
// correction's span, read once per font where Canvas measures an emoji wider than its
|
|
@@ -131,15 +131,12 @@ function prepareInternal(
|
|
|
131
131
|
// 2. Find break opportunities with the engine's own line-break scan
|
|
132
132
|
// 3. Split the text into segments between them ("better." as one unit)
|
|
133
133
|
// 4. Measure each segment via canvas measureText, cache by (segment, font).
|
|
134
|
-
//
|
|
135
|
-
// measures after that grapheme, and WebKit measures a word with the space after it
|
|
134
|
+
// WebKit measures a word with the space after it
|
|
136
135
|
// 5. Measure where each text segment of two or more graphemes can break under
|
|
137
136
|
// overflow-wrap: break-word: by graphemes, pairs or prefixes, per engine
|
|
138
137
|
// 6. Correct emoji canvas inflation (probed once per font)
|
|
139
138
|
// 7. Record what changes at a line's edges: Blink's halts of CJK punctuation,
|
|
140
|
-
// U+3000 hangs, how much narrower a soft hyphen's neighbors measure joined
|
|
141
|
-
// fresh-line widths inside segments with invisible characters, and the
|
|
142
|
-
// characters WebKit keeps after an overflowing first one
|
|
139
|
+
// U+3000 hangs, and how much narrower a soft hyphen's neighbors measure joined
|
|
143
140
|
export function prepare(text , font , options ) {
|
|
144
141
|
return prepareInternal(text, font, false, options)
|
|
145
142
|
}
|
|
@@ -279,13 +276,16 @@ export function measureNaturalWidth(prepared ) {
|
|
|
279
276
|
return measureLineStats(prepared, Number.POSITIVE_INFINITY).maxLineWidth
|
|
280
277
|
}
|
|
281
278
|
|
|
279
|
+
// Where a line stream starts without a `start`: the text's first line.
|
|
280
|
+
const TEXT_START_CURSOR = { segmentIndex: 0, graphemeIndex: 0 }
|
|
281
|
+
|
|
282
282
|
// Steps one streamed line from `start` into the result's cursors: the
|
|
283
283
|
// normalized line start and the line end. Returns the reported width, or null
|
|
284
284
|
// after the last line.
|
|
285
285
|
function stepNextLine(
|
|
286
286
|
prepared ,
|
|
287
|
-
start ,
|
|
288
287
|
maxWidth ,
|
|
288
|
+
start ,
|
|
289
289
|
lineStart ,
|
|
290
290
|
lineEnd ,
|
|
291
291
|
) {
|
|
@@ -300,14 +300,17 @@ function stepNextLine(
|
|
|
300
300
|
return width === null ? null : Math.max(0, width)
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
+
// The line streams take the width before the cursor, as layoutNextRichInlineLineRange()
|
|
304
|
+
// does, and start at the text's first line without one: pass each line's `end` back
|
|
305
|
+
// for the next.
|
|
303
306
|
export function layoutNextLine(
|
|
304
307
|
prepared ,
|
|
305
|
-
start ,
|
|
306
308
|
maxWidth ,
|
|
309
|
+
start = TEXT_START_CURSOR,
|
|
307
310
|
) {
|
|
308
311
|
const lineStart = { segmentIndex: 0, graphemeIndex: 0 }
|
|
309
312
|
const end = { segmentIndex: 0, graphemeIndex: 0 }
|
|
310
|
-
const width = stepNextLine(prepared,
|
|
313
|
+
const width = stepNextLine(prepared, maxWidth, start, lineStart, end)
|
|
311
314
|
if (width === null) return null
|
|
312
315
|
|
|
313
316
|
const text = buildLineTextFromRange(
|
|
@@ -322,12 +325,12 @@ export function layoutNextLine(
|
|
|
322
325
|
|
|
323
326
|
export function layoutNextLineRange(
|
|
324
327
|
prepared ,
|
|
325
|
-
start ,
|
|
326
328
|
maxWidth ,
|
|
329
|
+
start = TEXT_START_CURSOR,
|
|
327
330
|
) {
|
|
328
331
|
const lineStart = { segmentIndex: 0, graphemeIndex: 0 }
|
|
329
332
|
const end = { segmentIndex: 0, graphemeIndex: 0 }
|
|
330
|
-
const width = stepNextLine(prepared,
|
|
333
|
+
const width = stepNextLine(prepared, maxWidth, start, lineStart, end)
|
|
331
334
|
return width === null ? null : { width, start: lineStart, end }
|
|
332
335
|
}
|
|
333
336
|
|