coradoc 1.1.5 → 1.1.7
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/.envrc +1 -0
- data/.irbrc +1 -0
- data/.rspec +3 -0
- data/.rubocop.yml +5 -1
- data/.rubocop_todo.yml +179 -0
- data/Gemfile +11 -0
- data/README.adoc +5 -7
- data/coradoc.gemspec +5 -16
- data/exe/reverse_adoc +1 -1
- data/exe/w2a +1 -1
- data/flake.lock +114 -0
- data/flake.nix +135 -0
- data/lib/coradoc/cli.rb +1 -1
- data/lib/coradoc/converter.rb +4 -5
- data/lib/coradoc/element/attribute.rb +10 -1
- data/lib/coradoc/element/attribute_list.rb +4 -3
- data/lib/coradoc/element/audio.rb +1 -1
- data/lib/coradoc/element/author.rb +2 -2
- data/lib/coradoc/element/base.rb +14 -2
- data/lib/coradoc/element/bibliography.rb +1 -1
- data/lib/coradoc/element/bibliography_entry.rb +1 -1
- data/lib/coradoc/element/block/open.rb +1 -1
- data/lib/coradoc/element/block.rb +1 -1
- data/lib/coradoc/element/document_attributes.rb +8 -2
- data/lib/coradoc/element/image/block_image.rb +3 -2
- data/lib/coradoc/element/image/core.rb +5 -4
- data/lib/coradoc/element/inline/attribute_reference.rb +19 -0
- data/lib/coradoc/element/inline/cross_reference.rb +4 -3
- data/lib/coradoc/element/inline/footnote.rb +24 -0
- data/lib/coradoc/element/inline/small.rb +19 -0
- data/lib/coradoc/element/inline/span.rb +37 -0
- data/lib/coradoc/element/inline/underline.rb +19 -0
- data/lib/coradoc/element/inline.rb +5 -1
- data/lib/coradoc/element/list/core.rb +2 -2
- data/lib/coradoc/element/list/ordered.rb +1 -0
- data/lib/coradoc/element/list/unordered.rb +1 -0
- data/lib/coradoc/element/list_item.rb +19 -20
- data/lib/coradoc/element/table.rb +4 -2
- data/lib/coradoc/element/term.rb +1 -0
- data/lib/coradoc/element/text_element.rb +4 -1
- data/lib/coradoc/element/title.rb +1 -1
- data/lib/coradoc/element/video.rb +2 -2
- data/lib/coradoc/input/adoc.rb +20 -18
- data/lib/coradoc/input/docx.rb +25 -23
- data/lib/coradoc/input/html/README.adoc +1 -1
- data/lib/coradoc/input/html/cleaner.rb +121 -117
- data/lib/coradoc/input/html/config.rb +58 -56
- data/lib/coradoc/input/html/converters/a.rb +44 -39
- data/lib/coradoc/input/html/converters/aside.rb +12 -8
- data/lib/coradoc/input/html/converters/audio.rb +24 -20
- data/lib/coradoc/input/html/converters/base.rb +103 -99
- data/lib/coradoc/input/html/converters/blockquote.rb +18 -14
- data/lib/coradoc/input/html/converters/br.rb +11 -7
- data/lib/coradoc/input/html/converters/bypass.rb +77 -73
- data/lib/coradoc/input/html/converters/code.rb +18 -14
- data/lib/coradoc/input/html/converters/div.rb +15 -11
- data/lib/coradoc/input/html/converters/dl.rb +51 -44
- data/lib/coradoc/input/html/converters/drop.rb +21 -17
- data/lib/coradoc/input/html/converters/em.rb +16 -12
- data/lib/coradoc/input/html/converters/figure.rb +19 -15
- data/lib/coradoc/input/html/converters/h.rb +32 -30
- data/lib/coradoc/input/html/converters/head.rb +17 -13
- data/lib/coradoc/input/html/converters/hr.rb +11 -7
- data/lib/coradoc/input/html/converters/ignore.rb +15 -11
- data/lib/coradoc/input/html/converters/img.rb +98 -93
- data/lib/coradoc/input/html/converters/li.rb +13 -9
- data/lib/coradoc/input/html/converters/mark.rb +14 -10
- data/lib/coradoc/input/html/converters/markup.rb +22 -18
- data/lib/coradoc/input/html/converters/math.rb +26 -19
- data/lib/coradoc/input/html/converters/ol.rb +55 -50
- data/lib/coradoc/input/html/converters/p.rb +16 -12
- data/lib/coradoc/input/html/converters/pass_through.rb +12 -8
- data/lib/coradoc/input/html/converters/pre.rb +49 -45
- data/lib/coradoc/input/html/converters/q.rb +12 -8
- data/lib/coradoc/input/html/converters/strong.rb +15 -11
- data/lib/coradoc/input/html/converters/sub.rb +15 -11
- data/lib/coradoc/input/html/converters/sup.rb +15 -11
- data/lib/coradoc/input/html/converters/table.rb +21 -13
- data/lib/coradoc/input/html/converters/td.rb +64 -60
- data/lib/coradoc/input/html/converters/text.rb +24 -20
- data/lib/coradoc/input/html/converters/th.rb +13 -9
- data/lib/coradoc/input/html/converters/tr.rb +17 -13
- data/lib/coradoc/input/html/converters/video.rb +24 -20
- data/lib/coradoc/input/html/converters.rb +45 -43
- data/lib/coradoc/input/html/errors.rb +8 -6
- data/lib/coradoc/input/html/html_converter.rb +93 -90
- data/lib/coradoc/input/html/plugin.rb +104 -104
- data/lib/coradoc/input/html/plugins/plateau.rb +197 -190
- data/lib/coradoc/input/html/postprocessor.rb +188 -182
- data/lib/coradoc/input/html.rb +34 -32
- data/lib/coradoc/oscal.rb +18 -5
- data/lib/coradoc/output/adoc.rb +13 -11
- data/lib/coradoc/output/coradoc_tree_debug.rb +15 -13
- data/lib/coradoc/parser/asciidoc/admonition.rb +6 -6
- data/lib/coradoc/parser/asciidoc/attribute_list.rb +43 -27
- data/lib/coradoc/parser/asciidoc/base.rb +3 -6
- data/lib/coradoc/parser/asciidoc/bibliography.rb +5 -6
- data/lib/coradoc/parser/asciidoc/block.rb +30 -31
- data/lib/coradoc/parser/asciidoc/citation.rb +11 -29
- data/lib/coradoc/parser/asciidoc/content.rb +23 -33
- data/lib/coradoc/parser/asciidoc/document_attributes.rb +2 -3
- data/lib/coradoc/parser/asciidoc/header.rb +1 -2
- data/lib/coradoc/parser/asciidoc/inline.rb +165 -42
- data/lib/coradoc/parser/asciidoc/list.rb +27 -27
- data/lib/coradoc/parser/asciidoc/paragraph.rb +28 -19
- data/lib/coradoc/parser/asciidoc/section.rb +11 -17
- data/lib/coradoc/parser/asciidoc/table.rb +5 -5
- data/lib/coradoc/parser/asciidoc/term.rb +24 -8
- data/lib/coradoc/parser/asciidoc/text.rb +18 -21
- data/lib/coradoc/parser/base.rb +0 -3
- data/lib/coradoc/reverse_adoc.rb +3 -3
- data/lib/coradoc/transformer.rb +167 -137
- data/lib/coradoc/version.rb +1 -1
- data/lib/reverse_adoc.rb +1 -1
- data/utils/inspect_asciidoc.rb +29 -0
- data/utils/parser_analyzer.rb +14 -14
- data/utils/round_trip.rb +31 -15
- metadata +34 -137
- data/.hound.yml +0 -5
- data/lib/coradoc/element/inline/citation.rb +0 -24
- data/todo.md +0 -10
@@ -1,214 +1,220 @@
|
|
1
|
-
module Coradoc
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
@tree = coradoc
|
15
|
-
end
|
1
|
+
module Coradoc
|
2
|
+
module Input
|
3
|
+
module Html
|
4
|
+
# Postprocessor's aim is to convert a Coradoc tree from
|
5
|
+
# a mess that has been created from HTML into a tree that
|
6
|
+
# is compatible with what we would get out of Coradoc, if
|
7
|
+
# it parsed it directly.
|
8
|
+
class Postprocessor
|
9
|
+
Element = Coradoc::Element
|
10
|
+
|
11
|
+
def self.process(coradoc)
|
12
|
+
new(coradoc).process
|
13
|
+
end
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
#
|
20
|
-
# We are interested in a particular tree:
|
21
|
-
# Element::List::Ordered items:
|
22
|
-
# Element::List::Ordered items: (any depth)
|
23
|
-
# Element::ListItem content:
|
24
|
-
# Element::Title
|
25
|
-
# (any number of other titles of the same scheme)
|
26
|
-
#
|
27
|
-
# This tree is flattened into:
|
28
|
-
# Element::Title
|
29
|
-
# Element::Title (any number of titles)
|
30
|
-
def extract_titles_from_lists
|
31
|
-
@tree = Element::Base.visit(@tree) do |elem, dir|
|
32
|
-
next elem unless dir == :pre
|
33
|
-
next elem unless elem.is_a?(Element::List::Ordered)
|
34
|
-
next elem if elem.items.length != 1
|
35
|
-
|
36
|
-
anchors = []
|
37
|
-
anchors << elem.anchor if elem.anchor
|
38
|
-
|
39
|
-
# Extract ListItem from any depth of List::Ordered
|
40
|
-
processed = elem
|
41
|
-
while processed.is_a?(Element::List::Ordered)
|
42
|
-
if processed.items.length != 1
|
43
|
-
backtrack = true
|
44
|
-
break
|
45
|
-
end
|
46
|
-
anchors << processed.anchor if processed.anchor
|
47
|
-
processed = processed.items.first
|
15
|
+
def initialize(coradoc)
|
16
|
+
@tree = coradoc
|
48
17
|
end
|
49
18
|
|
50
|
-
#
|
51
|
-
|
52
|
-
|
19
|
+
# Extracts titles from lists. This happens in HTML files
|
20
|
+
# generated from DOCX documents by LibreOffice.
|
21
|
+
#
|
22
|
+
# We are interested in a particular tree:
|
23
|
+
# Element::List::Ordered items:
|
24
|
+
# Element::List::Ordered items: (any depth)
|
25
|
+
# Element::ListItem content:
|
26
|
+
# Element::Title
|
27
|
+
# (any number of other titles of the same scheme)
|
28
|
+
#
|
29
|
+
# This tree is flattened into:
|
30
|
+
# Element::Title
|
31
|
+
# Element::Title (any number of titles)
|
32
|
+
def extract_titles_from_lists
|
33
|
+
@tree = Element::Base.visit(@tree) do |elem, dir|
|
34
|
+
next elem unless dir == :pre
|
35
|
+
next elem unless elem.is_a?(Element::List::Ordered)
|
36
|
+
next elem if elem.items.length != 1
|
37
|
+
|
38
|
+
anchors = []
|
39
|
+
anchors << elem.anchor if elem.anchor
|
40
|
+
|
41
|
+
# Extract ListItem from any depth of List::Ordered
|
42
|
+
processed = elem
|
43
|
+
while processed.is_a?(Element::List::Ordered)
|
44
|
+
if processed.items.length != 1
|
45
|
+
backtrack = true
|
46
|
+
break
|
47
|
+
end
|
48
|
+
anchors << processed.anchor if processed.anchor
|
49
|
+
processed = processed.items.first
|
50
|
+
end
|
53
51
|
|
54
|
-
|
52
|
+
# Something went wrong? Anything not matching on the way?
|
53
|
+
next elem if backtrack
|
54
|
+
next elem unless processed.is_a?(Element::ListItem)
|
55
55
|
|
56
|
-
|
57
|
-
titles = processed.content.flatten
|
56
|
+
anchors << processed.anchor if processed.anchor
|
58
57
|
|
59
|
-
|
60
|
-
|
58
|
+
# Now we must have a title (or titles).
|
59
|
+
titles = processed.content.flatten
|
61
60
|
|
62
|
-
|
63
|
-
|
64
|
-
i.is_a?(Element::Title) || i.is_a?(Element::List::Ordered)
|
65
|
-
end
|
61
|
+
# Don't bother if there's no title in there.
|
62
|
+
next elem unless titles.any? { |i| i.is_a? Element::Title }
|
66
63
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
64
|
+
# Ordered is another iteration for our cleanup.
|
65
|
+
next elem unless titles.all? do |i|
|
66
|
+
i.is_a?(Element::Title) || i.is_a?(Element::List::Ordered)
|
67
|
+
end
|
71
68
|
|
72
|
-
|
73
|
-
|
74
|
-
@tree = Element::Base.visit(@tree) do |elem, _dir|
|
75
|
-
if elem.is_a?(Element::Section) && elem.safe_to_collapse?
|
76
|
-
children_classes = Array(elem.contents).map(&:class)
|
77
|
-
count = children_classes.length
|
78
|
-
safe_classes = [Element::Section, Element::Title]
|
79
|
-
|
80
|
-
# Count > 0 because some documents use <div> as a <br>.
|
81
|
-
if count > 0 && children_classes.all? { |i| safe_classes.include?(i) }
|
82
|
-
contents = elem.contents.dup
|
83
|
-
contents.prepend(elem.anchor) if elem.anchor
|
84
|
-
next contents
|
69
|
+
# We are done now.
|
70
|
+
titles + anchors
|
85
71
|
end
|
86
72
|
end
|
87
|
-
elem
|
88
|
-
end
|
89
|
-
end
|
90
73
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
# For each title element, we create a new section. Then we push
|
108
|
-
# all descendant sections into those sections. Otherwise, we push
|
109
|
-
# an element as content of current section.
|
110
|
-
elem.each do |e|
|
111
|
-
if e.is_a? Element::Title
|
112
|
-
title = e
|
113
|
-
content_array = []
|
114
|
-
section_array = []
|
115
|
-
level = title.level_int
|
116
|
-
section = Element::Section.new(
|
117
|
-
title, contents: content_array, sections: section_array
|
118
|
-
)
|
119
|
-
# Some documents may not be consistent and eg. follow H4 after
|
120
|
-
# H2. Let's ensure that proceeding sections will land in a
|
121
|
-
# correct place.
|
122
|
-
(8 - level).times do |j|
|
123
|
-
section_arrays_by_level[level + j] = section_array
|
74
|
+
# Collapse DIVs that only have a title, or nest another DIV.
|
75
|
+
def collapse_meaningless_sections
|
76
|
+
@tree = Element::Base.visit(@tree) do |elem, _dir|
|
77
|
+
if elem.is_a?(Element::Section) && elem.safe_to_collapse?
|
78
|
+
children_classes = Array(elem.contents).map(&:class)
|
79
|
+
count = children_classes.length
|
80
|
+
safe_classes = [Element::Section, Element::Title]
|
81
|
+
|
82
|
+
# Count > 0 because some documents use <div> as a <br>.
|
83
|
+
if count.positive? && children_classes.all? do |i|
|
84
|
+
safe_classes.include?(i)
|
85
|
+
end
|
86
|
+
contents = elem.contents.dup
|
87
|
+
contents.prepend(elem.anchor) if elem.anchor
|
88
|
+
next contents
|
124
89
|
end
|
125
|
-
section_arrays_by_level[level - 1] << section
|
126
|
-
else
|
127
|
-
content_array << e
|
128
90
|
end
|
91
|
+
elem
|
129
92
|
end
|
130
|
-
next new_array
|
131
93
|
end
|
132
|
-
elem
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
def split_sections
|
137
|
-
max_level = Coradoc::Input::HTML.config.split_sections
|
138
|
-
|
139
|
-
return unless max_level
|
140
94
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
95
|
+
# tree should now be more cleaned up, so we can progress with
|
96
|
+
# creating meaningful sections
|
97
|
+
def generate_meaningful_sections
|
98
|
+
@tree = Element::Base.visit(@tree) do |elem, dir|
|
99
|
+
# We are searching for an array, that has a title. This
|
100
|
+
# will be a candidate for our section array.
|
101
|
+
if dir == :post &&
|
102
|
+
elem.is_a?(Array) &&
|
103
|
+
!elem.flatten.grep(Element::Title).empty?
|
104
|
+
|
105
|
+
elem = elem.flatten
|
106
|
+
|
107
|
+
new_array = []
|
108
|
+
content_array = new_array
|
109
|
+
section_arrays_by_level = [new_array] * 8
|
110
|
+
|
111
|
+
# For each title element, we create a new section. Then we push
|
112
|
+
# all descendant sections into those sections. Otherwise, we push
|
113
|
+
# an element as content of current section.
|
114
|
+
elem.each do |e|
|
115
|
+
if e.is_a? Element::Title
|
116
|
+
title = e
|
117
|
+
content_array = []
|
118
|
+
section_array = []
|
119
|
+
level = title.level_int
|
120
|
+
section = Element::Section.new(
|
121
|
+
title, contents: content_array, sections: section_array
|
122
|
+
)
|
123
|
+
# Some documents may not be consistent and eg. follow H4 after
|
124
|
+
# H2. Let's ensure that proceeding sections will land in a
|
125
|
+
# correct place.
|
126
|
+
(8 - level).times do |j|
|
127
|
+
section_arrays_by_level[level + j] = section_array
|
128
|
+
end
|
129
|
+
section_arrays_by_level[level - 1] << section
|
148
130
|
else
|
149
|
-
|
131
|
+
content_array << e
|
150
132
|
end
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
133
|
+
end
|
134
|
+
next new_array
|
135
|
+
end
|
136
|
+
elem
|
137
|
+
end
|
156
138
|
end
|
157
|
-
level.is_a?(Integer) ? "%02d" % level : level
|
158
|
-
end
|
159
139
|
|
160
|
-
|
161
|
-
|
162
|
-
style += "-"
|
163
|
-
style
|
164
|
-
end
|
140
|
+
def split_sections
|
141
|
+
max_level = Coradoc::Input::Html.config.split_sections
|
165
142
|
|
166
|
-
|
167
|
-
title = elem.title if elem.is_a?(Element::Section)
|
143
|
+
return unless max_level
|
168
144
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
# we can compute numbers
|
173
|
-
previous_sections[elem] = parent_sections[title.level_int]
|
174
|
-
parent_sections[title.level_int] = elem
|
175
|
-
parent_sections[(title.level_int + 1)..nil] = nil
|
145
|
+
sections = {}
|
146
|
+
parent_sections = []
|
147
|
+
previous_sections = {}
|
176
148
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
"
|
149
|
+
determine_section_id = ->(elem) do
|
150
|
+
level = if elem.title.style == "appendix"
|
151
|
+
"A"
|
152
|
+
else
|
153
|
+
1
|
154
|
+
end
|
155
|
+
|
156
|
+
section = previous_sections[elem]
|
157
|
+
while section
|
158
|
+
level = level.succ if elem.title.style == section.title.style
|
159
|
+
section = previous_sections[section]
|
160
|
+
end
|
161
|
+
level.is_a?(Integer) ? "%02d" % level : level
|
190
162
|
end
|
191
|
-
else
|
192
|
-
elem
|
193
|
-
end
|
194
|
-
end
|
195
163
|
|
196
|
-
|
197
|
-
|
198
|
-
|
164
|
+
determine_style = ->(elem) do
|
165
|
+
style = elem.title.style || "section"
|
166
|
+
style += "-"
|
167
|
+
style
|
168
|
+
end
|
199
169
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
170
|
+
@tree = Element::Base.visit(@tree) do |elem, dir|
|
171
|
+
title = elem.title if elem.is_a?(Element::Section)
|
172
|
+
|
173
|
+
if title && title.level_int <= max_level
|
174
|
+
if dir == :pre
|
175
|
+
# In the PRE pass, we build a tree of sections, so that
|
176
|
+
# we can compute numbers
|
177
|
+
previous_sections[elem] = parent_sections[title.level_int]
|
178
|
+
parent_sections[title.level_int] = elem
|
179
|
+
parent_sections[(title.level_int + 1)..nil] = nil
|
180
|
+
|
181
|
+
elem
|
182
|
+
else
|
183
|
+
# In the POST pass, we replace the sections with their
|
184
|
+
# include tag.
|
185
|
+
section_file = "sections/"
|
186
|
+
section_file += parent_sections[1..title.level_int].map do |parent|
|
187
|
+
determine_style.(parent) + determine_section_id.(parent)
|
188
|
+
end.join("/")
|
189
|
+
section_file += ".adoc"
|
190
|
+
|
191
|
+
sections[section_file] = elem
|
192
|
+
up = "../" * (title.level_int - 1)
|
193
|
+
"\ninclude::#{up}#{section_file}[]\n"
|
194
|
+
end
|
195
|
+
else
|
196
|
+
elem
|
197
|
+
end
|
198
|
+
end
|
208
199
|
|
209
|
-
|
200
|
+
sections[nil] = @tree
|
201
|
+
@tree = sections
|
202
|
+
end
|
203
|
+
|
204
|
+
def process
|
205
|
+
extract_titles_from_lists
|
206
|
+
collapse_meaningless_sections
|
207
|
+
generate_meaningful_sections
|
208
|
+
# Do it again to simplify the document further.
|
209
|
+
# Since the structure is changed, we may have new meaningful
|
210
|
+
# sections as only children of some meaningless sections.
|
211
|
+
collapse_meaningless_sections
|
212
|
+
|
213
|
+
split_sections
|
210
214
|
|
211
|
-
|
215
|
+
@tree
|
216
|
+
end
|
217
|
+
end
|
212
218
|
end
|
213
219
|
end
|
214
220
|
end
|
data/lib/coradoc/input/html.rb
CHANGED
@@ -13,47 +13,49 @@ require_relative "html/plugin"
|
|
13
13
|
require_relative "html/postprocessor"
|
14
14
|
|
15
15
|
module Coradoc
|
16
|
-
module Input
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
module Input
|
17
|
+
module Html
|
18
|
+
def self.convert(input, options = {})
|
19
|
+
Coradoc::Input::Html::HtmlConverter.convert(input, options)
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
def self.to_coradoc(input, options = {})
|
23
|
+
Input::Html::HtmlConverter.to_coradoc(input, options)
|
24
|
+
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
def self.config
|
27
|
+
@config ||= Config.new
|
28
|
+
yield @config if block_given?
|
29
|
+
@config
|
30
|
+
end
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
32
|
+
def self.cleaner
|
33
|
+
@cleaner ||= Cleaner.new
|
34
|
+
end
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
def self.processor_id
|
37
|
+
:html
|
38
|
+
end
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
40
|
+
def self.processor_match?(filename)
|
41
|
+
%w[.html .htm].any? { |i| filename.downcase.end_with?(i) }
|
42
|
+
end
|
42
43
|
|
43
|
-
|
44
|
-
|
45
|
-
|
44
|
+
def self.processor_execute(input, options = {})
|
45
|
+
to_coradoc(input, options)
|
46
|
+
end
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
def self.processor_postprocess(data, options)
|
49
|
+
if options[:output_processor] == :adoc
|
50
|
+
data.transform_values do |v|
|
51
|
+
Input::Html::HtmlConverter.cleanup_result(v, options)
|
52
|
+
end
|
53
|
+
else
|
54
|
+
data
|
51
55
|
end
|
52
|
-
else
|
53
|
-
data
|
54
56
|
end
|
55
|
-
end
|
56
57
|
|
57
|
-
|
58
|
+
Coradoc::Input.define(self)
|
59
|
+
end
|
58
60
|
end
|
59
61
|
end
|
data/lib/coradoc/oscal.rb
CHANGED
@@ -15,7 +15,7 @@ module Coradoc
|
|
15
15
|
def to_oscal
|
16
16
|
{
|
17
17
|
"metadata" => _doc.document_attributes.to_hash,
|
18
|
-
"groups"
|
18
|
+
"groups" => sections_as_groups,
|
19
19
|
}
|
20
20
|
end
|
21
21
|
|
@@ -37,7 +37,15 @@ module Coradoc
|
|
37
37
|
sections.map do |section|
|
38
38
|
Hash.new.tap do |hash|
|
39
39
|
hash["id"] = section.id
|
40
|
-
|
40
|
+
# Use definition lists if present, otherwise fall back to glossaries
|
41
|
+
props_items = if section.respond_to?(:definition_lists) && section.definition_lists && !section.definition_lists.empty?
|
42
|
+
section.definition_lists.first.items
|
43
|
+
elsif section.glossaries && !section.glossaries.empty?
|
44
|
+
section.glossaries.items
|
45
|
+
else
|
46
|
+
[]
|
47
|
+
end
|
48
|
+
hash["props"] = build_oscal_props(props_items)
|
41
49
|
hash["parts"] = build_oscal_parts(section.sections)
|
42
50
|
end
|
43
51
|
end
|
@@ -71,16 +79,21 @@ module Coradoc
|
|
71
79
|
end
|
72
80
|
|
73
81
|
def build_oscal_props(attributes)
|
82
|
+
return [] unless attributes.respond_to?(:map)
|
83
|
+
|
74
84
|
attributes.map do |attribute|
|
85
|
+
next unless attribute.respond_to?(:key) && attribute.respond_to?(:value)
|
86
|
+
|
75
87
|
Hash.new.tap do |hash|
|
76
88
|
hash["name"] = attribute.key.to_s.downcase
|
77
|
-
hash["value"] = attribute.value
|
89
|
+
hash["value"] = attribute.value.to_s
|
78
90
|
end
|
79
|
-
end
|
91
|
+
end.compact
|
80
92
|
end
|
81
93
|
|
82
94
|
def build_oscal_prose(paragraph)
|
83
|
-
paragraph
|
95
|
+
return nil unless paragraph.respond_to?(:texts)
|
96
|
+
paragraph.texts&.join(" ")
|
84
97
|
end
|
85
98
|
end
|
86
99
|
end
|
data/lib/coradoc/output/adoc.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
module Coradoc
|
2
|
-
module Output
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
module Output
|
3
|
+
module Adoc
|
4
|
+
def self.processor_id
|
5
|
+
:adoc
|
6
|
+
end
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
def self.processor_match?(filename)
|
9
|
+
%w[.adoc].any? { |i| filename.downcase.end_with?(i) }
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
def self.processor_execute(input, _options = {})
|
13
|
+
input.transform_values { |i| Coradoc::Generator.gen_adoc(i) }
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
+
Coradoc::Output.define(self)
|
17
|
+
end
|
16
18
|
end
|
17
19
|
end
|
@@ -1,19 +1,21 @@
|
|
1
1
|
module Coradoc
|
2
|
-
module Output
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
module Output
|
3
|
+
module CoradocTreeDebug
|
4
|
+
def self.processor_id
|
5
|
+
:coradoc_tree_debug
|
6
|
+
end
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
def self.processor_match?(_filename)
|
9
|
+
false
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
def self.processor_execute(input, _options = {})
|
13
|
+
out = StringIO.new
|
14
|
+
PP.pp(input, out)
|
15
|
+
{ nil => out.string }
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
+
Coradoc::Output.define(self)
|
19
|
+
end
|
18
20
|
end
|
19
21
|
end
|
@@ -3,20 +3,20 @@ module Coradoc
|
|
3
3
|
module Asciidoc
|
4
4
|
module Admonition
|
5
5
|
def admonition_type
|
6
|
-
str(
|
7
|
-
|
8
|
-
|
6
|
+
str("NOTE") | str("TIP") | str("EDITOR") |
|
7
|
+
str("IMPORTANT") | str("WARNING") | str("CAUTION") |
|
8
|
+
str("TODO")
|
9
9
|
# requires atypical syntax for access?
|
10
10
|
# | str('DANGER')
|
11
11
|
# | str('SAFETY PRECAUTION')
|
12
12
|
end
|
13
|
+
|
13
14
|
def admonition_line
|
14
|
-
admonition_type.as(:admonition_type) >> str(
|
15
|
-
(
|
15
|
+
admonition_type.as(:admonition_type) >> str(": ") >>
|
16
16
|
(text.as(:text) >>
|
17
17
|
line_ending.as(:line_break)
|
18
18
|
).repeat(1)
|
19
|
-
|
19
|
+
.as(:content)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|