asciisourcerer 0.5.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 862206bd89bcd6930165344b8623239c8220f5d598f12d3050508b8386432546
4
- data.tar.gz: 6b95b84ae0f56421fc10b75a440cf4beaa29c24d7c3f7be50f9c168b3e4b9a63
3
+ metadata.gz: 7b6d7c78acf65b0a4c2b7aef397ea65a254fc486cc616a5977794cdd51eb67f2
4
+ data.tar.gz: 66de4e674a882d87dc919aa2eab680a10cd9fae2d8df5033b32f6b79d27b9a61
5
5
  SHA512:
6
- metadata.gz: a6ef512103f8978b1fe583a7e55061d94cade1f783cffb43bb68044d154a7c438f7a9e2a2e55a9a0ad499304881c30f375eb6b666f12e5d7d1ce56dc3401d49a
7
- data.tar.gz: 6101084fa33316a51458b08878a17b956dbb93558fe7acdd6f95675167daa2d7f8ee29e76943123b18889a54780914a6cc95fcef0ee7aee628daf0d201b0f550
6
+ metadata.gz: 86e2ef0fc8684ab20d29832f1a78d4d8171bd5f4a2de36659ae4cb96ddde8f37f42e35ed446afe466245e0ee4bbe596a9095549cf0f864fbea0ff86de588e54f
7
+ data.tar.gz: 3fc489d1777101bfbb178cbca588e0988828aa682fe4a763a9efd9cf4775cf2fe9bf7f1e887d0fba6c9a149353fa266747b44f30a4fad4a19791501c64e906e0
data/README.adoc CHANGED
@@ -37,11 +37,11 @@ endif::[]
37
37
  :this_prod_name: {this_proj_name}
38
38
  // end::universal-settings[]
39
39
  :this_prod_vrsn_major: 0
40
- :this_prod_vrsn_minor: 5
40
+ :this_prod_vrsn_minor: 6
41
41
  :this_prod_vrsn_majmin: {this_prod_vrsn_major}.{this_prod_vrsn_minor}
42
42
  :this_prod_vrsn_patch: 0
43
43
  :this_prod_vrsn: {this_prod_vrsn_majmin}.{this_prod_vrsn_patch}
44
- :next_prod_vrsn: 0.6.0
44
+ :next_prod_vrsn: 0.7.0
45
45
  // end::global-settings[]
46
46
  // end::ai-prompt[]
47
47
  :toc: macro
@@ -823,7 +823,9 @@ Avoid exporting helper methods as accidental public API.
823
823
  === Generated Reference Docs
824
824
 
825
825
  Some reference documentation is generated from data rather than hand-written, so it can't drift from what the code actually does.
826
- `specs/data/docs-manifest.yml` lists each generation job: a Liquid (or ERB) template, a YAML data source, an output path, and optional `vars` to parameterize a shared template into multiple outputs.
826
+ A manifest (`specs/data/docs-manifest.yml`) lists each generation job: a Liquid template, a YAML data source, an output path, and optional `vars` to parameterize a shared template into multiple outputs.
827
+ Each entry also accepts the Liquid-only `preserve_missing` and `preserve_empty` booleans (both default `false`), forwarded straight through to `Sourcerer::Rendering.render_template`.
828
+ See the API docs on `Sourcerer::Rendering.render_template` for exactly what each one preserves.
827
829
 
828
830
  For example, `specs/data/liquid-filters.yml` (the same source of truth used by the Liquid filter test suite; see <<tests>>) is rendered through `docs/templates/liquid-filters-ref.adoc.liquid` twice -- once grouped by filter category, once by filter source -- producing the partials committed at `lib/sourcerer/_docs/partials/liquid-filters-by-kind.adoc` and `liquid-filters-by-source.adoc`.
829
831
  These partials ship with the gem so downstream tools can `include::` them directly.
@@ -833,6 +835,15 @@ Regenerate all manifest entries with:
833
835
  [.prompt]
834
836
  bundle exec rake generate:docs
835
837
 
838
+ These same partials are also published to the `documentation` branch, under `partials/`.
839
+ That branch holds only generated output (no source code) so it can be pulled directly (ex: via raw.githubusercontent.com) by consumers who don't install the gem.
840
+ Regenerate and locally commit an update to that branch with:
841
+
842
+ [.prompt]
843
+ bundle exec rake generate:documentation
844
+
845
+ This only commits locally; push with `git push -f origin documentation` after reviewing the result.
846
+
836
847
  [[tests]]
837
848
  === Tests
838
849
 
@@ -857,19 +868,28 @@ Run the PR/CI test suite:
857
868
  === Release Process and History
858
869
 
859
870
  AsciiSourcerer is intended to be the most primal gem in the DocOps Lab pool.
860
- As such, its development is less formal.
871
+ As such, its release procedure is lighter and less formal.
861
872
 
862
- Each release is tested against all downstream gems and tools, but we are somewhat less formal about issue tracking and development branch management, at least in early stages.
873
+ Each release is tested against all downstream gems and tools, but we are less concerned with issue tracking and development branch management, at least in these early stages.
863
874
 
864
- Standard release flow:
875
+ Standard release flow differs from the general DocOps Lab conventions.
865
876
 
866
877
  . Update version in `lib/sourcerer/version.rb` and `README.adoc` attributes.
867
878
 
879
+ . Test all changes using local clones of the latest released versions of these downstream gems:
880
+
881
+ * link:{docopslab_src_www_url}/schemagraphy[DocOps/schemagraphy]
882
+ * link:{docopslab_src_www_url}/lab[DocOps/lab]
883
+ * link:{docopslab_src_www_url}/releasehx[DocOps/releasehx]
884
+
868
885
  . Commit to Git.
869
886
 
870
887
  . Push to GitHub.
871
888
 
872
- . Run `./scripts/build.sh` to validate the environment, run tests, and build the gem file to `pkg/`.
889
+ . Run `./scripts/build.sh` to:
890
+ .. validate the environment
891
+ .. run tests, and
892
+ .. build the gem file to `pkg/`
873
893
 
874
894
  . Tag the release in Git:
875
895
  +
@@ -37,7 +37,7 @@ module Sourcerer
37
37
  # @param includes_load_paths [Array<String>] Paths to load includes from.
38
38
  # @param plugin_dirs [Array<String>] Paths to load plugins from.
39
39
  # @return [Jekyll::Site] The initialized fake Jekyll site object.
40
- # rubocop:disable Lint/UnusedMethodArgument
40
+ # rubocop:disable-next Lint/UnusedMethodArgument
41
41
  def self.fake_site includes_load_paths: [], plugin_dirs: []
42
42
  # NOTE: plugin_dirs parameter is accepted but not yet implemented; reserved for future plugin loading
43
43
  ::Jekyll.logger.log_level = :error if ::Jekyll.logger.respond_to?(:log_level=)
@@ -72,7 +72,6 @@ module Sourcerer
72
72
 
73
73
  site
74
74
  end
75
- # rubocop:enable Lint/UnusedMethodArgument
76
75
  end
77
76
  end
78
77
  end
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'liquid'
4
+
5
+ module Sourcerer
6
+ module Jekyll
7
+ module Liquid
8
+ # Opt-in alternative to Liquid's default "render nil/empty as empty
9
+ # string" behavior: when active, a `{{ ... }}` expression that
10
+ # evaluates to a missing or empty value renders as its own original
11
+ # source text (e.g. `{{ data.foo | capitalize }}`) instead of
12
+ # vanishing. Useful for document templates where an unfilled field
13
+ # should stay visible for the preparer to fill in by hand, rather
14
+ # than silently disappearing.
15
+ #
16
+ # Two independent toggles, each off by default:
17
+ #
18
+ # - `preserve_missing`: an outright `nil` result is preserved.
19
+ # - `preserve_empty`: a defined-but-empty String/Array/Hash result
20
+ # (`""`, `[]`, `{}`) is preserved.
21
+ #
22
+ # Neither affects the other's target, and neither affects `0` or
23
+ # `false`. Both checks run against the fully-filtered result (i.e.
24
+ # any `| filters` in the tag have already run), matching what Liquid
25
+ # itself would otherwise render -- we never re-run the filters, we
26
+ # just restore the tag's own pre-render source text once a render
27
+ # has been judged missing/empty. `raw` is used verbatim (no
28
+ # whitespace trimming), so the reconstructed tag matches the
29
+ # original byte-for-byte -- except for `{{-`/`-}}` whitespace
30
+ # control markers, which Liquid's tokenizer strips before the
31
+ # markup ever reaches a `Variable` instance and so cannot be
32
+ # recovered here.
33
+ #
34
+ # Substitution only ever applies to a *top-level output* `{{ }}`
35
+ # tag -- never to a `Liquid::Variable` some other tag builds
36
+ # privately to parse its own syntax. `Assign`, for example, does
37
+ # exactly that (`lib/liquid/tags/assign.rb`: `@from = Variable.new(
38
+ # $2, options)`, then `@from.render(context)` directly), and that
39
+ # Variable's `#render` is the same patched method, with the same
40
+ # global toggle active. Without this distinction,
41
+ # `{% assign name = data.missing %}` under `preserve_missing: true`
42
+ # would assign the *reconstructed source text of the assign's own
43
+ # right-hand side* (a String) to `name`, rather than the real `nil`
44
+ # -- corrupting every later `{{ name }}` reference instead of
45
+ # leaving it to render its own clean placeholder. `BlockBodyPatch`
46
+ # below marks the one call site (`BlockBody#render_node_to_output`,
47
+ # when the node being rendered is itself a `Variable`) that
48
+ # corresponds to a literal `{{ }}` sitting directly in a template
49
+ # body's nodelist -- the only place a Variable's rendered text
50
+ # actually becomes document output. Any other tag's internal use of
51
+ # a Variable to compute a value (Assign's right-hand side, or
52
+ # anything similar) renders outside that marker and is left with
53
+ # Liquid's normal nil/empty behavior, exactly as if this feature
54
+ # were off.
55
+ #
56
+ # Liquid 4 has no built-in hook for this -- there is no Environment or
57
+ # parser-injection point (introduced only in Liquid 5) to substitute a
58
+ # custom Variable class per template -- so this prepends onto
59
+ # `::Liquid::Variable` globally and gates the actual behavior change
60
+ # with toggles scoped to one render call. See
61
+ # `Sourcerer::Rendering.render_template`'s `preserve_missing:`/
62
+ # `preserve_empty:` options, which flip these toggles for the
63
+ # duration of that one render.
64
+ module PreserveMissingVariables
65
+ def self.preserve_missing?
66
+ Thread.current[:sourcerer_preserve_missing] == true
67
+ end
68
+
69
+ def self.preserve_empty?
70
+ Thread.current[:sourcerer_preserve_empty] == true
71
+ end
72
+
73
+ def self.top_level_output?
74
+ Thread.current[:sourcerer_rendering_output_variable] == true
75
+ end
76
+
77
+ # Activates preserve-missing/-empty rendering for the duration of
78
+ # the block. Restores the prior values afterward so nested/
79
+ # sequential renders that don't ask for it are unaffected.
80
+ #
81
+ # @param preserve_missing [Boolean] See {PreserveMissingVariables}.
82
+ # @param preserve_empty [Boolean] See {PreserveMissingVariables}.
83
+ def self.with_active preserve_missing: false, preserve_empty: false
84
+ previous_missing = Thread.current[:sourcerer_preserve_missing]
85
+ previous_empty = Thread.current[:sourcerer_preserve_empty]
86
+ Thread.current[:sourcerer_preserve_missing] = preserve_missing
87
+ Thread.current[:sourcerer_preserve_empty] = preserve_empty
88
+ yield
89
+ ensure
90
+ Thread.current[:sourcerer_preserve_missing] = previous_missing
91
+ Thread.current[:sourcerer_preserve_empty] = previous_empty
92
+ end
93
+
94
+ # Prepended onto ::Liquid::Variable. Falls through to Liquid's own
95
+ # `render` untouched unless: this Variable is currently being
96
+ # rendered as a top-level output node (see `BlockBodyPatch`
97
+ # below), preserve-missing/-empty is active for this thread, and
98
+ # the fully-filtered result counts as missing (nil) or empty (a
99
+ # defined-but-empty String/Array/Hash).
100
+ module VariablePatch
101
+ def render context
102
+ result = super
103
+ return result unless PreserveMissingVariables.top_level_output?
104
+ return "{{#{raw}}}" if PreserveMissingVariables.preserve_missing? && result.nil?
105
+ return "{{#{raw}}}" if PreserveMissingVariables.preserve_empty? && empty_result?(result)
106
+
107
+ result
108
+ end
109
+
110
+ private
111
+
112
+ # Only the documented value types count as "empty" -- not any
113
+ # arbitrary object/Drop that happens to implement `empty?` with
114
+ # its own, possibly unrelated, meaning.
115
+ def empty_result? value
116
+ (value.is_a?(String) || value.is_a?(Array) || value.is_a?(Hash)) && value.empty?
117
+ end
118
+ end
119
+
120
+ # Prepended onto ::Liquid::BlockBody. `render_node_to_output` is
121
+ # the one call site where a node from a body's own nodelist --
122
+ # i.e. a literal `{{ }}` or `{% tag %}` written directly in
123
+ # template source -- gets rendered and appended to output. We
124
+ # only care about the `Variable` case: that's a genuine top-level
125
+ # `{{ }}` output tag, as opposed to a `Variable` some other tag
126
+ # (Assign, etc.) builds privately and renders itself, bypassing
127
+ # BlockBody entirely. See {PreserveMissingVariables} above for why
128
+ # this distinction matters.
129
+ module BlockBodyPatch
130
+ # rubocop:disable-next Style/OptionalBooleanParameter -- must match
131
+ # ::Liquid::BlockBody#render_node_to_output's own positional signature
132
+ def render_node_to_output node, output, context, skip_output = false
133
+ return super unless node.is_a?(::Liquid::Variable)
134
+
135
+ previous = Thread.current[:sourcerer_rendering_output_variable]
136
+ Thread.current[:sourcerer_rendering_output_variable] = true
137
+ super
138
+ ensure
139
+ Thread.current[:sourcerer_rendering_output_variable] = previous if node.is_a?(::Liquid::Variable)
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
146
+
147
+ Liquid::Variable.prepend(Sourcerer::Jekyll::Liquid::PreserveMissingVariables::VariablePatch)
148
+ Liquid::BlockBody.prepend(Sourcerer::Jekyll::Liquid::PreserveMissingVariables::BlockBodyPatch)
@@ -8,12 +8,25 @@ module Sourcerer
8
8
  # A Liquid tag for embedding and rendering a file within a template.
9
9
  # It searches for the file in the configured include paths.
10
10
  class EmbedTag < ::Liquid::Tag
11
+ # Matches an optional single- or double-quoted string, capturing the
12
+ # inner content; falls back to the whole (trimmed) markup as a bareword.
13
+ # Requires at least one character inside the quotes: an empty quoted
14
+ # name (`""`/`''`) would otherwise expand to the includes directory
15
+ # itself, pass File.exist?, and raise Errno::EISDIR from File.read
16
+ # instead of the intended missing-file error. Left unmatched, it
17
+ # falls through to the bareword branch instead, where the literal
18
+ # (quoted) name is looked up and not found -- reported normally.
19
+ PARTIAL_NAME_PATTERN = /\A(?:"([^"]+)"|'([^']+)')\z/
20
+
11
21
  # @param tag_name [String] The name of the tag ('embed').
12
- # @param markup [String] The name of the partial to embed.
22
+ # @param markup [String] The name of the partial to embed, quoted
23
+ # (+"foo.liquid"+ / +'foo.liquid'+) or bareword (+foo.liquid+).
13
24
  # @param tokens [Array<String>] The list of tokens.
14
25
  def initialize tag_name, markup, tokens
15
26
  super
16
- @partial_name = markup.strip
27
+ trimmed = markup.strip
28
+ match = trimmed.match(PARTIAL_NAME_PATTERN)
29
+ @partial_name = match ? (match[1] || match[2]) : trimmed
17
30
  end
18
31
 
19
32
  # Renders the embedded file.
@@ -22,7 +35,9 @@ module Sourcerer
22
35
  # @return [String] The rendered content of the embedded file.
23
36
  # @raise [IOError] if the embed file is not found.
24
37
  def render context
25
- includes_paths = context.registers[:includes_load_paths] || []
38
+ includes_paths = context.registers[:includes_load_paths]
39
+ includes_paths = site_includes_load_paths(context) if includes_paths.nil? || includes_paths.empty?
40
+ includes_paths ||= []
26
41
 
27
42
  found_path = includes_paths.find do |base|
28
43
  candidate = File.expand_path(@partial_name, base)
@@ -37,6 +52,19 @@ module Sourcerer
37
52
  partial = ::Liquid::Template.parse(source)
38
53
  partial.render!(context)
39
54
  end
55
+
56
+ private
57
+
58
+ # Fallback for callers that register a fake/real Jekyll +:site+ but
59
+ # forget the separate +:includes_load_paths+ register (e.g. any
60
+ # future caller mirroring {Sourcerer::Rendering.render_liquid}).
61
+ # Reads +site.config['includes_load_paths']+ directly rather than
62
+ # +site.includes_load_paths+: the latter is Jekyll's own attribute,
63
+ # derived only from +config['includes_dir']+ (effectively just the
64
+ # first path), not the full list Sourcerer stores in config.
65
+ def site_includes_load_paths context
66
+ context.registers[:site]&.config&.[]('includes_load_paths')
67
+ end
40
68
  end
41
69
  end
42
70
  end
@@ -5,6 +5,7 @@ require_relative 'jekyll/monkeypatches'
5
5
  require_relative 'jekyll/liquid/file_system'
6
6
  require_relative 'jekyll/liquid/filters'
7
7
  require_relative 'jekyll/liquid/tags'
8
+ require_relative 'jekyll/liquid/preserve_missing_variables'
8
9
  require 'jekyll-asciidoc'
9
10
 
10
11
  module Sourcerer
@@ -37,7 +37,9 @@ module Sourcerer
37
37
  data_object: data_obj,
38
38
  attrs_source: attrs_source,
39
39
  engine: engine,
40
- vars: render_entry[:vars] || {})
40
+ vars: render_entry[:vars] || {},
41
+ preserve_missing: render_entry[:preserve_missing] || false,
42
+ preserve_empty: render_entry[:preserve_empty] || false)
41
43
  end
42
44
  end
43
45
 
@@ -53,39 +55,53 @@ module Sourcerer
53
55
  # @param vars [Hash] Arbitrary caller-supplied variables, exposed to the
54
56
  # template as `vars` (e.g. to parameterize a shared template between
55
57
  # multiple render entries in a manifest).
58
+ # @param preserve_missing [Boolean] Liquid-only, independent of
59
+ # `preserve_empty`. When true, a `{{ ... }}` expression that evaluates
60
+ # to nil renders as its own original source text instead of an empty
61
+ # string, so an unfilled field stays visible for manual completion
62
+ # rather than silently disappearing. Has no effect on a defined
63
+ # empty value (`""`, `[]`, `{}`).
64
+ # @param preserve_empty [Boolean] Liquid-only, independent of
65
+ # `preserve_missing`. When true, a `{{ ... }}` expression that
66
+ # evaluates to a defined-but-empty String/Array/Hash (`""`, `[]`,
67
+ # `{}`) is preserved as its own original source text the same way.
68
+ # Has no effect on nil. `0` and `false` are never affected by either
69
+ # option.
56
70
  def self.render_template template_file, data_file, out_file, **options
57
- supported_option_keys = %i[data_object includes_load_paths attrs_source engine vars]
71
+ supported_option_keys = %i[data_object includes_load_paths attrs_source engine vars
72
+ preserve_missing preserve_empty]
58
73
  unknown_option_keys = options.keys - supported_option_keys
59
74
  raise ArgumentError, "unknown option(s): #{unknown_option_keys.join(', ')}" unless unknown_option_keys.empty?
60
75
 
61
76
  data_object = options.fetch(:data_object, 'data')
62
- includes_load_paths = options.fetch(:includes_load_paths, [])
63
- attrs_source = options[:attrs_source]
64
- engine = options.fetch(:engine, 'liquid')
77
+ data = load_render_data(data_file, options[:attrs_source])
65
78
  vars = (options[:vars] || {}).transform_keys(&:to_s)
79
+ context = { data_object => data, 'include' => { data_object => data }, 'vars' => vars }
80
+
81
+ preserve = { missing: options.fetch(:preserve_missing, false), empty: options.fetch(:preserve_empty, false) }
82
+ rendered = render_in_engine(
83
+ options.fetch(:engine, 'liquid'), template_file, context, options.fetch(:includes_load_paths, []), preserve)
66
84
 
67
- data = load_render_data(data_file, attrs_source)
68
85
  out_file = File.expand_path(out_file)
69
86
  FileUtils.mkdir_p(File.dirname(out_file))
70
-
71
- template_path = File.expand_path(template_file)
72
- template_content = File.read(template_path)
73
-
74
- context = {
75
- data_object => data,
76
- 'include' => { data_object => data },
77
- 'vars' => vars
78
- }
79
-
80
- rendered = case engine.to_s
81
- when 'erb' then render_erb(template_content, context)
82
- when 'liquid' then render_liquid(template_file, template_content, context, includes_load_paths)
83
- else raise ArgumentError, "Unsupported template engine: #{engine}"
84
- end
85
-
86
87
  File.write(out_file, rendered)
87
88
  end
88
89
 
90
+ # @api private
91
+ # Dispatches rendering to the requested template engine.
92
+ #
93
+ # @param preserve [Hash] `{missing:, empty:}` -- see {.render_template}'s
94
+ # `preserve_missing`/`preserve_empty` options.
95
+ # @return [String]
96
+ def self.render_in_engine engine, template_file, context, includes_load_paths, preserve
97
+ template_content = File.read(File.expand_path(template_file))
98
+ case engine.to_s
99
+ when 'erb' then render_erb(template_content, context)
100
+ when 'liquid' then render_liquid(template_file, template_content, context, includes_load_paths, preserve)
101
+ else raise ArgumentError, "Unsupported template engine: #{engine}"
102
+ end
103
+ end
104
+
89
105
  # Renders output using a converter callable or converter constant name.
90
106
  #
91
107
  # @param render_entry [Hash] Render entry containing converter config.
@@ -151,38 +167,43 @@ module Sourcerer
151
167
  # @param template_content [String]
152
168
  # @param context [Hash]
153
169
  # @param includes_load_paths [Array<String>]
170
+ # @param preserve [Hash] `{missing:, empty:}` -- see {.render_template}'s
171
+ # `preserve_missing`/`preserve_empty` options.
154
172
  # @return [String]
155
- def self.render_liquid template_file, template_content, context, includes_load_paths
173
+ def self.render_liquid template_file, template_content, context, includes_load_paths, preserve
156
174
  require_relative 'jekyll'
157
175
  require_relative 'jekyll/liquid/filters'
158
176
  require_relative 'jekyll/liquid/tags'
177
+ require_relative 'jekyll/liquid/preserve_missing_variables'
159
178
  require 'liquid' unless defined?(Liquid::Template)
160
179
  Sourcerer::Jekyll.initialize_liquid_runtime
161
180
 
181
+ registers = liquid_registers(template_file, includes_load_paths)
182
+ template = Liquid::Template.parse(template_content)
183
+ render = -> { template.render(context, registers: registers) }
184
+
185
+ return render.call unless preserve[:missing] || preserve[:empty]
186
+
187
+ Sourcerer::Jekyll::Liquid::PreserveMissingVariables.with_active(
188
+ preserve_missing: preserve[:missing], preserve_empty: preserve[:empty], &render)
189
+ end
190
+
191
+ # @api private
192
+ # Builds the Liquid registers hash (fake site + file system) a template
193
+ # render needs to resolve `{% embed %}`/include partials.
194
+ #
195
+ # @return [Hash]
196
+ def self.liquid_registers template_file, includes_load_paths
162
197
  fallback_templates_dir = File.expand_path('.', Dir.pwd)
163
198
  template_dir = File.dirname(File.expand_path(template_file))
164
199
  template_parent_dir = File.dirname(template_dir)
165
200
 
166
- paths = if includes_load_paths.any?
167
- includes_load_paths
168
- else
169
- [template_parent_dir, template_dir, fallback_templates_dir]
170
- end
171
-
172
- site = Sourcerer::Jekyll::Bootstrapper.fake_site(
173
- includes_load_paths: paths,
174
- plugin_dirs: [])
175
-
201
+ default_paths = [template_parent_dir, template_dir, fallback_templates_dir]
202
+ paths = includes_load_paths.any? ? includes_load_paths : default_paths
203
+ site = Sourcerer::Jekyll::Bootstrapper.fake_site(includes_load_paths: paths, plugin_dirs: [])
176
204
  file_system = Sourcerer::Jekyll::Liquid::FileSystem.new(paths)
177
205
 
178
- template = Liquid::Template.parse(template_content)
179
- options = {
180
- registers: {
181
- site: site,
182
- file_system: file_system
183
- }
184
- }
185
- template.render(context, options)
206
+ { site: site, file_system: file_system, includes_load_paths: paths }
186
207
  end
187
208
 
188
209
  # Render a Liquid template string directly with a data hash.
@@ -216,6 +237,8 @@ module Sourcerer
216
237
  private_class_method :load_render_data,
217
238
  :resolve_converter,
218
239
  :render_erb,
219
- :render_liquid
240
+ :render_liquid,
241
+ :render_in_engine,
242
+ :liquid_registers
220
243
  end
221
244
  end
@@ -229,7 +229,7 @@ module Sourcerer
229
229
  end
230
230
 
231
231
  def process_blocks blocks, level, section_id
232
- # rubocop:disable Metrics/BlockLength
232
+ # rubocop:disable-next Metrics/BlockLength
233
233
  blocks.each do |block|
234
234
  case block.context
235
235
  when :section
@@ -384,7 +384,6 @@ module Sourcerer
384
384
  process_blocks(block.blocks, level, section_id) if block.respond_to?(:blocks) && block.blocks.any?
385
385
  end
386
386
  end
387
- # rubocop:enable Metrics/BlockLength
388
387
  end
389
388
  end
390
389
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sourcerer
4
- VERSION = '0.5.0'
4
+ VERSION = '0.6.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asciisourcerer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - DocOps Lab
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-09-09 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: asciidoctor
@@ -145,6 +144,7 @@ files:
145
144
  - lib/sourcerer/jekyll/bootstrapper.rb
146
145
  - lib/sourcerer/jekyll/liquid/file_system.rb
147
146
  - lib/sourcerer/jekyll/liquid/filters.rb
147
+ - lib/sourcerer/jekyll/liquid/preserve_missing_variables.rb
148
148
  - lib/sourcerer/jekyll/liquid/tags.rb
149
149
  - lib/sourcerer/jekyll/monkeypatches.rb
150
150
  - lib/sourcerer/mark_down_grade.rb
@@ -172,7 +172,6 @@ licenses:
172
172
  metadata:
173
173
  allowed_push_host: https://rubygems.org
174
174
  rubygems_mfa_required: 'true'
175
- post_install_message:
176
175
  rdoc_options: []
177
176
  require_paths:
178
177
  - lib
@@ -187,8 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
186
  - !ruby/object:Gem::Version
188
187
  version: '0'
189
188
  requirements: []
190
- rubygems_version: 3.4.19
191
- signing_key:
189
+ rubygems_version: 3.7.2
192
190
  specification_version: 4
193
191
  summary: APIs for specialized handling of AsciiDoc, YAML, and Liquid documents.
194
192
  test_files: []