coradoc 2.0.1 → 2.0.2
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/.rubocop_todo.yml +55 -167
- data/coradoc-adoc/lib/coradoc/asciidoc/model/base.rb +4 -3
- data/coradoc-adoc/lib/coradoc/asciidoc/model/document.rb +1 -1
- data/coradoc-adoc/lib/coradoc/asciidoc/model/include.rb +1 -1
- data/coradoc-adoc/lib/coradoc/asciidoc/model/resolver.rb +2 -2
- data/coradoc-adoc/lib/coradoc/asciidoc/model/serialization/asciidoc_transform.rb +3 -3
- data/coradoc-adoc/lib/coradoc/asciidoc/model/table_row.rb +1 -1
- data/coradoc-adoc/lib/coradoc/asciidoc/model/text_element.rb +4 -8
- data/coradoc-adoc/lib/coradoc/asciidoc/parse_error.rb +6 -6
- data/coradoc-adoc/lib/coradoc/asciidoc/serializer/adoc_serializer.rb +5 -10
- data/coradoc-adoc/lib/coradoc/asciidoc/serializer/formatter.rb +4 -3
- data/coradoc-adoc/lib/coradoc/asciidoc/serializer/serializers/base.rb +8 -20
- data/coradoc-adoc/lib/coradoc/asciidoc/serializer/serializers/block/core.rb +1 -1
- data/coradoc-adoc/lib/coradoc/asciidoc/serializer/serializers/document.rb +3 -6
- data/coradoc-adoc/lib/coradoc/asciidoc/serializer/serializers/inline/strikethrough.rb +1 -1
- data/coradoc-adoc/lib/coradoc/asciidoc/serializer/serializers/list/item.rb +5 -9
- data/coradoc-adoc/lib/coradoc/asciidoc/transform/from_core_model.rb +26 -34
- data/coradoc-adoc/lib/coradoc/asciidoc/transform/from_core_model_registrations.rb +18 -18
- data/coradoc-adoc/lib/coradoc/asciidoc/transform/to_core_model.rb +96 -123
- data/coradoc-adoc/lib/coradoc/asciidoc/transform/to_core_model_registrations.rb +10 -6
- data/coradoc-adoc/lib/coradoc/asciidoc/transformer/header_rules.rb +5 -5
- data/coradoc-adoc/lib/coradoc/asciidoc/transformer/list_rules.rb +2 -2
- data/coradoc-adoc/lib/coradoc/asciidoc/transformer/structural_rules.rb +1 -1
- data/coradoc-adoc/lib/coradoc/asciidoc/transformer.rb +5 -5
- data/coradoc-adoc/lib/coradoc/asciidoc.rb +1 -1
- data/coradoc-adoc/lib/coradoc/util/asciidoc.rb +4 -3
- data/coradoc-adoc/spec/coradoc/asciidoc/transform/from_core_model_spec.rb +4 -2
- data/coradoc-docx/lib/coradoc/docx/transform/rules/run_rule.rb +4 -1
- data/coradoc-docx/lib/coradoc/docx/transform/rules/simple_field_rule.rb +5 -1
- data/coradoc-docx/lib/coradoc/docx/transform/rules/table_rule.rb +0 -1
- data/coradoc-docx/lib/coradoc/docx.rb +6 -4
- data/coradoc-docx/spec/coradoc/docx/transform/from_core_model_spec.rb +5 -2
- data/coradoc-docx/spec/coradoc/docx/transform/rules/rule_unit_spec.rb +27 -7
- data/coradoc-docx/spec/coradoc/docx/transform/to_core_model_spec.rb +6 -2
- data/coradoc-html/lib/coradoc/html/converters/base.rb +4 -1
- data/coradoc-html/lib/coradoc/html.rb +1 -1
- data/coradoc-markdown/lib/coradoc/markdown/transform/from_core_model.rb +2 -2
- data/coradoc-markdown/lib/coradoc/markdown.rb +1 -1
- data/lib/coradoc/configurable.rb +6 -2
- data/lib/coradoc/coradoc.rb +18 -16
- data/lib/coradoc/core_model/base.rb +3 -3
- data/lib/coradoc/core_model/list_item.rb +3 -3
- data/lib/coradoc/core_model/toc_generator.rb +1 -1
- data/lib/coradoc/document_manipulator.rb +9 -13
- data/lib/coradoc/format_module.rb +16 -4
- data/lib/coradoc/input.rb +1 -1
- data/lib/coradoc/output.rb +1 -1
- data/lib/coradoc/query.rb +38 -186
- data/lib/coradoc/registry.rb +5 -7
- data/lib/coradoc/serializer/registry.rb +3 -5
- data/lib/coradoc/validation.rb +40 -21
- data/lib/coradoc/version.rb +1 -1
- metadata +1 -1
|
@@ -148,7 +148,10 @@ RSpec.describe Coradoc::Docx::Transform::Rules::ParagraphRule do
|
|
|
148
148
|
end
|
|
149
149
|
|
|
150
150
|
describe '#apply' do
|
|
151
|
-
let(:context)
|
|
151
|
+
let(:context) do
|
|
152
|
+
build_context(registry: build_registry_with(described_class.new, Coradoc::Docx::Transform::Rules::RunRule.new,
|
|
153
|
+
Coradoc::Docx::Transform::Rules::TextRule.new))
|
|
154
|
+
end
|
|
152
155
|
|
|
153
156
|
it 'produces a Block paragraph with text content' do
|
|
154
157
|
para = build_paragraph('Hello')
|
|
@@ -188,7 +191,10 @@ RSpec.describe Coradoc::Docx::Transform::Rules::TableRule do
|
|
|
188
191
|
end
|
|
189
192
|
|
|
190
193
|
describe '#apply' do
|
|
191
|
-
let(:context)
|
|
194
|
+
let(:context) do
|
|
195
|
+
build_context(registry: build_registry_with(described_class.new, Coradoc::Docx::Transform::Rules::ParagraphRule.new,
|
|
196
|
+
Coradoc::Docx::Transform::Rules::RunRule.new, Coradoc::Docx::Transform::Rules::TextRule.new))
|
|
197
|
+
end
|
|
192
198
|
|
|
193
199
|
it 'produces a CoreModel::Table with rows and cells' do
|
|
194
200
|
table = build_table([%w[A B], %w[C D]])
|
|
@@ -213,7 +219,10 @@ RSpec.describe Coradoc::Docx::Transform::Rules::ListItemRule do
|
|
|
213
219
|
end
|
|
214
220
|
|
|
215
221
|
describe '#apply' do
|
|
216
|
-
let(:context)
|
|
222
|
+
let(:context) do
|
|
223
|
+
build_context(registry: build_registry_with(Coradoc::Docx::Transform::Rules::RunRule.new,
|
|
224
|
+
Coradoc::Docx::Transform::Rules::TextRule.new))
|
|
225
|
+
end
|
|
217
226
|
|
|
218
227
|
it 'produces a ListItem with content' do
|
|
219
228
|
para = build_list_paragraph('Item 1', num_id: 1)
|
|
@@ -242,7 +251,10 @@ RSpec.describe Coradoc::Docx::Transform::Rules::HeadingRule do
|
|
|
242
251
|
end
|
|
243
252
|
|
|
244
253
|
describe '#apply' do
|
|
245
|
-
let(:context)
|
|
254
|
+
let(:context) do
|
|
255
|
+
build_context(registry: build_registry_with(Coradoc::Docx::Transform::Rules::RunRule.new,
|
|
256
|
+
Coradoc::Docx::Transform::Rules::TextRule.new))
|
|
257
|
+
end
|
|
246
258
|
|
|
247
259
|
it 'produces a StructuralElement section with title and level' do
|
|
248
260
|
para = build_heading('My Title', level: 2)
|
|
@@ -363,7 +375,9 @@ RSpec.describe Coradoc::Docx::Transform::Rules::HyperlinkRule do
|
|
|
363
375
|
|
|
364
376
|
describe '#apply' do
|
|
365
377
|
let(:run_rule) { Coradoc::Docx::Transform::Rules::RunRule.new }
|
|
366
|
-
let(:context)
|
|
378
|
+
let(:context) do
|
|
379
|
+
build_context(registry: build_registry_with(run_rule, Coradoc::Docx::Transform::Rules::TextRule.new))
|
|
380
|
+
end
|
|
367
381
|
|
|
368
382
|
it 'produces InlineElement link with external URL' do
|
|
369
383
|
hl = build_hyperlink(
|
|
@@ -419,7 +433,10 @@ RSpec.describe Coradoc::Docx::Transform::Rules::SimpleFieldRule do
|
|
|
419
433
|
end
|
|
420
434
|
|
|
421
435
|
describe '#apply' do
|
|
422
|
-
let(:context)
|
|
436
|
+
let(:context) do
|
|
437
|
+
build_context(registry: build_registry_with(Coradoc::Docx::Transform::Rules::RunRule.new,
|
|
438
|
+
Coradoc::Docx::Transform::Rules::TextRule.new))
|
|
439
|
+
end
|
|
423
440
|
|
|
424
441
|
it 'returns nil for PAGE field (print layout)' do
|
|
425
442
|
field = Uniword::Wordprocessingml::SimpleField.new
|
|
@@ -449,7 +466,10 @@ RSpec.describe Coradoc::Docx::Transform::Rules::StructuredDocumentTagRule do
|
|
|
449
466
|
end
|
|
450
467
|
|
|
451
468
|
describe '#apply' do
|
|
452
|
-
let(:context)
|
|
469
|
+
let(:context) do
|
|
470
|
+
build_context(registry: build_registry_with(Coradoc::Docx::Transform::Rules::ParagraphRule.new,
|
|
471
|
+
Coradoc::Docx::Transform::Rules::RunRule.new, Coradoc::Docx::Transform::Rules::TextRule.new))
|
|
472
|
+
end
|
|
453
473
|
|
|
454
474
|
it 'unwraps SDT content and delegates to paragraph rules' do
|
|
455
475
|
sdt = Uniword::Wordprocessingml::StructuredDocumentTag.new
|
|
@@ -221,7 +221,9 @@ RSpec.describe Coradoc::Docx::Transform::ToCoreModel do
|
|
|
221
221
|
core = transform_to_core(doc)
|
|
222
222
|
|
|
223
223
|
blocks = core.children.select { |c| c.is_a?(Coradoc::CoreModel::Block) }
|
|
224
|
-
inline = blocks.first.children.find
|
|
224
|
+
inline = blocks.first.children.find do |c|
|
|
225
|
+
c.is_a?(Coradoc::CoreModel::InlineElement) && c.format_type == 'subscript'
|
|
226
|
+
end
|
|
225
227
|
expect(inline).not_to be_nil
|
|
226
228
|
expect(inline.content).to eq('2')
|
|
227
229
|
end
|
|
@@ -241,7 +243,9 @@ RSpec.describe Coradoc::Docx::Transform::ToCoreModel do
|
|
|
241
243
|
core = transform_to_core(doc)
|
|
242
244
|
|
|
243
245
|
blocks = core.children.select { |c| c.is_a?(Coradoc::CoreModel::Block) }
|
|
244
|
-
inline = blocks.first.children.find
|
|
246
|
+
inline = blocks.first.children.find do |c|
|
|
247
|
+
c.is_a?(Coradoc::CoreModel::InlineElement) && c.format_type == 'superscript'
|
|
248
|
+
end
|
|
245
249
|
expect(inline).not_to be_nil
|
|
246
250
|
expect(inline.content).to eq('2')
|
|
247
251
|
end
|
|
@@ -96,7 +96,10 @@ module Coradoc
|
|
|
96
96
|
|
|
97
97
|
return render_core_bibliography(content, state) if content.is_a?(Coradoc::CoreModel::Bibliography)
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
if content.is_a?(Coradoc::CoreModel::BibliographyEntry)
|
|
100
|
+
return render_core_bibliography_entry(content,
|
|
101
|
+
state)
|
|
102
|
+
end
|
|
100
103
|
|
|
101
104
|
# Handle unknown types gracefully
|
|
102
105
|
handle_unknown_content(content, state)
|
|
@@ -14,7 +14,7 @@ module Coradoc
|
|
|
14
14
|
# Register with the main coradoc registry
|
|
15
15
|
Coradoc.register_format(:html, self,
|
|
16
16
|
aliases: %w[html htm],
|
|
17
|
-
extensions: %w[.html .htm])
|
|
17
|
+
extensions: %w[.html .htm])
|
|
18
18
|
|
|
19
19
|
@registered = true
|
|
20
20
|
end
|
|
@@ -189,13 +189,13 @@ module Coradoc
|
|
|
189
189
|
|
|
190
190
|
# Check if first row has header cells
|
|
191
191
|
if first_row_cells.any?(&:header)
|
|
192
|
-
headers = first_row_cells.map
|
|
192
|
+
headers = first_row_cells.map(&:flat_text)
|
|
193
193
|
table_rows = table_rows[1..] || []
|
|
194
194
|
end
|
|
195
195
|
|
|
196
196
|
# Convert remaining rows to pipe-separated strings
|
|
197
197
|
rows = table_rows.map do |row|
|
|
198
|
-
Array(row.cells).map
|
|
198
|
+
Array(row.cells).map(&:flat_text).join(' | ')
|
|
199
199
|
end
|
|
200
200
|
end
|
|
201
201
|
|
|
@@ -186,5 +186,5 @@ module Coradoc
|
|
|
186
186
|
# Register the Markdown format with Coradoc
|
|
187
187
|
register_format(:markdown, Markdown,
|
|
188
188
|
aliases: %w[md markdown mdown mkd],
|
|
189
|
-
extensions: %w[.md .markdown .mdown .mkd])
|
|
189
|
+
extensions: %w[.md .markdown .mdown .mkd])
|
|
190
190
|
end
|
data/lib/coradoc/configurable.rb
CHANGED
|
@@ -45,9 +45,12 @@ module Coradoc
|
|
|
45
45
|
# @param options [Hash] Configuration options
|
|
46
46
|
def initialize(options = {})
|
|
47
47
|
@options = symbolize_keys(options)
|
|
48
|
-
after_initialize
|
|
48
|
+
after_initialize
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
+
# Hook for subclass initialization
|
|
52
|
+
def after_initialize; end
|
|
53
|
+
|
|
51
54
|
# Get a configuration value
|
|
52
55
|
#
|
|
53
56
|
# @param key [Symbol] Configuration key
|
|
@@ -95,7 +98,8 @@ module Coradoc
|
|
|
95
98
|
# Override in subclasses for custom handling
|
|
96
99
|
def apply_options(options)
|
|
97
100
|
options.each do |key, value|
|
|
98
|
-
|
|
101
|
+
setter = "#{key}="
|
|
102
|
+
instance_variable_set("@#{key}", value) if public_methods.include?(setter.to_sym)
|
|
99
103
|
end
|
|
100
104
|
end
|
|
101
105
|
end
|
data/lib/coradoc/coradoc.rb
CHANGED
|
@@ -67,6 +67,7 @@ module Coradoc
|
|
|
67
67
|
# @param options [Hash] optional configuration (e.g., extensions: [])
|
|
68
68
|
# @return [void]
|
|
69
69
|
def register_format(format_name, format_module, **options)
|
|
70
|
+
format_module.extend(FormatModule::Interface) unless format_module.is_a?(FormatModule::Interface)
|
|
70
71
|
registry.register(format_name, format_module, options)
|
|
71
72
|
FormatModule.validate!(format_module, format_name)
|
|
72
73
|
end
|
|
@@ -148,7 +149,7 @@ module Coradoc
|
|
|
148
149
|
return model if model.is_a?(CoreModel::Base)
|
|
149
150
|
|
|
150
151
|
registry.each_value do |format_module|
|
|
151
|
-
next unless format_module.
|
|
152
|
+
next unless format_module.handles_model?(model)
|
|
152
153
|
|
|
153
154
|
return format_module.to_core(model)
|
|
154
155
|
end
|
|
@@ -195,7 +196,7 @@ module Coradoc
|
|
|
195
196
|
# Coradoc.detect_format("file.md") # => :markdown
|
|
196
197
|
def detect_format(filename)
|
|
197
198
|
ext = File.extname(filename).downcase
|
|
198
|
-
registry.
|
|
199
|
+
registry.each_key do |name|
|
|
199
200
|
opts = registry.options_for(name)
|
|
200
201
|
return name if opts[:extensions]&.include?(ext)
|
|
201
202
|
end
|
|
@@ -243,7 +244,7 @@ module Coradoc
|
|
|
243
244
|
# @example
|
|
244
245
|
# html = Coradoc.convert_file("document.adoc", to: :html)
|
|
245
246
|
# adoc = Coradoc.convert_file("report.docx", to: :asciidoc)
|
|
246
|
-
def convert_file(path, from: nil,
|
|
247
|
+
def convert_file(path, to:, from: nil, **options)
|
|
247
248
|
source_format = from || detect_format(path)
|
|
248
249
|
raise UnsupportedFormatError, "Could not detect format for: #{path}" unless source_format
|
|
249
250
|
|
|
@@ -270,7 +271,7 @@ module Coradoc
|
|
|
270
271
|
return nil unless name
|
|
271
272
|
|
|
272
273
|
key = name.to_s.downcase
|
|
273
|
-
registry.
|
|
274
|
+
registry.each_key do |fmt_name|
|
|
274
275
|
opts = registry.options_for(fmt_name)
|
|
275
276
|
return fmt_name if opts[:aliases]&.include?(key)
|
|
276
277
|
end
|
|
@@ -285,9 +286,7 @@ module Coradoc
|
|
|
285
286
|
mod = get_format(format)
|
|
286
287
|
return false unless mod
|
|
287
288
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
true
|
|
289
|
+
mod.serialize?
|
|
291
290
|
end
|
|
292
291
|
|
|
293
292
|
# Check if a format supports parsing (reading input)
|
|
@@ -296,7 +295,9 @@ module Coradoc
|
|
|
296
295
|
# @return [Boolean] true if the format can parse
|
|
297
296
|
def parse_format?(format)
|
|
298
297
|
mod = get_format(format)
|
|
299
|
-
|
|
298
|
+
return false unless mod
|
|
299
|
+
|
|
300
|
+
mod.public_methods.include?(:parse_to_core) || mod.public_methods.include?(:parse)
|
|
300
301
|
end
|
|
301
302
|
|
|
302
303
|
# Get capability summary for all registered formats
|
|
@@ -361,9 +362,9 @@ module Coradoc
|
|
|
361
362
|
def document_stats(doc)
|
|
362
363
|
stats = {}
|
|
363
364
|
|
|
364
|
-
stats[:title] = doc.title if doc.
|
|
365
|
+
stats[:title] = doc.title if doc.title
|
|
365
366
|
|
|
366
|
-
if doc.
|
|
367
|
+
if doc.is_a?(CoreModel::StructuralElement)
|
|
367
368
|
stats[:child_count] = count_elements(doc)
|
|
368
369
|
stats[:element_counts] = count_element_types(doc)
|
|
369
370
|
end
|
|
@@ -379,9 +380,9 @@ module Coradoc
|
|
|
379
380
|
return elem.to_s unless elem.is_a?(CoreModel::Base)
|
|
380
381
|
|
|
381
382
|
type = elem.class.name.split('::').last
|
|
382
|
-
if elem.
|
|
383
|
+
if elem.title
|
|
383
384
|
"#{type}: #{elem.title}"
|
|
384
|
-
elsif elem.
|
|
385
|
+
elsif elem.is_a?(CoreModel::Block) && elem.content
|
|
385
386
|
preview = elem.content.to_s[0..50]
|
|
386
387
|
preview += '...' if elem.content.to_s.length > 50
|
|
387
388
|
"#{type}: #{preview}"
|
|
@@ -411,10 +412,10 @@ module Coradoc
|
|
|
411
412
|
private
|
|
412
413
|
|
|
413
414
|
def count_elements(doc)
|
|
414
|
-
return 0 unless doc.
|
|
415
|
+
return 0 unless doc.is_a?(CoreModel::StructuralElement)
|
|
415
416
|
|
|
416
417
|
doc.children.sum do |child|
|
|
417
|
-
1 + (child.
|
|
418
|
+
1 + (child.is_a?(CoreModel::StructuralElement) ? count_elements(child) : 0)
|
|
418
419
|
end
|
|
419
420
|
end
|
|
420
421
|
|
|
@@ -423,11 +424,12 @@ module Coradoc
|
|
|
423
424
|
visitor = Class.new(Visitor::Base) do
|
|
424
425
|
define_method(:visit) do |element|
|
|
425
426
|
if element.is_a?(CoreModel::Base)
|
|
426
|
-
|
|
427
|
+
has_element_type = element.is_a?(CoreModel::StructuralElement) || element.is_a?(CoreModel::Block)
|
|
428
|
+
type_key = if has_element_type && element.element_type
|
|
427
429
|
element.element_type
|
|
428
430
|
else
|
|
429
431
|
element.class.name.split('::').last
|
|
430
|
-
|
|
432
|
+
.gsub(/([A-Z])/, '_\1').downcase.sub(/^_/, '')
|
|
431
433
|
end
|
|
432
434
|
counts[type_key] += 1
|
|
433
435
|
end
|
|
@@ -136,7 +136,7 @@ module Coradoc
|
|
|
136
136
|
children_arr.map do |child|
|
|
137
137
|
if child.is_a?(String)
|
|
138
138
|
child
|
|
139
|
-
elsif child.
|
|
139
|
+
elsif child.is_a?(Lutaml::Model::Serializable)
|
|
140
140
|
child.to_hash
|
|
141
141
|
else
|
|
142
142
|
child.to_s
|
|
@@ -156,8 +156,8 @@ module Coradoc
|
|
|
156
156
|
|
|
157
157
|
# Compare a single attribute between this model and another
|
|
158
158
|
def compare_attribute(attr, other)
|
|
159
|
-
self_value =
|
|
160
|
-
other_value = other.
|
|
159
|
+
self_value = public_send(attr)
|
|
160
|
+
other_value = other.public_send(attr)
|
|
161
161
|
|
|
162
162
|
case self_value
|
|
163
163
|
when Array
|
|
@@ -45,13 +45,13 @@ module Coradoc
|
|
|
45
45
|
|
|
46
46
|
# Delegate nested to nested_list (lutaml attribute added by list_block.rb)
|
|
47
47
|
def nested
|
|
48
|
-
nested_list
|
|
48
|
+
nested_list
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
# Set nested list
|
|
52
52
|
# @param value [ListBlock, nil] nested list block
|
|
53
53
|
def nested=(value)
|
|
54
|
-
self.nested_list = value
|
|
54
|
+
self.nested_list = value
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
# Convert to hash representation
|
|
@@ -62,7 +62,7 @@ module Coradoc
|
|
|
62
62
|
marker: marker,
|
|
63
63
|
content: content,
|
|
64
64
|
nested_list: nested&.to_h,
|
|
65
|
-
children: children&.map { |child| child.
|
|
65
|
+
children: children&.map { |child| child.is_a?(CoreModel::Base) ? child.to_h : child }
|
|
66
66
|
}.compact
|
|
67
67
|
end
|
|
68
68
|
|
|
@@ -71,7 +71,7 @@ module Coradoc
|
|
|
71
71
|
# Find all sections in the document within level range
|
|
72
72
|
def find_sections(element, min_level, max_level)
|
|
73
73
|
sections = []
|
|
74
|
-
return sections unless element.
|
|
74
|
+
return sections unless element.is_a?(CoreModel::StructuralElement)
|
|
75
75
|
|
|
76
76
|
Array(element.children).each do |child|
|
|
77
77
|
next unless child.is_a?(CoreModel::StructuralElement)
|
|
@@ -22,7 +22,7 @@ module Coradoc
|
|
|
22
22
|
DocumentManipulator.new(filtered)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
def transform_text
|
|
25
|
+
def transform_text
|
|
26
26
|
return self unless block_given?
|
|
27
27
|
|
|
28
28
|
Visitor::Transformer.new do |element|
|
|
@@ -36,13 +36,11 @@ module Coradoc
|
|
|
36
36
|
self
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
def transform_headings
|
|
39
|
+
def transform_headings
|
|
40
40
|
return self unless block_given?
|
|
41
41
|
|
|
42
42
|
Visitor::Transformer.new do |element|
|
|
43
|
-
if element.is_a?(CoreModel::StructuralElement) && element.title.is_a?(String)
|
|
44
|
-
element.title = yield(element.title)
|
|
45
|
-
end
|
|
43
|
+
element.title = yield(element.title) if element.is_a?(CoreModel::StructuralElement) && element.title.is_a?(String)
|
|
46
44
|
end.visit(@document)
|
|
47
45
|
self
|
|
48
46
|
end
|
|
@@ -64,7 +62,7 @@ module Coradoc
|
|
|
64
62
|
|
|
65
63
|
def remove_elements(element_type)
|
|
66
64
|
Visitor::Transformer.new do |element|
|
|
67
|
-
next unless element.
|
|
65
|
+
next unless element.is_a?(CoreModel::StructuralElement) && element.children
|
|
68
66
|
|
|
69
67
|
element.children.reject! do |child|
|
|
70
68
|
match_element_type?(child, element_type)
|
|
@@ -128,15 +126,13 @@ module Coradoc
|
|
|
128
126
|
end
|
|
129
127
|
|
|
130
128
|
def filter_sections(element, level: nil, title: nil)
|
|
131
|
-
if element.
|
|
129
|
+
if element.is_a?(CoreModel::StructuralElement) && element.children
|
|
132
130
|
element.children = element.children
|
|
133
131
|
.map { |child| filter_sections(child, level: level, title: title) }
|
|
134
132
|
.compact
|
|
135
133
|
end
|
|
136
134
|
|
|
137
|
-
if element.is_a?(CoreModel::StructuralElement) && element.section? && !element.document?
|
|
138
|
-
return nil unless section_matches?(element, level: level, title: title)
|
|
139
|
-
end
|
|
135
|
+
return nil if element.is_a?(CoreModel::StructuralElement) && element.section? && !element.document? && !section_matches?(element, level: level, title: title)
|
|
140
136
|
|
|
141
137
|
element
|
|
142
138
|
end
|
|
@@ -154,7 +150,7 @@ module Coradoc
|
|
|
154
150
|
element_title = section.title || ''
|
|
155
151
|
case title
|
|
156
152
|
when String then return false unless element_title.include?(title)
|
|
157
|
-
when Regexp then return false unless element_title
|
|
153
|
+
when Regexp then return false unless element_title&.match?(title)
|
|
158
154
|
end
|
|
159
155
|
end
|
|
160
156
|
|
|
@@ -163,7 +159,7 @@ module Coradoc
|
|
|
163
159
|
|
|
164
160
|
def collect_sections(element, max_level: 3, current_level: 1)
|
|
165
161
|
sections = []
|
|
166
|
-
return sections unless element.
|
|
162
|
+
return sections unless element.is_a?(CoreModel::StructuralElement)
|
|
167
163
|
|
|
168
164
|
element.children.each do |child|
|
|
169
165
|
next unless child.is_a?(CoreModel::StructuralElement) &&
|
|
@@ -186,7 +182,7 @@ module Coradoc
|
|
|
186
182
|
when CoreModel::Base
|
|
187
183
|
cloned = element.class.new
|
|
188
184
|
element.class.attributes.each_key do |name|
|
|
189
|
-
cloned.
|
|
185
|
+
cloned.public_send("#{name}=", deep_clone(element.public_send(name)))
|
|
190
186
|
end
|
|
191
187
|
cloned
|
|
192
188
|
when Array
|
|
@@ -19,17 +19,29 @@ module Coradoc
|
|
|
19
19
|
MINIMUM_PARSE_METHODS = %i[parse_to_core parse].freeze
|
|
20
20
|
REQUIRED_METHODS = %i[serialize].freeze
|
|
21
21
|
|
|
22
|
+
# Default implementations for optional format module methods.
|
|
23
|
+
# Format modules are auto-extended with this during registration.
|
|
24
|
+
module Interface
|
|
25
|
+
def handles_model?(_model)
|
|
26
|
+
false
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def serialize?
|
|
30
|
+
true
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
22
34
|
# Validate that a format module implements the minimum interface.
|
|
23
35
|
# Warns to $stderr if methods are missing. Returns true if valid.
|
|
24
36
|
def self.validate!(format_module, format_name)
|
|
25
|
-
has_parse = MINIMUM_PARSE_METHODS.any? { |m| format_module.
|
|
26
|
-
has_serialize = REQUIRED_METHODS.all? { |m| format_module.
|
|
37
|
+
has_parse = MINIMUM_PARSE_METHODS.any? { |m| format_module.public_methods.include?(m) }
|
|
38
|
+
has_serialize = REQUIRED_METHODS.all? { |m| format_module.public_methods.include?(m) }
|
|
27
39
|
|
|
28
40
|
return true if has_parse && has_serialize
|
|
29
41
|
|
|
30
42
|
missing = []
|
|
31
|
-
missing <<
|
|
32
|
-
missing <<
|
|
43
|
+
missing << 'parse_to_core or parse' unless has_parse
|
|
44
|
+
missing << 'serialize' unless has_serialize
|
|
33
45
|
warn "Coradoc: format :#{format_name} (#{format_module}) missing: #{missing.join(', ')}"
|
|
34
46
|
false
|
|
35
47
|
end
|
data/lib/coradoc/input.rb
CHANGED