coradoc-html 1.1.7 → 1.1.13
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/lib/coradoc/html/config.rb +36 -12
- data/lib/coradoc/html/converter_base.rb +26 -68
- data/lib/coradoc/html/drop/annotation_drop.rb +31 -0
- data/lib/coradoc/html/drop/base.rb +77 -0
- data/lib/coradoc/html/drop/bibliography_drop.rb +15 -0
- data/lib/coradoc/html/drop/bibliography_entry_drop.rb +24 -0
- data/lib/coradoc/html/drop/block_drop.rb +69 -0
- data/lib/coradoc/html/drop/definition_item_drop.rb +36 -0
- data/lib/coradoc/html/drop/definition_list_drop.rb +15 -0
- data/lib/coradoc/html/drop/document_drop.rb +52 -0
- data/lib/coradoc/html/drop/drop_factory.rb +73 -0
- data/lib/coradoc/html/drop/footnote_drop.rb +24 -0
- data/lib/coradoc/html/drop/image_drop.rb +35 -0
- data/lib/coradoc/html/drop/inline_element_drop.rb +64 -0
- data/lib/coradoc/html/drop/list_block_drop.rb +23 -0
- data/lib/coradoc/html/drop/list_item_drop.rb +20 -0
- data/lib/coradoc/html/drop/table_cell_drop.rb +35 -0
- data/lib/coradoc/html/drop/table_drop.rb +15 -0
- data/lib/coradoc/html/drop/table_row_drop.rb +23 -0
- data/lib/coradoc/html/drop/term_drop.rb +24 -0
- data/lib/coradoc/html/drop/text_content_drop.rb +15 -0
- data/lib/coradoc/html/drop/toc_drop.rb +15 -0
- data/lib/coradoc/html/drop/toc_entry_drop.rb +32 -0
- data/lib/coradoc/html/escape.rb +29 -0
- data/lib/coradoc/html/input/cleaner.rb +4 -33
- data/lib/coradoc/html/input/config.rb +4 -3
- data/lib/coradoc/html/input/converters/a.rb +8 -19
- data/lib/coradoc/html/input/converters/aside.rb +4 -5
- data/lib/coradoc/html/input/converters/audio.rb +8 -35
- data/lib/coradoc/html/input/converters/base.rb +29 -27
- data/lib/coradoc/html/input/converters/blockquote.rb +4 -2
- data/lib/coradoc/html/input/converters/br.rb +4 -4
- data/lib/coradoc/html/input/converters/bypass.rb +68 -67
- data/lib/coradoc/html/input/converters/code.rb +7 -5
- data/lib/coradoc/html/input/converters/div.rb +4 -4
- data/lib/coradoc/html/input/converters/dl.rb +3 -25
- data/lib/coradoc/html/input/converters/drop.rb +13 -13
- data/lib/coradoc/html/input/converters/em.rb +5 -3
- data/lib/coradoc/html/input/converters/figure.rb +3 -26
- data/lib/coradoc/html/input/converters/h.rb +9 -11
- data/lib/coradoc/html/input/converters/head.rb +5 -4
- data/lib/coradoc/html/input/converters/hr.rb +4 -5
- data/lib/coradoc/html/input/converters/img.rb +4 -9
- data/lib/coradoc/html/input/converters/li.rb +3 -1
- data/lib/coradoc/html/input/converters/mark.rb +3 -1
- data/lib/coradoc/html/input/converters/markup.rb +4 -8
- data/lib/coradoc/html/input/converters/math.rb +7 -14
- data/lib/coradoc/html/input/converters/media_base.rb +50 -0
- data/lib/coradoc/html/input/converters/ol.rb +6 -8
- data/lib/coradoc/html/input/converters/p.rb +43 -34
- data/lib/coradoc/html/input/converters/pass_through.rb +2 -4
- data/lib/coradoc/html/input/converters/positional_formatting.rb +37 -0
- data/lib/coradoc/html/input/converters/pre.rb +3 -3
- data/lib/coradoc/html/input/converters/q.rb +6 -3
- data/lib/coradoc/html/input/converters/strong.rb +4 -2
- data/lib/coradoc/html/input/converters/sub.rb +7 -23
- data/lib/coradoc/html/input/converters/sup.rb +7 -23
- data/lib/coradoc/html/input/converters/table.rb +3 -1
- data/lib/coradoc/html/input/converters/td.rb +4 -30
- data/lib/coradoc/html/input/converters/text.rb +4 -3
- data/lib/coradoc/html/input/converters/tr.rb +3 -2
- data/lib/coradoc/html/input/converters/video.rb +14 -36
- data/lib/coradoc/html/input/converters.rb +17 -35
- data/lib/coradoc/html/input/html_converter.rb +2 -74
- data/lib/coradoc/html/input/plugin.rb +8 -50
- data/lib/coradoc/html/input/plugins/plateau.rb +4 -19
- data/lib/coradoc/html/input/postprocessor.rb +3 -9
- data/lib/coradoc/html/input.rb +26 -8
- data/lib/coradoc/html/layout_renderer.rb +163 -0
- data/lib/coradoc/html/output.rb +6 -12
- data/lib/coradoc/html/renderer.rb +84 -350
- data/lib/coradoc/html/section_numberable.rb +9 -0
- data/lib/coradoc/html/spa.rb +29 -270
- data/lib/coradoc/html/static.rb +29 -238
- data/lib/coradoc/html/template_caching.rb +31 -0
- data/lib/coradoc/html/template_config.rb +11 -70
- data/lib/coradoc/html/template_helpers.rb +39 -31
- data/lib/coradoc/html/template_locator.rb +17 -11
- data/lib/coradoc/html/theme.rb +1 -7
- data/lib/coradoc/html/title_text.rb +57 -0
- data/lib/coradoc/html/toc_builder.rb +105 -0
- data/lib/coradoc/html/toc_serializer.rb +33 -0
- data/lib/coradoc/html/transform/from_core_model.rb +13 -12
- data/lib/coradoc/html/transform/to_core_model.rb +10 -12
- data/lib/coradoc/html/version.rb +1 -1
- data/lib/coradoc/html.rb +43 -88
- metadata +37 -70
- data/lib/coradoc/html/base.rb +0 -157
- data/lib/coradoc/html/converters/admonition.rb +0 -180
- data/lib/coradoc/html/converters/attribute.rb +0 -68
- data/lib/coradoc/html/converters/attribute_reference.rb +0 -60
- data/lib/coradoc/html/converters/audio.rb +0 -165
- data/lib/coradoc/html/converters/base.rb +0 -615
- data/lib/coradoc/html/converters/bibliography.rb +0 -82
- data/lib/coradoc/html/converters/bibliography_entry.rb +0 -108
- data/lib/coradoc/html/converters/block_image.rb +0 -72
- data/lib/coradoc/html/converters/bold.rb +0 -34
- data/lib/coradoc/html/converters/break.rb +0 -32
- data/lib/coradoc/html/converters/comment_block.rb +0 -42
- data/lib/coradoc/html/converters/comment_line.rb +0 -54
- data/lib/coradoc/html/converters/cross_reference.rb +0 -59
- data/lib/coradoc/html/converters/document.rb +0 -108
- data/lib/coradoc/html/converters/example.rb +0 -114
- data/lib/coradoc/html/converters/highlight.rb +0 -34
- data/lib/coradoc/html/converters/include.rb +0 -68
- data/lib/coradoc/html/converters/inline_image.rb +0 -41
- data/lib/coradoc/html/converters/italic.rb +0 -34
- data/lib/coradoc/html/converters/line_break.rb +0 -31
- data/lib/coradoc/html/converters/link.rb +0 -46
- data/lib/coradoc/html/converters/list_item.rb +0 -75
- data/lib/coradoc/html/converters/listing.rb +0 -99
- data/lib/coradoc/html/converters/literal.rb +0 -102
- data/lib/coradoc/html/converters/monospace.rb +0 -34
- data/lib/coradoc/html/converters/open.rb +0 -78
- data/lib/coradoc/html/converters/ordered.rb +0 -53
- data/lib/coradoc/html/converters/paragraph.rb +0 -46
- data/lib/coradoc/html/converters/quote.rb +0 -113
- data/lib/coradoc/html/converters/reviewer_comment.rb +0 -74
- data/lib/coradoc/html/converters/reviewer_note.rb +0 -134
- data/lib/coradoc/html/converters/section.rb +0 -90
- data/lib/coradoc/html/converters/sidebar.rb +0 -113
- data/lib/coradoc/html/converters/source.rb +0 -137
- data/lib/coradoc/html/converters/source_code.rb +0 -16
- data/lib/coradoc/html/converters/span.rb +0 -61
- data/lib/coradoc/html/converters/strikethrough.rb +0 -34
- data/lib/coradoc/html/converters/subscript.rb +0 -34
- data/lib/coradoc/html/converters/superscript.rb +0 -34
- data/lib/coradoc/html/converters/table.rb +0 -85
- data/lib/coradoc/html/converters/table_cell.rb +0 -203
- data/lib/coradoc/html/converters/table_row.rb +0 -45
- data/lib/coradoc/html/converters/template_html_converter.rb +0 -105
- data/lib/coradoc/html/converters/term.rb +0 -58
- data/lib/coradoc/html/converters/text_element.rb +0 -44
- data/lib/coradoc/html/converters/underline.rb +0 -34
- data/lib/coradoc/html/converters/unordered.rb +0 -47
- data/lib/coradoc/html/converters/verse.rb +0 -105
- data/lib/coradoc/html/converters/video.rb +0 -179
- data/lib/coradoc/html/element_mapping.rb +0 -210
- data/lib/coradoc/html/entity.rb +0 -137
- data/lib/coradoc/html/input/converters/ignore.rb +0 -22
- data/lib/coradoc/html/input/converters/th.rb +0 -20
- data/lib/coradoc/html/theme/base.rb +0 -231
- data/lib/coradoc/html/theme/classic_renderer.rb +0 -390
- data/lib/coradoc/html/theme/modern/components/ui_components.rb +0 -344
- data/lib/coradoc/html/theme/modern/css_generator.rb +0 -311
- data/lib/coradoc/html/theme/modern/javascript_generator.rb +0 -314
- data/lib/coradoc/html/theme/modern/serializers/document_serializer.rb +0 -382
- data/lib/coradoc/html/theme/modern/tailwind_config_builder.rb +0 -164
- data/lib/coradoc/html/theme/modern/vue_template_generator.rb +0 -374
- data/lib/coradoc/html/theme/modern_renderer.rb +0 -250
- data/lib/coradoc/html/theme/registry.rb +0 -153
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d86ee1dfe0630fc0923c8bbaaf53a3a9653faf3a90f3fa6760e2abe765cc46a3
|
|
4
|
+
data.tar.gz: 228cb361cb1b9a7dc64823788fac88afa87e5d972049064ffdd51d9909ad11a4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c219dbf71096377f684cd4ac7888e63248f1bf0ae279aec7e64923a1188bab59e57db330f4582cf5801155f2bfd061746c88dc4e61d79550130782459fd4b5e5
|
|
7
|
+
data.tar.gz: db6bb17213127a330405a09785ae40a54c45c7ebfa5cf4f00709efeffe0534827401aa502e9fb10a3c6ab51c17cf257ad3129ffa7650d53c5a6f64c141954f50
|
data/lib/coradoc/html/config.rb
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'nokogiri'
|
|
4
|
+
|
|
3
5
|
module Coradoc
|
|
4
6
|
module Html
|
|
5
|
-
# HTML configuration and options
|
|
6
7
|
module Config
|
|
8
|
+
DEFAULT_LANG = 'en'
|
|
9
|
+
DEFAULT_TITLE = 'Untitled'
|
|
10
|
+
|
|
7
11
|
# Default HTML output options
|
|
8
12
|
DEFAULT_OPTIONS = {
|
|
9
13
|
# Theme system options
|
|
@@ -225,7 +229,11 @@ module Coradoc
|
|
|
225
229
|
# Build CSS link tag
|
|
226
230
|
def css_link_tag(options = {})
|
|
227
231
|
href = stylesheet_path(options)
|
|
228
|
-
|
|
232
|
+
doc = Nokogiri::HTML::Document.new
|
|
233
|
+
node = Nokogiri::XML::Node.new('link', doc)
|
|
234
|
+
node['rel'] = 'stylesheet'
|
|
235
|
+
node['href'] = href
|
|
236
|
+
node.to_html
|
|
229
237
|
end
|
|
230
238
|
|
|
231
239
|
# Build CSS style tag with embedded content
|
|
@@ -236,14 +244,14 @@ module Coradoc
|
|
|
236
244
|
content = css_content
|
|
237
245
|
content += "\n\n#{custom_css}" if custom_css && !custom_css.empty?
|
|
238
246
|
|
|
239
|
-
|
|
247
|
+
build_text_element('style', content)
|
|
240
248
|
end
|
|
241
249
|
|
|
242
250
|
# Build custom CSS style tag
|
|
243
251
|
def custom_css_tag(custom_css)
|
|
244
252
|
return '' unless custom_css && !custom_css.empty?
|
|
245
253
|
|
|
246
|
-
|
|
254
|
+
build_text_element('style', custom_css)
|
|
247
255
|
end
|
|
248
256
|
|
|
249
257
|
# Determine whether to embed or link CSS
|
|
@@ -305,7 +313,11 @@ module Coradoc
|
|
|
305
313
|
# Build JavaScript link tag
|
|
306
314
|
def js_link_tag(options = {})
|
|
307
315
|
src = javascript_path(options)
|
|
308
|
-
|
|
316
|
+
doc = Nokogiri::HTML::Document.new
|
|
317
|
+
node = Nokogiri::XML::Node.new('script', doc)
|
|
318
|
+
node['src'] = src
|
|
319
|
+
node['defer'] = ''
|
|
320
|
+
node.to_html
|
|
309
321
|
end
|
|
310
322
|
|
|
311
323
|
# Build JavaScript script tag with embedded content
|
|
@@ -313,7 +325,7 @@ module Coradoc
|
|
|
313
325
|
js_content = embedded_javascript(options)
|
|
314
326
|
return '' if js_content.empty?
|
|
315
327
|
|
|
316
|
-
|
|
328
|
+
build_text_element('script', js_content)
|
|
317
329
|
end
|
|
318
330
|
|
|
319
331
|
# Build complete JavaScript tags (link or embedded)
|
|
@@ -378,14 +390,19 @@ module Coradoc
|
|
|
378
390
|
# @return [String] HTML tags for Highlight.js
|
|
379
391
|
def highlightjs_tags(options = {})
|
|
380
392
|
theme = options[:highlightjs_theme] || DEFAULT_OPTIONS[:highlightjs_theme]
|
|
381
|
-
|
|
393
|
+
doc = Nokogiri::HTML::Document.new
|
|
382
394
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
tags << %(<script>hljs.highlightAll();</script>)
|
|
395
|
+
link_node = Nokogiri::XML::Node.new('link', doc)
|
|
396
|
+
link_node['rel'] = 'stylesheet'
|
|
397
|
+
link_node['href'] = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/#{theme}.min.css"
|
|
387
398
|
|
|
388
|
-
|
|
399
|
+
script_node = Nokogiri::XML::Node.new('script', doc)
|
|
400
|
+
script_node['src'] = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js'
|
|
401
|
+
|
|
402
|
+
init_node = Nokogiri::XML::Node.new('script', doc)
|
|
403
|
+
init_node.content = 'hljs.highlightAll();'
|
|
404
|
+
|
|
405
|
+
[link_node.to_html, script_node.to_html, init_node.to_html].join("\n")
|
|
389
406
|
end
|
|
390
407
|
|
|
391
408
|
# Get data attributes for code block
|
|
@@ -461,6 +478,13 @@ module Coradoc
|
|
|
461
478
|
line_break: 'br',
|
|
462
479
|
admonition: 'div'
|
|
463
480
|
}.freeze
|
|
481
|
+
|
|
482
|
+
def build_text_element(tag_name, content)
|
|
483
|
+
doc = Nokogiri::HTML::Document.new
|
|
484
|
+
node = Nokogiri::XML::Node.new(tag_name, doc)
|
|
485
|
+
node.content = content
|
|
486
|
+
node.to_html
|
|
487
|
+
end
|
|
464
488
|
end
|
|
465
489
|
end
|
|
466
490
|
end
|
|
@@ -23,6 +23,21 @@ module Coradoc
|
|
|
23
23
|
# Error class for unsupported document types
|
|
24
24
|
class UnsupportedDocumentError < Coradoc::Error; end
|
|
25
25
|
|
|
26
|
+
# Base class for output converter configurations.
|
|
27
|
+
#
|
|
28
|
+
# Provides shared `merge` and `defaults` patterns.
|
|
29
|
+
# Subclasses define `initialize`, `to_h`, and `validate!`.
|
|
30
|
+
class ConfigurationBase
|
|
31
|
+
def self.defaults
|
|
32
|
+
new
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def merge(other)
|
|
36
|
+
other_hash = other.is_a?(self.class) ? other.to_h : other.to_h.transform_keys(&:to_sym)
|
|
37
|
+
self.class.new(**to_h, **other_hash)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
26
41
|
attr_reader :document, :config
|
|
27
42
|
|
|
28
43
|
# Initialize a new converter instance
|
|
@@ -80,24 +95,8 @@ module Coradoc
|
|
|
80
95
|
new(document, config).to_file(output_path)
|
|
81
96
|
end
|
|
82
97
|
|
|
83
|
-
# Get the converter name
|
|
84
|
-
#
|
|
85
|
-
# @return [Symbol] Converter name (e.g., :static, :spa)
|
|
86
|
-
def converter_name
|
|
87
|
-
@converter_name ||= self.class.name.split('::').last
|
|
88
|
-
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
|
89
|
-
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
|
90
|
-
.downcase
|
|
91
|
-
.to_sym
|
|
92
|
-
end
|
|
93
|
-
|
|
94
98
|
protected
|
|
95
99
|
|
|
96
|
-
# Validate the input document
|
|
97
|
-
#
|
|
98
|
-
# @param document [Object] The document to validate
|
|
99
|
-
# @return [Coradoc::CoreModel::Base] The validated document
|
|
100
|
-
# @raise [UnsupportedDocumentError] if document is not valid
|
|
101
100
|
def validate_input(document)
|
|
102
101
|
# Handle transformer hash output
|
|
103
102
|
document = Coradoc::Transformer.transform(document) if document.is_a?(Hash) && document.key?(:document)
|
|
@@ -113,64 +112,23 @@ module Coradoc
|
|
|
113
112
|
document
|
|
114
113
|
end
|
|
115
114
|
|
|
116
|
-
# Build configuration from options
|
|
117
|
-
#
|
|
118
|
-
# @param config [Hash, Object] Configuration options or object
|
|
119
|
-
# @return [Object] Built configuration object
|
|
120
115
|
def build_config(config)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return config
|
|
124
|
-
end
|
|
116
|
+
klass = configuration_class
|
|
117
|
+
return config unless klass
|
|
125
118
|
|
|
126
|
-
config
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
return title if title.is_a?(String)
|
|
133
|
-
return title.text if title.is_a?(Coradoc::CoreModel::Base) && title.text
|
|
134
|
-
|
|
135
|
-
return title.to_s
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
'Untitled Document'
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def extract_text_from_content(content)
|
|
142
|
-
case content
|
|
143
|
-
when Array
|
|
144
|
-
content.map { |item| extract_text_from_content(item) }.join
|
|
145
|
-
when String
|
|
146
|
-
content
|
|
147
|
-
when Coradoc::CoreModel::InlineElement
|
|
148
|
-
content.content.to_s
|
|
149
|
-
when Coradoc::CoreModel::Base
|
|
150
|
-
if content.content
|
|
151
|
-
extract_text_from_content(content.content)
|
|
152
|
-
else
|
|
153
|
-
content.to_s
|
|
154
|
-
end
|
|
119
|
+
case config
|
|
120
|
+
when klass
|
|
121
|
+
config.validate!
|
|
122
|
+
config
|
|
123
|
+
when Hash
|
|
124
|
+
klass.new(**config)
|
|
155
125
|
else
|
|
156
|
-
|
|
126
|
+
klass.defaults
|
|
157
127
|
end
|
|
158
128
|
end
|
|
159
129
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
# @param text [String] Text to escape
|
|
163
|
-
# @return [String] Escaped text
|
|
164
|
-
def escape_html(text)
|
|
165
|
-
Coradoc::Html::Base.escape_html(text.to_s)
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
# Escape HTML attribute value
|
|
169
|
-
#
|
|
170
|
-
# @param value [String] Value to escape
|
|
171
|
-
# @return [String] Escaped value
|
|
172
|
-
def escape_attr(value)
|
|
173
|
-
value.to_s.gsub('"', '"').gsub('<', '<').gsub('>', '>')
|
|
130
|
+
def configuration_class
|
|
131
|
+
nil
|
|
174
132
|
end
|
|
175
133
|
end
|
|
176
134
|
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Html
|
|
5
|
+
module Drop
|
|
6
|
+
class AnnotationDrop < Base
|
|
7
|
+
def template_type
|
|
8
|
+
'annotation_block'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def annotation_type
|
|
12
|
+
(@model.annotation_type || 'note').to_s.downcase
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def label
|
|
16
|
+
Escape.escape_html(@model.annotation_label || annotation_type.upcase)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def content
|
|
20
|
+
content_to_liquid(@model.renderable_content)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def css_class
|
|
24
|
+
"admonitionblock #{annotation_type}"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
DropFactory.register(CoreModel::AnnotationBlock, AnnotationDrop)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'liquid'
|
|
4
|
+
|
|
5
|
+
module Coradoc
|
|
6
|
+
module Html
|
|
7
|
+
module Drop
|
|
8
|
+
class Base < Liquid::Drop
|
|
9
|
+
attr_reader :model
|
|
10
|
+
|
|
11
|
+
def initialize(model)
|
|
12
|
+
@model = model
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_liquid
|
|
16
|
+
self
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def template_type
|
|
20
|
+
self.class.name
|
|
21
|
+
.split('::').last
|
|
22
|
+
.sub(/Drop$/, '')
|
|
23
|
+
.gsub(/([A-Z])/, '_\1')
|
|
24
|
+
.downcase
|
|
25
|
+
.sub(/^_/, '')
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def id
|
|
29
|
+
@model.id
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def title
|
|
33
|
+
optional_text(@model.title)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
protected
|
|
37
|
+
|
|
38
|
+
def optional_text(value)
|
|
39
|
+
return nil unless value && !value.to_s.empty?
|
|
40
|
+
|
|
41
|
+
Escape.escape_html(value)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def extract_text(content)
|
|
45
|
+
case content
|
|
46
|
+
when nil then ''
|
|
47
|
+
when String then content
|
|
48
|
+
when Array then content.map { |c| extract_text(c) }.join
|
|
49
|
+
when CoreModel::InlineElement
|
|
50
|
+
content.text || extract_text(content.content)
|
|
51
|
+
when CoreModel::TextContent
|
|
52
|
+
content.text.to_s
|
|
53
|
+
when CoreModel::Base
|
|
54
|
+
TitleText.resolve(content).to_s
|
|
55
|
+
else
|
|
56
|
+
content.to_s
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def content_to_liquid(content)
|
|
61
|
+
DropFactory.create(content)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def children_to_liquid(children)
|
|
65
|
+
return [] unless children
|
|
66
|
+
|
|
67
|
+
children.map { |child| DropFactory.create(child) }
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Load DropFactory and all drops after Base is fully defined.
|
|
75
|
+
# Each drop self-registers; DropFactory sorts by type specificity
|
|
76
|
+
# so registration order doesn't matter.
|
|
77
|
+
require_relative 'drop_factory'
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Html
|
|
5
|
+
module Drop
|
|
6
|
+
class BibliographyDrop < Base
|
|
7
|
+
def entries
|
|
8
|
+
children_to_liquid(@model.entries)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
DropFactory.register(CoreModel::Bibliography, BibliographyDrop)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Html
|
|
5
|
+
module Drop
|
|
6
|
+
class BibliographyEntryDrop < Base
|
|
7
|
+
def anchor_name
|
|
8
|
+
n = @model.anchor_name
|
|
9
|
+
n && !n.to_s.empty? ? n : nil
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def document_id
|
|
13
|
+
optional_text(@model.document_id)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def ref_text
|
|
17
|
+
optional_text(@model.ref_text)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
DropFactory.register(CoreModel::BibliographyEntry, BibliographyEntryDrop)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Html
|
|
5
|
+
module Drop
|
|
6
|
+
class BlockDrop < Base
|
|
7
|
+
SEMANTIC_TAG_MAP = {
|
|
8
|
+
paragraph: 'p', source_code: 'pre', quote: 'blockquote',
|
|
9
|
+
verse: 'blockquote', example: 'div', sidebar: 'aside',
|
|
10
|
+
literal: 'pre', listing: 'pre', open: 'div',
|
|
11
|
+
horizontal_rule: 'hr'
|
|
12
|
+
}.freeze
|
|
13
|
+
|
|
14
|
+
SEMANTIC_CLASS_MAP = {
|
|
15
|
+
example: 'example', sidebar: 'sidebar', literal: 'literal'
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
18
|
+
def semantic_type
|
|
19
|
+
resolved_semantic_type.to_s
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def html_tag
|
|
23
|
+
SEMANTIC_TAG_MAP[resolved_semantic_type] || 'div'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def language
|
|
27
|
+
@model.language || @model.metadata('language')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def css_class
|
|
31
|
+
cls = SEMANTIC_CLASS_MAP[resolved_semantic_type]
|
|
32
|
+
cls ? "block-#{semantic_type} #{cls}" : "block-#{semantic_type}"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def content
|
|
36
|
+
content_to_liquid(@model.renderable_content)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def text
|
|
40
|
+
if %i[source_code literal listing].include?(resolved_semantic_type)
|
|
41
|
+
Escape.escape_html(@model.flat_text)
|
|
42
|
+
elsif resolved_semantic_type == :pass
|
|
43
|
+
@model.flat_text.to_s
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def hidden?
|
|
48
|
+
%i[comment reviewer].include?(resolved_semantic_type)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def raw?
|
|
52
|
+
resolved_semantic_type == :pass
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def hr?
|
|
56
|
+
resolved_semantic_type == :horizontal_rule
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def resolved_semantic_type
|
|
62
|
+
@resolved_semantic_type ||= @model.resolve_semantic_type || :paragraph
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
DropFactory.register(CoreModel::Block, BlockDrop)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Html
|
|
5
|
+
module Drop
|
|
6
|
+
class DefinitionItemDrop < Base
|
|
7
|
+
def term
|
|
8
|
+
Escape.escape_html(stripped_term)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def term_id
|
|
12
|
+
match = term_text.match(/\A\[\[([^\]]+)\]\]/)
|
|
13
|
+
match&.[](1)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def definitions
|
|
17
|
+
return [] unless @model.definitions
|
|
18
|
+
|
|
19
|
+
@model.definitions.map { |d| content_to_liquid(d) }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def term_text
|
|
25
|
+
@term_text ||= @model.term.to_s
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def stripped_term
|
|
29
|
+
term_text.sub(/\A\[\[[^\]]+\]\]/, '')
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
DropFactory.register(CoreModel::DefinitionItem, DefinitionItemDrop)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Html
|
|
5
|
+
module Drop
|
|
6
|
+
class DefinitionListDrop < Base
|
|
7
|
+
def items
|
|
8
|
+
children_to_liquid(@model.items)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
DropFactory.register(CoreModel::DefinitionList, DefinitionListDrop)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Html
|
|
5
|
+
module Drop
|
|
6
|
+
class DocumentDrop < Base
|
|
7
|
+
include SectionNumberable
|
|
8
|
+
|
|
9
|
+
def template_type
|
|
10
|
+
return 'document' if @model.is_a?(CoreModel::DocumentElement)
|
|
11
|
+
|
|
12
|
+
'section'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def title
|
|
16
|
+
text = TitleText.resolve(@model.title)
|
|
17
|
+
return nil unless text && !text.empty?
|
|
18
|
+
|
|
19
|
+
if @section_number
|
|
20
|
+
Escape.escape_html("#{@section_number}. #{text}")
|
|
21
|
+
else
|
|
22
|
+
Escape.escape_html(text)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def children
|
|
27
|
+
children_to_liquid(@model.children)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def structural_type
|
|
31
|
+
case @model
|
|
32
|
+
when CoreModel::DocumentElement then 'document'
|
|
33
|
+
when CoreModel::SectionElement then 'section'
|
|
34
|
+
when CoreModel::HeaderElement then 'header'
|
|
35
|
+
when CoreModel::PreambleElement then 'preamble'
|
|
36
|
+
else 'structural'
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def heading_level
|
|
41
|
+
if @model.is_a?(CoreModel::SectionElement)
|
|
42
|
+
[@model.heading_level + 1, 6].min
|
|
43
|
+
else
|
|
44
|
+
1
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
DropFactory.register(CoreModel::StructuralElement, DocumentDrop)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base'
|
|
4
|
+
|
|
5
|
+
module Coradoc
|
|
6
|
+
module Html
|
|
7
|
+
module Drop
|
|
8
|
+
module DropFactory
|
|
9
|
+
@registry = []
|
|
10
|
+
|
|
11
|
+
def self.register(model_class, drop_class)
|
|
12
|
+
@registry << [model_class, drop_class]
|
|
13
|
+
sort_registry!
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.create(obj)
|
|
17
|
+
return nil if obj.nil?
|
|
18
|
+
return obj.map { |o| create(o) } if obj.is_a?(Array)
|
|
19
|
+
return Escape.escape_html(obj) if obj.is_a?(String)
|
|
20
|
+
return obj.to_s if obj.is_a?(Numeric) || obj.is_a?(TrueClass) || obj.is_a?(FalseClass)
|
|
21
|
+
|
|
22
|
+
pair = lookup_pair(obj)
|
|
23
|
+
return pair.last.new(obj) if pair
|
|
24
|
+
|
|
25
|
+
Escape.escape_html(obj.to_s)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.drop_class_for(model)
|
|
29
|
+
pair = lookup_pair(model)
|
|
30
|
+
pair&.last
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.template_type_for(model)
|
|
34
|
+
drop = drop_class_for(model)
|
|
35
|
+
drop&.new(model)&.template_type
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class << self
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def lookup_pair(obj)
|
|
42
|
+
@registry.find { |klass, _drop_class| obj.is_a?(klass) }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def sort_registry!
|
|
46
|
+
@registry.sort_by! { |klass, _| -klass.ancestors.length }
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Load all drops — each self-registers with DropFactory
|
|
55
|
+
require_relative 'annotation_drop'
|
|
56
|
+
require_relative 'block_drop'
|
|
57
|
+
require_relative 'list_block_drop'
|
|
58
|
+
require_relative 'list_item_drop'
|
|
59
|
+
require_relative 'table_drop'
|
|
60
|
+
require_relative 'table_row_drop'
|
|
61
|
+
require_relative 'table_cell_drop'
|
|
62
|
+
require_relative 'image_drop'
|
|
63
|
+
require_relative 'inline_element_drop'
|
|
64
|
+
require_relative 'bibliography_entry_drop'
|
|
65
|
+
require_relative 'bibliography_drop'
|
|
66
|
+
require_relative 'toc_entry_drop'
|
|
67
|
+
require_relative 'toc_drop'
|
|
68
|
+
require_relative 'definition_item_drop'
|
|
69
|
+
require_relative 'definition_list_drop'
|
|
70
|
+
require_relative 'term_drop'
|
|
71
|
+
require_relative 'footnote_drop'
|
|
72
|
+
require_relative 'text_content_drop'
|
|
73
|
+
require_relative 'document_drop'
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Html
|
|
5
|
+
module Drop
|
|
6
|
+
class FootnoteDrop < Base
|
|
7
|
+
def footnote_id
|
|
8
|
+
@model.id || ''
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def content
|
|
12
|
+
Escape.escape_html(extract_text(@model.content || @model.inline_content))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def inline?
|
|
16
|
+
footnote_id.empty?
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
DropFactory.register(CoreModel::FootnoteReference, FootnoteDrop)
|
|
21
|
+
DropFactory.register(CoreModel::Footnote, FootnoteDrop)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|