asciidoctor-latexmath 1.0.0.beta.2 → 2.0.0.alpha.1

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 (31) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +119 -36
  3. data/lib/asciidoctor/latexmath/attribute_resolver.rb +485 -0
  4. data/lib/asciidoctor/latexmath/cache/cache_entry.rb +31 -0
  5. data/lib/asciidoctor/latexmath/cache/cache_key.rb +33 -0
  6. data/lib/asciidoctor/latexmath/cache/disk_cache.rb +151 -0
  7. data/lib/asciidoctor/latexmath/command_runner.rb +116 -0
  8. data/lib/asciidoctor/latexmath/converters/html5.rb +72 -0
  9. data/lib/asciidoctor/latexmath/errors.rb +134 -0
  10. data/lib/asciidoctor/latexmath/html_builder.rb +103 -0
  11. data/lib/asciidoctor/latexmath/math_expression.rb +22 -0
  12. data/lib/asciidoctor/latexmath/path_utils.rb +46 -0
  13. data/lib/asciidoctor/latexmath/processors/block_processor.rb +74 -0
  14. data/lib/asciidoctor/latexmath/processors/inline_macro_processor.rb +70 -0
  15. data/lib/asciidoctor/latexmath/processors/statistics_postprocessor.rb +18 -0
  16. data/lib/asciidoctor/latexmath/render_request.rb +32 -0
  17. data/lib/asciidoctor/latexmath/renderer_service.rb +741 -0
  18. data/lib/asciidoctor/latexmath/rendering/pdf_to_png_renderer.rb +97 -0
  19. data/lib/asciidoctor/latexmath/rendering/pdf_to_svg_renderer.rb +84 -0
  20. data/lib/asciidoctor/latexmath/rendering/pdflatex_renderer.rb +166 -0
  21. data/lib/asciidoctor/latexmath/rendering/pipeline.rb +58 -0
  22. data/lib/asciidoctor/latexmath/rendering/renderer.rb +33 -0
  23. data/lib/asciidoctor/latexmath/rendering/tool_detector.rb +320 -0
  24. data/lib/asciidoctor/latexmath/rendering/toolchain_record.rb +21 -0
  25. data/lib/asciidoctor/latexmath/statistics/collector.rb +47 -0
  26. data/lib/asciidoctor/latexmath/support/conflict_registry.rb +75 -0
  27. data/lib/{asciidoctor-latexmath → asciidoctor/latexmath}/version.rb +1 -1
  28. data/lib/asciidoctor-latexmath.rb +93 -3
  29. metadata +34 -12
  30. data/lib/asciidoctor-latexmath/renderer.rb +0 -526
  31. data/lib/asciidoctor-latexmath/treeprocessor.rb +0 -369
@@ -0,0 +1,320 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Shuai Zhang
4
+ #
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception
6
+
7
+ require "asciidoctor"
8
+ require "shellwords"
9
+
10
+ require_relative "toolchain_record"
11
+ require_relative "../../latexmath/errors"
12
+
13
+ module Asciidoctor
14
+ module Latexmath
15
+ module Rendering
16
+ class ToolDetector
17
+ SVG_PRIORITY = %i[dvisvgm pdf2svg].freeze
18
+ PNG_PRIORITY = %i[pdftoppm magick gs].freeze
19
+ SUMMARY_IDENTIFIERS = (SVG_PRIORITY + %i[pdflatex xelatex lualatex tectonic] + PNG_PRIORITY).freeze
20
+
21
+ def initialize(request, raw_attributes)
22
+ @request = request
23
+ @raw_attributes = raw_attributes || {}
24
+ @tool_presence_map = {}
25
+ @svg_log_emitted = false
26
+ end
27
+
28
+ def emit_tool_summary
29
+ self.class.emit_summary_once do
30
+ summary = SUMMARY_IDENTIFIERS.map do |identifier|
31
+ record = summary_record(identifier)
32
+ "#{identifier}=#{record.available ? "ok" : "missing"}"
33
+ end.join(" ")
34
+ Asciidoctor::LoggerManager.logger&.info { "latexmath.tools: #{summary}" }
35
+ end
36
+ end
37
+
38
+ def ensure_svg_tool!
39
+ return nil unless request.format == :svg
40
+
41
+ record = detect_svg_tool
42
+ log_svg_tool_selection(record)
43
+ return record if record.available
44
+
45
+ message = missing_tool_message(
46
+ "SVG",
47
+ record,
48
+ SVG_PRIORITY,
49
+ fallback_formats: "pdf|png",
50
+ attribute: ":latexmath-pdf2svg:"
51
+ )
52
+ raise MissingToolError.new(record.id, message)
53
+ end
54
+
55
+ def ensure_png_tool!
56
+ return nil unless request.format == :png
57
+
58
+ record = detect_png_tool
59
+ return record if record.available
60
+
61
+ message = missing_tool_message(
62
+ "PNG",
63
+ record,
64
+ PNG_PRIORITY,
65
+ fallback_formats: "svg|pdf",
66
+ attribute: ":latexmath-pdftoppm:"
67
+ )
68
+ raise MissingToolError.new(record.id, message)
69
+ end
70
+
71
+ def record_engine(command)
72
+ return if command.nil?
73
+
74
+ id = canonical_engine_id(command)
75
+ tool_presence_map[id] = true
76
+ end
77
+
78
+ def tool_presence
79
+ tool_presence_map.transform_keys(&:to_s)
80
+ end
81
+
82
+ private
83
+
84
+ attr_reader :request
85
+ attr_reader :raw_attributes
86
+ attr_reader :tool_presence_map
87
+
88
+ def log_svg_tool_selection(record)
89
+ return if @svg_log_emitted
90
+
91
+ selected = record&.available ? record.id.to_s : "missing"
92
+ Asciidoctor::LoggerManager.logger&.info { "latexmath.svg.tool=#{selected}" }
93
+ @svg_log_emitted = true
94
+ end
95
+
96
+ def detect_svg_tool
97
+ if (explicit = explicit_svg_path)
98
+ id = infer_identifier(request.tool_overrides[:svg] || :pdf2svg, SVG_PRIORITY)
99
+ available = executable_file?(explicit)
100
+ return remember_record(ToolchainRecord.new(id: id, available: available, path: explicit))
101
+ end
102
+
103
+ override = request.tool_overrides[:svg]
104
+ if override
105
+ record = resolve_override(override, SVG_PRIORITY)
106
+ return remember_record(record)
107
+ end
108
+
109
+ records = SVG_PRIORITY.map { |candidate| remember_record(memoized_lookup(candidate)) }
110
+ records.find(&:available) || records.first
111
+ end
112
+
113
+ def detect_png_tool
114
+ if (explicit = explicit_png_path)
115
+ id = infer_identifier(request.tool_overrides[:png] || :pdftoppm, PNG_PRIORITY)
116
+ available = executable_file?(explicit)
117
+ return remember_record(ToolchainRecord.new(id: id, available: available, path: explicit))
118
+ end
119
+
120
+ override = request.tool_overrides[:png]
121
+ if override
122
+ record = resolve_override(override, PNG_PRIORITY)
123
+ return remember_record(record)
124
+ end
125
+
126
+ records = PNG_PRIORITY.map { |candidate| remember_record(memoized_lookup(candidate)) }
127
+ records.find(&:available) || records.first
128
+ end
129
+
130
+ def detect_with_priority(priority)
131
+ priority.each do |candidate|
132
+ record = memoized_lookup(candidate)
133
+ return record if record.available
134
+ end
135
+
136
+ memoized_lookup(priority.first)
137
+ end
138
+
139
+ def resolve_override(value, priority)
140
+ return nil if value.nil? || value.to_s.strip.empty?
141
+
142
+ candidate = value.to_s.strip
143
+ id = infer_identifier(candidate, priority)
144
+
145
+ if File.exist?(candidate)
146
+ available = File.executable?(candidate)
147
+ return remember_record(ToolchainRecord.new(id: id, available: available, path: candidate))
148
+ end
149
+
150
+ record = memoized_lookup(id, candidate)
151
+ return remember_record(record) if record.available
152
+
153
+ remember_record(ToolchainRecord.new(id: id, available: false, path: candidate))
154
+ end
155
+
156
+ def infer_identifier(candidate, priority)
157
+ symbol = candidate.respond_to?(:to_sym) ? candidate.to_sym : candidate
158
+ normalized = symbol.to_s.downcase
159
+ explicit = normalized.gsub(/[^a-z0-9]+/, "_").to_sym
160
+ return explicit if priority.include?(explicit)
161
+
162
+ if File.exist?(candidate)
163
+ basename = File.basename(candidate)
164
+ inferred = basename.downcase.gsub(/[^a-z0-9]+/, "_").to_sym
165
+ return inferred if priority.include?(inferred)
166
+ return inferred
167
+ end
168
+
169
+ explicit
170
+ end
171
+
172
+ def memoized_lookup(identifier, override_command = nil)
173
+ command = override_command || identifier.to_s
174
+ self.class.lookup(identifier, command) do
175
+ path = find_executable(command)
176
+ if override_command
177
+ ToolchainRecord.new(id: identifier, available: !path.nil?, path: path)
178
+ else
179
+ ToolchainRecord.new(id: identifier, available: true, path: path || command)
180
+ end
181
+ end
182
+ end
183
+
184
+ def find_executable(command)
185
+ return command if executable_file?(command)
186
+
187
+ path_extensions = if Gem.win_platform?
188
+ ENV.fetch("PATHEXT", ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC").split(";")
189
+ else
190
+ [""]
191
+ end
192
+
193
+ ENV.fetch("PATH", "").split(File::PATH_SEPARATOR).each do |dir|
194
+ path_extensions.each do |ext|
195
+ candidate = File.join(dir, ext.empty? ? command : "#{command}#{ext}")
196
+ return candidate if executable_file?(candidate)
197
+ end
198
+ end
199
+
200
+ nil
201
+ end
202
+
203
+ def executable_file?(path)
204
+ File.exist?(path) && File.executable?(path) && !File.directory?(path)
205
+ end
206
+
207
+ def explicit_svg_path
208
+ override = request.tool_overrides[:svg_path]
209
+ return override if override && !override.to_s.strip.empty?
210
+
211
+ extract_path("latexmath-pdf2svg")
212
+ end
213
+
214
+ def explicit_png_path
215
+ override = request.tool_overrides[:png_path]
216
+ return override if override && !override.to_s.strip.empty?
217
+
218
+ extract_path("latexmath-pdftoppm")
219
+ end
220
+
221
+ def extract_path(key)
222
+ value = raw_attributes[key]
223
+ return nil if value.nil?
224
+
225
+ stripped = value.to_s.strip
226
+ stripped.empty? ? nil : stripped
227
+ end
228
+
229
+ def svg_candidates
230
+ override = request.tool_overrides[:svg]
231
+ return [override.to_s.strip].reject(&:empty?) unless override.nil? || override.to_s.strip.empty?
232
+
233
+ SVG_PRIORITY.map(&:to_s)
234
+ end
235
+
236
+ def png_candidates
237
+ override = request.tool_overrides[:png]
238
+ return [override.to_s.strip].reject(&:empty?) unless override.nil? || override.to_s.strip.empty?
239
+
240
+ PNG_PRIORITY.map(&:to_s)
241
+ end
242
+
243
+ def missing_tool_message(kind, record, priority, fallback_formats:, attribute:)
244
+ tried = if priority.include?(record.id)
245
+ priority.map(&:to_s)
246
+ else
247
+ ([record.id.to_s] + priority.map(&:to_s)).uniq
248
+ end
249
+
250
+ base = "Required #{kind} conversion tool not available. Tried: #{tried.join(", ")}. Configure #{attribute} with an executable path or install one of the supported tools."
251
+
252
+ preferred = record.id.to_s
253
+ alternates = (priority.map(&:to_s) - [preferred]).uniq
254
+ alt_hint = if alternates.empty?
255
+ "install #{preferred} (preferred)"
256
+ else
257
+ available_alternates = alternates.select { |name| tool_presence_map[name.to_sym] }
258
+ if available_alternates.any?
259
+ "install #{preferred} (preferred) or keep using #{available_alternates.join("/")}"
260
+ else
261
+ "install #{preferred} (preferred) or install #{alternates.join("/")}"
262
+ end
263
+ end
264
+
265
+ hints = [alt_hint, "set :latexmath-format: #{fallback_formats}"]
266
+ "#{base}\nhint: #{hints.join("; ")}"
267
+ end
268
+
269
+ def remember_record(record)
270
+ return record unless record
271
+
272
+ tool_presence_map[record.id] = record.available
273
+ record
274
+ end
275
+
276
+ def summary_record(identifier)
277
+ command = identifier.to_s
278
+ self.class.lookup(identifier, command) do
279
+ path = find_executable(command)
280
+ ToolchainRecord.new(id: identifier, available: !path.nil?, path: path || command)
281
+ end
282
+ end
283
+
284
+ def canonical_engine_id(command)
285
+ first = Shellwords.shellsplit(command.to_s).first
286
+ return :pdflatex unless first
287
+
288
+ first.downcase.gsub(/[^a-z0-9]+/, "_").to_sym
289
+ rescue ArgumentError
290
+ :pdflatex
291
+ end
292
+
293
+ class << self
294
+ def lookup(identifier, command)
295
+ @cache ||= {}
296
+ key = [identifier, command]
297
+ cached = @cache[key]
298
+ return cached if cached
299
+
300
+ record = yield
301
+ @cache[key] = record
302
+ record
303
+ end
304
+
305
+ def reset!
306
+ @cache = {}
307
+ @summary_emitted = false
308
+ end
309
+
310
+ def emit_summary_once
311
+ return if @summary_emitted
312
+
313
+ yield
314
+ @summary_emitted = true
315
+ end
316
+ end
317
+ end
318
+ end
319
+ end
320
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Shuai Zhang
4
+ #
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception
6
+
7
+ module Asciidoctor
8
+ module Latexmath
9
+ module Rendering
10
+ class ToolchainRecord
11
+ attr_reader :id, :available, :path
12
+
13
+ def initialize(id:, available:, path: nil)
14
+ @id = id
15
+ @available = available
16
+ @path = path
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Shuai Zhang
4
+ #
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception
6
+
7
+ module Asciidoctor
8
+ module Latexmath
9
+ module Statistics
10
+ class Collector
11
+ def initialize
12
+ @render_durations = []
13
+ @hit_durations = []
14
+ end
15
+
16
+ def record_render(duration_ms)
17
+ @render_durations << duration_ms
18
+ end
19
+
20
+ def record_hit(duration_ms)
21
+ @hit_durations << duration_ms
22
+ end
23
+
24
+ def to_line
25
+ return nil if @render_durations.empty? && @hit_durations.empty?
26
+
27
+ format(
28
+ "latexmath stats: renders=%<renders>d cache_hits=%<hits>d avg_render_ms=%<avg_render>d avg_hit_ms=%<avg_hit>d",
29
+ renders: @render_durations.size,
30
+ hits: @hit_durations.size,
31
+ avg_render: average(@render_durations),
32
+ avg_hit: average(@hit_durations)
33
+ )
34
+ end
35
+
36
+ private
37
+
38
+ def average(values)
39
+ return 0 if values.empty?
40
+
41
+ sum = values.sum
42
+ (sum.to_f / values.size).round(0, half: :up)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Shuai Zhang
4
+ #
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception
6
+
7
+ require_relative "../errors"
8
+
9
+ module Asciidoctor
10
+ module Latexmath
11
+ module Support
12
+ class ConflictRegistry
13
+ Entry = Struct.new(:signature, :details)
14
+
15
+ def initialize
16
+ @entries = {}
17
+ end
18
+
19
+ def register!(basename, signature, details)
20
+ normalized = normalize_details(details)
21
+ entry = entries[basename]
22
+ if entry
23
+ return if entry.signature == signature
24
+
25
+ raise TargetConflictError, conflict_message(basename, entry, normalized, signature)
26
+ end
27
+
28
+ entries[basename] = Entry.new(signature, normalized)
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :entries
34
+
35
+ def normalize_details(details)
36
+ {
37
+ location: details[:location] || "unknown location",
38
+ format: (details[:format] || "unknown").to_s,
39
+ content_hash: (details[:content_hash] || "").to_s,
40
+ preamble_hash: (details[:preamble_hash] || "").to_s,
41
+ fontsize_hash: (details[:fontsize_hash] || "").to_s,
42
+ entry_type: (details[:entry_type] || "unknown").to_s
43
+ }
44
+ end
45
+
46
+ def conflict_message(basename, existing_entry, incoming_details, incoming_signature)
47
+ existing_details = existing_entry.details
48
+ <<~MSG.strip
49
+ conflicting target '#{basename}' already defined at #{existing_details[:location]} (signature #{signature_summary(existing_entry.signature, existing_details)}).
50
+ new definition from #{incoming_details[:location]} would produce signature #{signature_summary(incoming_signature, incoming_details)}.
51
+ hint: choose a unique target basename or remove the explicit target attribute.
52
+ MSG
53
+ end
54
+
55
+ def signature_summary(signature, details)
56
+ parts = []
57
+ parts << "key=#{signature.to_s[0, 12]}" if signature
58
+ parts << "format=#{details[:format]}"
59
+ parts << "content=#{truncate(details[:content_hash])}"
60
+ parts << "preamble=#{truncate(details[:preamble_hash])}"
61
+ parts << "fontsize=#{truncate(details[:fontsize_hash])}"
62
+ parts << "entry=#{details[:entry_type]}"
63
+ parts.join(" ")
64
+ end
65
+
66
+ def truncate(value)
67
+ text = value.to_s
68
+ return "-" if text.empty?
69
+
70
+ text[0, 12]
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -6,6 +6,6 @@
6
6
 
7
7
  module Asciidoctor
8
8
  module Latexmath
9
- VERSION = "1.0.0.beta.2"
9
+ VERSION = "2.0.0.alpha.1"
10
10
  end
11
11
  end
@@ -4,9 +4,99 @@
4
4
  #
5
5
  # SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception
6
6
 
7
- require_relative "asciidoctor-latexmath/version"
8
- require_relative "asciidoctor-latexmath/treeprocessor"
7
+ require "asciidoctor"
8
+ require "asciidoctor/extensions"
9
+ require_relative "asciidoctor/latexmath/version"
10
+ require_relative "asciidoctor/latexmath/processors/block_processor"
11
+ require_relative "asciidoctor/latexmath/processors/inline_macro_processor"
12
+ require_relative "asciidoctor/latexmath/processors/statistics_postprocessor"
13
+ require_relative "asciidoctor/latexmath/converters/html5"
14
+
15
+ module Asciidoctor
16
+ module Latexmath
17
+ class << self
18
+ def register(registry = ::Asciidoctor::Extensions)
19
+ block_extension = registry.block Processors::BlockProcessor
20
+ inline_extension = registry.inline_macro Processors::InlineMacroProcessor
21
+ ensure_processor_collection!(registry, :@block_processors, :latexmath, block_extension)
22
+ ensure_processor_collection!(registry, :@inline_macros, :latexmath, inline_extension)
23
+ registry.postprocessor Processors::StatisticsPostprocessor
24
+
25
+ ensure_aliases!(registry)
26
+ ensure_empty_collection!(registry, :@block_macros, {})
27
+ ensure_empty_collection!(registry, :@tree_processors, [])
28
+ ensure_empty_collection!(registry, :@tree_processor_extensions, [])
29
+
30
+ registry
31
+ end
32
+
33
+ def reset_render_counters!
34
+ @render_invocations = 0
35
+ end
36
+
37
+ def record_render_invocation!
38
+ @render_invocations = render_invocations + 1
39
+ end
40
+
41
+ def render_invocations
42
+ @render_invocations ||= 0
43
+ end
44
+
45
+ private
46
+
47
+ def ensure_processor_collection!(registry, ivar, canonical_name, extension)
48
+ collection = registry.instance_variable_get(ivar)
49
+ unless collection
50
+ collection = {}
51
+ registry.instance_variable_set(ivar, collection)
52
+ end
53
+
54
+ canonical_name = canonical_name.to_sym
55
+ collection[canonical_name] ||= []
56
+ unless collection[canonical_name].include?(extension)
57
+ collection[canonical_name] << extension
58
+ end
59
+
60
+ collection
61
+ end
62
+
63
+ def ensure_aliases!(registry)
64
+ ensure_collection_alias!(registry.instance_variable_get(:@block_extensions), :latexmath, :stem)
65
+ ensure_collection_alias!(registry.instance_variable_get(:@inline_macro_extensions), :latexmath, :stem)
66
+ ensure_collection_alias!(registry.instance_variable_get(:@block_processors), :latexmath, :stem)
67
+ ensure_collection_alias!(registry.instance_variable_get(:@inline_macros), :latexmath, :stem)
68
+ end
69
+
70
+ def ensure_collection_alias!(collection, canonical_name, alias_name)
71
+ return unless collection
72
+ canonical_name = canonical_name.to_sym
73
+ alias_name = alias_name&.to_sym
74
+ return unless alias_name
75
+
76
+ existing_default = collection.default_proc
77
+
78
+ collection.default_proc = lambda do |hash, key|
79
+ key_sym = key.to_sym
80
+ if key_sym == alias_name
81
+ hash[canonical_name]
82
+ elsif existing_default
83
+ existing_default.call(hash, key)
84
+ end
85
+ end
86
+ end
87
+
88
+ def ensure_empty_collection!(registry, ivar, empty_value)
89
+ value = registry.instance_variable_get(ivar)
90
+ if value.nil?
91
+ registry.instance_variable_set(ivar, empty_value.dup)
92
+ else
93
+ value
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
9
99
 
10
100
  Asciidoctor::Extensions.register do
11
- treeprocessor Asciidoctor::Latexmath::Treeprocessor
101
+ Asciidoctor::Latexmath.register(self)
12
102
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asciidoctor-latexmath
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta.2
4
+ version: 2.0.0.alpha.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shuai Zhang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-09-28 00:00:00.000000000 Z
11
+ date: 2025-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -83,17 +83,39 @@ files:
83
83
  - LICENSE
84
84
  - README.md
85
85
  - lib/asciidoctor-latexmath.rb
86
- - lib/asciidoctor-latexmath/renderer.rb
87
- - lib/asciidoctor-latexmath/treeprocessor.rb
88
- - lib/asciidoctor-latexmath/version.rb
89
- homepage: https://github.com/hcoona/asciidoctor-latexmath
86
+ - lib/asciidoctor/latexmath/attribute_resolver.rb
87
+ - lib/asciidoctor/latexmath/cache/cache_entry.rb
88
+ - lib/asciidoctor/latexmath/cache/cache_key.rb
89
+ - lib/asciidoctor/latexmath/cache/disk_cache.rb
90
+ - lib/asciidoctor/latexmath/command_runner.rb
91
+ - lib/asciidoctor/latexmath/converters/html5.rb
92
+ - lib/asciidoctor/latexmath/errors.rb
93
+ - lib/asciidoctor/latexmath/html_builder.rb
94
+ - lib/asciidoctor/latexmath/math_expression.rb
95
+ - lib/asciidoctor/latexmath/path_utils.rb
96
+ - lib/asciidoctor/latexmath/processors/block_processor.rb
97
+ - lib/asciidoctor/latexmath/processors/inline_macro_processor.rb
98
+ - lib/asciidoctor/latexmath/processors/statistics_postprocessor.rb
99
+ - lib/asciidoctor/latexmath/render_request.rb
100
+ - lib/asciidoctor/latexmath/renderer_service.rb
101
+ - lib/asciidoctor/latexmath/rendering/pdf_to_png_renderer.rb
102
+ - lib/asciidoctor/latexmath/rendering/pdf_to_svg_renderer.rb
103
+ - lib/asciidoctor/latexmath/rendering/pdflatex_renderer.rb
104
+ - lib/asciidoctor/latexmath/rendering/pipeline.rb
105
+ - lib/asciidoctor/latexmath/rendering/renderer.rb
106
+ - lib/asciidoctor/latexmath/rendering/tool_detector.rb
107
+ - lib/asciidoctor/latexmath/rendering/toolchain_record.rb
108
+ - lib/asciidoctor/latexmath/statistics/collector.rb
109
+ - lib/asciidoctor/latexmath/support/conflict_registry.rb
110
+ - lib/asciidoctor/latexmath/version.rb
111
+ homepage: https://github.com/hcoona/asciidoctor-latexmath#readme
90
112
  licenses:
91
113
  - LGPL-3.0-or-later WITH LGPL-3.0-linking-exception
92
114
  metadata:
93
- homepage_uri: https://github.com/hcoona/asciidoctor-latexmath
115
+ homepage_uri: https://github.com/hcoona/asciidoctor-latexmath#readme
94
116
  source_code_uri: https://github.com/hcoona/asciidoctor-latexmath
95
117
  bug_tracker_uri: https://github.com/hcoona/asciidoctor-latexmath/issues
96
- documentation_uri: https://github.com/hcoona/asciidoctor-latexmath#readme
118
+ documentation_uri: https://github.com/hcoona/asciidoctor-latexmath/blob/main/README.md
97
119
  post_install_message:
98
120
  rdoc_options: []
99
121
  require_paths:
@@ -102,14 +124,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
102
124
  requirements:
103
125
  - - ">="
104
126
  - !ruby/object:Gem::Version
105
- version: '0'
127
+ version: '3.2'
106
128
  required_rubygems_version: !ruby/object:Gem::Requirement
107
129
  requirements:
108
- - - ">"
130
+ - - ">="
109
131
  - !ruby/object:Gem::Version
110
- version: 1.3.1
132
+ version: '0'
111
133
  requirements: []
112
- rubygems_version: 3.4.20
134
+ rubygems_version: 3.5.22
113
135
  signing_key:
114
136
  specification_version: 4
115
137
  summary: Offline latexmath rendering for Asciidoctor.