Skip to content

Commit b405b03

Browse files
authored
feat(document-api): inline formatting parity core end-to-end (#2197)
* feat(document-api): inline formatting parity core end-to-end * fix(document-api): normalize OFF toggles and re-export format helpers
1 parent 7f7ff93 commit b405b03

69 files changed

Lines changed: 4080 additions & 529 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/cli/src/__tests__/conformance/scenarios.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ export const SUCCESS_SCENARIOS = {
634634
'--target-json',
635635
JSON.stringify(target),
636636
'--inline-json',
637-
JSON.stringify({ bold: true }),
637+
JSON.stringify({ bold: 'on' }),
638638
'--out',
639639
harness.createOutputPath('doc-style-apply-output'),
640640
],

apps/cli/src/cli/helper-commands.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export const CLI_HELPER_COMMANDS: readonly CliHelperCommand[] = [
5353
{
5454
tokens: ['format', 'bold'],
5555
canonicalOperationId: 'format.apply',
56-
defaultInput: { inline: { bold: true } },
56+
defaultInput: { inline: { bold: 'on' } },
5757
description: 'Apply bold formatting to a text range.',
5858
category: 'format',
5959
mutates: true,
@@ -65,7 +65,7 @@ export const CLI_HELPER_COMMANDS: readonly CliHelperCommand[] = [
6565
{
6666
tokens: ['format', 'italic'],
6767
canonicalOperationId: 'format.apply',
68-
defaultInput: { inline: { italic: true } },
68+
defaultInput: { inline: { italic: 'on' } },
6969
description: 'Apply italic formatting to a text range.',
7070
category: 'format',
7171
mutates: true,
@@ -74,7 +74,7 @@ export const CLI_HELPER_COMMANDS: readonly CliHelperCommand[] = [
7474
{
7575
tokens: ['format', 'underline'],
7676
canonicalOperationId: 'format.apply',
77-
defaultInput: { inline: { underline: true } },
77+
defaultInput: { inline: { underline: 'on' } },
7878
description: 'Apply underline formatting to a text range.',
7979
category: 'format',
8080
mutates: true,
@@ -83,7 +83,7 @@ export const CLI_HELPER_COMMANDS: readonly CliHelperCommand[] = [
8383
{
8484
tokens: ['format', 'strikethrough'],
8585
canonicalOperationId: 'format.apply',
86-
defaultInput: { inline: { strike: true } },
86+
defaultInput: { inline: { strike: 'on' } },
8787
description: 'Apply strikethrough formatting to a text range.',
8888
category: 'format',
8989
mutates: true,

apps/cli/src/lib/operation-executor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ export async function executeOperation(request: ExecuteOperationRequest): Promis
192192
extraOptionSpecs: request.extraOptionSpecs,
193193
}),
194194
) ?? {}) as Record<string, unknown>;
195-
// Merge helper command defaults (e.g., inline: { bold: true } for `format bold`).
195+
// Merge helper command defaults (e.g., inline: { bold: 'on' } for `format bold`).
196196
// User-provided values take precedence over defaults.
197197
if (request.defaultInput) {
198198
input = { ...request.defaultInput, ...input };

apps/docs/document-api/common-workflows.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ const plan = {
7070
op: 'format.apply',
7171
where: { by: 'ref', ref },
7272
args: {
73-
marks: { bold: true },
73+
inline: { bold: 'on' },
7474
},
7575
},
7676
],
@@ -122,7 +122,7 @@ const target = { kind: 'text', blockId: 'p1', range: { start: 0, end: 3 } };
122122
if (caps.operations['format.apply'].available) {
123123
editor.doc.format.apply({
124124
target,
125-
marks: { bold: true },
125+
inline: { bold: 'on' },
126126
});
127127
}
128128

apps/docs/document-api/reference/_generated-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,5 +229,5 @@
229229
}
230230
],
231231
"marker": "{/* GENERATED FILE: DO NOT EDIT. Regenerate via `pnpm run docapi:sync`. */}",
232-
"sourceHash": "722ce545fc7c5373e23246fa7bbbc68b381e30bd8e2bc6c21d1616e6c5395ea9"
232+
"sourceHash": "5454f771b591f831325cc10903af71f01a064277b44a8c252b71855ff2b98a7d"
233233
}

apps/docs/document-api/reference/capabilities/get.mdx

Lines changed: 95 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,20 @@ _No fields._
4242
```json
4343
{
4444
"format": {
45-
"supportedMarks": [
46-
"bold"
47-
]
45+
"properties": {
46+
"bold": {
47+
"directives": [
48+
"example"
49+
],
50+
"kind": "example"
51+
},
52+
"italic": {
53+
"directives": [
54+
"example"
55+
],
56+
"kind": "example"
57+
}
58+
}
4859
},
4960
"global": {
5061
"comments": {
@@ -735,21 +746,91 @@ _No fields._
735746
"format": {
736747
"additionalProperties": false,
737748
"properties": {
738-
"supportedMarks": {
739-
"items": {
740-
"enum": [
741-
"bold",
742-
"italic",
743-
"underline",
744-
"strike"
745-
],
746-
"type": "string"
749+
"properties": {
750+
"additionalProperties": false,
751+
"properties": {
752+
"bold": {
753+
"additionalProperties": false,
754+
"properties": {
755+
"directives": {
756+
"items": {
757+
"type": "string"
758+
},
759+
"type": "array"
760+
},
761+
"kind": {
762+
"type": "string"
763+
}
764+
},
765+
"required": [
766+
"kind",
767+
"directives"
768+
],
769+
"type": "object"
770+
},
771+
"italic": {
772+
"additionalProperties": false,
773+
"properties": {
774+
"directives": {
775+
"items": {
776+
"type": "string"
777+
},
778+
"type": "array"
779+
},
780+
"kind": {
781+
"type": "string"
782+
}
783+
},
784+
"required": [
785+
"kind",
786+
"directives"
787+
],
788+
"type": "object"
789+
},
790+
"strike": {
791+
"additionalProperties": false,
792+
"properties": {
793+
"directives": {
794+
"items": {
795+
"type": "string"
796+
},
797+
"type": "array"
798+
},
799+
"kind": {
800+
"type": "string"
801+
}
802+
},
803+
"required": [
804+
"kind",
805+
"directives"
806+
],
807+
"type": "object"
808+
},
809+
"underline": {
810+
"additionalProperties": false,
811+
"properties": {
812+
"directives": {
813+
"items": {
814+
"type": "string"
815+
},
816+
"type": "array"
817+
},
818+
"kind": {
819+
"type": "string"
820+
}
821+
},
822+
"required": [
823+
"kind",
824+
"directives"
825+
],
826+
"type": "object"
827+
}
747828
},
748-
"type": "array"
829+
"type": "object"
749830
}
750831
},
751832
"required": [
752-
"supportedMarks"
833+
"properties"
753834
],
754835
"type": "object"
755836
},

apps/docs/document-api/reference/format/apply.mdx

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ description: Reference for format.apply
3030
```json
3131
{
3232
"inline": {
33-
"bold": true,
34-
"italic": true
33+
"bold": "on",
34+
"italic": "on"
3535
},
3636
"target": {
3737
"blockId": "block-abc123",
@@ -116,16 +116,32 @@ _No fields._
116116
"minProperties": 1,
117117
"properties": {
118118
"bold": {
119-
"type": "boolean"
119+
"enum": [
120+
"on",
121+
"off",
122+
"clear"
123+
]
120124
},
121125
"italic": {
122-
"type": "boolean"
126+
"enum": [
127+
"on",
128+
"off",
129+
"clear"
130+
]
123131
},
124132
"strike": {
125-
"type": "boolean"
133+
"enum": [
134+
"on",
135+
"off",
136+
"clear"
137+
]
126138
},
127139
"underline": {
128-
"type": "boolean"
140+
"enum": [
141+
"on",
142+
"off",
143+
"clear"
144+
]
129145
}
130146
},
131147
"type": "object"

apps/docs/document-api/reference/format/index.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ description: Format operation reference from the canonical Document API contract
1010
1111
[Back to full reference](../index)
1212

13-
Canonical formatting mutation with boolean patch semantics.
13+
Canonical formatting mutation with directive semantics ('on', 'off', 'clear').
1414

1515
| Operation | Member path | Mutates | Idempotency | Tracked | Dry run |
1616
| --- | --- | --- | --- | --- | --- |
@@ -25,8 +25,8 @@ Canonical formatting mutation with boolean patch semantics.
2525

2626
| Alias method | Canonical operation | Behavior |
2727
| --- | --- | --- |
28-
| `editor.doc.format.bold(...)` | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.apply</code></a></span> | Convenience alias for `format.apply` with `inline.bold: true`. |
29-
| `editor.doc.format.italic(...)` | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.apply</code></a></span> | Convenience alias for `format.apply` with `inline.italic: true`. |
30-
| `editor.doc.format.underline(...)` | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.apply</code></a></span> | Convenience alias for `format.apply` with `inline.underline: true`. |
31-
| `editor.doc.format.strikethrough(...)` | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.apply</code></a></span> | Convenience alias for `format.apply` with `inline.strike: true`. |
28+
| `editor.doc.format.bold(...)` | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.apply</code></a></span> | Convenience alias for `format.apply` with `inline.bold: 'on'`. |
29+
| `editor.doc.format.italic(...)` | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.apply</code></a></span> | Convenience alias for `format.apply` with `inline.italic: 'on'`. |
30+
| `editor.doc.format.underline(...)` | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.apply</code></a></span> | Convenience alias for `format.apply` with `inline.underline: 'on'`. |
31+
| `editor.doc.format.strikethrough(...)` | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.apply</code></a></span> | Convenience alias for `format.apply` with `inline.strike: 'on'`. |
3232

apps/docs/document-api/reference/index.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,15 @@ The tables below are grouped by namespace.
7474

7575
| Operation | API member path | Description |
7676
| --- | --- | --- |
77-
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.apply</code></a></span> | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.format.apply(...)</code></span> | Apply explicit inline style changes (bold, italic, underline, strike) to the target range using boolean patch semantics. |
77+
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.apply</code></a></span> | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.format.apply(...)</code></span> | Apply explicit inline style changes (bold, italic, underline, strike) to the target range using directive semantics ('on', 'off', 'clear'). |
7878
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/font-size"><code>format.fontSize</code></a></span> | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.format.fontSize(...)</code></span> | Set or unset the font size on the target text range. Pass null to remove. |
7979
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/font-family"><code>format.fontFamily</code></a></span> | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.format.fontFamily(...)</code></span> | Set or unset the font family on the target text range. Pass null to remove. |
8080
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/color"><code>format.color</code></a></span> | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.format.color(...)</code></span> | Set or unset the text color on the target text range. Pass null to remove. |
8181
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/align"><code>format.align</code></a></span> | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.format.align(...)</code></span> | Set or unset paragraph alignment on the block containing the target. Pass null to reset to default. |
82-
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.bold</code></a></span> | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.format.bold(...)</code></span> | Convenience alias for `format.apply` with `inline.bold: true`. |
83-
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.italic</code></a></span> | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.format.italic(...)</code></span> | Convenience alias for `format.apply` with `inline.italic: true`. |
84-
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.underline</code></a></span> | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.format.underline(...)</code></span> | Convenience alias for `format.apply` with `inline.underline: true`. |
85-
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.strikethrough</code></a></span> | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.format.strikethrough(...)</code></span> | Convenience alias for `format.apply` with `inline.strike: true`. |
82+
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.bold</code></a></span> | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.format.bold(...)</code></span> | Convenience alias for `format.apply` with `inline.bold: 'on'`. |
83+
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.italic</code></a></span> | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.format.italic(...)</code></span> | Convenience alias for `format.apply` with `inline.italic: 'on'`. |
84+
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.underline</code></a></span> | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.format.underline(...)</code></span> | Convenience alias for `format.apply` with `inline.underline: 'on'`. |
85+
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><a href="/document-api/reference/format/apply"><code>format.strikethrough</code></a></span> | <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.format.strikethrough(...)</code></span> | Convenience alias for `format.apply` with `inline.strike: 'on'`. |
8686

8787
#### Styles
8888

apps/docs/document-api/reference/query/match.mdx

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ description: Reference for query.match
5555
| --- | --- | --- | --- |
5656
| `evaluatedRevision` | string | yes | |
5757
| `items` | object(matchKind="text") \\| object(matchKind="node")[] | yes | |
58+
| `meta` | object | yes | |
5859
| `page` | PageInfo | yes | PageInfo |
5960
| `total` | integer | yes | |
6061

@@ -92,12 +93,20 @@ description: Reference for query.match
9293
"ref": "handle:abc123",
9394
"styleId": "style-001",
9495
"styles": {
95-
"bold": true,
9696
"color": "example",
97-
"highlight": "example",
98-
"italic": true,
99-
"strike": true,
100-
"underline": true
97+
"direct": {
98+
"bold": "on",
99+
"italic": "on",
100+
"strike": "on",
101+
"underline": "on"
102+
},
103+
"effective": {
104+
"bold": true,
105+
"italic": true,
106+
"strike": true,
107+
"underline": true
108+
},
109+
"highlight": "example"
101110
},
102111
"text": "Hello, world."
103112
}
@@ -119,6 +128,9 @@ description: Reference for query.match
119128
"snippet": "...the quick brown fox..."
120129
}
121130
],
131+
"meta": {
132+
"effectiveResolved": true
133+
},
122134
"page": {
123135
"limit": 50,
124136
"offset": 0,
@@ -336,6 +348,18 @@ description: Reference for query.match
336348
},
337349
"type": "array"
338350
},
351+
"meta": {
352+
"additionalProperties": false,
353+
"properties": {
354+
"effectiveResolved": {
355+
"type": "boolean"
356+
}
357+
},
358+
"required": [
359+
"effectiveResolved"
360+
],
361+
"type": "object"
362+
},
339363
"page": {
340364
"$ref": "#/$defs/PageInfo"
341365
},
@@ -348,7 +372,8 @@ description: Reference for query.match
348372
"evaluatedRevision",
349373
"total",
350374
"items",
351-
"page"
375+
"page",
376+
"meta"
352377
],
353378
"type": "object"
354379
}

0 commit comments

Comments
 (0)