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.
- checksums.yaml +4 -4
- data/lib/coradoc/asciidoc/delimiter_mapping.rb +16 -0
- data/lib/coradoc/asciidoc/transform/element_transformers/block_transformer.rb +89 -0
- data/lib/coradoc/asciidoc/transform/element_transformers/document_transformer.rb +43 -0
- data/lib/coradoc/asciidoc/transform/element_transformers/inline_transformer.rb +56 -0
- data/lib/coradoc/asciidoc/transform/element_transformers/list_transformer.rb +90 -0
- data/lib/coradoc/asciidoc/transform/element_transformers/other_transformer.rb +61 -0
- data/lib/coradoc/asciidoc/transform/element_transformers/table_transformer.rb +49 -0
- data/lib/coradoc/asciidoc/transform/element_transformers.rb +16 -0
- data/lib/coradoc/asciidoc/transform/from_core_model.rb +6 -77
- data/lib/coradoc/asciidoc/transform/inline_transform_visitor.rb +59 -0
- data/lib/coradoc/asciidoc/transform/text_extract_visitor.rb +126 -0
- data/lib/coradoc/asciidoc/transform/to_core_model.rb +42 -569
- data/lib/coradoc/asciidoc/transform/to_core_model_registrations.rb +31 -70
- data/lib/coradoc/asciidoc/transform/transformer_registry.rb +80 -0
- data/lib/coradoc/asciidoc/transform.rb +5 -1
- data/lib/coradoc/asciidoc/version.rb +1 -1
- data/lib/coradoc/asciidoc.rb +1 -0
- metadata +12 -2
- data/lib/coradoc/asciidoc/transform/registry.rb +0 -146
|
@@ -3,8 +3,14 @@
|
|
|
3
3
|
module Coradoc
|
|
4
4
|
module AsciiDoc
|
|
5
5
|
module Transform
|
|
6
|
-
# Registers all default AsciiDoc -> CoreModel transformers
|
|
7
6
|
module ToCoreModelRegistrations
|
|
7
|
+
Doc = ElementTransformers::DocumentTransformer
|
|
8
|
+
Blk = ElementTransformers::BlockTransformer
|
|
9
|
+
Lst = ElementTransformers::ListTransformer
|
|
10
|
+
Inl = ElementTransformers::InlineTransformer
|
|
11
|
+
Tbl = ElementTransformers::TableTransformer
|
|
12
|
+
Oth = ElementTransformers::OtherTransformer
|
|
13
|
+
|
|
8
14
|
class << self
|
|
9
15
|
def register_all!
|
|
10
16
|
register_document_transformers!
|
|
@@ -20,24 +26,24 @@ module Coradoc
|
|
|
20
26
|
def register_document_transformers!
|
|
21
27
|
Registry.register(
|
|
22
28
|
Coradoc::AsciiDoc::Model::Document,
|
|
23
|
-
|
|
29
|
+
->(model) { Doc.transform_document(model) }
|
|
24
30
|
)
|
|
25
31
|
|
|
26
32
|
Registry.register(
|
|
27
33
|
Coradoc::AsciiDoc::Model::Section,
|
|
28
|
-
|
|
34
|
+
->(model) { Doc.transform_section(model) }
|
|
29
35
|
)
|
|
30
36
|
|
|
31
37
|
Registry.register(
|
|
32
38
|
Coradoc::AsciiDoc::Model::Paragraph,
|
|
33
|
-
|
|
39
|
+
->(model) { Blk.transform_paragraph(model) }
|
|
34
40
|
)
|
|
35
41
|
end
|
|
36
42
|
|
|
37
43
|
def register_block_transformers!
|
|
38
44
|
Registry.register_with_priority(
|
|
39
45
|
Coradoc::AsciiDoc::Model::Block::SourceCode,
|
|
40
|
-
|
|
46
|
+
->(model) { Blk.transform_source_block(model) },
|
|
41
47
|
priority: 10
|
|
42
48
|
)
|
|
43
49
|
|
|
@@ -51,14 +57,14 @@ module Coradoc
|
|
|
51
57
|
}.each do |block_class, core_model_class|
|
|
52
58
|
Registry.register_with_priority(
|
|
53
59
|
block_class,
|
|
54
|
-
|
|
60
|
+
->(model) { Blk.transform_typed_block(model, core_model_class) },
|
|
55
61
|
priority: 10
|
|
56
62
|
)
|
|
57
63
|
end
|
|
58
64
|
|
|
59
65
|
Registry.register(
|
|
60
66
|
Coradoc::AsciiDoc::Model::Block::Core,
|
|
61
|
-
|
|
67
|
+
->(model) { Blk.transform_block(model, model.delimiter.to_s) }
|
|
62
68
|
)
|
|
63
69
|
|
|
64
70
|
Registry.register(
|
|
@@ -74,17 +80,17 @@ module Coradoc
|
|
|
74
80
|
def register_list_transformers!
|
|
75
81
|
Registry.register(
|
|
76
82
|
Coradoc::AsciiDoc::Model::List::Unordered,
|
|
77
|
-
|
|
83
|
+
->(model) { Lst.transform_list(model, 'unordered') }
|
|
78
84
|
)
|
|
79
85
|
|
|
80
86
|
Registry.register(
|
|
81
87
|
Coradoc::AsciiDoc::Model::List::Ordered,
|
|
82
|
-
|
|
88
|
+
->(model) { Lst.transform_list(model, 'ordered') }
|
|
83
89
|
)
|
|
84
90
|
|
|
85
91
|
Registry.register(
|
|
86
92
|
Coradoc::AsciiDoc::Model::List::Definition,
|
|
87
|
-
|
|
93
|
+
->(model) { Lst.transform_list(model, 'definition') }
|
|
88
94
|
)
|
|
89
95
|
end
|
|
90
96
|
|
|
@@ -100,33 +106,33 @@ module Coradoc
|
|
|
100
106
|
].each do |inline_class, format_type|
|
|
101
107
|
Registry.register(
|
|
102
108
|
inline_class,
|
|
103
|
-
|
|
109
|
+
->(model) { Inl.transform_inline(model, format_type) }
|
|
104
110
|
)
|
|
105
111
|
end
|
|
106
112
|
|
|
107
113
|
Registry.register(
|
|
108
114
|
Coradoc::AsciiDoc::Model::Inline::Underline,
|
|
109
|
-
|
|
115
|
+
->(model) { Inl.transform_inline_text(model, 'underline') }
|
|
110
116
|
)
|
|
111
117
|
|
|
112
118
|
Registry.register(
|
|
113
119
|
Coradoc::AsciiDoc::Model::Inline::Link,
|
|
114
|
-
|
|
120
|
+
->(model) { Inl.transform_link(model) }
|
|
115
121
|
)
|
|
116
122
|
|
|
117
123
|
Registry.register(
|
|
118
124
|
Coradoc::AsciiDoc::Model::Inline::CrossReference,
|
|
119
|
-
|
|
125
|
+
->(model) { Inl.transform_cross_reference(model) }
|
|
120
126
|
)
|
|
121
127
|
|
|
122
128
|
Registry.register(
|
|
123
129
|
Coradoc::AsciiDoc::Model::Inline::Footnote,
|
|
124
|
-
|
|
130
|
+
->(model) { Inl.transform_inline_footnote(model) }
|
|
125
131
|
)
|
|
126
132
|
|
|
127
133
|
Registry.register(
|
|
128
134
|
Coradoc::AsciiDoc::Model::Inline::Stem,
|
|
129
|
-
|
|
135
|
+
->(model) { Inl.transform_stem(model) }
|
|
130
136
|
)
|
|
131
137
|
|
|
132
138
|
Registry.register(
|
|
@@ -143,47 +149,46 @@ module Coradoc
|
|
|
143
149
|
def register_table_transformers!
|
|
144
150
|
Registry.register(
|
|
145
151
|
Coradoc::AsciiDoc::Model::Table,
|
|
146
|
-
|
|
152
|
+
->(model) { Tbl.transform_table(model) }
|
|
147
153
|
)
|
|
148
154
|
|
|
149
155
|
Registry.register(
|
|
150
156
|
Coradoc::AsciiDoc::Model::TableRow,
|
|
151
|
-
|
|
157
|
+
->(model) { Tbl.transform_table_row(model) }
|
|
152
158
|
)
|
|
153
159
|
|
|
154
160
|
Registry.register(
|
|
155
161
|
Coradoc::AsciiDoc::Model::TableCell,
|
|
156
|
-
|
|
162
|
+
->(model) { Tbl.transform_table_cell(model) }
|
|
157
163
|
)
|
|
158
164
|
end
|
|
159
165
|
|
|
160
166
|
def register_other_transformers!
|
|
161
167
|
Registry.register(
|
|
162
168
|
Coradoc::AsciiDoc::Model::Term,
|
|
163
|
-
|
|
169
|
+
->(model) { Oth.transform_term(model) }
|
|
164
170
|
)
|
|
165
171
|
|
|
166
172
|
Registry.register(
|
|
167
173
|
Coradoc::AsciiDoc::Model::Admonition,
|
|
168
|
-
|
|
174
|
+
->(model) { Oth.transform_admonition(model) }
|
|
169
175
|
)
|
|
170
176
|
|
|
171
177
|
Registry.register(
|
|
172
178
|
Coradoc::AsciiDoc::Model::Image::BlockImage,
|
|
173
|
-
|
|
179
|
+
->(model) { Oth.transform_image(model) }
|
|
174
180
|
)
|
|
175
181
|
|
|
176
182
|
Registry.register(
|
|
177
183
|
Coradoc::AsciiDoc::Model::Bibliography,
|
|
178
|
-
|
|
184
|
+
->(model) { Oth.transform_bibliography(model) }
|
|
179
185
|
)
|
|
180
186
|
|
|
181
187
|
Registry.register(
|
|
182
188
|
Coradoc::AsciiDoc::Model::BibliographyEntry,
|
|
183
|
-
|
|
189
|
+
->(model) { Oth.transform_bibliography_entry(model) }
|
|
184
190
|
)
|
|
185
191
|
|
|
186
|
-
# Passthrough types (no CoreModel equivalent)
|
|
187
192
|
[
|
|
188
193
|
Coradoc::AsciiDoc::Model::TextElement,
|
|
189
194
|
Coradoc::AsciiDoc::Model::Include,
|
|
@@ -195,57 +200,13 @@ module Coradoc
|
|
|
195
200
|
Registry.register(klass, ->(model) { model })
|
|
196
201
|
end
|
|
197
202
|
|
|
198
|
-
# Filtered types (layout-only, no CoreModel representation)
|
|
199
203
|
[
|
|
200
204
|
Coradoc::AsciiDoc::Model::LineBreak,
|
|
201
205
|
Coradoc::AsciiDoc::Model::Break::PageBreak
|
|
202
206
|
].each do |klass|
|
|
203
|
-
Registry.register(klass, ->(_model) {
|
|
207
|
+
Registry.register(klass, ->(_model) {})
|
|
204
208
|
end
|
|
205
209
|
end
|
|
206
|
-
|
|
207
|
-
METHOD_DISPATCH = {
|
|
208
|
-
transform_document: ->(model) { ToCoreModel.transform_document(model) },
|
|
209
|
-
transform_section: ->(model) { ToCoreModel.transform_section(model) },
|
|
210
|
-
transform_paragraph: ->(model) { ToCoreModel.transform_paragraph(model) },
|
|
211
|
-
transform_source_block: ->(model) { ToCoreModel.transform_source_block(model) },
|
|
212
|
-
transform_link: ->(model) { ToCoreModel.transform_link(model) },
|
|
213
|
-
transform_cross_reference: ->(model) { ToCoreModel.transform_cross_reference(model) },
|
|
214
|
-
transform_inline_footnote: ->(model) { ToCoreModel.transform_inline_footnote(model) },
|
|
215
|
-
transform_stem: ->(model) { ToCoreModel.transform_stem(model) },
|
|
216
|
-
transform_table: ->(model) { ToCoreModel.transform_table(model) },
|
|
217
|
-
transform_table_row: ->(model) { ToCoreModel.transform_table_row(model) },
|
|
218
|
-
transform_table_cell: ->(model) { ToCoreModel.transform_table_cell(model) },
|
|
219
|
-
transform_term: ->(model) { ToCoreModel.transform_term(model) },
|
|
220
|
-
transform_admonition: ->(model) { ToCoreModel.transform_admonition(model) },
|
|
221
|
-
transform_image: ->(model) { ToCoreModel.transform_image(model) },
|
|
222
|
-
transform_bibliography: ->(model) { ToCoreModel.transform_bibliography(model) },
|
|
223
|
-
transform_bibliography_entry: ->(model) { ToCoreModel.transform_bibliography_entry(model) }
|
|
224
|
-
}.freeze
|
|
225
|
-
|
|
226
|
-
def method_wrapper(method_name)
|
|
227
|
-
METHOD_DISPATCH.fetch(method_name)
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
def typed_block_wrapper(klass)
|
|
231
|
-
->(model) { ToCoreModel.transform_typed_block(model, klass) }
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
def block_model_wrapper
|
|
235
|
-
->(model) { ToCoreModel.transform_block(model, model.delimiter.to_s) }
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
def list_wrapper(marker_type)
|
|
239
|
-
->(model) { ToCoreModel.transform_list(model, marker_type) }
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
def inline_wrapper(format_type)
|
|
243
|
-
->(model) { ToCoreModel.transform_inline(model, format_type) }
|
|
244
|
-
end
|
|
245
|
-
|
|
246
|
-
def inline_text_wrapper(format_type)
|
|
247
|
-
->(model) { ToCoreModel.transform_inline_text(model, format_type) }
|
|
248
|
-
end
|
|
249
210
|
end
|
|
250
211
|
end
|
|
251
212
|
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Transform
|
|
6
|
+
class TransformerRegistry
|
|
7
|
+
class << self
|
|
8
|
+
def registry
|
|
9
|
+
@registry ||= {}
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def register(source_class, transformer, target_class: nil)
|
|
13
|
+
registry[source_class] = transformer
|
|
14
|
+
|
|
15
|
+
return unless target_class
|
|
16
|
+
|
|
17
|
+
reverse_registry[target_class] = transformer
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def register_with_priority(source_class, transformer, priority: 0)
|
|
21
|
+
@prioritized_registry ||= []
|
|
22
|
+
@prioritized_registry << {
|
|
23
|
+
class: source_class,
|
|
24
|
+
transformer: transformer,
|
|
25
|
+
priority: priority
|
|
26
|
+
}
|
|
27
|
+
@prioritized_registry.sort_by! { |e| -e[:priority] }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def lookup(model_class)
|
|
31
|
+
return registry[model_class] if registry.key?(model_class)
|
|
32
|
+
|
|
33
|
+
if @prioritized_registry
|
|
34
|
+
entry = @prioritized_registry.find { |e| model_class <= e[:class] }
|
|
35
|
+
return entry[:transformer] if entry
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
model_class.ancestors.each do |ancestor|
|
|
39
|
+
next if ancestor == model_class
|
|
40
|
+
next if [Object, BasicObject].include?(ancestor)
|
|
41
|
+
|
|
42
|
+
return registry[ancestor] if registry.key?(ancestor)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
nil
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def transform(model)
|
|
49
|
+
return model if model.nil?
|
|
50
|
+
return model.map { |item| transform(item) } if model.is_a?(Array)
|
|
51
|
+
|
|
52
|
+
transformer = lookup(model.class)
|
|
53
|
+
transformer ? transformer.call(model) : model
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def registered?(model_class)
|
|
57
|
+
!lookup(model_class).nil?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def clear
|
|
61
|
+
registry.clear
|
|
62
|
+
@prioritized_registry = nil
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def registered_classes
|
|
66
|
+
registry.keys
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
def reverse_registry
|
|
72
|
+
@reverse_registry ||= {}
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
Registry = TransformerRegistry
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -3,11 +3,15 @@
|
|
|
3
3
|
module Coradoc
|
|
4
4
|
module AsciiDoc
|
|
5
5
|
module Transform
|
|
6
|
-
autoload :
|
|
6
|
+
autoload :TransformerRegistry, "#{__dir__}/transform/transformer_registry"
|
|
7
|
+
autoload :Registry, "#{__dir__}/transform/transformer_registry"
|
|
7
8
|
autoload :ToCoreModel, "#{__dir__}/transform/to_core_model"
|
|
8
9
|
autoload :ToCoreModelRegistrations, "#{__dir__}/transform/to_core_model_registrations"
|
|
9
10
|
autoload :FromCoreModel, "#{__dir__}/transform/from_core_model"
|
|
10
11
|
autoload :FromCoreModelRegistrations, "#{__dir__}/transform/from_core_model_registrations"
|
|
12
|
+
autoload :TextExtractVisitor, "#{__dir__}/transform/text_extract_visitor"
|
|
13
|
+
autoload :InlineTransformVisitor, "#{__dir__}/transform/inline_transform_visitor"
|
|
14
|
+
autoload :ElementTransformers, "#{__dir__}/transform/element_transformers"
|
|
11
15
|
end
|
|
12
16
|
end
|
|
13
17
|
end
|
data/lib/coradoc/asciidoc.rb
CHANGED
|
@@ -27,6 +27,7 @@ end
|
|
|
27
27
|
# Autoload main components (lazy loading)
|
|
28
28
|
module Coradoc
|
|
29
29
|
module AsciiDoc
|
|
30
|
+
autoload :DelimiterMapping, "#{__dir__}/asciidoc/delimiter_mapping"
|
|
30
31
|
autoload :Model, "#{__dir__}/asciidoc/model"
|
|
31
32
|
autoload :Parser, "#{__dir__}/asciidoc/parser"
|
|
32
33
|
autoload :Transformer, "#{__dir__}/asciidoc/transformer"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: coradoc-adoc
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -111,6 +111,7 @@ files:
|
|
|
111
111
|
- lib/coradoc/asciidoc/builder/element_builder.rb
|
|
112
112
|
- lib/coradoc/asciidoc/builder/list_builder.rb
|
|
113
113
|
- lib/coradoc/asciidoc/builder/text_builder.rb
|
|
114
|
+
- lib/coradoc/asciidoc/delimiter_mapping.rb
|
|
114
115
|
- lib/coradoc/asciidoc/model.rb
|
|
115
116
|
- lib/coradoc/asciidoc/model/admonition.rb
|
|
116
117
|
- lib/coradoc/asciidoc/model/anchorable.rb
|
|
@@ -308,11 +309,20 @@ files:
|
|
|
308
309
|
- lib/coradoc/asciidoc/serializer/serializers/video.rb
|
|
309
310
|
- lib/coradoc/asciidoc/serializer/spacing_strategy.rb
|
|
310
311
|
- lib/coradoc/asciidoc/transform.rb
|
|
312
|
+
- lib/coradoc/asciidoc/transform/element_transformers.rb
|
|
313
|
+
- lib/coradoc/asciidoc/transform/element_transformers/block_transformer.rb
|
|
314
|
+
- lib/coradoc/asciidoc/transform/element_transformers/document_transformer.rb
|
|
315
|
+
- lib/coradoc/asciidoc/transform/element_transformers/inline_transformer.rb
|
|
316
|
+
- lib/coradoc/asciidoc/transform/element_transformers/list_transformer.rb
|
|
317
|
+
- lib/coradoc/asciidoc/transform/element_transformers/other_transformer.rb
|
|
318
|
+
- lib/coradoc/asciidoc/transform/element_transformers/table_transformer.rb
|
|
311
319
|
- lib/coradoc/asciidoc/transform/from_core_model.rb
|
|
312
320
|
- lib/coradoc/asciidoc/transform/from_core_model_registrations.rb
|
|
313
|
-
- lib/coradoc/asciidoc/transform/
|
|
321
|
+
- lib/coradoc/asciidoc/transform/inline_transform_visitor.rb
|
|
322
|
+
- lib/coradoc/asciidoc/transform/text_extract_visitor.rb
|
|
314
323
|
- lib/coradoc/asciidoc/transform/to_core_model.rb
|
|
315
324
|
- lib/coradoc/asciidoc/transform/to_core_model_registrations.rb
|
|
325
|
+
- lib/coradoc/asciidoc/transform/transformer_registry.rb
|
|
316
326
|
- lib/coradoc/asciidoc/transformer.rb
|
|
317
327
|
- lib/coradoc/asciidoc/transformer/block_rules.rb
|
|
318
328
|
- lib/coradoc/asciidoc/transformer/header_rules.rb
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Coradoc
|
|
4
|
-
module AsciiDoc
|
|
5
|
-
module Transform
|
|
6
|
-
# Registry for model transformers
|
|
7
|
-
#
|
|
8
|
-
# Provides a flexible, extensible way to register and lookup transformers
|
|
9
|
-
# that convert between different model types. This replaces case statements
|
|
10
|
-
# with a registry pattern, following the Open/Closed Principle.
|
|
11
|
-
#
|
|
12
|
-
# @example Register a transformer
|
|
13
|
-
# Coradoc::AsciiDoc::Transform::Registry.register(
|
|
14
|
-
# Coradoc::AsciiDoc::Model::Document,
|
|
15
|
-
# ->(model) { transform_document(model) }
|
|
16
|
-
# )
|
|
17
|
-
#
|
|
18
|
-
# @example Lookup and apply a transformer
|
|
19
|
-
# transformer = Coradoc::AsciiDoc::Transform::Registry.lookup(model.class)
|
|
20
|
-
# result = transformer.call(model) if transformer
|
|
21
|
-
#
|
|
22
|
-
class Registry
|
|
23
|
-
class << self
|
|
24
|
-
# Get the global registry instance
|
|
25
|
-
#
|
|
26
|
-
# @return [Hash] the registry hash
|
|
27
|
-
def registry
|
|
28
|
-
@registry ||= {}
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# Register a transformer for a source class
|
|
32
|
-
#
|
|
33
|
-
# @param source_class [Class] the source model class
|
|
34
|
-
# @param transformer [#call] a callable that transforms the model
|
|
35
|
-
# @param target_class [Class, nil] optional target class for bidirectional lookup
|
|
36
|
-
# @return [void]
|
|
37
|
-
def register(source_class, transformer, target_class: nil)
|
|
38
|
-
registry[source_class] = transformer
|
|
39
|
-
|
|
40
|
-
# Store reverse mapping if target class specified
|
|
41
|
-
return unless target_class
|
|
42
|
-
|
|
43
|
-
reverse_registry[target_class] = transformer
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# Register a transformer with a priority
|
|
47
|
-
#
|
|
48
|
-
# Higher priority transformers are checked first.
|
|
49
|
-
# This is useful for handling subclasses before parent classes.
|
|
50
|
-
#
|
|
51
|
-
# @param source_class [Class] the source model class
|
|
52
|
-
# @param transformer [#call] a callable that transforms the model
|
|
53
|
-
# @param priority [Integer] priority level (higher = checked first)
|
|
54
|
-
# @return [void]
|
|
55
|
-
def register_with_priority(source_class, transformer, priority: 0)
|
|
56
|
-
@prioritized_registry ||= []
|
|
57
|
-
@prioritized_registry << {
|
|
58
|
-
class: source_class,
|
|
59
|
-
transformer: transformer,
|
|
60
|
-
priority: priority
|
|
61
|
-
}
|
|
62
|
-
# Sort by priority descending
|
|
63
|
-
@prioritized_registry.sort_by! { |e| -e[:priority] }
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# Lookup a transformer for a model
|
|
67
|
-
#
|
|
68
|
-
# First checks exact class match, then checks prioritized registry,
|
|
69
|
-
# then walks up the inheritance chain.
|
|
70
|
-
#
|
|
71
|
-
# @param model_class [Class] the model class to find a transformer for
|
|
72
|
-
# @return [#call, nil] the transformer or nil if not found
|
|
73
|
-
def lookup(model_class)
|
|
74
|
-
# 1. Check exact match in main registry
|
|
75
|
-
return registry[model_class] if registry.key?(model_class)
|
|
76
|
-
|
|
77
|
-
# 2. Check prioritized registry
|
|
78
|
-
if @prioritized_registry
|
|
79
|
-
entry = @prioritized_registry.find { |e| model_class <= e[:class] }
|
|
80
|
-
return entry[:transformer] if entry
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# 3. Walk up inheritance chain
|
|
84
|
-
model_class.ancestors.each do |ancestor|
|
|
85
|
-
next if ancestor == model_class
|
|
86
|
-
next if [Object, BasicObject].include?(ancestor)
|
|
87
|
-
|
|
88
|
-
return registry[ancestor] if registry.key?(ancestor)
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
nil
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
# Transform a model using the registered transformer
|
|
95
|
-
#
|
|
96
|
-
# @param model [Object] the model to transform
|
|
97
|
-
# @return [Object] the transformed model
|
|
98
|
-
# @raise [ArgumentError] if no transformer is registered
|
|
99
|
-
def transform(model)
|
|
100
|
-
return model if model.nil?
|
|
101
|
-
|
|
102
|
-
# Handle arrays specially
|
|
103
|
-
return model.map { |item| transform(item) } if model.is_a?(Array)
|
|
104
|
-
|
|
105
|
-
transformer = lookup(model.class)
|
|
106
|
-
if transformer
|
|
107
|
-
transformer.call(model)
|
|
108
|
-
else
|
|
109
|
-
# Return unchanged if no transformer found
|
|
110
|
-
model
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
# Check if a transformer is registered for a class
|
|
115
|
-
#
|
|
116
|
-
# @param model_class [Class] the class to check
|
|
117
|
-
# @return [Boolean]
|
|
118
|
-
def registered?(model_class)
|
|
119
|
-
!lookup(model_class).nil?
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
# Clear all registrations (useful for testing)
|
|
123
|
-
#
|
|
124
|
-
# @return [void]
|
|
125
|
-
def clear
|
|
126
|
-
registry.clear
|
|
127
|
-
@prioritized_registry = nil
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
# Get all registered source classes
|
|
131
|
-
#
|
|
132
|
-
# @return [Array<Class>]
|
|
133
|
-
def registered_classes
|
|
134
|
-
registry.keys
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
private
|
|
138
|
-
|
|
139
|
-
def reverse_registry
|
|
140
|
-
@reverse_registry ||= {}
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
end
|