metanorma-standoc 1.9.3 → 1.10.2
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/.github/workflows/rake.yml +3 -13
- data/.hound.yml +3 -1
- data/.rubocop.yml +4 -6
- data/lib/asciidoctor/standoc/base.rb +3 -1
- data/lib/asciidoctor/standoc/blocks.rb +1 -1
- data/lib/asciidoctor/standoc/cleanup.rb +1 -2
- data/lib/asciidoctor/standoc/cleanup_block.rb +0 -1
- data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +2 -2
- data/lib/asciidoctor/standoc/cleanup_footnotes.rb +0 -1
- data/lib/asciidoctor/standoc/cleanup_inline.rb +117 -77
- data/lib/asciidoctor/standoc/cleanup_maths.rb +0 -1
- data/lib/asciidoctor/standoc/cleanup_ref.rb +7 -0
- data/lib/asciidoctor/standoc/cleanup_section.rb +13 -81
- data/lib/asciidoctor/standoc/cleanup_section_names.rb +75 -0
- data/lib/asciidoctor/standoc/cleanup_terms.rb +19 -18
- data/lib/asciidoctor/standoc/converter.rb +1 -0
- data/lib/asciidoctor/standoc/front.rb +0 -1
- data/lib/asciidoctor/standoc/front_contributor.rb +66 -42
- data/lib/asciidoctor/standoc/inline.rb +45 -34
- data/lib/asciidoctor/standoc/isodoc.rng +65 -7
- data/lib/asciidoctor/standoc/macros.rb +7 -5
- data/lib/asciidoctor/standoc/macros_plantuml.rb +21 -23
- data/lib/asciidoctor/standoc/macros_terms.rb +60 -23
- data/lib/asciidoctor/standoc/section.rb +19 -12
- data/lib/asciidoctor/standoc/term_lookup_cleanup.rb +69 -30
- data/lib/asciidoctor/standoc/terms.rb +1 -1
- data/lib/asciidoctor/standoc/utils.rb +0 -1
- data/lib/asciidoctor/standoc/validate.rb +22 -8
- data/lib/isodoc/html/html_titlepage.html +81 -0
- data/lib/isodoc/html/htmlstyle.css +983 -0
- data/lib/isodoc/html/htmlstyle.scss +714 -0
- data/lib/isodoc/html/scripts.html +71 -0
- data/lib/metanorma/standoc/processor.rb +16 -7
- data/lib/metanorma/standoc/version.rb +1 -1
- data/metanorma-standoc.gemspec +2 -2
- data/spec/asciidoctor/base_spec.rb +693 -553
- data/spec/asciidoctor/blocks_spec.rb +6 -6
- data/spec/asciidoctor/cleanup_spec.rb +899 -688
- data/spec/asciidoctor/inline_spec.rb +62 -14
- data/spec/asciidoctor/isobib_cache_spec.rb +4 -6
- data/spec/asciidoctor/lists_spec.rb +147 -135
- data/spec/asciidoctor/macros_json2text_spec.rb +1 -1
- data/spec/asciidoctor/macros_spec.rb +714 -168
- data/spec/asciidoctor/refs_spec.rb +1527 -1532
- data/spec/asciidoctor/validate_spec.rb +352 -304
- data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +51 -51
- data/spec/vcr_cassettes/isobib_get_123.yml +14 -14
- data/spec/vcr_cassettes/isobib_get_123_1.yml +27 -27
- data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +36 -36
- data/spec/vcr_cassettes/isobib_get_123_2001.yml +12 -12
- data/spec/vcr_cassettes/isobib_get_124.yml +13 -13
- data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +14 -14
- data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +46 -46
- metadata +10 -5
@@ -9,8 +9,8 @@ require "latexmath"
|
|
9
9
|
module Asciidoctor
|
10
10
|
module Standoc
|
11
11
|
module Inline
|
12
|
-
def refid?(
|
13
|
-
@refids.include?
|
12
|
+
def refid?(ref)
|
13
|
+
@refids.include? ref
|
14
14
|
end
|
15
15
|
|
16
16
|
def inline_anchor(node)
|
@@ -46,19 +46,20 @@ module Asciidoctor
|
|
46
46
|
def inline_anchor_xref_attrs(node)
|
47
47
|
m = /^(?<drop>droploc%)?(?<case>capital%|lowercase%)?(?<drop2>droploc%)?
|
48
48
|
(?<fn>fn:?\s*)?(?<text>.*)$/x.match node.text
|
49
|
-
casing = m.nil? ? nil : m[:case]&.sub(/%$/, "")
|
50
|
-
droploc = m.nil? ? nil : ((m[:drop].nil? && m[:drop2].nil?) ? nil: true)
|
51
|
-
f = (m.nil? || m[:fn].nil?) ? "inline" : "footnote"
|
52
|
-
c = (!m.nil? && (%i[case fn drop drop2].any? { |x| !m[x].nil? })) ?
|
53
|
-
m[:text] : node.text
|
54
49
|
t = node.target.gsub(/^#/, "").gsub(%r{(\.xml|\.adoc)(#.*$)}, "\\2")
|
55
|
-
{ target: t, type:
|
50
|
+
m.nil? and return { target: t, type: "inline", text: node.text }
|
51
|
+
droploc = m[:drop].nil? && m[:drop2].nil? ? nil : true
|
52
|
+
f = m[:fn].nil? ? "inline" : "footnote"
|
53
|
+
c = %i[case fn drop drop2].any? { |x| !m[x].nil? } ? m[:text] : node.text
|
54
|
+
{ target: t, type: f, case: m[:case]&.sub(/%$/, ""), droploc: droploc,
|
55
|
+
text: c }
|
56
56
|
end
|
57
57
|
|
58
58
|
def inline_anchor_link(node)
|
59
59
|
contents = node.text
|
60
60
|
contents = "" if node.target.gsub(%r{^mailto:}, "") == node.text
|
61
|
-
attributes = { "target": node.target, "alt": node.attr("title")
|
61
|
+
attributes = { "target": node.target, "alt": node.attr("title"),
|
62
|
+
"updatetype": node.attr("updatetype") }
|
62
63
|
noko do |xml|
|
63
64
|
xml.link **attr_code(attributes) do |l|
|
64
65
|
l << contents
|
@@ -67,8 +68,8 @@ module Asciidoctor
|
|
67
68
|
end
|
68
69
|
|
69
70
|
def inline_anchor_bibref(node)
|
70
|
-
eref_contents = (node.text || node.target || node.id)
|
71
|
-
sub(/^\[?([^\[\]]+?)\]?$/, "[\\1]")
|
71
|
+
eref_contents = (node.text || node.target || node.id)
|
72
|
+
&.sub(/^\[?([^\[\]]+?)\]?$/, "[\\1]")
|
72
73
|
eref_attributes = { id: node.target || node.id }
|
73
74
|
@refids << (node.target || node.id)
|
74
75
|
noko do |xml|
|
@@ -105,7 +106,7 @@ module Asciidoctor
|
|
105
106
|
attrs = {}
|
106
107
|
node.option?("landscape") and attrs[:orientation] = "landscape"
|
107
108
|
node.option?("portrait") and attrs[:orientation] = "portrait"
|
108
|
-
noko { |xml| xml.pagebreak **attr_code(attrs)}.join
|
109
|
+
noko { |xml| xml.pagebreak **attr_code(attrs) }.join
|
109
110
|
end
|
110
111
|
|
111
112
|
def thematic_break(_node)
|
@@ -113,41 +114,45 @@ module Asciidoctor
|
|
113
114
|
end
|
114
115
|
|
115
116
|
def xml_encode(text)
|
116
|
-
HTMLEntities.new.encode(text, :basic, :hexadecimal)
|
117
|
-
gsub(/&gt;/, ">").gsub(
|
118
|
-
gsub(/>/, ">").gsub(/</, "<").gsub(/&/, "&")
|
119
|
-
gsub(/"/, '"').gsub(/
/, "\n").gsub(/&#/, "&#")
|
117
|
+
HTMLEntities.new.encode(text, :basic, :hexadecimal)
|
118
|
+
.gsub(/&gt;/, ">").gsub(/&lt;/, "<").gsub(/&amp;/, "&")
|
119
|
+
.gsub(/>/, ">").gsub(/</, "<").gsub(/&/, "&")
|
120
|
+
.gsub(/"/, '"').gsub(/
/, "\n").gsub(/&#/, "&#")
|
120
121
|
end
|
121
122
|
|
122
|
-
def
|
123
|
+
def latex_parse1(text)
|
123
124
|
lxm_input = Unicode2LaTeX.unicode2latex(HTMLEntities.new.decode(text))
|
124
125
|
results = Latexmath.parse(lxm_input).to_mathml
|
125
126
|
results.nil? and
|
126
|
-
@log.add(
|
127
|
+
@log.add("Math", nil,
|
127
128
|
"latexmlmath failed to process equation:\n#{lxm_input}")
|
128
129
|
results&.sub(%r{<math ([^>]+ )?display="block"}, "<math \\1")
|
129
130
|
end
|
130
131
|
|
131
132
|
def stem_parse(text, xml, style)
|
132
133
|
if /<([^:>&]+:)?math(\s+[^>&]+)?> |
|
133
|
-
<([^:>&]+:)?math(\s+[^>&]+)?>/x.match text
|
134
|
+
<([^:>&]+:)?math(\s+[^>&]+)?>/x.match? text
|
134
135
|
math = xml_encode(text)
|
135
136
|
xml.stem math, **{ type: "MathML" }
|
136
|
-
elsif style == :latexmath
|
137
|
-
latex = latex_parse(text) or return xml.stem **{ type: "MathML" }
|
138
|
-
xml.stem **{ type: "MathML" } do |s|
|
139
|
-
math = Nokogiri::XML.fragment(latex.sub(/<\?[^>]+>/, "")).elements[0]
|
140
|
-
math.delete("alttext")
|
141
|
-
s.parent.children = math
|
142
|
-
end
|
137
|
+
elsif style == :latexmath then latex_parse(text, xml)
|
143
138
|
else
|
144
|
-
xml.stem text&.gsub(
|
139
|
+
xml.stem text&.gsub(/&#/, "&#"), **{ type: "AsciiMath" }
|
145
140
|
end
|
146
141
|
end
|
147
142
|
|
148
|
-
|
149
|
-
|
143
|
+
def latex_parse(text, xml)
|
144
|
+
latex = latex_parse1(text) or return xml.stem **{ type: "MathML" }
|
145
|
+
xml.stem **{ type: "MathML" } do |s|
|
146
|
+
math = Nokogiri::XML.fragment(latex.sub(/<\?[^>]+>/, ""))
|
147
|
+
.elements[0]
|
148
|
+
math.delete("alttext")
|
149
|
+
s.parent.children = math
|
150
150
|
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def highlight_parse(text, xml)
|
154
|
+
xml << text
|
155
|
+
end
|
151
156
|
|
152
157
|
def inline_quoted(node)
|
153
158
|
noko do |xml|
|
@@ -182,14 +187,20 @@ module Asciidoctor
|
|
182
187
|
|
183
188
|
def image_attributes(node)
|
184
189
|
uri = node.image_uri (node.attr("target") || node.target)
|
185
|
-
types = /^data:/.match(uri)
|
190
|
+
types = if /^data:/.match?(uri) then Metanorma::Utils::datauri2mime(uri)
|
191
|
+
else MIME::Types.type_for(uri)
|
192
|
+
end
|
186
193
|
type = types.first.to_s
|
187
194
|
uri = uri.sub(%r{^data:image/\*;}, "data:#{type};")
|
188
|
-
|
195
|
+
image_attributes1(node, uri, type)
|
196
|
+
end
|
197
|
+
|
198
|
+
def image_attributes1(node, uri, type)
|
199
|
+
attr_code(src: uri,
|
189
200
|
id: Metanorma::Utils::anchor_or_uuid,
|
190
201
|
mimetype: type,
|
191
202
|
height: node.attr("height") || "auto",
|
192
|
-
width: node.attr("width") || "auto"
|
203
|
+
width: node.attr("width") || "auto",
|
193
204
|
filename: node.attr("filename"),
|
194
205
|
title: node.attr("titleattr"),
|
195
206
|
alt: node.alt == node.attr("default-alt") ? nil : node.alt)
|
@@ -197,14 +208,14 @@ module Asciidoctor
|
|
197
208
|
|
198
209
|
def inline_image(node)
|
199
210
|
noko do |xml|
|
200
|
-
xml.image **
|
211
|
+
xml.image **image_attributes(node)
|
201
212
|
end.join("")
|
202
213
|
end
|
203
214
|
|
204
215
|
def inline_indexterm(node)
|
205
216
|
noko do |xml|
|
206
217
|
node.type == :visible and xml << node.text
|
207
|
-
|
218
|
+
terms = (node.attr("terms") || [node.text]).map { |x| xml_encode(x) }
|
208
219
|
xml.index do |i|
|
209
220
|
i.primary { |x| x << terms[0] }
|
210
221
|
a = terms.dig(1) and i.secondary { |x| x << a }
|
@@ -45,6 +45,11 @@
|
|
45
45
|
<optional>
|
46
46
|
<attribute name="alt"/>
|
47
47
|
</optional>
|
48
|
+
<optional>
|
49
|
+
<attribute name="updatetype">
|
50
|
+
<data type="boolean"/>
|
51
|
+
</attribute>
|
52
|
+
</optional>
|
48
53
|
<text/>
|
49
54
|
</element>
|
50
55
|
</define>
|
@@ -199,6 +204,18 @@
|
|
199
204
|
</zeroOrMore>
|
200
205
|
</element>
|
201
206
|
</define>
|
207
|
+
<define name="dt">
|
208
|
+
<element name="dt">
|
209
|
+
<optional>
|
210
|
+
<attribute name="id">
|
211
|
+
<data type="ID"/>
|
212
|
+
</attribute>
|
213
|
+
</optional>
|
214
|
+
<zeroOrMore>
|
215
|
+
<ref name="TextElement"/>
|
216
|
+
</zeroOrMore>
|
217
|
+
</element>
|
218
|
+
</define>
|
202
219
|
<define name="example">
|
203
220
|
<element name="example">
|
204
221
|
<attribute name="id">
|
@@ -543,6 +560,9 @@
|
|
543
560
|
</define>
|
544
561
|
<define name="BibDataExtensionType">
|
545
562
|
<ref name="doctype"/>
|
563
|
+
<optional>
|
564
|
+
<ref name="docsubtype"/>
|
565
|
+
</optional>
|
546
566
|
<optional>
|
547
567
|
<ref name="editorialgroup"/>
|
548
568
|
</optional>
|
@@ -890,6 +910,14 @@
|
|
890
910
|
</define>
|
891
911
|
</include>
|
892
912
|
<!-- end overrides -->
|
913
|
+
<define name="docsubtype">
|
914
|
+
<element name="subdoctype">
|
915
|
+
<ref name="DocumentSubtype"/>
|
916
|
+
</element>
|
917
|
+
</define>
|
918
|
+
<define name="DocumentSubtype">
|
919
|
+
<text/>
|
920
|
+
</define>
|
893
921
|
<define name="colgroup">
|
894
922
|
<element name="colgroup">
|
895
923
|
<oneOrMore>
|
@@ -939,7 +967,34 @@
|
|
939
967
|
<define name="concept">
|
940
968
|
<element name="concept">
|
941
969
|
<optional>
|
942
|
-
<attribute name="
|
970
|
+
<attribute name="ital">
|
971
|
+
<data type="boolean"/>
|
972
|
+
</attribute>
|
973
|
+
</optional>
|
974
|
+
<optional>
|
975
|
+
<attribute name="ref">
|
976
|
+
<data type="boolean"/>
|
977
|
+
</attribute>
|
978
|
+
</optional>
|
979
|
+
<optional>
|
980
|
+
<element name="refterm">
|
981
|
+
<zeroOrMore>
|
982
|
+
<choice>
|
983
|
+
<ref name="PureTextElement"/>
|
984
|
+
<ref name="stem"/>
|
985
|
+
</choice>
|
986
|
+
</zeroOrMore>
|
987
|
+
</element>
|
988
|
+
</optional>
|
989
|
+
<optional>
|
990
|
+
<element name="renderterm">
|
991
|
+
<zeroOrMore>
|
992
|
+
<choice>
|
993
|
+
<ref name="PureTextElement"/>
|
994
|
+
<ref name="stem"/>
|
995
|
+
</choice>
|
996
|
+
</zeroOrMore>
|
997
|
+
</element>
|
943
998
|
</optional>
|
944
999
|
<choice>
|
945
1000
|
<ref name="eref"/>
|
@@ -965,6 +1020,9 @@
|
|
965
1020
|
</attribute>
|
966
1021
|
<attribute name="name"/>
|
967
1022
|
<attribute name="action"/>
|
1023
|
+
<optional>
|
1024
|
+
<attribute name="class"/>
|
1025
|
+
</optional>
|
968
1026
|
<zeroOrMore>
|
969
1027
|
<choice>
|
970
1028
|
<ref name="TextElement"/>
|
@@ -1457,26 +1515,26 @@
|
|
1457
1515
|
<optional>
|
1458
1516
|
<ref name="section-title"/>
|
1459
1517
|
</optional>
|
1460
|
-
<
|
1518
|
+
<choice>
|
1461
1519
|
<choice>
|
1462
1520
|
<group>
|
1463
|
-
<
|
1521
|
+
<oneOrMore>
|
1464
1522
|
<ref name="BasicBlock"/>
|
1465
|
-
</
|
1523
|
+
</oneOrMore>
|
1466
1524
|
<zeroOrMore>
|
1467
1525
|
<ref name="note"/>
|
1468
1526
|
</zeroOrMore>
|
1469
1527
|
</group>
|
1470
1528
|
<ref name="amend"/>
|
1471
1529
|
</choice>
|
1472
|
-
<
|
1530
|
+
<oneOrMore>
|
1473
1531
|
<choice>
|
1474
1532
|
<ref name="clause-subsection"/>
|
1475
1533
|
<ref name="terms"/>
|
1476
1534
|
<ref name="definitions"/>
|
1477
1535
|
</choice>
|
1478
|
-
</
|
1479
|
-
</
|
1536
|
+
</oneOrMore>
|
1537
|
+
</choice>
|
1480
1538
|
</define>
|
1481
1539
|
<define name="Annex-Section">
|
1482
1540
|
<optional>
|
@@ -75,7 +75,7 @@ module Asciidoctor
|
|
75
75
|
def supply_br(lines)
|
76
76
|
ignore = false
|
77
77
|
lines.each_with_index do |l, i|
|
78
|
-
/^(
|
78
|
+
/^(--+|====+|\|===|\.\.\.\.+|\*\*\*\*+|\+\+\+\++|````+|____\+)$/
|
79
79
|
.match(l) && (ignore = !ignore)
|
80
80
|
next if l.empty? || l.match(/ \+$/) || /^\[.*\]$/.match?(l) || ignore
|
81
81
|
next if i == lines.size - 1 ||
|
@@ -107,7 +107,7 @@ module Asciidoctor
|
|
107
107
|
if (attributes.size == 1) && attributes.key?("text")
|
108
108
|
rt = attributes["text"]
|
109
109
|
elsif (attributes.size == 2) && attributes.key?(1) &&
|
110
|
-
|
110
|
+
attributes.key?("rpbegin")
|
111
111
|
rt = attributes[1] || ""
|
112
112
|
else
|
113
113
|
rpbegin = attributes["rpbegin"]
|
@@ -143,7 +143,7 @@ module Asciidoctor
|
|
143
143
|
para.set_attr("caption", "TODO")
|
144
144
|
para.lines[0].sub!(/^TODO: /, "")
|
145
145
|
todo = Block.new(parent, :admonition, attributes: para.attributes,
|
146
|
-
|
146
|
+
source: para.lines, content_model: :compound)
|
147
147
|
parent.blocks[parent.blocks.index(para)] = todo
|
148
148
|
end
|
149
149
|
end
|
@@ -168,9 +168,11 @@ module Asciidoctor
|
|
168
168
|
def process(parent, target, attrs)
|
169
169
|
/^(?<lang>[^-]*)(-(?<script>.*))?$/ =~ target
|
170
170
|
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
171
|
-
script
|
172
|
-
%{<variant lang=#{lang} script=#{script}>#{out}</variant>}
|
171
|
+
if script
|
172
|
+
%{<variant lang=#{lang} script=#{script}>#{out}</variant>}
|
173
|
+
else
|
173
174
|
%{<variant lang=#{lang}>#{out}</variant>}
|
175
|
+
end
|
174
176
|
end
|
175
177
|
end
|
176
178
|
|
@@ -4,18 +4,17 @@ module Asciidoctor
|
|
4
4
|
# https://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
|
5
5
|
def self.plantuml_installed?
|
6
6
|
cmd = "plantuml"
|
7
|
-
exts = ENV[
|
8
|
-
ENV[
|
7
|
+
exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [""]
|
8
|
+
ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
|
9
9
|
exts.each do |ext|
|
10
10
|
exe = File.join(path, "#{cmd}#{ext}")
|
11
11
|
return exe if File.executable?(exe) && !File.directory?(exe)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
raise "PlantUML not installed"
|
15
|
-
nil
|
16
15
|
end
|
17
16
|
|
18
|
-
def self.run
|
17
|
+
def self.run(umlfile, outfile)
|
19
18
|
system "plantuml #{umlfile.path}" or (warn $? and return false)
|
20
19
|
i = 0
|
21
20
|
until !Gem.win_platform? || File.exist?(outfile) || i == 15
|
@@ -29,9 +28,9 @@ module Asciidoctor
|
|
29
28
|
# sleep need for windows because dot works in separate process and
|
30
29
|
# plantuml process may finish earlier then dot, as result png file
|
31
30
|
# maybe not created yet after plantuml finish
|
32
|
-
def self.generate_file
|
31
|
+
def self.generate_file(parent, reader)
|
33
32
|
localdir = Metanorma::Utils::localdir(parent.document)
|
34
|
-
imagesdir = parent.document.attr(
|
33
|
+
imagesdir = parent.document.attr("imagesdir")
|
35
34
|
umlfile, outfile = save_plantuml parent, reader, localdir
|
36
35
|
run(umlfile, outfile) or raise "No image output from PlantUML (#{umlfile}, #{outfile})!"
|
37
36
|
umlfile.unlink
|
@@ -40,7 +39,7 @@ module Asciidoctor
|
|
40
39
|
File.writable?(localdir) or raise "Destination path #{path} not writable for PlantUML!"
|
41
40
|
path.mkpath
|
42
41
|
File.writable?(path) or raise "Destination path #{path} not writable for PlantUML!"
|
43
|
-
#File.exist?(path) or raise "Destination path #{path} already exists for PlantUML!"
|
42
|
+
# File.exist?(path) or raise "Destination path #{path} already exists for PlantUML!"
|
44
43
|
|
45
44
|
# Warning: metanorma/metanorma-standoc#187
|
46
45
|
# Windows Ruby 2.4 will crash if a Tempfile is "mv"ed.
|
@@ -51,21 +50,21 @@ module Asciidoctor
|
|
51
50
|
imagesdir ? filename : File.join(path, filename)
|
52
51
|
end
|
53
52
|
|
54
|
-
def self.save_plantuml
|
53
|
+
def self.save_plantuml(_parent, reader, _localdir)
|
55
54
|
src = reader.source
|
56
55
|
reader.lines.first.sub(/\s+$/, "").match /^@startuml($| )/ or
|
57
56
|
src = "@startuml\n#{src}\n@enduml\n"
|
58
57
|
/^@startuml (?<fn>[^\n]+)\n/ =~ src
|
59
|
-
Tempfile.open(["plantuml", ".pml"], :
|
58
|
+
Tempfile.open(["plantuml", ".pml"], encoding: "utf-8") do |f|
|
60
59
|
f.write(src)
|
61
60
|
[f, File.join(File.dirname(f.path),
|
62
|
-
|
61
|
+
"#{fn || File.basename(f.path, '.pml')}.png")]
|
63
62
|
end
|
64
63
|
end
|
65
64
|
|
66
|
-
def self.generate_attrs
|
67
|
-
|
68
|
-
inject({}) do |memo, key|
|
65
|
+
def self.generate_attrs(attrs)
|
66
|
+
%w(id align float title role width height alt)
|
67
|
+
.inject({}) do |memo, key|
|
69
68
|
memo[key] = attrs[key] if attrs.has_key? key
|
70
69
|
memo
|
71
70
|
end
|
@@ -81,19 +80,18 @@ module Asciidoctor
|
|
81
80
|
def abort(parent, reader, attrs, msg)
|
82
81
|
warn msg
|
83
82
|
attrs["language"] = "plantuml"
|
84
|
-
create_listing_block parent, reader.source,
|
83
|
+
create_listing_block parent, reader.source,
|
84
|
+
(attrs.reject { |k, _v| k == 1 })
|
85
85
|
end
|
86
86
|
|
87
87
|
def process(parent, reader, attrs)
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
abort(parent, reader, attrs, e.message)
|
96
|
-
end
|
88
|
+
PlantUMLBlockMacroBackend.plantuml_installed?
|
89
|
+
filename = PlantUMLBlockMacroBackend.generate_file(parent, reader)
|
90
|
+
through_attrs = PlantUMLBlockMacroBackend.generate_attrs attrs
|
91
|
+
through_attrs["target"] = filename
|
92
|
+
create_image_block parent, through_attrs
|
93
|
+
rescue StandardError => e
|
94
|
+
abort(parent, reader, attrs, e.message)
|
97
95
|
end
|
98
96
|
end
|
99
97
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "csv"
|
2
|
+
|
1
3
|
module Asciidoctor
|
2
4
|
module Standoc
|
3
5
|
class AltTermInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
@@ -36,46 +38,81 @@ module Asciidoctor
|
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
39
|
-
# Macro to transform `term[X,Y]` into em, termxref xml
|
40
41
|
class TermRefInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
41
42
|
use_dsl
|
42
43
|
named :term
|
43
|
-
name_positional_attributes
|
44
|
+
name_positional_attributes "name", "termxref"
|
45
|
+
using_format :short
|
46
|
+
|
47
|
+
def process(_parent, _target, attrs)
|
48
|
+
termref = attrs["termxref"] || attrs["name"]
|
49
|
+
"<concept type='term'><termxref>#{attrs['name']}</termxref>"\
|
50
|
+
"<renderterm>#{termref}</renderterm><xrefrender/></concept>"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class SymbolRefInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
55
|
+
use_dsl
|
56
|
+
named :symbol
|
57
|
+
name_positional_attributes "name", "termxref"
|
44
58
|
using_format :short
|
45
59
|
|
46
60
|
def process(_parent, _target, attrs)
|
47
|
-
termref = attrs[
|
48
|
-
"<
|
61
|
+
termref = attrs["termxref"] || attrs["name"]
|
62
|
+
"<concept type='symbol'><termxref>#{attrs['name']}</termxref>"\
|
63
|
+
"<renderterm>#{termref}</renderterm><xrefrender/></concept>"
|
49
64
|
end
|
50
65
|
end
|
51
66
|
|
67
|
+
# Possibilities:
|
68
|
+
# {{<<id>>, term}}
|
69
|
+
# {{<<id>>, term, text}}
|
70
|
+
# {{<<termbase:id>>, term}}
|
71
|
+
# {{<<termbase:id>>, term, text}}
|
72
|
+
# {{term}} equivalent to term:[term]
|
73
|
+
# {{term, text}} equivalent to term:[term, text]
|
74
|
+
# text may optionally be followed by crossreference-rendering, options=""
|
52
75
|
class ConceptInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
53
76
|
use_dsl
|
54
77
|
named :concept
|
55
|
-
name_positional_attributes "id", "word", "term"
|
56
|
-
# match %r{concept:(?<target>[^\[]*)\[(?<content>|.*?[^\\])\]$}
|
57
78
|
match /\{\{(?<content>|.*?[^\\])\}\}/
|
58
79
|
using_format :short
|
59
80
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
81
|
+
def preprocess_attrs(target)
|
82
|
+
m = /^(?<id><<.+?>>)?(?<rest>.*)$/.match(target)
|
83
|
+
ret = { id: m[:id]&.sub(/^<</, "")&.sub(/>>$/, "") }
|
84
|
+
if m2 = /^(?<rest>.*?)(?<opt>,option=.+)$/.match(m[:rest].sub(/^,/, ""))
|
85
|
+
ret[:opt] = CSV.parse_line(m2[:opt].sub(/^,option=/, "")
|
86
|
+
.sub(/^"(.+)"$/, "\\1").sub(/^'(.+)'$/, "\\1"))
|
87
|
+
attrs = CSV.parse_line(m2[:rest]) || []
|
88
|
+
else
|
89
|
+
attrs = CSV.parse_line(m[:rest].sub(/^,/, "")) || []
|
90
|
+
end
|
91
|
+
ret.merge(term: attrs[0], word: attrs[1] || attrs[0],
|
92
|
+
xrefrender: attrs[2])
|
93
|
+
end
|
94
|
+
|
95
|
+
def generate_attrs(opts)
|
96
|
+
ret = ""
|
97
|
+
opts.include?("noital") and ret += " ital='false'"
|
98
|
+
opts.include?("noref") and ret += " ref='false'"
|
99
|
+
opts.include?("ital") and ret += " ital='true'"
|
100
|
+
opts.include?("ref") and ret += " ref='true'"
|
101
|
+
ret
|
68
102
|
end
|
69
103
|
|
70
|
-
def process(parent,
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
104
|
+
def process(parent, target, _attrs)
|
105
|
+
attrs = preprocess_attrs(target)
|
106
|
+
termout = Asciidoctor::Inline.new(parent, :quoted, attrs[:term]).convert
|
107
|
+
wordout = Asciidoctor::Inline.new(parent, :quoted, attrs[:word]).convert
|
108
|
+
xrefout = Asciidoctor::Inline.new(parent, :quoted,
|
109
|
+
attrs[:xrefrender]).convert
|
110
|
+
optout = generate_attrs(attrs[:opt] || [])
|
111
|
+
attrs[:id] and return "<concept#{optout} key='#{attrs[:id]}'><refterm>"\
|
112
|
+
"#{termout}</refterm><renderterm>#{wordout}</renderterm>"\
|
113
|
+
"<xrefrender>#{xrefout}</xrefrender></concept>"
|
114
|
+
"<concept#{optout}><termxref>#{termout}</termxref><renderterm>"\
|
115
|
+
"#{wordout}</renderterm><xrefrender>#{xrefout}</xrefrender></concept>"
|
79
116
|
end
|
80
117
|
end
|
81
118
|
end
|