Skip to content

Commit eee1c58

Browse files
authored
fix(headings): error if line starts with uppercase #24
Problem: Plaintext lines starting with uppercase word(s) are flagged as (h3) ERROR. Solution: Tell the grammar explicitly that uppercase words are allowed at the start of a plaintext (line), this does not necessarily mean the line is an invalid (h3) heading.
1 parent 55292d9 commit eee1c58

File tree

4 files changed

+2789
-1532
lines changed

4 files changed

+2789
-1532
lines changed

corpus/heading3-column_heading.txt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ NOT h3 uppercase heading
151151
^V 0x16 22 (SYN)
152152
^W 0x17 23 END
153153

154+
ABC not-h3
155+
156+
4. 'runtimepath' `/xxx;yyy/baz`.The
157+
`/foo/bar`-and-`/abc`.
158+
5. PRODUCT of 3.
159+
...`/lua`-path,-leaving:
160+
154161
--------------------------------------------------------------------------------
155162

156163
(help_file
@@ -164,6 +171,29 @@ NOT h3 uppercase heading
164171
(word)
165172
(word)
166173
(word)
174+
(word)))
175+
(block
176+
(line
177+
(word)
178+
(word)))
179+
(block
180+
(line
181+
(word)
182+
(optionlink
183+
(word))
184+
(codespan
185+
(word))
186+
(word))
187+
(line
188+
(codespan
189+
(word))
190+
(word))
191+
(line
192+
(word)
193+
(word)
194+
(word)
195+
(word))
196+
(line
167197
(word))))
168198

169199
================================================================================

grammar.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1+
const _uppercase_word = /[A-Z0-9.()][-A-Z0-9.()_]+/;
2+
13
module.exports = grammar({
24
name: 'help', // The actual language name is help
35

46
extras: () => [/[\t ]/],
57

8+
inline: ($) => [
9+
$.uppercase_words,
10+
],
11+
612
rules: {
713
help_file: ($) =>
814
seq(
@@ -52,6 +58,17 @@ module.exports = grammar({
5258
/\{\}/,
5359
),
5460

61+
// First part (minus tags) of h3 or column_heading.
62+
uppercase_name: () => seq(
63+
token.immediate(_uppercase_word), // No whitespace before heading.
64+
repeat(_uppercase_word),
65+
),
66+
// Line (plaintext) can start with uppercase words; don't flag as "invalid h3".
67+
uppercase_words: ($) => prec.left(-1, seq(
68+
alias(token.immediate(_uppercase_word), $.word),
69+
alias(repeat(_uppercase_word), $.word),
70+
)),
71+
5572
// Text block/paragraph: adjacent lines followed by blank line(s).
5673
block: ($) => prec.right(seq(
5774
repeat1(choice($.line, $.line_li)),
@@ -111,10 +128,7 @@ module.exports = grammar({
111128
repeat(_blank()),
112129
),
113130

114-
// Heading 3: UPPERCASE WORDS, followed by optional *tags*.
115-
uppercase_name: () => seq(
116-
token.immediate(/[A-Z0-9.()][-A-Z0-9.()_]+/), // No whitespace before heading.
117-
repeat(/[A-Z0-9.()][-A-Z0-9.()_]+/)),
131+
// Heading 3: UPPERCASE NAME, followed by optional *tags*.
118132
h3: ($) =>
119133
seq(
120134
field('name', $.uppercase_name),
@@ -167,8 +181,9 @@ function _line($, require_eol) {
167181
const eol = require_eol ? '\n' : optional('\n');
168182
return choice(
169183
$.column_heading,
170-
seq(repeat($._atom), $.codeblock),
171-
seq(repeat1($._atom), choice($.codeblock, eol)));
184+
seq(optional($.uppercase_words), repeat($._atom), $.codeblock),
185+
seq(optional($.uppercase_words), repeat1($._atom), choice($.codeblock, eol)),
186+
);
172187
}
173188

174189
function _blank() {

src/grammar.json

Lines changed: 103 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,58 @@
180180
}
181181
]
182182
},
183+
"uppercase_name": {
184+
"type": "SEQ",
185+
"members": [
186+
{
187+
"type": "IMMEDIATE_TOKEN",
188+
"content": {
189+
"type": "PATTERN",
190+
"value": "[A-Z0-9.()][-A-Z0-9.()_]+"
191+
}
192+
},
193+
{
194+
"type": "REPEAT",
195+
"content": {
196+
"type": "PATTERN",
197+
"value": "[A-Z0-9.()][-A-Z0-9.()_]+"
198+
}
199+
}
200+
]
201+
},
202+
"uppercase_words": {
203+
"type": "PREC_LEFT",
204+
"value": -1,
205+
"content": {
206+
"type": "SEQ",
207+
"members": [
208+
{
209+
"type": "ALIAS",
210+
"content": {
211+
"type": "IMMEDIATE_TOKEN",
212+
"content": {
213+
"type": "PATTERN",
214+
"value": "[A-Z0-9.()][-A-Z0-9.()_]+"
215+
}
216+
},
217+
"named": true,
218+
"value": "word"
219+
},
220+
{
221+
"type": "ALIAS",
222+
"content": {
223+
"type": "REPEAT",
224+
"content": {
225+
"type": "PATTERN",
226+
"value": "[A-Z0-9.()][-A-Z0-9.()_]+"
227+
}
228+
},
229+
"named": true,
230+
"value": "word"
231+
}
232+
]
233+
}
234+
},
183235
"block": {
184236
"type": "PREC_RIGHT",
185237
"value": 0,
@@ -343,6 +395,18 @@
343395
{
344396
"type": "SEQ",
345397
"members": [
398+
{
399+
"type": "CHOICE",
400+
"members": [
401+
{
402+
"type": "SYMBOL",
403+
"name": "uppercase_words"
404+
},
405+
{
406+
"type": "BLANK"
407+
}
408+
]
409+
},
346410
{
347411
"type": "REPEAT",
348412
"content": {
@@ -359,6 +423,18 @@
359423
{
360424
"type": "SEQ",
361425
"members": [
426+
{
427+
"type": "CHOICE",
428+
"members": [
429+
{
430+
"type": "SYMBOL",
431+
"name": "uppercase_words"
432+
},
433+
{
434+
"type": "BLANK"
435+
}
436+
]
437+
},
362438
{
363439
"type": "REPEAT1",
364440
"content": {
@@ -393,6 +469,18 @@
393469
{
394470
"type": "SEQ",
395471
"members": [
472+
{
473+
"type": "CHOICE",
474+
"members": [
475+
{
476+
"type": "SYMBOL",
477+
"name": "uppercase_words"
478+
},
479+
{
480+
"type": "BLANK"
481+
}
482+
]
483+
},
396484
{
397485
"type": "REPEAT",
398486
"content": {
@@ -409,6 +497,18 @@
409497
{
410498
"type": "SEQ",
411499
"members": [
500+
{
501+
"type": "CHOICE",
502+
"members": [
503+
{
504+
"type": "SYMBOL",
505+
"name": "uppercase_words"
506+
},
507+
{
508+
"type": "BLANK"
509+
}
510+
]
511+
},
412512
{
413513
"type": "REPEAT1",
414514
"content": {
@@ -604,25 +704,6 @@
604704
}
605705
]
606706
},
607-
"uppercase_name": {
608-
"type": "SEQ",
609-
"members": [
610-
{
611-
"type": "IMMEDIATE_TOKEN",
612-
"content": {
613-
"type": "PATTERN",
614-
"value": "[A-Z0-9.()][-A-Z0-9.()_]+"
615-
}
616-
},
617-
{
618-
"type": "REPEAT",
619-
"content": {
620-
"type": "PATTERN",
621-
"value": "[A-Z0-9.()][-A-Z0-9.()_]+"
622-
}
623-
}
624-
]
625-
},
626707
"h3": {
627708
"type": "SEQ",
628709
"members": [
@@ -850,7 +931,9 @@
850931
"conflicts": [],
851932
"precedences": [],
852933
"externals": [],
853-
"inline": [],
934+
"inline": [
935+
"uppercase_words"
936+
],
854937
"supertypes": []
855938
}
856939

0 commit comments

Comments
 (0)