mn-requirements 0.1.7 → 0.1.9

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: c2e26c223fccd1addd079ca0f89fe9fad9f81e7fa1e43c4607245cb95e5c3292
4
- data.tar.gz: f6765320c97a6a49b164973d39084b72b57206f4a8b3e9eeb86a3835df1cbad0
3
+ metadata.gz: 835ebdf2e3bbc0dea0c8eb3103e3aebe23f896d9610a99a1ddafc45b3e7953f2
4
+ data.tar.gz: 984be6317de16bd417ae59c7645ba970a32ba2add0261679c683560a01c5476c
5
5
  SHA512:
6
- metadata.gz: 4eb0f1c8d3782eea7066f71809ee2ac05d5cc7d6fa470dee2054c4a4154cb08eda814b5fcc2241cdbe345b3f149b15a0152a2daa76d5fb5df4c1ce41b26cb6e4
7
- data.tar.gz: 76b1638cdc8a99eb7d6ff2fdfd321fff08fe64bf40b07a2b5ec46aecc7a1110a2feee171b25b334a6b468ab4636056511ad002aec3e78ba67c63d1d3f4ee3cc7
6
+ metadata.gz: 1fd6e0090c521fa3817505429b75ec281e1f801257143f675ec82eb90eea20d0a2848aff92fa9d13f95dde5ddf5b9bee11e15f5b919bf779b8ed1fbf2f6305fe
7
+ data.tar.gz: c7c3fabad721fa9c88e738bce338105b2b856de8747c60aee62b8cfc0e39e7c140afc328697c4f668f13704afc96ad896a5f61f96914e2fc0644b6e61b659ad9
data/Gemfile CHANGED
@@ -9,5 +9,3 @@ gemspec
9
9
  if File.exist? "Gemfile.devel"
10
10
  eval File.read("Gemfile.devel"), nil, "Gemfile.devel" # rubocop:disable Security/Eval
11
11
  end
12
-
13
- gem "isodoc", "~> 2.2.3.1"
@@ -20,9 +20,25 @@ 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
28
  guidance: إرشاد
29
+ implements: تنفذ
30
+ provision: بيان المعياري
31
+ inflection:
32
+ بيان المعياري:
33
+ sg: بيان المعياري
34
+ pl: البيانات المعيارية
35
+ اختبار المطابقة:
36
+ sg: اختبار المطابقة
37
+ pl: اختبارات المطابقة
38
+ المتطلبات المسبقة:
39
+ sg: المتطلبات المسبقة
40
+ pl: المتطلبات الأساسية
41
+ شرط مسبق غير مباشر:
42
+ sg: شرط مسبق غير مباشر
43
+ pl: المتطلبات الأساسية غير المباشرة
44
+
@@ -20,10 +20,24 @@ 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
28
  guidance: Anleitung
29
-
29
+ implements: Implementiert
30
+ provision: Normative Aussage
31
+ inflection:
32
+ Normative Aussage:
33
+ sg: Normative Aussage
34
+ pl: Normative Aussagen
35
+ Conformance test:
36
+ sg: Konformitätstest
37
+ pl: Konformitätstests
38
+ Voraussetzung:
39
+ sg: Voraussetzung
40
+ pl: Voraussetzungen
41
+ Indirekte Voraussetzung:
42
+ sg: Indirekte Voraussetzung
43
+ pl: Indirekte Voraussetzungen
@@ -20,10 +20,27 @@ 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
28
  guidance: Guidance
29
-
29
+ implements: Implements
30
+ provision: Normative statement
31
+ inflection:
32
+ Normative statement:
33
+ sg: Normative statement
34
+ pl: Normative statements
35
+ Conformance test:
36
+ sg: Conformance test
37
+ pl: Conformance tests
38
+ Statement:
39
+ sg: Statement
40
+ pl: Statements
41
+ Prerequisite:
42
+ sg: Prerequisite
43
+ pl: Prerequisites
44
+ Indirect prerequisite:
45
+ sg: Indirect prerequisite
46
+ pl: Indirect prerequisites
@@ -20,9 +20,28 @@ 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
28
  guidance: Orientación
29
+ implements: Implementa
30
+ provision: Declaración normativa
31
+ inflection:
32
+ Declaración normativa:
33
+ sg: Declaración normativa
34
+ pl: Declaraciones normativas
35
+ Prueba de conformidad:
36
+ sg: Prueba de conformidad
37
+ pl: Pruebas de conformidad
38
+ Déclaration:
39
+ sg: Déclaration
40
+ pl: Déclarations
41
+ Prérequis:
42
+ sg: Prérequis
43
+ pl: Prérequis
44
+ Dépendance indirecte:
45
+ sg: Prérequis indirect
46
+ pl: Prérequis indirects
47
+
@@ -20,10 +20,28 @@ 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
28
  guidance: Avis
29
+ implements: Implémente
30
+ provision: Déclaration normative
31
+ inflection:
32
+ Déclaration normative:
33
+ sg: Déclaration normative
34
+ pl: Déclarations normatives
35
+ Test de conformité:
36
+ sg: Tests de conformité
37
+ pl: Tests de conformité
38
+ Déclaration:
39
+ sg: Déclaration
40
+ pl: Déclarations
41
+ Prérequis:
42
+ sg: Prérequis
43
+ pl: Prérequis
44
+ Dépendance indirecte:
45
+ sg: Prérequis indirect
46
+ pl: Prérequis indirects
29
47
 
@@ -20,10 +20,28 @@ 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
28
  guidance: Руководство
29
+ implements: Реализует
30
+ provision: Нормативное положение
31
+ inflection:
32
+ Нормативное положение:
33
+ sg: Нормативное положение
34
+ pl: Нормативные положения
35
+ Проверка на соответствие:
36
+ sg: Проверка на соответствие
37
+ pl: Проверки на соответствие
38
+ Утверждение:
39
+ sg: Утверждение
40
+ pl: Утверждения
41
+ Условие:
42
+ sg: Условие
43
+ pl: Условия
44
+ Косвенное условие:
45
+ sg: Косвенное условие
46
+ pl: Косвенное условия
29
47
 
@@ -20,10 +20,11 @@ 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
28
  guidance: 指导意见
29
-
29
+ implements: 它实现
30
+ 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
@@ -45,12 +45,12 @@ module Metanorma
45
45
  label, title, name = recommendation_labels(node)
46
46
  ret = name ? [name] : []
47
47
  if label || title
48
- ret << l10n(":") unless ret.empty?
48
+ ret << ":" unless ret.empty?
49
49
  ret += ["<br/>", label]
50
- ret << l10n(". ") if label && title
50
+ ret << ". " if label && title
51
51
  ret << title
52
52
  end
53
- out << "<name>#{ret.compact.join}</name>"
53
+ out << "<name>#{l10n(ret.compact.join)}</name>"
54
54
  out
55
55
  end
56
56
 
@@ -76,7 +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
- "#{tag.text.capitalize}: #{value.children.to_xml}"
79
+ l10n("#{Metanorma::Utils.strict_capitalize_first tag.text}: " \
80
+ "#{value.children.to_xml}")
80
81
  end
81
82
 
82
83
  def recommendation_attributes(node, out)
@@ -49,9 +49,17 @@ module Metanorma
49
49
  requirement_metadata1(val, d, d)
50
50
  d.remove
51
51
  end
52
- requirement_metadata_requirement_tags.include?(term.text) &&
53
- !val.text.empty? and
52
+ requirement_metadata_requirement_tags.include?(term.text) or
53
+ return val
54
+ requirement_metadata1_component_val2id(val)
55
+ end
56
+
57
+ def requirement_metadata1_component_val2id(val)
58
+ if val.at(".//link") && val.text.strip.empty?
59
+ val.children = "<identifier>#{val.at('.//link')['target']}</identifier>"
60
+ elsif !val.text.strip.empty?
54
61
  val.children = "<identifier>#{val.text.strip}</identifier>"
62
+ end
55
63
  val
56
64
  end
57
65
 
@@ -66,7 +74,10 @@ module Metanorma
66
74
  end
67
75
 
68
76
  def requirement_target_identifiers(reqt)
69
- 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]")
70
81
  v.children = v.at("./link/@target").text
71
82
  end
72
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
@@ -7,7 +8,7 @@ module Metanorma
7
8
  def requirement_render1(node)
8
9
  init_lookups(node.document)
9
10
  ret = requirement_guidance_parse(node, super)
10
- requirement_table_cleanup(ret)
11
+ requirement_table_cleanup(node, ret)
11
12
  end
12
13
 
13
14
  def recommendation_base(node, _klass)
@@ -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
@@ -52,23 +53,23 @@ module Metanorma
52
53
  return ret unless title &&
53
54
  node.ancestors("requirement, recommendation, permission").empty?
54
55
 
55
- ret += l10n(": ") unless !name || name.text.empty?
56
+ ret += ": " unless !name || name.text.empty?
56
57
  ret += title.children.to_xml
57
- ret
58
+ l10n(ret)
58
59
  end
59
60
 
60
61
  def recommendation_attributes(node, out)
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
+ out.add_child("<tr><td scope='colgroup' colspan='2'>" \
72
73
  "<tt>#{label.children.to_xml}</tt></td>")
73
74
  end
74
75
 
@@ -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,8 +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
155
- [tag.text.capitalize, value.children]
165
+ !%w(target indirect-dependency implements).include?(tag.text.downcase) or
166
+ return nil
167
+ [Metanorma::Utils.strict_capitalize_first(tag.text), value.children]
156
168
  end
157
169
 
158
170
  def reqt_component_type(node)
@@ -181,7 +193,7 @@ module Metanorma
181
193
  def requirement_guidance_parse(node, out)
182
194
  ins = out.at(ns("./tbody"))
183
195
  node.xpath(ns("./component[@class = 'guidance']")).each do |f|
184
- ins << "<tr#{id_attr(f)}><td>#{@labels['modspec']['guidance']}</td>"\
196
+ ins << "<tr#{id_attr(f)}><th>#{@labels['modspec']['guidance']}</th>" \
185
197
  "<td>#{f.children}</td></tr>"
186
198
  end
187
199
  out
@@ -191,20 +203,12 @@ module Metanorma
191
203
  node.xpath(ns("./dt")).each do |dt|
192
204
  dd = dt.next_element
193
205
  dd&.name == "dd" or next
194
- out.add_child("<tr><td>#{dt.children.to_xml}</td>"\
206
+ out.add_child("<tr><th>#{dt.children.to_xml}</th>" \
195
207
  "<td>#{dd.children.to_xml}</td></tr>")
196
208
  end
197
209
  out
198
210
  end
199
211
 
200
- def requirement_table_cleanup(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
212
  def rec_subj(node)
209
213
  case node["type"]
210
214
  when "class" then @labels["modspec"]["targettype"]
@@ -48,7 +48,7 @@ module Metanorma
48
48
 
49
49
  def recommendation_class_label(node)
50
50
  case node["type"]
51
- when "verification" then @labels["modspec"]["#{node.name}test"]
51
+ when "verification" then @labels["modspec"]["conformancetest"]
52
52
  when "class" then @labels["modspec"]["#{node.name}class"]
53
53
  when "abstracttest" then @labels["modspec"]["abstracttest"]
54
54
  when "conformanceclass" then @labels["modspec"]["conformanceclass"]
@@ -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,22 @@ 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
119
145
  end
120
146
  end
121
147
  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,11 +22,13 @@ 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)
28
29
  type = reqt["type"]
29
30
  type = "general" if type.nil? || type.empty?
31
+ type = "verification" if type == "abstracttest"
30
32
  type
31
33
  end
32
34
 
@@ -35,12 +37,33 @@ module Metanorma
35
37
  verification: "Conformance test",
36
38
  class: "Requirement class",
37
39
  conformanceclass: "Conformance class",
40
+ provision: "Provision",
41
+ dependency: "Prerequisite",
42
+ indirect_dependency: "Indirect prerequisite",
43
+ implements: "Implemented provision",
38
44
  }.freeze
39
45
 
40
46
  def log_reqt(reqt, leftclass, rightclass)
41
- @log.add("Requirements", reqt[:elem],
42
- "#{CLASS2LABEL[leftclass.to_sym]} #{reqt[:label] || reqt[:id]} "\
43
- "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
44
67
  end
45
68
 
46
69
  def reqt_to_conformance(reqt, reqtclass, confclass)
@@ -48,7 +71,7 @@ module Metanorma
48
71
 
49
72
  r = @ids[:id][reqt["id"]]
50
73
  (r[:label] && @ids[:class][confclass]&.any? do |x|
51
- x[:subject] == r[:label]
74
+ x[:subject].include?(r[:label])
52
75
  end) and return
53
76
  log_reqt(r, reqtclass, confclass)
54
77
  end
@@ -58,7 +81,7 @@ module Metanorma
58
81
 
59
82
  r = @ids[:id][reqt["id"]]
60
83
  (r[:subject] && @ids[:class][reqtclass]&.any? do |x|
61
- r[:subject] == x[:label]
84
+ r[:subject].include?(x[:label])
62
85
  end) and return
63
86
  log_reqt(r, confclass, reqtclass)
64
87
  end
@@ -83,7 +106,7 @@ module Metanorma
83
106
 
84
107
  def reqt_links(docxml)
85
108
  docxml.xpath("//requirement | //recommendation | //permission")
86
- .each_with_object({ id: {}, class: {} }) do |r, m|
109
+ .each_with_object({ id: {}, class: {}, label: {} }) do |r, m|
87
110
  next if nested_reqt?(r)
88
111
 
89
112
  reqt_links1(r, m)
@@ -92,19 +115,30 @@ module Metanorma
92
115
 
93
116
  def reqt_links1(reqt, hash)
94
117
  type = type2validate(reqt)
95
- hash[:id][reqt["id"]] = reqt_links_struct(reqt)
118
+ a = reqt_links_struct(reqt)
119
+ hash[:id][reqt["id"]] = a
96
120
  hash[:class][type] ||= []
97
- hash[:class][type] << hash[:id][reqt["id"]]
121
+ hash[:class][type] << a
122
+ hash[:label][a[:label]] = reqt["id"]
98
123
  hash
99
124
  end
100
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
+
101
134
  def reqt_links_struct(reqt)
102
135
  { id: reqt["id"], elem: reqt, label: reqt.at("./identifier")&.text,
103
- subject: reqt.at("./classification[tag = 'target']/value")&.text,
136
+ subject: classif_tag(reqt, "target"),
104
137
  child: reqt.xpath("./requirement | ./recommendation | ./permission")
105
- .map do |r|
106
- r.at("./identifier")&.text
107
- 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") }
108
142
  end
109
143
  end
110
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"]["permissiontest"],
15
+ { klass: "permissiontest",
16
+ label: @labels["modspec"]["conformancetest"],
13
17
  xpath: "permission[@type = 'verification']" },
14
- { klass: "recommendationtest", label: @labels["modspec"]["recommendationtest"],
18
+ { klass: "recommendationtest",
19
+ label: @labels["modspec"]["conformancetest"],
15
20
  xpath: "recommendation[@type = 'verification']" },
16
- { klass: "requirementtest", label: @labels["modspec"]["requirementtest"],
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.7".freeze
3
+ VERSION = "0.1.9".freeze
4
4
  end
5
5
  end
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.require_paths = ["lib"]
25
25
  spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
26
26
 
27
- spec.add_dependency "isodoc-i18n", "~> 1.1.0"
27
+ spec.add_dependency "isodoc-i18n", "~> 1.1.2"
28
28
  spec.add_dependency "metanorma-utils", "~> 1.4.0"
29
29
 
30
30
  spec.add_development_dependency "debug"
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.7
4
+ version: 0.1.9
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-09-25 00:00:00.000000000 Z
11
+ date: 2022-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: isodoc-i18n
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.1.0
19
+ version: 1.1.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.1.0
26
+ version: 1.1.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: metanorma-utils
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -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