coradoc-adoc 2.0.18 → 2.0.19
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/parser/block.rb +39 -4
- data/lib/coradoc/asciidoc/transform/element_transformers/include_transformer.rb +56 -0
- data/lib/coradoc/asciidoc/transform/element_transformers.rb +1 -0
- data/lib/coradoc/asciidoc/transform/from_core_model.rb +43 -0
- data/lib/coradoc/asciidoc/transform/from_core_model_registrations.rb +5 -0
- data/lib/coradoc/asciidoc/transform/to_core_model_registrations.rb +10 -1
- data/lib/coradoc/asciidoc/transformer/block_rules.rb +4 -0
- data/lib/coradoc/asciidoc/transformer/block_type_classifier.rb +9 -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: 817eba65c55a5dea765ab8e80ee5542a1353741659c8a32ef4eb80e39f052dcb
|
|
4
|
+
data.tar.gz: 25a07bc63696b7ba27933c9724c0a5ada466dc7cd0f37350ae4c9a4a475afbec
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c3d26bcc8f91f799f455f051109933875545219b14e9556cc4d5774dcda16e9abdcb1f0e6a090f1d9aea35c49d4d7f5ed8c6bae2b1e47a76cc75a86270e47cd7
|
|
7
|
+
data.tar.gz: 50a575b3666d1d6df0a8813a9761345ced5d895b2c73bf80347d8fb24e36c396389d4901fa22a6f34e1adcea6cb4d5b697bdab121dc495603da88740753e821d
|
|
@@ -22,7 +22,8 @@ module Coradoc
|
|
|
22
22
|
# - "|" separates cells within the table
|
|
23
23
|
|
|
24
24
|
def block(n_deep = 3)
|
|
25
|
-
(
|
|
25
|
+
(markdown_code_block(n_deep) |
|
|
26
|
+
example_block(n_deep) |
|
|
26
27
|
sidebar_block(n_deep) |
|
|
27
28
|
source_block(n_deep) |
|
|
28
29
|
quote_block(n_deep) |
|
|
@@ -60,6 +61,38 @@ module Coradoc
|
|
|
60
61
|
block_style_exact(n_deep, '-', 2)
|
|
61
62
|
end
|
|
62
63
|
|
|
64
|
+
# Markdown-style fenced code block: triple-backtick (or longer)
|
|
65
|
+
# fence with an optional language tag on the opening line. Behaves
|
|
66
|
+
# as a verbatim source block — same model as `[source,lang]\n----`.
|
|
67
|
+
# Pragmatic permissiveness for content that originates from (or is
|
|
68
|
+
# edited alongside) Markdown; not standard AsciiDoc but widely
|
|
69
|
+
# accepted (GitHub's renderer treats ``` as a listing delimiter).
|
|
70
|
+
def markdown_code_block(n_deep = 3)
|
|
71
|
+
capture_key = :"md_fence_#{n_deep}"
|
|
72
|
+
opening_fence = str('`').repeat(3).capture(capture_key)
|
|
73
|
+
closing_fence = dynamic do |_s, c|
|
|
74
|
+
str(c.captures[capture_key].to_s.strip)
|
|
75
|
+
end
|
|
76
|
+
language = (space? >> match("[A-Za-z0-9_+.-]").repeat(1).as(:language)).maybe
|
|
77
|
+
|
|
78
|
+
block_content_with_closing = dynamic do |_s, c|
|
|
79
|
+
fence_str = c.captures[capture_key].to_s.strip
|
|
80
|
+
closing_pattern = closing_fence >> space? >> newline
|
|
81
|
+
|
|
82
|
+
content = text_line(false, unguarded: true, verbatim: true) |
|
|
83
|
+
empty_line.as(:line_break)
|
|
84
|
+
|
|
85
|
+
(closing_pattern.absent? >> content).repeat(1)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
block_header >>
|
|
89
|
+
line_start? >>
|
|
90
|
+
opening_fence.as(:delimiter) >> language >> newline >>
|
|
91
|
+
block_content_with_closing.as(:lines) >>
|
|
92
|
+
line_start? >>
|
|
93
|
+
closing_fence >> space? >> newline
|
|
94
|
+
end
|
|
95
|
+
|
|
63
96
|
def block_title
|
|
64
97
|
(line_start? >> block_delimiter.absent?) >>
|
|
65
98
|
str('.') >> space.absent? >> text.as(:title) >> newline
|
|
@@ -80,8 +113,9 @@ module Coradoc
|
|
|
80
113
|
c.repeat(1)
|
|
81
114
|
end
|
|
82
115
|
|
|
83
|
-
# Block delimiter: 4+ identical characters
|
|
84
|
-
#
|
|
116
|
+
# Block delimiter: 4+ identical characters, or 2 dashes for open
|
|
117
|
+
# blocks, or 3+ backticks for Markdown-style code fences. Used by
|
|
118
|
+
# paragraph.rb to reject lines that look like block delimiters.
|
|
85
119
|
# NOTE: repeat(4,) means 4 or more (not exactly 4)
|
|
86
120
|
def block_delimiter
|
|
87
121
|
line_start? >>
|
|
@@ -91,7 +125,8 @@ module Coradoc
|
|
|
91
125
|
str('+') |
|
|
92
126
|
str('.') |
|
|
93
127
|
str('-')).repeat(4) | # 4+ characters for most blocks
|
|
94
|
-
str('-').repeat(2, 2)
|
|
128
|
+
str('-').repeat(2, 2) | # Exactly 2 for open block
|
|
129
|
+
str('`').repeat(3)) >> # 3+ for Markdown code fences
|
|
95
130
|
newline
|
|
96
131
|
end
|
|
97
132
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Transform
|
|
6
|
+
module ElementTransformers
|
|
7
|
+
# Transforms AsciiDoc {Model::Include} into the canonical
|
|
8
|
+
# {CoreModel::Include}. The CoreModel node carries the parsed
|
|
9
|
+
# options as a typed {CoreModel::IncludeOptions} instance plus
|
|
10
|
+
# the raw bracket body for verbatim round-trip.
|
|
11
|
+
class IncludeTransformer
|
|
12
|
+
class << self
|
|
13
|
+
# @param model [Coradoc::AsciiDoc::Model::Include]
|
|
14
|
+
# @return [Coradoc::CoreModel::Include]
|
|
15
|
+
def transform_include(model)
|
|
16
|
+
options_hash = extract_options_hash(model.attributes)
|
|
17
|
+
options = CoreModel::IncludeOptions.from_hash(options_hash)
|
|
18
|
+
raw = extract_raw_options(model.attributes)
|
|
19
|
+
|
|
20
|
+
CoreModel::Include.new(
|
|
21
|
+
target: model.path.to_s,
|
|
22
|
+
options: options,
|
|
23
|
+
raw_options: raw,
|
|
24
|
+
line_break: model.line_break.to_s
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def extract_options_hash(attrs)
|
|
31
|
+
return {} unless attrs.is_a?(Coradoc::AsciiDoc::Model::AttributeList)
|
|
32
|
+
|
|
33
|
+
attrs.named.each_with_object({}) do |attr, hash|
|
|
34
|
+
hash[attr.name.to_s] = serialize_named_value(attr.value)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def serialize_named_value(value)
|
|
39
|
+
case value
|
|
40
|
+
when Array then value.map(&:to_s).join(';')
|
|
41
|
+
else value.to_s
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def extract_raw_options(attrs)
|
|
46
|
+
return '' unless attrs.is_a?(Coradoc::AsciiDoc::Model::AttributeList)
|
|
47
|
+
|
|
48
|
+
adoc = attrs.to_adoc(show_empty: false).to_s
|
|
49
|
+
adoc.gsub(/\A\[|\]\z/, '')
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -10,6 +10,7 @@ module Coradoc
|
|
|
10
10
|
autoload :InlineTransformer, "#{__dir__}/element_transformers/inline_transformer"
|
|
11
11
|
autoload :TableTransformer, "#{__dir__}/element_transformers/table_transformer"
|
|
12
12
|
autoload :OtherTransformer, "#{__dir__}/element_transformers/other_transformer"
|
|
13
|
+
autoload :IncludeTransformer, "#{__dir__}/element_transformers/include_transformer"
|
|
13
14
|
end
|
|
14
15
|
end
|
|
15
16
|
end
|
|
@@ -388,8 +388,51 @@ module Coradoc
|
|
|
388
388
|
)
|
|
389
389
|
end
|
|
390
390
|
|
|
391
|
+
def transform_include(include)
|
|
392
|
+
Coradoc::AsciiDoc::Model::Include.new(
|
|
393
|
+
path: include.target.to_s,
|
|
394
|
+
attributes: build_include_attributes(include),
|
|
395
|
+
line_break: include.line_break.to_s
|
|
396
|
+
)
|
|
397
|
+
end
|
|
398
|
+
|
|
391
399
|
private
|
|
392
400
|
|
|
401
|
+
def build_include_attributes(include)
|
|
402
|
+
list = Coradoc::AsciiDoc::Model::AttributeList.new
|
|
403
|
+
options = include.options
|
|
404
|
+
return list if options.nil?
|
|
405
|
+
|
|
406
|
+
add_tag_attribute(list, options)
|
|
407
|
+
add_simple_attribute(list, 'lines', options.lines_spec)
|
|
408
|
+
add_leveloffset_attribute(list, options)
|
|
409
|
+
add_simple_attribute(list, 'indent', options.indent&.to_s)
|
|
410
|
+
add_simple_attribute(list, 'encoding', options.file_encoding)
|
|
411
|
+
list
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
def add_simple_attribute(list, name, value)
|
|
415
|
+
return if value.nil? || value.to_s.empty?
|
|
416
|
+
|
|
417
|
+
list.add_named(name, value.to_s)
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
def add_tag_attribute(list, options)
|
|
421
|
+
if options.tags_wildcard
|
|
422
|
+
list.add_named('tags', '*')
|
|
423
|
+
elsif options.tags_inverted
|
|
424
|
+
list.add_named('tags', '**')
|
|
425
|
+
elsif options.tags.any?
|
|
426
|
+
list.add_named('tags', options.tags.join(';'))
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
def add_leveloffset_attribute(list, options)
|
|
431
|
+
return if options.leveloffset.nil?
|
|
432
|
+
|
|
433
|
+
list.add_named('leveloffset', options.leveloffset.to_s)
|
|
434
|
+
end
|
|
435
|
+
|
|
393
436
|
# If the first CoreModel child is a FrontmatterBlock, serialize
|
|
394
437
|
# it to YAML text via Codec (single source of truth) and pop it
|
|
395
438
|
# from the children list. Returns [remaining_children,
|
|
@@ -120,6 +120,11 @@ module Coradoc
|
|
|
120
120
|
Coradoc::CoreModel::CommentLine,
|
|
121
121
|
->(model) { FromCoreModel.transform_comment_line(model) }
|
|
122
122
|
)
|
|
123
|
+
|
|
124
|
+
Registry.register(
|
|
125
|
+
Coradoc::CoreModel::Include,
|
|
126
|
+
->(model) { FromCoreModel.transform_include(model) }
|
|
127
|
+
)
|
|
123
128
|
end
|
|
124
129
|
end
|
|
125
130
|
end
|
|
@@ -10,6 +10,7 @@ module Coradoc
|
|
|
10
10
|
Inl = ElementTransformers::InlineTransformer
|
|
11
11
|
Tbl = ElementTransformers::TableTransformer
|
|
12
12
|
Oth = ElementTransformers::OtherTransformer
|
|
13
|
+
Inc = ElementTransformers::IncludeTransformer
|
|
13
14
|
|
|
14
15
|
class << self
|
|
15
16
|
def register_all!
|
|
@@ -231,8 +232,16 @@ module Coradoc
|
|
|
231
232
|
->(model) { Oth.transform_bibliography_entry(model) }
|
|
232
233
|
)
|
|
233
234
|
|
|
234
|
-
|
|
235
|
+
# Include directives become first-class CoreModel::Include nodes
|
|
236
|
+
# (link edges in a text graph). To splice their content inline,
|
|
237
|
+
# call +Coradoc.resolve_includes(doc, base_dir:)+ on the parsed
|
|
238
|
+
# document — that step is intentionally separate from parse.
|
|
239
|
+
Registry.register(
|
|
235
240
|
Coradoc::AsciiDoc::Model::Include,
|
|
241
|
+
->(model) { Inc.transform_include(model) }
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
[
|
|
236
245
|
Coradoc::AsciiDoc::Model::Audio,
|
|
237
246
|
Coradoc::AsciiDoc::Model::Video,
|
|
238
247
|
Coradoc::AsciiDoc::Model::ContentList,
|
|
@@ -25,6 +25,10 @@ module Coradoc
|
|
|
25
25
|
lines: lines,
|
|
26
26
|
ordering: ordering
|
|
27
27
|
}
|
|
28
|
+
# Markdown fences carry the language tag inline (```ruby);
|
|
29
|
+
# pass it through so the SourceCode classifier entry can set
|
|
30
|
+
# block.lang directly, which extract_block_language prefers.
|
|
31
|
+
opts[:lang] = block[:language].to_s if block.key?(:language) && !block[:language].nil?
|
|
28
32
|
BlockTypeClassifier.classify(delimiter, opts, attribute_list)
|
|
29
33
|
end
|
|
30
34
|
|
|
@@ -28,7 +28,15 @@ module Coradoc
|
|
|
28
28
|
['.', 4, nil, ->(opts, attrs) { Model::Block::Literal.new(**opts.merge(attributes: attrs)) }],
|
|
29
29
|
['_', 4, nil, ->(opts, attrs) { Model::Block::Quote.new(**opts.merge(attributes: attrs)) }],
|
|
30
30
|
['-', 4, nil, ->(opts, attrs) { Model::Block::SourceCode.new(**opts.merge(attributes: attrs)) }],
|
|
31
|
-
['-', 2, 2, ->(opts, attrs) { Model::Block::Open.new(**opts.merge(attributes: attrs)) }]
|
|
31
|
+
['-', 2, 2, ->(opts, attrs) { Model::Block::Open.new(**opts.merge(attributes: attrs)) }],
|
|
32
|
+
# Markdown-style triple-backtick fence: behaves as a SourceCode
|
|
33
|
+
# block. The language tag parsed from the opening fence is passed
|
|
34
|
+
# through opts[:lang]; extract_block_language prefers block.lang.
|
|
35
|
+
['`', 3, nil, ->(opts, attrs) {
|
|
36
|
+
model_opts = opts.merge(attributes: attrs, delimiter_char: '`')
|
|
37
|
+
model_opts[:lang] = opts[:lang] if opts.key?(:lang)
|
|
38
|
+
Model::Block::SourceCode.new(**model_opts)
|
|
39
|
+
}]
|
|
32
40
|
].freeze
|
|
33
41
|
|
|
34
42
|
module_function
|
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.19
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -319,6 +319,7 @@ files:
|
|
|
319
319
|
- lib/coradoc/asciidoc/transform/element_transformers.rb
|
|
320
320
|
- lib/coradoc/asciidoc/transform/element_transformers/block_transformer.rb
|
|
321
321
|
- lib/coradoc/asciidoc/transform/element_transformers/document_transformer.rb
|
|
322
|
+
- lib/coradoc/asciidoc/transform/element_transformers/include_transformer.rb
|
|
322
323
|
- lib/coradoc/asciidoc/transform/element_transformers/inline_transformer.rb
|
|
323
324
|
- lib/coradoc/asciidoc/transform/element_transformers/list_transformer.rb
|
|
324
325
|
- lib/coradoc/asciidoc/transform/element_transformers/other_transformer.rb
|