htmlbeautifier 1.3.1 → 1.4.3
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 +5 -5
- data/README.md +4 -4
- data/bin/htmlbeautifier +44 -12
- data/lib/htmlbeautifier/builder.rb +25 -23
- data/lib/htmlbeautifier/html_parser.rb +27 -23
- data/lib/htmlbeautifier/parser.rb +7 -3
- data/lib/htmlbeautifier/ruby_indenter.rb +6 -4
- data/lib/htmlbeautifier/version.rb +6 -4
- data/lib/htmlbeautifier.rb +3 -1
- metadata +37 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fcd8d466ff4ebc3419c99968d8a82f617c9911c520a4623d649d72a821dcec5c
|
4
|
+
data.tar.gz: 28113c3062ebfcf3dd6cb5d30dfd551d658b6d3061e7127bfb50e5584266266c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c07ed38537750b35280e3131c9333f5c31deabff6da46f5a333557b8af5c261babda15f98a45f9ea9d8213f14368ad9b671fac38f61e7f7439a3d0edb2bb675
|
7
|
+
data.tar.gz: 76c39b1d92accd12e3b6c354b2214e0da149d7e400d0e66583b6505c498eadd8de79336abfcf90087d1ca9e56c00d6a0ec4b4f211da5924a7546fc65e1d84971
|
data/README.md
CHANGED
@@ -23,13 +23,13 @@ Ideal for tidying up Rails templates.
|
|
23
23
|
To update files in-place:
|
24
24
|
|
25
25
|
``` sh
|
26
|
-
$ htmlbeautifier file1 [file2 ...]
|
26
|
+
$ htmlbeautifier file1.html.erb [file2.html.erb ...]
|
27
27
|
```
|
28
28
|
|
29
29
|
or to operate on standard input and output:
|
30
30
|
|
31
31
|
``` sh
|
32
|
-
$ htmlbeautifier <
|
32
|
+
$ htmlbeautifier < untidy.html.erb > formatted.html.erb
|
33
33
|
```
|
34
34
|
|
35
35
|
### In your code
|
@@ -37,13 +37,13 @@ $ htmlbeautifier < input > output
|
|
37
37
|
```ruby
|
38
38
|
require 'htmlbeautifier'
|
39
39
|
|
40
|
-
beautiful = HtmlBeautifier.beautify(
|
40
|
+
beautiful = HtmlBeautifier.beautify(untify_html_string)
|
41
41
|
```
|
42
42
|
|
43
43
|
You can also specify how to indent (the default is two spaces):
|
44
44
|
|
45
45
|
```ruby
|
46
|
-
beautiful = HtmlBeautifier.beautify(
|
46
|
+
beautiful = HtmlBeautifier.beautify(untidy_html_string, indent: "\t")
|
47
47
|
```
|
48
48
|
|
49
49
|
## Installation
|
data/bin/htmlbeautifier
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
require "htmlbeautifier"
|
3
5
|
require "optparse"
|
4
6
|
require "fileutils"
|
7
|
+
require "stringio"
|
5
8
|
|
6
9
|
def beautify(name, input, output, options)
|
7
10
|
output.puts HtmlBeautifier.beautify(input, options)
|
@@ -11,21 +14,21 @@ end
|
|
11
14
|
|
12
15
|
executable = File.basename(__FILE__)
|
13
16
|
|
14
|
-
options = {
|
17
|
+
options = {indent: " "}
|
15
18
|
parser = OptionParser.new do |opts|
|
16
19
|
opts.banner = "Usage: #{executable} [options] [file ...]"
|
17
|
-
opts.separator
|
20
|
+
opts.separator <<~STRING
|
18
21
|
|
19
|
-
#{executable} has two modes of operation:
|
22
|
+
#{executable} has two modes of operation:
|
20
23
|
|
21
|
-
1. If no files are listed, it will read from standard input and write to
|
22
|
-
|
23
|
-
2. If files are listed, it will modify each file in place, overwriting it
|
24
|
-
|
24
|
+
1. If no files are listed, it will read from standard input and write to
|
25
|
+
standard output.
|
26
|
+
2. If files are listed, it will modify each file in place, overwriting it
|
27
|
+
with the beautified output.
|
25
28
|
|
26
|
-
The following options are available:
|
29
|
+
The following options are available:
|
27
30
|
|
28
|
-
|
31
|
+
STRING
|
29
32
|
opts.on(
|
30
33
|
"-t", "--tab-stops NUMBER", Integer,
|
31
34
|
"Set number of spaces per indent (default #{options[:tab_stops]})"
|
@@ -56,6 +59,20 @@ END
|
|
56
59
|
) do |num|
|
57
60
|
options[:keep_blank_lines] = num
|
58
61
|
end
|
62
|
+
opts.on(
|
63
|
+
"-l", "--lint-only",
|
64
|
+
"Lint only, error on files which would be modified",
|
65
|
+
"This is not available when reading from standard input"
|
66
|
+
) do |num|
|
67
|
+
options[:lint_only] = num
|
68
|
+
end
|
69
|
+
opts.on(
|
70
|
+
"-v", "--version",
|
71
|
+
"Display version and exit"
|
72
|
+
) do
|
73
|
+
puts HtmlBeautifier::VERSION::STRING
|
74
|
+
exit
|
75
|
+
end
|
59
76
|
opts.on(
|
60
77
|
"-h", "--help",
|
61
78
|
"Display this help message and exit"
|
@@ -64,16 +81,31 @@ END
|
|
64
81
|
exit
|
65
82
|
end
|
66
83
|
end
|
84
|
+
|
67
85
|
parser.parse!
|
68
86
|
|
69
87
|
if ARGV.any?
|
88
|
+
failures = []
|
70
89
|
ARGV.each do |path|
|
71
90
|
input = File.read(path)
|
72
|
-
|
73
|
-
|
91
|
+
if options[:lint_only]
|
92
|
+
output = StringIO.new
|
74
93
|
beautify path, input, output, options
|
94
|
+
failures << path unless input == output.string
|
95
|
+
else
|
96
|
+
temppath = "#{path}.tmp"
|
97
|
+
File.open(temppath, "w") do |file|
|
98
|
+
beautify path, input, file, options
|
99
|
+
end
|
100
|
+
FileUtils.mv temppath, path
|
75
101
|
end
|
76
|
-
|
102
|
+
end
|
103
|
+
unless failures.empty?
|
104
|
+
warn [
|
105
|
+
"Lint failed - files would be modified:",
|
106
|
+
*failures
|
107
|
+
].join("\n")
|
108
|
+
exit 1
|
77
109
|
end
|
78
110
|
else
|
79
111
|
beautify "standard input", $stdin.read, $stdout, options
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "htmlbeautifier/parser"
|
2
4
|
require "htmlbeautifier/ruby_indenter"
|
3
5
|
|
@@ -8,7 +10,7 @@ module HtmlBeautifier
|
|
8
10
|
initial_level: 0,
|
9
11
|
stop_on_errors: false,
|
10
12
|
keep_blank_lines: 0
|
11
|
-
}
|
13
|
+
}.freeze
|
12
14
|
|
13
15
|
def initialize(output, options = {})
|
14
16
|
options = DEFAULT_OPTIONS.merge(options)
|
@@ -23,10 +25,11 @@ module HtmlBeautifier
|
|
23
25
|
@embedded_indenter = RubyIndenter.new
|
24
26
|
end
|
25
27
|
|
26
|
-
|
28
|
+
private
|
27
29
|
|
28
30
|
def error(text)
|
29
31
|
return unless @stop_on_errors
|
32
|
+
|
30
33
|
raise text
|
31
34
|
end
|
32
35
|
|
@@ -40,9 +43,10 @@ module HtmlBeautifier
|
|
40
43
|
end
|
41
44
|
|
42
45
|
def emit(*strings)
|
46
|
+
strings_join = strings.join("")
|
43
47
|
@output << "\n" if @new_line && !@empty
|
44
|
-
@output << (@tab * @level) if @new_line
|
45
|
-
@output <<
|
48
|
+
@output << (@tab * @level) if @new_line && !strings_join.strip.empty?
|
49
|
+
@output << strings_join
|
46
50
|
@new_line = false
|
47
51
|
@empty = false
|
48
52
|
end
|
@@ -87,42 +91,42 @@ module HtmlBeautifier
|
|
87
91
|
new_line
|
88
92
|
end
|
89
93
|
|
90
|
-
def standalone_element(
|
91
|
-
emit
|
92
|
-
new_line if
|
94
|
+
def standalone_element(elem)
|
95
|
+
emit elem
|
96
|
+
new_line if elem =~ %r{^<br[^\w]}
|
93
97
|
end
|
94
98
|
|
95
|
-
def close_element(
|
99
|
+
def close_element(elem)
|
96
100
|
outdent
|
97
|
-
emit
|
101
|
+
emit elem
|
98
102
|
end
|
99
103
|
|
100
|
-
def close_block_element(
|
101
|
-
close_element
|
104
|
+
def close_block_element(elem)
|
105
|
+
close_element elem
|
102
106
|
new_line
|
103
107
|
end
|
104
108
|
|
105
|
-
def open_element(
|
106
|
-
emit
|
109
|
+
def open_element(elem)
|
110
|
+
emit elem
|
107
111
|
indent
|
108
112
|
end
|
109
113
|
|
110
|
-
def open_block_element(
|
114
|
+
def open_block_element(elem)
|
111
115
|
new_line
|
112
|
-
open_element
|
116
|
+
open_element elem
|
113
117
|
end
|
114
118
|
|
115
|
-
def close_ie_cc(
|
119
|
+
def close_ie_cc(elem)
|
116
120
|
if @ie_cc_levels.empty?
|
117
121
|
error "Unclosed conditional comment"
|
118
122
|
else
|
119
123
|
@level = @ie_cc_levels.pop
|
120
124
|
end
|
121
|
-
emit
|
125
|
+
emit elem
|
122
126
|
end
|
123
127
|
|
124
|
-
def open_ie_cc(
|
125
|
-
emit
|
128
|
+
def open_ie_cc(elem)
|
129
|
+
emit elem
|
126
130
|
@ie_cc_levels.push @level
|
127
131
|
indent
|
128
132
|
end
|
@@ -130,12 +134,10 @@ module HtmlBeautifier
|
|
130
134
|
def new_lines(*content)
|
131
135
|
blank_lines = content.first.scan(%r{\n}).count - 1
|
132
136
|
blank_lines = [blank_lines, @keep_blank_lines].min
|
133
|
-
@output << "\n" * blank_lines
|
137
|
+
@output << ("\n" * blank_lines)
|
134
138
|
new_line
|
135
139
|
end
|
136
140
|
|
137
|
-
|
138
|
-
emit t
|
139
|
-
end
|
141
|
+
alias_method :text, :emit
|
140
142
|
end
|
141
143
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "htmlbeautifier/parser"
|
2
4
|
|
3
5
|
module HtmlBeautifier
|
@@ -8,47 +10,49 @@ module HtmlBeautifier
|
|
8
10
|
link | meta | param | source | track | wbr
|
9
11
|
)}mix
|
10
12
|
HTML_BLOCK_ELEMENTS = %r{(?:
|
11
|
-
address | article | aside | audio | blockquote | canvas | dd |
|
12
|
-
dl | dt | fieldset | figcaption | figure | footer | form |
|
13
|
-
|
14
|
-
|
13
|
+
address | article | aside | audio | blockquote | canvas | dd | details |
|
14
|
+
dir | div | dl | dt | fieldset | figcaption | figure | footer | form |
|
15
|
+
h1 | h2 | h3 | h4 | h5 | h6 | header | hr | li | menu | noframes |
|
16
|
+
noscript | ol | p | pre | section | table | tbody | td | tfoot | th |
|
17
|
+
thead | tr | ul | video
|
15
18
|
)}mix
|
16
19
|
|
17
20
|
MAPPINGS = [
|
18
21
|
[%r{(<%-?=?)(.*?)(-?%>)}om,
|
19
|
-
|
22
|
+
:embed],
|
20
23
|
[%r{<!--\[.*?\]>}om,
|
21
|
-
|
24
|
+
:open_ie_cc],
|
22
25
|
[%r{<!\[.*?\]-->}om,
|
23
|
-
|
26
|
+
:close_ie_cc],
|
24
27
|
[%r{<!--.*?-->}om,
|
25
|
-
|
28
|
+
:standalone_element],
|
26
29
|
[%r{<!.*?>}om,
|
27
|
-
|
30
|
+
:standalone_element],
|
28
31
|
[%r{(<script#{ELEMENT_CONTENT}>)(.*?)(</script>)}omi,
|
29
|
-
|
32
|
+
:foreign_block],
|
30
33
|
[%r{(<style#{ELEMENT_CONTENT}>)(.*?)(</style>)}omi,
|
31
|
-
|
34
|
+
:foreign_block],
|
32
35
|
[%r{(<pre#{ELEMENT_CONTENT}>)(.*?)(</pre>)}omi,
|
33
|
-
|
36
|
+
:preformatted_block],
|
34
37
|
[%r{(<textarea#{ELEMENT_CONTENT}>)(.*?)(</textarea>)}omi,
|
35
|
-
|
38
|
+
:preformatted_block],
|
36
39
|
[%r{<#{HTML_VOID_ELEMENTS}(?: #{ELEMENT_CONTENT})?/?>}om,
|
37
|
-
|
38
|
-
[%r{<\w+(?: #{ELEMENT_CONTENT})?/>}om,
|
39
|
-
:standalone_element],
|
40
|
+
:standalone_element],
|
40
41
|
[%r{</#{HTML_BLOCK_ELEMENTS}>}om,
|
41
|
-
|
42
|
+
:close_block_element],
|
42
43
|
[%r{<#{HTML_BLOCK_ELEMENTS}(?: #{ELEMENT_CONTENT})?>}om,
|
43
|
-
|
44
|
+
:open_block_element],
|
44
45
|
[%r{</#{ELEMENT_CONTENT}>}om,
|
45
|
-
|
46
|
-
[%r{<#{ELEMENT_CONTENT}>}om,
|
47
|
-
|
46
|
+
:close_element],
|
47
|
+
[%r{<#{ELEMENT_CONTENT}[^/]>}om,
|
48
|
+
:open_element],
|
49
|
+
[%r{<[\w\-]+(?: #{ELEMENT_CONTENT})?/>}om,
|
50
|
+
:standalone_element],
|
48
51
|
[%r{(\s*\r?\n\s*)+}om,
|
49
|
-
|
52
|
+
:new_lines],
|
50
53
|
[%r{[^<\n]+},
|
51
|
-
|
54
|
+
:text]
|
55
|
+
].freeze
|
52
56
|
|
53
57
|
def initialize
|
54
58
|
super do |p|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "strscan"
|
2
4
|
|
3
5
|
module HtmlBeautifier
|
@@ -24,18 +26,20 @@ module HtmlBeautifier
|
|
24
26
|
[source_so_far.chomp.split(%r{\n}).count, 1].max
|
25
27
|
end
|
26
28
|
|
27
|
-
|
29
|
+
private
|
28
30
|
|
29
31
|
def dispatch(receiver)
|
30
32
|
_, method = @maps.find { |pattern, _| @scanner.scan(pattern) }
|
31
33
|
raise "Unmatched sequence" unless method
|
34
|
+
|
32
35
|
receiver.__send__(method, *extract_params(@scanner))
|
33
|
-
rescue =>
|
34
|
-
raise "#{
|
36
|
+
rescue => e
|
37
|
+
raise "#{e.message} on line #{source_line_number}"
|
35
38
|
end
|
36
39
|
|
37
40
|
def extract_params(scanner)
|
38
41
|
return [scanner[0]] unless scanner[1]
|
42
|
+
|
39
43
|
params = []
|
40
44
|
i = 1
|
41
45
|
while scanner[i]
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module HtmlBeautifier
|
2
4
|
class RubyIndenter
|
3
|
-
INDENT_KEYWORDS = %w[
|
4
|
-
OUTDENT_KEYWORDS = %w[
|
5
|
-
RUBY_INDENT
|
5
|
+
INDENT_KEYWORDS = %w[if elsif else unless while until begin for case when].freeze
|
6
|
+
OUTDENT_KEYWORDS = %w[elsif else end when].freeze
|
7
|
+
RUBY_INDENT = %r{
|
6
8
|
^ ( #{INDENT_KEYWORDS.join("|")} )\b
|
7
|
-
| \b ( do | \{ ) ( \s* \| [
|
9
|
+
| \b ( do | \{ ) ( \s* \| [^|]+ \| )? $
|
8
10
|
}xo
|
9
11
|
RUBY_OUTDENT = %r{ ^ ( #{OUTDENT_KEYWORDS.join("|")} | \} ) \b }xo
|
10
12
|
|
@@ -1,8 +1,10 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HtmlBeautifier # :nodoc:
|
4
|
+
module VERSION # :nodoc:
|
3
5
|
MAJOR = 1
|
4
|
-
MINOR =
|
5
|
-
TINY
|
6
|
+
MINOR = 4
|
7
|
+
TINY = 3
|
6
8
|
|
7
9
|
STRING = [MAJOR, MINOR, TINY].join(".")
|
8
10
|
end
|
data/lib/htmlbeautifier.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "htmlbeautifier/builder"
|
2
4
|
require "htmlbeautifier/html_parser"
|
3
5
|
require "htmlbeautifier/version"
|
@@ -22,7 +24,7 @@ module HtmlBeautifier
|
|
22
24
|
if options[:tab_stops]
|
23
25
|
options[:indent] = " " * options[:tab_stops]
|
24
26
|
end
|
25
|
-
|
27
|
+
String.new.tap { |output|
|
26
28
|
HtmlParser.new.scan html.to_s, Builder.new(output, options)
|
27
29
|
}
|
28
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: htmlbeautifier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3
|
4
|
+
version: 1.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Battley
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '13'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '13'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,19 +39,47 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '3'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: standard
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: '1.33'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: '1.33'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop-rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop-rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.6'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.6'
|
55
83
|
description: A normaliser/beautifier for HTML that also understands embedded Ruby.
|
56
84
|
email: pbattley@gmail.com
|
57
85
|
executables:
|
@@ -80,15 +108,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
80
108
|
requirements:
|
81
109
|
- - ">="
|
82
110
|
- !ruby/object:Gem::Version
|
83
|
-
version:
|
111
|
+
version: 2.6.0
|
84
112
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
113
|
requirements:
|
86
114
|
- - ">="
|
87
115
|
- !ruby/object:Gem::Version
|
88
116
|
version: '0'
|
89
117
|
requirements: []
|
90
|
-
|
91
|
-
rubygems_version: 2.4.5
|
118
|
+
rubygems_version: 3.4.15
|
92
119
|
signing_key:
|
93
120
|
specification_version: 4
|
94
121
|
summary: HTML/ERB beautifier
|