coradoc-adoc 2.0.7 → 2.0.8

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.
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module AsciiDoc
5
+ module Transform
6
+ # Visits AsciiDoc inline model nodes and extracts plain text.
7
+ #
8
+ # Replaces the 70-line extract_text_content case/when in ToCoreModel.
9
+ # Each visit_ method handles one model type — locality per element.
10
+ class TextExtractVisitor
11
+ def extract(model)
12
+ visit(model)
13
+ end
14
+
15
+ private
16
+
17
+ # Scalars
18
+ def visit_nil(_)
19
+ ''
20
+ end
21
+
22
+ def visit_string(model)
23
+ model
24
+ end
25
+
26
+ def visit_parslet_slice(model)
27
+ model.to_s
28
+ end
29
+
30
+ # Text carriers
31
+ def visit_text_element(model)
32
+ content = model.content
33
+ content.is_a?(Array) ? visit_array(content) : visit(content)
34
+ end
35
+
36
+ # Inline formatting — recurse into content
37
+ def visit_inline(model)
38
+ visit(model.content)
39
+ end
40
+
41
+ def visit_term(model)
42
+ model.term.to_s
43
+ end
44
+
45
+ def visit_link(model)
46
+ model.name || model.path || ''
47
+ end
48
+
49
+ def visit_cross_reference(model)
50
+ model.href || ''
51
+ end
52
+
53
+ def visit_stem(model)
54
+ model.content.to_s
55
+ end
56
+
57
+ def visit_footnote(model)
58
+ model.text ? visit(model.text) : ''
59
+ end
60
+
61
+ def visit_attribute_reference(model)
62
+ "{#{model.name}}"
63
+ end
64
+
65
+ def visit_core_model_text_content(model)
66
+ model.text.to_s
67
+ end
68
+
69
+ def visit_core_model_image(model)
70
+ model.alt || model.src || ''
71
+ end
72
+
73
+ def visit_adoc_image(model)
74
+ model.alt || model.src || ''
75
+ end
76
+
77
+ def visit_base_model(model)
78
+ model.content ? visit(model.content) : ''
79
+ end
80
+
81
+ def visit_core_model_inline(model)
82
+ model.content.to_s
83
+ end
84
+
85
+ # Collections
86
+ def visit_array(models)
87
+ result = []
88
+ models.each_with_index do |item, idx|
89
+ text = visit(item)
90
+ next if text.empty?
91
+
92
+ result << text
93
+ next unless idx < models.length - 1 && !text.empty?
94
+
95
+ result << ' ' if item.is_a?(Model::TextElement) && item.line_break != '+'
96
+ end
97
+ result.join
98
+ end
99
+
100
+ # Dispatch
101
+ def visit(model)
102
+ case model
103
+ when nil then visit_nil(model)
104
+ when String then visit_string(model)
105
+ when Parslet::Slice then visit_parslet_slice(model)
106
+ when CoreModel::TextContent then visit_core_model_text_content(model)
107
+ when CoreModel::Image then visit_core_model_image(model)
108
+ when CoreModel::InlineElement then visit_core_model_inline(model)
109
+ when Array then visit_array(model)
110
+ when Model::TextElement then visit_text_element(model)
111
+ when Model::Term then visit_term(model)
112
+ when Model::Inline::Link then visit_link(model)
113
+ when Model::Inline::CrossReference then visit_cross_reference(model)
114
+ when Model::Inline::Stem then visit_stem(model)
115
+ when Model::Inline::Footnote then visit_footnote(model)
116
+ when Model::Inline::AttributeReference then visit_attribute_reference(model)
117
+ when Model::Image::Core then visit_adoc_image(model)
118
+ when Model::Base then visit_base_model(model)
119
+ else
120
+ model.class.name.start_with?('Parslet::') ? model.to_s : ''
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end