rapier-markdown-kit 1.1.0
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/LICENSE +40 -0
- package/README.md +102 -0
- package/dist/agent/vendor/pretext/LICENSE +21 -0
- package/dist/agent/vendor/pretext/NOTICE +15 -0
- package/dist/agent/vendor/pretext/SOURCE.json +85 -0
- package/dist/agent/vendor/pretext/analysis.js +1234 -0
- package/dist/agent/vendor/pretext/bidi.js +151 -0
- package/dist/agent/vendor/pretext/generated/bidi-data.js +3831 -0
- package/dist/agent/vendor/pretext/layout.js +308 -0
- package/dist/agent/vendor/pretext/line-break.js +636 -0
- package/dist/agent/vendor/pretext/line-text.js +44 -0
- package/dist/agent/vendor/pretext/measurement.js +189 -0
- package/dist/agent/vendor/pretext/package.json +3 -0
- package/dist/agent/vendor/pretext/rich-inline.js +291 -0
- package/dist/agent/will.mjs +167 -0
- package/dist/kit/assets.mjs +3 -0
- package/dist/kit/conformance/01-inline.expected.json +82 -0
- package/dist/kit/conformance/01-inline.md +10 -0
- package/dist/kit/conformance/02-width-x-align.expected.json +83 -0
- package/dist/kit/conformance/02-width-x-align.md +12 -0
- package/dist/kit/conformance/03-wrap-around-silhouette.expected.json +177 -0
- package/dist/kit/conformance/03-wrap-around-silhouette.md +12 -0
- package/dist/kit/conformance/04-wrap-box.expected.json +173 -0
- package/dist/kit/conformance/04-wrap-box.md +12 -0
- package/dist/kit/conformance/05-behind.expected.json +122 -0
- package/dist/kit/conformance/05-behind.md +12 -0
- package/dist/kit/conformance/06-front.expected.json +122 -0
- package/dist/kit/conformance/06-front.md +12 -0
- package/dist/kit/conformance/07-rotate-raster.expected.json +179 -0
- package/dist/kit/conformance/07-rotate-raster.md +12 -0
- package/dist/kit/conformance/08-drawing-rotation.expected.json +188 -0
- package/dist/kit/conformance/08-drawing-rotation.md +12 -0
- package/dist/kit/conformance/09-drawing-ring-interior.expected.json +229 -0
- package/dist/kit/conformance/09-drawing-ring-interior.md +12 -0
- package/dist/kit/conformance/10-both-sides.expected.json +221 -0
- package/dist/kit/conformance/10-both-sides.md +10 -0
- package/dist/kit/conformance/11-neighbour-skips-image.expected.json +160 -0
- package/dist/kit/conformance/11-neighbour-skips-image.md +13 -0
- package/dist/kit/conformance/12-heading-barrier.expected.json +164 -0
- package/dist/kit/conformance/12-heading-barrier.md +12 -0
- package/dist/kit/conformance/13-rtl-text.expected.json +179 -0
- package/dist/kit/conformance/13-rtl-text.md +8 -0
- package/dist/kit/conformance/README.md +99 -0
- package/dist/kit/conformance/measurer.mjs +0 -0
- package/dist/kit/conformance/run.mjs +123 -0
- package/dist/kit/index.mjs +6 -0
- package/dist/kit/layout.mjs +2 -0
- package/dist/kit/marks.mjs +2 -0
- package/dist/kit/model.mjs +3 -0
- package/dist/kit/will.mjs +2 -0
- package/dist/layout/model.mjs +364 -0
- package/dist/spec/md-assets.mjs +323 -0
- package/dist/spec/md-layout.mjs +117 -0
- package/dist/spec/md-marks.mjs +78 -0
- package/package.json +33 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jack Skipworth
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
Files under this licence carry `SPDX-License-Identifier: MIT` in their first lines: the standard's
|
|
24
|
+
grammar and marks (`spec/md-layout.mjs`, `spec/md-marks.mjs`), the layout model and line planner
|
|
25
|
+
(`layout/model.mjs`), the Will grammar (`agent/will.mjs`), the picture appendix reader and writer
|
|
26
|
+
(`spec/md-assets.mjs`), the two shared-page reference readers (`tools/read-shared-page.mjs`,
|
|
27
|
+
`tools/read-shared-page.py`), and the host helper `packages/rapier-embed/embed.mjs`. The vendored Pretext (`agent/vendor/pretext`) and micromark carry their
|
|
28
|
+
own MIT notices. Everything else in Rapier is AGPL-3.0-only (see `LICENSE`).
|
|
29
|
+
|
|
30
|
+
The picture appendix reader and writer used to be part of `images/assets.mjs`, a file that also
|
|
31
|
+
holds JPEG XL/raster header inspection and SVG sanitizing -- both of which reach the editor's own
|
|
32
|
+
AGPL-3.0-only decoders (`images/raster.mjs`, `draw/font.mjs`), so the whole file could not honestly
|
|
33
|
+
sit in this list. The appendix logic (`parseAssets`, `documentAssets`, `imageEnvironment`,
|
|
34
|
+
`mayRetireImageDefinitions`, `retireDeletedImageDefinitions`, `assetOmissions`, `isAssetBlock`,
|
|
35
|
+
`serializeAsset`, `appendAssetText`, `appendAsset`, and the small markdown-it plumbing they share)
|
|
36
|
+
depends on nothing but a markdown-it factory, so it lives in `spec/md-assets.mjs`; `images/assets.mjs`
|
|
37
|
+
re-imports and re-exports that surface unchanged (one owner, no copy) and keeps everything that
|
|
38
|
+
needs the AGPL decoders, so it is AGPL-3.0-only like the rest of the editor. The `rapier-markdown-kit`
|
|
39
|
+
package re-exports `spec/md-assets.mjs` directly, never `images/assets.mjs`, so its import graph
|
|
40
|
+
never touches AGPL code.
|
package/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# rapier-markdown-kit
|
|
2
|
+
|
|
3
|
+
Read and write the Rapier Markdown standard -- picture layout, text marks, Will intent markers and
|
|
4
|
+
the picture appendix -- and lay text out around pictures exactly as Rapier does, without taking the
|
|
5
|
+
Rapier editor.
|
|
6
|
+
|
|
7
|
+
**MIT. No Rapier required. No npm dependencies.** The text layout engine it uses, Pretext, is
|
|
8
|
+
vendored inside the package with its own MIT licence. Nothing from the editor, Draw, the image
|
|
9
|
+
decoders or the apps is in here.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
Node 22 or newer:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
npm install rapier-markdown-kit
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## What it gives you
|
|
20
|
+
|
|
21
|
+
| Import | What it is |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| `rapier-markdown-kit/layout` | The `md-layout:v1` comment a picture carries: parse it, validate it, write it back. |
|
|
24
|
+
| `rapier-markdown-kit/marks` | Text colour and page-break markers. |
|
|
25
|
+
| `rapier-markdown-kit/model` | Occupancy profiles and the line planner: the wrapping itself. |
|
|
26
|
+
| `rapier-markdown-kit/will` | The Will/1 grammar (a separate, optional standard): the markers around an agent's intent regions. |
|
|
27
|
+
| `rapier-markdown-kit/assets` | The picture appendix: the reference definitions a document's pictures live in. It never decodes a picture. |
|
|
28
|
+
| `rapier-markdown-kit` | All five in one import. |
|
|
29
|
+
|
|
30
|
+
Every convention here is plain Markdown or an HTML comment that other readers ignore. Laying lines
|
|
31
|
+
out exactly as Rapier does also takes the same font metrics, which the host supplies (below).
|
|
32
|
+
|
|
33
|
+
## Example
|
|
34
|
+
|
|
35
|
+
Save this as `example.mjs` in the folder you installed into and run `node example.mjs`. It prints
|
|
36
|
+
`lines: 4 height: 80`.
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
import {parseLayout} from 'rapier-markdown-kit/layout';
|
|
40
|
+
import {parseProfile, pictureSlices, prepareRun, flowLines, prepareRichInline} from 'rapier-markdown-kit/model';
|
|
41
|
+
const {loadDocuments, installMeasurer} = await import(new URL(
|
|
42
|
+
'./dist/kit/conformance/measurer.mjs', import.meta.resolve('rapier-markdown-kit/package.json')));
|
|
43
|
+
|
|
44
|
+
// Text metrics: the widths the conformance documents recorded in Rapier's own browser, standing in
|
|
45
|
+
// for a font shaper so the example runs anywhere (see "What the host supplies").
|
|
46
|
+
installMeasurer(loadDocuments());
|
|
47
|
+
|
|
48
|
+
// 1. Parse the layout comment a picture carries.
|
|
49
|
+
const layout = parseLayout('<!--md-layout:v1 width=40% wrap=around x=25%-->');
|
|
50
|
+
// => {width: 40, wrap: 'around', x: 25}
|
|
51
|
+
|
|
52
|
+
// 2. The picture's shape: the occupancy descriptor Rapier's exports carry beside a picture
|
|
53
|
+
// (`data-rapier-occupancy`, one left-right pair per horizontal band), placed as obstacles.
|
|
54
|
+
const profile = parseProfile('0.1-0.9|0.2-0.8|0.3-0.7');
|
|
55
|
+
const obstacles = pictureSlices(profile, /* x */ 0, /* y */ 0, /* width */ 120, /* height */ 90);
|
|
56
|
+
|
|
57
|
+
// 3. Plan the lines of a paragraph around those obstacles.
|
|
58
|
+
const text = 'This anchor paragraph carries enough ordinary prose', font = 'normal 400 17.6px Geist, system-ui, sans-serif';
|
|
59
|
+
const run = prepareRun(text, font);
|
|
60
|
+
const flow = prepareRichInline([{text: run.raw, font, letterSpacing: 0}]);
|
|
61
|
+
const plan = flowLines(flow, /* column width */ 300, /* top */ 0, obstacles, /* line height */ 20, /* min slot */ 40);
|
|
62
|
+
// Each line carries its own x, y and width, and the text fragments laid into it.
|
|
63
|
+
console.log('lines:', plan.lines.length, 'height:', plan.height); // lines: 4 height: 80
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## What the host supplies
|
|
67
|
+
|
|
68
|
+
`prepareRun` and `prepareRichInline` measure text the way a browser does: they need a global
|
|
69
|
+
`OffscreenCanvas` (or a DOM `document`) whose `getContext('2d')` has a settable `font` and a
|
|
70
|
+
`measureText(text)` returning `{width}`. A browser has one already; in Node, put those two members
|
|
71
|
+
in front of whatever shaper you have. The example replays recorded measurements instead, and a
|
|
72
|
+
query they never recorded falls back to summing single characters, without kerning or shaping.
|
|
73
|
+
|
|
74
|
+
`alphaProfile(image)` samples a decoded `<img>` through a canvas, so it needs a browser. Without
|
|
75
|
+
one, read the saved descriptor with `parseProfile`, or sample the picture with your own image
|
|
76
|
+
library. `polygonProfile` and `rasterTiltProfile` are plain geometry.
|
|
77
|
+
|
|
78
|
+
The appendix parser takes a markdown-it-compatible parser factory from the caller
|
|
79
|
+
(`parseAssets(source, factory)`, or once through `configureParser`); no parser is bundled.
|
|
80
|
+
|
|
81
|
+
## Conformance
|
|
82
|
+
|
|
83
|
+
```sh
|
|
84
|
+
node node_modules/rapier-markdown-kit/dist/kit/conformance/run.mjs
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Thirteen small documents, each with the line boxes Rapier's own export produced for it. The runner
|
|
88
|
+
reports two things separately. **Preservation**: every layout comment round-trips exactly (12 of
|
|
89
|
+
the 12 documents that carry one). **Presentation**: how closely the planned lines match (4 agree
|
|
90
|
+
within 2px, 9 are close, none differ); each close row has a named cause, given in the runner's
|
|
91
|
+
output and in `dist/kit/conformance/README.md`. `--impl path/to/module.mjs` runs another
|
|
92
|
+
implementation against the same documents; `--tolerance 2` sets the pixel tolerance.
|
|
93
|
+
|
|
94
|
+
## Licence
|
|
95
|
+
|
|
96
|
+
MIT, the full text in `LICENSE`; every module keeps its own MIT line. Pretext's licence, notice and
|
|
97
|
+
pinned source inventory are in `dist/agent/vendor/pretext/`. The Rapier editor is AGPL-3.0-only and
|
|
98
|
+
none of it is in this package. The kit's version is its own and does not follow the editor's.
|
|
99
|
+
|
|
100
|
+
## Where the modules live
|
|
101
|
+
|
|
102
|
+
Each module of the standard has one home in the Rapier source (`spec/`, `layout/`, `agent/`), where Rapier itself reads it; `dist/` is that closure copied byte for byte, so an installed copy needs nothing beside it.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pretext contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Pretext 0.0.9
|
|
2
|
+
Copyright (c) 2026 Pretext contributors
|
|
3
|
+
https://github.com/chenglou/pretext
|
|
4
|
+
MIT license: see LICENSE.
|
|
5
|
+
|
|
6
|
+
Vendored from the user-supplied pretext-main source snapshot.
|
|
7
|
+
SOURCE.json records every original and generated module hash.
|
|
8
|
+
Node's built-in TypeScript transform generated these ESM modules;
|
|
9
|
+
the upstream runtime implementation is unchanged.
|
|
10
|
+
|
|
11
|
+
Upstream README credits Sebastian Markbage's text-layout research:
|
|
12
|
+
canvas measureText for shaping, bidi from pdf.js, and streaming line breaking.
|
|
13
|
+
Upstream src/bidi.ts identifies its simplified bidi metadata helper as
|
|
14
|
+
forked from pdf.js through Sebastian's text-layout. This provenance applies
|
|
15
|
+
to the generated bidi.js module as well.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"package": "@chenglou/pretext",
|
|
3
|
+
"version": "0.0.9",
|
|
4
|
+
"releaseDate": "2026-09-07",
|
|
5
|
+
"repository": "https://github.com/chenglou/pretext",
|
|
6
|
+
"sourceSnapshot": "User-supplied pretext-main archive; no commit identifier included",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"licenseSha256": "e9355cb16457e81acd97dac2e50f2f8bbf2a9a464025f9c46db3680cf9598846",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": "./layout.js",
|
|
11
|
+
"./rich-inline": "./rich-inline.js"
|
|
12
|
+
},
|
|
13
|
+
"compiler": {
|
|
14
|
+
"runtime": "v24.19.0",
|
|
15
|
+
"api": "node:module.stripTypeScriptTypes",
|
|
16
|
+
"mode": "transform"
|
|
17
|
+
},
|
|
18
|
+
"changes": "TypeScript erased by the Node built-in transform; attribution header added. Runtime semantics and module imports preserved.",
|
|
19
|
+
"files": [
|
|
20
|
+
{
|
|
21
|
+
"source": "src/analysis.ts",
|
|
22
|
+
"sourceBytes": 47015,
|
|
23
|
+
"sourceSha256": "45d06ff67f5e7c8334fd3188bc6e3d13c582c36714cbf584aca5c4280587f571",
|
|
24
|
+
"output": "analysis.js",
|
|
25
|
+
"outputBytes": 44912,
|
|
26
|
+
"outputSha256": "68f7c705892b03c6b2e93b5f86ec4216231246607aac11c2dab98ed06f0f602b"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"source": "src/bidi.ts",
|
|
30
|
+
"sourceBytes": 6034,
|
|
31
|
+
"sourceSha256": "70f7f01dcd866076b68dbf2a3c398364aceaba2ccf98037e77e0b3b8bcfbeaa5",
|
|
32
|
+
"output": "bidi.js",
|
|
33
|
+
"outputBytes": 5176,
|
|
34
|
+
"outputSha256": "f69a132df81d5ad666bd35a295e10bf2549f8f0bc6470ab37fe361eafd0162b5"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"source": "src/generated/bidi-data.ts",
|
|
38
|
+
"sourceBytes": 21681,
|
|
39
|
+
"sourceSha256": "745211b804d907af78afb6c1ed87eff6d7454a5e85152a6129eb7b3bf0f6f262",
|
|
40
|
+
"output": "generated/bidi-data.js",
|
|
41
|
+
"outputBytes": 44541,
|
|
42
|
+
"outputSha256": "2f3fd15a0dbc1df87fefc53e23d261419b392feab32e1288a3d7d568cd368fea"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"source": "src/layout.ts",
|
|
46
|
+
"sourceBytes": 22096,
|
|
47
|
+
"sourceSha256": "2b44bcc39ecf287de621d40dbc443815cf2faa8c976a98de8a02f1639b782b9d",
|
|
48
|
+
"output": "layout.js",
|
|
49
|
+
"outputBytes": 13886,
|
|
50
|
+
"outputSha256": "ed52968b68a8d7fb3726333ff522f41f10a779d2c072ba05eb9aa841a6daf469"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"source": "src/line-break.ts",
|
|
54
|
+
"sourceBytes": 30545,
|
|
55
|
+
"sourceSha256": "f226213c179d65adea48b849040719349c8c3928519348d03d38b7b41f344796",
|
|
56
|
+
"output": "line-break.js",
|
|
57
|
+
"outputBytes": 29515,
|
|
58
|
+
"outputSha256": "30d83886d6e681fec3da72073749d14f7d01e5371cc907554596782df9c3de7c"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"source": "src/line-text.ts",
|
|
62
|
+
"sourceBytes": 2234,
|
|
63
|
+
"sourceSha256": "5e21684d995df8c30324c03a14b8a0bc3a579ce169a0e10b6d579b6aeee577dc",
|
|
64
|
+
"output": "line-text.js",
|
|
65
|
+
"outputBytes": 1994,
|
|
66
|
+
"outputSha256": "d7485c43086420e37418b68a49bf42acc45c13a6045d170eecbf37df4738a03c"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"source": "src/measurement.ts",
|
|
70
|
+
"sourceBytes": 8430,
|
|
71
|
+
"sourceSha256": "7768e0452c9dcc027182a3ed8131ed4a26d1d6099c9642ed93389a1c52342b01",
|
|
72
|
+
"output": "measurement.js",
|
|
73
|
+
"outputBytes": 7468,
|
|
74
|
+
"outputSha256": "58d8827d10367319d667c54056ef1200b0850a4ef6d298eaad486217cc84277e"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"source": "src/rich-inline.ts",
|
|
78
|
+
"sourceBytes": 15398,
|
|
79
|
+
"sourceSha256": "5a7e5d339e1f703d52928913e3b7d6a5f5df04bdfdd365f47c1890dde3b61964",
|
|
80
|
+
"output": "rich-inline.js",
|
|
81
|
+
"outputBytes": 11352,
|
|
82
|
+
"outputSha256": "60b7d96428236a8f12f7d6fdbd7d402c8c3b39e4da9cd4bf83b1d3dee27a7418"
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
}
|