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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +3 -13
  3. data/.hound.yml +3 -1
  4. data/.rubocop.yml +3 -7
  5. data/Gemfile.devel +0 -0
  6. data/lib/asciidoctor/standoc/base.rb +42 -36
  7. data/lib/asciidoctor/standoc/biblio.rng +1 -0
  8. data/lib/asciidoctor/standoc/blocks.rb +25 -9
  9. data/lib/asciidoctor/standoc/blocks_notes.rb +41 -24
  10. data/lib/asciidoctor/standoc/cleanup.rb +59 -84
  11. data/lib/asciidoctor/standoc/cleanup_block.rb +63 -85
  12. data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +51 -29
  13. data/lib/asciidoctor/standoc/cleanup_footnotes.rb +1 -0
  14. data/lib/asciidoctor/standoc/cleanup_image.rb +71 -0
  15. data/lib/asciidoctor/standoc/cleanup_maths.rb +36 -27
  16. data/lib/asciidoctor/standoc/cleanup_ref.rb +24 -15
  17. data/lib/asciidoctor/standoc/cleanup_ref_dl.rb +1 -1
  18. data/lib/asciidoctor/standoc/cleanup_reqt.rb +47 -0
  19. data/lib/asciidoctor/standoc/cleanup_section.rb +77 -134
  20. data/lib/asciidoctor/standoc/cleanup_section_names.rb +75 -0
  21. data/lib/asciidoctor/standoc/converter.rb +10 -3
  22. data/lib/asciidoctor/standoc/datamodel/plantuml_renderer.rb +67 -66
  23. data/lib/asciidoctor/standoc/front.rb +35 -18
  24. data/lib/asciidoctor/standoc/front_contributor.rb +70 -45
  25. data/lib/asciidoctor/standoc/inline.rb +30 -22
  26. data/lib/asciidoctor/standoc/isodoc.rng +321 -4
  27. data/lib/asciidoctor/standoc/lists.rb +4 -2
  28. data/lib/asciidoctor/standoc/macros.rb +50 -23
  29. data/lib/asciidoctor/standoc/macros_form.rb +63 -0
  30. data/lib/asciidoctor/standoc/ref.rb +87 -112
  31. data/lib/asciidoctor/standoc/ref_date_id.rb +62 -0
  32. data/lib/asciidoctor/standoc/ref_sect.rb +20 -17
  33. data/lib/asciidoctor/standoc/section.rb +3 -1
  34. data/lib/asciidoctor/standoc/term_lookup_cleanup.rb +31 -16
  35. data/lib/asciidoctor/standoc/terms.rb +27 -16
  36. data/lib/asciidoctor/standoc/utils.rb +35 -9
  37. data/lib/asciidoctor/standoc/validate.rb +30 -28
  38. data/lib/metanorma-standoc.rb +0 -1
  39. data/lib/metanorma/standoc/version.rb +5 -5
  40. data/metanorma-standoc.gemspec +11 -11
  41. data/spec/asciidoctor/base_spec.rb +715 -509
  42. data/spec/asciidoctor/blocks_spec.rb +830 -727
  43. data/spec/asciidoctor/cleanup_sections_spec.rb +51 -14
  44. data/spec/asciidoctor/cleanup_spec.rb +1836 -1673
  45. data/spec/asciidoctor/inline_spec.rb +330 -283
  46. data/spec/asciidoctor/isobib_cache_spec.rb +406 -358
  47. data/spec/asciidoctor/lists_spec.rb +3 -3
  48. data/spec/asciidoctor/macros_plantuml_spec.rb +8 -8
  49. data/spec/asciidoctor/macros_spec.rb +546 -444
  50. data/spec/asciidoctor/macros_yaml2text_spec.rb +1 -1
  51. data/spec/asciidoctor/refs_dl_spec.rb +4 -4
  52. data/spec/asciidoctor/refs_spec.rb +1528 -1533
  53. data/spec/asciidoctor/section_spec.rb +778 -689
  54. data/spec/asciidoctor/table_spec.rb +6 -6
  55. data/spec/asciidoctor/validate_spec.rb +296 -304
  56. data/spec/spec_helper.rb +13 -9
  57. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +66 -66
  58. data/spec/vcr_cassettes/isobib_get_123.yml +17 -17
  59. data/spec/vcr_cassettes/isobib_get_123_1.yml +31 -31
  60. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +40 -40
  61. data/spec/vcr_cassettes/isobib_get_123_2001.yml +17 -17
  62. data/spec/vcr_cassettes/isobib_get_124.yml +16 -16
  63. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +14 -14
  64. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +78 -66
  65. metadata +69 -67
  66. data/lib/liquid/custom_blocks/key_iterator.rb +0 -21
  67. data/lib/liquid/custom_blocks/with_json_nested_context.rb +0 -18
  68. data/lib/liquid/custom_blocks/with_yaml_nested_context.rb +0 -19
  69. 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
- noko do |xml|
14
- node.items.each { |item| reference1(node, item.text, xml) }
15
- end.join
16
- end
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
- xml.references **attr_code(attrs.merge(
47
- normative: node.attr("normative") || true)) do |xml_section|
48
- xml_section.title { |t| t << node.title }
49
- xml_section << node.content
50
- end
51
- @norm_ref = false
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(x, code, opts)
95
- x.respond_to? :to_xml or return nil
96
- xstr = x.to_xml(lang: opts[:lang])
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 (@no_isobib_cache || @no_isobib)
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 || node.title.gsub(/<[^>]+>/, "").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('//termxref').each do |node|
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('AsciiDoc Input', node,
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 = 'xref'
53
- node['target'] = termlookup[target]
62
+ node.name = "xref"
63
+ node["target"] = termlookup[target]
54
64
  node.children.remove
55
- node.remove_attribute('defaultref')
65
+ node.remove_attribute("defaultref")
56
66
  end
57
67
 
58
68
  def replace_automatic_generated_ids_terms
59
- xmldoc.xpath('//term').each.with_object({}) do |term_node, res|
60
- normalize_id_and_memorize(term_node, res, './preferred')
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
- unless AUTOMATIC_GENERATED_ID_REGEXP.match(term_node['id']).nil?
67
- term_node['id'] = unique_text_id(term_text)
68
- end
69
- res_table[term_text] = term_node['id']
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
- return "term-#{text}" if xmldoc.at("//*[@id = 'term-#{text}']").nil?
89
+ unless @idhash["term-#{text}"]
90
+ return "term-#{text}"
91
+ end
92
+
78
93
  (1..Float::INFINITY).lazy.each do |index|
79
- if xmldoc.at("//*[@id = 'term-#{text}-#{index}']").nil?
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, a)
15
+ def symbols_attrs(node, attr)
16
16
  case sectiontype1(node)
17
- when "symbols" then a.merge(type: "symbols")
18
- when "abbreviated terms", "abbreviations" then a.merge(type: "abbreviated_terms")
17
+ when "symbols" then attr.merge(type: "symbols")
18
+ when "abbreviated terms", "abbreviations"
19
+ attr.merge(type: "abbreviated_terms")
19
20
  else
20
- a
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" and return nonterm_term_def_subclause_parse(attrs, xml, node)
55
- node.role == "boilerplate" and return terms_boilerplate_parse(attrs, xml, node)
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 (return symbols_parse(attrs, xml, node))
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, toplevel)
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
- { bibitemid: seen_xref.children[0]["target"],
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, m)
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
- xml_t.origin seen_xref.children[0].content, **attr_code(term_source_attrs(seen_xref))
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
- m[:text] && xml_t.modification do |mod|
94
- mod.p { |p| p << m[:text].sub(/^\s+/, "") }
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, "term reference not in expected format: #{text}")
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
- <!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>
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("&#150;", "\u0096").
38
- gsub("&#151;", "\u0097").gsub("&#x96;", "\u0096").
39
- gsub("&#x97;", "\u0097")
37
+ l.gsub(/>\n$/, ">").gsub(/\s*\n$/m, " ").gsub("&#150;", "\u0096")
38
+ .gsub("&#151;", "\u0097").gsub("&#x96;", "\u0096")
39
+ .gsub("&#x97;", "\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(_x)
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.rb"
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 /^\[\d+\]$/.match(docid.text)
48
- @log.add("Bibliography", b, "Numeric reference in normative references")
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
- if found
52
- clean_exit
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, x)
58
- if ids[x["id"]]
59
- @log.add("Anchors", x, "Anchor #{x['id']} has already been used "\
60
- "at line #{ids[x['id']]}")
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[x["id"]] = x.line
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
- clean_exit
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"], :encoding => 'UTF-8') do |f|
80
+ Tempfile.open(["tmp", ".xml"], encoding: "UTF-8") do |f|
82
81
  begin
83
- f.write(doc.to_xml)
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
- clean_exit
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").each do |n|
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) }