metanorma-standoc 2.2.0.1 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/lib/metanorma/standoc/base.rb +12 -0
  3. data/lib/metanorma/standoc/blocks.rb +26 -13
  4. data/lib/metanorma/standoc/cleanup_biblio.rb +14 -8
  5. data/lib/metanorma/standoc/cleanup_reqt.rb +3 -136
  6. data/lib/metanorma/standoc/front_contributor.rb +0 -10
  7. data/lib/metanorma/standoc/reqt.rb +19 -75
  8. data/lib/metanorma/standoc/section.rb +35 -3
  9. data/lib/metanorma/standoc/utils.rb +9 -43
  10. data/lib/metanorma/standoc/version.rb +1 -1
  11. data/metanorma-standoc.gemspec +2 -2
  12. data/spec/metanorma/biblio_spec.rb +8 -8
  13. data/spec/metanorma/blocks_spec.rb +20 -266
  14. data/spec/metanorma/cleanup_blocks_spec.rb +0 -168
  15. data/spec/metanorma/macros_concept_spec.rb +1033 -0
  16. data/spec/metanorma/macros_spec.rb +0 -1030
  17. data/spec/metanorma/reqt_spec.rb +130 -0
  18. data/spec/metanorma/section_spec.rb +5 -0
  19. data/spec/vcr_cassettes/bsi16341.yml +52 -36
  20. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +88 -88
  21. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +10 -10
  22. data/spec/vcr_cassettes/hide_refs.yml +65 -65
  23. data/spec/vcr_cassettes/isobib_get_123.yml +12 -12
  24. data/spec/vcr_cassettes/isobib_get_123_1.yml +22 -22
  25. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +30 -30
  26. data/spec/vcr_cassettes/isobib_get_123_2.yml +21 -21
  27. data/spec/vcr_cassettes/isobib_get_123_2001.yml +11 -11
  28. data/spec/vcr_cassettes/isobib_get_124.yml +11 -11
  29. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +34 -58
  30. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +45 -45
  31. data/spec/vcr_cassettes/std-link.yml +11 -11
  32. metadata +9 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e6a6d6a98133ba0cf81631287aff2157906da7d0978899abe5c00c78f0da6b2d
4
- data.tar.gz: 81c33e16f952e56dcff81bd0485ead5ba998839b307e30eb8de500bf2448a600
3
+ metadata.gz: 837bde4e0b1dcb3e1eeb5ffa7c56d063456f4a4cb3666eb00c18aaf6cae7d164
4
+ data.tar.gz: 69dcdc35a59b471bb2c6ac3cfd52a84b15625a45402c66f83c9e1ec70296b4f3
5
5
  SHA512:
6
- metadata.gz: b36c1f1766233c69f9b5a63298d8f7cd8745cac7f7186f210500bc23a27983b3202a724ebd799f6d305b928377ed5d2ef28dcb43aac4e9c91f65b9300a98ac19
7
- data.tar.gz: e4b1be10928b81269486083791e7dd23fab26b2697d1b1a82fa607dfa4c6f46a00bdc4373403605c2807a993ab2f4015f34f643607610d10344cfbd95a6a83b3
6
+ metadata.gz: 88ff22adce3bd32d0c2875acf926520a4950beb6e36e3b7e70cd7ffce68c75869fac1e6449ea0b975d2c87a2cce1b2d0e2898f7d7c29d30065abf6708df863f8
7
+ data.tar.gz: 86493fb18c13786a09a019a9a184684d90c19957c4154f01f13acd4d4b5cb1e7999cc8f0d0413f0b10ea870e676ab2bbe3e78cacc848a9799e0f9b5189d1efe3
@@ -9,6 +9,7 @@ require "fileutils"
9
9
  require "metanorma-utils"
10
10
  require "isodoc/xslfo_convert"
11
11
  require_relative "render"
12
+ require "mn-requirements"
12
13
 
13
14
  module Metanorma
14
15
  module Standoc
@@ -29,6 +30,7 @@ module Metanorma
29
30
  init_vars
30
31
  init_misc(node)
31
32
  init_processing(node)
33
+ init_reqt(node)
32
34
  init_toc(node)
33
35
  init_output(node)
34
36
  init_i18n(node)
@@ -42,7 +44,10 @@ module Metanorma
42
44
  @anchors = {}
43
45
  @internal_eref_namespaces = []
44
46
  @seen_headers = []
47
+ @seen_headers_canonical = []
45
48
  @embed_hdr = []
49
+ @reqt_model = nil
50
+ @preface = true
46
51
  end
47
52
 
48
53
  def init_misc(node)
@@ -63,6 +68,13 @@ module Metanorma
63
68
  @datauriimage = node.attr("data-uri-image") != "false"
64
69
  end
65
70
 
71
+ def init_reqt(node)
72
+ @default_requirement_model = (node.attr("requirements-model") ||
73
+ default_requirement_model)
74
+ @reqt_models = Metanorma::Requirements
75
+ .new({ default: @default_requirement_model })
76
+ end
77
+
66
78
  def init_toc(node)
67
79
  @htmltoclevels = node.attr("htmltoclevels")
68
80
  @doctoclevels = node.attr("doctoclevels")
@@ -15,7 +15,8 @@ module Metanorma
15
15
  attr_code(id_attr(node).merge(
16
16
  unnumbered: node.option?("unnumbered") ? "true" : nil,
17
17
  number: node.attr("number"),
18
- subsequence: node.attr("subsequence")))
18
+ subsequence: node.attr("subsequence"),
19
+ ))
19
20
  end
20
21
 
21
22
  def formula_attrs(node)
@@ -33,7 +34,7 @@ module Metanorma
33
34
  # We append each contained block to its parent
34
35
  def open(node)
35
36
  role = node.role || node.attr("style")
36
- reqt_subpart(role) and return requirement_subpart(node)
37
+ reqt_subpart?(role) and return requirement_subpart(node)
37
38
  role == "form" and return form(node)
38
39
  role == "definition" and return termdefinition(node)
39
40
  result = []
@@ -87,21 +88,33 @@ module Metanorma
87
88
  end
88
89
 
89
90
  def example(node)
90
- return term_example(node) if in_terms? || node.option?("termexample")
91
-
91
+ (in_terms? || node.option?("termexample")) and return term_example(node)
92
92
  role = node.role || node.attr("style")
93
- %w(recommendation requirement permission).include?(role) and
94
- return requirement(node, role)
95
- return pseudocode_example(node) if role == "pseudocode"
96
- return svgmap_example(node) if role == "svgmap"
97
- return form(node) if role == "form"
98
- return termdefinition(node) if role == "definition"
99
- return figure_example(node) if role == "figure"
100
-
101
- reqt_subpart(role) and return requirement_subpart(node)
93
+ ret = example_to_requirement(node, role) ||
94
+ example_by_role(node, role) and return ret
95
+ reqt_subpart?(role) and return requirement_subpart(node)
102
96
  example_proper(node)
103
97
  end
104
98
 
99
+ def example_by_role(node, role)
100
+ case role
101
+ when "pseudocode" then pseudocode_example(node)
102
+ when "svgmap" then svgmap_example(node)
103
+ when "form" then form(node)
104
+ when "definition" then termdefinition(node)
105
+ when "figure" then figure_example(node)
106
+ end
107
+ end
108
+
109
+ def example_to_requirement(node, role)
110
+ return unless @reqt_models.requirement_roles.key?(role&.to_sym)
111
+
112
+ # need to call here for proper recursion ordering
113
+ select_requirement_model(node)
114
+ requirement(node,
115
+ @reqt_models.requirement_roles[role.to_sym], role)
116
+ end
117
+
105
118
  def svgmap_attrs(node)
106
119
  attr_code(id_attr(node)
107
120
  .merge(id: node.id, number: node.attr("number"),
@@ -145,7 +145,7 @@ module Metanorma
145
145
  when "publisher"
146
146
  ret[:contributor] << { role: "publisher", entity: "organization",
147
147
  name: s[:val] }
148
- when "surname", "initials", "givenname"
148
+ when "surname", "initials", "givenname", "formatted-initials"
149
149
  ret[:contributor] = spans_preprocess_contrib(s, ret[:contributor])
150
150
  end
151
151
  end
@@ -153,6 +153,8 @@ module Metanorma
153
153
  end
154
154
 
155
155
  def spans_preprocess_contrib(span, contrib)
156
+ span[:key] = "formatted-initials" if span[:key] == "initials"
157
+
156
158
  spans_preprocess_new_contrib?(span, contrib) and
157
159
  contrib << { role: span[:type] || "author", entity: "person" }
158
160
  contrib[-1][span[:key].to_sym] = span[:val]
@@ -162,7 +164,7 @@ module Metanorma
162
164
  def spans_preprocess_new_contrib?(span, contrib)
163
165
  contrib.empty? ||
164
166
  (if span[:key] == "surname" then contrib[-1][:surname]
165
- else (contrib[-1][:initials] || contrib[-1][:givenname])
167
+ else (contrib[-1][:"formatted-initials"] || contrib[-1][:givenname])
166
168
  end) ||
167
169
  contrib[-1][:role] != (span[:type] || "author")
168
170
  end
@@ -190,15 +192,19 @@ module Metanorma
190
192
  def span_to_contrib(span)
191
193
  e = if span[:entity] == "organization"
192
194
  "<organization><name>#{span[:name]}</name></organization>"
193
- else
194
- pre = (span[:initials] and
195
- "<initial>#{span[:initials]}</initial>") ||
196
- "<forename>#{span[:givenname]}</forename>"
197
- "<person><name>#{pre}<surname>#{span[:surname]}</surname></name>"\
198
- "</person>"
195
+ else span_to_person(span)
199
196
  end
200
197
  "<contributor><role type='#{span[:role]}'/>#{e}</contributor>"
201
198
  end
199
+
200
+ def span_to_person(span)
201
+ pre = (span[:"formatted-initials"] and
202
+ "<formatted-initials>"\
203
+ "#{span[:"formatted-initials"]}</formatted-initials>") ||
204
+ "<forename>#{span[:givenname]}</forename>"
205
+ "<person><name>#{pre}<surname>#{span[:surname]}</surname></name>"\
206
+ "</person>"
207
+ end
202
208
  end
203
209
  end
204
210
  end
@@ -2,142 +2,9 @@ module Metanorma
2
2
  module Standoc
3
3
  module Cleanup
4
4
  def requirement_cleanup(xmldoc)
5
- requirement_metadata(xmldoc)
6
- requirement_inherit(xmldoc)
7
- requirement_descriptions(xmldoc)
8
- requirement_identifier(xmldoc)
9
- end
10
-
11
- REQRECPER = "//requirement | //recommendation | //permission".freeze
12
-
13
- def requirement_identifier(xmldoc)
14
- xmldoc.xpath(REQRECPER).each do |r|
15
- r.xpath("./identifier[link] | ./inherit[link]").each do |i|
16
- i.children = i.at("./link/@target").text
17
- end
18
- end
19
- end
20
-
21
- def requirement_inherit(xmldoc)
22
- xmldoc.xpath(REQRECPER).each do |r|
23
- ins = requirement_inherit_insert(r)
24
- r.xpath("./*//inherit").each { |i| ins.previous = i }
25
- end
26
- end
27
-
28
- def requirement_inherit_insert(reqt)
29
- ins = reqt.at("./classification") || reqt.at(
30
- "./description | ./measurementtarget | ./specification | "\
31
- "./verification | ./import | ./description | ./component | "\
32
- "./requirement | ./recommendation | ./permission",
33
- ) and return ins
34
- requirement_inherit_insert1(reqt)
35
- end
36
-
37
- def requirement_inherit_insert1(reqt)
38
- if t = reqt.at("./title")
39
- t.next = " "
40
- t.next
41
- else
42
- if reqt.children.empty? then reqt.add_child(" ")
43
- else reqt.children.first.previous = " "
44
- end
45
- reqt.children.first
46
- end
47
- end
48
-
49
- def requirement_descriptions(xmldoc)
50
- xmldoc.xpath(REQRECPER).each do |r|
51
- r.xpath(".//p[not(./*)][normalize-space(.)='']").each(&:remove)
52
- r.children.each do |e|
53
- requirement_description_wrap(r, e)
54
- end
55
- requirement_description_cleanup1(r)
56
- end
57
- end
58
-
59
- def requirement_description_wrap(reqt, text)
60
- return if (text.element? && (reqt_subpart(text.name) ||
61
- %w(requirement recommendation
62
- permission).include?(text.name))) ||
63
- (text.text.strip.empty? && !text.at(".//xref | .//eref | .//link"))
64
-
65
- t = Nokogiri::XML::Element.new("description", reqt.document)
66
- text.before(t)
67
- t.children = text.remove
68
- end
69
-
70
- def requirement_description_cleanup1(reqt)
71
- while d = reqt.at("./description[following-sibling::*[1]"\
72
- "[self::description]]")
73
- n = d.next.remove
74
- d << n.children
75
- end
76
- reqt.xpath("./description[normalize-space(.)='']").each do |r|
77
- r.replace("\n")
78
- end
79
- end
80
-
81
- def requirement_metadata(xmldoc)
82
- xmldoc.xpath(REQRECPER).each do |r|
83
- dl = r&.at("./dl[@metadata = 'true']")&.remove or next
84
- requirement_metadata1(r, dl, r.at("./title"))
85
- end
86
- end
87
-
88
- def requirement_metadata1_attrs
89
- %w(obligation model type)
90
- end
91
-
92
- def requirement_metadata1_tags
93
- %w(identifier subject inherit)
94
- end
95
-
96
- def requirement_metadata_component_tags
97
- []
98
- end
99
-
100
- def requirement_metadata1(reqt, dlist, ins)
101
- unless ins
102
- reqt.children.first.previous = " "
103
- ins = reqt.children.first
104
- end
105
- requirement_metadata1_attrs.each do |a|
106
- dl_to_attrs(reqt, dlist, a)
107
- end
108
- requirement_metadata1_tags.each do |a|
109
- ins = dl_to_elems(ins, reqt, dlist, a)
110
- end
111
- ins = reqt_dl_to_classif(ins, reqt, dlist)
112
- reqt_dl_to_classif1(ins, reqt, dlist)
113
- end
114
-
115
- def reqt_dl_to_classif(ins, reqt, dlist)
116
- if a = reqt.at("./classification[last()]") then ins = a end
117
- dlist.xpath("./dt[text()='classification']").each do |e|
118
- val = e.at("./following::dd/p") || e.at("./following::dd")
119
- req_classif_parse(val.children.to_xml).each do |r|
120
- ins.next = "<classification><tag>#{r[0]}</tag>"\
121
- "<value>#{r[1]}</value></classification>"
122
- ins = ins.next
123
- end
124
- end
125
- ins
126
- end
127
-
128
- def reqt_dl_to_classif1(ins, reqt, dlist)
129
- if a = reqt.at("./classification[last()]") then ins = a end
130
- dlist.xpath("./dt").each do |e|
131
- next if (requirement_metadata1_attrs + requirement_metadata1_tags +
132
- requirement_metadata_component_tags + %w(classification))
133
- .include?(e.text)
134
-
135
- val = e.at("./following::dd/p") || e.at("./following::dd")
136
- ins.next = "<classification><tag>#{e.text}</tag>"\
137
- "<value>#{val.children.to_xml}</value></classification>"
138
- ins = ins.next
139
- end
140
- ins
5
+ @reqt_models ||=
6
+ Metanorma::Requirements.new({ default: @default_requirement_model })
7
+ @reqt_models.requirement_cleanup(xmldoc)
141
8
  end
142
9
  end
143
10
  end
@@ -44,16 +44,6 @@ module Metanorma
44
44
  node.attr("pub-uri") and person.uri node.attr("pub-uri")
45
45
  end
46
46
 
47
- # , " => ," : CSV definition does not deal with space followed by quote
48
- # at start of field
49
- def csv_split(text, delim = ";")
50
- return if text.nil?
51
-
52
- CSV.parse_line(text&.gsub(/#{delim} "(?!")/, "#{delim}\""),
53
- liberal_parsing: true,
54
- col_sep: delim)&.compact&.map(&:strip)
55
- end
56
-
57
47
  def metadata_author(node, xml)
58
48
  csv_split(node.attr("publisher") || default_publisher || "")
59
49
  &.each do |p|
@@ -1,91 +1,35 @@
1
- require "htmlentities"
2
- require "uri" if /^2\./.match?(RUBY_VERSION)
3
- require "mime/types"
4
- require "base64"
5
-
6
1
  module Metanorma
7
2
  module Standoc
8
3
  module Blocks
9
- def reqt_subpart(name)
10
- %w(specification measurement-target verification import identifier title
11
- description component subject inherit classification).include? name
12
- end
13
-
14
- def reqt_subpart_attrs(node, name)
15
- klass = node.attr("class") || "component"
16
- attr_code(keep_attrs(node)
17
- .merge(exclude: node.option?("exclude"),
18
- type: node.attr("type"),
19
- class: name == "component" ? klass : nil))
4
+ def reqt_subpart?(name)
5
+ @reqt_model&.reqt_subpart?(name)
20
6
  end
21
7
 
22
8
  def requirement_subpart(node)
23
- name = node.role || node.attr("style")
24
- noko do |xml|
25
- xml.send name, **reqt_subpart_attrs(node, name) do |o|
26
- o << node.content
27
- end
28
- end
9
+ @reqt_model.requirement_subpart(node, keep_attrs(node))
29
10
  end
30
11
 
31
- def req_classif_parse(classif)
32
- ret = []
33
- @c.decode(classif).split(/;\s*/).each do |c|
34
- c1 = c.split(/:\s*/)
35
- next unless c1.size == 2
36
-
37
- c1[1].split(/,\s*/).each { |v| ret << [c1[0], v] }
38
- end
39
- ret
12
+ def default_requirement_model
13
+ :default
40
14
  end
41
15
 
42
- def requirement_classification(classif, out)
43
- req_classif_parse(classif).each do |r|
44
- out.classification do |c|
45
- c.tag { |t| t << r[0] }
46
- c.value { |v| v << r[1] }
47
- end
48
- end
49
- end
50
-
51
- def reqt_attrs(node)
52
- attr_code(keep_attrs(node).merge(id_unnum_attrs(node)).merge(
53
- id: Metanorma::Utils::anchor_or_uuid(node),
54
- unnumbered: node.option?("unnumbered") ? "true" : nil,
55
- number: node.attr("number"),
56
- subsequence: node.attr("subsequence"),
57
- obligation: node.attr("obligation"),
58
- filename: node.attr("filename"),
59
- type: node.attr("type"),
60
- model: node.attr("model"),
61
- ))
62
- end
16
+ def select_requirement_model(node)
17
+ return if @reqt_model
63
18
 
64
- def requirement_elems(node, out)
65
- node.title and out.title { |t| t << node.title }
66
- a = node.attr("identifier") and out.identifier do |l|
67
- l << out.text(a)
68
- end
69
- a = node.attr("subject") and csv_split(a)&.each do |subj|
70
- out.subject { |s| s << out.text(subj) }
71
- end
72
- a = @c.decode(node.attr("inherit")) and
73
- csv_split(a)&.each do |i|
74
- out.inherit do |inh|
75
- inh << @c.encode(i, :hexadecimal)
76
- end
77
- end
78
- classif = node.attr("classification") and
79
- requirement_classification(classif, out)
19
+ @reqt_model_name = node.attr("model") || @default_requirement_model
20
+ @reqt_model = @reqt_models.model(@reqt_model_name)
80
21
  end
81
22
 
82
- def requirement(node, obligation)
83
- noko do |xml|
84
- xml.send obligation, **reqt_attrs(node) do |ex|
85
- requirement_elems(node, ex)
86
- wrap_in_para(node, ex)
87
- end
88
- end.join("\n")
23
+ def requirement(node, obligation, type)
24
+ nested = @reqt_model
25
+ !node.attr("type") &&
26
+ !%w(requirement recommendation permission).include?(type) and
27
+ node.set_attr("type", type)
28
+ attrs = keep_attrs(node).merge(id_unnum_attrs(node))
29
+ .merge(model: @reqt_model_name)
30
+ ret = @reqt_model.requirement(node, obligation, attrs)
31
+ @reqt_model = nil unless nested
32
+ ret
89
33
  end
90
34
  end
91
35
  end
@@ -10,19 +10,26 @@ module Metanorma
10
10
  @norm_ref = false
11
11
 
12
12
  def sectiontype1(node)
13
+ return "abstract" if node.attr("style") == "abstract"
14
+
13
15
  node&.attr("heading")&.downcase ||
14
- node.title.gsub(%r{<index>.*?</index>}m, "").gsub(/<[^>]+>/, "")
16
+ node.title
17
+ .gsub(%r{<index>.*?</index>}m, "")
18
+ .gsub(%r{<fn[^>]*>.*?</fn>}m, "")
19
+ .gsub(/<[^>]+>/, "")
15
20
  .strip.downcase
21
+ .sub(/\.$/, "")
16
22
  end
17
23
 
18
24
  def sectiontype(node, level = true)
19
25
  ret = sectiontype1(node)
20
- ret1 = sectiontype_streamline(ret)
26
+ ret1 = preface_main_filter(sectiontype_streamline(ret), node)
21
27
  return ret1 if ret1 == "symbols and abbreviated terms"
22
28
  return nil unless !level || node.level == 1
23
29
  return nil if @seen_headers.include? ret
24
30
 
25
- @seen_headers << ret
31
+ @seen_headers << ret unless ret1.nil?
32
+ @seen_headers_canonical << ret1 unless ret1.nil?
26
33
  ret1
27
34
  end
28
35
 
@@ -45,6 +52,31 @@ module Metanorma
45
52
  end
46
53
  end
47
54
 
55
+ PREFACE_CLAUSE_NAMES = %w(abstract foreword introduction
56
+ acknowledgements).freeze
57
+
58
+ MAIN_CLAUSE_NAMES =
59
+ ["normative references", "terms and definitions", "scope",
60
+ "symbols and abbreviated terms", "clause", "bibliography"].freeze
61
+
62
+ def start_main_section(ret, node)
63
+ @preface = false if MAIN_CLAUSE_NAMES.include?(ret) &&
64
+ node.role != "preface" && node.attr("style") != "preface"
65
+ @preface = false if (PREFACE_CLAUSE_NAMES)
66
+ .intersection(@seen_headers_canonical + [ret]).empty?
67
+ end
68
+
69
+ def preface_main_filter(ret, node)
70
+ start_main_section(ret, node)
71
+ if @preface
72
+ self.class::MAIN_CLAUSE_NAMES.include?(ret) and return nil
73
+ else
74
+ self.class::PREFACE_CLAUSE_NAMES.include?(ret) and return nil
75
+ end
76
+
77
+ ret
78
+ end
79
+
48
80
  def section_attributes(node)
49
81
  ret = { id: Metanorma::Utils::anchor_or_uuid(node),
50
82
  language: node.attributes["language"],
@@ -17,43 +17,20 @@ module Metanorma
17
17
  nil
18
18
  end
19
19
 
20
- NOKOHEAD = <<~HERE.freeze
21
- <!DOCTYPE html SYSTEM
22
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
23
- <html xmlns="http://www.w3.org/1999/xhtml">
24
- <head> <title></title> <meta charset="UTF-8" /> </head>
25
- <body> </body> </html>
26
- HERE
27
-
28
- # block for processing XML document fragments as XHTML,
29
- # to allow for HTMLentities
30
- # Unescape special chars used in Asciidoctor substitution processing
31
20
  def noko(&block)
32
- doc = ::Nokogiri::XML.parse(NOKOHEAD)
33
- fragment = doc.fragment("")
34
- ::Nokogiri::XML::Builder.with fragment, &block
35
- fragment.to_xml(encoding: "US-ASCII", indent: 0,
36
- save_with: Nokogiri::XML::Node::SaveOptions::AS_XML)
37
- .lines.map do |l|
38
- l.gsub(/>\n$/, ">").gsub(/\s*\n$/m, " ").gsub("&#150;", "\u0096")
39
- .gsub("&#151;", "\u0097").gsub("&#x96;", "\u0096")
40
- .gsub("&#x97;", "\u0097")
41
- end
21
+ Metanorma::Utils::noko(&block)
42
22
  end
43
23
 
44
24
  def attr_code(attributes)
45
- attributes.compact.transform_values do |v|
46
- v.is_a?(String) ? HTMLEntities.new.decode(v) : v
47
- end
25
+ Metanorma::Utils::attr_code(attributes)
26
+ end
27
+
28
+ def csv_split(text, delim = ";")
29
+ Metanorma::Utils::csv_split(text, delim)
48
30
  end
49
31
 
50
- # if the contents of node are blocks, output them to out;
51
- # else, wrap them in <p>
52
32
  def wrap_in_para(node, out)
53
- if node.blocks? then out << node.content
54
- else
55
- out.p { |p| p << node.content }
56
- end
33
+ Metanorma::Utils::wrap_in_para(node, out)
57
34
  end
58
35
 
59
36
  SUBCLAUSE_XPATH = "//clause[not(parent::sections)]"\
@@ -67,22 +44,11 @@ module Metanorma
67
44
  end
68
45
 
69
46
  def dl_to_attrs(elem, dlist, name)
70
- e = dlist.at("./dt[text()='#{name}']") or return
71
- val = e.at("./following::dd/p") || e.at("./following::dd") or return
72
- elem[name] = val.text
47
+ Metanorma::Utils::dl_to_attrs(elem, dlist, name)
73
48
  end
74
49
 
75
50
  def dl_to_elems(ins, elem, dlist, name)
76
- a = elem.at("./#{name}[last()]")
77
- ins = a if a
78
- dlist.xpath("./dt[text()='#{name}']").each do |e|
79
- v = e.at("./following::dd")
80
- e = v.elements and e.size == 1 && e.first.name == "p" and v = e.first
81
- v.name = name
82
- ins.next = v
83
- ins = ins.next
84
- end
85
- ins
51
+ Metanorma::Utils::dl_to_elems(ins, elem, dlist, name)
86
52
  end
87
53
 
88
54
  def term_expr(elem)
@@ -19,6 +19,6 @@ module Metanorma
19
19
  end
20
20
 
21
21
  module Standoc
22
- VERSION = "2.2.0.1".freeze
22
+ VERSION = "2.2.1".freeze
23
23
  end
24
24
  end
@@ -36,8 +36,8 @@ Gem::Specification.new do |spec|
36
36
  spec.add_dependency "concurrent-ruby"
37
37
  spec.add_dependency "latexmath"
38
38
  spec.add_dependency "mathml2asciimath"
39
- spec.add_dependency "metanorma-utils", "~> 1.2.8"
40
- spec.add_dependency "relaton-cli", "~> 1.12.0"
39
+ spec.add_dependency "mn-requirements", "~> 0.0.1"
40
+ spec.add_dependency "relaton-cli", "~> 1.13.0"
41
41
  spec.add_dependency "relaton-iev", "~> 1.1.0"
42
42
  spec.add_dependency "unicode2latex", "~> 0.0.1"
43
43
 
@@ -235,7 +235,7 @@ RSpec.describe Metanorma::Standoc do
235
235
  person::
236
236
  name:::
237
237
  language:::: en
238
- initial:::: A.
238
+ formatted_initials:::: A.
239
239
  surname:::: Bierman
240
240
  affiliation:::
241
241
  +
@@ -377,8 +377,8 @@ RSpec.describe Metanorma::Standoc do
377
377
  <role type="author"/>
378
378
  <person>
379
379
  <name>
380
- <initial language="en">A.</initial>
381
- <surname language="en">Bierman</surname>
380
+ <formatted-initials>A.</formatted-initials>
381
+ <surname>Bierman</surname>
382
382
  </name>
383
383
  <affiliation>
384
384
  <description language="en" script="Latn">Affiliation description</description>
@@ -590,7 +590,7 @@ RSpec.describe Metanorma::Standoc do
590
590
  contributor.role:: publisher
591
591
  contributor::
592
592
  contributor.person.name.language:: en
593
- contributor.person.name.initial:: A.
593
+ contributor.person.name.formatted_initials:: A.
594
594
  contributor.person.name.surname:: Bierman
595
595
  contributor.person.affiliation.organization.name:: IETF
596
596
  contributor.person.affiliation.organization.abbreviation:: IETF
@@ -706,8 +706,8 @@ RSpec.describe Metanorma::Standoc do
706
706
  <role type="author"/>
707
707
  <person>
708
708
  <name>
709
- <initial language="en">A.</initial>
710
- <surname language="en">Bierman</surname>
709
+ <formatted-initials>A.</formatted-initials>
710
+ <surname>Bierman</surname>
711
711
  </name>
712
712
  <affiliation>
713
713
  <description language="en" script="Latn">Affiliation description</description>
@@ -933,7 +933,7 @@ RSpec.describe Metanorma::Standoc do
933
933
  <role type='author'/>
934
934
  <person>
935
935
  <name>
936
- <initial>S.</initial>
936
+ <formatted-initials>S.</formatted-initials>
937
937
  <surname>Wozniak</surname>
938
938
  </name>
939
939
  </person>
@@ -951,7 +951,7 @@ RSpec.describe Metanorma::Standoc do
951
951
  <role type='editor'/>
952
952
  <person>
953
953
  <name>
954
- <initial>W. H</initial>
954
+ <formatted-initials>W. H</formatted-initials>
955
955
  <surname>Gates</surname>
956
956
  </name>
957
957
  </person>