coradoc-adoc 2.0.0
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 +7 -0
- data/.rspec +3 -0
- data/lib/coradoc/asciidoc/model/admonition.rb +37 -0
- data/lib/coradoc/asciidoc/model/anchorable.rb +64 -0
- data/lib/coradoc/asciidoc/model/attached.rb +26 -0
- data/lib/coradoc/asciidoc/model/attribute.rb +22 -0
- data/lib/coradoc/asciidoc/model/attribute_list/matchers.rb +45 -0
- data/lib/coradoc/asciidoc/model/attribute_list.rb +230 -0
- data/lib/coradoc/asciidoc/model/attribute_list_attribute.rb +11 -0
- data/lib/coradoc/asciidoc/model/audio.rb +44 -0
- data/lib/coradoc/asciidoc/model/author.rb +36 -0
- data/lib/coradoc/asciidoc/model/base.rb +141 -0
- data/lib/coradoc/asciidoc/model/bibliography.rb +37 -0
- data/lib/coradoc/asciidoc/model/bibliography_entry.rb +38 -0
- data/lib/coradoc/asciidoc/model/block/core.rb +139 -0
- data/lib/coradoc/asciidoc/model/block/example.rb +14 -0
- data/lib/coradoc/asciidoc/model/block/listing.rb +14 -0
- data/lib/coradoc/asciidoc/model/block/literal.rb +14 -0
- data/lib/coradoc/asciidoc/model/block/open.rb +14 -0
- data/lib/coradoc/asciidoc/model/block/pass.rb +14 -0
- data/lib/coradoc/asciidoc/model/block/quote.rb +14 -0
- data/lib/coradoc/asciidoc/model/block/reviewer_comment.rb +14 -0
- data/lib/coradoc/asciidoc/model/block/side.rb +14 -0
- data/lib/coradoc/asciidoc/model/block/source_code.rb +14 -0
- data/lib/coradoc/asciidoc/model/block.rb +21 -0
- data/lib/coradoc/asciidoc/model/break.rb +33 -0
- data/lib/coradoc/asciidoc/model/comment_block.rb +33 -0
- data/lib/coradoc/asciidoc/model/comment_line.rb +30 -0
- data/lib/coradoc/asciidoc/model/content_list.rb +334 -0
- data/lib/coradoc/asciidoc/model/document.rb +197 -0
- data/lib/coradoc/asciidoc/model/document_attributes.rb +43 -0
- data/lib/coradoc/asciidoc/model/glossaries.rb +11 -0
- data/lib/coradoc/asciidoc/model/header.rb +57 -0
- data/lib/coradoc/asciidoc/model/highlight.rb +11 -0
- data/lib/coradoc/asciidoc/model/image/block_image/attribute_list.rb +23 -0
- data/lib/coradoc/asciidoc/model/image/block_image.rb +25 -0
- data/lib/coradoc/asciidoc/model/image/core/attribute_list.rb +43 -0
- data/lib/coradoc/asciidoc/model/image/core.rb +72 -0
- data/lib/coradoc/asciidoc/model/image/inline_image.rb +17 -0
- data/lib/coradoc/asciidoc/model/image.rb +14 -0
- data/lib/coradoc/asciidoc/model/include.rb +66 -0
- data/lib/coradoc/asciidoc/model/inline/anchor.rb +41 -0
- data/lib/coradoc/asciidoc/model/inline/attribute_reference.rb +25 -0
- data/lib/coradoc/asciidoc/model/inline/base.rb +15 -0
- data/lib/coradoc/asciidoc/model/inline/bold.rb +38 -0
- data/lib/coradoc/asciidoc/model/inline/cross_reference.rb +29 -0
- data/lib/coradoc/asciidoc/model/inline/cross_reference_arg.rb +15 -0
- data/lib/coradoc/asciidoc/model/inline/footnote.rb +34 -0
- data/lib/coradoc/asciidoc/model/inline/hard_line_break.rb +24 -0
- data/lib/coradoc/asciidoc/model/inline/highlight.rb +36 -0
- data/lib/coradoc/asciidoc/model/inline/italic.rb +38 -0
- data/lib/coradoc/asciidoc/model/inline/link.rb +46 -0
- data/lib/coradoc/asciidoc/model/inline/monospace.rb +39 -0
- data/lib/coradoc/asciidoc/model/inline/quotation.rb +25 -0
- data/lib/coradoc/asciidoc/model/inline/small.rb +25 -0
- data/lib/coradoc/asciidoc/model/inline/span.rb +38 -0
- data/lib/coradoc/asciidoc/model/inline/stem.rb +24 -0
- data/lib/coradoc/asciidoc/model/inline/strikethrough.rb +39 -0
- data/lib/coradoc/asciidoc/model/inline/subscript.rb +33 -0
- data/lib/coradoc/asciidoc/model/inline/superscript.rb +33 -0
- data/lib/coradoc/asciidoc/model/inline/underline.rb +25 -0
- data/lib/coradoc/asciidoc/model/inline.rb +31 -0
- data/lib/coradoc/asciidoc/model/line_break.rb +11 -0
- data/lib/coradoc/asciidoc/model/list/core.rb +61 -0
- data/lib/coradoc/asciidoc/model/list/definition.rb +27 -0
- data/lib/coradoc/asciidoc/model/list/definition_item.rb +43 -0
- data/lib/coradoc/asciidoc/model/list/item.rb +72 -0
- data/lib/coradoc/asciidoc/model/list/nestable.rb +14 -0
- data/lib/coradoc/asciidoc/model/list/ordered.rb +34 -0
- data/lib/coradoc/asciidoc/model/list/unordered.rb +34 -0
- data/lib/coradoc/asciidoc/model/list.rb +29 -0
- data/lib/coradoc/asciidoc/model/named_attribute.rb +12 -0
- data/lib/coradoc/asciidoc/model/paragraph.rb +59 -0
- data/lib/coradoc/asciidoc/model/rejected_positional_attribute.rb +12 -0
- data/lib/coradoc/asciidoc/model/resolvable.rb +71 -0
- data/lib/coradoc/asciidoc/model/resolver.rb +430 -0
- data/lib/coradoc/asciidoc/model/reviewer_note.rb +54 -0
- data/lib/coradoc/asciidoc/model/revision.rb +47 -0
- data/lib/coradoc/asciidoc/model/section.rb +109 -0
- data/lib/coradoc/asciidoc/model/serialization/asciidoc_adapter.rb +28 -0
- data/lib/coradoc/asciidoc/model/serialization/asciidoc_mapping.rb +42 -0
- data/lib/coradoc/asciidoc/model/serialization/asciidoc_mapping_rule.rb +41 -0
- data/lib/coradoc/asciidoc/model/serialization/asciidoc_transform.rb +211 -0
- data/lib/coradoc/asciidoc/model/serialization/errors.rb +57 -0
- data/lib/coradoc/asciidoc/model/serialization.rb +39 -0
- data/lib/coradoc/asciidoc/model/spacing.rb +282 -0
- data/lib/coradoc/asciidoc/model/table.rb +44 -0
- data/lib/coradoc/asciidoc/model/table_cell.rb +122 -0
- data/lib/coradoc/asciidoc/model/table_row.rb +26 -0
- data/lib/coradoc/asciidoc/model/tag.rb +36 -0
- data/lib/coradoc/asciidoc/model/term.rb +48 -0
- data/lib/coradoc/asciidoc/model/text_element.rb +66 -0
- data/lib/coradoc/asciidoc/model/title.rb +85 -0
- data/lib/coradoc/asciidoc/model/video/attribute_list.rb +43 -0
- data/lib/coradoc/asciidoc/model/video.rb +49 -0
- data/lib/coradoc/asciidoc/model.rb +75 -0
- data/lib/coradoc/asciidoc/parse_error.rb +161 -0
- data/lib/coradoc/asciidoc/parser/admonition.rb +26 -0
- data/lib/coradoc/asciidoc/parser/attribute_list.rb +110 -0
- data/lib/coradoc/asciidoc/parser/base.rb +159 -0
- data/lib/coradoc/asciidoc/parser/bibliography.rb +31 -0
- data/lib/coradoc/asciidoc/parser/block.rb +186 -0
- data/lib/coradoc/asciidoc/parser/block_assembler.rb +183 -0
- data/lib/coradoc/asciidoc/parser/cache.rb +155 -0
- data/lib/coradoc/asciidoc/parser/citation.rb +32 -0
- data/lib/coradoc/asciidoc/parser/content.rb +76 -0
- data/lib/coradoc/asciidoc/parser/document_attributes.rb +27 -0
- data/lib/coradoc/asciidoc/parser/fix_files.rb +76 -0
- data/lib/coradoc/asciidoc/parser/header.rb +31 -0
- data/lib/coradoc/asciidoc/parser/inline.rb +199 -0
- data/lib/coradoc/asciidoc/parser/list.rb +130 -0
- data/lib/coradoc/asciidoc/parser/metadata_detector.rb +164 -0
- data/lib/coradoc/asciidoc/parser/paragraph.rb +64 -0
- data/lib/coradoc/asciidoc/parser/section.rb +62 -0
- data/lib/coradoc/asciidoc/parser/stem.rb +19 -0
- data/lib/coradoc/asciidoc/parser/table.rb +166 -0
- data/lib/coradoc/asciidoc/parser/term.rb +70 -0
- data/lib/coradoc/asciidoc/parser/text.rb +156 -0
- data/lib/coradoc/asciidoc/parser.rb +10 -0
- data/lib/coradoc/asciidoc/serializer/adoc_serializer.rb +86 -0
- data/lib/coradoc/asciidoc/serializer/element_registry.rb +95 -0
- data/lib/coradoc/asciidoc/serializer/fallback_serializer.rb +21 -0
- data/lib/coradoc/asciidoc/serializer/formatter.rb +144 -0
- data/lib/coradoc/asciidoc/serializer/registrations.rb +108 -0
- data/lib/coradoc/asciidoc/serializer/serialization_context.rb +238 -0
- data/lib/coradoc/asciidoc/serializer/serializers/admonition.rb +19 -0
- data/lib/coradoc/asciidoc/serializer/serializers/attribute.rb +23 -0
- data/lib/coradoc/asciidoc/serializer/serializers/attribute_list.rb +40 -0
- data/lib/coradoc/asciidoc/serializer/serializers/attribute_list_attribute.rb +18 -0
- data/lib/coradoc/asciidoc/serializer/serializers/audio.rb +33 -0
- data/lib/coradoc/asciidoc/serializer/serializers/author.rb +20 -0
- data/lib/coradoc/asciidoc/serializer/serializers/base.rb +152 -0
- data/lib/coradoc/asciidoc/serializer/serializers/bibliography.rb +35 -0
- data/lib/coradoc/asciidoc/serializer/serializers/bibliography_entry.rb +24 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/core.rb +70 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/example.rb +17 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/listing.rb +22 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/literal.rb +17 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/open.rb +22 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/pass.rb +17 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/quote.rb +17 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/reviewer_comment.rb +17 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/side.rb +22 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/source_code.rb +22 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block.rb +23 -0
- data/lib/coradoc/asciidoc/serializer/serializers/break.rb +18 -0
- data/lib/coradoc/asciidoc/serializer/serializers/comment_block.rb +22 -0
- data/lib/coradoc/asciidoc/serializer/serializers/comment_line.rb +22 -0
- data/lib/coradoc/asciidoc/serializer/serializers/document.rb +65 -0
- data/lib/coradoc/asciidoc/serializer/serializers/document_attributes.rb +21 -0
- data/lib/coradoc/asciidoc/serializer/serializers/header.rb +24 -0
- data/lib/coradoc/asciidoc/serializer/serializers/highlight.rb +23 -0
- data/lib/coradoc/asciidoc/serializer/serializers/image/core.rb +30 -0
- data/lib/coradoc/asciidoc/serializer/serializers/image.rb +14 -0
- data/lib/coradoc/asciidoc/serializer/serializers/include.rb +19 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/anchor.rb +20 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/attribute_reference.rb +20 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/bold.rb +26 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/cross_reference.rb +30 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/cross_reference_arg.rb +20 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/footnote.rb +24 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/hard_line_break.rb +20 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/highlight.rb +26 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/italic.rb +26 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/link.rb +38 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/monospace.rb +26 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/quotation.rb +21 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/small.rb +20 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/span.rb +35 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/stem.rb +23 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/strikethrough.rb +29 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/subscript.rb +29 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/superscript.rb +26 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/underline.rb +20 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline.rb +32 -0
- data/lib/coradoc/asciidoc/serializer/serializers/line_break.rb +18 -0
- data/lib/coradoc/asciidoc/serializer/serializers/list/core.rb +47 -0
- data/lib/coradoc/asciidoc/serializer/serializers/list/definition.rb +35 -0
- data/lib/coradoc/asciidoc/serializer/serializers/list/definition_item.rb +38 -0
- data/lib/coradoc/asciidoc/serializer/serializers/list/item.rb +120 -0
- data/lib/coradoc/asciidoc/serializer/serializers/list/ordered.rb +24 -0
- data/lib/coradoc/asciidoc/serializer/serializers/list/unordered.rb +29 -0
- data/lib/coradoc/asciidoc/serializer/serializers/list.rb +19 -0
- data/lib/coradoc/asciidoc/serializer/serializers/named_attribute.rb +22 -0
- data/lib/coradoc/asciidoc/serializer/serializers/paragraph.rb +65 -0
- data/lib/coradoc/asciidoc/serializer/serializers/reviewer_note.rb +28 -0
- data/lib/coradoc/asciidoc/serializer/serializers/revision.rb +26 -0
- data/lib/coradoc/asciidoc/serializer/serializers/section.rb +37 -0
- data/lib/coradoc/asciidoc/serializer/serializers/table.rb +24 -0
- data/lib/coradoc/asciidoc/serializer/serializers/table_cell.rb +75 -0
- data/lib/coradoc/asciidoc/serializer/serializers/table_row.rb +24 -0
- data/lib/coradoc/asciidoc/serializer/serializers/tag.rb +19 -0
- data/lib/coradoc/asciidoc/serializer/serializers/term.rb +20 -0
- data/lib/coradoc/asciidoc/serializer/serializers/text_element.rb +23 -0
- data/lib/coradoc/asciidoc/serializer/serializers/title.rb +55 -0
- data/lib/coradoc/asciidoc/serializer/serializers/video.rb +33 -0
- data/lib/coradoc/asciidoc/serializer/spacing_strategy.rb +70 -0
- data/lib/coradoc/asciidoc/serializer.rb +75 -0
- data/lib/coradoc/asciidoc/transform/from_core_model.rb +502 -0
- data/lib/coradoc/asciidoc/transform/from_core_model_registrations.rb +126 -0
- data/lib/coradoc/asciidoc/transform/registry.rb +146 -0
- data/lib/coradoc/asciidoc/transform/to_core_model.rb +564 -0
- data/lib/coradoc/asciidoc/transform/to_core_model_registrations.rb +257 -0
- data/lib/coradoc/asciidoc/transform.rb +13 -0
- data/lib/coradoc/asciidoc/transformer/block_rules.rb +101 -0
- data/lib/coradoc/asciidoc/transformer/header_rules.rb +91 -0
- data/lib/coradoc/asciidoc/transformer/inline_rules.rb +179 -0
- data/lib/coradoc/asciidoc/transformer/list_rules.rb +131 -0
- data/lib/coradoc/asciidoc/transformer/misc_rules.rb +196 -0
- data/lib/coradoc/asciidoc/transformer/structural_rules.rb +216 -0
- data/lib/coradoc/asciidoc/transformer/text_rules.rb +107 -0
- data/lib/coradoc/asciidoc/transformer.rb +406 -0
- data/lib/coradoc/asciidoc/version.rb +7 -0
- data/lib/coradoc/asciidoc.rb +148 -0
- data/lib/coradoc/util/asciidoc.rb +71 -0
- data/lib/coradoc/util.rb +8 -0
- metadata +343 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Parser
|
|
6
|
+
module Text
|
|
7
|
+
def space?
|
|
8
|
+
space.maybe
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def space
|
|
12
|
+
str(' ').repeat(1)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def text
|
|
16
|
+
match("[^\n]").repeat(1)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def line_start?
|
|
20
|
+
match('^[^\n]').present?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def line_ending
|
|
24
|
+
str("\n") # | match('[\z]')# | match('$')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def eof?
|
|
28
|
+
any.absent?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def line_end
|
|
32
|
+
str("\n") | str("\r\n") | eof?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def endline
|
|
36
|
+
newline | any.absent?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# def endline_single
|
|
40
|
+
# newline_single | any.absent?
|
|
41
|
+
# end
|
|
42
|
+
|
|
43
|
+
def newline
|
|
44
|
+
(str("\n") | str("\r\n")).repeat(1)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def newline_single
|
|
48
|
+
(str("\n") | str("\r\n"))
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def keyword
|
|
52
|
+
(match('[a-zA-Z0-9_\-.,]') | str('.')).repeat(1)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def empty_line
|
|
56
|
+
str("\n")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def digit
|
|
60
|
+
match('[0-9]')
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def digits
|
|
64
|
+
match('[0-9]').repeat(1)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def word
|
|
68
|
+
match('[a-zA-Z0-9_-]').repeat(1)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def words
|
|
72
|
+
word >> (space? >> word).repeat
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def rich_texts
|
|
76
|
+
rich_text >> (space? >> rich_text).repeat
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def rich_text
|
|
80
|
+
(match('[a-zA-Z0-9_-]') | str('.') | str('*') | match('@')).repeat(1)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def email
|
|
84
|
+
word >> str('@') >> word >> str('.') >> word
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def special_character
|
|
88
|
+
match('^[*:=-]') | str('[#') | str('[[')
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def date
|
|
92
|
+
digit.repeat(2, 4) >> str('-') >>
|
|
93
|
+
digit.repeat(1, 2) >> str('-') >> digit.repeat(1, 2)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def attr_name
|
|
97
|
+
match("[^\t\s]").repeat(1)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def file_path
|
|
101
|
+
match('[^\[]').repeat(1)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def include_directive
|
|
105
|
+
(str('include::') >>
|
|
106
|
+
file_path.as(:path) >>
|
|
107
|
+
attribute_list >>
|
|
108
|
+
(newline | str('')).as(:line_break)
|
|
109
|
+
).as(:include)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# block_image is defined in inline.rb with full syntax
|
|
113
|
+
# inline_image is defined in inline.rb for inline images (image:)
|
|
114
|
+
|
|
115
|
+
def block_image
|
|
116
|
+
(element_id.maybe >>
|
|
117
|
+
block_title.maybe >>
|
|
118
|
+
(attribute_list >> newline).maybe >>
|
|
119
|
+
match('^i') >> str('mage::') >>
|
|
120
|
+
file_path.as(:path) >>
|
|
121
|
+
attribute_list(:attribute_list_macro) >>
|
|
122
|
+
newline.as(:line_break)
|
|
123
|
+
).as(:block_image)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def comment_line
|
|
127
|
+
tag.absent? >>
|
|
128
|
+
(str('//') >> str('/').absent? >>
|
|
129
|
+
space? >>
|
|
130
|
+
text.maybe.as(:comment_text) >>
|
|
131
|
+
line_ending.as(:line_break)
|
|
132
|
+
).as(:comment_line)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def tag
|
|
136
|
+
(str('//') >> str('/').absent? >>
|
|
137
|
+
space? >>
|
|
138
|
+
(str('tag') | str('end')).as(:prefix) >>
|
|
139
|
+
str('::') >> str(':').absent? >>
|
|
140
|
+
match('[^\[]').repeat(1).as(:name) >>
|
|
141
|
+
attribute_list >>
|
|
142
|
+
line_ending.maybe.as(:line_break)
|
|
143
|
+
).as(:tag)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def comment_block
|
|
147
|
+
(str('////') >> line_ending >>
|
|
148
|
+
((line_ending >> str('////')).absent? >> any
|
|
149
|
+
).repeat.as(:comment_text) >>
|
|
150
|
+
line_ending >> str('////')
|
|
151
|
+
).as(:comment_block)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Autoload FallbackSerializer - only needed when no registered serializer is found
|
|
4
|
+
autoload :FallbackSerializer, 'coradoc/asciidoc/serializer/fallback_serializer'
|
|
5
|
+
|
|
6
|
+
module Coradoc
|
|
7
|
+
module AsciiDoc
|
|
8
|
+
module Serializer
|
|
9
|
+
# Main orchestrator for serializing Coradoc models to AsciiDoc format.
|
|
10
|
+
# Dispatches to appropriate serializer via ElementRegistry.
|
|
11
|
+
#
|
|
12
|
+
# This class is ONLY responsible for orchestration and dispatch.
|
|
13
|
+
# Element registration is handled by ElementRegistry.
|
|
14
|
+
class AdocSerializer
|
|
15
|
+
class << self
|
|
16
|
+
# Serialize a Coradoc model to AsciiDoc string
|
|
17
|
+
# @param model [Coradoc::AsciiDoc::Model::Base, Array, String] Model to serialize
|
|
18
|
+
# @param options [Hash] Serialization options
|
|
19
|
+
# @return [String] AsciiDoc representation
|
|
20
|
+
def serialize(model, options = {})
|
|
21
|
+
case model
|
|
22
|
+
when nil
|
|
23
|
+
''
|
|
24
|
+
when String
|
|
25
|
+
model
|
|
26
|
+
when Array
|
|
27
|
+
serialize_array(model, options)
|
|
28
|
+
when Coradoc::AsciiDoc::Model::Base
|
|
29
|
+
serialize_model(model, options)
|
|
30
|
+
when Lutaml::Model::Serializable
|
|
31
|
+
raise ArgumentError,
|
|
32
|
+
"Cannot serialize #{model.class.name} to AsciiDoc. " \
|
|
33
|
+
'Expected a Coradoc::AsciiDoc::Model::Base with a registered serializer.'
|
|
34
|
+
else
|
|
35
|
+
raise ArgumentError,
|
|
36
|
+
"Unknown element type for AsciiDoc serialization: #{model.class}. " \
|
|
37
|
+
'Expected String, Array, or Coradoc::AsciiDoc::Model::Base.'
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Get appropriate serializer instance for a model
|
|
42
|
+
# @param model [Coradoc::AsciiDoc::Model::Base] Model to serialize
|
|
43
|
+
# @return [Serializers::Base] Serializer instance
|
|
44
|
+
def serializer_for(model)
|
|
45
|
+
# Try to find registered serializer
|
|
46
|
+
if ElementRegistry.registered?(model.class)
|
|
47
|
+
serializer_class = ElementRegistry.lookup(model.class)
|
|
48
|
+
return serializer_class.new
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Fallback: use FallbackSerializer which raises a clear error
|
|
52
|
+
return FallbackSerializer.new
|
|
53
|
+
|
|
54
|
+
raise ArgumentError, "No serializer registered for #{model.class.name} and model doesn't respond to to_adoc"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
# Serialize an array of models
|
|
60
|
+
# @param models [Array] Array of models
|
|
61
|
+
# @param options [Hash] Serialization options
|
|
62
|
+
# @return [String] Serialized array
|
|
63
|
+
def serialize_array(models, options = {})
|
|
64
|
+
results = models.map { |model| serialize(model, options) }
|
|
65
|
+
|
|
66
|
+
# Apply spacing if needed
|
|
67
|
+
if options[:apply_spacing]
|
|
68
|
+
SpacingStrategy.apply(models.zip(results).map(&:first), options)
|
|
69
|
+
else
|
|
70
|
+
results.join
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Serialize a single model
|
|
75
|
+
# @param model [Coradoc::AsciiDoc::Model::Base] Model to serialize
|
|
76
|
+
# @param options [Hash] Serialization options
|
|
77
|
+
# @return [String] Serialized model
|
|
78
|
+
def serialize_model(model, options = {})
|
|
79
|
+
serializer = serializer_for(model)
|
|
80
|
+
serializer.serialize(model, options)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Serializer
|
|
6
|
+
# Registry for mapping Coradoc model classes to their AsciiDoc serializers.
|
|
7
|
+
# This is the authoritative source for model→serializer mappings.
|
|
8
|
+
#
|
|
9
|
+
# Pattern mirrors Input::Html::Converters registry for symmetry.
|
|
10
|
+
#
|
|
11
|
+
# @example Registering a custom serializer
|
|
12
|
+
# ElementRegistry.override(Model::Paragraph, CustomParagraphSerializer)
|
|
13
|
+
#
|
|
14
|
+
# @example Wrapping an existing serializer
|
|
15
|
+
# original = ElementRegistry.get(Model::Paragraph)
|
|
16
|
+
# ElementRegistry.override(Model::Paragraph, WrapperSerializer.new(original))
|
|
17
|
+
class ElementRegistry
|
|
18
|
+
class << self
|
|
19
|
+
# Register a serializer for a model class
|
|
20
|
+
# @param model_class [Class] The Coradoc model class
|
|
21
|
+
# @param serializer_class [Class] The serializer class
|
|
22
|
+
def register(model_class, serializer_class)
|
|
23
|
+
registry[model_class] = serializer_class
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Override a serializer for a model class
|
|
27
|
+
# This is an alias for register that makes the intent explicit
|
|
28
|
+
# @param model_class [Class] The Coradoc model class
|
|
29
|
+
# @param serializer_class [Class] The new serializer class
|
|
30
|
+
# @return [Class, nil] The previous serializer class, or nil if none
|
|
31
|
+
def override(model_class, serializer_class)
|
|
32
|
+
previous = registry[model_class]
|
|
33
|
+
registry[model_class] = serializer_class
|
|
34
|
+
previous
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Unregister a serializer for a model class
|
|
38
|
+
# @param model_class [Class] The model class to unregister
|
|
39
|
+
# @return [Class, nil] The removed serializer class, or nil if none
|
|
40
|
+
def unregister(model_class)
|
|
41
|
+
registry.delete(model_class)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Get the serializer for a model class without raising
|
|
45
|
+
# @param model_class [Class] The model class
|
|
46
|
+
# @return [Class, nil] The serializer class, or nil if not registered
|
|
47
|
+
def get(model_class)
|
|
48
|
+
registry[model_class]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Lookup serializer for a model class
|
|
52
|
+
# @param model_class [Class] The model class
|
|
53
|
+
# @return [Class] The serializer class
|
|
54
|
+
# @raise [ArgumentError] If no serializer is registered
|
|
55
|
+
def lookup(model_class)
|
|
56
|
+
serializer_class = registry[model_class]
|
|
57
|
+
|
|
58
|
+
unless serializer_class
|
|
59
|
+
raise ArgumentError,
|
|
60
|
+
"No serializer registered for #{model_class.name}. " \
|
|
61
|
+
'Please register a serializer in ElementRegistry, or the serializer ' \
|
|
62
|
+
'may not have been loaded yet (check Registrations.load_all!)'
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
serializer_class
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Get all registered model classes
|
|
69
|
+
# @return [Array<Class>] Array of registered model classes
|
|
70
|
+
def registered_models
|
|
71
|
+
registry.keys
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Check if a model class has a registered serializer
|
|
75
|
+
# @param model_class [Class] The model class
|
|
76
|
+
# @return [Boolean] True if registered
|
|
77
|
+
def registered?(model_class)
|
|
78
|
+
registry.key?(model_class)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Clear all registrations (mainly for testing)
|
|
82
|
+
def clear!
|
|
83
|
+
registry.clear
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Get the registry hash
|
|
87
|
+
# @return [Hash] Model class => Serializer class mapping
|
|
88
|
+
def registry
|
|
89
|
+
@@registry ||= {}
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Serializer
|
|
6
|
+
# Fallback serializer for models that don't have explicit serializers.
|
|
7
|
+
#
|
|
8
|
+
# NOTE: This serializer does NOT call to_adoc on the model to avoid
|
|
9
|
+
# infinite recursion (model.to_adoc → Serializer.serialize → FallbackSerializer → model.to_adoc).
|
|
10
|
+
# Instead, it raises a clear error indicating the serializer is missing.
|
|
11
|
+
class FallbackSerializer
|
|
12
|
+
def serialize(model, _options = {})
|
|
13
|
+
raise ArgumentError,
|
|
14
|
+
"No serializer registered for #{model.class.name}. " \
|
|
15
|
+
'Please register a serializer in ElementRegistry, or the serializer ' \
|
|
16
|
+
'may not have been loaded yet (check Registrations.load_all!)'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Serializer
|
|
6
|
+
# Handles AsciiDoc-specific formatting for attributes and special structures
|
|
7
|
+
class Formatter
|
|
8
|
+
class << self
|
|
9
|
+
# Format an attribute list for AsciiDoc output
|
|
10
|
+
# @param attrs [Coradoc::AsciiDoc::Model::AttributeList] Attribute list
|
|
11
|
+
# @return [String] Formatted attribute list
|
|
12
|
+
def attribute_list(attrs)
|
|
13
|
+
return '' if attrs.nil?
|
|
14
|
+
|
|
15
|
+
attrs.to_s
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Format block attributes (anchor, role, options, etc.)
|
|
19
|
+
# @param attrs [Hash, Coradoc::AsciiDoc::Model::AttributeList] Block attributes
|
|
20
|
+
# @return [String] Formatted block attributes
|
|
21
|
+
def block_attributes(attrs)
|
|
22
|
+
return '' if attrs.nil?
|
|
23
|
+
return '' if attrs.is_a?(String) && attrs.empty?
|
|
24
|
+
return '' if attrs.is_a?(Hash) && attrs.empty?
|
|
25
|
+
|
|
26
|
+
# If it's an AttributeList model, use its serialization
|
|
27
|
+
return attribute_list(attrs) if attrs.is_a?(Coradoc::AsciiDoc::Model::AttributeList)
|
|
28
|
+
|
|
29
|
+
# Otherwise format as hash
|
|
30
|
+
lines = []
|
|
31
|
+
|
|
32
|
+
# Handle anchor if present
|
|
33
|
+
if attrs[:id] || attrs['id']
|
|
34
|
+
id = attrs[:id] || attrs['id']
|
|
35
|
+
lines << "[[#{id}]]"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Handle other attributes
|
|
39
|
+
attr_parts = []
|
|
40
|
+
attrs.each do |key, value|
|
|
41
|
+
next if [:id, 'id'].include?(key)
|
|
42
|
+
|
|
43
|
+
attr_parts << case key
|
|
44
|
+
when :role, 'role'
|
|
45
|
+
".#{value}"
|
|
46
|
+
when :options, 'options'
|
|
47
|
+
"[#{value}]"
|
|
48
|
+
else
|
|
49
|
+
"#{key}=#{value}"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
lines << "[#{attr_parts.join(',')}]" unless attr_parts.empty?
|
|
54
|
+
lines.join("\n")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Format a section heading
|
|
58
|
+
# @param level [Integer] Section level (1-6)
|
|
59
|
+
# @param title [String] Section title
|
|
60
|
+
# @param id [String, nil] Optional section ID
|
|
61
|
+
# @return [String] Formatted section heading
|
|
62
|
+
def section_heading(level, title, id = nil)
|
|
63
|
+
prefix = '=' * level
|
|
64
|
+
anchor = id ? "[[#{id}]]\n" : ''
|
|
65
|
+
"#{anchor}#{prefix} #{title}"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Format a block delimiter
|
|
69
|
+
# @param type [Symbol] Block type (:example, :sidebar, :quote, etc.)
|
|
70
|
+
# @return [String] Block delimiter
|
|
71
|
+
def block_delimiter(type)
|
|
72
|
+
case type
|
|
73
|
+
when :example
|
|
74
|
+
'===='
|
|
75
|
+
when :sidebar
|
|
76
|
+
'****'
|
|
77
|
+
when :quote
|
|
78
|
+
'____'
|
|
79
|
+
when :listing, :literal
|
|
80
|
+
'----'
|
|
81
|
+
when :passthrough
|
|
82
|
+
'++++'
|
|
83
|
+
else
|
|
84
|
+
'----'
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Format an admonition
|
|
89
|
+
# @param type [String] Admonition type (NOTE, TIP, etc.)
|
|
90
|
+
# @param content [String] Admonition content
|
|
91
|
+
# @return [String] Formatted admonition
|
|
92
|
+
def admonition(type, content)
|
|
93
|
+
"#{type.upcase}: #{content}"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Format a list marker
|
|
97
|
+
# @param type [Symbol] List type (:ordered, :unordered, :definition)
|
|
98
|
+
# @param level [Integer] Nesting level
|
|
99
|
+
# @param index [Integer, nil] Item index for ordered lists
|
|
100
|
+
# @return [String] List marker
|
|
101
|
+
def list_marker(type, level = 1, _index = nil)
|
|
102
|
+
case type
|
|
103
|
+
when :ordered
|
|
104
|
+
"#{'.' * level} "
|
|
105
|
+
when :unordered
|
|
106
|
+
"#{'*' * level} "
|
|
107
|
+
when :definition
|
|
108
|
+
''
|
|
109
|
+
else
|
|
110
|
+
'* '
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Escape special AsciiDoc characters in text
|
|
115
|
+
# Works by prepending a backslash to all delimiter characters
|
|
116
|
+
# in the string that are adjacent to a whitespace.
|
|
117
|
+
# @param text [String] Text to escape
|
|
118
|
+
# @param escape_chars [Array<String>] Characters to escape by prepending backslash
|
|
119
|
+
# @param pass_through [Array<String>] Characters to pass through using pass:[] macro
|
|
120
|
+
# @return [String] Escaped text
|
|
121
|
+
def escape_text(text, escape_chars: [], pass_through: [])
|
|
122
|
+
return '' if text.nil?
|
|
123
|
+
|
|
124
|
+
result = text.to_s.dup
|
|
125
|
+
|
|
126
|
+
regex_chars = Regexp.escape(escape_chars.join)
|
|
127
|
+
unless regex_chars.empty?
|
|
128
|
+
result.gsub!(
|
|
129
|
+
/((?<=\s)[#{regex_chars}]+)|([#{regex_chars}]+(?=\s))/
|
|
130
|
+
) do |match|
|
|
131
|
+
match.chars.map { |c| "\\#{c}" }.join
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
regex_pass = Regexp.escape(pass_through.join)
|
|
136
|
+
result.gsub!(/([#{regex_pass}]+)/, '{pass:[\\1]}') unless regex_pass.empty?
|
|
137
|
+
|
|
138
|
+
result
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Serializer
|
|
6
|
+
# Trigger loading of all serializer registrations
|
|
7
|
+
#
|
|
8
|
+
# Each serializer file self-registers when loaded via autoload.
|
|
9
|
+
# This module triggers the autoload of all serializers by accessing
|
|
10
|
+
# their constants, which causes the registration code in each file to execute.
|
|
11
|
+
module Registrations
|
|
12
|
+
class << self
|
|
13
|
+
# Load all serializers to trigger their registration
|
|
14
|
+
# rubocop:disable Lint/Void - Constants are referenced to trigger autoload
|
|
15
|
+
def load_all!
|
|
16
|
+
# Top-level serializers
|
|
17
|
+
Serializers::Base
|
|
18
|
+
Serializers::Admonition
|
|
19
|
+
Serializers::Attribute
|
|
20
|
+
Serializers::AttributeList
|
|
21
|
+
Serializers::AttributeListAttribute
|
|
22
|
+
Serializers::Audio
|
|
23
|
+
Serializers::Author
|
|
24
|
+
Serializers::Bibliography
|
|
25
|
+
Serializers::BibliographyEntry
|
|
26
|
+
Serializers::Break
|
|
27
|
+
Serializers::CommentBlock
|
|
28
|
+
Serializers::CommentLine
|
|
29
|
+
Serializers::Document
|
|
30
|
+
Serializers::DocumentAttributes
|
|
31
|
+
Serializers::Header
|
|
32
|
+
Serializers::Highlight
|
|
33
|
+
Serializers::Include
|
|
34
|
+
Serializers::LineBreak
|
|
35
|
+
Serializers::List
|
|
36
|
+
Serializers::NamedAttribute
|
|
37
|
+
Serializers::Paragraph
|
|
38
|
+
Serializers::ReviewerNote
|
|
39
|
+
Serializers::Revision
|
|
40
|
+
Serializers::Section
|
|
41
|
+
Serializers::Tag
|
|
42
|
+
Serializers::TableCell
|
|
43
|
+
Serializers::TableRow
|
|
44
|
+
Serializers::Table
|
|
45
|
+
Serializers::Term
|
|
46
|
+
Serializers::TextElement
|
|
47
|
+
Serializers::Title
|
|
48
|
+
Serializers::Video
|
|
49
|
+
|
|
50
|
+
# Block serializers
|
|
51
|
+
Serializers::Block
|
|
52
|
+
Serializers::Block::Core
|
|
53
|
+
Serializers::Block::Example
|
|
54
|
+
Serializers::Block::Listing
|
|
55
|
+
Serializers::Block::Literal
|
|
56
|
+
Serializers::Block::Open
|
|
57
|
+
Serializers::Block::Pass
|
|
58
|
+
Serializers::Block::Quote
|
|
59
|
+
Serializers::Block::ReviewerComment
|
|
60
|
+
Serializers::Block::Side
|
|
61
|
+
Serializers::Block::SourceCode
|
|
62
|
+
|
|
63
|
+
# Image serializers
|
|
64
|
+
Serializers::Image
|
|
65
|
+
Serializers::Image::Core
|
|
66
|
+
|
|
67
|
+
# Inline serializers
|
|
68
|
+
Serializers::Inline
|
|
69
|
+
Serializers::Inline::Anchor
|
|
70
|
+
Serializers::Inline::AttributeReference
|
|
71
|
+
Serializers::Inline::Bold
|
|
72
|
+
Serializers::Inline::CrossReference
|
|
73
|
+
Serializers::Inline::CrossReferenceArg
|
|
74
|
+
Serializers::Inline::Footnote
|
|
75
|
+
Serializers::Inline::HardLineBreak
|
|
76
|
+
Serializers::Inline::Highlight
|
|
77
|
+
Serializers::Inline::Italic
|
|
78
|
+
Serializers::Inline::Link
|
|
79
|
+
Serializers::Inline::Monospace
|
|
80
|
+
Serializers::Inline::Quotation
|
|
81
|
+
Serializers::Inline::Small
|
|
82
|
+
Serializers::Inline::Span
|
|
83
|
+
Serializers::Inline::Stem
|
|
84
|
+
Serializers::Inline::Strikethrough
|
|
85
|
+
Serializers::Inline::Subscript
|
|
86
|
+
Serializers::Inline::Superscript
|
|
87
|
+
Serializers::Inline::Underline
|
|
88
|
+
|
|
89
|
+
# List serializers
|
|
90
|
+
Serializers::List
|
|
91
|
+
Serializers::List::Core
|
|
92
|
+
Serializers::List::Definition
|
|
93
|
+
Serializers::List::DefinitionItem
|
|
94
|
+
Serializers::List::Item
|
|
95
|
+
Serializers::List::Ordered
|
|
96
|
+
Serializers::List::Unordered
|
|
97
|
+
|
|
98
|
+
true
|
|
99
|
+
end
|
|
100
|
+
# rubocop:enable Lint/Void
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Auto-load all on module inclusion
|
|
104
|
+
load_all!
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|