mn-requirements 0.4.3 → 0.5.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a12dad7f5d6cb715ade06167544dc2966581c8b9692b4d67de71664ddf401f23
4
- data.tar.gz: 04cff2ddfd3116155014720376fbcf98c2d88bece77a12c748cd0726814d4c2e
3
+ metadata.gz: 5d557ae4ed71baabb926e12c579a4c1e07f14f0573caacd8cea6b3f2be33057b
4
+ data.tar.gz: 0f2f09d925e1fbe06fbe782545d21823a34f687345b0993aa0e27c2c27436e1e
5
5
  SHA512:
6
- metadata.gz: dfc9ce13b9304cd254e0d2f941f04d48607041922aa0333417f57d61867495c4c486c2f2be459cbb46de52509a46e0f5b8f5460c6319310ee166864e2aac7797
7
- data.tar.gz: f7a0989cc2212bc9186acf262a75bac6712bb9e7bdc7ae0d5c417446bce63f40dc7c8af9568b144a59a95914a0ff82f116af49586c75887697b079f7afa386a5
6
+ metadata.gz: ee8c23fab75c8bfbfb679942af6053898eb1aa4f0c365fdc7244e6eb39541b05e59b1afa668628d9f6d4a4cb51e61e0d0059446640265717695dbbf61635c29d
7
+ data.tar.gz: 4e84dae849f84ab1392e3f25e571e3c0ff8a6328c885b468e834eec9e287e158a72bc4e59c98effe38eeff86e5185f64b04886436c53fe1e81760cabb52ee8a1
@@ -5,12 +5,42 @@ module Metanorma
5
5
  @i18n.l10n(text)
6
6
  end
7
7
 
8
+ # TODO: move to metanorma-utils
9
+ def semx_fmt_dup(elem)
10
+ elem["id"] ||= "_#{UUIDTools::UUID.random_create}"
11
+ new = Nokogiri::XML(<<~XML).root
12
+ <semx xmlns='#{elem.namespace.href}' element='#{elem.name}' source='#{elem['original-id'] || elem['id']}'>#{to_xml(elem.children)}</semx>
13
+ XML
14
+ strip_duplicate_ids(nil, elem, new)
15
+ new
16
+ end
17
+
18
+ def gather_all_ids(elem)
19
+ elem.xpath(".//*[@id]").each_with_object([]) do |i, m|
20
+ m << i["id"]
21
+ end
22
+ end
23
+
24
+ # remove ids duplicated between sem_title and pres_title
25
+ # index terms are assumed transferred to pres_title from sem_title
26
+ def strip_duplicate_ids(_node, sem_title, pres_title)
27
+ sem_title && pres_title or return
28
+ ids = gather_all_ids(pres_title)
29
+ sem_title.xpath(".//*[@id]").each do |x|
30
+ ids.include?(x["id"]) or next
31
+ x["original-id"] = x["id"]
32
+ x.delete("id")
33
+ end
34
+ sem_title.xpath(ns(".//index")).each(&:remove)
35
+ end
36
+
8
37
  def recommendation_label(elem, type, xrefs)
9
38
  label, title = recommendation_labels(elem)
10
39
  type = "<span class='fmt-element-name'>#{type}</span>"
11
40
  num = xrefs.anchor(elem["id"], :label, false)
12
41
  num &&= "<semx element='autonum' source='#{elem['id']}'>#{num}</semx>"
13
- ret = "#{type} #{num}".strip
42
+ ret = num
43
+ /<span class='fmt-element-name'>/.match?(ret) or ret = "#{type} #{num}".strip
14
44
  label || title and
15
45
  ret += recommendation_label_add(elem, label, title)
16
46
  ret
@@ -36,13 +66,22 @@ module Metanorma
36
66
  end
37
67
 
38
68
  def requirement_render1(node)
39
- out = recommendation_base(node, node.name)
69
+ out = recommendation_base(node, "fmt-provision")
40
70
  ins = recommendation_header(node, out)
41
71
  ins = recommendation_attributes(node, ins)
42
72
  node.elements.reject do |n|
43
73
  reqt_metadata_node?(n)
44
74
  end.each { |n| ins = requirement_component_parse(n, ins) }
45
- out
75
+ requirement_presentation(node, out)
76
+ end
77
+
78
+ def requirement_presentation(node, out)
79
+ out.default_namespace = node.namespace.href
80
+ node.xpath(ns("./*//fmt-name | ./*//fmt-xref-label")).each(&:remove)
81
+ node.xpath(ns(".//fmt-sourcecode")).each(&:remove)
82
+ ret = node.dup
83
+ ret << out
84
+ ret
46
85
  end
47
86
 
48
87
  def recommendation_header(_node, out)
@@ -54,15 +93,13 @@ module Metanorma
54
93
  node.attributes.each do |k, v|
55
94
  out[k] = v
56
95
  end
57
- n = node.at(ns("./fmt-name")) and out << n
58
- n = node.at(ns("./fmt-xref-label")) and out << n
59
96
  out
60
97
  end
61
98
 
62
99
  def recommendation_labels(node)
63
100
  [node.at(ns("./identifier")), node.at(ns("./title"))]
64
101
  .map do |n|
65
- to_xml(n&.children)
102
+ to_xml(n&.children)
66
103
  end
67
104
  end
68
105
 
@@ -70,7 +107,8 @@ module Metanorma
70
107
  oblig = node["obligation"] and
71
108
  out << l10n("#{@labels['default']['obligation']}: #{oblig}")
72
109
  node.xpath(ns("./subject")).each do |subj|
73
- out << l10n("#{@labels['default']['subject']}: #{subj.text}")
110
+ #out << l10n("#{@labels['default']['subject']}: #{subj.text}")
111
+ out << l10n("#{@labels['default']['subject']}: #{to_xml(semx_fmt_dup(subj))}")
74
112
  end
75
113
  node.xpath(ns("./inherit")).each do |i|
76
114
  out << recommendation_attr_parse(i, @labels["default"]["inherits"])
@@ -82,14 +120,16 @@ module Metanorma
82
120
  end
83
121
 
84
122
  def recommendation_attr_parse(node, label)
85
- l10n("#{label}: #{to_xml(node.children)}")
123
+ #l10n("#{label}: #{to_xml(node.children)}")
124
+ l10n("#{label}: #{to_xml(semx_fmt_dup(node))}")
86
125
  end
87
126
 
88
127
  def recommendation_attr_keyvalue(node, key, value)
89
128
  tag = node.at(ns("./#{key}")) or return nil
90
129
  value = node.at(ns("./#{value}")) or return nil
91
- l10n("#{Metanorma::Utils.strict_capitalize_first tag.text}: " \
92
- "#{to_xml(value.children)}")
130
+ lbl = semx_fmt_dup(tag)
131
+ lbl.children = Metanorma::Utils.strict_capitalize_first(lbl.text)
132
+ l10n("#{to_xml(lbl)}: #{to_xml(semx_fmt_dup(value))}")
93
133
  end
94
134
 
95
135
  def recommendation_attributes(node, out)
@@ -108,29 +148,37 @@ module Metanorma
108
148
 
109
149
  def requirement_component_parse(node, out)
110
150
  node["exclude"] == "true" and return out
111
- ret = node.dup
112
- if reqt_subpart?(node.name)
113
- ret["type"] = reqt_component_type(node)
114
- ret.name = "div"
115
- end
116
- descr_classif_render(ret)
117
- out << ret
151
+ reqt_subpart?(node.name) and type = reqt_component_type(node)
152
+ ret = semx_fmt_dup(node)
153
+ descr_classif_render(node, ret)
154
+ t = copy_style_attributes(node)
155
+ type and t += " type='#{type}'"
156
+ out << "<div#{t}>#{to_xml(ret)}</div>"
118
157
  out
119
158
  end
120
159
 
121
- def descr_classif_render(reqt)
122
- reqt.at(ns("./classification")) or return
160
+ def copy_style_attributes(node)
161
+ t = ""
162
+ %w(style keep-with-next keep-lines-together).each do |x|
163
+ node[x] and t += " #{x}='#{node[x]}'"
164
+ end
165
+ t
166
+ end
167
+
168
+ def descr_classif_render(node, reqt)
169
+ c = reqt.xpath(ns("./classification"))
170
+ c.empty? and return
123
171
  ins = reqt.at(ns("./classification")).before("<dl/>").previous
124
- descr_classif_extract(reqt, ins)
172
+ descr_classif_extract(node, ins)
173
+ c.each(&:remove)
125
174
  end
126
175
 
127
176
  def descr_classif_extract(desc, ins)
128
177
  dlist = desc.xpath(ns("./classification"))
129
178
  dlist.each do |x|
130
- x.at(ns("./tag")).name = "dt"
131
- x.at(ns("./value")).name = "dd"
132
- ins << x.children
133
- x.remove
179
+ dt = semx_fmt_dup(x.at(ns("./tag")))
180
+ dd = semx_fmt_dup(x.at(ns("./value")))
181
+ ins << "<dt>#{to_xml dt}</dt><dd>#{to_xml dd}</dd>"
134
182
  end
135
183
  end
136
184
  end
@@ -9,16 +9,25 @@ module Metanorma
9
9
  init_lookups(node.document)
10
10
  ret = requirement_guidance_parse(node, super)
11
11
  out = requirement_table_cleanup(node, ret)
12
- out["class"] = "modspec" # deferred; node["class"] is labelling class
12
+ truncate_id_base_fmtxreflabel(out)
13
13
  out
14
14
  end
15
15
 
16
+ def requirement_presentation(node, out)
17
+ ret = node.document.create_element("fmt-provision")
18
+ ret << out
19
+ out = ret
20
+ super
21
+ end
22
+
16
23
  def recommendation_base(node, _klass)
17
24
  out = node.document.create_element("table")
18
25
  out.default_namespace = node.namespace.href
19
26
  %w(id keep-with-next keep-lines-together unnumbered).each do |x|
20
27
  out[x] = node[x] if node[x]
21
28
  end
29
+ node["original-id"] = node["id"]
30
+ node.delete("id")
22
31
  out["type"] = recommend_class(node)
23
32
  recommendation_component_labels(node)
24
33
  out
@@ -34,7 +43,7 @@ module Metanorma
34
43
  end
35
44
 
36
45
  def recommendation_header(reqt, out)
37
- n = reqt.at(ns("./fmt-name"))
46
+ n = to_xml(reqt.at(ns("./fmt-name")))&.strip
38
47
  x = if reqt.ancestors("requirement, recommendation, permission").empty?
39
48
  <<~THEAD
40
49
  <thead><tr><th scope='colgroup' colspan='2'><p class='#{recommend_name_class(reqt)}'>#{n}</p></th></tr></thead>
@@ -47,20 +56,6 @@ module Metanorma
47
56
  out
48
57
  end
49
58
 
50
- =begin
51
- def recommendation_name(node, _out)
52
- ret = ""
53
- name = node.at(ns("./fmt-name")) and ret += name.children.to_xml
54
- title = node.at(ns("./fmt-title"))
55
- return ret unless title &&
56
- node.ancestors("requirement, recommendation, permission").empty?
57
-
58
- ret += ": " unless !name || name.text.empty?
59
- ret += title.children.to_xml
60
- l10n(ret)
61
- end
62
- =end
63
-
64
59
  def recommendation_label_add(elem, _label, title)
65
60
  title or return ""
66
61
  r = recommendation_label_caption_delim
@@ -92,7 +87,7 @@ module Metanorma
92
87
  label = node.at(ns("./identifier")) or return
93
88
  ret = <<~OUTPUT
94
89
  <tr><th>#{@labels['modspec']['identifier']}</th>
95
- <td><tt><modspec-ident>#{to_xml(label.children)}</modspec-ident></tt></td>
90
+ <td><tt><modspec-ident>#{to_xml(semx_fmt_dup(label))}</modspec-ident></tt></td>
96
91
  OUTPUT
97
92
  out.add_child(ret)
98
93
  end
@@ -100,8 +95,8 @@ module Metanorma
100
95
  def recommendation_attributes1(node)
101
96
  ret = recommendation_attributes1_head(node, [])
102
97
  node.xpath(ns("./classification")).each do |c|
103
- line = recommendation_attr_keyvalue(c, "tag",
104
- "value") and ret << line
98
+ line = recommendation_attr_keyvalue(c, "tag", "value") and
99
+ ret << line
105
100
  end
106
101
  ret
107
102
  end
@@ -109,8 +104,8 @@ module Metanorma
109
104
  def recommendation_attributes1_head(node, head)
110
105
  oblig = node["obligation"] and
111
106
  head << [@labels["default"]["obligation"], oblig]
112
- subj = node.at(ns("./subject"))&.children and
113
- head << [rec_subj(node), subj]
107
+ subj = node.at(ns("./subject")) and
108
+ head << [rec_subj(node), semx_fmt_dup(subj)]
114
109
  head = recommendation_attributes1_target(node, head)
115
110
  head += recommendation_backlinks(node)
116
111
  recommendation_attributes1_dependencies(node, head)
@@ -119,7 +114,7 @@ module Metanorma
119
114
  def recommendation_attributes1_target(node, head)
120
115
  node.xpath(ns("./classification[tag][value]")).each do |c|
121
116
  c.at(ns("./tag")).text.casecmp("target").zero? or next
122
- xref = recommendation_id(c.at(ns("./value")).text) and
117
+ xref = recommendation_id(semx_fmt_dup(c.at(ns("./value")))) and
123
118
  head << [rec_target(node), xref]
124
119
  end
125
120
  head
@@ -140,7 +135,7 @@ module Metanorma
140
135
  def recommendation_attributes1_inherit(node, head)
141
136
  node.xpath(ns("./inherit")).each do |i|
142
137
  head << [@labels["modspec"]["dependency"],
143
- recommendation_id(to_xml(i.children))]
138
+ recommendation_id(semx_fmt_dup(i))]
144
139
  end
145
140
  head
146
141
  end
@@ -149,7 +144,7 @@ module Metanorma
149
144
  %w(indirect-dependency implements).each do |x|
150
145
  node.xpath(ns("./classification[tag][value]")).each do |c|
151
146
  c.at(ns("./tag")).text.casecmp(x).zero? or next
152
- xref = recommendation_id(to_xml(c.at(ns("./value")).children)) and
147
+ xref = recommendation_id(semx_fmt_dup(c.at(ns("./value")))) and
153
148
  head << [@labels["modspec"][x.delete("-")], xref]
154
149
  end
155
150
  end
@@ -157,94 +152,167 @@ module Metanorma
157
152
  end
158
153
 
159
154
  def id_attr(node)
160
- node["id"] ? " id='#{node['id']}'" : ""
155
+ id = node["id"] || node["original-id"]
156
+ id ? " id='#{id}'" : ""
161
157
  end
162
158
 
163
- def recommendation_steps(node)
159
+ # KILL
160
+ def recommendation_stepsX(node)
164
161
  node.elements.each { |e| recommendation_steps(e) }
165
- return node unless node.at(ns("./component[@class = 'step']"))
166
-
162
+ node.at(ns("./component[@class = 'step']")) or return node
167
163
  d = node.at(ns("./component[@class = 'step']"))
168
164
  d = d.replace("<ol class='steps'><li#{id_attr(d)}>" \
169
- "#{to_xml(d.children)}</li></ol>").first
165
+ "#{to_xml(d.children)}</li></ol>").first
170
166
  node.xpath(ns("./component[@class = 'step']")).each do |f|
171
167
  f = f.replace("<li#{id_attr(f)}>#{to_xml(f.children)}</li>").first
172
168
  d << f
173
169
  end
174
- node
170
+ node
175
171
  end
176
172
 
177
- def recommendation_attributes1_component(node, out)
178
- return out if node["class"] == "guidance"
179
173
 
180
- node = recommendation_steps(node)
181
- out << "<tr#{id_attr(node)}><th>#{node['label']}</th>" \
182
- "<td>#{node.children}</td></tr>"
183
- out
184
- end
174
+ def recommendation_steps(node, ret)
175
+ ret.elements.each_with_index do |e, i|
176
+ e1 = nil
177
+ #require "debug"; e.name == "component" && e["class"] == "step" and binding.b
178
+ e.name == "component" && e["class"] == "step" and
179
+ e1 = e.replace(semx_fmt_dup(node.elements[i]))
180
+ #require "debug"; e.name == "component" && e["class"] == "step" and binding.b
181
+ recommendation_steps(node.elements[i], e1 || e)
182
+ end
183
+ node.name == "component" && node["class"] == "step" and ret["inlist"] = "true"
184
+ #require "debug"; node.name == "component" && node["class"] == "step" and binding.b
185
+ d = ret.at(ns("./semx[@inlist]")) or return ret
186
+ d.delete("inlist")
187
+ d = d.replace("<ol class='steps'><li#{id_attr(d)}>" \
188
+ "#{to_xml(d)}</li></ol>").first
189
+ ret.xpath(ns("./semx[@inlist]")).each do |f|
190
+ f.delete("inlist")
191
+ f = f.replace("<li#{id_attr(f)}>#{to_xml(f)}</li>").first
192
+ d << f
193
+ end
194
+ ret
195
+ end
185
196
 
186
- def recommendation_attr_keyvalue(node, key, value)
187
- tag = node.at(ns("./#{key}")) or return nil
188
- value = node.at(ns("./#{value}")) or return nil
189
- !%w(target indirect-dependency identifier-base
197
+ def recommendation_attributes1_component(node, ret, out)
198
+ node["class"] == "guidance" and return out
199
+ ret = recommendation_steps(node, ret)
200
+ out << "<tr#{id_attr(node)}><th>#{node['label']}</th>" \
201
+ "<td>#{to_xml(ret)}</td></tr>"
202
+ node.delete("label") # inserted in recommendation_component_labels
203
+ out
204
+ end
205
+
206
+ def recommendation_attr_keyvalue(node, key, value)
207
+ tag = node.at(ns("./#{key}")) or return nil
208
+ value = node.at(ns("./#{value}")) or return nil
209
+ !%w(target indirect-dependency identifier-base
190
210
  implements).include?(tag.text.downcase) or
191
- return nil
192
- [Metanorma::Utils.strict_capitalize_first(tag.text), value.children]
193
- end
211
+ return nil
212
+ lbl = semx_fmt_dup(tag)
213
+ lbl.children = Metanorma::Utils.strict_capitalize_first(lbl.text)
214
+ [to_xml(lbl), semx_fmt_dup(value)]
215
+ end
194
216
 
195
- def reqt_component_type(node)
196
- klass = node.name
197
- klass == "component" and klass = node["class"]
198
- "requirement-#{klass}"
199
- end
217
+ def reqt_component_type(node)
218
+ klass = node.name
219
+ klass == "component" and klass = node["class"]
220
+ "requirement-#{klass}"
221
+ end
200
222
 
201
- def preserve_in_nested_table?(node)
202
- %w(recommendation requirement permission
223
+ # KILL
224
+ def preserve_in_nested_table?(node)
225
+ %w(recommendation requirement permission
203
226
  table ol dl ul).include?(node.name)
204
- end
227
+ end
205
228
 
206
- def requirement_component_parse(node, out)
207
- node["exclude"] == "true" and return out
208
- descr_classif_render(node)
209
- node.elements.size == 1 && node.first_element_child.name == "dl" and
210
- return reqt_dl(node.first_element_child, out)
211
- node.name == "component" and
212
- return recommendation_attributes1_component(node, out)
213
- node.name == "description" and
214
- return requirement_description_parse(node, out)
215
- out.add_child("<tr#{id_attr(node)}><td colspan='2'></td></tr>").first
216
- .at(ns(".//td")) <<
217
- (preserve_in_nested_table?(node) ? node : node.children)
218
- out
219
- end
229
+ # KILL
230
+ def requirement_component_parse(node, out)
231
+ node["exclude"] == "true" and return out
232
+ ret = semx_fmt_dup(node)
233
+ descr_classif_render(node, ret)
234
+ ret.elements.size == 1 && ret.first_element_child.name == "dl" and
235
+ return reqt_dl(ret.first_element_child, out)
236
+ node.name == "component" and
237
+ return recommendation_attributes1_component(node, ret, out)
238
+ node.name == "description" and
239
+ return requirement_description_parse(node, ret, out)
240
+ id = node["id"] || node["original-id"]
241
+ !preserve_in_nested_table?(node) && id and attr = " id='#{id}'"
242
+ out.add_child("<tr#{id_attr(node)}><td colspan='2'#{attr}></td></tr>").first
243
+ .at(ns(".//td")) <<
244
+ (preserve_in_nested_table?(node) ? node.dup : ret)
245
+ out
246
+ end
220
247
 
221
- def requirement_description_parse(node, out)
222
- lbl = "description"
223
- recommend_class(node.parent) == "recommend" and
224
- lbl = "statement"
225
- out << "<tr><th>#{@labels['modspec'][lbl]}</th>" \
226
- "<td>#{to_xml(node.children)}</td></tr>"
227
- out
228
- end
248
+ def preserve_in_nested_table?(node)
249
+ #%w(recommendation requirement permission table ol dl ul hr br p).include?(node.name)
250
+ !%w(subject inherit identifier measurement-target specification verification import description component).include?(node.name)
251
+ end
229
252
 
230
- def requirement_guidance_parse(node, out)
231
- ins = out.at(ns("./tbody"))
232
- node.xpath(ns("./component[@class = 'guidance']")).each do |f|
233
- ins << "<tr#{id_attr(f)}><th>#{@labels['modspec']['guidance']}</th>" \
234
- "<td>#{f.children}</td></tr>"
253
+ def requirement_component_parse(node, out)
254
+ node["exclude"] == "true" and return out
255
+ ret = semx_fmt_dup(node)
256
+ descr_classif_render(node, ret)
257
+ id = node["id"] || node["original-id"]
258
+ id and attr = " id='#{id}'"
259
+ preserve = preserve_in_nested_table?(node)
260
+ if id == node["id"]
261
+ if node["original-id"]
262
+ attr = " id='#{node["original-id"]}'"
263
+ else
264
+ node["original-id"] = node["id"]
265
+ end
266
+ node.delete("id")
267
+ end
268
+ if preserve
269
+ n = Nokogiri::XML::Node.new(node.name, node.document)
270
+ node.attributes.each { |k, v| n[k] = v }
271
+ node.children.empty? or n << ret
272
+ ret = n
273
+ end
274
+ ret.elements.size == 1 && ret.first_element_child.name == "dl" and
275
+ return reqt_dl(ret.first_element_child, out)
276
+ node.name == "component" and
277
+ return recommendation_attributes1_component(node, ret, out)
278
+ node.name == "description" and
279
+ return requirement_description_parse(node, ret, out)
280
+ #!preserve_in_nested_table?(node) && id and attr = " id='#{id}'"
281
+ out.add_child("<tr#{attr}><td colspan='2'></td></tr>").first
282
+ .at(ns(".//td")) << (%(permission requirement recommendation).include?(node.name) ? node.dup : ret)
283
+ #(preserve_in_nested_table?(node) ? node.dup : ret)
284
+ out
235
285
  end
236
- out
237
- end
238
286
 
239
- def reqt_dl(node, out)
240
- node.xpath(ns("./dt")).each do |dt|
241
- dd = dt.next_element
242
- dd&.name == "dd" or next
243
- out.add_child("<tr><th>#{to_xml(dt.children)}</th>" \
244
- "<td>#{to_xml(dd.children)}</td></tr>")
287
+ def requirement_description_parse(node, ret, out)
288
+ lbl = "description"
289
+ recommend_class(node.parent) == "recommend" and
290
+ lbl = "statement"
291
+ out << "<tr><th>#{@labels['modspec'][lbl]}</th>" \
292
+ "<td>#{to_xml(ret)}</td></tr>"
293
+ out
294
+ end
295
+
296
+ def requirement_guidance_parse(node, out)
297
+ ins = out.at(ns("./fmt-provision/table/tbody"))
298
+ origs = node.xpath(ns("./component[@class = 'guidance']"))
299
+ out.xpath(ns("./component[@class = 'guidance']")).each_with_index do |f, i|
300
+ f.delete("label")
301
+ ins << "<tr#{id_attr(f)}><th>#{@labels['modspec']['guidance']}</th>" \
302
+ "<td>#{to_xml(semx_fmt_dup(origs[i]))}</td></tr>"
303
+ end
304
+ out
305
+ end
306
+
307
+ def reqt_dl(node, out)
308
+ node.xpath(ns("./dt")).each do |dt|
309
+ dd = dt.next_element
310
+ dd&.name == "dd" or next
311
+ out.add_child("<tr><th>#{to_xml(dt.children)}</th>" \
312
+ "<td>#{to_xml(dd.children)}</td></tr>")
313
+ end
314
+ out
245
315
  end
246
- out
247
316
  end
248
317
  end
249
318
  end
250
- end
@@ -162,7 +162,8 @@ module Metanorma
162
162
  end
163
163
 
164
164
  def recommendation_id(ident)
165
- test = @reqt_ids[ident&.strip] or return ident&.strip
165
+ id = to_xml(ident.children)
166
+ test = @reqt_ids[id&.strip] or return to_xml(ident)
166
167
  #require "debug"; binding.b if test.include?("<xref")
167
168
  #"<xref target='#{test[:id]}'>#{test[:lbl]}</xref>"
168
169
  test[:lbl]
@@ -189,11 +190,33 @@ module Metanorma
189
190
  (docxml.xpath(ns("//xref[@style = 'id']")) - docxml
190
191
  .xpath(ns("//requirement//xref | //permission//xref | " \
191
192
  "//recommendation//xref"))).each do |x|
192
- @reqt_id_base[x["target"]] or next # is a modspec requirement
193
- x.children = to_xml(x.children).delete_prefix(@modspecidentifierbase)
193
+ @reqt_id_base[x["target"]] or next # is a modspec requirement
194
+ truncate_id_base_outside_reqts1(x, @modspecidentifierbase)
194
195
  end
195
196
  end
196
197
 
198
+ def truncate_id_base_fmtxreflabel(node)
199
+ f = node.at(ns("./fmt-xref-label")) or return
200
+ x = f.at(ns(".//xref[@style = 'id']")) or return
201
+ if @reqt_id_base[x["target"]] && @modspecidentifierbase
202
+ f.next = f.dup
203
+ x = f.next_element.at(ns(".//xref[@style = 'id']"))
204
+ f.next_element["container"] = 'modspec-provision'
205
+ truncate_id_base_outside_reqts1(x, @modspecidentifierbase)
206
+ end
207
+ if base = @reqt_id_base[node["original-id"] || node["id"]]
208
+ f.next = f.dup
209
+ x = f.next_element.at(ns(".//xref[@style = 'id']"))
210
+ f["container"] = node["original-id"] || node["id"]
211
+ truncate_id_base_outside_reqts1(x, base)
212
+ end
213
+ end
214
+
215
+ def truncate_id_base_outside_reqts1(xref, base)
216
+ xref = xref.at(ns("./semx")) || xref
217
+ xref.children = to_xml(xref.children).delete_prefix(base)
218
+ end
219
+
197
220
  def rec_subj(node)
198
221
  case node["type"]
199
222
  when "class" then @labels["modspec"]["targettype"]
@@ -3,20 +3,24 @@ require "uri"
3
3
  module Metanorma
4
4
  class Requirements
5
5
  class Modspec < Default
6
- def requirement_table_cleanup(node, table)
7
- table = requirement_table_nested_cleanup(node, table)
6
+ def requirement_table_cleanup(node, out)
7
+ table = out.at(ns("./fmt-provision/table"))
8
+ table = requirement_table_nested_cleanup(node, out, table)
8
9
  requirement_table_consec_rows_cleanup(node, table)
9
10
  node.ancestors("requirement, recommendation, permission").empty? and
10
11
  truncate_id_base_in_reqt(table)
11
12
  cell2link(table)
12
- table
13
+ table["class"] = "modspec" # deferred; node["class"] is labelling class
14
+ out.xpath(ns("./fmt-name | ./fmt-identifier")).each(&:remove)
15
+ out
13
16
  end
14
17
 
15
18
  def cell2link(table)
16
19
  table.xpath(ns(".//td")).each do |td|
17
- td.elements.empty? or next
20
+ td.elements.empty? ||
21
+ (td.elements.size == 1 && td.elements.first.name == "semx") or next
18
22
  uri?(td.text.strip) or next
19
- td.children = "<link target='#{td.text.strip}'/>"
23
+ td.children = "<link target='#{td.text.strip}'>#{to_xml(td.children)}</link>"
20
24
  end
21
25
  end
22
26
 
@@ -43,24 +47,35 @@ module Metanorma
43
47
 
44
48
  def conflate_table_rows(trow)
45
49
  th = trow.at(ns("./th"))
46
- hdr = th.text
47
- th.children = @i18n.inflect(hdr, number: "pl")
50
+ hdr = plural_table_row_hdr(th)
48
51
  td = th.next_element
49
- res = [to_xml(td.children)]
52
+ id = td["id"] ? "<bookmark id='#{td['id']}'/>" : ""
53
+ td.delete("id")
54
+ res = [id + to_xml(td.children).strip]
50
55
  res += gather_consec_table_rows(trow, hdr)
51
56
  td.children = res.join("<br/>")
52
57
  end
53
58
 
59
+ def plural_table_row_hdr(thdr)
60
+ th1 = thdr.at(ns("./semx")) || thdr
61
+ hdr = th1.text
62
+ th1.children = @i18n.inflect(hdr, number: "pl")
63
+ hdr
64
+ end
65
+
54
66
  def gather_consec_table_rows(trow, hdr)
55
67
  ret = []
56
68
  trow.xpath("./following-sibling::xmlns:tr").each do |r|
57
- r.at(ns("./th[text() = '#{hdr}']")) or break
58
- ret << to_xml(r.remove.at(ns("./td")).children)
69
+ r.at(ns("./th"))&.text&.strip == hdr or break
70
+ td = r.remove.at(ns("./td"))
71
+ id = td["id"] ? "<bookmark id='#{td['id']}'/>" : ""
72
+ ret << id + to_xml(td.children).strip
59
73
  end
60
74
  ret
61
75
  end
62
76
 
63
- def requirement_table_nested_cleanup(node, table)
77
+ # KILL
78
+ def requirement_table_nested_cleanup(node, out, table)
64
79
  table.xpath(ns("./tbody/tr/td/table")).each do |t|
65
80
  x = t.at(ns("./thead/tr")) or next
66
81
  x.at(ns("./th")).children =
@@ -72,6 +87,25 @@ module Metanorma
72
87
  table
73
88
  end
74
89
 
90
+ def requirement_table_nested_cleanup(node, out, table)
91
+ table.xpath(ns("./tbody/tr/td/*/fmt-provision/table")).each do |t|
92
+ x = t.at(ns("./thead/tr")) or next
93
+ x.at(ns("./th")).children =
94
+ requirement_table_nested_cleanup_hdr(node)
95
+ f = x.at(ns("./td/fmt-name")) and
96
+ f.parent.children = to_xml(f.children).strip
97
+ td = x.at(ns("./td"))
98
+ td["id"] = t["original-id"] || t["id"]
99
+ if desc = t.at(ns("./tbody/tr/td/semx[@element = 'description']"))
100
+ p = desc.at(ns("./p")) and p.replace(p.children)
101
+ td << " #{to_xml(desc)}"
102
+ end
103
+ t.parent.parent.parent.parent.replace(x)
104
+ end
105
+ out.xpath(ns("./*/fmt-provision")).each(&:remove)
106
+ table
107
+ end
108
+
75
109
  def requirement_table_nested_cleanup_hdr(node)
76
110
  label = "provision"
77
111
  node["type"] == "conformanceclass" and label = "conformancetest"
@@ -86,10 +120,13 @@ module Metanorma
86
120
  def truncate_id_base_in_reqt1(table, base)
87
121
  table.xpath(ns(".//xref[@style = 'id']")).each do |x|
88
122
  @reqt_id_base[x["target"]] or next # is a modspec requirement
123
+ n = x.at(ns("./semx")) and x = n
89
124
  x.children = strip_id_base(x, base)
90
125
  end
91
126
  table.xpath(ns(".//modspec-ident")).each do |x|
92
- x.replace(strip_id_base(x, base))
127
+ n = x.at(ns("./semx")) || x
128
+ n.children = strip_id_base(n, base)
129
+ n != x and x.replace(n)
93
130
  end
94
131
  end
95
132
 
@@ -74,7 +74,7 @@ module Metanorma
74
74
  anchor[:xref_bare] = anchor[:xref]
75
75
  l = block.at(ns("./identifier")) and
76
76
  anchor[:xref] += l10n(": ") +
77
- "<tt><xref style='id' target='#{block['id']}'>#{l.text}</xref></tt>"
77
+ "<tt><xref style='id' target='#{block['id']}'>#{to_xml semx_fmt_dup(l)}</xref></tt>"
78
78
  anchor[:modspec] = anchor[:xref]
79
79
  anchor
80
80
  end
@@ -1,5 +1,5 @@
1
1
  module Metanorma
2
2
  class Requirements
3
- VERSION = "0.4.3".freeze
3
+ VERSION = "0.5.1".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mn-requirements
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-01-06 00:00:00.000000000 Z
11
+ date: 2025-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: isodoc-i18n