coradoc-adoc 2.0.16 → 2.0.17

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: e3b72474cf0652bc8f5702011009cab0caeb9dd5180a6f17510a2e081286951d
4
- data.tar.gz: 8218895ed5672fe9932747a025c54621ba02870daea6f964b1cc28d506968a1d
3
+ metadata.gz: 99b9b654a8eebde5418dfbee6f7b184e65bbbcd830b24f0211963d61ed6c1201
4
+ data.tar.gz: 93e69befaf29a65358e5b6655b7b6cf63d0fb9baab9a828848d7468290c87e3b
5
5
  SHA512:
6
- metadata.gz: 46c11254ea13b32498f66d11eb0ead0d13df136f7a0cca65e701373cf48f1edf9d9e1beb447553ddc1a14e4459052d559038aa1b6edb580731a6f91d27969616
7
- data.tar.gz: 3d6b4701f38cfd0042bcd14d77d094c6c48626bc85ffab3557a274f2fd90041d1df95f37a156a18ef7a73e8d2d9d4900f8048c8c8d021425ddd8ec38a587db84
6
+ metadata.gz: 1480db996c2768544ae15657c7f394bcaed954c31c79bdf1bfd3f3493b608aad77dc078ed44058ac0964632626585f096a7c96d6047a256ed07f902291ac204a
7
+ data.tar.gz: b3d0d2044b40702ad13d2f500e06e4e5881e865eda9ac0bc3f01fba94c82175b9b1752e3076b05781d7fd03075af7d276b8af55ef18b4be08576ea5018ea07b0
@@ -21,10 +21,21 @@ module Coradoc
21
21
  id: section_ast[:id],
22
22
  level: extract_level(section_ast),
23
23
  children: build_section_contents(section_ast[:contents]) +
24
- build_subsections(section_ast[:sections])
24
+ build_subsections(section_ast[:sections]),
25
+ attributes: build_section_metadata(section_ast[:attribute_list])
25
26
  )
26
27
  end
27
28
 
29
+ # Coerces the AST attribute_list (hash / string / nil) through the
30
+ # normalizer, then delegates to Transform::AttributeListToMetadata
31
+ # for the typed Model::AttributeList -> CoreModel::Metadata step.
32
+ # Single source of truth lives in the transform layer (DRY/MECE).
33
+ def build_section_metadata(attribute_list)
34
+ list = Coradoc::AsciiDoc::Transformer::AttributeListNormalizer
35
+ .coerce(attribute_list)
36
+ Coradoc::AsciiDoc::Transform::AttributeListToMetadata.call(list)
37
+ end
38
+
28
39
  def build_section_contents(contents_ast)
29
40
  return [] unless contents_ast
30
41
 
@@ -58,8 +58,21 @@ module Coradoc
58
58
  Coradoc::AsciiDoc::Model::Section,
59
59
  collection: true,
60
60
  initialize_empty: true
61
+ # Block-header attribute list (e.g. `[appendix]`, `[bibliography]`).
62
+ # Single source of truth for the AsciiDoc `[style]` hint; downstream
63
+ # consumers (coradoc-mirror) read `style` from SectionElement#attributes
64
+ # to dispatch JS section types (annex, references, ...).
65
+ attribute :attribute_list, Coradoc::AsciiDoc::Model::AttributeList
61
66
  # attribute :anchor, Coradoc::AsciiDoc::Model::Inline::Anchor
62
67
 
68
+ # Style hint derived from the first positional in `attribute_list`.
69
+ # Returns nil when no list is attached. Kept here so callers don't
70
+ # need to know the AttributeList shape.
71
+ def style
72
+ first_positional = attribute_list&.positional&.first
73
+ first_positional&.value
74
+ end
75
+
63
76
  # Allow setting level directly during initialization
64
77
  def initialize(**attributes)
65
78
  level_value = attributes.delete(:level)
@@ -44,7 +44,7 @@ module Coradoc
44
44
  end
45
45
 
46
46
  def positional_value_unquoted
47
- match['a-zA-Z0-9_\-%.'].repeat(1)
47
+ match('[^\]\s,]').repeat(1) >> space.absent?
48
48
  end
49
49
 
50
50
  def positional_value_single_quote
@@ -139,29 +139,57 @@ module Coradoc
139
139
  closing_delimiter >> newline
140
140
  end
141
141
 
142
- # Block style parser with EXACT delimiter length (for open blocks)
143
- # Open blocks use exactly 2 dashes and cannot nest within themselves
142
+ # Block style parser with EXACT delimiter length (for open blocks).
143
+ # Open blocks use exactly 2 dashes. A `[source]`/`[listing]`/`[literal]`
144
+ # positional attribute casts the body to verbatim — block macros like
145
+ # `image::` must survive byte-for-byte, same as delimited source blocks.
144
146
  def block_style_exact(n_deep = 3, delimiter = '-', exact_chars = 2)
145
147
  capture_key = :"delimit_#{delimiter}_exact_#{exact_chars}_#{n_deep}"
148
+ attr_capture_key = :"#{capture_key}_attrs"
146
149
  current_delimiter = str(delimiter).repeat(exact_chars, exact_chars).capture(capture_key)
147
150
  closing_delimiter = dynamic do |_s, c|
148
151
  str(c.captures[capture_key].to_s.strip)
149
152
  end
150
153
 
154
+ # Closure so the call bypasses Parslet's method_missing inside the
155
+ # dynamic block. capture() stashes the parsed AST (a nested Hash for
156
+ # a `[source,ruby]` header). Inspect the structure directly so we
157
+ # don't depend on Ruby's Hash#to_s format (it changed in 3.4).
158
+ verbatim_cast = lambda do |raw|
159
+ values = []
160
+ queue = [raw]
161
+ while (node = queue.shift)
162
+ case node
163
+ when Hash then queue.concat(node.values)
164
+ when Array then queue.concat(node)
165
+ else values << node
166
+ end
167
+ end
168
+ castable = %w[source listing literal]
169
+ values.any? { |v| castable.include?(v.to_s) }
170
+ end
171
+
151
172
  block_content_with_closing = dynamic do |_s, c|
152
173
  delim_str = c.captures[capture_key].to_s.strip
174
+ raw_header = c.captures[attr_capture_key]
153
175
  closing_pattern = str(delim_str) >> newline
154
176
 
155
- content = block_image
156
- content |= block(n_deep - 1) if n_deep.positive?
157
- content |= list
158
- content |= text_line(false, unguarded: true)
159
- content |= empty_line.as(:line_break)
177
+ content = if verbatim_cast.call(raw_header)
178
+ text_line(false, unguarded: true, verbatim: true) |
179
+ empty_line.as(:line_break)
180
+ else
181
+ alt = block_image
182
+ alt |= block(n_deep - 1) if n_deep.positive?
183
+ alt |= list
184
+ alt |= text_line(false, unguarded: true)
185
+ alt |= empty_line.as(:line_break)
186
+ alt
187
+ end
160
188
 
161
189
  (closing_pattern.absent? >> content).repeat(1)
162
190
  end
163
191
 
164
- block_header >>
192
+ block_header.capture(attr_capture_key) >>
165
193
  line_start? >>
166
194
  current_delimiter.as(:delimiter) >> newline >>
167
195
  block_content_with_closing.as(:lines) >>
@@ -14,6 +14,14 @@ module Coradoc
14
14
  str('>>')
15
15
  ).as(:cross_reference)
16
16
  end
17
+
18
+ # AsciiDoc escape: `\<<` produces the literal text `<<` without
19
+ # firing the cross-reference rule. Without this, documentation that
20
+ # shows AsciiDoc xref syntax as a literal example gets rewritten
21
+ # into a broken link to a non-existent anchor.
22
+ def escaped_xref
23
+ str('\\') >> str('<<').as(:text)
24
+ end
17
25
  end
18
26
  end
19
27
  end
@@ -158,7 +158,8 @@ module Coradoc
158
158
  str('+++').present? |
159
159
  term_type.present? |
160
160
  str('footnote').present? |
161
- stem_type.present?
161
+ stem_type.present? |
162
+ str('\\<<').present?
162
163
  end
163
164
 
164
165
  def inline
@@ -175,6 +176,7 @@ module Coradoc
175
176
  superscript |
176
177
  subscript |
177
178
  attribute_reference |
179
+ escaped_xref |
178
180
  cross_reference |
179
181
  term_inline |
180
182
  term_inline2 |
@@ -188,8 +190,12 @@ module Coradoc
188
190
  end
189
191
 
190
192
  def text_unformatted
191
- # line_not_text? >>
192
- (inline.absent? >>
193
+ # `str('\\<<').absent?` stops text from consuming the backslash of
194
+ # an escaped xref (`\<<`). Without this guard, the `\` is taken as
195
+ # plain text, the `<<` re-enters cross_reference, and the literal
196
+ # escape is destroyed.
197
+ (str('\\<<').absent? >>
198
+ inline.absent? >>
193
199
  match("[^\n]")
194
200
  ).repeat(1)
195
201
  end
@@ -52,21 +52,19 @@ module Coradoc
52
52
 
53
53
  def olist_item(nesting_level = 1)
54
54
  item = olist_marker(nesting_level).as(:marker) >>
55
- match("\n").absent? >> space >> text_line(true, unguarded: true)
56
- # >>
57
- # (list_continuation.present? >> list_continuation >>
58
- # paragraph #| example_block(n_deep: 1)
59
- # ).repeat(0).as(:attached)
55
+ match("\n").absent? >> space >>
56
+ (text_line(true, unguarded: true) >>
57
+ list_item_continuation_lines).as(:lines)
60
58
 
61
59
  att = (list_continuation.present? >>
62
60
  list_continuation >>
63
- (admonition_line | paragraph | block) # (n_deep: 1))
61
+ (admonition_line | paragraph | block)
64
62
  ).repeat(0).as(:attached)
65
63
  item >>= att.maybe
66
64
 
67
65
  if nesting_level <= 4
68
66
  item >>= (list_marker(nesting_level + 1).present? >>
69
- list(nesting_level + 1)).repeat(0).as(:nested) # ).maybe
67
+ list(nesting_level + 1)).repeat(0).as(:nested)
70
68
  end
71
69
  olist_marker(nesting_level).present? >> item.as(:list_item)
72
70
  end
@@ -82,21 +80,33 @@ module Coradoc
82
80
  def ulist_item(nesting_level = 1)
83
81
  item = ulist_marker(nesting_level).as(:marker) >>
84
82
  str(' [[[').absent? >>
85
- match("\n").absent? >> space >> text_line(true, unguarded: true)
83
+ match("\n").absent? >> space >>
84
+ (text_line(true, unguarded: true) >>
85
+ list_item_continuation_lines).as(:lines)
86
86
 
87
87
  att = (list_continuation.present? >>
88
88
  list_continuation >>
89
- (admonition_line | paragraph | block) # (n_deep: 1))
89
+ (admonition_line | paragraph | block)
90
90
  ).repeat(0).as(:attached)
91
91
  item >>= att.maybe
92
92
 
93
93
  if nesting_level <= 4
94
94
  item >>= (list_marker(nesting_level + 1).present? >>
95
- list(nesting_level + 1)).repeat(0).as(:nested) # ).maybe
95
+ list(nesting_level + 1)).repeat(0).as(:nested)
96
96
  end
97
97
  ulist_marker(nesting_level).present? >> item.as(:list_item)
98
98
  end
99
99
 
100
+ # Continuation lines of a list item's first paragraph. AsciiDoc
101
+ # joins consecutive non-blank lines into one paragraph within the
102
+ # item, but the lines must not start a sibling construct (another
103
+ # list marker, block delimiter, attribute list, section, element
104
+ # id, table boundary, list continuation, or list prefix).
105
+ # `line_not_text?` (from Paragraph) is that exact lookahead.
106
+ def list_item_continuation_lines
107
+ (line_not_text? >> text_line(true, unguarded: true)).repeat(0)
108
+ end
109
+
100
110
  def dlist_delimiter
101
111
  (
102
112
  (str(':::::') >> match(':').absent?) |
@@ -120,12 +130,18 @@ module Coradoc
120
130
  end
121
131
 
122
132
  def dlist_item(_delimiter = nil)
123
- (((dlist_term.as(:terms).repeat(1) >> line_ending >>
124
- empty_line.repeat(0)).repeat(1) >>
125
- dlist_definition) |
126
- (dlist_term.repeat(1, 1).as(:terms) >> space >>
127
- dlist_definition)
128
- ).as(:definition_list_item)
133
+ # Both forms below produce the same AST shape:
134
+ # {terms: [<dlist_term>, ...], definition: <text>}
135
+ # so the transformer's definition_list_item rule matches uniformly.
136
+ #
137
+ # Multi-line form: one or more term-lines (`term::` + newline +
138
+ # optional blank lines), then the definition on its own line(s).
139
+ # Single-line form: one term + inline space + definition.
140
+ term_line = dlist_term >> line_ending >> empty_line.repeat(0)
141
+
142
+ ((term_line.repeat(1).as(:terms) >> dlist_definition) |
143
+ (dlist_term.repeat(1, 1).as(:terms) >> space >>
144
+ dlist_definition)).as(:definition_list_item)
129
145
  end
130
146
  end
131
147
  end
@@ -13,7 +13,9 @@ module Coradoc
13
13
  list_prefix.absent? >>
14
14
  list_continuation.absent? >>
15
15
  element_id.absent? >>
16
- section_prefix.absent?
16
+ section_prefix.absent? >>
17
+ comment_line.absent? >>
18
+ tag.absent?
17
19
  end
18
20
 
19
21
  # NOTE: many_breaks parameter has three states for different parsing contexts:
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module AsciiDoc
5
+ module Transform
6
+ # Single source of truth for AsciiDoc Model::AttributeList ->
7
+ # CoreModel::Metadata conversion (DRY/MECE).
8
+ #
9
+ # Promotes the first positional attribute to `style` and the
10
+ # `role=` named attribute to `role`, matching the AsciiDoc
11
+ # block-header semantics that downstream consumers (coradoc-mirror)
12
+ # dispatch on to pick a JS section type (annex, abstract, ...).
13
+ #
14
+ # Returns nil for anything that isn't a typed AttributeList so
15
+ # callers can pass through optional/missing inputs without an
16
+ # extra guard.
17
+ module AttributeListToMetadata
18
+ module_function
19
+
20
+ def call(list)
21
+ return nil unless list.is_a?(Coradoc::AsciiDoc::Model::AttributeList)
22
+
23
+ metadata = Coradoc::CoreModel::Metadata.new
24
+ first_positional = list.positional.first
25
+ metadata['style'] = first_positional.value if first_positional
26
+ named_role = list.named.find { |n| n.name == 'role' }
27
+ metadata['role'] = named_role.value.first if named_role&.value&.any?
28
+ metadata
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -16,7 +16,12 @@ module Coradoc
16
16
  )
17
17
  end
18
18
 
19
- def transform_source_block(block)
19
+ # Verbatim blocks (source, listing, literal, pass) must round-trip
20
+ # their body byte-for-byte. Each source line becomes one content
21
+ # line; we join with "\n" so whitespace, indentation, and blank
22
+ # lines are preserved. Treating these as paragraphs would collapse
23
+ # whitespace and join consecutive lines into a single flowing text.
24
+ def transform_verbatim_block(block, klass)
20
25
  non_break_lines = Array(block.lines).reject do |line|
21
26
  line.is_a?(Coradoc::AsciiDoc::Model::LineBreak) ||
22
27
  line.is_a?(Coradoc::AsciiDoc::Model::Break::PageBreak)
@@ -25,16 +30,26 @@ module Coradoc
25
30
  ToCoreModel.extract_text_content(line)
26
31
  end.join("\n")
27
32
 
28
- language = ToCoreModel.extract_block_language(block)
29
-
30
- Coradoc::CoreModel::SourceBlock.new(
33
+ klass.new(
31
34
  id: block.id,
32
35
  title: ToCoreModel.extract_title_text(block.title),
33
36
  content: content_lines,
34
- language: language
37
+ language: ToCoreModel.extract_block_language(block)
35
38
  )
36
39
  end
37
40
 
41
+ def transform_source_block(block)
42
+ transform_verbatim_block(block, Coradoc::CoreModel::SourceBlock)
43
+ end
44
+
45
+ def transform_literal_block(block)
46
+ transform_verbatim_block(block, Coradoc::CoreModel::LiteralBlock)
47
+ end
48
+
49
+ def transform_pass_block(block)
50
+ transform_verbatim_block(block, Coradoc::CoreModel::PassBlock)
51
+ end
52
+
38
53
  # Open blocks (`--`) are generic containers. AsciiDoc allows
39
54
  # casting them to a different block type via positional
40
55
  # attributes: verbatim types (`[source]`, `[listing]`,
@@ -86,22 +101,11 @@ module Coradoc
86
101
  end
87
102
 
88
103
  def transform_listing_from_open(block)
89
- content_lines = Array(block.lines).map { |line| ToCoreModel.extract_text_content(line) }.join("\n")
90
- Coradoc::CoreModel::ListingBlock.new(
91
- id: block.id,
92
- title: ToCoreModel.extract_title_text(block.title),
93
- content: content_lines,
94
- language: ToCoreModel.extract_block_language(block)
95
- )
104
+ transform_verbatim_block(block, Coradoc::CoreModel::ListingBlock)
96
105
  end
97
106
 
98
107
  def transform_literal_from_open(block)
99
- content_lines = Array(block.lines).map { |line| ToCoreModel.extract_text_content(line) }.join("\n")
100
- Coradoc::CoreModel::LiteralBlock.new(
101
- id: block.id,
102
- title: ToCoreModel.extract_title_text(block.title),
103
- content: content_lines
104
- )
108
+ transform_verbatim_block(block, Coradoc::CoreModel::LiteralBlock)
105
109
  end
106
110
 
107
111
  def transform_block(block, semantic_type_or_delimiter)
@@ -123,15 +127,14 @@ module Coradoc
123
127
  end
124
128
 
125
129
  def transform_typed_block(block, klass, extra_attrs = {})
126
- lines = Array(block.lines).reject do |line|
127
- line.is_a?(Coradoc::AsciiDoc::Model::LineBreak) ||
128
- line.is_a?(Coradoc::AsciiDoc::Model::Break::PageBreak)
129
- end
130
-
131
- has_nested_blocks = lines.any?(Coradoc::AsciiDoc::Model::Block::Core)
130
+ raw_lines = Array(block.lines)
131
+ has_nested_blocks = raw_lines.any?(Coradoc::AsciiDoc::Model::Block::Core)
132
132
 
133
133
  if has_nested_blocks
134
- children = lines.filter_map do |line|
134
+ children = raw_lines.reject do |line|
135
+ line.is_a?(Coradoc::AsciiDoc::Model::LineBreak) ||
136
+ line.is_a?(Coradoc::AsciiDoc::Model::Break::PageBreak)
137
+ end.filter_map do |line|
135
138
  result = ToCoreModel.transform(line)
136
139
  next nil if result.nil?
137
140
  next result if result.is_a?(Coradoc::CoreModel::Base)
@@ -149,15 +152,21 @@ module Coradoc
149
152
  **extra_attrs
150
153
  )
151
154
  else
152
- content_lines = lines.map { |line| ToCoreModel.extract_text_content(line) }.join("\n")
153
- children = lines.map do |line|
154
- inline = ToCoreModel.transform_inline_content(line)
155
- inline = [Coradoc::CoreModel::TextContent.new(text: "")] if inline.empty?
155
+ paragraph_groups = group_block_lines_into_paragraphs(raw_lines)
156
+
157
+ content_lines = paragraph_groups.map do |group|
158
+ ToCoreModel.extract_text_content(group)
159
+ end.join("\n\n")
160
+
161
+ children = paragraph_groups.map do |group|
162
+ inline = ToCoreModel.transform_inline_content(group)
163
+ inline = [Coradoc::CoreModel::TextContent.new(text: '')] if inline.empty?
156
164
  Coradoc::CoreModel::ParagraphBlock.new(
157
- content: ToCoreModel.extract_text_content(line),
165
+ content: ToCoreModel.extract_text_content(group),
158
166
  children: Array(inline)
159
167
  )
160
168
  end
169
+
161
170
  klass.new(
162
171
  id: block.id,
163
172
  title: ToCoreModel.extract_title_text(block.title),
@@ -168,6 +177,24 @@ module Coradoc
168
177
  )
169
178
  end
170
179
  end
180
+
181
+ # AsciiDoc joins consecutive non-blank lines into one paragraph;
182
+ # blank lines (parsed as Model::LineBreak) separate paragraphs.
183
+ def group_block_lines_into_paragraphs(lines)
184
+ groups = []
185
+ current = []
186
+ lines.each do |line|
187
+ if line.is_a?(Coradoc::AsciiDoc::Model::LineBreak) ||
188
+ line.is_a?(Coradoc::AsciiDoc::Model::Break::PageBreak)
189
+ groups << current if current.any?
190
+ current = []
191
+ else
192
+ current << line
193
+ end
194
+ end
195
+ groups << current if current.any?
196
+ groups
197
+ end
171
198
  end
172
199
  end
173
200
  end
@@ -48,9 +48,19 @@ module Coradoc
48
48
  id: section_id,
49
49
  level: section.level,
50
50
  title: title_text,
51
- children: content_children + nested_sections
51
+ children: content_children + nested_sections,
52
+ attributes: section_metadata_from(section)
52
53
  )
53
54
  end
55
+
56
+ # Delegates to Transform::AttributeListToMetadata for the typed
57
+ # Model::AttributeList -> CoreModel::Metadata conversion. The
58
+ # helper handles the nil/non-AttributeList guard and is the
59
+ # single source of truth shared with Builder::ElementBuilder.
60
+ def section_metadata_from(section)
61
+ Coradoc::AsciiDoc::Transform::AttributeListToMetadata
62
+ .call(section.attribute_list)
63
+ end
54
64
  end
55
65
  end
56
66
  end
@@ -50,9 +50,7 @@ module Coradoc
50
50
  {
51
51
  Coradoc::AsciiDoc::Model::Block::Quote => Coradoc::CoreModel::QuoteBlock,
52
52
  Coradoc::AsciiDoc::Model::Block::Example => Coradoc::CoreModel::ExampleBlock,
53
- Coradoc::AsciiDoc::Model::Block::Side => Coradoc::CoreModel::SidebarBlock,
54
- Coradoc::AsciiDoc::Model::Block::Literal => Coradoc::CoreModel::LiteralBlock,
55
- Coradoc::AsciiDoc::Model::Block::Pass => Coradoc::CoreModel::PassBlock
53
+ Coradoc::AsciiDoc::Model::Block::Side => Coradoc::CoreModel::SidebarBlock
56
54
  }.each do |block_class, core_model_class|
57
55
  Registry.register_with_priority(
58
56
  block_class,
@@ -61,6 +59,22 @@ module Coradoc
61
59
  )
62
60
  end
63
61
 
62
+ # Verbatim typed blocks (literal, pass) preserve their body
63
+ # byte-for-byte — same line-joining strategy as source/listing.
64
+ # Routing them through `transform_typed_block` would collapse
65
+ # intra-block whitespace and join consecutive lines as paragraphs.
66
+ Registry.register_with_priority(
67
+ Coradoc::AsciiDoc::Model::Block::Literal,
68
+ ->(model) { Blk.transform_literal_block(model) },
69
+ priority: 10
70
+ )
71
+
72
+ Registry.register_with_priority(
73
+ Coradoc::AsciiDoc::Model::Block::Pass,
74
+ ->(model) { Blk.transform_pass_block(model) },
75
+ priority: 10
76
+ )
77
+
64
78
  Registry.register_with_priority(
65
79
  Coradoc::AsciiDoc::Model::Block::Open,
66
80
  ->(model) { Blk.transform_open_block(model) },
@@ -14,6 +14,7 @@ module Coradoc
14
14
  autoload :ElementTransformers, "#{__dir__}/transform/element_transformers"
15
15
  autoload :FrontmatterAttributeMap, "#{__dir__}/transform/frontmatter_attribute_map"
16
16
  autoload :CalloutMerger, "#{__dir__}/transform/callout_merger"
17
+ autoload :AttributeListToMetadata, "#{__dir__}/transform/attribute_list_to_metadata"
17
18
  end
18
19
  end
19
20
  end
@@ -47,8 +47,12 @@ module Coradoc
47
47
  rule(list_item: subtree(:list_item)) do
48
48
  marker = list_item[:marker]
49
49
  id = list_item[:id]
50
- text = list_item[:text]
51
- text = list_item[:text].to_s if list_item[:text].instance_of?(Parslet::Slice)
50
+ lines = list_item[:lines]
51
+ content = if lines
52
+ Transformer.lines_to_text_elements(lines)
53
+ else
54
+ list_item[:text].to_s
55
+ end
52
56
  attached = list_item[:attached]
53
57
  nested = list_item[:nested]
54
58
  line_break = list_item[:line_break]
@@ -70,7 +74,7 @@ module Coradoc
70
74
  end
71
75
 
72
76
  Model::List::Item.new(
73
- content: text, id:, marker:, attached:, nested:, line_break:
77
+ content: content, id:, marker:, attached:, nested:, line_break:
74
78
  )
75
79
  end
76
80
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Coradoc
4
4
  module AsciiDoc
5
- VERSION = '2.0.16'
5
+ VERSION = '2.0.17'
6
6
  end
7
7
  end
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.16
4
+ version: 2.0.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -314,6 +314,7 @@ files:
314
314
  - lib/coradoc/asciidoc/serializer/serializers/video.rb
315
315
  - lib/coradoc/asciidoc/serializer/spacing_strategy.rb
316
316
  - lib/coradoc/asciidoc/transform.rb
317
+ - lib/coradoc/asciidoc/transform/attribute_list_to_metadata.rb
317
318
  - lib/coradoc/asciidoc/transform/callout_merger.rb
318
319
  - lib/coradoc/asciidoc/transform/element_transformers.rb
319
320
  - lib/coradoc/asciidoc/transform/element_transformers/block_transformer.rb