coradoc-adoc 2.0.33 → 2.0.34
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/model/admonition.rb +0 -1
- data/lib/coradoc/asciidoc/model/attribute.rb +1 -1
- data/lib/coradoc/asciidoc/model/base.rb +1 -1
- data/lib/coradoc/asciidoc/model/bibliography_entry.rb +1 -1
- data/lib/coradoc/asciidoc/model/reviewer_note.rb +0 -2
- data/lib/coradoc/asciidoc/model/title.rb +1 -1
- data/lib/coradoc/asciidoc/parse_error.rb +6 -6
- data/lib/coradoc/asciidoc/parser/base.rb +18 -5
- data/lib/coradoc/asciidoc/parser/block.rb +1 -1
- data/lib/coradoc/asciidoc/parser/block_header.rb +8 -8
- data/lib/coradoc/asciidoc/parser/rule_dispatcher.rb +7 -7
- data/lib/coradoc/asciidoc/transform/text_extract_visitor.rb +3 -3
- data/lib/coradoc/asciidoc/transform/to_core_model.rb +2 -2
- data/lib/coradoc/asciidoc/transformer/attribute_list_normalizer.rb +2 -2
- data/lib/coradoc/asciidoc/transformer/block_rules.rb +3 -2
- data/lib/coradoc/asciidoc/transformer/block_type_classifier.rb +1 -1
- data/lib/coradoc/asciidoc/transformer/header_rules.rb +1 -1
- data/lib/coradoc/asciidoc/transformer/inline_rules.rb +1 -1
- data/lib/coradoc/asciidoc/transformer/list_rules.rb +3 -3
- data/lib/coradoc/asciidoc/transformer/misc_rules.rb +2 -2
- data/lib/coradoc/asciidoc/transformer/source_line_extractor.rb +7 -7
- data/lib/coradoc/asciidoc/transformer/structural_rules.rb +1 -1
- data/lib/coradoc/asciidoc/transformer/table_cell_builder.rb +6 -6
- data/lib/coradoc/asciidoc/transformer/table_layout.rb +1 -1
- data/lib/coradoc/asciidoc/transformer/text_rules.rb +1 -1
- data/lib/coradoc/asciidoc/transformer.rb +9 -8
- data/lib/coradoc/asciidoc/typographic_quotes.rb +2 -2
- data/lib/coradoc/asciidoc/version.rb +1 -1
- data/lib/coradoc/asciidoc.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bc2b5c2f53fa18844c9b33a2083b07e6f4a4fab8eac18ca2e3f0cc6211f5f4c7
|
|
4
|
+
data.tar.gz: 8b0d84abd2eef737e536e63811279e2520134d9f23860667dfcd2167855521f9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5e016f7d12d34b9dc307583120f436f4ab6742fbfec161cbb9b006a72efc373a2413fcc12010b2f395cbacb2586bf9096528a0c0a028cf934a5b4a543aa7ad6f
|
|
7
|
+
data.tar.gz: ca1cf91e5acca757738b3f39907376777f870b0e4a203fc746b96653b3dec58ab87d7ea2bbb5f7a8a266ed19c7010e6d5e98d8e9fd4623f68802bd34d0993bf3
|
|
@@ -36,7 +36,7 @@ module Coradoc
|
|
|
36
36
|
attribute :id, :string
|
|
37
37
|
|
|
38
38
|
# 1-indexed source line where this element begins, when known.
|
|
39
|
-
# Populated by the
|
|
39
|
+
# Populated by the Parsanol transformer from the matched Slice's
|
|
40
40
|
# line_and_column. nil for programmatically constructed models.
|
|
41
41
|
# Single source of truth for source-position propagation through
|
|
42
42
|
# AsciiDoc::Model → CoreModel (Issue 1, STATUS-2026-06-28).
|
|
@@ -35,7 +35,7 @@ module Coradoc
|
|
|
35
35
|
|
|
36
36
|
# Coerce a raw parser AST value into the canonical ref_text string.
|
|
37
37
|
# Accepts the shapes produced by Parser::Bibliography for `:ref_text`:
|
|
38
|
-
# nil,
|
|
38
|
+
# nil, Parsanol::Slice, plain String, single Model::Base, or an Array
|
|
39
39
|
# of any of these. Model objects (TextElement, Inline::Italic, etc.)
|
|
40
40
|
# are flattened via TextExtractVisitor so their text content is
|
|
41
41
|
# preserved instead of leaking `#<Class:0x...>` inspect strings.
|
|
@@ -39,8 +39,6 @@ module Coradoc
|
|
|
39
39
|
# Content can be any AsciiDoc elements (paragraphs, lists, etc.)
|
|
40
40
|
attribute :content,
|
|
41
41
|
Coradoc::AsciiDoc::Model::Base,
|
|
42
|
-
collection: true,
|
|
43
|
-
initialize_empty: true,
|
|
44
42
|
polymorphic: [
|
|
45
43
|
Coradoc::AsciiDoc::Model::TextElement,
|
|
46
44
|
Coradoc::AsciiDoc::Model::Paragraph,
|
|
@@ -37,7 +37,7 @@ module Coradoc
|
|
|
37
37
|
include Coradoc::AsciiDoc::Model::Anchorable
|
|
38
38
|
|
|
39
39
|
attribute :id, :string
|
|
40
|
-
attribute :content, Coradoc::AsciiDoc::Model::TextElement
|
|
40
|
+
attribute :content, Coradoc::AsciiDoc::Model::TextElement
|
|
41
41
|
# attribute :level, :string
|
|
42
42
|
attribute :level_int, :integer
|
|
43
43
|
attribute :line_break, :string, default: -> { "\n" }
|
|
@@ -81,12 +81,12 @@ module Coradoc
|
|
|
81
81
|
parts.join("\n")
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
# Create a ParseError from a
|
|
84
|
+
# Create a ParseError from a Parsanol exception
|
|
85
85
|
#
|
|
86
|
-
# @param exception [
|
|
86
|
+
# @param exception [Parsanol::ParseFailed] The Parsanol exception
|
|
87
87
|
# @param source [String] The original source text
|
|
88
88
|
# @return [ParseError] A new ParseError with extracted context
|
|
89
|
-
def self.
|
|
89
|
+
def self.from_parse_failure(exception, source = nil)
|
|
90
90
|
return exception if exception.is_a?(ParseError)
|
|
91
91
|
|
|
92
92
|
line, column = extract_location(exception)
|
|
@@ -107,12 +107,12 @@ module Coradoc
|
|
|
107
107
|
new(exception.message, cause: exception)
|
|
108
108
|
end
|
|
109
109
|
|
|
110
|
-
# Extract line and column from
|
|
110
|
+
# Extract line and column from Parsanol error
|
|
111
111
|
#
|
|
112
|
-
# @param exception [
|
|
112
|
+
# @param exception [Parsanol::ParseFailed] The Parsanol exception
|
|
113
113
|
# @return [Array<Integer, Integer>] Line and column numbers
|
|
114
114
|
def self.extract_location(exception)
|
|
115
|
-
return [nil, nil] unless exception.is_a?(
|
|
115
|
+
return [nil, nil] unless exception.is_a?(Parsanol::ParseFailed)
|
|
116
116
|
|
|
117
117
|
cause = exception.cause
|
|
118
118
|
return [nil, nil] unless cause
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require '
|
|
4
|
-
require '
|
|
3
|
+
require 'parsanol'
|
|
4
|
+
require 'parsanol/convenience'
|
|
5
5
|
|
|
6
6
|
module Coradoc
|
|
7
7
|
module AsciiDoc
|
|
@@ -26,7 +26,7 @@ module Coradoc
|
|
|
26
26
|
autoload :Text, 'coradoc/asciidoc/parser/text'
|
|
27
27
|
autoload :Stem, 'coradoc/asciidoc/parser/stem'
|
|
28
28
|
|
|
29
|
-
class Base <
|
|
29
|
+
class Base < Parsanol::Parser
|
|
30
30
|
include Admonition
|
|
31
31
|
include AttributeList
|
|
32
32
|
include Bibliography
|
|
@@ -81,10 +81,23 @@ module Coradoc
|
|
|
81
81
|
# @return [Hash] The parsed AST object
|
|
82
82
|
def self.parse(string)
|
|
83
83
|
new.parse(string)
|
|
84
|
-
rescue
|
|
84
|
+
rescue Parsanol::ParseFailed => e
|
|
85
85
|
warn e.parse_failure_cause.ascii_tree
|
|
86
86
|
end
|
|
87
87
|
|
|
88
|
+
# The Ruby engine is the required surface for this grammar.
|
|
89
|
+
# parsanol 1.3.44 fixes capture WRITES across the bridge
|
|
90
|
+
# (parsanol-ruby#80 — verified with a continuation-style repro),
|
|
91
|
+
# but the native tree still diverges from the Ruby-engine tree
|
|
92
|
+
# on attribute-list constructs: 69 suite failures natively from
|
|
93
|
+
# transform rules receiving raw Hashes where models are
|
|
94
|
+
# expected (e.g. Image::AttributeExtractor.promote_positional).
|
|
95
|
+
# Drop the override when native/Ruby tree parity holds for this
|
|
96
|
+
# grammar.
|
|
97
|
+
def parse(string, **options)
|
|
98
|
+
super(string, **options, mode: options.fetch(:mode, :ruby))
|
|
99
|
+
end
|
|
100
|
+
|
|
88
101
|
def rule_dispatch(rule_name, *, **)
|
|
89
102
|
RuleDispatcher.dispatch(self, rule_name, *, **)
|
|
90
103
|
end
|
|
@@ -98,7 +111,7 @@ module Coradoc
|
|
|
98
111
|
end
|
|
99
112
|
end
|
|
100
113
|
|
|
101
|
-
# Wrap every parser rule for
|
|
114
|
+
# Wrap every parser rule for Parsanol memoization. Must run after all
|
|
102
115
|
# parser modules are included in Base so that instance_method(rule_name)
|
|
103
116
|
# finds the methods defined by every module.
|
|
104
117
|
RuleDispatcher.apply(Base)
|
|
@@ -193,7 +193,7 @@ module Coradoc
|
|
|
193
193
|
str(c.captures[capture_key].to_s.strip)
|
|
194
194
|
end
|
|
195
195
|
|
|
196
|
-
# Closure so the call bypasses
|
|
196
|
+
# Closure so the call bypasses Parsanol's method_missing inside the
|
|
197
197
|
# dynamic block. capture() stashes the parsed AST (a nested Hash for
|
|
198
198
|
# a `[source,ruby]` header). Inspect the structure directly so we
|
|
199
199
|
# don't depend on Ruby's Hash#to_s format (it changed in 3.4).
|
|
@@ -18,17 +18,17 @@ module Coradoc
|
|
|
18
18
|
# titles. The section's heading IS its title. Mixing the two shapes
|
|
19
19
|
# into one rule caused `section_block` to admit `.Foo` lines that
|
|
20
20
|
# collided with `section_title`'s `:title` capture, triggering
|
|
21
|
-
#
|
|
21
|
+
# Parsanol's "Duplicate subtrees while merging result … (keys:
|
|
22
22
|
# [:title])" warning and silently dropping the block title.
|
|
23
23
|
#
|
|
24
24
|
# Before this module existed, every block-like rule inlined its own
|
|
25
25
|
# header rule with subtly different slot orderings — and several
|
|
26
|
-
# captured the same
|
|
27
|
-
# which triggered
|
|
26
|
+
# captured the same Parsanol key more than once in a single sequence,
|
|
27
|
+
# which triggered Parsanol's "Duplicate subtrees" warning and silently
|
|
28
28
|
# discarded one of the captured values.
|
|
29
29
|
#
|
|
30
30
|
# `attribute_blocks` accepts one or more consecutive `[...]` attribute
|
|
31
|
-
# lists, captured as a
|
|
31
|
+
# lists, captured as a Parsanol sequence under the :attribute_list key.
|
|
32
32
|
# Real-world AsciiDoc often stacks attribute lists before a block:
|
|
33
33
|
#
|
|
34
34
|
# [role=quote]
|
|
@@ -46,7 +46,7 @@ module Coradoc
|
|
|
46
46
|
# an optional `.Title` line before its body. Single canonical
|
|
47
47
|
# order; each of title, id, and attribute_blocks is optional and
|
|
48
48
|
# matched at most once.
|
|
49
|
-
# @return [
|
|
49
|
+
# @return [Parsanol::Atoms::Base]
|
|
50
50
|
def block_header
|
|
51
51
|
block_title.maybe >>
|
|
52
52
|
element_id.maybe >>
|
|
@@ -57,18 +57,18 @@ module Coradoc
|
|
|
57
57
|
# sections — the section heading itself is the title. Sections
|
|
58
58
|
# still accept the same element_id and attribute_blocks slots
|
|
59
59
|
# that blocks do (`[[anchor]]`, `[appendix]`, `[role=x]`, etc.).
|
|
60
|
-
# @return [
|
|
60
|
+
# @return [Parsanol::Atoms::Base]
|
|
61
61
|
def section_header
|
|
62
62
|
element_id.maybe >>
|
|
63
63
|
attribute_blocks.maybe
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
# One or more consecutive attribute_list + newline sequences, captured
|
|
67
|
-
# as a
|
|
67
|
+
# as a Parsanol sequence under :attribute_list. When multiple `[...]`
|
|
68
68
|
# blocks precede a delimiter, all of them reach the transformer; when
|
|
69
69
|
# only one appears, the sequence has a single element and the existing
|
|
70
70
|
# transformer rule handles it the same way as before.
|
|
71
|
-
# @return [
|
|
71
|
+
# @return [Parsanol::Atoms::Base]
|
|
72
72
|
def attribute_blocks
|
|
73
73
|
(attribute_list >> newline).repeat(1).as(:attribute_list)
|
|
74
74
|
end
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
module Coradoc
|
|
4
4
|
module AsciiDoc
|
|
5
5
|
module Parser
|
|
6
|
-
# Wraps every parser rule for
|
|
6
|
+
# Wraps every parser rule for Parsanol memoization.
|
|
7
7
|
#
|
|
8
8
|
# Parameterized rules (e.g., `block_style(n_deep, delimiter, repeater)`)
|
|
9
|
-
# cannot be memoized by
|
|
9
|
+
# cannot be memoized by Parsanol directly because their result depends
|
|
10
10
|
# on the args. This module aliases each rule to a per-args dispatch
|
|
11
|
-
# rule so
|
|
11
|
+
# rule so Parsanol sees a memoizable, parameterless rule for every
|
|
12
12
|
# (rule_name, args) combination. Parameterless rules get a single
|
|
13
13
|
# memoized alias.
|
|
14
14
|
#
|
|
@@ -141,11 +141,11 @@ module Coradoc
|
|
|
141
141
|
:"#{alias_name}_#{key}"
|
|
142
142
|
end
|
|
143
143
|
|
|
144
|
-
# Build a
|
|
145
|
-
# args and forwards to the original aliased rule. Using
|
|
144
|
+
# Build a Parsanol memoizable rule that closes over the captured
|
|
145
|
+
# args and forwards to the original aliased rule. Using Parsanol's
|
|
146
146
|
# class-level `rule()` (not define_method on singleton_class) is
|
|
147
|
-
# essential —
|
|
148
|
-
# depend on the rule going through the standard
|
|
147
|
+
# essential — Parsanol's memoization, `as()`, and tree building
|
|
148
|
+
# depend on the rule going through the standard Parsanol machinery.
|
|
149
149
|
def build_dispatch_rule(parser_class, original_alias, rule_name, args, kwargs)
|
|
150
150
|
parser_class.class_eval do
|
|
151
151
|
rule(rule_name) do
|
|
@@ -23,7 +23,7 @@ module Coradoc
|
|
|
23
23
|
model
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
def
|
|
26
|
+
def visit_parsanol_slice(model)
|
|
27
27
|
model.to_s
|
|
28
28
|
end
|
|
29
29
|
|
|
@@ -127,7 +127,7 @@ module Coradoc
|
|
|
127
127
|
case model
|
|
128
128
|
when nil then visit_nil(model)
|
|
129
129
|
when String then visit_string(model)
|
|
130
|
-
when
|
|
130
|
+
when Parsanol::Slice then visit_parsanol_slice(model)
|
|
131
131
|
when CoreModel::TextContent then visit_core_model_text_content(model)
|
|
132
132
|
when CoreModel::Image then visit_core_model_image(model)
|
|
133
133
|
when CoreModel::InlineElement then visit_core_model_inline(model)
|
|
@@ -149,7 +149,7 @@ module Coradoc
|
|
|
149
149
|
when Model::LineBreak, Model::CommentLine, Model::CommentBlock then ''
|
|
150
150
|
when Model::Base then visit_base_model(model)
|
|
151
151
|
else
|
|
152
|
-
model.class.name.start_with?('
|
|
152
|
+
model.class.name.start_with?('Parsanol::') ? model.to_s : ''
|
|
153
153
|
end
|
|
154
154
|
end
|
|
155
155
|
end
|
|
@@ -128,7 +128,7 @@ module Coradoc
|
|
|
128
128
|
else
|
|
129
129
|
[text]
|
|
130
130
|
end
|
|
131
|
-
rescue
|
|
131
|
+
rescue Parsanol::ParseFailed
|
|
132
132
|
[text]
|
|
133
133
|
end
|
|
134
134
|
|
|
@@ -151,7 +151,7 @@ module Coradoc
|
|
|
151
151
|
else
|
|
152
152
|
transformed
|
|
153
153
|
end
|
|
154
|
-
rescue
|
|
154
|
+
rescue Parsanol::ParseFailed
|
|
155
155
|
text
|
|
156
156
|
end
|
|
157
157
|
end
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
module Coradoc
|
|
4
4
|
module AsciiDoc
|
|
5
|
-
class Transformer <
|
|
5
|
+
class Transformer < Parsanol::Transform
|
|
6
6
|
# Pure-function module for normalizing raw parser `:attribute_list`
|
|
7
7
|
# values into a single canonical Model::AttributeList.
|
|
8
8
|
#
|
|
9
9
|
# The parser's `block_header` rule captures every consecutive `[...]`
|
|
10
|
-
# block before a structural element as a
|
|
10
|
+
# block before a structural element as a Parsanol sequence under
|
|
11
11
|
# `:attribute_list`. Real-world AsciiDoc often stacks multiple lists
|
|
12
12
|
# before a single delimiter:
|
|
13
13
|
#
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Coradoc
|
|
4
4
|
module AsciiDoc
|
|
5
|
-
class Transformer <
|
|
5
|
+
class Transformer < Parsanol::Transform
|
|
6
6
|
# Module containing block element transformation rules
|
|
7
7
|
module BlockRules
|
|
8
8
|
def self.apply(transformer_class)
|
|
@@ -48,8 +48,9 @@ module Coradoc
|
|
|
48
48
|
content: sequence(:content)
|
|
49
49
|
) do
|
|
50
50
|
canonical = Coradoc::AsciiDoc::Transform::ElementTransformers::AdmonitionStyles.canonicalize(admonition_type.to_s)
|
|
51
|
+
content_value = content.is_a?(Array) && content.length == 1 ? content.first : content
|
|
51
52
|
Model::Admonition.new(
|
|
52
|
-
content:
|
|
53
|
+
content: content_value,
|
|
53
54
|
type: canonical
|
|
54
55
|
)
|
|
55
56
|
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Coradoc
|
|
4
4
|
module AsciiDoc
|
|
5
|
-
class Transformer <
|
|
5
|
+
class Transformer < Parsanol::Transform
|
|
6
6
|
# Module containing list transformation rules
|
|
7
7
|
module ListRules
|
|
8
8
|
class << self
|
|
@@ -199,10 +199,10 @@ module Coradoc
|
|
|
199
199
|
case term_data
|
|
200
200
|
when Hash
|
|
201
201
|
text = term_data[:text]
|
|
202
|
-
text = text.to_s if text.is_a?(
|
|
202
|
+
text = text.to_s if text.is_a?(Parsanol::Slice) || text.is_a?(String)
|
|
203
203
|
text = text.content.to_s if text.is_a?(Model::TextElement)
|
|
204
204
|
id = term_data[:id]
|
|
205
|
-
id = id.to_s if id.is_a?(
|
|
205
|
+
id = id.to_s if id.is_a?(Parsanol::Slice)
|
|
206
206
|
{ text: text.to_s, id: id, delimiter: delim.to_s }
|
|
207
207
|
when Model::TextElement
|
|
208
208
|
{ text: term_data.content.to_s, id: term_data.id, delimiter: delim.to_s }
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Coradoc
|
|
4
4
|
module AsciiDoc
|
|
5
|
-
class Transformer <
|
|
5
|
+
class Transformer < Parsanol::Transform
|
|
6
6
|
# Module containing miscellaneous transformation rules
|
|
7
7
|
module MiscRules
|
|
8
8
|
def self.apply(transformer_class)
|
|
@@ -62,7 +62,7 @@ module Coradoc
|
|
|
62
62
|
|
|
63
63
|
attributes.each do |a|
|
|
64
64
|
case a
|
|
65
|
-
when
|
|
65
|
+
when Parsanol::Slice
|
|
66
66
|
attr_list.add_positional(a.to_s)
|
|
67
67
|
when String
|
|
68
68
|
attr_list.add_positional(a)
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require '
|
|
3
|
+
require 'parsanol'
|
|
4
4
|
|
|
5
5
|
module Coradoc
|
|
6
6
|
module AsciiDoc
|
|
7
|
-
class Transformer <
|
|
8
|
-
# Walks a
|
|
9
|
-
# returns the 1-indexed source line of the first +
|
|
7
|
+
class Transformer < Parsanol::Transform
|
|
8
|
+
# Walks a Parsanol AST subtree (Hash/Array/Slice/String/Model) and
|
|
9
|
+
# returns the 1-indexed source line of the first +Parsanol::Slice+
|
|
10
10
|
# or Model::Base#source_line it finds.
|
|
11
11
|
#
|
|
12
|
-
#
|
|
12
|
+
# Parsanol preserves byte offsets on every matched slice
|
|
13
13
|
# (+slice.line_and_column+ returns +[line, column]+); the
|
|
14
14
|
# transformer receives these slices in the AST but most rules
|
|
15
15
|
# discard the position when building Model objects. This helper
|
|
@@ -18,7 +18,7 @@ module Coradoc
|
|
|
18
18
|
# parser.
|
|
19
19
|
#
|
|
20
20
|
# Handles two distinct shapes:
|
|
21
|
-
# * Pre-transform AST (Hash/Array of
|
|
21
|
+
# * Pre-transform AST (Hash/Array of Parsanol::Slice) — used by
|
|
22
22
|
# rules that bind raw slices via +simple(:x)+.
|
|
23
23
|
# * Post-transform Model tree (Model::Base instances whose
|
|
24
24
|
# +source_line+ was populated by an earlier rule) — used by
|
|
@@ -33,7 +33,7 @@ module Coradoc
|
|
|
33
33
|
|
|
34
34
|
def extract(node)
|
|
35
35
|
case node
|
|
36
|
-
when
|
|
36
|
+
when Parsanol::Slice then line_of(node)
|
|
37
37
|
when Coradoc::AsciiDoc::Model::Base then node.source_line
|
|
38
38
|
when Hash then extract_from_hash(node)
|
|
39
39
|
when Array then extract_from_array(node)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Coradoc
|
|
4
4
|
module AsciiDoc
|
|
5
|
-
class Transformer <
|
|
5
|
+
class Transformer < Parsanol::Transform
|
|
6
6
|
# Pure functions for parsing the cell-format prefix (`2+^.^a`) and
|
|
7
7
|
# building a Model::TableCell from raw parser values.
|
|
8
8
|
#
|
|
@@ -27,7 +27,7 @@ module Coradoc
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
# Coerce the parser-supplied cell content into a plain String.
|
|
30
|
-
# The cell parser emits `text:` as either a single
|
|
30
|
+
# The cell parser emits `text:` as either a single Parsanol::Slice
|
|
31
31
|
# or an Array of slices (from `.repeat(0)`). An empty Array must
|
|
32
32
|
# map to "" — Ruby's `[].to_s` returns "[]", which previously
|
|
33
33
|
# leaked into TableCell content as a phantom "[]" cell.
|
|
@@ -70,7 +70,7 @@ module Coradoc
|
|
|
70
70
|
transformed = Transformer.new.apply(ast)
|
|
71
71
|
content_array = transformed.is_a?(Array) ? transformed : [transformed]
|
|
72
72
|
[Model::TextElement.new(content: content_array)]
|
|
73
|
-
rescue
|
|
73
|
+
rescue Parsanol::ParseFailed
|
|
74
74
|
[Model::TextElement.new(content: text.to_s)]
|
|
75
75
|
end
|
|
76
76
|
end
|
|
@@ -100,13 +100,13 @@ module Coradoc
|
|
|
100
100
|
before_transformed = Transformer.new.apply(before_ast)
|
|
101
101
|
before_array = before_transformed.is_a?(Array) ? before_transformed : [before_transformed]
|
|
102
102
|
before_elements = [Model::TextElement.new(content: before_array)]
|
|
103
|
-
rescue
|
|
103
|
+
rescue Parsanol::ParseFailed
|
|
104
104
|
before_elements = [Model::TextElement.new(content: before_list)]
|
|
105
105
|
end
|
|
106
106
|
end
|
|
107
107
|
|
|
108
108
|
return before_elements + [transformed]
|
|
109
|
-
rescue
|
|
109
|
+
rescue Parsanol::ParseFailed
|
|
110
110
|
# fall through to inline parsing
|
|
111
111
|
end
|
|
112
112
|
end
|
|
@@ -117,7 +117,7 @@ module Coradoc
|
|
|
117
117
|
transformed = Transformer.new.apply(ast)
|
|
118
118
|
content_array = transformed.is_a?(Array) ? transformed : [transformed]
|
|
119
119
|
[Model::TextElement.new(content: content_array)]
|
|
120
|
-
rescue
|
|
120
|
+
rescue Parsanol::ParseFailed
|
|
121
121
|
[Model::TextElement.new(content: text_str)]
|
|
122
122
|
end
|
|
123
123
|
end
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require '
|
|
3
|
+
require 'parsanol'
|
|
4
4
|
|
|
5
5
|
module Coradoc
|
|
6
6
|
module AsciiDoc
|
|
7
|
-
#
|
|
7
|
+
# Parsanol::Transform subclass that converts AST to AsciiDoc model objects.
|
|
8
8
|
#
|
|
9
9
|
# This transformer uses a modular rule system where each group of rules
|
|
10
10
|
# is defined in a separate file for maintainability.
|
|
@@ -18,7 +18,7 @@ module Coradoc
|
|
|
18
18
|
# - StructuralRules: Sections, tables, documents
|
|
19
19
|
# - MiscRules: Comments, attributes, media elements
|
|
20
20
|
#
|
|
21
|
-
class Transformer <
|
|
21
|
+
class Transformer < Parsanol::Transform
|
|
22
22
|
# Autoload rule modules at the class level.
|
|
23
23
|
# Each rule file reopens this class and defines a module inside it.
|
|
24
24
|
# The file path matches the expected constant path.
|
|
@@ -128,7 +128,7 @@ module Coradoc
|
|
|
128
128
|
# Used by the paragraph and reviewer_note rules to share the same
|
|
129
129
|
# line-shape handling (DRY).
|
|
130
130
|
def self.lines_to_text_elements(lines)
|
|
131
|
-
#
|
|
131
|
+
# Parsanol may deliver `lines` as a single Hash (one line captured)
|
|
132
132
|
# or an Array of Hashes (multiple lines). `Array(hash)` converts
|
|
133
133
|
# to nested pairs, which we don't want — normalize explicitly.
|
|
134
134
|
normalized = case lines
|
|
@@ -218,11 +218,12 @@ module Coradoc
|
|
|
218
218
|
new.apply(syntax_tree)
|
|
219
219
|
end
|
|
220
220
|
|
|
221
|
-
# Single deepening seam for source_line propagation.
|
|
221
|
+
# Single deepening seam for source_line propagation. Parsanol's
|
|
222
222
|
# transform pipeline funnels every rule block through
|
|
223
|
-
# +call_on_match(bindings, block)
|
|
224
|
-
#
|
|
225
|
-
#
|
|
223
|
+
# +call_on_match(bindings, block)+ (restored as the stable seam in
|
|
224
|
+
# parsanol 1.3.39, GH-74). Overriding it lets us post-process the
|
|
225
|
+
# block's result and inject +source_line+ from the matched
|
|
226
|
+
# bindings, so individual rules no longer need to call
|
|
226
227
|
# SourceLineExtractor.extract themselves (DRY — was 47 call
|
|
227
228
|
# sites across 7 rule files).
|
|
228
229
|
#
|
|
@@ -22,12 +22,12 @@ module Coradoc
|
|
|
22
22
|
"`'" => '’' # U+2019 right single
|
|
23
23
|
}.freeze
|
|
24
24
|
|
|
25
|
-
# All four 2-char patterns, suitable for building a
|
|
25
|
+
# All four 2-char patterns, suitable for building a Parsanol alternation.
|
|
26
26
|
# @return [Array<String>]
|
|
27
27
|
PATTERNS = PATTERN_TO_CHAR.keys.freeze
|
|
28
28
|
|
|
29
29
|
# Look up the Unicode char for a matched pattern.
|
|
30
|
-
# @param pattern [String,
|
|
30
|
+
# @param pattern [String, Parsanol::Slice] the matched 2-char pattern
|
|
31
31
|
# @return [String] the Unicode curly quote char
|
|
32
32
|
def self.char_for(pattern)
|
|
33
33
|
PATTERN_TO_CHAR.fetch(pattern.to_s, pattern.to_s)
|
data/lib/coradoc/asciidoc.rb
CHANGED
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.
|
|
4
|
+
version: 2.0.34
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -38,7 +38,7 @@ dependencies:
|
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
39
|
version: 0.8.0
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
|
-
name:
|
|
41
|
+
name: parsanol
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
43
43
|
requirements:
|
|
44
44
|
- - ">="
|