erb-linter 0.0.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7852edfabee0e8808f79b8722b4256a3ddb37cd0d4dcd5581ebd4c505eeb7aca
4
- data.tar.gz: 7988dbbceb52230a05fbb67a6ab638b37ea5eb068b1d6963b5fe278e66abdf66
3
+ metadata.gz: 44674209663a884ffa87821eea1396fdcfa779c67b7c1480c625b04111ffc645
4
+ data.tar.gz: f450b5dd3c9321c7f8854dcf68bb6dc38cf348b1cfab3c62b91fb73a6ebf5608
5
5
  SHA512:
6
- metadata.gz: 39f296bfb232df44446f560f44e27ff8c67a4f9302fd64eb3f73005a35bf60de786c55d59a520e84fa08ac5c241ea5534b26d16ddcfba5d00847e34542651b70
7
- data.tar.gz: f02389ff2ab6cfd34ff41596c26f93be8e8d2bec559a50c0978282e2de47997fae104ec59b498128ae27423531325d5e2750ccf0ae8ce92b01573dbd06b1e628
6
+ metadata.gz: 8a37692b76c98aa006fab462b58936a6b00cf4902a3badaf328406622267414abdd32a88c871bf742f10ce6a93793cf39b2239a9bfb55745a2c11a06edbcfc36
7
+ data.tar.gz: e14e4343a76cf0964e95ad73406a4e271be504ff1319096445778de58ddc2fa777e3638856650135ec6332f5b022d25382621f01d091009b6f7279fe4b0c0c4a
@@ -0,0 +1,26 @@
1
+ on:
2
+ - push
3
+ - pull_request
4
+
5
+ name: test
6
+
7
+ jobs:
8
+ test:
9
+ name: "ruby ${{ matrix.ruby }}"
10
+
11
+ strategy:
12
+ matrix:
13
+ os: [ 'ubuntu-latest' ]
14
+ ruby: [ "3.0", "2.7", "2.6", "2.5" ]
15
+
16
+ runs-on: ${{ matrix.os }}
17
+
18
+ steps:
19
+ - uses: actions/checkout@v2
20
+ - uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: ${{ matrix.ruby }}
23
+ - name: Setup project
24
+ run: bin/setup
25
+ - name: Run test
26
+ run: bin/rake
data/.gitignore CHANGED
@@ -6,3 +6,4 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ Gemfile.lock
data/README.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  <a href="https://nebulab.it?utm_source=github&utm_medium=badge"><img src="https://img.shields.io/static/v1?label=Nebulab&message=Open+Source&color=%235dbefd&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMQSURBVHgBrZZNTxNRFIbfczsgIMQiLBCRFDaGhUr9A9iiIa5EEneIwE/AlRsNv8KlIKwFl35RTUBX8rFBdiVKAgqmXSCY0M71nJl+zJTOdKh9k6Yzc8/cZ86555x7CQE0mji5hSyGlQoNaOgIPwrnhtIArWszu4EQFudjdR8rzUV+gw8/ZMZB9IwvIwimJJGafhmjWZwFOJ7QkYzWCwTdj+qUDJGKz8Rou3RAlT4YS+hHWW2u/QdM1MNzrI6+zwyXDrg8FANStIDaSXOIJ5whLgAljOIZiglRK6U4vDfz4S2ElGGJWsEaQkCTUbhtNbV+lb+xgFY2Bs9ET0h/GzBxlfAkqnCUKY5xKfVLbsi1/R126lcF6WgCYp2ES42EBp6tvQFY+alLTUlrUxizJEVNWiVwBkVagGg7oe+CDclLYOfrgMdfTBz8PfWa1lkzbsDEsH/5FyF9YUK0zQ1xwpoZtsm9pwxMRLyA9wyi0A2Jcjl1NNqeeEFEimxYPkmWd014ikIDnDTeBb53DOweaRxnvWGyhnmYfPZWGt487sNi6lsK67/lZ1oZGOtUaD3nhtU7etXXfe0VzrzCBgLKCR68rNDX6oaJlvd0xXnklbSfgSTL/QghXF8EP980cVKyVL/Ys9UDVFJa8Tdt+1lYmcmJM3Vd4UEvWeslRf32h9ubrVRl77gBrCto85OfUU+LXTMGx+JuN2Hoin3/Zkfjj6ObBAknV+KG4jpc9BqXMEpiCMz6Z9ZQ12kvJZxb6co4Zr1W83esY8F2OYsIe+eEyfTiVXczCl7uM2wliHfMEJaRc3Wa++mLUotrF4EW7h6f94Dvh6aVFM60Fy8Xkya+BfBOjh5yUWhqY0vmKi9q1GnVxZ7sHKIWSs7FQ71yUagkRTTCfymnVY1gsgHHC5z8hbUjaz0Fr8ZanXhX0pPOw5SrV8wNGjNscMrTKpXKaj05f9twVYHnMZGPHEuwTwEBNi+3NGiNt6GRcsfEIAfhp2cAV3cQLtXoOz7q8+ZJRLx3kmxn4dy7aas1SrfiBpKraV/9A+PSJLDAXLUvAAAAAElFTkSuQmCC"></a>
4
4
 
5
- It's all to easy to introduce errors inside ERB files, unclosed tags, wrong attribute names, bad indentation.
5
+ [![test](https://github.com/nebulab/erb-linter/actions/workflows/test.yml/badge.svg)](https://github.com/nebulab/erb-linter/actions/workflows/test.yml)
6
+
7
+ It's all too easy to introduce errors inside ERB files, unclosed tags, wrong attribute names, bad indentation.
6
8
 
7
9
  ERB::Linter can check for those errors by turning your ERB tags into HTML-ish tags and run a proper HTML linter on the result:
8
10
 
@@ -45,13 +47,9 @@ Add this line to your application's Gemfile:
45
47
  gem 'erb-linter'
46
48
  ```
47
49
 
48
- And then execute:
49
-
50
- $ bundle install
50
+ And add `linthtml` to yarn:
51
51
 
52
- Or install it yourself as:
53
-
54
- $ gem install erb-linter
52
+ $ yarn add --dev @linthtml/linthtml
55
53
 
56
54
  ## Usage
57
55
 
@@ -81,7 +79,9 @@ ERB::Linter::Task.new do |task|
81
79
  end
82
80
  ```
83
81
 
84
- Add a `linthtml` configuration:
82
+ ### Example linthtml configuration
83
+
84
+ And then add a `linthtml` configuration like this:
85
85
 
86
86
  `.linthtmlrc.js`
87
87
 
data/bin/rake ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rake' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("rake", "rake")
data/lib/erb/linter.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  require "erb"
4
4
 
5
5
  module ERB::Linter
6
- VERSION = "0.0.1"
6
+ VERSION = "0.2.0"
7
7
 
8
8
  class Error < StandardError; end
9
9
 
@@ -2,43 +2,82 @@
2
2
 
3
3
  require "cgi"
4
4
  require "ripper"
5
+ require 'securerandom'
6
+ require 'strscan'
5
7
 
6
8
  module ERB::Linter::Converter
7
9
  extend self
8
10
 
9
- # Credit to the Deface gem
11
+ # https://stackoverflow.com/a/317081
12
+ ATTR_NAME = %r{[^\r\n\t\f\v= '"<>]*[^\r\n\t\f\v= '"<>/]} # not ending with a slash
13
+ UNQUOTED_VALUE = ATTR_NAME
14
+ UNQUOTED_ATTR = %r{#{ATTR_NAME}=#{UNQUOTED_VALUE}}
15
+ SINGLE_QUOTE_ATTR = %r{(?:#{ATTR_NAME}='[^']*')}
16
+ DOUBLE_QUOTE_ATTR = %r{(?:#{ATTR_NAME}="[^"]*")}
17
+
18
+ ERB_TAG = %r{<%.*?%>}
19
+ HTML_ATTR = %r{\s+#{SINGLE_QUOTE_ATTR}|\s+#{DOUBLE_QUOTE_ATTR}|\s+#{UNQUOTED_ATTR}|\s+#{ATTR_NAME}}
20
+ HTML_TAG = %r{(<\w+)((?:#{HTML_ATTR})*)(\s*)(/>|>)}m
21
+
22
+ # (credit goes to the Deface gem for the original implementation)
10
23
  def erb2html(source)
11
24
  source = +source
12
25
 
13
- # all opening html tags that contain <% %> blocks
14
- source.scan(/<\w+[^<>]+(?:<%.*?%>[^<>]*)+/m).each do |line|
15
- # regexs to catch <% %> inside attributes id="<% something %>" - with double, single or no quotes
16
- erb_attrs_regexs = [
17
- /([\w-]+)(\s?=\s?)(")([^"]*<%.*?%>[^"]*)/m,
18
- /([\w-]+)(\s?=\s?)(')([^']*<%.*?%>[^']*)'/m,
19
- /([\w-]+)(\s?=\s?)()(<%.*?%>)(?:\s|>|\z)/m,
20
- ]
21
-
22
- # rubocop:disable Linter/ShadowingOuterLocalVariable
23
- replace_line = erb_attrs_regexs.inject(line.clone) do |replace_line, regex|
24
- replace_line = line.scan(regex).inject(replace_line) do |replace_line, match|
25
- replace_line.sub("#{match[0]}#{match[1]}#{match[2]}#{match[3]}#{match[2]}") { "data-erb-#{match[0]}=\"#{CGI.escapeHTML(match[3])}\"" }
26
- end
26
+ # encode all erb tags so that the HTML looks valid
27
+ erb_tags = {}
28
+ source.gsub!(ERB_TAG) do |tag|
29
+ uid = ["ERB_", SecureRandom.uuid].join.delete('-')
30
+ erb_tags[uid] = tag
31
+ uid
32
+ end
27
33
 
28
- replace_line
29
- end
30
- # rubocop:enable Linter/ShadowingOuterLocalVariable
34
+ erb_tags_matcher = Regexp.union(erb_tags.keys)
35
+
36
+ # transform/escape all the erb-attributes first
37
+ source.gsub!(HTML_TAG).each do |match|
38
+ line = Regexp.last_match.to_a[1..-1]
39
+ tag = [line[0], line[2]+line[3]]
40
+
41
+ # scan each attribute into an array
42
+ attr_scanner = StringScanner.new(line[1])
43
+ attributes = []
44
+ attributes << (attr_scanner.scan(HTML_ATTR) or raise "Can't scan: #{attr_scanner.string}") until attr_scanner.eos?
45
+ # attributes.compact!
31
46
 
32
47
  i = -1
48
+ attributes.map! do |attribute|
49
+ if attribute.match?(erb_tags_matcher)
50
+ space, attribute = attribute.scan(/\A(\s+)(.*)\z/m).flatten
51
+ attribute.gsub!(erb_tags_matcher, erb_tags)
52
+
53
+ attribute =
54
+ case attribute
55
+ when /\A#{ERB_TAG}\z/
56
+ %{data-erb-#{i += 1}="#{CGI.escapeHTML(attribute)}"}
57
+ when /\A#{ATTR_NAME}=/
58
+ name, value = attribute.split("=", 2)
59
+ quote = '"'
60
+ if value.match(/\A['"]/)
61
+ quote = value[0]
62
+ value = value[1...-1]
63
+ end
64
+ %{data-erb-#{name}=#{quote}#{CGI.escapeHTML(value)}#{quote}}
65
+ else
66
+ raise "Don't know how to process attribute: #{attribute.inspect}"
67
+ end
33
68
 
34
- # catch all <% %> inside tags id <p <%= test %>> , not inside attrs
35
- replace_line.scan(/(<%.*?%>)/m).each do |match|
36
- replace_line.sub!(match[0], " data-erb-#{i += 1}=\"#{CGI.escapeHTML(match[0])}\"")
69
+ "#{space}#{attribute}"
70
+ else
71
+ attribute
72
+ end
37
73
  end
38
74
 
39
- source.sub!(line, replace_line)
75
+ [tag[0], *attributes, tag[1]].join
40
76
  end
41
77
 
78
+ # restore the encoded erb tags
79
+ source.gsub!(erb_tags_matcher, erb_tags)
80
+
42
81
  # replaces all <% %> not inside opening html tags
43
82
  replacements = [
44
83
  { %r{<%\s*end\s*-?%>} => "</erb>" },
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: erb-linter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elia Schito
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-31 00:00:00.000000000 Z
11
+ date: 2021-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -31,13 +31,14 @@ executables: []
31
31
  extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
+ - ".github/workflows/test.yml"
34
35
  - ".gitignore"
35
36
  - Gemfile
36
- - Gemfile.lock
37
37
  - LICENSE.txt
38
38
  - README.md
39
39
  - Rakefile
40
40
  - bin/console
41
+ - bin/rake
41
42
  - bin/setup
42
43
  - erb-linter.gemspec
43
44
  - lib/erb/linter.rb
data/Gemfile.lock DELETED
@@ -1,22 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- erb-linter (0.0.1)
5
- rake
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- minitest (5.14.4)
11
- rake (13.0.3)
12
-
13
- PLATFORMS
14
- x86_64-darwin-20
15
-
16
- DEPENDENCIES
17
- erb-linter!
18
- minitest (~> 5.0)
19
- rake (~> 13.0)
20
-
21
- BUNDLED WITH
22
- 2.2.3