htx 0.1.0 → 1.0.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/LICENSE +1 -1
- data/README.md +27 -13
- data/VERSION +1 -1
- data/lib/htx/template.rb +132 -45
- data/lib/htx/version.rb +1 -1
- data/lib/htx.rb +6 -0
- metadata +12 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d869f62a146bed898334d085ce1dc507d214950d166454b65e502058bc68e6b6
|
4
|
+
data.tar.gz: fd81c8b3b82f2bd95e85899f14ee35f881f11a8b0f8b07b38af1f5b0ee599a87
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd23ac9b3363d467c1e47258654ed3d9a136e32e66379374b2d33a1abeeb358a1957de66364ad5af3dd20768a4ace5226ccb57c256b18b232de0381fe3144d25
|
7
|
+
data.tar.gz: e304e3e8b87c093eabc07628c0179c15eef76d9870483d96a129ce9f2f1358d0ec50df14e369e2c052aa59b992bcae2647753f3cb62f9e37de1d06b221332f4b
|
data/LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright 2019-
|
1
|
+
Copyright 2019-2024 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
@@ -1,8 +1,7 @@
|
|
1
1
|
# HTX Ruby Compiler
|
2
2
|
|
3
3
|
HTX templates are compiled to JavaScript before being used. This library provides a Ruby implementation of
|
4
|
-
the compiler. For more information on HTX, see
|
5
|
-
[https://github.com/npickens/htx](https://github.com/npickens/htx).
|
4
|
+
the compiler. For more information on HTX, see the main [README](https://github.com/npickens/htx).
|
6
5
|
|
7
6
|
## Installation
|
8
7
|
|
@@ -20,24 +19,39 @@ gem install htx
|
|
20
19
|
|
21
20
|
## Usage
|
22
21
|
|
23
|
-
|
24
|
-
|
22
|
+
HTX templates can be compiled to either a JavaScript module format or an IIFE assigned to a property on
|
23
|
+
either `globalThis` or a custom object. To compile as a module:
|
25
24
|
|
26
25
|
```ruby
|
27
26
|
path = '/components/crew.htx'
|
28
|
-
|
27
|
+
content = File.read("/assets#{path}")
|
28
|
+
|
29
|
+
HTX.compile(path, content, as_module: true, import_path: 'vendor/htx.js')
|
30
|
+
# => "import * as HTX from 'vendor/htx.js'
|
31
|
+
#
|
32
|
+
# ...
|
33
|
+
#
|
34
|
+
# export function Template { ... }"
|
35
|
+
#
|
36
|
+
```
|
29
37
|
|
30
|
-
|
38
|
+
Note that with the module format the name of the template does not appear anywhere in its compiled form, but
|
39
|
+
is still used/useful for tracking down errors when compilation is handled by an overall asset management
|
40
|
+
system (such as [Darkroom](https://github.com/npickens/darkroom)).
|
31
41
|
|
32
|
-
|
33
|
-
# // ...
|
34
|
-
# }
|
42
|
+
To compile to an IIFE assigned to a custom object:
|
35
43
|
|
36
|
-
|
44
|
+
```ruby
|
45
|
+
HTX.compile(path, content, as_module: false, assign_to: 'myTemplates')
|
46
|
+
# => "myTemplates['/components/crew.htx'] = ..."
|
47
|
+
```
|
37
48
|
|
38
|
-
|
39
|
-
|
40
|
-
|
49
|
+
Options can be configured globally so they don't have to be passed to `HTX.compile` every time:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
HTX.as_module = true # Default: false
|
53
|
+
HTX.import_path = 'vendor/htx.js' # Default: "/htx/htx.js"
|
54
|
+
HTX.assign_to = 'myTemplates' # Default: "globalThis"
|
41
55
|
```
|
42
56
|
|
43
57
|
## Contributing
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
1.0.0
|
data/lib/htx/template.rb
CHANGED
@@ -20,8 +20,8 @@ module HTX
|
|
20
20
|
INDENT_GUESS = /^( +|\t+)(?=\S)/.freeze
|
21
21
|
INDENT_REGEX = /\n(?=[^\n])/.freeze
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
AUTO_SEMICOLON_BEGIN = /\A\s*[\n;}]/.freeze
|
24
|
+
AUTO_SEMICOLON_END = /(\A|[\n;{}][^\S\n]*)\z/.freeze
|
25
25
|
|
26
26
|
NEWLINE_BEGIN = /\A\s*\n/.freeze
|
27
27
|
NEWLINE_END = /\n[^\S\n]*\z/.freeze
|
@@ -58,10 +58,14 @@ module HTX
|
|
58
58
|
##
|
59
59
|
# Compiles the HTX template.
|
60
60
|
#
|
61
|
-
# * +
|
61
|
+
# * +as_module+ - Boolean indicating whether or not to compile as a JavaScript module.
|
62
|
+
# * +import_path+ - Path to HTX JavaScript library for module import statement.
|
63
|
+
# * +assign_to+ - JavaScript object to assign the template function to if module not being used.
|
62
64
|
#
|
63
|
-
def compile(assign_to: nil)
|
64
|
-
@
|
65
|
+
def compile(as_module: nil, import_path: nil, assign_to: nil)
|
66
|
+
@as_module = as_module.nil? ? HTX.as_module : as_module
|
67
|
+
@import_path = import_path || HTX.import_path
|
68
|
+
@assign_to = assign_to || HTX.assign_to
|
65
69
|
@base_indent = @indent = @content[INDENT_GUESS] || INDENT_DEFAULT
|
66
70
|
@static_key = 0
|
67
71
|
@close_count = 0
|
@@ -141,32 +145,30 @@ module HTX
|
|
141
145
|
# * +node+ - Nokogiri node to process.
|
142
146
|
#
|
143
147
|
def process_fragment_node(node)
|
144
|
-
append(
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
JS
|
149
|
-
)
|
148
|
+
append("#{
|
149
|
+
@as_module ? "import * as HTX from '#{@import_path}'\n\n"
|
150
|
+
: "#{@assign_to}['#{@name}'] = ((HTX) => {\n#{@indent}"
|
151
|
+
}function render($renderer) {\n")
|
150
152
|
|
151
|
-
@indent = @base_indent * 2
|
153
|
+
@indent = @base_indent * 2 unless @as_module
|
152
154
|
|
153
155
|
node.children.each do |child|
|
154
156
|
process(child)
|
155
157
|
end
|
156
158
|
|
157
|
-
append("\n\n#{@indent}return $
|
159
|
+
append("\n\n#{@indent}return $renderer.rootNode")
|
158
160
|
|
159
|
-
@indent = @base_indent
|
161
|
+
@indent = @as_module ? '' : @base_indent
|
160
162
|
|
161
163
|
append(
|
162
|
-
|
164
|
+
<<~JS
|
163
165
|
|
164
166
|
#{@indent}}
|
165
167
|
|
166
|
-
#{@indent}return function Template(context) {
|
167
|
-
#{@indent
|
168
|
-
#{@indent}}
|
169
|
-
})(globalThis.HTX ||= {});
|
168
|
+
#{@indent}#{@as_module ? 'export' : 'return'} function Template(context) {
|
169
|
+
#{@indent}#{@base_indent}this.render = render.bind(context, new HTX.Renderer)
|
170
|
+
#{@indent}}#{
|
171
|
+
"\n})(globalThis.HTX ||= {});" unless @as_module}
|
170
172
|
JS
|
171
173
|
)
|
172
174
|
|
@@ -180,6 +182,7 @@ module HTX
|
|
180
182
|
# * +xmlns+ - True if node is the descendant of a node with an xmlns attribute.
|
181
183
|
#
|
182
184
|
def process_element_node(node, xmlns: false)
|
185
|
+
is_template = node.name == 'template'
|
183
186
|
children = node.children
|
184
187
|
childless = children.empty? || (children.size == 1 && self.class.formatting_node?(children.first))
|
185
188
|
dynamic_key = self.class.attribute_value(node.attr(DYNAMIC_KEY_ATTR))
|
@@ -199,19 +202,21 @@ module HTX
|
|
199
202
|
dynamic_key: dynamic_key,
|
200
203
|
)
|
201
204
|
else
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
205
|
+
unless is_template
|
206
|
+
append_htx_node(
|
207
|
+
"'#{self.class.tag_name(node.name)}'",
|
208
|
+
*attributes,
|
209
|
+
dynamic_key,
|
210
|
+
ELEMENT | (childless ? CHILDLESS : 0) | (xmlns ? XMLNS : 0),
|
211
|
+
)
|
212
|
+
end
|
208
213
|
|
209
214
|
unless childless
|
210
215
|
children.each do |child|
|
211
216
|
process(child, xmlns: xmlns)
|
212
217
|
end
|
213
218
|
|
214
|
-
@close_count += 1
|
219
|
+
@close_count += 1 unless is_template
|
215
220
|
end
|
216
221
|
end
|
217
222
|
end
|
@@ -268,7 +273,7 @@ module HTX
|
|
268
273
|
close_count = @close_count
|
269
274
|
@close_count = 0
|
270
275
|
|
271
|
-
append("$
|
276
|
+
append("$renderer.close(#{close_count unless close_count == 1})")
|
272
277
|
end
|
273
278
|
|
274
279
|
if @whitespace_buff
|
@@ -279,8 +284,14 @@ module HTX
|
|
279
284
|
|
280
285
|
if (confirmed_newline || @statement_buff.match?(NEWLINE_END)) && !text.match?(NEWLINE_BEGIN)
|
281
286
|
@statement_buff << @indent
|
282
|
-
|
283
|
-
@statement_buff
|
287
|
+
else
|
288
|
+
unless @statement_buff.match?(AUTO_SEMICOLON_END) || text.match?(AUTO_SEMICOLON_BEGIN)
|
289
|
+
@statement_buff << ";"
|
290
|
+
end
|
291
|
+
|
292
|
+
unless @statement_buff.empty? || text.match?(WHITESPACE_BEGIN)
|
293
|
+
@statement_buff << ' '
|
294
|
+
end
|
284
295
|
end
|
285
296
|
|
286
297
|
flush if text.match?(NON_WHITESPACE)
|
@@ -288,9 +299,9 @@ module HTX
|
|
288
299
|
end
|
289
300
|
|
290
301
|
##
|
291
|
-
# Appends an
|
302
|
+
# Appends an +$renderer.node+ call to the compiled template function string.
|
292
303
|
#
|
293
|
-
# * +args+ - Arguments to use for the
|
304
|
+
# * +args+ - Arguments to use for the +$renderer.node+ call (any +nil+ ones are removed).
|
294
305
|
#
|
295
306
|
def append_htx_node(*args)
|
296
307
|
return if args.first.nil?
|
@@ -299,7 +310,7 @@ module HTX
|
|
299
310
|
args << 0 unless args.last.kind_of?(Integer)
|
300
311
|
args[-1] |= (@static_key += 1) << FLAG_BITS
|
301
312
|
|
302
|
-
append("$
|
313
|
+
append("$renderer.node(#{args.join(', ')})")
|
303
314
|
end
|
304
315
|
|
305
316
|
##
|
@@ -408,24 +419,100 @@ module HTX
|
|
408
419
|
|
409
420
|
# Source: https://developer.mozilla.org/en-US/docs/Web/SVG/Element
|
410
421
|
TAG_MAP = %w[
|
411
|
-
animateMotion
|
412
|
-
|
413
|
-
|
414
|
-
|
422
|
+
animateMotion
|
423
|
+
animateTransform
|
424
|
+
clipPath
|
425
|
+
feBlend
|
426
|
+
feColorMatrix
|
427
|
+
feComponentTransfer
|
428
|
+
feComposite
|
429
|
+
feConvolveMatrix
|
430
|
+
feDiffuseLighting
|
431
|
+
feDisplacementMap
|
432
|
+
feDistantLight
|
433
|
+
feDropShadow
|
434
|
+
feFlood
|
435
|
+
feFuncA
|
436
|
+
feFuncB
|
437
|
+
feFuncG
|
438
|
+
feFuncR
|
439
|
+
feGaussianBlur
|
440
|
+
feImage
|
441
|
+
feMerge
|
442
|
+
feMergeNode
|
443
|
+
feMorphology
|
444
|
+
feOffset
|
445
|
+
fePointLight
|
446
|
+
feSpecularLighting
|
447
|
+
feSpotLight
|
448
|
+
feTile
|
449
|
+
feTurbulence
|
450
|
+
foreignObject
|
451
|
+
linearGradient
|
452
|
+
radialGradient
|
415
453
|
textPath
|
416
454
|
].map { |tag| [tag.downcase, tag] }.to_h.freeze
|
417
455
|
|
418
456
|
# Source: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute
|
419
457
|
ATTR_MAP = %w[
|
420
|
-
attributeName
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
458
|
+
attributeName
|
459
|
+
attributeType
|
460
|
+
baseFrequency
|
461
|
+
baseProfile
|
462
|
+
calcMode
|
463
|
+
clipPathUnits
|
464
|
+
diffuseConstant
|
465
|
+
edgeMode
|
466
|
+
filterUnits
|
467
|
+
glyphRef
|
468
|
+
gradientTransform
|
469
|
+
gradientUnits
|
470
|
+
kernelMatrix
|
471
|
+
kernelUnitLength
|
472
|
+
keyPoints
|
473
|
+
keySplines
|
474
|
+
keyTimes
|
475
|
+
lengthAdjust
|
476
|
+
limitingConeAngle
|
477
|
+
markerHeight
|
478
|
+
markerUnits
|
479
|
+
markerWidth
|
480
|
+
maskContentUnits
|
481
|
+
maskUnits
|
482
|
+
numOctaves
|
483
|
+
pathLength
|
484
|
+
patternContentUnits
|
485
|
+
patternTransform
|
486
|
+
patternUnits
|
487
|
+
pointsAtX
|
488
|
+
pointsAtY
|
489
|
+
pointsAtZ
|
490
|
+
preserveAlpha
|
491
|
+
preserveAspectRatio
|
492
|
+
primitiveUnits
|
493
|
+
refX
|
494
|
+
refY
|
495
|
+
referrerPolicy
|
496
|
+
repeatCount
|
497
|
+
repeatDur
|
498
|
+
requiredExtensions
|
499
|
+
requiredFeatures
|
500
|
+
specularConstant
|
501
|
+
specularExponent
|
502
|
+
spreadMethod
|
503
|
+
startOffset
|
504
|
+
stdDeviation
|
505
|
+
stitchTiles
|
506
|
+
surfaceScale
|
507
|
+
systemLanguage
|
508
|
+
tableValues
|
509
|
+
targetX
|
510
|
+
targetY
|
511
|
+
textLength
|
512
|
+
viewBox
|
513
|
+
xChannelSelector
|
514
|
+
yChannelSelector
|
515
|
+
zoomAndPan
|
429
516
|
].map { |attr| [attr.downcase, attr] }.to_h.freeze
|
430
517
|
end
|
431
518
|
end
|
data/lib/htx/version.rb
CHANGED
data/lib/htx.rb
CHANGED
@@ -11,6 +11,12 @@ require('htx/version')
|
|
11
11
|
module HTX
|
12
12
|
EMPTY_HASH = {}.freeze
|
13
13
|
|
14
|
+
@as_module = false
|
15
|
+
@import_path = '/htx/htx.js'
|
16
|
+
@assign_to = 'globalThis'
|
17
|
+
|
18
|
+
class << self; attr_accessor(:as_module, :import_path, :assign_to); end
|
19
|
+
|
14
20
|
##
|
15
21
|
# Convenience method to create a new Template instance and compile it.
|
16
22
|
#
|
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:
|
4
|
+
version: 1.0.0
|
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: 2024-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -42,22 +42,16 @@ dependencies:
|
|
42
42
|
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 5.11.2
|
48
|
-
- - "<"
|
45
|
+
- - "~>"
|
49
46
|
- !ruby/object:Gem::Version
|
50
|
-
version:
|
47
|
+
version: '5.21'
|
51
48
|
type: :development
|
52
49
|
prerelease: false
|
53
50
|
version_requirements: !ruby/object:Gem::Requirement
|
54
51
|
requirements:
|
55
|
-
- - "
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
version: 5.11.2
|
58
|
-
- - "<"
|
52
|
+
- - "~>"
|
59
53
|
- !ruby/object:Gem::Version
|
60
|
-
version:
|
54
|
+
version: '5.21'
|
61
55
|
description: HTX is a full-featured HTML template system that is simple, lightweight,
|
62
56
|
and highly performant. This library is a Ruby implementation of the HTX template
|
63
57
|
compiler--it converts HTX templates to their compiled JavaScript form.
|
@@ -78,9 +72,9 @@ homepage: https://github.com/npickens/htx
|
|
78
72
|
licenses:
|
79
73
|
- MIT
|
80
74
|
metadata:
|
81
|
-
|
82
|
-
|
83
|
-
source_code_uri: https://github.com/npickens/htx
|
75
|
+
bug_tracker_uri: https://github.com/npickens/htx/issues
|
76
|
+
documentation_uri: https://github.com/npickens/htx/blob/1.0.0/README.md
|
77
|
+
source_code_uri: https://github.com/npickens/htx/tree/1.0.0
|
84
78
|
post_install_message:
|
85
79
|
rdoc_options: []
|
86
80
|
require_paths:
|
@@ -89,14 +83,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
89
83
|
requirements:
|
90
84
|
- - ">="
|
91
85
|
- !ruby/object:Gem::Version
|
92
|
-
version:
|
86
|
+
version: 3.0.0
|
93
87
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
88
|
requirements:
|
95
89
|
- - ">="
|
96
90
|
- !ruby/object:Gem::Version
|
97
|
-
version:
|
91
|
+
version: 2.0.0
|
98
92
|
requirements: []
|
99
|
-
rubygems_version: 3.
|
93
|
+
rubygems_version: 3.5.10
|
100
94
|
signing_key:
|
101
95
|
specification_version: 4
|
102
96
|
summary: A Ruby compiler for HTX templates.
|