faml 0.2.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/.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
|