metanorma-oiml 0.1.0
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 +7 -0
- data/LICENSE +21 -0
- data/README.adoc +291 -0
- data/data/themes/oiml/assets/oiml-logo-full-dark.svg +1 -0
- data/data/themes/oiml/assets/oiml-logo-full-light.svg +1 -0
- data/data/themes/oiml/assets/oiml-logo-icon-dark.svg +1 -0
- data/data/themes/oiml/assets/oiml-logo-icon-light.svg +1 -0
- data/data/themes/oiml/assets/oiml-logo.svg +1 -0
- data/data/themes/oiml/theme.yaml +56 -0
- data/exe/oiml-sts +10 -0
- data/lib/metanorma/oiml/document/root.rb +29 -0
- data/lib/metanorma/oiml/document.rb +35 -0
- data/lib/metanorma/oiml/html/renderer.rb +14 -0
- data/lib/metanorma/oiml/html.rb +14 -0
- data/lib/metanorma/oiml/sts/cli.rb +89 -0
- data/lib/metanorma/oiml/sts/html_renderer/assets/metanorma-icon-dark.svg +1 -0
- data/lib/metanorma/oiml/sts/html_renderer/assets/metanorma-icon-light.svg +1 -0
- data/lib/metanorma/oiml/sts/html_renderer/assets/oiml-logo-dark.svg +1 -0
- data/lib/metanorma/oiml/sts/html_renderer/assets/oiml-logo.svg +1 -0
- data/lib/metanorma/oiml/sts/html_renderer/assets/oiml-smart-logo-dark.svg +1 -0
- data/lib/metanorma/oiml/sts/html_renderer/assets/oiml-smart-logo.svg +1 -0
- data/lib/metanorma/oiml/sts/html_renderer/assets/page.js +145 -0
- data/lib/metanorma/oiml/sts/html_renderer/assets/theme.css +509 -0
- data/lib/metanorma/oiml/sts/html_renderer/ruby.rb +1071 -0
- data/lib/metanorma/oiml/sts/html_renderer/templates/_element.html.liquid +1 -0
- data/lib/metanorma/oiml/sts/html_renderer/templates/_footer.html.liquid +21 -0
- data/lib/metanorma/oiml/sts/html_renderer/templates/_hero.html.liquid +9 -0
- data/lib/metanorma/oiml/sts/html_renderer/templates/_img.html.liquid +1 -0
- data/lib/metanorma/oiml/sts/html_renderer/templates/_link.html.liquid +1 -0
- data/lib/metanorma/oiml/sts/html_renderer/templates/_meta_header.html.liquid +1 -0
- data/lib/metanorma/oiml/sts/html_renderer/templates/document.html.liquid +43 -0
- data/lib/metanorma/oiml/sts/html_renderer.rb +19 -0
- data/lib/metanorma/oiml/sts/mathml_builder.rb +93 -0
- data/lib/metanorma/oiml/sts/parity_validator/normaliser.rb +95 -0
- data/lib/metanorma/oiml/sts/parity_validator/report.rb +137 -0
- data/lib/metanorma/oiml/sts/parity_validator.rb +23 -0
- data/lib/metanorma/oiml/sts/transformer/back_transformer.rb +55 -0
- data/lib/metanorma/oiml/sts/transformer/base.rb +71 -0
- data/lib/metanorma/oiml/sts/transformer/block_dispatcher.rb +145 -0
- data/lib/metanorma/oiml/sts/transformer/body_transformer.rb +23 -0
- data/lib/metanorma/oiml/sts/transformer/context.rb +27 -0
- data/lib/metanorma/oiml/sts/transformer/dl_transformer.rb +49 -0
- data/lib/metanorma/oiml/sts/transformer/document_transformer.rb +65 -0
- data/lib/metanorma/oiml/sts/transformer/figure_transformer.rb +49 -0
- data/lib/metanorma/oiml/sts/transformer/footnote_collector.rb +33 -0
- data/lib/metanorma/oiml/sts/transformer/formula_transformer.rb +45 -0
- data/lib/metanorma/oiml/sts/transformer/front_transformer.rb +84 -0
- data/lib/metanorma/oiml/sts/transformer/id_generator.rb +39 -0
- data/lib/metanorma/oiml/sts/transformer/inline_transformer.rb +14 -0
- data/lib/metanorma/oiml/sts/transformer/list_transformer.rb +82 -0
- data/lib/metanorma/oiml/sts/transformer/model_builder.rb +322 -0
- data/lib/metanorma/oiml/sts/transformer/note_transformer.rb +103 -0
- data/lib/metanorma/oiml/sts/transformer/paragraph_transformer.rb +574 -0
- data/lib/metanorma/oiml/sts/transformer/reference_transformer.rb +107 -0
- data/lib/metanorma/oiml/sts/transformer/rendered_text_extractor.rb +168 -0
- data/lib/metanorma/oiml/sts/transformer/section_transformer.rb +233 -0
- data/lib/metanorma/oiml/sts/transformer/source_document.rb +246 -0
- data/lib/metanorma/oiml/sts/transformer/standard.rb +37 -0
- data/lib/metanorma/oiml/sts/transformer/table_transformer.rb +290 -0
- data/lib/metanorma/oiml/sts/transformer/term_transformer.rb +236 -0
- data/lib/metanorma/oiml/sts/transformer.rb +47 -0
- data/lib/metanorma/oiml/sts/validation_report.rb +43 -0
- data/lib/metanorma/oiml/sts/validator.rb +126 -0
- data/lib/metanorma/oiml/sts/version.rb +9 -0
- data/lib/metanorma/oiml/sts.rb +84 -0
- data/lib/metanorma-oiml.rb +10 -0
- data/schematron/oiml-sts.sch +70 -0
- metadata +221 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Metanorma
|
|
4
|
+
module Oiml
|
|
5
|
+
module Sts
|
|
6
|
+
module Transformer
|
|
7
|
+
# Factory methods for building sts-ruby model instances.
|
|
8
|
+
# Zero Nokogiri — all models are constructed via lutaml-model.
|
|
9
|
+
module ModelBuilder
|
|
10
|
+
module_function
|
|
11
|
+
|
|
12
|
+
def standard(lang:, dtd_version: "1.2", front: nil, body: nil, back: nil)
|
|
13
|
+
::Sts::NisoSts::Standard.new(
|
|
14
|
+
lang: lang,
|
|
15
|
+
dtd_version: dtd_version
|
|
16
|
+
).tap do |std|
|
|
17
|
+
std.front = front if front
|
|
18
|
+
std.body = body if body
|
|
19
|
+
std.back = back if back
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def front(std_meta: nil)
|
|
24
|
+
::Sts::NisoSts::Front.new.tap { |f| f.std_meta = std_meta if std_meta }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def body(sec: [])
|
|
28
|
+
::Sts::NisoSts::Body.new(sec: Array(sec))
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def back(app_group: nil, ref_list: [])
|
|
32
|
+
attrs = {}
|
|
33
|
+
attrs[:ref_list] = Array(ref_list) if ref_list&.any?
|
|
34
|
+
::Sts::NisoSts::Back.new(attrs).tap do |b|
|
|
35
|
+
b.app_group = app_group if app_group
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def app_group(app: [])
|
|
40
|
+
::Sts::NisoSts::AppGroup.new(app: Array(app))
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def sec(id: nil, label: nil, title: nil, content: [], paragraph: [], sec: [],
|
|
44
|
+
list: [], table_wrap: [], fig: [], non_normative_note: [],
|
|
45
|
+
non_normative_example: [])
|
|
46
|
+
all_content = Array(content) + Array(paragraph)
|
|
47
|
+
distributed = distribute_sec_content(all_content)
|
|
48
|
+
|
|
49
|
+
attrs = {}
|
|
50
|
+
attrs[:id] = id if id
|
|
51
|
+
attrs[:title] = ::Sts::NisoSts::Title.new(content: [title]) if title
|
|
52
|
+
attrs[:paragraphs] = distributed[:paragraph] if distributed[:paragraph].any?
|
|
53
|
+
attrs[:sec] = Array(sec) if sec&.any?
|
|
54
|
+
attrs[:list] = (Array(list) + distributed[:list]) if (list&.any? || distributed[:list].any?)
|
|
55
|
+
attrs[:table_wrap] = (Array(table_wrap) + distributed[:table_wrap]) if (table_wrap&.any? || distributed[:table_wrap].any?)
|
|
56
|
+
attrs[:fig] = (Array(fig) + distributed[:fig]) if (fig&.any? || distributed[:fig].any?)
|
|
57
|
+
attrs[:non_normative_note] = (Array(non_normative_note) + distributed[:note]) if (non_normative_note&.any? || distributed[:note].any?)
|
|
58
|
+
attrs[:non_normative_example] = (Array(non_normative_example) + distributed[:example]) if (non_normative_example&.any? || distributed[:example].any?)
|
|
59
|
+
::Sts::NisoSts::Section.new(attrs)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def distribute_sec_content(content)
|
|
63
|
+
result = Hash.new { |h, k| h[k] = [] }
|
|
64
|
+
content.each do |item|
|
|
65
|
+
case item
|
|
66
|
+
when ::Sts::NisoSts::Paragraph then result[:paragraph] << item
|
|
67
|
+
when ::Sts::NisoSts::List then result[:list] << item
|
|
68
|
+
when ::Sts::NisoSts::Figure then result[:fig] << item
|
|
69
|
+
when ::Sts::TbxIsoTml::TableWrap then result[:table_wrap] << item
|
|
70
|
+
when ::Sts::NisoSts::NonNormativeNote then result[:note] << item
|
|
71
|
+
when ::Sts::NisoSts::NonNormativeExample then result[:example] << item
|
|
72
|
+
when ::Sts::NisoSts::DisplayFormula then result[:formula] << item
|
|
73
|
+
when ::Sts::NisoSts::DefList then result[:def_list] << item
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
result
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def paragraph(id: nil)
|
|
80
|
+
::Sts::NisoSts::Paragraph.new.tap do |p|
|
|
81
|
+
p.id = id if id
|
|
82
|
+
yield p if block_given?
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def list(list_type: "bullet", list_item: [])
|
|
87
|
+
::Sts::NisoSts::List.new(list_type: list_type, list_item: Array(list_item))
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def def_list(id: nil, def_items: [])
|
|
91
|
+
items = Array(def_items)
|
|
92
|
+
::Sts::NisoSts::DefList.new.tap do |dl|
|
|
93
|
+
dl.id = id if id
|
|
94
|
+
dl.def_item = items if items.any?
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def def_item(id: nil, term: nil, defn: nil)
|
|
99
|
+
::Sts::NisoSts::DefItem.new.tap do |di|
|
|
100
|
+
di.id = id if id
|
|
101
|
+
di.term = term if term
|
|
102
|
+
di.definition = defn if defn
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
def term(content: [])
|
|
106
|
+
::Sts::NisoSts::Term.new(text: Array(content))
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def def(paragraph: [])
|
|
110
|
+
::Sts::NisoSts::Def.new(paragraph: Array(paragraph))
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def list_item(paragraph: [])
|
|
114
|
+
::Sts::NisoSts::ListItem.new(p: Array(paragraph))
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def table_wrap(id: nil, caption: nil, table: nil)
|
|
118
|
+
::Sts::TbxIsoTml::TableWrap.new.tap do |tw|
|
|
119
|
+
tw.id = id if id
|
|
120
|
+
tw.caption = caption if caption
|
|
121
|
+
tw.table = [table] if table
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def table(thead: nil, tbody: nil)
|
|
126
|
+
::Sts::TbxIsoTml::Table.new.tap do |t|
|
|
127
|
+
t.thead = thead if thead
|
|
128
|
+
t.tbody = tbody if tbody
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def thead(tr: [])
|
|
133
|
+
::Sts::TbxIsoTml::Thead.new(tr: Array(tr))
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def tbody(tr: [])
|
|
137
|
+
::Sts::TbxIsoTml::Tbody.new(tr: Array(tr))
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def tr(th: [], td: [])
|
|
141
|
+
attrs = {}
|
|
142
|
+
attrs[:th] = Array(th) if th&.any?
|
|
143
|
+
attrs[:td] = Array(td) if td&.any?
|
|
144
|
+
::Sts::TbxIsoTml::Tr.new(attrs)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def th(content: nil)
|
|
148
|
+
::Sts::TbxIsoTml::Th.new.tap { |c| c.content = Array(content) if content }
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def td(content: nil)
|
|
152
|
+
::Sts::TbxIsoTml::Td.new.tap { |c| c.content = Array(content) if content }
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def fig(id: nil, label: nil, caption: nil, graphic: nil)
|
|
156
|
+
::Sts::NisoSts::Figure.new.tap do |f|
|
|
157
|
+
f.id = id if id
|
|
158
|
+
f.label = ::Sts::NisoSts::Label.new(content: [label]) if label
|
|
159
|
+
f.caption = caption if caption
|
|
160
|
+
f.graphic = [graphic] if graphic
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def graphic(href: nil)
|
|
165
|
+
::Sts::NisoSts::Graphic.new(href: xlink_href)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def caption(title: nil)
|
|
169
|
+
::Sts::NisoSts::Caption.new.tap do |c|
|
|
170
|
+
c.title = ::Sts::NisoSts::Title.new(content: [title]) if title
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def disp_formula(id: nil, label: nil, math: nil)
|
|
175
|
+
::Sts::NisoSts::DisplayFormula.new.tap do |f|
|
|
176
|
+
f.id = id if id
|
|
177
|
+
f.label = ::Sts::NisoSts::Label.new(content: [label]) if label
|
|
178
|
+
f.math = math if math
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def inline_formula(math: nil)
|
|
183
|
+
::Sts::NisoSts::InlineFormula.new(math: math)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def non_normative_note(paragraph: [], label: nil)
|
|
187
|
+
::Sts::NisoSts::NonNormativeNote.new.tap do |n|
|
|
188
|
+
n.p = Array(paragraph) if paragraph&.any?
|
|
189
|
+
n.label = ::Sts::NisoSts::Label.new(content: [label]) if label
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def non_normative_example(paragraph: [], label: nil)
|
|
194
|
+
::Sts::NisoSts::NonNormativeExample.new.tap do |e|
|
|
195
|
+
e.p = Array(paragraph) if paragraph&.any?
|
|
196
|
+
e.label = ::Sts::NisoSts::Label.new(content: [label]) if label
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def ref_list(content_type: nil, title: nil, ref: [])
|
|
201
|
+
::Sts::NisoSts::ReferenceList.new.tap do |rl|
|
|
202
|
+
rl.content_type = content_type if content_type
|
|
203
|
+
rl.title = ::Sts::NisoSts::Title.new(content: [title]) if title
|
|
204
|
+
rl.ref = Array(ref) if ref&.any?
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def ref(label: nil, mixed_citation: nil, std: nil)
|
|
209
|
+
::Sts::NisoSts::Reference.new.tap do |r|
|
|
210
|
+
r.label = ::Sts::NisoSts::Label.new(content: [label]) if label
|
|
211
|
+
r.mixed_citation = ::Sts::NisoSts::MixedCitation.new(content: [mixed_citation]) if mixed_citation
|
|
212
|
+
r.std = std if std
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# Builds the OIML front-matter metadata block. OIML is not
|
|
217
|
+
# ISO — the NISO-STS-correct container for an OIML publication
|
|
218
|
+
# is <std-meta> (the generic catch-all for non-ISO / non-
|
|
219
|
+
# national / non-regional SDOs). MetadataStd ships the same
|
|
220
|
+
# attribute set as MetadataIso (title_wrap, std_ident,
|
|
221
|
+
# permissions, pub_date, custom_meta_group), but several
|
|
222
|
+
# are collections where MetadataIso's were singular.
|
|
223
|
+
def std_meta(doc_identifier: nil, title: nil, pub_date: nil,
|
|
224
|
+
permissions: nil, custom_meta_group: nil)
|
|
225
|
+
::Sts::NisoSts::MetadataStd.new.tap do |m|
|
|
226
|
+
m.title_wrap = [::Sts::NisoSts::TitleWrap.new(main: title)] if title
|
|
227
|
+
m.std_ident = std_ident_for(doc_identifier) if doc_identifier
|
|
228
|
+
m.permissions = [permissions] if permissions
|
|
229
|
+
m.pub_date = pub_date.to_s if pub_date
|
|
230
|
+
m.custom_meta_group = [custom_meta_group] if custom_meta_group
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# <std-ident> per NISO STS (Z39.102-2022): the OIML identifier
|
|
235
|
+
# decomposed into originator + doc-type + doc-number
|
|
236
|
+
# (+ part-number). "OIML B 6-2:2024" → OIML / b / 6 / 2. The
|
|
237
|
+
# publication year is NOT repeated here — pub-date carries it.
|
|
238
|
+
# Identifiers that don't match the OIML pattern fall back to a
|
|
239
|
+
# plain originator string rather than being dropped.
|
|
240
|
+
OIML_ID_PATTERN = /\A(OIML)\s+([A-Z]+)\s+(\d+)(?:-(\d+))?(?::\d{4})?\z/.freeze
|
|
241
|
+
|
|
242
|
+
def std_ident_for(doc_identifier)
|
|
243
|
+
match = OIML_ID_PATTERN.match(doc_identifier.to_s.strip)
|
|
244
|
+
return plain_std_ident(doc_identifier) unless match
|
|
245
|
+
|
|
246
|
+
attrs = {
|
|
247
|
+
originator: match[1],
|
|
248
|
+
doc_type: match[2].downcase,
|
|
249
|
+
doc_number: match[3],
|
|
250
|
+
}
|
|
251
|
+
attrs[:part_number] = match[4] if match[4]
|
|
252
|
+
::Sts::NisoSts::StandardIdentification.new(attrs)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def plain_std_ident(doc_identifier)
|
|
256
|
+
::Sts::NisoSts::StandardIdentification.new(originator: doc_identifier)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def permissions(holder: nil, year: nil)
|
|
260
|
+
attrs = {}
|
|
261
|
+
attrs[:copyright_statement] = "© #{year} #{holder}" if year && holder
|
|
262
|
+
attrs[:copyright_year] = year.to_s if year
|
|
263
|
+
attrs[:copyright_holder] = holder.to_s if holder
|
|
264
|
+
::Sts::NisoSts::Permissions.new(attrs)
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def custom_meta_group(name: nil, value: nil)
|
|
268
|
+
::Sts::NisoSts::CustomMetaGroup.new(
|
|
269
|
+
custom_meta: [::Sts::NisoSts::CustomMeta.new(
|
|
270
|
+
meta_name: name, meta_value: value
|
|
271
|
+
)]
|
|
272
|
+
)
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def bold(content: [])
|
|
276
|
+
::Sts::TbxIsoTml::Bold.new(value: Array(content))
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def italic(content: [])
|
|
280
|
+
::Sts::TbxIsoTml::Italic.new(value: Array(content))
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def monospace(content: [])
|
|
284
|
+
::Sts::NisoSts::Monospace.new(content: Array(content))
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def sub(content: [])
|
|
288
|
+
::Sts::NisoSts::Sub.new(content: Array(content))
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def sup(content: [])
|
|
292
|
+
::Sts::NisoSts::Sup.new(content: Array(content))
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def ext_link(xlink_href: nil, content: [])
|
|
296
|
+
::Sts::NisoSts::ExtLink.new(
|
|
297
|
+
ext_link_type: "uri",
|
|
298
|
+
xlink_href: xlink_href,
|
|
299
|
+
content: Array(content)
|
|
300
|
+
)
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def xref(rid: nil, ref_type: "other", value: nil)
|
|
304
|
+
::Sts::TbxIsoTml::Xref.new(rid: rid, ref_type: ref_type, value: value)
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def fn(id: nil, value: nil)
|
|
308
|
+
::Sts::TbxIsoTml::Fn.new(id: id, value: value)
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def title(content: [])
|
|
312
|
+
::Sts::NisoSts::Title.new(content: Array(content))
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
def label(content: [])
|
|
316
|
+
::Sts::NisoSts::Label.new(content: Array(content))
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cgi"
|
|
4
|
+
|
|
5
|
+
module Metanorma
|
|
6
|
+
module Oiml
|
|
7
|
+
module Sts
|
|
8
|
+
module Transformer
|
|
9
|
+
# Converts MN <note> / <example> blocks (outside term entries)
|
|
10
|
+
# to STS <non-normative-note> / <non-normative-example>.
|
|
11
|
+
# Body notes carry NO label — the renderer prepends the kind
|
|
12
|
+
# label ("NOTE" / "EXAMPLE") outside the first paragraph, the
|
|
13
|
+
# way Metanorma marks up body notes ("<span class='note-label'>
|
|
14
|
+
# NOTE</span> <p>…"). Term entries use "Note N to entry:"
|
|
15
|
+
# via TermTransformer.
|
|
16
|
+
class NoteTransformer < Base
|
|
17
|
+
def transform(source_note)
|
|
18
|
+
paragraphs = extract_paragraphs(source_note)
|
|
19
|
+
return nil if paragraphs.empty?
|
|
20
|
+
|
|
21
|
+
if example?(source_note)
|
|
22
|
+
label = example_label(source_note)
|
|
23
|
+
ModelBuilder.non_normative_example(paragraph: paragraphs, label: label)
|
|
24
|
+
else
|
|
25
|
+
ModelBuilder.non_normative_note(paragraph: paragraphs)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# MN renders body examples as "<span class='example-label'>
|
|
30
|
+
# EXAMPLE N</span>" — "Example" plus the autonum, even when
|
|
31
|
+
# the source carries no explicit name. The label ends up
|
|
32
|
+
# inside the first paragraph so parity text comparison sees
|
|
33
|
+
# it on both sides.
|
|
34
|
+
def example_label(source_example)
|
|
35
|
+
return nil unless source_example.is_a?(example_block_class)
|
|
36
|
+
|
|
37
|
+
number = source_example.autonum if source_example.class.method_defined?(:autonum)
|
|
38
|
+
number && !number.to_s.empty? ? "Example #{number}" : nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# SourcecodeBlock stores its text in body.content (the bare
|
|
42
|
+
# `content` attribute is nil for parsed documents). The body's
|
|
43
|
+
# content is markup-encoded by the model's roundtrip contract;
|
|
44
|
+
# decoded_content (metanorma-document >= 0.3.1) unwraps it —
|
|
45
|
+
# with a local decode as the fallback for older releases.
|
|
46
|
+
def transform_preformat(source_code)
|
|
47
|
+
text = preformat_text(source_code)
|
|
48
|
+
return nil if text.nil? || text.empty?
|
|
49
|
+
|
|
50
|
+
::Sts::NisoSts::Preformat.new(content: [text])
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def example?(source_note)
|
|
56
|
+
source_note.is_a?(example_block_class)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def extract_paragraphs(source_note)
|
|
60
|
+
case source_note
|
|
61
|
+
when example_block_class
|
|
62
|
+
Array(source_note.paragraphs).map { |p| paragraph_transformer.transform(p) }
|
|
63
|
+
when note_block_class
|
|
64
|
+
Array(source_note.content)
|
|
65
|
+
.select { |p| p.is_a?(paragraph_block_class) }
|
|
66
|
+
.map { |p| paragraph_transformer.transform(p) }
|
|
67
|
+
else
|
|
68
|
+
[]
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def preformat_text(source_code)
|
|
73
|
+
return unless source_code.is_a?(sourcecode_block_class)
|
|
74
|
+
|
|
75
|
+
body = source_code.body
|
|
76
|
+
return source_code.text unless body
|
|
77
|
+
|
|
78
|
+
content = body.content if body.is_a?(Lutaml::Model::Serializable)
|
|
79
|
+
return CGI.unescapeHTML(Array(content).join) if content && !content.to_s.empty?
|
|
80
|
+
|
|
81
|
+
source_code.text
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def note_block_class
|
|
85
|
+
Metanorma::Document::Components::Blocks::NoteBlock
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def example_block_class
|
|
89
|
+
Metanorma::Document::Components::AncillaryBlocks::ExampleBlock
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def sourcecode_block_class
|
|
93
|
+
Metanorma::Document::Components::AncillaryBlocks::SourcecodeBlock
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def paragraph_block_class
|
|
97
|
+
Metanorma::Document::Components::Paragraphs::ParagraphBlock
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|