metanorma-standoc 2.9.2 → 2.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: afbcf21ea1b8e99868178616c755a4dcef811f631326c65f6835ad491d1f2835
4
- data.tar.gz: 9d3499adf6025521d2683f4456e64b1cd27dd63722c231de8fab7aa47fe79973
3
+ metadata.gz: 49c6dfeea46b38b2e162f13b0e5b8f1e57f446c433e2e30313fff2e4c5b4e96e
4
+ data.tar.gz: 188590c9c73a87e1ba73322a540986836b256541764ef4e45ba1a1a134eda1df
5
5
  SHA512:
6
- metadata.gz: 46a8beb31cb6230dccdcdb36352dd05e705a3114d0b1b6e04b46b1a445aa1fe30249426c81be8a441f615c95fe633cc078bd70c030616cdc25ff4c50eb45ab76
7
- data.tar.gz: 300aeca29fa514e88535c4f60577f9a6e83446f195b76e7e15029ae912d0beb06c0f6f028b098e4662ab53fbf83fc8e675a920ef7c3269f1e501afa835ba127f
6
+ metadata.gz: cc6aed2b8ca43330882c41c8a00e2bc679ff5de30e9c1f914eca253ecc7900368b4c1968a2dbeceeae9db025798a15fe73a68892d83c4c0dcc6080477e66327a
7
+ data.tar.gz: 0bf3a151f8dd22a2c28ee6ed158df5f8d8c6f2afe0d27cad2d8ec3234746d1994354ab52dbd1735b8c54ab99e44c3d3b7b10249a464205fc29c453d996e377c9
@@ -229,6 +229,46 @@ h6:hover > a.anchor,
229
229
  .inline-header:hover > a.anchor {
230
230
  visibility: visible; }
231
231
 
232
+ /* collapsible snippets: collapsible before hidable */
233
+ .hidable {
234
+ max-height: 0;
235
+ overflow: hidden;
236
+ transition: max-height 0.2s ease-out; }
237
+
238
+ .collapsible {
239
+ background-color: #777;
240
+ color: white;
241
+ cursor: pointer;
242
+ padding: 12px 0;
243
+ margin: 0;
244
+ width: 100%;
245
+ border: none;
246
+ text-align: left;
247
+ outline: none;
248
+ font-size: 15px; }
249
+
250
+ .active, .collapsible:hover {
251
+ background-color: #555; }
252
+
253
+ .collapsible:after {
254
+ content: '\25bc';
255
+ color: white;
256
+ font-weight: bold;
257
+ float: right;
258
+ margin-left: 12px;
259
+ margin-right: 12px; }
260
+
261
+ .active:after {
262
+ content: "\25b2"; }
263
+
264
+ /* collapsible: */
265
+ .collapsible + .hidable {
266
+ margin-top: 0; }
267
+
268
+ .collapsible:not(.active) + .hidable {
269
+ overflow: hidden;
270
+ padding: 0; }
271
+
232
272
  #brochure-band {
233
273
  background-color: #0AC442; }
234
274
 
@@ -15,7 +15,7 @@ module Metanorma
15
15
  def inline_anchor_ref(node)
16
16
  noko do |xml|
17
17
  xml.bookmark nil, **attr_code(id: node.id)
18
- end.join
18
+ end
19
19
  end
20
20
 
21
21
  def inline_anchor_xref(node)
@@ -26,7 +26,7 @@ module Metanorma
26
26
  xml.xref **attr_code(attrs) do |x|
27
27
  x << c
28
28
  end
29
- end.join
29
+ end
30
30
  end
31
31
 
32
32
  def inline_anchor_xref_attrs(node)
@@ -83,7 +83,7 @@ module Metanorma
83
83
  xml.link **attr_code(attributes) do |l|
84
84
  l << contents
85
85
  end
86
- end.join
86
+ end
87
87
  end
88
88
 
89
89
  def inline_anchor_link_attrs(node)
@@ -103,7 +103,7 @@ module Metanorma
103
103
  xml.ref **attr_code(id: node.target || node.id) do |r|
104
104
  r << eref_contents
105
105
  end
106
- end.join
106
+ end
107
107
  end
108
108
 
109
109
  def inline_anchor_bibref_contents(node)
@@ -114,7 +114,7 @@ module Metanorma
114
114
  def inline_callout(node)
115
115
  noko do |xml|
116
116
  xml.callout node.text
117
- end.join
117
+ end
118
118
  end
119
119
 
120
120
  def inline_footnote(node)
@@ -124,7 +124,7 @@ module Metanorma
124
124
  xml.fn reference: @fn_number do |fn|
125
125
  fn.p { |p| p << node.text }
126
126
  end
127
- end.join
127
+ end
128
128
  end
129
129
  end
130
130
  end
@@ -90,7 +90,7 @@ module Metanorma
90
90
  )) do |ex|
91
91
  wrap_in_para(node, ex)
92
92
  end
93
- end.join("")
93
+ end
94
94
  end
95
95
 
96
96
  def example(node)
@@ -128,7 +128,7 @@ module Metanorma
128
128
  figure_title(node, ex)
129
129
  wrap_in_para(node, ex)
130
130
  end
131
- end.join("")
131
+ end
132
132
  end
133
133
 
134
134
  def example_attrs(node)
@@ -141,7 +141,7 @@ module Metanorma
141
141
  node.title.nil? or ex.name { |name| name << node.title }
142
142
  wrap_in_para(node, ex)
143
143
  end
144
- end.join("")
144
+ end
145
145
  end
146
146
 
147
147
  def para_attrs(node)
@@ -158,7 +158,7 @@ module Metanorma
158
158
  xml.p **para_attrs(node) do |xml_t|
159
159
  xml_t << node.content
160
160
  end
161
- end.join("")
161
+ end
162
162
  end
163
163
 
164
164
  def quote_attrs(node)
@@ -183,7 +183,7 @@ module Metanorma
183
183
  quote_attribution(node, q)
184
184
  wrap_in_para(node, q)
185
185
  end
186
- end.join("")
186
+ end
187
187
  end
188
188
 
189
189
  def listing_attrs(node)
@@ -212,7 +212,8 @@ module Metanorma
212
212
  noko do |xml|
213
213
  xml.passthrough **attr_code(formats:
214
214
  node.attr("format") || "metanorma") do |p|
215
- p << @c.encode(@c.decode(node.content), :basic, :hexadecimal)
215
+ # p << @c.encode(@c.decode(node.content), :basic, :hexadecimal)
216
+ p << @c.encode(node.content, :basic, :hexadecimal)
216
217
  end
217
218
  end
218
219
  end
@@ -17,7 +17,7 @@ module Metanorma
17
17
  figure_title(node, ex)
18
18
  ex << node.content
19
19
  end
20
- end.join("\n")
20
+ end
21
21
  end
22
22
 
23
23
  def figure_example(node)
@@ -26,7 +26,7 @@ module Metanorma
26
26
  node.title.nil? or ex.name { |name| name << node.title }
27
27
  wrap_in_para(node, ex)
28
28
  end
29
- end.join("")
29
+ end
30
30
  end
31
31
 
32
32
  def figure_title(node, out)
@@ -32,7 +32,7 @@ module Metanorma
32
32
  xml.review **sidebar_attrs(node) do |r|
33
33
  wrap_in_para(node, r)
34
34
  end
35
- end.join("")
35
+ end
36
36
  end
37
37
 
38
38
  def todo_attrs(node)
@@ -49,7 +49,7 @@ module Metanorma
49
49
  xml.review **todo_attrs(node) do |r|
50
50
  wrap_in_para(node, r)
51
51
  end
52
- end.join("")
52
+ end
53
53
  end
54
54
 
55
55
  def termnote(node)
@@ -57,7 +57,7 @@ module Metanorma
57
57
  xml.termnote **termnote_attrs(node) do |ex|
58
58
  wrap_in_para(node, ex)
59
59
  end
60
- end.join("")
60
+ end
61
61
  end
62
62
 
63
63
  def note(node)
@@ -67,7 +67,7 @@ module Metanorma
67
67
  xml.note **note_attrs(node) do |c|
68
68
  wrap_in_para(node, c)
69
69
  end
70
- end.join("")
70
+ end
71
71
  end
72
72
 
73
73
  def boilerplate_note(node)
@@ -101,7 +101,7 @@ module Metanorma
101
101
  node.title.nil? or a.name { |name| name << node.title }
102
102
  wrap_in_para(node, a)
103
103
  end
104
- end.join("")
104
+ end
105
105
  end
106
106
 
107
107
  def admonition_alternatives(node)
@@ -82,6 +82,7 @@ module Metanorma
82
82
  boilerplate_cleanup(xmldoc)
83
83
  toc_cleanup(xmldoc)
84
84
  smartquotes_cleanup(xmldoc)
85
+ linebreak_cleanup(xmldoc)
85
86
  variant_cleanup(xmldoc)
86
87
  para_cleanup(xmldoc)
87
88
  empty_element_cleanup(xmldoc)
@@ -137,7 +138,7 @@ module Metanorma
137
138
  end
138
139
 
139
140
  def element_name_cleanup(xmldoc)
140
- xmldoc.traverse { |n| n.name = n.name.gsub("_", "-") }
141
+ xmldoc.traverse { |n| n.name = n.name.tr("_", "-") }
141
142
  end
142
143
 
143
144
  # allows us to deal with doc relation localities,
@@ -144,8 +144,7 @@ module Metanorma
144
144
  yaml.is_a?(Hash) && !yaml["contributor"] and yaml = [yaml]
145
145
  yaml.is_a?(Array) and yaml = { "contributor" => yaml }
146
146
  r = yaml2relaton(yaml)
147
- Nokogiri::XML(r).xpath("//contributor").reverse
148
- .each do |c|
147
+ Nokogiri::XML(r).xpath("//contributor").reverse_each do |c|
149
148
  ins.next = c
150
149
  end
151
150
  end
@@ -161,10 +161,12 @@ module Metanorma
161
161
  def datauri_attachment(path, doc)
162
162
  @datauriattachment or return
163
163
  m = add_misc_container(doc)
164
- f = File.basename(path)
165
- d = Vectory::Utils::datauri(path, @localdir)
166
- m << "<attachment name='#{f}'/>"
167
- m.last_element_child << d
164
+ f = File.join(@attachmentsdir, File.basename(path))
165
+ f = Pathname.new(File.expand_path(f))
166
+ .relative_path_from(Pathname.new(File.expand_path(@localdir)))
167
+ e = (m << "<attachment name='#{f}'/>").last_element_child
168
+ Vectory::Utils::datauri(path, @localdir).scan(/.{1,60}/)
169
+ .each { |dd| e << "#{dd}\n" }
168
170
  end
169
171
 
170
172
  def valid_attachment?(path, bib)
@@ -183,8 +185,28 @@ module Metanorma
183
185
  FileUtils.mkdir_p(@attachmentsdir)
184
186
  end
185
187
 
188
+ # remove dupes if both same ID and same docid, in case dupes introduced
189
+ # through termbases
190
+ def remove_dup_bibtem_id(xmldoc)
191
+ bibitem_id_docid_hash(xmldoc).each_value do |v|
192
+ v.each_value do |v1|
193
+ v1[1..].each(&:remove)
194
+ end
195
+ end
196
+ end
197
+
198
+ def bibitem_id_docid_hash(xmldoc)
199
+ xmldoc.xpath("//bibitem[@id]").each_with_object({}) do |b, m|
200
+ m[b["id"]] ||= {}
201
+ docid = b.at("./docidentifier")&.text || "NO ID"
202
+ m[b["id"]][docid] ||= []
203
+ m[b["id"]][docid] << b
204
+ end
205
+ end
206
+
186
207
  def bibitem_cleanup(xmldoc)
187
- bibitem_nested_id(xmldoc)
208
+ bibitem_nested_id(xmldoc) # feeds remove_dup_bibtem_id
209
+ remove_dup_bibtem_id(xmldoc)
188
210
  ref_dl_cleanup(xmldoc)
189
211
  formattedref_spans(xmldoc)
190
212
  fetch_local_bibitem(xmldoc)
@@ -10,7 +10,7 @@ module Metanorma
10
10
  def symbol_key(sym)
11
11
  @c.decode(asciimath_key(sym).text)
12
12
  .gsub(/[\[\]{}<>()]/, "").gsub(/\s/m, "")
13
- .gsub(/[[:punct:]]|[_^]/, ":\\0").gsub("`", "")
13
+ .gsub(/[[:punct:]]|[_^]/, ":\\0").delete("`")
14
14
  .gsub(/[0-9]+/, "þ\\0")
15
15
  .tr("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz",
16
16
  "ABCFEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
@@ -46,7 +46,7 @@ module Metanorma
46
46
  %w(absent geographic-area).each do |a|
47
47
  dl_to_attrs(prev, dlist, a)
48
48
  end
49
- %w(field-of-application usage-info).reverse.each do |a|
49
+ %w(field-of-application usage-info).reverse_each do |a|
50
50
  dl_to_elems(prev.at("./expression"), prev, dlist, a)
51
51
  end
52
52
  end
@@ -78,7 +78,7 @@ module Metanorma
78
78
  end
79
79
 
80
80
  def term_dl_to_expression_name_metadata(prev, dlist)
81
- %w(abbreviation-type pronunciation).reverse.each do |a|
81
+ %w(abbreviation-type pronunciation).reverse_each do |a|
82
82
  dl_to_elems(prev.at("./expression/name"), prev, dlist, a)
83
83
  end
84
84
  g = dlist.at("./dt[text()='grammar']/following::dd//dl") and
@@ -89,7 +89,7 @@ module Metanorma
89
89
  prev.at(".//expression") or return
90
90
  prev.at(".//expression") << "<grammar><sentinel/></grammar>"
91
91
  %w(gender number isPreposition isParticiple isAdjective isAdverb isNoun
92
- grammar-value).reverse.each do |a|
92
+ grammar-value).reverse_each do |a|
93
93
  dl_to_elems(prev.at(".//expression/grammar/*"), prev.elements.last,
94
94
  dlist, a)
95
95
  end
@@ -11,6 +11,54 @@ module Metanorma
11
11
  text
12
12
  end
13
13
 
14
+ def ancestor_include?(elem, ancestors)
15
+ path = elem.path.gsub(/\[\d+\]/, "").split(%r{/})[1..-2]
16
+ !path.intersection(ancestors).empty?
17
+ end
18
+
19
+ def linebreak_cleanup(xmldoc)
20
+ xmldoc.traverse do |x|
21
+ x.text? && x.text.include?("\n") or next
22
+ ancestor_include?(x, PRESERVE_LINEBREAK_ELEMENTS) and next
23
+ ancestor_include?(x, STRIP_LINEBREAK_ELEMENTS) or next
24
+ x.replace(Metanorma::Utils
25
+ .line_sanitise(x.text.lines.map(&:rstrip)).join)
26
+ end
27
+ end
28
+
29
+ # process example/p, example/sourcecode, not example on its own:
30
+ # this is about stripping lines for blocks containing inline elems & text
31
+ def linebreak_cleanup(xmldoc)
32
+ xmldoc.xpath(STRIP_LINEBREAK_ELEMENTS.map { |e| "//#{e}" }.join(" | "))
33
+ .each do |b|
34
+ b.xpath(STRIP_LINEBREAK_ELEMENTS.map { |e| ".//#{e}" }.join(" | "))
35
+ .empty? or next
36
+ linebreak_cleanup_block(gather_text_for_linebreak_cleanup(b))
37
+ end
38
+ end
39
+
40
+ def linebreak_cleanup_block(block)
41
+ block.each_with_index do |e, i|
42
+ e[:skip] and next
43
+ lines = e[:text].lines.map(&:rstrip)
44
+ e[:last] or lines << block[i + 1][:text].lines.first # next token context
45
+ out = Metanorma::Utils.line_sanitise(lines)
46
+ e[:last] or out.pop
47
+ e[:elem].replace(out.join)
48
+ end
49
+ end
50
+
51
+ def gather_text_for_linebreak_cleanup(block)
52
+ x = block.xpath(".//text()").map do |e|
53
+ { elem: e, text: e.text,
54
+ skip: ancestor_include?(e, PRESERVE_LINEBREAK_ELEMENTS) }
55
+ end
56
+ x.empty? and return x
57
+ x.each { |e| e[:skip] ||= !e[:text].include?("\n") }
58
+ x[-1][:last] = true
59
+ x
60
+ end
61
+
14
62
  def smartquotes_cleanup(xmldoc)
15
63
  xmldoc.xpath("//date").each { |d| Metanorma::Utils::endash_date(d) }
16
64
  if @smartquotes then smartquotes_cleanup1(xmldoc)
@@ -37,10 +85,20 @@ module Metanorma
37
85
  %w(pre tt sourcecode stem asciimath figure bibdata passthrough
38
86
  identifier metanorma-extension).freeze
39
87
 
88
+ PRESERVE_LINEBREAK_ELEMENTS =
89
+ %w(pre sourcecode passthrough metanorma-extension).freeze
90
+
91
+ STRIP_LINEBREAK_ELEMENTS =
92
+ %w(title name variant-title figure example review admonition
93
+ note li th td dt dd p quote label annotation
94
+ preferred admitted related deprecates field-of-application
95
+ usage-info expression pronunciation grammar-value domain
96
+ definition termnote termexample modification description
97
+ newcontent floating-title).freeze
98
+
40
99
  def uninterrupt_quotes_around_xml_skip(elem)
41
100
  !(/\A['"]/.match?(elem.text) &&
42
- elem.previous.path.gsub(/\[\d+\]/, "").split(%r{/})[1..-2]
43
- .intersection(IGNORE_QUOTES_ELEMENTS).empty? &&
101
+ !ancestor_include?(elem.previous, IGNORE_QUOTES_ELEMENTS) &&
44
102
  ((elem.previous.text.strip.empty? &&
45
103
  !empty_tag_with_text_content?(elem.previous)) ||
46
104
  ignoretext?(elem.previous)))
@@ -50,6 +108,7 @@ module Metanorma
50
108
  prev = elem.at(".//preceding::text()[1]") or return
51
109
  /\S\Z/.match?(prev.text) or return
52
110
  foll = elem.at(".//following::text()[1]")
111
+ /"$/.match?(prev.text) and /^"/.match?(foll&.text) and return # "<tag/>"
53
112
  m = /\A(["'][[:punct:]]*)(\s|\Z)/
54
113
  .match(@c.decode(foll&.text)) or return
55
114
  foll.content = foll.text.sub(/\A(["'][[:punct:]]*)/, "")
@@ -69,7 +128,7 @@ module Metanorma
69
128
  abstract preferred admitted related deprecates field-of-application
70
129
  usage-info expression pronunciation grammar-value domain
71
130
  definition termnote termexample modification description
72
- newcontent floating-title tab).include? elem.name
131
+ newcontent floating-title tab review admonition annotation).include? elem.name
73
132
  end
74
133
 
75
134
  def empty_tag_with_text_content?(elem)
@@ -83,8 +142,9 @@ module Metanorma
83
142
  empty_tag_with_text_content?(x) and prev = "dummy"
84
143
  x.text? or next
85
144
 
86
- ancestors = x.path.gsub(/\[\d+\]/, "").split(%r{/})[1..-2]
87
- ancestors.intersection(IGNORE_QUOTES_ELEMENTS).empty? or next
145
+ # ancestors = x.path.gsub(/\[\d+\]/, "").split(%r{/})[1..-2]
146
+ # ancestors.intersection(IGNORE_QUOTES_ELEMENTS).empty? or next
147
+ ancestor_include?(x, IGNORE_QUOTES_ELEMENTS) and next
88
148
  dumb2smart_quotes1(x, prev)
89
149
  prev = x.text
90
150
  end
@@ -10,7 +10,7 @@ module Metanorma
10
10
 
11
11
  def toc_cleanup_para(xmldoc)
12
12
  xmldoc.xpath("//p[toc]").each do |x|
13
- x.xpath("./toc").reverse.each do |t|
13
+ x.xpath("./toc").reverse_each do |t|
14
14
  x.next = t
15
15
  end
16
16
  x.remove if x.text.strip.empty?
@@ -29,7 +29,10 @@ module Metanorma
29
29
  inline_macro Metanorma::Plugin::Lutaml::LutamlFigureInlineMacro
30
30
  inline_macro Metanorma::Plugin::Lutaml::LutamlTableInlineMacro
31
31
  block_macro Metanorma::Plugin::Lutaml::LutamlDiagramBlockMacro
32
+ block_macro Metanorma::Plugin::Lutaml::LutamlEaDiagramBlockMacro
32
33
  block Metanorma::Plugin::Lutaml::LutamlDiagramBlock
34
+ block_macro Metanorma::Plugin::Lutaml::LutamlGmlDictionaryBlockMacro
35
+ block Metanorma::Plugin::Lutaml::LutamlGmlDictionaryBlock
33
36
  preprocessor Metanorma::Standoc::EmbedIncludeProcessor
34
37
  preprocessor Metanorma::Standoc::LinkProtectPreprocessor
35
38
  preprocessor Metanorma::Standoc::Datamodel::AttributesTablePreprocessor
@@ -21,8 +21,8 @@ module Metanorma
21
21
  def render
22
22
  ERB.new(
23
23
  File.read(
24
- File.join(TEMPLATES_PATH, "plantuml_representation.adoc.erb")
25
- )
24
+ File.join(TEMPLATES_PATH, "plantuml_representation.adoc.erb"),
25
+ ),
26
26
  ).result(binding)
27
27
  end
28
28
 
@@ -46,7 +46,7 @@ module Metanorma
46
46
  '******* CLASS DEFINITIONS ********************************************
47
47
  #{join_as_plantuml(
48
48
  classes_to_classes_plantuml(yml['classes']),
49
- enums_to_enums_plantuml(yml['enums'])
49
+ enums_to_enums_plantuml(yml['enums']),
50
50
  )}
51
51
  TEMPLATE
52
52
  end
@@ -57,7 +57,7 @@ module Metanorma
57
57
  <<~TEMPLATE
58
58
  '******* CLASS GROUPS *************************************************
59
59
  #{join_as_plantuml(
60
- groups_to_plantuml(yml['groups'])
60
+ groups_to_plantuml(yml['groups']),
61
61
  )}
62
62
  TEMPLATE
63
63
  end
@@ -69,7 +69,7 @@ module Metanorma
69
69
  '******* CLASS RELATIONS **********************************************
70
70
  #{join_as_plantuml(
71
71
  classes_to_relations_plantuml(yml['classes']),
72
- relations_to_plantuml(nil, yml['relations'])
72
+ relations_to_plantuml(nil, yml['relations']),
73
73
  )}
74
74
  TEMPLATE
75
75
  end
@@ -80,7 +80,7 @@ module Metanorma
80
80
  <<~TEMPLATE
81
81
  '******* DIAGRAM SPECIFIC CONFIG **************************************
82
82
  #{join_as_plantuml(
83
- diagram_options_to_plantuml(yml['diagram_options'])
83
+ diagram_options_to_plantuml(yml['diagram_options']),
84
84
  )}
85
85
  TEMPLATE
86
86
  end
@@ -122,7 +122,7 @@ module Metanorma
122
122
  class #{class_name}#{model_stereotype_to_plantuml(class_hash['type'])} {
123
123
  #{join_as_plantuml(
124
124
  attributes_to_plantuml(class_hash['attributes']),
125
- constraints_to_plantuml(class_hash['constraints'])
125
+ constraints_to_plantuml(class_hash['constraints']),
126
126
  )}
127
127
  }
128
128
  TEMPLATE
@@ -165,7 +165,7 @@ module Metanorma
165
165
  <<~TEMPLATE
166
166
  __ constraints __
167
167
  #{join_as_plantuml(
168
- *constraints_output
168
+ *constraints_output,
169
169
  )}
170
170
  TEMPLATE
171
171
  end
@@ -218,14 +218,14 @@ module Metanorma
218
218
 
219
219
  def source_arrow_end(source, relationship)
220
220
  source_attribute = relationship_cardinality_to_plantuml(
221
- relationship["source"]["attribute"]
221
+ relationship["source"]["attribute"],
222
222
  )
223
223
  [source, source_attribute].join(" ")
224
224
  end
225
225
 
226
226
  def target_arrow_end(target, relationship, action)
227
227
  target_attribute = relationship_cardinality_to_plantuml(
228
- relationship["target"]["attribute"]
228
+ relationship["target"]["attribute"],
229
229
  )
230
230
  [
231
231
  [target_attribute, target].join(" "),
@@ -283,7 +283,7 @@ module Metanorma
283
283
  if attribute_cardinality
284
284
  cardinality = attribute_cardinality_plantuml(
285
285
  attribute_cardinality,
286
- false
286
+ false,
287
287
  )
288
288
  cardinality = " #{cardinality}"
289
289
  end
@@ -11,19 +11,19 @@ module Metanorma
11
11
  noko do |xml|
12
12
  xml << node.text
13
13
  xml.br
14
- end.join
14
+ end
15
15
  end
16
16
 
17
17
  def page_break(node)
18
18
  attrs = {}
19
19
  node.option?("landscape") and attrs[:orientation] = "landscape"
20
20
  node.option?("portrait") and attrs[:orientation] = "portrait"
21
- noko { |xml| xml.pagebreak **attr_code(attrs) }.join
21
+ noko { |xml| xml.pagebreak **attr_code(attrs) }
22
22
  end
23
23
 
24
24
  def thematic_break(_node)
25
25
  # noko(&:hr).join # Do not do this, noko blows up
26
- noko { |xml| xml.hr }.join # rubocop:disable Style/SymbolProc
26
+ noko { |xml| xml.hr } # rubocop:disable Style/SymbolProc
27
27
  end
28
28
 
29
29
  def latex_parse1(text, block)
@@ -102,7 +102,7 @@ module Metanorma
102
102
  xml << node.text
103
103
  end
104
104
  end
105
- end.join
105
+ end
106
106
  end
107
107
 
108
108
  def hash2styles(role)
@@ -146,7 +146,7 @@ module Metanorma
146
146
  def inline_image(node)
147
147
  noko do |xml|
148
148
  xml.image **image_attributes(node)
149
- end.join
149
+ end
150
150
  end
151
151
 
152
152
  def inline_indexterm(node)
@@ -154,7 +154,7 @@ module Metanorma
154
154
  node.type == :visible and xml << node.text
155
155
  terms = (node.attr("terms") || [node.text]).map { |x| xml_encode(x) }
156
156
  inline_indexterm1(xml, terms)
157
- end.join
157
+ end
158
158
  end
159
159
 
160
160
  def inline_indexterm1(xml, terms)
@@ -41,7 +41,7 @@ module Metanorma
41
41
  list_caption(node, xml_ul)
42
42
  node.items.each { |item| ul_li(xml_ul, item) }
43
43
  end
44
- end.join("")
44
+ end
45
45
  end
46
46
 
47
47
  def olist_style(style)
@@ -67,7 +67,7 @@ module Metanorma
67
67
  list_caption(node, xml_ol)
68
68
  node.items.each { |item| li(xml_ol, item) }
69
69
  end
70
- end.join("")
70
+ end
71
71
  end
72
72
 
73
73
  def dt(terms, xml_dl)
@@ -107,7 +107,7 @@ module Metanorma
107
107
  dd(dd, xml_dl)
108
108
  end
109
109
  end
110
- end.join("")
110
+ end
111
111
  end
112
112
 
113
113
  def colist(node)
@@ -117,7 +117,7 @@ module Metanorma
117
117
  xml_li.p { |p| p << item.text }
118
118
  end
119
119
  end
120
- end.join("")
120
+ end
121
121
  end
122
122
 
123
123
  def list_caption(node, out)
@@ -24,7 +24,7 @@ module Metanorma
24
24
  def init_indent(line)
25
25
  /^(?<prefix>[ \t]*)(?<suffix>.*)$/ =~ line
26
26
  prefix = prefix.gsub("\t", "\u00a0\u00a0\u00a0\u00a0")
27
- .gsub(/ /, "\u00a0")
27
+ .tr(" ", "\u00a0")
28
28
  prefix + suffix
29
29
  end
30
30
 
@@ -126,19 +126,49 @@ module Metanorma
126
126
 
127
127
  def inlinelink_escape(text)
128
128
  text.gsub(InlineLinkRx) do
129
- body, suffix = $4.nil? ? [$3 + $6, "[]"] : [$3, ""]
130
- p = $1 and s = $2 and b = $4
131
- if p == "link:" then "#{p}++#{s}#{body}++#{b}#{suffix}"
132
- elsif p == "<"
133
- "#{p}link:++#{s}#{body.sub(/>$/, '')}++#{b}#{suffix}>"
134
- else "#{p}link:++#{s}#{body}++#{b}#{suffix}"
129
+ p = $1 and s = $2 and body = $3
130
+ suffix = $4.nil? ? "[]" : ""
131
+ wrapper = $6
132
+ if (!/^(&lt;|[<\(\["'])$/.match?($1) || $6 != BRACKETS[$1]) && $4.nil?
133
+ body += $6
134
+ wrapper = ""
135
135
  end
136
+ # body, suffix = $4.nil? ? [$3 + $6, "[]"] : [$3, ""]
137
+ b = linkcontents_escape($4)
138
+ if p == "link:"
139
+ "#{p}++#{s}#{body}++#{b}#{suffix}"
140
+ else
141
+ "#{p}link:++#{s}#{body}++#{b}#{suffix}#{wrapper}"
142
+ end
143
+ end
144
+ end
145
+
146
+ BRACKETS = {
147
+ "<" => ">",
148
+ "&lt;" => "&gt;",
149
+ "[" => "]",
150
+ '"' => '"',
151
+ "'" => "'",
152
+ }.freeze
153
+
154
+ # because links are escaped, https within link text also need
155
+ # to be escaped, # otherwise they will be treated as links themselves
156
+ def linkcontents_escape(text)
157
+ text.nil? and return nil
158
+ text
159
+ # .gsub(InlineLinkMacroRx) do
160
+ # $1.empty? ? "\\#{$2}#{$3}#{$4}" : text
161
+ # end
162
+ .gsub(InlineLinkRx) do
163
+ esc = $1 == "link:" ? "" : "\\"
164
+ x = $4 || "#{$5}#{$6}"
165
+ "#{$1}#{esc}#{$2}#{$3}#{x}"
136
166
  end
137
167
  end
138
168
 
139
169
  # InlineLinkMacroRx = /\\?(?:link|(mailto)):(|[^:\s\[][^\s\[]*)\[(|#{CC_ALL}*?[^\\])\]/m
140
170
  InlineLinkMacroRx1 = <<~REGEX.freeze
141
- (\\\\?\\b(?<!-) # optional backslash, no hyphen, word boundary
171
+ (\\\\?)(\\b(?<!-) # optional backslash, no hyphen, word boundary
142
172
  (?:link|mailto):) # link: or mailto:
143
173
  (?!\\+) # no link:+ passthrough
144
174
  (|[^:\\s\\[][^\\s\\[]*) # link: ... up to [
@@ -151,7 +181,7 @@ module Metanorma
151
181
  ((text.include? "link:") || (text.include? "ilto:"))) or return text
152
182
  pass_inline_split(text) do |x|
153
183
  x.gsub(InlineLinkMacroRx) do
154
- "#{$1}++#{$2}++#{$3}"
184
+ "#{$1}#{$2}++#{$3}++#{linkcontents_escape($4)}"
155
185
  end
156
186
  end.join
157
187
  end
@@ -24,7 +24,7 @@ module Metanorma
24
24
 
25
25
  def references2xml(ret)
26
26
  out = ret.map do |b|
27
- b.nil? ? nil : noko { |xml| reference1out(b, xml) }.join
27
+ b.nil? ? nil : noko { |xml| reference1out(b, xml) }
28
28
  end
29
29
  out.map { |x| x.nil? ? nil : Nokogiri::XML(x).root }
30
30
  end
@@ -34,7 +34,7 @@ module Metanorma
34
34
 
35
35
  def requirement_validate(docxml)
36
36
  docxml.xpath("//requirement | //recommendation | //permission")
37
- .each_with_object([]) do |r, m|
37
+ .each do |r|
38
38
  @reqt_models.model(r["model"]).validate(r, @log)
39
39
  end
40
40
  end
@@ -141,7 +141,7 @@ module Metanorma
141
141
  clause_parse(a, xml, node)
142
142
  end
143
143
  end
144
- end.join("\n")
144
+ end
145
145
  end
146
146
 
147
147
  def set_obligation(attrs, node)
@@ -162,7 +162,7 @@ module Metanorma
162
162
  end
163
163
  xml_abstract << node.content
164
164
  end
165
- end.join("\n")
165
+ end
166
166
  end
167
167
 
168
168
  def misccontainer_parse(_attrs, xml, node)
@@ -243,7 +243,7 @@ module Metanorma
243
243
  xml.floating_title **floating_title_attrs(node) do |xml_t|
244
244
  xml_t << node.title
245
245
  end
246
- end.join("\n")
246
+ end
247
247
  end
248
248
  end
249
249
  end
@@ -131,7 +131,7 @@ module Metanorma
131
131
  span[:surname] and return
132
132
  msg = "Missing surname: issue with bibliographic markup " \
133
133
  "in \"#{title}\": #{span}"
134
- @err << { msg: msg, fatal: true }
134
+ @err << { msg:, fatal: true }
135
135
  end
136
136
 
137
137
  def span_to_person(span, title)
@@ -38,7 +38,7 @@ module Metanorma
38
38
  case span[:key]
39
39
  when "uri", "docid"
40
40
  val = link_unwrap(Nokogiri::XML.fragment(span[:val])).to_xml
41
- ret[span[:key].to_sym] << { type: span[:type], val: val }
41
+ ret[span[:key].to_sym] << { type: span[:type], val: }
42
42
  when "date"
43
43
  ret[span[:key].to_sym] << { type: span[:type] || "published",
44
44
  val: span[:val] }
@@ -79,7 +79,7 @@ module Metanorma
79
79
  else
80
80
  msg = "unrecognised key '#{span[:key]}' in " \
81
81
  "`span:#{span[:key]}[#{span[:val]}]`"
82
- @err << { msg: msg }
82
+ @err << { msg: }
83
83
  end
84
84
  end
85
85
 
@@ -170,7 +170,7 @@ module Metanorma
170
170
  seen_xref = Nokogiri::XML.fragment(matched[:xref])
171
171
  add_term_source(node, xml_t, seen_xref, matched)
172
172
  end
173
- end.join("")
173
+ end
174
174
  end
175
175
 
176
176
  def termdefinition(node)
@@ -178,7 +178,7 @@ module Metanorma
178
178
  xml.definition **attr_code(type: node.attr("type")) do |d|
179
179
  d << node.content
180
180
  end
181
- end.join("")
181
+ end
182
182
  end
183
183
  end
184
184
  end
@@ -62,22 +62,24 @@ module Metanorma
62
62
  end
63
63
 
64
64
  def preferred_validate(doc)
65
- out = []
66
65
  ret = doc.xpath("//term").each_with_object({}) do |t, m|
67
66
  prefix = t.at("./domain")&.text
68
67
  t.xpath("./preferred//name").each do |n|
69
68
  ret = n.text
70
69
  prefix and ret = "<#{prefix}> #{ret}"
71
- (m[ret] and out << ret) or m[ret] = t
70
+ m[ret] ||= []
71
+ m[ret] << t
72
72
  end
73
73
  end
74
- preferred_validate_report(out, ret)
74
+ preferred_validate_report(ret)
75
75
  end
76
76
 
77
- def preferred_validate_report(terms, locations)
78
- terms.each do |e|
79
- err = "Term #{e} occurs twice as preferred designation"
80
- @log.add("Terms", locations[e], err, severity: 1)
77
+ def preferred_validate_report(terms)
78
+ terms.each do |k, v|
79
+ v.size > 1 or next
80
+ loc = v.map { |x| x["id"] }.join(", ")
81
+ err = "Term #{k} occurs twice as preferred designation: #{loc}"
82
+ @log.add("Terms", v.first, err, severity: 1)
81
83
  end
82
84
  end
83
85
  end
@@ -19,6 +19,6 @@ module Metanorma
19
19
  end
20
20
 
21
21
  module Standoc
22
- VERSION = "2.9.2".freeze
22
+ VERSION = "2.9.4".freeze
23
23
  end
24
24
  end
@@ -32,12 +32,12 @@ Gem::Specification.new do |spec|
32
32
  spec.add_dependency "asciidoctor", "~> 2.0.0"
33
33
  spec.add_dependency "crass", "~> 1.0.0"
34
34
  spec.add_dependency "iev", "~> 0.3.0"
35
- spec.add_dependency "isodoc", "~> 2.10.5"
35
+ spec.add_dependency "isodoc", "~> 2.11.0"
36
36
  spec.add_dependency "metanorma", ">= 1.6.0"
37
37
  spec.add_dependency "metanorma-plugin-datastruct", "~> 0.3.0"
38
38
  spec.add_dependency "metanorma-plugin-glossarist", "~> 0.2.0"
39
39
  spec.add_dependency "metanorma-plugin-lutaml", "~> 0.7.0"
40
- spec.add_dependency "metanorma-utils", "~> 1.9.0"
40
+ spec.add_dependency "metanorma-utils", "~> 1.10.0"
41
41
  spec.add_dependency "ruby-jing"
42
42
  # relaton-cli not just relaton, to avoid circular reference in metanorma
43
43
  spec.add_dependency "asciimath2unitsml", "~> 0.4.0"
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.9.2
4
+ version: 2.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-05 00:00:00.000000000 Z
11
+ date: 2024-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 2.10.5
75
+ version: 2.11.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 2.10.5
82
+ version: 2.11.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: metanorma
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -142,14 +142,14 @@ dependencies:
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: 1.9.0
145
+ version: 1.10.0
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: 1.9.0
152
+ version: 1.10.0
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: ruby-jing
155
155
  requirement: !ruby/object:Gem::Requirement