codemirror-lang-raku 0.0.0-stage → 0.2.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/CHANGELOG.md +82 -0
- package/LICENSE +23 -0
- package/README.md +238 -2
- package/dist/index.cjs +2422 -0
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +2417 -0
- package/package.json +65 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
## 0.2.0 (2026-10-07)
|
|
2
|
+
|
|
3
|
+
### New features
|
|
4
|
+
|
|
5
|
+
- Regexes are highlighted inside: the literals `/…/`, `rx/…/`, `m/…/` and
|
|
6
|
+
the pattern of `s/…/…/`, and the body of a `token`, `rule` or `regex`
|
|
7
|
+
declaration. A `Regex` node has children for character classes (`CharacterClass`),
|
|
8
|
+
`<…>` assertions (`Assertion`), quoted literals, escapes, quantifiers
|
|
9
|
+
and anchors, variables, comments, and the blocks of code in it, which
|
|
10
|
+
are read as code.
|
|
11
|
+
- `multi foo(…) { }`, `proto foo(…) {*}` and `only foo(…) { }`, without the
|
|
12
|
+
word `sub`, are `RoutineDeclaration` nodes with a `RoutineName`. The
|
|
13
|
+
node has no declarator keyword, and `multi` is the node before it.
|
|
14
|
+
- Pod blocks have child nodes for their directives (`PodDirective`),
|
|
15
|
+
headings (`PodHeading`) and formatting codes (`PodStrong`,
|
|
16
|
+
`PodEmphasis`, `PodCode`, `PodLink`, `PodFormat`), which are highlighted.
|
|
17
|
+
- Variables, blocks and escapes are interpolated in the text of a
|
|
18
|
+
`qq:to` heredoc. Its `Heredoc` node has the children of a string that
|
|
19
|
+
interpolates.
|
|
20
|
+
- Variables, blocks and escapes are interpolated in `<<…>>` and `«…»`
|
|
21
|
+
word lists. Such a list can hold code over several lines, and can be
|
|
22
|
+
a subscript: `%h«$key»`, `:a<<b $c>>`.
|
|
23
|
+
- Completion offers the names that the document declares: the variables
|
|
24
|
+
and attributes in scope, routines, classes, enums, subsets and
|
|
25
|
+
constants, and after a `.` the methods.
|
|
26
|
+
- Completion also offers placeholder variables (`$^a`) in their block,
|
|
27
|
+
and variables without a sigil (`my \x`).
|
|
28
|
+
- A line that starts with a trait, as in `is export {` under
|
|
29
|
+
`sub f($a)`, is indented as the continuation of its statement.
|
|
30
|
+
- Toggling a block comment picks brackets that fit the selection:
|
|
31
|
+
`` #`[ … ] `` when the selection holds an unbalanced parenthesis, and so
|
|
32
|
+
on. A comment is removed whichever bracket it was written with.
|
|
33
|
+
- A line that continues a statement is indented one unit further: after
|
|
34
|
+
a line that ends in an operator or a comma, and when it starts with a
|
|
35
|
+
method call or an infix operator.
|
|
36
|
+
- The adverbs of a quote that switch kinds of interpolation on and off
|
|
37
|
+
are taken into account: `q:c{…}` interpolates blocks, `qq:!s[…]` does
|
|
38
|
+
not interpolate `$` variables. This covers `:c`, `:s`, `:a`, `:h`, `:f`,
|
|
39
|
+
`:b`, `:qq`, `:q` and their long names.
|
|
40
|
+
- An operator referred to as a routine, as in `&infix:<+>`, is a single
|
|
41
|
+
`VariableName`. Operator names can also be written as `circumfix:<[ ]>`
|
|
42
|
+
and `infix:['+']`.
|
|
43
|
+
- `q`, `qq`, `Q` and their variants take a bracket after blanks: `q {…}`,
|
|
44
|
+
`qw <a b>`.
|
|
45
|
+
- An adverb with an argument that is `False` or `0` is switched off:
|
|
46
|
+
`qq:c(False)[…]`.
|
|
47
|
+
|
|
48
|
+
### Bug fixes
|
|
49
|
+
|
|
50
|
+
- A regex with bracket delimiters no longer ends at the `]` of a
|
|
51
|
+
character class in it: `rx[ <[a..z]> ]`.
|
|
52
|
+
- `multi foo`, `proto foo` and `only foo` declare a sub also when the
|
|
53
|
+
signature or the body starts on the next line.
|
|
54
|
+
- A long comment right after a type name (`my Foo # …`) no longer makes
|
|
55
|
+
every edit before it reparse the document up to that comment.
|
|
56
|
+
- After the built-in terms `pi`, `π`, `tau`, `τ`, `now`, `time` and `rand`, a
|
|
57
|
+
`/` or `<` is an operator whatever the spacing: `pi /2`.
|
|
58
|
+
- A keyword that is a routine and is called with parentheses, as in
|
|
59
|
+
`take(1)` or `not($x)`, is a plain name and not a keyword.
|
|
60
|
+
- The body of a regex declaration that is not closed ends before the next
|
|
61
|
+
`token`, `rule` or `regex` declaration, so that the declarations after
|
|
62
|
+
it are still found.
|
|
63
|
+
- A heredoc opener that is only mentioned in a string or in a comment no
|
|
64
|
+
longer starts a heredoc. Heredocs are now found from the quote tokens
|
|
65
|
+
of the line, not from its text.
|
|
66
|
+
|
|
67
|
+
## 0.1.0 (2026-10-06)
|
|
68
|
+
|
|
69
|
+
### New features
|
|
70
|
+
|
|
71
|
+
First release.
|
|
72
|
+
|
|
73
|
+
- Syntax highlighting with the standard tags of `@lezer/highlight`:
|
|
74
|
+
comments and Pod, quotes of all kinds with interpolation, heredocs,
|
|
75
|
+
regexes, numbers, variables with sigils and twigils, keywords, operators
|
|
76
|
+
and declarations
|
|
77
|
+
- A syntax tree with nodes for package, routine, regex, enum, subset and
|
|
78
|
+
constant declarations and their names
|
|
79
|
+
- Indentation, folding and matching of `{ }`, `( )` and `[ ]`, and folding
|
|
80
|
+
of Pod blocks, heredocs and embedded comments
|
|
81
|
+
- Completion of keywords and of the commonly used built-in types,
|
|
82
|
+
routines, methods and special variables
|
package/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (C) 2026 by Kan Fushihara
|
|
4
|
+
Copyright (C) 2021 by Marijn Haverbeke <marijnh@gmail.com> and others
|
|
5
|
+
(the CodeMirror language package template this project started from)
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
in the Software without restriction, including without limitation the rights
|
|
10
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
furnished to do so, subject to the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be included in
|
|
15
|
+
all copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
23
|
+
THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,239 @@
|
|
|
1
|
-
#
|
|
1
|
+
# codemirror-lang-raku
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/codemirror-lang-raku)
|
|
4
|
+
[](https://github.com/kan/codemirror-lang-raku/actions/workflows/test.yml)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
[Raku](https://raku.org/) (formerly Perl 6) language support for the
|
|
8
|
+
[CodeMirror 6](https://codemirror.net/) code editor: syntax highlighting,
|
|
9
|
+
indentation, code folding, bracket matching and completion, built on a
|
|
10
|
+
[Lezer](https://lezer.codemirror.net/) grammar.
|
|
11
|
+
|
|
12
|
+
It covers comments and Pod, quotes of all kinds (`'…'`, `"…"`, `q` / `qq` /
|
|
13
|
+
`Q` with any delimiter, heredocs, `<word lists>`) with interpolation,
|
|
14
|
+
regexes, numbers, variables with sigils and twigils, keywords, operators,
|
|
15
|
+
blocks and declarations.
|
|
16
|
+
|
|
17
|
+
Try it in the [demo](https://kan.github.io/codemirror-lang-raku/), which
|
|
18
|
+
shows the syntax tree next to the editor.
|
|
19
|
+
|
|
20
|
+
> **Status: 0.x.** The node names of the syntax tree can still change
|
|
21
|
+
> between minor versions. See [Known limitations](#known-limitations) for
|
|
22
|
+
> what is missing.
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
npm install codemirror-lang-raku
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
```javascript
|
|
33
|
+
import {EditorView, basicSetup} from "codemirror"
|
|
34
|
+
import {raku} from "codemirror-lang-raku"
|
|
35
|
+
|
|
36
|
+
new EditorView({
|
|
37
|
+
doc: 'say "Hello, Raku!";',
|
|
38
|
+
extensions: [basicSetup, raku()],
|
|
39
|
+
parent: document.body
|
|
40
|
+
})
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Highlighting uses only the standard tags of `@lezer/highlight`, so any
|
|
44
|
+
CodeMirror theme or highlight style applies.
|
|
45
|
+
|
|
46
|
+
To load the language on demand, the way `@codemirror/language-data` does:
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
import {LanguageDescription} from "@codemirror/language"
|
|
50
|
+
|
|
51
|
+
const rakuDescription = LanguageDescription.of({
|
|
52
|
+
name: "Raku",
|
|
53
|
+
alias: ["perl6"],
|
|
54
|
+
extensions: ["raku", "rakumod", "rakutest", "rakudoc", "p6", "pl6", "pm6", "pod6"],
|
|
55
|
+
load: () => import("codemirror-lang-raku").then(m => m.raku())
|
|
56
|
+
})
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## API Reference
|
|
60
|
+
|
|
61
|
+
<dl>
|
|
62
|
+
<dt><code><strong>raku</strong>() → LanguageSupport</code></dt>
|
|
63
|
+
<dd><p>Raku language support, with completion, and with block comment
|
|
64
|
+
tokens that fit the selection (<code>#`[ … ]</code> around text that holds an
|
|
65
|
+
unbalanced parenthesis).</p></dd>
|
|
66
|
+
<dt><code><strong>rakuLanguage</strong>: LRLanguage</code></dt>
|
|
67
|
+
<dd><p>A language provider based on the Lezer Raku parser, extended with
|
|
68
|
+
highlighting and indentation information.</p></dd>
|
|
69
|
+
<dt><code><strong>rakuCompletion</strong>: Extension</code></dt>
|
|
70
|
+
<dd><p>Completion of Raku keywords, of the commonly used built-in types,
|
|
71
|
+
routines, methods and special variables, and of the variables, routines,
|
|
72
|
+
types and methods that the document declares. <code>raku()</code> includes it. To
|
|
73
|
+
leave it out, use <code>rakuLanguage</code> in place of <code>raku()</code>.</p></dd>
|
|
74
|
+
<dt><code><strong>parser</strong>: LRParser</code></dt>
|
|
75
|
+
<dd><p>The Lezer parser for Raku, without the editor-specific node props.
|
|
76
|
+
Use <code>rakuLanguage.parser</code> for the configured one.</p></dd>
|
|
77
|
+
</dl>
|
|
78
|
+
|
|
79
|
+
## Syntax tree
|
|
80
|
+
|
|
81
|
+
The grammar does not parse statements and expressions. It tokenizes the
|
|
82
|
+
input, nests brackets, and recognizes declarations, which is enough for
|
|
83
|
+
highlighting, folding and building an outline, and keeps the tree usable
|
|
84
|
+
on incomplete code.
|
|
85
|
+
|
|
86
|
+
| Node | Covers |
|
|
87
|
+
|---|---|
|
|
88
|
+
| `PackageDeclaration` | `class`, `role`, `grammar`, `module`, `package`, with a `PackageName` child, up to the body `Block` or the `;` of a `unit` declaration |
|
|
89
|
+
| `RoutineDeclaration` | `sub`, `method`, `submethod`, with a `RoutineName` child (absent for anonymous routines), up to the body `Block`. Also the `foo(…) { }` of `multi foo(…) { }`, which declares a sub without the word `sub`: that node starts with its `RoutineName` |
|
|
90
|
+
| `RegexDeclaration` | `token`, `rule`, `regex`, with a `RegexName` child, up to the body `Block`, which holds one `Regex` |
|
|
91
|
+
| `EnumDeclaration`, `SubsetDeclaration`, `ConstantDeclaration` | The declarator and its `EnumName`, `SubsetName` or `ConstantName` |
|
|
92
|
+
| `Block`, `Parens`, `Brackets` | `{ }`, `( )`, `[ ]` |
|
|
93
|
+
| `VariableName`, `AttributeName`, `SpecialVariable` | `$x` / `$^a`, `$!x` / `$.x`, `$*x` / `$?x` |
|
|
94
|
+
| `StringLiteral` | A quote of any kind. One that interpolates has `Escape`, `Interpolation`, variable, `Brackets`, `Parens` and `MethodCall` children |
|
|
95
|
+
| `Heredoc` | The text of a heredoc, from the line after its `q:to/END/` opener through its terminator. The opener is a `StringLiteral`. The text of a `qq:to` heredoc has the same children as a string that interpolates. The texts of the heredocs that one line opens are a single node |
|
|
96
|
+
| `Regex` | `/…/`, `rx//`, `m//`, `s///`, `tr///`, or the body of a regex declaration. Its children are `CharacterClass` (`<[a..z]>`), `Assertion` (`<name>`, `<?before …>`), `StringLiteral`, `Escape` (`\d`), `Operator` (quantifiers, `\|`, anchors), `VariableName` (`$x`, `$<name>`), `LineComment`, and a `Block` for each `{ }` of code |
|
|
97
|
+
| `LineComment`, `DocComment`, `BlockComment` | `#`, `#|` / `#=`, `` #`( ) `` |
|
|
98
|
+
| `Pod` | `=begin` … `=end` and the other Pod blocks. Its children are `PodDirective` (`=begin`, `=head1`, `=end pod`), `PodHeading` (the text after `=head1`), and the formatting codes `PodStrong` (`B<…>`), `PodEmphasis` (`I<…>`), `PodCode` (`C<…>`), `PodLink` (`L<…>`) and `PodFormat` (the others) |
|
|
99
|
+
|
|
100
|
+
Each declarator keyword is a child node named after the keyword (`class`,
|
|
101
|
+
`sub`, `token`, …). The words `unit`, `multi`, `proto`, `only`, `my` and
|
|
102
|
+
`our` are not part of the declaration node. They are the nodes right
|
|
103
|
+
before it, also in `multi foo(…) { }`, where the declaration node has no
|
|
104
|
+
declarator keyword.
|
|
105
|
+
|
|
106
|
+
## Known limitations
|
|
107
|
+
|
|
108
|
+
Not supported yet:
|
|
109
|
+
|
|
110
|
+
- Nothing is highlighted in the replacement of `s/…/…/`, nor in
|
|
111
|
+
`tr/…/…/`.
|
|
112
|
+
- In a regex, a `<…>` is one
|
|
113
|
+
token, with the code or the nested `<…>` in it, and has to be closed on
|
|
114
|
+
its line unless it is a character class. Groups (`[ ]`, `( )`) and
|
|
115
|
+
adverbs (`:i`, `:my`) are plain text, so the text after `:my` is read
|
|
116
|
+
as regex.
|
|
117
|
+
- A heredoc is interpolated when everything interpolates in it, as in
|
|
118
|
+
`qq:to`. One that interpolates in part (`q:c:to`, `qq:!s:to`) is not
|
|
119
|
+
highlighted inside. When a line opens several heredocs, they are
|
|
120
|
+
interpolated only if all of them are. A `{` that is not closed in the
|
|
121
|
+
text takes the rest of the heredoc, with its terminator, for code.
|
|
122
|
+
- In Pod, a formatting code is one token: the codes inside it
|
|
123
|
+
(`B<I<…>>`) are not told apart. Formatting codes are left alone in a
|
|
124
|
+
block that is code (`=begin code`, `=code`, `=for code`), but not in a
|
|
125
|
+
code block inside another block, nor in an indented code paragraph.
|
|
126
|
+
Tables and the configuration after a directive (`:numbered`) are plain
|
|
127
|
+
text.
|
|
128
|
+
- A `<<…>>` or `«…»` word list that holds `{ }`, `( )` or `;` can span up
|
|
129
|
+
to 10 lines. A longer one is not taken to be a word list. Nothing is
|
|
130
|
+
interpolated in a list that holds an unbalanced `{` or its own
|
|
131
|
+
delimiter: it is a single token.
|
|
132
|
+
- A Pod block is read where a statement or a term can stand, not
|
|
133
|
+
everywhere that whitespace can: one between `class` and the name of
|
|
134
|
+
the class is not read as Pod.
|
|
135
|
+
- A quote adverb is switched off by the argument `False` or `0`, as in
|
|
136
|
+
`qq:c(False)[…]`. With any other argument, such as a variable, it
|
|
137
|
+
counts as switched on.
|
|
138
|
+
- The brackets of a block comment are picked for the `toggleBlockComment`
|
|
139
|
+
command. Text that unbalances every bracket that is tried gets
|
|
140
|
+
`` #`( `` … `)`, which then does not cover exactly that text.
|
|
141
|
+
- A user-defined operator is recognized where it is declared
|
|
142
|
+
(`sub infix:<+++>`) and as a routine (`&infix:<+++>`), not where it is
|
|
143
|
+
used as an operator.
|
|
144
|
+
- Completion does not know types. After a `.` it offers the built-in
|
|
145
|
+
methods and every method that the document declares, whatever the
|
|
146
|
+
invocant is. Names from other files are not offered.
|
|
147
|
+
- Completion takes a variable to be declared by `my`, `our`, `state` or
|
|
148
|
+
`has`, in a signature, after the `->` of a pointy block, or by being a
|
|
149
|
+
placeholder variable (`$^a`, `$:a`). A sigilless variable is offered
|
|
150
|
+
when it is declared with a backslash (`my \x`, `sub f(\x)`, `-> \x`),
|
|
151
|
+
not as a term (`my constant x`, `sub term:<x>`).
|
|
152
|
+
- In a string, only the code in `{ }` and in a subscript is completed,
|
|
153
|
+
not the method name of `"$x.name()"`.
|
|
154
|
+
|
|
155
|
+
Heuristics that can be wrong:
|
|
156
|
+
|
|
157
|
+
- A line is indented as the continuation of a statement when the line
|
|
158
|
+
before it ends in an operator or a comma, or when it starts with a
|
|
159
|
+
method call, with an operator that has a space after it, or with a
|
|
160
|
+
trait (`is`, `does`, `returns`, `handles`, `where`, `will`, as in
|
|
161
|
+
`is export {`). A statement that continues in another way is not
|
|
162
|
+
indented further. A line that starts with one of these words for
|
|
163
|
+
another reason, such as a call of the `is` of `Test`, is indented when
|
|
164
|
+
the line before it does not end in a `;` or a `}`. Inside `( )` and
|
|
165
|
+
`[ ]`, indentation follows the brackets only.
|
|
166
|
+
- A capitalized word is taken to be a type name.
|
|
167
|
+
- Whether `/` starts a regex and `<` starts a word list is decided from
|
|
168
|
+
the token before it. After a bare name, spacing decides: `say /x/` and
|
|
169
|
+
`say <a b>` are a regex and a word list, `foo / 2` and `n < 3` are not.
|
|
170
|
+
The built-in terms `pi`, `π`, `tau`, `τ`, `now`, `time` and `rand` are
|
|
171
|
+
followed by an operator whatever the spacing (`pi /2`), also when a
|
|
172
|
+
routine of your own has one of these names. After a closing brace, a
|
|
173
|
+
line break decides.
|
|
174
|
+
- A `<…>` right after a term is a subscript only when it holds plain words
|
|
175
|
+
on one line: `%h<key>`, but not `$a<$b`. A `<<…>>` or `«…»` that touches
|
|
176
|
+
the term before it is a subscript when it is at most 24 characters
|
|
177
|
+
long and starts and ends in a word, a variable or a quote: `%h«$key»`,
|
|
178
|
+
but not the hyper operators of `@a<<+>>@b` and `@a«R-»@b`. A hyper
|
|
179
|
+
operator that is a word and touches both of its operands, as in
|
|
180
|
+
`@a<<min>>@b`, is misread as a subscript.
|
|
181
|
+
- A `<<` or `«` where a term is expected starts a word list when a `>>`
|
|
182
|
+
or `»` follows, within 10 lines if there is a `{ }`, `( )` or `;` in
|
|
183
|
+
between. One that is being typed takes the code up to there for its
|
|
184
|
+
content.
|
|
185
|
+
- In a `<<…>>` word list, a `>>` in a subscript or a call that is
|
|
186
|
+
interpolated ends the list: `<<@a[1 >> 2]>>`. A heredoc that is opened
|
|
187
|
+
in a block in a word list or in a regex literal is not read as one.
|
|
188
|
+
- `q`, `qq`, `Q`, `m`, `rx`, `s`, `tr` and their variants start a quote
|
|
189
|
+
when a delimiter follows directly, so a sigilless `s/2` is misread.
|
|
190
|
+
`q`, `qq` and `Q` also take a bracket after blanks (`q {…}`), so a
|
|
191
|
+
routine or a sigilless variable of your own named `q`, before a block
|
|
192
|
+
or a subscript, is misread. The
|
|
193
|
+
regex words do not: `m {…}` and `s {…}` are calls.
|
|
194
|
+
- `%name` and `&name` are variables, except between two terms with no
|
|
195
|
+
space on either side: `$a%b`.
|
|
196
|
+
- After `multi`, `proto` or `only`, a name is taken to declare a sub when
|
|
197
|
+
a `(` or a `{` follows it, on the same line or the next:
|
|
198
|
+
`multi foo($x) { }`. One that follows a comment or more than 20
|
|
199
|
+
characters of whitespace is not seen, and a call such as `only foo(1)`, of a
|
|
200
|
+
routine of your own that is named `only`, is read as a declaration.
|
|
201
|
+
- A word spelled like a keyword is a keyword wherever it appears, except
|
|
202
|
+
as a method name, as a declared name, before `=>`, and for the
|
|
203
|
+
keywords that are routines (`take`, `return`, `next`, `not`, …) right
|
|
204
|
+
before a `(`: `take(1)`. A sigilless variable or a routine of your own
|
|
205
|
+
that is named like a keyword is highlighted as one.
|
|
206
|
+
- A quote that does not interpolate (`'…'`, `q{…}`), a regex and a
|
|
207
|
+
heredoc have to be closed. Otherwise their opener is read as ordinary
|
|
208
|
+
code.
|
|
209
|
+
- A quote that interpolates (`"…`, `qq[…`), a Pod block or an embedded
|
|
210
|
+
comment that is not closed runs to the end of the document.
|
|
211
|
+
- The body of a regex declaration that is not closed runs up to the next
|
|
212
|
+
line that starts a `token`, `rule` or `regex` declaration, or to the
|
|
213
|
+
end of the document.
|
|
214
|
+
|
|
215
|
+
## Development
|
|
216
|
+
|
|
217
|
+
```sh
|
|
218
|
+
npm install
|
|
219
|
+
npm test # builds, then runs the tests in test/
|
|
220
|
+
npm run dev # serves demo/, an editor next to the syntax tree of its content
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
The demo loads the sources, so a change to the grammar shows up on reload.
|
|
224
|
+
|
|
225
|
+
To release a version:
|
|
226
|
+
|
|
227
|
+
1. Run `npm version 1.2.3 --no-git-tag-version`, and turn the
|
|
228
|
+
`## Unreleased` heading of `CHANGELOG.md` into `## 1.2.3 (2026-01-31)`.
|
|
229
|
+
Commit and push.
|
|
230
|
+
2. Run `npm publish` from that commit. It first runs the tests and checks
|
|
231
|
+
that `CHANGELOG.md` has that section and that nothing is uncommitted.
|
|
232
|
+
3. Tag that commit `v1.2.3` and push the tag. A workflow then checks that
|
|
233
|
+
the tag matches `package.json` and that npm has the version, published
|
|
234
|
+
from that commit, and creates the GitHub release from the section of
|
|
235
|
+
`CHANGELOG.md`.
|
|
236
|
+
|
|
237
|
+
## License
|
|
238
|
+
|
|
239
|
+
[MIT](LICENSE)
|