metanorma-standoc 1.9.0 → 1.10.0

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 (72) 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 +4 -8
  5. data/lib/asciidoctor/standoc/base.rb +31 -35
  6. data/lib/asciidoctor/standoc/biblio.rng +1 -0
  7. data/lib/asciidoctor/standoc/blocks.rb +25 -9
  8. data/lib/asciidoctor/standoc/blocks_notes.rb +41 -24
  9. data/lib/asciidoctor/standoc/cleanup.rb +59 -84
  10. data/lib/asciidoctor/standoc/cleanup_block.rb +63 -85
  11. data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +28 -15
  12. data/lib/asciidoctor/standoc/cleanup_footnotes.rb +1 -0
  13. data/lib/asciidoctor/standoc/cleanup_image.rb +71 -0
  14. data/lib/asciidoctor/standoc/cleanup_inline.rb +117 -77
  15. data/lib/asciidoctor/standoc/cleanup_maths.rb +36 -27
  16. data/lib/asciidoctor/standoc/cleanup_ref.rb +31 -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 -135
  20. data/lib/asciidoctor/standoc/cleanup_section_names.rb +75 -0
  21. data/lib/asciidoctor/standoc/cleanup_terms.rb +19 -18
  22. data/lib/asciidoctor/standoc/converter.rb +7 -2
  23. data/lib/asciidoctor/standoc/datamodel/plantuml_renderer.rb +67 -66
  24. data/lib/asciidoctor/standoc/front.rb +35 -18
  25. data/lib/asciidoctor/standoc/front_contributor.rb +70 -45
  26. data/lib/asciidoctor/standoc/inline.rb +45 -34
  27. data/lib/asciidoctor/standoc/isodoc.rng +209 -4
  28. data/lib/asciidoctor/standoc/lists.rb +4 -2
  29. data/lib/asciidoctor/standoc/macros.rb +11 -11
  30. data/lib/asciidoctor/standoc/macros_form.rb +63 -0
  31. data/lib/asciidoctor/standoc/macros_plantuml.rb +19 -21
  32. data/lib/asciidoctor/standoc/macros_terms.rb +33 -23
  33. data/lib/asciidoctor/standoc/ref.rb +87 -112
  34. data/lib/asciidoctor/standoc/ref_date_id.rb +62 -0
  35. data/lib/asciidoctor/standoc/ref_sect.rb +20 -17
  36. data/lib/asciidoctor/standoc/section.rb +3 -1
  37. data/lib/asciidoctor/standoc/term_lookup_cleanup.rb +40 -27
  38. data/lib/asciidoctor/standoc/terms.rb +25 -18
  39. data/lib/asciidoctor/standoc/utils.rb +35 -9
  40. data/lib/asciidoctor/standoc/validate.rb +48 -33
  41. data/lib/metanorma-standoc.rb +0 -1
  42. data/lib/metanorma/standoc/version.rb +1 -1
  43. data/metanorma-standoc.gemspec +4 -4
  44. data/spec/asciidoctor/base_spec.rb +701 -508
  45. data/spec/asciidoctor/blocks_spec.rb +831 -738
  46. data/spec/asciidoctor/cleanup_sections_spec.rb +51 -14
  47. data/spec/asciidoctor/cleanup_spec.rb +889 -682
  48. data/spec/asciidoctor/inline_spec.rb +62 -14
  49. data/spec/asciidoctor/isobib_cache_spec.rb +404 -358
  50. data/spec/asciidoctor/lists_spec.rb +149 -137
  51. data/spec/asciidoctor/macros_plantuml_spec.rb +8 -8
  52. data/spec/asciidoctor/macros_spec.rb +923 -503
  53. data/spec/asciidoctor/macros_yaml2text_spec.rb +1 -1
  54. data/spec/asciidoctor/refs_dl_spec.rb +4 -4
  55. data/spec/asciidoctor/refs_spec.rb +1528 -1533
  56. data/spec/asciidoctor/section_spec.rb +405 -299
  57. data/spec/asciidoctor/table_spec.rb +6 -6
  58. data/spec/asciidoctor/validate_spec.rb +342 -304
  59. data/spec/spec_helper.rb +13 -9
  60. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +54 -54
  61. data/spec/vcr_cassettes/isobib_get_123.yml +13 -13
  62. data/spec/vcr_cassettes/isobib_get_123_1.yml +25 -25
  63. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +37 -37
  64. data/spec/vcr_cassettes/isobib_get_123_2001.yml +12 -12
  65. data/spec/vcr_cassettes/isobib_get_124.yml +13 -13
  66. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +14 -14
  67. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +46 -46
  68. metadata +16 -15
  69. data/lib/liquid/custom_blocks/key_iterator.rb +0 -21
  70. data/lib/liquid/custom_blocks/with_json_nested_context.rb +0 -18
  71. data/lib/liquid/custom_blocks/with_yaml_nested_context.rb +0 -19
  72. data/lib/liquid/custom_filters/values.rb +0 -7
@@ -1,3 +1,5 @@
1
+ require "csv"
2
+
1
3
  module Asciidoctor
2
4
  module Standoc
3
5
  class AltTermInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
@@ -36,46 +38,54 @@ module Asciidoctor
36
38
  end
37
39
  end
38
40
 
39
- # Macro to transform `term[X,Y]` into em, termxref xml
40
41
  class TermRefInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
41
42
  use_dsl
42
43
  named :term
43
- name_positional_attributes 'name', 'termxref'
44
+ name_positional_attributes "name", "termxref"
44
45
  using_format :short
45
46
 
46
47
  def process(_parent, _target, attrs)
47
- termref = attrs['termxref'] || attrs['name']
48
- "<em>#{attrs['name']}</em> (<termxref>#{termref}</termxref>)"
48
+ termref = attrs["termxref"] || attrs["name"]
49
+ "<concept><termxref>#{attrs['name']}</termxref>"\
50
+ "<renderterm>#{termref}</renderterm><xrefrender/></concept>"
49
51
  end
50
52
  end
51
53
 
54
+ # Possibilities:
55
+ # {{<<id>>, term}}
56
+ # {{<<id>>, term, text}}
57
+ # {{<<termbase:id>>, term}}
58
+ # {{<<termbase:id>>, term, text}}
59
+ # {{term}} equivalent to term:[term]
60
+ # {{term, text}} equivalent to term:[term, text]
61
+ # text may optionally be followed by crossreference-rendering, options=""
52
62
  class ConceptInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
53
63
  use_dsl
54
64
  named :concept
55
- name_positional_attributes "id", "word", "term"
56
- # match %r{concept:(?<target>[^\[]*)\[(?<content>|.*?[^\\])\]$}
57
65
  match /\{\{(?<content>|.*?[^\\])\}\}/
58
66
  using_format :short
59
67
 
60
- # deal with locality attrs and their disruption of positional attrs
61
- def preprocess_attrs(attrs)
62
- attrs.delete("term") if attrs["term"] && !attrs["word"]
63
- attrs.delete(3) if attrs[3] == attrs["term"]
64
- a = attrs.keys.reject { |k| k.is_a?(String) || [1, 2].include?(k) }
65
- attrs["word"] ||= attrs[a[0]] if !a.empty?
66
- attrs["term"] ||= attrs[a[1]] if a.length > 1
67
- attrs
68
+ def preprocess_attrs(target)
69
+ m = /^(?<id>&lt;&lt;.+?&gt;&gt;)?(?<rest>.*)$/.match(target)
70
+ ret = { id: m[:id]&.sub(/^&lt;&lt;/, "")&.sub(/&gt;&gt;$/, "") }
71
+ m2 = /^(?<rest>.*)(?<opt>,option=.+)?$/.match(m[:rest].sub(/^,/, ""))
72
+ ret[:opt] = m2[:opt]&.sub(/^,option=/, "")
73
+ attrs = CSV.parse_line(m2[:rest]) || []
74
+ ret.merge(term: attrs[0], word: attrs[1] || attrs[0],
75
+ xrefrender: attrs[2])
68
76
  end
69
77
 
70
- def process(parent, _target, attr)
71
- attr = preprocess_attrs(attr)
72
- localities = attr.keys.reject { |k| %w(id word term).include? k }.
73
- reject { |k| k.is_a? Numeric }.
74
- map { |k| "#{k}=#{attr[k]}" }.join(",")
75
- text = [localities, attr["word"]].reject{ |k| k.nil? || k.empty? }.
76
- join(",")
77
- out = Asciidoctor::Inline.new(parent, :quoted, text).convert
78
- %{<concept key="#{attr['id']}" term="#{attr['term']}">#{out}</concept>}
78
+ def process(parent, target, _attrs)
79
+ attrs = preprocess_attrs(target)
80
+ termout = Asciidoctor::Inline.new(parent, :quoted, attrs[:term]).convert
81
+ wordout = Asciidoctor::Inline.new(parent, :quoted, attrs[:word]).convert
82
+ xrefout = Asciidoctor::Inline.new(parent, :quoted,
83
+ attrs[:xrefrender]).convert
84
+ attrs[:id] and return "<concept key='#{attrs[:id]}'><refterm>"\
85
+ "#{termout}</refterm><renderterm>#{wordout}</renderterm>"\
86
+ "<xrefrender>#{xrefout}</xrefrender></concept>"
87
+ "<concept><termxref>#{termout}</termxref><renderterm>#{wordout}"\
88
+ "</renderterm><xrefrender>#{xrefout}</xrefrender></concept>"
79
89
  end
80
90
  end
81
91
  end
@@ -1,12 +1,14 @@
1
+ require_relative "ref_date_id"
2
+
1
3
  module Asciidoctor
2
4
  module Standoc
3
5
  module Refs
4
- def iso_publisher(t, code)
6
+ def iso_publisher(bib, code)
5
7
  code.sub(/ .*$/, "").split(/\//).each do |abbrev|
6
- t.contributor do |c|
8
+ bib.contributor do |c|
7
9
  c.role **{ type: "publisher" }
8
10
  c.organization do |org|
9
- organization(org, abbrev)
11
+ organization(org, abbrev, true)
10
12
  end
11
13
  end
12
14
  end
@@ -20,58 +22,19 @@ module Asciidoctor
20
22
  { id: m[:anchor], type: "standard" }
21
23
  end
22
24
 
23
- def set_date_range(date, text)
24
- matched = /^(?<from>[0-9]+)(-+(?<to>[0-9]+))?$/.match text
25
- return unless matched[:from]
26
- if matched[:to]
27
- date.from matched[:from]
28
- date.to matched[:to]
29
- else
30
- date.on matched[:from]
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 id_and_year(id, year)
40
- year ? "#{id}:#{year}" : id
41
- end
42
-
43
- def docid(t, code)
44
- type, code1 = /^\[\d+\]$|^\([^)]+\).*$/.match(code) ?
45
- ["metanorma", mn_code(code)] : @bibdb&.docid_type(code) || [nil, code]
46
- code1.sub!(/^nofetch\((.+)\)$/, "\\1")
47
- t.docidentifier **attr_code(type: type) do |d|
48
- d << code1
49
- end
50
- end
51
-
52
- def docnumber(t, code)
53
- t.docnumber do |d|
54
- d << HTMLEntities.new.decode(code).sub(/^[^\d]*/, "")
55
- end
56
- end
57
-
58
- def norm_year(yr)
59
- /^\&\#821[12];$/.match(yr) and return "--"
60
- /^\d\d\d\d-\d\d\d\d$/.match(yr) and return yr
61
- yr&.sub(/(?<=[0-9])-.*$/, "")
62
- end
63
-
64
- def isorefrender1(t, m, yr, allp = "")
65
- t.title(**plaintxt) { |i| i << ref_normalise(m[:text]) }
66
- docid(t, m[:usrlbl]) if m[:usrlbl]
67
- docid(t, id_and_year(m[:code], yr) + allp)
68
- docnumber(t, m[:code])
25
+ def isorefrender1(bib, m, yr, allp = "")
26
+ bib.title(**plaintxt) { |i| i << ref_normalise(m[:text]) }
27
+ docid(bib, m[:usrlbl]) if m[:usrlbl]
28
+ docid(bib, id_and_year(m[:code], yr) + allp)
29
+ docnumber(bib, m[:code])
69
30
  end
70
31
 
71
32
  def isorefmatches(xml, m)
72
33
  yr = norm_year(m[:year])
73
- ref = fetch_ref xml, m[:code], yr, title: m[:text], usrlbl: m[:usrlbl], lang: (@lang || :all)
34
+ ref = fetch_ref xml, m[:code], yr, title: m[:text], usrlbl: m[:usrlbl],
35
+ lang: (@lang || :all)
74
36
  return use_my_anchor(ref, m[:anchor]) if ref
37
+
75
38
  xml.bibitem **attr_code(ref_attributes(m)) do |t|
76
39
  isorefrender1(t, m, yr)
77
40
  yr and t.date **{ type: "published" } do |d|
@@ -85,6 +48,7 @@ module Asciidoctor
85
48
  ref = fetch_ref xml, m[:code], nil, no_year: true, note: m[:fn],
86
49
  title: m[:text], usrlbl: m[:usrlbl], lang: (@lang || :all)
87
50
  return use_my_anchor(ref, m[:anchor]) if ref
51
+
88
52
  isorefmatches2_1(xml, m)
89
53
  end
90
54
 
@@ -95,49 +59,51 @@ module Asciidoctor
95
59
  d.on "--"
96
60
  end
97
61
  iso_publisher(t, m[:code])
98
- m[:fn].nil? or t.note(**plaintxt.merge(type: "Unpublished-Status")) do |p|
99
- p << "#{m[:fn]}"
62
+ unless m[:fn].nil?
63
+ t.note(**plaintxt.merge(type: "Unpublished-Status")) do |p|
64
+ p << (m[:fn]).to_s
65
+ end
100
66
  end
101
67
  end
102
68
  end
103
69
 
104
- def conditional_date(t, m, noyr)
105
- m.names.include?("year") and !m[:year].nil? and
106
- t.date(**{ type: "published" }) do |d|
107
- noyr and d.on "--" or set_date_range(d, norm_year(m[:year]))
108
- end
109
- end
110
-
111
70
  def isorefmatches3(xml, m)
112
71
  yr = norm_year(m[:year])
113
72
  hasyr = !yr.nil? && yr != "--"
114
- ref = fetch_ref xml, m[:code], hasyr ? yr : nil, all_parts: true,
115
- no_year: yr == "--", text: m[:text], usrlbl: m[:usrlbl], lang: (@lang || :all)
73
+ ref = fetch_ref(xml, m[:code], hasyr ? yr : nil,
74
+ all_parts: true,
75
+ no_year: yr == "--", text: m[:text], usrlbl: m[:usrlbl],
76
+ lang: (@lang || :all))
116
77
  return use_my_anchor(ref, m[:anchor]) if ref
78
+
117
79
  isorefmatches3_1(xml, m, yr, hasyr, ref)
118
80
  end
119
81
 
120
- def isorefmatches3_1(xml, m, yr, hasyr, ref)
82
+ def isorefmatches3_1(xml, m, yr, _hasyr, _ref)
121
83
  xml.bibitem(**attr_code(ref_attributes(m))) do |t|
122
84
  isorefrender1(t, m, yr, " (all parts)")
123
85
  conditional_date(t, m, yr == "--")
124
86
  iso_publisher(t, m[:code])
125
- m.names.include?("fn") && m[:fn] and
126
- t.note(**plaintxt.merge(type: "Unpublished-Status")) { |p| p << "#{m[:fn]}" }
127
- t.extent **{ type: 'part' } do |e|
87
+ if m.names.include?("fn") && m[:fn]
88
+ t.note(**plaintxt.merge(type: "Unpublished-Status")) do |p|
89
+ p << (m[:fn]).to_s
90
+ end
91
+ end
92
+ t.extent **{ type: "part" } do |e|
128
93
  e.referenceFrom "all"
129
94
  end
130
95
  end
131
96
  end
132
97
 
133
- def refitem_render1(m, code, t)
98
+ def refitem_render1(m, code, bib)
134
99
  if code[:type] == "path"
135
- t.uri code[:key].sub(/\.[a-zA-Z0-9]+$/, ""), **{ type: "URI" }
136
- t.uri code[:key].sub(/\.[a-zA-Z0-9]+$/, ""), **{ type: "citation" }
100
+ bib.uri code[:key].sub(/\.[a-zA-Z0-9]+$/, ""), **{ type: "URI" }
101
+ bib.uri code[:key].sub(/\.[a-zA-Z0-9]+$/, ""), **{ type: "citation" }
137
102
  end
138
- docid(t, m[:usrlbl]) if m[:usrlbl]
139
- docid(t, /^\d+$/.match(code[:id]) ? "[#{code[:id]}]" : code[:id])
140
- code[:type] == "repo" and t.docidentifier code[:key], **{ type: "repository" }
103
+ docid(bib, m[:usrlbl]) if m[:usrlbl]
104
+ docid(bib, /^\d+$/.match?(code[:id]) ? "[#{code[:id]}]" : code[:id])
105
+ code[:type] == "repo" and
106
+ bib.docidentifier code[:key], **{ type: "repository" }
141
107
  end
142
108
 
143
109
  def refitem_render(xml, m, code)
@@ -146,7 +112,7 @@ module Asciidoctor
146
112
  i << ref_normalise_no_format(m[:text])
147
113
  end
148
114
  refitem_render1(m, code, t)
149
- docnumber(t, code[:id]) unless /^\d+$|^\(.+\)$/.match(code[:id])
115
+ docnumber(t, code[:id]) unless /^\d+$|^\(.+\)$/.match?(code[:id])
150
116
  end
151
117
  end
152
118
 
@@ -156,25 +122,30 @@ module Asciidoctor
156
122
 
157
123
  def analyse_ref_nofetch(ret)
158
124
  return ret unless m = /^nofetch\((?<id>.+)\)$/.match(ret[:id])
125
+
159
126
  ret.merge(id: m[:id], nofetch: true)
160
127
  end
161
128
 
162
129
  def analyse_ref_repo_path(ret)
163
- return ret unless m = /^(?<type>repo|path):\((?<key>[^,]+),?(?<id>.*)\)$/.match(ret[:id])
130
+ return ret unless m =
131
+ /^(?<type>repo|path):\((?<key>[^,]+),?(?<id>.*)\)$/.match(ret[:id])
132
+
164
133
  id = m[:id].empty? ? m[:key].sub(%r{^[^/]+/}, "") : m[:id]
165
134
  ret.merge(id: id, type: m[:type], key: m[:key], nofetch: true)
166
135
  end
167
136
 
168
137
  def analyse_ref_numeric(ret)
169
- return ret unless /^\d+$/.match(ret[:id])
138
+ return ret unless /^\d+$/.match?(ret[:id])
139
+
170
140
  ret.merge(numeric: true)
171
141
  end
172
142
 
173
143
  # ref id = (usrlbl)code[:-]year
174
144
  # code = nofetch(code) | (repo|path):(key,code) | \[? number \]? | ident
175
145
  def analyse_ref_code(code)
176
- ret = {id: code}
177
- return ret if code.nil? || code.empty?
146
+ ret = { id: code }
147
+ return ret if code.blank?
148
+
178
149
  analyse_ref_nofetch(analyse_ref_repo_path(analyse_ref_numeric(ret)))
179
150
  end
180
151
 
@@ -185,11 +156,13 @@ module Asciidoctor
185
156
  nil
186
157
  end
187
158
 
188
- def refitem1(xml, item, m)
159
+ def refitem1(xml, _item, m)
189
160
  code = analyse_ref_code(m[:code])
190
161
  unless code[:id] && code[:numeric] || code[:nofetch]
191
- ref = fetch_ref xml, code[:id], m.names.include?("year") ? m[:year] : nil, title: m[:text],
192
- usrlbl: m[:usrlbl], lang: (@lang || :all)
162
+ ref = fetch_ref(xml, code[:id],
163
+ m.names.include?("year") ? m[:year] : nil,
164
+ title: m[:text],
165
+ usrlbl: m[:usrlbl], lang: (@lang || :all))
193
166
  return use_my_anchor(ref, m[:anchor]) if ref
194
167
  end
195
168
  refitem_render(xml, m, code)
@@ -203,44 +176,46 @@ module Asciidoctor
203
176
  ref.gsub(/&amp;amp;/, "&amp;")
204
177
  end
205
178
 
206
- ISO_REF = %r{^<ref\sid="(?<anchor>[^"]+)">
179
+ ISO_REF =
180
+ %r{^<ref\sid="(?<anchor>[^"]+)">
207
181
  \[(?<usrlbl>\([^)]+\))?(?<code>(ISO|IEC)[^0-9]*\s[0-9-]+|IEV)
208
- (:(?<year>[0-9][0-9-]+))?\]</ref>,?\s*(?<text>.*)$}xm
182
+ (:(?<year>[0-9][0-9-]+))?\]</ref>,?\s*(?<text>.*)$}xm.freeze
209
183
 
210
- ISO_REF_NO_YEAR = %r{^<ref\sid="(?<anchor>[^"]+)">
184
+ ISO_REF_NO_YEAR =
185
+ %r{^<ref\sid="(?<anchor>[^"]+)">
211
186
  \[(?<usrlbl>\([^)]+\))?(?<code>(ISO|IEC)[^0-9]*\s[0-9-]+):
212
- (--|\&\#821[12]\;)\]</ref>,?\s*
187
+ (--|&\#821[12];)\]</ref>,?\s*
213
188
  (<fn[^>]*>\s*<p>(?<fn>[^\]]+)</p>\s*</fn>)?,?\s?(?<text>.*)$}xm
214
-
215
- ISO_REF_ALL_PARTS = %r{^<ref\sid="(?<anchor>[^"]+)">
216
- \[(?<usrlbl>\([^)]+\))?(?<code>(ISO|IEC)[^0-9]*\s[0-9]+)
217
- (:(?<year>--|\&\#821[12]\;|[0-9][0-9-]+))?\s
218
- \(all\sparts\)\]</ref>,?\s*
219
- (<fn[^>]*>\s*<p>(?<fn>[^\]]+)</p>\s*</fn>,?\s?)?(?<text>.*)$}xm
220
-
221
- NON_ISO_REF = %r{^<ref\sid="(?<anchor>[^"]+)">
222
- \[(?<usrlbl>\([^)]+\))?(?<code>[^\]]+?)
223
- ([:-](?<year>(19|20)[0-9][0-9][0-9-]*))?\]</ref>,?\s*(?<text>.*)$}xm
224
-
225
- def reference1_matches(item)
226
- matched = ISO_REF.match item
227
- matched2 = ISO_REF_NO_YEAR.match item
228
- matched3 = ISO_REF_ALL_PARTS.match item
229
- [matched, matched2, matched3]
230
- end
231
-
232
- def reference1(node, item, xml)
233
- matched, matched2, matched3 = reference1_matches(item)
234
- if matched3.nil? && matched2.nil? && matched.nil? then refitem(xml, item, node)
235
- elsif !matched.nil? then isorefmatches(xml, matched)
236
- elsif !matched2.nil? then isorefmatches2(xml, matched2)
237
- elsif !matched3.nil? then isorefmatches3(xml, matched3)
238
- end
239
- end
240
-
241
- def mn_code(code)
242
- code.sub(/^\(/, "[").sub(/\).*$/, "]").sub(/^nofetch\((.+)\)$/, "\\1")
189
+ .freeze
190
+
191
+ ISO_REF_ALL_PARTS =
192
+ %r{^<ref\sid="(?<anchor>[^"]+)">
193
+ \[(?<usrlbl>\([^)]+\))?(?<code>(ISO|IEC)[^0-9]*\s[0-9]+)
194
+ (:(?<year>--|&\#821[12];|[0-9][0-9-]+))?\s
195
+ \(all\sparts\)\]</ref>,?\s*
196
+ (<fn[^>]*>\s*<p>(?<fn>[^\]]+)</p>\s*</fn>,?\s?)?(?<text>.*)$}xm.freeze
197
+
198
+ NON_ISO_REF = %r{^<ref\sid="(?<anchor>[^"]+)">
199
+ \[(?<usrlbl>\([^)]+\))?(?<code>[^\]]+?)
200
+ ([:-](?<year>(19|20)[0-9][0-9][0-9-]*))?\]</ref>,?\s*(?<text>.*)$}xm
201
+ .freeze
202
+
203
+ def reference1_matches(item)
204
+ matched = ISO_REF.match item
205
+ matched2 = ISO_REF_NO_YEAR.match item
206
+ matched3 = ISO_REF_ALL_PARTS.match item
207
+ [matched, matched2, matched3]
208
+ end
209
+
210
+ def reference1(node, item, xml)
211
+ matched, matched2, matched3 = reference1_matches(item)
212
+ if matched3.nil? && matched2.nil? && matched.nil?
213
+ refitem(xml, item, node)
214
+ elsif !matched.nil? then isorefmatches(xml, matched)
215
+ elsif !matched2.nil? then isorefmatches2(xml, matched2)
216
+ elsif !matched3.nil? then isorefmatches3(xml, matched3)
243
217
  end
218
+ end
244
219
  end
245
220
  end
246
221
  end
@@ -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