metanorma-standoc 1.10.7 → 1.11.1

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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +19 -23
  3. data/Rakefile +1 -1
  4. data/lib/asciidoctor/standoc/base.rb +7 -4
  5. data/lib/asciidoctor/standoc/basicdoc.rng +21 -4
  6. data/lib/asciidoctor/standoc/blocks.rb +23 -23
  7. data/lib/asciidoctor/standoc/blocks_notes.rb +17 -22
  8. data/lib/asciidoctor/standoc/cleanup.rb +20 -11
  9. data/lib/asciidoctor/standoc/cleanup_image.rb +6 -7
  10. data/lib/asciidoctor/standoc/cleanup_inline.rb +45 -7
  11. data/lib/asciidoctor/standoc/cleanup_maths.rb +5 -6
  12. data/lib/asciidoctor/standoc/cleanup_ref.rb +5 -0
  13. data/lib/asciidoctor/standoc/cleanup_reqt.rb +2 -21
  14. data/lib/asciidoctor/standoc/cleanup_symbols.rb +48 -0
  15. data/lib/asciidoctor/standoc/cleanup_terms.rb +48 -77
  16. data/lib/asciidoctor/standoc/cleanup_terms_designations.rb +162 -0
  17. data/lib/asciidoctor/standoc/cleanup_text.rb +23 -0
  18. data/lib/asciidoctor/standoc/converter.rb +2 -0
  19. data/lib/asciidoctor/standoc/inline.rb +7 -5
  20. data/lib/asciidoctor/standoc/isodoc.rng +420 -76
  21. data/lib/asciidoctor/standoc/lists.rb +14 -16
  22. data/lib/asciidoctor/standoc/macros_plantuml.rb +29 -14
  23. data/lib/asciidoctor/standoc/macros_terms.rb +55 -8
  24. data/lib/asciidoctor/standoc/ref.rb +1 -1
  25. data/lib/asciidoctor/standoc/ref_sect.rb +26 -18
  26. data/lib/asciidoctor/standoc/reqt.rng +23 -2
  27. data/lib/asciidoctor/standoc/section.rb +13 -12
  28. data/lib/asciidoctor/standoc/term_lookup_cleanup.rb +50 -11
  29. data/lib/asciidoctor/standoc/terms.rb +12 -2
  30. data/lib/asciidoctor/standoc/utils.rb +36 -23
  31. data/lib/asciidoctor/standoc/validate.rb +45 -27
  32. data/lib/asciidoctor/standoc/validate_section.rb +5 -2
  33. data/lib/metanorma/standoc/version.rb +1 -1
  34. data/metanorma-standoc.gemspec +1 -1
  35. data/spec/asciidoctor/base_spec.rb +4 -3
  36. data/spec/asciidoctor/blocks_spec.rb +230 -49
  37. data/spec/asciidoctor/cleanup_sections_spec.rb +7 -7
  38. data/spec/asciidoctor/cleanup_spec.rb +105 -286
  39. data/spec/asciidoctor/cleanup_terms_spec.rb +1020 -0
  40. data/spec/asciidoctor/inline_spec.rb +2 -2
  41. data/spec/asciidoctor/lists_spec.rb +6 -6
  42. data/spec/asciidoctor/macros_plantuml_spec.rb +36 -1
  43. data/spec/asciidoctor/macros_spec.rb +190 -113
  44. data/spec/asciidoctor/refs_dl_spec.rb +4 -4
  45. data/spec/asciidoctor/refs_spec.rb +268 -108
  46. data/spec/asciidoctor/section_spec.rb +18 -18
  47. data/spec/asciidoctor/validate_spec.rb +87 -2
  48. data/spec/spec_helper.rb +8 -8
  49. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +50 -50
  50. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +12 -12
  51. data/spec/vcr_cassettes/isobib_get_123.yml +13 -13
  52. data/spec/vcr_cassettes/isobib_get_123_1.yml +25 -25
  53. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +31 -31
  54. data/spec/vcr_cassettes/isobib_get_123_2001.yml +12 -12
  55. data/spec/vcr_cassettes/isobib_get_124.yml +11 -11
  56. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +14 -14
  57. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +45 -45
  58. metadata +8 -5
@@ -40,10 +40,9 @@ module Asciidoctor
40
40
  end
41
41
 
42
42
  def attr_code(attributes)
43
- attributes = attributes.reject { |_, val| val.nil? }.map
44
- attributes.map do |k, v|
45
- [k, (v.is_a? String) ? HTMLEntities.new.decode(v) : v]
46
- end.to_h
43
+ attributes.compact.transform_values do |v|
44
+ v.is_a?(String) ? HTMLEntities.new.decode(v) : v
45
+ end
47
46
  end
48
47
 
49
48
  # if the contents of node are blocks, output them to out;
@@ -56,7 +55,7 @@ module Asciidoctor
56
55
  end
57
56
 
58
57
  SUBCLAUSE_XPATH = "//clause[not(parent::sections)]"\
59
- "[not(ancestor::boilerplate)]".freeze
58
+ "[not(ancestor::boilerplate)]".freeze
60
59
 
61
60
  def isodoc(lang, script, i18nyaml = nil)
62
61
  conv = html_converter(EmptyAttr.new)
@@ -67,29 +66,43 @@ module Asciidoctor
67
66
 
68
67
  def default_script(lang)
69
68
  case lang
70
- when "ar", "fa"
71
- "Arab"
72
- when "ur"
73
- "Aran"
74
- when "ru", "bg"
75
- "Cyrl"
76
- when "hi"
77
- "Deva"
78
- when "el"
79
- "Grek"
80
- when "zh"
81
- "Hans"
82
- when "ko"
83
- "Kore"
84
- when "he"
85
- "Hebr"
86
- when "ja"
87
- "Jpan"
69
+ when "ar", "fa" then "Arab"
70
+ when "ur" then "Aran"
71
+ when "ru", "bg" then "Cyrl"
72
+ when "hi" then "Deva"
73
+ when "el" then "Grek"
74
+ when "zh" then "Hans"
75
+ when "ko" then "Kore"
76
+ when "he" then "Hebr"
77
+ when "ja" then "Jpan"
88
78
  else
89
79
  "Latn"
90
80
  end
91
81
  end
92
82
 
83
+ def dl_to_attrs(elem, dlist, name)
84
+ e = dlist.at("./dt[text()='#{name}']") or return
85
+ val = e.at("./following::dd/p") || e.at("./following::dd") or return
86
+ elem[name] = val.text
87
+ end
88
+
89
+ def dl_to_elems(ins, elem, dlist, name)
90
+ a = elem.at("./#{name}[last()]")
91
+ ins = a if a
92
+ dlist.xpath("./dt[text()='#{name}']").each do |e|
93
+ v = e.at("./following::dd")
94
+ e = v.elements and e.size == 1 && e.first.name == "p" and v = e.first
95
+ v.name = name
96
+ ins.next = v
97
+ ins = ins.next
98
+ end
99
+ ins
100
+ end
101
+
102
+ def term_expr(elem)
103
+ "<expression><name>#{elem}</name></expression>"
104
+ end
105
+
93
106
  class EmptyAttr
94
107
  def attr(_any_attribute)
95
108
  nil
@@ -7,8 +7,8 @@ require "iev"
7
7
  module Asciidoctor
8
8
  module Standoc
9
9
  module Validate
10
- SOURCELOCALITY = "./termsource/origin//locality[@type = 'clause']/"\
11
- "referenceFrom".freeze
10
+ SOURCELOCALITY = "./origin//locality[@type = 'clause']/"\
11
+ "referenceFrom".freeze
12
12
 
13
13
  def init_iev
14
14
  return nil if @no_isobib
@@ -21,24 +21,35 @@ module Asciidoctor
21
21
  def iev_validate(xmldoc)
22
22
  @iev = init_iev or return
23
23
  xmldoc.xpath("//term").each do |t|
24
- /^IEC 60050-/.match(t&.at("./termsource/origin/@citeas")&.text) &&
25
- loc = t.xpath(SOURCELOCALITY)&.text or next
26
- iev = @iev.fetch(loc, xmldoc&.at("//language")&.text || "en") or next
27
- pref = t.xpath("./preferred").inject([]) do |m, x|
28
- m << x&.text&.downcase
24
+ t.xpath(".//termsource").each do |src|
25
+ (/^IEC 60050-/.match(src&.at("./origin/@citeas")&.text) &&
26
+ loc = src.xpath(SOURCELOCALITY)&.text) or next
27
+ iev_validate1(t, loc, xmldoc)
29
28
  end
30
- pref.include?(iev.downcase) or
31
- @log.add("Bibliography", t, %(Term "#{pref[0]}" does not match ) +
32
- %(IEV #{loc} "#{iev}"))
33
29
  end
34
30
  end
35
31
 
32
+ def iev_validate1(term, loc, xmldoc)
33
+ iev = @iev.fetch(loc,
34
+ xmldoc&.at("//language")&.text || "en") or return
35
+ pref = term.xpath("./preferred//name").inject([]) do |m, x|
36
+ m << x&.text&.downcase
37
+ end
38
+ pref.include?(iev.downcase) or
39
+ @log.add("Bibliography", term, %(Term "#{pref[0]}" does not match ) +
40
+ %(IEV #{loc} "#{iev}"))
41
+ end
42
+
36
43
  def content_validate(doc)
44
+ @fatalerror = []
45
+ xref_validate(doc)
37
46
  section_validate(doc)
38
47
  norm_ref_validate(doc)
39
48
  repeat_id_validate(doc.root)
40
49
  iev_validate(doc.root)
41
- concept_validate(doc)
50
+ concept_validate(doc, "concept", "refterm")
51
+ concept_validate(doc, "related", "preferred//name")
52
+ @fatalerror.empty? or clean_abort(@fatalerror.join("\n"), doc.to_xml)
42
53
  end
43
54
 
44
55
  def norm_ref_validate(doc)
@@ -51,30 +62,30 @@ module Asciidoctor
51
62
  "Numeric reference in normative references")
52
63
  found = true
53
64
  end
54
- found and
55
- clean_abort("Numeric reference in normative references", doc.to_xml)
65
+ found and @fatalerror << "Numeric reference in normative references"
56
66
  end
57
67
 
58
- def concept_validate(doc)
68
+ def concept_validate(doc, tag, refterm)
59
69
  found = false
60
- doc.xpath("//concept/xref").each do |x|
70
+ doc.xpath("//#{tag}/xref").each do |x|
61
71
  next if doc.at("//term[@id = '#{x['target']}']")
62
72
  next if doc.at("//definitions//dt[@id = '#{x['target']}']")
63
73
 
64
- ref = x&.at("../refterm")&.text
65
- @log.add("Anchors", x, "Concept #{ref} is pointing to "\
74
+ ref = x&.at("../#{refterm}")&.text
75
+ @log.add("Anchors", x,
76
+ "#{tag.capitalize} #{ref} is pointing to "\
66
77
  "#{x['target']}, which is not a term or symbol")
67
78
  found = true
68
79
  end
69
- found and clean_abort("Concept not cross-referencing term or symbol",
70
- doc.to_xml)
80
+ found and
81
+ @fatalerror << "#{tag.capitalize} not cross-referencing term or symbol"
71
82
  end
72
83
 
73
84
  def repeat_id_validate1(ids, elem)
74
85
  if ids[elem["id"]]
75
86
  @log.add("Anchors", elem, "Anchor #{elem['id']} has already been "\
76
- "used at line #{ids[elem['id']]}")
77
- raise StandardError.new "Error: multiple instances of same ID"
87
+ "used at line #{ids[elem['id']]}")
88
+ @fatalerror << "Multiple instances of same ID: #{elem['id']}"
78
89
  else
79
90
  ids[elem["id"]] = elem.line
80
91
  end
@@ -83,12 +94,8 @@ module Asciidoctor
83
94
 
84
95
  def repeat_id_validate(doc)
85
96
  ids = {}
86
- begin
87
- doc.xpath("//*[@id]").each do |x|
88
- ids = repeat_id_validate1(ids, x)
89
- end
90
- rescue StandardError => e
91
- clean_abort(e.message, doc.to_xml)
97
+ doc.xpath("//*[@id]").each do |x|
98
+ ids = repeat_id_validate1(ids, x)
92
99
  end
93
100
  end
94
101
 
@@ -130,6 +137,17 @@ module Asciidoctor
130
137
  doc
131
138
  end
132
139
 
140
+ # manually check for xref/@target, xref/@to integrity
141
+ def xref_validate(doc)
142
+ ids = doc.xpath("//*/@id").each_with_object({}) { |x, m| m[x.text] = 1 }
143
+ doc.xpath("//xref/@target | //xref/@to").each do |x|
144
+ next if ids[x.text]
145
+
146
+ @log.add("Anchors", x.parent,
147
+ "Crossreference target #{x.text} is undefined")
148
+ end
149
+ end
150
+
133
151
  def validate(doc)
134
152
  content_validate(doc)
135
153
  schema_validate(formattedstr_strip(doc.dup),
@@ -14,7 +14,8 @@ module Asciidoctor
14
14
  callouts = x.elements.select { |e| e.name == "callout" }
15
15
  annotations = x.elements.select { |e| e.name == "annotation" }
16
16
  if callouts.size != annotations.size
17
- @log.add("AsciiDoc Input", x, "mismatch of callouts and annotations")
17
+ @log.add("AsciiDoc Input", x,
18
+ "mismatch of callouts and annotations")
18
19
  end
19
20
  end
20
21
  end
@@ -42,7 +43,9 @@ module Asciidoctor
42
43
  root.xpath("//clause | //annex | //foreword | //introduction | "\
43
44
  "//acknowledgements").each do |c|
44
45
  next unless c.at("./clause")
45
- next if c.elements.reject { |n| %w(clause title).include? n.name }.empty?
46
+ next if c.elements.reject do |n|
47
+ %w(clause title).include? n.name
48
+ end.empty?
46
49
 
47
50
  style_warning(c, "Hanging paragraph in clause")
48
51
  end
@@ -19,6 +19,6 @@ module Metanorma
19
19
  end
20
20
 
21
21
  module Standoc
22
- VERSION = "1.10.7".freeze
22
+ VERSION = "1.11.1".freeze
23
23
  end
24
24
  end
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
28
28
 
29
29
  spec.add_dependency "asciidoctor", "~> 2.0.0"
30
30
  spec.add_dependency "iev", "~> 0.2.1"
31
- spec.add_dependency "isodoc", "~> 1.7.0"
31
+ spec.add_dependency "isodoc", "~> 1.8.0"
32
32
  spec.add_dependency "metanorma-plugin-datastruct"
33
33
  spec.add_dependency "metanorma-plugin-lutaml"
34
34
  spec.add_dependency "ruby-jing"
@@ -959,14 +959,15 @@ QU1FOiB0ZXN0Cgo=
959
959
 
960
960
  it "process mn2pdf attributes" do
961
961
  node = Nokogiri::XML("<fake/>").at("fake")
962
- node["mn2pdf-font-manifest-file"] = "passed/as/font/manifest/to/mn2pdf.jar"
962
+ node[Asciidoctor::Standoc::Base::FONTS_MANIFEST] =
963
+ "passed/as/font/manifest/to/mn2pdf.jar"
963
964
 
964
965
  options = Asciidoctor::Standoc::Converter
965
966
  .new(:standoc, header_footer: true)
966
967
  .doc_extract_attributes(node)
967
968
 
968
- expect(options.dig(:mn2pdf, :font_manifest_file))
969
- .to eq(node["mn2pdf-font-manifest-file"])
969
+ expect(options.dig(:mn2pdf, :font_manifest))
970
+ .to eq(node[Asciidoctor::Standoc::Base::FONTS_MANIFEST])
970
971
  end
971
972
 
972
973
  private