mn-requirements 0.1.8 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 241d16930a4f1ea42bad8fb33599eae423582f76111dbf64272afb20141b69ea
4
- data.tar.gz: 63c1107edba65cade52ddd9bda6af1fac1e02540ab2f2904a9e6c1af264f4e3a
3
+ metadata.gz: 1cc32c6334d63f4745d279e84ea08305400eccc4f020ac410b85488e47e3c6ce
4
+ data.tar.gz: 57e1f8b559a619d6d01a18520d15f3de7787d0eb7fed17add4c120bc58b0d862
5
5
  SHA512:
6
- metadata.gz: d33e761d47985154817ac6334406771946fc1dc88c6fb38a1a76f0db7d0c43beb5bd316bfe5bcf2c5aab7a2bb1c9953e3e4a544ca354b8e4f08a004e3bc14a87
7
- data.tar.gz: d276f8e75000218b83442b3c8daa76d43f295b2781488fba401cffc6ec92b76f9fe27313f16135392c40a793f216ec6701e03b45c6d6cbe983d44678bc718b59
6
+ metadata.gz: 817a441beba95552171c674b07c7d447808496a642c90181baf039723b7fcdef1dbb5ee23ecac9e167ffea9d09871af3bfa48dec7c40c7cc46b4fe48559e1286
7
+ data.tar.gz: '09ee6db13e6fc2eb7e99ec2fbeb281a6ce3a9aed08e8d41b865a1acd458c2ec9fa642325bfff50de1ec8689ba9f8e8a74f914e0c5e3759670ee85c183f787ec1'
@@ -20,9 +20,26 @@ requirements:
20
20
  target: استهداف
21
21
  testpurpose: هدف الاختبار
22
22
  testmethod: طريقة اختبار
23
- dependency: الاعتماد
24
- indirectdependency: التبعية غير المباشرة
23
+ dependency: المتطلبات المسبقة
24
+ indirectdependency: شرط مسبق غير مباشر
25
25
  identifier: المعرف
26
26
  included_in: مدرج في
27
27
  statement: بيان
28
+ description: وصف
28
29
  guidance: إرشاد
30
+ implements: تنفذ
31
+ provision: بيان المعياري
32
+ inflection:
33
+ بيان المعياري:
34
+ sg: بيان المعياري
35
+ pl: البيانات المعيارية
36
+ اختبار المطابقة:
37
+ sg: اختبار المطابقة
38
+ pl: اختبارات المطابقة
39
+ المتطلبات المسبقة:
40
+ sg: المتطلبات المسبقة
41
+ pl: المتطلبات الأساسية
42
+ شرط مسبق غير مباشر:
43
+ sg: شرط مسبق غير مباشر
44
+ pl: المتطلبات الأساسية غير المباشرة
45
+
@@ -20,10 +20,25 @@ requirements:
20
20
  target: Ziel
21
21
  testpurpose: Testzweck
22
22
  testmethod: Testmethode
23
- dependency: Abhängigkeit
24
- indirectdependency: Indirekte Abhängigkeit
23
+ dependency: Voraussetzung
24
+ indirectdependency: Indirekte Voraussetzung
25
25
  identifier: Kennung
26
26
  included_in: Enthalten in
27
27
  statement: Aussage
28
+ description: Beschreibung
28
29
  guidance: Anleitung
29
-
30
+ implements: Implementiert
31
+ provision: Normative Aussage
32
+ inflection:
33
+ Normative Aussage:
34
+ sg: Normative Aussage
35
+ pl: Normative Aussagen
36
+ Conformance test:
37
+ sg: Konformitätstest
38
+ pl: Konformitätstests
39
+ Voraussetzung:
40
+ sg: Voraussetzung
41
+ pl: Voraussetzungen
42
+ Indirekte Voraussetzung:
43
+ sg: Indirekte Voraussetzung
44
+ pl: Indirekte Voraussetzungen
@@ -20,10 +20,28 @@ requirements:
20
20
  target: Target
21
21
  testpurpose: Test purpose
22
22
  testmethod: Test method
23
- dependency: Dependency
24
- indirectdependency: Indirect Dependency
23
+ dependency: Prerequisite
24
+ indirectdependency: Indirect prerequisite
25
25
  identifier: Identifier
26
26
  included_in: Included in
27
27
  statement: Statement
28
+ description: Description
28
29
  guidance: Guidance
29
-
30
+ implements: Implements
31
+ provision: Normative statement
32
+ inflection:
33
+ Normative statement:
34
+ sg: Normative statement
35
+ pl: Normative statements
36
+ Conformance test:
37
+ sg: Conformance test
38
+ pl: Conformance tests
39
+ Statement:
40
+ sg: Statement
41
+ pl: Statements
42
+ Prerequisite:
43
+ sg: Prerequisite
44
+ pl: Prerequisites
45
+ Indirect prerequisite:
46
+ sg: Indirect prerequisite
47
+ pl: Indirect prerequisites
@@ -20,9 +20,29 @@ requirements:
20
20
  target: Objetivo
21
21
  testpurpose: Propósito de prueba
22
22
  testmethod: Método de prueba
23
- dependency: Dependencia
24
- indirectdependency: Dependencia indirecta
23
+ dependency: Requisito
24
+ indirectdependency: Requisito indirecto
25
25
  identifier: Identificador
26
26
  included_in: Incluido en
27
27
  statement: Declaración
28
+ description: Descripción
28
29
  guidance: Orientación
30
+ implements: Implementa
31
+ provision: Declaración normativa
32
+ inflection:
33
+ Declaración normativa:
34
+ sg: Declaración normativa
35
+ pl: Declaraciones normativas
36
+ Prueba de conformidad:
37
+ sg: Prueba de conformidad
38
+ pl: Pruebas de conformidad
39
+ Déclaration:
40
+ sg: Déclaration
41
+ pl: Déclarations
42
+ Prérequis:
43
+ sg: Prérequis
44
+ pl: Prérequis
45
+ Dépendance indirecte:
46
+ sg: Prérequis indirect
47
+ pl: Prérequis indirects
48
+
@@ -20,10 +20,29 @@ requirements:
20
20
  target: Cible
21
21
  testpurpose: Objectif du test
22
22
  testmethod: Méthode du test
23
- dependency: Dépendance
24
- indirectdependency: Dépendance indirecte
23
+ dependency: Prérequis
24
+ indirectdependency: Prérequis indirect
25
25
  identifier: Identifiant
26
26
  included_in: Inclus dans
27
27
  statement: Déclaration
28
+ description: Description
28
29
  guidance: Avis
30
+ implements: Implémente
31
+ provision: Déclaration normative
32
+ inflection:
33
+ Déclaration normative:
34
+ sg: Déclaration normative
35
+ pl: Déclarations normatives
36
+ Test de conformité:
37
+ sg: Tests de conformité
38
+ pl: Tests de conformité
39
+ Déclaration:
40
+ sg: Déclaration
41
+ pl: Déclarations
42
+ Prérequis:
43
+ sg: Prérequis
44
+ pl: Prérequis
45
+ Dépendance indirecte:
46
+ sg: Prérequis indirect
47
+ pl: Prérequis indirects
29
48
 
@@ -20,10 +20,29 @@ requirements:
20
20
  target: Цель
21
21
  testpurpose: Цель теста
22
22
  testmethod: Метод теста
23
- dependency: Зависимость
24
- indirectdependency: Косвенная зависимость
23
+ dependency: Условие
24
+ indirectdependency: Косвенное условие
25
25
  identifier: Идентификатор
26
26
  included_in: Входит в
27
27
  statement: Утверждение
28
+ description: Описание
28
29
  guidance: Руководство
30
+ implements: Реализует
31
+ provision: Нормативное положение
32
+ inflection:
33
+ Нормативное положение:
34
+ sg: Нормативное положение
35
+ pl: Нормативные положения
36
+ Проверка на соответствие:
37
+ sg: Проверка на соответствие
38
+ pl: Проверки на соответствие
39
+ Утверждение:
40
+ sg: Утверждение
41
+ pl: Утверждения
42
+ Условие:
43
+ sg: Условие
44
+ pl: Условия
45
+ Косвенное условие:
46
+ sg: Косвенное условие
47
+ pl: Косвенное условия
29
48
 
@@ -20,10 +20,12 @@ requirements:
20
20
  target: 目标
21
21
  testpurpose: 测试目的
22
22
  testmethod: 测试方法
23
- dependency: 依赖
24
- indirectdependency: 间接依赖
23
+ dependency: 先决条件
24
+ indirectdependency: 间接先决条件
25
25
  identifier: 标识符
26
26
  included_in: 包含在
27
27
  statement: 陈述
28
+ description: 描述
28
29
  guidance: 指导意见
29
-
30
+ implements: 它实现
31
+ provision: 规范性陈述
@@ -16,8 +16,8 @@ module Metanorma
16
16
 
17
17
  def requirement_inherit_insert(reqt)
18
18
  ins = reqt.at("./classification") || reqt.at(
19
- "./description | ./measurementtarget | ./specification | "\
20
- "./verification | ./import | ./description | ./component | "\
19
+ "./description | ./measurementtarget | ./specification | " \
20
+ "./verification | ./import | ./description | ./component | " \
21
21
  "./requirement | ./recommendation | ./permission",
22
22
  ) and return ins
23
23
  requirement_inherit_insert1(reqt)
@@ -56,7 +56,7 @@ module Metanorma
56
56
  end
57
57
 
58
58
  def requirement_description_cleanup1(reqt)
59
- while d = reqt.at("./description[following-sibling::*[1]"\
59
+ while d = reqt.at("./description[following-sibling::*[1]" \
60
60
  "[self::description]]")
61
61
  n = d.next.remove
62
62
  d << n.children
@@ -115,7 +115,7 @@ module Metanorma
115
115
  dlist.xpath("./dt[text()='classification']").each do |e|
116
116
  val = e.at("./following::dd/p") || e.at("./following::dd")
117
117
  req_classif_parse(val.children.to_xml).each do |r|
118
- ins.next = "<classification><tag>#{r[0]}</tag>"\
118
+ ins.next = "<classification><tag>#{r[0]}</tag>" \
119
119
  "<value>#{r[1]}</value></classification>"
120
120
  ins = ins.next
121
121
  end
@@ -137,7 +137,7 @@ module Metanorma
137
137
 
138
138
  def reqt_dl_to_classif2(term, ins)
139
139
  val = term.at("./following::dd/p") || e.at("./following::dd")
140
- ins.next = "<classification><tag>#{term.text}</tag>"\
140
+ ins.next = "<classification><tag>#{term.text}</tag>" \
141
141
  "<value>#{val.children.to_xml}</value></classification>"
142
142
  ins.next
143
143
  end
@@ -76,8 +76,8 @@ module Metanorma
76
76
  def recommendation_attr_keyvalue(node, key, value)
77
77
  tag = node.at(ns("./#{key}")) or return nil
78
78
  value = node.at(ns("./#{value}")) or return nil
79
- l10n("#{Metanorma::Utils.strict_capitalize_first tag.text}: "\
80
- "#{value.children.to_xml}")
79
+ l10n("#{Metanorma::Utils.strict_capitalize_first tag.text}: " \
80
+ "#{value.children.to_xml}")
81
81
  end
82
82
 
83
83
  def recommendation_attributes(node, out)
@@ -74,7 +74,10 @@ module Metanorma
74
74
  end
75
75
 
76
76
  def requirement_target_identifiers(reqt)
77
- reqt.xpath("./classification[tag = 'target']/value[link]").each do |v|
77
+ reqt.xpath("./classification[tag][value/link]").each do |c|
78
+ %w(target indirect-dependency implements)
79
+ .include?(c.at("./tag").text.downcase) or next
80
+ v = c.at("./value[link]")
78
81
  v.children = v.at("./link/@target").text
79
82
  end
80
83
  end
@@ -1,5 +1,6 @@
1
1
  require_relative "xrefs"
2
2
  require_relative "reqt_label"
3
+ require_relative "table_cleanup"
3
4
 
4
5
  module Metanorma
5
6
  class Requirements
@@ -34,11 +35,11 @@ module Metanorma
34
35
  def recommendation_header(reqt, out)
35
36
  n = recommendation_name(reqt, nil)
36
37
  x = if reqt.ancestors("requirement, recommendation, permission").empty?
37
- "<thead><tr><th scope='colgroup' colspan='2'>"\
38
- "<p class='#{recommend_name_class(reqt)}'>#{n}</p>"\
38
+ "<thead><tr><th scope='colgroup' colspan='2'>" \
39
+ "<p class='#{recommend_name_class(reqt)}'>#{n}</p>" \
39
40
  "</th></tr></thead>"
40
41
  else
41
- "<thead><tr><td>#{recommendation_class_label(reqt)}</td>"\
42
+ "<thead><tr><th>#{recommendation_class_label(reqt)}</th>" \
42
43
  "<td>#{n}</td></tr></thead>"
43
44
  end
44
45
  out << x
@@ -61,15 +62,15 @@ module Metanorma
61
62
  ins = out.add_child("<tbody></tbody>").first
62
63
  recommend_title(node, ins)
63
64
  recommendation_attributes1(node).each do |i|
64
- ins.add_child("<tr><td>#{i[0]}</td><td>#{i[1]}</td></tr>")
65
+ ins.add_child("<tr><th>#{i[0]}</th><td>#{i[1]}</td></tr>")
65
66
  end
66
67
  ins
67
68
  end
68
69
 
69
70
  def recommend_title(node, out)
70
71
  label = node.at(ns("./identifier")) or return
71
- out.add_child("<tr><td scope='colgroup' colspan='2'>"\
72
- "<tt>#{label.children.to_xml}</tt></td>")
72
+ out.add_child("<tr><th>#{@labels['modspec']['identifier']}</th>" \
73
+ "<td><tt>#{label.children.to_xml}</tt></td>")
73
74
  end
74
75
 
75
76
  def recommendation_attributes1(node)
@@ -86,37 +87,47 @@ module Metanorma
86
87
  head << [@labels["default"]["obligation"], oblig]
87
88
  subj = node.at(ns("./subject"))&.children and
88
89
  head << [rec_subj(node), subj]
89
- node.xpath(ns("./classification[tag = 'target']/value")).each do |v|
90
- xref = recommendation_id(v.text) and
91
- head << [rec_target(node), xref]
92
- end
90
+ head = recommendation_attributes1_target(node, head)
93
91
  head += recommendation_backlinks(node)
94
92
  recommendation_attributes1_dependencies(node, head)
95
93
  end
96
94
 
95
+ def recommendation_attributes1_target(node, head)
96
+ node.xpath(ns("./classification[tag][value]")).each do |c|
97
+ c.at(ns("./tag")).text.casecmp("target").zero? or next
98
+ xref = recommendation_id(c.at(ns("./value")).text) and
99
+ head << [rec_target(node), xref]
100
+ end
101
+ head
102
+ end
103
+
97
104
  def recommendation_backlinks(node)
98
105
  ret = []
99
106
  id = node.at(ns("./identifier")) or return ret
100
- %w(general class).include?(node["type"]) and
101
- xref = recommendation_link_test(id.text) and
102
- ret << [@labels["modspec"]["conformancetest"], xref]
103
- ret
104
- (node["type"].nil? || node["type"].empty? ||
105
- node["type"] == "verification") and
106
- xref = recommendation_link_class(id.text) and
107
- ret << [@labels["modspec"]["included_in"], xref]
108
- ret
107
+ ret = recommendation_backlinks_test(node, id, ret)
108
+ recommendation_backlinks_class(node, id, ret)
109
109
  end
110
110
 
111
111
  def recommendation_attributes1_dependencies(node, head)
112
+ head = recommendation_attributes1_inherit(node, head)
113
+ recommendation_attributes_dependencies2(node, head)
114
+ end
115
+
116
+ def recommendation_attributes1_inherit(node, head)
112
117
  node.xpath(ns("./inherit")).each do |i|
113
118
  head << [@labels["modspec"]["dependency"],
114
119
  recommendation_id(i.children.to_xml)]
115
120
  end
116
- node.xpath(ns("./classification[tag = 'indirect-dependency']/value"))
117
- .each do |v|
118
- xref = recommendation_id(v.children.to_xml) and
119
- head << [@labels["modspec"]["indirectdependency"], xref]
121
+ head
122
+ end
123
+
124
+ def recommendation_attributes_dependencies2(node, head)
125
+ %w(indirect-dependency implements).each do |x|
126
+ node.xpath(ns("./classification[tag][value]")).each do |c|
127
+ c.at(ns("./tag")).text.casecmp(x).zero? or next
128
+ xref = recommendation_id(c.at(ns("./value")).children.to_xml) and
129
+ head << [@labels["modspec"][x.gsub(/-/, "")], xref]
130
+ end
120
131
  end
121
132
  head
122
133
  end
@@ -130,7 +141,7 @@ module Metanorma
130
141
  return node unless node.at(ns("./component[@class = 'step']"))
131
142
 
132
143
  d = node.at(ns("./component[@class = 'step']"))
133
- d = d.replace("<ol class='steps'><li#{id_attr(d)}>"\
144
+ d = d.replace("<ol class='steps'><li#{id_attr(d)}>" \
134
145
  "#{d.children.to_xml}</li></ol>").first
135
146
  node.xpath(ns("./component[@class = 'step']")).each do |f|
136
147
  f = f.replace("<li#{id_attr(f)}>#{f.children.to_xml}</li>").first
@@ -143,7 +154,7 @@ module Metanorma
143
154
  return out if node["class"] == "guidance"
144
155
 
145
156
  node = recommendation_steps(node)
146
- out << "<tr#{id_attr(node)}><td>#{node['label']}</td>"\
157
+ out << "<tr#{id_attr(node)}><th>#{node['label']}</th>" \
147
158
  "<td>#{node.children}</td></tr>"
148
159
  out
149
160
  end
@@ -151,7 +162,9 @@ module Metanorma
151
162
  def recommendation_attr_keyvalue(node, key, value)
152
163
  tag = node.at(ns("./#{key}")) or return nil
153
164
  value = node.at(ns("./#{value}")) or return nil
154
- !%w(target indirect-dependency).include?(tag.text) or return nil
165
+ !%w(target indirect-dependency
166
+ implements).include?(tag.text.downcase) or
167
+ return nil
155
168
  [Metanorma::Utils.strict_capitalize_first(tag.text), value.children]
156
169
  end
157
170
 
@@ -172,16 +185,27 @@ module Metanorma
172
185
  return reqt_dl(node.first_element_child, out)
173
186
  node.name == "component" and
174
187
  return recommendation_attributes1_component(node, out)
188
+ node.name == "description" and
189
+ return requirement_description_parse(node, out)
175
190
  out.add_child("<tr#{id_attr(node)}><td colspan='2'></td></tr>").first
176
191
  .at(ns(".//td")) <<
177
192
  (preserve_in_nested_table?(node) ? node : node.children)
178
193
  out
179
194
  end
180
195
 
196
+ def requirement_description_parse(node, out)
197
+ lbl = "statement"
198
+ recommend_class(node.parent) == "recommendclass" and
199
+ lbl = "description"
200
+ out << "<tr><th>#{@labels['modspec'][lbl]}</th>" \
201
+ "<td>#{node.children.to_xml}</td></tr>"
202
+ out
203
+ end
204
+
181
205
  def requirement_guidance_parse(node, out)
182
206
  ins = out.at(ns("./tbody"))
183
207
  node.xpath(ns("./component[@class = 'guidance']")).each do |f|
184
- ins << "<tr#{id_attr(f)}><td>#{@labels['modspec']['guidance']}</td>"\
208
+ ins << "<tr#{id_attr(f)}><th>#{@labels['modspec']['guidance']}</th>" \
185
209
  "<td>#{f.children}</td></tr>"
186
210
  end
187
211
  out
@@ -191,60 +215,11 @@ module Metanorma
191
215
  node.xpath(ns("./dt")).each do |dt|
192
216
  dd = dt.next_element
193
217
  dd&.name == "dd" or next
194
- out.add_child("<tr><td>#{dt.children.to_xml}</td>"\
218
+ out.add_child("<tr><th>#{dt.children.to_xml}</th>" \
195
219
  "<td>#{dd.children.to_xml}</td></tr>")
196
220
  end
197
221
  out
198
222
  end
199
-
200
- def requirement_table_cleanup(_node, table)
201
- table.xpath(ns("./tbody/tr/td/table")).each do |t|
202
- x = t.at(ns("./thead/tr")) or next
203
- t.parent.parent.replace(x)
204
- end
205
- table
206
- end
207
-
208
- def rec_subj(node)
209
- case node["type"]
210
- when "class" then @labels["modspec"]["targettype"]
211
- else @labels["default"]["subject"]
212
- end
213
- end
214
-
215
- def rec_target(node)
216
- case node["type"]
217
- when "class" then @labels["modspec"]["targettype"]
218
- when "conformanceclass" then @labels["modspec"]["requirementclass"]
219
- when "verification", "abstracttest" then @labels["default"]["requirement"]
220
- else @labels["modspec"]["target"]
221
- end
222
- end
223
-
224
- def recommend_class(node)
225
- case node["type"]
226
- when "verification", "abstracttest" then "recommendtest"
227
- when "class", "conformanceclass" then "recommendclass"
228
- else "recommend"
229
- end
230
- end
231
-
232
- def recommend_name_class(node)
233
- if %w(verification abstracttest).include?(node["type"])
234
- "RecommendationTestTitle"
235
- else "RecommendationTitle"
236
- end
237
- end
238
-
239
- def recommend_component_label(node)
240
- c = case node["class"]
241
- when "test-purpose" then "Test purpose"
242
- when "test-method" then "Test method"
243
- else node["class"]
244
- end
245
- @labels["default"][c] || @labels["modspec"][c] ||
246
- Metanorma::Utils.strict_capitalize_first(c)
247
- end
248
223
  end
249
224
  end
250
225
  end
@@ -73,16 +73,26 @@ module Metanorma
73
73
  def reqt_links_test(docxml)
74
74
  docxml.xpath(ns("//requirement | //recommendation | //permission"))
75
75
  .each_with_object({}) do |r, m|
76
- next unless %w(conformanceclass
77
- verification).include?(r["type"])
76
+ reqt_links_test1(r, m)
77
+ end
78
+ end
78
79
 
79
- subj = r.at(ns("./classification[tag = 'target']/value"))
80
- id = r.at(ns("./identifier")) or next
81
- lbl = @xrefs.anchor(@reqt_ids[id.text.strip][:id], :xref, false)
82
- next unless subj && lbl
80
+ def reqt_links_test1(reqt, acc)
81
+ return unless %w(conformanceclass
82
+ verification).include?(reqt["type"])
83
83
 
84
- m[subj.text] = { lbl: lbl, id: r["id"] }
85
- end
84
+ subj = reqt_extract_target(reqt)
85
+ id = reqt.at(ns("./identifier")) or return
86
+ lbl = @xrefs.anchor(@reqt_ids[id.text.strip][:id], :xref, false)
87
+ return unless subj && lbl
88
+
89
+ acc[subj.text] = { lbl: lbl, id: reqt["id"] }
90
+ end
91
+
92
+ def reqt_extract_target(reqt)
93
+ reqt.xpath(ns("./classification[tag][value]")).detect do |x|
94
+ x.at(ns("./tag")).text.casecmp("target").zero?
95
+ end&.at(ns("./value"))
86
96
  end
87
97
 
88
98
  def recommendation_link_test(ident)
@@ -116,6 +126,63 @@ module Metanorma
116
126
  test = @reqt_ids[ident&.strip] or return ident&.strip
117
127
  "<xref target='#{test[:id]}'>#{test[:lbl]}</xref>"
118
128
  end
129
+
130
+ def recommendation_backlinks_test(node, id, ret)
131
+ (%w(general class).include?(node["type"]) &&
132
+ xref = recommendation_link_test(id.text)) or return ret
133
+ lbl = node["type"] == "general" ? "conformancetest" : "conformanceclass"
134
+ ret << [@labels["modspec"][lbl], xref]
135
+ ret
136
+ end
137
+
138
+ def recommendation_backlinks_class(node, id, ret)
139
+ (node["type"].nil? || node["type"].empty? ||
140
+ node["type"] == "verification") and
141
+ xref = recommendation_link_class(id.text) and
142
+ ret << [@labels["modspec"]["included_in"], xref]
143
+ ret
144
+ end
145
+
146
+ def rec_subj(node)
147
+ case node["type"]
148
+ when "class" then @labels["modspec"]["targettype"]
149
+ else @labels["default"]["subject"]
150
+ end
151
+ end
152
+
153
+ def rec_target(node)
154
+ case node["type"]
155
+ when "class" then @labels["modspec"]["targettype"]
156
+ when "conformanceclass" then @labels["modspec"]["requirementclass"]
157
+ when "verification", "abstracttest" then @labels["default"]["requirement"]
158
+ else @labels["modspec"]["target"]
159
+ end
160
+ end
161
+
162
+ def recommend_class(node)
163
+ case node["type"]
164
+ when "verification", "abstracttest" then "recommendtest"
165
+ when "class", "conformanceclass" then "recommendclass"
166
+ else "recommend"
167
+ end
168
+ end
169
+
170
+ def recommend_name_class(node)
171
+ if %w(verification abstracttest).include?(node["type"])
172
+ "RecommendationTestTitle"
173
+ else "RecommendationTitle"
174
+ end
175
+ end
176
+
177
+ def recommend_component_label(node)
178
+ c = case node["class"]
179
+ when "test-purpose" then "Test purpose"
180
+ when "test-method" then "Test method"
181
+ else node["class"]
182
+ end
183
+ @labels["default"][c] || @labels["modspec"][c] ||
184
+ Metanorma::Utils.strict_capitalize_first(c)
185
+ end
119
186
  end
120
187
  end
121
188
  end
@@ -0,0 +1,62 @@
1
+ module Metanorma
2
+ class Requirements
3
+ class Modspec < Default
4
+ def requirement_table_cleanup(node, table)
5
+ table = requirement_table_nested_cleanup(node, table)
6
+ requirement_table_consec_rows_cleanup(node, table)
7
+ table
8
+ end
9
+
10
+ def requirement_table_consec_rows_cleanup(_node, table)
11
+ table.xpath(ns("./tbody/tr")).each do |tr|
12
+ conflate_table_rows?(tr) or next
13
+ conflate_table_rows(tr)
14
+ end
15
+ end
16
+
17
+ def conflate_table_rows?(trow)
18
+ tr1 = trow.next or return
19
+ tr1.name == "tr" or return
20
+
21
+ th = trow.at(ns("./th"))&.text
22
+ th && th == tr1.at(ns("./th"))&.text
23
+ end
24
+
25
+ def conflate_table_rows(trow)
26
+ th = trow.at(ns("./th"))
27
+ hdr = th.text
28
+ th.children = @i18n.inflect(hdr, number: "pl")
29
+ td = th.next_element
30
+ res = [td.children.to_xml]
31
+ res += gather_consec_table_rows(trow, hdr)
32
+ td.children = res.join("<br/>")
33
+ end
34
+
35
+ def gather_consec_table_rows(trow, hdr)
36
+ ret = []
37
+ trow.xpath("./following-sibling::xmlns:tr").each do |r|
38
+ break unless r.at(ns("./th[text() = '#{hdr}']"))
39
+
40
+ ret << r.remove.at(ns("./td")).children.to_xml
41
+ end
42
+ ret
43
+ end
44
+
45
+ def requirement_table_nested_cleanup(node, table)
46
+ table.xpath(ns("./tbody/tr/td/table")).each do |t|
47
+ x = t.at(ns("./thead/tr")) or next
48
+ x.at(ns("./th")).children =
49
+ requirement_table_nested_cleanup_hdr(node)
50
+ t.parent.parent.replace(x)
51
+ end
52
+ table
53
+ end
54
+
55
+ def requirement_table_nested_cleanup_hdr(node)
56
+ label = "provision"
57
+ node["type"] == "conformanceclass" and label = "conformancetest"
58
+ @i18n.get["requirements"]["modspec"][label]
59
+ end
60
+ end
61
+ end
62
+ end
@@ -8,7 +8,7 @@ module Metanorma
8
8
  end
9
9
 
10
10
  def nested_reqt?(reqt)
11
- reqt.at("./ancestor::requirement | ./ancestor::recommendation | "\
11
+ reqt.at("./ancestor::requirement | ./ancestor::recommendation | " \
12
12
  "./ancestor::permission")
13
13
  end
14
14
 
@@ -22,6 +22,7 @@ module Metanorma
22
22
  class_to_children(reqt, "class", "general")
23
23
  class_to_children(reqt, "conformanceclass", "verification")
24
24
  children_to_class(reqt, "verification", "conformanceclass")
25
+ reqt_to_dependency(reqt)
25
26
  end
26
27
 
27
28
  def type2validate(reqt)
@@ -36,12 +37,33 @@ module Metanorma
36
37
  verification: "Conformance test",
37
38
  class: "Requirement class",
38
39
  conformanceclass: "Conformance class",
40
+ provision: "Provision",
41
+ dependency: "Prerequisite",
42
+ indirect_dependency: "Indirect prerequisite",
43
+ implements: "Implemented provision",
39
44
  }.freeze
40
45
 
41
46
  def log_reqt(reqt, leftclass, rightclass)
42
- @log.add("Requirements", reqt[:elem],
43
- "#{CLASS2LABEL[leftclass.to_sym]} #{reqt[:label] || reqt[:id]} "\
44
- "has no corresponding #{CLASS2LABEL[rightclass.to_sym]}")
47
+ @log.add("Requirements", reqt[:elem], <<~MSG
48
+ #{CLASS2LABEL[leftclass.to_sym]} #{reqt[:label] || reqt[:id]} has no corresponding #{CLASS2LABEL[rightclass.to_sym]}
49
+ MSG
50
+ )
51
+ end
52
+
53
+ def log_reqt2(reqt, leftclass, target, rightclass)
54
+ @log.add("Requirements", reqt[:elem], <<~MSG
55
+ #{CLASS2LABEL[leftclass]} #{reqt[:label] || reqt[:id]} points to #{CLASS2LABEL[rightclass]} #{target} outside this document
56
+ MSG
57
+ )
58
+ end
59
+
60
+ def reqt_to_dependency(reqt)
61
+ r = @ids[:id][reqt["id"]]
62
+ %i(dependency indirect_dependency implements).each do |x|
63
+ r[x].each do |d|
64
+ @ids[:label][d] or log_reqt2(r, :provision, d, x)
65
+ end
66
+ end
45
67
  end
46
68
 
47
69
  def reqt_to_conformance(reqt, reqtclass, confclass)
@@ -84,7 +106,7 @@ module Metanorma
84
106
 
85
107
  def reqt_links(docxml)
86
108
  docxml.xpath("//requirement | //recommendation | //permission")
87
- .each_with_object({ id: {}, class: {} }) do |r, m|
109
+ .each_with_object({ id: {}, class: {}, label: {} }) do |r, m|
88
110
  next if nested_reqt?(r)
89
111
 
90
112
  reqt_links1(r, m)
@@ -93,20 +115,30 @@ module Metanorma
93
115
 
94
116
  def reqt_links1(reqt, hash)
95
117
  type = type2validate(reqt)
96
- hash[:id][reqt["id"]] = reqt_links_struct(reqt)
118
+ a = reqt_links_struct(reqt)
119
+ hash[:id][reqt["id"]] = a
97
120
  hash[:class][type] ||= []
98
- hash[:class][type] << hash[:id][reqt["id"]]
121
+ hash[:class][type] << a
122
+ hash[:label][a[:label]] = reqt["id"]
99
123
  hash
100
124
  end
101
125
 
126
+ def classif_tag(reqt, tag)
127
+ reqt.xpath("./classification[tag][value]")
128
+ .each_with_object([]) do |c, m|
129
+ c.at("./tag").text.casecmp(tag).zero? or next
130
+ m << c.at("./value").text
131
+ end
132
+ end
133
+
102
134
  def reqt_links_struct(reqt)
103
135
  { id: reqt["id"], elem: reqt, label: reqt.at("./identifier")&.text,
104
- subject: reqt.xpath("./classification[tag = 'target']/value")
105
- .map(&:text),
136
+ subject: classif_tag(reqt, "target"),
106
137
  child: reqt.xpath("./requirement | ./recommendation | ./permission")
107
- .map do |r|
108
- r.at("./identifier")&.text
109
- end }
138
+ .map { |r| r.at("./identifier")&.text },
139
+ dependency: reqt.xpath("./inherit").map(&:text),
140
+ indirect_dependency: classif_tag(reqt, "indirect-dependency"),
141
+ implements: classif_tag(reqt, "implements") }
110
142
  end
111
143
  end
112
144
  end
@@ -3,39 +3,54 @@ module Metanorma
3
3
  class Modspec < Default
4
4
  def req_class_paths
5
5
  [
6
- { klass: "permissionclass", label: @labels["modspec"]["permissionclass"],
6
+ { klass: "permissionclass",
7
+ label: @labels["modspec"]["permissionclass"],
7
8
  xpath: "permission[@type = 'class']" },
8
- { klass: "requirementclass", label: @labels["modspec"]["requirementclass"],
9
+ { klass: "requirementclass",
10
+ label: @labels["modspec"]["requirementclass"],
9
11
  xpath: "requirement[@type = 'class']" },
10
- { klass: "recommendationclass", label: @labels["modspec"]["recommendationclass"],
12
+ { klass: "recommendationclass",
13
+ label: @labels["modspec"]["recommendationclass"],
11
14
  xpath: "recommendation[@type = 'class']" },
12
- { klass: "permissiontest", label: @labels["modspec"]["conformancetest"],
15
+ { klass: "permissiontest",
16
+ label: @labels["modspec"]["conformancetest"],
13
17
  xpath: "permission[@type = 'verification']" },
14
- { klass: "recommendationtest", label: @labels["modspec"]["conformancetest"],
18
+ { klass: "recommendationtest",
19
+ label: @labels["modspec"]["conformancetest"],
15
20
  xpath: "recommendation[@type = 'verification']" },
16
- { klass: "requirementtest", label: @labels["modspec"]["conformancetest"],
21
+ { klass: "requirementtest",
22
+ label: @labels["modspec"]["conformancetest"],
17
23
  xpath: "requirement[@type = 'verification']" },
18
- { klass: "abstracttest", label: @labels["modspec"]["abstracttest"],
24
+ { klass: "abstracttest",
25
+ label: @labels["modspec"]["abstracttest"],
19
26
  xpath: "permission[@type = 'abstracttest']" },
20
- { klass: "abstracttest", label: @labels["modspec"]["abstracttest"],
27
+ { klass: "abstracttest",
28
+ label: @labels["modspec"]["abstracttest"],
21
29
  xpath: "requirement[@type = 'abstracttest']" },
22
- { klass: "abstracttest", label: @labels["modspec"]["abstracttest"],
30
+ { klass: "abstracttest",
31
+ label: @labels["modspec"]["abstracttest"],
23
32
  xpath: "recommendation[@type = 'abstracttest']" },
24
- { klass: "conformanceclass", label: @labels["modspec"]["conformanceclass"],
33
+ { klass: "conformanceclass",
34
+ label: @labels["modspec"]["conformanceclass"],
25
35
  xpath: "permission[@type = 'conformanceclass']" },
26
- { klass: "conformanceclass", label: @labels["modspec"]["conformanceclass"],
36
+ { klass: "conformanceclass",
37
+ label: @labels["modspec"]["conformanceclass"],
27
38
  xpath: "requirement[@type = 'conformanceclass']" },
28
- { klass: "conformanceclass", label: @labels["modspec"]["conformanceclass"],
39
+ { klass: "conformanceclass",
40
+ label: @labels["modspec"]["conformanceclass"],
29
41
  xpath: "recommendation[@type = 'conformanceclass']" },
30
- { klass: "permission", label: @labels["default"]["permission"],
31
- xpath: "permission[not(@type = 'verification' or @type = 'class' "\
42
+ { klass: "permission",
43
+ label: @labels["default"]["permission"],
44
+ xpath: "permission[not(@type = 'verification' or @type = 'class' " \
32
45
  "or @type = 'abstracttest' or @type = 'conformanceclass')]" },
33
- { klass: "recommendation", label: @labels["default"]["recommendation"],
34
- xpath: "recommendation[not(@type = 'verification' or "\
35
- "@type = 'class' or @type = 'abstracttest' or "\
46
+ { klass: "recommendation",
47
+ label: @labels["default"]["recommendation"],
48
+ xpath: "recommendation[not(@type = 'verification' or " \
49
+ "@type = 'class' or @type = 'abstracttest' or " \
36
50
  "@type = 'conformanceclass')]" },
37
- { klass: "requirement", label: @labels["default"]["requirement"],
38
- xpath: "requirement[not(@type = 'verification' or @type = 'class' "\
51
+ { klass: "requirement",
52
+ label: @labels["default"]["requirement"],
53
+ xpath: "requirement[not(@type = 'verification' or @type = 'class' " \
39
54
  "or @type = 'abstracttest' or @type = 'conformanceclass')]" },
40
55
  ]
41
56
  end
@@ -14,8 +14,9 @@ module Metanorma
14
14
  @i18n = i18n_klass(options[:lang] || "en",
15
15
  options[:script] || "Latn",
16
16
  options[:locale],
17
- options[:i18nhash])
18
- @labels = @i18n.get.deep_merge(options[:labels] || {})["requirements"]
17
+ options[:labels])
18
+ # @labels = @i18n.get.deep_merge(options[:labels] || {})["requirements"]
19
+ @labels = @i18n.get["requirements"]
19
20
  @models =
20
21
  model_names.each_with_object({}) { |k, m| m[k] = create(k) }
21
22
  end
@@ -1,5 +1,5 @@
1
1
  module Metanorma
2
2
  class Requirements
3
- VERSION = "0.1.8".freeze
3
+ VERSION = "0.2.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.1.8
4
+ version: 0.2.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: 2022-10-05 00:00:00.000000000 Z
11
+ date: 2022-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: isodoc-i18n
@@ -230,6 +230,7 @@ files:
230
230
  - lib/metanorma/modspec/isodoc.rb
231
231
  - lib/metanorma/modspec/modspec.rb
232
232
  - lib/metanorma/modspec/reqt_label.rb
233
+ - lib/metanorma/modspec/table_cleanup.rb
233
234
  - lib/metanorma/modspec/validate.rb
234
235
  - lib/metanorma/modspec/xrefs.rb
235
236
  - lib/metanorma/requirements/selector.rb