Skip to content

Commit f3f3402

Browse files
committed
fix: keep \vale off\ working when QDoc prose is escaped
Signed-off-by: Joseph Kato <joseph@jdkato.io>
1 parent 54efd3b commit f3f3402

3 files changed

Lines changed: 69 additions & 1 deletion

File tree

‎internal/lint/qdoc.go‎

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,30 @@ var qdocInlineNames = map[string]struct{}{
209209
// raw-text mode, so the rest of the page is swallowed looking for a close
210210
// that never comes. The tokenizer decodes these again, so the text a rule
211211
// sees, and the text located in the source, are unchanged.
212-
var qdocEsc = strings.NewReplacer("&", "&amp;", "<", "&lt;", ">", "&gt;").Replace
212+
var qdocEscAll = strings.NewReplacer("&", "&amp;", "<", "&lt;", ">", "&gt;").Replace
213+
214+
// An HTML comment, which survives escaping: `vale off` and `vale on` reach
215+
// the walker as comments, and a QDoc file writes them the same way any other
216+
// markup does.
217+
var qdocHTMLComment = regexp.MustCompile(`(?s)<!--.*?-->`)
218+
219+
func qdocEsc(text string) string {
220+
spans := qdocHTMLComment.FindAllStringIndex(text, -1)
221+
if spans == nil {
222+
return qdocEscAll(text)
223+
}
224+
225+
var out strings.Builder
226+
last := 0
227+
for _, s := range spans {
228+
out.WriteString(qdocEscAll(text[last:s[0]]))
229+
out.WriteString(text[s[0]:s[1]])
230+
last = s[1]
231+
}
232+
out.WriteString(qdocEscAll(text[last:]))
233+
234+
return out.String()
235+
}
213236

214237
// qdocArg strips the braces from a command argument.
215238
func qdocArg(arg string) string {

‎internal/lint/qdoc_test.go‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@ func TestQdocHTML(t *testing.T) {
122122
[]string{"using a &lt;script&gt; tag.", "<p>Prose after it.</p>"},
123123
nil,
124124
},
125+
{
126+
"an HTML comment survives escaping",
127+
"A <!-- vale off --> toggle and a <script> tag.\n",
128+
[]string{"<!-- vale off -->", "&lt;script&gt;"},
129+
[]string{"&lt;!--"},
130+
},
125131
{
126132
"sa lines are markup",
127133
"Prose here.\n\n\\sa QWidget, QObject\n",

‎testdata/e2e/lint.yaml‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,45 @@ cases:
481481
markers.qdoc:6:16:T.Mark:'MARKB'
482482
snippet.qdoc:7:17:T.Mark:'MARKA'
483483
484+
- name: qdoc-toggles
485+
about: "`vale off` and `vale on` work in QDoc, as an HTML comment and
486+
through `CommentDelimiters`, even though the prose around them may
487+
talk about markup"
488+
files:
489+
.vale.ini: |
490+
StylesPath = styles
491+
MinAlertLevel = suggestion
492+
493+
[*.qdoc]
494+
T.Tok = YES
495+
CommentDelimiters = [[, ]]
496+
styles/T/Tok.yml: |
497+
extends: existence
498+
message: "'%s'"
499+
level: error
500+
nonword: true
501+
raw:
502+
- ZQX
503+
t.qdoc: |
504+
/*!
505+
A ZQX before, in a <script> tag sentence.
506+
507+
<!-- vale off -->
508+
A ZQX an HTML comment suppresses.
509+
<!-- vale on -->
510+
511+
[[ vale off ]]
512+
A ZQX custom delimiters suppress.
513+
[[ vale on ]]
514+
515+
A ZQX after.
516+
*/
517+
args: t.qdoc
518+
exit: 1
519+
want: |
520+
t.qdoc:2:7:T.Tok:'ZQX'
521+
t.qdoc:12:7:T.Tok:'ZQX'
522+
484523
- name: qdoc-classes
485524
about: "`.qdocinc` is QDoc without configuration, and `\\div` and `\\span`
486525
carry their class into the scope so a rule can target the prose they

0 commit comments

Comments
 (0)