coradoc-adoc 2.0.24 → 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/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/from_core_model.rb +5 -2
- data/lib/coradoc/asciidoc/transform/inline_transform_visitor.rb +6 -1
- data/lib/coradoc/asciidoc/transformer/block_rules.rb +3 -7
- data/lib/coradoc/asciidoc/transformer/block_type_classifier.rb +10 -10
- data/lib/coradoc/asciidoc/transformer/header_rules.rb +3 -6
- data/lib/coradoc/asciidoc/transformer/inline_rules.rb +20 -40
- data/lib/coradoc/asciidoc/transformer/list_rules.rb +5 -10
- data/lib/coradoc/asciidoc/transformer/misc_rules.rb +10 -20
- data/lib/coradoc/asciidoc/transformer/source_line_extractor.rb +0 -1
- data/lib/coradoc/asciidoc/transformer/structural_rules.rb +3 -7
- data/lib/coradoc/asciidoc/transformer/table_layout.rb +1 -3
- data/lib/coradoc/asciidoc/transformer/text_rules.rb +9 -18
- data/lib/coradoc/asciidoc/transformer.rb +26 -2
- data/lib/coradoc/asciidoc/version.rb +1 -1
- metadata +1 -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
|
|
@@ -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
|
|
@@ -300,8 +300,11 @@ module Coradoc
|
|
|
300
300
|
end
|
|
301
301
|
|
|
302
302
|
def transform_image(image)
|
|
303
|
-
target_class = image.inline
|
|
304
|
-
|
|
303
|
+
target_class = if image.inline
|
|
304
|
+
Coradoc::AsciiDoc::Model::Image::InlineImage
|
|
305
|
+
else
|
|
306
|
+
Coradoc::AsciiDoc::Model::Image::BlockImage
|
|
307
|
+
end
|
|
305
308
|
target_class.new(**image_attributes(image))
|
|
306
309
|
end
|
|
307
310
|
|
|
@@ -62,10 +62,15 @@ module Coradoc
|
|
|
62
62
|
result
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
+
# Two adjacent TextElements in the content array indicate the
|
|
66
|
+
# parser split a paragraph across source lines. Join them with a
|
|
67
|
+
# space (soft break) unless the second one carries a hard-break
|
|
68
|
+
# marker — the model owns that predicate, so this method does
|
|
69
|
+
# not reach into parser-specific line_break string values.
|
|
65
70
|
def soft_break_before?(previous, current)
|
|
66
71
|
previous.is_a?(Model::TextElement) &&
|
|
67
72
|
current.is_a?(Model::TextElement) &&
|
|
68
|
-
current.
|
|
73
|
+
!current.hard_break?
|
|
69
74
|
end
|
|
70
75
|
|
|
71
76
|
def visit_model(model)
|
|
@@ -23,8 +23,7 @@ module Coradoc
|
|
|
23
23
|
title: title,
|
|
24
24
|
delimiter_len: delimiter.size,
|
|
25
25
|
lines: lines,
|
|
26
|
-
ordering: ordering
|
|
27
|
-
source_line: SourceLineExtractor.extract(block)
|
|
26
|
+
ordering: ordering
|
|
28
27
|
}
|
|
29
28
|
# Markdown fences carry the language tag inline (```ruby);
|
|
30
29
|
# pass it through so the SourceCode classifier entry can set
|
|
@@ -37,8 +36,7 @@ module Coradoc
|
|
|
37
36
|
rule(example: sequence(:example)) do
|
|
38
37
|
Model::Block::Example.new(
|
|
39
38
|
title: '',
|
|
40
|
-
lines: example
|
|
41
|
-
source_line: SourceLineExtractor.extract(example)
|
|
39
|
+
lines: example
|
|
42
40
|
)
|
|
43
41
|
end
|
|
44
42
|
|
|
@@ -52,8 +50,7 @@ module Coradoc
|
|
|
52
50
|
canonical = Coradoc::AsciiDoc::Transform::ElementTransformers::AdmonitionStyles.canonicalize(admonition_type.to_s)
|
|
53
51
|
Model::Admonition.new(
|
|
54
52
|
content: content,
|
|
55
|
-
type: canonical
|
|
56
|
-
source_line: SourceLineExtractor.extract(admonition_type)
|
|
53
|
+
type: canonical
|
|
57
54
|
)
|
|
58
55
|
end
|
|
59
56
|
|
|
@@ -72,7 +69,6 @@ module Coradoc
|
|
|
72
69
|
src: path,
|
|
73
70
|
attributes: residual,
|
|
74
71
|
line_break: "\n",
|
|
75
|
-
source_line: SourceLineExtractor.extract(block_image),
|
|
76
72
|
**promoted
|
|
77
73
|
)
|
|
78
74
|
end
|
|
@@ -16,23 +16,23 @@ module Coradoc
|
|
|
16
16
|
# returning a Model::Block::* instance. `max_length` nil means
|
|
17
17
|
# unbounded.
|
|
18
18
|
DELIMITER_CLASSIFICATIONS = [
|
|
19
|
-
['*', 4, nil,
|
|
19
|
+
['*', 4, nil, lambda { |opts, attrs|
|
|
20
20
|
if attrs && attrs.positional == [] && attrs.named.first&.name == 'reviewer'
|
|
21
|
-
Model::Block::ReviewerComment.new(**opts
|
|
21
|
+
Model::Block::ReviewerComment.new(**opts, attributes: attrs)
|
|
22
22
|
else
|
|
23
|
-
Model::Block::Side.new(**opts
|
|
23
|
+
Model::Block::Side.new(**opts, attributes: attrs)
|
|
24
24
|
end
|
|
25
25
|
}],
|
|
26
|
-
['=', 4, nil, ->(opts, attrs) { Model::Block::Example.new(**opts
|
|
27
|
-
['+', 4, nil, ->(opts, attrs) { Model::Block::Pass.new(**opts
|
|
28
|
-
['.', 4, nil, ->(opts, attrs) { Model::Block::Literal.new(**opts
|
|
29
|
-
['_', 4, nil, ->(opts, attrs) { Model::Block::Quote.new(**opts
|
|
30
|
-
['-', 4, nil, ->(opts, attrs) { Model::Block::SourceCode.new(**opts
|
|
31
|
-
['-', 2, 2,
|
|
26
|
+
['=', 4, nil, ->(opts, attrs) { Model::Block::Example.new(**opts, attributes: attrs) }],
|
|
27
|
+
['+', 4, nil, ->(opts, attrs) { Model::Block::Pass.new(**opts, attributes: attrs) }],
|
|
28
|
+
['.', 4, nil, ->(opts, attrs) { Model::Block::Literal.new(**opts, attributes: attrs) }],
|
|
29
|
+
['_', 4, nil, ->(opts, attrs) { Model::Block::Quote.new(**opts, attributes: attrs) }],
|
|
30
|
+
['-', 4, nil, ->(opts, attrs) { Model::Block::SourceCode.new(**opts, attributes: attrs) }],
|
|
31
|
+
['-', 2, 2, ->(opts, attrs) { Model::Block::Open.new(**opts, attributes: attrs) }],
|
|
32
32
|
# Markdown-style triple-backtick fence: behaves as a SourceCode
|
|
33
33
|
# block. The language tag parsed from the opening fence is passed
|
|
34
34
|
# through opts[:lang]; extract_block_language prefers block.lang.
|
|
35
|
-
['`', 3, nil,
|
|
35
|
+
['`', 3, nil, lambda { |opts, attrs|
|
|
36
36
|
model_opts = opts.merge(attributes: attrs, delimiter_char: '`')
|
|
37
37
|
model_opts[:lang] = opts[:lang] if opts.key?(:lang)
|
|
38
38
|
Model::Block::SourceCode.new(**model_opts)
|
|
@@ -22,8 +22,7 @@ module Coradoc
|
|
|
22
22
|
id = nil if id && id.empty?
|
|
23
23
|
|
|
24
24
|
Model::Header.new(
|
|
25
|
-
id:, title:, author:, revision
|
|
26
|
-
source_line: SourceLineExtractor.extract(header)
|
|
25
|
+
id:, title:, author:, revision:
|
|
27
26
|
)
|
|
28
27
|
end
|
|
29
28
|
|
|
@@ -38,8 +37,7 @@ module Coradoc
|
|
|
38
37
|
email: simple(:email)
|
|
39
38
|
) do
|
|
40
39
|
Model::Author.new(
|
|
41
|
-
first_name:, last_name:, email:, middle_name: nil
|
|
42
|
-
source_line: SourceLineExtractor.extract(first_name)
|
|
40
|
+
first_name:, last_name:, email:, middle_name: nil
|
|
43
41
|
)
|
|
44
42
|
end
|
|
45
43
|
|
|
@@ -50,8 +48,7 @@ module Coradoc
|
|
|
50
48
|
remark: simple(:remark)
|
|
51
49
|
) do
|
|
52
50
|
Model::Revision.new(
|
|
53
|
-
number:, date:, remark
|
|
54
|
-
source_line: SourceLineExtractor.extract(number)
|
|
51
|
+
number:, date:, remark:
|
|
55
52
|
)
|
|
56
53
|
end
|
|
57
54
|
end
|
|
@@ -10,8 +10,8 @@ module Coradoc
|
|
|
10
10
|
# `span` is excluded because it carries `text:` + `attributes:`
|
|
11
11
|
# rather than `content:`, so it gets its own pair of rules.
|
|
12
12
|
FORMATTING_VARIANTS = [
|
|
13
|
-
%i[bold
|
|
14
|
-
%i[italic
|
|
13
|
+
%i[bold Bold],
|
|
14
|
+
%i[italic Italic],
|
|
15
15
|
%i[highlight Highlight],
|
|
16
16
|
%i[monospace Monospace]
|
|
17
17
|
].freeze
|
|
@@ -22,8 +22,7 @@ module Coradoc
|
|
|
22
22
|
rule(link: subtree(:link)) do
|
|
23
23
|
Model::Inline::Link.new(
|
|
24
24
|
path: link[:path].to_s,
|
|
25
|
-
name: link[:text]&.to_s
|
|
26
|
-
source_line: SourceLineExtractor.extract(link)
|
|
25
|
+
name: link[:text]&.to_s
|
|
27
26
|
)
|
|
28
27
|
end
|
|
29
28
|
|
|
@@ -33,8 +32,7 @@ module Coradoc
|
|
|
33
32
|
text = xref[:text]
|
|
34
33
|
args = text ? [text.to_s] : []
|
|
35
34
|
Model::Inline::CrossReference.new(
|
|
36
|
-
href:, args
|
|
37
|
-
source_line: SourceLineExtractor.extract(xref)
|
|
35
|
+
href:, args:
|
|
38
36
|
)
|
|
39
37
|
end
|
|
40
38
|
|
|
@@ -47,7 +45,6 @@ module Coradoc
|
|
|
47
45
|
Model::Image::InlineImage.new(
|
|
48
46
|
src: inline_image[:path],
|
|
49
47
|
attributes: residual,
|
|
50
|
-
source_line: SourceLineExtractor.extract(inline_image),
|
|
51
48
|
**promoted
|
|
52
49
|
)
|
|
53
50
|
end
|
|
@@ -59,16 +56,14 @@ module Coradoc
|
|
|
59
56
|
rule(inline_passthrough: subtree(:passthrough)) do
|
|
60
57
|
Model::Inline::Passthrough.new(
|
|
61
58
|
content: passthrough[:raw].to_s,
|
|
62
|
-
form: 'triple'
|
|
63
|
-
source_line: SourceLineExtractor.extract(passthrough)
|
|
59
|
+
form: 'triple'
|
|
64
60
|
)
|
|
65
61
|
end
|
|
66
62
|
|
|
67
63
|
# Attribute reference
|
|
68
64
|
rule(attribute_reference: simple(:name)) do
|
|
69
65
|
Model::Inline::AttributeReference.new(
|
|
70
|
-
name
|
|
71
|
-
source_line: SourceLineExtractor.extract(name)
|
|
66
|
+
name:
|
|
72
67
|
)
|
|
73
68
|
end
|
|
74
69
|
|
|
@@ -78,9 +73,7 @@ module Coradoc
|
|
|
78
73
|
# blank lines. Hard breaks carry semantic meaning: HTML/Markdown
|
|
79
74
|
# renderers map them to <br>.
|
|
80
75
|
rule(hard_line_break: simple(:hard_line_break)) do
|
|
81
|
-
Model::Inline::HardLineBreak.new
|
|
82
|
-
source_line: SourceLineExtractor.extract(hard_line_break)
|
|
83
|
-
)
|
|
76
|
+
Model::Inline::HardLineBreak.new
|
|
84
77
|
end
|
|
85
78
|
|
|
86
79
|
# Term
|
|
@@ -89,8 +82,7 @@ module Coradoc
|
|
|
89
82
|
term: simple(:term)
|
|
90
83
|
) do
|
|
91
84
|
Coradoc::AsciiDoc::Model::Term.new(
|
|
92
|
-
term:, type: term_type, lang: :en
|
|
93
|
-
source_line: SourceLineExtractor.extract(term_type)
|
|
85
|
+
term:, type: term_type, lang: :en
|
|
94
86
|
)
|
|
95
87
|
end
|
|
96
88
|
|
|
@@ -98,16 +90,14 @@ module Coradoc
|
|
|
98
90
|
rule(footnote: simple(:footnote)) do
|
|
99
91
|
text_str = footnote.to_s
|
|
100
92
|
Coradoc::AsciiDoc::Model::Inline::Footnote.new(
|
|
101
|
-
text: text_str
|
|
102
|
-
source_line: SourceLineExtractor.extract(footnote)
|
|
93
|
+
text: text_str
|
|
103
94
|
)
|
|
104
95
|
end
|
|
105
96
|
|
|
106
97
|
rule(footnote: simple(:footnote), id: simple(:id)) do
|
|
107
98
|
text_str = footnote.to_s
|
|
108
99
|
Coradoc::AsciiDoc::Model::Inline::Footnote.new(
|
|
109
|
-
text: text_str, id: id.to_s
|
|
110
|
-
source_line: SourceLineExtractor.extract(footnote)
|
|
100
|
+
text: text_str, id: id.to_s
|
|
111
101
|
)
|
|
112
102
|
end
|
|
113
103
|
|
|
@@ -115,8 +105,7 @@ module Coradoc
|
|
|
115
105
|
rule(footnote: sequence(:footnote), id: simple(:id)) do
|
|
116
106
|
text_str = footnote.map(&:to_s).join
|
|
117
107
|
Coradoc::AsciiDoc::Model::Inline::Footnote.new(
|
|
118
|
-
text: text_str, id: id.to_s
|
|
119
|
-
source_line: SourceLineExtractor.extract(footnote)
|
|
108
|
+
text: text_str, id: id.to_s
|
|
120
109
|
)
|
|
121
110
|
end
|
|
122
111
|
|
|
@@ -124,8 +113,7 @@ module Coradoc
|
|
|
124
113
|
rule(footnote: sequence(:footnote)) do
|
|
125
114
|
text_str = footnote.map(&:to_s).join
|
|
126
115
|
Coradoc::AsciiDoc::Model::Inline::Footnote.new(
|
|
127
|
-
text: text_str
|
|
128
|
-
source_line: SourceLineExtractor.extract(footnote)
|
|
116
|
+
text: text_str
|
|
129
117
|
)
|
|
130
118
|
end
|
|
131
119
|
|
|
@@ -141,15 +129,13 @@ module Coradoc
|
|
|
141
129
|
rule(constrained_key => subtree(:subtree)) do
|
|
142
130
|
content = Transformer.extract_inline_content(subtree)
|
|
143
131
|
klass.new(
|
|
144
|
-
content: content, unconstrained: false
|
|
145
|
-
source_line: SourceLineExtractor.extract(subtree)
|
|
132
|
+
content: content, unconstrained: false
|
|
146
133
|
)
|
|
147
134
|
end
|
|
148
135
|
rule(unconstrained_key => subtree(:subtree)) do
|
|
149
136
|
content = Transformer.extract_inline_content(subtree)
|
|
150
137
|
klass.new(
|
|
151
|
-
content: content, unconstrained: true
|
|
152
|
-
source_line: SourceLineExtractor.extract(subtree)
|
|
138
|
+
content: content, unconstrained: true
|
|
153
139
|
)
|
|
154
140
|
end
|
|
155
141
|
end
|
|
@@ -159,8 +145,7 @@ module Coradoc
|
|
|
159
145
|
Model::Inline::Span.new(
|
|
160
146
|
text: span_constrained[:text],
|
|
161
147
|
unconstrained: false,
|
|
162
|
-
attributes: span_constrained[:attribute_list]
|
|
163
|
-
source_line: SourceLineExtractor.extract(span_constrained)
|
|
148
|
+
attributes: span_constrained[:attribute_list]
|
|
164
149
|
)
|
|
165
150
|
end
|
|
166
151
|
|
|
@@ -169,8 +154,7 @@ module Coradoc
|
|
|
169
154
|
Model::Inline::Span.new(
|
|
170
155
|
text: span_unconstrained[:text],
|
|
171
156
|
unconstrained: true,
|
|
172
|
-
attributes: span_unconstrained[:attribute_list]
|
|
173
|
-
source_line: SourceLineExtractor.extract(span_unconstrained)
|
|
157
|
+
attributes: span_unconstrained[:attribute_list]
|
|
174
158
|
)
|
|
175
159
|
end
|
|
176
160
|
|
|
@@ -178,8 +162,7 @@ module Coradoc
|
|
|
178
162
|
rule(superscript: subtree(:superscript)) do
|
|
179
163
|
content = Transformer.extract_simple_inline_content(superscript)
|
|
180
164
|
Model::Inline::Superscript.new(
|
|
181
|
-
content
|
|
182
|
-
source_line: SourceLineExtractor.extract(superscript)
|
|
165
|
+
content:
|
|
183
166
|
)
|
|
184
167
|
end
|
|
185
168
|
|
|
@@ -187,24 +170,21 @@ module Coradoc
|
|
|
187
170
|
rule(subscript: subtree(:subscript)) do
|
|
188
171
|
content = Transformer.extract_simple_inline_content(subscript)
|
|
189
172
|
Model::Inline::Subscript.new(
|
|
190
|
-
content
|
|
191
|
-
source_line: SourceLineExtractor.extract(subscript)
|
|
173
|
+
content:
|
|
192
174
|
)
|
|
193
175
|
end
|
|
194
176
|
|
|
195
177
|
# Highlight (simple)
|
|
196
178
|
rule(highlight: simple(:text)) do
|
|
197
179
|
Model::Highlight.new(
|
|
198
|
-
content: text
|
|
199
|
-
source_line: SourceLineExtractor.extract(text)
|
|
180
|
+
content: text
|
|
200
181
|
)
|
|
201
182
|
end
|
|
202
183
|
# Stem
|
|
203
184
|
rule(stem: subtree(:stem)) do
|
|
204
185
|
Coradoc::AsciiDoc::Model::Inline::Stem.new(
|
|
205
186
|
type: stem[:stem_type],
|
|
206
|
-
content: stem[:content]
|
|
207
|
-
source_line: SourceLineExtractor.extract(stem)
|
|
187
|
+
content: stem[:content]
|
|
208
188
|
)
|
|
209
189
|
end
|
|
210
190
|
end
|
|
@@ -74,8 +74,7 @@ module Coradoc
|
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
Model::List::Item.new(
|
|
77
|
-
content: content, id:, marker:, attached:, nested:, line_break
|
|
78
|
-
source_line: SourceLineExtractor.extract(list_item)
|
|
77
|
+
content: content, id:, marker:, attached:, nested:, line_break:
|
|
79
78
|
)
|
|
80
79
|
end
|
|
81
80
|
|
|
@@ -87,8 +86,7 @@ module Coradoc
|
|
|
87
86
|
# Unordered list
|
|
88
87
|
rule(unordered: sequence(:list_items)) do
|
|
89
88
|
Model::List::Unordered.new(
|
|
90
|
-
items: list_items
|
|
91
|
-
source_line: SourceLineExtractor.extract(list_items)
|
|
89
|
+
items: list_items
|
|
92
90
|
)
|
|
93
91
|
end
|
|
94
92
|
|
|
@@ -98,16 +96,14 @@ module Coradoc
|
|
|
98
96
|
) do
|
|
99
97
|
Model::List::Unordered.new(
|
|
100
98
|
items: list_items,
|
|
101
|
-
attrs: attribute_list
|
|
102
|
-
source_line: SourceLineExtractor.extract(attribute_list)
|
|
99
|
+
attrs: attribute_list
|
|
103
100
|
)
|
|
104
101
|
end
|
|
105
102
|
|
|
106
103
|
# Ordered list
|
|
107
104
|
rule(ordered: sequence(:list_items)) do
|
|
108
105
|
Model::List::Ordered.new(
|
|
109
|
-
items: list_items
|
|
110
|
-
source_line: SourceLineExtractor.extract(list_items)
|
|
106
|
+
items: list_items
|
|
111
107
|
)
|
|
112
108
|
end
|
|
113
109
|
|
|
@@ -117,8 +113,7 @@ module Coradoc
|
|
|
117
113
|
) do
|
|
118
114
|
Model::List::Ordered.new(
|
|
119
115
|
items: list_items,
|
|
120
|
-
attrs: attribute_list
|
|
121
|
-
source_line: SourceLineExtractor.extract(attribute_list)
|
|
116
|
+
attrs: attribute_list
|
|
122
117
|
)
|
|
123
118
|
end
|
|
124
119
|
|
|
@@ -14,23 +14,19 @@ module Coradoc
|
|
|
14
14
|
}) do
|
|
15
15
|
Model::CommentLine.new(
|
|
16
16
|
text: comment_text,
|
|
17
|
-
line_break: line_break
|
|
18
|
-
source_line: SourceLineExtractor.extract(comment_text)
|
|
17
|
+
line_break: line_break
|
|
19
18
|
)
|
|
20
19
|
end
|
|
21
20
|
|
|
22
21
|
rule(comment_block: { comment_text: simple(:comment_text) }) do
|
|
23
22
|
Model::CommentBlock.new(
|
|
24
|
-
text: comment_text
|
|
25
|
-
source_line: SourceLineExtractor.extract(comment_text)
|
|
23
|
+
text: comment_text
|
|
26
24
|
)
|
|
27
25
|
end
|
|
28
26
|
|
|
29
27
|
# Page break
|
|
30
28
|
rule(page_break: simple(:page_break)) do
|
|
31
|
-
Model::Break::PageBreak.new
|
|
32
|
-
source_line: SourceLineExtractor.extract(page_break)
|
|
33
|
-
)
|
|
29
|
+
Model::Break::PageBreak.new
|
|
34
30
|
end
|
|
35
31
|
|
|
36
32
|
# Tag
|
|
@@ -39,8 +35,7 @@ module Coradoc
|
|
|
39
35
|
name: tag[:name],
|
|
40
36
|
attrs: tag[:attribute_list],
|
|
41
37
|
line_break: tag[:line_break],
|
|
42
|
-
prefix: tag[:prefix]
|
|
43
|
-
source_line: SourceLineExtractor.extract(tag)
|
|
38
|
+
prefix: tag[:prefix]
|
|
44
39
|
)
|
|
45
40
|
end
|
|
46
41
|
|
|
@@ -63,9 +58,8 @@ module Coradoc
|
|
|
63
58
|
end
|
|
64
59
|
|
|
65
60
|
rule(attribute_array: sequence(:attributes)) do
|
|
66
|
-
attr_list = Model::AttributeList.new
|
|
67
|
-
|
|
68
|
-
)
|
|
61
|
+
attr_list = Model::AttributeList.new
|
|
62
|
+
|
|
69
63
|
attributes.each do |a|
|
|
70
64
|
case a
|
|
71
65
|
when Parslet::Slice
|
|
@@ -119,8 +113,7 @@ module Coradoc
|
|
|
119
113
|
Model::Include.new(
|
|
120
114
|
path: path.to_s,
|
|
121
115
|
attributes: attribute_list,
|
|
122
|
-
line_break: line_break
|
|
123
|
-
source_line: SourceLineExtractor.extract(path)
|
|
116
|
+
line_break: line_break
|
|
124
117
|
)
|
|
125
118
|
end
|
|
126
119
|
|
|
@@ -135,8 +128,7 @@ module Coradoc
|
|
|
135
128
|
Model::Audio.new(
|
|
136
129
|
src: path.to_s,
|
|
137
130
|
attributes: attribute_list,
|
|
138
|
-
line_break: line_break
|
|
139
|
-
source_line: SourceLineExtractor.extract(path)
|
|
131
|
+
line_break: line_break
|
|
140
132
|
)
|
|
141
133
|
end
|
|
142
134
|
|
|
@@ -151,8 +143,7 @@ module Coradoc
|
|
|
151
143
|
Model::Video.new(
|
|
152
144
|
src: path.to_s,
|
|
153
145
|
attributes: attribute_list,
|
|
154
|
-
line_break: line_break
|
|
155
|
-
source_line: SourceLineExtractor.extract(path)
|
|
146
|
+
line_break: line_break
|
|
156
147
|
)
|
|
157
148
|
end
|
|
158
149
|
|
|
@@ -180,8 +171,7 @@ module Coradoc
|
|
|
180
171
|
date: attrs[:date],
|
|
181
172
|
from: attrs[:from],
|
|
182
173
|
to: attrs[:to],
|
|
183
|
-
content: Transformer.lines_to_text_elements(lines)
|
|
184
|
-
source_line: SourceLineExtractor.extract(reviewer_note)
|
|
174
|
+
content: Transformer.lines_to_text_elements(lines)
|
|
185
175
|
)
|
|
186
176
|
end
|
|
187
177
|
end
|
|
@@ -72,7 +72,6 @@ module Coradoc
|
|
|
72
72
|
opts = { rows: Transformer.regroup_table_rows(rows, attrs), attrs: attrs }
|
|
73
73
|
opts[:id] = id if id
|
|
74
74
|
opts[:title] = title unless title.nil? || title.empty?
|
|
75
|
-
opts[:source_line] = SourceLineExtractor.extract(table)
|
|
76
75
|
Model::Table.new(**opts)
|
|
77
76
|
end
|
|
78
77
|
|
|
@@ -85,8 +84,7 @@ module Coradoc
|
|
|
85
84
|
Model::Title.new(
|
|
86
85
|
content: text,
|
|
87
86
|
level_int: level.size - 1,
|
|
88
|
-
line_break: line_break
|
|
89
|
-
source_line: SourceLineExtractor.extract(level)
|
|
87
|
+
line_break: line_break
|
|
90
88
|
)
|
|
91
89
|
end
|
|
92
90
|
|
|
@@ -100,8 +98,7 @@ module Coradoc
|
|
|
100
98
|
content: text,
|
|
101
99
|
level_int: level.size - 1,
|
|
102
100
|
line_break: line_break,
|
|
103
|
-
id: name
|
|
104
|
-
source_line: SourceLineExtractor.extract(name)
|
|
101
|
+
id: name
|
|
105
102
|
)
|
|
106
103
|
end
|
|
107
104
|
|
|
@@ -120,8 +117,7 @@ module Coradoc
|
|
|
120
117
|
id: id,
|
|
121
118
|
attribute_list: attribute_list,
|
|
122
119
|
contents: contents,
|
|
123
|
-
sections: sections
|
|
124
|
-
source_line: SourceLineExtractor.extract(section)
|
|
120
|
+
sections: sections
|
|
125
121
|
)
|
|
126
122
|
end
|
|
127
123
|
|
|
@@ -46,9 +46,7 @@ module Coradoc
|
|
|
46
46
|
normalized_cells = cells.map { |cell| TableCellBuilder.normalize_cell(cell) }
|
|
47
47
|
|
|
48
48
|
col_count = explicit_col_count
|
|
49
|
-
if col_count.nil? || col_count.zero?
|
|
50
|
-
col_count = infer_column_count(normalized_cells)
|
|
51
|
-
end
|
|
49
|
+
col_count = infer_column_count(normalized_cells) if col_count.nil? || col_count.zero?
|
|
52
50
|
col_count = normalized_cells.size if col_count.nil? || col_count.zero?
|
|
53
51
|
|
|
54
52
|
rows = []
|
|
@@ -10,8 +10,7 @@ module Coradoc
|
|
|
10
10
|
# Text Model
|
|
11
11
|
rule(text: simple(:text)) do
|
|
12
12
|
Model::TextElement.new(
|
|
13
|
-
content: text.to_s
|
|
14
|
-
source_line: Transformer::SourceLineExtractor.extract(text)
|
|
13
|
+
content: text.to_s
|
|
15
14
|
)
|
|
16
15
|
end
|
|
17
16
|
|
|
@@ -22,31 +21,27 @@ module Coradoc
|
|
|
22
21
|
rule(text: simple(:text), line_break: simple(:line_break)) do
|
|
23
22
|
Model::TextElement.new(
|
|
24
23
|
content: text.to_s,
|
|
25
|
-
line_break: line_break
|
|
26
|
-
source_line: Transformer::SourceLineExtractor.extract(text)
|
|
24
|
+
line_break: line_break
|
|
27
25
|
)
|
|
28
26
|
end
|
|
29
27
|
|
|
30
28
|
rule(text: sequence(:text), line_break: simple(:line_break)) do
|
|
31
29
|
Model::TextElement.new(
|
|
32
30
|
content: text,
|
|
33
|
-
line_break: line_break
|
|
34
|
-
source_line: Transformer::SourceLineExtractor.extract(text)
|
|
31
|
+
line_break: line_break
|
|
35
32
|
)
|
|
36
33
|
end
|
|
37
34
|
|
|
38
35
|
rule(id: simple(:id), text: simple(:text)) do
|
|
39
36
|
Model::TextElement.new(
|
|
40
37
|
content: text.to_s,
|
|
41
|
-
id: id.to_s
|
|
42
|
-
source_line: Transformer::SourceLineExtractor.extract(id)
|
|
38
|
+
id: id.to_s
|
|
43
39
|
)
|
|
44
40
|
end
|
|
45
41
|
|
|
46
42
|
rule(text: sequence(:text)) do
|
|
47
43
|
Model::TextElement.new(
|
|
48
|
-
content: text
|
|
49
|
-
source_line: Transformer::SourceLineExtractor.extract(text)
|
|
44
|
+
content: text
|
|
50
45
|
)
|
|
51
46
|
end
|
|
52
47
|
|
|
@@ -58,8 +53,7 @@ module Coradoc
|
|
|
58
53
|
Model::TextElement.new(
|
|
59
54
|
content: text.to_s,
|
|
60
55
|
id: id.to_s,
|
|
61
|
-
line_break: line_break
|
|
62
|
-
source_line: Transformer::SourceLineExtractor.extract(id)
|
|
56
|
+
line_break: line_break
|
|
63
57
|
)
|
|
64
58
|
end
|
|
65
59
|
|
|
@@ -71,16 +65,14 @@ module Coradoc
|
|
|
71
65
|
Model::TextElement.new(
|
|
72
66
|
content: text,
|
|
73
67
|
id: id.to_s,
|
|
74
|
-
line_break: line_break
|
|
75
|
-
source_line: Transformer::SourceLineExtractor.extract(id)
|
|
68
|
+
line_break: line_break
|
|
76
69
|
)
|
|
77
70
|
end
|
|
78
71
|
|
|
79
72
|
# Line break
|
|
80
73
|
rule(line_break: simple(:line_break)) do
|
|
81
74
|
Model::LineBreak.new(
|
|
82
|
-
line_break
|
|
83
|
-
source_line: Transformer::SourceLineExtractor.extract(line_break)
|
|
75
|
+
line_break:
|
|
84
76
|
)
|
|
85
77
|
end
|
|
86
78
|
|
|
@@ -95,8 +87,7 @@ module Coradoc
|
|
|
95
87
|
content: Transformer.lines_to_text_elements(paragraph[:lines]),
|
|
96
88
|
id: paragraph[:id],
|
|
97
89
|
attributes: paragraph[:attribute_list],
|
|
98
|
-
title: paragraph[:title]
|
|
99
|
-
source_line: Transformer::SourceLineExtractor.extract(paragraph)
|
|
90
|
+
title: paragraph[:title]
|
|
100
91
|
)
|
|
101
92
|
end
|
|
102
93
|
end
|
|
@@ -142,8 +142,7 @@ module Coradoc
|
|
|
142
142
|
|
|
143
143
|
Model::TextElement.new(
|
|
144
144
|
content: transformed,
|
|
145
|
-
line_break: line[:line_break]
|
|
146
|
-
source_line: SourceLineExtractor.extract(line)
|
|
145
|
+
line_break: line[:line_break]
|
|
147
146
|
)
|
|
148
147
|
end
|
|
149
148
|
end
|
|
@@ -153,6 +152,31 @@ module Coradoc
|
|
|
153
152
|
def self.legacy_transform(syntax_tree)
|
|
154
153
|
new.apply(syntax_tree)
|
|
155
154
|
end
|
|
155
|
+
|
|
156
|
+
# Single deepening seam for source_line propagation. Parslet's
|
|
157
|
+
# transform pipeline funnels every rule block through
|
|
158
|
+
# +call_on_match(bindings, block)+; overriding it lets us post-
|
|
159
|
+
# process the block's result and inject +source_line+ from the
|
|
160
|
+
# matched bindings, so individual rules no longer need to call
|
|
161
|
+
# SourceLineExtractor.extract themselves (DRY — was 47 call
|
|
162
|
+
# sites across 7 rule files).
|
|
163
|
+
#
|
|
164
|
+
# Safety:
|
|
165
|
+
# * Only Model::Base results get an injection — Strings, Arrays,
|
|
166
|
+
# and intermediate hashes pass through unchanged.
|
|
167
|
+
# * Existing explicit source_line values are preserved — the
|
|
168
|
+
# injection is fill-in-the-blank, never overwrite.
|
|
169
|
+
# * No Slice in the bindings → SourceLineExtractor returns nil,
|
|
170
|
+
# no injection (synthetic transformations stay clean).
|
|
171
|
+
def call_on_match(bindings, block)
|
|
172
|
+
result = super
|
|
173
|
+
return result unless result.is_a?(Model::Base)
|
|
174
|
+
return result if result.source_line
|
|
175
|
+
|
|
176
|
+
line = self.class::SourceLineExtractor.extract(bindings)
|
|
177
|
+
result.source_line = line if line
|
|
178
|
+
result
|
|
179
|
+
end
|
|
156
180
|
end
|
|
157
181
|
end
|
|
158
182
|
end
|