diff --git a/.vale/fixtures/RedHat/YamlEllipses/.vale.ini b/.vale/fixtures/RedHat/YamlEllipses/.vale.ini new file mode 100644 index 00000000..d8d86796 --- /dev/null +++ b/.vale/fixtures/RedHat/YamlEllipses/.vale.ini @@ -0,0 +1,5 @@ +; Vale configuration file to test the `YamlEllipses` rule +StylesPath = ../../../styles +MinAlertLevel = suggestion +[*.adoc] +RedHat.YamlEllipses = YES diff --git a/.vale/fixtures/RedHat/YamlEllipses/testinvalid.adoc b/.vale/fixtures/RedHat/YamlEllipses/testinvalid.adoc new file mode 100644 index 00000000..18378f31 --- /dev/null +++ b/.vale/fixtures/RedHat/YamlEllipses/testinvalid.adoc @@ -0,0 +1,6 @@ +[source,yaml] +---- +... + ... + ... +---- diff --git a/.vale/fixtures/RedHat/YamlEllipses/testvalid.adoc b/.vale/fixtures/RedHat/YamlEllipses/testvalid.adoc new file mode 100644 index 00000000..e6508464 --- /dev/null +++ b/.vale/fixtures/RedHat/YamlEllipses/testvalid.adoc @@ -0,0 +1,9 @@ +[source,yaml] +---- +# ... + # ... +# This is an ordinary comment +---- + +... + diff --git a/.vale/styles/RedHat/YamlEllipses.yml b/.vale/styles/RedHat/YamlEllipses.yml new file mode 100644 index 00000000..41f31336 --- /dev/null +++ b/.vale/styles/RedHat/YamlEllipses.yml @@ -0,0 +1,35 @@ +--- +extends: script +level: suggestion +message: "Use '# ...' instead of '...' in YAML code blocks." +link: https://yaml.org/spec/1.2.2/#22-structures +scope: raw +script: | + text := import("text") + matches := [] + + // clean out multi-line comments + scope = text.re_replace("(?s) *(\n////.*?////\n)", scope, "") + //add a newline, it might be missing + scope += "\n" + + codeblock_delim_regex := "^-{4,}$" + comment_ellipsis := "^# \\.{3}$" + reg_ellipsis := "^\\s*\\.{3}$" + inside_codeblock := false + + for line in text.split(scope, "\n") { + // trim trailing whitespace + line = text.trim_space(line) + //ignore content in codeblocks + if text.re_match(codeblock_delim_regex, line) && inside_codeblock == false { + inside_codeblock = true + } else if text.re_match(codeblock_delim_regex, line) && inside_codeblock == true { + inside_codeblock = false + } + if !text.re_match(comment_ellipsis, line) && text.re_match(reg_ellipsis, line) && inside_codeblock == true { + start := text.index(scope, line) + matches = append(matches, {begin: start, end: start + len(line)}) + } + } + diff --git a/modules/reference-guide/pages/ellipses.adoc b/modules/reference-guide/pages/ellipses.adoc index ad3d863a..9abbc474 100644 --- a/modules/reference-guide/pages/ellipses.adoc +++ b/modules/reference-guide/pages/ellipses.adoc @@ -5,8 +5,12 @@ Avoid ellipsis (...) except to indicate omitted words. +Use a commented out ellipsis (# ...) in YAML code blocks. YAML uses '...' to indicate the end of a document without starting a new one. + .Additional resources * link:{ibmsg-url-print}[{ibmsg-print} - Ellipses, p. 49] * link:{ibmsg-url}?topic=punctuation-ellipses[{ibmsg} - Ellipses] * link:{repository-url}blob/main/.vale/styles/RedHat/Ellipses.yml[`Ellipses.yml` source code] +* link:https://yaml.org/spec/1.2.2/#22-structures[YAML 1.2: Structures] +* link:{repository-url}blob/main/.vale/styles/RedHat/YamlEllipses.yml[`YamlEllipses.yml` source code] diff --git a/tengo-rule-scripts/YamlEllipses.tengo b/tengo-rule-scripts/YamlEllipses.tengo new file mode 100644 index 00000000..9298ae8b --- /dev/null +++ b/tengo-rule-scripts/YamlEllipses.tengo @@ -0,0 +1,42 @@ +/* + Tengo Language + $ tengo ValidYamlCodeBlocks.tengo +*/ + +fmt := import("fmt") +os := import("os") +text := import("text") + +input := os.args() +scope := os.read_file(input[2]) +matches := [] + +// clean out multi-line comments +scope = text.re_replace("(?s) *(\n////.*?////\n)", scope, "") +//add a newline, it might be missing +scope += "\n" + +codeblock_delim_regex := "^-{4,}$" +yaml_block_regex := "^\\[(source,yaml).*\\]" +ellipses := 0 +comment_ellipsis := "^# \\.{3}$" +reg_ellipsis := "^\\s*\\.{3}$" +inside_codeblock := false + +for line in text.split(scope, "\n") { + // trim trailing whitespace + line = text.trim_space(line) + // check only content in codeblocks + if text.re_match(codeblock_delim_regex, line) && inside_codeblock == false { + inside_codeblock = true + } else if text.re_match(codeblock_delim_regex, line) && inside_codeblock == true { + inside_codeblock = false + } + if !text.re_match(comment_ellipsis, line) && text.re_match(reg_ellipsis, line) && inside_codeblock == true { + start := text.index(scope, line) + matches = append(matches, {begin: start, end: start + len(line)}) + } +} + +fmt.println(matches) +