metanorma-standoc 1.3.20 → 1.3.21

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: b599dbb549f1bb38b237e1bb8463162420d93939f424f10937ee589a7ae12218
4
- data.tar.gz: 3ad036f4058f7aed94269495553e1ea5be516a10f59af7f8f669e42d117709f1
3
+ metadata.gz: c62f787dbc1d97b2175f66f6130d2b365af18bedffa9de98a236f39f756c3ae8
4
+ data.tar.gz: 9d5225d78dc9168036d78f8a4765010efe5017deeaa9ba14b38073ab5c35f26b
5
5
  SHA512:
6
- metadata.gz: 1d542f2813cc0f5fd7280d4d9f642ef4f63bc45e6003e93819a3826f4a9d1b303d5dbd7f28ba07088191bd1ec098d7c037dced992ee3a8086c1d11853d6c2afc
7
- data.tar.gz: 46a117312369b8738f561401ad03fc71f68ec5f7dee6f5f2370dd7a53be95a5f0abf704da62d8bcb56e7a6026af8bfc0ddf5843707b643bdf5b37f949bd7311a
6
+ metadata.gz: e35a45da117851d8eb4802262438c056d9813c840ecbc7bd0775f81d1b2effe03e7e9697ebfe92db2962b05ff20d62f708c274786491fcafb6fba14c92480967
7
+ data.tar.gz: d8e98169fb0e2696063c28feb8e52c2b0305c83755cfe415f0c29de468465b2ed0d36c06f4502f0a9a0b924d083f64ed1675808b563c9c6f6f004e40530c3fd6
@@ -18,6 +18,7 @@ module Asciidoctor
18
18
  inline_macro Asciidoctor::Standoc::AltTermInlineMacro
19
19
  inline_macro Asciidoctor::Standoc::DeprecatedTermInlineMacro
20
20
  inline_macro Asciidoctor::Standoc::DomainTermInlineMacro
21
+ inline_macro Asciidoctor::Standoc::InheritInlineMacro
21
22
  inline_macro Asciidoctor::Standoc::HTML5RubyMacro
22
23
  inline_macro Asciidoctor::Standoc::ConceptInlineMacro
23
24
  block Asciidoctor::Standoc::ToDoAdmonitionBlock
@@ -32,8 +33,9 @@ module Asciidoctor
32
33
 
33
34
  def skip(node, name = nil)
34
35
  name = name || node.node_name
35
- w = "converter missing for #{name} node in ISO backend"
36
- Utils::warning(node, w, nil)
36
+ w = "converter missing for #{name} node in Metanorma backend"
37
+ @log.add("Asciidoctor Input", node, w)
38
+ #Utils::warning(node, w, nil)
37
39
  nil
38
40
  end
39
41
 
@@ -105,6 +107,7 @@ module Asciidoctor
105
107
  @seen_headers = []
106
108
  @datauriimage = node.attr("data-uri-image")
107
109
  @boilerplateauthority = node.attr("boilerplate-authority")
110
+ @log = Asciidoctor::Standoc::Log.new
108
111
  init_bib_caches(node)
109
112
  init_iev_caches(node)
110
113
  lang = (node.attr("language") || "en")
@@ -156,6 +159,7 @@ module Asciidoctor
156
159
  html_converter(node).convert(@filename + ".xml")
157
160
  doc_converter(node).convert(@filename + ".xml")
158
161
  end
162
+ @log.write(@filename + ".err") unless @novalid
159
163
  @files_to_delete.each { |f| FileUtils.rm f }
160
164
  ret
161
165
  end
@@ -223,7 +227,8 @@ module Asciidoctor
223
227
  def extract_termsource_refs(text, node)
224
228
  matched = TERM_REFERENCE_RE.match text
225
229
  matched.nil? and
226
- Utils::warning(node, "term reference not in expected format", text)
230
+ #Utils::warning(node, "term reference not in expected format", text)
231
+ @log.add("Asciidoctor Input", node, "term reference not in expected format: #{text}")
227
232
  matched
228
233
  end
229
234
 
@@ -138,6 +138,21 @@ module Asciidoctor
138
138
  end
139
139
 
140
140
  def requirement_cleanup(x)
141
+ requirement_descriptions(x)
142
+ requirement_inherit(x)
143
+ end
144
+
145
+ def requirement_inherit(x)
146
+ x.xpath("//requirement | //recommendation | //permission").each do |r|
147
+ ins = r.at("./classification") ||
148
+ r.at("./description | ./measurementtarget | ./specification | "\
149
+ "./verification | ./import | ./description | ./requirement | "\
150
+ "./recommendation | ./permission")
151
+ r.xpath("./*//inherit").each { |i| ins.previous = i }
152
+ end
153
+ end
154
+
155
+ def requirement_descriptions(x)
141
156
  x.xpath("//requirement | //recommendation | //permission").each do |r|
142
157
  r.children.each do |e|
143
158
  unless e.element? && (Utils::reqt_subpart(e.name) ||
@@ -15,8 +15,11 @@ module Asciidoctor
15
15
 
16
16
  def term_defs_boilerplate(div, source, term, preface, isodoc)
17
17
  div.next = @term_def_boilerplate
18
- source.each { |s| @anchors[s["bibitemid"]] or
19
- warn "term source #{s['bibitemid']} not referenced" }
18
+ source.each do |s|
19
+ @anchors[s["bibitemid"]] or
20
+ @log.add("Crossreferences", nil, "term source #{s['bibitemid']} not referenced")
21
+ #warn "term source #{s['bibitemid']} not referenced"
22
+ end
20
23
  if source.empty? && term.nil?
21
24
  div.next = @no_terms_boilerplate
22
25
  else
@@ -47,7 +47,7 @@ module Asciidoctor
47
47
  xmldoc.xpath("//table | //figure").each do |t|
48
48
  seen = {}
49
49
  i = 0
50
- t.xpath(".//fn").each do |fn|
50
+ t.xpath(".//fn[not(ancestor::name)]").each do |fn|
51
51
  i, seen = table_footnote_renumber1(fn, i, seen)
52
52
  end
53
53
  end
@@ -63,7 +63,8 @@ module Asciidoctor
63
63
  def xref_to_eref(x)
64
64
  x["bibitemid"] = x["target"]
65
65
  x["citeas"] = @anchors&.dig(x["target"], :xref) ||
66
- warn("#{x['target']} is not a real reference!")
66
+ #warn("#{x['target']} is not a real reference!")
67
+ @log.add("Crossreferences", nil, "#{x['target']} is not a real reference!")
67
68
  x.delete("target")
68
69
  extract_localities(x) unless x.children.empty?
69
70
  end
@@ -88,7 +89,8 @@ module Asciidoctor
88
89
  def origin_cleanup(xmldoc)
89
90
  xmldoc.xpath("//origin").each do |x|
90
91
  x["citeas"] = @anchors&.dig(x["bibitemid"], :xref) ||
91
- warn("#{x['bibitemid']} is not a real reference!")
92
+ # warn("#{x['bibitemid']} is not a real reference!")
93
+ @log.add("Crossreferences", nil, "#{x['bibitemid']} is not a real reference!")
92
94
  extract_localities(x) unless x.children.empty?
93
95
  end
94
96
  end
@@ -11,15 +11,36 @@ module Asciidoctor
11
11
  end
12
12
 
13
13
  def biblio_reorder1(refs)
14
+ fold_notes_into_biblio(refs)
14
15
  bib = sort_biblio(refs.xpath("./bibitem"))
16
+ insert = refs&.at("./bibitem")&.previous_element
15
17
  refs.xpath("./bibitem").each { |b| b.remove }
16
18
  bib.reverse.each do |b|
17
- insert = refs.at("./title") and insert.next = b.to_xml or
19
+ insert and insert.next = b.to_xml or
18
20
  refs.children.first.add_previous_sibling b.to_xml
19
21
  end
22
+ extract_notes_from_biblio(refs)
20
23
  refs.xpath("./references").each { |r| biblio_reorder1(r) }
21
24
  end
22
25
 
26
+ def fold_notes_into_biblio(refs)
27
+ refs.xpath("./bibitem").each do |r|
28
+ while r&.next_element&.name == "note" do
29
+ r.next_element["appended"] = true
30
+ r << r.next_element.remove
31
+ end
32
+ end
33
+ end
34
+
35
+ def extract_notes_from_biblio(refs)
36
+ refs.xpath("./bibitem").each do |r|
37
+ r.xpath("./note[@appended]").reverse.each do |n|
38
+ n.delete("appended")
39
+ r.next = n
40
+ end
41
+ end
42
+ end
43
+
23
44
  def sort_biblio(bib)
24
45
  bib
25
46
  end
@@ -47,9 +68,10 @@ module Asciidoctor
47
68
 
48
69
  def normref_cleanup(xmldoc)
49
70
  r = xmldoc.at(NORM_REF) || return
50
- r.elements.each do |n|
51
- n.remove unless ["title", "bibitem"].include? n.name
52
- end
71
+ #return if r.at("./bibitem[1]/preceding-sibling::*[1][local-name()='title']")
72
+ preface = r.xpath("./title/following-sibling::*") &
73
+ r.xpath("./bibitem[1]/preceding-sibling::*")
74
+ preface.each { |n| n.remove }
53
75
  end
54
76
 
55
77
  def biblio_cleanup(xmldoc)
@@ -14,6 +14,7 @@ require "asciidoctor/standoc/cleanup"
14
14
  require "asciidoctor/standoc/i18n"
15
15
  require "asciidoctor/standoc/reqt"
16
16
  require_relative "./macros.rb"
17
+ require_relative "./log.rb"
17
18
 
18
19
  module Asciidoctor
19
20
  module Standoc
@@ -43,7 +44,6 @@ module Asciidoctor
43
44
  super
44
45
  basebackend "html"
45
46
  outfilesuffix ".xml"
46
- #@libdir = File.dirname(__FILE__)
47
47
  @libdir = File.dirname(self.class::_file || __FILE__)
48
48
  end
49
49
 
@@ -645,6 +645,11 @@
645
645
  <optional>
646
646
  <attribute name="script"/>
647
647
  </optional>
648
+ <optional>
649
+ <attribute name="inline-header">
650
+ <data type="boolean"/>
651
+ </attribute>
652
+ </optional>
648
653
  <optional>
649
654
  <attribute name="obligation">
650
655
  <choice>
@@ -12,16 +12,34 @@ module Asciidoctor
12
12
  end
13
13
  end
14
14
 
15
+ def ul_li(xml_ul, item)
16
+ xml_ul.li **ul_li_attr(item) do |xml_li|
17
+ if item.blocks?
18
+ xml_li.p(**id_attr(item)) { |t| t << item.text }
19
+ xml_li << item.content
20
+ else
21
+ xml_li.p(**id_attr(item)) { |p| p << item.text }
22
+ end
23
+ end
24
+ end
25
+
15
26
  def ul_attr(node)
16
27
  attr_code(id_attr(node))
17
28
  end
18
29
 
30
+ def ul_li_attr(node)
31
+ attr_code(
32
+ uncheckedcheckbox: node.attr?("checkbox") ? !node.attr?("checked") : nil,
33
+ checkedcheckbox: node.attr?("checkbox") ? node.attr?("checked") : nil,
34
+ )
35
+ end
36
+
19
37
  def ulist(node)
20
38
  return reference(node) if in_norm_ref? || in_biblio?
21
39
  noko do |xml|
22
40
  xml.ul **ul_attr(node) do |xml_ul|
23
41
  node.items.each do |item|
24
- li(xml_ul, item)
42
+ ul_li(xml_ul, item)
25
43
  end
26
44
  end
27
45
  end.join("\n")
@@ -37,7 +55,7 @@ module Asciidoctor
37
55
 
38
56
  def ol_attr(node)
39
57
  attr_code(id: Utils::anchor_or_uuid(node),
40
- type: olist_style(node.style))
58
+ type: olist_style(node.style))
41
59
  end
42
60
 
43
61
  def olist(node)
@@ -0,0 +1,50 @@
1
+ module Asciidoctor
2
+ module Standoc
3
+ class Log
4
+ def initialize
5
+ @log = {}
6
+ end
7
+
8
+ def add(category, loc, msg)
9
+ return if @novalid
10
+ @log[category] = [] unless @log[category]
11
+ @log[category] << { location: current_location(loc), message: msg }
12
+ loc = loc.nil? ? "" : "(#{current_location(loc)}): "
13
+ warn "#{category}: #{loc}#{msg}"
14
+ end
15
+
16
+ def current_location(n)
17
+ return "" if n.nil?
18
+ return n if n.is_a? String
19
+ return "Asciidoctor Line #{"%06d" % n.lineno}" if n.respond_to?(:lineno) &&
20
+ !n.lineno.nil? && !n.lineno.empty?
21
+ return "XML Line #{"%06d" % n.line}" if n.respond_to?(:line) &&
22
+ !n.line.nil?
23
+ return "ID #{n.id}" if n.respond_to?(:id) && !n.id.nil?
24
+ while !n.nil? &&
25
+ (!n.respond_to?(:level) || n.level.positive?) &&
26
+ (!n.respond_to?(:context) || n.context != :section)
27
+ n = n.parent
28
+ return "Section: #{n.title}" if n&.respond_to?(:context) &&
29
+ n&.context == :section
30
+ end
31
+ "??"
32
+ end
33
+
34
+ def write(file)
35
+ File.open(file, "w:UTF-8") do |f|
36
+ f.puts "#{file} errors"
37
+ @log.keys.each do |key|
38
+ f.puts "\n\n== #{key}\n\n"
39
+ @log[key].sort do |a, b|
40
+ a[:location] <=> b[:location]
41
+ end.each do |n|
42
+ loc = n[:location] ? "(#{n[:location]}): " : ""
43
+ f.puts "#{loc}#{n[:message]}"
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -41,6 +41,18 @@ module Asciidoctor
41
41
  end
42
42
  end
43
43
 
44
+ class InheritInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
45
+ use_dsl
46
+ named :inherit
47
+ parse_content_as :text
48
+ using_format :short
49
+
50
+ def process(parent, _target, attrs)
51
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
52
+ %{<inherit>#{out}</inherit>}
53
+ end
54
+ end
55
+
44
56
  class ConceptInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
45
57
  use_dsl
46
58
  named :concept
@@ -43,7 +43,7 @@ module Asciidoctor
43
43
 
44
44
  def docid(t, code)
45
45
  type, code1 = /^\[\d+\]$|^\([^)]+\).*$/.match(code) ?
46
- ["metanorma", Utils::mn_code(code)] :
46
+ ["metanorma", mn_code(code)] :
47
47
  @bibdb&.docid_type(code) || [nil, code]
48
48
  code1.sub!(/^nofetch\((.+)\)$/, "\\1")
49
49
  t.docidentifier code1, **attr_code(type: type)
@@ -123,10 +123,12 @@ module Asciidoctor
123
123
  code = code.sub(/^\([^)]+\)/, "")
124
124
  hit = @bibdb&.fetch(code, year, opts)
125
125
  return nil if hit.nil?
126
- xml.parent.add_child(Utils::smart_render_xml(hit, code, opts[:title], opts[:usrlbl]))
126
+ xml.parent.add_child(smart_render_xml(hit, code, opts[:title],
127
+ opts[:usrlbl]))
127
128
  xml
128
129
  rescue RelatonBib::RequestError
129
- warn "Could not retrieve #{code}: no access to online site"
130
+ @log.add("Bibliography", nil, "Could not retrieve #{code}: "\
131
+ "no access to online site")
130
132
  nil
131
133
  end
132
134
 
@@ -140,34 +142,31 @@ module Asciidoctor
140
142
  end
141
143
  end
142
144
 
143
- MALFORMED_REF =
144
- "no anchor on reference, markup may be malformed: "\
145
- "see https://www.metanorma.com/author/topics/document-format/bibliography/ , "\
145
+ MALFORMED_REF = "no anchor on reference, markup may be malformed: see "\
146
+ "https://www.metanorma.com/author/topics/document-format/bibliography/ , "\
146
147
  "https://www.metanorma.com/author/iso/topics/markup/#bibliographies".freeze
147
148
 
148
149
  # TODO: alternative where only title is available
149
150
  def refitem(xml, item, node)
150
151
  unless m = NON_ISO_REF.match(item)
151
- Utils::warning(node, MALFORMED_REF, item)
152
+ @log.add("Asciidoctor Input", node, "#{MALFORMED_REF}: #{item}")
152
153
  return
153
154
  end
154
155
  unless m[:code] && /^\d+$/.match(m[:code])
155
156
  ref = fetch_ref xml, m[:code],
156
- m.names.include?("year") ? m[:year] : nil, title: m[:text], usrlbl: m[:usrlbl]
157
+ m.names.include?("year") ? m[:year] : nil, title: m[:text],
158
+ usrlbl: m[:usrlbl]
157
159
  return use_my_anchor(ref, m[:anchor]) if ref
158
160
  end
159
161
  refitem_render(xml, m)
160
162
  end
161
163
 
162
164
  def ref_normalise(ref)
163
- ref.
164
- gsub(/&amp;amp;/, "&amp;").
165
- gsub(%r{^<em>(.*)</em>}, "\\1")
165
+ ref.gsub(/&amp;amp;/, "&amp;").gsub(%r{^<em>(.*)</em>}, "\\1")
166
166
  end
167
167
 
168
168
  def ref_normalise_no_format(ref)
169
- ref.
170
- gsub(/&amp;amp;/, "&amp;")
169
+ ref.gsub(/&amp;amp;/, "&amp;")
171
170
  end
172
171
 
173
172
  ISO_REF = %r{^<ref\sid="(?<anchor>[^"]+)">
@@ -188,8 +187,6 @@ module Asciidoctor
188
187
  \[(?<usrlbl>\([^)]+\))?(?<code>[^\]]+?)([:-](?<year>(19|20)[0-9][0-9]))?\]</ref>,?\s*
189
188
  (?<text>.*)$}xm
190
189
 
191
- # @param item [String]
192
- # @return [Array<MatchData>]
193
190
  def reference1_matches(item)
194
191
  matched = ISO_REF.match item
195
192
  matched2 = ISO_REF_NO_YEAR.match item
@@ -197,9 +194,6 @@ module Asciidoctor
197
194
  [matched, matched2, matched3]
198
195
  end
199
196
 
200
- # @param node [Asciidoctor::List]
201
- # @param item [String]
202
- # @param xml [Nokogiri::XML::Builder]
203
197
  def reference1(node, item, xml)
204
198
  matched, matched2, matched3 = reference1_matches(item)
205
199
  if matched3.nil? && matched2.nil? && matched.nil?
@@ -228,6 +222,36 @@ module Asciidoctor
228
222
  cachename = "iev" if cachename.empty?
229
223
  "#{cachename}/cache"
230
224
  end
225
+
226
+ def mn_code(code)
227
+ code.sub(/^\(/, "[").sub(/\).*$/, "]").sub(/^nofetch\((.+)\)$/, "\\1")
228
+ end
229
+
230
+ def emend_biblio(xml, code, title, usrlbl)
231
+ unless xml.at("/bibitem/docidentifier[not(@type = 'DOI')][text()]")
232
+ @log.add("Bibliography", nil,
233
+ "ERROR: No document identifier retrieved for #{code}")
234
+ xml.root << "<docidentifier>#{code}</docidentifier>"
235
+ end
236
+ unless xml.at("/bibitem/title[text()]")
237
+ @log.add("Bibliography", nil,
238
+ "ERROR: No title retrieved for #{code}")
239
+ xml.root << "<title>#{title || "(MISSING TITLE)"}</title>"
240
+ end
241
+ usrlbl and xml.at("/bibitem/docidentifier").next =
242
+ "<docidentifier type='metanorma'>#{mn_code(usrlbl)}</docidentifier>"
243
+ end
244
+
245
+ def smart_render_xml(x, code, title, usrlbl)
246
+ xstr = x.to_xml if x.respond_to? :to_xml
247
+ xml = Nokogiri::XML(xstr)
248
+ emend_biblio(xml, code, title, usrlbl)
249
+ xml.xpath("//date").each { |d| Utils::endash_date(d) }
250
+ xml.traverse do |n|
251
+ n.text? and n.replace(Utils::smartformat(n.text))
252
+ end
253
+ xml.to_xml.sub(/<\?[^>]+>/, "")
254
+ end
231
255
  end
232
256
  end
233
257
  end
@@ -138,7 +138,8 @@ module Asciidoctor
138
138
 
139
139
  def bibliography_parse(attrs, xml, node)
140
140
  node.attr("style") == "bibliography" or
141
- warn "Section not marked up as [bibliography]!"
141
+ #warn "Section not marked up as [bibliography]!"
142
+ @log.add("Asciidoctor Input", node, "Section not marked up as [bibliography]!")
142
143
  @biblio = true
143
144
  xml.references **attr_code(attrs) do |xml_section|
144
145
  title = node.level == 1 ? "Bibliography" : node.title