coradoc-adoc 2.0.30 → 2.0.32
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/lib/coradoc/asciidoc/reference_materializers/navigation.rb +52 -0
- data/lib/coradoc/asciidoc/reference_materializers.rb +18 -0
- data/lib/coradoc/asciidoc/transform/element_transformers/block_transformer.rb +85 -73
- data/lib/coradoc/asciidoc/version.rb +1 -1
- data/lib/coradoc/asciidoc.rb +10 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 451e2ccdd5dbbd4771079ee9bdc1041c3ee0d3ff74847237d7f3d4aea5064031
|
|
4
|
+
data.tar.gz: 9f161020aca1c07565f9f20c510114b562925cbfb55d4666db14f1d61a68ed81
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 20150d6a118ae76db46737ca68c47b87a1195cd716ee88700de2afdb06094dd3edee9c66a5b224702e20c6333d28c4082d9840e24b590210154abe46643aad7a
|
|
7
|
+
data.tar.gz: a881fc61dd3bce4e276f3db93fd250d3cf0cd0ab18a2e93a296887a416070b43b0da61972818e79ff0d7c00bd9f4af6320bb8cae8976402fff8519943ce05299
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module ReferenceMaterializers
|
|
6
|
+
# Render a navigation edge as a first-class CrossReferenceElement
|
|
7
|
+
# — the model-driven xref node the AsciiDoc serializer already
|
|
8
|
+
# knows how to emit (never a raw macro string). Materializing for
|
|
9
|
+
# AsciiDoc fills in the visible text from the authored label or
|
|
10
|
+
# the resolved target's title.
|
|
11
|
+
class Navigation < Coradoc::Reference::Materializer::Base
|
|
12
|
+
class << self
|
|
13
|
+
def kind
|
|
14
|
+
:navigation
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def presentation
|
|
18
|
+
:any
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def format
|
|
22
|
+
:asciidoc
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def materialize(edge:, result:, **)
|
|
27
|
+
text = display_text(edge, result)
|
|
28
|
+
Coradoc::CoreModel::CrossReferenceElement.new(
|
|
29
|
+
target: xref_target(edge.address),
|
|
30
|
+
content: text,
|
|
31
|
+
children: [
|
|
32
|
+
Coradoc::CoreModel::TextElement.new(content: text)
|
|
33
|
+
]
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def xref_target(address)
|
|
40
|
+
[address.target, address.fragment].compact.join('#')
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def display_text(edge, result)
|
|
44
|
+
return edge.label if edge.label && !edge.label.empty?
|
|
45
|
+
return result.target.title if result.is_a?(Coradoc::Reference::Result::Resolved) && result.target&.title
|
|
46
|
+
|
|
47
|
+
edge.address.to_s
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
# Materializers rendering resolved reference Edges into
|
|
6
|
+
# AsciiDoc-shaped CoreModel nodes. They live in the format gem
|
|
7
|
+
# (not coradoc core) so format knowledge stays at the spoke of the
|
|
8
|
+
# hub-and-spoke architecture; registration is a load-time side
|
|
9
|
+
# effect via the Materializer registry's global extension point.
|
|
10
|
+
module ReferenceMaterializers
|
|
11
|
+
autoload :Navigation, "#{__dir__}/reference_materializers/navigation"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Coradoc::Reference::Materializer::Registry.register_global(
|
|
17
|
+
Coradoc::AsciiDoc::ReferenceMaterializers::Navigation
|
|
18
|
+
)
|
|
@@ -169,19 +169,22 @@ module Coradoc
|
|
|
169
169
|
|
|
170
170
|
# Single admonition dispatch used by every block-form path
|
|
171
171
|
# (example / sidebar / quote / pass / open). Builds an
|
|
172
|
-
# AnnotationBlock
|
|
173
|
-
#
|
|
174
|
-
#
|
|
175
|
-
#
|
|
176
|
-
#
|
|
172
|
+
# AnnotationBlock by delegating to +transform_typed_block+
|
|
173
|
+
# with +annotation_type+ injected via +extra_attrs+. This
|
|
174
|
+
# preserves inline formatting (links, monospace, bold), list
|
|
175
|
+
# structure, and paragraph breaks — the typed-block pipeline
|
|
176
|
+
# already groups lines into ParagraphBlock children and
|
|
177
|
+
# dispatches block-level lines (lists, tables) through
|
|
178
|
+
# ToCoreModel.transform. Type is canonicalised via
|
|
179
|
+
# AdmonitionStyles so every code path (line admonition, block
|
|
180
|
+
# admonition, attribute-cast admonition) produces the same
|
|
181
|
+
# uppercase key.
|
|
177
182
|
def transform_admonition_block(block, type)
|
|
178
183
|
canonical = AdmonitionStyles.canonicalize(type) || type.to_s
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
title: ToCoreModel.extract_title_text(block.title),
|
|
184
|
-
source_line: block.source_line
|
|
184
|
+
transform_typed_block(
|
|
185
|
+
block,
|
|
186
|
+
Coradoc::CoreModel::AnnotationBlock,
|
|
187
|
+
annotation_type: canonical
|
|
185
188
|
)
|
|
186
189
|
end
|
|
187
190
|
|
|
@@ -214,76 +217,85 @@ module Coradoc
|
|
|
214
217
|
end
|
|
215
218
|
|
|
216
219
|
def transform_typed_block(block, klass, extra_attrs = {})
|
|
217
|
-
|
|
218
|
-
has_nested_blocks = raw_lines.any? { |line| block_level_child?(line) }
|
|
219
|
-
|
|
220
|
-
if has_nested_blocks
|
|
221
|
-
children = raw_lines.reject do |line|
|
|
222
|
-
line.is_a?(Coradoc::AsciiDoc::Model::LineBreak) ||
|
|
223
|
-
line.is_a?(Coradoc::AsciiDoc::Model::Break::PageBreak)
|
|
224
|
-
end.filter_map do |line|
|
|
225
|
-
result = ToCoreModel.transform(line)
|
|
226
|
-
next nil if result.nil?
|
|
227
|
-
next result if result.is_a?(Coradoc::CoreModel::Base)
|
|
228
|
-
|
|
229
|
-
text = ToCoreModel.extract_text_content(result)
|
|
230
|
-
next nil if text.nil? || text.strip.empty?
|
|
231
|
-
|
|
232
|
-
Coradoc::CoreModel::TextContent.new(text: text)
|
|
233
|
-
end
|
|
234
|
-
klass.new(
|
|
235
|
-
id: block.id,
|
|
236
|
-
title: ToCoreModel.extract_title_text(block.title),
|
|
237
|
-
children: children,
|
|
238
|
-
language: ToCoreModel.extract_block_language(block),
|
|
239
|
-
source_line: block.source_line,
|
|
240
|
-
**extra_attrs
|
|
241
|
-
)
|
|
242
|
-
else
|
|
243
|
-
paragraph_groups = group_block_lines_into_paragraphs(raw_lines)
|
|
244
|
-
|
|
245
|
-
content_lines = paragraph_groups.map do |group|
|
|
246
|
-
ToCoreModel.extract_text_content(group)
|
|
247
|
-
end.join("\n\n")
|
|
248
|
-
|
|
249
|
-
children = paragraph_groups.map do |group|
|
|
250
|
-
inline = ToCoreModel.transform_inline_content(group)
|
|
251
|
-
inline = [Coradoc::CoreModel::TextContent.new(text: '')] if inline.empty?
|
|
252
|
-
Coradoc::CoreModel::ParagraphBlock.new(
|
|
253
|
-
content: ToCoreModel.extract_text_content(group),
|
|
254
|
-
children: Array(inline),
|
|
255
|
-
source_line: ToCoreModel.extract_source_line(group)
|
|
256
|
-
)
|
|
257
|
-
end
|
|
220
|
+
children, content = build_typed_block_children(block.lines)
|
|
258
221
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
end
|
|
222
|
+
klass.new(
|
|
223
|
+
id: block.id,
|
|
224
|
+
title: ToCoreModel.extract_title_text(block.title),
|
|
225
|
+
content: content,
|
|
226
|
+
children: children,
|
|
227
|
+
language: ToCoreModel.extract_block_language(block),
|
|
228
|
+
source_line: block.source_line,
|
|
229
|
+
**extra_attrs
|
|
230
|
+
)
|
|
269
231
|
end
|
|
270
232
|
|
|
271
|
-
#
|
|
272
|
-
#
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
233
|
+
# Walks block.lines in document order and emits the typed
|
|
234
|
+
# block's children alongside the prose-string view of its
|
|
235
|
+
# paragraphs.
|
|
236
|
+
#
|
|
237
|
+
# Consecutive inline lines coalesce into one ParagraphBlock
|
|
238
|
+
# (preserving AsciiDoc paragraph semantics: soft-wrapped
|
|
239
|
+
# source lines are one paragraph, blank lines split them).
|
|
240
|
+
# Block-level lines (lists, tables, nested blocks — anything
|
|
241
|
+
# whose AsciiDoc model returns true from +block_level?+)
|
|
242
|
+
# dispatch through +ToCoreModel.transform+ and slot in at
|
|
243
|
+
# their original document-order position. LineBreak /
|
|
244
|
+
# PageBreak lines flush the pending inline paragraph.
|
|
245
|
+
#
|
|
246
|
+
# Returns [+children+, +content+] where +content+ is the
|
|
247
|
+
# paragraph text joined with blank-line separators (nil when
|
|
248
|
+
# the block has no paragraphs, e.g. contains only nested
|
|
249
|
+
# blocks).
|
|
250
|
+
#
|
|
251
|
+
# Single source of truth for typed-block body construction.
|
|
252
|
+
# Used by every typed-block transformer (example, sidebar,
|
|
253
|
+
# quote, open, typed-cast, admonition) so they all preserve
|
|
254
|
+
# inline formatting, list structure, and paragraph breaks
|
|
255
|
+
# identically.
|
|
256
|
+
def build_typed_block_children(lines)
|
|
257
|
+
children = []
|
|
258
|
+
paragraph_texts = []
|
|
259
|
+
pending_inline = []
|
|
260
|
+
|
|
261
|
+
Array(lines).each do |line|
|
|
277
262
|
if line.is_a?(Coradoc::AsciiDoc::Model::LineBreak) ||
|
|
278
263
|
line.is_a?(Coradoc::AsciiDoc::Model::Break::PageBreak)
|
|
279
|
-
|
|
280
|
-
|
|
264
|
+
flush_inline_paragraph(pending_inline, children, paragraph_texts)
|
|
265
|
+
pending_inline.clear
|
|
266
|
+
elsif block_level_child?(line)
|
|
267
|
+
flush_inline_paragraph(pending_inline, children, paragraph_texts)
|
|
268
|
+
pending_inline.clear
|
|
269
|
+
dispatched = ToCoreModel.transform(line)
|
|
270
|
+
children << dispatched if dispatched
|
|
281
271
|
else
|
|
282
|
-
|
|
272
|
+
pending_inline << line
|
|
283
273
|
end
|
|
284
274
|
end
|
|
285
|
-
|
|
286
|
-
|
|
275
|
+
flush_inline_paragraph(pending_inline, children, paragraph_texts)
|
|
276
|
+
|
|
277
|
+
content = paragraph_texts.any? ? paragraph_texts.join("\n\n") : nil
|
|
278
|
+
[children, content]
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# Materialises +pending_inline+ into a ParagraphBlock and
|
|
282
|
+
# appends it to +children+, recording its flat text in
|
|
283
|
+
# +paragraph_texts+ for later content-string joining. No-op
|
|
284
|
+
# when +pending_inline+ is empty so callers can flush
|
|
285
|
+
# unconditionally at every boundary (blank line, block-level
|
|
286
|
+
# child, end-of-input) without producing empty paragraphs.
|
|
287
|
+
def flush_inline_paragraph(pending_inline, children, paragraph_texts)
|
|
288
|
+
return if pending_inline.empty?
|
|
289
|
+
|
|
290
|
+
inline = ToCoreModel.transform_inline_content(pending_inline)
|
|
291
|
+
inline = [Coradoc::CoreModel::TextContent.new(text: '')] if inline.empty?
|
|
292
|
+
text = ToCoreModel.extract_text_content(pending_inline)
|
|
293
|
+
paragraph_texts << text
|
|
294
|
+
children << Coradoc::CoreModel::ParagraphBlock.new(
|
|
295
|
+
content: text,
|
|
296
|
+
children: Array(inline),
|
|
297
|
+
source_line: ToCoreModel.extract_source_line(pending_inline)
|
|
298
|
+
)
|
|
287
299
|
end
|
|
288
300
|
|
|
289
301
|
# A line that should be emitted as a direct child of the
|
data/lib/coradoc/asciidoc.rb
CHANGED
|
@@ -94,6 +94,12 @@ module Coradoc
|
|
|
94
94
|
document.to_adoc
|
|
95
95
|
end
|
|
96
96
|
end
|
|
97
|
+
|
|
98
|
+
# AsciiDoc round-trips include:: directives natively — graph-mode
|
|
99
|
+
# documents serialize losslessly, no hydration required.
|
|
100
|
+
def preserves_unresolved_includes?
|
|
101
|
+
true
|
|
102
|
+
end
|
|
97
103
|
end
|
|
98
104
|
|
|
99
105
|
# Backward-compatible aliases for model classes
|
|
@@ -152,3 +158,7 @@ Coradoc.register_format(:asciidoc, Coradoc::AsciiDoc,
|
|
|
152
158
|
# Backward-compatibility: Coradoc::Model is now Coradoc::AsciiDoc::Model
|
|
153
159
|
# This alias is provided for legacy code that hasn't been updated
|
|
154
160
|
Coradoc::Model = Coradoc::AsciiDoc::Model unless defined?(Coradoc::Model)
|
|
161
|
+
|
|
162
|
+
# Reference materializers for format: :asciidoc. Required (not autoloaded)
|
|
163
|
+
# because registration is a load-time side effect, like register_format.
|
|
164
|
+
require 'coradoc/asciidoc/reference_materializers'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: coradoc-adoc
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.32
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -235,6 +235,8 @@ files:
|
|
|
235
235
|
- lib/coradoc/asciidoc/parser/table.rb
|
|
236
236
|
- lib/coradoc/asciidoc/parser/term.rb
|
|
237
237
|
- lib/coradoc/asciidoc/parser/text.rb
|
|
238
|
+
- lib/coradoc/asciidoc/reference_materializers.rb
|
|
239
|
+
- lib/coradoc/asciidoc/reference_materializers/navigation.rb
|
|
238
240
|
- lib/coradoc/asciidoc/serializer.rb
|
|
239
241
|
- lib/coradoc/asciidoc/serializer/adoc_serializer.rb
|
|
240
242
|
- lib/coradoc/asciidoc/serializer/element_registry.rb
|