htx 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +9 -0
  4. data/lib/htx.rb +41 -20
  5. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32fe6cdd2942dae5d197592bc9dbe2248b93bebcfe0d0fb5a82b463b9e953c28
4
- data.tar.gz: 36496d0d5395836bb8196f6a1fe2b02af7634c97c2028536e149b7a69d1603d9
3
+ metadata.gz: ad1aaabd0904124ebc249af10fd5e8e93c11009f0fc0f7cb31f2f8656d4bb47d
4
+ data.tar.gz: 44e8808f07d173efc4830f07e0732822715e9837764518b780efe300ff08f2e6
5
5
  SHA512:
6
- metadata.gz: e9c9bf24ca54886e6f4b9ad8e2bd8796436f299b2c0af7a0d742ac1b6ade2e55a30e477e4e5bb5b6d17a766641cd20cac8b3a0140e1fbfa48dda234664bf9c95
7
- data.tar.gz: 85640a72d956e08d1f1467b8b3ef609e91f9bbc918e15b5c1faaf9065410b3b1f9324d30f82b65f9b12deae5417132f0aa6fa8fb081b8ccd7cb173f5f5af9360
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
- class MalformedTemplateError < StandardError; end
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.any?(&:text?)
61
- raise(MalformedTemplateError.new('Template contains text at its root level'))
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('Template does not have a root node'))
63
+ raise(MalformedTemplateError.new('a root node is required', @name))
64
64
  elsif root_nodes.size > 1
65
- raise(MalformedTemplateError.new('Template has more than one node at its root level'))
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) | (node.children.empty? ? CHILDLESS : 0),
127
+ ((@static_key += 1) << FLAG_BITS) | (childless ? CHILDLESS : 0),
121
128
  ].compact.flatten.join(', ')})")
122
129
 
123
- unless node.children.empty?
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 diffuseConstant edgeMode filterUnits
213
- gradientTransform gradientUnits kernelMatrix kernelUnitLength keyPoints keySplines keyTimes lengthAdjust
214
- limitingConeAngle markerHeight markerUnits markerWidth maskContentUnits maskUnits numOctaves pathLength
215
- patternContentUnits patternTransform patternUnits pointsAtX pointsAtY pointsAtZ preserveAlpha
216
- preserveAspectRatio primitiveUnits refX refY repeatCount repeatDur requiredExtensions specularConstant
217
- specularExponent spreadMethod startOffset stdDeviation stitchTiles surfaceScale systemLanguage
218
- tableValues targetX targetY textLength viewBox xChannelSelector yChannelSelector zoomAndPan
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.2
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: 2019-10-29 00:00:00.000000000 Z
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.0.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.