metanorma-standoc 2.6.1 → 2.6.3

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: 42b32b109ae4f5ac4505f2218a4d4c5768ad388ffb29d3ae292b61fab8923030
4
- data.tar.gz: aafef4197f9d88913ef52f8effacb515e54e94f456757758e9ac0bfe41b2656d
3
+ metadata.gz: c8505150e755f57c7d7d9a02212bc3915ee49d8547f4c2143369ea00f4d9b623
4
+ data.tar.gz: d2dd6aae079a71359d5012f03ea6f937eb998f2a9912d1b5886246de9797d81c
5
5
  SHA512:
6
- metadata.gz: 13a8345e82e041ebbefecddeea7ba719898b6997877891d76177872b672e9bce7d00c060bf98569b0acd49c0c3ba691a989032e3650066030cf99a86991b5cbb
7
- data.tar.gz: 37c1b235d071bb2d7b4f5ff8e73e3f5a3ca668c726245ea75002152bbd9931b07e67869dee8b0b6b8685e4480054f50244ddfa492cdd12275e30d27ec2d389e2
6
+ metadata.gz: 33a2b3eae8bb5f0092e5bd36ceb05f9a653fb3f5af645d035641f2e64076b2746738bb23dd75d83191a835873aef921a28a2baed313fb1b3fb939c747543acee
7
+ data.tar.gz: ba20076eab6ecc6a2ffcda225012863094ef6f24abcb85feb7da4f4fd46dd1caa259938a7aa970911841665e7cdce328f95e0e899dc6250ba2c8776eb574895a
@@ -0,0 +1,112 @@
1
+ require "asciidoctor/extensions"
2
+
3
+ module Metanorma
4
+ module Standoc
5
+ module Inline
6
+ def inline_anchor(node)
7
+ case node.type
8
+ when :ref then inline_anchor_ref node
9
+ when :xref then inline_anchor_xref node
10
+ when :link then inline_anchor_link node
11
+ when :bibref then inline_anchor_bibref node
12
+ end
13
+ end
14
+
15
+ def inline_anchor_ref(node)
16
+ noko do |xml|
17
+ xml.bookmark nil, **attr_code(id: node.id)
18
+ end.join
19
+ end
20
+
21
+ def inline_anchor_xref(node)
22
+ noko do |xml|
23
+ attrs = inline_anchor_xref_attrs(node)
24
+ c = attrs[:text]
25
+ attrs.delete(:text) unless c.nil?
26
+ xml.xref **attr_code(attrs) do |x|
27
+ x << c
28
+ end
29
+ end.join
30
+ end
31
+
32
+ def inline_anchor_xref_attrs(node)
33
+ text = concatenate_attributes_to_xref_text(node)
34
+ m = inline_anchor_xref_match(text)
35
+ t = node.target.gsub(/^#/, "").gsub(%r{(\.xml|\.adoc)(#.*$)}, "\\2")
36
+ m.nil? and return { target: t, type: "inline", text: text }
37
+ inline_anchor_xref_attrs1(m, t, text)
38
+ end
39
+
40
+ def concatenate_attributes_to_xref_text(node)
41
+ node.attributes.each_with_object([]) do |(k, v), m|
42
+ %w(path fragment refid).include?(k) and next
43
+ m << "#{k}=#{v}%"
44
+ end.map { |x| x.sub(/%+/, "%") }.join + (node.text || "")
45
+ end
46
+
47
+ def inline_anchor_xref_attrs1(match, target, text)
48
+ { target: target, hidden: match[:hidden],
49
+ type: match[:fn].nil? ? "inline" : "footnote",
50
+ case: match[:case]&.sub(/%$/, ""),
51
+ style: match[:style]&.sub(/^style=/, "")&.sub(/%$/, "") || @xrefstyle,
52
+ droploc: match[:drop].nil? && match[:drop2].nil? ? nil : true,
53
+ text: inline_anchor_xref_text(match, text) }
54
+ end
55
+
56
+ def inline_anchor_xref_match(text)
57
+ /^(?:hidden%(?<hidden>[^,]+),?)?
58
+ (?<style>style=[^%]+%)?
59
+ (?<drop>droploc%)?(?<case>capital%|lowercase%)?(?<drop2>droploc%)?
60
+ (?<fn>fn:?\s*)?(?<text>.*)$/x.match text
61
+ end
62
+
63
+ def inline_anchor_xref_text(match, text)
64
+ if %i[case fn drop drop2 hidden style].any? { |x| !match[x].nil? }
65
+ match[:text]
66
+ else text
67
+ end
68
+ end
69
+
70
+ def inline_anchor_link(node)
71
+ contents = node.text
72
+ contents = "" if node.target.gsub(%r{^mailto:}, "") == node.text
73
+ attributes = { target: node.target, alt: node.attr("title"),
74
+ "update-type": node.attr("updatetype") ||
75
+ node.attr("update-type") }
76
+ noko do |xml|
77
+ xml.link **attr_code(attributes) do |l|
78
+ l << contents
79
+ end
80
+ end.join
81
+ end
82
+
83
+ def inline_anchor_bibref(node)
84
+ eref_contents =
85
+ @c.decode(node.text || node.target || node.id)
86
+ &.sub(/^\[?([^\[\]]+?)\]?$/, "[\\1]")
87
+ @refids << (node.target || node.id)
88
+ noko do |xml|
89
+ xml.ref **attr_code(id: node.target || node.id) do |r|
90
+ r << eref_contents
91
+ end
92
+ end.join
93
+ end
94
+
95
+ def inline_callout(node)
96
+ noko do |xml|
97
+ xml.callout node.text
98
+ end.join
99
+ end
100
+
101
+ def inline_footnote(node)
102
+ @fn_number ||= 0
103
+ noko do |xml|
104
+ @fn_number += 1
105
+ xml.fn reference: @fn_number do |fn|
106
+ fn.p { |p| p << node.text }
107
+ end
108
+ end.join
109
+ end
110
+ end
111
+ end
112
+ end
@@ -914,44 +914,47 @@
914
914
  -->
915
915
  <define name="image">
916
916
  <element name="image">
917
- <attribute name="id">
918
- <data type="ID"/>
917
+ <ref name="Image"/>
918
+ </element>
919
+ </define>
920
+ <define name="Image">
921
+ <attribute name="id">
922
+ <data type="ID"/>
923
+ </attribute>
924
+ <attribute name="src">
925
+ <data type="anyURI"/>
926
+ </attribute>
927
+ <attribute name="mimetype"/>
928
+ <optional>
929
+ <attribute name="filename"/>
930
+ </optional>
931
+ <optional>
932
+ <attribute name="width">
933
+ <choice>
934
+ <data type="int"/>
935
+ <value>auto</value>
936
+ </choice>
919
937
  </attribute>
920
- <attribute name="src">
938
+ </optional>
939
+ <optional>
940
+ <attribute name="height">
941
+ <choice>
942
+ <data type="int"/>
943
+ <value>auto</value>
944
+ </choice>
945
+ </attribute>
946
+ </optional>
947
+ <optional>
948
+ <attribute name="alt"/>
949
+ </optional>
950
+ <optional>
951
+ <attribute name="title"/>
952
+ </optional>
953
+ <optional>
954
+ <attribute name="longdesc">
921
955
  <data type="anyURI"/>
922
956
  </attribute>
923
- <attribute name="mimetype"/>
924
- <optional>
925
- <attribute name="filename"/>
926
- </optional>
927
- <optional>
928
- <attribute name="width">
929
- <choice>
930
- <data type="int"/>
931
- <value>auto</value>
932
- </choice>
933
- </attribute>
934
- </optional>
935
- <optional>
936
- <attribute name="height">
937
- <choice>
938
- <data type="int"/>
939
- <value>auto</value>
940
- </choice>
941
- </attribute>
942
- </optional>
943
- <optional>
944
- <attribute name="alt"/>
945
- </optional>
946
- <optional>
947
- <attribute name="title"/>
948
- </optional>
949
- <optional>
950
- <attribute name="longdesc">
951
- <data type="anyURI"/>
952
- </attribute>
953
- </optional>
954
- </element>
957
+ </optional>
955
958
  </define>
956
959
  <define name="video">
957
960
  <element name="video">
@@ -348,6 +348,9 @@
348
348
  <zeroOrMore>
349
349
  <ref name="contact"/>
350
350
  </zeroOrMore>
351
+ <optional>
352
+ <ref name="logo"/>
353
+ </optional>
351
354
  </element>
352
355
  </define>
353
356
  <define name="orgname">
@@ -366,6 +369,11 @@
366
369
  </choice>
367
370
  </element>
368
371
  </define>
372
+ <define name="logo">
373
+ <element name="logo">
374
+ <ref name="image"/>
375
+ </element>
376
+ </define>
369
377
  <define name="NameWithVariants">
370
378
  <element name="primary">
371
379
  <ref name="LocalizedString"/>
@@ -942,6 +950,7 @@
942
950
  <value>obsoleted</value>
943
951
  <value>confirmed</value>
944
952
  <value>updated</value>
953
+ <value>corrected</value>
945
954
  <value>issued</value>
946
955
  <value>transmitted</value>
947
956
  <value>copied</value>
@@ -1,5 +1,6 @@
1
1
  require "uri" if /^2\./.match?(RUBY_VERSION)
2
2
  require_relative "./blocks_notes"
3
+ require_relative "./blocks_image"
3
4
 
4
5
  module Metanorma
5
6
  module Standoc
@@ -93,10 +94,10 @@ module Metanorma
93
94
  end
94
95
 
95
96
  def example(node)
96
- (in_terms? || node.option?("termexample")) and return term_example(node)
97
97
  role = node.role || node.attr("style")
98
98
  ret = example_to_requirement(node, role) ||
99
99
  example_by_role(node, role) and return ret
100
+ (in_terms? || node.option?("termexample")) and return term_example(node)
100
101
  reqt_subpart?(role) and return requirement_subpart(node)
101
102
  example_proper(node)
102
103
  end
@@ -119,25 +120,6 @@ module Metanorma
119
120
  @reqt_models.requirement_roles[role.to_sym], role)
120
121
  end
121
122
 
122
- def svgmap_attrs(node)
123
- attr_code(id_attr(node)
124
- .merge(id: node.id, number: node.attr("number"),
125
- unnumbered: node.option?("unnumbered") ? "true" : nil,
126
- subsequence: node.attr("subsequence"))
127
- .merge(keep_attrs(node)))
128
- end
129
-
130
- def svgmap_example(node)
131
- noko do |xml|
132
- xml.svgmap **attr_code(svgmap_attrs(node).merge(
133
- src: node.attr("src"), alt: node.attr("alt"),
134
- )) do |ex|
135
- figure_title(node, ex)
136
- ex << node.content
137
- end
138
- end.join("\n")
139
- end
140
-
141
123
  # prevent A's and other subs inappropriate for pseudocode
142
124
  def pseudocode_example(node)
143
125
  node.blocks.each { |b| b.remove_sub(:replacements) }
@@ -162,34 +144,6 @@ module Metanorma
162
144
  end.join("\n")
163
145
  end
164
146
 
165
- def figure_example(node)
166
- noko do |xml|
167
- xml.figure **figure_attrs(node) do |ex|
168
- node.title.nil? or ex.name { |name| name << node.title }
169
- wrap_in_para(node, ex)
170
- end
171
- end.join("\n")
172
- end
173
-
174
- def figure_title(node, out)
175
- node.title.nil? and return
176
- out.name { |name| name << node.title }
177
- end
178
-
179
- def figure_attrs(node)
180
- attr_code(id_unnum_attrs(node).merge(keep_attrs(node))
181
- .merge(class: node.attr("class")))
182
- end
183
-
184
- def image(node)
185
- noko do |xml|
186
- xml.figure **figure_attrs(node) do |f|
187
- figure_title(node, f)
188
- f.image **image_attributes(node)
189
- end
190
- end
191
- end
192
-
193
147
  def para_attrs(node)
194
148
  attr_code(id_attr(node).merge(keep_attrs(node)
195
149
  .merge(align: node.attr("align"),
@@ -0,0 +1,52 @@
1
+ module Metanorma
2
+ module Standoc
3
+ module Blocks
4
+ def svgmap_attrs(node)
5
+ attr_code(id_attr(node)
6
+ .merge(id: node.id, number: node.attr("number"),
7
+ unnumbered: node.option?("unnumbered") ? "true" : nil,
8
+ subsequence: node.attr("subsequence"))
9
+ .merge(keep_attrs(node)))
10
+ end
11
+
12
+ def svgmap_example(node)
13
+ noko do |xml|
14
+ xml.svgmap **attr_code(svgmap_attrs(node).merge(
15
+ src: node.attr("src"), alt: node.attr("alt"),
16
+ )) do |ex|
17
+ figure_title(node, ex)
18
+ ex << node.content
19
+ end
20
+ end.join("\n")
21
+ end
22
+
23
+ def figure_example(node)
24
+ noko do |xml|
25
+ xml.figure **figure_attrs(node) do |ex|
26
+ node.title.nil? or ex.name { |name| name << node.title }
27
+ wrap_in_para(node, ex)
28
+ end
29
+ end.join("\n")
30
+ end
31
+
32
+ def figure_title(node, out)
33
+ node.title.nil? and return
34
+ out.name { |name| name << node.title }
35
+ end
36
+
37
+ def figure_attrs(node)
38
+ attr_code(id_unnum_attrs(node).merge(keep_attrs(node))
39
+ .merge(class: node.attr("class")))
40
+ end
41
+
42
+ def image(node)
43
+ noko do |xml|
44
+ xml.figure **figure_attrs(node) do |f|
45
+ figure_title(node, f)
46
+ f.image **image_attributes(node)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -45,7 +45,7 @@ module Metanorma
45
45
  element_name_cleanup(xmldoc)
46
46
  ref_cleanup(xmldoc) # feeds: bibitem_cleanup
47
47
  note_cleanup(xmldoc)
48
- clausebefore_cleanup(xmldoc)
48
+ clausebefore_cleanup(xmldoc) # feeeds: floatingtitle_cleanup
49
49
  floatingtitle_cleanup(xmldoc)
50
50
  bibitem_cleanup(xmldoc) # feeds: normref_cleanup, biblio_cleanup,
51
51
  # reference_names, bpart_cleanup
@@ -158,8 +158,7 @@ module Metanorma
158
158
  end
159
159
 
160
160
  def metadata_cleanup(xmldoc)
161
- return if @metadata_attrs.nil? || @metadata_attrs.empty?
162
-
161
+ (@metadata_attrs.nil? || @metadata_attrs.empty?) and return
163
162
  ins = add_misc_container(xmldoc)
164
163
  ins << @metadata_attrs
165
164
  end
@@ -86,16 +86,33 @@ module Metanorma
86
86
  end
87
87
 
88
88
  def termdef_boilerplate_insert(xmldoc, isodoc, once = false)
89
- xmldoc.xpath(self.class::TERM_CLAUSE).each do |f|
90
- f.at("./clause[@type = 'boilerplate'] | " \
91
- "./note[@type = 'boilerplate']") and next
92
- term_defs_boilerplate(f.at("./title"),
93
- xmldoc.xpath(".//termdocsource"),
94
- f.at(".//term"), f.at(".//p"), isodoc)
95
- once and break
89
+ if once
90
+ f = termdef_boilerplate_insert_location(xmldoc) and
91
+ termdef_boilerplate_insert1(f, xmldoc, isodoc)
92
+ else
93
+ xmldoc.xpath(self.class::TERM_CLAUSE).each do |f|
94
+ termdef_boilerplate_insert1(f, xmldoc, isodoc)
95
+ end
96
96
  end
97
97
  end
98
98
 
99
+ def termdef_boilerplate_insert_location(xmldoc)
100
+ f = xmldoc.at(self.class::TERM_CLAUSE)
101
+ root = xmldoc.at("//sections/terms | //sections/clause[.//terms]")
102
+ !f || !root and return f || root
103
+ f.at("./following::terms") and return root
104
+ f.at("./preceding-sibling::clause") and return root
105
+ f
106
+ end
107
+
108
+ def termdef_boilerplate_insert1(sect, xmldoc, isodoc)
109
+ sect.at("./clause[@type = 'boilerplate'] | " \
110
+ "./note[@type = 'boilerplate']") and return
111
+ term_defs_boilerplate(sect.at("./title"),
112
+ xmldoc.xpath(".//termdocsource"),
113
+ sect.at(".//term"), sect.at(".//p"), isodoc)
114
+ end
115
+
99
116
  def boilerplate_cleanup(xmldoc)
100
117
  isodoc = boilerplate_isodoc(xmldoc)
101
118
  termdef_boilerplate_cleanup(xmldoc)
@@ -178,8 +178,8 @@ module Metanorma
178
178
  end
179
179
 
180
180
  def clausebefore_cleanup(xmldoc)
181
- preface_clausebefore_cleanup(xmldoc)
182
181
  sections_clausebefore_cleanup(xmldoc)
182
+ preface_clausebefore_cleanup(xmldoc)
183
183
  end
184
184
 
185
185
  def preface_clausebefore_cleanup(xmldoc)
@@ -196,10 +196,20 @@ module Metanorma
196
196
  end
197
197
 
198
198
  def sections_clausebefore_cleanup(xmldoc)
199
- return unless xmldoc.at("//sections")
200
-
199
+ xmldoc.at("//sections") or return
201
200
  ins = insert_before(xmldoc, "//sections")
202
- xmldoc.xpath("//sections//*[@beforeclauses = 'true']").each do |x|
201
+ xmldoc.xpath("//sections//*[@beforeclauses = 'true']").reverse.each do |x|
202
+ x.delete("beforeclauses")
203
+ ins.previous = x.remove
204
+ end
205
+ endofpreface_clausebefore(xmldoc, ins)
206
+ end
207
+
208
+ # only move clausebefore notes at the very end of preface
209
+ def endofpreface_clausebefore(xmldoc, ins)
210
+ xmldoc.xpath("//preface//*[@beforeclauses = 'true']").reverse.each do |x|
211
+ textafternote = xmldoc.xpath("//preface//*") & x.xpath("./following::*")
212
+ textafternote.text.strip.empty? or break
203
213
  x.delete("beforeclauses")
204
214
  ins.previous = x.remove
205
215
  end
@@ -214,6 +224,7 @@ module Metanorma
214
224
  end
215
225
 
216
226
  def floatingtitle_cleanup(xmldoc)
227
+ pop_floating_title(xmldoc) # done again, after endofpreface_clausebefore
217
228
  floating_title_preface2sections(xmldoc)
218
229
  end
219
230
 
@@ -50,10 +50,30 @@ module Metanorma
50
50
  "[not(.//definitions[@type = 'symbols'])]".freeze
51
51
 
52
52
  def section_names_terms_cleanup(xml)
53
- replace_title(xml, "//definitions[@type = 'symbols']", @i18n&.symbols)
53
+ section_names_definitions(xml)
54
+ section_names_terms1_cleanup(xml)
55
+ end
56
+
57
+ def section_names_definitions(xml)
58
+ auto_name_definitions(xml) or return
59
+ replace_title(xml, "//definitions[@type = 'symbols']",
60
+ @i18n&.symbols)
54
61
  replace_title(xml, "//definitions[@type = 'abbreviated_terms']",
55
62
  @i18n&.abbrev)
56
- replace_title(xml, "//definitions[not(@type)]", @i18n&.symbolsabbrev)
63
+ replace_title(xml, "//definitions[not(@type)]",
64
+ @i18n&.symbolsabbrev)
65
+ end
66
+
67
+ def auto_name_definitions(xml)
68
+ xml.xpath("//definitions[@type = 'symbols']").size > 1 and return false
69
+ xml.xpath("//definitions[@type = 'abbreviated_terms']").size > 1 and
70
+ return false
71
+ xml.xpath("//definitions[not(@type)]").size > 1 and return false
72
+ true
73
+ end
74
+
75
+ def section_names_terms1_cleanup(xml)
76
+ auto_name_terms(xml) or return
57
77
  replace_title(xml, "//terms#{SYMnoABBR} | //clause[.//terms]#{SYMnoABBR}",
58
78
  @i18n&.termsdefsymbols, true)
59
79
  replace_title(xml, "//terms#{ABBRnoSYM} | //clause[.//terms]#{ABBRnoSYM}",
@@ -69,6 +89,54 @@ module Metanorma
69
89
  )
70
90
  end
71
91
 
92
+ # do not auto-name terms sections if there are terms subclauses
93
+ # not covered by the auto titles,
94
+ # or if more than one title is covered by an auto title
95
+ def auto_name_terms(xml)
96
+ n = xml.at("//terms | //clause[.//terms]")
97
+ out = terms_subclauses(n)
98
+ .each_with_object({ term: 0, sna: 0, ans: 0, sa: 0, nsa: 0,
99
+ tsna: 0, tans: 0, tsa: 0, tnsa: 0,
100
+ termdef: 0, other: 0 }) do |x, m|
101
+ terms_subclause_type_tally(x, m, n)
102
+ end
103
+ out.delete(:parent)
104
+ !out.values.detect { |x| x > 1 } && out[:other].zero?
105
+ end
106
+
107
+ def terms_subclauses(node)
108
+ legal = %w(terms definitions clause)
109
+ [node, node&.elements].compact.flatten
110
+ .select do |x|
111
+ legal.include?(x.name) &&
112
+ !(x.name == "clause" && x["type"] == "boilerplate")
113
+ end
114
+ end
115
+
116
+ def terms_subclause_type_tally(node, m, parent)
117
+ sym = if (node.at(".//term") && !node.at(".//definitions")) ||
118
+ (node.name == "terms" && !node.at(".//term"))
119
+ unless m[:parent] == :term # don't count Term > Term twice
120
+ :term
121
+ end
122
+ elsif node.at(".//term") && node.at("./self::*#{SYMnoABBR}") then :tsna
123
+ elsif node.at(".//term") && node.at("./self::*#{ABBRnoSYM}") then :tans
124
+ elsif node.at(".//term") && node.at("./self::*#{SYMABBR}") then :tsa
125
+ elsif node.at(".//term") && node.at("./self::*#{NO_SYMABBR}") then :tnsa
126
+ elsif node.at("./self::*#{SYMnoABBR}") then :sna
127
+ elsif node.at("./self::*#{ABBRnoSYM}") then :ans
128
+ elsif node.at("./self::*#{SYMABBR}") then :sa
129
+ elsif node.at("./self::*#{NO_SYMABBR}") then :nsa
130
+ elsif node.name == "definitions" # ignore
131
+ elsif node == parent && node.at(".//term") &&
132
+ node.at(".//definitions")
133
+ :termdef
134
+ else :other
135
+ end
136
+ node == parent and m[:parent] = sym
137
+ sym and m[sym] += 1
138
+ end
139
+
72
140
  SECTION_CONTAINERS = %w(foreword introduction acknowledgements abstract
73
141
  clause clause references terms definitions annex
74
142
  appendix).freeze
@@ -35,12 +35,12 @@ module Metanorma
35
35
 
36
36
  IGNORE_QUOTES_ELEMENTS =
37
37
  %w(pre tt sourcecode stem asciimath figure bibdata passthrough
38
- identifier).freeze
38
+ identifier presentation-metadata semantic-metadata).freeze
39
39
 
40
40
  def uninterrupt_quotes_around_xml_skip(elem)
41
41
  !(/\A['"]/.match?(elem.text) &&
42
- elem.previous.path.gsub(/\[\d+\]/, "").split(%r{/})[1..-2]
43
- .intersection(IGNORE_QUOTES_ELEMENTS).empty? &&
42
+ elem.previous.path.gsub(/\[\d+\]/, "").split(%r{/})[1..-2].
43
+ intersection(IGNORE_QUOTES_ELEMENTS).empty? &&
44
44
  ((elem.previous.text.strip.empty? &&
45
45
  !empty_tag_with_text_content?(elem.previous)) ||
46
46
  ignoretext?(elem.previous)))
@@ -50,8 +50,8 @@ module Metanorma
50
50
  prev = elem.at(".//preceding::text()[1]") or return
51
51
  /\S\Z/.match?(prev.text) or return
52
52
  foll = elem.at(".//following::text()[1]")
53
- m = /\A(["'][[:punct:]]*)(\s|\Z)/
54
- .match(@c.decode(foll&.text)) or return
53
+ m = /\A(["'][[:punct:]]*)(\s|\Z)/.
54
+ match(@c.decode(foll&.text)) or return
55
55
  foll.content = foll.text.sub(/\A(["'][[:punct:]]*)/, "")
56
56
  prev.content = "#{prev.text}#{m[1]}"
57
57
  end
@@ -103,8 +103,8 @@ module Metanorma
103
103
  next unless n.text? && /\u2019/.match?(n.text)
104
104
 
105
105
  n.replace(@c.encode(
106
- @c.decode(n.text)
107
- .gsub(/(?<=\p{Alnum})\u2019(?=\p{Alpha})/, "'"),
106
+ @c.decode(n.text).
107
+ gsub(/(?<=\p{Alnum})\u2019(?=\p{Alpha})/, "'"),
108
108
  :basic, :hexadecimal
109
109
  ))
110
110
  end
@@ -78,8 +78,7 @@ module Metanorma
78
78
  end
79
79
 
80
80
  def toc_metadata(xmldoc)
81
- return unless @htmltoclevels || @doctoclevels || @toclevels
82
-
81
+ @htmltoclevels || @doctoclevels || @toclevels or return
83
82
  ins = add_misc_container(xmldoc)
84
83
  toc_metadata1(ins)
85
84
  end
@@ -5,6 +5,7 @@ require_relative "front"
5
5
  require_relative "lists"
6
6
  require_relative "ref"
7
7
  require_relative "inline"
8
+ require_relative "anchor"
8
9
  require_relative "blocks"
9
10
  require_relative "section"
10
11
  require_relative "table"
@@ -21,13 +22,13 @@ module Metanorma
21
22
  class Converter
22
23
  Asciidoctor::Extensions.register do
23
24
  preprocessor Metanorma::Standoc::EmbedIncludeProcessor
24
- preprocessor Metanorma::Standoc::NamedEscapePreprocessor
25
25
  preprocessor Metanorma::Standoc::LinkProtectPreprocessor
26
26
  preprocessor Metanorma::Standoc::Datamodel::AttributesTablePreprocessor
27
27
  preprocessor Metanorma::Standoc::Datamodel::DiagramPreprocessor
28
28
  preprocessor Metanorma::Plugin::Datastruct::Json2TextPreprocessor
29
29
  preprocessor Metanorma::Plugin::Datastruct::Yaml2TextPreprocessor
30
30
  preprocessor Metanorma::Plugin::Glossarist::DatasetPreprocessor
31
+ preprocessor Metanorma::Standoc::NamedEscapePreprocessor
31
32
  inline_macro Metanorma::Standoc::PreferredTermInlineMacro
32
33
  inline_macro Metanorma::Standoc::DateInlineMacro
33
34
  inline_macro Metanorma::Standoc::SpanInlineMacro
@@ -63,6 +64,7 @@ module Metanorma
63
64
  treeprocessor Metanorma::Standoc::ToDoInlineAdmonitionBlock
64
65
  block Metanorma::Standoc::PlantUMLBlockMacro
65
66
  block Metanorma::Standoc::PseudocodeBlockMacro
67
+ block_macro Metanorma::Standoc::ColumnBreakBlockMacro
66
68
  end
67
69
 
68
70
  include ::Asciidoctor::Converter
@@ -81,7 +81,7 @@ module Metanorma
81
81
 
82
82
  def datetypes
83
83
  %w{ published accessed created implemented obsoleted
84
- confirmed updated issued circulated unchanged received
84
+ confirmed updated corrected issued circulated unchanged received
85
85
  vote-started vote-ended announced }
86
86
  end
87
87
 
@@ -1,4 +1,3 @@
1
- require "asciidoctor/extensions"
2
1
  require "unicode2latex"
3
2
  require "mime/types"
4
3
  require "base64"
@@ -8,115 +7,6 @@ require "plurimath"
8
7
  module Metanorma
9
8
  module Standoc
10
9
  module Inline
11
- def refid?(ref)
12
- @refids.include? ref
13
- end
14
-
15
- def inline_anchor(node)
16
- case node.type
17
- when :ref then inline_anchor_ref node
18
- when :xref then inline_anchor_xref node
19
- when :link then inline_anchor_link node
20
- when :bibref then inline_anchor_bibref node
21
- end
22
- end
23
-
24
- def inline_anchor_ref(node)
25
- noko do |xml|
26
- xml.bookmark nil, **attr_code(id: node.id)
27
- end.join
28
- end
29
-
30
- def inline_anchor_xref(node)
31
- noko do |xml|
32
- attrs = inline_anchor_xref_attrs(node)
33
- c = attrs[:text]
34
- attrs.delete(:text) unless c.nil?
35
- xml.xref **attr_code(attrs) do |x|
36
- x << c
37
- end
38
- end.join
39
- end
40
-
41
- def inline_anchor_xref_attrs(node)
42
- text = concatenate_attributes_to_xref_text(node)
43
- m = inline_anchor_xref_match(text)
44
- t = node.target.gsub(/^#/, "").gsub(%r{(\.xml|\.adoc)(#.*$)}, "\\2")
45
- m.nil? and return { target: t, type: "inline", text: text }
46
- inline_anchor_xref_attrs1(m, t, text)
47
- end
48
-
49
- def concatenate_attributes_to_xref_text(node)
50
- node.attributes.each_with_object([]) do |(k, v), m|
51
- %w(path fragment refid).include?(k) and next
52
- m << "#{k}=#{v}%"
53
- end.map { |x| x.sub(/%+/, "%") }.join + (node.text || "")
54
- end
55
-
56
- def inline_anchor_xref_attrs1(match, target, text)
57
- { target: target, hidden: match[:hidden],
58
- type: match[:fn].nil? ? "inline" : "footnote",
59
- case: match[:case]&.sub(/%$/, ""),
60
- style: match[:style]&.sub(/^style=/, "")&.sub(/%$/, "") || @xrefstyle,
61
- droploc: match[:drop].nil? && match[:drop2].nil? ? nil : true,
62
- text: inline_anchor_xref_text(match, text) }
63
- end
64
-
65
- def inline_anchor_xref_match(text)
66
- /^(?:hidden%(?<hidden>[^,]+),?)?
67
- (?<style>style=[^%]+%)?
68
- (?<drop>droploc%)?(?<case>capital%|lowercase%)?(?<drop2>droploc%)?
69
- (?<fn>fn:?\s*)?(?<text>.*)$/x.match text
70
- end
71
-
72
- def inline_anchor_xref_text(match, text)
73
- if %i[case fn drop drop2 hidden style].any? { |x| !match[x].nil? }
74
- match[:text]
75
- else text
76
- end
77
- end
78
-
79
- def inline_anchor_link(node)
80
- contents = node.text
81
- contents = "" if node.target.gsub(%r{^mailto:}, "") == node.text
82
- attributes = { target: node.target, alt: node.attr("title"),
83
- "update-type": node.attr("updatetype") ||
84
- node.attr("update-type") }
85
- noko do |xml|
86
- xml.link **attr_code(attributes) do |l|
87
- l << contents
88
- end
89
- end.join
90
- end
91
-
92
- def inline_anchor_bibref(node)
93
- eref_contents =
94
- @c.decode(node.text || node.target || node.id)
95
- &.sub(/^\[?([^\[\]]+?)\]?$/, "[\\1]")
96
- @refids << (node.target || node.id)
97
- noko do |xml|
98
- xml.ref **attr_code(id: node.target || node.id) do |r|
99
- r << eref_contents
100
- end
101
- end.join
102
- end
103
-
104
- def inline_callout(node)
105
- noko do |xml|
106
- xml.callout node.text
107
- end.join
108
- end
109
-
110
- def inline_footnote(node)
111
- @fn_number ||= 0
112
- noko do |xml|
113
- @fn_number += 1
114
- xml.fn reference: @fn_number do |fn|
115
- fn.p { |p| p << node.text }
116
- end
117
- end.join
118
- end
119
-
120
10
  def inline_break(node)
121
11
  noko do |xml|
122
12
  xml << node.text
@@ -137,8 +27,8 @@ module Metanorma
137
27
 
138
28
  def latex_parse1(text, block)
139
29
  lxm_input = Unicode2LaTeX.unicode2latex(@c.decode(text))
140
- results = Plurimath::Math.parse(lxm_input, "latex")
141
- .to_mathml(display_style: block)
30
+ results = Plurimath::Math.parse(lxm_input, "latex").
31
+ to_mathml(display_style: block)
142
32
  if results.nil?
143
33
  @log.add("Math", nil,
144
34
  "latexmlmath failed to process equation:\n#{lxm_input}")
@@ -164,8 +54,8 @@ module Metanorma
164
54
  latex = latex_parse1(text, block) or
165
55
  return xml.stem type: "MathML", block: block
166
56
  xml.stem type: "MathML", block: block do |s|
167
- math = Nokogiri::XML.fragment(latex.sub(/<\?[^>]+>/, ""))
168
- .elements[0]
57
+ math = Nokogiri::XML.fragment(latex.sub(/<\?[^>]+>/, "")).
58
+ elements[0]
169
59
  math.delete("alttext")
170
60
  s.parent.children = math
171
61
  s << "<latexmath>#{text}</latexmath>"
@@ -202,6 +92,10 @@ module Metanorma
202
92
  xml.span style: node.role.sub(/^css /, "") do |s|
203
93
  s << node.text
204
94
  end
95
+ when /:/
96
+ xml.span **attr_code(hash2styles(node.role)) do |s|
97
+ s << node.text
98
+ end
205
99
  else
206
100
  xml << node.text
207
101
  end
@@ -209,6 +103,17 @@ module Metanorma
209
103
  end.join
210
104
  end
211
105
 
106
+ def hash2styles(role)
107
+ CSV.parse_line(role, liberal_parsing: true).
108
+ each_with_object({}) do |r, m|
109
+ kv = r.split(":", 2).map(&:strip)
110
+ case kv[0]
111
+ when "custom-charset"
112
+ m[kv[0]] = kv[1]
113
+ end
114
+ end
115
+ end
116
+
212
117
  def image_attributes(node)
213
118
  nodetarget = node.attr("target") || node.target
214
119
  if Gem.win_platform? && /^[a-zA-Z]:/.match?(nodetarget)
@@ -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.5 -->
20
+ <!-- VERSION v1.2.8 -->
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">
@@ -1013,6 +1013,14 @@
1013
1013
  </oneOrMore>
1014
1014
  </element>
1015
1015
  </define>
1016
+ <define name="BasicBlock" combine="choice">
1017
+ <ref name="columnbreak"/>
1018
+ </define>
1019
+ <define name="columnbreak">
1020
+ <element name="columnbreak">
1021
+ <empty/>
1022
+ </element>
1023
+ </define>
1016
1024
  <define name="MultilingualRenderingType">
1017
1025
  <choice>
1018
1026
  <value>common</value>
@@ -1046,6 +1054,17 @@
1046
1054
  <ref name="date_inline"/>
1047
1055
  </choice>
1048
1056
  </define>
1057
+ <define name="PureTextElement" combine="choice">
1058
+ <ref name="passthrough_inline"/>
1059
+ </define>
1060
+ <define name="passthrough_inline">
1061
+ <element name="passthrough">
1062
+ <optional>
1063
+ <attribute name="formats"/>
1064
+ </optional>
1065
+ <text/>
1066
+ </element>
1067
+ </define>
1049
1068
  <define name="add">
1050
1069
  <element name="add">
1051
1070
  <choice>
@@ -1084,6 +1103,9 @@
1084
1103
  <optional>
1085
1104
  <attribute name="style"/>
1086
1105
  </optional>
1106
+ <optional>
1107
+ <attribute name="custom-charset"/>
1108
+ </optional>
1087
1109
  <oneOrMore>
1088
1110
  <ref name="TextElement"/>
1089
1111
  </oneOrMore>
@@ -1386,6 +1408,9 @@
1386
1408
  <optional>
1387
1409
  <attribute name="number"/>
1388
1410
  </optional>
1411
+ <optional>
1412
+ <attribute name="branch-number"/>
1413
+ </optional>
1389
1414
  <optional>
1390
1415
  <attribute name="obligation">
1391
1416
  <choice>
@@ -1609,6 +1634,9 @@
1609
1634
  <optional>
1610
1635
  <attribute name="number"/>
1611
1636
  </optional>
1637
+ <optional>
1638
+ <attribute name="branch-number"/>
1639
+ </optional>
1612
1640
  <optional>
1613
1641
  <attribute name="type"/>
1614
1642
  </optional>
@@ -1660,6 +1688,9 @@
1660
1688
  <optional>
1661
1689
  <attribute name="number"/>
1662
1690
  </optional>
1691
+ <optional>
1692
+ <attribute name="branch-number"/>
1693
+ </optional>
1663
1694
  <optional>
1664
1695
  <ref name="section-title"/>
1665
1696
  </optional>
@@ -1757,6 +1788,9 @@
1757
1788
  <optional>
1758
1789
  <attribute name="number"/>
1759
1790
  </optional>
1791
+ <optional>
1792
+ <attribute name="branch-number"/>
1793
+ </optional>
1760
1794
  <optional>
1761
1795
  <attribute name="obligation">
1762
1796
  <choice>
@@ -61,6 +61,15 @@ module Metanorma
61
61
  end
62
62
  end
63
63
 
64
+ class ColumnBreakBlockMacro < Asciidoctor::Extensions::BlockMacroProcessor
65
+ use_dsl
66
+ named :columnbreak
67
+
68
+ def process(parent, _reader, _attrs)
69
+ create_pass_block parent, "<columnbreak/>", {}, subs: nil
70
+ end
71
+ end
72
+
64
73
  # refer https://github.com/asciidoctor/asciidoctor/blob/main/lib/asciidoctor/substitutors.rb
65
74
  # Not using TreeProcessor because that is still too close to
66
75
  # inline expressions being processed on access (e.g. titles)
@@ -88,7 +97,8 @@ module Metanorma
88
97
 
89
98
  def pass_status(status, text)
90
99
  text == "++++" && !status[:delimln] and status[:pass] = !status[:pass]
91
- if status[:is_delim] && /^(-+|\*+|=+|_+)$/.match?(text)
100
+ if (status[:is_delim] && /^(-+|\*+|=+|_+)$/.match?(text)) ||
101
+ (!status[:is_delim] && !status[:delimln] && text == "----")
92
102
  status[:delimln] = text
93
103
  status[:pass] = true
94
104
  elsif status[:pass_delim]
@@ -32,6 +32,7 @@ module Metanorma
32
32
  end
33
33
 
34
34
  def output(isodoc_node, inname, outname, format, options = {})
35
+ options_preprocess(options)
35
36
  case format
36
37
  when :html
37
38
  options = options
@@ -142,7 +142,12 @@ module Metanorma
142
142
  nil
143
143
  end
144
144
 
145
+ def supply_ref_prefix(ret)
146
+ ret
147
+ end
148
+
145
149
  def fetch_ref1(code, year, opts)
150
+ code = supply_ref_prefix(code)
146
151
  if opts[:localfile]
147
152
  @local_bibdb.get(code, opts[:localfile])
148
153
  else @bibdb&.fetch(code, year, opts)
@@ -156,6 +161,7 @@ module Metanorma
156
161
  end
157
162
 
158
163
  def fetch_ref_async(ref, idx, res)
164
+ ref[:code] &&= supply_ref_prefix(ref[:code])
159
165
  if unfetchable_ref_code?(ref)
160
166
  res << [ref, idx, nil]
161
167
  idx += 1
@@ -91,7 +91,7 @@ module Metanorma
91
91
  pdf-allow-print pdf-allow-print-hq
92
92
  pdf-allow-access-content pdf-encrypt-metadata fonts
93
93
  font-license-agreement).each_with_object({}) do |x, m|
94
- m[x.gsub(/-/, "").to_i] = node.attr(x)
94
+ m[x.gsub("-", "").to_i] = node.attr(x)
95
95
  end
96
96
 
97
97
  pdf_options.merge(fonts_manifest_option(node) || {})
@@ -102,7 +102,9 @@ module Metanorma
102
102
  end
103
103
 
104
104
  def presentation_xml_converter(node)
105
- IsoDoc::PresentationXMLConvert.new(html_extract_attributes(node))
105
+ IsoDoc::PresentationXMLConvert
106
+ .new(html_extract_attributes(node)
107
+ .merge(output_formats: ::Metanorma::Standoc::Processor.new.output_formats) )
106
108
  end
107
109
 
108
110
  def default_fonts(node)
@@ -84,6 +84,7 @@ module Metanorma
84
84
  language: node.attributes["language"],
85
85
  script: node.attributes["script"],
86
86
  number: node.attributes["number"],
87
+ "branch-number": node.attributes["branch-number"],
87
88
  type: node.attributes["type"],
88
89
  annex: (if (node.attr("style") == "appendix" ||
89
90
  node.role == "appendix") &&
@@ -69,11 +69,11 @@ module Metanorma
69
69
  end
70
70
 
71
71
  def xml_encode(text)
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;", "'")
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;", "'")
77
77
  end
78
78
 
79
79
  # wrapped in <sections>
@@ -104,6 +104,10 @@ module Metanorma
104
104
  psi|omega)\b/xi, "&\\1;")
105
105
  end
106
106
 
107
+ def refid?(ref)
108
+ @refids.include? ref
109
+ end
110
+
107
111
  module_function :adoc2xml
108
112
 
109
113
  class EmptyAttr
@@ -19,6 +19,6 @@ module Metanorma
19
19
  end
20
20
 
21
21
  module Standoc
22
- VERSION = "2.6.1".freeze
22
+ VERSION = "2.6.3".freeze
23
23
  end
24
24
  end
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
31
31
  spec.add_dependency "addressable", "~> 2.8.0"
32
32
  spec.add_dependency "asciidoctor", "~> 2.0.0"
33
33
  spec.add_dependency "iev", "~> 0.3.0"
34
- spec.add_dependency "isodoc", "~> 2.6.3"
34
+ spec.add_dependency "isodoc", "~> 2.7.0"
35
35
  spec.add_dependency "metanorma", ">= 1.6.0"
36
36
  spec.add_dependency "metanorma-plugin-datastruct", "~> 0.2.0"
37
37
  spec.add_dependency "metanorma-plugin-glossarist", "~> 0.1.1"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma-standoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.1
4
+ version: 2.6.3
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-10-09 00:00:00.000000000 Z
11
+ date: 2023-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 2.6.3
61
+ version: 2.7.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 2.6.3
68
+ version: 2.7.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: metanorma
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -466,11 +466,13 @@ files:
466
466
  - lib/isodoc/pdf_convert.rb
467
467
  - lib/metanorma-standoc.rb
468
468
  - lib/metanorma/standoc.rb
469
+ - lib/metanorma/standoc/anchor.rb
469
470
  - lib/metanorma/standoc/base.rb
470
471
  - lib/metanorma/standoc/basicdoc.rng
471
472
  - lib/metanorma/standoc/biblio-standoc.rng
472
473
  - lib/metanorma/standoc/biblio.rng
473
474
  - lib/metanorma/standoc/blocks.rb
475
+ - lib/metanorma/standoc/blocks_image.rb
474
476
  - lib/metanorma/standoc/blocks_notes.rb
475
477
  - lib/metanorma/standoc/cleanup.rb
476
478
  - lib/metanorma/standoc/cleanup_amend.rb