haml 5.2.2 → 6.0.0.beta.1
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 +4 -4
- data/.github/FUNDING.yml +1 -0
- data/.github/workflows/test.yml +13 -9
- data/.gitignore +16 -16
- data/CHANGELOG.md +13 -3
- data/Gemfile +18 -11
- data/MIT-LICENSE +1 -1
- data/README.md +13 -19
- data/Rakefile +95 -93
- data/bin/bench +66 -0
- data/bin/console +11 -0
- data/bin/ruby +3 -0
- data/bin/setup +7 -0
- data/bin/stackprof +27 -0
- data/bin/test +24 -0
- data/exe/haml +6 -0
- data/ext/haml/extconf.rb +10 -0
- data/ext/haml/haml.c +537 -0
- data/ext/haml/hescape.c +108 -0
- data/ext/haml/hescape.h +20 -0
- data/haml.gemspec +39 -37
- data/lib/haml/ambles.rb +20 -0
- data/lib/haml/attribute_builder.rb +135 -179
- data/lib/haml/attribute_compiler.rb +85 -194
- data/lib/haml/attribute_parser.rb +86 -126
- data/lib/haml/cli.rb +154 -0
- data/lib/haml/compiler/children_compiler.rb +126 -0
- data/lib/haml/compiler/comment_compiler.rb +39 -0
- data/lib/haml/compiler/doctype_compiler.rb +46 -0
- data/lib/haml/compiler/script_compiler.rb +116 -0
- data/lib/haml/compiler/silent_script_compiler.rb +24 -0
- data/lib/haml/compiler/tag_compiler.rb +76 -0
- data/lib/haml/compiler.rb +63 -296
- data/lib/haml/dynamic_merger.rb +67 -0
- data/lib/haml/engine.rb +42 -227
- data/lib/haml/error.rb +3 -52
- data/lib/haml/escapable.rb +6 -70
- data/lib/haml/filters/base.rb +12 -0
- data/lib/haml/filters/cdata.rb +20 -0
- data/lib/haml/filters/coffee.rb +17 -0
- data/lib/haml/filters/css.rb +33 -0
- data/lib/haml/filters/erb.rb +10 -0
- data/lib/haml/filters/escaped.rb +22 -0
- data/lib/haml/filters/javascript.rb +33 -0
- data/lib/haml/filters/less.rb +20 -0
- data/lib/haml/filters/markdown.rb +11 -0
- data/lib/haml/filters/plain.rb +29 -0
- data/lib/haml/filters/preserve.rb +22 -0
- data/lib/haml/filters/ruby.rb +10 -0
- data/lib/haml/filters/sass.rb +15 -0
- data/lib/haml/filters/scss.rb +15 -0
- data/lib/haml/filters/text_base.rb +25 -0
- data/lib/haml/filters/tilt_base.rb +49 -0
- data/lib/haml/filters.rb +54 -378
- data/lib/haml/force_escapable.rb +29 -0
- data/lib/haml/haml_error.rb +66 -0
- data/lib/haml/helpers.rb +3 -697
- data/lib/haml/html.rb +22 -0
- data/lib/haml/identity.rb +13 -0
- data/lib/haml/object_ref.rb +30 -0
- data/lib/haml/parser.rb +179 -49
- data/lib/haml/rails_helpers.rb +51 -0
- data/lib/haml/rails_template.rb +55 -0
- data/lib/haml/railtie.rb +7 -45
- data/lib/haml/ruby_expression.rb +32 -0
- data/lib/haml/string_splitter.rb +20 -0
- data/lib/haml/template.rb +15 -34
- data/lib/haml/temple_line_counter.rb +2 -1
- data/lib/haml/util.rb +17 -15
- data/lib/haml/version.rb +1 -2
- data/lib/haml.rb +8 -20
- metadata +211 -57
- data/.gitmodules +0 -3
- data/.yardopts +0 -22
- data/TODO +0 -24
- data/benchmark.rb +0 -70
- data/bin/haml +0 -9
- data/lib/haml/.gitattributes +0 -1
- data/lib/haml/buffer.rb +0 -182
- data/lib/haml/exec.rb +0 -347
- data/lib/haml/generator.rb +0 -42
- data/lib/haml/helpers/action_view_extensions.rb +0 -60
- data/lib/haml/helpers/action_view_mods.rb +0 -132
- data/lib/haml/helpers/action_view_xss_mods.rb +0 -60
- data/lib/haml/helpers/safe_erubi_template.rb +0 -20
- data/lib/haml/helpers/safe_erubis_template.rb +0 -33
- data/lib/haml/helpers/xss_mods.rb +0 -114
- data/lib/haml/options.rb +0 -273
- data/lib/haml/plugin.rb +0 -54
- data/lib/haml/sass_rails_filter.rb +0 -47
- data/lib/haml/template/options.rb +0 -27
- data/lib/haml/temple_engine.rb +0 -124
- data/yard/default/.gitignore +0 -1
- data/yard/default/fulldoc/html/css/common.sass +0 -15
- data/yard/default/layout/html/footer.erb +0 -12
data/TODO
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
# -*- mode: org -*-
|
2
|
-
#+STARTUP: nofold
|
3
|
-
|
4
|
-
* Documentation
|
5
|
-
Redo tutorial?
|
6
|
-
Using helpers
|
7
|
-
haml_concat and haml_tag in particular
|
8
|
-
Syntax highlighting?
|
9
|
-
|
10
|
-
* Code
|
11
|
-
Keep track of error offsets everywhere
|
12
|
-
Use this to show error location in messages
|
13
|
-
** Haml
|
14
|
-
Support finer-grained HTML-escaping in filters
|
15
|
-
Speed
|
16
|
-
Make tags with dynamic attributes pre-render as much as possible
|
17
|
-
Including the attribute name where doable
|
18
|
-
:html improvements
|
19
|
-
Ignore closing tags where we can
|
20
|
-
http://code.google.com/speed/articles/optimizing-html.html
|
21
|
-
Requires Haml parsing refactor
|
22
|
-
Don't quote attributes that don't require it
|
23
|
-
http://www.w3.org/TR/REC-html40/intro/sgmltut.html#h-3.2.2
|
24
|
-
http://www.w3.org/TR/html5/syntax.html#attributes
|
data/benchmark.rb
DELETED
@@ -1,70 +0,0 @@
|
|
1
|
-
require "bundler/setup"
|
2
|
-
require "haml"
|
3
|
-
require "rbench"
|
4
|
-
|
5
|
-
times = (ARGV.first || 1000).to_i
|
6
|
-
|
7
|
-
if times == 0 # Invalid parameter
|
8
|
-
puts <<END
|
9
|
-
ruby #$0 [times=1000]
|
10
|
-
Benchmark Haml against various other templating languages.
|
11
|
-
END
|
12
|
-
exit 1
|
13
|
-
end
|
14
|
-
|
15
|
-
%w[erb erubi rails active_support action_controller
|
16
|
-
action_view action_pack haml/template rbench].each {|dep| require(dep)}
|
17
|
-
|
18
|
-
def view
|
19
|
-
base = ActionView::Base.new
|
20
|
-
base.view_paths << File.join(File.dirname(__FILE__), '/test')
|
21
|
-
base
|
22
|
-
end
|
23
|
-
|
24
|
-
def render(view, file)
|
25
|
-
view.render :file => file
|
26
|
-
end
|
27
|
-
|
28
|
-
RBench.run(times) do
|
29
|
-
column :haml, :title => "Haml"
|
30
|
-
column :erb, :title => "ERB"
|
31
|
-
column :erubi, :title => "Erubi"
|
32
|
-
|
33
|
-
template_name = 'standard'
|
34
|
-
haml_template = File.read("#{File.dirname(__FILE__)}/test/templates/#{template_name}.haml")
|
35
|
-
erb_template = File.read("#{File.dirname(__FILE__)}/test/erb/#{template_name}.erb")
|
36
|
-
|
37
|
-
report "Cached" do
|
38
|
-
obj = Object.new
|
39
|
-
|
40
|
-
Haml::Engine.new(haml_template).def_method(obj, :haml)
|
41
|
-
if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
|
42
|
-
obj.instance_eval("def erb; #{ERB.new(erb_template, trim_mode: '-').src}; end")
|
43
|
-
else
|
44
|
-
obj.instance_eval("def erb; #{ERB.new(erb_template, nil, '-').src}; end")
|
45
|
-
end
|
46
|
-
obj.instance_eval("def erubi; #{Erubi::Engine.new(erb_template).src}; end")
|
47
|
-
|
48
|
-
haml { obj.haml }
|
49
|
-
erb { obj.erb }
|
50
|
-
erubi { obj.erubi }
|
51
|
-
end
|
52
|
-
|
53
|
-
report "ActionView" do
|
54
|
-
# To cache the template
|
55
|
-
render view, 'templates/standard'
|
56
|
-
render view, 'erb/standard'
|
57
|
-
|
58
|
-
haml { render view, 'templates/standard' }
|
59
|
-
erubi { render view, 'erb/standard' }
|
60
|
-
end
|
61
|
-
|
62
|
-
report "ActionView with deep partials" do
|
63
|
-
# To cache the template
|
64
|
-
render view, 'templates/action_view'
|
65
|
-
render view, 'erb/action_view'
|
66
|
-
|
67
|
-
haml { render view, 'templates/action_view' }
|
68
|
-
erubi { render view, 'erb/action_view' }
|
69
|
-
end
|
70
|
-
end
|
data/bin/haml
DELETED
data/lib/haml/.gitattributes
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
version.rb merge=ours
|
data/lib/haml/buffer.rb
DELETED
@@ -1,182 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Haml
|
4
|
-
# This class is used only internally. It holds the buffer of HTML that
|
5
|
-
# is eventually output as the resulting document.
|
6
|
-
# It's called from within the precompiled code,
|
7
|
-
# and helps reduce the amount of processing done within `instance_eval`ed code.
|
8
|
-
class Buffer
|
9
|
-
include Haml::Helpers
|
10
|
-
include Haml::Util
|
11
|
-
|
12
|
-
# The string that holds the compiled HTML. This is aliased as
|
13
|
-
# `_erbout` for compatibility with ERB-specific code.
|
14
|
-
#
|
15
|
-
# @return [String]
|
16
|
-
attr_accessor :buffer
|
17
|
-
|
18
|
-
# The options hash passed in from {Haml::Engine}.
|
19
|
-
#
|
20
|
-
# @return [{String => Object}]
|
21
|
-
# @see Haml::Options#for_buffer
|
22
|
-
attr_accessor :options
|
23
|
-
|
24
|
-
# The {Buffer} for the enclosing Haml document.
|
25
|
-
# This is set for partials and similar sorts of nested templates.
|
26
|
-
# It's `nil` at the top level (see \{#toplevel?}).
|
27
|
-
#
|
28
|
-
# @return [Buffer]
|
29
|
-
attr_accessor :upper
|
30
|
-
|
31
|
-
# nil if there's no capture_haml block running,
|
32
|
-
# and the position at which it's beginning the capture if there is one.
|
33
|
-
#
|
34
|
-
# @return [Fixnum, nil]
|
35
|
-
attr_accessor :capture_position
|
36
|
-
|
37
|
-
# @return [Boolean]
|
38
|
-
# @see #active?
|
39
|
-
attr_writer :active
|
40
|
-
|
41
|
-
# @return [Boolean] Whether or not the format is XHTML
|
42
|
-
def xhtml?
|
43
|
-
not html?
|
44
|
-
end
|
45
|
-
|
46
|
-
# @return [Boolean] Whether or not the format is any flavor of HTML
|
47
|
-
def html?
|
48
|
-
html4? or html5?
|
49
|
-
end
|
50
|
-
|
51
|
-
# @return [Boolean] Whether or not the format is HTML4
|
52
|
-
def html4?
|
53
|
-
@options[:format] == :html4
|
54
|
-
end
|
55
|
-
|
56
|
-
# @return [Boolean] Whether or not the format is HTML5.
|
57
|
-
def html5?
|
58
|
-
@options[:format] == :html5
|
59
|
-
end
|
60
|
-
|
61
|
-
# @return [Boolean] Whether or not this buffer is a top-level template,
|
62
|
-
# as opposed to a nested partial
|
63
|
-
def toplevel?
|
64
|
-
upper.nil?
|
65
|
-
end
|
66
|
-
|
67
|
-
# Whether or not this buffer is currently being used to render a Haml template.
|
68
|
-
# Returns `false` if a subtemplate is being rendered,
|
69
|
-
# even if it's a subtemplate of this buffer's template.
|
70
|
-
#
|
71
|
-
# @return [Boolean]
|
72
|
-
def active?
|
73
|
-
@active
|
74
|
-
end
|
75
|
-
|
76
|
-
# @return [Fixnum] The current indentation level of the document
|
77
|
-
def tabulation
|
78
|
-
@real_tabs + @tabulation
|
79
|
-
end
|
80
|
-
|
81
|
-
# Sets the current tabulation of the document.
|
82
|
-
#
|
83
|
-
# @param val [Fixnum] The new tabulation
|
84
|
-
def tabulation=(val)
|
85
|
-
val = val - @real_tabs
|
86
|
-
@tabulation = val > -1 ? val : 0
|
87
|
-
end
|
88
|
-
|
89
|
-
# @param upper [Buffer] The parent buffer
|
90
|
-
# @param options [{Symbol => Object}] An options hash.
|
91
|
-
# See {Haml::Engine#options\_for\_buffer}
|
92
|
-
def initialize(upper = nil, options = {})
|
93
|
-
@active = true
|
94
|
-
@upper = upper
|
95
|
-
@options = Options.buffer_defaults
|
96
|
-
@options = @options.merge(options) unless options.empty?
|
97
|
-
@buffer = new_encoded_string
|
98
|
-
@tabulation = 0
|
99
|
-
|
100
|
-
# The number of tabs that Engine thinks we should have
|
101
|
-
# @real_tabs + @tabulation is the number of tabs actually output
|
102
|
-
@real_tabs = 0
|
103
|
-
end
|
104
|
-
|
105
|
-
# Appends text to the buffer, properly tabulated.
|
106
|
-
# Also modifies the document's indentation.
|
107
|
-
#
|
108
|
-
# @param text [String] The text to append
|
109
|
-
# @param tab_change [Fixnum] The number of tabs by which to increase
|
110
|
-
# or decrease the document's indentation
|
111
|
-
# @param dont_tab_up [Boolean] If true, don't indent the first line of `text`
|
112
|
-
def push_text(text, tab_change, dont_tab_up)
|
113
|
-
if @tabulation > 0
|
114
|
-
# Have to push every line in by the extra user set tabulation.
|
115
|
-
# Don't push lines with just whitespace, though,
|
116
|
-
# because that screws up precompiled indentation.
|
117
|
-
text.gsub!(/^(?!\s+$)/m, tabs)
|
118
|
-
text.sub!(tabs, '') if dont_tab_up
|
119
|
-
end
|
120
|
-
|
121
|
-
@real_tabs += tab_change
|
122
|
-
@buffer << text
|
123
|
-
end
|
124
|
-
|
125
|
-
# Modifies the indentation of the document.
|
126
|
-
#
|
127
|
-
# @param tab_change [Fixnum] The number of tabs by which to increase
|
128
|
-
# or decrease the document's indentation
|
129
|
-
def adjust_tabs(tab_change)
|
130
|
-
@real_tabs += tab_change
|
131
|
-
end
|
132
|
-
|
133
|
-
# Remove the whitespace from the right side of the buffer string.
|
134
|
-
# Doesn't do anything if we're at the beginning of a capture_haml block.
|
135
|
-
def rstrip!
|
136
|
-
if capture_position.nil?
|
137
|
-
buffer.rstrip!
|
138
|
-
return
|
139
|
-
end
|
140
|
-
|
141
|
-
buffer << buffer.slice!(capture_position..-1).rstrip
|
142
|
-
end
|
143
|
-
|
144
|
-
# Works like #{find_and_preserve}, but allows the first newline after a
|
145
|
-
# preserved opening tag to remain unencoded, and then outdents the content.
|
146
|
-
# This change was motivated primarily by the change in Rails 3.2.3 to emit
|
147
|
-
# a newline after textarea helpers.
|
148
|
-
#
|
149
|
-
# @param input [String] The text to process
|
150
|
-
# @since Haml 4.0.1
|
151
|
-
# @private
|
152
|
-
def fix_textareas!(input)
|
153
|
-
return input unless input.include?('<textarea'.freeze)
|
154
|
-
|
155
|
-
pattern = /<(textarea)([^>]*)>(\n|
)(.*?)<\/textarea>/im
|
156
|
-
input.gsub!(pattern) do |s|
|
157
|
-
match = pattern.match(s)
|
158
|
-
content = match[4]
|
159
|
-
if match[3] == '
'
|
160
|
-
content.sub!(/\A /, ' ')
|
161
|
-
else
|
162
|
-
content.sub!(/\A[ ]*/, '')
|
163
|
-
end
|
164
|
-
"<#{match[1]}#{match[2]}>\n#{content}</#{match[1]}>"
|
165
|
-
end
|
166
|
-
input
|
167
|
-
end
|
168
|
-
|
169
|
-
private
|
170
|
-
|
171
|
-
def new_encoded_string
|
172
|
-
"".encode(options[:encoding])
|
173
|
-
end
|
174
|
-
|
175
|
-
@@tab_cache = {}
|
176
|
-
# Gets `count` tabs. Mostly for internal use.
|
177
|
-
def tabs(count = 0)
|
178
|
-
tabs = [count + @tabulation, 0].max
|
179
|
-
@@tab_cache[tabs] ||= ' ' * tabs
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
data/lib/haml/exec.rb
DELETED
@@ -1,347 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'optparse'
|
4
|
-
require 'rbconfig'
|
5
|
-
require 'pp'
|
6
|
-
|
7
|
-
module Haml
|
8
|
-
# This module handles the various Haml executables (`haml` and `haml-convert`).
|
9
|
-
module Exec
|
10
|
-
# An abstract class that encapsulates the executable code for all three executables.
|
11
|
-
class Generic
|
12
|
-
# @param args [Array<String>] The command-line arguments
|
13
|
-
def initialize(args)
|
14
|
-
@args = args
|
15
|
-
@options = {:for_engine => {}}
|
16
|
-
end
|
17
|
-
|
18
|
-
# Parses the command-line arguments and runs the executable.
|
19
|
-
# Calls `Kernel#exit` at the end, so it never returns.
|
20
|
-
#
|
21
|
-
# @see #parse
|
22
|
-
def parse!
|
23
|
-
begin
|
24
|
-
parse
|
25
|
-
rescue Exception => e
|
26
|
-
raise e if @options[:trace] || e.is_a?(SystemExit)
|
27
|
-
|
28
|
-
$stderr.print "#{e.class}: " unless e.class == RuntimeError
|
29
|
-
$stderr.puts "#{e.message}"
|
30
|
-
$stderr.puts " Use --trace for backtrace."
|
31
|
-
exit 1
|
32
|
-
end
|
33
|
-
exit 0
|
34
|
-
end
|
35
|
-
|
36
|
-
# Parses the command-line arguments and runs the executable.
|
37
|
-
# This does not handle exceptions or exit the program.
|
38
|
-
#
|
39
|
-
# @see #parse!
|
40
|
-
def parse
|
41
|
-
@opts = OptionParser.new(&method(:set_opts))
|
42
|
-
@opts.parse!(@args)
|
43
|
-
|
44
|
-
process_result
|
45
|
-
|
46
|
-
@options
|
47
|
-
end
|
48
|
-
|
49
|
-
# @return [String] A description of the executable
|
50
|
-
def to_s
|
51
|
-
@opts.to_s
|
52
|
-
end
|
53
|
-
|
54
|
-
protected
|
55
|
-
|
56
|
-
# Finds the line of the source template
|
57
|
-
# on which an exception was raised.
|
58
|
-
#
|
59
|
-
# @param exception [Exception] The exception
|
60
|
-
# @return [String] The line number
|
61
|
-
def get_line(exception)
|
62
|
-
# SyntaxErrors have weird line reporting
|
63
|
-
# when there's trailing whitespace,
|
64
|
-
# which there is for Haml documents.
|
65
|
-
return (exception.message.scan(/:(\d+)/).first || ["??"]).first if exception.is_a?(::SyntaxError)
|
66
|
-
(exception.backtrace[0].scan(/:(\d+)/).first || ["??"]).first
|
67
|
-
end
|
68
|
-
|
69
|
-
# Tells optparse how to parse the arguments
|
70
|
-
# available for all executables.
|
71
|
-
#
|
72
|
-
# This is meant to be overridden by subclasses
|
73
|
-
# so they can add their own options.
|
74
|
-
#
|
75
|
-
# @param opts [OptionParser]
|
76
|
-
def set_opts(opts)
|
77
|
-
opts.on('-s', '--stdin', :NONE, 'Read input from standard input instead of an input file') do
|
78
|
-
@options[:input] = $stdin
|
79
|
-
end
|
80
|
-
|
81
|
-
opts.on('--trace', :NONE, 'Show a full traceback on error') do
|
82
|
-
@options[:trace] = true
|
83
|
-
end
|
84
|
-
|
85
|
-
opts.on('--unix-newlines', 'Use Unix-style newlines in written files.') do
|
86
|
-
# Note that this is the preferred way to check for Windows, since
|
87
|
-
# JRuby and Rubinius also run there.
|
88
|
-
if RbConfig::CONFIG['host_os'] =~ /mswin|windows|mingw/i
|
89
|
-
@options[:unix_newlines] = true
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
opts.on_tail("-?", "-h", "--help", "Show this message") do
|
94
|
-
puts opts
|
95
|
-
exit
|
96
|
-
end
|
97
|
-
|
98
|
-
opts.on_tail("-v", "--version", "Print version") do
|
99
|
-
puts("Haml #{::Haml::VERSION}")
|
100
|
-
exit
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
# Processes the options set by the command-line arguments.
|
105
|
-
# In particular, sets `@options[:input]` and `@options[:output]`
|
106
|
-
# to appropriate IO streams.
|
107
|
-
#
|
108
|
-
# This is meant to be overridden by subclasses
|
109
|
-
# so they can run their respective programs.
|
110
|
-
def process_result
|
111
|
-
input, output = @options[:input], @options[:output]
|
112
|
-
args = @args.dup
|
113
|
-
input ||=
|
114
|
-
begin
|
115
|
-
filename = args.shift
|
116
|
-
@options[:filename] = filename
|
117
|
-
open_file(filename) || $stdin
|
118
|
-
end
|
119
|
-
output ||= open_file(args.shift, 'w') || $stdout
|
120
|
-
|
121
|
-
@options[:input], @options[:output] = input, output
|
122
|
-
end
|
123
|
-
|
124
|
-
COLORS = {red: 31, green: 32, yellow: 33}.freeze
|
125
|
-
|
126
|
-
# Prints a status message about performing the given action,
|
127
|
-
# colored using the given color (via terminal escapes) if possible.
|
128
|
-
#
|
129
|
-
# @param name [#to_s] A short name for the action being performed.
|
130
|
-
# Shouldn't be longer than 11 characters.
|
131
|
-
# @param color [Symbol] The name of the color to use for this action.
|
132
|
-
# Can be `:red`, `:green`, or `:yellow`.
|
133
|
-
def puts_action(name, color, arg)
|
134
|
-
return if @options[:for_engine][:quiet]
|
135
|
-
printf color(color, "%11s %s\n"), name, arg
|
136
|
-
end
|
137
|
-
|
138
|
-
# Same as `Kernel.puts`, but doesn't print anything if the `--quiet` option is set.
|
139
|
-
#
|
140
|
-
# @param args [Array] Passed on to `Kernel.puts`
|
141
|
-
def puts(*args)
|
142
|
-
return if @options[:for_engine][:quiet]
|
143
|
-
Kernel.puts(*args)
|
144
|
-
end
|
145
|
-
|
146
|
-
# Wraps the given string in terminal escapes
|
147
|
-
# causing it to have the given color.
|
148
|
-
# If terminal esapes aren't supported on this platform,
|
149
|
-
# just returns the string instead.
|
150
|
-
#
|
151
|
-
# @param color [Symbol] The name of the color to use.
|
152
|
-
# Can be `:red`, `:green`, or `:yellow`.
|
153
|
-
# @param str [String] The string to wrap in the given color.
|
154
|
-
# @return [String] The wrapped string.
|
155
|
-
def color(color, str)
|
156
|
-
raise "[BUG] Unrecognized color #{color}" unless COLORS[color]
|
157
|
-
|
158
|
-
# Almost any real Unix terminal will support color,
|
159
|
-
# so we just filter for Windows terms (which don't set TERM)
|
160
|
-
# and not-real terminals, which aren't ttys.
|
161
|
-
return str if ENV["TERM"].nil? || ENV["TERM"].empty? || !STDOUT.tty?
|
162
|
-
return "\e[#{COLORS[color]}m#{str}\e[0m"
|
163
|
-
end
|
164
|
-
|
165
|
-
private
|
166
|
-
|
167
|
-
def open_file(filename, flag = 'r')
|
168
|
-
return if filename.nil?
|
169
|
-
flag = 'wb' if @options[:unix_newlines] && flag == 'w'
|
170
|
-
File.open(filename, flag)
|
171
|
-
end
|
172
|
-
|
173
|
-
def handle_load_error(err)
|
174
|
-
dep = err.message[/^no such file to load -- (.*)/, 1]
|
175
|
-
raise err if @options[:trace] || dep.nil? || dep.empty?
|
176
|
-
$stderr.puts <<MESSAGE
|
177
|
-
Required dependency #{dep} not found!
|
178
|
-
Run "gem install #{dep}" to get it.
|
179
|
-
Use --trace for backtrace.
|
180
|
-
MESSAGE
|
181
|
-
exit 1
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
# The `haml` executable.
|
186
|
-
class Haml < Generic
|
187
|
-
# @param args [Array<String>] The command-line arguments
|
188
|
-
def initialize(args)
|
189
|
-
super
|
190
|
-
@options[:for_engine] = {}
|
191
|
-
@options[:requires] = []
|
192
|
-
@options[:load_paths] = []
|
193
|
-
end
|
194
|
-
|
195
|
-
# Tells optparse how to parse the arguments.
|
196
|
-
#
|
197
|
-
# @param opts [OptionParser]
|
198
|
-
def set_opts(opts)
|
199
|
-
super
|
200
|
-
|
201
|
-
opts.banner = <<END
|
202
|
-
Usage: haml [options] [INPUT] [OUTPUT]
|
203
|
-
|
204
|
-
Description:
|
205
|
-
Converts Haml files to HTML.
|
206
|
-
|
207
|
-
Options:
|
208
|
-
END
|
209
|
-
|
210
|
-
opts.on('-c', '--check', "Just check syntax, don't evaluate.") do
|
211
|
-
require 'stringio'
|
212
|
-
@options[:check_syntax] = true
|
213
|
-
@options[:output] = StringIO.new
|
214
|
-
end
|
215
|
-
|
216
|
-
opts.on('-f', '--format NAME',
|
217
|
-
'Output format. Can be html5 (default), xhtml, or html4.') do |name|
|
218
|
-
@options[:for_engine][:format] = name.to_sym
|
219
|
-
end
|
220
|
-
|
221
|
-
opts.on('-e', '--escape-html',
|
222
|
-
'Escape HTML characters (like ampersands and angle brackets) by default.') do
|
223
|
-
@options[:for_engine][:escape_html] = true
|
224
|
-
end
|
225
|
-
|
226
|
-
opts.on('--no-escape-attrs',
|
227
|
-
"Don't escape HTML characters (like ampersands and angle brackets) in attributes.") do
|
228
|
-
@options[:for_engine][:escape_attrs] = false
|
229
|
-
end
|
230
|
-
|
231
|
-
opts.on('-q', '--double-quote-attributes',
|
232
|
-
'Set attribute wrapper to double-quotes (default is single).') do
|
233
|
-
@options[:for_engine][:attr_wrapper] = '"'
|
234
|
-
end
|
235
|
-
|
236
|
-
opts.on('--remove-whitespace',
|
237
|
-
'Remove whitespace surrounding and within tags') do
|
238
|
-
@options[:for_engine][:remove_whitespace] = true
|
239
|
-
end
|
240
|
-
|
241
|
-
opts.on('--cdata',
|
242
|
-
'Always add CDATA sections to javascript and css blocks.') do
|
243
|
-
@options[:for_engine][:cdata] = true
|
244
|
-
end
|
245
|
-
|
246
|
-
opts.on('--autoclose LIST',
|
247
|
-
'Comma separated list of elements to be automatically self-closed.') do |list|
|
248
|
-
@options[:for_engine][:autoclose] = list.split(',')
|
249
|
-
end
|
250
|
-
|
251
|
-
opts.on('--suppress-eval',
|
252
|
-
'Don\'t evaluate Ruby scripts.') do
|
253
|
-
@options[:for_engine][:suppress_eval] = true
|
254
|
-
end
|
255
|
-
|
256
|
-
opts.on('-r', '--require FILE', "Same as 'ruby -r'.") do |file|
|
257
|
-
@options[:requires] << file
|
258
|
-
end
|
259
|
-
|
260
|
-
opts.on('-I', '--load-path PATH', "Same as 'ruby -I'.") do |path|
|
261
|
-
@options[:load_paths] << path
|
262
|
-
end
|
263
|
-
|
264
|
-
opts.on('-E ex[:in]', 'Specify the default external and internal character encodings.') do |encoding|
|
265
|
-
external, internal = encoding.split(':')
|
266
|
-
Encoding.default_external = external if external && !external.empty?
|
267
|
-
Encoding.default_internal = internal if internal && !internal.empty?
|
268
|
-
end
|
269
|
-
|
270
|
-
opts.on('-d', '--debug', "Print out the precompiled Ruby source, and show syntax errors in the Ruby code.") do
|
271
|
-
@options[:debug] = true
|
272
|
-
end
|
273
|
-
|
274
|
-
opts.on('-p', '--parse', "Print out Haml parse tree.") do
|
275
|
-
@options[:parse] = true
|
276
|
-
end
|
277
|
-
|
278
|
-
end
|
279
|
-
|
280
|
-
# Processes the options set by the command-line arguments,
|
281
|
-
# and runs the Haml compiler appropriately.
|
282
|
-
def process_result
|
283
|
-
super
|
284
|
-
@options[:for_engine][:filename] = @options[:filename]
|
285
|
-
input = @options[:input]
|
286
|
-
output = @options[:output]
|
287
|
-
|
288
|
-
template = input.read()
|
289
|
-
input.close() if input.is_a? File
|
290
|
-
|
291
|
-
@options[:load_paths].each {|p| $LOAD_PATH << p}
|
292
|
-
@options[:requires].each {|f| require f}
|
293
|
-
|
294
|
-
begin
|
295
|
-
|
296
|
-
if @options[:parse]
|
297
|
-
parser = ::Haml::Parser.new(::Haml::Options.new(@options))
|
298
|
-
pp parser.call(template)
|
299
|
-
return
|
300
|
-
end
|
301
|
-
|
302
|
-
engine = ::Haml::Engine.new(template, @options[:for_engine])
|
303
|
-
|
304
|
-
if @options[:check_syntax]
|
305
|
-
error = validate_ruby(engine.precompiled)
|
306
|
-
if error
|
307
|
-
puts error.message.split("\n").first
|
308
|
-
exit 1
|
309
|
-
end
|
310
|
-
puts "Syntax OK"
|
311
|
-
return
|
312
|
-
end
|
313
|
-
|
314
|
-
if @options[:debug]
|
315
|
-
puts engine.precompiled
|
316
|
-
error = validate_ruby(engine.precompiled)
|
317
|
-
if error
|
318
|
-
puts '=' * 100
|
319
|
-
puts error.message.split("\n")[0]
|
320
|
-
exit 1
|
321
|
-
end
|
322
|
-
return
|
323
|
-
end
|
324
|
-
|
325
|
-
result = engine.to_html
|
326
|
-
rescue Exception => e
|
327
|
-
raise e if @options[:trace]
|
328
|
-
|
329
|
-
case e
|
330
|
-
when ::Haml::SyntaxError; raise "Syntax error on line #{get_line e}: #{e.message}"
|
331
|
-
when ::Haml::Error; raise "Haml error on line #{get_line e}: #{e.message}"
|
332
|
-
else raise "Exception on line #{get_line e}: #{e.message}"
|
333
|
-
end
|
334
|
-
end
|
335
|
-
|
336
|
-
output.write(result)
|
337
|
-
output.close() if output.is_a? File
|
338
|
-
end
|
339
|
-
|
340
|
-
def validate_ruby(code)
|
341
|
-
eval("BEGIN {return nil}; #{code}", binding, @options[:filename] || "")
|
342
|
-
rescue ::SyntaxError # Not to be confused with Haml::SyntaxError
|
343
|
-
$!
|
344
|
-
end
|
345
|
-
end
|
346
|
-
end
|
347
|
-
end
|
data/lib/haml/generator.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Haml
|
4
|
-
# Ruby code generator, which is a limited version of Temple::Generator.
|
5
|
-
# Limit methods since Haml doesn't need most of them.
|
6
|
-
class Generator
|
7
|
-
include Temple::Mixins::CompiledDispatcher
|
8
|
-
include Temple::Mixins::Options
|
9
|
-
|
10
|
-
define_options freeze_static: RUBY_VERSION >= '2.1'
|
11
|
-
|
12
|
-
def call(exp)
|
13
|
-
compile(exp)
|
14
|
-
end
|
15
|
-
|
16
|
-
def on_multi(*exp)
|
17
|
-
exp.map { |e| compile(e) }.join('; ')
|
18
|
-
end
|
19
|
-
|
20
|
-
def on_static(text)
|
21
|
-
concat(options[:freeze_static] ? "#{Util.inspect_obj(text)}.freeze" : Util.inspect_obj(text))
|
22
|
-
end
|
23
|
-
|
24
|
-
def on_dynamic(code)
|
25
|
-
concat(code)
|
26
|
-
end
|
27
|
-
|
28
|
-
def on_code(exp)
|
29
|
-
exp
|
30
|
-
end
|
31
|
-
|
32
|
-
def on_newline
|
33
|
-
"\n"
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def concat(str)
|
39
|
-
"_hamlout.buffer << (#{str});"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|