htx 0.0.2 → 0.0.4
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/LICENSE +1 -1
- data/README.md +9 -0
- data/lib/htx.rb +41 -20
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad1aaabd0904124ebc249af10fd5e8e93c11009f0fc0f7cb31f2f8656d4bb47d
|
4
|
+
data.tar.gz: 44e8808f07d173efc4830f07e0732822715e9837764518b780efe300ff08f2e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c7533d1b88bfc3365794cd18b8f26083364a060d4fdc1d4d1b3cef6dcb13af87e2ce4beb06553846da8add2481bda8fae5666a614b1c0ffff8b97d2b5aadd9d
|
7
|
+
data.tar.gz: ef37756cd45b5e7c58ababb1b9350467748816b998f50976055f2541356d282bd15bad20d47325f4ba4a32af1256b7ca407293b45ec496ba23fab494fd4c9f31
|
data/LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright 2019 Nate Pickens
|
1
|
+
Copyright 2019-2020 Nate Pickens
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
4
4
|
documentation files (the "Software"), to deal in the Software without restriction, including without
|
data/README.md
CHANGED
@@ -29,11 +29,20 @@ template = File.read(File.join('some/asset/dir', path))
|
|
29
29
|
|
30
30
|
HTX.compile(path, template)
|
31
31
|
|
32
|
+
# Or to attach to a custom object instead of `window`:
|
33
|
+
HTX.compile(path, template, assign_to: 'myTemplates')
|
34
|
+
|
32
35
|
# Result:
|
33
36
|
#
|
34
37
|
# window['/my/hot/template.htx'] = function(htx) {
|
35
38
|
# ...
|
36
39
|
# }
|
40
|
+
#
|
41
|
+
# If `assign_to` is specified:
|
42
|
+
#
|
43
|
+
# myTemplates['/components/people.htx'] = function(htx) {
|
44
|
+
# // ...
|
45
|
+
# }
|
37
46
|
```
|
38
47
|
|
39
48
|
## Contributing
|
data/lib/htx.rb
CHANGED
@@ -6,9 +6,7 @@ require('nokogiri')
|
|
6
6
|
# A Ruby compiler for HTX templates.
|
7
7
|
#
|
8
8
|
class HTX
|
9
|
-
|
10
|
-
|
11
|
-
VERSION = '0.0.2'
|
9
|
+
VERSION = '0.0.4'
|
12
10
|
|
13
11
|
CHILDLESS = 0b01
|
14
12
|
TEXT_NODE = 0b10
|
@@ -34,11 +32,13 @@ class HTX
|
|
34
32
|
CONTROL_STATEMENT = /[{}();]/.freeze
|
35
33
|
CLOSE_STATEMENT = /;?\s*htx\.close\((\d*)\);?(\s*)\z/.freeze
|
36
34
|
|
35
|
+
EMPTY_HASH = {}.freeze
|
36
|
+
|
37
37
|
##
|
38
38
|
# Convenience method to create a new instance and immediately call compile on it.
|
39
39
|
#
|
40
|
-
def self.compile(name, template)
|
41
|
-
new(name, template).compile
|
40
|
+
def self.compile(name, template, options = EMPTY_HASH)
|
41
|
+
new(name, template).compile(options)
|
42
42
|
end
|
43
43
|
|
44
44
|
##
|
@@ -53,16 +53,17 @@ class HTX
|
|
53
53
|
##
|
54
54
|
# Compiles the HTX template.
|
55
55
|
#
|
56
|
-
def compile
|
56
|
+
def compile(options = EMPTY_HASH)
|
57
57
|
doc = Nokogiri::HTML::DocumentFragment.parse(@template)
|
58
58
|
root_nodes = doc.children.select { |n| n.element? || (n.text? && n.text.strip != '') }
|
59
59
|
|
60
|
-
if root_nodes.
|
61
|
-
raise(MalformedTemplateError.new('
|
60
|
+
if (text_node = root_nodes.find(&:text?))
|
61
|
+
raise(MalformedTemplateError.new('text nodes are not allowed at root level', @name, text_node))
|
62
62
|
elsif root_nodes.size == 0
|
63
|
-
raise(MalformedTemplateError.new('
|
63
|
+
raise(MalformedTemplateError.new('a root node is required', @name))
|
64
64
|
elsif root_nodes.size > 1
|
65
|
-
raise(MalformedTemplateError.new(
|
65
|
+
raise(MalformedTemplateError.new("root node already defined on line #{root_nodes[0].line}", @name,
|
66
|
+
root_nodes[1]))
|
66
67
|
end
|
67
68
|
|
68
69
|
@compiled = ''.dup
|
@@ -72,7 +73,7 @@ class HTX
|
|
72
73
|
@compiled.rstrip!
|
73
74
|
|
74
75
|
<<~EOS
|
75
|
-
window['#{@name}'] = function(htx) {
|
76
|
+
#{options[:assign_to] || 'window'}['#{@name}'] = function(htx) {
|
76
77
|
#{@compiled}
|
77
78
|
}
|
78
79
|
EOS
|
@@ -90,6 +91,10 @@ class HTX
|
|
90
91
|
dynamic_key = process_value(node.attr(DYNAMIC_KEY_ATTR), :attr)
|
91
92
|
|
92
93
|
if node.text? || node.name == ':'
|
94
|
+
if (non_text_node = node.children.find { |n| !n.text? })
|
95
|
+
raise(MalformedTemplateError.new('dummy tags may not contain child tags', @name, non_text_node))
|
96
|
+
end
|
97
|
+
|
93
98
|
text = (node.text? ? node : node.children).text
|
94
99
|
|
95
100
|
if (value = process_value(text))
|
@@ -113,14 +118,16 @@ class HTX
|
|
113
118
|
attrs << process_value(attr.value, :attr)
|
114
119
|
end
|
115
120
|
|
121
|
+
childless = node.children.empty? || (node.children.size == 1 && node.children[0].text.strip == '')
|
122
|
+
|
116
123
|
append("htx.node(#{[
|
117
124
|
"'#{TAG_MAP[node.name] || node.name}'",
|
118
125
|
attrs,
|
119
126
|
dynamic_key,
|
120
|
-
((@static_key += 1) << FLAG_BITS) | (
|
127
|
+
((@static_key += 1) << FLAG_BITS) | (childless ? CHILDLESS : 0),
|
121
128
|
].compact.flatten.join(', ')})")
|
122
129
|
|
123
|
-
unless
|
130
|
+
unless childless
|
124
131
|
process(node)
|
125
132
|
|
126
133
|
count = ''
|
@@ -198,6 +205,18 @@ class HTX
|
|
198
205
|
value.encode('ascii', fallback: ->(c) { "\\u#{c.ord.to_s(16).rjust(4, '0')}" })
|
199
206
|
end
|
200
207
|
|
208
|
+
class MalformedTemplateError < StandardError
|
209
|
+
def initialize(message, name, node = nil)
|
210
|
+
if node
|
211
|
+
line = node.line
|
212
|
+
line = node.parent.line if line < 1
|
213
|
+
line = nil if line == -1
|
214
|
+
end
|
215
|
+
|
216
|
+
super("Malformed template #{name}#{":#{line}" if line}: #{message}")
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
201
220
|
# The Nokogiri HTML parser downcases all tag and attribute names, but SVG tags and attributes are case
|
202
221
|
# sensitive and often mix cased. These maps are used to restore the correct case of such tags and
|
203
222
|
# attributes.
|
@@ -209,12 +228,14 @@ class HTX
|
|
209
228
|
].map { |tag| [tag.downcase, tag] }.to_h.freeze
|
210
229
|
|
211
230
|
ATTR_MAP = %w[
|
212
|
-
attributeName baseFrequency calcMode clipPathUnits
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
231
|
+
allowReorder attributeName attributeType autoReverse baseFrequency baseProfile calcMode clipPathUnits
|
232
|
+
contentScriptType contentStyleType diffuseConstant edgeMode externalResourcesRequired filterRes
|
233
|
+
filterUnits glyphRef gradientTransform gradientUnits kernelMatrix kernelUnitLength keyPoints keySplines
|
234
|
+
keyTimes lengthAdjust limitingConeAngle markerHeight markerUnits markerWidth maskContentUnits maskUnits
|
235
|
+
numOctaves pathLength patternContentUnits patternTransform patternUnits pointsAtX pointsAtY pointsAtZ
|
236
|
+
preserveAlpha preserveAspectRatio primitiveUnits refX refY referrerPolicy repeatCount repeatDur
|
237
|
+
requiredExtensions requiredFeatures specularConstant specularExponent spreadMethod startOffset
|
238
|
+
stdDeviation stitchTiles surfaceScale systemLanguage tableValues targetX targetY textLength viewBox
|
239
|
+
viewTarget xChannelSelector yChannelSelector zoomAndPan
|
219
240
|
].map { |attr| [attr.downcase, attr] }.to_h.freeze
|
220
241
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: htx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nate Pickens
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-04-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -85,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
85
|
- !ruby/object:Gem::Version
|
86
86
|
version: '0'
|
87
87
|
requirements: []
|
88
|
-
rubygems_version: 3.
|
88
|
+
rubygems_version: 3.1.2
|
89
89
|
signing_key:
|
90
90
|
specification_version: 4
|
91
91
|
summary: A Ruby compiler for HTX templates.
|