Skip to content

Commit d622c1d

Browse files
committed
Add DITA vale config
1 parent 2e26b23 commit d622c1d

27 files changed

+1072
-2
lines changed

.vale.ini

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ IgnoredScopes = code, tt, img, url, a, body.id
66

77
SkippedScopes = script, style, pre, figure, code, tt, blockquote, listingblock, literalblock, strong, term, xref, link
88

9-
Packages = RedHat, AsciiDoc
9+
Packages = RedHat, AsciiDoc, https://github.com/jhradilek/asciidoctor-dita-vale/releases/latest/download/AsciiDocDITA.zip
1010

1111
Vocab = Foreman
1212

@@ -17,7 +17,7 @@ Vale.Avoid = YES
1717
# Ignore files in dirs starting with `.` to avoid raising errors for `.vale/fidns_ndotsures/*/testinvalid.adoc` files
1818
[[!.]*.adoc]
1919

20-
BasedOnStyles = RedHat, AsciiDoc
20+
BasedOnStyles = RedHat, AsciiDoc, AsciiDocDITA
2121

2222
# Match INI files. See: https://docs.errata.ai/vale/scoping
2323
[*.ini]
@@ -36,3 +36,4 @@ RedHat.Slash = NO
3636
RedHat.Spacing = NO
3737
RedHat.Spelling = NO
3838
RedHat.TermsSuggestions = NO
39+
AsciiDocDITA.ShortDescription = NO
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Report that admonition titles are not supported.
2+
---
3+
extends: script
4+
message: "Admonition titles are not supported in DITA."
5+
level: warning
6+
scope: raw
7+
script: |
8+
text := import("text")
9+
matches := []
10+
11+
r_comment_line := text.re_compile("^(//|//[^/].*)$")
12+
r_comment_block := text.re_compile("^/{4,}\\s*$")
13+
r_block_title := text.re_compile("^\\.{1,2}[^ \\t.].*$")
14+
r_admonition_para := text.re_compile("^(?:NOTE|TIP|IMPORTANT|WARNING|CAUTION):[ \\t]")
15+
r_admonition_block := text.re_compile("^\\[(?:NOTE|TIP|IMPORTANT|WARNING|CAUTION)\\][ \\t]*$")
16+
r_empty_line := text.re_compile("^[ \\t]*$")
17+
18+
document := text.split(text.trim_suffix(scope, "\n"), "\n")
19+
20+
in_comment_block := false
21+
expect_title := false
22+
expect_admonition := false
23+
start := 0
24+
end := 0
25+
26+
for line in document {
27+
start += end
28+
end = len(line) + 1
29+
30+
if r_comment_block.match(line) {
31+
delimiter := text.trim_space(line)
32+
if ! in_comment_block {
33+
in_comment_block = delimiter
34+
} else if in_comment_block == delimiter {
35+
in_comment_block = false
36+
}
37+
continue
38+
}
39+
if in_comment_block { continue }
40+
if r_comment_line.match(line) { continue }
41+
if r_empty_line.match(line) { continue }
42+
43+
if r_block_title.match(line) {
44+
if expect_title {
45+
matches = append(matches, {begin: start, end: start + end - 1})
46+
expect_title = false
47+
expect_admonition = false
48+
} else {
49+
expect_admonition = {begin: start, end: start + end - 1}
50+
}
51+
} else if r_admonition_block.match(line) {
52+
if expect_admonition {
53+
matches = append(matches, expect_admonition)
54+
expect_admonition = false
55+
expect_title = false
56+
} else {
57+
expect_title = true
58+
}
59+
} else if r_admonition_para.match(line) {
60+
if expect_admonition {
61+
matches = append(matches, expect_admonition)
62+
expect_admonition = false
63+
}
64+
expect_title = false
65+
} else {
66+
expect_title = false
67+
expect_admonition = false
68+
}
69+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Report custom attribute references.
2+
---
3+
extends: existence
4+
message: "%s"
5+
level: suggestion
6+
scope: raw
7+
nonword: true
8+
tokens:
9+
- '\{([0-9A-Za-z][0-9A-Za-z-]*|set:.+?|counter2?:.+?)\}'
10+
exceptions:
11+
- blank
12+
- empty
13+
- sp
14+
- nbsp
15+
- zwsp
16+
- wj
17+
- apos
18+
- quot
19+
- lsquo
20+
- rsquo
21+
- ldquo
22+
- rdquo
23+
- deg
24+
- plus
25+
- brvbar
26+
- vbar
27+
- amp
28+
- lt
29+
- gt
30+
- startsb
31+
- endsb
32+
- caret
33+
- asterisk
34+
- tilde
35+
- backslash
36+
- backtick
37+
- two-colons
38+
- two-semicolons
39+
- cpp
40+
- pp
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Report accidental author lines.
2+
---
3+
extends: script
4+
message: "Author lines are not supported for topics."
5+
level: warning
6+
scope: raw
7+
script: |
8+
text := import("text")
9+
matches := []
10+
11+
r_comment_line := text.re_compile("^(//|//[^/].*)$")
12+
r_comment_block := text.re_compile("^/{4,}\\s*$")
13+
r_document_title := text.re_compile("^=[ \\t]+\\S.*$")
14+
r_attribute := text.re_compile("^:!?\\S[^:]*:")
15+
16+
document := text.split(text.trim_suffix(scope, "\n"), "\n")
17+
18+
in_comment_block := false
19+
need_empty_line := false
20+
start := 0
21+
end := 0
22+
23+
for line in document {
24+
start += end
25+
end = len(line) + 1
26+
27+
if r_comment_block.match(line) {
28+
delimiter := text.trim_space(line)
29+
if ! in_comment_block {
30+
in_comment_block = delimiter
31+
} else if in_comment_block == delimiter {
32+
in_comment_block = false
33+
}
34+
continue
35+
}
36+
if in_comment_block { continue }
37+
if r_comment_line.match(line) { continue }
38+
39+
if r_document_title.match(line) {
40+
if need_empty_line {
41+
matches = append(matches, {begin: start, end: start + end - 1})
42+
break
43+
}
44+
need_empty_line = true
45+
} else if need_empty_line {
46+
if r_attribute.match(line) {
47+
continue
48+
} else if text.trim_space(line) != "" {
49+
matches = append(matches, {begin: start, end: start + end - 1})
50+
}
51+
break
52+
}
53+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Report unsupported block titles.
2+
---
3+
extends: script
4+
message: "Block titles can only be assigned to examples, figures, and tables in DITA."
5+
level: warning
6+
scope: raw
7+
script: |
8+
text := import("text")
9+
matches := []
10+
11+
r_add_resources := text.re_compile("^\\.{1,2}Additional resources[ \\t]*$")
12+
r_attribute_list := text.re_compile("^\\[(?:|[\\w.#%{,\"'].*)\\][ \\t]*$")
13+
r_attribute := text.re_compile("^:!?\\S[^:]*:")
14+
r_block_title := text.re_compile("^\\.{1,2}[^ \\t.].*$")
15+
r_comment_block := text.re_compile("^/{4,}\\s*$")
16+
r_comment_line := text.re_compile("^(//|//[^/].*)$")
17+
r_conditional := text.re_compile("^(?:ifn?def|ifeval|endif)::\\S*\\[.*\\][ \\t]*$")
18+
r_content_type := text.re_compile("^:_(?:mod-docs-content|content|module)-type:[ \\t](?i:procedure)")
19+
r_empty_line := text.re_compile("^[ \\t]*$")
20+
r_example_block := text.re_compile("^\\[example\\][ \\t]*$")
21+
r_example_delim := text.re_compile("^={4,}[ \\t]*$")
22+
r_image := text.re_compile("^image::(?:\\S|\\S.*\\S)\\[.*\\][ \\t]*$")
23+
r_supported_title := text.re_compile("^\\.{1,2}(?:Prerequisites?|Procedure|Verification|Results?|Troubleshooting|Troubleshooting steps?|Next steps?)[ \\t]*$")
24+
r_table_cell := text.re_compile("^\\.[^ \\t|]+\\|")
25+
r_table := text.re_compile("^\\|={3,}[ \\t]*$")
26+
27+
document := text.split(text.trim_suffix(scope, "\n"), "\n")
28+
29+
in_comment_block := false
30+
is_procedure := false
31+
expect_block := false
32+
start := 0
33+
end := 0
34+
35+
for line in document {
36+
start += end
37+
end = len(line) + 1
38+
39+
if r_comment_block.match(line) {
40+
delimiter := text.trim_space(line)
41+
if ! in_comment_block {
42+
in_comment_block = delimiter
43+
} else if in_comment_block == delimiter {
44+
in_comment_block = false
45+
}
46+
continue
47+
}
48+
if in_comment_block { continue }
49+
if r_comment_line.match(line) { continue }
50+
51+
if r_content_type.match(line) {
52+
is_procedure = true
53+
continue
54+
}
55+
56+
if r_attribute_list.match(line) && ! r_example_block.match(line) { continue }
57+
if r_attribute.match(line) { continue }
58+
if r_conditional.match(line) { continue }
59+
if r_empty_line.match(line) { continue }
60+
61+
if r_block_title.match(line) {
62+
if is_procedure && r_supported_title.match(line) { continue }
63+
if r_add_resources.match(line) { continue }
64+
if r_table_cell.match(line) { continue }
65+
66+
expect_block = {begin: start, end: start + end -1}
67+
continue
68+
}
69+
70+
if r_table.match(line) || r_image.match(line) ||
71+
r_example_block.match(line) || r_example_delim.match(line) {
72+
expect_block = false
73+
continue
74+
}
75+
76+
if expect_block {
77+
matches = append(matches, expect_block)
78+
}
79+
80+
expect_block = false
81+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Report conditional directives.
2+
---
3+
extends: existence
4+
message: "%s"
5+
level: suggestion
6+
scope: raw
7+
nonword: true
8+
tokens:
9+
- '^(?:ifn?def|ifeval)::\S*\[.*\][ \t]*$'
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Report a missing content type definition.
2+
---
3+
extends: occurrence
4+
message: "The '_mod-docs-content-type' attribute definition is missing."
5+
level: warning
6+
scope: raw
7+
min: 1
8+
token: '(?:^|[\n\r]):_(?:mod-docs-content|content|module)-type:[ \t]+\S'
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Report cross references that use an ID not defined within the document.
2+
---
3+
extends: existence
4+
message: "Cross references to external IDs cannot be converted to DITA."
5+
level: warning
6+
scope: raw
7+
nonword: true
8+
tokens:
9+
- 'xref:[A-Za-z0-9/.:{].*?(?<!\.adoc#?.*?)\[.*?\]'
10+
- '<<[A-Za-z0-9/.:{].*?>>'
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Report that discrete headings are not supported.
2+
---
3+
extends: existence
4+
message: "Discrete headings are not supported in DITA."
5+
level: warning
6+
scope: raw
7+
nonword: true
8+
tokens:
9+
- '^\[discrete\b[^\n\]]*?\]'
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Report unsupported character entity references.
2+
---
3+
extends: script
4+
message: "HTML character entity references are not supported in DITA."
5+
level: error
6+
scope: raw
7+
script: |
8+
text := import("text")
9+
matches := []
10+
11+
r_comment_line := text.re_compile("^(//|//[^/].*)$")
12+
r_comment_block := text.re_compile("^/{4,}\\s*$")
13+
r_entity_reference := text.re_compile("&[a-zA-Z][a-zA-Z0-9]*;")
14+
r_supported_entity := text.re_compile("&(?:amp|lt|gt|apos|quot);")
15+
16+
document := text.split(text.trim_suffix(scope, "\n"), "\n")
17+
18+
in_comment_block := false
19+
start := 0
20+
end := 0
21+
22+
for line in document {
23+
start += end
24+
end = len(line) + 1
25+
26+
if r_comment_block.match(line) {
27+
delimiter := text.trim_space(line)
28+
if ! in_comment_block {
29+
in_comment_block = delimiter
30+
} else if in_comment_block == delimiter {
31+
in_comment_block = false
32+
}
33+
continue
34+
}
35+
if in_comment_block { continue }
36+
if r_comment_line.match(line) { continue }
37+
38+
for i, entry in r_entity_reference.find(line, -1) {
39+
if ! r_supported_entity.match(entry[0].text) {
40+
matches = append(matches, {begin: start + entry[0].begin, end: start + entry[0].end - 1})
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)