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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b92ff55d4eb765b9042dad38b321944bacf5334db4d2cfe17aabc8fa6c6fcbf3
|
4
|
+
data.tar.gz: 956b776ba58413cc70e70fe8b98a8392ea7091994127070852323c84ca7b2dcf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6172c9434d1aeaafe2ff0a45e257ddc022214f5f81895cf3d763327d26e087e5ce50cd0b585a1a3c47cb193f8048c4a14c59ef4d4ca508988a62b6e229ba7409
|
7
|
+
data.tar.gz: eb267997efa8f7a953d9bb7fc385147aefff84684db57f7caa45c21f34cf89776af42c0ba9694e6887b30f894dc50bdb75ab8c98a61ff4343c772f170cfb995c
|
data/.github/workflows/ci.yml
CHANGED
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,14 +1,61 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
deadfire (0.
|
4
|
+
deadfire (0.5.0)
|
5
|
+
actionpack (>= 7.0.0)
|
6
|
+
activesupport (>= 7.0.0)
|
7
|
+
propshaft (>= 0.9.0)
|
8
|
+
railties (>= 7.0.0)
|
5
9
|
|
6
10
|
GEM
|
7
11
|
remote: https://rubygems.org/
|
8
12
|
specs:
|
13
|
+
actionpack (7.1.3.4)
|
14
|
+
actionview (= 7.1.3.4)
|
15
|
+
activesupport (= 7.1.3.4)
|
16
|
+
nokogiri (>= 1.8.5)
|
17
|
+
racc
|
18
|
+
rack (>= 2.2.4)
|
19
|
+
rack-session (>= 1.0.1)
|
20
|
+
rack-test (>= 0.6.3)
|
21
|
+
rails-dom-testing (~> 2.2)
|
22
|
+
rails-html-sanitizer (~> 1.6)
|
23
|
+
actionview (7.1.3.4)
|
24
|
+
activesupport (= 7.1.3.4)
|
25
|
+
builder (~> 3.1)
|
26
|
+
erubi (~> 1.11)
|
27
|
+
rails-dom-testing (~> 2.2)
|
28
|
+
rails-html-sanitizer (~> 1.6)
|
29
|
+
activesupport (7.1.3.4)
|
30
|
+
base64
|
31
|
+
bigdecimal
|
32
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
33
|
+
connection_pool (>= 2.2.5)
|
34
|
+
drb
|
35
|
+
i18n (>= 1.6, < 2)
|
36
|
+
minitest (>= 5.1)
|
37
|
+
mutex_m
|
38
|
+
tzinfo (~> 2.0)
|
9
39
|
ansi (1.5.0)
|
10
|
-
|
11
|
-
|
40
|
+
base64 (0.2.0)
|
41
|
+
bigdecimal (3.1.8)
|
42
|
+
builder (3.3.0)
|
43
|
+
concurrent-ruby (1.3.4)
|
44
|
+
connection_pool (2.4.1)
|
45
|
+
crass (1.0.6)
|
46
|
+
drb (2.2.1)
|
47
|
+
erubi (1.13.0)
|
48
|
+
i18n (1.14.6)
|
49
|
+
concurrent-ruby (~> 1.0)
|
50
|
+
io-console (0.7.2)
|
51
|
+
irb (1.14.0)
|
52
|
+
rdoc (>= 4.0.0)
|
53
|
+
reline (>= 0.4.2)
|
54
|
+
loofah (2.23.1)
|
55
|
+
crass (~> 1.0.2)
|
56
|
+
nokogiri (>= 1.12.0)
|
57
|
+
mini_portile2 (2.8.7)
|
58
|
+
minitest (5.25.1)
|
12
59
|
minitest-focus (1.3.1)
|
13
60
|
minitest (>= 4, < 6)
|
14
61
|
minitest-reporters (1.5.0)
|
@@ -16,8 +63,53 @@ GEM
|
|
16
63
|
builder
|
17
64
|
minitest (>= 5.0)
|
18
65
|
ruby-progressbar
|
66
|
+
mutex_m (0.2.0)
|
67
|
+
nokogiri (1.16.7)
|
68
|
+
mini_portile2 (~> 2.8.2)
|
69
|
+
racc (~> 1.4)
|
70
|
+
propshaft (0.9.0)
|
71
|
+
actionpack (>= 7.0.0)
|
72
|
+
activesupport (>= 7.0.0)
|
73
|
+
rack
|
74
|
+
railties (>= 7.0.0)
|
75
|
+
psych (5.1.2)
|
76
|
+
stringio
|
77
|
+
racc (1.8.1)
|
78
|
+
rack (3.1.8)
|
79
|
+
rack-session (2.0.0)
|
80
|
+
rack (>= 3.0.0)
|
81
|
+
rack-test (2.1.0)
|
82
|
+
rack (>= 1.3)
|
83
|
+
rackup (2.1.0)
|
84
|
+
rack (>= 3)
|
85
|
+
webrick (~> 1.8)
|
86
|
+
rails-dom-testing (2.2.0)
|
87
|
+
activesupport (>= 5.0.0)
|
88
|
+
minitest
|
89
|
+
nokogiri (>= 1.6)
|
90
|
+
rails-html-sanitizer (1.6.0)
|
91
|
+
loofah (~> 2.21)
|
92
|
+
nokogiri (~> 1.14)
|
93
|
+
railties (7.1.3.4)
|
94
|
+
actionpack (= 7.1.3.4)
|
95
|
+
activesupport (= 7.1.3.4)
|
96
|
+
irb
|
97
|
+
rackup (>= 1.0.0)
|
98
|
+
rake (>= 12.2)
|
99
|
+
thor (~> 1.0, >= 1.2.2)
|
100
|
+
zeitwerk (~> 2.6)
|
19
101
|
rake (12.3.3)
|
102
|
+
rdoc (6.7.0)
|
103
|
+
psych (>= 4.0.0)
|
104
|
+
reline (0.5.9)
|
105
|
+
io-console (~> 0.5)
|
20
106
|
ruby-progressbar (1.11.0)
|
107
|
+
stringio (3.1.1)
|
108
|
+
thor (1.3.1)
|
109
|
+
tzinfo (2.0.6)
|
110
|
+
concurrent-ruby (~> 1.0)
|
111
|
+
webrick (1.9.0)
|
112
|
+
zeitwerk (2.6.16)
|
21
113
|
|
22
114
|
PLATFORMS
|
23
115
|
ruby
|
@@ -30,4 +122,4 @@ DEPENDENCIES
|
|
30
122
|
rake
|
31
123
|
|
32
124
|
BUNDLED WITH
|
33
|
-
2.
|
125
|
+
2.6.1
|
data/README.md
CHANGED
@@ -50,11 +50,11 @@ Output;
|
|
50
50
|
|
51
51
|
### @apply
|
52
52
|
|
53
|
-
|
53
|
+
The `@apply` directive inlines your classes into your custom CSS, simplifying the process of applying existing styles to a new class.
|
54
54
|
|
55
55
|
The CSS apply rule was [proposed to be included into CSS](https://tabatkins.github.io/specs/css-apply-rule/) however it was abandoned. Mixins simplify applying existing css to a new class.
|
56
56
|
|
57
|
-
Let's
|
57
|
+
Let's take a look at an example of how to use the @apply directive. Note that all utility classes are automatically cached.
|
58
58
|
|
59
59
|
```CSS
|
60
60
|
.font-bold: {
|
@@ -67,7 +67,7 @@ Let's see an example of how to declare mixins and use the @apply directive.
|
|
67
67
|
}
|
68
68
|
```
|
69
69
|
|
70
|
-
|
70
|
+
Re-use the styles using @apply:
|
71
71
|
|
72
72
|
```CSS
|
73
73
|
.btn-blue {
|
@@ -103,39 +103,14 @@ Or install it yourself as:
|
|
103
103
|
|
104
104
|
## Deadfire + Ruby on Rails
|
105
105
|
|
106
|
-
|
107
|
-
|
108
|
-
### Propshaft
|
109
|
-
|
110
|
-
To setup Propshaft to use Deadfire as a preprocessor:
|
106
|
+
Propshaft is the new asset pipeline for Rails, to use Deadfire as a preprocessor add the deadfire gem to your Gemfile.
|
111
107
|
|
112
108
|
```ruby
|
113
|
-
|
114
|
-
class DeadfireCompiler < Propshaft::Compiler
|
115
|
-
def compile(logical_path, input)
|
116
|
-
Deadfire.parse(input, root_path: Rails.root.join("app", "assets", "stylesheets"))
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
Rails.application.config.assets.compilers << ["text/css", DeadfireCompiler]
|
109
|
+
gem "deadfire"
|
121
110
|
```
|
122
|
-
### Sprockets
|
123
|
-
|
124
|
-
To setup Sprocket to use Deadfire as a preprocessor:
|
125
111
|
|
126
|
-
|
127
|
-
# config/initializers/assets.rb
|
128
|
-
class DeadfireProcessor
|
129
|
-
def call(input)
|
130
|
-
return { data: Deadfire.parse(input[:data]) }
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
Deadfire.configuration.root_path = Rails.root.join('app', 'assets', 'stylesheets')
|
135
|
-
Sprockets.register_preprocessor('text/css', DeadfireProcessor.new)
|
136
|
-
```
|
112
|
+
That's all, your css file should now be run through Deadfire.
|
137
113
|
|
138
|
-
Your css file should now be run through Deadfire.
|
139
114
|
## Development
|
140
115
|
|
141
116
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -8,6 +8,7 @@ gemfile(true) do
|
|
8
8
|
gem "sassc"
|
9
9
|
gem "deadfire", github: "hahmed/deadfire", branch: "main"
|
10
10
|
gem "syntax_tree-css"
|
11
|
+
gem "sass-embedded"
|
11
12
|
|
12
13
|
gem "benchmark-ips"
|
13
14
|
end
|
@@ -25,7 +26,7 @@ body {
|
|
25
26
|
}
|
26
27
|
|
27
28
|
h1 {
|
28
|
-
font-size: 40px;
|
29
|
+
font-size: 40px;
|
29
30
|
}
|
30
31
|
/* Just
|
31
32
|
a
|
@@ -59,21 +60,52 @@ code {
|
|
59
60
|
}
|
60
61
|
CSS
|
61
62
|
|
62
|
-
def dartsass
|
63
|
-
system "sass benchmarks/input.scss output.css", exception: true
|
64
|
-
end
|
65
|
-
|
66
63
|
Benchmark.ips do |x|
|
67
64
|
x.config(:time => 5, :warmup => 2)
|
68
65
|
|
69
|
-
x.report("dartsass") { dartsass }
|
66
|
+
# x.report("dartsass") { dartsass }
|
70
67
|
x.report("deadfire") { Deadfire.parse(css) }
|
71
68
|
x.report("sassc") { SassC::Engine.new(css).render }
|
72
69
|
x.report("sytanx_tree") { SyntaxTree::CSS.parse(css) }
|
70
|
+
x.report("dart sass") { Sass.compile_string(css) }
|
73
71
|
x.compare!
|
74
72
|
end
|
75
73
|
|
76
|
-
#
|
74
|
+
# May 2024: Re-added dart sass
|
75
|
+
# Warming up --------------------------------------
|
76
|
+
# deadfire 172.000 i/100ms
|
77
|
+
# sassc 85.000 i/100ms
|
78
|
+
# sytanx_tree 79.000 i/100ms
|
79
|
+
# dart sass 520.000 i/100ms
|
80
|
+
# Calculating -------------------------------------
|
81
|
+
# deadfire 1.680k (± 0.9%) i/s - 8.428k in 5.018094s
|
82
|
+
# sassc 816.292 (± 0.2%) i/s - 4.165k in 5.102378s
|
83
|
+
# sytanx_tree 750.421 (± 1.9%) i/s - 3.792k in 5.054908s
|
84
|
+
# dart sass 5.225k (± 4.7%) i/s - 26.520k in 5.090927s
|
85
|
+
|
86
|
+
# Comparison:
|
87
|
+
# dart sass: 5224.7 i/s
|
88
|
+
# deadfire: 1679.7 i/s - 3.11x slower
|
89
|
+
# sassc: 816.3 i/s - 6.40x slower
|
90
|
+
# sytanx_tree: 750.4 i/s - 6.96x slower
|
91
|
+
|
92
|
+
# Nov 2023: (Note: removed dart sass because I don't have it installed, need to re-run again)
|
93
|
+
# Warming up --------------------------------------
|
94
|
+
# deadfire 116.000 i/100ms
|
95
|
+
# sassc 69.000 i/100ms
|
96
|
+
# sytanx_tree 64.000 i/100ms
|
97
|
+
# Calculating -------------------------------------
|
98
|
+
# deadfire 1.164k (± 1.2%) i/s - 5.916k in 5.084777s
|
99
|
+
# sassc 695.721 (± 1.3%) i/s - 3.519k in 5.059025s
|
100
|
+
# sytanx_tree 635.684 (± 3.3%) i/s - 3.200k in 5.040489s
|
101
|
+
|
102
|
+
# Comparison:
|
103
|
+
# deadfire: 1163.6 i/s
|
104
|
+
# sassc: 695.7 i/s - 1.67x slower
|
105
|
+
# sytanx_tree: 635.7 i/s - 1.83x slower
|
106
|
+
|
107
|
+
|
108
|
+
# Sep 2022:
|
77
109
|
# Warming up --------------------------------------
|
78
110
|
# dartsass 1.000 i/100ms
|
79
111
|
# deadfire 1.088k i/100ms
|
data/changelog.md
CHANGED
@@ -1,4 +1,29 @@
|
|
1
1
|
## Changelog
|
2
|
+
### 0.6.0 (current)
|
3
|
+
|
4
|
+
### 0.5.0 (12 Dec 2024)
|
5
|
+
- Drop ruby 2.7
|
6
|
+
- Add a railties to make it real simple to pre-process every file for a simple setup
|
7
|
+
- Added the asset registry to make it easier to control how or which file is used as a mixin
|
8
|
+
- Excluded files are no longer pro-processed
|
9
|
+
- Make rails + propshaft dependencies
|
10
|
+
|
11
|
+
### 0.4.0 (18 May 2024)
|
12
|
+
- Fix parsing comments that have 2 stars e.g. /**
|
13
|
+
- Adds a logger and a default setting that suppresses the logs which can be configured to report errors.
|
14
|
+
- Fixes issue with import's not parsing correctly when there is no ending semicolon.
|
15
|
+
- Added ci for ruby 3.3
|
16
|
+
- Add support for importing .scss files, making it easier to migrate from other libraries.
|
17
|
+
```
|
18
|
+
@import "nav"
|
19
|
+
@import "sidebar.scss"
|
20
|
+
.image { padding: 2px; }
|
21
|
+
```
|
22
|
+
Deadfire will look for the file nav.css, then nav.scss in the `config.root_path` in the case when a file extension is not included.
|
23
|
+
|
24
|
+
- Simplify the configuration by having one option called compressed instead of keep_newlines and keep_comments.
|
25
|
+
- Add the ability to exclude files from being pre-processed via the `config.deadfire.excluded_files` option.
|
26
|
+
|
2
27
|
### 0.3.0 (15 November 2023)
|
3
28
|
|
4
29
|
- Redo the parser by splitting up the tokenizer, parser, interpreter and generator phases which makes each step simpler. It's still faster than sassc but much slower than it was previously which is something I hope to address soon.
|
data/deadfire.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.summary = "Deadfire - lightweight css preprocessor"
|
10
10
|
spec.homepage = "https://github.com/hahmed/deadfire"
|
11
11
|
spec.license = "MIT"
|
12
|
-
spec.required_ruby_version = Gem::Requirement.new(">=
|
12
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 3.0")
|
13
13
|
|
14
14
|
spec.metadata["homepage_uri"] = spec.homepage
|
15
15
|
spec.metadata["source_code_uri"] = "https://github.com/hahmed/deadfire"
|
@@ -23,4 +23,9 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.bindir = "exe"
|
24
24
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
25
|
spec.require_paths = ["lib"]
|
26
|
+
|
27
|
+
spec.add_dependency "actionpack", ">= 7.0.0"
|
28
|
+
spec.add_dependency "activesupport", ">= 7.0.0"
|
29
|
+
spec.add_dependency "railties", ">= 7.0.0"
|
30
|
+
spec.add_dependency "propshaft", ">= 0.9.0"
|
26
31
|
end
|
data/lib/.keep
ADDED
File without changes
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Deadfire
|
4
|
+
# AssetLoader is responsible for loading mixin templates from the file system which can be used to mixin css into
|
5
|
+
# your stylesheet.
|
6
|
+
class AssetLoader
|
7
|
+
attr_reader :settings
|
8
|
+
|
9
|
+
def initialize(path)
|
10
|
+
@path = path
|
11
|
+
@cache = ActiveSupport::Cache::FileStore.new("tmp/deadfire_cache")
|
12
|
+
end
|
13
|
+
|
14
|
+
def cache_css(name, value)
|
15
|
+
cached_mixins[name] = value
|
16
|
+
end
|
17
|
+
|
18
|
+
def cached_css(name)
|
19
|
+
cached_mixins[name]
|
20
|
+
end
|
21
|
+
|
22
|
+
def preload(force_reload=false)
|
23
|
+
if force_reload
|
24
|
+
@_cached_mixins = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
cached_mixins
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def cached_mixins
|
33
|
+
@_cached_mixins ||= load_mixins
|
34
|
+
end
|
35
|
+
|
36
|
+
def load_mixins
|
37
|
+
Array.wrap(Deadfire.configuration.asset_registry.mixins_for(@path)).each.with_object({}) do |filename, data|
|
38
|
+
unless File.exist?(filename)
|
39
|
+
Deadfire.config.logger.error("Mixin not found: #{filename}")
|
40
|
+
next
|
41
|
+
end
|
42
|
+
|
43
|
+
stat = File.stat(filename)
|
44
|
+
key = "#{filename}-#{stat.mtime.hash}"
|
45
|
+
|
46
|
+
content = @cache.fetch(key)
|
47
|
+
|
48
|
+
if content.nil?
|
49
|
+
content = load_and_parse_mixin(filename, key)
|
50
|
+
end
|
51
|
+
|
52
|
+
content.each do |key, value|
|
53
|
+
Deadfire.config.logger.warn("Mixin '#{key}' will be overrided with a new value.") if data.key?(key)
|
54
|
+
|
55
|
+
data[key] = value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def load_and_parse_mixin(filename, key)
|
61
|
+
content = File.read(filename)
|
62
|
+
mixins = ParserEngine.new(content).load_mixins
|
63
|
+
@cache.write(key, mixins)
|
64
|
+
mixins
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Deadfire
|
4
|
+
class AssetRegistry
|
5
|
+
attr_reader :settings
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@settings = Hash.new { |h, k| h[k] = [] }
|
9
|
+
end
|
10
|
+
|
11
|
+
# for a given path, load all the mixins that are registered
|
12
|
+
# this makes it possible to load admin or other scoped mixins for a
|
13
|
+
# specific path
|
14
|
+
def register_path(path, *mixins)
|
15
|
+
normalized_mixins = Array.wrap(mixins).map { |p| full_path(p) }
|
16
|
+
normalize_path = strip_path(path).to_s
|
17
|
+
@settings[normalize_path].concat(normalized_mixins)
|
18
|
+
end
|
19
|
+
|
20
|
+
# for a given path, load all the mixins that are registered
|
21
|
+
# e.g. admin/ or admin will load all mixins for admin, if admin is a scope
|
22
|
+
# all mixins for admin/* will be loaded
|
23
|
+
def mixins_for(path)
|
24
|
+
return [] unless path.present?
|
25
|
+
|
26
|
+
mixins = []
|
27
|
+
|
28
|
+
mixins.concat Array.wrap(@settings[path])
|
29
|
+
|
30
|
+
if settings["*"].present?
|
31
|
+
mixins.concat Array.wrap(settings["*"])
|
32
|
+
end
|
33
|
+
|
34
|
+
scope = scope_from_path(path)
|
35
|
+
|
36
|
+
if scope.present? && settings[scope].present?
|
37
|
+
mixins.concat Array.wrap(settings[scope])
|
38
|
+
end
|
39
|
+
|
40
|
+
mixins.compact.uniq
|
41
|
+
end
|
42
|
+
|
43
|
+
def clear
|
44
|
+
@settings.clear
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def full_path(filename)
|
50
|
+
if File.exist?(filename)
|
51
|
+
filename
|
52
|
+
else
|
53
|
+
normalize_path(filename)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def normalize_path(filename)
|
58
|
+
path = File.join(Deadfire.config.root_path, filename)
|
59
|
+
path = css_extension(path)
|
60
|
+
|
61
|
+
unless File.exist?(path)
|
62
|
+
raise "Error finding asset path #{path}"
|
63
|
+
end
|
64
|
+
|
65
|
+
path
|
66
|
+
end
|
67
|
+
|
68
|
+
def css_extension(filename)
|
69
|
+
filename.end_with?(".css") ? filename : "#{filename}.css"
|
70
|
+
end
|
71
|
+
|
72
|
+
def scope?(path)
|
73
|
+
path.include?("/")
|
74
|
+
end
|
75
|
+
|
76
|
+
def scope_from_path(path)
|
77
|
+
if scope?(path)
|
78
|
+
path.split("/")[0...-1].join("/")
|
79
|
+
else
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def strip_path(path)
|
85
|
+
path.split("/").last
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/deadfire/ast_printer.rb
CHANGED
@@ -13,7 +13,7 @@ module Deadfire
|
|
13
13
|
def visit_stylesheet_node(node)
|
14
14
|
puts "StylesheetNode"
|
15
15
|
node.statements.each do |statement|
|
16
|
-
#
|
16
|
+
# todo
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -54,5 +54,10 @@ module Deadfire
|
|
54
54
|
puts "CommentNode"
|
55
55
|
puts " Comment: #{node.comment.lexeme}"
|
56
56
|
end
|
57
|
+
|
58
|
+
def visit_newline_node(node)
|
59
|
+
puts "NewlineNode"
|
60
|
+
puts " Newline: #{node.text}"
|
61
|
+
end
|
57
62
|
end
|
58
63
|
end
|
@@ -1,29 +1,47 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require "logger"
|
2
3
|
|
3
4
|
module Deadfire
|
4
5
|
class Configuration
|
5
|
-
attr_reader :directories, :root_path, :
|
6
|
+
attr_reader :directories, :root_path, :compressed, :logger, :supressed, :excluded_files, :asset_registry
|
6
7
|
|
7
8
|
def initialize
|
8
9
|
@directories = []
|
9
10
|
@root_path = ""
|
10
|
-
@
|
11
|
-
@
|
11
|
+
@compressed = false
|
12
|
+
@logger = Logger.new(STDOUT, level: :warn)
|
13
|
+
@supressed = true
|
14
|
+
@excluded_files = []
|
15
|
+
@asset_registry = AssetRegistry.new
|
12
16
|
end
|
13
17
|
|
14
18
|
def root_path=(value)
|
19
|
+
return if value.nil?
|
20
|
+
|
15
21
|
unless Dir.exist?(value)
|
16
22
|
raise DirectoryNotFoundError.new("Root not found #{value}")
|
17
23
|
end
|
18
24
|
@root_path = value
|
19
25
|
end
|
20
26
|
|
21
|
-
def
|
22
|
-
@
|
27
|
+
def compressed=(value)
|
28
|
+
@compressed = value unless value.nil?
|
29
|
+
end
|
30
|
+
|
31
|
+
def logger=(value)
|
32
|
+
@logger = value
|
33
|
+
end
|
34
|
+
|
35
|
+
def supressed=(value)
|
36
|
+
@supressed = value
|
37
|
+
end
|
38
|
+
|
39
|
+
def excluded_files=(value)
|
40
|
+
@excluded_files = value
|
23
41
|
end
|
24
42
|
|
25
|
-
def
|
26
|
-
@
|
43
|
+
def preprocess(*mixins, path: "*")
|
44
|
+
@asset_registry.register_path(path, *mixins)
|
27
45
|
end
|
28
46
|
end
|
29
47
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
require "stringio"
|
3
3
|
|
4
4
|
module Deadfire
|
@@ -19,7 +19,6 @@ module Deadfire
|
|
19
19
|
|
20
20
|
def visit_at_rule_node(node)
|
21
21
|
@output << node.at_keyword.lexeme
|
22
|
-
@output << " "
|
23
22
|
node.value.each do |value|
|
24
23
|
@output << value.lexeme
|
25
24
|
end
|
@@ -60,7 +59,7 @@ module Deadfire
|
|
60
59
|
end
|
61
60
|
|
62
61
|
def visit_comment_node(node)
|
63
|
-
@output << node.comment.lexeme
|
62
|
+
@output << node.comment.lexeme unless Deadfire.configuration.compressed
|
64
63
|
end
|
65
64
|
end
|
66
65
|
end
|
@@ -9,7 +9,9 @@ module Deadfire
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def error(line, message)
|
12
|
-
|
12
|
+
error = Error.new(line, message)
|
13
|
+
Deadfire.configuration.logger.error(error.to_s) unless Deadfire.configuration.supressed
|
14
|
+
@errors << error
|
13
15
|
end
|
14
16
|
|
15
17
|
def errors?
|
@@ -19,6 +21,10 @@ module Deadfire
|
|
19
21
|
private
|
20
22
|
|
21
23
|
# create error struct with line and message
|
22
|
-
Error = Struct.new(:line, :message)
|
24
|
+
Error = Struct.new(:line, :message) do
|
25
|
+
def to_s
|
26
|
+
"Line #{line}: #{message}"
|
27
|
+
end
|
28
|
+
end
|
23
29
|
end
|
24
30
|
end
|
data/lib/deadfire/errors.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
module Deadfire
|
4
4
|
class DirectoryNotFoundError < StandardError; end
|
5
|
-
class Error < StandardError; end
|
6
5
|
|
7
6
|
class DuplicateImportException < StandardError
|
8
7
|
def initialize(filename = "", lineno = "")
|
@@ -27,44 +26,4 @@ module Deadfire
|
|
27
26
|
super(msg)
|
28
27
|
end
|
29
28
|
end
|
30
|
-
|
31
|
-
class EarlyApplyException < StandardError
|
32
|
-
def initialize(input = "", lineno = "")
|
33
|
-
msg = if input
|
34
|
-
"Error with input: `#{input}` line: #{lineno}"
|
35
|
-
else
|
36
|
-
"Apply called too early in css. There are no mixins defined."
|
37
|
-
end
|
38
|
-
|
39
|
-
super(msg)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
class SyntaxError < StandardError
|
44
|
-
def initialize(message = "", lineno = "", original_line = "")
|
45
|
-
msg = if message
|
46
|
-
"#{original_line}\nline: #{lineno}: #{message}"
|
47
|
-
else
|
48
|
-
"Syntax "
|
49
|
-
end
|
50
|
-
|
51
|
-
super(msg)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
class ErrorsList
|
56
|
-
attr_reader :errors
|
57
|
-
|
58
|
-
def initialize
|
59
|
-
@errors = []
|
60
|
-
end
|
61
|
-
|
62
|
-
def add(message:, lineno:, original_line:)
|
63
|
-
@errors << SyntaxError.new(message, lineno, original_line)
|
64
|
-
end
|
65
|
-
|
66
|
-
def empty?
|
67
|
-
@errors.empty?
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
29
|
+
end
|