htmlbeautifier 1.2.1 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 657518afa5b160297e6b490855c02526f48ad144
4
- data.tar.gz: bfdfbca49d50e276f2314a893ecc0b70b6392115
2
+ SHA256:
3
+ metadata.gz: 4ad32fe5c137d828c711e50642ff3b00af14e3b8cdf18105506c1149de2c6cde
4
+ data.tar.gz: d42bcce139d8a3e9a96f73735fbb068044f1f43c8d9951c89cd642bf4e996bef
5
5
  SHA512:
6
- metadata.gz: 9a96bc60da54b69d972b80d5faf47a547dc7ab403e19c4ab6685dce4896a71a76bf9b7f49ce3b2c8039d8f0b661fe5c9b21c740116ac49e7e49313a11bd0a903
7
- data.tar.gz: cfe7bb9dceaad5997e65ba6fdc397a0ce5a30ee3012e295c1a1fdc2dedcf3a34661d662b92c83ec28ea4d675f99c82a05c7a2924f8f3f13d32f12db094d82fb8
6
+ metadata.gz: 89dc1309a74d24da1f91ec626e3a0291918c9e0ef64370d10893ee30c961bcb788efa2bc99fbdb89af96d643cf418333b6b5b6eb3ec3e54dfb164398d0cdf0b5
7
+ data.tar.gz: accce8738133c66d40ddcbdc21aee322f7b68e2d9bcca81102fbecc680a5a3b021d8911587e31e0a1963f3cae166e2f436a76800feebde59da411d96cb5fe628
data/bin/htmlbeautifier CHANGED
@@ -1,11 +1,14 @@
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)
8
- rescue => e
11
+ rescue StandardError => e
9
12
  raise "Error parsing #{name}: #{e}"
10
13
  end
11
14
 
@@ -14,18 +17,18 @@ executable = File.basename(__FILE__)
14
17
  options = { indent: " " }
15
18
  parser = OptionParser.new do |opts|
16
19
  opts.banner = "Usage: #{executable} [options] [file ...]"
17
- opts.separator <<END
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
- standard output.
23
- 2. If files are listed, it will modify each file in place, overwriting it
24
- with the beautified output.
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
- END
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]})"
@@ -50,6 +53,26 @@ END
50
53
  ) do |num|
51
54
  options[:stop_on_errors] = num
52
55
  end
56
+ opts.on(
57
+ "-b", "--keep-blank-lines NUMBER", Integer,
58
+ "Set number of consecutive blank lines"
59
+ ) do |num|
60
+ options[:keep_blank_lines] = num
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
53
76
  opts.on(
54
77
  "-h", "--help",
55
78
  "Display this help message and exit"
@@ -58,16 +81,34 @@ END
58
81
  exit
59
82
  end
60
83
  end
84
+
61
85
  parser.parse!
62
86
 
63
87
  if ARGV.any?
88
+ failures = []
64
89
  ARGV.each do |path|
65
90
  input = File.read(path)
66
- temppath = path + ".tmp"
67
- File.open(temppath, "w") do |output|
91
+ if options[:lint_only]
92
+ output = StringIO.new
68
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
69
101
  end
70
- FileUtils.mv temppath, path
102
+ end
103
+ unless failures.empty?
104
+ relative_paths = failures.map { |path|
105
+ Pathname.new(path).relative_path_from Dir.pwd
106
+ }
107
+ $stderr.puts [
108
+ "Lint failed - files would be modified:",
109
+ *relative_paths
110
+ ].join("\n")
111
+ exit 1
71
112
  end
72
113
  else
73
114
  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
 
@@ -6,14 +8,16 @@ module HtmlBeautifier
6
8
  DEFAULT_OPTIONS = {
7
9
  indent: " ",
8
10
  initial_level: 0,
9
- stop_on_errors: false
10
- }
11
+ stop_on_errors: false,
12
+ keep_blank_lines: 0
13
+ }.freeze
11
14
 
12
15
  def initialize(output, options = {})
13
16
  options = DEFAULT_OPTIONS.merge(options)
14
17
  @tab = options[:indent]
15
18
  @stop_on_errors = options[:stop_on_errors]
16
19
  @level = options[:initial_level]
20
+ @keep_blank_lines = options[:keep_blank_lines]
17
21
  @new_line = false
18
22
  @empty = true
19
23
  @ie_cc_levels = []
@@ -25,6 +29,7 @@ module HtmlBeautifier
25
29
 
26
30
  def error(text)
27
31
  return unless @stop_on_errors
32
+
28
33
  raise text
29
34
  end
30
35
 
@@ -38,14 +43,15 @@ module HtmlBeautifier
38
43
  end
39
44
 
40
45
  def emit(*strings)
46
+ strings_join = strings.join("")
41
47
  @output << "\n" if @new_line && !@empty
42
- @output << (@tab * @level) if @new_line
43
- @output << strings.join("")
48
+ @output << (@tab * @level) if @new_line && !strings_join.strip.empty?
49
+ @output << strings_join
44
50
  @new_line = false
45
51
  @empty = false
46
52
  end
47
53
 
48
- def new_line(*)
54
+ def new_line
49
55
  @new_line = true
50
56
  end
51
57
 
@@ -64,7 +70,7 @@ module HtmlBeautifier
64
70
 
65
71
  def emit_reindented_block_content(code)
66
72
  lines = code.strip.split(%r{\n})
67
- indentation = lines.first[%r{^\s+}]
73
+ indentation = foreign_block_indentation(code)
68
74
 
69
75
  indent
70
76
  new_line
@@ -75,55 +81,63 @@ module HtmlBeautifier
75
81
  outdent
76
82
  end
77
83
 
84
+ def foreign_block_indentation(code)
85
+ code.split(%r{\n}).find { |ln| !ln.strip.empty? }[%r{^\s+}]
86
+ end
87
+
78
88
  def preformatted_block(opening, content, closing)
79
89
  new_line
80
90
  emit opening, content, closing
81
91
  new_line
82
92
  end
83
93
 
84
- def standalone_element(e)
85
- emit e
86
- new_line if e =~ %r{^<br[^\w]}
94
+ def standalone_element(elem)
95
+ emit elem
96
+ new_line if elem =~ %r{^<br[^\w]}
87
97
  end
88
98
 
89
- def close_element(e)
99
+ def close_element(elem)
90
100
  outdent
91
- emit e
101
+ emit elem
92
102
  end
93
103
 
94
- def close_block_element(e)
95
- close_element e
104
+ def close_block_element(elem)
105
+ close_element elem
96
106
  new_line
97
107
  end
98
108
 
99
- def open_element(e)
100
- emit e
109
+ def open_element(elem)
110
+ emit elem
101
111
  indent
102
112
  end
103
113
 
104
- def open_block_element(e)
114
+ def open_block_element(elem)
105
115
  new_line
106
- open_element e
116
+ open_element elem
107
117
  end
108
118
 
109
- def close_ie_cc(e)
119
+ def close_ie_cc(elem)
110
120
  if @ie_cc_levels.empty?
111
121
  error "Unclosed conditional comment"
112
122
  else
113
123
  @level = @ie_cc_levels.pop
114
124
  end
115
- emit e
125
+ emit elem
116
126
  end
117
127
 
118
- def open_ie_cc(e)
119
- emit e
128
+ def open_ie_cc(elem)
129
+ emit elem
120
130
  @ie_cc_levels.push @level
121
131
  indent
122
132
  end
123
133
 
124
- def text(t)
125
- emit t.chomp
126
- new_line if t.end_with?("\n")
134
+ def new_lines(*content)
135
+ blank_lines = content.first.scan(%r{\n}).count - 1
136
+ blank_lines = [blank_lines, @keep_blank_lines].min
137
+ @output << ("\n" * blank_lines)
138
+ new_line
127
139
  end
140
+
141
+ alias_method :text, :emit
128
142
  end
129
143
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "htmlbeautifier/parser"
2
4
 
3
5
  module HtmlBeautifier
@@ -35,20 +37,21 @@ module HtmlBeautifier
35
37
  :preformatted_block],
36
38
  [%r{<#{HTML_VOID_ELEMENTS}(?: #{ELEMENT_CONTENT})?/?>}om,
37
39
  :standalone_element],
38
- [%r{<\w+(?: #{ELEMENT_CONTENT})?/>}om,
39
- :standalone_element],
40
40
  [%r{</#{HTML_BLOCK_ELEMENTS}>}om,
41
41
  :close_block_element],
42
42
  [%r{<#{HTML_BLOCK_ELEMENTS}(?: #{ELEMENT_CONTENT})?>}om,
43
43
  :open_block_element],
44
44
  [%r{</#{ELEMENT_CONTENT}>}om,
45
45
  :close_element],
46
- [%r{<#{ELEMENT_CONTENT}>}om,
46
+ [%r{<#{ELEMENT_CONTENT}[^/]>}om,
47
47
  :open_element],
48
- [%r{\s*\r?\n\s*}om,
49
- :new_line],
50
- [%r{[^<]+},
51
- :text]]
48
+ [%r{<[\w\-]+(?: #{ELEMENT_CONTENT})?/>}om,
49
+ :standalone_element],
50
+ [%r{(\s*\r?\n\s*)+}om,
51
+ :new_lines],
52
+ [%r{[^<\n]+},
53
+ :text]
54
+ ].freeze
52
55
 
53
56
  def initialize
54
57
  super do |p|
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "strscan"
2
4
 
3
5
  module HtmlBeautifier
@@ -29,13 +31,15 @@ module HtmlBeautifier
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 => ex
34
- raise "#{ex.message} on line #{source_line_number}"
36
+ rescue StandardError => 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[ if elsif else unless while until begin for ]
4
- OUTDENT_KEYWORDS = %w[ elsif else end ]
5
- RUBY_INDENT = %r{
5
+ INDENT_KEYWORDS = %w[if elsif else unless while until begin for].freeze
6
+ OUTDENT_KEYWORDS = %w[elsif else end].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,7 +1,9 @@
1
- module HtmlBeautifier #:nodoc:
2
- module VERSION #:nodoc:
1
+ # frozen_string_literal: true
2
+
3
+ module HtmlBeautifier # :nodoc:
4
+ module VERSION # :nodoc:
3
5
  MAJOR = 1
4
- MINOR = 2
6
+ MINOR = 4
5
7
  TINY = 1
6
8
 
7
9
  STRING = [MAJOR, MINOR, TINY].join(".")
@@ -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"
@@ -15,12 +17,14 @@ module HtmlBeautifier
15
17
  # is false, i.e. continue to process the rest of the document.
16
18
  # initial_level - The entire output will be indented by this number of steps.
17
19
  # Default is 0.
20
+ # keep_blank_lines - an integer for the number of consecutive empty lines
21
+ # to keep in output.
18
22
  #
19
23
  def self.beautify(html, options = {})
20
24
  if options[:tab_stops]
21
25
  options[:indent] = " " * options[:tab_stops]
22
26
  end
23
- "".tap { |output|
27
+ String.new.tap { |output|
24
28
  HtmlParser.new.scan html.to_s, Builder.new(output, options)
25
29
  }
26
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.2.1
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Battley
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-22 00:00:00.000000000 Z
11
+ date: 2021-12-05 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: '0'
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: '0'
26
+ version: '13'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,14 +44,42 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.30.0
47
+ version: '1'
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: 0.30.0
54
+ version: '1'
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: 1.9.2
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
- rubyforge_project:
91
- rubygems_version: 2.5.1
118
+ rubygems_version: 3.2.22
92
119
  signing_key:
93
120
  specification_version: 4
94
121
  summary: HTML/ERB beautifier