metanorma-standoc 1.10.6 → 1.10.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/lib/asciidoctor/standoc/base.rb +3 -13
  3. data/lib/asciidoctor/standoc/cleanup.rb +26 -1
  4. data/lib/asciidoctor/standoc/cleanup_block.rb +3 -71
  5. data/lib/asciidoctor/standoc/cleanup_inline.rb +0 -102
  6. data/lib/asciidoctor/standoc/cleanup_reqt.rb +3 -3
  7. data/lib/asciidoctor/standoc/cleanup_section_names.rb +5 -5
  8. data/lib/asciidoctor/standoc/cleanup_table.rb +68 -0
  9. data/lib/asciidoctor/standoc/cleanup_text.rb +5 -2
  10. data/lib/asciidoctor/standoc/cleanup_xref.rb +107 -0
  11. data/lib/asciidoctor/standoc/converter.rb +12 -0
  12. data/lib/asciidoctor/standoc/isodoc.rng +9 -0
  13. data/lib/asciidoctor/standoc/macros.rb +14 -43
  14. data/lib/asciidoctor/standoc/macros_note.rb +45 -0
  15. data/lib/metanorma/standoc/version.rb +1 -1
  16. data/spec/asciidoctor/base_spec.rb +0 -33
  17. data/spec/asciidoctor/blank_spec.rb +37 -0
  18. data/spec/asciidoctor/blocks_spec.rb +31 -0
  19. data/spec/asciidoctor/cleanup_sections_spec.rb +146 -5
  20. data/spec/asciidoctor/cleanup_spec.rb +1 -1
  21. data/spec/asciidoctor/inline_spec.rb +36 -0
  22. data/spec/asciidoctor/macros_plantuml_spec.rb +1 -1
  23. data/spec/asciidoctor/macros_spec.rb +1 -1
  24. data/spec/fixtures/datamodel_description_sections_tree.xml +3 -2
  25. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +45 -45
  26. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +12 -12
  27. data/spec/vcr_cassettes/isobib_get_123.yml +13 -13
  28. data/spec/vcr_cassettes/isobib_get_123_1.yml +23 -23
  29. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +33 -33
  30. data/spec/vcr_cassettes/isobib_get_123_2001.yml +12 -12
  31. data/spec/vcr_cassettes/isobib_get_124.yml +13 -13
  32. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +16 -16
  33. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +52 -50
  34. metadata +6 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5982aeb8f67b56ccf4da3cf8589b3855fda38e646650074f8804d8e94de9a791
4
- data.tar.gz: 6efa1a3eb9fce06dfcce893c835152a2ee642418cd35f06981d4a3d7e4408832
3
+ metadata.gz: 90fb9b89f2c7070b763519843f307f4d3ecebb8ee462d7017afb886a397de8a8
4
+ data.tar.gz: b6f2e8253577f05a76e833d3a1e5d9f64fd47a7de48d8ec6703056b04965096a
5
5
  SHA512:
6
- metadata.gz: 4d4cd2f1c480899fe9221482e53bff2702d96cc1688937b15b993eddcddbca80cb7c5d931913ceaa5e06f9c0b6a70723fc3a84c275a259c5a9bb21fb8b3d42fe
7
- data.tar.gz: 61cf1ff021b2f6365ad83311478732ed431dc2f3328e11ec1a96ebfa264c463ded7198779a86928bb3a82ce4153f4934b96aeccccff5d136d3018cd9b6025173
6
+ metadata.gz: 17eb330f74f079b78db600f8030c15e497b6e0b1251157b9499cf532974280e6d4bb61ebe7d4c52cc443ca4d407371b575f6425783aa384e4c977733de528c5e
7
+ data.tar.gz: f3063d8116e77c1e00cf6f9ba12668e5bfbb581d41e02e9d4c4fee2dc21884754f8102a718d7318d3b0619abaf1715528162e9aebcb97895a7ab85bbeb6fccd4
@@ -23,17 +23,6 @@ module Asciidoctor
23
23
  self.class::XML_NAMESPACE
24
24
  end
25
25
 
26
- def content(node)
27
- node.content
28
- end
29
-
30
- def skip(node, name = nil)
31
- name = name || node.node_name
32
- w = "converter missing for #{name} node in Metanorma backend"
33
- @log.add("AsciiDoc Input", node, w)
34
- nil
35
- end
36
-
37
26
  def html_extract_attributes(node)
38
27
  {
39
28
  script: node.attr("script"),
@@ -56,6 +45,7 @@ module Asciidoctor
56
45
  suppressasciimathdup: node.attr("suppress-asciimath-dup"),
57
46
  bare: node.attr("bare"),
58
47
  sectionsplit: node.attr("sectionsplit"),
48
+ baseassetpath: node.attr("base-asset-path"),
59
49
  }
60
50
  end
61
51
 
@@ -90,6 +80,7 @@ module Asciidoctor
90
80
  break_up_urls_in_tables: node.attr("break-up-urls-in-tables"),
91
81
  suppressasciimathdup: node.attr("suppress-asciimath-dup"),
92
82
  bare: node.attr("bare"),
83
+ baseassetpath: node.attr("base-asset-path"),
93
84
  }
94
85
 
95
86
  if font_manifest_file = node.attr("mn2pdf-font-manifest-file")
@@ -124,8 +115,7 @@ module Asciidoctor
124
115
  @files_to_delete = []
125
116
  @filename = if node.attr("docfile")
126
117
  File.basename(node.attr("docfile"))&.gsub(/\.adoc$/, "")
127
- else
128
- ""
118
+ else ""
129
119
  end
130
120
  @localdir = Metanorma::Utils::localdir(node)
131
121
  @output_dir = outputdir node
@@ -2,12 +2,14 @@ require "nokogiri"
2
2
  require "pathname"
3
3
  require "html2doc"
4
4
  require_relative "./cleanup_block"
5
+ require_relative "./cleanup_table"
5
6
  require_relative "./cleanup_footnotes"
6
7
  require_relative "./cleanup_ref"
7
8
  require_relative "./cleanup_ref_dl"
8
9
  require_relative "./cleanup_boilerplate"
9
10
  require_relative "./cleanup_section"
10
11
  require_relative "./cleanup_terms"
12
+ require_relative "./cleanup_xref"
11
13
  require_relative "./cleanup_inline"
12
14
  require_relative "./cleanup_amend"
13
15
  require_relative "./cleanup_maths"
@@ -129,13 +131,18 @@ module Asciidoctor
129
131
  end
130
132
 
131
133
  def toc_cleanup(xmldoc)
134
+ toc_cleanup_para(xmldoc)
135
+ xmldoc.xpath("//toc").each { |t| toc_cleanup1(t, xmldoc) }
136
+ toc_cleanup_clause(xmldoc)
137
+ end
138
+
139
+ def toc_cleanup_para(xmldoc)
132
140
  xmldoc.xpath("//p[toc]").each do |x|
133
141
  x.xpath("./toc").reverse.each do |t|
134
142
  x.next = t
135
143
  end
136
144
  x.remove if x.text.strip.empty?
137
145
  end
138
- xmldoc.xpath("//toc").each { |t| toc_cleanup1(t, xmldoc) }
139
146
  end
140
147
 
141
148
  def toc_index(toc, xmldoc)
@@ -169,6 +176,24 @@ module Asciidoctor
169
176
  end
170
177
  toc.children = "<ul>#{ret}</ul>"
171
178
  end
179
+
180
+ def toc_cleanup_clause(xmldoc)
181
+ xmldoc
182
+ .xpath("//clause[@type = 'toc'] | //annex[@type = 'toc']").each do |c|
183
+ c.xpath(".//ul[not(ancestor::ul)]").each do |ul|
184
+ toc_cleanup_clause_entry(xmldoc, ul)
185
+ ul.replace("<toc>#{ul.to_xml}</toc>")
186
+ end
187
+ end
188
+ end
189
+
190
+ def toc_cleanup_clause_entry(xmldoc, list)
191
+ list.xpath(".//xref[not(text())]").each do |x|
192
+ c1 = xmldoc.at("//*[@id = '#{x['target']}']")
193
+ t = c1.at("./variant-title[@type = 'toc']") || c1.at("./title")
194
+ x << t.dup.children
195
+ end
196
+ end
172
197
  end
173
198
  end
174
199
  end
@@ -9,9 +9,7 @@ module Asciidoctor
9
9
  "//ul[not(ancestor::bibdata)]", "//quote[not(ancestor::bibdata)]",
10
10
  "//note[not(ancestor::bibitem or "\
11
11
  "ancestor::table or ancestor::bibdata)]"].each do |w|
12
- inject_id(
13
- xmldoc, w
14
- )
12
+ inject_id(xmldoc, w)
15
13
  end
16
14
  end
17
15
 
@@ -21,70 +19,6 @@ module Asciidoctor
21
19
  end
22
20
  end
23
21
 
24
- def dl1_table_cleanup(xmldoc)
25
- q = "//table/following-sibling::*[1][self::dl]"
26
- xmldoc.xpath(q).each do |s|
27
- s["key"] == "true" and s.previous_element << s.remove
28
- end
29
- end
30
-
31
- # move Key dl after table footer
32
- def dl2_table_cleanup(xmldoc)
33
- q = "//table/following-sibling::*[1][self::p]"
34
- xmldoc.xpath(q).each do |s|
35
- if s.text =~ /^\s*key[^a-z]*$/i && s&.next_element&.name == "dl"
36
- s.next_element["key"] = "true"
37
- s.previous_element << s.next_element.remove
38
- s.remove
39
- end
40
- end
41
- end
42
-
43
- def insert_thead(table)
44
- thead = table.at("./thead")
45
- return thead unless thead.nil?
46
-
47
- if tname = table.at("./name")
48
- thead = tname.add_next_sibling("<thead/>").first
49
- return thead
50
- end
51
- table.children.first.add_previous_sibling("<thead/>").first
52
- end
53
-
54
- def header_rows_cleanup(xmldoc)
55
- xmldoc.xpath("//table[@headerrows]").each do |s|
56
- thead = insert_thead(s)
57
- (thead.xpath("./tr").size...s["headerrows"].to_i).each do
58
- row = s.at("./tbody/tr")
59
- row.parent = thead
60
- end
61
- thead.xpath(".//td").each { |n| n.name = "th" }
62
- s.delete("headerrows")
63
- end
64
- end
65
-
66
- def table_cleanup(xmldoc)
67
- dl1_table_cleanup(xmldoc)
68
- dl2_table_cleanup(xmldoc)
69
- notes_table_cleanup(xmldoc)
70
- header_rows_cleanup(xmldoc)
71
- end
72
-
73
- # move notes into table
74
- def notes_table_cleanup(xmldoc)
75
- nomatches = false
76
- until nomatches
77
- q = "//table/following-sibling::*[1]"\
78
- "[self::note[not(@keep-separate = 'true')]]"
79
- nomatches = true
80
- xmldoc.xpath(q).each do |n|
81
- n.delete("keep-separate")
82
- n.previous_element << n.remove
83
- nomatches = false
84
- end
85
- end
86
- end
87
-
88
22
  # include where definition list inside stem block
89
23
  def formula_cleanup(formula)
90
24
  formula_cleanup_where1(formula)
@@ -216,18 +150,16 @@ module Asciidoctor
216
150
  end
217
151
 
218
152
  def sourcecode_markup(node)
219
- acc = []
220
153
  node.text.split(/(#{Regexp.escape(@sourcecode_markup_start)}|
221
154
  #{Regexp.escape(@sourcecode_markup_end)})/x)
222
- .each_slice(4).map do |a|
155
+ .each_slice(4).map.with_object([]) do |a, acc|
223
156
  acc << safe_noko(a[0], node.document)
224
157
  next unless a.size == 4
225
158
 
226
159
  acc << Asciidoctor.convert(
227
160
  a[2], doctype: :inline, backend: (self&.backend&.to_sym || :standoc)
228
161
  )
229
- end
230
- acc.join
162
+ end.join
231
163
  end
232
164
 
233
165
  def form_cleanup(xmldoc)
@@ -55,108 +55,6 @@ module Asciidoctor
55
55
  end
56
56
  end
57
57
 
58
- # extending localities to cover ISO referencing
59
- LOCALITY_REGEX_STR = <<~REGEXP.freeze
60
- ^((?<locality>section|clause|part|paragraph|chapter|page|
61
- table|annex|figure|example|note|formula|list|time|anchor|
62
- locality:[^ \\t\\n\\r:,;=]+)(\\s+|=)
63
- (?<ref>[^"][^ \\t\\n,:-]*|"[^"]+")
64
- (-(?<to>[^"][^ \\t\\n,:-]*|"[^"]"))?|
65
- (?<locality2>whole|locality:[^ \\t\\n\\r:,;=]+))(?<punct>[,:;]?)\\s*
66
- (?<text>.*)$
67
- REGEXP
68
- LOCALITY_RE = Regexp.new(LOCALITY_REGEX_STR.gsub(/\s/, ""),
69
- Regexp::IGNORECASE | Regexp::MULTILINE)
70
-
71
- def tq(text)
72
- text.sub(/^"/, "").sub(/"$/, "")
73
- end
74
-
75
- def extract_localities(elem)
76
- f = elem&.children&.first or return
77
- f.text? or return
78
- head = f.remove.text
79
- tail = elem&.children&.remove
80
- extract_localities1(elem, head)
81
- tail and elem << tail
82
- end
83
-
84
- def extract_localities1(elem, text)
85
- b = elem.add_child("<localityStack/>").first if LOCALITY_RE.match text
86
- while (m = LOCALITY_RE.match text)
87
- ref = m[:ref] ? "<referenceFrom>#{tq m[:ref]}</referenceFrom>" : ""
88
- refto = m[:to] ? "<referenceTo>#{tq m[:to]}</referenceTo>" : ""
89
- b.add_child("<locality type='#{locality_label(m)}'>#{ref}#{refto}"\
90
- "</locality>")
91
- text = m[:text]
92
- b = elem.add_child("<localityStack/>").first if m[:punct] == ";"
93
- end
94
- elem.add_child(text) if text
95
- end
96
-
97
- def locality_label(match)
98
- loc = match[:locality] || match[:locality2]
99
- /^locality:/.match?(loc) ? loc : loc&.downcase
100
- end
101
-
102
- def xref_to_eref(elem)
103
- elem["bibitemid"] = elem["target"]
104
- unless elem["citeas"] = @anchors&.dig(elem["target"], :xref)
105
- @internal_eref_namespaces.include?(elem["type"]) or
106
- @log.add("Crossreferences", elem,
107
- "#{elem['target']} does not have a corresponding "\
108
- "anchor ID in the bibliography!")
109
- end
110
- elem.delete("target")
111
- extract_localities(elem) unless elem.children.empty?
112
- end
113
-
114
- def xref_cleanup(xmldoc)
115
- xmldoc.xpath("//xref").each do |x|
116
- /:/.match(x["target"]) and xref_to_internal_eref(x)
117
- next unless x.name == "xref"
118
-
119
- if refid? x["target"]
120
- x.name = "eref"
121
- xref_to_eref(x)
122
- else x.delete("type")
123
- end
124
- end
125
- end
126
-
127
- def xref_to_internal_eref(elem)
128
- a = elem["target"].split(":", 3)
129
- unless a.size < 2 || a[0].empty? || a[1].empty?
130
- elem["target"] = "#{a[0]}_#{a[1]}"
131
- a.size > 2 and
132
- elem.children = %{anchor="#{a[2..-1].join}",#{elem&.children&.text}}
133
- elem["type"] = a[0]
134
- @internal_eref_namespaces << a[0]
135
- elem.name = "eref"
136
- xref_to_eref(elem)
137
- end
138
- end
139
-
140
- def quotesource_cleanup(xmldoc)
141
- xmldoc.xpath("//quote/source | //terms/source").each do |x|
142
- xref_to_eref(x)
143
- end
144
- end
145
-
146
- def origin_cleanup(xmldoc)
147
- xmldoc.xpath("//origin/concept[termref]").each do |x|
148
- t = x.at("./termref")
149
- x.replace(t)
150
- end
151
- xmldoc.xpath("//origin").each do |x|
152
- x["citeas"] = @anchors&.dig(x["bibitemid"], :xref) or
153
- @log.add("Crossreferences", x,
154
- "#{x['bibitemid']} does not have a corresponding anchor "\
155
- "ID in the bibliography!")
156
- extract_localities(x) unless x.children.empty?
157
- end
158
- end
159
-
160
58
  def concept_cleanup(xmldoc)
161
59
  xmldoc.xpath("//concept[not(termxref)]").each do |x|
162
60
  term = x.at("./refterm")
@@ -72,7 +72,7 @@ module Asciidoctor
72
72
  def requirement_metadata(xmldoc)
73
73
  xmldoc.xpath(REQRECPER).each do |r|
74
74
  dl = r&.at("./dl[@metadata = 'true']")&.remove or next
75
- requirement_metadata1(r, dl)
75
+ requirement_metadata1(r, dl, r.at("./title"))
76
76
  end
77
77
  end
78
78
 
@@ -80,8 +80,8 @@ module Asciidoctor
80
80
  %w(label subject inherit)
81
81
  end
82
82
 
83
- def requirement_metadata1(reqt, dlist)
84
- unless ins = reqt.at("./title")
83
+ def requirement_metadata1(reqt, dlist, ins)
84
+ unless ins
85
85
  reqt.children.first.previous = " "
86
86
  ins = reqt.children.first
87
87
  end
@@ -78,12 +78,12 @@ module Asciidoctor
78
78
  def sections_variant_title_cleanup(xml)
79
79
  path = SECTION_CONTAINERS.map { |x| "./ancestor::#{x}" }.join(" | ")
80
80
  xml.xpath("//p[@variant_title]").each do |p|
81
+ p.name = "variant-title"
82
+ p.delete("id")
83
+ p.delete("variant_title")
81
84
  p.xpath("(#{path})[last()]").each do |sect|
82
- p.name = "variant-title"
83
- p.delete("id")
84
- if ins = sect.at("./title") then ins.next = p
85
- else sect.children.first.previous = p
86
- end
85
+ ins = sect.at("./title") and ins.next = p or
86
+ sect.children.first.previous = p
87
87
  end
88
88
  end
89
89
  end
@@ -0,0 +1,68 @@
1
+ module Asciidoctor
2
+ module Standoc
3
+ module Cleanup
4
+ def dl1_table_cleanup(xmldoc)
5
+ q = "//table/following-sibling::*[1][self::dl]"
6
+ xmldoc.xpath(q).each do |s|
7
+ s["key"] == "true" and s.previous_element << s.remove
8
+ end
9
+ end
10
+
11
+ # move Key dl after table footer
12
+ def dl2_table_cleanup(xmldoc)
13
+ q = "//table/following-sibling::*[1][self::p]"
14
+ xmldoc.xpath(q).each do |s|
15
+ if s.text =~ /^\s*key[^a-z]*$/i && s&.next_element&.name == "dl"
16
+ s.next_element["key"] = "true"
17
+ s.previous_element << s.next_element.remove
18
+ s.remove
19
+ end
20
+ end
21
+ end
22
+
23
+ def insert_thead(table)
24
+ thead = table.at("./thead")
25
+ return thead unless thead.nil?
26
+
27
+ if tname = table.at("./name")
28
+ thead = tname.add_next_sibling("<thead/>").first
29
+ return thead
30
+ end
31
+ table.children.first.add_previous_sibling("<thead/>").first
32
+ end
33
+
34
+ def header_rows_cleanup(xmldoc)
35
+ xmldoc.xpath("//table[@headerrows]").each do |s|
36
+ thead = insert_thead(s)
37
+ (thead.xpath("./tr").size...s["headerrows"].to_i).each do
38
+ row = s.at("./tbody/tr")
39
+ row.parent = thead
40
+ end
41
+ thead.xpath(".//td").each { |n| n.name = "th" }
42
+ s.delete("headerrows")
43
+ end
44
+ end
45
+
46
+ def table_cleanup(xmldoc)
47
+ dl1_table_cleanup(xmldoc)
48
+ dl2_table_cleanup(xmldoc)
49
+ notes_table_cleanup(xmldoc)
50
+ header_rows_cleanup(xmldoc)
51
+ end
52
+
53
+ # move notes into table
54
+ def notes_table_cleanup(xmldoc)
55
+ nomatches = false
56
+ until nomatches
57
+ nomatches = true
58
+ xmldoc.xpath("//table/following-sibling::*[1]"\
59
+ "[self::note[not(@keep-separate = 'true')]]").each do |n|
60
+ n.delete("keep-separate")
61
+ n.previous_element << n.remove
62
+ nomatches = false
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -9,7 +9,8 @@ module Asciidoctor
9
9
  </passthrough>}mx) { HTMLEntities.new.decode($1) }
10
10
  end
11
11
 
12
- IGNORE_DUMBQUOTES = "//pre | //pre//* | //tt | //tt//* | "\
12
+ IGNORE_DUMBQUOTES =
13
+ "//pre | //pre//* | //tt | //tt//* | "\
13
14
  "//sourcecode | //sourcecode//* | //bibdata//* | //stem | "\
14
15
  "//stem//* | //figure[@class = 'pseudocode'] | "\
15
16
  "//figure[@class = 'pseudocode']//*".freeze
@@ -32,6 +33,7 @@ module Asciidoctor
32
33
  "[starts-with(., '\"') or starts-with(., \"'\")]]")
33
34
  .each do |x|
34
35
  next if !x.ancestors("pre, tt, sourcecode, stem, figure").empty?
36
+
35
37
  uninterrupt_quotes_around_xml1(x)
36
38
  end
37
39
  end
@@ -40,7 +42,8 @@ module Asciidoctor
40
42
  prev = elem.at(".//preceding::text()[1]") or return
41
43
  /\S$/.match?(prev.text) or return
42
44
  foll = elem.at(".//following::text()[1]")
43
- m = /^(["'][[:punct:]]*)(\s|$)/.match(HTMLEntities.new.decode(foll&.text)) or return
45
+ m = /^(["'][[:punct:]]*)(\s|$)/
46
+ .match(HTMLEntities.new.decode(foll&.text)) or return
44
47
  foll.content = foll.text.sub(/^(["'][[:punct:]]*)/, "")
45
48
  prev.content = "#{prev.text}#{m[1]}"
46
49
  end
@@ -0,0 +1,107 @@
1
+ module Asciidoctor
2
+ module Standoc
3
+ module Cleanup
4
+ # extending localities to cover ISO referencing
5
+ LOCALITY_REGEX_STR = <<~REGEXP.freeze
6
+ ^((?<locality>section|clause|part|paragraph|chapter|page|
7
+ table|annex|figure|example|note|formula|list|time|anchor|
8
+ locality:[^ \\t\\n\\r:,;=]+)(\\s+|=)
9
+ (?<ref>[^"][^ \\t\\n,:-]*|"[^"]+")
10
+ (-(?<to>[^"][^ \\t\\n,:-]*|"[^"]"))?|
11
+ (?<locality2>whole|locality:[^ \\t\\n\\r:,;=]+))(?<punct>[,:;]?)\\s*
12
+ (?<text>.*)$
13
+ REGEXP
14
+ LOCALITY_RE = Regexp.new(LOCALITY_REGEX_STR.gsub(/\s/, ""),
15
+ Regexp::IGNORECASE | Regexp::MULTILINE)
16
+
17
+ def tq(text)
18
+ text.sub(/^"/, "").sub(/"$/, "")
19
+ end
20
+
21
+ def extract_localities(elem)
22
+ f = elem&.children&.first or return
23
+ f.text? or return
24
+ head = f.remove.text
25
+ tail = elem&.children&.remove
26
+ extract_localities1(elem, head)
27
+ tail and elem << tail
28
+ end
29
+
30
+ def extract_localities1(elem, text)
31
+ b = elem.add_child("<localityStack/>").first if LOCALITY_RE.match text
32
+ while (m = LOCALITY_RE.match text)
33
+ ref = m[:ref] ? "<referenceFrom>#{tq m[:ref]}</referenceFrom>" : ""
34
+ refto = m[:to] ? "<referenceTo>#{tq m[:to]}</referenceTo>" : ""
35
+ b.add_child("<locality type='#{locality_label(m)}'>#{ref}#{refto}"\
36
+ "</locality>")
37
+ text = m[:text]
38
+ b = elem.add_child("<localityStack/>").first if m[:punct] == ";"
39
+ end
40
+ elem.add_child(text) if text
41
+ end
42
+
43
+ def locality_label(match)
44
+ loc = match[:locality] || match[:locality2]
45
+ /^locality:/.match?(loc) ? loc : loc&.downcase
46
+ end
47
+
48
+ def xref_to_eref(elem)
49
+ elem["bibitemid"] = elem["target"]
50
+ unless elem["citeas"] = @anchors&.dig(elem["target"], :xref)
51
+ @internal_eref_namespaces.include?(elem["type"]) or
52
+ @log.add("Crossreferences", elem,
53
+ "#{elem['target']} does not have a corresponding "\
54
+ "anchor ID in the bibliography!")
55
+ end
56
+ elem.delete("target")
57
+ extract_localities(elem) unless elem.children.empty?
58
+ end
59
+
60
+ def xref_cleanup(xmldoc)
61
+ xmldoc.xpath("//xref").each do |x|
62
+ /:/.match(x["target"]) and xref_to_internal_eref(x)
63
+ next unless x.name == "xref"
64
+
65
+ if refid? x["target"]
66
+ x.name = "eref"
67
+ xref_to_eref(x)
68
+ else x.delete("type")
69
+ end
70
+ end
71
+ end
72
+
73
+ def xref_to_internal_eref(elem)
74
+ a = elem["target"].split(":", 3)
75
+ unless a.size < 2 || a[0].empty? || a[1].empty?
76
+ elem["target"] = "#{a[0]}_#{a[1]}"
77
+ a.size > 2 and
78
+ elem.children = %{anchor="#{a[2..-1].join}",#{elem&.children&.text}}
79
+ elem["type"] = a[0]
80
+ @internal_eref_namespaces << a[0]
81
+ elem.name = "eref"
82
+ xref_to_eref(elem)
83
+ end
84
+ end
85
+
86
+ def quotesource_cleanup(xmldoc)
87
+ xmldoc.xpath("//quote/source | //terms/source").each do |x|
88
+ xref_to_eref(x)
89
+ end
90
+ end
91
+
92
+ def origin_cleanup(xmldoc)
93
+ xmldoc.xpath("//origin/concept[termref]").each do |x|
94
+ t = x.at("./termref")
95
+ x.replace(t)
96
+ end
97
+ xmldoc.xpath("//origin").each do |x|
98
+ x["citeas"] = @anchors&.dig(x["bibitemid"], :xref) or
99
+ @log.add("Crossreferences", x,
100
+ "#{x['bibitemid']} does not have a corresponding anchor "\
101
+ "ID in the bibliography!")
102
+ extract_localities(x) unless x.children.empty?
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -49,6 +49,7 @@ module Asciidoctor
49
49
  inline_macro Asciidoctor::Standoc::FormSelectMacro
50
50
  inline_macro Asciidoctor::Standoc::FormOptionMacro
51
51
  inline_macro Asciidoctor::Standoc::ToCInlineMacro
52
+ inline_macro Asciidoctor::Standoc::PassInlineMacro
52
53
  inline_macro Metanorma::Plugin::Lutaml::LutamlFigureInlineMacro
53
54
  inline_macro Metanorma::Plugin::Lutaml::LutamlTableInlineMacro
54
55
  block_macro Metanorma::Plugin::Lutaml::LutamlDiagramBlockMacro
@@ -98,6 +99,17 @@ module Asciidoctor
98
99
  File.join(@libdir, "../../isodoc/html", file)
99
100
  end
100
101
 
102
+ def content(node)
103
+ node.content
104
+ end
105
+
106
+ def skip(node, name = nil)
107
+ name = name || node.node_name
108
+ w = "converter missing for #{name} node in Metanorma backend"
109
+ @log.add("AsciiDoc Input", node, w)
110
+ nil
111
+ end
112
+
101
113
  alias_method :embedded, :content
102
114
  alias_method :verse, :quote
103
115
  alias_method :audio, :skip
@@ -1036,6 +1036,7 @@
1036
1036
  <ref name="svgmap"/>
1037
1037
  <ref name="inputform"/>
1038
1038
  <ref name="toc"/>
1039
+ <ref name="passthrough"/>
1039
1040
  </choice>
1040
1041
  </define>
1041
1042
  <define name="toc">
@@ -1043,6 +1044,14 @@
1043
1044
  <ref name="ul"/>
1044
1045
  </element>
1045
1046
  </define>
1047
+ <define name="passthrough">
1048
+ <element name="passthrough">
1049
+ <optional>
1050
+ <attribute name="formats"/>
1051
+ </optional>
1052
+ <text/>
1053
+ </element>
1054
+ </define>
1046
1055
  <define name="inputform">
1047
1056
  <element name="form">
1048
1057
  <attribute name="id">