coradoc-adoc 2.0.30 → 2.0.31

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: 79a252c883acda46234ba968656577308075f2c1694ee2cdff96aa78006d3fe4
4
- data.tar.gz: 20186d4848bfe7a63a16a11a43ce3b6ae861bb1bf60be7a71af4d96e7e31ea2b
3
+ metadata.gz: 22eb5a515f97c8954148e99ef280dd4bb8ac3bed03d59d745291dc3d7ac302c2
4
+ data.tar.gz: 0435ded18a2f7895426d1de9aba45c5c3ccaeea442c287fb1f5cd6d14581b117
5
5
  SHA512:
6
- metadata.gz: dbb9841fe7829f87693c9d31bea1303d2f00c1762810e0f948112e01a6958210700bf90e5df15b3685fb49868dba22cf77f169e8842e420c15fa43e1160ec266
7
- data.tar.gz: eb765458ac486a19fca72b69fcb15dea61eb09bb4c0f7ab1bc48793997653ae64dc24dbcd070fa526f3f9b8f467a6a7e157e353719a08d6ed2f795e5e2a1de7d
6
+ metadata.gz: cc35eb17f93b7c78fc2f935cf71ef18d76af08eb36a52ab7040d90e735c72a4d1f990339fc414803ccbf767d0b57bf636be79d76940fa8a091e52bcd37091544
7
+ data.tar.gz: 8c93968c63d400dfb86d0855c6bb1a2ebc6bbe200a85b07da5d2861771baeacf2beb11cd811c136e912fae302d0003c8aa822f12c73ef2ae5d127ced9caea829
@@ -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 with annotation_type set from the style and
173
- # the block's body lines joined into a single content string.
174
- # Type is canonicalised via AdmonitionStyles so every code path
175
- # (line admonition, block admonition, attribute-cast admonition)
176
- # produces the same uppercase key.
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
- content_lines = Array(block.lines).map { |line| ToCoreModel.extract_text_content(line) }.join("\n")
180
- Coradoc::CoreModel::AnnotationBlock.new(
181
- annotation_type: canonical,
182
- content: content_lines,
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
- raw_lines = Array(block.lines)
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
- klass.new(
260
- id: block.id,
261
- title: ToCoreModel.extract_title_text(block.title),
262
- content: content_lines,
263
- children: children,
264
- language: ToCoreModel.extract_block_language(block),
265
- source_line: block.source_line,
266
- **extra_attrs
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
- # AsciiDoc joins consecutive non-blank lines into one paragraph;
272
- # blank lines (parsed as Model::LineBreak) separate paragraphs.
273
- def group_block_lines_into_paragraphs(lines)
274
- groups = []
275
- current = []
276
- lines.each do |line|
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
- groups << current if current.any?
280
- current = []
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
- current << line
272
+ pending_inline << line
283
273
  end
284
274
  end
285
- groups << current if current.any?
286
- groups
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Coradoc
4
4
  module AsciiDoc
5
- VERSION = '2.0.30'
5
+ VERSION = '2.0.31'
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.30
4
+ version: 2.0.31
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.