metanorma-standoc 2.4.9 → 2.5.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 70483d0ae3e7369ea535a02fed125b9b073c2792cc9a589c22cd94ea98948d1e
4
- data.tar.gz: 9fb3bcbfb78079b25cbdfb6f49fdefc4df8928a8d0782878396be6a6f286374c
3
+ metadata.gz: 5ccb10f13350a471175edadd3a93a922226bf6f383faa3b4bcceff74735ff5e8
4
+ data.tar.gz: c7e6f17307599cc0ae13f88868aba8c8168c1e9a638b57a8a8c325e33cf2f0be
5
5
  SHA512:
6
- metadata.gz: f2b70e60bd3f83f8218c16bf24d9ff8a164b4a0467cf6f47e4090da745034f048a5dd91d813e0242f365eccf52ab71e2af1b477b320d1e310412c8065b02742b
7
- data.tar.gz: 2008df0fab61498838336fa8ddbf94efa3845583ed1740223a877b8ad27ccfc8d257553067f3a84226ff41ef0cc2bda91b2fd90e88a2d8be2aaf3032688bebef
6
+ metadata.gz: ae8763f5ae8953bf858720cc6ab658281299794fb24a172957d144564d1ac55432a0f08611b9ab243f9f87ebf568edd508f199442ad9c4e675775d4f40cae4aa
7
+ data.tar.gz: 4e4fcee2168ab3218355a73075c50d3f42ba6d1068839dbe2260e60a8c65a25f113d55576db49e5a436ef6757a90915cc60b59150dfa30747469d898ac6fcf6d
@@ -76,7 +76,7 @@ module Metanorma
76
76
  def stem(node)
77
77
  noko do |xml|
78
78
  xml.formula **formula_attrs(node) do |s|
79
- stem_parse(node.lines.join("\n"), s, node.style.to_sym)
79
+ stem_parse(node.lines.join("\n"), s, node.style.to_sym, node.block?)
80
80
  end
81
81
  end
82
82
  end
@@ -1,24 +1,24 @@
1
1
  require "nokogiri"
2
2
  require "pathname"
3
3
  require "html2doc"
4
- require_relative "./cleanup_block"
5
- require_relative "./cleanup_table"
6
- require_relative "./cleanup_footnotes"
7
- require_relative "./cleanup_ref"
8
- require_relative "./cleanup_asciibib"
9
- require_relative "./cleanup_boilerplate"
10
- require_relative "./cleanup_bibdata"
11
- require_relative "./cleanup_section"
12
- require_relative "./cleanup_terms"
13
- require_relative "./cleanup_symbols"
14
- require_relative "./cleanup_xref"
15
- require_relative "./cleanup_inline"
16
- require_relative "./cleanup_amend"
17
- require_relative "./cleanup_maths"
18
- require_relative "./cleanup_image"
19
- require_relative "./cleanup_reqt"
20
- require_relative "./cleanup_text"
21
- require_relative "./cleanup_toc"
4
+ require_relative "cleanup_block"
5
+ require_relative "cleanup_table"
6
+ require_relative "cleanup_footnotes"
7
+ require_relative "cleanup_ref"
8
+ require_relative "cleanup_asciibib"
9
+ require_relative "cleanup_boilerplate"
10
+ require_relative "cleanup_bibdata"
11
+ require_relative "cleanup_section"
12
+ require_relative "cleanup_terms"
13
+ require_relative "cleanup_symbols"
14
+ require_relative "cleanup_xref"
15
+ require_relative "cleanup_inline"
16
+ require_relative "cleanup_amend"
17
+ require_relative "cleanup_maths"
18
+ require_relative "cleanup_image"
19
+ require_relative "cleanup_reqt"
20
+ require_relative "cleanup_text"
21
+ require_relative "cleanup_toc"
22
22
  require "relaton_iev"
23
23
 
24
24
  module Metanorma
@@ -51,6 +51,7 @@ module Metanorma
51
51
  normref_cleanup(xmldoc)
52
52
  biblio_cleanup(xmldoc)
53
53
  reference_names(xmldoc)
54
+ asciimath_cleanup(xmldoc) # feeds: mathml_cleanup, termdef_cleanup, symbols_cleanup
54
55
  symbols_cleanup(xmldoc) # feeds: termdef_cleanup
55
56
  xref_cleanup(xmldoc) # feeds: concept_cleanup, origin_cleanup
56
57
  concept_cleanup(xmldoc) # feeds: related_cleanup, termdef_cleanup
@@ -79,6 +80,7 @@ module Metanorma
79
80
  empty_element_cleanup(xmldoc)
80
81
  img_cleanup(xmldoc)
81
82
  anchor_cleanup(xmldoc)
83
+ link_cleanup(xmldoc)
82
84
  xmldoc
83
85
  end
84
86
 
@@ -107,7 +109,7 @@ module Metanorma
107
109
  end
108
110
 
109
111
  def element_name_cleanup(xmldoc)
110
- xmldoc.traverse { |n| n.name = n.name.gsub(/_/, "-") }
112
+ xmldoc.traverse { |n| n.name = n.name.gsub("_", "-") }
111
113
  end
112
114
 
113
115
  # allows us to deal with doc relation localities,
@@ -1,5 +1,6 @@
1
1
  require "metanorma-utils"
2
2
  require "digest"
3
+ require "addressable/uri"
3
4
 
4
5
  module Metanorma
5
6
  module Standoc
@@ -78,7 +79,7 @@ module Metanorma
78
79
  def concept_cleanup1(elem)
79
80
  elem.children.remove if elem&.children&.text&.strip&.empty?
80
81
  key_extract_locality(elem)
81
- if /:/.match?(elem["key"]) then concept_termbase_cleanup(elem)
82
+ if elem["key"].include?(":") then concept_termbase_cleanup(elem)
82
83
  elsif refid? elem["key"] then concept_eref_cleanup(elem)
83
84
  else concept_xref_cleanup(elem)
84
85
  end
@@ -95,15 +96,14 @@ module Metanorma
95
96
  end
96
97
 
97
98
  def key_extract_locality(elem)
98
- return unless /,/.match?(elem["key"])
99
-
99
+ elem["key"].include?(",") or return
100
100
  elem.add_child("<locality>#{elem['key'].sub(/^[^,]+,/, '')}</locality>")
101
101
  elem["key"] = elem["key"].sub(/,.*$/, "")
102
102
  end
103
103
 
104
104
  def concept_termbase_cleanup(elem)
105
105
  t = elem&.at("./xrefrender")&.remove&.children
106
- termbase, key = elem["key"].split(/:/, 2)
106
+ termbase, key = elem["key"].split(":", 2)
107
107
  elem.add_child(%(<termref base="#{termbase}" target="#{key}">) +
108
108
  "#{t&.to_xml}</termref>")
109
109
  end
@@ -207,6 +207,21 @@ module Metanorma
207
207
  end
208
208
  end
209
209
 
210
+ def link_cleanup(xmldoc)
211
+ xmldoc.xpath("//link[@target]").each do |l|
212
+ l["target"] = Addressable::URI.parse(l["target"]).to_s
213
+ rescue Addressable::URI::InvalidURIError
214
+ err = "Malformed URI: #{l['target']}"
215
+ @log.add("Anchors", l, err)
216
+ @fatalerror << err
217
+ warn err
218
+ end
219
+ end
220
+
221
+ def uri_component_encode(comp)
222
+ CGI.escape(comp).gsub("+", "%20")
223
+ end
224
+
210
225
  private
211
226
 
212
227
  # skip ZWNJ inserted to prevent regexes operating in asciidoctor
@@ -3,17 +3,28 @@ require "asciimath2unitsml"
3
3
  module Metanorma
4
4
  module Standoc
5
5
  module Cleanup
6
- def asciimath2mathml(text)
7
- text = text.gsub(%r{<stem type="AsciiMath">(.+?)</stem>}m) do
8
- "<amathstem>#{@c.decode($1)}</amathstem>"
6
+ def asciimath_cleanup(xml)
7
+ !@keepasciimath and asciimath2mathml(xml)
8
+ end
9
+
10
+ def asciimath2mathml(xml)
11
+ xpath = xml.xpath("//stem[@type = 'AsciiMath']")
12
+ xpath.each_with_index do |x, i|
13
+ progress_conv(i, 500, xpath.size, 1000, "AsciiMath")
14
+ asciimath2mathml_indiv(x)
9
15
  end
10
- text = Html2Doc.new({})
11
- .asciimath_to_mathml(text, ["<amathstem>", "</amathstem>"],
12
- retain_asciimath: true)
13
- asciimath2mathml_wrap(text)
16
+ asciimath2mathml_wrap(xml)
17
+ end
18
+
19
+ def asciimath2mathml_indiv(elem)
20
+ elem["type"] = "MathML"
21
+ expr = @c.decode(elem.text)
22
+ ret = Plurimath::Math.parse(expr, "asciimath")
23
+ .to_mathml(display_style: elem["block"])
24
+ ret += "<asciimath>#{@c.encode(@c.decode(expr), :basic)}</asciimath>"
25
+ elem.children = ret
14
26
  rescue StandardError => e
15
- asciimath2mathml_err(text, e)
16
- text
27
+ asciimath2mathml_err(elem.to_xml, e)
17
28
  end
18
29
 
19
30
  def asciimath2mathml_err(text, expr)
@@ -23,25 +34,27 @@ module Metanorma
23
34
  warn err
24
35
  end
25
36
 
26
- def asciimath2mathml_wrap(text)
27
- x = Nokogiri::XML(text)
28
- x.xpath("//*[local-name() = 'math'][@display]").each do |y|
37
+ def asciimath2mathml_wrap(xml)
38
+ xml.xpath("//*[local-name() = 'math'][@display]").each do |y|
29
39
  y.delete("display")
30
40
  end
31
- x.xpath("//*[local-name() = 'math'][not(parent::stem)]").each do |y|
32
- y.wrap("<stem type='MathML'></stem>")
33
- end
34
- x.xpath("//stem").each do |y|
35
- y.next_element&.name == "asciimath" and y << y.next_element
36
- end
37
- to_xml(x)
41
+ # x.xpath("//stem").each do |y|
42
+ # y.next_element&.name == "asciimath" and y << y.next_element
43
+ # end
44
+ xml
45
+ end
46
+
47
+ def progress_conv(idx, step, total, threshold, msg)
48
+ return unless (idx % step).zero? && total > threshold && idx.positive?
49
+
50
+ warn "#{msg} #{idx} of #{total}"
38
51
  end
39
52
 
40
53
  def xml_unescape_mathml(xml)
41
54
  return if xml.children.any?(&:element?)
42
55
 
43
- math = xml.text.gsub(/&lt;/, "<").gsub(/&gt;/, ">")
44
- .gsub(/&quot;/, '"').gsub(/&apos;/, "'").gsub(/&amp;/, "&")
56
+ math = xml.text.gsub("&lt;", "<").gsub("&gt;", ">")
57
+ .gsub("&quot;", '"').gsub("&apos;", "'").gsub("&amp;", "&")
45
58
  .gsub(/<[^: \r\n\t\/]+:/, "<").gsub(/<\/[^ \r\n\t:]+:/, "</")
46
59
  xml.children = math
47
60
  end
@@ -1,3 +1,5 @@
1
+ require "metanorma/standoc/utils"
2
+
1
3
  module Metanorma
2
4
  module Standoc
3
5
  module Cleanup
@@ -8,31 +10,12 @@ module Metanorma
8
10
  def symbol_key(sym)
9
11
  @c.decode(asciimath_key(sym).text)
10
12
  .gsub(/[\[\]{}<>()]/, "").gsub(/\s/m, "")
11
- .gsub(/[[:punct:]]|[_^]/, ":\\0").gsub(/`/, "")
13
+ .gsub(/[[:punct:]]|[_^]/, ":\\0").gsub("`", "")
12
14
  .gsub(/[0-9]+/, "þ\\0")
13
15
  .tr("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz",
14
16
  "ABCFEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
15
17
  end
16
18
 
17
- def asciimath_key(sym)
18
- key = sym.dup
19
- key.traverse do |n|
20
- if n.name == "stem" && a = n.at(".//asciimath")
21
- n.children = @c.encode(
22
- @c.decode(grkletters(a.text)), :basic
23
- )
24
- end
25
- end
26
- key.xpath(".//asciimath").each(&:remove)
27
- Nokogiri::XML(key.to_xml)
28
- end
29
-
30
- def grkletters(text)
31
- text.gsub(/\b(alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|
32
- lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|
33
- psi|omega)\b/xi, "&\\1;")
34
- end
35
-
36
19
  def extract_symbols_list(dlist)
37
20
  dl_out = []
38
21
  dlist.xpath("./dt | ./dd").each do |dtd|
@@ -3,7 +3,6 @@ module Metanorma
3
3
  module Cleanup
4
4
  def textcleanup(result)
5
5
  text = result.flatten.map { |l| l.sub(/\s*\Z/, "") } * "\n"
6
- !@keepasciimath and text = asciimath2mathml(text)
7
6
  text = text.gsub(/\s+<fn /, "<fn ")
8
7
  %w(passthrough passthrough-inline).each do |v|
9
8
  text.gsub!(%r{<#{v}\s+formats="metanorma">([^<]*)
@@ -12,7 +12,7 @@ require_relative "validate"
12
12
  require_relative "utils"
13
13
  require_relative "cleanup"
14
14
  require_relative "reqt"
15
- require_relative "./macros"
15
+ require_relative "macros"
16
16
 
17
17
  module Metanorma
18
18
  module Standoc
@@ -22,6 +22,7 @@ module Metanorma
22
22
  Asciidoctor::Extensions.register do
23
23
  preprocessor Metanorma::Standoc::EmbedIncludeProcessor
24
24
  preprocessor Metanorma::Standoc::NamedEscapePreprocessor
25
+ preprocessor Metanorma::Standoc::LinkProtectPreprocessor
25
26
  preprocessor Metanorma::Standoc::Datamodel::AttributesTablePreprocessor
26
27
  preprocessor Metanorma::Standoc::Datamodel::DiagramPreprocessor
27
28
  preprocessor Metanorma::Plugin::Datastruct::Json2TextPreprocessor
@@ -138,9 +138,10 @@ module Metanorma
138
138
  noko { |xml| xml.hr }.join
139
139
  end
140
140
 
141
- def latex_parse1(text)
141
+ def latex_parse1(text, block)
142
142
  lxm_input = Unicode2LaTeX.unicode2latex(@c.decode(text))
143
- results = Plurimath::Math.parse(lxm_input, "latex").to_mathml
143
+ results = Plurimath::Math.parse(lxm_input, "latex")
144
+ .to_mathml(display_style: block)
144
145
  if results.nil?
145
146
  @log.add("Math", nil,
146
147
  "latexmlmath failed to process equation:\n#{lxm_input}")
@@ -149,22 +150,23 @@ module Metanorma
149
150
  results.sub(%r{<math ([^>]+ )?display="block"}, "<math \\1")
150
151
  end
151
152
 
152
- def stem_parse(text, xml, style)
153
+ def stem_parse(text, xml, style, block)
153
154
  if /&lt;([^:>&]+:)?math(\s+[^>&]+)?&gt; |
154
155
  <([^:>&]+:)?math(\s+[^>&]+)?>/x.match? text
155
156
  math = xml_encode(text)
156
- xml.stem type: "MathML" do |s|
157
+ xml.stem type: "MathML", block: block do |s|
157
158
  s << math
158
159
  end
159
- elsif style == :latexmath then latex_parse(text, xml)
160
+ elsif style == :latexmath then latex_parse(text, xml, block)
160
161
  else
161
- xml.stem text&.gsub(/&amp;#/, "&#"), type: "AsciiMath"
162
+ xml.stem text&.gsub("&amp;#", "&#"), type: "AsciiMath", block: block
162
163
  end
163
164
  end
164
165
 
165
- def latex_parse(text, xml)
166
- latex = latex_parse1(text) or return xml.stem type: "MathML"
167
- xml.stem type: "MathML" do |s|
166
+ def latex_parse(text, xml, block)
167
+ latex = latex_parse1(text, block) or
168
+ return xml.stem type: "MathML", block: block
169
+ xml.stem type: "MathML", block: block do |s|
168
170
  math = Nokogiri::XML.fragment(latex.sub(/<\?[^>]+>/, ""))
169
171
  .elements[0]
170
172
  math.delete("alttext")
@@ -187,8 +189,8 @@ module Metanorma
187
189
  when :single then xml << "'#{node.text}'"
188
190
  when :superscript then xml.sup { |s| s << node.text }
189
191
  when :subscript then xml.sub { |s| s << node.text }
190
- when :asciimath then stem_parse(node.text, xml, :asciimath)
191
- when :latexmath then stem_parse(node.text, xml, :latexmath)
192
+ when :asciimath then stem_parse(node.text, xml, :asciimath, false)
193
+ when :latexmath then stem_parse(node.text, xml, :latexmath, false)
192
194
  when :mark then highlight_parse(node.text, xml)
193
195
  else
194
196
  case node.role
@@ -17,7 +17,7 @@
17
17
  these elements; we just want one namespace for any child grammars
18
18
  of this.
19
19
  -->
20
- <!-- VERSION v1.2.2 -->
20
+ <!-- VERSION v1.2.3 -->
21
21
  <grammar xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
22
22
  <include href="reqt.rng"/>
23
23
  <include href="basicdoc.rng">
@@ -192,9 +192,11 @@
192
192
  </attribute>
193
193
  </optional>
194
194
  <attribute name="citeas"/>
195
- <attribute name="type">
196
- <ref name="ReferenceFormat"/>
197
- </attribute>
195
+ <optional>
196
+ <attribute name="type">
197
+ <ref name="ReferenceFormat"/>
198
+ </attribute>
199
+ </optional>
198
200
  <optional>
199
201
  <attribute name="alt"/>
200
202
  </optional>
@@ -836,6 +838,26 @@
836
838
  <ref name="paragraph"/>
837
839
  </element>
838
840
  </define>
841
+ <define name="stem">
842
+ <element name="stem">
843
+ <attribute name="type">
844
+ <choice>
845
+ <value>MathML</value>
846
+ <value>AsciiMath</value>
847
+ <value>LatexMath</value>
848
+ </choice>
849
+ </attribute>
850
+ <attribute name="block">
851
+ <data type="boolean"/>
852
+ </attribute>
853
+ <oneOrMore>
854
+ <choice>
855
+ <text/>
856
+ <ref name="AnyElement"/>
857
+ </choice>
858
+ </oneOrMore>
859
+ </element>
860
+ </define>
839
861
  <define name="em">
840
862
  <element name="em">
841
863
  <zeroOrMore>
@@ -1,14 +1,14 @@
1
1
  require "uuidtools"
2
2
  require "yaml"
3
3
  require "csv"
4
- require_relative "./macros_inline"
5
- require_relative "./macros_plantuml"
6
- require_relative "./macros_terms"
7
- require_relative "./macros_form"
8
- require_relative "./macros_note"
9
- require_relative "./macros_embed"
10
- require_relative "./datamodel/attributes_table_preprocessor"
11
- require_relative "./datamodel/diagram_preprocessor"
4
+ require_relative "macros_inline"
5
+ require_relative "macros_plantuml"
6
+ require_relative "macros_terms"
7
+ require_relative "macros_form"
8
+ require_relative "macros_note"
9
+ require_relative "macros_embed"
10
+ require_relative "datamodel/attributes_table_preprocessor"
11
+ require_relative "datamodel/diagram_preprocessor"
12
12
  require "metanorma-plugin-datastruct"
13
13
  require "metanorma-plugin-glossarist"
14
14
  require "metanorma-plugin-lutaml"
@@ -22,7 +22,7 @@ module Metanorma
22
22
 
23
23
  def init_indent(line)
24
24
  /^(?<prefix>[ \t]*)(?<suffix>.*)$/ =~ line
25
- prefix = prefix.gsub(/\t/, "\u00a0\u00a0\u00a0\u00a0")
25
+ prefix = prefix.gsub("\t", "\u00a0\u00a0\u00a0\u00a0")
26
26
  .gsub(/ /, "\u00a0")
27
27
  prefix + suffix
28
28
  end
@@ -31,9 +31,9 @@ module Metanorma
31
31
  ignore = false
32
32
  lines.each_with_index do |l, i|
33
33
  /^(--+|====+|\|===|\.\.\.\.+|\*\*\*\*+|\+\+\+\++|````+|____\+)$/
34
- .match(l) && (ignore = !ignore)
35
- next if l.empty? || l.match(/ \+$/) || /^\[.*\]$/.match?(l) || ignore
36
- next if i == lines.size - 1 ||
34
+ .match(l) and (ignore = !ignore)
35
+ next if l.empty? || l.match(/ \+$/) || /^\[.*\]$/.match?(l) ||
36
+ ignore || i == lines.size - 1 ||
37
37
  (i < lines.size - 1 && lines[i + 1].empty?)
38
38
 
39
39
  lines[i] += " +"
@@ -60,5 +60,111 @@ module Metanorma
60
60
  ::Asciidoctor::Reader.new lines
61
61
  end
62
62
  end
63
+
64
+ # refer https://github.com/asciidoctor/asciidoctor/blob/main/lib/asciidoctor/substitutors.rb
65
+ # Not using TreeProcessor because that is still too close to
66
+ # inline expressions being processed on access (e.g. titles)
67
+ class LinkProtectPreprocessor < Asciidoctor::Extensions::Preprocessor
68
+ def init
69
+ pass = true # process as passthrough: init = true until
70
+ # hit end of doc header
71
+ is_delim = false # current line is a no-substititon block delimiter
72
+ pass_delim = false # current line is a passthrough delimiter
73
+ delimln = "" # delimiter line of current block(s);
74
+ # init value looks for end of doc header
75
+ { pass: pass, is_delim: is_delim, pass_delim: pass_delim,
76
+ delimln: delimln }
77
+ end
78
+
79
+ def process(_document, reader)
80
+ p = init
81
+ lines = reader.readlines.map do |t|
82
+ p = pass_status(p, t.rstrip)
83
+ !p[:pass] && t.include?(":") and t = inlinelinkmacro(inlinelink(t))
84
+ t
85
+ end
86
+ ::Asciidoctor::Reader.new lines
87
+ end
88
+
89
+ def pass_status(status, text)
90
+ text == "++++" && !status[:delimln] and status[:pass] = !status[:pass]
91
+ if status[:is_delim] && /^(-+|\*+|=+|_+)$/.match?(text)
92
+ status[:delimln] = text
93
+ status[:pass] = true
94
+ elsif status[:pass_delim]
95
+ status[:delimln] = "" # end of paragraph for paragraph with [pass]
96
+ elsif status[:delimln] && text == status[:delimln]
97
+ status[:pass] = false
98
+ status[:delimln] = nil
99
+ end
100
+ status[:is_delim] = /^\[(source|listing|literal|pass)\b/.match?(text)
101
+ status[:pass_delim] = /^\[(pass)\b/.match?(text)
102
+ status
103
+ end
104
+
105
+ PASS_INLINE_MACROS = %w(pass pass-format identifier std-link stem)
106
+ .join("|").freeze
107
+
108
+ PASS_INLINE_MACRO_STR = <<~REGEX.freeze
109
+ (
110
+ \\b(?<!-) # word-separator, no hyphen
111
+ (?: # don't capture these!
112
+ (?:#{PASS_INLINE_MACROS}):[^\\s\\[]* | # macro name, :, second key. OR:
113
+ span:uri \\b [^\\s\\[]* # span:uri, third key
114
+ )
115
+ \\[.*?(?<!\\\\)\\] # [ ... ] not preceded by \\
116
+ )
117
+ REGEX
118
+ PASS_INLINE_MACRO_RX = /#{PASS_INLINE_MACRO_STR}/xo.freeze
119
+
120
+ def pass_inline_split(text)
121
+ text.split(PASS_INLINE_MACRO_RX).each.map do |x|
122
+ PASS_INLINE_MACRO_RX.match?(x) ? x : yield(x)
123
+ end
124
+ end
125
+
126
+ # InlineLinkRx = %r((^|link:|#{CG_BLANK}|&lt;|[>\(\)\[\];"'])(\\?(?:https?|file|ftp|irc)://)(?:([^\s\[\]]+)\[(|#{CC_ALL}*?[^\\])\]|([^\s\[\]<]*([^\s,.?!\[\]<\)]))))m
127
+ #
128
+ InlineLinkRx = %r((^|(?<!-)\blink:(?!\+)|\p{Blank}|&lt;|[<>\(\)\[\];"'])(\\?(?:https?|file|ftp|irc)://)(?:([^\s\[\]]+)(?:(\[(|.*?[^\\])\])|([^\s\[\]<]*([^\s,.?!\[\]<\)])))))m.freeze
129
+
130
+ def inlinelink(text)
131
+ text.include?("://") or return text
132
+ pass_inline_split(text) do |x|
133
+ inlinelink_escape(x)
134
+ end.join
135
+ end
136
+
137
+ def inlinelink_escape(text)
138
+ text.gsub(InlineLinkRx) do
139
+ body, suffix = $4.nil? ? [$3 + $6, "[]"] : [$3, ""]
140
+ p = $1 and s = $2 and b = $4
141
+ if p == "link:" then "#{p}++#{s}#{body}++#{b}#{suffix}"
142
+ elsif p == "<"
143
+ "#{p}link:++#{s}#{body.sub(/>$/, '')}++#{b}#{suffix}>"
144
+ else "#{p}link:++#{s}#{body}++#{b}#{suffix}"
145
+ end
146
+ end
147
+ end
148
+
149
+ # InlineLinkMacroRx = /\\?(?:link|(mailto)):(|[^:\s\[][^\s\[]*)\[(|#{CC_ALL}*?[^\\])\]/m
150
+ InlineLinkMacroRx1 = <<~REGEX.freeze
151
+ (\\\\?\\b(?<!-) # optional backslash, no hyphen, word boundary
152
+ (?:link|mailto):) # link: or mailto:
153
+ (?!\\+) # no link:+ passthrough
154
+ (|[^:\\s\\[][^\\s\\[]*) # link: ... up to [
155
+ (\\[(|.*?[^\\\\])\\]) # [ ... ], no ]
156
+ REGEX
157
+ InlineLinkMacroRx = /#{InlineLinkMacroRx1}/x.freeze
158
+
159
+ def inlinelinkmacro(text)
160
+ (text.include?("[") &&
161
+ ((text.include? "link:") || (text.include? "ilto:"))) or return text
162
+ pass_inline_split(text) do |x|
163
+ x.gsub(InlineLinkMacroRx) do
164
+ "#{$1}++#{$2}++#{$3}"
165
+ end
166
+ end.join
167
+ end
168
+ end
63
169
  end
64
170
  end
@@ -44,7 +44,7 @@ module Metanorma
44
44
  text = attr["text"]
45
45
  text = "((#{text}))" unless /^\(\(.+\)\)$/.match?(text)
46
46
  out = parent.sub_macros(text)
47
- out.sub(/<index>/, "<index to='#{target}'>")
47
+ out.sub("<index>", "<index to='#{target}'>")
48
48
  end
49
49
  end
50
50
 
@@ -148,7 +148,7 @@ module Metanorma
148
148
  content = CSV.parse_line(out).map do |x|
149
149
  x.sub!(/^(["'])(.+)\1/, "\\2")
150
150
  m = /^(.*?)(:\d+)?$/.match(x)
151
- %{<toc-xpath depth='#{m[2]&.sub(/:/, '') || 1}'>#{m[1]}</toc-xpath>}
151
+ %{<toc-xpath depth='#{m[2]&.sub(':', '') || 1}'>#{m[1]}</toc-xpath>}
152
152
  end.join
153
153
  "<toc>#{content}</toc>"
154
154
  end
@@ -49,7 +49,8 @@ module Metanorma
49
49
  def concept_cleanup
50
50
  xmldoc.xpath("//concept").each do |n|
51
51
  refterm = n.at("./refterm") or next
52
- p = @termlookup[:secondary2primary][@c.encode(refterm.text)] and
52
+ lookup = normalize_ref_id_text(refterm.text.strip)
53
+ p = @termlookup[:secondary2primary][lookup] and
53
54
  refterm.children = @c.encode(p)
54
55
  end
55
56
  end
@@ -61,7 +62,7 @@ module Metanorma
61
62
  def related_cleanup
62
63
  xmldoc.xpath("//related").each do |n|
63
64
  refterm = n.at("./refterm") or next
64
- lookup = @c.encode(refterm.text)
65
+ lookup = normalize_ref_id_text(refterm.text.strip)
65
66
  p = @termlookup[:secondary2primary][lookup] and
66
67
  refterm.children = @c.encode(p)
67
68
  p || @termlookup[:term][lookup] and
@@ -133,7 +134,7 @@ module Metanorma
133
134
  end
134
135
 
135
136
  def remove_missing_ref_msg1(_node, target, ret)
136
- target2 = "_#{target.downcase.gsub(/-/, '_')}"
137
+ target2 = "_#{target.downcase.gsub('-', '_')}"
137
138
  if @terms_tags[target] || @terms_tags[target2]
138
139
  ret.strip!
139
140
  ret += ". Did you mean to point to a subterm?"
@@ -185,17 +186,20 @@ module Metanorma
185
186
 
186
187
  def pref_secondary2primary_preferred(term, res, primary)
187
188
  term.xpath("./preferred//name").each_with_index do |p, i|
188
- i.positive? and res[domain_prefix(term, p.text)] = primary
189
- @unique_designs[p.text] && term.at(".//domain") and
190
- res[p.text] = primary
189
+ t = p.text.strip
190
+ i.positive? and
191
+ res[normalize_ref_id_text(domain_prefix(term, t))] = primary
192
+ @unique_designs[t] && term.at(".//domain") and
193
+ res[normalize_ref_id_text(t)] = primary
191
194
  end
192
195
  end
193
196
 
194
197
  def pref_secondary2primary_admitted(term, res, primary)
195
198
  term.xpath("./admitted//name").each do |p|
196
- res[domain_prefix(term, p.text)] = primary
197
- @unique_designs[p.text] && term.at(".//domain") and
198
- res[p.text] = primary
199
+ t = p.text.strip
200
+ res[normalize_ref_id_text(domain_prefix(term, t))] = primary
201
+ @unique_designs[t] && term.at(".//domain") and
202
+ res[normalize_ref_id_text(t)] = primary
199
203
  end
200
204
  end
201
205
 
@@ -234,9 +238,13 @@ module Metanorma
234
238
  def normalize_ref_id1(term, node = nil)
235
239
  t = term.dup
236
240
  t.xpath(".//index").map(&:remove)
237
- ret = t.text.strip
241
+ ret = asciimath_key(t).text.strip
238
242
  node and ret = domain_prefix(node, ret)
239
- Metanorma::Utils::to_ncname(ret.gsub(/[[:space:]]+/, "-"))
243
+ normalize_ref_id_text(ret)
244
+ end
245
+
246
+ def normalize_ref_id_text(text)
247
+ Metanorma::Utils::to_ncname(text.gsub(/[[:space:]]+/, "-"))
240
248
  end
241
249
 
242
250
  def unique_text_id(text, prefix)
@@ -248,6 +256,8 @@ module Metanorma
248
256
  end
249
257
  end
250
258
  end
259
+
260
+ include ::Metanorma::Standoc::Utils
251
261
  end
252
262
  end
253
263
  end
@@ -70,10 +70,10 @@ module Metanorma
70
70
 
71
71
  def xml_encode(text)
72
72
  @c.encode(text, :basic, :hexadecimal)
73
- .gsub(/&amp;gt;/, ">").gsub(/&amp;lt;/, "<").gsub(/&amp;amp;/, "&")
74
- .gsub(/&gt;/, ">").gsub(/&lt;/, "<").gsub(/&amp;/, "&")
75
- .gsub(/&quot;/, '"').gsub(/&#xa;/, "\n").gsub(/&amp;#/, "&#")
76
- .gsub(/&apos;/, "'")
73
+ .gsub("&amp;gt;", ">").gsub("&amp;lt;", "<").gsub("&amp;amp;", "&")
74
+ .gsub("&gt;", ">").gsub("&lt;", "<").gsub("&amp;", "&")
75
+ .gsub("&quot;", '"').gsub("&#xa;", "\n").gsub("&amp;#", "&#")
76
+ .gsub("&apos;", "'")
77
77
  end
78
78
 
79
79
  # wrapped in <sections>
@@ -85,6 +85,25 @@ module Metanorma
85
85
  Nokogiri::XML(c).at("//xmlns:sections")
86
86
  end
87
87
 
88
+ def asciimath_key(sym)
89
+ key = sym.dup
90
+ key.traverse do |n|
91
+ if n.name == "stem" && a = n.at(".//asciimath")
92
+ n.children = @c.encode(
93
+ @c.decode(grkletters(a.text)), :basic
94
+ )
95
+ end
96
+ end
97
+ key.xpath(".//asciimath").each(&:remove)
98
+ Nokogiri::XML(key.to_xml)
99
+ end
100
+
101
+ def grkletters(text)
102
+ text.gsub(/\b(alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|
103
+ lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|
104
+ psi|omega)\b/xi, "&\\1;")
105
+ end
106
+
88
107
  module_function :adoc2xml
89
108
 
90
109
  class EmptyAttr
@@ -1,7 +1,7 @@
1
1
  require "metanorma/standoc/utils"
2
- require_relative "./validate_section"
3
- require_relative "./validate_table"
4
- require_relative "./validate_term"
2
+ require_relative "validate_section"
3
+ require_relative "validate_table"
4
+ require_relative "validate_term"
5
5
  require "nokogiri"
6
6
  require "jing"
7
7
  require "iev"
@@ -19,6 +19,6 @@ module Metanorma
19
19
  end
20
20
 
21
21
  module Standoc
22
- VERSION = "2.4.9".freeze
22
+ VERSION = "2.5.1".freeze
23
23
  end
24
24
  end
@@ -28,10 +28,11 @@ Gem::Specification.new do |spec|
28
28
  end
29
29
  spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
30
30
 
31
+ spec.add_dependency "addressable", "~> 2.8.0"
31
32
  spec.add_dependency "asciidoctor", "~> 2.0.0"
32
33
  spec.add_dependency "iev", "~> 0.3.0"
33
- spec.add_dependency "isodoc", "~> 2.5.4"
34
- spec.add_dependency "metanorma", ">= 1.5.0"
34
+ spec.add_dependency "isodoc", "~> 2.6.0"
35
+ spec.add_dependency "metanorma", ">= 1.6.0"
35
36
  spec.add_dependency "metanorma-plugin-datastruct", "~> 0.2.0"
36
37
  spec.add_dependency "metanorma-plugin-glossarist", "~> 0.1.1"
37
38
  spec.add_dependency "metanorma-plugin-lutaml"
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma-standoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.9
4
+ version: 2.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-24 00:00:00.000000000 Z
11
+ date: 2023-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: addressable
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.8.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.8.0
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: asciidoctor
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,28 +58,28 @@ dependencies:
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: 2.5.4
61
+ version: 2.6.0
48
62
  type: :runtime
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: 2.5.4
68
+ version: 2.6.0
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: metanorma
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - ">="
60
74
  - !ruby/object:Gem::Version
61
- version: 1.5.0
75
+ version: 1.6.0
62
76
  type: :runtime
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - ">="
67
81
  - !ruby/object:Gem::Version
68
- version: 1.5.0
82
+ version: 1.6.0
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: metanorma-plugin-datastruct
71
85
  requirement: !ruby/object:Gem::Requirement