metanorma-standoc 2.2.8 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 243e174494c4a7ce6b3b8ca5d861feb72d045439ce32948b44af9c14f9180981
4
- data.tar.gz: 40c2d970ccb90fdf19c77cd38d5e9e7c7626fa10c96050a0486a4697c3146624
3
+ metadata.gz: 95723e2c2f2095e87fcc969fafc1372b8297cd68b4376ce49b50e8bbd3b993b5
4
+ data.tar.gz: ad570f41788f288d281b419d72eb1026b046e7d4f35260281ccd09138c181ebd
5
5
  SHA512:
6
- metadata.gz: d957db18f3b90d596f69c048fa93c703e45736c23bbaa5787fd5111aaded043fd532a219187a4ff174067a3e456c0bfb48fea4e38d1c4705d6e97754a92ed26b
7
- data.tar.gz: 7c37929c7115382a789348ee12041496f4fe10847c2aac893cd7f60ac3e0b413d63c5573dfd6dfadf6e58af5c5455bca09ca150fe0262f9e6324b6e064cfdabe
6
+ metadata.gz: 135b01bb780350e849b3dd5dc7edac3600a1a75fcfdc336b904ca67dfac219923e5c697e5d05b4871ac827194cb582aadb0abcdcfb84280f024a3b7c75c0881f
7
+ data.tar.gz: e8a1dbe9aeaced49888d73b237c13a8531471c567c7d5ff4278e8cd38d0cdb171bc6c5f3ff824e2df57e7e8bb9e8dd0ff493df6ca16e5c1efda7364e4f692364
@@ -9,6 +9,7 @@ require "fileutils"
9
9
  require "metanorma-utils"
10
10
  require "isodoc/xslfo_convert"
11
11
  require_relative "render"
12
+ require_relative "localbib"
12
13
  require "mn-requirements"
13
14
 
14
15
  module Metanorma
@@ -18,6 +19,8 @@ module Metanorma
18
19
  XML_NAMESPACE = "https://www.metanorma.org/ns/standoc".freeze
19
20
  FONTS_MANIFEST = "fonts-manifest".freeze
20
21
 
22
+ attr_accessor :log, :fatalerror
23
+
21
24
  def xml_root_tag
22
25
  self.class::XML_ROOT_TAG
23
26
  end
@@ -32,7 +35,7 @@ module Metanorma
32
35
  init_processing(node)
33
36
  init_reqt(node)
34
37
  init_toc(node)
35
- init_output(node)
38
+ init_output(node) # feeds init_biblio
36
39
  init_i18n(node)
37
40
  init_biblio(node)
38
41
  @metadata_attrs = metadata_attrs(node)
@@ -96,6 +99,7 @@ module Metanorma
96
99
  end
97
100
  @localdir = Metanorma::Utils::localdir(node)
98
101
  @output_dir = outputdir node
102
+ @fatalerror = []
99
103
  end
100
104
 
101
105
  def init_i18n(node)
@@ -113,6 +117,8 @@ module Metanorma
113
117
  @bibdb = nil
114
118
  init_bib_caches(node)
115
119
  init_iev_caches(node)
120
+ @local_bibdb =
121
+ ::Metanorma::Standoc::LocalBiblio.new(node, @localdir, self)
116
122
  end
117
123
 
118
124
  def requirements_processor
@@ -226,8 +232,7 @@ module Metanorma
226
232
  def outputdir(node)
227
233
  if node.attr("output_dir").nil_or_empty?
228
234
  Metanorma::Utils::localdir(node)
229
- else
230
- File.join(node.attr("output_dir"), "")
235
+ else File.join(node.attr("output_dir"), "")
231
236
  end
232
237
  end
233
238
  end
@@ -683,6 +683,9 @@
683
683
  </define>
684
684
  <define name="underline">
685
685
  <element name="underline">
686
+ <optional>
687
+ <attribute name="style"/>
688
+ </optional>
686
689
  <zeroOrMore>
687
690
  <ref name="PureTextElement"/>
688
691
  </zeroOrMore>
@@ -47,7 +47,7 @@
47
47
  </element>
48
48
  </define>
49
49
  <define name="DocumentType">
50
- <value>document</value>
50
+ <text/>
51
51
  </define>
52
52
  <define name="docsubtype">
53
53
  <element name="subdoctype">
@@ -37,6 +37,7 @@ module Metanorma
37
37
  reqt_subpart?(role) and return requirement_subpart(node)
38
38
  role == "form" and return form(node)
39
39
  role == "definition" and return termdefinition(node)
40
+ role == "boilerplate" and return boilerplate_note(node)
40
41
  result = []
41
42
  node.blocks.each { |b| result << send(b.context, b) }
42
43
  result
@@ -71,6 +71,11 @@ module Metanorma
71
71
  end.join("\n")
72
72
  end
73
73
 
74
+ def boilerplate_note(node)
75
+ node.set_attr("type", "boilerplate")
76
+ note(node)
77
+ end
78
+
74
79
  def admonition_attrs(node)
75
80
  attr_code(keep_attrs(node).merge(id_attr(node)
76
81
  .merge(admonition_core_attrs(node)
@@ -66,6 +66,8 @@ module Metanorma
66
66
  name: span[:val] }
67
67
  when "surname", "initials", "givenname", "formatted-initials"
68
68
  ret[:contrib] = spans_preprocess_contrib(span, ret[:contrib])
69
+ when "fullname"
70
+ ret[:contrib] = spans_preprocess_fullname(span, ret[:contrib])
69
71
  when "organization"
70
72
  ret[:contrib] = spans_preprocess_org(span, ret[:contrib])
71
73
  when "in_surname", "in_initials", "in_givenname",
@@ -74,11 +76,18 @@ module Metanorma
74
76
  span[:key].sub!(/^in_/, "")
75
77
  ret[:in][:contrib] =
76
78
  spans_preprocess_contrib(span, ret[:in][:contrib])
79
+ when "in_fullname"
80
+ ret[:in][:contrib] ||= []
81
+ span[:key].sub!(/^in_/, "")
82
+ ret[:in][:contrib] =
83
+ spans_preprocess_fullname(span, ret[:in][:contrib])
77
84
  when "in_organization"
78
85
  ret[:in][:contrib] ||= []
79
86
  span[:key].sub!(/^in_/, "")
80
87
  ret[:in][:contrib] =
81
88
  spans_preprocess_org(span, ret[:in][:contrib])
89
+ else
90
+ warn "unrecognised `span:#{span["key"]}`"
82
91
  end
83
92
  end
84
93
 
@@ -100,7 +109,12 @@ module Metanorma
100
109
 
101
110
  spans_preprocess_new_contrib?(span, contrib) and
102
111
  contrib << { role: span[:type] || "author", entity: "person" }
103
- contrib[-1][span[:key].to_sym] = span[:val]
112
+ if span[:key] == "givenname" && contrib[-1][span[:key].to_sym]
113
+ contrib[-1][span[:key].to_sym] =
114
+ Array(contrib[-1][span[:key].to_sym]) + span[:val]
115
+ else
116
+ contrib[-1][span[:key].to_sym] = span[:val]
117
+ end
104
118
  contrib
105
119
  end
106
120
 
@@ -112,6 +126,19 @@ module Metanorma
112
126
  contrib[-1][:role] != (span[:type] || "author")
113
127
  end
114
128
 
129
+ def spans_preprocess_fullname(span, contrib)
130
+ name = span[:val].gsub(/\.(?=\p{Alpha})/, ". ").split(/ /)
131
+ out = { role: span[:type] || "author", entity: "person",
132
+ surname: name[-1] }
133
+ if name.size > 1 && name[0..-2].all? { |x| /\.$/.match?(x) }
134
+ out[:"formatted-initials"] = name[0..-2].join(" ")
135
+ else
136
+ out[:givenname] = name[0..-2]
137
+ end
138
+ contrib << out
139
+ contrib
140
+ end
141
+
115
142
  def spans_preprocess_org(span, contrib)
116
143
  contrib << { role: span[:type] || "author", entity: "organization",
117
144
  name: span[:val] }
@@ -122,7 +149,7 @@ module Metanorma
122
149
  ret = ""
123
150
  spans[:title] and ret += "<title>#{spans[:title]}</title>"
124
151
  ret += spans_to_bibitem_docid(spans)
125
- spans[:contrib].each { |s| ret += span_to_contrib(s) }
152
+ spans[:contrib].each { |s| ret += span_to_contrib(s, spans[:title]) }
126
153
  spans[:series] and
127
154
  ret += "<series><title>#{spans[:series]}</title></series>"
128
155
  spans[:pubplace] and ret += "<place>#{spans[:pubplace]}</place>"
@@ -152,6 +179,8 @@ module Metanorma
152
179
  { volume: "volume", issue: "issue", pages: "page" }.each do |k, v|
153
180
  spans[k]&.each { |s| ret += span_to_extent(s, v) }
154
181
  end
182
+ return "" if ret.empty?
183
+
155
184
  "<extent>#{ret}</extent>"
156
185
  end
157
186
 
@@ -172,19 +201,28 @@ module Metanorma
172
201
  end
173
202
  end
174
203
 
175
- def span_to_contrib(span)
204
+ def span_to_contrib(span, title)
176
205
  e = if span[:entity] == "organization"
177
206
  "<organization><name>#{span[:name]}</name></organization>"
178
- else span_to_person(span)
207
+ else span_to_person(span, title)
179
208
  end
180
209
  "<contributor><role type='#{span[:role]}'/>#{e}</contributor>"
181
210
  end
182
211
 
183
- def span_to_person(span)
212
+ def validate_span_to_person(span, title)
213
+ span[:surname] and return
214
+ msg = "Missing surname: issue with bibliographic markup " \
215
+ "in \"#{title}\": #{span}"
216
+ @log.add("Bibliography", nil, msg)
217
+ @fatalerror << msg
218
+ end
219
+
220
+ def span_to_person(span, title)
221
+ validate_span_to_person(span, title)
184
222
  pre = (span[:"formatted-initials"] and
185
223
  "<formatted-initials>" \
186
224
  "#{span[:"formatted-initials"]}</formatted-initials>") ||
187
- "<forename>#{span[:givenname]}</forename>"
225
+ Array(span[:givenname]).map { |x| "<forename>#{x}</forename>" }.join
188
226
  "<person><name>#{pre}<surname>#{span[:surname]}</surname></name>" \
189
227
  "</person>"
190
228
  end
@@ -89,7 +89,8 @@ module Metanorma
89
89
 
90
90
  def termdef_boilerplate_insert(xmldoc, isodoc, once = false)
91
91
  xmldoc.xpath(self.class::TERM_CLAUSE).each do |f|
92
- next if f.at("./clause[@type = 'boilerplate']")
92
+ next if f.at("./clause[@type = 'boilerplate'] | " \
93
+ "./note[@type = 'boilerplate']")
93
94
 
94
95
  term_defs_boilerplate(f.at("./title"),
95
96
  xmldoc.xpath(".//termdocsource"),
@@ -44,11 +44,11 @@ module Metanorma
44
44
  end
45
45
 
46
46
  NO_SYMABBR = "[.//definitions[not(@type)]]".freeze
47
- SYMABBR = "[.//definitions[@type = 'symbols']]"\
47
+ SYMABBR = "[.//definitions[@type = 'symbols']]" \
48
48
  "[.//definitions[@type = 'abbreviated_terms']]".freeze
49
- SYMnoABBR = "[.//definitions[@type = 'symbols']]"\
49
+ SYMnoABBR = "[.//definitions[@type = 'symbols']]" \
50
50
  "[not(.//definitions[@type = 'abbreviated_terms'])]".freeze
51
- ABBRnoSYM = "[.//definitions[@type = 'abbreviated_terms']]"\
51
+ ABBRnoSYM = "[.//definitions[@type = 'abbreviated_terms']]" \
52
52
  "[not(.//definitions[@type = 'symbols'])]".freeze
53
53
 
54
54
  def section_names_terms_cleanup(xml)
@@ -2653,6 +2653,7 @@
2653
2653
  <value>full</value>
2654
2654
  <value>short</value>
2655
2655
  <value>id</value>
2656
+ <value>modspec</value>
2656
2657
  </choice>
2657
2658
  </define>
2658
2659
  <define name="erefTypeWithConnective">
@@ -0,0 +1,77 @@
1
+ require "relaton_bib"
2
+
3
+ module Metanorma
4
+ module Standoc
5
+ class LocalBiblio
6
+ def initialize(node, localdir, parent)
7
+ @file_bibdb = {}
8
+ @localdir = localdir
9
+ @parent = parent
10
+ read_files(node)
11
+ end
12
+
13
+ def read_files(node)
14
+ if node.attr("relaton-data-source")
15
+ init_file_bibdb1(node.attr("relaton-data-source"), "default")
16
+ else
17
+ node.attributes.each do |k, v|
18
+ /^relaton-data-source-.+/.match?(k) or next
19
+ init_file_bibdb1(v, k.sub(/^relaton-data-source-/, ""))
20
+ end
21
+ end
22
+ end
23
+
24
+ def init_file_bibdb_config(defn, key)
25
+ /=/.match?(defn) or defn = "file=#{defn}"
26
+ values = defn.split(",").map { |item| item.split /\s*=\s*/ }.to_h
27
+ values["key"] = key
28
+ values["format"] ||= "bibtex" # all we currently suppoort
29
+ values
30
+ end
31
+
32
+ def init_file_bibdb1(defn, key)
33
+ v = init_file_bibdb_config(defn, key)
34
+ r = read_file(v)
35
+ @file_bibdb[v["key"]] =
36
+ case v["format"]
37
+ when "bibtex"
38
+ RelatonBib::BibtexParser.from_bibtex(r)
39
+ else
40
+ format_error(v)
41
+ end
42
+ end
43
+
44
+ def read_file(config)
45
+ f = File.join(@localdir, config["file"])
46
+ File.exist?(f) or return file_error(config)
47
+ File.read(f)
48
+ end
49
+
50
+ def file_error(config)
51
+ msg = "Cannot process file #{config['file']} for local relaton " \
52
+ "data source #{config['key']}"
53
+ @parent.fatalerror << msg
54
+ @parent.log.add("Bibliography", nil, msg)
55
+ ""
56
+ end
57
+
58
+ def format_error(config)
59
+ msg = "Cannot process format #{config['format']} for local relaton " \
60
+ "data source #{config['key']}"
61
+ @parent.fatalerror << msg
62
+ @parent.log.add("Bibliography", nil, msg)
63
+ {}
64
+ end
65
+
66
+ def get(id, file = default)
67
+ ret = @file_bibdb.dig(file, id) and return ret
68
+
69
+ msg = "Cannot find reference #{id} for local relaton " \
70
+ "data source #{file}"
71
+ @parent.fatalerror << msg
72
+ @parent.log.add("Bibliography", nil, msg)
73
+ Nokogiri::XML("<bibitem/>")
74
+ end
75
+ end
76
+ end
77
+ end
@@ -74,7 +74,7 @@ module Metanorma
74
74
 
75
75
  def process(_parent, _target, attrs)
76
76
  termref = attrs["termxref"] || attrs["name"]
77
- "<concept type='term'><termxref>#{attrs['name']}</termxref>"\
77
+ "<concept type='term'><termxref>#{attrs['name']}</termxref>" \
78
78
  "<renderterm>#{termref}</renderterm><xrefrender/></concept>"
79
79
  end
80
80
  end
@@ -87,7 +87,7 @@ module Metanorma
87
87
 
88
88
  def process(_parent, _target, attrs)
89
89
  termref = attrs["termxref"] || attrs["name"]
90
- "<concept type='symbol'><termxref>#{attrs['name']}</termxref>"\
90
+ "<concept type='symbol'><termxref>#{attrs['name']}</termxref>" \
91
91
  "<renderterm>#{termref}</renderterm><xrefrender/></concept>"
92
92
  end
93
93
  end
@@ -113,50 +113,40 @@ module Metanorma
113
113
  .match(m[:rest].sub(/^,/, ""))
114
114
  ret[:opt] = CSV.parse_line(m2[:opt].sub(/^,opt(ion)?s=/, "")
115
115
  .sub(/^"(.+)"$/m, "\\1").sub(/^'(.+)'$/m, "\\1"))
116
- begin
117
- attrs = CSV.parse_line(m2[:rest]) || []
118
- rescue StandardError
119
- raise "error processing #{m2[:rest]} as CSV"
120
- end
121
- else
122
- begin
123
- attrs = CSV.parse_line(m[:rest].sub(/^,/, "")) || []
124
- rescue StandardError
125
- raise "error processing #{m[:rest]} as CSV"
126
- end
116
+ attrs = preprocess_attrs_csv(m2[:rest])
117
+ else attrs = preprocess_attrs_csv(m[:rest])
127
118
  end
128
119
  attrs.map! { |x| x.gsub(/\s+/, " ") }
129
120
  ret.merge(term: attrs[0], word: attrs[1] || attrs[0],
130
121
  render: attrs[2])
131
122
  end
132
123
 
124
+ def preprocess_attrs_csv(line)
125
+ CSV.parse_line(line.sub(/^,/, "")) || []
126
+ rescue StandardError
127
+ raise "error processing #{line} as CSV"
128
+ end
129
+
133
130
  def generate_attrs(opts)
134
131
  ret = ""
135
- opts.include?("noital") and ret += " ital='false'"
136
- opts.include?("noref") and ret += " ref='false'"
137
- opts.include?("ital") and ret += " ital='true'"
138
- opts.include?("ref") and ret += " ref='true'"
139
- opts.include?("nolinkmention") and ret += " linkmention='false'"
140
- opts.include?("linkmention") and ret += " linkmention='true'"
141
- opts.include?("nolinkref") and ret += " linkref='false'"
142
- opts.include?("linkref") and ret += " linkref='true'"
132
+ %w(ital ref linkmention linkref).each do |x|
133
+ opts.include?("no#{x}") and ret += " #{x}='false'"
134
+ opts.include?(x) and ret += " #{x}='true'"
135
+ end
143
136
  ret
144
137
  end
145
138
 
146
139
  def process(parent, target, _attrs)
147
140
  attrs = preprocess_attrs(target)
148
- term = Asciidoctor::Inline.new(parent, :quoted,
149
- attrs[:term]).convert
150
- word = Asciidoctor::Inline.new(parent, :quoted,
151
- attrs[:word]).convert
152
- xref = Asciidoctor::Inline.new(parent, :quoted,
153
- attrs[:render]).convert
141
+ term, word, render = %i(term word render).each_with_object([]) do |x, m|
142
+ m << Asciidoctor::Inline.new(parent, :quoted, attrs[x]).convert
143
+ end
154
144
  opt = generate_attrs(attrs[:opt] || [])
155
- if attrs[:id] then "<concept#{opt} key='#{attrs[:id]}'><refterm>"\
156
- "#{term}</refterm><renderterm>#{word}</renderterm>"\
157
- "<xrefrender>#{xref}</xrefrender></concept>"
158
- else "<concept#{opt}><termxref>#{term}</termxref><renderterm>"\
159
- "#{word}</renderterm><xrefrender>#{xref}</xrefrender></concept>"
145
+ if attrs[:id] then "<concept#{opt} key='#{attrs[:id]}'><refterm>" \
146
+ "#{term}</refterm><renderterm>#{word}</renderterm>" \
147
+ "<xrefrender>#{render}</xrefrender></concept>"
148
+ else "<concept#{opt}><termxref>#{term}</termxref><renderterm>" \
149
+ "#{word}</renderterm><xrefrender>#{render}</xrefrender></concept>"
160
150
  end
161
151
  rescue StandardError => e
162
152
  raise("processing {{#{target}}}: #{e.message}")
@@ -182,9 +172,9 @@ module Metanorma
182
172
  out = preprocess_attrs(attrs["text"])
183
173
  term = Asciidoctor::Inline.new(parent, :quoted,
184
174
  out[:term]).convert
185
- if out[:id] then "<related type='#{target}' key='#{out[:id]}'>"\
175
+ if out[:id] then "<related type='#{target}' key='#{out[:id]}'>" \
186
176
  "<refterm>#{term}</refterm></related>"
187
- else "<related type='#{target}'><termxref>#{term}</termxref>"\
177
+ else "<related type='#{target}'><termxref>#{term}</termxref>" \
188
178
  "<xrefrender>#{term}</xrefrender></related>"
189
179
  end
190
180
  rescue StandardError => e
@@ -42,10 +42,9 @@ module Metanorma
42
42
  end
43
43
 
44
44
  def isorefmatches2code(match)
45
- { code: match[:code], no_year: true,
45
+ { code: match[:code], no_year: true, lang: (@lang || :all),
46
46
  note: match[:fn], year: nil, match: match,
47
- title: match[:text], usrlbl: match[:usrlbl],
48
- lang: (@lang || :all) }
47
+ title: match[:text], usrlbl: match[:usrlbl] }
49
48
  end
50
49
 
51
50
  def isorefmatches2out(item, xml)
@@ -145,7 +144,7 @@ module Metanorma
145
144
  return { code: nil, match: match, analyse_code: code,
146
145
  hidden: code[:hidden] }
147
146
  year = refitem1yr(code[:id])
148
- { code: code[:id], analyse_code: code,
147
+ { code: code[:id], analyse_code: code, localfile: code[:localfile],
149
148
  year: year,
150
149
  title: match[:text], match: match, hidden: code[:hidden],
151
150
  usrlbl: match[:usrlbl], lang: (@lang || :all) }
@@ -221,7 +220,13 @@ module Metanorma
221
220
  refs = node.items.each_with_object([]) do |b, m|
222
221
  m << reference1code(b.text, node)
223
222
  end
224
- reference_populate(refs)
223
+ reference_populate(reference_normalise(refs))
224
+ end
225
+
226
+ def reference_normalise(refs)
227
+ refs.each do |r|
228
+ r[:code] = @c.decode(r[:code]).gsub(/\u2009\u2014\u2009/, " -- ")
229
+ end
225
230
  end
226
231
 
227
232
  def reference_populate(refs)
@@ -239,7 +244,7 @@ module Metanorma
239
244
  ref, i, doc = results.pop
240
245
  m[i.to_i] = { ref: ref }
241
246
  if doc.is_a?(RelatonBib::RequestError)
242
- @log.add("Bibliography", nil, "Could not retrieve #{ref[:code]}: "\
247
+ @log.add("Bibliography", nil, "Could not retrieve #{ref[:code]}: " \
243
248
  "no access to online site")
244
249
  else m[i.to_i][:doc] = doc
245
250
  end
@@ -69,41 +69,63 @@ module Metanorma
69
69
  return nil if opts[:no_year]
70
70
 
71
71
  code = code.sub(/^\([^)]+\)/, "")
72
- hit = @bibdb&.fetch(code, year, opts)
73
- return nil if hit.nil?
74
-
72
+ hit = fetch_ref1(code, year, opts) or return nil
75
73
  xml.parent.add_child(smart_render_xml(hit, code, opts))
76
74
  xml
77
75
  rescue RelatonBib::RequestError
78
- @log.add("Bibliography", nil, "Could not retrieve #{code}: "\
76
+ @log.add("Bibliography", nil, "Could not retrieve #{code}: " \
79
77
  "no access to online site")
80
78
  nil
81
79
  end
82
80
 
81
+ def fetch_ref1(code, year, opts)
82
+ if opts[:localfile]
83
+ @local_bibdb.get(code, opts[:localfile])
84
+ else @bibdb&.fetch(code, year, opts)
85
+ end
86
+ end
87
+
83
88
  def fetch_ref_async(ref, idx, res)
84
- if ref[:code].nil? || ref[:no_year] || @bibdb.nil?
89
+ if ref[:code].nil? || ref[:no_year] || (@bibdb.nil? && !ref[:localfile])
85
90
  res << [ref, idx, nil]
86
- else
87
- @bibdb.fetch_async(@c.decode(ref[:code]),
88
- ref[:year], ref) do |doc|
89
- res << [ref, idx, doc]
90
- end
91
+ elsif ref[:localfile]
92
+ res << [ref, idx, @local_bibdb.get(ref[:code], ref[:localfile])]
93
+ else fetch_ref_async1(ref, idx, res)
94
+ end
95
+ end
96
+
97
+ def fetch_ref_async1(ref, idx, res)
98
+ @bibdb.fetch_async(ref[:code], ref[:year], ref) do |doc|
99
+ res << [ref, idx, doc]
91
100
  end
92
101
  end
93
102
 
94
103
  def emend_biblio(xml, code, title, usrlbl)
104
+ emend_biblio_id(xml, code)
105
+ emend_biblio_title(xml, code, title)
106
+ emend_biblio_usrlbl(xml, usrlbl)
107
+ end
108
+
109
+ def emend_biblio_id(xml, code)
95
110
  unless xml.at("/bibitem/docidentifier[not(@type = 'DOI')][text()]")
96
111
  @log.add("Bibliography", nil,
97
112
  "ERROR: No document identifier retrieved for #{code}")
98
113
  xml.root << "<docidentifier>#{code}</docidentifier>"
99
114
  end
115
+ end
116
+
117
+ def emend_biblio_title(xml, code, title)
100
118
  unless xml.at("/bibitem/title[text()]")
101
119
  @log.add("Bibliography", nil,
102
120
  "ERROR: No title retrieved for #{code}")
103
121
  xml.root << "<title>#{title || '(MISSING TITLE)'}</title>"
104
122
  end
105
- usrlbl and xml.at("/bibitem/docidentifier").next =
106
- "<docidentifier type='metanorma'>#{mn_code(usrlbl)}</docidentifier>"
123
+ end
124
+
125
+ def emend_biblio_usrlbl(xml, usrlbl)
126
+ usrlbl or return
127
+ xml.at("/bibitem/docidentifier").next =
128
+ "<docidentifier type='metanorma'>#{mn_code(usrlbl)}</docidentifier>"
107
129
  end
108
130
 
109
131
  def smart_render_xml(xml, code, opts)
@@ -62,6 +62,14 @@ module Metanorma
62
62
  .sub(/^dropid\((.+)\)$/, "\\1")
63
63
  .sub(/^hidden\((.+)\)$/, "\\1")
64
64
  .sub(/^nofetch\((.+)\)$/, "\\1")
65
+ .sub(/^local-file\((.+)\)$/, "\\1")
66
+ end
67
+
68
+ def analyse_ref_localfile(ret)
69
+ m = /^local-file\((?:(?<source>[^,]+),\s*)?(?<id>.+)\)$/.match(ret[:id])
70
+ m or return ret
71
+
72
+ ret.merge(id: m[:id], localfile: (m[:source] || "default"))
65
73
  end
66
74
 
67
75
  def analyse_ref_nofetch(ret)
@@ -98,15 +106,19 @@ module Metanorma
98
106
  end
99
107
 
100
108
  # ref id = (usrlbl)code[:-]year
101
- # code = nofetch(code) | hidden(code) | dropid(code) | (repo|path):(key,code) |
102
- # \[? number \]? | ident
109
+ # code = \[? number \]? | ident | nofetch(code) | hidden(code) |
110
+ # dropid(code) | # (repo|path):(key,code) | local-file(source,? key)
103
111
  def analyse_ref_code(code)
104
112
  ret = { id: code }
105
113
  return ret if code.blank?
106
114
 
107
115
  analyse_ref_numeric(
108
116
  analyse_ref_repo_path(
109
- analyse_ref_dropid(analyse_ref_hidden(analyse_ref_nofetch(ret))),
117
+ analyse_ref_dropid(
118
+ analyse_ref_hidden(
119
+ analyse_ref_nofetch(analyse_ref_localfile(ret)),
120
+ ),
121
+ ),
110
122
  ),
111
123
  )
112
124
  end
@@ -34,8 +34,9 @@ module Metanorma
34
34
 
35
35
  def requirement_validate(docxml)
36
36
  docxml.xpath("//requirement | //recommendation | //permission")
37
- .each do |r|
38
- @reqt_models.model(r["model"]).validate(r, @log)
37
+ .each_with_object([]) do |r, m|
38
+ ret = @reqt_models.model(r["model"]).validate(r, @log)
39
+ ret.each { |x| m << x }
39
40
  end
40
41
  end
41
42
  end
@@ -60,8 +60,9 @@ module Metanorma
60
60
  "symbols and abbreviated terms", "clause", "bibliography"].freeze
61
61
 
62
62
  def start_main_section(ret, node)
63
- @preface = false if self.class::MAIN_CLAUSE_NAMES.include?(ret) &&
64
- node.role != "preface" && node.attr("style") != "preface"
63
+ return if node.role == "preface" || node.attr("style") == "preface"
64
+
65
+ @preface = false if self.class::MAIN_CLAUSE_NAMES.include?(ret)
65
66
  @preface = false if self.class::PREFACE_CLAUSE_NAMES
66
67
  .intersection(@seen_headers_canonical + [ret]).empty?
67
68
  end
@@ -43,7 +43,6 @@ module Metanorma
43
43
  end
44
44
 
45
45
  def content_validate(doc)
46
- @fatalerror = []
47
46
  xref_validate(doc)
48
47
  section_validate(doc)
49
48
  norm_ref_validate(doc)
@@ -52,7 +51,7 @@ module Metanorma
52
51
  concept_validate(doc, "concept", "refterm")
53
52
  concept_validate(doc, "related", "preferred//name")
54
53
  table_validate(doc)
55
- requirement_validate(doc)
54
+ @fatalerror += requirement_validate(doc)
56
55
  image_validate(doc)
57
56
  @fatalerror.empty? or
58
57
  clean_abort(@fatalerror.join("\n"), doc)
@@ -19,6 +19,6 @@ module Metanorma
19
19
  end
20
20
 
21
21
  module Standoc
22
- VERSION = "2.2.8".freeze
22
+ VERSION = "2.3.0".freeze
23
23
  end
24
24
  end
@@ -30,7 +30,7 @@ Gem::Specification.new do |spec|
30
30
 
31
31
  spec.add_dependency "asciidoctor", "~> 2.0.0"
32
32
  spec.add_dependency "iev", "~> 0.3.0"
33
- spec.add_dependency "isodoc", "~> 2.3.1"
33
+ spec.add_dependency "isodoc", "~> 2.4.0"
34
34
  spec.add_dependency "metanorma"
35
35
  spec.add_dependency "metanorma-plugin-datastruct", "~> 0.2.0"
36
36
  spec.add_dependency "metanorma-plugin-lutaml"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma-standoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.8
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-21 00:00:00.000000000 Z
11
+ date: 2022-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 2.3.1
47
+ version: 2.4.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 2.3.1
54
+ version: 2.4.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: metanorma
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -503,6 +503,7 @@ files:
503
503
  - lib/metanorma/standoc/isodoc-compile.rng
504
504
  - lib/metanorma/standoc/isodoc.rng
505
505
  - lib/metanorma/standoc/lists.rb
506
+ - lib/metanorma/standoc/localbib.rb
506
507
  - lib/metanorma/standoc/macros.rb
507
508
  - lib/metanorma/standoc/macros_embed.rb
508
509
  - lib/metanorma/standoc/macros_form.rb
@@ -548,7 +549,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
548
549
  - !ruby/object:Gem::Version
549
550
  version: '0'
550
551
  requirements: []
551
- rubygems_version: 3.3.7
552
+ rubygems_version: 3.3.26
552
553
  signing_key:
553
554
  specification_version: 4
554
555
  summary: metanorma-standoc realises standards following the Metanorma standoc model