metanorma-standoc 2.8.11 → 2.9.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/.rubocop.yml +1 -1
- data/lib/metanorma/standoc/anchor.rb +3 -3
- data/lib/metanorma/standoc/base.rb +1 -1
- data/lib/metanorma/standoc/blocks.rb +5 -5
- data/lib/metanorma/standoc/blocks_image.rb +1 -1
- data/lib/metanorma/standoc/blocks_notes.rb +6 -6
- data/lib/metanorma/standoc/cleanup.rb +15 -0
- data/lib/metanorma/standoc/cleanup_block.rb +1 -1
- data/lib/metanorma/standoc/cleanup_boilerplate.rb +67 -31
- data/lib/metanorma/standoc/cleanup_maths.rb +24 -1
- data/lib/metanorma/standoc/cleanup_ref.rb +0 -1
- data/lib/metanorma/standoc/cleanup_section.rb +5 -9
- data/lib/metanorma/standoc/cleanup_section_names.rb +5 -5
- data/lib/metanorma/standoc/cleanup_terms.rb +6 -5
- data/lib/metanorma/standoc/cleanup_xref.rb +6 -10
- data/lib/metanorma/standoc/converter.rb +1 -0
- data/lib/metanorma/standoc/init.rb +23 -2
- data/lib/metanorma/standoc/inline.rb +5 -5
- data/lib/metanorma/standoc/isodoc.rng +5 -5
- data/lib/metanorma/standoc/lists.rb +4 -4
- data/lib/metanorma/standoc/macros.rb +16 -44
- data/lib/metanorma/standoc/macros_embed.rb +14 -12
- data/lib/metanorma/standoc/macros_inline.rb +38 -75
- data/lib/metanorma/standoc/macros_link.rb +81 -0
- data/lib/metanorma/standoc/ref.rb +9 -12
- data/lib/metanorma/standoc/ref_queue.rb +2 -4
- data/lib/metanorma/standoc/ref_utility.rb +2 -2
- data/lib/metanorma/standoc/section.rb +3 -3
- data/lib/metanorma/standoc/terms.rb +2 -2
- data/lib/metanorma/standoc/utils.rb +22 -2
- data/lib/metanorma/standoc/validate.rb +14 -2
- data/lib/metanorma/standoc/validate_table.rb +7 -0
- data/lib/metanorma/standoc/version.rb +1 -1
- data/metanorma-standoc.gemspec +5 -4
- metadata +24 -9
@@ -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.join("")
|
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.join("")
|
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.join("")
|
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.join("")
|
121
121
|
end
|
122
122
|
|
123
123
|
def list_caption(node, out)
|
@@ -7,6 +7,7 @@ require_relative "macros_terms"
|
|
7
7
|
require_relative "macros_form"
|
8
8
|
require_relative "macros_note"
|
9
9
|
require_relative "macros_embed"
|
10
|
+
require_relative "macros_link"
|
10
11
|
require_relative "datamodel/attributes_table_preprocessor"
|
11
12
|
require_relative "datamodel/diagram_preprocessor"
|
12
13
|
require "metanorma-plugin-datastruct"
|
@@ -52,13 +53,19 @@ module Metanorma
|
|
52
53
|
class NamedEscapePreprocessor < Asciidoctor::Extensions::Preprocessor
|
53
54
|
def process(document, reader)
|
54
55
|
c = HTMLEntities.new
|
56
|
+
p = Metanorma::Utils::LineStatus.new
|
55
57
|
lines = reader.lines.map do |l|
|
56
|
-
|
57
|
-
|
58
|
-
end.join
|
58
|
+
p.process(l)
|
59
|
+
p.pass ? l : convert(l, c)
|
59
60
|
end
|
60
61
|
::Asciidoctor::PreprocessorReader.new document, lines
|
61
62
|
end
|
63
|
+
|
64
|
+
def convert(line, esc)
|
65
|
+
line.split(/(&[A-Za-z][^&;]*;)/).map do |s|
|
66
|
+
/^&[A-Za-z]/.match?(s) ? esc.encode(esc.decode(s), :hexadecimal) : s
|
67
|
+
end.join
|
68
|
+
end
|
62
69
|
end
|
63
70
|
|
64
71
|
class ColumnBreakBlockMacro < Asciidoctor::Extensions::BlockMacroProcessor
|
@@ -74,51 +81,16 @@ module Metanorma
|
|
74
81
|
# Not using TreeProcessor because that is still too close to
|
75
82
|
# inline expressions being processed on access (e.g. titles)
|
76
83
|
class LinkProtectPreprocessor < Asciidoctor::Extensions::Preprocessor
|
77
|
-
def init
|
78
|
-
pass = true # process as passthrough: init = true until
|
79
|
-
# hit end of doc header
|
80
|
-
is_delim = false # current line is a no-substititon block delimiter
|
81
|
-
pass_delim = false # current line is a passthrough delimiter
|
82
|
-
delimln = "" # delimiter line of current block(s);
|
83
|
-
# init value looks for end of doc header
|
84
|
-
{ pass: pass, is_delim: is_delim, pass_delim: pass_delim,
|
85
|
-
delimln: delimln }
|
86
|
-
end
|
87
|
-
|
88
84
|
def process(document, reader)
|
89
|
-
p =
|
85
|
+
p = Metanorma::Utils::LineStatus.new
|
90
86
|
lines = reader.lines.map do |t|
|
91
|
-
p
|
92
|
-
!p
|
87
|
+
p.process(t)
|
88
|
+
!p.pass && t.include?(":") and t = inlinelinkmacro(inlinelink(t))
|
93
89
|
t
|
94
90
|
end
|
95
91
|
::Asciidoctor::PreprocessorReader.new document, lines
|
96
92
|
end
|
97
93
|
|
98
|
-
def pass_status(status, text)
|
99
|
-
text == "++++" && !status[:delimln] and status[:pass] = !status[:pass]
|
100
|
-
status[:midline_docattr] && !/^:[^ :]+: /.match?(text) and
|
101
|
-
status[:midline_docattr] = false
|
102
|
-
if (status[:is_delim] && /^(-+|\*+|=+|_+)$/.match?(text)) ||
|
103
|
-
(!status[:is_delim] && !status[:delimln] && /^-----*$|^\.\.\.\.\.*$/.match?(text))
|
104
|
-
status[:delimln] = text
|
105
|
-
status[:pass] = true
|
106
|
-
elsif status[:pass_delim]
|
107
|
-
status[:delimln] = "" # end of paragraph for paragraph with [pass]
|
108
|
-
elsif status[:delimln] && text == status[:delimln]
|
109
|
-
status[:pass] = false
|
110
|
-
status[:delimln] = nil
|
111
|
-
elsif /^:[^ :]+: /.match?(text) &&
|
112
|
-
(status[:prev_line].empty? || status[:midline_docattr])
|
113
|
-
status[:pass] = true
|
114
|
-
status[:midline_docattr] = true
|
115
|
-
end
|
116
|
-
status[:is_delim] = /^\[(source|listing|literal|pass)\b/.match?(text)
|
117
|
-
status[:pass_delim] = /^\[(pass)\b/.match?(text)
|
118
|
-
status[:prev_line] = text.strip
|
119
|
-
status
|
120
|
-
end
|
121
|
-
|
122
94
|
PASS_INLINE_MACROS = %w(pass pass-format identifier std-link stem)
|
123
95
|
.join("|").freeze
|
124
96
|
|
@@ -132,7 +104,7 @@ module Metanorma
|
|
132
104
|
\\[.*?(?<!\\\\)\\] # [ ... ] not preceded by \\
|
133
105
|
)
|
134
106
|
REGEX
|
135
|
-
PASS_INLINE_MACRO_RX = /#{PASS_INLINE_MACRO_STR}/xo
|
107
|
+
PASS_INLINE_MACRO_RX = /#{PASS_INLINE_MACRO_STR}/xo
|
136
108
|
|
137
109
|
def pass_inline_split(text)
|
138
110
|
text.split(PASS_INLINE_MACRO_RX).each.map do |x|
|
@@ -142,7 +114,7 @@ module Metanorma
|
|
142
114
|
|
143
115
|
# InlineLinkRx = %r((^|link:|#{CG_BLANK}|<|[>\(\)\[\];"'])(\\?(?:https?|file|ftp|irc)://)(?:([^\s\[\]]+)\[(|#{CC_ALL}*?[^\\])\]|([^\s\[\]<]*([^\s,.?!\[\]<\)]))))m
|
144
116
|
#
|
145
|
-
InlineLinkRx = %r((^|(?<![-\\])\blink:(?!\+)|\p{Blank}|<|[<>\(\)\[\];"'])((?:https?|file|ftp|irc)://)(?:([^\s\[\]]+)(?:(\[(|.*?[^\\])\])|([^\s\[\]<]*([^\s,.?!\[\]<\)])))))m
|
117
|
+
InlineLinkRx = %r((^|(?<![-\\])\blink:(?!\+)|\p{Blank}|<|[<>\(\)\[\];"'])((?:https?|file|ftp|irc)://)(?:([^\s\[\]]+)(?:(\[(|.*?[^\\])\])|([^\s\[\]<]*([^\s,.?!\[\]<\)])))))m
|
146
118
|
|
147
119
|
def inlinelink(text)
|
148
120
|
text.include?("://") or return text
|
@@ -172,7 +144,7 @@ module Metanorma
|
|
172
144
|
(|[^:\\s\\[][^\\s\\[]*) # link: ... up to [
|
173
145
|
(\\[(|.*?[^\\\\])\\]) # [ ... ], no ]
|
174
146
|
REGEX
|
175
|
-
InlineLinkMacroRx = /#{InlineLinkMacroRx1}/x
|
147
|
+
InlineLinkMacroRx = /#{InlineLinkMacroRx1}/x
|
176
148
|
|
177
149
|
def inlinelinkmacro(text)
|
178
150
|
(text.include?("[") &&
|
@@ -37,18 +37,19 @@ module Metanorma
|
|
37
37
|
def process(doc, reader)
|
38
38
|
reader.eof? and return reader
|
39
39
|
r = ::Asciidoctor::PreprocessorNoIfdefsReader.new doc, reader.lines
|
40
|
+
p = Metanorma::Utils::LineStatus.new
|
40
41
|
lines = r.readlines
|
41
42
|
headings = lines.grep(/^== /).map(&:strip)
|
42
43
|
ret = lines.each_with_object(embed_acc(doc, r)) do |line, m|
|
43
|
-
process_line(line, m, headings)
|
44
|
+
process_line(line, m, headings, p)
|
44
45
|
end
|
45
46
|
return_to_document(doc, ret)
|
46
47
|
end
|
47
48
|
|
48
49
|
def embed_acc(doc, reader)
|
49
50
|
{ lines: [], hdr: [], id: [],
|
50
|
-
orig: doc, doc
|
51
|
-
reader
|
51
|
+
orig: doc, doc:, file: nil, path: nil,
|
52
|
+
reader:, prev: nil }
|
52
53
|
end
|
53
54
|
|
54
55
|
# presupposes single embed
|
@@ -93,13 +94,14 @@ module Metanorma
|
|
93
94
|
|
94
95
|
def update_embeds(lines, acc, emb)
|
95
96
|
lines.empty? or
|
96
|
-
acc << { file: emb[:file], path: emb[:path], lines:
|
97
|
+
acc << { file: emb[:file], path: emb[:path], lines: }
|
97
98
|
[[], acc]
|
98
99
|
end
|
99
100
|
|
100
|
-
def process_line(line, acc, headings)
|
101
|
-
|
102
|
-
|
101
|
+
def process_line(line, acc, headings, status)
|
102
|
+
status.process(line)
|
103
|
+
if !status.pass && /^embed::/.match?(line)
|
104
|
+
e = embed(line, acc, headings, status)
|
103
105
|
acc = process_embed(acc, e, acc[:prev])
|
104
106
|
else
|
105
107
|
acc[:lines] << line
|
@@ -148,7 +150,7 @@ module Metanorma
|
|
148
150
|
end
|
149
151
|
end
|
150
152
|
|
151
|
-
def embed(line, acc, headings)
|
153
|
+
def embed(line, acc, headings, status)
|
152
154
|
fname, inc_path = filename(line, acc)
|
153
155
|
lines = filter_sections(read(inc_path), headings)
|
154
156
|
n = Asciidoctor::Document
|
@@ -158,12 +160,12 @@ module Metanorma
|
|
158
160
|
.merge(file: fname, path: inc_path, orig: acc[:orig])
|
159
161
|
ret[:hdr] or
|
160
162
|
raise "Embedding an incomplete document with no header: #{ret[:path]}"
|
161
|
-
embed_recurse(ret, n, r, headings)
|
163
|
+
embed_recurse(ret, n, r, headings, status)
|
162
164
|
end
|
163
165
|
|
164
|
-
def embed_recurse(ret, doc, reader, headings)
|
166
|
+
def embed_recurse(ret, doc, reader, headings, status)
|
165
167
|
ret1 = ret[:lines].each_with_object(embed_acc(doc, reader)) do |line, m|
|
166
|
-
process_line(line, m, headings)
|
168
|
+
process_line(line, m, headings, status)
|
167
169
|
end
|
168
170
|
ret.merge(
|
169
171
|
{ lines: ret1[:lines], id: ret[:id] + ret1[:id],
|
@@ -172,7 +174,7 @@ module Metanorma
|
|
172
174
|
end
|
173
175
|
|
174
176
|
def strip_header(lines)
|
175
|
-
return { lines
|
177
|
+
return { lines:, hdr: nil } unless !lines.empty? &&
|
176
178
|
lines.first.start_with?("= ")
|
177
179
|
|
178
180
|
skip = true
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative "utils"
|
2
|
+
|
1
3
|
module Metanorma
|
2
4
|
module Standoc
|
3
5
|
class InheritInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
@@ -12,49 +14,6 @@ module Metanorma
|
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
15
|
-
class IndexXrefInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
16
|
-
use_dsl
|
17
|
-
named :index
|
18
|
-
|
19
|
-
def preprocess_attrs(attrs)
|
20
|
-
ret = { primary: attrs[1], target: attrs[attrs.size] }
|
21
|
-
ret[:secondary] = attrs[2] if attrs.size > 2
|
22
|
-
ret[:tertiary] = attrs[3] if attrs.size > 3
|
23
|
-
ret
|
24
|
-
end
|
25
|
-
|
26
|
-
def validate(parent, target, attrs)
|
27
|
-
attrs.size > 1 && attrs.size < 5 and return true
|
28
|
-
e = "invalid index \"#{target}\" cross-reference: wrong number of " \
|
29
|
-
"attributes in `index:#{target}[#{attrs.values.join(',')}]`"
|
30
|
-
parent.converter.log.add("Crossreferences", parent, e, severity: 0)
|
31
|
-
false
|
32
|
-
end
|
33
|
-
|
34
|
-
def process(parent, target, attr)
|
35
|
-
validate(parent, target, attr) or return
|
36
|
-
args = preprocess_attrs(attr)
|
37
|
-
ret = "<index-xref also='#{target == 'also'}'>" \
|
38
|
-
"<primary>#{args[:primary]}</primary>"
|
39
|
-
ret += "<secondary>#{args[:secondary]}</secondary>" if args[:secondary]
|
40
|
-
ret += "<tertiary>#{args[:tertiary]}</tertiary>" if args[:tertiary]
|
41
|
-
ret + "<target>#{args[:target]}</target></index-xref>"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class IndexRangeInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
46
|
-
use_dsl
|
47
|
-
named :"index-range"
|
48
|
-
parse_content_as :text
|
49
|
-
|
50
|
-
def process(parent, target, attr)
|
51
|
-
text = attr["text"]
|
52
|
-
text = "((#{text}))" unless /^\(\(.+\)\)$/.match?(text)
|
53
|
-
out = parent.sub_macros(text)
|
54
|
-
out.sub("<index>", "<index to='#{target}'>")
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
17
|
class HTML5RubyMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
59
18
|
use_dsl
|
60
19
|
named :ruby
|
@@ -151,23 +110,6 @@ module Metanorma
|
|
151
110
|
end
|
152
111
|
end
|
153
112
|
|
154
|
-
class ToCInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
155
|
-
use_dsl
|
156
|
-
named :toc
|
157
|
-
parse_content_as :text
|
158
|
-
using_format :short
|
159
|
-
|
160
|
-
def process(parent, _target, attrs)
|
161
|
-
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
162
|
-
content = CSV.parse_line(out).map do |x|
|
163
|
-
x.sub!(/^(["'])(.+)\1/, "\\2")
|
164
|
-
m = /^(.*?)(:\d+)?$/.match(x)
|
165
|
-
%{<toc-xpath depth='#{m[2]&.sub(':', '') || 1}'>#{m[1]}</toc-xpath>}
|
166
|
-
end.join
|
167
|
-
"<toc>#{content}</toc>"
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
113
|
# inject ZWNJ to prevent Asciidoctor from attempting regex substitutions
|
172
114
|
class PassInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
173
115
|
use_dsl
|
@@ -194,32 +136,53 @@ module Metanorma
|
|
194
136
|
end
|
195
137
|
end
|
196
138
|
|
197
|
-
class
|
139
|
+
class SpanInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
198
140
|
use_dsl
|
199
|
-
named :
|
141
|
+
named :span
|
200
142
|
parse_content_as :text
|
201
|
-
using_format :short
|
202
143
|
|
203
|
-
def process(parent,
|
204
|
-
|
205
|
-
|
206
|
-
t.sub(/,/, "%")
|
207
|
-
else
|
208
|
-
"#{t}%"
|
209
|
-
end
|
210
|
-
create_anchor(parent, "hidden=#{t}",
|
211
|
-
type: :xref, target: "_#{UUIDTools::UUID.random_create}")
|
144
|
+
def process(parent, target, attrs)
|
145
|
+
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
146
|
+
%{<span class="#{target}">#{out}</span>}
|
212
147
|
end
|
213
148
|
end
|
214
149
|
|
215
|
-
class
|
150
|
+
class NumberInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
151
|
+
include ::Metanorma::Standoc::Utils
|
152
|
+
|
216
153
|
use_dsl
|
217
|
-
named :
|
154
|
+
named :number
|
218
155
|
parse_content_as :text
|
219
156
|
|
157
|
+
MATHML_NS = "http://www.w3.org/1998/Math/MathML".freeze
|
158
|
+
|
159
|
+
def unquote(str)
|
160
|
+
str.sub(/^(["'])(.+)\1$/, "\\2")
|
161
|
+
end
|
162
|
+
|
163
|
+
def format(attrs)
|
164
|
+
# a="," => "a=,"
|
165
|
+
quoted_csv_split(attrs || "", ",").map do |x|
|
166
|
+
m = /^(.+?)=(.+)?$/.match(x) or next
|
167
|
+
"#{m[1]}='#{m[2]}'"
|
168
|
+
end.join(",")
|
169
|
+
end
|
170
|
+
|
171
|
+
def number(text)
|
172
|
+
n = BigDecimal(text)
|
173
|
+
trailing_zeroes = 0
|
174
|
+
m = /\.[1-9]*(0+)/.match(text) and trailing_zeroes += m[1].size
|
175
|
+
n.to_s("E").sub("e", "0" * trailing_zeroes + "e")
|
176
|
+
end
|
177
|
+
|
220
178
|
def process(parent, target, attrs)
|
221
179
|
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
222
|
-
|
180
|
+
fmt = format(out)
|
181
|
+
fmt.empty? and fmt = "notation='basic'"
|
182
|
+
fmt = %( data-metanorma-numberformat="#{fmt}")
|
183
|
+
<<~OUTPUT
|
184
|
+
<stem type="MathML"><math xmlns='#{MATHML_NS}'><mn#{fmt}>#{number(target)}</mn></math></stem>
|
185
|
+
OUTPUT
|
223
186
|
end
|
224
187
|
end
|
225
188
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Metanorma
|
2
|
+
module Standoc
|
3
|
+
class IndexXrefInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
4
|
+
use_dsl
|
5
|
+
named :index
|
6
|
+
|
7
|
+
def preprocess_attrs(attrs)
|
8
|
+
ret = { primary: attrs[1], target: attrs[attrs.size] }
|
9
|
+
ret[:secondary] = attrs[2] if attrs.size > 2
|
10
|
+
ret[:tertiary] = attrs[3] if attrs.size > 3
|
11
|
+
ret
|
12
|
+
end
|
13
|
+
|
14
|
+
def validate(parent, target, attrs)
|
15
|
+
attrs.size > 1 && attrs.size < 5 and return true
|
16
|
+
e = "invalid index \"#{target}\" cross-reference: wrong number of " \
|
17
|
+
"attributes in `index:#{target}[#{attrs.values.join(',')}]`"
|
18
|
+
parent.converter.log.add("Crossreferences", parent, e, severity: 0)
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
def process(parent, target, attr)
|
23
|
+
validate(parent, target, attr) or return
|
24
|
+
args = preprocess_attrs(attr)
|
25
|
+
ret = "<index-xref also='#{target == 'also'}'>" \
|
26
|
+
"<primary>#{args[:primary]}</primary>"
|
27
|
+
ret += "<secondary>#{args[:secondary]}</secondary>" if args[:secondary]
|
28
|
+
ret += "<tertiary>#{args[:tertiary]}</tertiary>" if args[:tertiary]
|
29
|
+
ret + "<target>#{args[:target]}</target></index-xref>"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class IndexRangeInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
34
|
+
use_dsl
|
35
|
+
named :"index-range"
|
36
|
+
parse_content_as :text
|
37
|
+
|
38
|
+
def process(parent, target, attr)
|
39
|
+
text = attr["text"]
|
40
|
+
text = "((#{text}))" unless /^\(\(.+\)\)$/.match?(text)
|
41
|
+
out = parent.sub_macros(text)
|
42
|
+
out.sub("<index>", "<index to='#{target}'>")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class ToCInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
47
|
+
use_dsl
|
48
|
+
named :toc
|
49
|
+
parse_content_as :text
|
50
|
+
using_format :short
|
51
|
+
|
52
|
+
def process(parent, _target, attrs)
|
53
|
+
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
54
|
+
content = CSV.parse_line(out).map do |x|
|
55
|
+
x.sub!(/^(["'])(.+)\1/, "\\2")
|
56
|
+
m = /^(.*?)(:\d+)?$/.match(x)
|
57
|
+
%{<toc-xpath depth='#{m[2]&.sub(':', '') || 1}'>#{m[1]}</toc-xpath>}
|
58
|
+
end.join
|
59
|
+
"<toc>#{content}</toc>"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class StdLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
64
|
+
use_dsl
|
65
|
+
named :"std-link"
|
66
|
+
parse_content_as :text
|
67
|
+
using_format :short
|
68
|
+
|
69
|
+
def process(parent, _target, attrs)
|
70
|
+
t = attrs["text"]
|
71
|
+
t = if /,/.match?(t)
|
72
|
+
t.sub(/,/, "%")
|
73
|
+
else
|
74
|
+
"#{t}%"
|
75
|
+
end
|
76
|
+
create_anchor(parent, "hidden=#{t}",
|
77
|
+
type: :xref, target: "_#{UUIDTools::UUID.random_create}")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -27,7 +27,7 @@ module Metanorma
|
|
27
27
|
def isorefmatchescode(match, _item)
|
28
28
|
code = analyse_ref_code(match[:code])
|
29
29
|
yr = norm_year(match[:year])
|
30
|
-
{ code: match[:code], year: yr, match
|
30
|
+
{ code: match[:code], year: yr, match:,
|
31
31
|
title: match[:text], usrlbl: match[:usrlbl] || code[:usrlabel],
|
32
32
|
analyse_code: code, lang: @lang || :all }
|
33
33
|
end
|
@@ -47,7 +47,7 @@ module Metanorma
|
|
47
47
|
def isorefmatches2code(match, _item)
|
48
48
|
code = analyse_ref_code(match[:code])
|
49
49
|
{ code: match[:code], no_year: true, lang: @lang || :all,
|
50
|
-
note: match[:fn], year: nil, match
|
50
|
+
note: match[:fn], year: nil, match:, analyse_code: code,
|
51
51
|
title: match[:text], usrlbl: match[:usrlbl] || code[:usrlabel] }
|
52
52
|
end
|
53
53
|
|
@@ -77,7 +77,7 @@ module Metanorma
|
|
77
77
|
code = analyse_ref_code(match[:code])
|
78
78
|
yr = norm_year(match[:year])
|
79
79
|
hasyr = !yr.nil? && yr != "--"
|
80
|
-
{ code: match[:code], match
|
80
|
+
{ code: match[:code], match:, yr:, hasyr:,
|
81
81
|
year: hasyr ? yr : nil, lang: @lang || :all,
|
82
82
|
all_parts: true, no_year: yr == "--",
|
83
83
|
title: match[:text], usrlbl: match[:usrlbl] || code[:usrlabel] }
|
@@ -162,11 +162,11 @@ module Metanorma
|
|
162
162
|
def refitem1code(_item, match)
|
163
163
|
code = analyse_ref_code(match[:code])
|
164
164
|
((code[:id] && code[:numeric]) || code[:nofetch]) and
|
165
|
-
return { code: nil, match
|
165
|
+
return { code: nil, match:, analyse_code: code,
|
166
166
|
hidden: code[:hidden] }
|
167
167
|
{ code: code[:id], analyse_code: code, localfile: code[:localfile],
|
168
168
|
year: (m = refitem1yr(code[:id])) ? m[:year] : nil,
|
169
|
-
title: match[:text], match
|
169
|
+
title: match[:text], match:, hidden: code[:hidden],
|
170
170
|
usrlbl: match[:usrlbl] || code[:usrlabel], lang: @lang || :all }
|
171
171
|
end
|
172
172
|
|
@@ -187,29 +187,26 @@ module Metanorma
|
|
187
187
|
ISO_REF =
|
188
188
|
%r{^<ref\sid="(?<anchor>[^"]+)">
|
189
189
|
\[(?<usrlbl>\([^)]+\))?(?<code>(?:ISO|IEC)[^0-9]*\s[0-9-]+|IEV)
|
190
|
-
(?::(?<year>[0-9][0-9-]+))?\]</ref>,?\s*(?<text>.*)$}xm
|
190
|
+
(?::(?<year>[0-9][0-9-]+))?\]</ref>,?\s*(?<text>.*)$}xm
|
191
191
|
|
192
192
|
ISO_REF_NO_YEAR =
|
193
193
|
%r{^<ref\sid="(?<anchor>[^"]+)">
|
194
194
|
\[(?<usrlbl>\([^)]+\))?(?<code>(?:ISO|IEC)[^0-9]*\s[0-9-]+):
|
195
|
-
(
|
195
|
+
(?:--|–|—|&\#821[12];)\]</ref>,?\s*
|
196
196
|
(?:<fn[^>]*>\s*<p>(?<fn>[^\]]+)</p>\s*</fn>)?,?\s?(?<text>.*)$}xm
|
197
|
-
.freeze
|
198
197
|
|
199
198
|
ISO_REF_ALL_PARTS =
|
200
199
|
%r{^<ref\sid="(?<anchor>[^"]+)">
|
201
200
|
\[(?<usrlbl>\([^)]+\))?(?<code>(?:ISO|IEC)[^0-9]*\s[0-9]+)
|
202
|
-
(?::(?<year
|
201
|
+
(?::(?<year>--|–|—|&\#821[12];|[0-9][0-9-]+))?\s
|
203
202
|
\(all\sparts\)\]</ref>,?\s*
|
204
|
-
(?:<fn[^>]*>\s*<p>(?<fn>[^\]]+)</p>\s*</fn>,?\s?)?(?<text>.*)$}xm
|
203
|
+
(?:<fn[^>]*>\s*<p>(?<fn>[^\]]+)</p>\s*</fn>,?\s?)?(?<text>.*)$}xm
|
205
204
|
|
206
205
|
NON_ISO_REF = %r{^<ref\sid="(?<anchor>[^"]+)">
|
207
206
|
\[(?<usrlbl>\([^)]+\))?(?<code>.+?)\]</ref>,?\s*(?<text>.*)$}xm
|
208
|
-
.freeze
|
209
207
|
|
210
208
|
NON_ISO_REF1 = %r{^<ref\sid="(?<anchor>[^"]+)">
|
211
209
|
(?<usrlbl>\([^)]+\))?(?<code>.+?)</ref>,?\s*(?<text>.*)$}xm
|
212
|
-
.freeze
|
213
210
|
|
214
211
|
def reference1_matches(item)
|
215
212
|
matched = ISO_REF.match item
|
@@ -122,16 +122,14 @@ module Metanorma
|
|
122
122
|
end
|
123
123
|
|
124
124
|
def local_ievcache_name(cachename)
|
125
|
-
|
126
|
-
|
125
|
+
cachename.nil? and return nil
|
127
126
|
cachename += "_iev" unless cachename.empty?
|
128
127
|
cachename = "iev" if cachename.empty?
|
129
128
|
"#{cachename}/cache"
|
130
129
|
end
|
131
130
|
|
132
131
|
def fetch_ref(xml, code, year, **opts)
|
133
|
-
|
134
|
-
|
132
|
+
opts[:no_year] and return nil
|
135
133
|
code = code.sub(/^\([^)]+\)/, "")
|
136
134
|
hit = fetch_ref1(code, year, opts) or return nil
|
137
135
|
xml.parent.add_child(smart_render_xml(hit, code, opts))
|
@@ -200,8 +200,8 @@ module Metanorma
|
|
200
200
|
|
201
201
|
MALFORMED_REF = <<~REF.freeze
|
202
202
|
no anchor on reference, markup may be malformed: see
|
203
|
-
https://www.metanorma.
|
204
|
-
https://www.metanorma.
|
203
|
+
https://www.metanorma.org/author/topics/sections/bibliography/ ,
|
204
|
+
https://www.metanorma.org/author/iso/topics/markup/#bibliographies
|
205
205
|
REF
|
206
206
|
|
207
207
|
def ref_normalise(ref)
|
@@ -16,8 +16,7 @@ module Metanorma
|
|
16
16
|
.gsub(%r{<index>.*?</index>}m, "")
|
17
17
|
.gsub(%r{<fn[^>]*>.*?</fn>}m, "")
|
18
18
|
.gsub(/<[^>]+>/, "")
|
19
|
-
.strip.downcase
|
20
|
-
.sub(/\.$/, "")
|
19
|
+
.strip.downcase.sub(/\.$/, "")
|
21
20
|
end
|
22
21
|
|
23
22
|
def sectiontype(node, level = true)
|
@@ -41,7 +40,8 @@ module Metanorma
|
|
41
40
|
"terms, definitions and abbreviated terms"
|
42
41
|
"terms and definitions"
|
43
42
|
when "symbols and abbreviated terms",
|
44
|
-
"symbols", "abbreviated terms", "abbreviations"
|
43
|
+
"symbols", "abbreviated terms", "abbreviations",
|
44
|
+
"symbols and abbreviations"
|
45
45
|
"symbols and abbreviated terms"
|
46
46
|
when "acknowledgements", "acknowledgments"
|
47
47
|
"acknowledgements"
|
@@ -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.join("")
|
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.join("")
|
182
182
|
end
|
183
183
|
end
|
184
184
|
end
|
@@ -17,8 +17,8 @@ module Metanorma
|
|
17
17
|
nil
|
18
18
|
end
|
19
19
|
|
20
|
-
def noko(&
|
21
|
-
Metanorma::Utils::noko(@script, &
|
20
|
+
def noko(&)
|
21
|
+
Metanorma::Utils::noko(@script, &)
|
22
22
|
end
|
23
23
|
|
24
24
|
def attr_code(attributes)
|
@@ -30,6 +30,26 @@ module Metanorma
|
|
30
30
|
.map { |x| @c.encode(x, :basic, :hexadecimal) }
|
31
31
|
end
|
32
32
|
|
33
|
+
def quoted_csv_split(text, delim = ",", eql = "=")
|
34
|
+
# quoted strings: key="va,lue",
|
35
|
+
c = HTMLEntities.new
|
36
|
+
text = c.decode(text).gsub(/([a-zA-Z_]+)#{eql}(["'])(.+?)\2/,
|
37
|
+
%("\\1#{eql}\\3"))
|
38
|
+
Metanorma::Utils::csv_split(text, delim)
|
39
|
+
.map do |x|
|
40
|
+
c.encode(x.sub(/^(["'])(.+)\1$/, "\\2"), :basic, :hexadecimal)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def kv_parse(text, delim = ",", eql = "=")
|
45
|
+
text or return {}
|
46
|
+
c = HTMLEntities.new
|
47
|
+
quoted_csv_split(text, delim).each_with_object({}) do |k, m|
|
48
|
+
x = k.split(eql, 2)
|
49
|
+
m[x[0]] = c.decode(x[1])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
33
53
|
def wrap_in_para(node, out)
|
34
54
|
Metanorma::Utils::wrap_in_para(node, out)
|
35
55
|
end
|
@@ -48,7 +48,6 @@ module Metanorma
|
|
48
48
|
def mathml_sanitise(math)
|
49
49
|
math.to_xml(encoding: "US-ASCII").gsub(/ xmlns=["'][^"']+["']/, "")
|
50
50
|
.gsub(%r{<[^:/>]+:}, "<").gsub(%r{</[^:/>]+:}, "</")
|
51
|
-
# .gsub(/&#([^;]+);/) { |x| "&#x#{$1.to_i.to_s(16)};" }
|
52
51
|
end
|
53
52
|
|
54
53
|
def math_validate_error(math, elem, error)
|
@@ -133,7 +132,7 @@ module Metanorma
|
|
133
132
|
doc.xpath(WILDCARD_ATTRS, "m" => SVG_NS).each do |n|
|
134
133
|
n.elements.each do |e|
|
135
134
|
e.traverse do |e1|
|
136
|
-
e1.element? and e1.each { |k, _v| e1.delete(k) }
|
135
|
+
e1.element? and e1.each { |k, _v| e1.delete(k) } # rubocop:disable Style/HashEachMethods
|
137
136
|
end
|
138
137
|
end
|
139
138
|
end
|
@@ -143,6 +142,7 @@ module Metanorma
|
|
143
142
|
|
144
143
|
def image_validate(doc)
|
145
144
|
image_exists(doc)
|
145
|
+
image_toobig(doc)
|
146
146
|
png_validate(doc)
|
147
147
|
end
|
148
148
|
|
@@ -183,6 +183,18 @@ module Metanorma
|
|
183
183
|
"Corrupt PNG image detected: #{e.message}")
|
184
184
|
end
|
185
185
|
|
186
|
+
TOO_BIG_IMG_ERR = <<~ERR.freeze
|
187
|
+
Image too large for Data URI encoding: disable Data URI encoding (`:data-uri-image: false`), or set `:data-uri-maxsize: 0`
|
188
|
+
ERR
|
189
|
+
|
190
|
+
def image_toobig(doc)
|
191
|
+
@dataurimaxsize.zero? and return
|
192
|
+
doc.xpath("//image").each do |i|
|
193
|
+
i["src"].size > @dataurimaxsize and
|
194
|
+
@log.add("Images", i.parent, TOO_BIG_IMG_ERR, severity: 0)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
186
198
|
def validate(doc)
|
187
199
|
content_validate(doc)
|
188
200
|
schema_validate(formattedstr_strip(doc.dup),
|