metanorma-standoc 2.0.3 → 2.0.4

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/metanorma/standoc/base.rb +61 -22
  3. data/lib/metanorma/standoc/blocks.rb +3 -3
  4. data/lib/metanorma/standoc/cleanup_boilerplate.rb +3 -3
  5. data/lib/metanorma/standoc/cleanup_ref.rb +31 -2
  6. data/lib/metanorma/standoc/cleanup_ref_dl.rb +20 -16
  7. data/lib/metanorma/standoc/cleanup_section.rb +1 -1
  8. data/lib/metanorma/standoc/cleanup_terms_designations.rb +4 -2
  9. data/lib/metanorma/standoc/cleanup_xref.rb +70 -8
  10. data/lib/metanorma/standoc/converter.rb +1 -0
  11. data/lib/metanorma/standoc/inline.rb +21 -12
  12. data/lib/metanorma/standoc/isodoc.rng +63 -3
  13. data/lib/metanorma/standoc/macros.rb +13 -1
  14. data/lib/metanorma/standoc/macros_embed.rb +1 -1
  15. data/lib/metanorma/standoc/ref.rb +5 -6
  16. data/lib/metanorma/standoc/render.rb +7 -3
  17. data/lib/metanorma/standoc/table.rb +8 -10
  18. data/lib/metanorma/standoc/term_lookup_cleanup.rb +2 -1
  19. data/lib/metanorma/standoc/utils.rb +3 -1
  20. data/lib/metanorma/standoc/version.rb +1 -1
  21. data/spec/metanorma/base_spec.rb +1 -1
  22. data/spec/metanorma/cleanup_spec.rb +10 -10
  23. data/spec/metanorma/cleanup_terms_spec.rb +1 -1
  24. data/spec/metanorma/inline_spec.rb +31 -0
  25. data/spec/metanorma/macros_plantuml_spec.rb +41 -42
  26. data/spec/metanorma/macros_spec.rb +138 -2
  27. data/spec/metanorma/processor_spec.rb +17 -13
  28. data/spec/metanorma/refs_spec.rb +129 -2
  29. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +45 -45
  30. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +10 -10
  31. data/spec/vcr_cassettes/hide_refs.yml +39 -39
  32. data/spec/vcr_cassettes/isobib_get_123.yml +12 -12
  33. data/spec/vcr_cassettes/isobib_get_123_1.yml +23 -23
  34. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +28 -28
  35. data/spec/vcr_cassettes/isobib_get_123_2001.yml +11 -11
  36. data/spec/vcr_cassettes/isobib_get_124.yml +12 -12
  37. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +18 -18
  38. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +75 -65
  39. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc4b55c7be36492191bd86bc19646a520c76e94bd2e2af9f96cf0d80d25fb05e
4
- data.tar.gz: 533fc5380552ab239528a559ee41a47c246203e17cb33df64cb5cdef5df21f34
3
+ metadata.gz: 48ca241528c217b9b563a2d3f6f2e13b52f2fa24e679ca2de431ebde8d10fb98
4
+ data.tar.gz: f6b70cd60a959376474a35ef4d364f69f9e15fd6582a53571a71cec995d90a01
5
5
  SHA512:
6
- metadata.gz: adc2d0b10dd30e5f59060b20574701dc6049b25a9d25eff06557ac51ca66645f62b553517690380009460f01fe135d26e83ab653b81c7746209e8f55221c3703
7
- data.tar.gz: 8bc78cf1ab42e80d93c8a22f0028e44e7ba735914fa43c2dcdd5eb53cb57b3a3ee52ea1677cae5033dbc738f8b444bc0dc2e5021ff08a443d991535c84c373b2
6
+ metadata.gz: f175a4b49b2aa24d8c8b566a6929401f1a61fb217cf2ee03b506d93482a086afb7b09c85e7c6d88c93d1ef57d41e5a79dc6122bf41624842118dfa75759823b4
7
+ data.tar.gz: c395e93a7f1d3c03c63f1063f1689beb3e1725b81d26b2b38769038d491e8fade8462ab1b2f3b6324eede90c7e03b1473ce40873b903fd3859852436d69e7a9a
@@ -31,48 +31,65 @@ module Metanorma
31
31
  @refids = Set.new
32
32
  @anchors = {}
33
33
  @internal_eref_namespaces = []
34
+ @seen_headers = []
34
35
  @draft = node.attributes.has_key?("draft")
35
36
  @novalid = node.attr("novalid")
36
37
  @smartquotes = node.attr("smartquotes") != "false"
37
38
  @keepasciimath = node.attr("mn-keep-asciimath") &&
38
39
  node.attr("mn-keep-asciimath") != "false"
39
- @fontheader = default_fonts(node)
40
- @files_to_delete = []
41
- @filename = if node.attr("docfile")
42
- File.basename(node.attr("docfile"))&.gsub(/\.adoc$/, "")
43
- else ""
44
- end
45
- @localdir = Metanorma::Utils::localdir(node)
46
- @output_dir = outputdir node
47
- @no_isobib_cache = node.attr("no-isobib-cache")
48
- @no_isobib = node.attr("no-isobib")
49
40
  @index_terms = node.attr("index-terms")
50
41
  @sourcecode_markup_start = node.attr("sourcecode-markup-start") || "{{{"
51
42
  @sourcecode_markup_end = node.attr("sourcecode-markup-end") || "}}}"
52
- @bibdb = nil
53
- @seen_headers = []
54
43
  @datauriimage = node.attr("data-uri-image") != "false"
55
44
  @boilerplateauthority = node.attr("boilerplate-authority")
56
45
  @sourcecode_markup_start = node.attr("sourcecode-markup-start") || "{{{"
57
46
  @sourcecode_markup_end = node.attr("sourcecode-markup-end") || "}}}"
47
+ init_toc(node)
48
+ init_output(node)
49
+ init_i18n(node)
50
+ init_biblio(node)
51
+ @metadata_attrs = metadata_attrs(node)
52
+ end
53
+
54
+ def init_toc(node)
55
+ @htmltoclevels = node.attr("htmltoclevels")
56
+ @doctoclevels = node.attr("doctoclevels")
57
+ @toclevels = node.attr("toclevels")
58
+ @tocfigures = node.attr("toc-figures")
59
+ @toctables = node.attr("toc-tables")
60
+ @tocrecommendations = node.attr("toc-recommendations")
61
+ end
62
+
63
+ def init_output(node)
64
+ @fontheader = default_fonts(node)
58
65
  @log = Metanorma::Utils::Log.new
59
- init_bib_caches(node)
60
- init_iev_caches(node)
66
+ @files_to_delete = []
67
+ @filename = if node.attr("docfile")
68
+ File.basename(node.attr("docfile"))&.gsub(/\.adoc$/, "")
69
+ else ""
70
+ end
71
+ @localdir = Metanorma::Utils::localdir(node)
72
+ @output_dir = outputdir node
73
+ end
74
+
75
+ def init_i18n(node)
61
76
  @lang = (node.attr("language") || "en")
62
77
  @script = (node.attr("script") ||
63
78
  Metanorma::Utils.default_script(node.attr("language")))
64
79
  @isodoc = isodoc(@lang, @script, node.attr("i18nyaml"))
65
80
  @i18n = @isodoc.i18n
66
- @htmltoclevels = node.attr("htmltoclevels")
67
- @doctoclevels = node.attr("doctoclevels")
68
- @toclevels = node.attr("toclevels")
69
- @metadata_attrs = metadata_attrs(node)
81
+ end
82
+
83
+ def init_biblio(node)
84
+ @no_isobib_cache = node.attr("no-isobib-cache")
85
+ @no_isobib = node.attr("no-isobib")
86
+ @bibdb = nil
87
+ init_bib_caches(node)
88
+ init_iev_caches(node)
70
89
  end
71
90
 
72
91
  def document(node)
73
- init(node)
74
- ret = makexml(node).to_xml(encoding: "UTF-8", indent: 2)
75
- outputs(node, ret) unless node.attr("nodoc") || !node.attr("docfile")
92
+ ret = document1(node)
76
93
  clean_exit
77
94
  ret
78
95
  rescue StandardError => e
@@ -81,6 +98,28 @@ module Metanorma
81
98
  raise e
82
99
  end
83
100
 
101
+ def document1(node)
102
+ init(node)
103
+ ret = makexml(node)
104
+ .to_xml(encoding: "UTF-8", indent: 2,
105
+ save_with: Nokogiri::XML::Node::SaveOptions::AS_XML)
106
+ outputs(node, ret) unless node.attr("nodoc") || !node.attr("docfile")
107
+ ret
108
+ end
109
+
110
+ def insert_xml_cr(doc)
111
+ doc
112
+ .gsub(%r{(</(clause|table|figure|p|bibitem|ul|ol|dl|dt|dd|li|example|
113
+ sourcecode|formula|quote|references|annex|appendix|title|
114
+ name|note|thead|tbody|tfoot|th|td|form|requirement|
115
+ recommendation|permission|imagemap|svgmap|preferred|
116
+ admitted|related|deprecates|letter-symbol|domain|
117
+ graphical-symbol|expression|abbreviation-type|subject|
118
+ pronunciation|grammar|term|terms|termnote|termexample|
119
+ termsource|origin|termref|modification)>)}x, "\\1\n")
120
+ .gsub(%r{(<(title|name))}x, "\n\\1")
121
+ end
122
+
84
123
  def version
85
124
  flavour = self.class.name.sub(/::Converter$/, "").sub(/^.+::/, "")
86
125
  Metanorma.versioned(Metanorma, flavour)[-1]::VERSION
@@ -110,7 +149,7 @@ module Metanorma
110
149
 
111
150
  def makexml(node)
112
151
  result = makexml1(node)
113
- ret1 = cleanup(Nokogiri::XML(result))
152
+ ret1 = cleanup(Nokogiri::XML(insert_xml_cr(result)))
114
153
  ret1.root.add_namespace(nil, xml_namespace)
115
154
  validate(ret1) unless @novalid
116
155
  ret1
@@ -174,11 +174,11 @@ module Metanorma
174
174
  def paragraph(node)
175
175
  return termsource(node) if node.role == "source"
176
176
 
177
- noko do |xml|
177
+ ret = noko do |xml|
178
178
  xml.p **para_attrs(node) do |xml_t|
179
179
  xml_t << node.content
180
180
  end
181
- end.join("\n")
181
+ end.join
182
182
  end
183
183
 
184
184
  def quote_attrs(node)
@@ -203,7 +203,7 @@ module Metanorma
203
203
  quote_attribution(node, q)
204
204
  wrap_in_para(node, q)
205
205
  end
206
- end.join("\n")
206
+ end.join
207
207
  end
208
208
 
209
209
  def listing_attrs(node)
@@ -56,9 +56,9 @@ module Metanorma
56
56
  TERM_CLAUSE = "//sections/terms | "\
57
57
  "//sections/clause[descendant::terms]".freeze
58
58
 
59
- NORM_REF = "//bibliography/references[@normative = 'true'] | "\
60
- "//bibliography/clause[.//references[@normative = 'true']]"
61
- .freeze
59
+ NORM_REF =
60
+ "//bibliography/references[@normative = 'true'][not(@hidden)] | "\
61
+ "//bibliography/clause[.//references[@normative = 'true']]".freeze
62
62
 
63
63
  def boilerplate_isodoc(xmldoc)
64
64
  x = xmldoc.dup
@@ -16,7 +16,7 @@ module Metanorma
16
16
  insert = refs&.at("./bibitem")&.previous_element
17
17
  refs.xpath("./bibitem").each(&:remove)
18
18
  bib.reverse.each do |b|
19
- insert and insert.next = b.to_xml or
19
+ (insert and insert.next = b.to_xml) or
20
20
  refs.children.first.add_previous_sibling b.to_xml
21
21
  end
22
22
  extract_notes_from_biblio(refs)
@@ -84,9 +84,39 @@ module Metanorma
84
84
  biblio_reorder(xmldoc)
85
85
  biblio_nested(xmldoc)
86
86
  biblio_renumber(xmldoc)
87
+ biblio_linkonly(xmldoc)
88
+ biblio_hidden_inherit(xmldoc)
87
89
  biblio_no_ext(xmldoc)
88
90
  end
89
91
 
92
+ def biblio_hidden_inherit(xmldoc)
93
+ xmldoc.xpath("//references[@hidden = 'true']").each do |r|
94
+ r.xpath("./bibitem").each do |b|
95
+ b["hidden"] = true
96
+ end
97
+ end
98
+ end
99
+
100
+ def biblio_linkonly(xmldoc)
101
+ return unless xmldoc.at("//xref[@hidden]")
102
+
103
+ ins = xmldoc.at("//bibliography")
104
+ .add_child("<references hidden='true' normative='true'/>").first
105
+ refs = xmldoc.xpath("//xref[@hidden]").each_with_object([]) do |x, m|
106
+ @refids << x["target"]
107
+ m << { id: x["target"], ref: x["hidden"] }
108
+ x.delete("hidden")
109
+ end
110
+ ins << insert_hidden_bibitems(refs)
111
+ end
112
+
113
+ def insert_hidden_bibitems(bib)
114
+ refs = bib.each_with_object([]) do |b, m|
115
+ m << reference1code(%(<ref id="#{b[:id]}">[#{b[:ref]}]</ref>), nil)
116
+ end
117
+ reference_populate(refs)
118
+ end
119
+
90
120
  def biblio_no_ext(xmldoc)
91
121
  xmldoc.xpath("//bibitem/ext").each(&:remove)
92
122
  end
@@ -114,7 +144,6 @@ module Metanorma
114
144
 
115
145
  def reference_names(xmldoc)
116
146
  xmldoc.xpath("//bibitem[not(ancestor::bibitem)]").each do |ref|
117
- # isopub = ref.at(ISO_PUBLISHER_XPATH)
118
147
  docid = ref.at("./docidentifier[@type = 'metanorma']") ||
119
148
  ref.at("./docidentifier[not(@type = 'DOI')]") or next
120
149
  reference = format_ref(docid.children.to_xml, docid["type"])
@@ -15,19 +15,20 @@ module Metanorma
15
15
  end
16
16
  end
17
17
 
18
- def validate_ref_dl(bib, c)
18
+ def validate_ref_dl(bib, clause)
19
19
  id = bib["id"]
20
- id ||= c["id"] unless /^_/.match?(c["id"]) # do not accept implicit id
20
+ # do not accept implicit id
21
+ id ||= clause["id"] unless /^_/.match?(clause["id"])
21
22
  unless id
22
- @log.add("Anchors", c,
23
- "The following reference is missing an anchor:\n" + c.to_xml)
23
+ @log.add("Anchors", clause,
24
+ "The following reference is missing an anchor:\n#{clause.to_xml}")
24
25
  return
25
26
  end
26
27
  @refids << id
27
28
  bib["title"] or
28
- @log.add("Bibliography", c, "Reference #{id} is missing a title")
29
+ @log.add("Bibliography", clause, "Reference #{id} is missing a title")
29
30
  bib["docid"] or
30
- @log.add("Bibliography", c,
31
+ @log.add("Bibliography", clause,
31
32
  "Reference #{id} is missing a document identifier (docid)")
32
33
  end
33
34
 
@@ -76,27 +77,30 @@ module Metanorma
76
77
  end
77
78
 
78
79
  # definition list, with at most one level of unordered lists
79
- def dl_bib_extract(c, nested = false)
80
- dl = c.at("./dl") or return
80
+ def dl_bib_extract(clause, nested = false)
81
+ dl = clause.at("./dl") or return
81
82
  bib = {}
82
83
  key = ""
83
84
  dl.xpath("./dt | ./dd").each do |dtd|
84
85
  (dtd.name == "dt" and key = dtd.text.sub(/:+$/, "")) or
85
86
  add_to_hash(bib, key, dd_bib_extract(dtd))
86
87
  end
87
- c.xpath("./clause").each do |c1|
88
+ clause.xpath("./clause").each do |c1|
88
89
  key = c1&.at("./title")&.text&.downcase&.strip
89
90
  next unless %w(contributor relation series).include? key
90
91
 
91
92
  add_to_hash(bib, key, dl_bib_extract(c1, true))
92
93
  end
93
- if !nested && c.at("./title")
94
- title = c.at("./title").remove.children.to_xml
95
- bib["title"] = [bib["title"]] if bib["title"].is_a? Hash
96
- bib["title"] = [bib["title"]] if bib["title"].is_a? String
97
- bib["title"] = [] unless bib["title"]
98
- bib["title"] << title if !title.empty?
99
- end
94
+ dl_bib_extract_title(bib, clause, nested)
95
+ end
96
+
97
+ def dl_bib_extract_title(bib, clause, nested)
98
+ (!nested && clause.at("./title")) or return bib
99
+ title = clause.at("./title").remove.children.to_xml
100
+ bib["title"] = [bib["title"]] if bib["title"].is_a?(Hash) ||
101
+ bib["title"].is_a?(String)
102
+ bib["title"] = [] unless bib["title"]
103
+ bib["title"] << title if !title.empty?
100
104
  bib
101
105
  end
102
106
  end
@@ -54,7 +54,7 @@ module Metanorma
54
54
  end
55
55
 
56
56
  def make_bibliography(xml, sect)
57
- if xml.at("//sections/references")
57
+ if xml.at("//sections/references | //xref[@hidden]")
58
58
  biblio = sect.add_next_sibling("<bibliography/>").first
59
59
  xml.xpath("//sections/references").each do |r|
60
60
  biblio.add_child r.remove
@@ -182,10 +182,12 @@ module Metanorma
182
182
 
183
183
  def term_designation_reorder(xmldoc)
184
184
  xmldoc.xpath("//term").each do |t|
185
- %w(preferred admitted deprecates related)
185
+ des = %w(preferred admitted deprecates related)
186
186
  .each_with_object([]) do |tag, m|
187
187
  t.xpath("./#{tag}").each { |x| m << x.remove }
188
- end.reverse.each do |x|
188
+ end.reverse
189
+ t << " "
190
+ des.each do |x|
189
191
  t.children.first.previous = x
190
192
  end
191
193
  end
@@ -3,11 +3,12 @@ module Metanorma
3
3
  module Cleanup
4
4
  # extending localities to cover ISO referencing
5
5
  LOCALITY_REGEX_STR = <<~REGEXP.freeze
6
- ^((?<locality>section|clause|part|paragraph|chapter|page|
6
+ ^(((?<conn>and|or|from|to)!)?
7
+ (?<locality>section|clause|part|paragraph|chapter|page|
7
8
  table|annex|figure|example|note|formula|list|time|anchor|
8
9
  locality:[^ \\t\\n\\r:,;=]+)(\\s+|=)
9
- (?<ref>[^"][^ \\t\\n,:-]*|"[^"]+")
10
- (-(?<to>[^"][^ \\t\\n,:-]*|"[^"]"))?|
10
+ (?<ref>[^"][^ \\t\\n,:;-]*|"[^"]+")
11
+ (-(?<to>[^"][^ \\t\\n,:;-]*|"[^"]"))?|
11
12
  (?<locality2>whole|locality:[^ \\t\\n\\r:,;=]+))(?<punct>[,:;]?)\\s*
12
13
  (?<text>.*)$
13
14
  REGEXP
@@ -30,16 +31,37 @@ module Metanorma
30
31
  def extract_localities1(elem, text)
31
32
  b = elem.add_child("<localityStack/>").first if LOCALITY_RE.match text
32
33
  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>")
34
+ add_locality(b, m)
37
35
  text = m[:text]
38
36
  b = elem.add_child("<localityStack/>").first if m[:punct] == ";"
39
37
  end
38
+ fill_in_eref_connectives(elem)
40
39
  elem.add_child(text) if text
41
40
  end
42
41
 
42
+ def add_locality(stack, match)
43
+ stack.children.empty? && match[:conn] and
44
+ stack["connective"] = match[:conn]
45
+ ref =
46
+ match[:ref] ? "<referenceFrom>#{tq match[:ref]}</referenceFrom>" : ""
47
+ refto = match[:to] ? "<referenceTo>#{tq match[:to]}</referenceTo>" : ""
48
+ stack.add_child("<locality type='#{locality_label(match)}'>#{ref}"\
49
+ "#{refto}</locality>")
50
+ end
51
+
52
+ def fill_in_eref_connectives(elem)
53
+ return if elem.xpath("./localityStack").size < 2
54
+
55
+ elem.xpath("./localityStack[not(@connective)]").each do |l|
56
+ n = l.next_element
57
+ l["connective"] = if n && n.name == "localityStack" &&
58
+ n["connective"] == "to"
59
+ "from"
60
+ else "and"
61
+ end
62
+ end
63
+ end
64
+
43
65
  def locality_label(match)
44
66
  loc = match[:locality] || match[:locality2]
45
67
  /^locality:/.match?(loc) ? loc : loc&.downcase
@@ -65,8 +87,48 @@ module Metanorma
65
87
  end
66
88
 
67
89
  def xref_cleanup(xmldoc)
90
+ xref_compound_cleanup(xmldoc)
91
+ xref_cleanup1(xmldoc)
92
+ xref_compound_wrapup(xmldoc)
93
+ end
94
+
95
+ def xref_compound_cleanup(xmldoc)
96
+ xmldoc.xpath("//xref").each do |x|
97
+ /;/.match?(x["target"]) or next
98
+ locations = x["target"].split(";")
99
+ x["target"] = locations.first.sub(/^[^!]*!/, "")
100
+ xref_compound_cleanup1(x, locations)
101
+ end
102
+ end
103
+
104
+ def xref_compound_cleanup1(xref, locations)
105
+ xref.children.empty? and xref.children = "<sentinel/>"
106
+ xref_parse_compound_locations(locations).reverse.each do |y|
107
+ xref.children.first.previous =
108
+ "<xref target='#{y[1]}' connective='#{y[0]}'/>"
109
+ end
110
+ xref&.at("./sentinel")&.remove
111
+ end
112
+
113
+ def xref_parse_compound_locations(locations)
114
+ l = locations.map { |y| y.split("!", 2) }
115
+ l.map.with_index do |y, i|
116
+ if y.size == 1
117
+ y.unshift(l.dig(i + 1, 0) == "to" ? "from" : "and")
118
+ end
119
+ y
120
+ end
121
+ end
122
+
123
+ def xref_compound_wrapup(xmldoc)
124
+ xmldoc.xpath("//xref//xref").each do |x|
125
+ x.name = "location"
126
+ end
127
+ end
128
+
129
+ def xref_cleanup1(xmldoc)
68
130
  xmldoc.xpath("//xref").each do |x|
69
- /:/.match(x["target"]) and xref_to_internal_eref(x)
131
+ /:/.match?(x["target"]) and xref_to_internal_eref(x)
70
132
  next unless x.name == "xref"
71
133
 
72
134
  if refid? x["target"]
@@ -53,6 +53,7 @@ module Metanorma
53
53
  inline_macro Metanorma::Standoc::FormOptionMacro
54
54
  inline_macro Metanorma::Standoc::ToCInlineMacro
55
55
  inline_macro Metanorma::Standoc::PassInlineMacro
56
+ inline_macro Metanorma::Standoc::StdLinkInlineMacro
56
57
  inline_macro Metanorma::Plugin::Lutaml::LutamlFigureInlineMacro
57
58
  inline_macro Metanorma::Plugin::Lutaml::LutamlTableInlineMacro
58
59
  block_macro Metanorma::Plugin::Lutaml::LutamlDiagramBlockMacro
@@ -40,20 +40,29 @@ module Metanorma
40
40
  end
41
41
 
42
42
  def inline_anchor_xref_attrs(node)
43
- m = /^(?<drop>droploc%)?(?<case>capital%|lowercase%)?(?<drop2>droploc%)?
44
- (?<fn>fn:?\s*)?(?<text>.*)$/x.match node.text
43
+ m = inline_anchor_xref_match(node)
45
44
  t = node.target.gsub(/^#/, "").gsub(%r{(\.xml|\.adoc)(#.*$)}, "\\2")
46
45
  m.nil? and return { target: t, type: "inline", text: node.text }
47
- droploc = m[:drop].nil? && m[:drop2].nil? ? nil : true
48
- f = m[:fn].nil? ? "inline" : "footnote"
49
- c = if %i[case fn drop drop2].any? do |x|
50
- !m[x].nil?
51
- end
52
- m[:text]
53
- else node.text
54
- end
55
- { target: t, type: f, case: m[:case]&.sub(/%$/, ""), droploc: droploc,
56
- text: c }
46
+ { target: t, type: m[:fn].nil? ? "inline" : "footnote",
47
+ case: m[:case]&.sub(/%$/, ""),
48
+ droploc: m[:drop].nil? && m[:drop2].nil? ? nil : true,
49
+ text: inline_anchor_xref_text(m, node),
50
+ hidden: m[:hidden] }
51
+ end
52
+
53
+ def inline_anchor_xref_match(node)
54
+ /^(hidden%(?<hidden>[^,]+),?)?
55
+ (?<drop>droploc%)?(?<case>capital%|lowercase%)?(?<drop2>droploc%)?
56
+ (?<fn>fn:?\s*)?(?<text>.*)$/x.match node.text
57
+ end
58
+
59
+ def inline_anchor_xref_text(match, node)
60
+ if %i[case fn drop drop2 hidden].any? do |x|
61
+ !match[x].nil?
62
+ end
63
+ match[:text]
64
+ else node.text
65
+ end
57
66
  end
58
67
 
59
68
  def inline_anchor_link(node)
@@ -152,9 +152,7 @@
152
152
  <data type="boolean"/>
153
153
  </attribute>
154
154
  </optional>
155
- <oneOrMore>
156
- <ref name="PureTextElement"/>
157
- </oneOrMore>
155
+ <ref name="XrefBody"/>
158
156
  </element>
159
157
  </define>
160
158
  <define name="erefType">
@@ -188,6 +186,42 @@
188
186
  <ref name="PureTextElement"/>
189
187
  </oneOrMore>
190
188
  </define>
189
+ <define name="localityStack">
190
+ <element name="localityStack">
191
+ <optional>
192
+ <attribute name="connective">
193
+ <choice>
194
+ <value>and</value>
195
+ <value>or</value>
196
+ <value>from</value>
197
+ <value>to</value>
198
+ <value/>
199
+ </choice>
200
+ </attribute>
201
+ </optional>
202
+ <zeroOrMore>
203
+ <ref name="locality"/>
204
+ </zeroOrMore>
205
+ </element>
206
+ </define>
207
+ <define name="sourceLocalityStack">
208
+ <element name="sourceLocalityStack">
209
+ <optional>
210
+ <attribute name="connective">
211
+ <choice>
212
+ <value>and</value>
213
+ <value>or</value>
214
+ <value>from</value>
215
+ <value>to</value>
216
+ <value/>
217
+ </choice>
218
+ </attribute>
219
+ </optional>
220
+ <zeroOrMore>
221
+ <ref name="sourceLocality"/>
222
+ </zeroOrMore>
223
+ </element>
224
+ </define>
191
225
  <define name="ul">
192
226
  <element name="ul">
193
227
  <attribute name="id">
@@ -2641,4 +2675,30 @@
2641
2675
  </zeroOrMore>
2642
2676
  </element>
2643
2677
  </define>
2678
+ <define name="XrefBody">
2679
+ <zeroOrMore>
2680
+ <ref name="XrefTarget"/>
2681
+ </zeroOrMore>
2682
+ <oneOrMore>
2683
+ <ref name="PureTextElement"/>
2684
+ </oneOrMore>
2685
+ </define>
2686
+ <define name="XrefTarget">
2687
+ <element name="location">
2688
+ <attribute name="target">
2689
+ <data type="string">
2690
+ <param name="pattern">\i\c*|\c+#\c+</param>
2691
+ </data>
2692
+ </attribute>
2693
+ <attribute name="connective">
2694
+ <choice>
2695
+ <value>and</value>
2696
+ <value>or</value>
2697
+ <value>from</value>
2698
+ <value>to</value>
2699
+ <value/>
2700
+ </choice>
2701
+ </attribute>
2702
+ </element>
2703
+ </define>
2644
2704
  </grammar>
@@ -82,7 +82,7 @@ module Metanorma
82
82
  .match(l) && (ignore = !ignore)
83
83
  next if l.empty? || l.match(/ \+$/) || /^\[.*\]$/.match?(l) || ignore
84
84
  next if i == lines.size - 1 ||
85
- i < lines.size - 1 && lines[i + 1].empty?
85
+ (i < lines.size - 1 && lines[i + 1].empty?)
86
86
 
87
87
  lines[i] += " +"
88
88
  end
@@ -201,5 +201,17 @@ module Metanorma
201
201
  %{<passthrough formats="#{format}">#{out}</passthrough>}
202
202
  end
203
203
  end
204
+
205
+ class StdLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
206
+ use_dsl
207
+ named :"std-link"
208
+ parse_content_as :text
209
+ using_format :short
210
+
211
+ def process(parent, _target, attrs)
212
+ create_anchor(parent, "hidden%#{attrs['text']}",
213
+ type: :xref, target: "_#{UUIDTools::UUID.random_create}")
214
+ end
215
+ end
204
216
  end
205
217
  end
@@ -56,7 +56,7 @@ module Metanorma
56
56
  lines.each_with_index.with_object([]) do |(l, i), m|
57
57
  if headings.include?(l.strip)
58
58
  skip = true
59
- m.unshift while !m.empty? && /^\S/.match?(m[-1])
59
+ m.pop while !m.empty? && /^\S/.match?(m[-1])
60
60
  elsif skip && /^== |^embed::|^include::/.match?(l)
61
61
  skip = false
62
62
  j = i
@@ -214,18 +214,17 @@ module Metanorma
214
214
  end
215
215
  end
216
216
 
217
- def reference_preproc(node)
217
+ def reference(node)
218
218
  refs = node.items.each_with_object([]) do |b, m|
219
219
  m << reference1code(b.text, node)
220
220
  end
221
+ reference_populate(refs)
222
+ end
223
+
224
+ def reference_populate(refs)
221
225
  results = refs.each_with_index.with_object(Queue.new) do |(ref, i), res|
222
226
  fetch_ref_async(ref.merge(ord: i), i, res)
223
227
  end
224
- [refs, results]
225
- end
226
-
227
- def reference(node)
228
- refs, results = reference_preproc(node)
229
228
  ret = reference_queue(refs, results)
230
229
  noko do |xml|
231
230
  ret.each { |b| reference1out(b, xml) }
@@ -25,6 +25,9 @@ module Metanorma
25
25
  sectionsplit: node.attr("sectionsplit"),
26
26
  baseassetpath: node.attr("base-asset-path"),
27
27
  aligncrosselements: node.attr("align-cross-elements"),
28
+ tocfigures: @tocfigures,
29
+ toctables: @toctables,
30
+ tocrecommendations: @tocrecommendations,
28
31
  }
29
32
  end
30
33
 
@@ -61,12 +64,13 @@ module Metanorma
61
64
  bare: node.attr("bare"),
62
65
  baseassetpath: node.attr("base-asset-path"),
63
66
  aligncrosselements: node.attr("align-cross-elements"),
67
+ tocfigures: @tocfigures,
68
+ toctables: @toctables,
69
+ tocrecommendations: @tocrecommendations,
64
70
  }
65
71
 
66
72
  if fonts_manifest = node.attr(FONTS_MANIFEST)
67
- attrs[IsoDoc::XslfoPdfConvert::MN2PDF_OPTIONS] = {
68
- IsoDoc::XslfoPdfConvert::MN2PDF_FONT_MANIFEST => fonts_manifest,
69
- }
73
+ attrs[IsoDoc::XslfoPdfConvert::MN2PDF_FONT_MANIFEST] = fonts_manifest
70
74
  end
71
75
 
72
76
  attrs