coradoc-adoc 2.0.31 → 2.0.33

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: 22eb5a515f97c8954148e99ef280dd4bb8ac3bed03d59d745291dc3d7ac302c2
4
- data.tar.gz: 0435ded18a2f7895426d1de9aba45c5c3ccaeea442c287fb1f5cd6d14581b117
3
+ metadata.gz: 70861dce3318bead6c8153bfa44090dc2da49a1f9889cb517dcdb559a4eaeb9c
4
+ data.tar.gz: 94b397c634354792bb99678f71d3fc15221cb1f7feb42894d514e96c644f47f1
5
5
  SHA512:
6
- metadata.gz: cc35eb17f93b7c78fc2f935cf71ef18d76af08eb36a52ab7040d90e735c72a4d1f990339fc414803ccbf767d0b57bf636be79d76940fa8a091e52bcd37091544
7
- data.tar.gz: 8c93968c63d400dfb86d0855c6bb1a2ebc6bbe200a85b07da5d2861771baeacf2beb11cd811c136e912fae302d0003c8aa822f12c73ef2ae5d127ced9caea829
6
+ metadata.gz: f2283331458aaae5a07cd9f135aa3e8e2a6b09f9e7df12336233dd43313c2dc4775e988ef49ef23428a131019fb00c3feaaf0127b9f7521e222fc460c12b5c83
7
+ data.tar.gz: 7c0cc22f6919a661e4d17adf687611ae7c2194bd4bf3dd7184ba073bc44e7e38ab716e20764affab27d97b7536f4caac02151ad170dde5c531871588ea7f643f
@@ -17,21 +17,56 @@ module Coradoc
17
17
  line_start? >> str("+\n")
18
18
  end
19
19
 
20
+ # Single source of truth for "what can appear between consecutive
21
+ # list items without ending the list". Asciidoctor treats blank
22
+ # lines and `//` comment lines as non-terminating inside every
23
+ # list type. Comments are consumed without capture — they are
24
+ # structurally invisible inside a list (no CommentLine node is
25
+ # emitted). Tag directives (`// tag::`) keep their separate
26
+ # handling via `comment_line_content`'s `tag.absent?` guard.
27
+ def list_item_separator
28
+ (comment_line_content | empty_line).repeat(0)
29
+ end
30
+
31
+ # Single source of truth for "what block can attach to a list
32
+ # item via a `+` continuation marker". The `+` line is consumed
33
+ # by {#list_item_attached}; this rule expresses only the block
34
+ # that follows. Definition lists are intentionally excluded —
35
+ # `+` before a continuing dlist run is handled inside
36
+ # `dlist_item` as a continuation marker so the run nests by
37
+ # delimiter depth (see there).
38
+ def list_attached_block
39
+ admonition_line | unordered_list(1) | ordered_list(1) | paragraph | block
40
+ end
41
+
42
+ # Shared `+`-continuation attachment for every list item type
43
+ # (ulist, olist, dlist). A `+` line directly followed by an
44
+ # attached block becomes a child of the current item. The
45
+ # `list_continuation.present?` lookahead prevents greedy
46
+ # over-match when the `+` actually belongs to surrounding
47
+ # context.
48
+ def list_item_attached
49
+ (list_continuation.present? >>
50
+ list_continuation >>
51
+ list_attached_block
52
+ ).repeat(0).as(:attached)
53
+ end
54
+
20
55
  def ordered_list(nesting_level = 1)
21
56
  attrs = (attribute_list >> newline).maybe
22
57
  r = olist_item(nesting_level)
23
- attrs >> (empty_line.repeat(0) >> r).repeat(1).as(:ordered)
58
+ attrs >> (list_item_separator >> r).repeat(1).as(:ordered)
24
59
  end
25
60
 
26
61
  def unordered_list(nesting_level = 1)
27
62
  attrs = (attribute_list >> newline).maybe
28
63
  r = ulist_item(nesting_level)
29
- attrs >> (empty_line.repeat(0) >> r).repeat(1).as(:unordered)
64
+ attrs >> (list_item_separator >> r).repeat(1).as(:unordered)
30
65
  end
31
66
 
32
67
  def definition_list(_delimiter = nil)
33
68
  (attribute_list >> newline).maybe >>
34
- dlist_item.repeat(1).as(:definition_list) >>
69
+ (list_item_separator >> dlist_item).repeat(1).as(:definition_list) >>
35
70
  dlist_item.absent?
36
71
  end
37
72
 
@@ -56,11 +91,7 @@ module Coradoc
56
91
  (list_body_text_line >>
57
92
  list_item_continuation_lines).as(:lines)
58
93
 
59
- att = (list_continuation.present? >>
60
- list_continuation >>
61
- (admonition_line | paragraph | block)
62
- ).repeat(0).as(:attached)
63
- item >>= att.maybe
94
+ item >>= list_item_attached.maybe
64
95
 
65
96
  if nesting_level <= 4
66
97
  item >>= (list_marker(nesting_level + 1).present? >>
@@ -108,11 +139,7 @@ module Coradoc
108
139
  (list_body_text_line >>
109
140
  list_item_continuation_lines).as(:lines)
110
141
 
111
- att = (list_continuation.present? >>
112
- list_continuation >>
113
- (admonition_line | paragraph | block)
114
- ).repeat(0).as(:attached)
115
- item >>= att.maybe
142
+ item >>= list_item_attached.maybe
116
143
 
117
144
  if nesting_level <= 4
118
145
  item >>= (list_marker(nesting_level + 1).present? >>
@@ -273,11 +300,14 @@ module Coradoc
273
300
 
274
301
  item = multi_line | inline
275
302
 
276
- attached = (list_continuation.present? >>
277
- list_continuation >>
278
- (admonition_line | paragraph | block)
279
- ).repeat(0).as(:attached)
280
- item >>= attached.maybe
303
+ item >>= list_item_attached.maybe
304
+
305
+ # A `+` line directly before a continuing dlist run is a
306
+ # list-continuation marker (asciidoctor semantics): consume it
307
+ # so the following items stay in the current list and nest by
308
+ # delimiter depth. Without this, the `+` dangles and the run
309
+ # splits off as a detached sibling list.
310
+ item >>= (list_continuation >> dlist_item.present?).repeat(0)
281
311
 
282
312
  item.as(:definition_list_item)
283
313
  end
@@ -121,6 +121,26 @@ module Coradoc
121
121
  ).as(:block_image)
122
122
  end
123
123
 
124
+ # Non-capturing form of {#comment_line}. Same shape (a `//`
125
+ # comment line, excluding tag directives like `// tag::`), but
126
+ # consumes without producing an AST node.
127
+ #
128
+ # Used by list rules to absorb inter-item comments so the list
129
+ # continues across them — asciidoctor treats `//` comments inside
130
+ # any list as structurally invisible. Uses raw character matchers
131
+ # instead of `text` so no inner captures leak into the consuming
132
+ # rule's AST.
133
+ #
134
+ # Single source of truth for the comment-line shape: any future
135
+ # adjustment to the `//`-line grammar happens here and both the
136
+ # capturing and non-capturing forms stay in sync.
137
+ def comment_line_content
138
+ tag.absent? >>
139
+ str('//') >> str('/').absent? >>
140
+ space? >>
141
+ match('[^\n]').repeat(0) >> line_ending
142
+ end
143
+
124
144
  def comment_line
125
145
  tag.absent? >>
126
146
  (str('//') >> str('/').absent? >>
@@ -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
+ )
@@ -114,14 +114,17 @@ module Coradoc
114
114
 
115
115
  def transform_list_item(item)
116
116
  content_val = item.content
117
- children = ToCoreModel.transform_inline_content(content_val)
117
+ inline_children = ToCoreModel.transform_inline_content(content_val)
118
+ attached_children = Array(item.attached).filter_map do |block|
119
+ ToCoreModel.transform(block)
120
+ end
118
121
 
119
122
  li = Coradoc::CoreModel::ListItem.new(
120
123
  content: ToCoreModel.extract_text_content(content_val),
121
124
  marker: item.marker,
122
125
  source_line: item.source_line
123
126
  )
124
- li.children = children
127
+ li.children = inline_children + attached_children
125
128
 
126
129
  nested_lists = extract_nested_lists(item)
127
130
  li.nested_list = nested_lists.first if nested_lists.size == 1
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Coradoc
4
4
  module AsciiDoc
5
- VERSION = '2.0.31'
5
+ VERSION = '2.0.33'
6
6
  end
7
7
  end
@@ -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.31
4
+ version: 2.0.33
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