metanorma-standoc 1.10.6 → 1.10.7

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 (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">