htmlbeautifier 1.1.0 → 1.1.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
2
  SHA1:
3
- metadata.gz: eb927f5efa5cd85b002af5945bd03106b0fc7c31
4
- data.tar.gz: a2dfedd5c2565b7245d1473d77fd729f621e0f0c
3
+ metadata.gz: 3b82dd8d2489286ab4474e1690d0a47ff91ffce8
4
+ data.tar.gz: e20a70c076be7e6eda31e456b0fd56715c1554ce
5
5
  SHA512:
6
- metadata.gz: 2a06c094220e541614b3026403dfe017207d2b09821044720a5bb4093fc580007c638b746022739d1ba75a22b96e6a9a46bb21eeab293bc84c1a313bacd4f0ed
7
- data.tar.gz: 1d29ae0712bed379920a1c1a3e3431d7ffc5404388b1bad04e8b32ae542efdb10f14605fc39e03028a852ddab060ac3e216dcafa5be48fca8c7940736b7ee40a
6
+ metadata.gz: 9da8945658fddb13a0af61e5d61e05b381ffdb8168247d22fe6026043c41822cce4bce45910e844cb8f5183f01a790836a209802531cd4e13a1bbd67b0092877
7
+ data.tar.gz: 224c74e0769b2e208505cd0d1461f4c971ed9a264f2ed78bf27c6311c5fa037e40295b8beb607fed7edf114e354138805cec3e766432b9a3a8e08e0b66a86950
data/README.md CHANGED
@@ -1,11 +1,9 @@
1
- HTML Beautifier
2
- ===============
1
+ # HTML Beautifier
3
2
 
4
3
  A normaliser/beautifier for HTML that also understands embedded Ruby.
5
4
  Ideal for tidying up Rails templates.
6
5
 
7
- What it does
8
- ------------
6
+ ## What it does
9
7
 
10
8
  * Normalises hard tabs to spaces
11
9
  * Removes trailing spaces
@@ -18,8 +16,7 @@ What it does
18
16
  * Indents the left-hand margin of JavaScript and CSS blocks to match the
19
17
  indentation level of the code
20
18
 
21
- Usage
22
- -----
19
+ ## Usage
23
20
 
24
21
  ### From the command line
25
22
 
@@ -35,7 +32,7 @@ or to operate on standard input and output:
35
32
  $ htmlbeautifier < input > output
36
33
  ```
37
34
 
38
- ## In your code
35
+ ### In your code
39
36
 
40
37
  ```ruby
41
38
  require 'htmlbeautifier'
@@ -48,3 +45,27 @@ You can also specify the number of spaces to indent (the default is 2):
48
45
  ```ruby
49
46
  beautiful = HtmlBeautifier.beautify(messy, tab_stops: 4)
50
47
  ```
48
+
49
+ ## Installation
50
+
51
+ This is a Ruby gem.
52
+ To install the command-line tool (you may need `sudo`):
53
+
54
+ ```sh
55
+ $ gem install htmlbeautifier
56
+ ```
57
+
58
+ To use the gem with Bundler, add to your `Gemfile`:
59
+
60
+ ```ruby
61
+ gem 'htmlbeautifier'
62
+ ```
63
+
64
+ ## Contributing
65
+
66
+ 1. Follow [these guidelines][git-commit] when writing commit messages (briefly,
67
+ the first line should begin with a capital letter, use the imperative mood,
68
+ be no more than 50 characters, and not end with a period).
69
+ 2. Include tests.
70
+
71
+ [git-commit]:http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
data/Rakefile CHANGED
@@ -7,3 +7,10 @@ RSpec::Core::RakeTask.new do |t|
7
7
  end
8
8
 
9
9
  task :default => [:spec]
10
+
11
+ if Gem.loaded_specs.key?('rubocop')
12
+ require 'rubocop/rake_task'
13
+ RuboCop::RakeTask.new
14
+
15
+ task(:default).prerequisites << task(:rubocop)
16
+ end
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
- require 'htmlbeautifier'
3
- require 'optparse'
4
- require 'fileutils'
2
+ require "htmlbeautifier"
3
+ require "optparse"
4
+ require "fileutils"
5
5
 
6
6
  def beautify(name, input, output, options)
7
7
  output.puts HtmlBeautifier.beautify(input, options)
@@ -11,7 +11,7 @@ end
11
11
 
12
12
  executable = File.basename(__FILE__)
13
13
 
14
- options = {:tab_stops => 2}
14
+ options = { tab_stops: 2 }
15
15
  parser = OptionParser.new do |opts|
16
16
  opts.banner = "Usage: #{executable} [options] [file ...]"
17
17
  opts.separator <<END
@@ -1,9 +1,9 @@
1
- require 'htmlbeautifier/builder'
2
- require 'htmlbeautifier/html_parser'
3
- require 'htmlbeautifier/version'
1
+ require "htmlbeautifier/builder"
2
+ require "htmlbeautifier/html_parser"
3
+ require "htmlbeautifier/version"
4
4
 
5
5
  module HtmlBeautifier
6
-
6
+ #
7
7
  # Returns a beautified HTML/HTML+ERB document as a String.
8
8
  # html must be an object that responds to +#to_s+.
9
9
  #
@@ -13,7 +13,7 @@ module HtmlBeautifier
13
13
  # is false, i.e. continue to process the rest of the document.
14
14
  #
15
15
  def self.beautify(html, options = {})
16
- ''.tap { |output|
16
+ "".tap { |output|
17
17
  HtmlParser.new.scan html.to_s, Builder.new(output, options)
18
18
  }
19
19
  end
@@ -1,17 +1,8 @@
1
- require 'htmlbeautifier/parser'
1
+ require "htmlbeautifier/parser"
2
+ require "htmlbeautifier/ruby_indenter"
2
3
 
3
4
  module HtmlBeautifier
4
5
  class Builder
5
-
6
- RUBY_INDENT =
7
- %r{ ^ ( if | unless | while | begin | elsif | else )\b
8
- | \b ( do | \{ ) ( \s* \| [^\|]+ \| )? $
9
- }x
10
- RUBY_OUTDENT =
11
- %r{ ^ ( end | elsif | else |\} ) \b
12
- }x
13
- ELEMENT_CONTENT = %r{ (?:[^<>]|<%.*?%>)* }mx
14
-
15
6
  DEFAULT_OPTIONS = {
16
7
  tab_stops: 2,
17
8
  stop_on_errors: false
@@ -19,20 +10,21 @@ module HtmlBeautifier
19
10
 
20
11
  def initialize(output, options = {})
21
12
  options = DEFAULT_OPTIONS.merge(options)
13
+ @tab = " " * options[:tab_stops]
14
+ @stop_on_errors = options[:stop_on_errors]
22
15
  @level = 0
23
16
  @new_line = false
24
- @tab = ' ' * options[:tab_stops]
25
- @stop_on_errors = options[:stop_on_errors]
26
- @output = output
27
17
  @empty = true
28
18
  @ie_cc_levels = []
19
+ @output = output
20
+ @embedded_indenter = RubyIndenter.new
29
21
  end
30
22
 
31
23
  private
32
24
 
33
25
  def error(text)
34
26
  return unless @stop_on_errors
35
- raise RuntimeError, text
27
+ raise text
36
28
  end
37
29
 
38
30
  def indent
@@ -44,75 +36,62 @@ module HtmlBeautifier
44
36
  @level = [@level - 1, 0].max
45
37
  end
46
38
 
47
- def emit(s)
48
- if @new_line && !@empty
49
- @output << ("\n" + @tab * @level)
50
- end
51
- @output << s
39
+ def emit(*strings)
40
+ @output << ("\n" + @tab * @level) if @new_line && !@empty
41
+ @output << strings.join("")
52
42
  @new_line = false
53
43
  @empty = false
54
44
  end
55
45
 
56
- def new_line(*_args)
46
+ def new_line(*)
57
47
  @new_line = true
58
48
  end
59
49
 
60
50
  def embed(opening, code, closing)
61
- lines = code.split(/\n/).map{ |l| l.strip }
62
- outdent if lines.first =~ RUBY_OUTDENT
63
- emit opening + code + closing
64
- indent if lines.last =~ RUBY_INDENT
51
+ lines = code.split(%r{\n}).map(&:strip)
52
+ outdent if @embedded_indenter.outdent?(lines)
53
+ emit opening, code, closing
54
+ indent if @embedded_indenter.indent?(lines)
65
55
  end
66
56
 
67
57
  def foreign_block(opening, code, closing)
68
58
  emit opening
69
- unless code.strip.empty?
70
- indent
59
+ emit_reindented_block_content code unless code.strip.empty?
60
+ emit closing
61
+ end
71
62
 
72
- lines = code.split(/\n/)
73
- lines.shift while lines.first.strip.empty?
74
- lines.pop while lines.last.strip.empty?
75
- indentation = lines.first[/^ +/]
63
+ def emit_reindented_block_content(code)
64
+ lines = code.strip.split(%r{\n})
65
+ indentation = lines.first[%r{^\s+}]
76
66
 
67
+ indent
68
+ new_line
69
+ lines.each do |line|
70
+ emit line.rstrip.sub(%r{^#{indentation}}, "")
77
71
  new_line
78
- lines.each do |line|
79
- emit line.rstrip.sub(/^#{indentation}/, '')
80
- new_line
81
- end
82
-
83
- outdent
84
72
  end
85
- emit closing
73
+ outdent
86
74
  end
87
75
 
88
76
  def preformatted_block(opening, content, closing)
89
77
  new_line
90
- emit opening
91
- emit content
92
- emit closing
78
+ emit opening, content, closing
93
79
  new_line
94
80
  end
95
81
 
96
82
  def standalone_element(e)
97
83
  emit e
98
- new_line if e =~ /^<br[^\w]/
84
+ new_line if e =~ %r{^<br[^\w]}
99
85
  end
100
86
 
101
- def close_block_element(e)
87
+ def close_element(e)
102
88
  outdent
103
89
  emit e
104
- new_line
105
90
  end
106
91
 
107
- def open_block_element(e)
92
+ def close_block_element(e)
93
+ close_element e
108
94
  new_line
109
- emit e
110
- indent
111
- end
112
-
113
- def close_element(e)
114
- outdent
115
- emit e
116
95
  end
117
96
 
118
97
  def open_element(e)
@@ -120,6 +99,11 @@ module HtmlBeautifier
120
99
  indent
121
100
  end
122
101
 
102
+ def open_block_element(e)
103
+ new_line
104
+ open_element e
105
+ end
106
+
123
107
  def close_ie_cc(e)
124
108
  if @ie_cc_levels.empty?
125
109
  error "Unclosed conditional comment"
@@ -137,7 +121,7 @@ module HtmlBeautifier
137
121
 
138
122
  def text(t)
139
123
  emit t.chomp
140
- new_line if t.end_with? $/
124
+ new_line if t.end_with?("\n")
141
125
  end
142
126
  end
143
127
  end
@@ -1,4 +1,4 @@
1
- require 'htmlbeautifier/parser'
1
+ require "htmlbeautifier/parser"
2
2
 
3
3
  module HtmlBeautifier
4
4
  class HtmlParser < Parser
@@ -14,38 +14,45 @@ module HtmlBeautifier
14
14
  pre | section | table | tbody | td | tfoot | th | thead | tr | ul | video
15
15
  )}mix
16
16
 
17
+ MAPPINGS = [
18
+ [%r{(<%-?=?)(.*?)(-?%>)}om,
19
+ :embed],
20
+ [%r{<!--\[.*?\]>}om,
21
+ :open_ie_cc],
22
+ [%r{<!\[.*?\]-->}om,
23
+ :close_ie_cc],
24
+ [%r{<!--.*?-->}om,
25
+ :standalone_element],
26
+ [%r{<!.*?>}om,
27
+ :standalone_element],
28
+ [%r{(<script#{ELEMENT_CONTENT}>)(.*?)(</script>)}omi,
29
+ :foreign_block],
30
+ [%r{(<style#{ELEMENT_CONTENT}>)(.*?)(</style>)}omi,
31
+ :foreign_block],
32
+ [%r{(<pre#{ELEMENT_CONTENT}>)(.*?)(</pre>)}omi,
33
+ :preformatted_block],
34
+ [%r{(<textarea#{ELEMENT_CONTENT}>)(.*?)(</textarea>)}omi,
35
+ :preformatted_block],
36
+ [%r{<#{HTML_VOID_ELEMENTS}(?: #{ELEMENT_CONTENT})?/?>}om,
37
+ :standalone_element],
38
+ [%r{</#{HTML_BLOCK_ELEMENTS}>}om,
39
+ :close_block_element],
40
+ [%r{<#{HTML_BLOCK_ELEMENTS}(?: #{ELEMENT_CONTENT})?>}om,
41
+ :open_block_element],
42
+ [%r{</#{ELEMENT_CONTENT}>}om,
43
+ :close_element],
44
+ [%r{<#{ELEMENT_CONTENT}>}om,
45
+ :open_element],
46
+ [%r{\s*\r?\n\s*}om,
47
+ :new_line],
48
+ [%r{[^<]+},
49
+ :text]]
50
+
17
51
  def initialize
18
52
  super do |p|
19
- p.map %r{(<%-?=?)(.*?)(-?%>)}m,
20
- :embed
21
- p.map %r{<!--\[.*?\]>}m,
22
- :open_ie_cc
23
- p.map %r{<!\[.*?\]-->}m,
24
- :close_ie_cc
25
- p.map %r{<!--.*?-->}m,
26
- :standalone_element
27
- p.map %r{<!.*?>}m,
28
- :standalone_element
29
- p.map %r{(<script#{ELEMENT_CONTENT}>)(.*?)(</script>)}mi,
30
- :foreign_block
31
- p.map %r{(<style#{ELEMENT_CONTENT}>)(.*?)(</style>)}mi,
32
- :foreign_block
33
- p.map %r{(<pre#{ELEMENT_CONTENT}>)(.*?)(</pre>)}mi,
34
- :preformatted_block
35
- p.map %r{<#{HTML_VOID_ELEMENTS}(?: #{ELEMENT_CONTENT})?/?>}m,
36
- :standalone_element
37
- p.map %r{</#{HTML_BLOCK_ELEMENTS}>}m,
38
- :close_block_element
39
- p.map %r{<#{HTML_BLOCK_ELEMENTS}(?: #{ELEMENT_CONTENT})?>}m,
40
- :open_block_element
41
- p.map %r{</#{ELEMENT_CONTENT}>}m,
42
- :close_element
43
- p.map %r{<#{ELEMENT_CONTENT}>}m,
44
- :open_element
45
- p.map %r{\s*\r?\n\s*}m,
46
- :new_line
47
- p.map %r{[^<]+},
48
- :text
53
+ MAPPINGS.each do |regexp, method|
54
+ p.map regexp, method
55
+ end
49
56
  end
50
57
  end
51
58
  end
@@ -1,19 +1,8 @@
1
- require 'strscan'
1
+ require "strscan"
2
2
 
3
3
  module HtmlBeautifier
4
4
  class Parser
5
-
6
- def self.debug_block(&blk)
7
- @debug_block = blk
8
- end
9
-
10
- def self.debug(match, method)
11
- if defined? @debug_block
12
- @debug_block.call(match, method)
13
- end
14
- end
15
-
16
- def initialize(&blk)
5
+ def initialize
17
6
  @maps = []
18
7
  yield self if block_given?
19
8
  end
@@ -24,9 +13,7 @@ module HtmlBeautifier
24
13
 
25
14
  def scan(subject, receiver)
26
15
  @scanner = StringScanner.new(subject)
27
- until @scanner.eos?
28
- dispatch(receiver)
29
- end
16
+ dispatch(receiver) until @scanner.eos?
30
17
  end
31
18
 
32
19
  def source_so_far
@@ -34,28 +21,28 @@ module HtmlBeautifier
34
21
  end
35
22
 
36
23
  def source_line_number
37
- [source_so_far.chomp.split(/\n/).count, 1].max
24
+ [source_so_far.chomp.split(%r{\n}).count, 1].max
38
25
  end
39
26
 
40
27
  private
28
+
41
29
  def dispatch(receiver)
42
- @maps.each do |pattern, method|
43
- if @scanner.scan(pattern)
44
- params = []
45
- i = 1
46
- while @scanner[i]
47
- params << @scanner[i]
48
- i += 1
49
- end
50
- params = [@scanner[0]] if params.empty?
51
- self.class.debug(@scanner[0], method)
52
- receiver.__send__(method, *params)
53
- return
54
- end
55
- end
56
- raise "Unmatched sequence"
30
+ _, method = @maps.find { |pattern, _| @scanner.scan(pattern) }
31
+ raise "Unmatched sequence" unless method
32
+ receiver.__send__(method, *extract_params(@scanner))
57
33
  rescue => ex
58
34
  raise "#{ex.message} on line #{source_line_number}"
59
35
  end
36
+
37
+ def extract_params(scanner)
38
+ return [scanner[0]] unless scanner[1]
39
+ params = []
40
+ i = 1
41
+ while scanner[i]
42
+ params << scanner[i]
43
+ i += 1
44
+ end
45
+ params
46
+ end
60
47
  end
61
48
  end
@@ -0,0 +1,19 @@
1
+ module HtmlBeautifier
2
+ 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{
6
+ ^ ( #{INDENT_KEYWORDS.join("|")} )\b
7
+ | \b ( do | \{ ) ( \s* \| [^\|]+ \| )? $
8
+ }xo
9
+ RUBY_OUTDENT = %r{ ^ ( #{OUTDENT_KEYWORDS.join("|")} | \} ) \b }xo
10
+
11
+ def outdent?(lines)
12
+ lines.first =~ RUBY_OUTDENT
13
+ end
14
+
15
+ def indent?(lines)
16
+ lines.last =~ RUBY_INDENT
17
+ end
18
+ end
19
+ end
@@ -2,8 +2,8 @@ module HtmlBeautifier #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 1
4
4
  MINOR = 1
5
- TINY = 0
5
+ TINY = 1
6
6
 
7
- STRING = [MAJOR, MINOR, TINY].join('.')
7
+ STRING = [MAJOR, MINOR, TINY].join(".")
8
8
  end
9
9
  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.1.0
4
+ version: 1.1.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: 2015-03-07 00:00:00.000000000 Z
11
+ date: 2015-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.30.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.30.0
41
55
  description: A normaliser/beautifier for HTML that also understands embedded Ruby.
42
56
  email: pbattley@gmail.com
43
57
  executables:
@@ -52,6 +66,7 @@ files:
52
66
  - lib/htmlbeautifier/builder.rb
53
67
  - lib/htmlbeautifier/html_parser.rb
54
68
  - lib/htmlbeautifier/parser.rb
69
+ - lib/htmlbeautifier/ruby_indenter.rb
55
70
  - lib/htmlbeautifier/version.rb
56
71
  homepage: http://github.com/threedaymonk/htmlbeautifier
57
72
  licenses:
@@ -73,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
88
  version: '0'
74
89
  requirements: []
75
90
  rubyforge_project:
76
- rubygems_version: 2.2.2
91
+ rubygems_version: 2.4.5
77
92
  signing_key:
78
93
  specification_version: 4
79
94
  summary: HTML/ERB beautifier