coradoc-html 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 +7 -0
- data/LICENSE.txt +21 -0
- data/lib/coradoc/html/base.rb +157 -0
- data/lib/coradoc/html/config.rb +467 -0
- data/lib/coradoc/html/converter_base.rb +177 -0
- data/lib/coradoc/html/converters/admonition.rb +180 -0
- data/lib/coradoc/html/converters/attribute.rb +68 -0
- data/lib/coradoc/html/converters/attribute_reference.rb +60 -0
- data/lib/coradoc/html/converters/audio.rb +165 -0
- data/lib/coradoc/html/converters/base.rb +615 -0
- data/lib/coradoc/html/converters/bibliography.rb +82 -0
- data/lib/coradoc/html/converters/bibliography_entry.rb +108 -0
- data/lib/coradoc/html/converters/block_image.rb +72 -0
- data/lib/coradoc/html/converters/bold.rb +34 -0
- data/lib/coradoc/html/converters/break.rb +32 -0
- data/lib/coradoc/html/converters/comment_block.rb +42 -0
- data/lib/coradoc/html/converters/comment_line.rb +54 -0
- data/lib/coradoc/html/converters/cross_reference.rb +59 -0
- data/lib/coradoc/html/converters/document.rb +108 -0
- data/lib/coradoc/html/converters/example.rb +114 -0
- data/lib/coradoc/html/converters/highlight.rb +34 -0
- data/lib/coradoc/html/converters/include.rb +68 -0
- data/lib/coradoc/html/converters/inline_image.rb +41 -0
- data/lib/coradoc/html/converters/italic.rb +34 -0
- data/lib/coradoc/html/converters/line_break.rb +31 -0
- data/lib/coradoc/html/converters/link.rb +46 -0
- data/lib/coradoc/html/converters/list_item.rb +75 -0
- data/lib/coradoc/html/converters/listing.rb +99 -0
- data/lib/coradoc/html/converters/literal.rb +102 -0
- data/lib/coradoc/html/converters/monospace.rb +34 -0
- data/lib/coradoc/html/converters/open.rb +78 -0
- data/lib/coradoc/html/converters/ordered.rb +53 -0
- data/lib/coradoc/html/converters/paragraph.rb +46 -0
- data/lib/coradoc/html/converters/quote.rb +113 -0
- data/lib/coradoc/html/converters/reviewer_comment.rb +74 -0
- data/lib/coradoc/html/converters/reviewer_note.rb +134 -0
- data/lib/coradoc/html/converters/section.rb +90 -0
- data/lib/coradoc/html/converters/sidebar.rb +113 -0
- data/lib/coradoc/html/converters/source.rb +137 -0
- data/lib/coradoc/html/converters/source_code.rb +16 -0
- data/lib/coradoc/html/converters/span.rb +61 -0
- data/lib/coradoc/html/converters/strikethrough.rb +34 -0
- data/lib/coradoc/html/converters/subscript.rb +34 -0
- data/lib/coradoc/html/converters/superscript.rb +34 -0
- data/lib/coradoc/html/converters/table.rb +85 -0
- data/lib/coradoc/html/converters/table_cell.rb +203 -0
- data/lib/coradoc/html/converters/table_row.rb +45 -0
- data/lib/coradoc/html/converters/template_html_converter.rb +105 -0
- data/lib/coradoc/html/converters/term.rb +58 -0
- data/lib/coradoc/html/converters/text_element.rb +44 -0
- data/lib/coradoc/html/converters/underline.rb +34 -0
- data/lib/coradoc/html/converters/unordered.rb +47 -0
- data/lib/coradoc/html/converters/verse.rb +105 -0
- data/lib/coradoc/html/converters/video.rb +179 -0
- data/lib/coradoc/html/element_mapping.rb +210 -0
- data/lib/coradoc/html/entity.rb +137 -0
- data/lib/coradoc/html/input/cleaner.rb +163 -0
- data/lib/coradoc/html/input/config.rb +79 -0
- data/lib/coradoc/html/input/converters/a.rb +90 -0
- data/lib/coradoc/html/input/converters/aside.rb +23 -0
- data/lib/coradoc/html/input/converters/audio.rb +50 -0
- data/lib/coradoc/html/input/converters/base.rb +116 -0
- data/lib/coradoc/html/input/converters/blockquote.rb +25 -0
- data/lib/coradoc/html/input/converters/br.rb +19 -0
- data/lib/coradoc/html/input/converters/bypass.rb +83 -0
- data/lib/coradoc/html/input/converters/code.rb +25 -0
- data/lib/coradoc/html/input/converters/div.rb +25 -0
- data/lib/coradoc/html/input/converters/dl.rb +106 -0
- data/lib/coradoc/html/input/converters/drop.rb +28 -0
- data/lib/coradoc/html/input/converters/em.rb +23 -0
- data/lib/coradoc/html/input/converters/figure.rb +58 -0
- data/lib/coradoc/html/input/converters/h.rb +76 -0
- data/lib/coradoc/html/input/converters/head.rb +30 -0
- data/lib/coradoc/html/input/converters/hr.rb +20 -0
- data/lib/coradoc/html/input/converters/ignore.rb +22 -0
- data/lib/coradoc/html/input/converters/img.rb +110 -0
- data/lib/coradoc/html/input/converters/li.rb +35 -0
- data/lib/coradoc/html/input/converters/mark.rb +21 -0
- data/lib/coradoc/html/input/converters/markup.rb +107 -0
- data/lib/coradoc/html/input/converters/math.rb +46 -0
- data/lib/coradoc/html/input/converters/ol.rb +46 -0
- data/lib/coradoc/html/input/converters/p.rb +81 -0
- data/lib/coradoc/html/input/converters/pass_through.rb +19 -0
- data/lib/coradoc/html/input/converters/pre.rb +59 -0
- data/lib/coradoc/html/input/converters/q.rb +24 -0
- data/lib/coradoc/html/input/converters/strong.rb +22 -0
- data/lib/coradoc/html/input/converters/sub.rb +40 -0
- data/lib/coradoc/html/input/converters/sup.rb +40 -0
- data/lib/coradoc/html/input/converters/table.rb +64 -0
- data/lib/coradoc/html/input/converters/td.rb +70 -0
- data/lib/coradoc/html/input/converters/text.rb +67 -0
- data/lib/coradoc/html/input/converters/th.rb +20 -0
- data/lib/coradoc/html/input/converters/tr.rb +28 -0
- data/lib/coradoc/html/input/converters/video.rb +53 -0
- data/lib/coradoc/html/input/converters.rb +122 -0
- data/lib/coradoc/html/input/errors.rb +22 -0
- data/lib/coradoc/html/input/html_converter.rb +170 -0
- data/lib/coradoc/html/input/plugin.rb +169 -0
- data/lib/coradoc/html/input/plugins/plateau.rb +229 -0
- data/lib/coradoc/html/input/postprocessor.rb +31 -0
- data/lib/coradoc/html/input.rb +68 -0
- data/lib/coradoc/html/output.rb +95 -0
- data/lib/coradoc/html/renderer.rb +409 -0
- data/lib/coradoc/html/spa.rb +309 -0
- data/lib/coradoc/html/static.rb +293 -0
- data/lib/coradoc/html/template_config.rb +151 -0
- data/lib/coradoc/html/template_helpers.rb +58 -0
- data/lib/coradoc/html/template_locator.rb +114 -0
- data/lib/coradoc/html/theme/base.rb +231 -0
- data/lib/coradoc/html/theme/classic_renderer.rb +390 -0
- data/lib/coradoc/html/theme/modern/components/ui_components.rb +344 -0
- data/lib/coradoc/html/theme/modern/css_generator.rb +311 -0
- data/lib/coradoc/html/theme/modern/javascript_generator.rb +314 -0
- data/lib/coradoc/html/theme/modern/serializers/document_serializer.rb +382 -0
- data/lib/coradoc/html/theme/modern/tailwind_config_builder.rb +164 -0
- data/lib/coradoc/html/theme/modern/vue_template_generator.rb +374 -0
- data/lib/coradoc/html/theme/modern_renderer.rb +250 -0
- data/lib/coradoc/html/theme/registry.rb +153 -0
- data/lib/coradoc/html/theme.rb +13 -0
- data/lib/coradoc/html/transform/from_core_model.rb +32 -0
- data/lib/coradoc/html/transform/to_core_model.rb +39 -0
- data/lib/coradoc/html/version.rb +7 -0
- data/lib/coradoc/html.rb +255 -0
- metadata +264 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Input
|
|
5
|
+
module Html
|
|
6
|
+
module Converters
|
|
7
|
+
class Aside < Base
|
|
8
|
+
def to_coradoc(node, state = {})
|
|
9
|
+
content = treat_children_coradoc(node, state)
|
|
10
|
+
# Use AnnotationBlock with annotation_type: "sidebar" for aside elements
|
|
11
|
+
Coradoc::CoreModel::AnnotationBlock.new(
|
|
12
|
+
annotation_type: 'sidebar',
|
|
13
|
+
block_semantic_type: :sidebar,
|
|
14
|
+
children: content
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
register :aside, Aside.new
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Input
|
|
5
|
+
module Html
|
|
6
|
+
module Converters
|
|
7
|
+
class Audio < Base
|
|
8
|
+
def to_coradoc(node, _state = {})
|
|
9
|
+
src = node['src']
|
|
10
|
+
id = node['id']
|
|
11
|
+
title = extract_title(node)
|
|
12
|
+
options(node)
|
|
13
|
+
|
|
14
|
+
# Use Block with custom attributes to store audio info
|
|
15
|
+
# CoreModel doesn't have a specific Audio type, so we use Block
|
|
16
|
+
# with element_attributes to store audio-specific data
|
|
17
|
+
Coradoc::CoreModel::Block.new(
|
|
18
|
+
element_type: 'audio',
|
|
19
|
+
block_semantic_type: :audio,
|
|
20
|
+
content: src,
|
|
21
|
+
title: title,
|
|
22
|
+
id: id,
|
|
23
|
+
element_attributes: {
|
|
24
|
+
autoplay: node['autoplay'],
|
|
25
|
+
loop: node['loop'],
|
|
26
|
+
controls: node['controls']
|
|
27
|
+
}.compact
|
|
28
|
+
)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def extract_title(node)
|
|
32
|
+
title = node.at('./track') || node.at('.//source')
|
|
33
|
+
return '' if title.nil?
|
|
34
|
+
|
|
35
|
+
title['label'] || title['srclang'] || ''
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def options(node)
|
|
39
|
+
autoplay = node['autoplay']
|
|
40
|
+
loop_attr = node['loop']
|
|
41
|
+
controls = node['controls']
|
|
42
|
+
[autoplay, loop_attr, controls].compact
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
register :audio, Audio.new
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Input
|
|
5
|
+
module Html
|
|
6
|
+
module Converters
|
|
7
|
+
class Base
|
|
8
|
+
# Default implementation to convert a given Nokogiri node
|
|
9
|
+
# to a CoreModel type.
|
|
10
|
+
# Can be overriden by subclasses.
|
|
11
|
+
def convert(node, state = {})
|
|
12
|
+
to_coradoc(node, state)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# NOTE: treat_children won't run plugin hooks
|
|
16
|
+
def treat_children(node, state)
|
|
17
|
+
node.children.map do |child|
|
|
18
|
+
treat(child, state)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def treat(node, state)
|
|
23
|
+
Converters.process(node, state)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def treat_children_coradoc(node, state)
|
|
27
|
+
results = node.children.map do |child|
|
|
28
|
+
treat_coradoc(child, state)
|
|
29
|
+
end.flatten
|
|
30
|
+
|
|
31
|
+
results.reject do |x|
|
|
32
|
+
x.nil? || (x.is_a?(String) && x.strip.empty?)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def treat_coradoc(node, state)
|
|
37
|
+
Converters.process_coradoc(node, state)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def extract_title(node)
|
|
41
|
+
node['title'].to_s
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def node_has_ancestor?(node, name)
|
|
45
|
+
case name
|
|
46
|
+
when String
|
|
47
|
+
node.ancestors.map(&:name).include?(name)
|
|
48
|
+
when Array
|
|
49
|
+
(node.ancestors.map(&:name) & name).any?
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def textnode_before_end_with?(node, str)
|
|
54
|
+
return nil unless [String, Regexp].include?(str.class)
|
|
55
|
+
return nil if str.is_a?(String) && str.empty?
|
|
56
|
+
|
|
57
|
+
str = /#{Regexp.escape(str)}/ if str.is_a?(String)
|
|
58
|
+
str = /(?:#{str})\z/
|
|
59
|
+
|
|
60
|
+
node2 = node.at_xpath('preceding-sibling::node()[1]')
|
|
61
|
+
node2.is_a?(Nokogiri::XML::Text) && node2.text.match?(str)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def textnode_after_start_with?(node, str)
|
|
65
|
+
return nil unless [String, Regexp].include?(str.class)
|
|
66
|
+
return nil if str.is_a?(String) && str.empty?
|
|
67
|
+
|
|
68
|
+
str = /#{Regexp.escape(str)}/ if str.is_a?(String)
|
|
69
|
+
str = /\A(?:#{str})/
|
|
70
|
+
|
|
71
|
+
node2 = node.at_xpath('following-sibling::node()[1]')
|
|
72
|
+
node2.is_a?(Nokogiri::XML::Text) && node2.text.match?(str)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def extract_leading_trailing_whitespace(node)
|
|
76
|
+
node.text =~ /^(\s+)/
|
|
77
|
+
leading_whitespace = ::Regexp.last_match(1)
|
|
78
|
+
unless leading_whitespace.nil?
|
|
79
|
+
first_text = node.at_xpath('./text()[1]')
|
|
80
|
+
first_text&.replace(first_text.text.lstrip)
|
|
81
|
+
leading_whitespace = ' '
|
|
82
|
+
end
|
|
83
|
+
node.text =~ /(\s+)$/
|
|
84
|
+
trailing_whitespace = ::Regexp.last_match(1)
|
|
85
|
+
unless trailing_whitespace.nil?
|
|
86
|
+
last_text = node.at_xpath('./text()[last()]')
|
|
87
|
+
last_text&.replace(last_text.text.rstrip)
|
|
88
|
+
trailing_whitespace = ' '
|
|
89
|
+
end
|
|
90
|
+
[leading_whitespace, trailing_whitespace]
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def unconstrained_before?(node)
|
|
94
|
+
before = node.at_xpath('preceding::node()[1]')
|
|
95
|
+
|
|
96
|
+
before &&
|
|
97
|
+
!before.text.strip.empty? &&
|
|
98
|
+
before.text[-1]&.match?(/\w/)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def unconstrained_after?(node)
|
|
102
|
+
after = node.at_xpath('following::node()[1]')
|
|
103
|
+
|
|
104
|
+
after && !after.text.strip.empty? &&
|
|
105
|
+
after.text[0]&.match?(/\w|,|;|"|\.\?!/)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Helper to escape text content
|
|
109
|
+
def escape_text(text)
|
|
110
|
+
text.to_s.gsub(/[<>&]/, '<' => '<', '>' => '>', '&' => '&')
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Input
|
|
5
|
+
module Html
|
|
6
|
+
module Converters
|
|
7
|
+
class Blockquote < Base
|
|
8
|
+
def to_coradoc(node, state = {})
|
|
9
|
+
id = node['id']
|
|
10
|
+
cite = node['cite']
|
|
11
|
+
content = treat_children_coradoc(node, state)
|
|
12
|
+
|
|
13
|
+
Coradoc::CoreModel::QuoteBlock.new(
|
|
14
|
+
content: content,
|
|
15
|
+
id: id,
|
|
16
|
+
attribution: cite
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
register :blockquote, Blockquote.new
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Input
|
|
5
|
+
module Html
|
|
6
|
+
module Converters
|
|
7
|
+
class Br < Base
|
|
8
|
+
def to_coradoc(_node, _state = {})
|
|
9
|
+
Coradoc::CoreModel::InlineElement.new(
|
|
10
|
+
format_type: 'line_break'
|
|
11
|
+
)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
register :br, Br.new
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Input
|
|
5
|
+
module Html
|
|
6
|
+
module Converters
|
|
7
|
+
class Bypass < Base
|
|
8
|
+
def to_coradoc(node, state = {})
|
|
9
|
+
treat_children_coradoc(node, state)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
register :document, Bypass.new
|
|
14
|
+
register :html, Bypass.new
|
|
15
|
+
register :body, Bypass.new
|
|
16
|
+
register :span, Bypass.new
|
|
17
|
+
register :thead, Bypass.new
|
|
18
|
+
register :tbody, Bypass.new
|
|
19
|
+
register :tfoot, Bypass.new
|
|
20
|
+
register :abbr, Bypass.new
|
|
21
|
+
register :acronym, Bypass.new
|
|
22
|
+
register :address, Bypass.new
|
|
23
|
+
register :applet, Bypass.new
|
|
24
|
+
register :map, Bypass.new
|
|
25
|
+
register :area, Bypass.new
|
|
26
|
+
register :bdi, Bypass.new
|
|
27
|
+
register :bdo, Bypass.new
|
|
28
|
+
register :big, Bypass.new
|
|
29
|
+
register :button, Bypass.new
|
|
30
|
+
register :canvas, Bypass.new
|
|
31
|
+
register :data, Bypass.new
|
|
32
|
+
register :datalist, Bypass.new
|
|
33
|
+
register :del, Bypass.new
|
|
34
|
+
register :ins, Bypass.new
|
|
35
|
+
register :dfn, Bypass.new
|
|
36
|
+
register :dialog, Bypass.new
|
|
37
|
+
register :embed, Bypass.new
|
|
38
|
+
register :fieldset, Bypass.new
|
|
39
|
+
register :font, Bypass.new
|
|
40
|
+
register :footer, Bypass.new
|
|
41
|
+
register :form, Bypass.new
|
|
42
|
+
register :frame, Bypass.new
|
|
43
|
+
register :frameset, Bypass.new
|
|
44
|
+
register :header, Bypass.new
|
|
45
|
+
register :iframe, Bypass.new
|
|
46
|
+
register :input, Bypass.new
|
|
47
|
+
register :label, Bypass.new
|
|
48
|
+
register :legend, Bypass.new
|
|
49
|
+
register :main, Bypass.new
|
|
50
|
+
register :menu, Bypass.new
|
|
51
|
+
register :menulist, Bypass.new
|
|
52
|
+
register :meter, Bypass.new
|
|
53
|
+
register :nav, Bypass.new
|
|
54
|
+
register :noframes, Bypass.new
|
|
55
|
+
register :noscript, Bypass.new
|
|
56
|
+
register :object, Bypass.new
|
|
57
|
+
register :optgroup, Bypass.new
|
|
58
|
+
register :option, Bypass.new
|
|
59
|
+
register :output, Bypass.new
|
|
60
|
+
register :param, Bypass.new
|
|
61
|
+
register :picture, Bypass.new
|
|
62
|
+
register :progress, Bypass.new
|
|
63
|
+
register :ruby, Bypass.new
|
|
64
|
+
register :rt, Bypass.new
|
|
65
|
+
register :rp, Bypass.new
|
|
66
|
+
register :s, Bypass.new
|
|
67
|
+
register :select, Bypass.new
|
|
68
|
+
register :small, Bypass.new
|
|
69
|
+
register :span, Bypass.new
|
|
70
|
+
register :strike, Bypass.new
|
|
71
|
+
register :details, Bypass.new
|
|
72
|
+
register :section, Bypass.new
|
|
73
|
+
register :summary, Bypass.new
|
|
74
|
+
register :svg, Bypass.new
|
|
75
|
+
register :template, Bypass.new
|
|
76
|
+
register :textarea, Bypass.new
|
|
77
|
+
register :track, Bypass.new
|
|
78
|
+
register :u, Bypass.new
|
|
79
|
+
register :wbr, Bypass.new
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Input
|
|
5
|
+
module Html
|
|
6
|
+
module Converters
|
|
7
|
+
class Code < Markup
|
|
8
|
+
def coradoc_format_type
|
|
9
|
+
'monospace'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def markup_ancestor_tag_names
|
|
13
|
+
%w[code tt kbd samp var]
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
register :code, Code.new
|
|
18
|
+
register :tt, Code.new
|
|
19
|
+
register :kbd, Code.new
|
|
20
|
+
register :samp, Code.new
|
|
21
|
+
register :var, Code.new
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Input
|
|
5
|
+
module Html
|
|
6
|
+
module Converters
|
|
7
|
+
class Div < Base
|
|
8
|
+
def to_coradoc(node, state = {})
|
|
9
|
+
id = node['id']
|
|
10
|
+
contents = treat_children_coradoc(node, state)
|
|
11
|
+
|
|
12
|
+
Coradoc::CoreModel::OpenBlock.new(
|
|
13
|
+
content: contents,
|
|
14
|
+
id: id
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
register :div, Div.new
|
|
20
|
+
register :article, Div.new
|
|
21
|
+
register :center, Div.new
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Input
|
|
5
|
+
module Html
|
|
6
|
+
module Converters
|
|
7
|
+
class Dl < Base
|
|
8
|
+
def to_coradoc(node, state = {})
|
|
9
|
+
items = process_dl(node, state)
|
|
10
|
+
|
|
11
|
+
# Convert items to CoreModel::ListItem objects
|
|
12
|
+
# For definition lists, term goes in content, definition goes in children
|
|
13
|
+
list_items = items.map do |item|
|
|
14
|
+
term_text = extract_text_from_content(item[:name])
|
|
15
|
+
Coradoc::CoreModel::ListItem.new(
|
|
16
|
+
content: term_text,
|
|
17
|
+
children: item[:value]
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Use CoreModel::ListBlock with marker_type "definition"
|
|
22
|
+
Coradoc::CoreModel::ListBlock.new(
|
|
23
|
+
marker_type: 'definition',
|
|
24
|
+
items: list_items
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def process_dl(node, state = {})
|
|
29
|
+
groups = []
|
|
30
|
+
current = { name: [], value: [] }
|
|
31
|
+
|
|
32
|
+
seen_dd = false
|
|
33
|
+
child = node.at_xpath('*[1]')
|
|
34
|
+
grandchild = nil
|
|
35
|
+
until child.nil?
|
|
36
|
+
if child.name == 'div'
|
|
37
|
+
grandchild = child.at_xpath('*[1]')
|
|
38
|
+
until grandchild.nil?
|
|
39
|
+
groups, current, seen_dd = process_dt_or_dd(
|
|
40
|
+
groups,
|
|
41
|
+
current,
|
|
42
|
+
seen_dd,
|
|
43
|
+
grandchild,
|
|
44
|
+
state
|
|
45
|
+
)
|
|
46
|
+
grandchild = grandchild.at_xpath('following-sibling::*[1]')
|
|
47
|
+
end
|
|
48
|
+
elsif %w[dt dd].include?(child.name)
|
|
49
|
+
groups, current, seen_dd = process_dt_or_dd(
|
|
50
|
+
groups,
|
|
51
|
+
current,
|
|
52
|
+
seen_dd,
|
|
53
|
+
child,
|
|
54
|
+
state
|
|
55
|
+
)
|
|
56
|
+
end
|
|
57
|
+
child = child.at_xpath('following-sibling::*[1]')
|
|
58
|
+
groups << current if current[:name].any? && current[:value].any?
|
|
59
|
+
end
|
|
60
|
+
groups
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def process_dt_or_dd(groups, current, seen_dd, subnode, state = {})
|
|
64
|
+
if subnode.name == 'dt'
|
|
65
|
+
if seen_dd
|
|
66
|
+
# groups << current
|
|
67
|
+
current = { name: [], value: [] }
|
|
68
|
+
seen_dd = false
|
|
69
|
+
end
|
|
70
|
+
current[:name] += treat_children_coradoc(subnode, state)
|
|
71
|
+
elsif subnode.name == 'dd'
|
|
72
|
+
current[:value] += treat_children_coradoc(subnode, state)
|
|
73
|
+
seen_dd = true
|
|
74
|
+
end
|
|
75
|
+
[groups, current, seen_dd]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Extract text from content array
|
|
79
|
+
def extract_text_from_content(content)
|
|
80
|
+
return content if content.is_a?(String)
|
|
81
|
+
return '' if content.nil?
|
|
82
|
+
|
|
83
|
+
content.map do |item|
|
|
84
|
+
case item
|
|
85
|
+
when String
|
|
86
|
+
item
|
|
87
|
+
when Coradoc::CoreModel::InlineElement
|
|
88
|
+
item.content.to_s
|
|
89
|
+
when Coradoc::CoreModel::Base
|
|
90
|
+
if item.content
|
|
91
|
+
item.content.to_s
|
|
92
|
+
else
|
|
93
|
+
''
|
|
94
|
+
end
|
|
95
|
+
else
|
|
96
|
+
item.to_s
|
|
97
|
+
end
|
|
98
|
+
end.join
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
register :dl, Dl.new
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Input
|
|
5
|
+
module Html
|
|
6
|
+
module Converters
|
|
7
|
+
class Drop < Base
|
|
8
|
+
def to_coradoc(node, state = {})
|
|
9
|
+
convert(node, state)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def convert(_node, _state = {})
|
|
13
|
+
''
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
register :caption, Drop.new
|
|
18
|
+
register :figcaption, Drop.new
|
|
19
|
+
register :title, Drop.new
|
|
20
|
+
register :link, Drop.new
|
|
21
|
+
register :style, Drop.new
|
|
22
|
+
register :meta, Drop.new
|
|
23
|
+
register :script, Drop.new
|
|
24
|
+
register :comment, Drop.new
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Input
|
|
5
|
+
module Html
|
|
6
|
+
module Converters
|
|
7
|
+
class Em < Markup
|
|
8
|
+
def coradoc_format_type
|
|
9
|
+
'italic'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def markup_ancestor_tag_names
|
|
13
|
+
%w[em i cite]
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
register :em, Em.new
|
|
18
|
+
register :i, Em.new
|
|
19
|
+
register :cite, Em.new
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Input
|
|
5
|
+
module Html
|
|
6
|
+
module Converters
|
|
7
|
+
class Figure < Base
|
|
8
|
+
def to_coradoc(node, state = {})
|
|
9
|
+
id = node['id']
|
|
10
|
+
title_content = extract_title(node)
|
|
11
|
+
content = treat_children_coradoc(node, state)
|
|
12
|
+
|
|
13
|
+
# Use CoreModel::ExampleBlock for example/figure
|
|
14
|
+
Coradoc::CoreModel::ExampleBlock.new(
|
|
15
|
+
title: extract_text_from_content(title_content),
|
|
16
|
+
children: content,
|
|
17
|
+
id: id
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def extract_title(node)
|
|
22
|
+
title = node.at('./figcaption')
|
|
23
|
+
return '' if title.nil?
|
|
24
|
+
|
|
25
|
+
treat_children_coradoc(title, {})
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Extract text from content array
|
|
29
|
+
def extract_text_from_content(content)
|
|
30
|
+
return content if content.is_a?(String)
|
|
31
|
+
return '' if content.nil?
|
|
32
|
+
|
|
33
|
+
content.map do |item|
|
|
34
|
+
case item
|
|
35
|
+
when String
|
|
36
|
+
item
|
|
37
|
+
when Coradoc::CoreModel::InlineElement
|
|
38
|
+
item.content.to_s
|
|
39
|
+
when Coradoc::CoreModel::Base
|
|
40
|
+
if item.content
|
|
41
|
+
item.content.to_s
|
|
42
|
+
elsif item.title
|
|
43
|
+
item.title.to_s
|
|
44
|
+
else
|
|
45
|
+
''
|
|
46
|
+
end
|
|
47
|
+
else
|
|
48
|
+
item.to_s
|
|
49
|
+
end
|
|
50
|
+
end.join
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
register :figure, Figure.new
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Input
|
|
5
|
+
module Html
|
|
6
|
+
module Converters
|
|
7
|
+
class H < Base
|
|
8
|
+
def to_coradoc(node, state = {})
|
|
9
|
+
id = node['id']
|
|
10
|
+
internal_anchor = treat_children_anchors(node, state)
|
|
11
|
+
|
|
12
|
+
# Check if it has id attribute
|
|
13
|
+
if id.to_s.empty? && internal_anchor.size.positive?
|
|
14
|
+
first_model = internal_anchor.first
|
|
15
|
+
# InlineElement (anchor) has a target attribute
|
|
16
|
+
id = first_model.target if first_model.is_a?(Coradoc::CoreModel::InlineElement) && first_model.target
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
level_int = node.name[/\d/].to_i
|
|
20
|
+
content = treat_children_no_anchors(node, state)
|
|
21
|
+
|
|
22
|
+
Coradoc::CoreModel::StructuralElement.new(
|
|
23
|
+
element_type: 'section',
|
|
24
|
+
title: extract_title_text(content),
|
|
25
|
+
level: level_int,
|
|
26
|
+
id: id,
|
|
27
|
+
children: []
|
|
28
|
+
)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def treat_children_no_anchors(node, state)
|
|
32
|
+
node.children.reject { |a| a.name == 'a' }
|
|
33
|
+
.map do |child|
|
|
34
|
+
treat_coradoc(child, state)
|
|
35
|
+
end.flatten.compact
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def treat_children_anchors(node, state)
|
|
39
|
+
node.children.select { |a| a.name == 'a' }
|
|
40
|
+
.map do |child|
|
|
41
|
+
treat_coradoc(child, state)
|
|
42
|
+
end.flatten.compact
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def extract_title_text(content)
|
|
48
|
+
return '' if content.nil? || content.empty?
|
|
49
|
+
|
|
50
|
+
# Extract text from content
|
|
51
|
+
if content.is_a?(Array)
|
|
52
|
+
content.map do |c|
|
|
53
|
+
if c.is_a?(Coradoc::CoreModel::InlineElement)
|
|
54
|
+
c.content.to_s
|
|
55
|
+
else
|
|
56
|
+
c.to_s
|
|
57
|
+
end
|
|
58
|
+
end.join.strip
|
|
59
|
+
elsif content.is_a?(Coradoc::CoreModel::InlineElement)
|
|
60
|
+
content.content.to_s
|
|
61
|
+
else
|
|
62
|
+
content.to_s
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
register :h1, H.new
|
|
68
|
+
register :h2, H.new
|
|
69
|
+
register :h3, H.new
|
|
70
|
+
register :h4, H.new
|
|
71
|
+
register :h5, H.new
|
|
72
|
+
register :h6, H.new
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Input
|
|
5
|
+
module Html
|
|
6
|
+
module Converters
|
|
7
|
+
class Head < Base
|
|
8
|
+
def to_coradoc(node, _state = {})
|
|
9
|
+
title = extract_title(node)
|
|
10
|
+
# Use StructuralElement with element_type "document" for document header
|
|
11
|
+
Coradoc::CoreModel::StructuralElement.new(
|
|
12
|
+
element_type: 'document',
|
|
13
|
+
title: title,
|
|
14
|
+
level: 0
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def extract_title(node)
|
|
19
|
+
title = node.at('./title')
|
|
20
|
+
return '(???)' if title.nil?
|
|
21
|
+
|
|
22
|
+
title.text
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
register :head, Head.new
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|