Skip to content

Commit

Permalink
feat: add comment syntax for switching styles (#772)
Browse files Browse the repository at this point in the history
Individual styles can be switched on and off:
```
<!-- vale StyleName1 = YES -->
<!-- vale StyleName2 = NO -->
```
For a rule to be effective both the rule and the style has to be enabled.

`on` and `off` is accepted in addition to `YES` and `NO`
```
<!-- vale StyleName1 = on -->
<!-- vale StyleName2 = off -->
```

Styles can be set (enabling them and switching off any other styles):
```
<!-- vale style = StyleName1 -->
<!-- vale styles = StyleName1, StyleName2 -->
```

Co-authored-by: Joseph Kato <joseph@jdkato.io>
  • Loading branch information
ak-1 and jdkato authored Nov 4, 2024
1 parent 309c52c commit e6eec99
Show file tree
Hide file tree
Showing 4 changed files with 219 additions and 35 deletions.
28 changes: 22 additions & 6 deletions internal/core/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import (
"github.com/errata-ai/vale/v3/internal/nlp"
)

var commentControlRE = regexp.MustCompile(`^vale (.+\..+) = (YES|NO)$`)
var commentControlRE = regexp.MustCompile(`^vale (.+\..+|[^.]+) = (YES|NO|on|off)$`)

var commentStyleRE = regexp.MustCompile(`^vale styles? = (.*)$`)

// A File represents a linted text file.
type File struct {
Expand Down Expand Up @@ -317,19 +319,33 @@ func (f *File) UpdateComments(comment string) {
} else if commentControlRE.MatchString(comment) {
check := commentControlRE.FindStringSubmatch(comment)
if len(check) == 3 {
f.Comments[check[1]] = check[2] == "NO"
f.Comments[check[1]] = (check[2] == "NO" || check[2] == "off")
}
} else if commentStyleRE.MatchString(comment) {
for _, style := range f.BaseStyles {
f.Comments[style] = true
}
check := commentStyleRE.FindStringSubmatch(comment)
for _, style := range strings.Split(check[1], ", ") {
f.Comments[style] = false
}
}
}

// QueryComments checks if there has been an in-text comment for this check.
func (f *File) QueryComments(check string) bool {
if !f.Comments["off"] {
if status, ok := f.Comments[check]; ok {
return status
if f.Comments["off"] {
return true
}
if style, _, ok := strings.Cut(check, "."); ok {
if status := f.Comments[style]; status {
return true
}
}
return f.Comments["off"]
if status := f.Comments[check]; status {
return true
}
return false
}

// ResetComments resets the state of all checks back to active.
Expand Down
94 changes: 65 additions & 29 deletions testdata/features/comments.feature
Original file line number Diff line number Diff line change
@@ -1,35 +1,71 @@
Feature: Comments

Scenario: MDX
When I test comments for ".mdx"
Then the output should contain exactly:
"""
test.mdx:15:19:vale.Redundancy:'ACT test' is redundant
test.mdx:19:19:vale.Redundancy:'ACT test' is redundant
test.mdx:25:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.mdx:77:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.mdx:87:16:demo.Raw:Link "[must not use `.html`](../index.html)" must use the .md file extension.
"""

Scenario: Markdown
When I test comments for ".md"
Then the output should contain exactly:
"""
test.md:15:19:vale.Redundancy:'ACT test' is redundant
test.md:19:19:vale.Redundancy:'ACT test' is redundant
test.md:25:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.md:77:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.md:87:16:demo.Raw:Link "[must not use `.html`](../index.html)" must use the .md file extension.
"""
Scenario: MDX
When I test comments for ".mdx"
Then the output should contain exactly:
"""
test.mdx:15:19:vale.Redundancy:'ACT test' is redundant
test.mdx:19:19:vale.Redundancy:'ACT test' is redundant
test.mdx:25:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.mdx:77:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.mdx:87:16:demo.Raw:Link "[must not use `.html`](../index.html)" must use the .md file extension.
"""

Scenario: Markdown
When I test comments for ".md"
Then the output should contain exactly:
"""
test.md:15:19:vale.Redundancy:'ACT test' is redundant
test.md:19:19:vale.Redundancy:'ACT test' is redundant
test.md:25:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.md:77:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.md:87:16:demo.Raw:Link "[must not use `.html`](../index.html)" must use the .md file extension.
test.md:91:48:demo.Ending-Preposition:Don't end a sentence with 'for.'
test.md:93:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.md:103:19:vale.Redundancy:'ACT test' is redundant
test.md:109:19:vale.Redundancy:'ACT test' is redundant
test.md:109:48:demo.Ending-Preposition:Don't end a sentence with 'for.'
test.md:111:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.md:115:48:demo.Ending-Preposition:Don't end a sentence with 'for.'
test.md:117:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.md:127:19:vale.Redundancy:'ACT test' is redundant
test.md:133:19:vale.Redundancy:'ACT test' is redundant
test.md:133:48:demo.Ending-Preposition:Don't end a sentence with 'for.'
test.md:135:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.md:139:19:vale.Redundancy:'ACT test' is redundant
test.md:145:48:demo.Ending-Preposition:Don't end a sentence with 'for.'
test.md:147:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.md:151:19:vale.Redundancy:'ACT test' is redundant
test.md:151:48:demo.Ending-Preposition:Don't end a sentence with 'for.'
test.md:153:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
"""

Scenario: reStructuredText
When I test comments for ".rst"
Then the output should contain exactly:
"""
test.rst:15:19:vale.Redundancy:'ACT test' is redundant
test.rst:19:19:vale.Redundancy:'ACT test' is redundant
test.rst:25:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
"""
Scenario: reStructuredText
When I test comments for ".rst"
Then the output should contain exactly:
"""
test.rst:15:19:vale.Redundancy:'ACT test' is redundant
test.rst:19:19:vale.Redundancy:'ACT test' is redundant
test.rst:25:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.rst:41:48:demo.Ending-Preposition:Don't end a sentence with 'for.'
test.rst:43:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.rst:53:19:vale.Redundancy:'ACT test' is redundant
test.rst:59:19:vale.Redundancy:'ACT test' is redundant
test.rst:59:48:demo.Ending-Preposition:Don't end a sentence with 'for.'
test.rst:61:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.rst:65:48:demo.Ending-Preposition:Don't end a sentence with 'for.'
test.rst:67:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.rst:77:19:vale.Redundancy:'ACT test' is redundant
test.rst:83:19:vale.Redundancy:'ACT test' is redundant
test.rst:83:48:demo.Ending-Preposition:Don't end a sentence with 'for.'
test.rst:85:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.rst:89:19:vale.Redundancy:'ACT test' is redundant
test.rst:95:48:demo.Ending-Preposition:Don't end a sentence with 'for.'
test.rst:97:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
test.rst:101:19:vale.Redundancy:'ACT test' is redundant
test.rst:101:48:demo.Ending-Preposition:Don't end a sentence with 'for.'
test.rst:103:20:demo.Ending-Preposition:Don't end a sentence with 'of.'
"""

Scenario: AsciiDoc
When I test comments for ".adoc"
Expand Down
66 changes: 66 additions & 0 deletions testdata/fixtures/comments/test.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,69 @@ This is a sentance of.
<!-- vale demo.Raw = NO -->

Internal Links [must not use `.html`](../index.html)

<!-- vale vale = off -->

This is some text ACT test. This is a sentence for.

This is a sentance of.

<!-- vale demo = off -->

This is some text ACT test. This is a sentence for.

This is a sentance of.

<!-- vale vale = on -->

This is some text ACT test. This is a sentence for.

This is a sentance of.

<!-- vale demo = on -->

This is some text ACT test. This is a sentence for.

This is a sentance of.

<!-- vale vale = NO -->

This is some text ACT test. This is a sentence for.

This is a sentance of.

<!-- vale demo = NO -->

This is some text ACT test. This is a sentence for.

This is a sentance of.

<!-- vale vale = YES -->

This is some text ACT test. This is a sentence for.

This is a sentance of.

<!-- vale demo = YES -->

This is some text ACT test. This is a sentence for.

This is a sentance of.

<!-- vale style = vale -->

This is some text ACT test. This is a sentence for.

This is a sentance of.

<!-- vale style = demo -->

This is some text ACT test. This is a sentence for.

This is a sentance of.

<!-- vale styles = vale, demo -->

This is some text ACT test. This is a sentence for.

This is a sentance of.
66 changes: 66 additions & 0 deletions testdata/fixtures/comments/test.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,69 @@ The default types are as follows:
- Virtual

.. vale on
.. vale vale = off
This is some text ACT test. This is a sentance for.

This is a sentance of.

.. vale demo = off
This is some text ACT test. This is a sentance for.

This is a sentance of.

.. vale vale = on
This is some text ACT test. This is a sentance for.

This is a sentance of.

.. vale demo = on
This is some text ACT test. This is a sentance for.

This is a sentance of.

.. vale vale = NO
This is some text ACT test. This is a sentance for.

This is a sentance of.

.. vale demo = NO
This is some text ACT test. This is a sentance for.

This is a sentance of.

.. vale vale = YES
This is some text ACT test. This is a sentance for.

This is a sentance of.

.. vale demo = YES
This is some text ACT test. This is a sentance for.

This is a sentance of.

.. vale style = vale
This is some text ACT test. This is a sentance for.

This is a sentance of.

.. vale style = demo
This is some text ACT test. This is a sentance for.

This is a sentance of.

.. vale styles = vale, demo
This is some text ACT test. This is a sentance for.

This is a sentance of.

0 comments on commit e6eec99

Please sign in to comment.