coradoc 0.2.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.docker/Dockerfile +1 -1
- data/.docker/docker-compose.yml +2 -2
- data/.editorconfig +15 -0
- data/CHANGELOG.md +4 -0
- data/README.md +4 -0
- data/Rakefile +10 -0
- data/coradoc.gemspec +11 -2
- data/exe/reverse_adoc +91 -0
- data/exe/w2a +72 -0
- data/lib/coradoc/document.rb +6 -6
- data/lib/coradoc/element/admonition.rb +8 -6
- data/lib/coradoc/element/attribute.rb +2 -2
- data/lib/coradoc/element/attribute_list.rb +94 -15
- data/lib/coradoc/element/audio.rb +14 -3
- data/lib/coradoc/element/author.rb +18 -14
- data/lib/coradoc/element/base.rb +69 -8
- data/lib/coradoc/element/block/core.rb +10 -6
- data/lib/coradoc/element/block/literal.rb +1 -1
- data/lib/coradoc/element/block/quote.rb +1 -1
- data/lib/coradoc/element/block/sourcecode.rb +2 -2
- data/lib/coradoc/element/break.rb +1 -1
- data/lib/coradoc/element/document_attributes.rb +6 -6
- data/lib/coradoc/element/header.rb +4 -2
- data/lib/coradoc/element/image/block_image.rb +13 -2
- data/lib/coradoc/element/image/core.rb +35 -5
- data/lib/coradoc/element/image/inline_image.rb +2 -2
- data/lib/coradoc/element/image.rb +0 -1
- data/lib/coradoc/element/inline/anchor.rb +4 -2
- data/lib/coradoc/element/inline/bold.rb +10 -4
- data/lib/coradoc/element/inline/cross_reference.rb +4 -2
- data/lib/coradoc/element/inline/hard_line_break.rb +1 -1
- data/lib/coradoc/element/inline/highlight.rb +12 -6
- data/lib/coradoc/element/inline/italic.rb +10 -4
- data/lib/coradoc/element/inline/link.rb +26 -10
- data/lib/coradoc/element/inline/monospace.rb +10 -4
- data/lib/coradoc/element/inline/quotation.rb +4 -1
- data/lib/coradoc/element/inline/subscript.rb +5 -2
- data/lib/coradoc/element/inline/superscript.rb +5 -2
- data/lib/coradoc/element/inline.rb +0 -1
- data/lib/coradoc/element/list/core.rb +10 -8
- data/lib/coradoc/element/list/definition.rb +19 -0
- data/lib/coradoc/element/list/ordered.rb +1 -1
- data/lib/coradoc/element/list/unordered.rb +1 -1
- data/lib/coradoc/element/list.rb +1 -1
- data/lib/coradoc/element/list_item.rb +9 -4
- data/lib/coradoc/element/list_item_definition.rb +32 -0
- data/lib/coradoc/element/paragraph.rb +5 -3
- data/lib/coradoc/element/revision.rb +20 -16
- data/lib/coradoc/element/section.rb +21 -4
- data/lib/coradoc/element/table.rb +36 -19
- data/lib/coradoc/element/text_element.rb +63 -17
- data/lib/coradoc/element/title.rb +27 -7
- data/lib/coradoc/element/video.rb +33 -6
- data/lib/coradoc/generator.rb +2 -2
- data/lib/coradoc/legacy_parser.rb +41 -41
- data/lib/coradoc/oscal.rb +2 -4
- data/lib/coradoc/parser/asciidoc/content.rb +15 -15
- data/lib/coradoc/parser/asciidoc/document_attributes.rb +1 -1
- data/lib/coradoc/parser/asciidoc/header.rb +6 -6
- data/lib/coradoc/parser/asciidoc/section.rb +1 -1
- data/lib/coradoc/reverse_adoc/LICENSE.txt +25 -0
- data/lib/coradoc/reverse_adoc/README.adoc +308 -0
- data/lib/coradoc/reverse_adoc/cleaner.rb +125 -0
- data/lib/coradoc/reverse_adoc/config.rb +73 -0
- data/lib/coradoc/reverse_adoc/converters/a.rb +47 -0
- data/lib/coradoc/reverse_adoc/converters/aside.rb +12 -0
- data/lib/coradoc/reverse_adoc/converters/audio.rb +25 -0
- data/lib/coradoc/reverse_adoc/converters/base.rb +104 -0
- data/lib/coradoc/reverse_adoc/converters/blockquote.rb +18 -0
- data/lib/coradoc/reverse_adoc/converters/br.rb +11 -0
- data/lib/coradoc/reverse_adoc/converters/bypass.rb +77 -0
- data/lib/coradoc/reverse_adoc/converters/code.rb +19 -0
- data/lib/coradoc/reverse_adoc/converters/div.rb +14 -0
- data/lib/coradoc/reverse_adoc/converters/dl.rb +55 -0
- data/lib/coradoc/reverse_adoc/converters/drop.rb +22 -0
- data/lib/coradoc/reverse_adoc/converters/em.rb +17 -0
- data/lib/coradoc/reverse_adoc/converters/figure.rb +21 -0
- data/lib/coradoc/reverse_adoc/converters/h.rb +38 -0
- data/lib/coradoc/reverse_adoc/converters/head.rb +19 -0
- data/lib/coradoc/reverse_adoc/converters/hr.rb +11 -0
- data/lib/coradoc/reverse_adoc/converters/ignore.rb +16 -0
- data/lib/coradoc/reverse_adoc/converters/img.rb +98 -0
- data/lib/coradoc/reverse_adoc/converters/li.rb +13 -0
- data/lib/coradoc/reverse_adoc/converters/mark.rb +15 -0
- data/lib/coradoc/reverse_adoc/converters/markup.rb +27 -0
- data/lib/coradoc/reverse_adoc/converters/math.rb +31 -0
- data/lib/coradoc/reverse_adoc/converters/ol.rb +60 -0
- data/lib/coradoc/reverse_adoc/converters/p.rb +19 -0
- data/lib/coradoc/reverse_adoc/converters/pass_through.rb +13 -0
- data/lib/coradoc/reverse_adoc/converters/pre.rb +51 -0
- data/lib/coradoc/reverse_adoc/converters/q.rb +12 -0
- data/lib/coradoc/reverse_adoc/converters/strong.rb +16 -0
- data/lib/coradoc/reverse_adoc/converters/sub.rb +18 -0
- data/lib/coradoc/reverse_adoc/converters/sup.rb +18 -0
- data/lib/coradoc/reverse_adoc/converters/table.rb +280 -0
- data/lib/coradoc/reverse_adoc/converters/td.rb +77 -0
- data/lib/coradoc/reverse_adoc/converters/text.rb +28 -0
- data/lib/coradoc/reverse_adoc/converters/th.rb +14 -0
- data/lib/coradoc/reverse_adoc/converters/tr.rb +18 -0
- data/lib/coradoc/reverse_adoc/converters/video.rb +25 -0
- data/lib/coradoc/reverse_adoc/converters.rb +53 -0
- data/lib/coradoc/reverse_adoc/errors.rb +10 -0
- data/lib/coradoc/reverse_adoc/html_converter.rb +150 -0
- data/lib/coradoc/reverse_adoc/plugin.rb +131 -0
- data/lib/coradoc/reverse_adoc/plugins/plateau.rb +174 -0
- data/lib/coradoc/reverse_adoc/postprocessor.rb +148 -0
- data/lib/coradoc/reverse_adoc.rb +30 -0
- data/lib/coradoc/transformer.rb +24 -14
- data/lib/coradoc/version.rb +1 -1
- data/lib/reverse_adoc.rb +20 -0
- metadata +184 -5
- data/lib/coradoc/element/inline/image.rb +0 -25
@@ -0,0 +1,47 @@
|
|
1
|
+
require "coradoc"
|
2
|
+
|
3
|
+
module Coradoc::ReverseAdoc
|
4
|
+
module Converters
|
5
|
+
class A < Base
|
6
|
+
def to_coradoc(node, state = {})
|
7
|
+
name = treat_children(node, state)
|
8
|
+
|
9
|
+
href = node["href"]
|
10
|
+
title = extract_title(node)
|
11
|
+
id = node["id"] || node["name"]
|
12
|
+
|
13
|
+
id = id&.gsub(/\s/, "")&.gsub(/__+/, "_")
|
14
|
+
id = nil if id&.empty?
|
15
|
+
|
16
|
+
return "" if /^_Toc\d+$|^_GoBack$/.match?(id)
|
17
|
+
|
18
|
+
return Coradoc::Element::Inline::Anchor.new(id) if id
|
19
|
+
|
20
|
+
if href.to_s.start_with?("#")
|
21
|
+
href = href.sub(/^#/, "").gsub(/\s/, "").gsub(/__+/, "_")
|
22
|
+
return Coradoc::Element::Inline::CrossReference.new(href, name)
|
23
|
+
end
|
24
|
+
|
25
|
+
return name if href.to_s.empty?
|
26
|
+
|
27
|
+
ambigous_characters = /[\w.?&#=%;\[\u{ff}-\u{10ffff}]/
|
28
|
+
if name&.strip == href
|
29
|
+
name = ""
|
30
|
+
right_constrain = textnode_after_start_with?(node, ambigous_characters)
|
31
|
+
end
|
32
|
+
|
33
|
+
out = []
|
34
|
+
out << " " if textnode_before_end_with?(node, ambigous_characters)
|
35
|
+
out << Coradoc::Element::Inline::Link.new(
|
36
|
+
path: href,
|
37
|
+
name: name.strip,
|
38
|
+
title: title.strip,
|
39
|
+
right_constrain: right_constrain,
|
40
|
+
)
|
41
|
+
out
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
register :a, A.new
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Coradoc::ReverseAdoc
|
2
|
+
module Converters
|
3
|
+
class Aside < Base
|
4
|
+
def to_coradoc(node, state = {})
|
5
|
+
content = treat_children(node, state)
|
6
|
+
Coradoc::Element::Block::Side.new(lines: content.lines)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
register :aside, Aside.new
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Coradoc::ReverseAdoc
|
2
|
+
module Converters
|
3
|
+
class Audio < Base
|
4
|
+
def to_coradoc(node, _state = {})
|
5
|
+
src = node["src"]
|
6
|
+
id = node["id"]
|
7
|
+
title = extract_title(node)
|
8
|
+
attributes = Coradoc::Element::AttributeList.new
|
9
|
+
options = options(node)
|
10
|
+
attributes.add_named("options", options) if options.any?
|
11
|
+
Coradoc::Element::Audio.new(title, id: id, src: src,
|
12
|
+
attributes: attributes)
|
13
|
+
end
|
14
|
+
|
15
|
+
def options(node)
|
16
|
+
autoplay = node["autoplay"]
|
17
|
+
loop_attr = node["loop"]
|
18
|
+
controls = node["controls"]
|
19
|
+
[autoplay, loop_attr, controls].compact
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
register :audio, Audio.new
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module Coradoc::ReverseAdoc
|
2
|
+
module Converters
|
3
|
+
class Base
|
4
|
+
# Default implementation to convert a given Nokogiri node
|
5
|
+
# to an AsciiDoc script.
|
6
|
+
# Can be overriden by subclasses.
|
7
|
+
def convert(node, state = {})
|
8
|
+
Coradoc::Generator.gen_adoc(to_coradoc(node, state))
|
9
|
+
end
|
10
|
+
|
11
|
+
# Note: treat_children won't run plugin hooks
|
12
|
+
def treat_children(node, state)
|
13
|
+
node.children.inject("") do |memo, child|
|
14
|
+
memo << treat(child, state)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def treat(node, state)
|
19
|
+
Converters.process(node, state)
|
20
|
+
end
|
21
|
+
|
22
|
+
def treat_children_coradoc(node, state)
|
23
|
+
node.children.inject([]) do |memo, child|
|
24
|
+
memo << treat_coradoc(child, state)
|
25
|
+
end.flatten.reject { |x| x == "" || x.nil? }
|
26
|
+
end
|
27
|
+
|
28
|
+
def treat_coradoc(node, state)
|
29
|
+
Converters.process_coradoc(node, state)
|
30
|
+
end
|
31
|
+
|
32
|
+
def extract_title(node)
|
33
|
+
title = Coradoc::Element::TextElement.escape_keychars(
|
34
|
+
node["title"].to_s,
|
35
|
+
)
|
36
|
+
title.empty? ? "" : %[ #{title}]
|
37
|
+
end
|
38
|
+
|
39
|
+
def node_has_ancestor?(node, name)
|
40
|
+
case name
|
41
|
+
when String
|
42
|
+
node.ancestors.map(&:name).include?(name)
|
43
|
+
when Array
|
44
|
+
(node.ancestors.map(&:name) & name).any?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def textnode_before_end_with?(node, str)
|
49
|
+
return nil unless [String, Regexp].include?(str.class)
|
50
|
+
return nil if str.is_a?(String) && str.empty?
|
51
|
+
|
52
|
+
str = /#{Regexp.escape(str)}/ if str.is_a?(String)
|
53
|
+
str = /(?:#{str})\z/
|
54
|
+
|
55
|
+
node2 = node.at_xpath("preceding-sibling::node()[1]")
|
56
|
+
node2.respond_to?(:text) && node2.text.match?(str)
|
57
|
+
end
|
58
|
+
|
59
|
+
def textnode_after_start_with?(node, str)
|
60
|
+
return nil unless [String, Regexp].include?(str.class)
|
61
|
+
return nil if str.is_a?(String) && str.empty?
|
62
|
+
|
63
|
+
str = /#{Regexp.escape(str)}/ if str.is_a?(String)
|
64
|
+
str = /\A(?:#{str})/
|
65
|
+
|
66
|
+
node2 = node.at_xpath("following-sibling::node()[1]")
|
67
|
+
node2.respond_to?(:text) && node2.text.match?(str)
|
68
|
+
end
|
69
|
+
|
70
|
+
def extract_leading_trailing_whitespace(node)
|
71
|
+
node.text =~ /^(\s+)/
|
72
|
+
leading_whitespace = $1
|
73
|
+
if !leading_whitespace.nil?
|
74
|
+
first_text = node.at_xpath("./text()[1]")
|
75
|
+
first_text.replace(first_text.text.lstrip)
|
76
|
+
leading_whitespace = " "
|
77
|
+
end
|
78
|
+
node.text =~ /(\s+)$/
|
79
|
+
trailing_whitespace = $1
|
80
|
+
if !trailing_whitespace.nil?
|
81
|
+
last_text = node.at_xpath("./text()[last()]")
|
82
|
+
last_text.replace(last_text.text.rstrip)
|
83
|
+
trailing_whitespace = " "
|
84
|
+
end
|
85
|
+
[leading_whitespace, trailing_whitespace]
|
86
|
+
end
|
87
|
+
|
88
|
+
def unconstrained_before?(node)
|
89
|
+
before = node.at_xpath("preceding::node()[1]")
|
90
|
+
|
91
|
+
before &&
|
92
|
+
!before.text.strip.empty? &&
|
93
|
+
before.text[-1]&.match?(/\w/)
|
94
|
+
end
|
95
|
+
|
96
|
+
def unconstrained_after?(node)
|
97
|
+
after = node.at_xpath("following::node()[1]")
|
98
|
+
|
99
|
+
after && !after.text.strip.empty? &&
|
100
|
+
after.text[0]&.match?(/\w|,|;|"|\.\?!/)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Coradoc::ReverseAdoc
|
2
|
+
module Converters
|
3
|
+
class Blockquote < Base
|
4
|
+
def to_coradoc(node, state = {})
|
5
|
+
node["id"]
|
6
|
+
cite = node["cite"]
|
7
|
+
attributes = Coradoc::Element::AttributeList.new
|
8
|
+
attributes.add_positional("quote", cite) if !cite.nil?
|
9
|
+
content = treat_children(node, state).strip
|
10
|
+
content = Coradoc::ReverseAdoc.cleaner.remove_newlines(content)
|
11
|
+
Coradoc::Element::Block::Quote.new(nil, lines: content,
|
12
|
+
attributes: attributes)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
register :blockquote, Blockquote.new
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Coradoc::ReverseAdoc
|
2
|
+
module Converters
|
3
|
+
class Bypass < Base
|
4
|
+
def to_coradoc(node, state = {})
|
5
|
+
treat_children_coradoc(node, state)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
register :document, Bypass.new
|
10
|
+
register :html, Bypass.new
|
11
|
+
register :body, Bypass.new
|
12
|
+
register :span, Bypass.new
|
13
|
+
register :thead, Bypass.new
|
14
|
+
register :tbody, Bypass.new
|
15
|
+
register :tfoot, Bypass.new
|
16
|
+
register :abbr, Bypass.new
|
17
|
+
register :acronym, Bypass.new
|
18
|
+
register :address, Bypass.new
|
19
|
+
register :applet, Bypass.new
|
20
|
+
register :map, Bypass.new
|
21
|
+
register :area, Bypass.new
|
22
|
+
register :bdi, Bypass.new
|
23
|
+
register :bdo, Bypass.new
|
24
|
+
register :big, Bypass.new
|
25
|
+
register :button, Bypass.new
|
26
|
+
register :canvas, Bypass.new
|
27
|
+
register :data, Bypass.new
|
28
|
+
register :datalist, Bypass.new
|
29
|
+
register :del, Bypass.new
|
30
|
+
register :ins, Bypass.new
|
31
|
+
register :dfn, Bypass.new
|
32
|
+
register :dialog, Bypass.new
|
33
|
+
register :embed, Bypass.new
|
34
|
+
register :fieldset, Bypass.new
|
35
|
+
register :font, Bypass.new
|
36
|
+
register :footer, Bypass.new
|
37
|
+
register :form, Bypass.new
|
38
|
+
register :frame, Bypass.new
|
39
|
+
register :frameset, Bypass.new
|
40
|
+
register :header, Bypass.new
|
41
|
+
register :iframe, Bypass.new
|
42
|
+
register :input, Bypass.new
|
43
|
+
register :label, Bypass.new
|
44
|
+
register :legend, Bypass.new
|
45
|
+
register :main, Bypass.new
|
46
|
+
register :menu, Bypass.new
|
47
|
+
register :menulist, Bypass.new
|
48
|
+
register :meter, Bypass.new
|
49
|
+
register :nav, Bypass.new
|
50
|
+
register :noframes, Bypass.new
|
51
|
+
register :noscript, Bypass.new
|
52
|
+
register :object, Bypass.new
|
53
|
+
register :optgroup, Bypass.new
|
54
|
+
register :option, Bypass.new
|
55
|
+
register :output, Bypass.new
|
56
|
+
register :param, Bypass.new
|
57
|
+
register :picture, Bypass.new
|
58
|
+
register :progress, Bypass.new
|
59
|
+
register :ruby, Bypass.new
|
60
|
+
register :rt, Bypass.new
|
61
|
+
register :rp, Bypass.new
|
62
|
+
register :s, Bypass.new
|
63
|
+
register :select, Bypass.new
|
64
|
+
register :small, Bypass.new
|
65
|
+
register :span, Bypass.new
|
66
|
+
register :strike, Bypass.new
|
67
|
+
register :details, Bypass.new
|
68
|
+
register :section, Bypass.new
|
69
|
+
register :summary, Bypass.new
|
70
|
+
register :svg, Bypass.new
|
71
|
+
register :template, Bypass.new
|
72
|
+
register :textarea, Bypass.new
|
73
|
+
register :track, Bypass.new
|
74
|
+
register :u, Bypass.new
|
75
|
+
register :wbr, Bypass.new
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Coradoc::ReverseAdoc
|
2
|
+
module Converters
|
3
|
+
class Code < Markup
|
4
|
+
def coradoc_class
|
5
|
+
Coradoc::Element::Inline::Monospace
|
6
|
+
end
|
7
|
+
|
8
|
+
def markup_ancestor_tag_names
|
9
|
+
%w[code tt kbd samp var]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
register :code, Code.new
|
14
|
+
register :tt, Code.new
|
15
|
+
register :kbd, Code.new
|
16
|
+
register :samp, Code.new
|
17
|
+
register :var, Code.new
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Coradoc::ReverseAdoc
|
2
|
+
module Converters
|
3
|
+
class Div < Base
|
4
|
+
def to_coradoc(node, state = {})
|
5
|
+
id = node["id"]
|
6
|
+
contents = treat_children_coradoc(node, state)
|
7
|
+
Coradoc::Element::Section.new(nil, id: id, contents: contents)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
register :div, Div.new
|
12
|
+
register :article, Div.new
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Coradoc::ReverseAdoc
|
2
|
+
module Converters
|
3
|
+
class Dl < Base
|
4
|
+
def to_coradoc(node, state = {})
|
5
|
+
items = process_dl(node, state)
|
6
|
+
items2 = items.map do |item|
|
7
|
+
Coradoc::Element::ListItemDefinition.new(item[:name], item[:value])
|
8
|
+
end
|
9
|
+
Coradoc::Element::List::Definition.new(items2, delimiter: "::")
|
10
|
+
end
|
11
|
+
|
12
|
+
def process_dl(node, state = {})
|
13
|
+
groups = []
|
14
|
+
current = {name: [], value: []}
|
15
|
+
|
16
|
+
seen_dd = false
|
17
|
+
child = node.at_xpath("*[1]")
|
18
|
+
grandchild = nil
|
19
|
+
while !child.nil?
|
20
|
+
if child.name == "div"
|
21
|
+
grandchild = child.at_xpath("*[1]")
|
22
|
+
while !grandchild.nil?
|
23
|
+
groups, current, seen_dd = process_dt_or_dd(groups, current, seen_dd, grandchild, state)
|
24
|
+
grandchild = grandchild.at_xpath("following-sibling::*[1]")
|
25
|
+
end
|
26
|
+
elsif ["dt", "dd"].include?(child.name)
|
27
|
+
groups, current, seen_dd = process_dt_or_dd(groups, current, seen_dd, child, state)
|
28
|
+
end
|
29
|
+
child = child.at_xpath("following-sibling::*[1]")
|
30
|
+
if current[:name].any? && current[:value].any?
|
31
|
+
groups << current
|
32
|
+
end
|
33
|
+
end
|
34
|
+
groups
|
35
|
+
end
|
36
|
+
|
37
|
+
def process_dt_or_dd(groups, current, seen_dd, subnode, state = {})
|
38
|
+
if subnode.name == "dt"
|
39
|
+
if seen_dd
|
40
|
+
# groups << current
|
41
|
+
current = {name: [], value: []}
|
42
|
+
seen_dd = false
|
43
|
+
end
|
44
|
+
current[:name] += treat_children_coradoc(subnode, state)
|
45
|
+
elsif subnode.name == "dd"
|
46
|
+
current[:value] += treat_children_coradoc(subnode, state)
|
47
|
+
seen_dd = true
|
48
|
+
end
|
49
|
+
[groups, current, seen_dd]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
register :dl, Dl.new
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Coradoc::ReverseAdoc
|
2
|
+
module Converters
|
3
|
+
class Drop < Base
|
4
|
+
def to_coradoc(node, state = {})
|
5
|
+
convert(node, state)
|
6
|
+
end
|
7
|
+
|
8
|
+
def convert(_node, _state = {})
|
9
|
+
""
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
register :caption, Drop.new
|
14
|
+
register :figcaption, Drop.new
|
15
|
+
register :title, Drop.new
|
16
|
+
register :link, Drop.new
|
17
|
+
register :style, Drop.new
|
18
|
+
register :meta, Drop.new
|
19
|
+
register :script, Drop.new
|
20
|
+
register :comment, Drop.new
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Coradoc::ReverseAdoc
|
2
|
+
module Converters
|
3
|
+
class Em < Markup
|
4
|
+
def coradoc_class
|
5
|
+
Coradoc::Element::Inline::Italic
|
6
|
+
end
|
7
|
+
|
8
|
+
def markup_ancestor_tag_names
|
9
|
+
%w[em i cite]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
register :em, Em.new
|
14
|
+
register :i, Em.new
|
15
|
+
register :cite, Em.new
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Coradoc::ReverseAdoc
|
2
|
+
module Converters
|
3
|
+
class Figure < Base
|
4
|
+
def to_coradoc(node, state = {})
|
5
|
+
id = node["id"]
|
6
|
+
title = extract_title(node)
|
7
|
+
content = treat_children_coradoc(node, state)
|
8
|
+
Coradoc::Element::Block::Example.new(title, lines: content, id: id)
|
9
|
+
end
|
10
|
+
|
11
|
+
def extract_title(node)
|
12
|
+
title = node.at("./figcaption")
|
13
|
+
return "" if title.nil?
|
14
|
+
|
15
|
+
treat_children_coradoc(title, {})
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
register :figure, Figure.new
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Coradoc::ReverseAdoc
|
2
|
+
module Converters
|
3
|
+
class H < Base
|
4
|
+
def to_coradoc(node, state = {})
|
5
|
+
id = node["id"]
|
6
|
+
internal_anchor = treat_children_anchors(node, state)
|
7
|
+
|
8
|
+
if id.to_s.empty? && internal_anchor.size.positive?
|
9
|
+
id = internal_anchor.first.id
|
10
|
+
end
|
11
|
+
|
12
|
+
level = node.name[/\d/].to_i
|
13
|
+
content = treat_children_no_anchors(node, state)
|
14
|
+
|
15
|
+
Coradoc::Element::Title.new(content, level, id: id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def treat_children_no_anchors(node, state)
|
19
|
+
node.children.reject { |a| a.name == "a" }.inject([]) do |memo, child|
|
20
|
+
memo << treat_coradoc(child, state)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def treat_children_anchors(node, state)
|
25
|
+
node.children.select { |a| a.name == "a" }.inject([]) do |memo, child|
|
26
|
+
memo << treat_coradoc(child, state)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
register :h1, H.new
|
32
|
+
register :h2, H.new
|
33
|
+
register :h3, H.new
|
34
|
+
register :h4, H.new
|
35
|
+
register :h5, H.new
|
36
|
+
register :h6, H.new
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Coradoc::ReverseAdoc
|
2
|
+
module Converters
|
3
|
+
class Head < Base
|
4
|
+
def to_coradoc(node, _state = {})
|
5
|
+
title = extract_title(node)
|
6
|
+
Coradoc::Element::Header.new(title)
|
7
|
+
end
|
8
|
+
|
9
|
+
def extract_title(node)
|
10
|
+
title = node.at("./title")
|
11
|
+
return "(???)" if title.nil?
|
12
|
+
|
13
|
+
title.text
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
register :head, Head.new
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Coradoc::ReverseAdoc
|
2
|
+
module Converters
|
3
|
+
class Ignore < Base
|
4
|
+
def to_coradoc(node, state = {})
|
5
|
+
convert(node, state)
|
6
|
+
end
|
7
|
+
|
8
|
+
def convert(_node, _state = {})
|
9
|
+
"" # noop
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
register :colgroup, Ignore.new
|
14
|
+
register :col, Ignore.new
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "pathname"
|
3
|
+
require "tempfile"
|
4
|
+
require "base64"
|
5
|
+
require "marcel"
|
6
|
+
|
7
|
+
module Coradoc::ReverseAdoc
|
8
|
+
module Converters
|
9
|
+
class Img < Base
|
10
|
+
def image_number
|
11
|
+
sprintf(
|
12
|
+
Coradoc::ReverseAdoc.config.image_counter_pattern,
|
13
|
+
Coradoc::ReverseAdoc.config.image_counter,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
def image_number_increment
|
18
|
+
Coradoc::ReverseAdoc.config.image_counter += 1
|
19
|
+
end
|
20
|
+
|
21
|
+
def datauri2file(src)
|
22
|
+
return unless src
|
23
|
+
|
24
|
+
%r{^data:image/(?:[^;]+);base64,(?<imgdata>.+)$} =~ src
|
25
|
+
|
26
|
+
dest_dir = Pathname.new(Coradoc::ReverseAdoc.config.destination).dirname
|
27
|
+
images_dir = dest_dir.join("images")
|
28
|
+
FileUtils.mkdir_p(images_dir)
|
29
|
+
|
30
|
+
ext, image_src_path, tempfile = determine_image_src_path(src, imgdata)
|
31
|
+
image_dest_path = images_dir + "#{image_number}.#{ext}"
|
32
|
+
|
33
|
+
# puts "image_dest_path: #{image_dest_path.to_s}"
|
34
|
+
# puts "image_src_path: #{image_src_path.to_s}"
|
35
|
+
|
36
|
+
FileUtils.cp(image_src_path, image_dest_path)
|
37
|
+
image_number_increment
|
38
|
+
|
39
|
+
image_dest_path.relative_path_from(dest_dir)
|
40
|
+
ensure
|
41
|
+
tempfile&.close!
|
42
|
+
end
|
43
|
+
|
44
|
+
def determine_image_src_path(src, imgdata)
|
45
|
+
return copy_temp_file(imgdata) if imgdata
|
46
|
+
|
47
|
+
ext = File.extname(src).strip.downcase[1..-1]
|
48
|
+
[ext, Pathname.new(Coradoc::ReverseAdoc.config.sourcedir).join(src)]
|
49
|
+
end
|
50
|
+
|
51
|
+
def copy_temp_file(imgdata)
|
52
|
+
f = Tempfile.open(["radoc", ".jpg"])
|
53
|
+
f.binmode
|
54
|
+
f.write(Base64.strict_decode64(imgdata))
|
55
|
+
f.rewind
|
56
|
+
ext = Marcel::MimeType.for(f).sub(%r{^[^/]+/}, "")
|
57
|
+
ext = "svg" if ext == "svg+xml"
|
58
|
+
[ext, f.path, f]
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_coradoc(node, _state = {})
|
62
|
+
id = node["id"]
|
63
|
+
alt = node["alt"]
|
64
|
+
src = node["src"]
|
65
|
+
width = node["width"]
|
66
|
+
height = node["height"]
|
67
|
+
|
68
|
+
width = width.to_i if width&.match?(/\A\d+\z/)
|
69
|
+
height = height.to_i if height&.match?(/\A\d+\z/)
|
70
|
+
|
71
|
+
title = extract_title(node)
|
72
|
+
|
73
|
+
if Coradoc::ReverseAdoc.config.external_images
|
74
|
+
# puts "external image conversion #{id}, #{src}"
|
75
|
+
src = datauri2file(src)
|
76
|
+
end
|
77
|
+
|
78
|
+
attributes = Coradoc::Element::AttributeList.new
|
79
|
+
# attributes.add_named("id", id) if id
|
80
|
+
if alt # && !alt.to_s.empty?
|
81
|
+
attributes.add_positional(alt)
|
82
|
+
elsif width || height
|
83
|
+
attributes.add_positional(nil)
|
84
|
+
end
|
85
|
+
attributes.add_named("title", title) if title && !title.empty?
|
86
|
+
attributes.add_positional(width) if width
|
87
|
+
attributes.add_positional(height) if height
|
88
|
+
|
89
|
+
if src
|
90
|
+
Coradoc::Element::Image::BlockImage.new(title, id, src,
|
91
|
+
attributes: attributes)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
register :img, Img.new
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Coradoc::ReverseAdoc
|
2
|
+
module Converters
|
3
|
+
class Li < Base
|
4
|
+
def to_coradoc(node, state = {})
|
5
|
+
id = node["id"]
|
6
|
+
content = treat_children_coradoc(node, state)
|
7
|
+
Coradoc::Element::ListItem.new(content, id: id)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
register :li, Li.new
|
12
|
+
end
|
13
|
+
end
|