coradoc-adoc 2.0.23 → 2.0.25
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/builder/detection.rb +4 -4
- data/lib/coradoc/asciidoc/model/attribute_list/matchers.rb +4 -4
- data/lib/coradoc/asciidoc/model/base.rb +7 -0
- data/lib/coradoc/asciidoc/model/block/core.rb +1 -1
- data/lib/coradoc/asciidoc/model/content_list.rb +8 -8
- data/lib/coradoc/asciidoc/model/inline/bold.rb +1 -1
- data/lib/coradoc/asciidoc/model/inline/highlight.rb +1 -1
- data/lib/coradoc/asciidoc/model/inline/italic.rb +1 -1
- data/lib/coradoc/asciidoc/model/inline/monospace.rb +1 -1
- data/lib/coradoc/asciidoc/model/inline/strikethrough.rb +2 -2
- data/lib/coradoc/asciidoc/model/inline/subscript.rb +1 -1
- data/lib/coradoc/asciidoc/model/inline/superscript.rb +1 -1
- data/lib/coradoc/asciidoc/model/serialization/asciidoc_mapping.rb +3 -4
- data/lib/coradoc/asciidoc/model/text_element.rb +22 -0
- data/lib/coradoc/asciidoc/parser/block.rb +3 -3
- data/lib/coradoc/asciidoc/transform/element_transformers/admonition_styles.rb +6 -1
- data/lib/coradoc/asciidoc/transform/element_transformers/block_transformer.rb +39 -16
- data/lib/coradoc/asciidoc/transform/element_transformers/document_transformer.rb +2 -27
- data/lib/coradoc/asciidoc/transform/element_transformers/include_transformer.rb +2 -1
- data/lib/coradoc/asciidoc/transform/element_transformers/inline_transformer.rb +12 -6
- data/lib/coradoc/asciidoc/transform/element_transformers/list_transformer.rb +10 -4
- data/lib/coradoc/asciidoc/transform/element_transformers/other_transformer.rb +10 -5
- data/lib/coradoc/asciidoc/transform/element_transformers/table_transformer.rb +6 -3
- data/lib/coradoc/asciidoc/transform/from_core_model.rb +6 -30
- data/lib/coradoc/asciidoc/transform/inline_transform_visitor.rb +28 -5
- data/lib/coradoc/asciidoc/transform/to_core_model.rb +30 -6
- data/lib/coradoc/asciidoc/transformer/block_rules.rb +8 -2
- data/lib/coradoc/asciidoc/transformer/block_type_classifier.rb +10 -10
- data/lib/coradoc/asciidoc/transformer/header_rules.rb +9 -3
- data/lib/coradoc/asciidoc/transformer/inline_rules.rb +39 -15
- data/lib/coradoc/asciidoc/transformer/list_rules.rb +14 -4
- data/lib/coradoc/asciidoc/transformer/misc_rules.rb +14 -5
- data/lib/coradoc/asciidoc/transformer/source_line_extractor.rb +66 -0
- data/lib/coradoc/asciidoc/transformer/table_layout.rb +1 -3
- data/lib/coradoc/asciidoc/transformer/text_rules.rb +21 -6
- data/lib/coradoc/asciidoc/transformer.rb +30 -1
- data/lib/coradoc/asciidoc/version.rb +1 -1
- 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: 4ecb988af13f918e49f0249e3691e22fd98f21beffd3f0e2d6c98affc39d64dc
|
|
4
|
+
data.tar.gz: 4db6ab5b2227364c2092f00b40167fa054ed1dd43592150baf1c745e39f98a09
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 26ea9aeac36925a4ce0df0221ffba1e0c5ba41fc33de0b8c0937229e353f2f758e101a873e0eab76ed46408fe71990c0001088612ecef50c0f3a22fba17646db
|
|
7
|
+
data.tar.gz: 2a7a709b48e9c0764c12b5a54be0846ecd08551245e92dd6028deb881c1ebff634514445a72cf28d24a6e31a5bdd90b12c6519e523e440977a7bfe9f767949a5
|
|
@@ -70,10 +70,10 @@ module Coradoc
|
|
|
70
70
|
return false
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
-
key = "#{format_type}_constrained"
|
|
73
|
+
key = :"#{format_type}_constrained"
|
|
74
74
|
return true if ast.key?(key)
|
|
75
75
|
|
|
76
|
-
unconstrained_key = "#{format_type}_unconstrained"
|
|
76
|
+
unconstrained_key = :"#{format_type}_unconstrained"
|
|
77
77
|
return false if ast.key?(unconstrained_key)
|
|
78
78
|
|
|
79
79
|
true
|
|
@@ -158,8 +158,8 @@ module Coradoc
|
|
|
158
158
|
def extract_inline_content(ast, format_type)
|
|
159
159
|
content_key = format_type.to_sym
|
|
160
160
|
content = ast[content_key] ||
|
|
161
|
-
ast["#{format_type}_constrained"
|
|
162
|
-
ast["#{format_type}_unconstrained"
|
|
161
|
+
ast[:"#{format_type}_constrained"] ||
|
|
162
|
+
ast[:"#{format_type}_unconstrained"]
|
|
163
163
|
|
|
164
164
|
extract_text_content(content)
|
|
165
165
|
end
|
|
@@ -5,8 +5,8 @@ module Coradoc
|
|
|
5
5
|
module Model
|
|
6
6
|
class AttributeList < Base
|
|
7
7
|
module Matchers
|
|
8
|
-
def one(*
|
|
9
|
-
One.new(*
|
|
8
|
+
def one(*)
|
|
9
|
+
One.new(*)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
class One
|
|
@@ -19,8 +19,8 @@ module Coradoc
|
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
def many(*
|
|
23
|
-
Many.new(*
|
|
22
|
+
def many(*)
|
|
23
|
+
Many.new(*)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
# NOTE: The Many matcher validates that all values in an array/string match
|
|
@@ -35,6 +35,13 @@ module Coradoc
|
|
|
35
35
|
|
|
36
36
|
attribute :id, :string
|
|
37
37
|
|
|
38
|
+
# 1-indexed source line where this element begins, when known.
|
|
39
|
+
# Populated by the Parslet transformer from the matched Slice's
|
|
40
|
+
# line_and_column. nil for programmatically constructed models.
|
|
41
|
+
# Single source of truth for source-position propagation through
|
|
42
|
+
# AsciiDoc::Model → CoreModel (Issue 1, STATUS-2026-06-28).
|
|
43
|
+
attribute :source_line, :integer
|
|
44
|
+
|
|
38
45
|
# Element classification for spacing and serialization decisions.
|
|
39
46
|
# Subclasses override these to declare their level.
|
|
40
47
|
def block_level?
|
|
@@ -54,7 +54,7 @@ module Coradoc
|
|
|
54
54
|
include Coradoc::AsciiDoc::Model::Anchorable
|
|
55
55
|
|
|
56
56
|
attribute :id, :string
|
|
57
|
-
attribute :title, :string, default: -> {
|
|
57
|
+
attribute :title, :string, default: -> {} # Polymorphic: string or array of Model objects
|
|
58
58
|
attribute :attributes, Coradoc::AsciiDoc::Model::AttributeList, default: lambda {
|
|
59
59
|
Coradoc::AsciiDoc::Model::AttributeList.new
|
|
60
60
|
}
|
|
@@ -86,8 +86,8 @@ module Coradoc
|
|
|
86
86
|
# @example Iterate
|
|
87
87
|
# content.each { |item| puts item }
|
|
88
88
|
#
|
|
89
|
-
def each(&
|
|
90
|
-
@items.each(&
|
|
89
|
+
def each(&)
|
|
90
|
+
@items.each(&)
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
# Add an item to the content
|
|
@@ -199,8 +199,8 @@ module Coradoc
|
|
|
199
199
|
# @example Map
|
|
200
200
|
# content.map(&:class) # => [String, Bold, String]
|
|
201
201
|
#
|
|
202
|
-
def map(&
|
|
203
|
-
@items.map(&
|
|
202
|
+
def map(&)
|
|
203
|
+
@items.map(&)
|
|
204
204
|
end
|
|
205
205
|
|
|
206
206
|
# Select items matching predicate
|
|
@@ -211,8 +211,8 @@ module Coradoc
|
|
|
211
211
|
# @example Select strings
|
|
212
212
|
# content.select { |i| i.is_a?(String) }
|
|
213
213
|
#
|
|
214
|
-
def select(&
|
|
215
|
-
@items.select(&
|
|
214
|
+
def select(&)
|
|
215
|
+
@items.select(&)
|
|
216
216
|
end
|
|
217
217
|
|
|
218
218
|
# Reject items matching predicate
|
|
@@ -220,8 +220,8 @@ module Coradoc
|
|
|
220
220
|
# @yield [Object] Each item
|
|
221
221
|
# @return [Array] Remaining items
|
|
222
222
|
#
|
|
223
|
-
def reject(&
|
|
224
|
-
@items.reject(&
|
|
223
|
+
def reject(&)
|
|
224
|
+
@items.reject(&)
|
|
225
225
|
end
|
|
226
226
|
|
|
227
227
|
# Check if content includes an item
|
|
@@ -25,12 +25,12 @@ module Coradoc
|
|
|
25
25
|
class Strikethrough < Base
|
|
26
26
|
attribute :content,
|
|
27
27
|
Lutaml::Model::Serializable,
|
|
28
|
-
default: -> {
|
|
28
|
+
default: -> {},
|
|
29
29
|
polymorphic: [
|
|
30
30
|
Lutaml::Model::Type::String,
|
|
31
31
|
:array
|
|
32
32
|
]
|
|
33
|
-
attribute :text, :string, default: -> {
|
|
33
|
+
attribute :text, :string, default: -> {}
|
|
34
34
|
attribute :unconstrained, :boolean, default: -> { false }
|
|
35
35
|
end
|
|
36
36
|
end
|
|
@@ -6,8 +6,7 @@ module Coradoc
|
|
|
6
6
|
module Serialization
|
|
7
7
|
# Define the DSL for defining mappings in Asciidoc format
|
|
8
8
|
class AsciidocMapping < Lutaml::Model::Mapping
|
|
9
|
-
|
|
10
|
-
attr_writer :mappings
|
|
9
|
+
attr_accessor :mappings
|
|
11
10
|
|
|
12
11
|
def initialize
|
|
13
12
|
super
|
|
@@ -33,8 +32,8 @@ module Coradoc
|
|
|
33
32
|
|
|
34
33
|
private
|
|
35
34
|
|
|
36
|
-
def add_mapping(name, to, **
|
|
37
|
-
@mappings << AsciidocMappingRule.new(name, to: to, **
|
|
35
|
+
def add_mapping(name, to, **)
|
|
36
|
+
@mappings << AsciidocMappingRule.new(name, to: to, **)
|
|
38
37
|
end
|
|
39
38
|
end
|
|
40
39
|
end
|
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
module Coradoc
|
|
4
4
|
module AsciiDoc
|
|
5
5
|
module Model
|
|
6
|
+
# Single source of truth for the markers AsciiDoc uses to terminate
|
|
7
|
+
# a TextElement. Exposed as a module so the transformer can compare
|
|
8
|
+
# against the constant without hand-writing string literals across
|
|
9
|
+
# the codebase (DRY), and so future markers (e.g. a hypothetical
|
|
10
|
+
# backslash-style hard break) extend one place.
|
|
11
|
+
module LineBreakMarker
|
|
12
|
+
HARD = '+'
|
|
13
|
+
end
|
|
14
|
+
private_constant :LineBreakMarker
|
|
15
|
+
|
|
6
16
|
class TextElement < Base
|
|
7
17
|
def inline?
|
|
8
18
|
true
|
|
@@ -18,6 +28,18 @@ module Coradoc
|
|
|
18
28
|
]
|
|
19
29
|
attribute :line_break, :string, default: -> { '' }
|
|
20
30
|
|
|
31
|
+
# Semantic predicates over the line-break marker. Consumers (the
|
|
32
|
+
# transformer, the serializer) call these instead of comparing
|
|
33
|
+
# line_break against literal strings, so the wire format for
|
|
34
|
+
# hard breaks is owned by the model layer (SRP).
|
|
35
|
+
def hard_break?
|
|
36
|
+
line_break == LineBreakMarker::HARD
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def soft_break?
|
|
40
|
+
line_break.to_s.empty?
|
|
41
|
+
end
|
|
42
|
+
|
|
21
43
|
def self.escape_keychars(string)
|
|
22
44
|
subs = { '*' => '\*', '_' => '\_' }
|
|
23
45
|
string
|
|
@@ -73,14 +73,14 @@ module Coradoc
|
|
|
73
73
|
closing_fence = dynamic do |_s, c|
|
|
74
74
|
str(c.captures[capture_key].to_s.strip)
|
|
75
75
|
end
|
|
76
|
-
language = (space? >> match(
|
|
76
|
+
language = (space? >> match('[A-Za-z0-9_+.-]').repeat(1).as(:language)).maybe
|
|
77
77
|
|
|
78
78
|
block_content_with_closing = dynamic do |_s, c|
|
|
79
|
-
|
|
79
|
+
c.captures[capture_key].to_s.strip
|
|
80
80
|
closing_pattern = closing_fence >> space? >> newline
|
|
81
81
|
|
|
82
82
|
content = text_line(false, unguarded: true, verbatim: true) |
|
|
83
|
-
|
|
83
|
+
empty_line.as(:line_break)
|
|
84
84
|
|
|
85
85
|
(closing_pattern.absent? >> content).repeat(1)
|
|
86
86
|
end
|
|
@@ -13,7 +13,12 @@ module Coradoc
|
|
|
13
13
|
# block-form transformer that needs to decide between an admonition
|
|
14
14
|
# and the block's native type.
|
|
15
15
|
module AdmonitionStyles
|
|
16
|
-
|
|
16
|
+
# Generic `[admonition]` (capitalized as ADMONITION by
|
|
17
|
+
# +canonicalize+) is the spec-defined generic admonition style.
|
|
18
|
+
# It is rarely used directly but exists in the AsciiDoc spec;
|
|
19
|
+
# treating it as a real admonition prevents it from collapsing
|
|
20
|
+
# to an ExampleBlock when applied to a delimited block.
|
|
21
|
+
BUILTIN = %w[note tip warning caution important editor todo admonition].freeze
|
|
17
22
|
|
|
18
23
|
@custom = []
|
|
19
24
|
|
|
@@ -8,10 +8,13 @@ module Coradoc
|
|
|
8
8
|
class << self
|
|
9
9
|
def transform_paragraph(para)
|
|
10
10
|
children = ToCoreModel.transform_inline_content(para.content)
|
|
11
|
+
source_lines = ToCoreModel.extract_source_lines(para.content)
|
|
11
12
|
|
|
12
13
|
Coradoc::CoreModel::ParagraphBlock.new(
|
|
13
14
|
id: para.id,
|
|
14
15
|
content: ToCoreModel.extract_text_content(para.content),
|
|
16
|
+
lines: source_lines,
|
|
17
|
+
source_line: para.source_line,
|
|
15
18
|
children: children
|
|
16
19
|
)
|
|
17
20
|
end
|
|
@@ -22,19 +25,15 @@ module Coradoc
|
|
|
22
25
|
# lines are preserved. Treating these as paragraphs would collapse
|
|
23
26
|
# whitespace and join consecutive lines into a single flowing text.
|
|
24
27
|
def transform_verbatim_block(block, klass, language_override: nil)
|
|
25
|
-
|
|
26
|
-
line.is_a?(Coradoc::AsciiDoc::Model::LineBreak) ||
|
|
27
|
-
line.is_a?(Coradoc::AsciiDoc::Model::Break::PageBreak)
|
|
28
|
-
end
|
|
29
|
-
content_lines = non_break_lines.map do |line|
|
|
30
|
-
ToCoreModel.extract_text_content(line)
|
|
31
|
-
end.join("\n")
|
|
28
|
+
source_lines = ToCoreModel.extract_source_lines(block.lines)
|
|
32
29
|
|
|
33
30
|
klass.new(
|
|
34
31
|
id: block.id,
|
|
35
32
|
title: ToCoreModel.extract_title_text(block.title),
|
|
36
|
-
content:
|
|
37
|
-
|
|
33
|
+
content: source_lines.join("\n"),
|
|
34
|
+
lines: source_lines,
|
|
35
|
+
language: language_override || ToCoreModel.extract_block_language(block),
|
|
36
|
+
source_line: block.source_line
|
|
38
37
|
)
|
|
39
38
|
end
|
|
40
39
|
|
|
@@ -74,7 +73,7 @@ module Coradoc
|
|
|
74
73
|
# AsciiDoc spec, every delimited block accepts both admonition
|
|
75
74
|
# labels and verbatim/stem casts in its attribute line. The cast
|
|
76
75
|
# is resolved by +block_cast_semantic+ in MECE order:
|
|
77
|
-
# admonition > stem > verbatim > fallback.
|
|
76
|
+
# admonition > stem > verbatim > typed-cast > fallback.
|
|
78
77
|
def transform_with_admonition_check(block, native_class)
|
|
79
78
|
semantic = block_cast_semantic(block)
|
|
80
79
|
case semantic
|
|
@@ -88,6 +87,9 @@ module Coradoc
|
|
|
88
87
|
transform_listing_from_open(block)
|
|
89
88
|
when :literal
|
|
90
89
|
transform_literal_from_open(block)
|
|
90
|
+
when :typed_cast
|
|
91
|
+
style = first_positional_attr(block).to_s.downcase
|
|
92
|
+
transform_typed_block(block, TYPED_BLOCK_CAST_STYLES.fetch(style))
|
|
91
93
|
else
|
|
92
94
|
transform_typed_block(block, native_class)
|
|
93
95
|
end
|
|
@@ -119,11 +121,25 @@ module Coradoc
|
|
|
119
121
|
|
|
120
122
|
VERBATILE_CAST_STYLES = %w[source listing literal].freeze
|
|
121
123
|
|
|
124
|
+
# Positional style → typed CoreModel class for blocks whose
|
|
125
|
+
# attribute line casts an open block into a richer semantic
|
|
126
|
+
# type (e.g. `[sidebar]\n--\n...\n--`). Single source of
|
|
127
|
+
# truth: adding a new style cast is one line here, no edits
|
|
128
|
+
# to dispatch (OCP).
|
|
129
|
+
TYPED_BLOCK_CAST_STYLES = {
|
|
130
|
+
'sidebar' => Coradoc::CoreModel::SidebarBlock,
|
|
131
|
+
'example' => Coradoc::CoreModel::ExampleBlock,
|
|
132
|
+
'quote' => Coradoc::CoreModel::QuoteBlock,
|
|
133
|
+
'abstract' => Coradoc::CoreModel::AbstractBlock,
|
|
134
|
+
'partintro' => Coradoc::CoreModel::PartintroBlock
|
|
135
|
+
}.freeze
|
|
136
|
+
|
|
122
137
|
# Resolve a delimited block's cast from its first positional
|
|
123
138
|
# attribute. Single source of truth for the cast ladder used
|
|
124
139
|
# by every block-form transformer (example/sidebar/quote/open).
|
|
125
140
|
# Returns one of: :admonition, :stem, :source, :listing,
|
|
126
|
-
# :literal, or nil (no cast — use the block's
|
|
141
|
+
# :literal, :typed_cast, or nil (no cast — use the block's
|
|
142
|
+
# native class).
|
|
127
143
|
def block_cast_semantic(block)
|
|
128
144
|
style = first_positional_attr(block)
|
|
129
145
|
return nil unless style
|
|
@@ -131,6 +147,7 @@ module Coradoc
|
|
|
131
147
|
style_str = style.to_s.downcase
|
|
132
148
|
return :admonition if AdmonitionStyles.admonition?(style)
|
|
133
149
|
return :stem if STEM_STYLES.key?(style_str)
|
|
150
|
+
return :typed_cast if TYPED_BLOCK_CAST_STYLES.key?(style_str)
|
|
134
151
|
return style_str.to_sym if VERBATILE_CAST_STYLES.include?(style_str)
|
|
135
152
|
|
|
136
153
|
nil
|
|
@@ -163,7 +180,8 @@ module Coradoc
|
|
|
163
180
|
Coradoc::CoreModel::AnnotationBlock.new(
|
|
164
181
|
annotation_type: canonical,
|
|
165
182
|
content: content_lines,
|
|
166
|
-
title: ToCoreModel.extract_title_text(block.title)
|
|
183
|
+
title: ToCoreModel.extract_title_text(block.title),
|
|
184
|
+
source_line: block.source_line
|
|
167
185
|
)
|
|
168
186
|
end
|
|
169
187
|
|
|
@@ -176,7 +194,7 @@ module Coradoc
|
|
|
176
194
|
end
|
|
177
195
|
|
|
178
196
|
def transform_block(block, semantic_type_or_delimiter)
|
|
179
|
-
|
|
197
|
+
source_lines = ToCoreModel.extract_source_lines(block.lines)
|
|
180
198
|
semantic_type = if semantic_type_or_delimiter.is_a?(Symbol)
|
|
181
199
|
semantic_type_or_delimiter
|
|
182
200
|
else
|
|
@@ -188,8 +206,10 @@ module Coradoc
|
|
|
188
206
|
delimiter_type: semantic_type_or_delimiter.is_a?(String) ? semantic_type_or_delimiter : nil,
|
|
189
207
|
id: block.id,
|
|
190
208
|
title: ToCoreModel.extract_title_text(block.title),
|
|
191
|
-
content:
|
|
192
|
-
|
|
209
|
+
content: source_lines.join("\n"),
|
|
210
|
+
lines: source_lines,
|
|
211
|
+
language: ToCoreModel.extract_block_language(block),
|
|
212
|
+
source_line: block.source_line
|
|
193
213
|
)
|
|
194
214
|
end
|
|
195
215
|
|
|
@@ -216,6 +236,7 @@ module Coradoc
|
|
|
216
236
|
title: ToCoreModel.extract_title_text(block.title),
|
|
217
237
|
children: children,
|
|
218
238
|
language: ToCoreModel.extract_block_language(block),
|
|
239
|
+
source_line: block.source_line,
|
|
219
240
|
**extra_attrs
|
|
220
241
|
)
|
|
221
242
|
else
|
|
@@ -230,7 +251,8 @@ module Coradoc
|
|
|
230
251
|
inline = [Coradoc::CoreModel::TextContent.new(text: '')] if inline.empty?
|
|
231
252
|
Coradoc::CoreModel::ParagraphBlock.new(
|
|
232
253
|
content: ToCoreModel.extract_text_content(group),
|
|
233
|
-
children: Array(inline)
|
|
254
|
+
children: Array(inline),
|
|
255
|
+
source_line: ToCoreModel.extract_source_line(group)
|
|
234
256
|
)
|
|
235
257
|
end
|
|
236
258
|
|
|
@@ -240,6 +262,7 @@ module Coradoc
|
|
|
240
262
|
content: content_lines,
|
|
241
263
|
children: children,
|
|
242
264
|
language: ToCoreModel.extract_block_language(block),
|
|
265
|
+
source_line: block.source_line,
|
|
243
266
|
**extra_attrs
|
|
244
267
|
)
|
|
245
268
|
end
|
|
@@ -12,7 +12,6 @@ module Coradoc
|
|
|
12
12
|
children = ToCoreModel.transform(doc.sections || doc.contents || [])
|
|
13
13
|
children = CalloutMerger.call(children)
|
|
14
14
|
children = prepend_frontmatter(children, doc.frontmatter)
|
|
15
|
-
children = insert_title_heading_after_frontmatter(children, title_text)
|
|
16
15
|
children = resolve_attribute_references(children, attributes)
|
|
17
16
|
|
|
18
17
|
Coradoc::CoreModel::DocumentElement.new(
|
|
@@ -34,31 +33,6 @@ module Coradoc
|
|
|
34
33
|
[block, *children]
|
|
35
34
|
end
|
|
36
35
|
|
|
37
|
-
# Per the AsciiDoc spec, the document title (`= Title`) is the
|
|
38
|
-
# document's level-0 heading. Asciidoctor renders it as an
|
|
39
|
-
# <h1> at the top of the body by default. Emit a HeaderElement
|
|
40
|
-
# at level 0 so consumers that walk the body's children see the
|
|
41
|
-
# title (the standard ProseMirror/HTML rendering pattern)
|
|
42
|
-
# instead of having to read Document.title separately.
|
|
43
|
-
#
|
|
44
|
-
# The title attribute on DocumentElement is preserved for
|
|
45
|
-
# consumers that read it directly. The title heading is placed
|
|
46
|
-
# after any FrontmatterBlock (frontmatter is metadata that
|
|
47
|
-
# precedes the body).
|
|
48
|
-
def insert_title_heading_after_frontmatter(children, title_text)
|
|
49
|
-
return children if title_text.nil? || title_text.strip.empty?
|
|
50
|
-
|
|
51
|
-
title_heading = Coradoc::CoreModel::HeaderElement.new(
|
|
52
|
-
level: 0,
|
|
53
|
-
title: title_text,
|
|
54
|
-
content: title_text
|
|
55
|
-
)
|
|
56
|
-
frontmatter_count = children.count do |child|
|
|
57
|
-
child.is_a?(Coradoc::CoreModel::FrontmatterBlock)
|
|
58
|
-
end
|
|
59
|
-
children.insert(frontmatter_count, title_heading)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
36
|
# Resolve `{name}` attribute references in the body against the
|
|
63
37
|
# document's own declared attributes. Single source of truth:
|
|
64
38
|
# the resolver lives in core so other format gems can reuse it
|
|
@@ -86,7 +60,8 @@ module Coradoc
|
|
|
86
60
|
level: section.level,
|
|
87
61
|
title: title_text,
|
|
88
62
|
children: content_children + nested_sections,
|
|
89
|
-
attributes: section_metadata_from(section)
|
|
63
|
+
attributes: section_metadata_from(section),
|
|
64
|
+
source_line: section.source_line
|
|
90
65
|
)
|
|
91
66
|
end
|
|
92
67
|
|
|
@@ -9,14 +9,16 @@ module Coradoc
|
|
|
9
9
|
def transform_inline(inline, format_type)
|
|
10
10
|
klass = Coradoc::CoreModel::InlineElement.format_type_class(format_type)
|
|
11
11
|
klass.new(
|
|
12
|
-
content: ToCoreModel.extract_text_content(inline.content)
|
|
12
|
+
content: ToCoreModel.extract_text_content(inline.content),
|
|
13
|
+
source_line: inline.source_line
|
|
13
14
|
)
|
|
14
15
|
end
|
|
15
16
|
|
|
16
17
|
def transform_inline_text(inline, format_type)
|
|
17
18
|
klass = Coradoc::CoreModel::InlineElement.format_type_class(format_type)
|
|
18
19
|
klass.new(
|
|
19
|
-
content: inline.text.to_s
|
|
20
|
+
content: inline.text.to_s,
|
|
21
|
+
source_line: inline.source_line
|
|
20
22
|
)
|
|
21
23
|
end
|
|
22
24
|
|
|
@@ -24,28 +26,32 @@ module Coradoc
|
|
|
24
26
|
parsed_content = ToCoreModel.parse_and_transform_inline(footnote.text.to_s)
|
|
25
27
|
Coradoc::CoreModel::FootnoteElement.new(
|
|
26
28
|
target: footnote.id,
|
|
27
|
-
content: parsed_content
|
|
29
|
+
content: parsed_content,
|
|
30
|
+
source_line: footnote.source_line
|
|
28
31
|
)
|
|
29
32
|
end
|
|
30
33
|
|
|
31
34
|
def transform_link(link)
|
|
32
35
|
Coradoc::CoreModel::LinkElement.new(
|
|
33
36
|
target: link.path,
|
|
34
|
-
content: link.name || link.path
|
|
37
|
+
content: link.name || link.path,
|
|
38
|
+
source_line: link.source_line
|
|
35
39
|
)
|
|
36
40
|
end
|
|
37
41
|
|
|
38
42
|
def transform_cross_reference(xref)
|
|
39
43
|
Coradoc::CoreModel::CrossReferenceElement.new(
|
|
40
44
|
target: xref.href,
|
|
41
|
-
content: xref.args&.first || xref.href
|
|
45
|
+
content: xref.args&.first || xref.href,
|
|
46
|
+
source_line: xref.source_line
|
|
42
47
|
)
|
|
43
48
|
end
|
|
44
49
|
|
|
45
50
|
def transform_stem(stem)
|
|
46
51
|
Coradoc::CoreModel::StemElement.new(
|
|
47
52
|
content: stem.content,
|
|
48
|
-
stem_type: stem.type || 'stem'
|
|
53
|
+
stem_type: stem.type || 'stem',
|
|
54
|
+
source_line: stem.source_line
|
|
49
55
|
)
|
|
50
56
|
end
|
|
51
57
|
end
|
|
@@ -16,11 +16,15 @@ module Coradoc
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
if marker_type == 'definition'
|
|
19
|
-
Coradoc::CoreModel::DefinitionList.new(
|
|
19
|
+
Coradoc::CoreModel::DefinitionList.new(
|
|
20
|
+
items: items,
|
|
21
|
+
source_line: list.source_line
|
|
22
|
+
)
|
|
20
23
|
else
|
|
21
24
|
Coradoc::CoreModel::ListBlock.new(
|
|
22
25
|
marker_type: marker_type,
|
|
23
|
-
items: items
|
|
26
|
+
items: items,
|
|
27
|
+
source_line: list.source_line
|
|
24
28
|
)
|
|
25
29
|
end
|
|
26
30
|
end
|
|
@@ -45,7 +49,8 @@ module Coradoc
|
|
|
45
49
|
term: ToCoreModel.extract_text_content(term_children),
|
|
46
50
|
definitions: [ToCoreModel.extract_text_content(def_children)],
|
|
47
51
|
term_children: term_children,
|
|
48
|
-
definition_children: def_children
|
|
52
|
+
definition_children: def_children,
|
|
53
|
+
source_line: item.source_line
|
|
49
54
|
)
|
|
50
55
|
di.id = item.id if item.id
|
|
51
56
|
|
|
@@ -63,7 +68,8 @@ module Coradoc
|
|
|
63
68
|
|
|
64
69
|
li = Coradoc::CoreModel::ListItem.new(
|
|
65
70
|
content: ToCoreModel.extract_text_content(content_val),
|
|
66
|
-
marker: item.marker
|
|
71
|
+
marker: item.marker,
|
|
72
|
+
source_line: item.source_line
|
|
67
73
|
)
|
|
68
74
|
li.children = children
|
|
69
75
|
|
|
@@ -10,7 +10,8 @@ module Coradoc
|
|
|
10
10
|
Coradoc::CoreModel::Term.new(
|
|
11
11
|
text: term.term.to_s,
|
|
12
12
|
type: term.type&.to_s || 'preferred',
|
|
13
|
-
lang: term.lang&.to_s || 'en'
|
|
13
|
+
lang: term.lang&.to_s || 'en',
|
|
14
|
+
source_line: term.source_line
|
|
14
15
|
)
|
|
15
16
|
end
|
|
16
17
|
|
|
@@ -19,7 +20,8 @@ module Coradoc
|
|
|
19
20
|
children = ToCoreModel.transform_inline_content(admonition.content)
|
|
20
21
|
block = Coradoc::CoreModel::AnnotationBlock.new(
|
|
21
22
|
annotation_type: canonical,
|
|
22
|
-
content: ToCoreModel.extract_text_content(admonition.content)
|
|
23
|
+
content: ToCoreModel.extract_text_content(admonition.content),
|
|
24
|
+
source_line: admonition.source_line
|
|
23
25
|
)
|
|
24
26
|
block.children = children
|
|
25
27
|
block
|
|
@@ -35,7 +37,8 @@ module Coradoc
|
|
|
35
37
|
alt: image.alt, title: image.title, caption: image.caption,
|
|
36
38
|
width: image.width, height: image.height,
|
|
37
39
|
link: image.link, role: image.role,
|
|
38
|
-
inline: image.is_a?(Coradoc::AsciiDoc::Model::Image::InlineImage)
|
|
40
|
+
inline: image.is_a?(Coradoc::AsciiDoc::Model::Image::InlineImage),
|
|
41
|
+
source_line: image.source_line
|
|
39
42
|
}
|
|
40
43
|
end
|
|
41
44
|
|
|
@@ -53,7 +56,8 @@ module Coradoc
|
|
|
53
56
|
id: bib.id,
|
|
54
57
|
title: bib.title.to_s,
|
|
55
58
|
level: nil,
|
|
56
|
-
entries: entries
|
|
59
|
+
entries: entries,
|
|
60
|
+
source_line: bib.source_line
|
|
57
61
|
)
|
|
58
62
|
end
|
|
59
63
|
|
|
@@ -61,7 +65,8 @@ module Coradoc
|
|
|
61
65
|
Coradoc::CoreModel::BibliographyEntry.new(
|
|
62
66
|
anchor_name: entry.anchor_name,
|
|
63
67
|
document_id: entry.document_id,
|
|
64
|
-
ref_text: entry.ref_text.to_s
|
|
68
|
+
ref_text: entry.ref_text.to_s,
|
|
69
|
+
source_line: entry.source_line
|
|
65
70
|
)
|
|
66
71
|
end
|
|
67
72
|
end
|