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.
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.