weml-monaco 0.3.2 → 0.3.3
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/CHANGELOG.md +97 -97
- package/README.md +139 -139
- package/dist/weml-monaco.esm.js.map +1 -1
- package/dist/weml-monaco.js.map +1 -1
- package/package.json +43 -42
package/CHANGELOG.md
CHANGED
|
@@ -1,97 +1,97 @@
|
|
|
1
|
-
# Changelog — WEML Monaco
|
|
2
|
-
|
|
3
|
-
All notable changes to the **Monaco** contribution (`weml-monaco`) are documented
|
|
4
|
-
here. The format is based on [Keep a Changelog](https://keepachangelog.com/), and
|
|
5
|
-
this project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
|
-
|
|
7
|
-
This package mirrors the language logic of the VS Code extension; entries below
|
|
8
|
-
track the port catching up with the VS Code provider changes (see the root
|
|
9
|
-
`CHANGELOG.md` for the extension).
|
|
10
|
-
|
|
11
|
-
## [0.3.2] — 2026-08-13
|
|
12
|
-
|
|
13
|
-
Synced with VS Code extension `0.7.7`.
|
|
14
|
-
|
|
15
|
-
### Fixed
|
|
16
|
-
- Switched canonical formatting to the safe V2 normalizer. Structurally invalid
|
|
17
|
-
input now produces a typed validation failure and no model edit instead of a
|
|
18
|
-
replacement containing an empty `<body>`.
|
|
19
|
-
- The HTML/pretty half of the format cycle remains usable after canonical
|
|
20
|
-
formatting is rejected, allowing users to repair invalid documents safely.
|
|
21
|
-
- Added browser/Monaco regressions for unclosed WEML containers, lists, tables,
|
|
22
|
-
inline elements and half-typed tags.
|
|
23
|
-
|
|
24
|
-
## [0.3.1] — 2026-08-12
|
|
25
|
-
|
|
26
|
-
Synced with VS Code extension `0.7.6`.
|
|
27
|
-
|
|
28
|
-
### Fixed
|
|
29
|
-
- **Canonical formatting of void HTML elements is more robust.** Known void
|
|
30
|
-
tags are normalized before parsing, preventing earlier non-self-closing tags
|
|
31
|
-
from corrupting later markup.
|
|
32
|
-
- **Inline whitespace handling now respects element boundaries and comments.**
|
|
33
|
-
Edge-space bleeding uses parser-compatible sibling insertion and stops at
|
|
34
|
-
block or void elements instead of crossing structural boundaries.
|
|
35
|
-
|
|
36
|
-
## [0.3.0] — 2026-07-01
|
|
37
|
-
|
|
38
|
-
Ports the VS Code extension's toolbar and editor commands to Monaco.
|
|
39
|
-
|
|
40
|
-
### Added
|
|
41
|
-
- **WEML toolbar** (`createWemlToolbar(monaco, editor, options)`) — a DOM top
|
|
42
|
-
panel with the same controls as the VS Code toolbar webview: a (stub) search
|
|
43
|
-
row, a "wrap selection" dropdown (`w-format` per text-formatting value, plus
|
|
44
|
-
`w-lang`, `w-non-egw`, `w-entity`, `a`), snippet buttons (`w-para`,
|
|
45
|
-
`w-heading`, `w-note`, `table`, `list`, `figure`) and "Renumber div ids (1…n)".
|
|
46
|
-
Mount it anywhere around the editor.
|
|
47
|
-
- **Editor actions / keybindings** (`registerWemlEditorActions`, also wired by
|
|
48
|
-
the toolbar): `Ctrl+B` / `Ctrl+I` / `Ctrl+U` wrap the selection in
|
|
49
|
-
`<w-format type="bold|italic|underline">`, `Alt+Shift+F` cycles the document
|
|
50
|
-
between HTML and canonical WEML formatting, plus a "Renumber <div> ids"
|
|
51
|
-
action. All are available in the command palette.
|
|
52
|
-
- Exposed the underlying operations (`wrapSelection`, `insertSnippetById`,
|
|
53
|
-
`renumberDivIds`, `cycleFormat`) and pure helpers (`planDivIdRenumber`,
|
|
54
|
-
`buildWrapSnippet`) for host/toolbar reuse and testing.
|
|
55
|
-
|
|
56
|
-
`planDivIdRenumber`/`buildWrapSnippet` are kept byte-identical to the VS Code
|
|
57
|
-
extension's `src/toolbar/*`; snippet insertion uses Monaco's `snippetController2`
|
|
58
|
-
so `$1`/`$2` tab stops behave like `editor.insertSnippet` in VS Code.
|
|
59
|
-
|
|
60
|
-
## [0.2.1] — 2026-06-20
|
|
61
|
-
|
|
62
|
-
Synced with VS Code extension `0.7.4`.
|
|
63
|
-
|
|
64
|
-
### Added
|
|
65
|
-
- **Hover tooltips for HTML character references (entities)** — named
|
|
66
|
-
(`—`, `'`, …), decimal (`—`) and hexadecimal (`—`)
|
|
67
|
-
references show name, rendered character and Unicode code point, in text and
|
|
68
|
-
inside attribute values.
|
|
69
|
-
- **Entity autocomplete** — typing `&` in text content or an attribute value
|
|
70
|
-
suggests named character references.
|
|
71
|
-
|
|
72
|
-
## [0.2.0] — 2026-06-20
|
|
73
|
-
|
|
74
|
-
Synced the completion/hover providers with VS Code extension `0.7.3`.
|
|
75
|
-
|
|
76
|
-
### Changed
|
|
77
|
-
- Completion is **strict and structure-aware**: only the tags allowed at the current
|
|
78
|
-
structural position are offered, with no generic HTML fallback noise in plain text.
|
|
79
|
-
- Tag completion inserts **only the opening tag** (e.g. `<w-format type="$1">`) — no
|
|
80
|
-
child scaffold or line breaks.
|
|
81
|
-
- Attribute-name completion inserts `name=""` and re-triggers the suggest widget
|
|
82
|
-
(`editor.action.triggerSuggest`) when the attribute has known values.
|
|
83
|
-
|
|
84
|
-
### Fixed
|
|
85
|
-
- Typing a tag name after `<` (e.g. `<w`) no longer empties the suggestion list:
|
|
86
|
-
items carry a `<`-aware `filterText`. Same fix for closing tags after `</`.
|
|
87
|
-
- Half-typed `<w-` elements are no longer mistaken for their own parent, so the
|
|
88
|
-
structural tag list is offered correctly.
|
|
89
|
-
- Closing tags after `</` are suggested explicitly based on the nearest open element.
|
|
90
|
-
- Removed the (now unused) plain-text node hover.
|
|
91
|
-
|
|
92
|
-
## [0.1.x] — initial port
|
|
93
|
-
|
|
94
|
-
Initial Monaco port of the WEML language support: language registration + Monarch
|
|
95
|
-
tokenizer, autocomplete, hover docs, structure diagnostics, document outline and
|
|
96
|
-
canonical formatting, plus a CDN demo and a smoke test. Parsing reuses
|
|
97
|
-
`vscode-html-languageservice`; Monaco is passed into `registerWeml(monaco)`.
|
|
1
|
+
# Changelog — WEML Monaco
|
|
2
|
+
|
|
3
|
+
All notable changes to the **Monaco** contribution (`weml-monaco`) are documented
|
|
4
|
+
here. The format is based on [Keep a Changelog](https://keepachangelog.com/), and
|
|
5
|
+
this project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
This package mirrors the language logic of the VS Code extension; entries below
|
|
8
|
+
track the port catching up with the VS Code provider changes (see the root
|
|
9
|
+
`CHANGELOG.md` for the extension).
|
|
10
|
+
|
|
11
|
+
## [0.3.2] — 2026-08-13
|
|
12
|
+
|
|
13
|
+
Synced with VS Code extension `0.7.7`.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- Switched canonical formatting to the safe V2 normalizer. Structurally invalid
|
|
17
|
+
input now produces a typed validation failure and no model edit instead of a
|
|
18
|
+
replacement containing an empty `<body>`.
|
|
19
|
+
- The HTML/pretty half of the format cycle remains usable after canonical
|
|
20
|
+
formatting is rejected, allowing users to repair invalid documents safely.
|
|
21
|
+
- Added browser/Monaco regressions for unclosed WEML containers, lists, tables,
|
|
22
|
+
inline elements and half-typed tags.
|
|
23
|
+
|
|
24
|
+
## [0.3.1] — 2026-08-12
|
|
25
|
+
|
|
26
|
+
Synced with VS Code extension `0.7.6`.
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
- **Canonical formatting of void HTML elements is more robust.** Known void
|
|
30
|
+
tags are normalized before parsing, preventing earlier non-self-closing tags
|
|
31
|
+
from corrupting later markup.
|
|
32
|
+
- **Inline whitespace handling now respects element boundaries and comments.**
|
|
33
|
+
Edge-space bleeding uses parser-compatible sibling insertion and stops at
|
|
34
|
+
block or void elements instead of crossing structural boundaries.
|
|
35
|
+
|
|
36
|
+
## [0.3.0] — 2026-07-01
|
|
37
|
+
|
|
38
|
+
Ports the VS Code extension's toolbar and editor commands to Monaco.
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
- **WEML toolbar** (`createWemlToolbar(monaco, editor, options)`) — a DOM top
|
|
42
|
+
panel with the same controls as the VS Code toolbar webview: a (stub) search
|
|
43
|
+
row, a "wrap selection" dropdown (`w-format` per text-formatting value, plus
|
|
44
|
+
`w-lang`, `w-non-egw`, `w-entity`, `a`), snippet buttons (`w-para`,
|
|
45
|
+
`w-heading`, `w-note`, `table`, `list`, `figure`) and "Renumber div ids (1…n)".
|
|
46
|
+
Mount it anywhere around the editor.
|
|
47
|
+
- **Editor actions / keybindings** (`registerWemlEditorActions`, also wired by
|
|
48
|
+
the toolbar): `Ctrl+B` / `Ctrl+I` / `Ctrl+U` wrap the selection in
|
|
49
|
+
`<w-format type="bold|italic|underline">`, `Alt+Shift+F` cycles the document
|
|
50
|
+
between HTML and canonical WEML formatting, plus a "Renumber <div> ids"
|
|
51
|
+
action. All are available in the command palette.
|
|
52
|
+
- Exposed the underlying operations (`wrapSelection`, `insertSnippetById`,
|
|
53
|
+
`renumberDivIds`, `cycleFormat`) and pure helpers (`planDivIdRenumber`,
|
|
54
|
+
`buildWrapSnippet`) for host/toolbar reuse and testing.
|
|
55
|
+
|
|
56
|
+
`planDivIdRenumber`/`buildWrapSnippet` are kept byte-identical to the VS Code
|
|
57
|
+
extension's `src/toolbar/*`; snippet insertion uses Monaco's `snippetController2`
|
|
58
|
+
so `$1`/`$2` tab stops behave like `editor.insertSnippet` in VS Code.
|
|
59
|
+
|
|
60
|
+
## [0.2.1] — 2026-06-20
|
|
61
|
+
|
|
62
|
+
Synced with VS Code extension `0.7.4`.
|
|
63
|
+
|
|
64
|
+
### Added
|
|
65
|
+
- **Hover tooltips for HTML character references (entities)** — named
|
|
66
|
+
(`—`, `'`, …), decimal (`—`) and hexadecimal (`—`)
|
|
67
|
+
references show name, rendered character and Unicode code point, in text and
|
|
68
|
+
inside attribute values.
|
|
69
|
+
- **Entity autocomplete** — typing `&` in text content or an attribute value
|
|
70
|
+
suggests named character references.
|
|
71
|
+
|
|
72
|
+
## [0.2.0] — 2026-06-20
|
|
73
|
+
|
|
74
|
+
Synced the completion/hover providers with VS Code extension `0.7.3`.
|
|
75
|
+
|
|
76
|
+
### Changed
|
|
77
|
+
- Completion is **strict and structure-aware**: only the tags allowed at the current
|
|
78
|
+
structural position are offered, with no generic HTML fallback noise in plain text.
|
|
79
|
+
- Tag completion inserts **only the opening tag** (e.g. `<w-format type="$1">`) — no
|
|
80
|
+
child scaffold or line breaks.
|
|
81
|
+
- Attribute-name completion inserts `name=""` and re-triggers the suggest widget
|
|
82
|
+
(`editor.action.triggerSuggest`) when the attribute has known values.
|
|
83
|
+
|
|
84
|
+
### Fixed
|
|
85
|
+
- Typing a tag name after `<` (e.g. `<w`) no longer empties the suggestion list:
|
|
86
|
+
items carry a `<`-aware `filterText`. Same fix for closing tags after `</`.
|
|
87
|
+
- Half-typed `<w-` elements are no longer mistaken for their own parent, so the
|
|
88
|
+
structural tag list is offered correctly.
|
|
89
|
+
- Closing tags after `</` are suggested explicitly based on the nearest open element.
|
|
90
|
+
- Removed the (now unused) plain-text node hover.
|
|
91
|
+
|
|
92
|
+
## [0.1.x] — initial port
|
|
93
|
+
|
|
94
|
+
Initial Monaco port of the WEML language support: language registration + Monarch
|
|
95
|
+
tokenizer, autocomplete, hover docs, structure diagnostics, document outline and
|
|
96
|
+
canonical formatting, plus a CDN demo and a smoke test. Parsing reuses
|
|
97
|
+
`vscode-html-languageservice`; Monaco is passed into `registerWeml(monaco)`.
|
package/README.md
CHANGED
|
@@ -1,139 +1,139 @@
|
|
|
1
|
-
# WEML language support for Monaco
|
|
2
|
-
|
|
3
|
-
A Monaco-editor port of the WEML (White Estate Markup Language) VS Code
|
|
4
|
-
extension. It provides, for models with language id `weml`:
|
|
5
|
-
|
|
6
|
-
- **Syntax highlighting** — a Monarch tokenizer (HTML-flavoured, since WEML is
|
|
7
|
-
HTML5-compatible).
|
|
8
|
-
- **Context-aware autocomplete** — tags / attributes / attribute values that
|
|
9
|
-
respect the WEML nesting rules, with element-scaffolding snippets and
|
|
10
|
-
composite snippets (`table`, `w-list`, `figure`, `div + w-heading`, …).
|
|
11
|
-
- **Hover tooltips** — documentation generated from `docs/` (tags, attributes,
|
|
12
|
-
enum values, `meta` fields, `<a href>` link types).
|
|
13
|
-
- **Structure diagnostics** — unknown tags/attributes, required attributes,
|
|
14
|
-
enum values, child cardinality, `<a href>`/`id` rules, duplicate `<div id>`,
|
|
15
|
-
required `<meta>` in `<head>`; surfaced as editor markers.
|
|
16
|
-
- **Document outline** — by `<w-heading level=…>` and top-level `<div>`s.
|
|
17
|
-
- **Formatting** — "Format Document" runs the safe V2 canonical normalizer.
|
|
18
|
-
It validates matching/closed tags and text preservation before returning an
|
|
19
|
-
edit; invalid documents remain unchanged.
|
|
20
|
-
- **Toolbar & editor commands** — an optional DOM toolbar (top panel) plus
|
|
21
|
-
keybindings that mirror the VS Code extension: wrap selection in
|
|
22
|
-
`<w-format>`/other inlines, snippet buttons, "Renumber div ids", and a
|
|
23
|
-
HTML ↔ canonical format cycle.
|
|
24
|
-
|
|
25
|
-
This package does **not** modify the original VS Code extension — it is a
|
|
26
|
-
standalone re-implementation living entirely under `monaco-editor/`.
|
|
27
|
-
|
|
28
|
-
## Install & build
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
cd monaco-editor
|
|
32
|
-
npm install
|
|
33
|
-
npm run build # → dist/weml-monaco.js (IIFE global), .esm.js (ESM), *.d.ts
|
|
34
|
-
npm run typecheck # tsc --noEmit
|
|
35
|
-
npm test # build the ESM bundle + run the Node smoke test
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Usage
|
|
39
|
-
|
|
40
|
-
Monaco is **passed in** at registration time, so this works no matter how
|
|
41
|
-
Monaco itself is loaded (AMD/CDN, ESM bundle, or a global):
|
|
42
|
-
|
|
43
|
-
```ts
|
|
44
|
-
import * as monaco from 'monaco-editor';
|
|
45
|
-
import { registerWeml } from 'weml-monaco'; // or the bundled dist/weml-monaco.esm.js
|
|
46
|
-
|
|
47
|
-
const disposable = registerWeml(monaco);
|
|
48
|
-
|
|
49
|
-
const model = monaco.editor.createModel(source, 'weml');
|
|
50
|
-
monaco.editor.create(document.getElementById('container'), { model });
|
|
51
|
-
|
|
52
|
-
// disposable.dispose(); // tears down every provider + diagnostics listener
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
`registerWeml(monaco, options?)` accepts:
|
|
56
|
-
|
|
57
|
-
| option | default | meaning |
|
|
58
|
-
| ---------------------- | ----------- | -------------------------------------------------- |
|
|
59
|
-
| `extensions` | `['.weml']` | file extensions associated with the language |
|
|
60
|
-
| `diagnostics` | `true` | wire live validation → `setModelMarkers` |
|
|
61
|
-
| `diagnosticsDebounceMs`| `300` | debounce for re-validating after edits |
|
|
62
|
-
|
|
63
|
-
Diagnostics are attached to every `weml` model automatically (on creation,
|
|
64
|
-
content change, and language switch) and cleared on disposal. To validate a
|
|
65
|
-
model on demand instead, call `validateWemlModel(monaco, model)` and feed the
|
|
66
|
-
returned `IMarkerData[]` to `monaco.editor.setModelMarkers`. To run the
|
|
67
|
-
formatter directly, call `formatWemlText(source)`.
|
|
68
|
-
Structural validation failures are also available through
|
|
69
|
-
`isWemlStructureValidationFailure(error)` and include a code, line and column.
|
|
70
|
-
|
|
71
|
-
## Toolbar & editor commands
|
|
72
|
-
|
|
73
|
-
Monaco has no webview panels, so the VS Code toolbar is ported as a **DOM top
|
|
74
|
-
panel** you mount yourself, plus per-editor actions/keybindings. Button
|
|
75
|
-
behaviour is identical to the VS Code toolbar.
|
|
76
|
-
|
|
77
|
-
```ts
|
|
78
|
-
import { registerWeml, createWemlToolbar } from 'weml-monaco';
|
|
79
|
-
|
|
80
|
-
registerWeml(monaco);
|
|
81
|
-
const editor = monaco.editor.create(container, { model });
|
|
82
|
-
|
|
83
|
-
const toolbar = createWemlToolbar(monaco, editor, {
|
|
84
|
-
container: document.getElementById('weml-toolbar'), // where to mount the panel
|
|
85
|
-
onStatus: (msg) => console.log(msg), // optional status sink
|
|
86
|
-
// includeSearchRow: true, // stub search row (as in VS Code); default true
|
|
87
|
-
// onSearch: (query, lang) => { ... },
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// toolbar.element → the toolbar DOM node
|
|
91
|
-
// toolbar.dispose() → removes the panel and its actions
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
`createWemlToolbar` also registers the editor actions (so they work without the
|
|
95
|
-
panel too, via keybindings and the command palette):
|
|
96
|
-
|
|
97
|
-
| action / command | keybinding | effect |
|
|
98
|
-
| ------------------------- | ------------- | -------------------------------------------------- |
|
|
99
|
-
| `weml.wrapFormat.bold` | `Ctrl+B` | wrap selection in `<w-format type="bold">` |
|
|
100
|
-
| `weml.wrapFormat.italic` | `Ctrl+I` | wrap selection in `<w-format type="italic">` |
|
|
101
|
-
| `weml.wrapFormat.underline`| `Ctrl+U` | wrap selection in `<w-format type="underline">` |
|
|
102
|
-
| `weml.cycleFormat` | `Alt+Shift+F` | cycle document: HTML ↔ canonical WEML formatting |
|
|
103
|
-
| `weml.renumberDivIds` | — | renumber every `<div>` id to a sequential 1…n |
|
|
104
|
-
|
|
105
|
-
To register the actions without a toolbar, call
|
|
106
|
-
`registerWemlEditorActions(monaco, editor, options)`. The underlying operations
|
|
107
|
-
(`wrapSelection`, `insertSnippetById`, `renumberDivIds`, `cycleFormat`) and the
|
|
108
|
-
pure helpers (`planDivIdRenumber`, `buildWrapSnippet`) are exported too.
|
|
109
|
-
|
|
110
|
-
Snippet insertion uses Monaco's `snippetController2`, so `$1`/`$2` tab stops
|
|
111
|
-
behave like `editor.insertSnippet` in VS Code.
|
|
112
|
-
|
|
113
|
-
## Demo
|
|
114
|
-
|
|
115
|
-
```bash
|
|
116
|
-
npm run demo # bundles src/index.ts → demo/weml-monaco.js
|
|
117
|
-
# then open demo/index.html in a browser
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
`demo/index.html` loads Monaco from a CDN (AMD loader) and the WEML bundle as a
|
|
121
|
-
global, registers the language and opens a sample document. Try Ctrl+Space for
|
|
122
|
-
completions, hover a tag, "Format Document", Ctrl+Shift+O for the outline, or
|
|
123
|
-
introduce an error to see diagnostics.
|
|
124
|
-
|
|
125
|
-
## How it relates to the VS Code extension
|
|
126
|
-
|
|
127
|
-
The schema and rules are reused verbatim from the extension:
|
|
128
|
-
|
|
129
|
-
| reused as-is | adapted for Monaco |
|
|
130
|
-
| ------------------------------------ | ---------------------------------------- |
|
|
131
|
-
| `generated/schema.ts` | `schema/docs.ts` (plain `IMarkdownString`) |
|
|
132
|
-
| `schema/structureRules.ts` | `wemlDocument.ts` (model ↔ LSP positions) |
|
|
133
|
-
| `schema/snippets.ts` | `providers/*` (Monaco provider APIs) |
|
|
134
|
-
| `wemlContentNormalizeV2.js` | `index.ts` (registration + diagnostics) |
|
|
135
|
-
|
|
136
|
-
Parsing still uses `vscode-html-languageservice` (it is editor-agnostic and
|
|
137
|
-
runs in the browser); the only real work was swapping the `vscode.*` provider
|
|
138
|
-
APIs for `monaco.languages.*` and converting between Monaco's 1-based
|
|
139
|
-
line/column positions and the language service's 0-based LSP positions.
|
|
1
|
+
# WEML language support for Monaco
|
|
2
|
+
|
|
3
|
+
A Monaco-editor port of the WEML (White Estate Markup Language) VS Code
|
|
4
|
+
extension. It provides, for models with language id `weml`:
|
|
5
|
+
|
|
6
|
+
- **Syntax highlighting** — a Monarch tokenizer (HTML-flavoured, since WEML is
|
|
7
|
+
HTML5-compatible).
|
|
8
|
+
- **Context-aware autocomplete** — tags / attributes / attribute values that
|
|
9
|
+
respect the WEML nesting rules, with element-scaffolding snippets and
|
|
10
|
+
composite snippets (`table`, `w-list`, `figure`, `div + w-heading`, …).
|
|
11
|
+
- **Hover tooltips** — documentation generated from `docs/` (tags, attributes,
|
|
12
|
+
enum values, `meta` fields, `<a href>` link types).
|
|
13
|
+
- **Structure diagnostics** — unknown tags/attributes, required attributes,
|
|
14
|
+
enum values, child cardinality, `<a href>`/`id` rules, duplicate `<div id>`,
|
|
15
|
+
required `<meta>` in `<head>`; surfaced as editor markers.
|
|
16
|
+
- **Document outline** — by `<w-heading level=…>` and top-level `<div>`s.
|
|
17
|
+
- **Formatting** — "Format Document" runs the safe V2 canonical normalizer.
|
|
18
|
+
It validates matching/closed tags and text preservation before returning an
|
|
19
|
+
edit; invalid documents remain unchanged.
|
|
20
|
+
- **Toolbar & editor commands** — an optional DOM toolbar (top panel) plus
|
|
21
|
+
keybindings that mirror the VS Code extension: wrap selection in
|
|
22
|
+
`<w-format>`/other inlines, snippet buttons, "Renumber div ids", and a
|
|
23
|
+
HTML ↔ canonical format cycle.
|
|
24
|
+
|
|
25
|
+
This package does **not** modify the original VS Code extension — it is a
|
|
26
|
+
standalone re-implementation living entirely under `monaco-editor/`.
|
|
27
|
+
|
|
28
|
+
## Install & build
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
cd monaco-editor
|
|
32
|
+
npm install
|
|
33
|
+
npm run build # → dist/weml-monaco.js (IIFE global), .esm.js (ESM), *.d.ts
|
|
34
|
+
npm run typecheck # tsc --noEmit
|
|
35
|
+
npm test # build the ESM bundle + run the Node smoke test
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
Monaco is **passed in** at registration time, so this works no matter how
|
|
41
|
+
Monaco itself is loaded (AMD/CDN, ESM bundle, or a global):
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import * as monaco from 'monaco-editor';
|
|
45
|
+
import { registerWeml } from 'weml-monaco'; // or the bundled dist/weml-monaco.esm.js
|
|
46
|
+
|
|
47
|
+
const disposable = registerWeml(monaco);
|
|
48
|
+
|
|
49
|
+
const model = monaco.editor.createModel(source, 'weml');
|
|
50
|
+
monaco.editor.create(document.getElementById('container'), { model });
|
|
51
|
+
|
|
52
|
+
// disposable.dispose(); // tears down every provider + diagnostics listener
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`registerWeml(monaco, options?)` accepts:
|
|
56
|
+
|
|
57
|
+
| option | default | meaning |
|
|
58
|
+
| ---------------------- | ----------- | -------------------------------------------------- |
|
|
59
|
+
| `extensions` | `['.weml']` | file extensions associated with the language |
|
|
60
|
+
| `diagnostics` | `true` | wire live validation → `setModelMarkers` |
|
|
61
|
+
| `diagnosticsDebounceMs`| `300` | debounce for re-validating after edits |
|
|
62
|
+
|
|
63
|
+
Diagnostics are attached to every `weml` model automatically (on creation,
|
|
64
|
+
content change, and language switch) and cleared on disposal. To validate a
|
|
65
|
+
model on demand instead, call `validateWemlModel(monaco, model)` and feed the
|
|
66
|
+
returned `IMarkerData[]` to `monaco.editor.setModelMarkers`. To run the
|
|
67
|
+
formatter directly, call `formatWemlText(source)`.
|
|
68
|
+
Structural validation failures are also available through
|
|
69
|
+
`isWemlStructureValidationFailure(error)` and include a code, line and column.
|
|
70
|
+
|
|
71
|
+
## Toolbar & editor commands
|
|
72
|
+
|
|
73
|
+
Monaco has no webview panels, so the VS Code toolbar is ported as a **DOM top
|
|
74
|
+
panel** you mount yourself, plus per-editor actions/keybindings. Button
|
|
75
|
+
behaviour is identical to the VS Code toolbar.
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { registerWeml, createWemlToolbar } from 'weml-monaco';
|
|
79
|
+
|
|
80
|
+
registerWeml(monaco);
|
|
81
|
+
const editor = monaco.editor.create(container, { model });
|
|
82
|
+
|
|
83
|
+
const toolbar = createWemlToolbar(monaco, editor, {
|
|
84
|
+
container: document.getElementById('weml-toolbar'), // where to mount the panel
|
|
85
|
+
onStatus: (msg) => console.log(msg), // optional status sink
|
|
86
|
+
// includeSearchRow: true, // stub search row (as in VS Code); default true
|
|
87
|
+
// onSearch: (query, lang) => { ... },
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// toolbar.element → the toolbar DOM node
|
|
91
|
+
// toolbar.dispose() → removes the panel and its actions
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`createWemlToolbar` also registers the editor actions (so they work without the
|
|
95
|
+
panel too, via keybindings and the command palette):
|
|
96
|
+
|
|
97
|
+
| action / command | keybinding | effect |
|
|
98
|
+
| ------------------------- | ------------- | -------------------------------------------------- |
|
|
99
|
+
| `weml.wrapFormat.bold` | `Ctrl+B` | wrap selection in `<w-format type="bold">` |
|
|
100
|
+
| `weml.wrapFormat.italic` | `Ctrl+I` | wrap selection in `<w-format type="italic">` |
|
|
101
|
+
| `weml.wrapFormat.underline`| `Ctrl+U` | wrap selection in `<w-format type="underline">` |
|
|
102
|
+
| `weml.cycleFormat` | `Alt+Shift+F` | cycle document: HTML ↔ canonical WEML formatting |
|
|
103
|
+
| `weml.renumberDivIds` | — | renumber every `<div>` id to a sequential 1…n |
|
|
104
|
+
|
|
105
|
+
To register the actions without a toolbar, call
|
|
106
|
+
`registerWemlEditorActions(monaco, editor, options)`. The underlying operations
|
|
107
|
+
(`wrapSelection`, `insertSnippetById`, `renumberDivIds`, `cycleFormat`) and the
|
|
108
|
+
pure helpers (`planDivIdRenumber`, `buildWrapSnippet`) are exported too.
|
|
109
|
+
|
|
110
|
+
Snippet insertion uses Monaco's `snippetController2`, so `$1`/`$2` tab stops
|
|
111
|
+
behave like `editor.insertSnippet` in VS Code.
|
|
112
|
+
|
|
113
|
+
## Demo
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
npm run demo # bundles src/index.ts → demo/weml-monaco.js
|
|
117
|
+
# then open demo/index.html in a browser
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`demo/index.html` loads Monaco from a CDN (AMD loader) and the WEML bundle as a
|
|
121
|
+
global, registers the language and opens a sample document. Try Ctrl+Space for
|
|
122
|
+
completions, hover a tag, "Format Document", Ctrl+Shift+O for the outline, or
|
|
123
|
+
introduce an error to see diagnostics.
|
|
124
|
+
|
|
125
|
+
## How it relates to the VS Code extension
|
|
126
|
+
|
|
127
|
+
The schema and rules are reused verbatim from the extension:
|
|
128
|
+
|
|
129
|
+
| reused as-is | adapted for Monaco |
|
|
130
|
+
| ------------------------------------ | ---------------------------------------- |
|
|
131
|
+
| `generated/schema.ts` | `schema/docs.ts` (plain `IMarkdownString`) |
|
|
132
|
+
| `schema/structureRules.ts` | `wemlDocument.ts` (model ↔ LSP positions) |
|
|
133
|
+
| `schema/snippets.ts` | `providers/*` (Monaco provider APIs) |
|
|
134
|
+
| `wemlContentNormalizeV2.js` | `index.ts` (registration + diagnostics) |
|
|
135
|
+
|
|
136
|
+
Parsing still uses `vscode-html-languageservice` (it is editor-agnostic and
|
|
137
|
+
runs in the browser); the only real work was swapping the `vscode.*` provider
|
|
138
|
+
APIs for `monaco.languages.*` and converting between Monaco's 1-based
|
|
139
|
+
line/column positions and the language service's 0-based LSP positions.
|