metanorma-standoc 2.1.4 → 2.2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/metanorma/standoc/base.rb +1 -0
- data/lib/metanorma/standoc/blocks.rb +3 -7
- data/lib/metanorma/standoc/cleanup.rb +4 -2
- data/lib/metanorma/standoc/cleanup_biblio.rb +204 -0
- data/lib/metanorma/standoc/cleanup_block.rb +46 -4
- data/lib/metanorma/standoc/cleanup_maths.rb +2 -15
- data/lib/metanorma/standoc/cleanup_ref.rb +22 -13
- data/lib/metanorma/standoc/cleanup_reqt.rb +37 -4
- data/lib/metanorma/standoc/cleanup_symbols.rb +1 -1
- data/lib/metanorma/standoc/cleanup_terms.rb +6 -2
- data/lib/metanorma/standoc/cleanup_text.rb +10 -8
- data/lib/metanorma/standoc/cleanup_xref.rb +1 -2
- data/lib/metanorma/standoc/converter.rb +2 -0
- data/lib/metanorma/standoc/front.rb +1 -1
- data/lib/metanorma/standoc/inline.rb +8 -4
- data/lib/metanorma/standoc/isodoc.rng +16 -1
- data/lib/metanorma/standoc/macros.rb +1 -180
- data/lib/metanorma/standoc/macros_inline.rb +194 -0
- data/lib/metanorma/standoc/ref_sect.rb +2 -2
- data/lib/metanorma/standoc/ref_utility.rb +5 -6
- data/lib/metanorma/standoc/reqt.rb +5 -5
- data/lib/metanorma/standoc/reqt.rng +1 -1
- data/lib/metanorma/standoc/section.rb +2 -0
- data/lib/metanorma/standoc/term_lookup_cleanup.rb +1 -1
- data/lib/metanorma/standoc/utils.rb +1 -1
- data/lib/metanorma/standoc/validate.rb +1 -69
- data/lib/metanorma/standoc/validate_table.rb +91 -0
- data/lib/metanorma/standoc/version.rb +1 -1
- data/metanorma-standoc.gemspec +2 -3
- data/spec/metanorma/{refs_dl_spec.rb → biblio_spec.rb} +84 -1
- data/spec/metanorma/blocks_spec.rb +68 -8
- data/spec/metanorma/cleanup_blocks_spec.rb +107 -27
- data/spec/metanorma/inline_spec.rb +4 -0
- data/spec/metanorma/isobib_cache_spec.rb +6 -4
- data/spec/metanorma/macros_spec.rb +6 -2
- data/spec/metanorma/refs_spec.rb +261 -232
- data/spec/metanorma/validate_spec.rb +106 -7
- data/spec/vcr_cassettes/bsi16341.yml +63 -51
- data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +62 -62
- data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +12 -12
- data/spec/vcr_cassettes/hide_refs.yml +58 -58
- data/spec/vcr_cassettes/isobib_get_123.yml +12 -12
- data/spec/vcr_cassettes/isobib_get_123_1.yml +22 -22
- data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +33 -33
- data/spec/vcr_cassettes/isobib_get_123_2.yml +295 -0
- data/spec/vcr_cassettes/isobib_get_123_2001.yml +11 -11
- data/spec/vcr_cassettes/isobib_get_124.yml +12 -12
- data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +24 -30
- data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +46 -46
- data/spec/vcr_cassettes/std-link.yml +14 -72
- metadata +9 -6
- data/lib/metanorma/standoc/cleanup_ref_dl.rb +0 -113
@@ -121,7 +121,7 @@ module Metanorma
|
|
121
121
|
|
122
122
|
def metadata_getrelation(node, xml, type, desc = nil)
|
123
123
|
docs = node.attr(desc || type) or return
|
124
|
-
|
124
|
+
@c.decode(docs).split(/;\s*/).each do |d|
|
125
125
|
metadata_getrelation1(d, xml, type, desc)
|
126
126
|
end
|
127
127
|
end
|
@@ -79,8 +79,8 @@ module Metanorma
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def inline_anchor_bibref(node)
|
82
|
-
eref_contents =
|
83
|
-
.decode(node.text || node.target || node.id)
|
82
|
+
eref_contents =
|
83
|
+
@c.decode(node.text || node.target || node.id)
|
84
84
|
&.sub(/^\[?([^\[\]]+?)\]?$/, "[\\1]")
|
85
85
|
@refids << (node.target || node.id)
|
86
86
|
noko do |xml|
|
@@ -125,14 +125,14 @@ module Metanorma
|
|
125
125
|
end
|
126
126
|
|
127
127
|
def xml_encode(text)
|
128
|
-
|
128
|
+
@c.encode(text, :basic, :hexadecimal)
|
129
129
|
.gsub(/&gt;/, ">").gsub(/&lt;/, "<").gsub(/&amp;/, "&")
|
130
130
|
.gsub(/>/, ">").gsub(/</, "<").gsub(/&/, "&")
|
131
131
|
.gsub(/"/, '"').gsub(/
/, "\n").gsub(/&#/, "&#")
|
132
132
|
end
|
133
133
|
|
134
134
|
def latex_parse1(text)
|
135
|
-
lxm_input = Unicode2LaTeX.unicode2latex(
|
135
|
+
lxm_input = Unicode2LaTeX.unicode2latex(@c.decode(text))
|
136
136
|
results = Latexmath.parse(lxm_input).to_mathml
|
137
137
|
results.nil? and
|
138
138
|
@log.add("Math", nil,
|
@@ -191,6 +191,10 @@ module Metanorma
|
|
191
191
|
when "underline" then xml.underline { |s| s << node.text }
|
192
192
|
when "smallcap" then xml.smallcap { |s| s << node.text }
|
193
193
|
when "keyword" then xml.keyword { |s| s << node.text }
|
194
|
+
when /^css /
|
195
|
+
xml.span **{ style: node.role.sub(/^css /, "") } do |s|
|
196
|
+
s << node.text
|
197
|
+
end
|
194
198
|
else
|
195
199
|
xml << node.text
|
196
200
|
end
|
@@ -1285,7 +1285,12 @@
|
|
1285
1285
|
</define>
|
1286
1286
|
<define name="span">
|
1287
1287
|
<element name="span">
|
1288
|
-
<
|
1288
|
+
<optional>
|
1289
|
+
<attribute name="class"/>
|
1290
|
+
</optional>
|
1291
|
+
<optional>
|
1292
|
+
<attribute name="style"/>
|
1293
|
+
</optional>
|
1289
1294
|
<oneOrMore>
|
1290
1295
|
<ref name="TextElement"/>
|
1291
1296
|
</oneOrMore>
|
@@ -2504,6 +2509,16 @@
|
|
2504
2509
|
<text/>
|
2505
2510
|
</element>
|
2506
2511
|
</optional>
|
2512
|
+
<optional>
|
2513
|
+
<element name="amendment">
|
2514
|
+
<text/>
|
2515
|
+
</element>
|
2516
|
+
</optional>
|
2517
|
+
<optional>
|
2518
|
+
<element name="corrigendum">
|
2519
|
+
<text/>
|
2520
|
+
</element>
|
2521
|
+
</optional>
|
2507
2522
|
<optional>
|
2508
2523
|
<element name="language">
|
2509
2524
|
<text/>
|
@@ -3,6 +3,7 @@ require "fileutils"
|
|
3
3
|
require "uuidtools"
|
4
4
|
require "yaml"
|
5
5
|
require "csv"
|
6
|
+
require_relative "./macros_inline"
|
6
7
|
require_relative "./macros_plantuml"
|
7
8
|
require_relative "./macros_terms"
|
8
9
|
require_relative "./macros_form"
|
@@ -15,54 +16,6 @@ require "metanorma-plugin-lutaml"
|
|
15
16
|
|
16
17
|
module Metanorma
|
17
18
|
module Standoc
|
18
|
-
class InheritInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
19
|
-
use_dsl
|
20
|
-
named :inherit
|
21
|
-
parse_content_as :text
|
22
|
-
using_format :short
|
23
|
-
|
24
|
-
def process(parent, _target, attrs)
|
25
|
-
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
26
|
-
%{<inherit>#{out}</inherit>}
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
class IndexXrefInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
31
|
-
use_dsl
|
32
|
-
named :index
|
33
|
-
|
34
|
-
def preprocess_attrs(attrs)
|
35
|
-
return unless attrs.size > 1 && attrs.size < 5
|
36
|
-
|
37
|
-
ret = { primary: attrs[1], target: attrs[attrs.size] }
|
38
|
-
ret[:secondary] = attrs[2] if attrs.size > 2
|
39
|
-
ret[:tertiary] = attrs[3] if attrs.size > 3
|
40
|
-
ret
|
41
|
-
end
|
42
|
-
|
43
|
-
def process(_parent, target, attr)
|
44
|
-
args = preprocess_attrs(attr) or return
|
45
|
-
ret = "<index-xref also='#{target == 'also'}'>"\
|
46
|
-
"<primary>#{args[:primary]}</primary>"
|
47
|
-
ret += "<secondary>#{args[:secondary]}</secondary>" if args[:secondary]
|
48
|
-
ret += "<tertiary>#{args[:tertiary]}</tertiary>" if args[:tertiary]
|
49
|
-
ret + "<target>#{args[:target]}</target></index-xref>"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
class IndexRangeInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
54
|
-
use_dsl
|
55
|
-
named :"index-range"
|
56
|
-
parse_content_as :text
|
57
|
-
|
58
|
-
def process(parent, target, attr)
|
59
|
-
text = attr["text"]
|
60
|
-
text = "((#{text}))" unless /^\(\(.+\)\)$/.match?(text)
|
61
|
-
out = parent.sub_macros(text)
|
62
|
-
out.sub(/<index>/, "<index to='#{target}'>")
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
19
|
class PseudocodeBlockMacro < Asciidoctor::Extensions::BlockProcessor
|
67
20
|
use_dsl
|
68
21
|
named :pseudocode
|
@@ -97,138 +50,6 @@ module Metanorma
|
|
97
50
|
end
|
98
51
|
end
|
99
52
|
|
100
|
-
class HTML5RubyMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
101
|
-
use_dsl
|
102
|
-
named :ruby
|
103
|
-
parse_content_as :text
|
104
|
-
option :pos_attrs, %w(rpbegin rt rpend)
|
105
|
-
|
106
|
-
# for example, html5ruby:楽聖少女[がくせいしょうじょ]
|
107
|
-
def process(_parent, target, attributes)
|
108
|
-
rpbegin = "("
|
109
|
-
rpend = ")"
|
110
|
-
if (attributes.size == 1) && attributes.key?("text")
|
111
|
-
rt = attributes["text"]
|
112
|
-
elsif (attributes.size == 2) && attributes.key?(1) &&
|
113
|
-
attributes.key?("rpbegin")
|
114
|
-
rt = attributes[1] || ""
|
115
|
-
else
|
116
|
-
rpbegin = attributes["rpbegin"]
|
117
|
-
rt = attributes["rt"]
|
118
|
-
rpend = attributes["rpend"]
|
119
|
-
end
|
120
|
-
|
121
|
-
"<ruby>#{target}<rp>#{rpbegin}</rp><rt>#{rt}</rt>"\
|
122
|
-
"<rp>#{rpend}</rp></ruby>"
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
class AutonumberInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
127
|
-
use_dsl
|
128
|
-
named :autonumber
|
129
|
-
parse_content_as :text
|
130
|
-
|
131
|
-
def process(parent, target, attrs)
|
132
|
-
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
133
|
-
%{<autonumber type='#{target}'>#{out}</autonumber>}
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
class VariantInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
138
|
-
use_dsl
|
139
|
-
named :lang
|
140
|
-
parse_content_as :text
|
141
|
-
|
142
|
-
def process(parent, target, attrs)
|
143
|
-
/^(?<lang>[^-]*)(?:-(?<script>.*))?$/ =~ target
|
144
|
-
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
145
|
-
if script
|
146
|
-
%{<variant lang='#{lang}' script='#{script}'>#{out}</variant>}
|
147
|
-
else
|
148
|
-
%{<variant lang='#{lang}'>#{out}</variant>}
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
class AddMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
154
|
-
use_dsl
|
155
|
-
named :add
|
156
|
-
parse_content_as :text
|
157
|
-
using_format :short
|
158
|
-
|
159
|
-
def process(parent, _target, attrs)
|
160
|
-
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
161
|
-
%{<add>#{out}</add>}
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
class DelMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
166
|
-
use_dsl
|
167
|
-
named :del
|
168
|
-
parse_content_as :text
|
169
|
-
using_format :short
|
170
|
-
|
171
|
-
def process(parent, _target, attrs)
|
172
|
-
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
173
|
-
%{<del>#{out}</del>}
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
class ToCInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
178
|
-
use_dsl
|
179
|
-
named :toc
|
180
|
-
parse_content_as :text
|
181
|
-
using_format :short
|
182
|
-
|
183
|
-
def process(parent, _target, attrs)
|
184
|
-
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
185
|
-
content = CSV.parse_line(out).map do |x|
|
186
|
-
x.sub!(/^(["'])(.+)\1/, "\\2")
|
187
|
-
m = /^(.*?)(:\d+)?$/.match(x)
|
188
|
-
%{<toc-xpath depth='#{m[2]&.sub(/:/, '') || 1}'>#{m[1]}</toc-xpath>}
|
189
|
-
end.join
|
190
|
-
"<toc>#{content}</toc>"
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
# inject ZWNJ to prevent Asciidoctor from attempting regex substitutions
|
195
|
-
class PassInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
196
|
-
use_dsl
|
197
|
-
named :"pass-format"
|
198
|
-
|
199
|
-
def process(parent, target, attrs)
|
200
|
-
format = target || "metanorma"
|
201
|
-
out = Asciidoctor::Inline.new(parent, :quoted, attrs[1]).convert
|
202
|
-
.gsub(/((?![<>&])[[:punct:]])/, "\\1‌")
|
203
|
-
%{<passthrough-inline formats="#{format}">#{out}</passthrough-inline>}
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
class IdentifierInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
208
|
-
use_dsl
|
209
|
-
named :identifier
|
210
|
-
parse_content_as :raw
|
211
|
-
using_format :short
|
212
|
-
|
213
|
-
def process(parent, _target, attrs)
|
214
|
-
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
215
|
-
.gsub(/((?![<>&])[[:punct:]])/, "\\1‌")
|
216
|
-
%{<identifier>#{out}</identifier>}
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
class StdLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
221
|
-
use_dsl
|
222
|
-
named :"std-link"
|
223
|
-
parse_content_as :text
|
224
|
-
using_format :short
|
225
|
-
|
226
|
-
def process(parent, _target, attrs)
|
227
|
-
create_anchor(parent, "hidden%#{attrs['text']}",
|
228
|
-
type: :xref, target: "_#{UUIDTools::UUID.random_create}")
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
53
|
class NamedEscapePreprocessor < Asciidoctor::Extensions::Preprocessor
|
233
54
|
def process(_document, reader)
|
234
55
|
c = HTMLEntities.new
|
@@ -0,0 +1,194 @@
|
|
1
|
+
module Metanorma
|
2
|
+
module Standoc
|
3
|
+
class InheritInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
4
|
+
use_dsl
|
5
|
+
named :inherit
|
6
|
+
parse_content_as :text
|
7
|
+
using_format :short
|
8
|
+
|
9
|
+
def process(parent, _target, attrs)
|
10
|
+
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
11
|
+
%{<inherit>#{out}</inherit>}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class IndexXrefInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
16
|
+
use_dsl
|
17
|
+
named :index
|
18
|
+
|
19
|
+
def preprocess_attrs(attrs)
|
20
|
+
return unless attrs.size > 1 && attrs.size < 5
|
21
|
+
|
22
|
+
ret = { primary: attrs[1], target: attrs[attrs.size] }
|
23
|
+
ret[:secondary] = attrs[2] if attrs.size > 2
|
24
|
+
ret[:tertiary] = attrs[3] if attrs.size > 3
|
25
|
+
ret
|
26
|
+
end
|
27
|
+
|
28
|
+
def process(_parent, target, attr)
|
29
|
+
args = preprocess_attrs(attr) or return
|
30
|
+
ret = "<index-xref also='#{target == 'also'}'>"\
|
31
|
+
"<primary>#{args[:primary]}</primary>"
|
32
|
+
ret += "<secondary>#{args[:secondary]}</secondary>" if args[:secondary]
|
33
|
+
ret += "<tertiary>#{args[:tertiary]}</tertiary>" if args[:tertiary]
|
34
|
+
ret + "<target>#{args[:target]}</target></index-xref>"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class IndexRangeInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
39
|
+
use_dsl
|
40
|
+
named :"index-range"
|
41
|
+
parse_content_as :text
|
42
|
+
|
43
|
+
def process(parent, target, attr)
|
44
|
+
text = attr["text"]
|
45
|
+
text = "((#{text}))" unless /^\(\(.+\)\)$/.match?(text)
|
46
|
+
out = parent.sub_macros(text)
|
47
|
+
out.sub(/<index>/, "<index to='#{target}'>")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class HTML5RubyMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
52
|
+
use_dsl
|
53
|
+
named :ruby
|
54
|
+
parse_content_as :text
|
55
|
+
option :pos_attrs, %w(rpbegin rt rpend)
|
56
|
+
|
57
|
+
# for example, html5ruby:楽聖少女[がくせいしょうじょ]
|
58
|
+
def process(_parent, target, attributes)
|
59
|
+
rpbegin = "("
|
60
|
+
rpend = ")"
|
61
|
+
if (attributes.size == 1) && attributes.key?("text")
|
62
|
+
rt = attributes["text"]
|
63
|
+
elsif (attributes.size == 2) && attributes.key?(1) &&
|
64
|
+
attributes.key?("rpbegin")
|
65
|
+
rt = attributes[1] || ""
|
66
|
+
else
|
67
|
+
rpbegin = attributes["rpbegin"]
|
68
|
+
rt = attributes["rt"]
|
69
|
+
rpend = attributes["rpend"]
|
70
|
+
end
|
71
|
+
|
72
|
+
"<ruby>#{target}<rp>#{rpbegin}</rp><rt>#{rt}</rt>"\
|
73
|
+
"<rp>#{rpend}</rp></ruby>"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class AutonumberInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
78
|
+
use_dsl
|
79
|
+
named :autonumber
|
80
|
+
parse_content_as :text
|
81
|
+
|
82
|
+
def process(parent, target, attrs)
|
83
|
+
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
84
|
+
%{<autonumber type='#{target}'>#{out}</autonumber>}
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
class VariantInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
89
|
+
use_dsl
|
90
|
+
named :lang
|
91
|
+
parse_content_as :text
|
92
|
+
|
93
|
+
def process(parent, target, attrs)
|
94
|
+
/^(?<lang>[^-]*)(?:-(?<script>.*))?$/ =~ target
|
95
|
+
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
96
|
+
if script
|
97
|
+
%{<variant lang='#{lang}' script='#{script}'>#{out}</variant>}
|
98
|
+
else
|
99
|
+
%{<variant lang='#{lang}'>#{out}</variant>}
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class AddMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
105
|
+
use_dsl
|
106
|
+
named :add
|
107
|
+
parse_content_as :text
|
108
|
+
using_format :short
|
109
|
+
|
110
|
+
def process(parent, _target, attrs)
|
111
|
+
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
112
|
+
%{<add>#{out}</add>}
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
class DelMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
117
|
+
use_dsl
|
118
|
+
named :del
|
119
|
+
parse_content_as :text
|
120
|
+
using_format :short
|
121
|
+
|
122
|
+
def process(parent, _target, attrs)
|
123
|
+
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
124
|
+
%{<del>#{out}</del>}
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
class ToCInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
129
|
+
use_dsl
|
130
|
+
named :toc
|
131
|
+
parse_content_as :text
|
132
|
+
using_format :short
|
133
|
+
|
134
|
+
def process(parent, _target, attrs)
|
135
|
+
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
136
|
+
content = CSV.parse_line(out).map do |x|
|
137
|
+
x.sub!(/^(["'])(.+)\1/, "\\2")
|
138
|
+
m = /^(.*?)(:\d+)?$/.match(x)
|
139
|
+
%{<toc-xpath depth='#{m[2]&.sub(/:/, '') || 1}'>#{m[1]}</toc-xpath>}
|
140
|
+
end.join
|
141
|
+
"<toc>#{content}</toc>"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# inject ZWNJ to prevent Asciidoctor from attempting regex substitutions
|
146
|
+
class PassInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
147
|
+
use_dsl
|
148
|
+
named :"pass-format"
|
149
|
+
|
150
|
+
def process(parent, target, attrs)
|
151
|
+
format = target || "metanorma"
|
152
|
+
out = Asciidoctor::Inline.new(parent, :quoted, attrs[1]).convert
|
153
|
+
.gsub(/((?![<>&])[[:punct:]])/, "\\1‌")
|
154
|
+
%{<passthrough-inline formats="#{format}">#{out}</passthrough-inline>}
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
class IdentifierInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
159
|
+
use_dsl
|
160
|
+
named :identifier
|
161
|
+
parse_content_as :raw
|
162
|
+
using_format :short
|
163
|
+
|
164
|
+
def process(parent, _target, attrs)
|
165
|
+
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
166
|
+
.gsub(/((?![<>&])[[:punct:]])/, "\\1‌")
|
167
|
+
%{<identifier>#{out}</identifier>}
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
class StdLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
172
|
+
use_dsl
|
173
|
+
named :"std-link"
|
174
|
+
parse_content_as :text
|
175
|
+
using_format :short
|
176
|
+
|
177
|
+
def process(parent, _target, attrs)
|
178
|
+
create_anchor(parent, "hidden%#{attrs['text']}",
|
179
|
+
type: :xref, target: "_#{UUIDTools::UUID.random_create}")
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
class SpanInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
184
|
+
use_dsl
|
185
|
+
named :span
|
186
|
+
parse_content_as :text
|
187
|
+
|
188
|
+
def process(parent, target, attrs)
|
189
|
+
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
190
|
+
%{<span class="#{target}">#{out}</span>}
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
@@ -84,7 +84,7 @@ module Metanorma
|
|
84
84
|
if ref[:code].nil? || ref[:no_year] || @bibdb.nil?
|
85
85
|
res << [ref, idx, nil]
|
86
86
|
else
|
87
|
-
@bibdb.fetch_async(
|
87
|
+
@bibdb.fetch_async(@c.decode(ref[:code]),
|
88
88
|
ref[:year], ref) do |doc|
|
89
89
|
res << [ref, idx, doc]
|
90
90
|
end
|
@@ -131,7 +131,7 @@ module Metanorma
|
|
131
131
|
global = !@no_isobib_cache && !node.attr("local-cache-only")
|
132
132
|
local = node.attr("local-cache") || node.attr("local-cache-only")
|
133
133
|
local = nil if @no_isobib_cache
|
134
|
-
@bibdb = Relaton::
|
134
|
+
@bibdb = Relaton::Db.init_bib_caches(
|
135
135
|
local_cache: local,
|
136
136
|
flush_caches: node.attr("flush-caches"),
|
137
137
|
global_cache: global,
|
@@ -53,7 +53,7 @@ module Metanorma
|
|
53
53
|
|
54
54
|
def docnumber(bib, code)
|
55
55
|
bib.docnumber do |d|
|
56
|
-
d <<
|
56
|
+
d << @c.decode(code).sub(/^[^\d]*/, "")
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
@@ -104,9 +104,9 @@ module Metanorma
|
|
104
104
|
ret = { id: code }
|
105
105
|
return ret if code.blank?
|
106
106
|
|
107
|
-
|
108
|
-
|
109
|
-
analyse_ref_dropid(
|
107
|
+
analyse_ref_numeric(
|
108
|
+
analyse_ref_repo_path(
|
109
|
+
analyse_ref_dropid(analyse_ref_hidden(analyse_ref_nofetch(ret))),
|
110
110
|
),
|
111
111
|
)
|
112
112
|
end
|
@@ -121,8 +121,7 @@ module Metanorma
|
|
121
121
|
end
|
122
122
|
|
123
123
|
def ref_attributes(match)
|
124
|
-
|
125
|
-
code = analyse_ref_code(match[:code])
|
124
|
+
code = analyse_ref_code(match[:code])
|
126
125
|
|
127
126
|
{ id: match[:anchor], type: "standard",
|
128
127
|
suppress_identifier: code[:dropid] || nil }
|
@@ -7,7 +7,7 @@ module Metanorma
|
|
7
7
|
module Standoc
|
8
8
|
module Blocks
|
9
9
|
def reqt_subpart(name)
|
10
|
-
%w(specification measurement-target verification import
|
10
|
+
%w(specification measurement-target verification import identifier title
|
11
11
|
description component subject inherit classification).include? name
|
12
12
|
end
|
13
13
|
|
@@ -30,7 +30,7 @@ module Metanorma
|
|
30
30
|
|
31
31
|
def req_classif_parse(classif)
|
32
32
|
ret = []
|
33
|
-
|
33
|
+
@c.decode(classif).split(/;\s*/).each do |c|
|
34
34
|
c1 = c.split(/:\s*/)
|
35
35
|
next unless c1.size == 2
|
36
36
|
|
@@ -63,16 +63,16 @@ module Metanorma
|
|
63
63
|
|
64
64
|
def requirement_elems(node, out)
|
65
65
|
node.title and out.title { |t| t << node.title }
|
66
|
-
a = node.attr("
|
66
|
+
a = node.attr("identifier") and out.identifier do |l|
|
67
67
|
l << out.text(a)
|
68
68
|
end
|
69
69
|
a = node.attr("subject") and csv_split(a)&.each do |subj|
|
70
70
|
out.subject { |s| s << out.text(subj) }
|
71
71
|
end
|
72
|
-
a =
|
72
|
+
a = @c.decode(node.attr("inherit")) and
|
73
73
|
csv_split(a)&.each do |i|
|
74
74
|
out.inherit do |inh|
|
75
|
-
inh <<
|
75
|
+
inh << @c.encode(i, :hexadecimal)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
classif = node.attr("classification") and
|
@@ -60,7 +60,7 @@ module Metanorma
|
|
60
60
|
"[not(ancestor::boilerplate)]".freeze
|
61
61
|
|
62
62
|
def isodoc(lang, script, i18nyaml = nil)
|
63
|
-
conv =
|
63
|
+
conv = presentation_xml_converter(EmptyAttr.new)
|
64
64
|
i18n = conv.i18n_init(lang, script, i18nyaml)
|
65
65
|
conv.metadata_init(lang, script, i18n)
|
66
66
|
conv
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require "metanorma/standoc/utils"
|
2
2
|
require_relative "./validate_section"
|
3
|
+
require_relative "./validate_table"
|
3
4
|
require "nokogiri"
|
4
5
|
require "jing"
|
5
6
|
require "iev"
|
@@ -53,75 +54,6 @@ module Metanorma
|
|
53
54
|
@fatalerror.empty? or clean_abort(@fatalerror.join("\n"), doc.to_xml)
|
54
55
|
end
|
55
56
|
|
56
|
-
def table_validate(doc)
|
57
|
-
doc.xpath("//table[colgroup]").each do |t|
|
58
|
-
maxrowcols_validate(t, t.xpath("./colgroup/col").size)
|
59
|
-
end
|
60
|
-
doc.xpath("//table[.//*[@colspan] | .//*[@rowspan]]").each do |t|
|
61
|
-
maxrowcols_validate(t, max_td_count(t))
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def max_td_count(table)
|
66
|
-
max = 0
|
67
|
-
table.xpath("./tr").each do |tr|
|
68
|
-
n = tr.xpath("./td | ./th").size
|
69
|
-
max < n and max = n
|
70
|
-
end
|
71
|
-
max
|
72
|
-
end
|
73
|
-
|
74
|
-
def maxrowcols_validate(table, maxcols)
|
75
|
-
cells2d = table.xpath("./*/tr").each_with_object([]) { |_r, m| m << {} }
|
76
|
-
table.xpath("./*/tr").each_with_index do |tr, r|
|
77
|
-
curr = 0
|
78
|
-
tr.xpath("./td | ./th").each do |td|
|
79
|
-
curr = maxcols_validate1(td, r, curr, cells2d, maxcols)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
maxrows_validate(table, cells2d)
|
83
|
-
end
|
84
|
-
|
85
|
-
# code doesn't actually do anything, since Asciidoctor refuses to generate
|
86
|
-
# table with inconsistent column count
|
87
|
-
def maxcols_validate1(tcell, row, curr, cells2d, maxcols)
|
88
|
-
rs = tcell&.attr("rowspan")&.to_i || 1
|
89
|
-
cs = tcell&.attr("colspan")&.to_i || 1
|
90
|
-
curr = table_tracker_update(cells2d, row, curr, rs, cs)
|
91
|
-
maxcols_check(curr + cs - 1, maxcols, tcell)
|
92
|
-
curr + cs
|
93
|
-
end
|
94
|
-
|
95
|
-
def table_tracker_update(cells2d, row, curr, rowspan, colspan)
|
96
|
-
cells2d[row] ||= {}
|
97
|
-
while cells2d[row][curr]
|
98
|
-
curr += 1
|
99
|
-
end
|
100
|
-
(row..(row + rowspan - 1)).each do |y2|
|
101
|
-
cells2d[y2] ||= {}
|
102
|
-
(curr..(curr + colspan - 1)).each { |x2| cells2d[y2][x2] = 1 }
|
103
|
-
end
|
104
|
-
curr
|
105
|
-
end
|
106
|
-
|
107
|
-
def maxrows_validate(table, cells2d)
|
108
|
-
if cells2d.any? { |x| x.size != cells2d.first.size }
|
109
|
-
@log.add("Table", table,
|
110
|
-
"Table rows in table are inconsistent: check rowspan")
|
111
|
-
@fatalerror << "Table rows in table are inconsistent: check rowspan"
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
# if maxcols or maxrows negative, do not check them
|
116
|
-
def maxcols_check(col, maxcols, tcell)
|
117
|
-
if maxcols.positive? && col > maxcols
|
118
|
-
@log.add("Table", tcell, "Table exceeds maximum number of columns "\
|
119
|
-
"defined (#{maxcols})")
|
120
|
-
@fatalerror << "Table exceeds maximum number of columns defined "\
|
121
|
-
"(#{maxcols})"
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
57
|
def norm_ref_validate(doc)
|
126
58
|
found = false
|
127
59
|
doc.xpath("//references[@normative = 'true']/bibitem").each do |b|
|