metanorma-standoc 1.8.8 → 1.9.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/rake.yml +3 -13
- data/.hound.yml +3 -1
- data/.rubocop.yml +3 -7
- data/Gemfile.devel +0 -0
- data/lib/asciidoctor/standoc/base.rb +42 -36
- data/lib/asciidoctor/standoc/biblio.rng +1 -0
- data/lib/asciidoctor/standoc/blocks.rb +25 -9
- data/lib/asciidoctor/standoc/blocks_notes.rb +41 -24
- data/lib/asciidoctor/standoc/cleanup.rb +59 -84
- data/lib/asciidoctor/standoc/cleanup_block.rb +63 -85
- data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +51 -29
- data/lib/asciidoctor/standoc/cleanup_footnotes.rb +1 -0
- data/lib/asciidoctor/standoc/cleanup_image.rb +71 -0
- data/lib/asciidoctor/standoc/cleanup_maths.rb +36 -27
- data/lib/asciidoctor/standoc/cleanup_ref.rb +24 -15
- data/lib/asciidoctor/standoc/cleanup_ref_dl.rb +1 -1
- data/lib/asciidoctor/standoc/cleanup_reqt.rb +47 -0
- data/lib/asciidoctor/standoc/cleanup_section.rb +77 -134
- data/lib/asciidoctor/standoc/cleanup_section_names.rb +75 -0
- data/lib/asciidoctor/standoc/converter.rb +10 -3
- data/lib/asciidoctor/standoc/datamodel/plantuml_renderer.rb +67 -66
- data/lib/asciidoctor/standoc/front.rb +35 -18
- data/lib/asciidoctor/standoc/front_contributor.rb +70 -45
- data/lib/asciidoctor/standoc/inline.rb +30 -22
- data/lib/asciidoctor/standoc/isodoc.rng +321 -4
- data/lib/asciidoctor/standoc/lists.rb +4 -2
- data/lib/asciidoctor/standoc/macros.rb +50 -23
- data/lib/asciidoctor/standoc/macros_form.rb +63 -0
- data/lib/asciidoctor/standoc/ref.rb +87 -112
- data/lib/asciidoctor/standoc/ref_date_id.rb +62 -0
- data/lib/asciidoctor/standoc/ref_sect.rb +20 -17
- data/lib/asciidoctor/standoc/section.rb +3 -1
- data/lib/asciidoctor/standoc/term_lookup_cleanup.rb +31 -16
- data/lib/asciidoctor/standoc/terms.rb +27 -16
- data/lib/asciidoctor/standoc/utils.rb +35 -9
- data/lib/asciidoctor/standoc/validate.rb +30 -28
- data/lib/metanorma-standoc.rb +0 -1
- data/lib/metanorma/standoc/version.rb +5 -5
- data/metanorma-standoc.gemspec +11 -11
- data/spec/asciidoctor/base_spec.rb +715 -509
- data/spec/asciidoctor/blocks_spec.rb +830 -727
- data/spec/asciidoctor/cleanup_sections_spec.rb +51 -14
- data/spec/asciidoctor/cleanup_spec.rb +1836 -1673
- data/spec/asciidoctor/inline_spec.rb +330 -283
- data/spec/asciidoctor/isobib_cache_spec.rb +406 -358
- data/spec/asciidoctor/lists_spec.rb +3 -3
- data/spec/asciidoctor/macros_plantuml_spec.rb +8 -8
- data/spec/asciidoctor/macros_spec.rb +546 -444
- data/spec/asciidoctor/macros_yaml2text_spec.rb +1 -1
- data/spec/asciidoctor/refs_dl_spec.rb +4 -4
- data/spec/asciidoctor/refs_spec.rb +1528 -1533
- data/spec/asciidoctor/section_spec.rb +778 -689
- data/spec/asciidoctor/table_spec.rb +6 -6
- data/spec/asciidoctor/validate_spec.rb +296 -304
- data/spec/spec_helper.rb +13 -9
- data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +66 -66
- data/spec/vcr_cassettes/isobib_get_123.yml +17 -17
- data/spec/vcr_cassettes/isobib_get_123_1.yml +31 -31
- data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +40 -40
- data/spec/vcr_cassettes/isobib_get_123_2001.yml +17 -17
- data/spec/vcr_cassettes/isobib_get_124.yml +16 -16
- data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +14 -14
- data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +78 -66
- metadata +69 -67
- data/lib/liquid/custom_blocks/key_iterator.rb +0 -21
- data/lib/liquid/custom_blocks/with_json_nested_context.rb +0 -18
- data/lib/liquid/custom_blocks/with_yaml_nested_context.rb +0 -19
- data/lib/liquid/custom_filters/values.rb +0 -7
@@ -0,0 +1,62 @@
|
|
1
|
+
module Asciidoctor
|
2
|
+
module Standoc
|
3
|
+
module Refs
|
4
|
+
def set_date_range(date, text)
|
5
|
+
matched = /^(?<from>[0-9]+)(-+(?<to>[0-9]+))?$/.match text
|
6
|
+
return unless matched[:from]
|
7
|
+
|
8
|
+
if matched[:to]
|
9
|
+
date.from matched[:from]
|
10
|
+
date.to matched[:to]
|
11
|
+
else
|
12
|
+
date.on matched[:from]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def id_and_year(id, year)
|
17
|
+
year ? "#{id}:#{year}" : id
|
18
|
+
end
|
19
|
+
|
20
|
+
def norm_year(year)
|
21
|
+
/^&\#821[12];$/.match(year) and return "--"
|
22
|
+
/^\d\d\d\d-\d\d\d\d$/.match(year) and return year
|
23
|
+
year&.sub(/(?<=[0-9])-.*$/, "")
|
24
|
+
end
|
25
|
+
|
26
|
+
def conditional_date(bib, match, noyr)
|
27
|
+
if match.names.include?("year") && !match[:year].nil?
|
28
|
+
bib.date(**{ type: "published" }) do |d|
|
29
|
+
noyr and d.on "--" or set_date_range(d, norm_year(match[:year]))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def use_my_anchor(ref, id)
|
35
|
+
ref.parent.elements.last["id"] = id
|
36
|
+
ref
|
37
|
+
end
|
38
|
+
|
39
|
+
def docid(bib, code)
|
40
|
+
type, code1 = if /^\[\d+\]$|^\([^)]+\).*$/.match?(code)
|
41
|
+
["metanorma", mn_code(code)]
|
42
|
+
else
|
43
|
+
@bibdb&.docid_type(code) || [nil, code]
|
44
|
+
end
|
45
|
+
code1.sub!(/^nofetch\((.+)\)$/, "\\1")
|
46
|
+
bib.docidentifier **attr_code(type: type) do |d|
|
47
|
+
d << code1
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def docnumber(bib, code)
|
52
|
+
bib.docnumber do |d|
|
53
|
+
d << HTMLEntities.new.decode(code).sub(/^[^\d]*/, "")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def mn_code(code)
|
58
|
+
code.sub(/^\(/, "[").sub(/\).*$/, "]").sub(/^nofetch\((.+)\)$/, "\\1")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -10,10 +10,10 @@ module Asciidoctor
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def reference(node)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
noko do |xml|
|
14
|
+
node.items.each { |item| reference1(node, item.text, xml) }
|
15
|
+
end.join
|
16
|
+
end
|
17
17
|
|
18
18
|
def bibliography_parse(attrs, xml, node)
|
19
19
|
node.option? "bibitem" and return bibitem_parse(attrs, xml, node)
|
@@ -43,12 +43,12 @@ module Asciidoctor
|
|
43
43
|
node.attr("style") == "bibliography" or
|
44
44
|
@log.add("AsciiDoc Input", node, "Section not marked up as [bibliography]!")
|
45
45
|
@norm_ref = true
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
46
|
+
attrs = attrs.merge(normative: node.attr("normative") || true)
|
47
|
+
xml.references **attr_code(attrs) do |xml_section|
|
48
|
+
xml_section.title { |t| t << node.title }
|
49
|
+
xml_section << node.content
|
50
|
+
end
|
51
|
+
@norm_ref = false
|
52
52
|
end
|
53
53
|
|
54
54
|
def global_ievcache_name
|
@@ -57,6 +57,7 @@ module Asciidoctor
|
|
57
57
|
|
58
58
|
def local_ievcache_name(cachename)
|
59
59
|
return nil if cachename.nil?
|
60
|
+
|
60
61
|
cachename += "_iev" unless cachename.empty?
|
61
62
|
cachename = "iev" if cachename.empty?
|
62
63
|
"#{cachename}/cache"
|
@@ -64,10 +65,11 @@ module Asciidoctor
|
|
64
65
|
|
65
66
|
def fetch_ref(xml, code, year, **opts)
|
66
67
|
return nil if opts[:no_year]
|
68
|
+
|
67
69
|
code = code.sub(/^\([^)]+\)/, "")
|
68
|
-
#require "byebug"; byebug if opts[:lang] == "fr"
|
69
70
|
hit = @bibdb&.fetch(code, year, opts)
|
70
71
|
return nil if hit.nil?
|
72
|
+
|
71
73
|
xml.parent.add_child(smart_render_xml(hit, code, opts))
|
72
74
|
xml
|
73
75
|
rescue RelatonBib::RequestError
|
@@ -91,10 +93,9 @@ module Asciidoctor
|
|
91
93
|
"<docidentifier type='metanorma'>#{mn_code(usrlbl)}</docidentifier>"
|
92
94
|
end
|
93
95
|
|
94
|
-
def smart_render_xml(
|
95
|
-
|
96
|
-
|
97
|
-
xml = Nokogiri::XML(xstr)
|
96
|
+
def smart_render_xml(xml, code, opts)
|
97
|
+
xml.respond_to? :to_xml or return nil
|
98
|
+
xml = Nokogiri::XML(xml.to_xml(lang: opts[:lang]))
|
98
99
|
emend_biblio(xml, code, opts[:title], opts[:usrlbl])
|
99
100
|
xml.xpath("//date").each { |d| Metanorma::Utils::endash_date(d) }
|
100
101
|
xml.traverse do |n|
|
@@ -105,17 +106,19 @@ module Asciidoctor
|
|
105
106
|
|
106
107
|
def init_bib_caches(node)
|
107
108
|
return if @no_isobib
|
109
|
+
|
108
110
|
global = !@no_isobib_cache && !node.attr("local-cache-only")
|
109
111
|
local = node.attr("local-cache") || node.attr("local-cache-only")
|
110
112
|
local = nil if @no_isobib_cache
|
111
113
|
@bibdb = Relaton::DbCache.init_bib_caches(
|
112
114
|
local_cache: local,
|
113
115
|
flush_caches: node.attr("flush-caches"),
|
114
|
-
global_cache: global
|
116
|
+
global_cache: global
|
117
|
+
)
|
115
118
|
end
|
116
119
|
|
117
120
|
def init_iev_caches(node)
|
118
|
-
unless
|
121
|
+
unless @no_isobib_cache || @no_isobib
|
119
122
|
node.attr("local-cache-only") or
|
120
123
|
@iev_globalname = global_ievcache_name
|
121
124
|
@iev_localname = local_ievcache_name(node.attr("local-cache") ||
|
@@ -10,7 +10,9 @@ module Asciidoctor
|
|
10
10
|
@norm_ref = false
|
11
11
|
|
12
12
|
def sectiontype1(node)
|
13
|
-
node&.attr("heading")&.downcase ||
|
13
|
+
node&.attr("heading")&.downcase ||
|
14
|
+
node.title.gsub(%r{<index>.*?</index>}m, "").gsub(/<[^>]+>/, "")
|
15
|
+
.strip.downcase
|
14
16
|
end
|
15
17
|
|
16
18
|
def sectiontype(node, level = true)
|
@@ -6,8 +6,8 @@ module Asciidoctor
|
|
6
6
|
# Lookup all `term` and `calause` tags and replace `termxref` tags with
|
7
7
|
# `xref`:target tag
|
8
8
|
class TermLookupCleanup
|
9
|
-
AUTOMATIC_GENERATED_ID_REGEXP = /\A_
|
10
|
-
EXISTING_TERM_REGEXP = /\Aterm
|
9
|
+
AUTOMATIC_GENERATED_ID_REGEXP = /\A_/.freeze
|
10
|
+
EXISTING_TERM_REGEXP = /\Aterm-/.freeze
|
11
11
|
|
12
12
|
attr_reader :xmldoc, :termlookup, :log
|
13
13
|
|
@@ -15,17 +15,27 @@ module Asciidoctor
|
|
15
15
|
@xmldoc = xmldoc
|
16
16
|
@log = log
|
17
17
|
@termlookup = {}
|
18
|
+
@idhash = {}
|
18
19
|
end
|
19
20
|
|
20
21
|
def call
|
22
|
+
@idhash = populate_idhash
|
21
23
|
@termlookup = replace_automatic_generated_ids_terms
|
22
24
|
set_termxref_tags_target
|
23
25
|
end
|
24
26
|
|
25
27
|
private
|
26
28
|
|
29
|
+
def populate_idhash
|
30
|
+
xmldoc.xpath("//*[@id]").each_with_object({}) do |n, mem|
|
31
|
+
next unless /^term-/.match?(n["id"])
|
32
|
+
|
33
|
+
mem[n["id"]] = true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
27
37
|
def set_termxref_tags_target
|
28
|
-
xmldoc.xpath(
|
38
|
+
xmldoc.xpath("//termxref").each do |node|
|
29
39
|
target = normalize_ref_id(node.text)
|
30
40
|
if termlookup[target].nil?
|
31
41
|
remove_missing_ref(node, target)
|
@@ -36,7 +46,7 @@ module Asciidoctor
|
|
36
46
|
end
|
37
47
|
|
38
48
|
def remove_missing_ref(node, target)
|
39
|
-
log.add(
|
49
|
+
log.add("AsciiDoc Input", node,
|
40
50
|
%(Error: Term reference in `term[#{target}]` missing: \
|
41
51
|
"#{target}" is not defined in document))
|
42
52
|
term_name_node = node.previous.previous
|
@@ -49,34 +59,39 @@ module Asciidoctor
|
|
49
59
|
end
|
50
60
|
|
51
61
|
def modify_ref_node(node, target)
|
52
|
-
node.name =
|
53
|
-
node[
|
62
|
+
node.name = "xref"
|
63
|
+
node["target"] = termlookup[target]
|
54
64
|
node.children.remove
|
55
|
-
node.remove_attribute(
|
65
|
+
node.remove_attribute("defaultref")
|
56
66
|
end
|
57
67
|
|
58
68
|
def replace_automatic_generated_ids_terms
|
59
|
-
xmldoc.xpath(
|
60
|
-
normalize_id_and_memorize(term_node, res,
|
69
|
+
xmldoc.xpath("//term").each.with_object({}) do |term_node, res|
|
70
|
+
normalize_id_and_memorize(term_node, res, "./preferred")
|
61
71
|
end
|
62
72
|
end
|
63
73
|
|
64
74
|
def normalize_id_and_memorize(term_node, res_table, text_selector)
|
65
75
|
term_text = normalize_ref_id(term_node.at(text_selector).text)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
76
|
+
unless AUTOMATIC_GENERATED_ID_REGEXP.match(term_node["id"]).nil?
|
77
|
+
id = unique_text_id(term_text)
|
78
|
+
term_node["id"] = id
|
79
|
+
@idhash[id] = true
|
80
|
+
end
|
81
|
+
res_table[term_text] = term_node["id"]
|
70
82
|
end
|
71
83
|
|
72
84
|
def normalize_ref_id(text)
|
73
|
-
text.downcase.gsub(/[[:space:]]/,
|
85
|
+
text.downcase.gsub(/[[:space:]]/, "-")
|
74
86
|
end
|
75
87
|
|
76
88
|
def unique_text_id(text)
|
77
|
-
|
89
|
+
unless @idhash["term-#{text}"]
|
90
|
+
return "term-#{text}"
|
91
|
+
end
|
92
|
+
|
78
93
|
(1..Float::INFINITY).lazy.each do |index|
|
79
|
-
|
94
|
+
unless @idhash["term-#{text}-#{index}"]
|
80
95
|
break("term-#{text}-#{index}")
|
81
96
|
end
|
82
97
|
end
|
@@ -12,12 +12,13 @@ module Asciidoctor
|
|
12
12
|
@definitions = defs
|
13
13
|
end
|
14
14
|
|
15
|
-
def symbols_attrs(node,
|
15
|
+
def symbols_attrs(node, attr)
|
16
16
|
case sectiontype1(node)
|
17
|
-
when "symbols" then
|
18
|
-
when "abbreviated terms", "abbreviations"
|
17
|
+
when "symbols" then attr.merge(type: "symbols")
|
18
|
+
when "abbreviated terms", "abbreviations"
|
19
|
+
attr.merge(type: "abbreviated_terms")
|
19
20
|
else
|
20
|
-
|
21
|
+
attr
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
@@ -51,13 +52,17 @@ module Asciidoctor
|
|
51
52
|
|
52
53
|
# subclause contains subclauses
|
53
54
|
def term_def_subclause_parse(attrs, xml, node)
|
54
|
-
node.role == "nonterm"
|
55
|
-
|
55
|
+
node.role == "nonterm" and
|
56
|
+
return nonterm_term_def_subclause_parse(attrs, xml, node)
|
57
|
+
node.role == "boilerplate" and
|
58
|
+
return terms_boilerplate_parse(attrs, xml, node)
|
56
59
|
st = sectiontype(node, false)
|
57
60
|
return symbols_parse(attrs, xml, node) if @definitions
|
61
|
+
|
58
62
|
sub = node.find_by(context: :section) { |s| s.level == node.level + 1 }
|
59
63
|
sub.empty? || (return term_def_parse(attrs, xml, node, false))
|
60
|
-
st == "symbols and abbreviated terms" and
|
64
|
+
st == "symbols and abbreviated terms" and
|
65
|
+
return symbols_parse(attrs, xml, node)
|
61
66
|
st == "terms and definitions" and return clause_parse(attrs, xml, node)
|
62
67
|
term_def_subclause_parse1(attrs, xml, node)
|
63
68
|
end
|
@@ -69,7 +74,7 @@ module Asciidoctor
|
|
69
74
|
end
|
70
75
|
end
|
71
76
|
|
72
|
-
def term_def_parse(attrs, xml, node,
|
77
|
+
def term_def_parse(attrs, xml, node, _toplevel)
|
73
78
|
xml.terms **attr_code(attrs) do |section|
|
74
79
|
section.title { |t| t << node.title }
|
75
80
|
(s = node.attr("source")) && s.split(/,/).each do |s1|
|
@@ -79,19 +84,23 @@ module Asciidoctor
|
|
79
84
|
end
|
80
85
|
end
|
81
86
|
|
82
|
-
def term_source_attrs(seen_xref)
|
83
|
-
{
|
87
|
+
def term_source_attrs(_node, seen_xref)
|
88
|
+
{ case: seen_xref.children[0]["case"],
|
89
|
+
droploc: seen_xref.children[0]["droploc"],
|
90
|
+
bibitemid: seen_xref.children[0]["target"],
|
84
91
|
format: seen_xref.children[0]["format"], type: "inline" }
|
85
92
|
end
|
86
93
|
|
87
|
-
def add_term_source(xml_t, seen_xref,
|
94
|
+
def add_term_source(node, xml_t, seen_xref, match)
|
88
95
|
if seen_xref.children[0].name == "concept"
|
89
96
|
xml_t.origin { |o| o << seen_xref.children[0].to_xml }
|
90
97
|
else
|
91
|
-
|
98
|
+
attrs = term_source_attrs(node, seen_xref)
|
99
|
+
attrs.delete(:text)
|
100
|
+
xml_t.origin seen_xref.children[0].content, **attr_code(attrs)
|
92
101
|
end
|
93
|
-
|
94
|
-
mod.p { |p| p <<
|
102
|
+
match[:text] && xml_t.modification do |mod|
|
103
|
+
mod.p { |p| p << match[:text].sub(/^\s+/, "") }
|
95
104
|
end
|
96
105
|
end
|
97
106
|
|
@@ -106,7 +115,9 @@ module Asciidoctor
|
|
106
115
|
|
107
116
|
def extract_termsource_refs(text, node)
|
108
117
|
matched = TERM_REFERENCE_RE.match text
|
109
|
-
matched.nil? and @log.add("AsciiDoc Input", node,
|
118
|
+
matched.nil? and @log.add("AsciiDoc Input", node,
|
119
|
+
"term reference not in expected format:"\
|
120
|
+
"#{text}")
|
110
121
|
matched
|
111
122
|
end
|
112
123
|
|
@@ -116,7 +127,7 @@ module Asciidoctor
|
|
116
127
|
attrs = { status: matched[:text] ? "modified" : "identical" }
|
117
128
|
xml.termsource **attrs do |xml_t|
|
118
129
|
seen_xref = Nokogiri::XML.fragment(matched[:xref])
|
119
|
-
add_term_source(xml_t, seen_xref, matched)
|
130
|
+
add_term_source(node, xml_t, seen_xref, matched)
|
120
131
|
end
|
121
132
|
end.join("\n")
|
122
133
|
end
|
@@ -19,11 +19,11 @@ module Asciidoctor
|
|
19
19
|
end
|
20
20
|
|
21
21
|
NOKOHEAD = <<~HERE.freeze
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
<!DOCTYPE html SYSTEM
|
23
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
24
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
25
|
+
<head> <title></title> <meta charset="UTF-8" /> </head>
|
26
|
+
<body> </body> </html>
|
27
27
|
HERE
|
28
28
|
|
29
29
|
# block for processing XML document fragments as XHTML,
|
@@ -34,9 +34,9 @@ module Asciidoctor
|
|
34
34
|
fragment = doc.fragment("")
|
35
35
|
::Nokogiri::XML::Builder.with fragment, &block
|
36
36
|
fragment.to_xml(encoding: "US-ASCII", indent: 0).lines.map do |l|
|
37
|
-
l.gsub(/>\n$/, ">").gsub(/\s*\n$/m, " ").gsub("–", "\u0096")
|
38
|
-
gsub("—", "\u0097").gsub("–", "\u0096")
|
39
|
-
gsub("—", "\u0097")
|
37
|
+
l.gsub(/>\n$/, ">").gsub(/\s*\n$/m, " ").gsub("–", "\u0096")
|
38
|
+
.gsub("—", "\u0097").gsub("–", "\u0096")
|
39
|
+
.gsub("—", "\u0097")
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -66,10 +66,36 @@ module Asciidoctor
|
|
66
66
|
conv
|
67
67
|
end
|
68
68
|
|
69
|
+
def default_script(lang)
|
70
|
+
case lang
|
71
|
+
when "ar", "fa"
|
72
|
+
"Arab"
|
73
|
+
when "ur"
|
74
|
+
"Aran"
|
75
|
+
when "ru", "bg"
|
76
|
+
"Cyrl"
|
77
|
+
when "hi"
|
78
|
+
"Deva"
|
79
|
+
when "el"
|
80
|
+
"Grek"
|
81
|
+
when "zh"
|
82
|
+
"Hans"
|
83
|
+
when "ko"
|
84
|
+
"Kore"
|
85
|
+
when "he"
|
86
|
+
"Hebr"
|
87
|
+
when "ja"
|
88
|
+
"Jpan"
|
89
|
+
else
|
90
|
+
"Latn"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
69
94
|
class EmptyAttr
|
70
|
-
def attr(
|
95
|
+
def attr(_any_attribute)
|
71
96
|
nil
|
72
97
|
end
|
98
|
+
|
73
99
|
def attributes
|
74
100
|
{}
|
75
101
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require "asciidoctor/standoc/utils"
|
2
|
-
require_relative "./validate_section
|
2
|
+
require_relative "./validate_section"
|
3
3
|
require "nokogiri"
|
4
4
|
require "jing"
|
5
5
|
require "iev"
|
@@ -7,13 +7,13 @@ require "iev"
|
|
7
7
|
module Asciidoctor
|
8
8
|
module Standoc
|
9
9
|
module Validate
|
10
|
-
|
11
10
|
SOURCELOCALITY = "./termsource/origin//locality[@type = 'clause']/"\
|
12
11
|
"referenceFrom".freeze
|
13
12
|
|
14
13
|
def init_iev
|
15
14
|
return nil if @no_isobib
|
16
15
|
return @iev if @iev
|
16
|
+
|
17
17
|
@iev = Iev::Db.new(@iev_globalname, @iev_localname) unless @no_isobib
|
18
18
|
@iev
|
19
19
|
end
|
@@ -44,23 +44,23 @@ module Asciidoctor
|
|
44
44
|
found = false
|
45
45
|
doc.xpath("//references[@normative = 'true']/bibitem").each do |b|
|
46
46
|
next unless docid = b.at("./docidentifier[@type = 'metanorma']")
|
47
|
-
next unless
|
48
|
-
|
47
|
+
next unless /^\[\d+\]$/.match?(docid.text)
|
48
|
+
|
49
|
+
@log.add("Bibliography", b,
|
50
|
+
"Numeric reference in normative references")
|
49
51
|
found = true
|
50
52
|
end
|
51
|
-
|
52
|
-
|
53
|
-
abort("Numeric reference in normative references")
|
54
|
-
end
|
53
|
+
found and
|
54
|
+
clean_abort("Numeric reference in normative references", doc.to_xml)
|
55
55
|
end
|
56
56
|
|
57
|
-
def repeat_id_validate1(ids,
|
58
|
-
if ids[
|
59
|
-
@log.add("Anchors",
|
60
|
-
"at line #{ids[
|
57
|
+
def repeat_id_validate1(ids, elem)
|
58
|
+
if ids[elem["id"]]
|
59
|
+
@log.add("Anchors", elem, "Anchor #{elem['id']} has already been "\
|
60
|
+
"used at line #{ids[elem['id']]}")
|
61
61
|
raise StandardError.new "Error: multiple instances of same ID"
|
62
62
|
else
|
63
|
-
ids[
|
63
|
+
ids[elem["id"]] = elem.line
|
64
64
|
end
|
65
65
|
ids
|
66
66
|
end
|
@@ -72,39 +72,41 @@ module Asciidoctor
|
|
72
72
|
ids = repeat_id_validate1(ids, x)
|
73
73
|
end
|
74
74
|
rescue StandardError => e
|
75
|
-
|
76
|
-
abort(e.message)
|
75
|
+
clean_abort(e.message, doc.to_xml)
|
77
76
|
end
|
78
77
|
end
|
79
78
|
|
80
79
|
def schema_validate(doc, schema)
|
81
|
-
Tempfile.open(["tmp", ".xml"], :
|
80
|
+
Tempfile.open(["tmp", ".xml"], encoding: "UTF-8") do |f|
|
82
81
|
begin
|
83
|
-
f
|
84
|
-
f.close
|
85
|
-
errors = Jing.new(schema).validate(f.path)
|
86
|
-
warn "Syntax Valid!" if errors.none?
|
87
|
-
errors.each do |e|
|
88
|
-
@log.add("Metanorma XML Syntax",
|
89
|
-
"XML Line #{"%06d" % e[:line]}:#{e[:column]}",
|
90
|
-
e[:message])
|
91
|
-
end
|
82
|
+
schema_validate1(f, doc, schema)
|
92
83
|
rescue Jing::Error => e
|
93
|
-
|
94
|
-
abort "Jing failed with error: #{e}"
|
84
|
+
clean_abort("Jing failed with error: #{e}", doc.to_xml)
|
95
85
|
ensure
|
96
86
|
f.close!
|
97
87
|
end
|
98
88
|
end
|
99
89
|
end
|
100
90
|
|
91
|
+
def schema_validate1(file, doc, schema)
|
92
|
+
file.write(doc.to_xml)
|
93
|
+
file.close
|
94
|
+
errors = Jing.new(schema).validate(file.path)
|
95
|
+
warn "Syntax Valid!" if errors.none?
|
96
|
+
errors.each do |e|
|
97
|
+
@log.add("Metanorma XML Syntax",
|
98
|
+
"XML Line #{'%06d' % e[:line]}:#{e[:column]}", e[:message])
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
101
102
|
# RelaxNG cannot cope well with wildcard attributes. So we strip
|
102
103
|
# any attributes from FormattedString instances (which can contain
|
103
104
|
# xs:any markup, and are signalled with @format) before validation.
|
104
105
|
def formattedstr_strip(doc)
|
105
106
|
doc.xpath("//*[@format] | //stem | //bibdata//description | "\
|
106
107
|
"//formattedref | //bibdata//note | //bibdata/abstract | "\
|
107
|
-
"//bibitem/abstract | //bibitem/note | //misc-container")
|
108
|
+
"//bibitem/abstract | //bibitem/note | //misc-container")
|
109
|
+
.each do |n|
|
108
110
|
n.elements.each do |e|
|
109
111
|
e.traverse do |e1|
|
110
112
|
e1.element? and e1.each { |k, _v| e1.delete(k) }
|