metanorma-standoc 1.8.1 → 1.8.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 28995a48904029f160e1da3411c440ac27e3b4f84405e8fc1f8680214bc79c42
4
- data.tar.gz: bfce935749b5da318ebfe12c458210db5bc884ce7fa37126de4c3eff0e22e9d4
3
+ metadata.gz: 90c09f71739f8d485363ce3a4f950b143c0264f5b4657fd0891df83a00c44f72
4
+ data.tar.gz: cb0c51236e8c1780aa2a89b7a0c53efeabc2a4af3ef68e6c08aa8936efdea47d
5
5
  SHA512:
6
- metadata.gz: b3839c128f0b278364e7a91f64529cbe2709c504e52aa82c31d284986b45f8ffc8a55a8c2871a7eee481bdbe8c5bdedb58c7b459b3a5aab0d64d7baf7d46f859
7
- data.tar.gz: d26bfe3ca6146c2d6d7bf68d3a1112a8afde89f88a9713dbafb40a304f002b76d6e225d5fda3dd71eaa2f6c603cd4a362d1735cc4e83e822f0545efb86665adf
6
+ metadata.gz: 96533136bca911c4f886e6d0aeaa0e86ce94cf754d721af5537c835b744980fef11555e494d5d485a348c1ea911d1394cfb215f9f02cbf095a90bd652cae2916
7
+ data.tar.gz: 80bd100da6d8d05fdc69f8f52d20e9af182bd3196c42074663241dc8e35bee952eb8bf7ef95fbf444dbcd25f1bd45ac7d864f70c394df372f8d24b1e26a385d7
@@ -104,12 +104,14 @@ module Asciidoctor
104
104
  @output_dir = outputdir node
105
105
  @no_isobib_cache = node.attr("no-isobib-cache")
106
106
  @no_isobib = node.attr("no-isobib")
107
+ @sourcecode_markup_start = node.attr("sourcecode-markup-start") || "{{{"
108
+ @sourcecode_markup_end = node.attr("sourcecode-markup-end") || "}}}"
107
109
  @bibdb = nil
108
110
  @seen_headers = []
109
111
  @datauriimage = node.attr("data-uri-image")
110
112
  @boilerplateauthority = node.attr("boilerplate-authority")
111
113
  @sourcecode_markup_start = node.attr("sourcecode-markup-start") || "{{{"
112
- @sourcecode_markup_end = node.attr("sourcecode-markup-start") || "}}}"
114
+ @sourcecode_markup_end = node.attr("sourcecode-markup-end") || "}}}"
113
115
  @log = Metanorma::Utils::Log.new
114
116
  init_bib_caches(node)
115
117
  init_iev_caches(node)
@@ -11,6 +11,7 @@ require_relative "./cleanup_section.rb"
11
11
  require_relative "./cleanup_terms.rb"
12
12
  require_relative "./cleanup_inline.rb"
13
13
  require_relative "./cleanup_amend.rb"
14
+ require_relative "./cleanup_maths.rb"
14
15
  require "relaton_iev"
15
16
 
16
17
  module Asciidoctor
@@ -24,25 +25,15 @@ module Asciidoctor
24
25
  </passthrough>}mx) { |m| HTMLEntities.new.decode($1) }
25
26
  end
26
27
 
27
- def asciimath2mathml(text)
28
- text = text.gsub(%r{<stem type="AsciiMath">(.+?)</stem>}m) do |m|
29
- "<amathstem>#{HTMLEntities.new.decode($1)}</amathstem>"
30
- end
31
- text = Html2Doc.asciimath_to_mathml(text, ["<amathstem>", "</amathstem>"])
32
- x = Nokogiri::XML(text)
33
- x.xpath("//*[local-name() = 'math'][not(parent::stem)]").each do |y|
34
- y.wrap("<stem type='MathML'></stem>")
35
- end
36
- x.to_xml
37
- end
38
-
39
28
  def cleanup(xmldoc)
40
29
  element_name_cleanup(xmldoc)
41
30
  sections_cleanup(xmldoc)
42
31
  obligations_cleanup(xmldoc)
43
32
  table_cleanup(xmldoc)
44
33
  formula_cleanup(xmldoc)
34
+ sourcecode_cleanup(xmldoc)
45
35
  figure_cleanup(xmldoc)
36
+ element_name_cleanup(xmldoc)
46
37
  ref_cleanup(xmldoc)
47
38
  note_cleanup(xmldoc)
48
39
  clausebefore_cleanup(xmldoc)
@@ -83,8 +74,7 @@ module Asciidoctor
83
74
  next unless n.text?
84
75
  if @smartquotes
85
76
  /[-'"(<>]|\.\.|\dx/.match(n) or next
86
- n.ancestors("pre, tt, sourcecode, bibdata, on, "\
87
- "stem, figure[@class = 'pseudocode']").empty? or next
77
+ n.ancestors("pre, tt, sourcecode, bibdata, on, stem, figure[@class = 'pseudocode']").empty? or next
88
78
  n.replace(Metanorma::Utils::smartformat(n.text))
89
79
  else
90
80
  n.replace(n.text.gsub(/(?<=\p{Alnum})\u2019(?=\p{Alpha})/, "'"))#.
@@ -148,59 +138,26 @@ module Asciidoctor
148
138
  align_callouts_to_annotations(xmldoc)
149
139
  end
150
140
 
151
- def xml_unescape_mathml(x)
152
- return if x.children.any? { |y| y.element? }
153
- math = x.text.gsub(/&lt;/, "<").gsub(/&gt;/, ">").gsub(/&quot;/, '"').
154
- gsub(/&apos;/, "'").gsub(/&amp;/, "&").
155
- gsub(/<[^: \r\n\t\/]+:/, "<").gsub(/<\/[^ \r\n\t:]+:/, "</")
156
- x.children = math
157
- end
158
-
159
- MATHML_NS = "http://www.w3.org/1998/Math/MathML".freeze
160
-
161
- def mathml_preserve_space(m)
162
- m.xpath(".//m:mtext", "m" => MATHML_NS).each do |x|
163
- x.children = x.children.to_xml.gsub(/^\s/, "&#xA0;").gsub(/\s$/, "&#xA0;")
164
- end
165
- end
166
-
167
- def mathml_namespace(stem)
168
- stem.xpath("./math", ).each { |x| x.default_namespace = MATHML_NS }
169
- end
170
-
171
- def mathml_mi_italics
172
- { uppergreek: true, upperroman: true,
173
- lowergreek: true, lowerroman: true }
174
- end
175
-
176
- # presuppose multichar mi upright, singlechar mi MathML default italic
177
- def mathml_italicise(x)
178
- x.xpath(".//m:mi[not(ancestor::*[@mathvariant])]", "m" => MATHML_NS).each do |i|
179
- char = HTMLEntities.new.decode(i.text)
180
- i["mathvariant"] = "normal" if mi_italicise?(char)
181
- end
182
- end
183
-
184
- def mi_italicise?(c)
185
- return false if c.length > 1
186
- if /\p{Greek}/.match(c)
187
- /\p{Lower}/.match(c) && !mathml_mi_italics[:lowergreek] ||
188
- /\p{Upper}/.match(c) && !mathml_mi_italics[:uppergreek]
189
- elsif /\p{Latin}/.match(c)
190
- /\p{Lower}/.match(c) && !mathml_mi_italics[:lowerroman] ||
191
- /\p{Upper}/.match(c) && !mathml_mi_italics[:upperroman]
192
- else
193
- false
141
+ def sourcecode_cleanup(xmldoc)
142
+ xmldoc.xpath("//sourcecode").each do |x|
143
+ x.traverse do |n|
144
+ next unless n.text?
145
+ next unless /#{Regexp.escape(@sourcecode_markup_start)}/.match(n.text)
146
+ n.replace(sourcecode_markup(n))
147
+ end
194
148
  end
195
149
  end
196
150
 
197
- def mathml_cleanup(xmldoc)
198
- xmldoc.xpath("//stem[@type = 'MathML']").each do |x|
199
- xml_unescape_mathml(x)
200
- mathml_namespace(x)
201
- mathml_preserve_space(x)
202
- mathml_italicise(x)
151
+ def sourcecode_markup(n)
152
+ acc = []
153
+ n.text.split(/(#{Regexp.escape(@sourcecode_markup_start)}|#{Regexp.escape(@sourcecode_markup_end)})/).
154
+ each_slice(4).map do |a|
155
+ acc << Nokogiri::XML::Text.new(a[0], n.document).
156
+ to_xml(encoding: "US-ASCII", save_with: Nokogiri::XML::Node::SaveOptions::NO_DECLARATION)
157
+ next unless a.size == 4
158
+ acc << Asciidoctor.convert(a[2], backend: (self&.backend&.to_sym || :standoc), doctype: :inline)
203
159
  end
160
+ acc.join
204
161
  end
205
162
 
206
163
  # allows us to deal with doc relation localities,
@@ -214,23 +171,18 @@ module Asciidoctor
214
171
 
215
172
  def img_cleanup(xmldoc)
216
173
  return xmldoc unless @datauriimage
217
- xmldoc.xpath("//image").each do |i|
218
- i["src"] = datauri(i["src"])
219
- end
174
+ xmldoc.xpath("//image").each { |i| i["src"] = datauri(i["src"]) }
220
175
  end
221
176
 
222
177
  def variant_cleanup(xmldoc)
223
178
  xmldoc.xpath("//*[variant]").each do |c|
224
- c&.next&.text? && c&.next&.next&.name == "variant" &&
225
- c.next.text.gsub(/\s/, "").empty? and c.next.remove
179
+ c&.next&.text? && c&.next&.next&.name == "variant" && c.next.text.gsub(/\s/, "").empty? and
180
+ c.next.remove
226
181
  end
227
182
  xmldoc.xpath("//*[variant]").each do |c|
228
- next unless c.children.any? do |n|
229
- n.name != "variant" && (!n.text? || !n.text.gsub(/\s/, "").empty?)
230
- end
183
+ next unless c.children.any? { |n| n.name != "variant" && (!n.text? || !n.text.gsub(/\s/, "").empty?) }
231
184
  c.xpath("./variant").each do |n|
232
- if n.at_xpath('preceding-sibling::node()[not(self::text()'\
233
- '[not(normalize-space())])][1][self::variantwrap]')
185
+ if n.at_xpath('preceding-sibling::node()[not(self::text()[not(normalize-space())])][1][self::variantwrap]')
234
186
  n.previous_element << n
235
187
  else
236
188
  n.replace('<variantwrap/>').first << n
@@ -32,8 +32,7 @@ module Asciidoctor
32
32
  def dl2_table_cleanup(xmldoc)
33
33
  q = "//table/following-sibling::*[1][self::p]"
34
34
  xmldoc.xpath(q).each do |s|
35
- if s.text =~ /^\s*key[^a-z]*$/i && !s.next_element.nil? &&
36
- s.next_element.name == "dl"
35
+ if s.text =~ /^\s*key[^a-z]*$/i && !s.next_element.nil? && s.next_element.name == "dl"
37
36
  s.next_element["key"] = "true"
38
37
  s.previous_element << s.next_element.remove
39
38
  s.remove
@@ -101,8 +100,7 @@ module Asciidoctor
101
100
  def formula_cleanup_where2(x)
102
101
  q = "//formula/following-sibling::*[1][self::p]"
103
102
  x.xpath(q).each do |s|
104
- if s.text =~ /^\s*where[^a-z]*$/i && !s.next_element.nil? &&
105
- s.next_element.name == "dl"
103
+ if s.text =~ /^\s*where[^a-z]*$/i && !s.next_element.nil? && s.next_element.name == "dl"
106
104
  s.next_element["key"] = "true"
107
105
  s.previous_element << s.next_element.remove
108
106
  s.remove
@@ -0,0 +1,86 @@
1
+ require "nokogiri"
2
+ require "pathname"
3
+ require "open-uri"
4
+ require "html2doc"
5
+ require_relative "./cleanup_block.rb"
6
+ require_relative "./cleanup_footnotes.rb"
7
+ require_relative "./cleanup_ref.rb"
8
+ require_relative "./cleanup_ref_dl.rb"
9
+ require_relative "./cleanup_boilerplate.rb"
10
+ require_relative "./cleanup_section.rb"
11
+ require_relative "./cleanup_terms.rb"
12
+ require_relative "./cleanup_inline.rb"
13
+ require_relative "./cleanup_amend.rb"
14
+ require "relaton_iev"
15
+
16
+ module Asciidoctor
17
+ module Standoc
18
+ module Cleanup
19
+ def asciimath2mathml(text)
20
+ text = text.gsub(%r{<stem type="AsciiMath">(.+?)</stem>}m) do |m|
21
+ "<amathstem>#{HTMLEntities.new.decode($1)}</amathstem>"
22
+ end
23
+ text = Html2Doc.asciimath_to_mathml(text, ["<amathstem>", "</amathstem>"])
24
+ x = Nokogiri::XML(text)
25
+ x.xpath("//*[local-name() = 'math'][not(parent::stem)]").each do |y|
26
+ y.wrap("<stem type='MathML'></stem>")
27
+ end
28
+ x.to_xml
29
+ end
30
+
31
+ def xml_unescape_mathml(x)
32
+ return if x.children.any? { |y| y.element? }
33
+ math = x.text.gsub(/&lt;/, "<").gsub(/&gt;/, ">").gsub(/&quot;/, '"').gsub(/&apos;/, "'").gsub(/&amp;/, "&").
34
+ gsub(/<[^: \r\n\t\/]+:/, "<").gsub(/<\/[^ \r\n\t:]+:/, "</")
35
+ x.children = math
36
+ end
37
+
38
+ MATHML_NS = "http://www.w3.org/1998/Math/MathML".freeze
39
+
40
+ def mathml_preserve_space(m)
41
+ m.xpath(".//m:mtext", "m" => MATHML_NS).each do |x|
42
+ x.children = x.children.to_xml.gsub(/^\s/, "&#xA0;").gsub(/\s$/, "&#xA0;")
43
+ end
44
+ end
45
+
46
+ def mathml_namespace(stem)
47
+ stem.xpath("./math", ).each { |x| x.default_namespace = MATHML_NS }
48
+ end
49
+
50
+ def mathml_mi_italics
51
+ { uppergreek: true, upperroman: true,
52
+ lowergreek: true, lowerroman: true }
53
+ end
54
+
55
+ # presuppose multichar mi upright, singlechar mi MathML default italic
56
+ def mathml_italicise(x)
57
+ x.xpath(".//m:mi[not(ancestor::*[@mathvariant])]", "m" => MATHML_NS).each do |i|
58
+ char = HTMLEntities.new.decode(i.text)
59
+ i["mathvariant"] = "normal" if mi_italicise?(char)
60
+ end
61
+ end
62
+
63
+ def mi_italicise?(c)
64
+ return false if c.length > 1
65
+ if /\p{Greek}/.match(c)
66
+ /\p{Lower}/.match(c) && !mathml_mi_italics[:lowergreek] ||
67
+ /\p{Upper}/.match(c) && !mathml_mi_italics[:uppergreek]
68
+ elsif /\p{Latin}/.match(c)
69
+ /\p{Lower}/.match(c) && !mathml_mi_italics[:lowerroman] ||
70
+ /\p{Upper}/.match(c) && !mathml_mi_italics[:upperroman]
71
+ else
72
+ false
73
+ end
74
+ end
75
+
76
+ def mathml_cleanup(xmldoc)
77
+ xmldoc.xpath("//stem[@type = 'MathML']").each do |x|
78
+ xml_unescape_mathml(x)
79
+ mathml_namespace(x)
80
+ mathml_preserve_space(x)
81
+ mathml_italicise(x)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -19,6 +19,6 @@ module Metanorma
19
19
  end
20
20
 
21
21
  module Standoc
22
- VERSION= "1.8.1".freeze
22
+ VERSION= "1.8.2".freeze
23
23
  end
24
24
  end
@@ -3,6 +3,71 @@ require "relaton_iec"
3
3
  require "fileutils"
4
4
 
5
5
  RSpec.describe Asciidoctor::Standoc do
6
+ it "processes markup in sourcecode" do
7
+ expect(xmlpp(strip_guid(Asciidoctor.convert(<<~"INPUT", backend: :standoc, header_footer: true)))).to be_equivalent_to xmlpp(<<~"OUTPUT")
8
+ #{ASCIIDOC_BLANK_HDR}
9
+
10
+ [source]
11
+ ----
12
+ <tag/>
13
+ ----
14
+
15
+ [[A]]
16
+ [source]
17
+ ----
18
+ var {{{*x*}}} : {{{<<A,recursive>>}}} <tag/>
19
+ ----
20
+
21
+
22
+ INPUT
23
+ #{BLANK_HDR}
24
+ <sections>
25
+ <sourcecode id='_'>&lt;tag/&gt;</sourcecode>
26
+ <sourcecode id='A'>
27
+ var
28
+ <strong>x</strong>
29
+ :
30
+ <xref target='A'>recursive</xref>
31
+ &lt;tag/&gt;
32
+ </sourcecode>
33
+ </sections>
34
+ </standard-document>
35
+ OUTPUT
36
+ end
37
+
38
+ it "processes markup in sourcecode with custom delimiters" do
39
+ expect(xmlpp(strip_guid(Asciidoctor.convert(<<~"INPUT", backend: :standoc, header_footer: true)))).to be_equivalent_to xmlpp(<<~"OUTPUT")
40
+ = Document title
41
+ Author
42
+ :docfile: test.adoc
43
+ :nodoc:
44
+ :novalid:
45
+ :no-isobib:
46
+ :sourcecode-markup-start: [[[
47
+ :sourcecode-markup-end: ]]]
48
+
49
+ [[A]]
50
+ [source]
51
+ ----
52
+ var [[[*x*]]] : [[[<<A,recursive>>]]]
53
+ ----
54
+
55
+
56
+ INPUT
57
+ #{BLANK_HDR}
58
+ <sections>
59
+ <sourcecode id='A'>
60
+ var
61
+ <strong>x</strong>
62
+ :
63
+ <xref target='A'>recursive</xref>
64
+ </sourcecode>
65
+ </sections>
66
+ </standard-document>
67
+ OUTPUT
68
+ end
69
+
70
+
6
71
  it "applies smartquotes by default" do
7
72
  expect(xmlpp(strip_guid(Asciidoctor.convert(<<~"INPUT", backend: :standoc, header_footer: true)))).to be_equivalent_to xmlpp(<<~"OUTPUT")
8
73
  #{ASCIIDOC_BLANK_HDR}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma-standoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.1
4
+ version: 1.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -412,6 +412,7 @@ files:
412
412
  - lib/asciidoctor/standoc/cleanup_boilerplate.rb
413
413
  - lib/asciidoctor/standoc/cleanup_footnotes.rb
414
414
  - lib/asciidoctor/standoc/cleanup_inline.rb
415
+ - lib/asciidoctor/standoc/cleanup_maths.rb
415
416
  - lib/asciidoctor/standoc/cleanup_ref.rb
416
417
  - lib/asciidoctor/standoc/cleanup_ref_dl.rb
417
418
  - lib/asciidoctor/standoc/cleanup_section.rb