luoma 0.1.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.
Files changed (152) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +2 -0
  3. data/.rdoc_options +16 -0
  4. data/CHANGELOG.md +5 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +68 -0
  7. data/Rakefile +69 -0
  8. data/Steepfile +41 -0
  9. data/certs/jgrp.pem +27 -0
  10. data/docs/configuration.md +180 -0
  11. data/docs/custom_filters.md +3 -0
  12. data/docs/custom_tags.md +3 -0
  13. data/docs/expressions.md +3 -0
  14. data/docs/extension_types.md +41 -0
  15. data/docs/filter_reference.md +1702 -0
  16. data/docs/index.md +73 -0
  17. data/docs/luoma_for_template_authors.md +3 -0
  18. data/docs/markdown.md +111 -0
  19. data/docs/predicate_reference.md +3 -0
  20. data/docs/static_analysis.md +3 -0
  21. data/docs/tag_reference.md +352 -0
  22. data/docs/template_loaders.md +177 -0
  23. data/docs/undefined_variables.md +3 -0
  24. data/docs-requirements.txt +11 -0
  25. data/docs_/cycle.md +17 -0
  26. data/docs_/font_rendering_example.md +157 -0
  27. data/docs_/header_block_example.md +51 -0
  28. data/docs_/increment_and_decrement.md +49 -0
  29. data/docs_/logo_style_example.md +40 -0
  30. data/docs_/migration.md +11 -0
  31. data/docs_/notes.md +19 -0
  32. data/lib/luoma/cache.rb +80 -0
  33. data/lib/luoma/chain_hash.rb +54 -0
  34. data/lib/luoma/context.rb +227 -0
  35. data/lib/luoma/drop.rb +84 -0
  36. data/lib/luoma/drops/block.rb +33 -0
  37. data/lib/luoma/drops/expression.rb +29 -0
  38. data/lib/luoma/drops/html_safe.rb +36 -0
  39. data/lib/luoma/drops/range.rb +69 -0
  40. data/lib/luoma/drops/undefined.rb +119 -0
  41. data/lib/luoma/environment.rb +479 -0
  42. data/lib/luoma/errors.rb +79 -0
  43. data/lib/luoma/escape.rb +35 -0
  44. data/lib/luoma/expression.rb +1271 -0
  45. data/lib/luoma/filter.rb +97 -0
  46. data/lib/luoma/filters/array.rb +372 -0
  47. data/lib/luoma/filters/date.rb +19 -0
  48. data/lib/luoma/filters/default.rb +16 -0
  49. data/lib/luoma/filters/json.rb +14 -0
  50. data/lib/luoma/filters/math.rb +84 -0
  51. data/lib/luoma/filters/size.rb +13 -0
  52. data/lib/luoma/filters/slice.rb +52 -0
  53. data/lib/luoma/filters/sort.rb +113 -0
  54. data/lib/luoma/filters/string.rb +186 -0
  55. data/lib/luoma/fnv.rb +15 -0
  56. data/lib/luoma/lexer.rb +106 -0
  57. data/lib/luoma/lexer_legacy.rb +396 -0
  58. data/lib/luoma/lexer_unified.rb +279 -0
  59. data/lib/luoma/loader.rb +50 -0
  60. data/lib/luoma/loaders/choice_loader.rb +20 -0
  61. data/lib/luoma/loaders/file_system_loader.rb +75 -0
  62. data/lib/luoma/loaders/mixins.rb +52 -0
  63. data/lib/luoma/markup.rb +109 -0
  64. data/lib/luoma/parser.rb +252 -0
  65. data/lib/luoma/parser_unified.rb +979 -0
  66. data/lib/luoma/predicates/blank.rb +19 -0
  67. data/lib/luoma/predicates/defined.rb +10 -0
  68. data/lib/luoma/predicates/empty.rb +15 -0
  69. data/lib/luoma/predicates/type.rb +35 -0
  70. data/lib/luoma/static_analysis.rb +427 -0
  71. data/lib/luoma/tags/assign.rb +63 -0
  72. data/lib/luoma/tags/break.rb +23 -0
  73. data/lib/luoma/tags/capture.rb +43 -0
  74. data/lib/luoma/tags/case.rb +137 -0
  75. data/lib/luoma/tags/comment.rb +17 -0
  76. data/lib/luoma/tags/continue.rb +23 -0
  77. data/lib/luoma/tags/define.rb +42 -0
  78. data/lib/luoma/tags/else.rb +30 -0
  79. data/lib/luoma/tags/for.rb +108 -0
  80. data/lib/luoma/tags/if.rb +109 -0
  81. data/lib/luoma/tags/import.rb +91 -0
  82. data/lib/luoma/tags/include.rb +77 -0
  83. data/lib/luoma/tags/output.rb +20 -0
  84. data/lib/luoma/tags/raw.rb +26 -0
  85. data/lib/luoma/tags/render.rb +92 -0
  86. data/lib/luoma/tags/with.rb +55 -0
  87. data/lib/luoma/template.rb +178 -0
  88. data/lib/luoma/token.rb +84 -0
  89. data/lib/luoma/version.rb +5 -0
  90. data/lib/luoma.rb +75 -0
  91. data/sig/luoma/cache.rbs +44 -0
  92. data/sig/luoma/chain_hash.rbs +26 -0
  93. data/sig/luoma/context.rbs +115 -0
  94. data/sig/luoma/drop.rbs +44 -0
  95. data/sig/luoma/drops/block.rbs +10 -0
  96. data/sig/luoma/drops/expression.rbs +10 -0
  97. data/sig/luoma/drops/html_safe.rbs +14 -0
  98. data/sig/luoma/drops/range.rbs +15 -0
  99. data/sig/luoma/drops/undefined.rbs +27 -0
  100. data/sig/luoma/environment.rbs +212 -0
  101. data/sig/luoma/errors.rbs +67 -0
  102. data/sig/luoma/escape.rbs +15 -0
  103. data/sig/luoma/expression.rbs +514 -0
  104. data/sig/luoma/filter.rbs +66 -0
  105. data/sig/luoma/filters/array.rbs +74 -0
  106. data/sig/luoma/filters/date.rbs +9 -0
  107. data/sig/luoma/filters/default.rbs +8 -0
  108. data/sig/luoma/filters/json.rbs +7 -0
  109. data/sig/luoma/filters/math.rbs +37 -0
  110. data/sig/luoma/filters/size.rbs +6 -0
  111. data/sig/luoma/filters/slice.rbs +10 -0
  112. data/sig/luoma/filters/sort.rbs +17 -0
  113. data/sig/luoma/filters/string.rbs +103 -0
  114. data/sig/luoma/fnv.rbs +3 -0
  115. data/sig/luoma/lexer.rbs +42 -0
  116. data/sig/luoma/lexer_legacy.rbs +81 -0
  117. data/sig/luoma/lexer_unified.rbs +49 -0
  118. data/sig/luoma/loader.rbs +40 -0
  119. data/sig/luoma/loaders/choice_loader.rbs +9 -0
  120. data/sig/luoma/loaders/file_system_loader.rbs +19 -0
  121. data/sig/luoma/loaders/mixins.rbs +16 -0
  122. data/sig/luoma/markup.rbs +68 -0
  123. data/sig/luoma/parser.rbs +105 -0
  124. data/sig/luoma/parser_unified.rbs +150 -0
  125. data/sig/luoma/predicates/blank.rbs +6 -0
  126. data/sig/luoma/predicates/defined.rbs +6 -0
  127. data/sig/luoma/predicates/empty.rbs +6 -0
  128. data/sig/luoma/predicates/type.rbs +21 -0
  129. data/sig/luoma/static_analysis.rbs +141 -0
  130. data/sig/luoma/tags/assign.rbs +12 -0
  131. data/sig/luoma/tags/break.rbs +11 -0
  132. data/sig/luoma/tags/capture.rbs +14 -0
  133. data/sig/luoma/tags/case.rbs +36 -0
  134. data/sig/luoma/tags/comment.rbs +11 -0
  135. data/sig/luoma/tags/continue.rbs +11 -0
  136. data/sig/luoma/tags/define.rbs +16 -0
  137. data/sig/luoma/tags/else.rbs +17 -0
  138. data/sig/luoma/tags/for.rbs +26 -0
  139. data/sig/luoma/tags/if.rbs +45 -0
  140. data/sig/luoma/tags/import.rbs +13 -0
  141. data/sig/luoma/tags/include.rbs +13 -0
  142. data/sig/luoma/tags/output.rbs +13 -0
  143. data/sig/luoma/tags/raw.rbs +11 -0
  144. data/sig/luoma/tags/render.rbs +13 -0
  145. data/sig/luoma/tags/with.rbs +15 -0
  146. data/sig/luoma/template.rbs +117 -0
  147. data/sig/luoma/token.rbs +81 -0
  148. data/sig/luoma.rbs +11 -0
  149. data/zensical.toml +363 -0
  150. data.tar.gz.sig +0 -0
  151. metadata +233 -0
  152. metadata.gz.sig +0 -0
@@ -0,0 +1,37 @@
1
+ module Luoma
2
+ module Filters
3
+ # Return the absolute value of `left`.
4
+ def self.abs: (FilterContext context, untyped left) -> untyped
5
+
6
+ # Return the maximum of `left` and `right`.
7
+ def self.at_least: (FilterContext context, untyped left, untyped right) -> untyped
8
+
9
+ # Return the minimum of `left` and `right`.
10
+ def self.at_most: (FilterContext context, untyped left, untyped right) -> untyped
11
+
12
+ # Return `left` rounded up to the next whole number.
13
+ def self.ceil: (FilterContext context, untyped left) -> untyped
14
+
15
+ # Return the result of dividing `left` by `right`.
16
+ # If both `left` and `right` are integers, integer division is performed.
17
+ def self.divided_by: (FilterContext context, untyped left, untyped right) -> untyped
18
+
19
+ # Return the result of multiplying `left` by `right`.
20
+ def self.times: (FilterContext context, untyped left, untyped right) -> untyped
21
+
22
+ # Return `left` rounded down to the next whole number.
23
+ def self.floor: (FilterContext context, untyped left) -> untyped
24
+
25
+ # Return `right` subtracted from `left`.
26
+ def self.minus: (FilterContext context, untyped left, untyped right) -> untyped
27
+
28
+ # Return the remainder of dividing `left` by `right`.
29
+ def self.modulo: (FilterContext context, untyped left, untyped right) -> untyped
30
+
31
+ # Return `right` added to `left`.
32
+ def self.plus: (FilterContext context, untyped left, untyped right) -> untyped
33
+
34
+ # Return `left` rounded to `ndigits` decimal digits.
35
+ def self.round: (FilterContext context, untyped left, ?::Integer ndigits) -> untyped
36
+ end
37
+ end
@@ -0,0 +1,6 @@
1
+ module Luoma
2
+ module Filters
3
+ # Return the size of _left_, or zero if _left_ has no size.
4
+ def self.size: (FilterContext context, untyped left) -> Integer
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ module Luoma
2
+ module Filters
3
+ def self.slice: (
4
+ FilterContext context,
5
+ untyped left,
6
+ ?untyped start_, ?untyped stop_, ?untyped step_,
7
+ ?start: untyped, ?stop: untyped, ?step: untyped
8
+ ) -> Array[untyped]
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ module Luoma
2
+ module Filters
3
+ INFINITY_ARRAY: ::Array[untyped]
4
+
5
+ def self.sort: (FilterContext context, untyped left, ?untyped? key) -> untyped
6
+
7
+ def self.sort_natural: (FilterContext context, untyped left, ?untyped? key) -> untyped
8
+
9
+ def self.sort_numeric: (FilterContext context, untyped left, ?untyped? key) -> untyped
10
+
11
+ def self.nil_safe_casecmp: (untyped left, untyped right) -> (untyped | 0 | 1 | -1)
12
+
13
+ def self.numeric_compare: (untyped left, untyped right, FilterContext context) -> untyped
14
+
15
+ def self.ints: (untyped obj, FilterContext context) -> (::Array[untyped] | untyped)
16
+ end
17
+ end
@@ -0,0 +1,103 @@
1
+ module Luoma
2
+ module Filters
3
+ # Return _left_ concatenated with _right_.
4
+ # Coerce _left_ and _right_ to strings if they aren't strings already.
5
+ def self.append: (FilterContext context, untyped left, untyped right) -> untyped
6
+
7
+ # Return _left_ with the first character in uppercase and the rest lowercase.
8
+ # Coerce _left_ to a string if it is not one already.
9
+ def self.capitalize: (FilterContext context, untyped left) -> untyped
10
+
11
+ # Return _left_ with all characters converted to lowercase.
12
+ # Coerce _left_ to a string if it is not one already.
13
+ def self.downcase: (FilterContext context, untyped left) -> untyped
14
+
15
+ # Return _left_ with all characters converted to uppercase.
16
+ # Coerce _left_ to a string if it is not one already.
17
+ def self.upcase: (FilterContext context, untyped left) -> untyped
18
+
19
+ # Return _left_ with special HTML characters replaced with their HTML-safe escape sequences.
20
+ # Coerce _left_ to a string if it is not one already.
21
+ def self.escape: (FilterContext context, untyped left) -> (untyped | nil)
22
+
23
+ # Return _left_ with special HTML characters replaced with their HTML-safe escape sequences.
24
+ # Coerce _left_ to a string if it is not one already.
25
+ #
26
+ # It is safe to use `escape_once` on string values that already contain HTML-escape sequences.
27
+ def self.escape_once: (FilterContext context, untyped left) -> untyped
28
+
29
+ # Return _left_ with leading whitespace removed.
30
+ # Coerce _left_ to a string if it is not one already.
31
+ def self.lstrip: (FilterContext context, untyped left) -> untyped
32
+
33
+ # Return _left_ with trailing whitespace removed.
34
+ # Coerce _left_ to a string if it is not one already.
35
+ def self.rstrip: (FilterContext context, untyped left) -> untyped
36
+
37
+ # Return _left_ with leading and trailing whitespace removed.
38
+ # Coerce _left_ to a string if it is not one already.
39
+ def self.strip: (FilterContext context, untyped left) -> untyped
40
+
41
+ # Return _left_ with LF or CRLF replaced with `<br />\n`.
42
+ def self.newline_to_br: (FilterContext context, untyped left) -> untyped
43
+
44
+ # Return _right_ concatenated with _left_.
45
+ # Coerce _left_ and _right_ to strings if they aren't strings already.
46
+ def self.prepend_: (FilterContext context, untyped left, untyped right) -> untyped
47
+
48
+ # Return _left_ with all occurrences of _pattern_ replaced with _replacement_.
49
+ # All arguments are coerced to strings if they aren't strings already.
50
+ def self.replace: (FilterContext context, untyped left, untyped pattern, ?::String replacement) -> untyped
51
+
52
+ # Return _left_ with the first occurrence of _pattern_ replaced with _replacement_.
53
+ # All arguments are coerced to strings if they aren't strings already.
54
+ def self.replace_first: (FilterContext context, untyped left, untyped pattern, ?::String replacement) -> untyped
55
+
56
+ # Return _left_ with the last occurrence of _pattern_ replaced with _replacement_.
57
+ # All arguments are coerced to strings if they aren't strings already.
58
+ def self.replace_last: (FilterContext context, untyped left, untyped pattern, untyped replacement) -> untyped
59
+
60
+ # Return _left_ with all occurrences of _pattern_ removed.
61
+ # All arguments are coerced to strings if they aren't strings already.
62
+ def self.remove: (FilterContext context, untyped left, untyped pattern) -> untyped
63
+
64
+ # Return _left_ with the first occurrence of _pattern_ removed.
65
+ # All arguments are coerced to strings if they aren't strings already.
66
+ def self.remove_first: (FilterContext context, untyped left, untyped pattern) -> untyped
67
+
68
+ # Return _left_ with the last occurrence of _pattern_ removed.
69
+ # All arguments are coerced to strings if they aren't strings already.
70
+ def self.remove_last: (FilterContext context, untyped left, untyped pattern) -> untyped
71
+
72
+ # Split _left_ on every occurrence of _pattern_.
73
+ def self.split: (FilterContext context, untyped left, untyped pattern) -> untyped
74
+
75
+ RE_HTML_BLOCKS: ::Regexp
76
+
77
+ RE_HTML_TAGS: ::Regexp
78
+
79
+ # Return _left_ with HTML tags removed.
80
+ def self.strip_html: (FilterContext context, untyped left) -> untyped
81
+
82
+ # Return _left_ with CR and LF removed.
83
+ def self.strip_newlines: (FilterContext context, untyped left) -> untyped
84
+
85
+ def self.truncate: (FilterContext context, untyped left, ?::Integer max_length, ?::String ellipsis) -> untyped
86
+
87
+ def self.truncatewords: (FilterContext context, untyped left, ?::Integer max_words, ?::String ellipsis) -> untyped
88
+
89
+ def self.url_encode: (FilterContext context, untyped left) -> untyped
90
+
91
+ def self.url_decode: (FilterContext context, untyped left) -> untyped
92
+
93
+ def self.base64_encode: (FilterContext context, untyped left) -> untyped
94
+
95
+ def self.base64_decode: (FilterContext context, untyped left) -> untyped
96
+
97
+ def self.base64_url_safe_encode: (FilterContext context, untyped left) -> untyped
98
+
99
+ def self.base64_url_safe_decode: (FilterContext context, untyped left) -> untyped
100
+
101
+ def self.squish: (FilterContext context, untyped left) -> untyped
102
+ end
103
+ end
data/sig/luoma/fnv.rbs ADDED
@@ -0,0 +1,3 @@
1
+ module Luoma
2
+ def self.fnv1a32: (String s) -> Integer
3
+ end
@@ -0,0 +1,42 @@
1
+ module Luoma
2
+ class BaseLexer
3
+ @env: Environment
4
+
5
+ @source: String
6
+
7
+ @scanner: StringScanner
8
+
9
+ @start: Integer
10
+
11
+ @tokens: Array[t_token]
12
+
13
+ attr_reader tokens: Array[t_token]
14
+
15
+ def self.tokenize: (Environment env, String source) -> Array[t_token]
16
+
17
+ def initialize: (Environment env, String source) -> void
18
+
19
+ def go: () -> void
20
+
21
+ # () -> Symbol?
22
+ def scan_markup: () -> Symbol?
23
+
24
+ # (t_token_kind) -> void
25
+ def emit: (t_token_kind kind) -> void
26
+
27
+ # (Regexp) -> Integer?
28
+ def index: (Regexp pattern) -> Integer?
29
+
30
+ # (Regexp) -> String?
31
+ def scan: (Regexp pattern) -> String?
32
+
33
+ # (Regexp) -> bool
34
+ def scan_until?: (Regexp pattern) -> bool
35
+
36
+ # (Regexp) -> bool
37
+ def skip?: (Regexp pattern) -> bool
38
+
39
+ # (Regexp) -> bool
40
+ def skip_until?: (Regexp pattern) -> bool
41
+ end
42
+ end
@@ -0,0 +1,81 @@
1
+ module Luoma
2
+ # A single-pass template tokenizer that matches Shopify/liquid v5.12.0 strict
3
+ # mode syntax and semantics.
4
+ #
5
+ # We use lookahead and byte offset limits to achieve behavior equivalent to
6
+ # Shopify's two-pass tokenizer/parser.
7
+ class LegacyLexer < BaseLexer
8
+ RE_MARKUP: ::Regexp
9
+
10
+ RE_OUT_END: ::Regexp
11
+
12
+ RE_UP_TO_OUT_END: ::Regexp
13
+
14
+ RE_TAG_END: ::Regexp
15
+
16
+ RE_UP_TO_TAG_END: ::Regexp
17
+
18
+ RE_TRIVIA: ::Regexp
19
+
20
+ RE_LINE_TRIVIA: ::Regexp
21
+
22
+ RE_TAG_NAME: ::Regexp
23
+
24
+ RE_PUNCTUATION: ::Regexp
25
+
26
+ RE_IDENT: ::Regexp
27
+
28
+ RE_FLOAT: ::Regexp
29
+
30
+ RE_INT: ::Regexp
31
+
32
+ RE_COMMENT_SEGMENT: ::Regexp
33
+
34
+ RE_LINE_COMMENT_SEGMENT: ::Regexp
35
+
36
+ RE_END_DOC: ::Regexp
37
+
38
+ RE_END_RAW: ::Regexp
39
+
40
+ TOKEN_MAP: Hash[String, t_token_kind]
41
+
42
+ # () -> Symbol?
43
+ def scan_markup: () -> Symbol?
44
+
45
+ # (Integer) -> void
46
+ def accept_tag: (Integer limit) -> void
47
+
48
+ # (Integer) -> void
49
+ def accept_expression: (Integer limit , ?Regexp trivia) -> void
50
+
51
+ # (Integer) -> void
52
+ def accept_inline_comment: (Integer limit) -> void
53
+
54
+ # (Integer) -> void
55
+ def accept_block_comment: (Integer limit) -> void
56
+
57
+ # (Integer) -> void
58
+ def accept_doc_comment: (Integer limit) -> void
59
+
60
+ # (Integer) -> void
61
+ def accept_raw_tag: (Integer limit) -> void
62
+
63
+ # (Integer) -> void
64
+ def accept_line_statements: (Integer limit) -> void
65
+
66
+ # (Integer) -> void
67
+ def accept_line_block_comment: (Integer limit) -> void
68
+
69
+ # (Integer) -> void
70
+ def accept_line_doc_comment: (Integer limit) -> void
71
+
72
+ # (Integer) -> void
73
+ def accept_line_raw_tag: (Integer limit) -> void
74
+
75
+ # (Integer) -> void
76
+ def accept_string_literal: (Integer limit) -> void
77
+
78
+ # () -> bool
79
+ def accept_whitespace_control?: () -> bool
80
+ end
81
+ end
@@ -0,0 +1,49 @@
1
+ module Luoma
2
+ class UnifiedLexer < BaseLexer
3
+ RE_FLOAT: ::Regexp
4
+
5
+ RE_INT: ::Regexp
6
+
7
+ RE_MARKUP_START: ::Regexp
8
+
9
+ RE_OUTPUT_END: ::Regexp
10
+
11
+ RE_PUNCTUATION: ::Regexp
12
+
13
+ RE_RAW_END: ::Regexp
14
+
15
+ RE_TAG_END: ::Regexp
16
+
17
+ RE_TAG_NAME: ::Regexp
18
+
19
+ RE_TRIVIA: ::Regexp
20
+
21
+ RE_WHITESPACE_CONTROL: ::Regexp
22
+
23
+ RE_WORD: ::Regexp
24
+
25
+ RE_HASH_COUNT: Hash[Integer, Regexp]
26
+
27
+ # Keywords and symbols that get their own token kind.
28
+ TOKEN_MAP: Hash[String, t_token_kind]
29
+
30
+
31
+ # () -> void?
32
+ def accept_tag: () -> void
33
+
34
+ # () -> void
35
+ def accept_expression: () -> void
36
+
37
+ # () -> void
38
+ def accept_comment: () -> void
39
+
40
+ # () -> void
41
+ def accept_string: () -> void
42
+
43
+ # () -> void
44
+ def accept_object: () -> void
45
+
46
+ # () -> bool
47
+ def accept_whitespace_control?: () -> bool
48
+ end
49
+ end
@@ -0,0 +1,40 @@
1
+ module Luoma
2
+ # The base class for all template loaders.
3
+ class TemplateLoader
4
+ # Load and return template source text and any associated data.
5
+ # (Environment, String, ?context: RenderContext?, **untyped) -> TemplateSource
6
+ def get_source: (Environment env, String name, ?context: RenderContext?, **untyped kwargs) -> TemplateSource
7
+
8
+ # (Environment, String, ?globals: t_namespace?, ?context: RenderContext?, **kwargs) -> Template
9
+ def load: (Environment env, String name, ?globals: t_namespace?, ?context: RenderContext?, **untyped kwargs) -> Template
10
+ end
11
+
12
+ # Template source text and meta data.
13
+ class TemplateSource
14
+ @source: String
15
+
16
+ @name: String
17
+
18
+ @up_to_date: Proc::_Callable?
19
+
20
+ @matter: t_namespace?
21
+
22
+ attr_accessor source: String
23
+
24
+ attr_accessor name: String
25
+
26
+ attr_accessor up_to_date: Proc::_Callable?
27
+
28
+ attr_accessor matter: t_namespace?
29
+
30
+ def initialize: (source: String, name: String, ?up_to_date: Proc::_Callable?, ?matter: t_namespace?) -> void
31
+ end
32
+
33
+ # A template loader that reads templates from a hash.
34
+ class HashLoader < TemplateLoader
35
+ @templates: Hash[String, String]
36
+
37
+ #: (Hash<String, String>) -> void
38
+ def initialize: (Hash[String, String] templates) -> void
39
+ end
40
+ end
@@ -0,0 +1,9 @@
1
+ module Luoma
2
+ class ChoiceLoader < TemplateLoader
3
+ @loaders: Array[TemplateLoader]
4
+
5
+ def initialize: (*TemplateLoader loaders) -> void
6
+
7
+ def load: (Environment env, String name, **untyped) -> Template
8
+ end
9
+ end
@@ -0,0 +1,19 @@
1
+ module Luoma
2
+ # A template loader that reads template from a file system.
3
+ class FileSystemLoader < TemplateLoader
4
+ @search_path: Array[Pathname]
5
+
6
+ @default_extension: String?
7
+
8
+ def initialize: (String | Array[String] search_path, ?default_extension: String?) -> void
9
+
10
+ def resolve_path: (String template_name) -> Pathname
11
+ end
12
+
13
+ # A file system template loader that caches parsed templates.
14
+ class CachingFileSystemLoader < FileSystemLoader
15
+ include CachingLoaderMixin
16
+
17
+ def initialize: (String | Array[String] search_path, ?default_extension: String?, ?auto_reload: bool, ?namespace_key: ::String, ?capacity: ::Integer, ?thread_safe: bool) -> void
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ module Luoma
2
+ # A mixin that adds caching to a template loader.
3
+ module CachingLoaderMixin
4
+ @auto_reload: bool
5
+
6
+ @namespace_key: String?
7
+
8
+ @cache: LRUCache
9
+
10
+ def initialize_cache: (?auto_reload: bool, ?namespace_key: ::String, ?capacity: ::Integer, ?thread_safe: bool) -> untyped
11
+
12
+ def load: (Environment env, String name, ?globals: _Namespace?, ?context: RenderContext?, **untyped kwargs) -> Template
13
+
14
+ def cache_key: (String name, ?context: RenderContext?, **untyped kwargs) -> String
15
+ end
16
+ end
@@ -0,0 +1,68 @@
1
+ module Luoma
2
+ interface _Tag
3
+ def parse: (t_token, String, Parser) -> Markup
4
+ end
5
+
6
+ # The base class for all tag nodes and the output statement.
7
+ class Markup
8
+ @token: t_token
9
+
10
+ @blank: bool
11
+
12
+ @tag_name: String
13
+
14
+ attr_reader token: t_token
15
+
16
+ attr_reader blank: bool
17
+
18
+ attr_reader tag_name: String
19
+
20
+ # (t_token) -> void
21
+ def initialize: (t_token token) -> void
22
+
23
+ # (RenderContext, String) -> void
24
+ def render: (RenderContext context, String buffer) -> void
25
+
26
+ # (RenderContext) -> Array[Markup]
27
+ def children: (RenderContext static_context) -> ::Array[Markup]
28
+
29
+ # () -> Array[Expression]
30
+ def expressions: () -> ::Array[Expression]
31
+
32
+ # () -> Array[Name]
33
+ def block_scope: () -> ::Array[Name]
34
+
35
+ # () -> Array[Name]
36
+ def template_scope: () -> ::Array[Name]
37
+
38
+ # (RenderContext) -> Partial?
39
+ def partial: (RenderContext static_context) -> Partial?
40
+ end
41
+
42
+ class Partial
43
+ @template: Template
44
+
45
+ @scope_kind: (:shared | :isolated | :inherited)
46
+
47
+ @in_scope: Array[Name]
48
+
49
+ @key: Integer
50
+
51
+ attr_reader template: Template
52
+
53
+ attr_reader scope_kind: :shared | :isolated | :inherited
54
+
55
+ attr_reader in_scope: Array[Name]
56
+
57
+ attr_reader key: Integer
58
+
59
+ # (Template, :shared | :isolated | :inherited, Array[Name], Integer) -> void
60
+ def initialize: (Template template, :shared | :isolated | :inherited scope_kind, Array[Name] in_scope, Integer key) -> void
61
+ end
62
+
63
+ # (t_block, RenderContext, String) -> void
64
+ def self.render_block: (t_block block, RenderContext context, String buffer, ?root: bool) -> void
65
+
66
+ # (t_block) -> bool
67
+ def self.blank_block?: (t_block block) -> bool
68
+ end
@@ -0,0 +1,105 @@
1
+ module Luoma
2
+ class Parser
3
+ @env: Environment
4
+
5
+ @source: String
6
+
7
+ @template_name: String
8
+
9
+ @tokens: Array[t_token]
10
+
11
+ @pos: Integer
12
+
13
+ @eoi: t_token
14
+
15
+ @whitespace_control_carry: "-" | "+" | "~" | nil
16
+
17
+ TERMINATE_EXPRESSION: Set[t_token_kind]
18
+
19
+ attr_reader env: Environment
20
+
21
+ attr_reader source: String
22
+
23
+ attr_reader template_name: String
24
+
25
+ # (Environment, String, String, Array[t_token]) -> t_block
26
+ def self.parse: (Environment env, String source, String template_name, Array[t_token] tokens) -> t_block
27
+
28
+ # (Environment, String, String, Array[t_token]) -> void
29
+ def initialize: (Environment env, String source, String template_name, Array[t_token] tokens) -> void
30
+
31
+ # () -> void
32
+ def carry_whitespace_control: () -> void
33
+
34
+ # () -> t_token
35
+ def current: () -> t_token
36
+
37
+ # () -> t_token_kind
38
+ def kind: () -> t_token_kind
39
+
40
+ # () -> String
41
+ def current_value: () -> String
42
+
43
+ # () -> t_token
44
+ def next: () -> t_token
45
+
46
+ def peek: (?::Integer offset) -> t_token
47
+
48
+ # (t_token_kind, ?message: String?) -> t_token
49
+ def eat: (t_token_kind kind, ?message: String?) -> t_token
50
+
51
+ # (String) -> t_token
52
+ def eat_empty_tag: (String name) -> t_token
53
+
54
+ # (Set[t_token_kind]) -> t_token
55
+ def eat_one_of: (Set[t_token_kind] kinds) -> t_token
56
+
57
+ # (String) -> t_token
58
+ def eat_tag: (String name) -> t_token
59
+
60
+ # Raise an error if we're not at the start of an expression.
61
+ # () -> void
62
+ def expect_expression: () -> void
63
+
64
+ # (?require_commas: bool?) -> Array[Expression | KeywordArgument]
65
+ def parse_arguments: (?require_commas: bool?) -> Array[Expression | KeywordArgument]
66
+
67
+ # (?stop: Set[String]?) -> t_block
68
+ def parse_block: (?stop: Set[String]?) -> t_block
69
+
70
+ # (?precedence: Integer) -> Expression
71
+ def parse_expression: (?precedence: Integer) -> Expression
72
+
73
+ # () -> Name
74
+ def parse_ident: () -> Name
75
+
76
+ # (?require_commas: bool?) -> Array[KeywordArgument]
77
+ def parse_keyword_arguments: (?require_commas: bool?) -> Array[KeywordArgument]
78
+
79
+ # Parse an identifier, possibly surrounded by quotes.
80
+ # () -> Name
81
+ def parse_name: () -> Name
82
+
83
+ # (?require_commas: bool?) -> Array[Expression]
84
+ def parse_positional_arguments: (?require_commas: bool?) -> Array[Expression]
85
+
86
+ # () -> StringLiteral
87
+ def parse_string_literal: () -> StringLiteral
88
+
89
+ # () -> String
90
+ def peek_tag_name: () -> String
91
+
92
+ # () -> String?
93
+ def peek_whitespace_control: () -> String?
94
+
95
+ # () -> void
96
+ def skip_whitespace_control: () -> void
97
+
98
+ # Return `true` if we're at the start of a tag named `name`.
99
+ # (String) -> bool
100
+ def tag?: (String name) -> bool
101
+
102
+ # (Set[String]) -> String?
103
+ def tags: (Set[String] names) -> String?
104
+ end
105
+ end