faml 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.gitmodules +3 -0
- data/.rspec +2 -0
- data/.travis.yml +27 -0
- data/Appraisals +26 -0
- data/CHANGELOG.md +47 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +115 -0
- data/Rakefile +28 -0
- data/benchmark/attribute_builder.haml +5 -0
- data/benchmark/rendering.rb +35 -0
- data/bin/faml +4 -0
- data/ext/attribute_builder/attribute_builder.c +261 -0
- data/ext/attribute_builder/extconf.rb +3 -0
- data/faml.gemspec +38 -0
- data/gemfiles/rails_4.0.gemfile +9 -0
- data/gemfiles/rails_4.1.gemfile +9 -0
- data/gemfiles/rails_4.2.gemfile +9 -0
- data/gemfiles/rails_edge.gemfile +10 -0
- data/haml_spec_test.rb +22 -0
- data/lib/faml.rb +10 -0
- data/lib/faml/ast.rb +112 -0
- data/lib/faml/cli.rb +38 -0
- data/lib/faml/compiler.rb +374 -0
- data/lib/faml/element_parser.rb +235 -0
- data/lib/faml/engine.rb +34 -0
- data/lib/faml/filter_compilers.rb +41 -0
- data/lib/faml/filter_compilers/base.rb +43 -0
- data/lib/faml/filter_compilers/cdata.rb +15 -0
- data/lib/faml/filter_compilers/coffee.rb +16 -0
- data/lib/faml/filter_compilers/css.rb +16 -0
- data/lib/faml/filter_compilers/escaped.rb +23 -0
- data/lib/faml/filter_compilers/javascript.rb +16 -0
- data/lib/faml/filter_compilers/markdown.rb +18 -0
- data/lib/faml/filter_compilers/plain.rb +15 -0
- data/lib/faml/filter_compilers/preserve.rb +26 -0
- data/lib/faml/filter_compilers/ruby.rb +17 -0
- data/lib/faml/filter_compilers/sass.rb +15 -0
- data/lib/faml/filter_compilers/scss.rb +16 -0
- data/lib/faml/filter_compilers/tilt_base.rb +34 -0
- data/lib/faml/filter_parser.rb +54 -0
- data/lib/faml/html.rb +58 -0
- data/lib/faml/indent_tracker.rb +84 -0
- data/lib/faml/line_parser.rb +66 -0
- data/lib/faml/newline.rb +30 -0
- data/lib/faml/parser.rb +211 -0
- data/lib/faml/parser_utils.rb +17 -0
- data/lib/faml/rails_handler.rb +10 -0
- data/lib/faml/railtie.rb +9 -0
- data/lib/faml/ruby_multiline.rb +23 -0
- data/lib/faml/script_parser.rb +84 -0
- data/lib/faml/static_hash_parser.rb +113 -0
- data/lib/faml/syntax_error.rb +10 -0
- data/lib/faml/text_compiler.rb +69 -0
- data/lib/faml/tilt.rb +17 -0
- data/lib/faml/version.rb +3 -0
- data/spec/compiler_newline_spec.rb +162 -0
- data/spec/rails/Rakefile +6 -0
- data/spec/rails/app/assets/images/.keep +0 -0
- data/spec/rails/app/assets/javascripts/application.js +13 -0
- data/spec/rails/app/assets/stylesheets/application.css +15 -0
- data/spec/rails/app/controllers/application_controller.rb +5 -0
- data/spec/rails/app/controllers/books_controller.rb +8 -0
- data/spec/rails/app/controllers/concerns/.keep +0 -0
- data/spec/rails/app/helpers/application_helper.rb +2 -0
- data/spec/rails/app/mailers/.keep +0 -0
- data/spec/rails/app/models/.keep +0 -0
- data/spec/rails/app/models/book.rb +9 -0
- data/spec/rails/app/models/concerns/.keep +0 -0
- data/spec/rails/app/views/books/hello.html.haml +2 -0
- data/spec/rails/app/views/books/with_capture.html.haml +4 -0
- data/spec/rails/app/views/books/with_variables.html.haml +4 -0
- data/spec/rails/app/views/layouts/application.html.haml +9 -0
- data/spec/rails/bin/bundle +3 -0
- data/spec/rails/bin/rails +4 -0
- data/spec/rails/bin/rake +4 -0
- data/spec/rails/bin/setup +29 -0
- data/spec/rails/config.ru +4 -0
- data/spec/rails/config/application.rb +12 -0
- data/spec/rails/config/boot.rb +3 -0
- data/spec/rails/config/database.yml +25 -0
- data/spec/rails/config/environment.rb +5 -0
- data/spec/rails/config/environments/development.rb +41 -0
- data/spec/rails/config/environments/production.rb +79 -0
- data/spec/rails/config/environments/test.rb +42 -0
- data/spec/rails/config/initializers/assets.rb +11 -0
- data/spec/rails/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails/config/initializers/cookies_serializer.rb +3 -0
- data/spec/rails/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/rails/config/initializers/inflections.rb +16 -0
- data/spec/rails/config/initializers/mime_types.rb +4 -0
- data/spec/rails/config/initializers/secret_key_base.rb +6 -0
- data/spec/rails/config/initializers/session_store.rb +3 -0
- data/spec/rails/config/initializers/wrap_parameters.rb +14 -0
- data/spec/rails/config/locales/en.yml +23 -0
- data/spec/rails/config/routes.rb +7 -0
- data/spec/rails/config/secrets.yml +22 -0
- data/spec/rails/db/seeds.rb +7 -0
- data/spec/rails/lib/assets/.keep +0 -0
- data/spec/rails/lib/tasks/.keep +0 -0
- data/spec/rails/log/.keep +0 -0
- data/spec/rails/public/404.html +67 -0
- data/spec/rails/public/422.html +67 -0
- data/spec/rails/public/500.html +66 -0
- data/spec/rails/public/favicon.ico +0 -0
- data/spec/rails/public/robots.txt +5 -0
- data/spec/rails/spec/requests/faml_spec.rb +41 -0
- data/spec/rails/vendor/assets/javascripts/.keep +0 -0
- data/spec/rails/vendor/assets/stylesheets/.keep +0 -0
- data/spec/rails_helper.rb +4 -0
- data/spec/render/attribute_spec.rb +241 -0
- data/spec/render/comment_spec.rb +61 -0
- data/spec/render/doctype_spec.rb +57 -0
- data/spec/render/element_spec.rb +136 -0
- data/spec/render/filters/cdata_spec.rb +12 -0
- data/spec/render/filters/coffee_spec.rb +25 -0
- data/spec/render/filters/css_spec.rb +45 -0
- data/spec/render/filters/escaped_spec.rb +14 -0
- data/spec/render/filters/javascript_spec.rb +44 -0
- data/spec/render/filters/markdown_spec.rb +19 -0
- data/spec/render/filters/plain_spec.rb +24 -0
- data/spec/render/filters/preserve_spec.rb +24 -0
- data/spec/render/filters/ruby_spec.rb +13 -0
- data/spec/render/filters/sass_spec.rb +28 -0
- data/spec/render/filters/scss_spec.rb +32 -0
- data/spec/render/filters_spec.rb +11 -0
- data/spec/render/haml_comment_spec.rb +24 -0
- data/spec/render/multiline_spec.rb +39 -0
- data/spec/render/newline_spec.rb +83 -0
- data/spec/render/plain_spec.rb +20 -0
- data/spec/render/preserve_spec.rb +8 -0
- data/spec/render/sanitize_spec.rb +36 -0
- data/spec/render/script_spec.rb +81 -0
- data/spec/render/silent_script_spec.rb +97 -0
- data/spec/render/unescape_spec.rb +45 -0
- data/spec/spec_helper.rb +47 -0
- data/spec/tilt_spec.rb +33 -0
- metadata +489 -0
@@ -0,0 +1,235 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
require 'faml/ast'
|
3
|
+
require 'faml/parser_utils'
|
4
|
+
require 'faml/ruby_multiline'
|
5
|
+
require 'faml/script_parser'
|
6
|
+
require 'faml/syntax_error'
|
7
|
+
|
8
|
+
module Faml
|
9
|
+
class ElementParser
|
10
|
+
def initialize(line_parser)
|
11
|
+
@line_parser = line_parser
|
12
|
+
end
|
13
|
+
|
14
|
+
ELEMENT_REGEXP = /\A%([-:\w]+)([-:\w.#]*)(.+)?\z/o
|
15
|
+
|
16
|
+
def parse(text)
|
17
|
+
m = text.match(ELEMENT_REGEXP)
|
18
|
+
unless m
|
19
|
+
syntax_error!('Invalid element declaration')
|
20
|
+
end
|
21
|
+
|
22
|
+
element = Ast::Element.new
|
23
|
+
element.tag_name = m[1]
|
24
|
+
element.static_class, element.static_id = parse_class_and_id(m[2])
|
25
|
+
rest = m[3] || ''
|
26
|
+
|
27
|
+
element.attributes, rest = parse_attributes(rest)
|
28
|
+
element.nuke_inner_whitespace, element.nuke_outer_whitespace, rest = parse_nuke_whitespace(rest)
|
29
|
+
element.self_closing, rest = parse_self_closing(rest)
|
30
|
+
element.oneline_child = ScriptParser.new(@line_parser).parse(rest)
|
31
|
+
|
32
|
+
element
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def parse_class_and_id(class_and_id)
|
38
|
+
classes = []
|
39
|
+
id = ''
|
40
|
+
class_and_id.scan(/([#.])([-:_a-zA-Z0-9]+)/) do |type, prop|
|
41
|
+
case type
|
42
|
+
when '.'
|
43
|
+
classes << prop
|
44
|
+
when '#'
|
45
|
+
id = prop
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
[classes.join(' '), id]
|
50
|
+
end
|
51
|
+
|
52
|
+
OLD_ATTRIBUTE_BEGIN = '{'
|
53
|
+
NEW_ATTRIBUTE_BEGIN = '('
|
54
|
+
|
55
|
+
def parse_attributes(rest)
|
56
|
+
old_attributes = ''
|
57
|
+
new_attributes = ''
|
58
|
+
|
59
|
+
loop do
|
60
|
+
case rest[0]
|
61
|
+
when OLD_ATTRIBUTE_BEGIN
|
62
|
+
unless old_attributes.empty?
|
63
|
+
break
|
64
|
+
end
|
65
|
+
old_attributes, rest = parse_old_attributes(rest)
|
66
|
+
when NEW_ATTRIBUTE_BEGIN
|
67
|
+
unless new_attributes.empty?
|
68
|
+
break
|
69
|
+
end
|
70
|
+
new_attributes, rest = parse_new_attributes(rest)
|
71
|
+
else
|
72
|
+
break
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
attributes = old_attributes
|
77
|
+
unless new_attributes.empty?
|
78
|
+
t = to_old_syntax(new_attributes)
|
79
|
+
if attributes.empty?
|
80
|
+
attributes = t
|
81
|
+
else
|
82
|
+
attributes << ", " << t
|
83
|
+
end
|
84
|
+
end
|
85
|
+
[attributes, rest]
|
86
|
+
end
|
87
|
+
|
88
|
+
def parse_old_attributes(text)
|
89
|
+
text = text.dup
|
90
|
+
s = StringScanner.new(text)
|
91
|
+
s.pos = 1
|
92
|
+
depth = 1
|
93
|
+
loop do
|
94
|
+
depth = ParserUtils.balance(s, '{', '}', depth)
|
95
|
+
if depth == 0
|
96
|
+
attr = s.pre_match + s.matched
|
97
|
+
return [attr[1, attr.size-2], s.rest.lstrip]
|
98
|
+
else
|
99
|
+
if text[-1] == ',' && @line_parser.has_next?
|
100
|
+
text << @line_parser.next_line
|
101
|
+
else
|
102
|
+
syntax_error!('Unmatched brace')
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def parse_new_attributes(text)
|
109
|
+
text = text.dup
|
110
|
+
s = StringScanner.new(text)
|
111
|
+
s.pos = 1
|
112
|
+
depth = 1
|
113
|
+
new_attributes = []
|
114
|
+
loop do
|
115
|
+
pre_pos = s.pos
|
116
|
+
depth = ParserUtils.balance(s, '(', ')', depth)
|
117
|
+
if depth == 0
|
118
|
+
t = s.string.byteslice(pre_pos ... s.pos-1)
|
119
|
+
new_attributes.concat(parse_new_attribute_list(t))
|
120
|
+
return [new_attributes, s.rest.lstrip]
|
121
|
+
else
|
122
|
+
if @line_parser.has_next?
|
123
|
+
text << ' ' << @line_parser.next_line
|
124
|
+
else
|
125
|
+
syntax_error!('Unmatched paren')
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def parse_new_attribute_list(text)
|
132
|
+
s = StringScanner.new(text)
|
133
|
+
list = []
|
134
|
+
until s.eos?
|
135
|
+
name = scan_key(s)
|
136
|
+
s.skip(/\s*/)
|
137
|
+
|
138
|
+
if scan_operator(s)
|
139
|
+
s.skip(/\s*/)
|
140
|
+
value = scan_value(s)
|
141
|
+
else
|
142
|
+
value = 'true'
|
143
|
+
end
|
144
|
+
s.skip(/\s*/)
|
145
|
+
|
146
|
+
list << [name, value]
|
147
|
+
end
|
148
|
+
list
|
149
|
+
end
|
150
|
+
|
151
|
+
def scan_key(scanner)
|
152
|
+
scanner.scan(/[-:\w]+/).tap do |name|
|
153
|
+
unless name
|
154
|
+
syntax_error!('Invalid attribute list (missing attributename)')
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def scan_operator(scanner)
|
160
|
+
scanner.skip(/=/)
|
161
|
+
end
|
162
|
+
|
163
|
+
def scan_value(scanner)
|
164
|
+
if quote = scanner.scan(/["']/)
|
165
|
+
scan_quoted_value(scanner, quote)
|
166
|
+
else
|
167
|
+
scan_variable_value(scanner)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def scan_quoted_value(scanner, quote)
|
172
|
+
re = /((?:\\.|\#(?!\{)|[^#{quote}\\#])*)(#{quote}|#\{)/
|
173
|
+
pos = scanner.pos
|
174
|
+
loop do
|
175
|
+
unless scanner.scan(re)
|
176
|
+
syntax_error!('Invalid attribute list (mismatched quotation)')
|
177
|
+
end
|
178
|
+
if scanner[2] == quote
|
179
|
+
break
|
180
|
+
end
|
181
|
+
depth = ParserUtils.balance(scanner, '{', '}')
|
182
|
+
if depth != 0
|
183
|
+
syntax_error!('Invalid attribute list (mismatched interpolation)')
|
184
|
+
end
|
185
|
+
end
|
186
|
+
str = scanner.string.byteslice(pos-1 .. scanner.pos-1)
|
187
|
+
|
188
|
+
# Even if the quote is single, string interpolation is performed in Haml.
|
189
|
+
str[0] = '"'
|
190
|
+
str[-1] = '"'
|
191
|
+
str
|
192
|
+
end
|
193
|
+
|
194
|
+
def scan_variable_value(scanner)
|
195
|
+
scanner.scan(/(@@?|\$)?\w+/).tap do |var|
|
196
|
+
unless var
|
197
|
+
syntax_error!('Invalid attribute list (invalid variable name)')
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def to_old_syntax(new_attributes)
|
203
|
+
new_attributes.map { |k, v| "#{k.inspect} => #{v}" }.join(', ')
|
204
|
+
end
|
205
|
+
|
206
|
+
def parse_nuke_whitespace(rest)
|
207
|
+
m = rest.match(/\A(><|<>|[><])(.*)\z/)
|
208
|
+
if m
|
209
|
+
nuke_whitespace = m[1]
|
210
|
+
[
|
211
|
+
nuke_whitespace.include?('<'),
|
212
|
+
nuke_whitespace.include?('>'),
|
213
|
+
m[2],
|
214
|
+
]
|
215
|
+
else
|
216
|
+
[false, false, rest]
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def parse_self_closing(rest)
|
221
|
+
if rest[0] == '/'
|
222
|
+
if rest.size > 1
|
223
|
+
syntax_error!("Self-closing tags can't have content")
|
224
|
+
end
|
225
|
+
[true, '']
|
226
|
+
else
|
227
|
+
[false, rest]
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def syntax_error!(message)
|
232
|
+
raise SyntaxError.new(message, @line_parser.lineno)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
data/lib/faml/engine.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'temple'
|
2
|
+
require 'faml/compiler'
|
3
|
+
require 'faml/html'
|
4
|
+
require 'faml/newline'
|
5
|
+
require 'faml/parser'
|
6
|
+
|
7
|
+
module Faml
|
8
|
+
class Engine < Temple::Engine
|
9
|
+
define_options(
|
10
|
+
generator: Temple::Generators::ArrayBuffer,
|
11
|
+
)
|
12
|
+
|
13
|
+
DEFAULT_OPTIONS = {
|
14
|
+
format: :html,
|
15
|
+
attr_quote: "'",
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
def initialize(opts = {})
|
19
|
+
super(DEFAULT_OPTIONS.merge(opts))
|
20
|
+
end
|
21
|
+
|
22
|
+
use Parser
|
23
|
+
use Compiler
|
24
|
+
use Html
|
25
|
+
filter :Escapable
|
26
|
+
filter :ControlFlow
|
27
|
+
filter :MultiFlattener
|
28
|
+
use Newline
|
29
|
+
filter :StaticMerger
|
30
|
+
use :Generator do
|
31
|
+
options[:generator].new(options.to_hash.reject {|k,v| !options[:generator].options.valid_key?(k) })
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Faml
|
2
|
+
module FilterCompilers
|
3
|
+
class NotFound < StandardError
|
4
|
+
attr_reader
|
5
|
+
|
6
|
+
def initialize(name)
|
7
|
+
super("Unable to find compiler for #{name}")
|
8
|
+
@name = name
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.compilers
|
13
|
+
@compilers ||= {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.register(name, compiler)
|
17
|
+
compilers[name.to_s] = compiler
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.find(name)
|
21
|
+
name = name.to_s
|
22
|
+
if compilers.has_key?(name.to_s)
|
23
|
+
compilers[name].new
|
24
|
+
else
|
25
|
+
raise NotFound.new(name)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
require 'faml/filter_compilers/cdata'
|
32
|
+
require 'faml/filter_compilers/coffee'
|
33
|
+
require 'faml/filter_compilers/css'
|
34
|
+
require 'faml/filter_compilers/escaped'
|
35
|
+
require 'faml/filter_compilers/javascript'
|
36
|
+
require 'faml/filter_compilers/markdown'
|
37
|
+
require 'faml/filter_compilers/plain'
|
38
|
+
require 'faml/filter_compilers/preserve'
|
39
|
+
require 'faml/filter_compilers/ruby'
|
40
|
+
require 'faml/filter_compilers/sass'
|
41
|
+
require 'faml/filter_compilers/scss'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'faml/text_compiler'
|
2
|
+
|
3
|
+
module Faml
|
4
|
+
module FilterCompilers
|
5
|
+
class Base
|
6
|
+
def need_newline?
|
7
|
+
true
|
8
|
+
end
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
def compile_texts(temple, texts, tab_width: 0, keep_last_empty_lines: false)
|
13
|
+
tabs = ' ' * tab_width
|
14
|
+
n = 0
|
15
|
+
unless keep_last_empty_lines
|
16
|
+
texts, n = strip_last_empty_lines(texts)
|
17
|
+
end
|
18
|
+
texts.each do |text|
|
19
|
+
temple << [:static, tabs] << text_compiler.compile(text)
|
20
|
+
unless texts.last.equal?(text)
|
21
|
+
temple << [:static, "\n"] << [:newline]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
temple.concat([[:newline]] * n)
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def text_compiler
|
29
|
+
@text_compiler ||= TextCompiler.new(escape_html: false)
|
30
|
+
end
|
31
|
+
|
32
|
+
def strip_last_empty_lines(texts)
|
33
|
+
n = 0
|
34
|
+
texts = texts.dup
|
35
|
+
while texts.last && texts.last.empty?
|
36
|
+
n += 1
|
37
|
+
texts.pop
|
38
|
+
end
|
39
|
+
[texts, n]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'faml/filter_compilers/base'
|
2
|
+
|
3
|
+
module Faml
|
4
|
+
module FilterCompilers
|
5
|
+
class Cdata < Base
|
6
|
+
def compile(texts)
|
7
|
+
temple = [:multi, [:static, "<![CDATA[\n"], [:newline]]
|
8
|
+
compile_texts(temple, texts, tab_width: 4)
|
9
|
+
temple << [:static, "\n]]>"]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
register(:cdata, Cdata)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'faml/filter_compilers/tilt_base'
|
2
|
+
|
3
|
+
module Faml
|
4
|
+
module FilterCompilers
|
5
|
+
class Coffee < TiltBase
|
6
|
+
def compile(texts)
|
7
|
+
temple = [:multi, [:static, "\n"], [:newline]]
|
8
|
+
compile_with_tilt(temple, 'coffee', texts)
|
9
|
+
temple << [:static, "\n"]
|
10
|
+
[:haml, :tag, 'script', false, [:html, :attrs], [:html, :js, temple]]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
register(:coffee, Coffee)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'faml/filter_compilers/base'
|
2
|
+
|
3
|
+
module Faml
|
4
|
+
module FilterCompilers
|
5
|
+
class Css < Base
|
6
|
+
def compile(texts)
|
7
|
+
temple = [:multi, [:static, "\n"], [:newline]]
|
8
|
+
compile_texts(temple, texts, tab_width: 2)
|
9
|
+
temple << [:static, "\n"]
|
10
|
+
[:haml, :tag, 'style', false, [:html, :attrs], temple]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
register(:css, Css)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'faml/filter_compilers/base'
|
2
|
+
|
3
|
+
module Faml
|
4
|
+
module FilterCompilers
|
5
|
+
class Escaped < Base
|
6
|
+
include Temple::Utils
|
7
|
+
|
8
|
+
def compile(texts)
|
9
|
+
temple = [:multi, [:newline]]
|
10
|
+
compile_texts(temple, texts)
|
11
|
+
temple << [:static, "\n"]
|
12
|
+
escape_code = Temple::Filters::Escapable.new.instance_variable_get(:@escape_code)
|
13
|
+
sym = unique_name
|
14
|
+
[:multi,
|
15
|
+
[:capture, sym, temple],
|
16
|
+
[:dynamic, escape_code % sym],
|
17
|
+
]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
register(:escaped, Escaped)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'faml/filter_compilers/base'
|
2
|
+
|
3
|
+
module Faml
|
4
|
+
module FilterCompilers
|
5
|
+
class Javascript < Base
|
6
|
+
def compile(texts)
|
7
|
+
temple = [:multi, [:static, "\n"], [:newline]]
|
8
|
+
compile_texts(temple, texts, tab_width: 2)
|
9
|
+
temple << [:static, "\n"]
|
10
|
+
[:haml, :tag, 'script', false, [:html, :attrs], [:html, :js, temple]]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
register(:javascript, Javascript)
|
15
|
+
end
|
16
|
+
end
|