metanorma-standoc 2.6.1 → 2.6.3

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: 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