mn-requirements 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a12dad7f5d6cb715ade06167544dc2966581c8b9692b4d67de71664ddf401f23
4
- data.tar.gz: 04cff2ddfd3116155014720376fbcf98c2d88bece77a12c748cd0726814d4c2e
3
+ metadata.gz: 0badc555e06715baca7220440eb81778bf749207c6ff43e15e1c8e0417679cd3
4
+ data.tar.gz: dff076524388287b831304ea8abb1806880d0e960335991bd27b395f58ffdec8
5
5
  SHA512:
6
- metadata.gz: dfc9ce13b9304cd254e0d2f941f04d48607041922aa0333417f57d61867495c4c486c2f2be459cbb46de52509a46e0f5b8f5460c6319310ee166864e2aac7797
7
- data.tar.gz: f7a0989cc2212bc9186acf262a75bac6712bb9e7bdc7ae0d5c417446bce63f40dc7c8af9568b144a59a95914a0ff82f116af49586c75887697b079f7afa386a5
6
+ metadata.gz: 1cb0ad289dd8ffef0bf50e94b70cf8cbb08b52132dd7326fbda1ee4e23c13f3836af0ec23532ef3a88537e1621e82625a0a09d0fcde8e24e30a9eee87dbf0812
7
+ data.tar.gz: 1870ea682f4e7120da000da28e6473bf064161bb8c54fcc30e0a8f1679f77a9b6a3981eadca48b5b316ceaa3239f420e0acdd6458f3a365f9d2ec290ee7e299b
@@ -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
@@ -160,91 +155,122 @@ module Metanorma
160
155
  node["id"] ? " id='#{node['id']}'" : ""
161
156
  end
162
157
 
163
- def recommendation_steps(node)
158
+ # KILL
159
+ def recommendation_stepsX(node)
164
160
  node.elements.each { |e| recommendation_steps(e) }
165
- return node unless node.at(ns("./component[@class = 'step']"))
166
-
161
+ node.at(ns("./component[@class = 'step']")) or return node
167
162
  d = node.at(ns("./component[@class = 'step']"))
168
163
  d = d.replace("<ol class='steps'><li#{id_attr(d)}>" \
169
- "#{to_xml(d.children)}</li></ol>").first
164
+ "#{to_xml(d.children)}</li></ol>").first
170
165
  node.xpath(ns("./component[@class = 'step']")).each do |f|
171
166
  f = f.replace("<li#{id_attr(f)}>#{to_xml(f.children)}</li>").first
172
167
  d << f
173
168
  end
174
- node
169
+ node
175
170
  end
176
171
 
177
- def recommendation_attributes1_component(node, out)
178
- return out if node["class"] == "guidance"
179
172
 
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
173
+ def recommendation_steps(node, ret)
174
+ ret.elements.each_with_index do |e, i|
175
+ e1 = nil
176
+ #require "debug"; e.name == "component" && e["class"] == "step" and binding.b
177
+ e.name == "component" && e["class"] == "step" and
178
+ e1 = e.replace(semx_fmt_dup(node.elements[i]))
179
+ #require "debug"; e.name == "component" && e["class"] == "step" and binding.b
180
+ recommendation_steps(node.elements[i], e1 || e)
181
+ end
182
+ node.name == "component" && node["class"] == "step" and ret["inlist"] = "true"
183
+ #require "debug"; node.name == "component" && node["class"] == "step" and binding.b
184
+ d = ret.at(ns("./semx[@inlist]")) or return ret
185
+ d.delete("inlist")
186
+ d = d.replace("<ol class='steps'><li#{id_attr(d)}>" \
187
+ "#{to_xml(d)}</li></ol>").first
188
+ ret.xpath(ns("./semx[@inlist]")).each do |f|
189
+ f.delete("inlist")
190
+ f = f.replace("<li#{id_attr(f)}>#{to_xml(f)}</li>").first
191
+ d << f
192
+ end
193
+ ret
194
+ end
185
195
 
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
196
+ def recommendation_attributes1_component(node, ret, out)
197
+ node["class"] == "guidance" and return out
198
+ ret = recommendation_steps(node, ret)
199
+ out << "<tr#{id_attr(node)}><th>#{node['label']}</th>" \
200
+ "<td>#{to_xml(ret)}</td></tr>"
201
+ node.delete("label") # inserted in recommendation_component_labels
202
+ out
203
+ end
204
+
205
+ def recommendation_attr_keyvalue(node, key, value)
206
+ tag = node.at(ns("./#{key}")) or return nil
207
+ value = node.at(ns("./#{value}")) or return nil
208
+ !%w(target indirect-dependency identifier-base
190
209
  implements).include?(tag.text.downcase) or
191
- return nil
192
- [Metanorma::Utils.strict_capitalize_first(tag.text), value.children]
193
- end
210
+ return nil
211
+ lbl = semx_fmt_dup(tag)
212
+ lbl.children = Metanorma::Utils.strict_capitalize_first(lbl.text)
213
+ [to_xml(lbl), semx_fmt_dup(value)]
214
+ end
194
215
 
195
- def reqt_component_type(node)
196
- klass = node.name
197
- klass == "component" and klass = node["class"]
198
- "requirement-#{klass}"
199
- end
216
+ def reqt_component_type(node)
217
+ klass = node.name
218
+ klass == "component" and klass = node["class"]
219
+ "requirement-#{klass}"
220
+ end
200
221
 
201
- def preserve_in_nested_table?(node)
202
- %w(recommendation requirement permission
222
+ def preserve_in_nested_table?(node)
223
+ %w(recommendation requirement permission
203
224
  table ol dl ul).include?(node.name)
204
- end
225
+ end
205
226
 
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
227
+ def requirement_component_parse(node, out)
228
+ node["exclude"] == "true" and return out
229
+ ret = semx_fmt_dup(node)
230
+ descr_classif_render(node, ret)
231
+ ret.elements.size == 1 && ret.first_element_child.name == "dl" and
232
+ return reqt_dl(ret.first_element_child, out)
233
+ node.name == "component" and
234
+ return recommendation_attributes1_component(node, ret, out)
235
+ node.name == "description" and
236
+ return requirement_description_parse(node, ret, out)
237
+ id = node["id"] || node["original-id"]
238
+ !preserve_in_nested_table?(node) && id and attr = " id='#{id}'"
239
+ out.add_child("<tr#{id_attr(node)}><td colspan='2'#{attr}></td></tr>").first
240
+ .at(ns(".//td")) <<
241
+ (preserve_in_nested_table?(node) ? node.dup : ret)
242
+ out
243
+ end
220
244
 
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
245
+ def requirement_description_parse(node, ret, out)
246
+ lbl = "description"
247
+ recommend_class(node.parent) == "recommend" and
248
+ lbl = "statement"
249
+ out << "<tr><th>#{@labels['modspec'][lbl]}</th>" \
250
+ "<td>#{to_xml(ret)}</td></tr>"
251
+ out
252
+ end
229
253
 
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>"
254
+ def requirement_guidance_parse(node, out)
255
+ ins = out.at(ns("./fmt-provision/table/tbody"))
256
+ origs = node.xpath(ns("./component[@class = 'guidance']"))
257
+ out.xpath(ns("./component[@class = 'guidance']")).each_with_index do |f, i|
258
+ f.delete("label")
259
+ ins << "<tr#{id_attr(f)}><th>#{@labels['modspec']['guidance']}</th>" \
260
+ "<td>#{to_xml(semx_fmt_dup(origs[i]))}</td></tr>"
261
+ end
262
+ out
235
263
  end
236
- out
237
- end
238
264
 
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>")
265
+ def reqt_dl(node, out)
266
+ node.xpath(ns("./dt")).each do |dt|
267
+ dd = dt.next_element
268
+ dd&.name == "dd" or next
269
+ out.add_child("<tr><th>#{to_xml(dt.children)}</th>" \
270
+ "<td>#{to_xml(dd.children)}</td></tr>")
271
+ end
272
+ out
245
273
  end
246
- out
247
274
  end
248
275
  end
249
276
  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.0".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.0
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-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: isodoc-i18n