coradoc-html 1.1.18 → 1.1.20

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.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/lib/coradoc/html/cleaner.rb +128 -0
  3. data/lib/coradoc/html/converters/a.rb +77 -0
  4. data/lib/coradoc/html/converters/aside.rb +20 -0
  5. data/lib/coradoc/html/converters/audio.rb +19 -0
  6. data/lib/coradoc/html/converters/base.rb +98 -0
  7. data/lib/coradoc/html/converters/blockquote.rb +25 -0
  8. data/lib/coradoc/html/converters/br.rb +17 -0
  9. data/lib/coradoc/html/converters/bypass.rb +82 -0
  10. data/lib/coradoc/html/converters/code.rb +25 -0
  11. data/lib/coradoc/html/converters/div.rb +23 -0
  12. data/lib/coradoc/html/converters/dl.rb +82 -0
  13. data/lib/coradoc/html/converters/drop.rb +26 -0
  14. data/lib/coradoc/html/converters/em.rb +23 -0
  15. data/lib/coradoc/html/converters/figure.rb +33 -0
  16. data/lib/coradoc/html/converters/h.rb +58 -0
  17. data/lib/coradoc/html/converters/head.rb +29 -0
  18. data/lib/coradoc/html/converters/hr.rb +17 -0
  19. data/lib/coradoc/html/converters/img.rb +103 -0
  20. data/lib/coradoc/html/converters/li.rb +35 -0
  21. data/lib/coradoc/html/converters/mark.rb +21 -0
  22. data/lib/coradoc/html/converters/markup.rb +93 -0
  23. data/lib/coradoc/html/converters/math.rb +37 -0
  24. data/lib/coradoc/html/converters/media_base.rb +48 -0
  25. data/lib/coradoc/html/converters/ol.rb +42 -0
  26. data/lib/coradoc/html/converters/p.rb +64 -0
  27. data/lib/coradoc/html/converters/pass_through.rb +15 -0
  28. data/lib/coradoc/html/converters/positional_formatting.rb +35 -0
  29. data/lib/coradoc/html/converters/pre.rb +57 -0
  30. data/lib/coradoc/html/converters/q.rb +25 -0
  31. data/lib/coradoc/html/converters/strong.rb +22 -0
  32. data/lib/coradoc/html/converters/sub.rb +20 -0
  33. data/lib/coradoc/html/converters/sup.rb +20 -0
  34. data/lib/coradoc/html/converters/table.rb +64 -0
  35. data/lib/coradoc/html/converters/td.rb +42 -0
  36. data/lib/coradoc/html/converters/text.rb +66 -0
  37. data/lib/coradoc/html/converters/tr.rb +27 -0
  38. data/lib/coradoc/html/converters/video.rb +27 -0
  39. data/lib/coradoc/html/converters.rb +104 -0
  40. data/lib/coradoc/html/drop/definition_item_drop.rb +17 -0
  41. data/lib/coradoc/html/drop/drop_factory.rb +14 -22
  42. data/lib/coradoc/html/drop/inline_element_drop.rb +3 -5
  43. data/lib/coradoc/html/drop/raw_inline_element_drop.rb +30 -0
  44. data/lib/coradoc/html/drop.rb +30 -8
  45. data/lib/coradoc/html/errors.rb +11 -0
  46. data/lib/coradoc/html/html_converter.rb +78 -0
  47. data/lib/coradoc/html/input_config.rb +66 -0
  48. data/lib/coradoc/html/plugin.rb +90 -0
  49. data/lib/coradoc/html/plugins/plateau.rb +212 -0
  50. data/lib/coradoc/html/postprocessor.rb +19 -0
  51. data/lib/coradoc/html/spa.rb +0 -2
  52. data/lib/coradoc/html/static.rb +0 -2
  53. data/lib/coradoc/html/tag_mapping.rb +3 -1
  54. data/lib/coradoc/html/transform/from_core_model.rb +2 -2
  55. data/lib/coradoc/html/transform/to_core_model.rb +3 -3
  56. data/lib/coradoc/html/version.rb +1 -1
  57. data/lib/coradoc/html.rb +30 -5
  58. metadata +46 -47
  59. data/lib/coradoc/html/input/cleaner.rb +0 -134
  60. data/lib/coradoc/html/input/config.rb +0 -80
  61. data/lib/coradoc/html/input/converters/a.rb +0 -79
  62. data/lib/coradoc/html/input/converters/aside.rb +0 -22
  63. data/lib/coradoc/html/input/converters/audio.rb +0 -21
  64. data/lib/coradoc/html/input/converters/base.rb +0 -118
  65. data/lib/coradoc/html/input/converters/blockquote.rb +0 -27
  66. data/lib/coradoc/html/input/converters/br.rb +0 -19
  67. data/lib/coradoc/html/input/converters/bypass.rb +0 -84
  68. data/lib/coradoc/html/input/converters/code.rb +0 -27
  69. data/lib/coradoc/html/input/converters/div.rb +0 -25
  70. data/lib/coradoc/html/input/converters/dl.rb +0 -84
  71. data/lib/coradoc/html/input/converters/drop.rb +0 -28
  72. data/lib/coradoc/html/input/converters/em.rb +0 -25
  73. data/lib/coradoc/html/input/converters/figure.rb +0 -35
  74. data/lib/coradoc/html/input/converters/h.rb +0 -74
  75. data/lib/coradoc/html/input/converters/head.rb +0 -31
  76. data/lib/coradoc/html/input/converters/hr.rb +0 -19
  77. data/lib/coradoc/html/input/converters/img.rb +0 -105
  78. data/lib/coradoc/html/input/converters/li.rb +0 -37
  79. data/lib/coradoc/html/input/converters/mark.rb +0 -23
  80. data/lib/coradoc/html/input/converters/markup.rb +0 -103
  81. data/lib/coradoc/html/input/converters/math.rb +0 -39
  82. data/lib/coradoc/html/input/converters/media_base.rb +0 -50
  83. data/lib/coradoc/html/input/converters/ol.rb +0 -44
  84. data/lib/coradoc/html/input/converters/p.rb +0 -90
  85. data/lib/coradoc/html/input/converters/pass_through.rb +0 -17
  86. data/lib/coradoc/html/input/converters/positional_formatting.rb +0 -37
  87. data/lib/coradoc/html/input/converters/pre.rb +0 -59
  88. data/lib/coradoc/html/input/converters/q.rb +0 -27
  89. data/lib/coradoc/html/input/converters/strong.rb +0 -24
  90. data/lib/coradoc/html/input/converters/sub.rb +0 -22
  91. data/lib/coradoc/html/input/converters/sup.rb +0 -22
  92. data/lib/coradoc/html/input/converters/table.rb +0 -66
  93. data/lib/coradoc/html/input/converters/td.rb +0 -44
  94. data/lib/coradoc/html/input/converters/text.rb +0 -68
  95. data/lib/coradoc/html/input/converters/tr.rb +0 -29
  96. data/lib/coradoc/html/input/converters/video.rb +0 -29
  97. data/lib/coradoc/html/input/converters.rb +0 -107
  98. data/lib/coradoc/html/input/errors.rb +0 -22
  99. data/lib/coradoc/html/input/html_converter.rb +0 -98
  100. data/lib/coradoc/html/input/plugin.rb +0 -120
  101. data/lib/coradoc/html/input/plugins/plateau.rb +0 -214
  102. data/lib/coradoc/html/input/postprocessor.rb +0 -25
  103. data/lib/coradoc/html/input.rb +0 -86
  104. data/lib/coradoc/html/output.rb +0 -89
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coradoc
4
- module Input
5
- module Html
6
- module Converters
7
- class Text < Base
8
- INSTANCE = new
9
-
10
- def to_coradoc(node, state = {})
11
- return treat_empty(node, state) if node.text.strip.empty?
12
-
13
- # HTML cleanup is performed in the converter layer
14
- cleaned_content = cleanup_html_text(node.text)
15
-
16
- # Return as CoreModel::InlineElement with format_type "text"
17
- Coradoc::CoreModel::TextElement.new(
18
- content: cleaned_content
19
- )
20
- end
21
-
22
- private
23
-
24
- def treat_empty(node, state)
25
- parent = node.parent.name.to_sym
26
- if %i[ol ul].include?(parent) # Otherwise the indentation is broken
27
- nil
28
- elsif state[:tdsinglepara]
29
- nil
30
- elsif node.text == ' ' # Regular whitespace text node
31
- ' '
32
- else
33
- nil
34
- end
35
- end
36
-
37
- # HTML-to-CoreModel text cleanup
38
- def cleanup_html_text(text)
39
- text = preserve_nbsp(text)
40
- text = remove_border_newlines(text)
41
- text = remove_inner_newlines(text)
42
- escape_links(text)
43
- end
44
-
45
- def preserve_nbsp(text)
46
- text.gsub("\u00A0", '&nbsp;')
47
- end
48
-
49
- def escape_links(text)
50
- text.gsub(/<<([^ ][^>]*)>>/, '\\<<\\1>>')
51
- end
52
-
53
- def remove_border_newlines(text)
54
- text.gsub(/\A\n+/, '').gsub(/\n+\z/, '')
55
- end
56
-
57
- def remove_inner_newlines(text)
58
- # Convert newlines/tabs to spaces and squeeze multiple spaces
59
- # Preserve single leading/trailing space for inline contexts
60
- text.tr("\n\t", ' ').squeeze(' ')
61
- end
62
- end
63
-
64
- register :text, Text::INSTANCE
65
- end
66
- end
67
- end
68
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coradoc
4
- module Input
5
- module Html
6
- module Converters
7
- class Tr < Base
8
- INSTANCE = new
9
-
10
- def to_coradoc(node, state = {})
11
- content = treat_children_coradoc(node, state)
12
- header = table_header_row?(node)
13
- # Use CoreModel::TableRow with cells (not columns)
14
- Coradoc::CoreModel::TableRow.new(
15
- cells: content,
16
- header: header
17
- )
18
- end
19
-
20
- def table_header_row?(node)
21
- node.previous_element.nil?
22
- end
23
- end
24
-
25
- register :tr, Tr::INSTANCE
26
- end
27
- end
28
- end
29
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coradoc
4
- module Input
5
- module Html
6
- module Converters
7
- class Video < MediaBase
8
- INSTANCE = new
9
-
10
- private
11
-
12
- def semantic_type
13
- :video
14
- end
15
-
16
- def build_attributes(node)
17
- base_attributes(node).merge(
18
- poster: node['poster'],
19
- width: node['width'],
20
- height: node['height']
21
- ).compact
22
- end
23
- end
24
-
25
- register :video, Video::INSTANCE
26
- end
27
- end
28
- end
29
- end
@@ -1,107 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coradoc
4
- module Input
5
- module Html
6
- module Converters
7
- # Autoload converter classes — they self-register when loaded.
8
- # Adding a new converter requires only adding one entry here.
9
- CONVERTERS = {
10
- Base: 'coradoc/html/input/converters/base',
11
- Markup: 'coradoc/html/input/converters/markup',
12
- A: 'coradoc/html/input/converters/a',
13
- Aside: 'coradoc/html/input/converters/aside',
14
- Audio: 'coradoc/html/input/converters/audio',
15
- Blockquote: 'coradoc/html/input/converters/blockquote',
16
- Br: 'coradoc/html/input/converters/br',
17
- Bypass: 'coradoc/html/input/converters/bypass',
18
- Code: 'coradoc/html/input/converters/code',
19
- Div: 'coradoc/html/input/converters/div',
20
- Dl: 'coradoc/html/input/converters/dl',
21
- Skip: 'coradoc/html/input/converters/drop',
22
- Em: 'coradoc/html/input/converters/em',
23
- Figure: 'coradoc/html/input/converters/figure',
24
- H: 'coradoc/html/input/converters/h',
25
- Head: 'coradoc/html/input/converters/head',
26
- Hr: 'coradoc/html/input/converters/hr',
27
- Img: 'coradoc/html/input/converters/img',
28
- Li: 'coradoc/html/input/converters/li',
29
- Mark: 'coradoc/html/input/converters/mark',
30
- Math: 'coradoc/html/input/converters/math',
31
- MediaBase: 'coradoc/html/input/converters/media_base',
32
- Ol: 'coradoc/html/input/converters/ol',
33
- P: 'coradoc/html/input/converters/p',
34
- PassThrough: 'coradoc/html/input/converters/pass_through',
35
- PositionalFormatting: 'coradoc/html/input/converters/positional_formatting',
36
- Pre: 'coradoc/html/input/converters/pre',
37
- Q: 'coradoc/html/input/converters/q',
38
- Strong: 'coradoc/html/input/converters/strong',
39
- Sup: 'coradoc/html/input/converters/sup',
40
- Sub: 'coradoc/html/input/converters/sub',
41
- Table: 'coradoc/html/input/converters/table',
42
- Td: 'coradoc/html/input/converters/td',
43
- Text: 'coradoc/html/input/converters/text',
44
- Tr: 'coradoc/html/input/converters/tr',
45
- Video: 'coradoc/html/input/converters/video'
46
- }.freeze
47
- private_constant :CONVERTERS
48
-
49
- CONVERTERS.each do |name, path|
50
- autoload name, path
51
- end
52
-
53
- @converters = {}
54
- @converters_loaded = false
55
-
56
- def self.register(tag_name, converter)
57
- @converters[tag_name.to_sym] = converter
58
- end
59
-
60
- def self.unregister(tag_name)
61
- @converters.delete(tag_name.to_sym)
62
- end
63
-
64
- def self.ensure_converters_loaded
65
- return if @converters_loaded
66
-
67
- @converters_loaded = true
68
- CONVERTERS.each_key { |name| const_get(name) }
69
- end
70
-
71
- def self.lookup(tag_name)
72
- ensure_converters_loaded
73
- @converters[tag_name.to_sym] || default_converter(tag_name)
74
- end
75
-
76
- def self.process_coradoc(node, state)
77
- node = node.to_a if node.is_a? Nokogiri::XML::NodeSet
78
- return node.map { |i| process_coradoc(i, state) } if node.is_a? Array
79
-
80
- plugins = state[:plugin_instances] || {}
81
- process = proc { lookup(node.name).to_coradoc(node, state) }
82
- plugins.each do |i|
83
- prev_process = process
84
- process = proc { i.html_tree_run_hooks(node, state, &prev_process) }
85
- end
86
- process.call(node, state)
87
- end
88
-
89
- def self.default_converter(tag_name)
90
- case Html.config.unknown_tags.to_sym
91
- when :pass_through
92
- PassThrough::INSTANCE
93
- when :drop
94
- Skip::INSTANCE
95
- when :bypass
96
- Bypass::INSTANCE
97
- when :raise
98
- raise Errors::UnknownTagError, "unknown tag: #{tag_name}"
99
- else
100
- raise Errors::InvalidConfigurationError,
101
- "unknown value #{Html.config.unknown_tags.inspect} for Coradoc::Input::Html.config.unknown_tags"
102
- end
103
- end
104
- end
105
- end
106
- end
107
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coradoc
4
- module Input
5
- module Html
6
- module Errors
7
- # Base error class for HTML input errors
8
- # Inherits from Coradoc::Error for unified error handling
9
- class Error < Coradoc::Error
10
- end
11
-
12
- # Raised when an unknown HTML tag is encountered
13
- class UnknownTagError < Error
14
- end
15
-
16
- # Raised when HTML input configuration is invalid
17
- class InvalidConfigurationError < Error
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,98 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coradoc
4
- module Input
5
- module Html
6
- # HTML to CoreModel converter
7
- #
8
- # This class handles the conversion of HTML documents to CoreModel.
9
- # It does NOT handle serialization to any specific output format.
10
- # For serialization, use Coradoc.serialize(coremodel, to: :format)
11
- #
12
- # @example Basic usage - get CoreModel
13
- # coremodel = HtmlConverter.to_core_model(html_string)
14
- #
15
- # @example Serialize to AsciiDoc
16
- # coremodel = HtmlConverter.to_core_model(html_string)
17
- # adoc_text = Coradoc.serialize(coremodel, to: :asciidoc)
18
- #
19
- class HtmlConverter
20
- # Convert HTML to CoreModel
21
- #
22
- # @param input [String, Nokogiri::XML::Document, Nokogiri::XML::Node] HTML input
23
- # @param options [Hash] Conversion options
24
- # @return [Coradoc::CoreModel::Base] CoreModel document
25
- def self.to_core_model(input, options = {})
26
- Input::Html.config.with(options) do
27
- plugin_instances = prepare_plugin_instances(options)
28
-
29
- root = track_time 'Loading input HTML document' do
30
- case input
31
- when String
32
- Nokogiri::HTML(input).root
33
- when Nokogiri::XML::Document
34
- input.root
35
- when Nokogiri::XML::Node
36
- input
37
- end
38
- end
39
-
40
- return nil unless root
41
-
42
- plugin_instances.each do |plugin|
43
- plugin.html_tree = root
44
- track_time "Preprocessing document with #{plugin.name} plugin" do
45
- plugin.preprocess_html_tree
46
- end
47
- root = plugin.html_tree
48
- end
49
-
50
- coremodel = track_time 'Converting input document tree to CoreModel' do
51
- Converters.process_coradoc(
52
- root,
53
- plugin_instances: plugin_instances
54
- )
55
- end
56
-
57
- coremodel = track_time 'Post-process CoreModel tree' do
58
- Postprocessor.process(coremodel)
59
- end
60
-
61
- plugin_instances.each do |plugin|
62
- plugin.coremodel_tree = coremodel
63
- track_time "Postprocessing CoreModel tree with #{plugin.name} plugin" do
64
- plugin.postprocess_coremodel_tree
65
- end
66
- coremodel = plugin.coremodel_tree
67
- end
68
-
69
- options[:plugin_instances] = plugin_instances unless options.frozen?
70
-
71
- coremodel
72
- end
73
- end
74
-
75
- def self.prepare_plugin_instances(options)
76
- options[:plugin_instances] || Html.config.plugins.map(&:new)
77
- end
78
-
79
- @track_time_indentation = 0
80
- def self.track_time(task)
81
- if Input::Html.config.track_time
82
- warn (' ' * @track_time_indentation) + "* #{task} is starting..."
83
- @track_time_indentation += 1
84
- t0 = Time.now
85
- ret = yield
86
- time_elapsed = Time.now - t0
87
- @track_time_indentation -= 1
88
- warn (' ' * @track_time_indentation) +
89
- "* #{task} took #{time_elapsed.round(3)} seconds"
90
- ret
91
- else
92
- yield
93
- end
94
- end
95
- end
96
- end
97
- end
98
- end
@@ -1,120 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coradoc
4
- module Input
5
- module Html
6
- class Plugin
7
- #### Plugin system general
8
-
9
- # Allow building plugins with a shorthand syntax:
10
- # plugin = Coradoc::Html::Input::Plugin.new do
11
- # def name = "Test"
12
- # end
13
-
14
- def self.new(&)
15
- if self == Plugin
16
- Class.new(Plugin, &)
17
- else
18
- super
19
- end
20
- end
21
-
22
- def initialize
23
- @html_tree_hooks_pre = {}
24
- @html_tree_hooks_post = {}
25
- end
26
-
27
- def name
28
- self.class.name
29
- end
30
-
31
- # Default no-op hooks. Plugins override these as needed.
32
- def preprocess_html_tree; end
33
- def postprocess_coremodel_tree; end
34
- def postprocess_output_string; end
35
-
36
- #### HTML Tree functionalities
37
-
38
- attr_accessor :html_tree, :coremodel_tree, :output_string
39
-
40
- def html_tree_change_tag_name_by_css(css, new_name)
41
- html_tree.css(css).each do |e|
42
- e.name = new_name
43
- end
44
- end
45
-
46
- def html_tree_change_properties_by_css(css, properties)
47
- html_tree.css(css).each do |e|
48
- properties.each do |k, v|
49
- e[k.to_s] = v
50
- end
51
- end
52
- end
53
-
54
- def html_tree_remove_by_css(css)
55
- html_tree.css(css).each(&:remove)
56
- end
57
-
58
- def html_tree_replace_with_children_by_css(css)
59
- html_tree.css(css).each do |e|
60
- e.replace(e.children)
61
- end
62
- end
63
-
64
- def html_tree_process_to_coremodel(tree, state = {})
65
- Coradoc::Html::Input::Converters.process_coradoc(tree, state)
66
- end
67
-
68
- # define preprocess_html_tree to process HTML trees
69
-
70
- # Creates a hook to be called instead of converting an element
71
- # to a CoreModel node.
72
- #
73
- # proc |html_node, state|
74
- # coremodel_node
75
- # end
76
- def html_tree_add_hook_pre(element, &block)
77
- @html_tree_hooks_pre[element] = block
78
- end
79
-
80
- def html_tree_add_hook_pre_by_css(css, &block)
81
- html_tree.css(css).each do |e|
82
- html_tree_add_hook_pre(e, &block)
83
- end
84
- end
85
-
86
- # Creates a hook to be called after converting an element
87
- # to a CoreModel node.
88
- #
89
- # proc |html_node, coremodel_node, state|
90
- # coremodel_node
91
- # end
92
- def html_tree_add_hook_post(element, &block)
93
- @html_tree_hooks_post[element] = block
94
- end
95
-
96
- def html_tree_add_hook_post_by_css(css, &block)
97
- html_tree.css(css).each do |e|
98
- html_tree_add_hook_post(e, &block)
99
- end
100
- end
101
-
102
- def html_tree_run_hooks(node, state, &)
103
- hook_pre = @html_tree_hooks_pre[node]
104
- hook_post = @html_tree_hooks_post[node]
105
-
106
- coremodel = hook_pre.call(node, state) if hook_pre
107
- coremodel ||= yield node, state
108
-
109
- coremodel = hook_post.call(node, coremodel, state) if hook_post
110
-
111
- coremodel
112
- end
113
-
114
- #### CoreModel tree functionalities
115
-
116
- #### Output string functionalities
117
- end
118
- end
119
- end
120
- end
@@ -1,214 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coradoc
4
- module Input
5
- module Html
6
- class Plugin
7
- # This plugin enhances documents from the PLATEAU project
8
- # to extract more data.
9
- #
10
- # Usage:
11
- # coradoc convert -rcoradoc/input/html/plugins/plateau
12
- # --external-images -u raise --output _out/index.adoc index.html
13
- class Plateau < Plugin
14
- def name
15
- 'PLATEAU'
16
- end
17
-
18
- def preprocess_html_tree
19
- # Remove side menu, so we can generate TOC ourselves
20
- html_tree_remove_by_css('.sideMenu')
21
-
22
- # Correct non-semantic classes into semantic HTML tags
23
- html_tree_change_tag_name_by_css('.titledata', 'h1')
24
- html_tree_change_tag_name_by_css('.subtitledata', 'h2')
25
- html_tree_change_tag_name_by_css('.pitemdata', 'h3')
26
- html_tree_change_tag_name_by_css('.sitemdata', 'h4')
27
- html_tree_change_tag_name_by_css('td[bgcolor="#D0CECE"]', 'th')
28
- html_tree_change_tag_name_by_css('td[bgcolor="#d0cece"]', 'th')
29
- html_tree_change_tag_name_by_css(
30
- '.framedata, .frame_container_box',
31
- 'aside'
32
- )
33
- html_tree_change_tag_name_by_css('.frame2data', 'pre')
34
- # Assumption that all code snippets in those documents are XML...
35
- html_tree_change_properties_by_css(
36
- '.frame2data',
37
- class: 'brush:xml;'
38
- )
39
-
40
- # Remove some CSS ids that are not important to us
41
- html_tree_change_properties_by_css('#__nuxt', id: nil)
42
- html_tree_change_properties_by_css('#__layout', id: nil)
43
- html_tree_change_properties_by_css('#app', id: nil)
44
-
45
- # Handle lists of document 02
46
- html_tree_replace_with_children_by_css('.list_num-wrap')
47
-
48
- # Convert table/img caption to become a caption
49
- html_tree.css('.imagedata').each do |e|
50
- table = e.parent.next&.children&.first
51
- if table&.name == 'table'
52
- e.name = 'caption'
53
- table.prepend_child(e)
54
- next
55
- end
56
-
57
- img = e.parent.previous&.children&.first
58
- next unless img&.name == 'img' && img['src']
59
-
60
- title = e.text.strip
61
- img['title'] = title
62
- e.remove
63
- next
64
- end
65
-
66
- # Add hooks for H1, H2, H3, H4
67
- html_tree_add_hook_post_by_css(
68
- 'h1, h2, h3',
69
- &method(:handle_headers)
70
- )
71
- html_tree_add_hook_post_by_css('h4', &method(:handle_headers_h4))
72
-
73
- # Table cells aligned to center
74
- html_tree_change_properties_by_css(
75
- '.tableTopCenter',
76
- align: 'center'
77
- )
78
-
79
- # Handle non-semantic lists and indentation
80
- html_tree_add_hook_pre_by_css '.text2data' do |node,|
81
- text = html_tree_process_to_coremodel(node).strip
82
- next '' if text.empty? || text == "\u3000"
83
-
84
- if text.start_with?(/\d+\./)
85
- text = text.sub(/\A\d+.\s*/, '')
86
- ".. #{text}\n"
87
- else
88
- text = text.gsub(/^/, '** ')
89
- "\n\n//-PT2D\n#{text}\n//-ENDPT2D\n\n"
90
- end
91
- end
92
-
93
- (3..4).each do |i|
94
- html_tree_add_hook_pre_by_css ".text#{i}data" do |node,|
95
- text = html_tree_process_to_coremodel(node).strip
96
- next '' if text.empty? || text == "\u3000"
97
-
98
- text = text.strip.gsub(/^/, "#{'*' * i} ")
99
- "\n\n//-PT#{i}D\n#{text}\n//-ENDPT#{i}D\n\n"
100
- end
101
- end
102
-
103
- (2..3).each do |i|
104
- html_tree_add_hook_pre_by_css ".text#{i}data_point ul" do |node,|
105
- text = html_tree_process_to_coremodel(node.children.first.children).strip
106
-
107
- "#{'*' * i} #{text}\n"
108
- end
109
- end
110
-
111
- (1..20).each do |i|
112
- html_tree_add_hook_pre_by_css ".numtextdata_num .list_num#{i}" do |node,|
113
- text = html_tree_process_to_coremodel(node).strip
114
-
115
- "[start=#{i}]\n. #{text}\n"
116
- end
117
- end
118
- end
119
-
120
- IM = /[A-Z0-9]{1,3}/
121
-
122
- def handle_headers(node, coradoc, _state)
123
- content = coradoc.content.map(&:content).join
124
-
125
- if %w[toc0 toc_0].any? { |i| coradoc.id&.start_with?(i) }
126
- # Special content
127
- case content.strip
128
- when 'はじめに' # Introduction
129
- coradoc.style = 'abstract' # The older version document has ".preface"
130
- coradoc.level_int = 1
131
- when '改定の概要' # Revision overview
132
- coradoc.style = 'abstract' # The older version document has ".preface"
133
- coradoc.level_int = 1
134
- when '参考文献' # Bibliography
135
- coradoc.style = 'bibliography'
136
- coradoc.level_int = 1
137
- when '改訂履歴' # Document history
138
- coradoc.style = 'appendix'
139
- coradoc.level_int = 1
140
- when '0 概要' # Overview
141
- coradoc.style = 'abstract' # I'm not sure this is correct
142
- coradoc.level_int = 1
143
- when '索引' # Index
144
- coradoc.style = 'index' # I'm not sure this is correct
145
- coradoc.level_int = 1
146
- else
147
- warn "Unknown section #{content.inspect}"
148
- end
149
- end
150
-
151
- if node.name == 'h1' && content.start_with?('Annex')
152
- coradoc.style = 'appendix'
153
- coradoc.content.first.content.sub!(/\AAnnex [A-Z]/, '')
154
- end
155
-
156
- # Remove numbers
157
- coradoc.content.first.content.sub!(
158
- /\A(#{IM}\.)*#{IM}[[:space:]]/o,
159
- ''
160
- )
161
-
162
- coradoc
163
- end
164
-
165
- def handle_headers_h4(_node, coradoc, _state)
166
- title = Coradoc.strip_unicode(coradoc.content.first.content)
167
- case title
168
- when /\A\(\d+\)(.*)/
169
- coradoc.level_int = 4
170
- coradoc.content.first.content = ::Regexp.last_match(1).strip
171
- coradoc
172
- when /\A\d+\)(.*)/
173
- coradoc.level_int = 5
174
- coradoc.content.first.content = ::Regexp.last_match(1).strip
175
- coradoc
176
- when /\A#{IM}\.#{IM}\.#{IM}\.#{IM}(.*)/o
177
- coradoc.level_int = 4
178
- coradoc.content.first.content = ::Regexp.last_match(1).strip
179
- else
180
- if title.empty?
181
- # Strip instances of faulty empty paragraphs
182
- nil
183
- else
184
- ["// Unhandled h4 content\n", coradoc]
185
- end
186
- end
187
- end
188
-
189
- def postprocess_output_string
190
- str = output_string
191
-
192
- ### Custom indentation handling
193
- # If there's a step up, add [none]
194
- str = str.gsub(%r{\s+//-ENDPT2D\s+//-PT3D\s+}, "\n[none]\n")
195
- str = str.gsub(%r{\s+//-ENDPT2D\s+//-PT4D\s+}, "\n[none]\n")
196
- str = str.gsub(%r{\s+//-ENDPT3D\s+//-PT4D\s+}, "\n[none]\n")
197
- # Collapse blocks of text[2,3]data
198
- str = str.gsub(%r{\s+//-ENDPT[234]D\s+//-PT[234]D\s+}, "\n\n")
199
- # In the beginning, add [none]
200
- str = str.gsub(%r{\s+//-PT[234]D\s+}, "\n\n[none]\n")
201
- # If following with another list, ensure we readd styling
202
- str = str.gsub(%r{\s+//-ENDPT[234]D\s+\*}, "\n\n[disc]\n*")
203
- # Otherwise, clean up
204
- str = str.gsub(%r{\s+//-ENDPT[234]D\s+}, "\n\n")
205
-
206
- self.output_string = str
207
- end
208
- end
209
- end
210
- end
211
- end
212
- end
213
-
214
- Coradoc::Input::Html.config.plugins << Coradoc::Input::Html::Plugin::Plateau