coradoc-markdown 1.0.9 → 1.0.11
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/markdown/model/admonition.rb +6 -7
- data/lib/coradoc/markdown/model/blockquote.rb +0 -5
- data/lib/coradoc/markdown/model/code_block.rb +0 -6
- data/lib/coradoc/markdown/model/comment.rb +1 -1
- data/lib/coradoc/markdown/model/definition_term.rb +0 -8
- data/lib/coradoc/markdown/model/example_block.rb +0 -7
- data/lib/coradoc/markdown/model/heading.rb +0 -6
- data/lib/coradoc/markdown/model/list_item.rb +1 -16
- data/lib/coradoc/markdown/model/literal.rb +0 -5
- data/lib/coradoc/markdown/model/open_block.rb +0 -5
- data/lib/coradoc/markdown/model/paragraph.rb +1 -14
- data/lib/coradoc/markdown/model/pass.rb +0 -5
- data/lib/coradoc/markdown/model/sidebar.rb +0 -7
- data/lib/coradoc/markdown/model/verse.rb +0 -7
- data/lib/coradoc/markdown/parser/ast_processor.rb +1 -1
- data/lib/coradoc/markdown/parser/block_parser.rb +13 -13
- data/lib/coradoc/markdown/parser/inline_parser.rb +1 -1
- data/lib/coradoc/markdown/parser_util.rb +2 -2
- data/lib/coradoc/markdown/serializer/config.rb +4 -10
- data/lib/coradoc/markdown/serializer/registry.rb +1 -1
- data/lib/coradoc/markdown/serializer/runner.rb +1 -1
- data/lib/coradoc/markdown/serializer/serializers/list.rb +1 -3
- data/lib/coradoc/markdown/serializer/strategies/definition_list/nested_html.rb +1 -1
- data/lib/coradoc/markdown/transform/from_core_model.rb +76 -12
- data/lib/coradoc/markdown/transform/list_transformer.rb +11 -5
- data/lib/coradoc/markdown/transform/structural_transformer.rb +1 -1
- data/lib/coradoc/markdown/transform/to_core_model.rb +3 -1
- data/lib/coradoc/markdown/version.rb +1 -1
- data/lib/coradoc/markdown.rb +9 -2
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 860562e968c6a646a564edac417a882d9d477ef09c7bb84c477a6ab13fcd6fd0
|
|
4
|
+
data.tar.gz: de5901c3b2e6eb123a718a14466d6bf688358e350ad95564abfcc17ebd62c660
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 313e3f097c07329bfacd65ce3283c33087136a9e3d8f5259298c40781b76d10495b98dd89c3c3977b27e40d667d0a056ef9c012dc89165bcecc47293333e3442
|
|
7
|
+
data.tar.gz: 5125a17bab25bde3da034de5b898fd28214f9e18857a9ca471e03795683fd2a9f85d3d7c3bd2925d0abf1f4b36acf6e37c71ef6f4ce2aa7389a65c7e562f8bf3
|
|
@@ -27,14 +27,13 @@ module Coradoc
|
|
|
27
27
|
# Mixed inline content (strings and inline model objects) carried
|
|
28
28
|
# from the CoreModel children so serializers can preserve cross
|
|
29
29
|
# references, code spans, etc. When empty, fall back to `content`.
|
|
30
|
-
|
|
30
|
+
attribute :children, Coradoc::Markdown::Base, collection: true, default: []
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
@children = Array(children)
|
|
32
|
+
# Normalize type on assignment. Callers can pass "NOTE", "Note",
|
|
33
|
+
# or "note" — storage is always lowercase so downstream comparison
|
|
34
|
+
# and CSS class generation don't need to repeat the normalization.
|
|
35
|
+
def admonition_type=(value)
|
|
36
|
+
super(value.to_s.downcase)
|
|
38
37
|
end
|
|
39
38
|
end
|
|
40
39
|
end
|
|
@@ -24,14 +24,6 @@ module Coradoc
|
|
|
24
24
|
# When present, the flat-PHP-Markdown-Extra syntax is no longer
|
|
25
25
|
# sufficient and the serializer falls back to HTML <dl>/<dt>/<dd>.
|
|
26
26
|
attribute :nested, Coradoc::Markdown::DefinitionList
|
|
27
|
-
|
|
28
|
-
def initialize(text: '', definitions: [], nested: nil, text_children: [], **rest)
|
|
29
|
-
super
|
|
30
|
-
@text = text
|
|
31
|
-
@definitions = definitions
|
|
32
|
-
@nested = nested
|
|
33
|
-
@text_children = Array(text_children)
|
|
34
|
-
end
|
|
35
27
|
end
|
|
36
28
|
end
|
|
37
29
|
end
|
|
@@ -16,13 +16,6 @@ module Coradoc
|
|
|
16
16
|
attribute :content, :string
|
|
17
17
|
attribute :caption, :string
|
|
18
18
|
attribute :children, Coradoc::Markdown::Base, collection: true, default: []
|
|
19
|
-
|
|
20
|
-
def initialize(content:, caption: nil, children: [], **rest)
|
|
21
|
-
super
|
|
22
|
-
@content = content
|
|
23
|
-
@caption = caption
|
|
24
|
-
@children = Array(children)
|
|
25
|
-
end
|
|
26
19
|
end
|
|
27
20
|
end
|
|
28
21
|
end
|
|
@@ -11,12 +11,6 @@ module Coradoc
|
|
|
11
11
|
attribute :level, :integer, default: 1
|
|
12
12
|
attribute :text, :string
|
|
13
13
|
|
|
14
|
-
def initialize(level: 1, text: '')
|
|
15
|
-
super()
|
|
16
|
-
@level = level
|
|
17
|
-
@text = text
|
|
18
|
-
end
|
|
19
|
-
|
|
20
14
|
# Generate an auto ID from the heading text
|
|
21
15
|
#
|
|
22
16
|
# @return [String] A slugified version of the text suitable for use as an ID
|
|
@@ -8,22 +8,7 @@ module Coradoc
|
|
|
8
8
|
attribute :text, :string
|
|
9
9
|
attribute :checked, :boolean # For task lists (- [ ] or - [x])
|
|
10
10
|
attribute :sublist, Coradoc::Markdown::List # Nested list
|
|
11
|
-
|
|
12
|
-
# Mixed content (strings and inline model objects)
|
|
13
|
-
# @return [Array] mixed content array
|
|
14
|
-
attr_reader :children
|
|
15
|
-
|
|
16
|
-
def initialize(args = {})
|
|
17
|
-
super()
|
|
18
|
-
@text = args[:text] || ''
|
|
19
|
-
@checked = args[:checked]
|
|
20
|
-
@sublist = args[:sublist]
|
|
21
|
-
@children = args.fetch(:children, [])
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def children=(value)
|
|
25
|
-
@children = value || []
|
|
26
|
-
end
|
|
11
|
+
attribute :children, Coradoc::Markdown::Base, collection: true, default: []
|
|
27
12
|
end
|
|
28
13
|
end
|
|
29
14
|
end
|
|
@@ -12,11 +12,6 @@ module Coradoc
|
|
|
12
12
|
# - With id/classes → emit `<div id="...">...</div>` wrapper
|
|
13
13
|
class OpenBlock < Base
|
|
14
14
|
attribute :children, Coradoc::Markdown::Base, collection: true, default: []
|
|
15
|
-
|
|
16
|
-
def initialize(children: [], **rest)
|
|
17
|
-
super
|
|
18
|
-
@children = Array(children)
|
|
19
|
-
end
|
|
20
15
|
end
|
|
21
16
|
end
|
|
22
17
|
end
|
|
@@ -9,20 +9,7 @@ module Coradoc
|
|
|
9
9
|
#
|
|
10
10
|
class Paragraph < Base
|
|
11
11
|
attribute :text, :string
|
|
12
|
-
|
|
13
|
-
# Mixed content (strings and inline model objects)
|
|
14
|
-
# @return [Array] mixed content array
|
|
15
|
-
attr_reader :children
|
|
16
|
-
|
|
17
|
-
def initialize(text: '', children: [])
|
|
18
|
-
super()
|
|
19
|
-
@text = text
|
|
20
|
-
@children = children
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def children=(value)
|
|
24
|
-
@children = value || []
|
|
25
|
-
end
|
|
12
|
+
attribute :children, Base, collection: true, default: []
|
|
26
13
|
end
|
|
27
14
|
end
|
|
28
15
|
end
|
|
@@ -13,13 +13,6 @@ module Coradoc
|
|
|
13
13
|
attribute :content, :string
|
|
14
14
|
attribute :title, :string
|
|
15
15
|
attribute :children, Coradoc::Markdown::Base, collection: true, default: []
|
|
16
|
-
|
|
17
|
-
def initialize(content:, title: nil, children: [], **rest)
|
|
18
|
-
super
|
|
19
|
-
@content = content
|
|
20
|
-
@title = title
|
|
21
|
-
@children = Array(children)
|
|
22
|
-
end
|
|
23
16
|
end
|
|
24
17
|
end
|
|
25
18
|
end
|
|
@@ -15,13 +15,6 @@ module Coradoc
|
|
|
15
15
|
attribute :content, :string
|
|
16
16
|
attribute :attribution, :string
|
|
17
17
|
attribute :citetitle, :string
|
|
18
|
-
|
|
19
|
-
def initialize(content:, attribution: nil, citetitle: nil, **rest)
|
|
20
|
-
super
|
|
21
|
-
@content = content
|
|
22
|
-
@attribution = attribution
|
|
23
|
-
@citetitle = citetitle
|
|
24
|
-
end
|
|
25
18
|
end
|
|
26
19
|
end
|
|
27
20
|
end
|
|
@@ -390,7 +390,7 @@ module Coradoc
|
|
|
390
390
|
|
|
391
391
|
# Pattern to match HTML tags with markdown attribute
|
|
392
392
|
# Captures: tag name, markdown value, content, closing tag
|
|
393
|
-
pattern = %r{<(#{HTML_TAG_PATTERN})\s+([^>]*?)markdown\s*=\s*["']([^"']+)["']([^>]*)>(.*?)</\1>}
|
|
393
|
+
pattern = %r{<(#{HTML_TAG_PATTERN})\s+([^>]*?)markdown\s*=\s*["']([^"']+)["']([^>]*)>(.*?)</\1>}imo
|
|
394
394
|
|
|
395
395
|
text.gsub(pattern) do |_match|
|
|
396
396
|
tag_name = ::Regexp.last_match(1)
|
|
@@ -23,9 +23,9 @@ module Coradoc
|
|
|
23
23
|
|
|
24
24
|
rule(:whitespace) { match[" \t"] }
|
|
25
25
|
# NOTE: repeat(1) before EOF (any.absent?) because infinite loop otherwise
|
|
26
|
-
rule(:blank_line) { (whitespace.repeat(1) >> any.absent? | whitespace.repeat >> line_ending).ignore }
|
|
26
|
+
rule(:blank_line) { ((whitespace.repeat(1) >> any.absent?) | (whitespace.repeat >> line_ending)).ignore }
|
|
27
27
|
rule(:blank_line_verbatim) do
|
|
28
|
-
whitespace.repeat(1).as(:ln) >> any.absent? | whitespace.repeat.as(:ln) >> line_ending
|
|
28
|
+
(whitespace.repeat(1).as(:ln) >> any.absent?) | (whitespace.repeat.as(:ln) >> line_ending)
|
|
29
29
|
end
|
|
30
30
|
rule(:line_char) { match["^\r\n"] }
|
|
31
31
|
rule(:line_verbatim) { line_char.repeat(1).as(:ln) >> line_ending_or_eof }
|
|
@@ -222,7 +222,7 @@ module Coradoc
|
|
|
222
222
|
end
|
|
223
223
|
|
|
224
224
|
rule(:paragraph_line) do
|
|
225
|
-
line_char.repeat(1).as(:ln) >> any.absent? | line_char.repeat.as(:ln) >> line_ending
|
|
225
|
+
(line_char.repeat(1).as(:ln) >> any.absent?) | (line_char.repeat.as(:ln) >> line_ending)
|
|
226
226
|
end
|
|
227
227
|
|
|
228
228
|
rule(:paragraph_continued_line) do
|
|
@@ -286,8 +286,8 @@ module Coradoc
|
|
|
286
286
|
rule(:ial_key_value) do
|
|
287
287
|
match['\\w\\-'].repeat(1) >> str('=') >>
|
|
288
288
|
(
|
|
289
|
-
str('"') >> match['^"'].repeat(0) >> str('"') |
|
|
290
|
-
str("'") >> match["^'"].repeat(0) >> str("'") |
|
|
289
|
+
(str('"') >> match['^"'].repeat(0) >> str('"')) |
|
|
290
|
+
(str("'") >> match["^'"].repeat(0) >> str("'")) |
|
|
291
291
|
match['^\\s\\}'].repeat(1)
|
|
292
292
|
)
|
|
293
293
|
end
|
|
@@ -322,8 +322,8 @@ module Coradoc
|
|
|
322
322
|
rule(:extension_option) do
|
|
323
323
|
match['\\w\\-'].repeat(1) >> str('=') >>
|
|
324
324
|
(
|
|
325
|
-
str('"') >> match['^"'].repeat(0) >> str('"') |
|
|
326
|
-
str("'") >> match["^'"].repeat(0) >> str("'") |
|
|
325
|
+
(str('"') >> match['^"'].repeat(0) >> str('"')) |
|
|
326
|
+
(str("'") >> match["^'"].repeat(0) >> str("'")) |
|
|
327
327
|
match['^\\s/\\}'].repeat(1)
|
|
328
328
|
)
|
|
329
329
|
end
|
|
@@ -466,11 +466,11 @@ module Coradoc
|
|
|
466
466
|
# List item continuation line (indented content that's not a block)
|
|
467
467
|
# Excludes lines that look like nested list markers
|
|
468
468
|
rule(:list_continuation_line) do
|
|
469
|
-
(str(' ') | str("\t")) >>
|
|
470
|
-
nested_list_marker.absent? >>
|
|
471
|
-
line_verbatim |
|
|
469
|
+
((str(' ') | str("\t")) >>
|
|
472
470
|
nested_list_marker.absent? >>
|
|
473
|
-
line_verbatim
|
|
471
|
+
line_verbatim) |
|
|
472
|
+
(nested_list_marker.absent? >>
|
|
473
|
+
line_verbatim)
|
|
474
474
|
end
|
|
475
475
|
|
|
476
476
|
# Nested list marker detection (for 4-space indented lists)
|
|
@@ -513,8 +513,8 @@ module Coradoc
|
|
|
513
513
|
|
|
514
514
|
# Nested block (indented list, etc.)
|
|
515
515
|
rule(:nested_block) do
|
|
516
|
-
(str(' ') | str("\t")) >> nested_unordered_list |
|
|
517
|
-
(str(' ') | str("\t")) >> nested_ordered_list
|
|
516
|
+
((str(' ') | str("\t")) >> nested_unordered_list) |
|
|
517
|
+
((str(' ') | str("\t")) >> nested_ordered_list)
|
|
518
518
|
end
|
|
519
519
|
|
|
520
520
|
# Nested unordered list (4-space indented)
|
|
@@ -71,11 +71,11 @@ module Coradoc
|
|
|
71
71
|
def self.extract_quoted_value(scanner, handle_escapes: false)
|
|
72
72
|
if scanner.scan(/"([^"\\]*(?:\\.[^"\\]*)*)"/)
|
|
73
73
|
value = scanner[1]
|
|
74
|
-
value = value.gsub(
|
|
74
|
+
value = value.gsub('\"', '"') if handle_escapes
|
|
75
75
|
value
|
|
76
76
|
elsif scanner.scan(/'([^'\\]*(?:\\.[^'\\]*)*)'/)
|
|
77
77
|
value = scanner[1]
|
|
78
|
-
value = value.gsub(
|
|
78
|
+
value = value.gsub('\\\'', "'") if handle_escapes
|
|
79
79
|
value
|
|
80
80
|
elsif scanner.scan(/(\S+)/)
|
|
81
81
|
scanner[1]
|
|
@@ -48,7 +48,7 @@ module Coradoc
|
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def with(overrides)
|
|
51
|
-
self.class.new(**to_h
|
|
51
|
+
self.class.new(**to_h, **symbolize(overrides))
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
private
|
|
@@ -58,15 +58,9 @@ module Coradoc
|
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def validate_options!(resolved)
|
|
61
|
-
unless %i[github container html gfm_alert].include?(resolved.fetch(:admonition_style))
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
unless %i[html flatten].include?(resolved.fetch(:definition_list_nested))
|
|
65
|
-
raise ArgumentError, "Unknown definition_list_nested: #{resolved[:definition_list_nested].inspect}"
|
|
66
|
-
end
|
|
67
|
-
unless [true, false].include?(resolved.fetch(:suppress_comments))
|
|
68
|
-
raise ArgumentError, 'suppress_comments must be boolean'
|
|
69
|
-
end
|
|
61
|
+
raise ArgumentError, "Unknown admonition_style: #{resolved[:admonition_style].inspect}" unless %i[github container html gfm_alert].include?(resolved.fetch(:admonition_style))
|
|
62
|
+
raise ArgumentError, "Unknown definition_list_nested: #{resolved[:definition_list_nested].inspect}" unless %i[html flatten].include?(resolved.fetch(:definition_list_nested))
|
|
63
|
+
raise ArgumentError, 'suppress_comments must be boolean' unless [true, false].include?(resolved.fetch(:suppress_comments))
|
|
70
64
|
return if [true, false].include?(resolved.fetch(:autolinks))
|
|
71
65
|
|
|
72
66
|
raise ArgumentError, 'autolinks must be boolean'
|
|
@@ -13,9 +13,7 @@ module Coradoc
|
|
|
13
13
|
marker = element.ordered ? '1.' : '-'
|
|
14
14
|
element.items.flat_map do |item|
|
|
15
15
|
lines = [render_item(item, marker, _ctx)]
|
|
16
|
-
if item.sublist
|
|
17
|
-
lines += call(item.sublist, _ctx).split("\n").map { |l| " #{l}" }
|
|
18
|
-
end
|
|
16
|
+
lines += call(item.sublist, _ctx).split("\n").map { |l| " #{l}" } if item.sublist
|
|
19
17
|
lines
|
|
20
18
|
end.join("\n")
|
|
21
19
|
end
|
|
@@ -35,7 +35,7 @@ module Coradoc
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def render_term(term)
|
|
38
|
-
dt = "<dt>#{term.text
|
|
38
|
+
dt = "<dt>#{term.text}</dt>"
|
|
39
39
|
dds = term.definitions.map { |d| render_dd(d) }.join
|
|
40
40
|
nested = term.nested ? "\n #{render_dl(term.nested)}" : ''
|
|
41
41
|
"#{dt}\n#{dds}#{nested unless nested.empty?}"
|
|
@@ -55,6 +55,8 @@ module Coradoc
|
|
|
55
55
|
Coradoc::Markdown::Text.new(content: model.title.to_s)
|
|
56
56
|
when Coradoc::CoreModel::CommentLine
|
|
57
57
|
Coradoc::Markdown::Comment.new(text: model.text.to_s)
|
|
58
|
+
when Coradoc::CoreModel::Include
|
|
59
|
+
transform_include(model)
|
|
58
60
|
when Coradoc::CoreModel::TextContent
|
|
59
61
|
model.text.to_s
|
|
60
62
|
when Array
|
|
@@ -66,6 +68,17 @@ module Coradoc
|
|
|
66
68
|
|
|
67
69
|
private
|
|
68
70
|
|
|
71
|
+
# Markdown has no transclusion — an unresolved include edge is
|
|
72
|
+
# preserved as an HTML comment so no information is lost and
|
|
73
|
+
# serialization never crashes on graph-mode documents.
|
|
74
|
+
def transform_include(element)
|
|
75
|
+
Coradoc::Markdown::Comment.new(text: include_directive_text(element))
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def include_directive_text(element)
|
|
79
|
+
"include::#{element.target}[#{element.raw_options}]"
|
|
80
|
+
end
|
|
81
|
+
|
|
69
82
|
def transform_structural_element(element)
|
|
70
83
|
case element
|
|
71
84
|
when CoreModel::DocumentElement
|
|
@@ -219,7 +232,7 @@ module Coradoc
|
|
|
219
232
|
def transform_verse_block(block)
|
|
220
233
|
Coradoc::Markdown::Verse.new(
|
|
221
234
|
content: block.flat_text,
|
|
222
|
-
attribution: block.
|
|
235
|
+
attribution: block.is_a?(Coradoc::CoreModel::VerseBlock) ? block.attribution : nil
|
|
223
236
|
)
|
|
224
237
|
end
|
|
225
238
|
|
|
@@ -272,10 +285,17 @@ module Coradoc
|
|
|
272
285
|
|
|
273
286
|
def transform_admonition_block(block, default_type: 'note')
|
|
274
287
|
children = transform_inline_array(block.renderable_content)
|
|
288
|
+
if block.is_a?(Coradoc::CoreModel::AnnotationBlock)
|
|
289
|
+
adm_type = block.annotation_type || default_type
|
|
290
|
+
adm_label = block.annotation_label
|
|
291
|
+
else
|
|
292
|
+
adm_type = default_type
|
|
293
|
+
adm_label = nil
|
|
294
|
+
end
|
|
275
295
|
Coradoc::Markdown::Admonition.new(
|
|
276
|
-
admonition_type:
|
|
296
|
+
admonition_type: adm_type,
|
|
277
297
|
content: block.flat_text,
|
|
278
|
-
title:
|
|
298
|
+
title: adm_label,
|
|
279
299
|
children: children
|
|
280
300
|
)
|
|
281
301
|
end
|
|
@@ -374,7 +394,7 @@ module Coradoc
|
|
|
374
394
|
)
|
|
375
395
|
end
|
|
376
396
|
|
|
377
|
-
CALLOUT_MARKER_IN_CELL = /\s*<\d+>(?=\s|\z)
|
|
397
|
+
CALLOUT_MARKER_IN_CELL = /\s*<\d+>(?=\s|\z)/
|
|
378
398
|
|
|
379
399
|
def strip_cell_callouts(text)
|
|
380
400
|
text.to_s.gsub(CALLOUT_MARKER_IN_CELL, '')
|
|
@@ -428,21 +448,52 @@ module Coradoc
|
|
|
428
448
|
end
|
|
429
449
|
|
|
430
450
|
def transform_definition_list(dl)
|
|
431
|
-
|
|
432
|
-
|
|
451
|
+
# flat_map because each CoreModel DefinitionItem may emit
|
|
452
|
+
# multiple Markdown DefinitionTerms (multi-term `<dt>`).
|
|
453
|
+
items = Array(dl.items).flat_map do |item|
|
|
454
|
+
definitions = [build_definition_item(item)]
|
|
455
|
+
# `+`-continuation blocks attached to the dd become
|
|
456
|
+
# additional definitions in Markdown (each renders as
|
|
457
|
+
# `: line` in the Flat serializer). One DefinitionItem
|
|
458
|
+
# per attached block, preserving their distinct content
|
|
459
|
+
# without jamming them into the primary definition's text.
|
|
460
|
+
definitions.concat(Array(item.attached_children).map { |b| build_attached_definition_item(b) })
|
|
433
461
|
nested = item.nested ? transform_definition_list(item.nested) : nil
|
|
434
462
|
term_children = Array(item.term_children).map { |c| transform_inline_content(c) }
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
)
|
|
463
|
+
# Multi-term `<dt>`: emit one Markdown DefinitionTerm per
|
|
464
|
+
# term string. Inline children map 1:1 to the FIRST term
|
|
465
|
+
# (matches the mirror handler's behaviour; multi-term
|
|
466
|
+
# with inline markup on later terms is rare and the
|
|
467
|
+
# parser doesn't capture per-term children today).
|
|
468
|
+
terms = terms_for(item)
|
|
469
|
+
if terms.empty?
|
|
470
|
+
# Defensive: term and terms both empty — emit nothing.
|
|
471
|
+
next
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
terms.each_with_index.map do |term_text, idx|
|
|
475
|
+
Coradoc::Markdown::DefinitionTerm.new(
|
|
476
|
+
text: term_text.to_s,
|
|
477
|
+
text_children: idx.zero? ? term_children : [],
|
|
478
|
+
definitions: definitions,
|
|
479
|
+
nested: nested
|
|
480
|
+
)
|
|
481
|
+
end
|
|
441
482
|
end
|
|
442
483
|
|
|
443
484
|
Coradoc::Markdown::DefinitionList.new(items: items)
|
|
444
485
|
end
|
|
445
486
|
|
|
487
|
+
# Source of truth for "the terms on this <dt>": the `terms`
|
|
488
|
+
# collection when populated, else `[term]` for legacy callers.
|
|
489
|
+
def terms_for(item)
|
|
490
|
+
collection = item.terms if item.is_a?(Coradoc::CoreModel::DefinitionItem)
|
|
491
|
+
return Array(collection) unless collection.nil? || collection.empty?
|
|
492
|
+
|
|
493
|
+
primary = item.term
|
|
494
|
+
primary.to_s.empty? ? [] : [primary.to_s]
|
|
495
|
+
end
|
|
496
|
+
|
|
446
497
|
def build_definition_item(item)
|
|
447
498
|
children = Array(item.definition_children)
|
|
448
499
|
if children.empty?
|
|
@@ -457,6 +508,19 @@ module Coradoc
|
|
|
457
508
|
)
|
|
458
509
|
end
|
|
459
510
|
|
|
511
|
+
# Build a DefinitionItem from a single attached block (e.g.
|
|
512
|
+
# paragraph from a `+`-continuation). Flat-text extraction
|
|
513
|
+
# via ChildrenContent is the single source of truth — every
|
|
514
|
+
# attached block in CoreModel includes ChildrenContent.
|
|
515
|
+
def build_attached_definition_item(block)
|
|
516
|
+
content = if block.is_a?(Coradoc::CoreModel::ChildrenContent)
|
|
517
|
+
block.flat_text
|
|
518
|
+
else
|
|
519
|
+
block.to_s
|
|
520
|
+
end
|
|
521
|
+
Coradoc::Markdown::DefinitionItem.new(content: content)
|
|
522
|
+
end
|
|
523
|
+
|
|
460
524
|
def transform_footnote(fn)
|
|
461
525
|
Coradoc::Markdown::Footnote.new(
|
|
462
526
|
id: fn.id.to_s,
|
|
@@ -30,14 +30,20 @@ module Coradoc
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def transform_definition_list(dl)
|
|
33
|
-
|
|
33
|
+
# flat_map because multi-term `<dt>`'s emit multiple
|
|
34
|
+
# DefinitionTerms per CoreModel DefinitionItem.
|
|
35
|
+
items = Array(dl.items).flat_map do |item|
|
|
34
36
|
definitions = Array(item.definitions).map do |defn|
|
|
35
37
|
Coradoc::Markdown::DefinitionItem.new(content: defn.to_s)
|
|
36
38
|
end
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
terms = item.terms
|
|
40
|
+
term_strings = terms.nil? || terms.empty? ? [item.term.to_s] : terms.map(&:to_s)
|
|
41
|
+
term_strings.map do |term_text|
|
|
42
|
+
Coradoc::Markdown::DefinitionTerm.new(
|
|
43
|
+
text: term_text,
|
|
44
|
+
definitions: definitions
|
|
45
|
+
)
|
|
46
|
+
end
|
|
41
47
|
end
|
|
42
48
|
|
|
43
49
|
Coradoc::Markdown::DefinitionList.new(items: items)
|
|
@@ -80,7 +80,7 @@ module Coradoc
|
|
|
80
80
|
def transform_bibliography_entry(entry)
|
|
81
81
|
FromCoreModel.transform_bibliography_entry(entry)
|
|
82
82
|
end
|
|
83
|
-
end
|
|
83
|
+
end
|
|
84
84
|
|
|
85
85
|
# Register with FromCoreModel
|
|
86
86
|
FromCoreModel.register(CoreModel::StructuralElement, method(:transform_structural_element))
|
|
@@ -165,7 +165,9 @@ module Coradoc
|
|
|
165
165
|
cells = if row.is_a?(Array)
|
|
166
166
|
row.map { |c| Coradoc::CoreModel::TableCell.new(content: c.to_s, header: false) }
|
|
167
167
|
else
|
|
168
|
-
row.to_s.split(' | ').map
|
|
168
|
+
row.to_s.split(' | ').map do |c|
|
|
169
|
+
Coradoc::CoreModel::TableCell.new(content: c.to_s, header: false)
|
|
170
|
+
end
|
|
169
171
|
end
|
|
170
172
|
rows << Coradoc::CoreModel::TableRow.new(cells: cells)
|
|
171
173
|
end
|
data/lib/coradoc/markdown.rb
CHANGED
|
@@ -127,9 +127,9 @@ module Coradoc
|
|
|
127
127
|
# @param filename [String] Path to the Markdown file
|
|
128
128
|
# @param options [Hash] Parsing options (see #parse)
|
|
129
129
|
# @return [Array] The parsed AST
|
|
130
|
-
def from_file(filename, **
|
|
130
|
+
def from_file(filename, **)
|
|
131
131
|
content = File.read(filename)
|
|
132
|
-
parse(content, **
|
|
132
|
+
parse(content, **)
|
|
133
133
|
end
|
|
134
134
|
|
|
135
135
|
# Parse inline Markdown content
|
|
@@ -150,6 +150,13 @@ module Coradoc
|
|
|
150
150
|
Serializer.serialize(document, options)
|
|
151
151
|
end
|
|
152
152
|
|
|
153
|
+
# Markdown preserves unresolved include edges as HTML comments
|
|
154
|
+
# (Transform::FromCoreModel#transform_include) — lossy formatting,
|
|
155
|
+
# but never silent content loss.
|
|
156
|
+
def preserves_unresolved_includes?
|
|
157
|
+
true
|
|
158
|
+
end
|
|
159
|
+
|
|
153
160
|
# Check if this format can transform the given model to CoreModel
|
|
154
161
|
#
|
|
155
162
|
# @param model [Object] The model to check
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: coradoc-markdown
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.11
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -232,6 +232,7 @@ metadata:
|
|
|
232
232
|
homepage_uri: https://github.com/metanorma/coradoc
|
|
233
233
|
source_code_uri: https://github.com/metanorma/coradoc
|
|
234
234
|
changelog_uri: https://github.com/metanorma/coradoc/releases
|
|
235
|
+
rubygems_mfa_required: 'true'
|
|
235
236
|
rdoc_options: []
|
|
236
237
|
require_paths:
|
|
237
238
|
- lib
|