metanorma-standoc 1.3.20 → 1.3.21
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 +4 -4
- data/lib/asciidoctor/standoc/base.rb +8 -3
- data/lib/asciidoctor/standoc/cleanup_block.rb +15 -0
- data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +5 -2
- data/lib/asciidoctor/standoc/cleanup_footnotes.rb +1 -1
- data/lib/asciidoctor/standoc/cleanup_inline.rb +4 -2
- data/lib/asciidoctor/standoc/cleanup_ref.rb +26 -4
- data/lib/asciidoctor/standoc/converter.rb +1 -1
- data/lib/asciidoctor/standoc/isodoc.rng +5 -0
- data/lib/asciidoctor/standoc/lists.rb +20 -2
- data/lib/asciidoctor/standoc/log.rb +50 -0
- data/lib/asciidoctor/standoc/macros.rb +12 -0
- data/lib/asciidoctor/standoc/ref.rb +42 -18
- data/lib/asciidoctor/standoc/section.rb +2 -1
- data/lib/asciidoctor/standoc/table.rb +3 -1
- data/lib/asciidoctor/standoc/utils.rb +10 -51
- data/lib/asciidoctor/standoc/validate.rb +16 -3
- data/lib/asciidoctor/standoc/validate_section.rb +5 -4
- data/lib/metanorma/standoc/version.rb +1 -1
- data/metanorma-standoc.gemspec +1 -2
- data/spec/asciidoctor-standoc/cleanup_spec.rb +164 -2
- data/spec/asciidoctor-standoc/lists_spec.rb +49 -36
- data/spec/asciidoctor-standoc/macros_spec.rb +29 -6
- data/spec/asciidoctor-standoc/table_spec.rb +2 -2
- data/spec/asciidoctor-standoc/validate_spec.rb +52 -11
- metadata +5 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c62f787dbc1d97b2175f66f6130d2b365af18bedffa9de98a236f39f756c3ae8
|
4
|
+
data.tar.gz: 9d5225d78dc9168036d78f8a4765010efe5017deeaa9ba14b38073ab5c35f26b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
36
|
-
|
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
|
19
|
-
|
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
|
@@ -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
|
-
|
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
|
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.
|
51
|
-
|
52
|
-
|
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
|
|
@@ -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
|
-
|
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
|
-
|
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",
|
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(
|
126
|
+
xml.parent.add_child(smart_render_xml(hit, code, opts[:title],
|
127
|
+
opts[:usrlbl]))
|
127
128
|
xml
|
128
129
|
rescue RelatonBib::RequestError
|
129
|
-
|
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
|
-
"
|
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
|
-
|
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],
|
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;/, "&").
|
165
|
-
gsub(%r{^<em>(.*)</em>}, "\\1")
|
165
|
+
ref.gsub(/&amp;/, "&").gsub(%r{^<em>(.*)</em>}, "\\1")
|
166
166
|
end
|
167
167
|
|
168
168
|
def ref_normalise_no_format(ref)
|
169
|
-
ref.
|
170
|
-
gsub(/&amp;/, "&")
|
169
|
+
ref.gsub(/&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
|