metanorma-standoc 2.1.5 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/lib/metanorma/standoc/base.rb +13 -0
  3. data/lib/metanorma/standoc/blocks.rb +26 -17
  4. data/lib/metanorma/standoc/cleanup.rb +1 -1
  5. data/lib/metanorma/standoc/cleanup_biblio.rb +210 -0
  6. data/lib/metanorma/standoc/cleanup_block.rb +6 -4
  7. data/lib/metanorma/standoc/cleanup_maths.rb +2 -15
  8. data/lib/metanorma/standoc/cleanup_ref.rb +22 -13
  9. data/lib/metanorma/standoc/cleanup_reqt.rb +3 -103
  10. data/lib/metanorma/standoc/cleanup_symbols.rb +1 -1
  11. data/lib/metanorma/standoc/cleanup_text.rb +10 -8
  12. data/lib/metanorma/standoc/cleanup_xref.rb +1 -2
  13. data/lib/metanorma/standoc/converter.rb +2 -0
  14. data/lib/metanorma/standoc/front.rb +1 -1
  15. data/lib/metanorma/standoc/front_contributor.rb +0 -10
  16. data/lib/metanorma/standoc/inline.rb +8 -4
  17. data/lib/metanorma/standoc/isodoc.rng +6 -1
  18. data/lib/metanorma/standoc/macros.rb +1 -180
  19. data/lib/metanorma/standoc/macros_inline.rb +194 -0
  20. data/lib/metanorma/standoc/ref_sect.rb +2 -2
  21. data/lib/metanorma/standoc/ref_utility.rb +1 -1
  22. data/lib/metanorma/standoc/reqt.rb +19 -75
  23. data/lib/metanorma/standoc/reqt.rng +1 -1
  24. data/lib/metanorma/standoc/section.rb +35 -3
  25. data/lib/metanorma/standoc/utils.rb +9 -43
  26. data/lib/metanorma/standoc/validate.rb +1 -69
  27. data/lib/metanorma/standoc/validate_table.rb +91 -0
  28. data/lib/metanorma/standoc/version.rb +1 -1
  29. data/metanorma-standoc.gemspec +4 -5
  30. data/spec/metanorma/{refs_dl_spec.rb → biblio_spec.rb} +90 -7
  31. data/spec/metanorma/blocks_spec.rb +31 -267
  32. data/spec/metanorma/cleanup_blocks_spec.rb +0 -171
  33. data/spec/metanorma/inline_spec.rb +4 -0
  34. data/spec/metanorma/macros_concept_spec.rb +1033 -0
  35. data/spec/metanorma/macros_spec.rb +2 -1030
  36. data/spec/metanorma/refs_spec.rb +0 -2
  37. data/spec/metanorma/reqt_spec.rb +130 -0
  38. data/spec/metanorma/section_spec.rb +5 -0
  39. data/spec/metanorma/validate_spec.rb +46 -6
  40. data/spec/vcr_cassettes/bsi16341.yml +80 -52
  41. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +94 -94
  42. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +12 -12
  43. data/spec/vcr_cassettes/hide_refs.yml +70 -70
  44. data/spec/vcr_cassettes/isobib_get_123.yml +11 -11
  45. data/spec/vcr_cassettes/isobib_get_123_1.yml +23 -23
  46. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +35 -35
  47. data/spec/vcr_cassettes/isobib_get_123_2.yml +22 -22
  48. data/spec/vcr_cassettes/isobib_get_123_2001.yml +13 -13
  49. data/spec/vcr_cassettes/isobib_get_124.yml +11 -11
  50. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +34 -64
  51. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +45 -45
  52. data/spec/vcr_cassettes/std-link.yml +12 -12
  53. metadata +15 -11
  54. data/lib/metanorma/standoc/cleanup_ref_dl.rb +0 -113
@@ -29,6 +29,7 @@ module Metanorma
29
29
  preprocessor Metanorma::Plugin::Lutaml::LutamlUmlAttributesTablePreprocessor
30
30
  preprocessor Metanorma::Plugin::Lutaml::LutamlUmlDatamodelDescriptionPreprocessor
31
31
  inline_macro Metanorma::Standoc::PreferredTermInlineMacro
32
+ inline_macro Metanorma::Standoc::SpanInlineMacro
32
33
  inline_macro Metanorma::Standoc::AltTermInlineMacro
33
34
  inline_macro Metanorma::Standoc::AdmittedTermInlineMacro
34
35
  inline_macro Metanorma::Standoc::DeprecatedTermInlineMacro
@@ -93,6 +94,7 @@ module Metanorma
93
94
  basebackend "html"
94
95
  outfilesuffix ".xml"
95
96
  @libdir = File.dirname(self.class::_file || __FILE__)
97
+ @c = HTMLEntities.new
96
98
  end
97
99
 
98
100
  class << self
@@ -121,7 +121,7 @@ module Metanorma
121
121
 
122
122
  def metadata_getrelation(node, xml, type, desc = nil)
123
123
  docs = node.attr(desc || type) or return
124
- HTMLEntities.new.decode(docs).split(/;\s*/).each do |d|
124
+ @c.decode(docs).split(/;\s*/).each do |d|
125
125
  metadata_getrelation1(d, xml, type, desc)
126
126
  end
127
127
  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|
@@ -79,8 +79,8 @@ module Metanorma
79
79
  end
80
80
 
81
81
  def inline_anchor_bibref(node)
82
- eref_contents = HTMLEntities.new
83
- .decode(node.text || node.target || node.id)
82
+ eref_contents =
83
+ @c.decode(node.text || node.target || node.id)
84
84
  &.sub(/^\[?([^\[\]]+?)\]?$/, "[\\1]")
85
85
  @refids << (node.target || node.id)
86
86
  noko do |xml|
@@ -125,14 +125,14 @@ module Metanorma
125
125
  end
126
126
 
127
127
  def xml_encode(text)
128
- HTMLEntities.new.encode(text, :basic, :hexadecimal)
128
+ @c.encode(text, :basic, :hexadecimal)
129
129
  .gsub(/&amp;gt;/, ">").gsub(/&amp;lt;/, "<").gsub(/&amp;amp;/, "&")
130
130
  .gsub(/&gt;/, ">").gsub(/&lt;/, "<").gsub(/&amp;/, "&")
131
131
  .gsub(/&quot;/, '"').gsub(/&#xa;/, "\n").gsub(/&amp;#/, "&#")
132
132
  end
133
133
 
134
134
  def latex_parse1(text)
135
- lxm_input = Unicode2LaTeX.unicode2latex(HTMLEntities.new.decode(text))
135
+ lxm_input = Unicode2LaTeX.unicode2latex(@c.decode(text))
136
136
  results = Latexmath.parse(lxm_input).to_mathml
137
137
  results.nil? and
138
138
  @log.add("Math", nil,
@@ -191,6 +191,10 @@ module Metanorma
191
191
  when "underline" then xml.underline { |s| s << node.text }
192
192
  when "smallcap" then xml.smallcap { |s| s << node.text }
193
193
  when "keyword" then xml.keyword { |s| s << node.text }
194
+ when /^css /
195
+ xml.span **{ style: node.role.sub(/^css /, "") } do |s|
196
+ s << node.text
197
+ end
194
198
  else
195
199
  xml << node.text
196
200
  end
@@ -1285,7 +1285,12 @@
1285
1285
  </define>
1286
1286
  <define name="span">
1287
1287
  <element name="span">
1288
- <attribute name="class"/>
1288
+ <optional>
1289
+ <attribute name="class"/>
1290
+ </optional>
1291
+ <optional>
1292
+ <attribute name="style"/>
1293
+ </optional>
1289
1294
  <oneOrMore>
1290
1295
  <ref name="TextElement"/>
1291
1296
  </oneOrMore>
@@ -3,6 +3,7 @@ require "fileutils"
3
3
  require "uuidtools"
4
4
  require "yaml"
5
5
  require "csv"
6
+ require_relative "./macros_inline"
6
7
  require_relative "./macros_plantuml"
7
8
  require_relative "./macros_terms"
8
9
  require_relative "./macros_form"
@@ -15,54 +16,6 @@ require "metanorma-plugin-lutaml"
15
16
 
16
17
  module Metanorma
17
18
  module Standoc
18
- class InheritInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
19
- use_dsl
20
- named :inherit
21
- parse_content_as :text
22
- using_format :short
23
-
24
- def process(parent, _target, attrs)
25
- out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
26
- %{<inherit>#{out}</inherit>}
27
- end
28
- end
29
-
30
- class IndexXrefInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
31
- use_dsl
32
- named :index
33
-
34
- def preprocess_attrs(attrs)
35
- return unless attrs.size > 1 && attrs.size < 5
36
-
37
- ret = { primary: attrs[1], target: attrs[attrs.size] }
38
- ret[:secondary] = attrs[2] if attrs.size > 2
39
- ret[:tertiary] = attrs[3] if attrs.size > 3
40
- ret
41
- end
42
-
43
- def process(_parent, target, attr)
44
- args = preprocess_attrs(attr) or return
45
- ret = "<index-xref also='#{target == 'also'}'>"\
46
- "<primary>#{args[:primary]}</primary>"
47
- ret += "<secondary>#{args[:secondary]}</secondary>" if args[:secondary]
48
- ret += "<tertiary>#{args[:tertiary]}</tertiary>" if args[:tertiary]
49
- ret + "<target>#{args[:target]}</target></index-xref>"
50
- end
51
- end
52
-
53
- class IndexRangeInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
54
- use_dsl
55
- named :"index-range"
56
- parse_content_as :text
57
-
58
- def process(parent, target, attr)
59
- text = attr["text"]
60
- text = "((#{text}))" unless /^\(\(.+\)\)$/.match?(text)
61
- out = parent.sub_macros(text)
62
- out.sub(/<index>/, "<index to='#{target}'>")
63
- end
64
- end
65
-
66
19
  class PseudocodeBlockMacro < Asciidoctor::Extensions::BlockProcessor
67
20
  use_dsl
68
21
  named :pseudocode
@@ -97,138 +50,6 @@ module Metanorma
97
50
  end
98
51
  end
99
52
 
100
- class HTML5RubyMacro < Asciidoctor::Extensions::InlineMacroProcessor
101
- use_dsl
102
- named :ruby
103
- parse_content_as :text
104
- option :pos_attrs, %w(rpbegin rt rpend)
105
-
106
- # for example, html5ruby:楽聖少女[がくせいしょうじょ]
107
- def process(_parent, target, attributes)
108
- rpbegin = "("
109
- rpend = ")"
110
- if (attributes.size == 1) && attributes.key?("text")
111
- rt = attributes["text"]
112
- elsif (attributes.size == 2) && attributes.key?(1) &&
113
- attributes.key?("rpbegin")
114
- rt = attributes[1] || ""
115
- else
116
- rpbegin = attributes["rpbegin"]
117
- rt = attributes["rt"]
118
- rpend = attributes["rpend"]
119
- end
120
-
121
- "<ruby>#{target}<rp>#{rpbegin}</rp><rt>#{rt}</rt>"\
122
- "<rp>#{rpend}</rp></ruby>"
123
- end
124
- end
125
-
126
- class AutonumberInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
127
- use_dsl
128
- named :autonumber
129
- parse_content_as :text
130
-
131
- def process(parent, target, attrs)
132
- out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
133
- %{<autonumber type='#{target}'>#{out}</autonumber>}
134
- end
135
- end
136
-
137
- class VariantInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
138
- use_dsl
139
- named :lang
140
- parse_content_as :text
141
-
142
- def process(parent, target, attrs)
143
- /^(?<lang>[^-]*)(?:-(?<script>.*))?$/ =~ target
144
- out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
145
- if script
146
- %{<variant lang='#{lang}' script='#{script}'>#{out}</variant>}
147
- else
148
- %{<variant lang='#{lang}'>#{out}</variant>}
149
- end
150
- end
151
- end
152
-
153
- class AddMacro < Asciidoctor::Extensions::InlineMacroProcessor
154
- use_dsl
155
- named :add
156
- parse_content_as :text
157
- using_format :short
158
-
159
- def process(parent, _target, attrs)
160
- out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
161
- %{<add>#{out}</add>}
162
- end
163
- end
164
-
165
- class DelMacro < Asciidoctor::Extensions::InlineMacroProcessor
166
- use_dsl
167
- named :del
168
- parse_content_as :text
169
- using_format :short
170
-
171
- def process(parent, _target, attrs)
172
- out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
173
- %{<del>#{out}</del>}
174
- end
175
- end
176
-
177
- class ToCInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
178
- use_dsl
179
- named :toc
180
- parse_content_as :text
181
- using_format :short
182
-
183
- def process(parent, _target, attrs)
184
- out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
185
- content = CSV.parse_line(out).map do |x|
186
- x.sub!(/^(["'])(.+)\1/, "\\2")
187
- m = /^(.*?)(:\d+)?$/.match(x)
188
- %{<toc-xpath depth='#{m[2]&.sub(/:/, '') || 1}'>#{m[1]}</toc-xpath>}
189
- end.join
190
- "<toc>#{content}</toc>"
191
- end
192
- end
193
-
194
- # inject ZWNJ to prevent Asciidoctor from attempting regex substitutions
195
- class PassInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
196
- use_dsl
197
- named :"pass-format"
198
-
199
- def process(parent, target, attrs)
200
- format = target || "metanorma"
201
- out = Asciidoctor::Inline.new(parent, :quoted, attrs[1]).convert
202
- .gsub(/((?![<>&])[[:punct:]])/, "\\1&#x200c;")
203
- %{<passthrough-inline formats="#{format}">#{out}</passthrough-inline>}
204
- end
205
- end
206
-
207
- class IdentifierInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
208
- use_dsl
209
- named :identifier
210
- parse_content_as :raw
211
- using_format :short
212
-
213
- def process(parent, _target, attrs)
214
- out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
215
- .gsub(/((?![<>&])[[:punct:]])/, "\\1&#x200c;")
216
- %{<identifier>#{out}</identifier>}
217
- end
218
- end
219
-
220
- class StdLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
221
- use_dsl
222
- named :"std-link"
223
- parse_content_as :text
224
- using_format :short
225
-
226
- def process(parent, _target, attrs)
227
- create_anchor(parent, "hidden%#{attrs['text']}",
228
- type: :xref, target: "_#{UUIDTools::UUID.random_create}")
229
- end
230
- end
231
-
232
53
  class NamedEscapePreprocessor < Asciidoctor::Extensions::Preprocessor
233
54
  def process(_document, reader)
234
55
  c = HTMLEntities.new
@@ -0,0 +1,194 @@
1
+ module Metanorma
2
+ module Standoc
3
+ class InheritInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
4
+ use_dsl
5
+ named :inherit
6
+ parse_content_as :text
7
+ using_format :short
8
+
9
+ def process(parent, _target, attrs)
10
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
11
+ %{<inherit>#{out}</inherit>}
12
+ end
13
+ end
14
+
15
+ class IndexXrefInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
16
+ use_dsl
17
+ named :index
18
+
19
+ def preprocess_attrs(attrs)
20
+ return unless attrs.size > 1 && attrs.size < 5
21
+
22
+ ret = { primary: attrs[1], target: attrs[attrs.size] }
23
+ ret[:secondary] = attrs[2] if attrs.size > 2
24
+ ret[:tertiary] = attrs[3] if attrs.size > 3
25
+ ret
26
+ end
27
+
28
+ def process(_parent, target, attr)
29
+ args = preprocess_attrs(attr) or return
30
+ ret = "<index-xref also='#{target == 'also'}'>"\
31
+ "<primary>#{args[:primary]}</primary>"
32
+ ret += "<secondary>#{args[:secondary]}</secondary>" if args[:secondary]
33
+ ret += "<tertiary>#{args[:tertiary]}</tertiary>" if args[:tertiary]
34
+ ret + "<target>#{args[:target]}</target></index-xref>"
35
+ end
36
+ end
37
+
38
+ class IndexRangeInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
39
+ use_dsl
40
+ named :"index-range"
41
+ parse_content_as :text
42
+
43
+ def process(parent, target, attr)
44
+ text = attr["text"]
45
+ text = "((#{text}))" unless /^\(\(.+\)\)$/.match?(text)
46
+ out = parent.sub_macros(text)
47
+ out.sub(/<index>/, "<index to='#{target}'>")
48
+ end
49
+ end
50
+
51
+ class HTML5RubyMacro < Asciidoctor::Extensions::InlineMacroProcessor
52
+ use_dsl
53
+ named :ruby
54
+ parse_content_as :text
55
+ option :pos_attrs, %w(rpbegin rt rpend)
56
+
57
+ # for example, html5ruby:楽聖少女[がくせいしょうじょ]
58
+ def process(_parent, target, attributes)
59
+ rpbegin = "("
60
+ rpend = ")"
61
+ if (attributes.size == 1) && attributes.key?("text")
62
+ rt = attributes["text"]
63
+ elsif (attributes.size == 2) && attributes.key?(1) &&
64
+ attributes.key?("rpbegin")
65
+ rt = attributes[1] || ""
66
+ else
67
+ rpbegin = attributes["rpbegin"]
68
+ rt = attributes["rt"]
69
+ rpend = attributes["rpend"]
70
+ end
71
+
72
+ "<ruby>#{target}<rp>#{rpbegin}</rp><rt>#{rt}</rt>"\
73
+ "<rp>#{rpend}</rp></ruby>"
74
+ end
75
+ end
76
+
77
+ class AutonumberInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
78
+ use_dsl
79
+ named :autonumber
80
+ parse_content_as :text
81
+
82
+ def process(parent, target, attrs)
83
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
84
+ %{<autonumber type='#{target}'>#{out}</autonumber>}
85
+ end
86
+ end
87
+
88
+ class VariantInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
89
+ use_dsl
90
+ named :lang
91
+ parse_content_as :text
92
+
93
+ def process(parent, target, attrs)
94
+ /^(?<lang>[^-]*)(?:-(?<script>.*))?$/ =~ target
95
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
96
+ if script
97
+ %{<variant lang='#{lang}' script='#{script}'>#{out}</variant>}
98
+ else
99
+ %{<variant lang='#{lang}'>#{out}</variant>}
100
+ end
101
+ end
102
+ end
103
+
104
+ class AddMacro < Asciidoctor::Extensions::InlineMacroProcessor
105
+ use_dsl
106
+ named :add
107
+ parse_content_as :text
108
+ using_format :short
109
+
110
+ def process(parent, _target, attrs)
111
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
112
+ %{<add>#{out}</add>}
113
+ end
114
+ end
115
+
116
+ class DelMacro < Asciidoctor::Extensions::InlineMacroProcessor
117
+ use_dsl
118
+ named :del
119
+ parse_content_as :text
120
+ using_format :short
121
+
122
+ def process(parent, _target, attrs)
123
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
124
+ %{<del>#{out}</del>}
125
+ end
126
+ end
127
+
128
+ class ToCInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
129
+ use_dsl
130
+ named :toc
131
+ parse_content_as :text
132
+ using_format :short
133
+
134
+ def process(parent, _target, attrs)
135
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
136
+ content = CSV.parse_line(out).map do |x|
137
+ x.sub!(/^(["'])(.+)\1/, "\\2")
138
+ m = /^(.*?)(:\d+)?$/.match(x)
139
+ %{<toc-xpath depth='#{m[2]&.sub(/:/, '') || 1}'>#{m[1]}</toc-xpath>}
140
+ end.join
141
+ "<toc>#{content}</toc>"
142
+ end
143
+ end
144
+
145
+ # inject ZWNJ to prevent Asciidoctor from attempting regex substitutions
146
+ class PassInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
147
+ use_dsl
148
+ named :"pass-format"
149
+
150
+ def process(parent, target, attrs)
151
+ format = target || "metanorma"
152
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs[1]).convert
153
+ .gsub(/((?![<>&])[[:punct:]])/, "\\1&#x200c;")
154
+ %{<passthrough-inline formats="#{format}">#{out}</passthrough-inline>}
155
+ end
156
+ end
157
+
158
+ class IdentifierInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
159
+ use_dsl
160
+ named :identifier
161
+ parse_content_as :raw
162
+ using_format :short
163
+
164
+ def process(parent, _target, attrs)
165
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
166
+ .gsub(/((?![<>&])[[:punct:]])/, "\\1&#x200c;")
167
+ %{<identifier>#{out}</identifier>}
168
+ end
169
+ end
170
+
171
+ class StdLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
172
+ use_dsl
173
+ named :"std-link"
174
+ parse_content_as :text
175
+ using_format :short
176
+
177
+ def process(parent, _target, attrs)
178
+ create_anchor(parent, "hidden%#{attrs['text']}",
179
+ type: :xref, target: "_#{UUIDTools::UUID.random_create}")
180
+ end
181
+ end
182
+
183
+ class SpanInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
184
+ use_dsl
185
+ named :span
186
+ parse_content_as :text
187
+
188
+ def process(parent, target, attrs)
189
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
190
+ %{<span class="#{target}">#{out}</span>}
191
+ end
192
+ end
193
+ end
194
+ end
@@ -84,7 +84,7 @@ module Metanorma
84
84
  if ref[:code].nil? || ref[:no_year] || @bibdb.nil?
85
85
  res << [ref, idx, nil]
86
86
  else
87
- @bibdb.fetch_async(HTMLEntities.new.decode(ref[:code]),
87
+ @bibdb.fetch_async(@c.decode(ref[:code]),
88
88
  ref[:year], ref) do |doc|
89
89
  res << [ref, idx, doc]
90
90
  end
@@ -131,7 +131,7 @@ module Metanorma
131
131
  global = !@no_isobib_cache && !node.attr("local-cache-only")
132
132
  local = node.attr("local-cache") || node.attr("local-cache-only")
133
133
  local = nil if @no_isobib_cache
134
- @bibdb = Relaton::DbCache.init_bib_caches(
134
+ @bibdb = Relaton::Db.init_bib_caches(
135
135
  local_cache: local,
136
136
  flush_caches: node.attr("flush-caches"),
137
137
  global_cache: global,
@@ -53,7 +53,7 @@ module Metanorma
53
53
 
54
54
  def docnumber(bib, code)
55
55
  bib.docnumber do |d|
56
- d << HTMLEntities.new.decode(code).sub(/^[^\d]*/, "")
56
+ d << @c.decode(code).sub(/^[^\d]*/, "")
57
57
  end
58
58
  end
59
59
 
@@ -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 label 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
- HTMLEntities.new.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("label") and out.label 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 = HTMLEntities.new.decode(node.attr("inherit")) and
73
- csv_split(a)&.each do |i|
74
- out.inherit do |inh|
75
- inh << HTMLEntities.new.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
@@ -108,7 +108,7 @@
108
108
  </element>
109
109
  </define>
110
110
  <define name="label">
111
- <element name="label">
111
+ <element name="identifier">
112
112
  <oneOrMore>
113
113
  <ref name="TextElement"/>
114
114
  </oneOrMore>