metanorma-standoc 1.3.28 → 1.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/macos.yml +8 -7
  3. data/.github/workflows/ubuntu.yml +14 -11
  4. data/.github/workflows/windows.yml +8 -8
  5. data/.gitignore +1 -0
  6. data/lib/asciidoctor/standoc/base.rb +29 -48
  7. data/lib/asciidoctor/standoc/biblio.rng +36 -6
  8. data/lib/asciidoctor/standoc/blocks.rb +32 -96
  9. data/lib/asciidoctor/standoc/blocks_notes.rb +89 -0
  10. data/lib/asciidoctor/standoc/cleanup.rb +12 -6
  11. data/lib/asciidoctor/standoc/cleanup_block.rb +5 -2
  12. data/lib/asciidoctor/standoc/cleanup_inline.rb +1 -1
  13. data/lib/asciidoctor/standoc/cleanup_ref.rb +47 -1
  14. data/lib/asciidoctor/standoc/cleanup_section.rb +8 -125
  15. data/lib/asciidoctor/standoc/cleanup_terms.rb +134 -0
  16. data/lib/asciidoctor/standoc/converter.rb +16 -0
  17. data/lib/asciidoctor/standoc/datamodel/attributes_table_preprocessor.rb +57 -0
  18. data/lib/asciidoctor/standoc/datamodel/diagram_preprocessor.rb +102 -0
  19. data/lib/asciidoctor/standoc/datamodel/plantuml_renderer.rb +408 -0
  20. data/lib/asciidoctor/standoc/inline.rb +11 -6
  21. data/lib/asciidoctor/standoc/isodoc.rng +444 -1
  22. data/lib/asciidoctor/standoc/lists.rb +12 -12
  23. data/lib/asciidoctor/standoc/macros.rb +13 -8
  24. data/lib/asciidoctor/standoc/macros_yaml2text.rb +44 -21
  25. data/lib/asciidoctor/standoc/ref.rb +78 -79
  26. data/lib/asciidoctor/standoc/ref_sect.rb +124 -0
  27. data/lib/asciidoctor/standoc/reqt.rb +11 -6
  28. data/lib/asciidoctor/standoc/reqt.rng +23 -0
  29. data/lib/asciidoctor/standoc/section.rb +2 -46
  30. data/lib/asciidoctor/standoc/table.rb +3 -2
  31. data/lib/asciidoctor/standoc/validate.rb +8 -2
  32. data/lib/asciidoctor/standoc/validate_section.rb +0 -2
  33. data/lib/asciidoctor/standoc/views/datamodel/model_representation.adoc.erb +30 -0
  34. data/lib/asciidoctor/standoc/views/datamodel/plantuml_representation.adoc.erb +20 -0
  35. data/lib/metanorma/standoc/processor.rb +5 -7
  36. data/lib/metanorma/standoc/version.rb +1 -1
  37. data/metanorma-standoc.gemspec +2 -2
  38. data/spec/asciidoctor-standoc/blocks_spec.rb +68 -23
  39. data/spec/asciidoctor-standoc/cleanup_spec.rb +85 -5
  40. data/spec/asciidoctor-standoc/datamodel/attributes_table_preprocessor_spec.rb +111 -0
  41. data/spec/asciidoctor-standoc/datamodel/diagram_preprocessor_spec.rb +72 -0
  42. data/spec/asciidoctor-standoc/inline_spec.rb +7 -3
  43. data/spec/asciidoctor-standoc/isobib_cache_spec.rb +4 -4
  44. data/spec/asciidoctor-standoc/lists_spec.rb +7 -5
  45. data/spec/asciidoctor-standoc/macros_spec.rb +54 -2
  46. data/spec/asciidoctor-standoc/macros_yaml2text_spec.rb +2 -1
  47. data/spec/asciidoctor-standoc/refs_dl_spec.rb +4 -2
  48. data/spec/asciidoctor-standoc/refs_spec.rb +283 -24
  49. data/spec/asciidoctor-standoc/table_spec.rb +3 -3
  50. data/spec/asciidoctor-standoc/validate_spec.rb +77 -7
  51. data/spec/assets/iso123.rxl +107 -0
  52. data/spec/assets/xref_error.adoc +7 -0
  53. data/spec/examples/datamodel/address_class_profile.adoc +4 -0
  54. data/spec/examples/datamodel/address_component_profile.adoc +4 -0
  55. data/spec/examples/datamodel/blank_definition_profile.adoc +4 -0
  56. data/spec/examples/datamodel/common_models_diagram.adoc +4 -0
  57. data/spec/examples/datamodel/models/models/AddressClassProfile.yml +90 -0
  58. data/spec/examples/datamodel/models/models/AddressComponentProfile.yml +63 -0
  59. data/spec/examples/datamodel/models/models/AddressComponentSpecification.yml +15 -0
  60. data/spec/examples/datamodel/models/models/AddressProfile.yml +36 -0
  61. data/spec/examples/datamodel/models/models/AttributeProfile.yml +32 -0
  62. data/spec/examples/datamodel/models/models/InterchangeAddressClassProfile.yml +79 -0
  63. data/spec/examples/datamodel/models/models/Localization copy.yml +23 -0
  64. data/spec/examples/datamodel/models/models/Localization.yml +23 -0
  65. data/spec/examples/datamodel/models/models/ProfileCompliantAddress.yml +36 -0
  66. data/spec/examples/datamodel/models/models/ProfileCompliantAddressComponent.yml +15 -0
  67. data/spec/examples/datamodel/models/models/Signature.yml +20 -0
  68. data/spec/examples/datamodel/models/models/SignatureBlankDefinition.yml +20 -0
  69. data/spec/examples/datamodel/models/models/TextDirectionCode copy.yml +16 -0
  70. data/spec/examples/datamodel/models/models/TextDirectionCode.yml +16 -0
  71. data/spec/examples/datamodel/models/models/Validity.yml +14 -0
  72. data/spec/examples/datamodel/models/models/iso19160-1/Address.yml +22 -0
  73. data/spec/examples/datamodel/models/models/iso19160-1/AddressComponent.yml +2 -0
  74. data/spec/examples/datamodel/models/style.uml.inc +37 -0
  75. data/spec/examples/datamodel/models/views/CommonModels.yml +9 -0
  76. data/spec/examples/datamodel/models/views/TopDown.yml +62 -0
  77. data/spec/examples/datamodel/top_down_diagram.adoc +4 -0
  78. data/spec/fixtures/macros_datamodel/address_class_profile.xml +149 -0
  79. data/spec/fixtures/macros_datamodel/address_component_profile.xml +71 -0
  80. data/spec/fixtures/macros_datamodel/blank_definition_profile.xml +51 -0
  81. data/spec/fixtures/macros_datamodel/common_models_diagram.xml +7 -0
  82. data/spec/fixtures/macros_datamodel/top_down_diagram.xml +7 -0
  83. data/spec/metanorma/processor_spec.rb +4 -4
  84. data/spec/spec_helper.rb +13 -2
  85. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +85 -85
  86. data/spec/vcr_cassettes/isobib_get_123.yml +19 -198
  87. data/spec/vcr_cassettes/isobib_get_123_1.yml +361 -0
  88. data/spec/vcr_cassettes/isobib_get_123_2001.yml +22 -22
  89. data/spec/vcr_cassettes/isobib_get_124.yml +21 -21
  90. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +10 -10
  91. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +47 -44
  92. metadata +53 -11
@@ -13,7 +13,7 @@ module Asciidoctor
13
13
  end
14
14
 
15
15
  def ul_li(xml_ul, item)
16
- xml_ul.li **ul_li_attr(item) do |xml_li|
16
+ xml_ul.li **ul_li_attrs(item) do |xml_li|
17
17
  if item.blocks?
18
18
  xml_li.p(**id_attr(item)) { |t| t << item.text }
19
19
  xml_li << item.content
@@ -23,11 +23,11 @@ module Asciidoctor
23
23
  end
24
24
  end
25
25
 
26
- def ul_attr(node)
27
- attr_code(id_attr(node))
26
+ def ul_attrs(node)
27
+ attr_code(id_attr(node).merge(keep_attrs(node)))
28
28
  end
29
29
 
30
- def ul_li_attr(node)
30
+ def ul_li_attrs(node)
31
31
  attr_code(
32
32
  uncheckedcheckbox: node.attr?("checkbox") ? !node.attr?("checked") : nil,
33
33
  checkedcheckbox: node.attr?("checkbox") ? node.attr?("checked") : nil,
@@ -37,7 +37,7 @@ module Asciidoctor
37
37
  def ulist(node)
38
38
  return reference(node) if in_norm_ref? || in_biblio?
39
39
  noko do |xml|
40
- xml.ul **ul_attr(node) do |xml_ul|
40
+ xml.ul **ul_attrs(node) do |xml_ul|
41
41
  node.items.each do |item|
42
42
  ul_li(xml_ul, item)
43
43
  end
@@ -53,14 +53,14 @@ module Asciidoctor
53
53
  style
54
54
  end
55
55
 
56
- def ol_attr(node)
57
- attr_code(id: Utils::anchor_or_uuid(node),
58
- type: olist_style(node.style))
56
+ def ol_attrs(node)
57
+ attr_code(keep_attrs(node).merge(id: Utils::anchor_or_uuid(node),
58
+ type: olist_style(node.style)))
59
59
  end
60
60
 
61
61
  def olist(node)
62
62
  noko do |xml|
63
- xml.ol **ol_attr(node) do |xml_ol|
63
+ xml.ol **ol_attrs(node) do |xml_ol|
64
64
  node.items.each { |item| li(xml_ol, item) }
65
65
  end
66
66
  end.join("\n")
@@ -86,13 +86,13 @@ module Asciidoctor
86
86
  end
87
87
  end
88
88
 
89
- def dl_attr(node)
90
- attr_code(id_attr(node))
89
+ def dl_attrs(node)
90
+ attr_code(id_attr(node).merge(keep_attrs(node)))
91
91
  end
92
92
 
93
93
  def dlist(node)
94
94
  noko do |xml|
95
- xml.dl **dl_attr(node) do |xml_dl|
95
+ xml.dl **dl_attrs(node) do |xml_dl|
96
96
  node.items.each do |terms, dd|
97
97
  dt(terms, xml_dl)
98
98
  dd(dd, xml_dl)
@@ -1,8 +1,11 @@
1
1
  require "asciidoctor/extensions"
2
2
  require "fileutils"
3
3
  require "uuidtools"
4
- require_relative "./macros_plantuml.rb"
5
- require_relative "./macros_yaml2text.rb"
4
+ require 'yaml'
5
+ require_relative './macros_plantuml.rb'
6
+ require_relative './datamodel/attributes_table_preprocessor.rb'
7
+ require_relative './datamodel/diagram_preprocessor.rb'
8
+ require_relative './macros_yaml2text.rb'
6
9
 
7
10
  module Asciidoctor
8
11
  module Standoc
@@ -97,23 +100,25 @@ module Asciidoctor
97
100
  end
98
101
 
99
102
  def supply_br(lines)
103
+ ignore = false
100
104
  lines.each_with_index do |l, i|
105
+ /^(--+|====+|\|===|\.\.\.\.+|\*\*\*\*+|\+\+\+\++|\`\`\`\`+|____\+)$/.match(l) and
106
+ ignore = !ignore
101
107
  next if l.empty? || l.match(/ \+$/)
108
+ next if /^\[.*\]$/.match(l)
109
+ next if ignore
102
110
  next if i == lines.size - 1 || i < lines.size - 1 && lines[i+1].empty?
103
111
  lines[i] += " +"
104
112
  end
105
113
  lines
106
114
  end
107
115
 
108
- def prevent_smart_quotes(m)
109
- m.gsub(/'/, "&#x27;").gsub(/"/, "&#x22;")
110
- end
111
-
112
116
  def process parent, reader, attrs
113
117
  attrs['role'] = 'pseudocode'
114
- lines = reader.lines.map { |m| prevent_smart_quotes(init_indent(m)) }
115
- create_block(parent, :example, supply_br(lines),
118
+ lines = reader.lines.map { |m| init_indent(m) }
119
+ ret = create_block(parent, :example, supply_br(lines),
116
120
  attrs, content_model: :compound)
121
+ ret
117
122
  end
118
123
  end
119
124
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ostruct'
2
4
 
3
5
  module Asciidoctor
@@ -44,8 +46,8 @@ module Asciidoctor
44
46
  end
45
47
 
46
48
  class Yaml2TextPreprocessor < Asciidoctor::Extensions::Preprocessor
47
- BLOCK_START_REGEXP = /\{(.+?)\.\*,(.+),(.+)\}/.freeze
48
- BLOCK_END_REGEXP = /\A\{[A-Z]+\}\z/.freeze
49
+ BLOCK_START_REGEXP = /\{(.+?)\.\*,(.+),(.+)\}/
50
+ BLOCK_END_REGEXP = /\A\{[A-Z]+\}\z/
49
51
  # search document for block `yaml2text`
50
52
  # after that take template from block and read file into this template
51
53
  # example:
@@ -61,7 +63,7 @@ module Asciidoctor
61
63
  # - name: spaghetti
62
64
  # desc: wheat noodles of 9mm diameter
63
65
  # symbol: SPAG
64
- # symbol_def: the situation is message like spaghetti at a kid's meal
66
+ # symbol_def: the situation is message like spaghetti at a kid's
65
67
  #
66
68
  # will produce:
67
69
  # === spaghetti
@@ -77,19 +79,20 @@ module Asciidoctor
77
79
 
78
80
  def processed_lines(document, input_lines)
79
81
  result = []
82
+ current_macro_line_num = 0
80
83
  loop do
81
84
  line = input_lines.next
85
+ current_macro_line_num += 1
82
86
  if yaml_block_match = line.match(/^\[yaml2text,(.+?),(.+?)\]/)
83
87
  mark = input_lines.next
84
88
  current_yaml_block = []
85
89
  while (yaml_block_line = input_lines.next) != mark
86
90
  current_yaml_block.push(yaml_block_line)
87
91
  end
88
- content = nested_open_struct_from_yaml(yaml_block_match[1], document)
89
- result.push(*
90
- parse_blocks_recursively(lines: current_yaml_block,
91
- attributes: content,
92
- context_name: yaml_block_match[2]))
92
+ result.push(*read_yaml_and_parse_template(current_yaml_block,
93
+ document,
94
+ yaml_block_match,
95
+ current_macro_line_num))
93
96
  else
94
97
  result.push(line)
95
98
  end
@@ -97,9 +100,23 @@ module Asciidoctor
97
100
  result
98
101
  end
99
102
 
103
+ def read_yaml_and_parse_template(current_yaml_block, document, yaml_block_match, current_macro_line_num)
104
+ content = nested_open_struct_from_yaml(yaml_block_match[1], document)
105
+ parse_blocks_recursively(lines: current_yaml_block,
106
+ attributes: content,
107
+ context_name: yaml_block_match[2])
108
+ rescue StandardError => exception
109
+ document
110
+ .logger
111
+ .warn("Failed to parse yaml2text block on line #{current_macro_line_num}: #{exception.message}")
112
+ []
113
+ end
114
+
100
115
  def nested_open_struct_from_yaml(file_path, document)
101
116
  docfile_directory = File.dirname(document.attributes['docfile'] || '.')
102
- yaml_file_path = document.path_resolver.system_path(file_path, docfile_directory)
117
+ yaml_file_path = document
118
+ .path_resolver
119
+ .system_path(file_path, docfile_directory)
103
120
  content = YAML.safe_load(File.read(yaml_file_path))
104
121
  # Load content as json, then parse with JSON as nested open_struct
105
122
  JSON.parse(content.to_json, object_class: YamlBlockStruct)
@@ -107,35 +124,41 @@ module Asciidoctor
107
124
 
108
125
  def parse_blocks_recursively(lines:,
109
126
  attributes:,
110
- context_name:,
111
- parent_context: nil)
127
+ context_name:)
112
128
  lines = lines.to_enum
113
129
  result = []
114
130
  loop do
115
131
  line = lines.next
116
- if line.match(BLOCK_START_REGEXP)
117
- line.gsub!(BLOCK_START_REGEXP, '<% \1.each.with_index do |\2,index| %>')
132
+ if line.match?(BLOCK_START_REGEXP)
133
+ line.gsub!(BLOCK_START_REGEXP,
134
+ '<% \1.each&.with_index do |\2,index| %>')
118
135
  end
119
136
 
120
- if line.match(BLOCK_END_REGEXP)
137
+ if line.strip.match?(BLOCK_END_REGEXP)
121
138
  line.gsub!(BLOCK_END_REGEXP, '<% end %>')
122
139
  end
123
- line = line.gsub(/{(.+?[^}]*)}/, '<%= \1 %>').gsub(/[a-z\.]+\#/, 'index')
140
+ line.gsub!(/{\s*if\s*([^}]+)}/, '<% if \1 %>')
141
+ line.gsub!(/{\s*?end\s*?}/, '<% end %>')
142
+ line = line
143
+ .gsub(/{(.+?[^}]*)}/, '<%= \1 %>')
144
+ .gsub(/[a-z\.]+\#/, 'index')
124
145
  result.push(line)
125
146
  end
126
147
  result = parse_context_block(context_lines: result,
127
148
  context_items: attributes,
128
- context_name: context_name,
129
- parent_context: parent_context)
149
+ context_name: context_name)
130
150
  result
131
151
  end
132
152
 
133
153
  def parse_context_block(context_lines:,
134
154
  context_items:,
135
- context_name:,
136
- parent_context: nil)
137
- renderer = YamlContextRenderer.new(context_object: context_items, context_name: context_name)
138
- renderer.render(context_lines.join('\n')).split('\n')
155
+ context_name:)
156
+ renderer = YamlContextRenderer
157
+ .new(
158
+ context_object: context_items,
159
+ context_name: context_name
160
+ )
161
+ renderer.render(context_lines.join("\n")).split("\n")
139
162
  end
140
163
  end
141
164
  end
@@ -37,8 +37,7 @@ module Asciidoctor
37
37
  end
38
38
 
39
39
  def id_and_year(id, year)
40
- return id unless year
41
- "#{id}:#{year}"
40
+ year ? "#{id}:#{year}" : id
42
41
  end
43
42
 
44
43
  def docid(t, code)
@@ -46,12 +45,26 @@ module Asciidoctor
46
45
  ["metanorma", mn_code(code)] :
47
46
  @bibdb&.docid_type(code) || [nil, code]
48
47
  code1.sub!(/^nofetch\((.+)\)$/, "\\1")
49
- t.docidentifier code1, **attr_code(type: type)
48
+ t.docidentifier **attr_code(type: type) do |d|
49
+ d << code1
50
+ end
51
+ end
52
+
53
+ def docnumber(t, code)
54
+ t.docnumber do |d|
55
+ d << HTMLEntities.new.decode(code).sub(/^[^\d]*/, "")
56
+ end
50
57
  end
51
58
 
52
59
  def norm_year(yr)
53
- return "--" if /^\&\#821[12];$/.match yr
54
- yr
60
+ /^\&\#821[12];$/.match(yr) ? "--" : yr
61
+ end
62
+
63
+ def isorefrender1(t, m, yr, allp = "")
64
+ t.title(**plaintxt) { |i| i << ref_normalise(m[:text]) }
65
+ docid(t, m[:usrlbl]) if m[:usrlbl]
66
+ docid(t, id_and_year(m[:code], yr) + allp)
67
+ docnumber(t, m[:code])
55
68
  end
56
69
 
57
70
  def isorefmatches(xml, m)
@@ -59,10 +72,7 @@ module Asciidoctor
59
72
  ref = fetch_ref xml, m[:code], yr, title: m[:text], usrlbl: m[:usrlbl]
60
73
  return use_my_anchor(ref, m[:anchor]) if ref
61
74
  xml.bibitem **attr_code(ref_attributes(m)) do |t|
62
- t.title(**plaintxt) { |i| i << ref_normalise(m[:text]) }
63
- docid(t, m[:usrlbl]) if m[:usrlbl]
64
- docid(t, id_and_year(m[:code], yr))
65
- t.docnumber m[:code].sub(/^[^\d]*/, "")
75
+ isorefrender1(t, m, yr)
66
76
  yr and t.date **{ type: "published" } do |d|
67
77
  set_date_range(d, yr)
68
78
  end
@@ -74,27 +84,23 @@ module Asciidoctor
74
84
  ref = fetch_ref xml, m[:code], nil, no_year: true, note: m[:fn],
75
85
  title: m[:text], usrlbl: m[:usrlbl]
76
86
  return use_my_anchor(ref, m[:anchor]) if ref
77
-
78
87
  xml.bibitem **attr_code(ref_attributes(m)) do |t|
79
- t.title(**plaintxt) { |i| i << ref_normalise(m[:text]) }
80
- docid(t, m[:usrlbl]) if m[:usrlbl]
81
- docid(t, id_and_year(m[:code], "--"))
82
- t.docnumber m[:code].sub(/^[^\d]*/, "")
88
+ isorefrender1(t, m, "--")
83
89
  t.date **{ type: "published" } do |d|
84
90
  d.on "--"
85
91
  end
86
92
  iso_publisher(t, m[:code])
87
- m[:fn].nil? or t.note(**plaintxt) { |p| p << "ISO DATE: #{m[:fn]}" }
93
+ m[:fn].nil? or t.note(**plaintxt.merge(type: "ISO DATE")) do |p|
94
+ p << "#{m[:fn]}"
95
+ end
88
96
  end
89
97
  end
90
98
 
91
99
  def conditional_date(t, m, noyr)
92
100
  m.names.include?("year") and !m[:year].nil? and
93
101
  t.date(**{ type: "published" }) do |d|
94
- if noyr then d.on "--"
95
- else
102
+ noyr and d.on "--" or
96
103
  set_date_range(d, norm_year(m[:year]))
97
- end
98
104
  end
99
105
  end
100
106
 
@@ -107,42 +113,35 @@ module Asciidoctor
107
113
  return use_my_anchor(ref, m[:anchor]) if ref
108
114
 
109
115
  xml.bibitem(**attr_code(ref_attributes(m))) do |t|
110
- t.title(**plaintxt) { |i| i << ref_normalise(m[:text]) }
111
- docid(t, m[:usrlbl]) if m[:usrlbl]
112
- docid(t, id_and_year(m[:code], yr) + " (all parts)")
113
- t.docnumber m[:code].sub(/^[^\d]*/, "")
116
+ isorefrender1(t, m, yr, " (all parts)")
114
117
  conditional_date(t, m, noyr)
115
118
  iso_publisher(t, m[:code])
116
119
  m.names.include?("fn") && m[:fn] and
117
- t.note(**plaintxt) { |p| p << "ISO DATE: #{m[:fn]}" }
120
+ t.note(**plaintxt.merge(type: "ISO DATE")) { |p| p << "#{m[:fn]}" }
118
121
  t.extent **{ type: 'part' } do |e|
119
122
  e.referenceFrom "all"
120
123
  end
121
124
  end
122
125
  end
123
126
 
124
- def fetch_ref(xml, code, year, **opts)
125
- return nil if opts[:no_year]
126
- code = code.sub(/^\([^)]+\)/, "")
127
- hit = @bibdb&.fetch(code, year, opts)
128
- return nil if hit.nil?
129
- xml.parent.add_child(smart_render_xml(hit, code, opts[:title],
130
- opts[:usrlbl]))
131
- xml
132
- rescue RelatonBib::RequestError
133
- @log.add("Bibliography", nil, "Could not retrieve #{code}: "\
134
- "no access to online site")
135
- nil
127
+ def refitem_render1(m, code, t)
128
+ if code[:type] == "path"
129
+ t.uri code[:key].sub(/\.[a-zA-Z0-9]+$/, ""), **{ type: "URI" }
130
+ t.uri code[:key].sub(/\.[a-zA-Z0-9]+$/, ""), **{ type: "citation" }
131
+ end
132
+ docid(t, m[:usrlbl]) if m[:usrlbl]
133
+ docid(t, /^\d+$/.match(code[:id]) ? "[#{code[:id]}]" : code[:id])
134
+ code[:type] == "repo" and
135
+ t.docidentifier code[:key], **{ type: "repository" }
136
136
  end
137
137
 
138
- def refitem_render(xml, m)
138
+ def refitem_render(xml, m, code)
139
139
  xml.bibitem **attr_code(id: m[:anchor]) do |t|
140
140
  t.formattedref **{ format: "application/x-isodoc+xml" } do |i|
141
141
  i << ref_normalise_no_format(m[:text])
142
142
  end
143
- docid(t, m[:usrlbl]) if m[:usrlbl]
144
- docid(t, /^\d+$/.match(m[:code]) ? "[#{m[:code]}]" : m[:code])
145
- t.docnumber m[:code].sub(/^[^\d]*/, "") unless /^\d+$|^\(.+\)$/.match(m[:code])
143
+ refitem_render1(m, code, t)
144
+ docnumber(t, code[:id]) unless /^\d+$|^\(.+\)$/.match(code[:id])
146
145
  end
147
146
  end
148
147
 
@@ -150,19 +149,56 @@ module Asciidoctor
150
149
  "https://www.metanorma.com/author/topics/document-format/bibliography/ , "\
151
150
  "https://www.metanorma.com/author/iso/topics/markup/#bibliographies".freeze
152
151
 
152
+ def analyse_ref_nofetch(ret)
153
+ if m = /^nofetch\((?<id>.+)\)$/.match(ret[:id])
154
+ ret[:id] = m[:id]
155
+ ret[:nofetch] = true
156
+ end
157
+ ret
158
+ end
159
+
160
+ def analyse_ref_repo_path(ret)
161
+ if m = /^(?<type>repo|path):\((?<key>[^,]+),(?<id>.+)\)$/.match(ret[:id])
162
+ ret[:id] = m[:id]
163
+ ret[:type] = m[:type]
164
+ ret[:key] = m[:key]
165
+ ret[:nofetch] = true
166
+ end
167
+ ret
168
+ end
169
+
170
+ def analyse_ref_numeric(ret)
171
+ if /^\d+$/.match(ret[:id])
172
+ ret[:numeric] = true
173
+ end
174
+ ret
175
+ end
176
+
177
+ # ref id = (usrlbl)code[:-]year
178
+ # code = nofetch(code) | (repo|path):(key,code) | \[? number \]? | identifier
179
+ def analyse_ref_code(code)
180
+ ret = {id: code}
181
+ return ret if code.nil? || code.empty?
182
+ ret = analyse_ref_nofetch(ret)
183
+ ret = analyse_ref_repo_path(ret)
184
+ ret = analyse_ref_numeric(ret)
185
+ ret
186
+ end
187
+
153
188
  # TODO: alternative where only title is available
154
189
  def refitem(xml, item, node)
155
190
  unless m = NON_ISO_REF.match(item)
156
191
  @log.add("AsciiDoc Input", node, "#{MALFORMED_REF}: #{item}")
157
192
  return
158
193
  end
159
- unless m[:code] && /^\d+$/.match(m[:code])
160
- ref = fetch_ref xml, m[:code],
194
+ code = analyse_ref_code(m[:code])
195
+ unless code[:id] && code[:numeric] || code[:nofetch]
196
+ ref = fetch_ref xml, code[:id],
161
197
  m.names.include?("year") ? m[:year] : nil, title: m[:text],
162
198
  usrlbl: m[:usrlbl]
163
199
  return use_my_anchor(ref, m[:anchor]) if ref
164
200
  end
165
- refitem_render(xml, m)
201
+ refitem_render(xml, m, code)
166
202
  end
167
203
 
168
204
  def ref_normalise(ref)
@@ -214,46 +250,9 @@ module Asciidoctor
214
250
  end.join
215
251
  end
216
252
 
217
- def global_ievcache_name
218
- "#{Dir.home}/.iev/cache"
219
- end
220
-
221
- def local_ievcache_name(cachename)
222
- return nil if cachename.nil?
223
- cachename += "_iev" unless cachename.empty?
224
- cachename = "iev" if cachename.empty?
225
- "#{cachename}/cache"
226
- end
227
-
228
253
  def mn_code(code)
229
254
  code.sub(/^\(/, "[").sub(/\).*$/, "]").sub(/^nofetch\((.+)\)$/, "\\1")
230
255
  end
231
-
232
- def emend_biblio(xml, code, title, usrlbl)
233
- unless xml.at("/bibitem/docidentifier[not(@type = 'DOI')][text()]")
234
- @log.add("Bibliography", nil,
235
- "ERROR: No document identifier retrieved for #{code}")
236
- xml.root << "<docidentifier>#{code}</docidentifier>"
237
- end
238
- unless xml.at("/bibitem/title[text()]")
239
- @log.add("Bibliography", nil,
240
- "ERROR: No title retrieved for #{code}")
241
- xml.root << "<title>#{title || "(MISSING TITLE)"}</title>"
242
- end
243
- usrlbl and xml.at("/bibitem/docidentifier").next =
244
- "<docidentifier type='metanorma'>#{mn_code(usrlbl)}</docidentifier>"
245
- end
246
-
247
- def smart_render_xml(x, code, title, usrlbl)
248
- xstr = x.to_xml if x.respond_to? :to_xml
249
- xml = Nokogiri::XML(xstr)
250
- emend_biblio(xml, code, title, usrlbl)
251
- xml.xpath("//date").each { |d| Utils::endash_date(d) }
252
- xml.traverse do |n|
253
- n.text? and n.replace(Utils::smartformat(n.text))
254
- end
255
- xml.to_xml.sub(/<\?[^>]+>/, "")
256
- end
257
256
  end
258
257
  end
259
258
  end