Skip to content

Commit 0bde563

Browse files
jedudenclaude
andauthored
Add MDS041 rule to flag raw HTML in Markdown documents (#199)
* Implement MDS041 no-inline-html rule Adds a new opt-in rule (MDS041) that flags raw HTML in Markdown — both block-level HTMLBlock nodes and inline RawHTML nodes — with configurable `allow` (tag allowlist) and `allow-comments` settings. PI directives, autolinks, code blocks, and closing tags are unconditionally skipped. Includes unit tests, integration fixtures, rule README, and registration in main + integration test runner. https://claude.ai/code/session_01MmZvugtRBav5yYwZ4gzZYS * Fix coverage gaps in noinlinehtml rule Remove unreachable defensive guards in htmlBlockBytes, blockLine, and inlineLine (goldmark always produces non-empty Lines for HTMLBlock and non-empty Segments for RawHTML). Add TestMetadata to cover Category(). Rule package is now at 100% statement coverage. https://claude.ai/code/session_01MmZvugtRBav5yYwZ4gzZYS * Address Copilot review: accurate column, fix comment message - Compute line and column from the raw byte offset (via lineColOfOffset) so inline HTML mid-line reports the correct column instead of always 1. - Fix comment diagnostic message from confusing "inline HTML <<!--> is not allowed" to "inline HTML <!-- is not allowed" by passing the display string pre-formatted instead of wrapping all tags in <>. - Update unit tests to assert correct column numbers. - Update bad fixtures to match the new column and message values. https://claude.ai/code/session_01MmZvugtRBav5yYwZ4gzZYS * Fix HTMLBlock column for indented block HTML CommonMark allows up to 3 spaces of indentation before block HTML. Use bytes.IndexByte to find the '<' within the line segment so the reported column points at the tag rather than the start of the line. Add TestCheck_IndentedBlockHTML_CorrectColumn to cover this path. https://claude.ai/code/session_01MmZvugtRBav5yYwZ4gzZYS --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 6af677f commit 0bde563

16 files changed

Lines changed: 659 additions & 57 deletions

File tree

PLAN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ footer: |
2121
| 102 | 🔲 | opus | [Builder interface and mdsmith build subcommand](plan/102_build-subcommand.md) |
2222
| 103 | 🔲 | opus | [Build target staleness and dependency tracking](plan/103_build-staleness-and-deps.md) |
2323
| 104 | 🔲 | sonnet | [Build lifecycle hooks (before/after)](plan/104_build-lifecycle-hooks.md) |
24-
| 105 | 🔲 | sonnet | [No inline HTML rule](plan/105_no-inline-html.md) |
24+
| 105 | | sonnet | [No inline HTML rule](plan/105_no-inline-html.md) |
2525
| 106 | 🔲 | sonnet | [Emphasis style rule](plan/106_emphasis-style.md) |
2626
| 107 | 🔲 | opus | [No reference-style links rule](plan/107_no-reference-style.md) |
2727
| 108 | 🔲 | sonnet | [Horizontal rule style rule](plan/108_horizontal-rule-style.md) |

cmd/mdsmith/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import (
4949
_ "github.com/jeduden/mdsmith/internal/rules/noemphasisasheading"
5050
_ "github.com/jeduden/mdsmith/internal/rules/noemptyalttext"
5151
_ "github.com/jeduden/mdsmith/internal/rules/nohardtabs"
52+
_ "github.com/jeduden/mdsmith/internal/rules/noinlinehtml"
5253
_ "github.com/jeduden/mdsmith/internal/rules/nomultipleblanks"
5354
_ "github.com/jeduden/mdsmith/internal/rules/notrailingpunctuation"
5455
_ "github.com/jeduden/mdsmith/internal/rules/notrailingspaces"

internal/integration/rules_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import (
4141
_ "github.com/jeduden/mdsmith/internal/rules/noemphasisasheading"
4242
_ "github.com/jeduden/mdsmith/internal/rules/noemptyalttext"
4343
_ "github.com/jeduden/mdsmith/internal/rules/nohardtabs"
44+
_ "github.com/jeduden/mdsmith/internal/rules/noinlinehtml"
4445
_ "github.com/jeduden/mdsmith/internal/rules/nomultipleblanks"
4546
_ "github.com/jeduden/mdsmith/internal/rules/notrailingpunctuation"
4647
_ "github.com/jeduden/mdsmith/internal/rules/notrailingspaces"
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
---
2+
id: MDS041
3+
name: no-inline-html
4+
status: ready
5+
description: >-
6+
Raw HTML tags in Markdown are not allowed; use a
7+
Markdown construct or an mdsmith directive instead.
8+
---
9+
# MDS041: no-inline-html
10+
11+
Raw HTML tags in Markdown are not allowed; use a
12+
Markdown construct or an mdsmith directive instead.
13+
14+
## Config
15+
16+
Enable with default settings (empty allowlist,
17+
comments permitted):
18+
19+
```yaml
20+
rules:
21+
no-inline-html: true
22+
```
23+
24+
Enable with specific tags allowed:
25+
26+
```yaml
27+
rules:
28+
no-inline-html:
29+
allow: [kbd, sub, sup]
30+
allow-comments: true
31+
```
32+
33+
Disable:
34+
35+
```yaml
36+
rules:
37+
no-inline-html: false
38+
```
39+
40+
### Settings
41+
42+
| Setting | Type | Default | Description |
43+
|------------------|-----------------|---------|--------------------------------------------------------|
44+
| `allow` | list of strings | `[]` | Tag names that are permitted (replaces, not appended). |
45+
| `allow-comments` | bool | `true` | Whether HTML comments (`<!-- ... -->`) are allowed. |
46+
47+
## Examples
48+
49+
### Bad
50+
51+
<?include
52+
file: bad/inline-span.md
53+
wrap: markdown
54+
?>
55+
56+
```markdown
57+
# Title
58+
59+
text <span>x</span> text
60+
```
61+
62+
<?/include?>
63+
64+
### Good
65+
66+
<?include
67+
file: good/allowed-tag.md
68+
wrap: markdown
69+
?>
70+
71+
```markdown
72+
# Title
73+
74+
Press <kbd>Enter</kbd> to continue.
75+
```
76+
77+
<?/include?>
78+
79+
## What is not flagged
80+
81+
- Fenced and indented code blocks containing HTML
82+
- Inline code spans
83+
- Autolinks (`<https://example.com>`)
84+
- mdsmith directives (`<?name ... ?>`) — block forms
85+
are parsed as `ProcessingInstruction` nodes; inline
86+
forms are skipped because they start with `<?`
87+
- HTML entities in text (`&amp;`, `&#x2014;`)
88+
- Closing tags (`</div>`) — the matching opening tag
89+
already produced a diagnostic
90+
91+
## Meta-Information
92+
93+
- **ID**: MDS041
94+
- **Name**: `no-inline-html`
95+
- **Status**: ready
96+
- **Default**: disabled (opt-in)
97+
- **Fixable**: no
98+
- **Implementation**:
99+
[source](./)
100+
- **Category**: meta
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
settings:
3+
allow-comments: true
4+
diagnostics:
5+
- line: 3
6+
column: 1
7+
message: "inline HTML <div> is not allowed"
8+
---
9+
# Title
10+
11+
<div>block content</div>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
settings:
3+
allow-comments: false
4+
diagnostics:
5+
- line: 3
6+
column: 1
7+
message: "inline HTML <!-- is not allowed"
8+
---
9+
# Title
10+
11+
<!-- this comment is not allowed -->
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
settings:
3+
allow-comments: true
4+
diagnostics:
5+
- line: 3
6+
column: 6
7+
message: "inline HTML <span> is not allowed"
8+
---
9+
# Title
10+
11+
text <span>x</span> text
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
settings:
3+
allow-comments: true
4+
diagnostics:
5+
- line: 3
6+
column: 5
7+
message: "inline HTML <br> is not allowed"
8+
---
9+
# Title
10+
11+
text<br/>more text
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
settings:
3+
allow:
4+
- kbd
5+
allow-comments: true
6+
---
7+
# Title
8+
9+
Press <kbd>Enter</kbd> to continue.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
settings:
3+
allow-comments: true
4+
---
5+
# Title
6+
7+
See <https://example.com> for details.

0 commit comments

Comments
 (0)