deadfire 0.3.0 → 0.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 +4 -4
- data/.github/workflows/ci.yml +4 -1
- data/.gitignore +1 -0
- data/Gemfile.lock +96 -4
- data/README.md +6 -31
- data/benchmarks/basic_benchmark.rb +39 -7
- data/changelog.md +25 -0
- data/deadfire.gemspec +6 -1
- data/lib/.keep +0 -0
- data/lib/deadfire/asset_loader.rb +67 -0
- data/lib/deadfire/asset_registry.rb +88 -0
- data/lib/deadfire/ast_printer.rb +6 -1
- data/lib/deadfire/configuration.rb +25 -7
- data/lib/deadfire/css_generator.rb +2 -3
- data/lib/deadfire/error_reporter.rb +8 -2
- data/lib/deadfire/errors.rb +1 -42
- data/lib/deadfire/filename_helper.rb +30 -10
- data/lib/deadfire/front_end/apply_node.rb +1 -2
- data/lib/deadfire/front_end/parser.rb +13 -17
- data/lib/deadfire/front_end/scanner.rb +54 -40
- data/lib/deadfire/front_end/stylesheet_node.rb +1 -1
- data/lib/deadfire/interpreter.rb +6 -14
- data/lib/deadfire/mixin_parser.rb +51 -0
- data/lib/deadfire/parser_engine.rb +11 -1
- data/lib/deadfire/railtie.rb +38 -0
- data/lib/deadfire/spec.rb +28 -27
- data/lib/deadfire/version.rb +1 -1
- data/lib/deadfire.rb +13 -4
- metadata +66 -7
- data/lib/deadfire/css_buffer.rb +0 -37
- data/lib/deadfire/parser.rb +0 -258
@@ -5,18 +5,16 @@ module Deadfire
|
|
5
5
|
class << self
|
6
6
|
def resolve_import_path(line, lineno = 0)
|
7
7
|
path = normalize_path(line)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
potential = potential_path(path)
|
9
|
+
ext = File.extname(path)
|
10
|
+
|
11
|
+
if ext && valid_file?(potential)
|
12
|
+
potential
|
13
|
+
else
|
14
|
+
possible_paths(path)
|
15
15
|
end
|
16
|
-
|
17
|
-
import_path
|
18
16
|
end
|
19
|
-
|
17
|
+
|
20
18
|
def normalize_path(line)
|
21
19
|
path = line.split.last
|
22
20
|
path.gsub!("\"", "")
|
@@ -24,6 +22,28 @@ module Deadfire
|
|
24
22
|
path.gsub!(";", "")
|
25
23
|
path
|
26
24
|
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def valid_file_extension?(ext)
|
29
|
+
Deadfire::PERMISSIBLE_FILE_EXTENSIONS.include?(ext)
|
30
|
+
end
|
31
|
+
|
32
|
+
def valid_file?(path)
|
33
|
+
File.exist?(path)
|
34
|
+
end
|
35
|
+
|
36
|
+
def possible_paths(path)
|
37
|
+
Deadfire::PERMISSIBLE_FILE_EXTENSIONS.each do |ext|
|
38
|
+
option = File.join(Deadfire.configuration.root_path, path + ext)
|
39
|
+
return option if valid_file?(option)
|
40
|
+
end
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def potential_path(path)
|
45
|
+
File.join(Deadfire.configuration.root_path, path)
|
46
|
+
end
|
27
47
|
end
|
28
48
|
end
|
29
49
|
end
|
@@ -1,11 +1,10 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Deadfire
|
4
4
|
class ApplyNode
|
5
5
|
attr_reader :node, :mixin_names
|
6
6
|
|
7
7
|
def initialize(node, mixin_names)
|
8
|
-
# TODO: mixin name can be single or multiple names, separated by a comma
|
9
8
|
@node = node
|
10
9
|
@mixin_names = fetch_mixin_name_from(mixin_names)
|
11
10
|
end
|
@@ -13,19 +13,13 @@ module Deadfire
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def parse
|
16
|
-
# top level it's a list of statements
|
17
|
-
# statements are either rules or at-rules
|
18
|
-
# rules are selectors + declarations
|
19
|
-
# at-rules are at-keyword + block
|
20
|
-
# block is a list of declarations?
|
21
|
-
# declarations are property + value
|
22
16
|
while !is_at_end?
|
23
17
|
if check(:comment)
|
24
18
|
comment = add_comment
|
25
|
-
@stylesheet << comment
|
19
|
+
@stylesheet << comment unless Deadfire.configuration.compressed
|
26
20
|
elsif check(:newline)
|
27
21
|
newline = add_newline
|
28
|
-
@stylesheet << newline
|
22
|
+
@stylesheet << newline unless Deadfire.configuration.compressed
|
29
23
|
elsif matches_at_rule?
|
30
24
|
@stylesheet << at_rule_declaration
|
31
25
|
else
|
@@ -84,10 +78,6 @@ module Deadfire
|
|
84
78
|
check(:at_rule)
|
85
79
|
end
|
86
80
|
|
87
|
-
def matches_nested_rule?
|
88
|
-
match?(:ampersand)
|
89
|
-
end
|
90
|
-
|
91
81
|
def parse_block
|
92
82
|
block = BlockNode.new
|
93
83
|
block << previous
|
@@ -111,7 +101,11 @@ module Deadfire
|
|
111
101
|
def ruleset_declaration
|
112
102
|
values = []
|
113
103
|
while !match?(:left_brace)
|
114
|
-
|
104
|
+
unless match?(:comment)
|
105
|
+
values << advance
|
106
|
+
else
|
107
|
+
values << advance unless Deadfire.configuration.compressed
|
108
|
+
end
|
115
109
|
end
|
116
110
|
|
117
111
|
selector = SelectorNode.new(values[0..-1])
|
@@ -142,14 +136,16 @@ module Deadfire
|
|
142
136
|
|
143
137
|
if previous.type == :semicolon
|
144
138
|
if keyword.lexeme == "@apply"
|
145
|
-
|
139
|
+
ApplyNode.new(keyword, values)
|
146
140
|
else
|
147
141
|
values << previous # add the semicolon to the values
|
148
|
-
|
142
|
+
AtRuleNode.new(keyword, values, nil)
|
149
143
|
end
|
144
|
+
elsif is_at_end?
|
145
|
+
AtRuleNode.new(keyword, values, nil)
|
146
|
+
else
|
147
|
+
AtRuleNode.new(keyword, values[0..-1], parse_block) # remove the left brace, because it's not a value, but part of the block
|
150
148
|
end
|
151
|
-
|
152
|
-
AtRuleNode.new(keyword, values[0..-1], parse_block) # remove the left brace, because it's not a value, but part of the block
|
153
149
|
end
|
154
150
|
end
|
155
151
|
end
|
@@ -75,26 +75,15 @@ module Deadfire
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def add_at_rule(literal = nil)
|
78
|
-
|
79
|
-
|
80
|
-
while Spec::CSS_AT_RULES.none? { |kwrd| kwrd == selector.join + peek } && !at_end?
|
81
|
-
break if peek == NEWLINE
|
82
|
-
selector << advance
|
83
|
-
end
|
84
|
-
|
85
|
-
# final char in at-rule
|
86
|
-
selector << advance
|
87
|
-
|
88
|
-
current_at_rule = selector.join
|
89
|
-
at_rule = Spec::CSS_AT_RULES.find { |kwrd| kwrd == current_at_rule }
|
78
|
+
at_rule = determine_at_rule
|
90
79
|
|
91
80
|
if peek == NEWLINE
|
92
81
|
@line += 1
|
93
82
|
@error_reporter.error(@line, "at-rule cannot be on multiple lines.")
|
94
|
-
add_token(:at_rule,
|
83
|
+
add_token(:at_rule, at_rule)
|
95
84
|
elsif at_rule
|
96
85
|
token = add_token(:at_rule, "at_#{at_rule[1..-1]}")
|
97
|
-
if at_rule ==
|
86
|
+
if at_rule == Spec::IMPORT
|
98
87
|
prescan_import_rule(token.last)
|
99
88
|
else
|
100
89
|
token
|
@@ -172,32 +161,38 @@ module Deadfire
|
|
172
161
|
end
|
173
162
|
|
174
163
|
def add_forward_slash_or_comment
|
175
|
-
|
176
|
-
advance # consume the *
|
177
|
-
while peek != "*" && peek_next != "/" && !at_end?
|
178
|
-
@line += 1 if peek == NEWLINE
|
179
|
-
advance
|
180
|
-
end
|
164
|
+
return add_token(:forward_slash) unless peek == "*"
|
181
165
|
|
182
|
-
|
166
|
+
advance # consume the *
|
167
|
+
while true
|
168
|
+
if at_end?
|
183
169
|
@error_reporter.error(@line, "Unterminated comment on line #{@line}.")
|
184
|
-
|
185
|
-
advance # consume the *
|
186
|
-
advance # consume the /
|
170
|
+
break
|
187
171
|
end
|
188
|
-
|
189
|
-
|
190
|
-
|
172
|
+
|
173
|
+
case peek
|
174
|
+
when NEWLINE
|
175
|
+
@line += 1
|
176
|
+
when "*"
|
177
|
+
if peek_next == "/"
|
178
|
+
advance # consume the *
|
179
|
+
advance # consume the /
|
180
|
+
break
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
advance
|
191
185
|
end
|
186
|
+
add_token(:comment) # Add the comment anyway, but report an error.
|
192
187
|
end
|
193
188
|
|
194
189
|
def add_whitespace_token
|
195
|
-
add_token(:whitespace)
|
190
|
+
add_token(:whitespace) unless Deadfire.configuration.compressed
|
196
191
|
end
|
197
192
|
|
198
193
|
def add_newline_token
|
199
194
|
@line += 1
|
200
|
-
add_token(:newline)
|
195
|
+
add_token(:newline) unless Deadfire.configuration.compressed
|
201
196
|
end
|
202
197
|
|
203
198
|
def current_char_position
|
@@ -229,6 +224,21 @@ module Deadfire
|
|
229
224
|
(char >= "a" && char <= "z") || (char >= "A" && char <= "Z")
|
230
225
|
end
|
231
226
|
|
227
|
+
def determine_at_rule
|
228
|
+
selector = [current_char]
|
229
|
+
|
230
|
+
while Spec::CSS_AT_RULES.none? { |kwrd| kwrd == selector.join + peek } && !at_end?
|
231
|
+
break if peek == NEWLINE
|
232
|
+
selector << advance
|
233
|
+
end
|
234
|
+
|
235
|
+
# final char in at-rule
|
236
|
+
selector << advance
|
237
|
+
|
238
|
+
current_at_rule = selector.join
|
239
|
+
Spec::CSS_AT_RULES.find { |kwrd| kwrd == current_at_rule }
|
240
|
+
end
|
241
|
+
|
232
242
|
def prescan_import_rule(token)
|
233
243
|
# we want to get all the text between the @import and the semicolon
|
234
244
|
# so we can parse the file and add it to the ast
|
@@ -237,29 +247,33 @@ module Deadfire
|
|
237
247
|
while peek != ";" && !at_end?
|
238
248
|
advance
|
239
249
|
end
|
250
|
+
|
251
|
+
add_token(:text)
|
240
252
|
|
241
253
|
if at_end?
|
242
|
-
@error_reporter.error(@line, "
|
254
|
+
@error_reporter.error(@line, "Imports must be terminated correctly with a ';'.")
|
243
255
|
return
|
244
256
|
end
|
245
257
|
|
246
|
-
add_token(:text)
|
247
|
-
advance # remove the semicolon
|
248
|
-
|
249
258
|
text_token = @tokens.last
|
250
259
|
|
251
260
|
text = text_token.lexeme.gsub(/\\|"/, '')
|
252
261
|
file = FilenameHelper.resolve_import_path(text, @line)
|
253
262
|
|
254
|
-
|
255
|
-
|
256
|
-
|
263
|
+
if file
|
264
|
+
# file is ready for scanning
|
265
|
+
content = File.read(file)
|
266
|
+
scanner = Scanner.new(content, @error_reporter)
|
257
267
|
|
258
|
-
|
259
|
-
|
268
|
+
advance # remove the semicolon
|
269
|
+
@tokens.pop # remove the text token
|
270
|
+
@tokens.pop # remove the at_rule token
|
260
271
|
|
261
|
-
|
262
|
-
|
272
|
+
imported_tokens = scanner.tokenize[0..-2]
|
273
|
+
@tokens.concat imported_tokens
|
274
|
+
else
|
275
|
+
@error_reporter.error(@line, "File not found '#{text}'")
|
276
|
+
end
|
263
277
|
end
|
264
278
|
end
|
265
279
|
end
|
data/lib/deadfire/interpreter.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Deadfire
|
4
4
|
class Interpreter # :nodoc:
|
5
|
-
|
6
|
-
self.cached_apply_rules = Hash.new { |h, k| h[k] = nil }
|
7
|
-
|
8
|
-
def initialize(error_reporter)
|
5
|
+
def initialize(error_reporter, asset_loader)
|
9
6
|
@error_reporter = error_reporter
|
7
|
+
@asset_loader = asset_loader
|
10
8
|
end
|
11
9
|
|
12
10
|
def interpret(node)
|
@@ -27,8 +25,8 @@ module Deadfire
|
|
27
25
|
if node.block
|
28
26
|
visit_block_node(node.block, node)
|
29
27
|
|
30
|
-
unless
|
31
|
-
|
28
|
+
unless @asset_loader.cached_css(node.selector.selector)
|
29
|
+
@asset_loader.cache_css(node.selector.selector, node.block) if node.selector.cacheable?
|
32
30
|
end
|
33
31
|
end
|
34
32
|
end
|
@@ -44,10 +42,6 @@ module Deadfire
|
|
44
42
|
end
|
45
43
|
end
|
46
44
|
|
47
|
-
def visit_declaration_node(node)
|
48
|
-
node.accept(self)
|
49
|
-
end
|
50
|
-
|
51
45
|
def visit_comment_node(node)
|
52
46
|
# node.accept(self)
|
53
47
|
end
|
@@ -64,9 +58,7 @@ module Deadfire
|
|
64
58
|
def apply_mixin(mixin, node)
|
65
59
|
updated_declarations = []
|
66
60
|
mixin.mixin_names.each do |mixin_name|
|
67
|
-
if
|
68
|
-
cached_block = Interpreter.cached_apply_rules[mixin_name]
|
69
|
-
|
61
|
+
if cached_block = @asset_loader.cached_css(mixin_name)
|
70
62
|
# NOTE: remove the left and right brace but we probably don't need to do this, how can this be simplified?
|
71
63
|
cached_block.declarations[1...-1].each do |cached_declaration|
|
72
64
|
updated_declarations << cached_declaration
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Deadfire
|
4
|
+
class MixinParser # :nodoc:
|
5
|
+
attr_reader :mixins
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@mixins = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def interpret(node)
|
12
|
+
node.accept(self)
|
13
|
+
end
|
14
|
+
|
15
|
+
def visit_stylesheet_node(node)
|
16
|
+
node.statements.each { |child| child.accept(self) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def visit_at_rule_node(node)
|
20
|
+
if node.block
|
21
|
+
visit_block_node(node.block, node)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def visit_ruleset_node(node)
|
26
|
+
if node.block
|
27
|
+
visit_block_node(node.block, node)
|
28
|
+
|
29
|
+
if node.selector.cacheable?
|
30
|
+
if @mixins.key?(node.selector.selector)
|
31
|
+
Deadfire.config.logger.warn("Mixin '#{node.selector.selector}' will be overrided with a new value.")
|
32
|
+
end
|
33
|
+
|
34
|
+
@mixins[node.selector.selector] = node.block
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def visit_block_node(node, parent)
|
40
|
+
end
|
41
|
+
|
42
|
+
def visit_comment_node(node)
|
43
|
+
end
|
44
|
+
|
45
|
+
def visit_apply_node(node)
|
46
|
+
end
|
47
|
+
|
48
|
+
def visit_newline_node(node)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -7,12 +7,13 @@ module Deadfire
|
|
7
7
|
def initialize(content, options = {})
|
8
8
|
@error_reporter = ErrorReporter.new
|
9
9
|
@options = {}
|
10
|
+
@asset_loader = AssetLoader.new(options[:filename])
|
10
11
|
@scanner = FrontEnd::Scanner.new(content, error_reporter)
|
11
12
|
end
|
12
13
|
|
13
14
|
def parse
|
14
15
|
ast = _parse
|
15
|
-
interpreter = Interpreter.new(error_reporter)
|
16
|
+
interpreter = Interpreter.new(error_reporter, @asset_loader)
|
16
17
|
ast.statements.each do |node|
|
17
18
|
interpreter.interpret(node)
|
18
19
|
end
|
@@ -31,6 +32,15 @@ module Deadfire
|
|
31
32
|
@error_reporter.errors?
|
32
33
|
end
|
33
34
|
|
35
|
+
def load_mixins
|
36
|
+
ast = _parse
|
37
|
+
parser = MixinParser.new
|
38
|
+
ast.statements.each do |node|
|
39
|
+
parser.interpret(node)
|
40
|
+
end
|
41
|
+
parser.mixins
|
42
|
+
end
|
43
|
+
|
34
44
|
private
|
35
45
|
|
36
46
|
def _parse
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "rails"
|
3
|
+
require "propshaft"
|
4
|
+
|
5
|
+
module Deadfire
|
6
|
+
class Railties < ::Rails::Railtie
|
7
|
+
config.deadfire = ActiveSupport::OrderedOptions.new
|
8
|
+
config.deadfire.root_path = nil
|
9
|
+
config.deadfire.excluded_files = []
|
10
|
+
|
11
|
+
initializer :deadfire do |app|
|
12
|
+
Deadfire.configure do |deadfire_config|
|
13
|
+
deadfire_config.root_path = config.deadfire.root_path || app.root.join("app", "assets", "stylesheets")
|
14
|
+
deadfire_config.excluded_files = config.deadfire.excluded_files
|
15
|
+
deadfire_config.compressed = config.assets.compressed
|
16
|
+
deadfire_config.logger = config.assets.logger || Rails.logger
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class DeadfireCompiler < ::Propshaft::Compiler
|
21
|
+
def compile(logical_path, input)
|
22
|
+
path = logical_path.path.to_s
|
23
|
+
|
24
|
+
return input if Deadfire.config.excluded_files.include?(path)
|
25
|
+
|
26
|
+
# by default, all files in the will be preprocessed
|
27
|
+
if Deadfire.config.asset_registry.settings.empty?
|
28
|
+
all_files = Dir.glob("#{Deadfire.config.root_path}/**/*.css")
|
29
|
+
Deadfire.config.preprocess(*all_files)
|
30
|
+
end
|
31
|
+
|
32
|
+
Deadfire.parse(input, filename: logical_path.logical_path.to_s)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
config.assets.compilers << ["text/css", DeadfireCompiler]
|
37
|
+
end
|
38
|
+
end
|
data/lib/deadfire/spec.rb
CHANGED
@@ -17,35 +17,36 @@ module Deadfire
|
|
17
17
|
# value = any-value [ ',' S* any-value ]*;
|
18
18
|
# any-value = IDENT | STRING | NUMBER | PERCENTAGE | DIMENSION | COLOR | URI | FUNCTION any-value* ')' | '(' any-value* ')' | '[' any-value* ']' | '{' any-value* '}' | ';';
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
20
|
+
CHARSET = "@charset"
|
21
|
+
IMPORT = "@import"
|
22
|
+
MEDIA = "@media"
|
23
|
+
PAGE = "@page"
|
24
|
+
FONT_FACE = "@font-face"
|
25
|
+
KEYFRAMES = "@keyframes"
|
26
|
+
WEBKIT_KEYFRAMES = "@-webkit-keyframes"
|
27
|
+
SUPPORTS = "@supports"
|
28
|
+
NAMESPACE = "@namespace"
|
29
|
+
COUNTER_STYLE = "@counter-style"
|
30
|
+
VIEWPORT = "@viewport"
|
31
|
+
DOCUMENT = "@document"
|
32
|
+
APPLY = "@apply"
|
33
|
+
LAYER = "@layer"
|
34
34
|
|
35
35
|
CSS_AT_RULES = [
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
36
|
+
CHARSET,
|
37
|
+
IMPORT,
|
38
|
+
MEDIA,
|
39
|
+
PAGE,
|
40
|
+
FONT_FACE,
|
41
|
+
KEYFRAMES,
|
42
|
+
WEBKIT_KEYFRAMES,
|
43
|
+
SUPPORTS,
|
44
|
+
NAMESPACE,
|
45
|
+
COUNTER_STYLE,
|
46
|
+
VIEWPORT,
|
47
|
+
DOCUMENT,
|
48
|
+
APPLY,
|
49
|
+
LAYER
|
49
50
|
]
|
50
51
|
|
51
52
|
CSS_SELECTORS = [
|
data/lib/deadfire/version.rb
CHANGED
data/lib/deadfire.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "deadfire/ast_printer"
|
4
|
-
require_relative "deadfire/
|
4
|
+
require_relative "deadfire/asset_loader"
|
5
|
+
require_relative "deadfire/asset_registry"
|
5
6
|
require_relative "deadfire/css_generator"
|
6
7
|
require_relative "deadfire/configuration"
|
7
8
|
require_relative "deadfire/errors"
|
8
9
|
require_relative "deadfire/error_reporter"
|
9
10
|
require_relative "deadfire/interpreter"
|
10
|
-
require_relative "deadfire/
|
11
|
+
require_relative "deadfire/mixin_parser"
|
11
12
|
require_relative "deadfire/parser_engine"
|
12
13
|
require_relative "deadfire/spec"
|
13
14
|
require_relative "deadfire/filename_helper"
|
@@ -26,6 +27,8 @@ require_relative "deadfire/front_end/selector_node"
|
|
26
27
|
require_relative "deadfire/front_end/stylesheet_node"
|
27
28
|
|
28
29
|
module Deadfire
|
30
|
+
PERMISSIBLE_FILE_EXTENSIONS = [".css", ".scss"].freeze
|
31
|
+
|
29
32
|
class << self
|
30
33
|
attr_reader :config
|
31
34
|
|
@@ -42,9 +45,15 @@ module Deadfire
|
|
42
45
|
end
|
43
46
|
|
44
47
|
def parse(content, options = {})
|
45
|
-
|
46
|
-
|
48
|
+
configure do |config|
|
49
|
+
config.root_path = options[:root_path]
|
50
|
+
config.compressed = options[:compressed]
|
51
|
+
end
|
52
|
+
|
53
|
+
parser = ParserEngine.new(content, filename: options[:filename])
|
47
54
|
parser.parse
|
48
55
|
end
|
49
56
|
end
|
50
57
|
end
|
58
|
+
|
59
|
+
require_relative "deadfire/railtie"
|