htmlformatter 1.5.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 +7 -0
- data/README.md +71 -0
- data/Rakefile +16 -0
- data/bin/htmlformatter +86 -0
- data/lib/htmlformatter.rb +29 -0
- data/lib/htmlformatter/builder.rb +147 -0
- data/lib/htmlformatter/elixir_indenter.rb +19 -0
- data/lib/htmlformatter/html_parser.rb +61 -0
- data/lib/htmlformatter/parser.rb +48 -0
- data/lib/htmlformatter/ruby_indenter.rb +19 -0
- data/lib/htmlformatter/version.rb +9 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a5ebc277c83a5ccab865848d6aeb362fc75d2f79e873521840c11bb279462a9e
|
4
|
+
data.tar.gz: 5068a689fedc3844836affa11eb2fa2afb0018073be7802f22f7fa5b1068f4bf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 578e632d90a7c13840b0f195e0eba4f983f9f4ddd4d3ce7c63e6f1197d5cb88765a8496af8057e33c69037806a45d0b57cd54cf765ed78c504b61bb241d9c8ab
|
7
|
+
data.tar.gz: 4a88997ed83e8086e696ccd053c9af830bca8ac8f6d0377ab612aa5a6d9812df2b0951312e74caf8849d1478c16e9d0604d5bc6952f1433b2518e1830590f360
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# HTML Formatter
|
2
|
+
|
3
|
+
A normaliser/formatter for HTML that also understands embedded Ruby and Elixir.
|
4
|
+
Ideal for tidying up Rails and Phoenix templates.
|
5
|
+
|
6
|
+
## What it does
|
7
|
+
|
8
|
+
* Normalises hard tabs to spaces (or vice versa)
|
9
|
+
* Removes trailing spaces
|
10
|
+
* Indents after opening HTML elements
|
11
|
+
* Outdents before closing elements
|
12
|
+
* Collapses multiple whitespace
|
13
|
+
* Indents after block-opening embedded Ruby or Elixir (if, do etc.)
|
14
|
+
* Outdents before closing Ruby or Elixir blocks
|
15
|
+
* Outdents elsif and then indents again
|
16
|
+
* Indents the left-hand margin of JavaScript and CSS blocks to match the
|
17
|
+
indentation level of the code
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
### From the command line
|
22
|
+
|
23
|
+
To update files in-place:
|
24
|
+
|
25
|
+
``` sh
|
26
|
+
$ htmlformatter file1 [file2 ...]
|
27
|
+
```
|
28
|
+
|
29
|
+
or to operate on standard input and output:
|
30
|
+
|
31
|
+
``` sh
|
32
|
+
$ htmlformatter < input > output
|
33
|
+
```
|
34
|
+
|
35
|
+
### In your code
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
require 'htmlformatter'
|
39
|
+
|
40
|
+
formatted = HtmlFormatter.format(messy)
|
41
|
+
```
|
42
|
+
|
43
|
+
You can also specify how to indent (the default is two spaces):
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
formatted = HtmlFormatter.format(messy, indent: "\t")
|
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 htmlformatter
|
56
|
+
```
|
57
|
+
|
58
|
+
To use the gem with Bundler, add to your `Gemfile`:
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
gem 'htmlformatter'
|
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
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "rspec/core/rake_task"
|
2
|
+
|
3
|
+
desc "Run the specs."
|
4
|
+
RSpec::Core::RakeTask.new do |t|
|
5
|
+
t.pattern = "spec/**/*_spec.rb"
|
6
|
+
t.verbose = false
|
7
|
+
end
|
8
|
+
|
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
|
data/bin/htmlformatter
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "htmlformatter"
|
3
|
+
require "optparse"
|
4
|
+
require "fileutils"
|
5
|
+
|
6
|
+
def format(name, input, output, options)
|
7
|
+
output.puts HtmlFormatter.format(input, options)
|
8
|
+
rescue => e
|
9
|
+
raise "Error parsing #{name}: #{e}"
|
10
|
+
end
|
11
|
+
|
12
|
+
executable = File.basename(__FILE__)
|
13
|
+
|
14
|
+
options = { indent: " " }
|
15
|
+
parser = OptionParser.new do |opts|
|
16
|
+
opts.banner = "Usage: #{executable} [options] [file ...]"
|
17
|
+
opts.separator <<END
|
18
|
+
|
19
|
+
#{executable} has two modes of operation:
|
20
|
+
|
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 formatted output.
|
25
|
+
|
26
|
+
The following options are available:
|
27
|
+
|
28
|
+
END
|
29
|
+
opts.on(
|
30
|
+
"-t", "--tab-stops NUMBER", Integer,
|
31
|
+
"Set number of spaces per indent (default #{options[:tab_stops]})"
|
32
|
+
) do |num|
|
33
|
+
options[:indent] = " " * num
|
34
|
+
end
|
35
|
+
opts.on(
|
36
|
+
"-T", "--tab",
|
37
|
+
"Indent using tabs"
|
38
|
+
) do
|
39
|
+
options[:indent] = "\t"
|
40
|
+
end
|
41
|
+
opts.on(
|
42
|
+
"-i", "--indent-by NUMBER", Integer,
|
43
|
+
"Indent the output by NUMBER steps (default 0)."
|
44
|
+
) do |num|
|
45
|
+
options[:initial_level] = num
|
46
|
+
end
|
47
|
+
opts.on(
|
48
|
+
"-e", "--stop-on-errors",
|
49
|
+
"Stop when invalid nesting is encountered in the input"
|
50
|
+
) do |num|
|
51
|
+
options[:stop_on_errors] = num
|
52
|
+
end
|
53
|
+
opts.on(
|
54
|
+
"-b", "--keep-blank-lines NUMBER", Integer,
|
55
|
+
"Set number of consecutive blank lines"
|
56
|
+
) do |num|
|
57
|
+
options[:keep_blank_lines] = num
|
58
|
+
end
|
59
|
+
opts.on(
|
60
|
+
"-n", "--engine STRING", String,
|
61
|
+
"Use engine STRING (default erb, allowed: eex)."
|
62
|
+
) do |eng|
|
63
|
+
options[:engine] = eng
|
64
|
+
end
|
65
|
+
opts.on(
|
66
|
+
"-h", "--help",
|
67
|
+
"Display this help message and exit"
|
68
|
+
) do
|
69
|
+
puts opts
|
70
|
+
exit
|
71
|
+
end
|
72
|
+
end
|
73
|
+
parser.parse!
|
74
|
+
|
75
|
+
if ARGV.any?
|
76
|
+
ARGV.each do |path|
|
77
|
+
input = File.read(path)
|
78
|
+
temppath = path + ".tmp"
|
79
|
+
File.open(temppath, "w") do |output|
|
80
|
+
format path, input, output, options
|
81
|
+
end
|
82
|
+
FileUtils.mv temppath, path
|
83
|
+
end
|
84
|
+
else
|
85
|
+
format "standard input", $stdin.read, $stdout, options
|
86
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "htmlformatter/builder"
|
2
|
+
require "htmlformatter/html_parser"
|
3
|
+
require "htmlformatter/version"
|
4
|
+
|
5
|
+
module HtmlFormatter
|
6
|
+
#
|
7
|
+
# Returns a formatted HTML/HTML+EEX document as a String.
|
8
|
+
# html must be an object that responds to +#to_s+.
|
9
|
+
#
|
10
|
+
# Available options are:
|
11
|
+
# tab_stops - an integer for the number of spaces to indent, default 2.
|
12
|
+
# Deprecated: see indent.
|
13
|
+
# indent - what to indent with (" ", "\t" etc.), default " "
|
14
|
+
# stop_on_errors - raise an exception on a badly-formed document. Default
|
15
|
+
# is false, i.e. continue to process the rest of the document.
|
16
|
+
# initial_level - The entire output will be indented by this number of steps.
|
17
|
+
# Default is 0.
|
18
|
+
# keep_blank_lines - an integer for the number of consecutive empty lines
|
19
|
+
# to keep in output.
|
20
|
+
#
|
21
|
+
def self.format(html, options = {})
|
22
|
+
if options[:tab_stops]
|
23
|
+
options[:indent] = " " * options[:tab_stops]
|
24
|
+
end
|
25
|
+
"".tap { |output|
|
26
|
+
HtmlParser.new.scan html.to_s, Builder.new(output, options)
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require "htmlformatter/parser"
|
2
|
+
require "htmlformatter/ruby_indenter"
|
3
|
+
require "htmlformatter/elixir_indenter"
|
4
|
+
|
5
|
+
module HtmlFormatter
|
6
|
+
class Builder
|
7
|
+
DEFAULT_OPTIONS = {
|
8
|
+
indent: " ",
|
9
|
+
initial_level: 0,
|
10
|
+
stop_on_errors: false,
|
11
|
+
keep_blank_lines: 0
|
12
|
+
}
|
13
|
+
|
14
|
+
def initialize(output, options = {})
|
15
|
+
options = DEFAULT_OPTIONS.merge(options)
|
16
|
+
@tab = options[:indent]
|
17
|
+
@stop_on_errors = options[:stop_on_errors]
|
18
|
+
@level = options[:initial_level]
|
19
|
+
@keep_blank_lines = options[:keep_blank_lines]
|
20
|
+
@new_line = false
|
21
|
+
@empty = true
|
22
|
+
@ie_cc_levels = []
|
23
|
+
@output = output
|
24
|
+
|
25
|
+
if options[:engine] == "eex"
|
26
|
+
@embedded_indenter = ElixirIndenter.new
|
27
|
+
else
|
28
|
+
@embedded_indenter = RubyIndenter.new
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def error(text)
|
35
|
+
return unless @stop_on_errors
|
36
|
+
raise text
|
37
|
+
end
|
38
|
+
|
39
|
+
def indent
|
40
|
+
@level += 1
|
41
|
+
end
|
42
|
+
|
43
|
+
def outdent
|
44
|
+
error "Extraneous closing tag" if @level == 0
|
45
|
+
@level = [@level - 1, 0].max
|
46
|
+
end
|
47
|
+
|
48
|
+
def emit(*strings)
|
49
|
+
@output << "\n" if @new_line && !@empty
|
50
|
+
@output << (@tab * @level) if @new_line
|
51
|
+
@output << strings.join("")
|
52
|
+
@new_line = false
|
53
|
+
@empty = false
|
54
|
+
end
|
55
|
+
|
56
|
+
def new_line
|
57
|
+
@new_line = true
|
58
|
+
end
|
59
|
+
|
60
|
+
def embed(opening, code, closing)
|
61
|
+
lines = code.split(%r{\n}).map(&:strip)
|
62
|
+
outdent if @embedded_indenter.outdent?(lines)
|
63
|
+
emit opening, code, closing
|
64
|
+
indent if @embedded_indenter.indent?(lines)
|
65
|
+
end
|
66
|
+
|
67
|
+
def foreign_block(opening, code, closing)
|
68
|
+
emit opening
|
69
|
+
emit_reindented_block_content code unless code.strip.empty?
|
70
|
+
emit closing
|
71
|
+
end
|
72
|
+
|
73
|
+
def emit_reindented_block_content(code)
|
74
|
+
lines = code.strip.split(%r{\n})
|
75
|
+
indentation = foreign_block_indentation(code)
|
76
|
+
|
77
|
+
indent
|
78
|
+
new_line
|
79
|
+
lines.each do |line|
|
80
|
+
emit line.rstrip.sub(%r{^#{indentation}}, "")
|
81
|
+
new_line
|
82
|
+
end
|
83
|
+
outdent
|
84
|
+
end
|
85
|
+
|
86
|
+
def foreign_block_indentation(code)
|
87
|
+
code.split(%r{\n}).find { |ln| !ln.strip.empty? }[%r{^\s+}]
|
88
|
+
end
|
89
|
+
|
90
|
+
def preformatted_block(opening, content, closing)
|
91
|
+
new_line
|
92
|
+
emit opening, content, closing
|
93
|
+
new_line
|
94
|
+
end
|
95
|
+
|
96
|
+
def standalone_element(e)
|
97
|
+
emit e
|
98
|
+
new_line if e =~ %r{^<br[^\w]}
|
99
|
+
end
|
100
|
+
|
101
|
+
def close_element(e)
|
102
|
+
outdent
|
103
|
+
emit e
|
104
|
+
end
|
105
|
+
|
106
|
+
def close_block_element(e)
|
107
|
+
close_element e
|
108
|
+
new_line
|
109
|
+
end
|
110
|
+
|
111
|
+
def open_element(e)
|
112
|
+
emit e
|
113
|
+
indent
|
114
|
+
end
|
115
|
+
|
116
|
+
def open_block_element(e)
|
117
|
+
new_line
|
118
|
+
open_element e
|
119
|
+
end
|
120
|
+
|
121
|
+
def close_ie_cc(e)
|
122
|
+
if @ie_cc_levels.empty?
|
123
|
+
error "Unclosed conditional comment"
|
124
|
+
else
|
125
|
+
@level = @ie_cc_levels.pop
|
126
|
+
end
|
127
|
+
emit e
|
128
|
+
end
|
129
|
+
|
130
|
+
def open_ie_cc(e)
|
131
|
+
emit e
|
132
|
+
@ie_cc_levels.push @level
|
133
|
+
indent
|
134
|
+
end
|
135
|
+
|
136
|
+
def new_lines(*content)
|
137
|
+
blank_lines = content.first.scan(%r{\n}).count - 1
|
138
|
+
blank_lines = [blank_lines, @keep_blank_lines].min
|
139
|
+
@output << "\n" * blank_lines
|
140
|
+
new_line
|
141
|
+
end
|
142
|
+
|
143
|
+
def text(t)
|
144
|
+
emit t
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module HtmlFormatter
|
2
|
+
class ElixirIndenter
|
3
|
+
INDENT_KEYWORDS = %w[ else ]
|
4
|
+
OUTDENT_KEYWORDS = %w[ else end ]
|
5
|
+
ELIXIR_INDENT = %r{
|
6
|
+
^ ( #{INDENT_KEYWORDS.join("|")} )\b
|
7
|
+
| ( -\> | do ) $
|
8
|
+
}xo
|
9
|
+
ELIXIR_OUTDENT = %r{ ^ ( #{OUTDENT_KEYWORDS.join("|")} | \} ) \b }xo
|
10
|
+
|
11
|
+
def outdent?(lines)
|
12
|
+
lines.first =~ ELIXIR_OUTDENT
|
13
|
+
end
|
14
|
+
|
15
|
+
def indent?(lines)
|
16
|
+
lines.last =~ ELIXIR_INDENT
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "htmlformatter/parser"
|
2
|
+
|
3
|
+
module HtmlFormatter
|
4
|
+
class HtmlParser < Parser
|
5
|
+
ELEMENT_CONTENT = %r{ (?:<%.*?%>|[^>])* }mx
|
6
|
+
HTML_VOID_ELEMENTS = %r{(?:
|
7
|
+
area | base | br | col | command | embed | hr | img | input | keygen |
|
8
|
+
link | meta | param | source | track | wbr
|
9
|
+
)}mix
|
10
|
+
HTML_BLOCK_ELEMENTS = %r{(?:
|
11
|
+
address | article | aside | audio | blockquote | canvas | dd | dir | div |
|
12
|
+
dl | dt | fieldset | figcaption | figure | footer | form | h1 | h2 | h3 |
|
13
|
+
h4 | h5 | h6 | header | hr | li | menu | noframes | noscript | ol | p |
|
14
|
+
pre | section | table | tbody | td | tfoot | th | thead | tr | ul | video
|
15
|
+
)}mix
|
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{<\w+(?: #{ELEMENT_CONTENT})?/>}om,
|
39
|
+
:standalone_element],
|
40
|
+
[%r{</#{HTML_BLOCK_ELEMENTS}>}om,
|
41
|
+
:close_block_element],
|
42
|
+
[%r{<#{HTML_BLOCK_ELEMENTS}(?: #{ELEMENT_CONTENT})?>}om,
|
43
|
+
:open_block_element],
|
44
|
+
[%r{</#{ELEMENT_CONTENT}>}om,
|
45
|
+
:close_element],
|
46
|
+
[%r{<#{ELEMENT_CONTENT}>}om,
|
47
|
+
:open_element],
|
48
|
+
[%r{(\s*\r?\n\s*)+}om,
|
49
|
+
:new_lines],
|
50
|
+
[%r{[^<\n]+},
|
51
|
+
:text]]
|
52
|
+
|
53
|
+
def initialize
|
54
|
+
super do |p|
|
55
|
+
MAPPINGS.each do |regexp, method|
|
56
|
+
p.map regexp, method
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "strscan"
|
2
|
+
|
3
|
+
module HtmlFormatter
|
4
|
+
class Parser
|
5
|
+
def initialize
|
6
|
+
@maps = []
|
7
|
+
yield self if block_given?
|
8
|
+
end
|
9
|
+
|
10
|
+
def map(pattern, method)
|
11
|
+
@maps << [pattern, method]
|
12
|
+
end
|
13
|
+
|
14
|
+
def scan(subject, receiver)
|
15
|
+
@scanner = StringScanner.new(subject)
|
16
|
+
dispatch(receiver) until @scanner.eos?
|
17
|
+
end
|
18
|
+
|
19
|
+
def source_so_far
|
20
|
+
@scanner.string[0...@scanner.pos]
|
21
|
+
end
|
22
|
+
|
23
|
+
def source_line_number
|
24
|
+
[source_so_far.chomp.split(%r{\n}).count, 1].max
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def dispatch(receiver)
|
30
|
+
_, method = @maps.find { |pattern, _| @scanner.scan(pattern) }
|
31
|
+
raise "Unmatched sequence" unless method
|
32
|
+
receiver.__send__(method, *extract_params(@scanner))
|
33
|
+
rescue => ex
|
34
|
+
raise "#{ex.message} on line #{source_line_number}"
|
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
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module HtmlFormatter
|
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
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: htmlformatter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.5.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Paul Battley
|
8
|
+
- Bartosz Kalinowski
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2021-06-11 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rspec
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '3'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '3'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rubocop
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 0.30.0
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 0.30.0
|
56
|
+
description: A normaliser/formatter for HTML that also understands embedded Ruby and
|
57
|
+
Elixir.
|
58
|
+
email: kelostrada@gmail.com
|
59
|
+
executables:
|
60
|
+
- htmlformatter
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- README.md
|
65
|
+
- Rakefile
|
66
|
+
- bin/htmlformatter
|
67
|
+
- lib/htmlformatter.rb
|
68
|
+
- lib/htmlformatter/builder.rb
|
69
|
+
- lib/htmlformatter/elixir_indenter.rb
|
70
|
+
- lib/htmlformatter/html_parser.rb
|
71
|
+
- lib/htmlformatter/parser.rb
|
72
|
+
- lib/htmlformatter/ruby_indenter.rb
|
73
|
+
- lib/htmlformatter/version.rb
|
74
|
+
homepage: http://github.com/kelostrada/htmlformatter
|
75
|
+
licenses:
|
76
|
+
- MIT
|
77
|
+
metadata: {}
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options: []
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: 1.9.2
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
requirements: []
|
93
|
+
rubygems_version: 3.0.3
|
94
|
+
signing_key:
|
95
|
+
specification_version: 4
|
96
|
+
summary: HTML/ERB/EEX formatter
|
97
|
+
test_files: []
|