isodoc 1.5.3 → 1.5.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/rake.yml +1 -1
- data/lib/isodoc/function/blocks.rb +4 -0
- data/lib/isodoc/function/to_word_html.rb +1 -0
- data/lib/isodoc/presentation_function/block.rb +11 -5
- data/lib/isodoc/presentation_function/inline.rb +16 -22
- data/lib/isodoc/version.rb +1 -1
- data/lib/isodoc/word_function/inline.rb +6 -0
- data/lib/twitter-cldr/patch.rb +39 -0
- data/spec/isodoc/blocks_spec.rb +87 -0
- data/spec/isodoc/presentation_xml_spec.rb +6 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8da1e26ad7132ffa08da0fcea2d5690591d195fed192f9de480f142045526f00
|
4
|
+
data.tar.gz: 6f7790baee1639e89aa09f8234a17dd024cac0a9d47ad95039f2caa273264d94
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f72f7cbc23636918dade5e52ceb6e1115cdd018b4a051ffd965162d11c081b6e7dfcafe04cf583373e55d5f2262d4393823497b7a5ed4a0a8d248dc5c1574a6
|
7
|
+
data.tar.gz: 249e6bb5247039595870c52969c49bc4acbb40a1dcae798a4f925ab6fa5ea4640a22a8defdd60ad64134159a21f26088268324ce2381f00aa79db673ffcb3695
|
data/.github/workflows/rake.yml
CHANGED
@@ -50,4 +50,4 @@ jobs:
|
|
50
50
|
token: ${{ secrets.METANORMA_CI_PAT_TOKEN || secrets.GITHUB_TOKEN }}
|
51
51
|
repository: ${{ github.repository }}
|
52
52
|
event-type: notify
|
53
|
-
client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}"}'
|
53
|
+
client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}"}'
|
@@ -225,6 +225,7 @@ module IsoDoc::Function
|
|
225
225
|
when "passthrough" then passthrough_parse(node, out)
|
226
226
|
when "amend" then amend_parse(node, out)
|
227
227
|
when "tab" then clausedelimspace(out) # in Presentation XML only
|
228
|
+
when "svg" then svg_parse(node, out) # introduced in Presentation XML only
|
228
229
|
else
|
229
230
|
error_parse(node, out)
|
230
231
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "base64"
|
2
|
+
|
1
3
|
module IsoDoc
|
2
4
|
class PresentationXMLConvert < ::IsoDoc::Convert
|
3
5
|
def lower2cap(s)
|
@@ -6,9 +8,8 @@ module IsoDoc
|
|
6
8
|
end
|
7
9
|
|
8
10
|
def figure(docxml)
|
9
|
-
docxml.xpath(ns("//
|
10
|
-
|
11
|
-
end
|
11
|
+
docxml.xpath(ns("//image")).each { |f| svg_extract(f) }
|
12
|
+
docxml.xpath(ns("//figure")).each { |f| figure1(f) }
|
12
13
|
docxml.xpath(ns("//svgmap")).each do |s|
|
13
14
|
if f = s.at(ns("./figure")) then s.replace(f)
|
14
15
|
else
|
@@ -17,9 +18,14 @@ module IsoDoc
|
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
21
|
+
def svg_extract(f)
|
22
|
+
return unless %r{^data:image/svg\+xml;base64,}.match(f["src"])
|
23
|
+
svg = Base64.strict_decode64(f["src"].sub(%r{^data:image/svg\+xml;base64,}, ""))
|
24
|
+
f.replace(svg.sub(/<\?xml[^>]*>/, ""))
|
25
|
+
end
|
26
|
+
|
20
27
|
def figure1(f)
|
21
|
-
return sourcecode1(f) if f["class"] == "pseudocode" ||
|
22
|
-
f["type"] == "pseudocode"
|
28
|
+
return sourcecode1(f) if f["class"] == "pseudocode" || f["type"] == "pseudocode"
|
23
29
|
return if labelled_ancestor(f) && f.ancestors("figure").empty?
|
24
30
|
return if f.at(ns("./figure")) and !f.at(ns("./name"))
|
25
31
|
lbl = @xrefs.anchor(f['id'], :label, false) or return
|
@@ -1,4 +1,6 @@
|
|
1
1
|
require "twitter_cldr"
|
2
|
+
require "bigdecimal"
|
3
|
+
require_relative "../../twitter-cldr/patch"
|
2
4
|
|
3
5
|
module IsoDoc
|
4
6
|
class PresentationXMLConvert < ::IsoDoc::Convert
|
@@ -10,8 +12,7 @@ module IsoDoc
|
|
10
12
|
if node["citeas"].nil? && node["bibitemid"]
|
11
13
|
return @xrefs.anchor(node["bibitemid"] ,:xref) || "???"
|
12
14
|
elsif node["target"] && node["droploc"]
|
13
|
-
return @xrefs.anchor(node["target"], :value) ||
|
14
|
-
@xrefs.anchor(node["target"], :label) ||
|
15
|
+
return @xrefs.anchor(node["target"], :value) || @xrefs.anchor(node["target"], :label) ||
|
15
16
|
@xrefs.anchor(node["target"], :xref) || "???"
|
16
17
|
elsif node["target"] && !/.#./.match(node["target"])
|
17
18
|
linkend = anchor_linkend1(node)
|
@@ -22,9 +23,8 @@ module IsoDoc
|
|
22
23
|
def anchor_linkend1(node)
|
23
24
|
linkend = @xrefs.anchor(node["target"], :xref)
|
24
25
|
container = @xrefs.anchor(node["target"], :container, false)
|
25
|
-
(container && get_note_container_id(node) != container &&
|
26
|
-
|
27
|
-
linkend = prefix_container(container, linkend, node["target"])
|
26
|
+
(container && get_note_container_id(node) != container && @xrefs.get[node["target"]]) &&
|
27
|
+
linkend = prefix_container(container, linkend, node["target"])
|
28
28
|
capitalise_xref(node, linkend)
|
29
29
|
end
|
30
30
|
|
@@ -35,13 +35,11 @@ module IsoDoc
|
|
35
35
|
return linkend if linkend[0,1].match(/\p{Upper}/)
|
36
36
|
prec = nearest_block_parent(node).xpath("./descendant-or-self::text()") &
|
37
37
|
node.xpath("./preceding::text()")
|
38
|
-
(prec.empty? || /(?!<[^.].)\.\s+$/.match(prec.map { |p| p.text }.join)) ?
|
39
|
-
linkend&.capitalize : linkend
|
38
|
+
(prec.empty? || /(?!<[^.].)\.\s+$/.match(prec.map { |p| p.text }.join)) ? linkend&.capitalize : linkend
|
40
39
|
end
|
41
40
|
|
42
41
|
def nearest_block_parent(node)
|
43
|
-
until %w(p title td th name formula
|
44
|
-
li dt dd sourcecode pre).include?(node.name)
|
42
|
+
until %w(p title td th name formula li dt dd sourcecode pre).include?(node.name)
|
45
43
|
node = node.parent
|
46
44
|
end
|
47
45
|
node
|
@@ -89,8 +87,7 @@ module IsoDoc
|
|
89
87
|
def eref_localities0(r, i, target, delim)
|
90
88
|
if r["type"] == "whole" then l10n("#{delim} #{@i18n.wholeoftext}")
|
91
89
|
else
|
92
|
-
eref_localities1(target, r["type"], r.at(ns("./referenceFrom")),
|
93
|
-
r.at(ns("./referenceTo")), delim, @lang)
|
90
|
+
eref_localities1(target, r["type"], r.at(ns("./referenceFrom")), r.at(ns("./referenceTo")), delim, @lang)
|
94
91
|
end
|
95
92
|
end
|
96
93
|
|
@@ -106,8 +103,7 @@ module IsoDoc
|
|
106
103
|
# TODO: move to localization file
|
107
104
|
def eref_localities1(target, type, from, to, delim, lang = "en")
|
108
105
|
return "" if type == "anchor"
|
109
|
-
lang == "zh" and
|
110
|
-
return l10n(eref_localities1_zh(target, type, from, to, delim))
|
106
|
+
lang == "zh" and return l10n(eref_localities1_zh(target, type, from, to, delim))
|
111
107
|
ret = delim
|
112
108
|
loc = @i18n.locality[type] || type.sub(/^locality:/, "").capitalize
|
113
109
|
ret += " #{loc}"
|
@@ -163,23 +159,23 @@ module IsoDoc
|
|
163
159
|
# TwitterCldr::DataReaders::NumberDataReader.new(locale).symbols
|
164
160
|
def localize_maths(f, locale)
|
165
161
|
f.xpath(".//m:mn", MATHML).each do |x|
|
166
|
-
num =
|
162
|
+
num = BigDecimal(x.text)
|
167
163
|
precision = /\./.match(x.text) ? x.text.sub(/^.*\./, "").size : 0
|
168
164
|
x.children = localized_number(num, locale, precision)
|
169
165
|
end
|
170
166
|
end
|
171
167
|
|
172
|
-
# By itself
|
168
|
+
# By itself twitter-cldr does not support fraction part digits grouping
|
173
169
|
# and custom delimeter, will decorate fraction part manually
|
174
170
|
def localized_number(num, locale, precision)
|
175
|
-
|
171
|
+
TwitterCldr::Localized::LocalizedNumber.localize(BigDecimal)
|
172
|
+
localized = (precision == 0) ? num.localize(locale).to_s :
|
176
173
|
num.localize(locale).to_decimal.to_s(:precision => precision)
|
177
174
|
twitter_cldr_reader_symbols = twitter_cldr_reader(locale)
|
178
175
|
return localized unless twitter_cldr_reader_symbols[:decimal]
|
179
176
|
integer, fraction = localized.split(twitter_cldr_reader_symbols[:decimal])
|
180
177
|
return localized if fraction.nil? || fraction.length.zero?
|
181
|
-
[integer, decorate_fraction_part(fraction, locale)].
|
182
|
-
join(twitter_cldr_reader_symbols[:decimal])
|
178
|
+
[integer, decorate_fraction_part(fraction, locale)].join(twitter_cldr_reader_symbols[:decimal])
|
183
179
|
end
|
184
180
|
|
185
181
|
def decorate_fraction_part(fract, locale)
|
@@ -229,8 +225,7 @@ module IsoDoc
|
|
229
225
|
end
|
230
226
|
|
231
227
|
def variant1(node)
|
232
|
-
if (!node["lang"] || node["lang"] == @lang) &&
|
233
|
-
(!node["script"] || node["script"] == @script)
|
228
|
+
if (!node["lang"] || node["lang"] == @lang) && (!node["script"] || node["script"] == @script)
|
234
229
|
elsif found_matching_variant_sibling(node)
|
235
230
|
node["remove"] = "true"
|
236
231
|
else
|
@@ -243,8 +238,7 @@ module IsoDoc
|
|
243
238
|
foll = node.xpath("./following-sibling::xmlns:variant")
|
244
239
|
found = false
|
245
240
|
(prev + foll).each do |n|
|
246
|
-
found = true if n["lang"] == @lang &&
|
247
|
-
(!n["script"] || n["script"] == @script)
|
241
|
+
found = true if n["lang"] == @lang && (!n["script"] || n["script"] == @script)
|
248
242
|
end
|
249
243
|
found
|
250
244
|
end
|
data/lib/isodoc/version.rb
CHANGED
@@ -22,6 +22,12 @@ module IsoDoc::WordFunction
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
def svg_parse(node, out)
|
26
|
+
svg = Base64.strict_encode64(node.to_xml)
|
27
|
+
r = node.replace("<img src='data:image/svg+xml;base64,#{svg}' mimetype='image/svg+xml'/>").first
|
28
|
+
image_parse(r, out, nil)
|
29
|
+
end
|
30
|
+
|
25
31
|
def imgsrc(node)
|
26
32
|
ret = svg_to_emf(node) and return ret
|
27
33
|
return node["src"] unless %r{^data:}.match node["src"]
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module ::TwitterCldr
|
2
|
+
module Formatters
|
3
|
+
class NumberFormatter
|
4
|
+
def parse_number(number, options = {})
|
5
|
+
precision = options[:precision] || precision_from(number)
|
6
|
+
rounding = options[:rounding] || 0
|
7
|
+
if number.is_a? BigDecimal
|
8
|
+
number = precision == 0 ?
|
9
|
+
round_to(number, precision, rounding).abs.fix.to_s("F") :
|
10
|
+
round_to(number, precision, rounding).abs.round(precision).to_s("F")
|
11
|
+
else
|
12
|
+
number = "%.#{precision}f" % round_to(number, precision, rounding).abs
|
13
|
+
end
|
14
|
+
number.split(".")
|
15
|
+
end
|
16
|
+
|
17
|
+
def round_to(number, precision, rounding = 0)
|
18
|
+
factor = 10 ** precision
|
19
|
+
result = number.is_a?(BigDecimal) ?
|
20
|
+
((number * factor).fix / factor) :
|
21
|
+
((number * factor).round.to_f / factor)
|
22
|
+
if rounding > 0
|
23
|
+
rounding = rounding.to_f / factor
|
24
|
+
result = number.is_a?(BigDecimal) ?
|
25
|
+
((result * (1.0 / rounding)).fix / (1.0 / rounding)) :
|
26
|
+
((result * (1.0 / rounding)).round.to_f / (1.0 / rounding))
|
27
|
+
end
|
28
|
+
result
|
29
|
+
end
|
30
|
+
|
31
|
+
def precision_from(num)
|
32
|
+
return 0 if num.is_a?(BigDecimal) && num.fix == num
|
33
|
+
parts = (num.is_a?(BigDecimal) ? num.to_s("F") : num.to_s ).split(".")
|
34
|
+
parts.size == 2 ? parts[1].size : 0
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
data/spec/isodoc/blocks_spec.rb
CHANGED
@@ -768,6 +768,93 @@ B</pre>
|
|
768
768
|
expect(xmlpp(strip_guid(IsoDoc::WordConvert.new({}).convert("test", presxml, true).gsub(/['"][^'".]+\.(gif|xml)['"]/, "'_.\\1'").gsub(/mso-bookmark:_Ref\d+/, "mso-bookmark:_Ref")))).to be_equivalent_to xmlpp(word)
|
769
769
|
end
|
770
770
|
|
771
|
+
it "processes SVG" do
|
772
|
+
input = <<~INPUT
|
773
|
+
<iso-standard xmlns="http://riboseinc.com/isoxml">
|
774
|
+
<preface><foreword>
|
775
|
+
<figure id="figureA-1">
|
776
|
+
<image src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj4KICA8Y2lyY2xlIGZpbGw9IiMwMDkiIHI9IjQ1IiBjeD0iNTAiIGN5PSI1MCIvPgogIDxwYXRoIGQ9Ik0zMywyNkg3OEEzNywzNywwLDAsMSwzMyw4M1Y1N0g1OVY0M0gzM1oiIGZpbGw9IiNGRkYiLz4KPC9zdmc+Cg==" id="_d3731866-1a07-435a-a6c2-1acd41023a4e" mimetype="image/svg+xml" height="auto" width="auto"/>
|
777
|
+
</figure>
|
778
|
+
</foreword></preface>
|
779
|
+
</iso-standard>
|
780
|
+
INPUT
|
781
|
+
|
782
|
+
presxml = <<~OUTPUT
|
783
|
+
<iso-standard xmlns='http://riboseinc.com/isoxml' type='presentation'>
|
784
|
+
<preface>
|
785
|
+
<foreword>
|
786
|
+
<figure id='figureA-1'>
|
787
|
+
<name>Figure 1</name>
|
788
|
+
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>
|
789
|
+
<circle fill='#009' r='45' cx='50' cy='50'/>
|
790
|
+
<path d='M33,26H78A37,37,0,0,1,33,83V57H59V43H33Z' fill='#FFF'/>
|
791
|
+
</svg>
|
792
|
+
</figure>
|
793
|
+
</foreword>
|
794
|
+
</preface>
|
795
|
+
</iso-standard>
|
796
|
+
OUTPUT
|
797
|
+
|
798
|
+
html = <<~HTML
|
799
|
+
#{HTML_HDR}
|
800
|
+
<br/>
|
801
|
+
<div>
|
802
|
+
<h1 class='ForewordTitle'>Foreword</h1>
|
803
|
+
<div id='figureA-1' class='figure'>
|
804
|
+
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>
|
805
|
+
<circle fill='#009' r='45' cx='50' cy='50'/>
|
806
|
+
<path d='M33,26H78A37,37,0,0,1,33,83V57H59V43H33Z' fill='#FFF'/>
|
807
|
+
</svg>
|
808
|
+
<p class='FigureTitle' style='text-align:center;'>Figure 1</p>
|
809
|
+
</div>
|
810
|
+
</div>
|
811
|
+
<p class='zzSTDTitle1'/>
|
812
|
+
</div>
|
813
|
+
</body>
|
814
|
+
</html>
|
815
|
+
HTML
|
816
|
+
|
817
|
+
doc = <<~DOC
|
818
|
+
<html xmlns:epub='http://www.idpf.org/2007/ops' lang='en'>
|
819
|
+
<head>
|
820
|
+
<style>
|
821
|
+
</style>
|
822
|
+
</head>
|
823
|
+
<body lang='EN-US' link='blue' vlink='#954F72'>
|
824
|
+
<div class='WordSection1'>
|
825
|
+
<p> </p>
|
826
|
+
</div>
|
827
|
+
<p>
|
828
|
+
<br clear='all' class='section'/>
|
829
|
+
</p>
|
830
|
+
<div class='WordSection2'>
|
831
|
+
<p>
|
832
|
+
<br clear='all' style='mso-special-character:line-break;page-break-before:always'/>
|
833
|
+
</p>
|
834
|
+
<div>
|
835
|
+
<h1 class='ForewordTitle'>Foreword</h1>
|
836
|
+
<div id='figureA-1' class='figure'>
|
837
|
+
<img src='_.emf'/>
|
838
|
+
<p class='FigureTitle' style='text-align:center;'>Figure 1</p>
|
839
|
+
</div>
|
840
|
+
</div>
|
841
|
+
<p> </p>
|
842
|
+
</div>
|
843
|
+
<p>
|
844
|
+
<br clear='all' class='section'/>
|
845
|
+
</p>
|
846
|
+
<div class='WordSection3'>
|
847
|
+
<p class='zzSTDTitle1'/>
|
848
|
+
</div>
|
849
|
+
</body>
|
850
|
+
</html>
|
851
|
+
DOC
|
852
|
+
|
853
|
+
expect(xmlpp(IsoDoc::PresentationXMLConvert.new({}).convert("test", input, true).gsub(/\</, "<"))).to be_equivalent_to xmlpp(presxml)
|
854
|
+
expect(xmlpp(strip_guid(IsoDoc::HtmlConvert.new({}).convert("test", presxml, true)))).to be_equivalent_to xmlpp(html)
|
855
|
+
expect(xmlpp(strip_guid(IsoDoc::WordConvert.new({}).convert("test", presxml, true).gsub(/['"][^'".]+(?<!odf1)(?<!odf)\.emf['"]/, "'_.emf'").gsub(/['"][^'".]+\.(gif|xml)['"]/, "'_.\\1'")))).to be_equivalent_to xmlpp(doc)
|
856
|
+
end
|
857
|
+
|
771
858
|
it "converts SVG (Word)" do
|
772
859
|
FileUtils.rm_rf "spec/assets/odf1.emf"
|
773
860
|
expect(xmlpp(strip_guid(IsoDoc::WordConvert.new({}).convert("test", <<~"INPUT", true).gsub(/['"][^'".]+(?<!odf1)(?<!odf)\.emf['"]/, "'_.emf'").gsub(/['"][^'".]+\.(gif|xml)['"]/, "'_.\\1'").gsub(/mso-bookmark:_Ref\d+/, "mso-bookmark:_Ref")))).to be_equivalent_to xmlpp(<<~"OUTPUT")
|
@@ -25,7 +25,10 @@ it "localises numbers in MathML" do
|
|
25
25
|
<title language="en">test</title>
|
26
26
|
</bibdata>
|
27
27
|
<preface>
|
28
|
-
<p
|
28
|
+
<p>
|
29
|
+
<stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><mn>64212149677264515</mn></math></stem>
|
30
|
+
<stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><mn>642121496772645.15</mn></math></stem>
|
31
|
+
<stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><mn>30000</mn></math></stem>
|
29
32
|
<stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>P</mi><mfenced open="(" close=")"><mrow><mi>X</mi><mo>≥</mo><msub><mrow><mi>X</mi></mrow><mrow><mo>max</mo></mrow></msub></mrow></mfenced><mo>=</mo><munderover><mrow><mo>∑</mo></mrow><mrow><mrow><mi>j</mi><mo>=</mo><msub><mrow><mi>X</mi></mrow><mrow><mo>max</mo></mrow></msub></mrow></mrow><mrow><mn>1000</mn></mrow></munderover><mfenced open="(" close=")"><mtable><mtr><mtd><mn>1000</mn></mtd></mtr><mtr><mtd><mi>j</mi></mtd></mtr></mtable></mfenced><msup><mrow><mi>p</mi></mrow><mrow><mi>j</mi></mrow></msup><msup><mrow><mfenced open="(" close=")"><mrow><mn>1</mn><mo>−</mo><mi>p</mi></mrow></mfenced></mrow><mrow><mrow><mn>1.003</mn><mo>−</mo><mi>j</mi></mrow></mrow></msup></math></stem></p>
|
30
33
|
</preface>
|
31
34
|
</iso-standard>
|
@@ -37,7 +40,8 @@ it "localises numbers in MathML" do
|
|
37
40
|
|
38
41
|
<preface>
|
39
42
|
<p>
|
40
|
-
|
43
|
+
64,212,149,677,264,515
|
44
|
+
642,121,496,772,645.15 30,000
|
41
45
|
<stem type='MathML'>
|
42
46
|
<math xmlns='http://www.w3.org/1998/Math/MathML'>
|
43
47
|
<mi>P</mi>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: isodoc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.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: 2021-
|
11
|
+
date: 2021-03-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciimath
|
@@ -418,6 +418,7 @@ files:
|
|
418
418
|
- lib/isodoc/xref/xref_gen_seq.rb
|
419
419
|
- lib/isodoc/xref/xref_sect_gen.rb
|
420
420
|
- lib/isodoc/xslfo_convert.rb
|
421
|
+
- lib/twitter-cldr/patch.rb
|
421
422
|
- spec/assets/header.html
|
422
423
|
- spec/assets/html.scss
|
423
424
|
- spec/assets/htmlcover.html
|