a11y-lint 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -0
- data/CHANGELOG.md +12 -0
- data/CLAUDE.md +4 -1
- data/README.md +2 -2
- data/lib/a11y/lint/cli.rb +6 -3
- data/lib/a11y/lint/erb_node.rb +42 -0
- data/lib/a11y/lint/erb_runner.rb +67 -0
- data/lib/a11y/lint/{runner.rb → slim_runner.rb} +1 -1
- data/lib/a11y/lint/version.rb +1 -1
- data/lib/a11y/lint.rb +4 -1
- metadata +18 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: df2381933d808c2694937750b55b63897d22feb8b3726e8635504afa6bcb320b
|
|
4
|
+
data.tar.gz: 5b04343e74f0ebb363cb2b2c065d67b9b20398d4b5bd12e86e89fe38a7bcfa8d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4a71a89a925316ae52107958bed1cdc927d653ccc0425b81ad2bca612f694cdc63b52d9c277f24c1957976e5972ed5c810b831f150c353393014908e7e187a6d
|
|
7
|
+
data.tar.gz: d9982d126da0a7f412d8d43b68e90b27fcde739a3b08c2b6cc0e948241eb18b95e9e42542e5bb7ce75048f389fec11351901da0e900076369c3889d1e8c16b0a
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.0] - 2026-03-27
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- ERB template support: scans `.erb` files using Nokogiri for HTML parsing
|
|
15
|
+
- Both `ImgMissingAlt` and `ImageTagMissingAlt` rules now work on ERB templates
|
|
16
|
+
- CLI automatically detects and routes `.slim` and `.erb` files to the appropriate runner
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- **Breaking:** `Runner` has been renamed to `SlimRunner`
|
|
21
|
+
|
|
10
22
|
## [0.3.1] - 2026-03-27
|
|
11
23
|
|
|
12
24
|
### Fixed
|
data/CLAUDE.md
CHANGED
|
@@ -19,8 +19,11 @@ a11y-lint is a Ruby gem (v0.1.0) for accessibility linting. It uses the `A11y::L
|
|
|
19
19
|
|
|
20
20
|
## Architecture
|
|
21
21
|
|
|
22
|
-
- **CLI:** `lib/a11y/lint/cli.rb` — command-line interface; executable at `exe/a11y-lint`
|
|
22
|
+
- **CLI:** `lib/a11y/lint/cli.rb` — command-line interface; executable at `exe/a11y-lint`; routes `.slim` files to `SlimRunner` and `.erb` files to `ErbRunner`
|
|
23
23
|
- **Entry point:** `lib/a11y/lint.rb` — defines the `A11y::Lint` module and `A11y::Lint::Error` exception
|
|
24
|
+
- **Slim pipeline:** `SlimRunner` parses Slim templates via `Slim::Parser`; `Node` wraps Slim S-expressions
|
|
25
|
+
- **ERB pipeline:** `ErbRunner` parses ERB templates via Nokogiri; `ErbNode` wraps Nokogiri nodes and extracted `<%= %>` Ruby code
|
|
26
|
+
- **Rules:** `lib/a11y/lint/rules/` — rules implement `check(node)` against the shared node interface (`tag_name`, `attribute?`, `attributes`, `ruby_code`, `line`)
|
|
24
27
|
- **Version:** `lib/a11y/lint/version.rb`
|
|
25
28
|
- **Type signatures (RBS):** `sig/a11y/lint.rbs`
|
|
26
29
|
- **Tests:** `test/` directory using Minitest; test helper at `test/test_helper.rb`
|
data/README.md
CHANGED
|
@@ -33,7 +33,7 @@ a11y-lint app/views/
|
|
|
33
33
|
a11y-lint app/views/home.html.slim app/views/about.html.slim
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
With no arguments, it scans the current directory recursively for `.slim` files:
|
|
36
|
+
With no arguments, it scans the current directory recursively for `.slim` and `.erb` files:
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
39
|
a11y-lint
|
|
@@ -45,7 +45,7 @@ a11y-lint
|
|
|
45
45
|
require "a11y/lint"
|
|
46
46
|
|
|
47
47
|
source = File.read("app/views/home.html.slim")
|
|
48
|
-
runner = A11y::Lint::
|
|
48
|
+
runner = A11y::Lint::SlimRunner.new([A11y::Lint::Rules::ImgMissingAlt.new])
|
|
49
49
|
offenses = runner.run(source, filename: "app/views/home.html.slim")
|
|
50
50
|
|
|
51
51
|
offenses.each do |offense|
|
data/lib/a11y/lint/cli.rb
CHANGED
|
@@ -17,7 +17,7 @@ module A11y
|
|
|
17
17
|
files = resolve_files(@argv)
|
|
18
18
|
|
|
19
19
|
if files.empty?
|
|
20
|
-
@stderr.puts("No .slim files found")
|
|
20
|
+
@stderr.puts("No .slim or .erb files found")
|
|
21
21
|
return 0
|
|
22
22
|
end
|
|
23
23
|
|
|
@@ -56,7 +56,7 @@ module A11y
|
|
|
56
56
|
|
|
57
57
|
def expand_path(path)
|
|
58
58
|
if File.directory?(path)
|
|
59
|
-
Dir.glob(File.join(path, "**", "*.slim"))
|
|
59
|
+
Dir.glob(File.join(path, "**", "*.{slim,erb}"))
|
|
60
60
|
elsif File.file?(path)
|
|
61
61
|
[path]
|
|
62
62
|
else
|
|
@@ -66,10 +66,13 @@ module A11y
|
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
def lint_files(files)
|
|
69
|
-
|
|
69
|
+
rules = all_rules
|
|
70
|
+
slim_runner = SlimRunner.new(rules)
|
|
71
|
+
erb_runner = ErbRunner.new(rules)
|
|
70
72
|
|
|
71
73
|
files.flat_map do |file|
|
|
72
74
|
source = File.read(file)
|
|
75
|
+
runner = file.end_with?(".erb") ? erb_runner : slim_runner
|
|
73
76
|
runner.run(source, filename: file)
|
|
74
77
|
end
|
|
75
78
|
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module A11y
|
|
4
|
+
module Lint
|
|
5
|
+
# Wraps a Nokogiri node or extracted ERB output tag as a queryable node for lint rules.
|
|
6
|
+
class ErbNode
|
|
7
|
+
attr_reader :line
|
|
8
|
+
|
|
9
|
+
def initialize(line:, nokogiri_node: nil, ruby_code: nil)
|
|
10
|
+
@nokogiri_node = nokogiri_node
|
|
11
|
+
@ruby_code_string = ruby_code
|
|
12
|
+
@line = line
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def tag_name
|
|
16
|
+
@nokogiri_node&.name
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def attribute?(name)
|
|
20
|
+
attributes.key?(name)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def attributes
|
|
24
|
+
@attributes ||= extract_attributes
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def ruby_code
|
|
28
|
+
@ruby_code_string
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def extract_attributes
|
|
34
|
+
return {} unless @nokogiri_node
|
|
35
|
+
|
|
36
|
+
@nokogiri_node.attributes.each_with_object({}) do |(name, _attr), result|
|
|
37
|
+
result[name] = true
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "nokogiri"
|
|
4
|
+
|
|
5
|
+
module A11y
|
|
6
|
+
module Lint
|
|
7
|
+
# Parses ERB templates and checks them against accessibility rules.
|
|
8
|
+
class ErbRunner
|
|
9
|
+
ERB_TAG = /<%.*?%>/m
|
|
10
|
+
ERB_OUTPUT_TAG = /<%=\s*(.*?)\s*-?%>/m
|
|
11
|
+
|
|
12
|
+
def initialize(rules)
|
|
13
|
+
@rules = rules
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def run(source, filename:)
|
|
17
|
+
@filename = filename
|
|
18
|
+
@offenses = []
|
|
19
|
+
|
|
20
|
+
check_html_nodes(source)
|
|
21
|
+
check_erb_output_tags(source)
|
|
22
|
+
|
|
23
|
+
@offenses
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
attr_reader :rules
|
|
29
|
+
|
|
30
|
+
def check_html_nodes(source)
|
|
31
|
+
html = source.gsub(ERB_TAG, "")
|
|
32
|
+
doc = Nokogiri::HTML4::DocumentFragment.parse(html)
|
|
33
|
+
|
|
34
|
+
doc.traverse do |nokogiri_node|
|
|
35
|
+
next unless nokogiri_node.element?
|
|
36
|
+
|
|
37
|
+
node = ErbNode.new(nokogiri_node: nokogiri_node, line: nokogiri_node.line)
|
|
38
|
+
check_node(node)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def check_erb_output_tags(source)
|
|
43
|
+
source.scan(ERB_OUTPUT_TAG) do
|
|
44
|
+
match = Regexp.last_match
|
|
45
|
+
code = match[1]
|
|
46
|
+
line_number = source[0...match.begin(0)].count("\n") + 1
|
|
47
|
+
node = ErbNode.new(ruby_code: code, line: line_number)
|
|
48
|
+
check_node(node)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def check_node(node)
|
|
53
|
+
rules.each do |rule|
|
|
54
|
+
message = rule.check(node)
|
|
55
|
+
next unless message
|
|
56
|
+
|
|
57
|
+
@offenses << Offense.new(
|
|
58
|
+
rule: rule.name,
|
|
59
|
+
filename: @filename,
|
|
60
|
+
line: node.line,
|
|
61
|
+
message: message
|
|
62
|
+
)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
data/lib/a11y/lint/version.rb
CHANGED
data/lib/a11y/lint.rb
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "slim"
|
|
4
|
+
require "nokogiri"
|
|
4
5
|
require_relative "lint/version"
|
|
5
6
|
require_relative "lint/offense"
|
|
6
7
|
require_relative "lint/node"
|
|
8
|
+
require_relative "lint/erb_node"
|
|
7
9
|
require_relative "lint/rule"
|
|
8
10
|
require_relative "lint/rules/image_tag_missing_alt"
|
|
9
11
|
require_relative "lint/rules/img_missing_alt"
|
|
10
|
-
require_relative "lint/
|
|
12
|
+
require_relative "lint/slim_runner"
|
|
13
|
+
require_relative "lint/erb_runner"
|
|
11
14
|
|
|
12
15
|
module A11y
|
|
13
16
|
module Lint
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: a11y-lint
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Abdullah Hashim
|
|
@@ -9,6 +9,20 @@ bindir: exe
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: nokogiri
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.13'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '1.13'
|
|
12
26
|
- !ruby/object:Gem::Dependency
|
|
13
27
|
name: slim
|
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -42,12 +56,14 @@ files:
|
|
|
42
56
|
- exe/a11y-lint
|
|
43
57
|
- lib/a11y/lint.rb
|
|
44
58
|
- lib/a11y/lint/cli.rb
|
|
59
|
+
- lib/a11y/lint/erb_node.rb
|
|
60
|
+
- lib/a11y/lint/erb_runner.rb
|
|
45
61
|
- lib/a11y/lint/node.rb
|
|
46
62
|
- lib/a11y/lint/offense.rb
|
|
47
63
|
- lib/a11y/lint/rule.rb
|
|
48
64
|
- lib/a11y/lint/rules/image_tag_missing_alt.rb
|
|
49
65
|
- lib/a11y/lint/rules/img_missing_alt.rb
|
|
50
|
-
- lib/a11y/lint/
|
|
66
|
+
- lib/a11y/lint/slim_runner.rb
|
|
51
67
|
- lib/a11y/lint/version.rb
|
|
52
68
|
- sig/a11y/lint.rbs
|
|
53
69
|
homepage: https://github.com/Guided-Rails/a11y-lint
|