metanorma-standoc 2.2.0 → 2.2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/metanorma/standoc/blocks.rb +2 -5
- data/lib/metanorma/standoc/macros_inline.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/spec/metanorma/biblio_spec.rb +1 -1
- data/spec/metanorma/macros_spec.rb +1 -1
- data/spec/metanorma/refs_spec.rb +0 -2
- data/spec/metanorma/validate_spec.rb +46 -6
- data/spec/vcr_cassettes/bsi16341.yml +65 -53
- data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +58 -58
- data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +12 -12
- data/spec/vcr_cassettes/hide_refs.yml +54 -54
- data/spec/vcr_cassettes/isobib_get_123.yml +12 -12
- data/spec/vcr_cassettes/isobib_get_123_1.yml +23 -23
- data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +29 -29
- data/spec/vcr_cassettes/isobib_get_123_2.yml +23 -23
- 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 +28 -34
- data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +45 -45
- data/spec/vcr_cassettes/std-link.yml +11 -11
- 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: e6a6d6a98133ba0cf81631287aff2157906da7d0978899abe5c00c78f0da6b2d
|
4
|
+
data.tar.gz: 81c33e16f952e56dcff81bd0485ead5ba998839b307e30eb8de500bf2448a600
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b36c1f1766233c69f9b5a63298d8f7cd8745cac7f7186f210500bc23a27983b3202a724ebd799f6d305b928377ed5d2ef28dcb43aac4e9c91f65b9300a98ac19
|
7
|
+
data.tar.gz: e4b1be10928b81269486083791e7dd23fab26b2697d1b1a82fa607dfa4c6f46a00bdc4373403605c2807a993ab2f4015f34f643607610d10344cfbd95a6a83b3
|
@@ -15,8 +15,7 @@ module Metanorma
|
|
15
15
|
attr_code(id_attr(node).merge(
|
16
16
|
unnumbered: node.option?("unnumbered") ? "true" : nil,
|
17
17
|
number: node.attr("number"),
|
18
|
-
subsequence: node.attr("subsequence")
|
19
|
-
))
|
18
|
+
subsequence: node.attr("subsequence")))
|
20
19
|
end
|
21
20
|
|
22
21
|
def formula_attrs(node)
|
@@ -105,9 +104,8 @@ module Metanorma
|
|
105
104
|
|
106
105
|
def svgmap_attrs(node)
|
107
106
|
attr_code(id_attr(node)
|
108
|
-
.merge(id: node.id,
|
107
|
+
.merge(id: node.id, number: node.attr("number"),
|
109
108
|
unnumbered: node.option?("unnumbered") ? "true" : nil,
|
110
|
-
number: node.attr("number"),
|
111
109
|
subsequence: node.attr("subsequence"))
|
112
110
|
.merge(keep_attrs(node)))
|
113
111
|
end
|
@@ -225,7 +223,6 @@ module Metanorma
|
|
225
223
|
filename: node.attr("filename"))))
|
226
224
|
end
|
227
225
|
|
228
|
-
# NOTE: html escaping is performed by Nokogiri
|
229
226
|
def listing(node)
|
230
227
|
fragment = ::Nokogiri::XML::Builder.new do |xml|
|
231
228
|
xml.sourcecode **listing_attrs(node) do |s|
|
@@ -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|
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Metanorma
|
2
|
+
module Standoc
|
3
|
+
module Validate
|
4
|
+
def table_validate(doc)
|
5
|
+
doc.xpath("//table[colgroup]").each do |t|
|
6
|
+
maxrowcols_validate(t, t.xpath("./colgroup/col").size)
|
7
|
+
end
|
8
|
+
doc.xpath("//table[.//*[@colspan] | .//*[@rowspan]]").each do |t|
|
9
|
+
maxrowcols_validate(t, max_td_count(t), mode: "row_cols")
|
10
|
+
end
|
11
|
+
doc.xpath("//table[.//*[@rowspan]]").each do |t|
|
12
|
+
maxrowcols_validate(t, max_td_count(t), mode: "thead_row")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def max_td_count(table)
|
17
|
+
max = 0
|
18
|
+
table.xpath("./tr").each do |tr|
|
19
|
+
n = tr.xpath("./td | ./th").size
|
20
|
+
max < n and max = n
|
21
|
+
end
|
22
|
+
max
|
23
|
+
end
|
24
|
+
|
25
|
+
def maxrowcols_validate(table, maxcols, mode: "row_cols")
|
26
|
+
case mode
|
27
|
+
when "row_cols"
|
28
|
+
maxrowcols_validate0(table, maxcols, "*", mode)
|
29
|
+
when "thead_row"
|
30
|
+
%w{thead tbody tfoot}.each do |w|
|
31
|
+
maxrowcols_validate0(table, maxcols, w, mode)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def maxrowcols_validate0(table, maxcols, tablechild, mode)
|
37
|
+
cells2d = table.xpath("./#{tablechild}/tr")
|
38
|
+
.each_with_object([]) { |_r, m| m << {} }
|
39
|
+
table.xpath("./#{tablechild}/tr").each_with_index do |tr, r|
|
40
|
+
curr = 0
|
41
|
+
tr.xpath("./td | ./th").each do |td|
|
42
|
+
curr = maxcols_validate1(td, r, curr, cells2d, maxcols, mode)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
maxrows_validate(table, cells2d, tablechild, mode)
|
46
|
+
end
|
47
|
+
|
48
|
+
# code doesn't actually do anything, since Asciidoctor refuses to generate
|
49
|
+
# table with inconsistent column count
|
50
|
+
def maxcols_validate1(tcell, row, curr, cells2d, maxcols, mode)
|
51
|
+
rs = tcell&.attr("rowspan")&.to_i || 1
|
52
|
+
cs = tcell&.attr("colspan")&.to_i || 1
|
53
|
+
curr = table_tracker_update(cells2d, row, curr, rs, cs)
|
54
|
+
maxcols_check(curr + cs - 1, maxcols, tcell) if mode == "row_cols"
|
55
|
+
curr + cs
|
56
|
+
end
|
57
|
+
|
58
|
+
def table_tracker_update(cells2d, row, curr, rowspan, colspan)
|
59
|
+
cells2d[row] ||= {}
|
60
|
+
while cells2d[row][curr]
|
61
|
+
curr += 1
|
62
|
+
end
|
63
|
+
(row..(row + rowspan - 1)).each do |y2|
|
64
|
+
cells2d[y2] ||= {}
|
65
|
+
(curr..(curr + colspan - 1)).each { |x2| cells2d[y2][x2] = 1 }
|
66
|
+
end
|
67
|
+
curr
|
68
|
+
end
|
69
|
+
|
70
|
+
def maxrows_validate(table, cells2d, tablechild, mode)
|
71
|
+
err = "are inconsistent"
|
72
|
+
mode == "thead_row" and err = "cannot go outside #{tablechild}"
|
73
|
+
err = "Table rows in table #{err}: check rowspan"
|
74
|
+
if cells2d.any? { |x| x.size != cells2d.first.size }
|
75
|
+
@log.add("Table", table, err)
|
76
|
+
@fatalerror << err
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# if maxcols or maxrows negative, do not check them
|
81
|
+
def maxcols_check(col, maxcols, tcell)
|
82
|
+
if maxcols.positive? && col > maxcols
|
83
|
+
@log.add("Table", tcell, "Table exceeds maximum number of columns "\
|
84
|
+
"defined (#{maxcols})")
|
85
|
+
@fatalerror << "Table exceeds maximum number of columns defined "\
|
86
|
+
"(#{maxcols})"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -896,7 +896,7 @@ RSpec.describe Metanorma::Standoc do
|
|
896
896
|
[bibliography]
|
897
897
|
=== Normative References
|
898
898
|
|
899
|
-
* [[[A, B]]],
|
899
|
+
* [[[A, B]]], span:surname[Wozniak], span:initials[S.] & span:givenname[Steve] span:surname[Jobs]. span:pubyear[1996]. span:title[_Work_]. In span:surname.editor[Gates], span:initials.editor[W. H], Collected Essays. span:docid.ISO[ISO 1234]. span:pubplace[Geneva]: span:publisher[International Standardization Organization]. span:uri.citation[http://www.example.com]. span:type[inbook]
|
900
900
|
INPUT
|
901
901
|
output = <<~OUTPUT
|
902
902
|
#{BLANK_HDR}
|
data/spec/metanorma/refs_spec.rb
CHANGED
@@ -1732,7 +1732,6 @@ RSpec.describe Metanorma::Standoc do
|
|
1732
1732
|
<title type='main' format='text/plain'>Network Configuration Access Control Model</title>
|
1733
1733
|
<uri type='src'>https://www.rfc-editor.org/info/rfc8341</uri>
|
1734
1734
|
<docidentifier type='IETF' primary='true'>RFC 8341</docidentifier>
|
1735
|
-
<docidentifier type='IETF' scope='anchor'>RFC8341</docidentifier>
|
1736
1735
|
<docidentifier type='DOI'>10.17487/RFC8341</docidentifier>
|
1737
1736
|
<docnumber>RFC8341</docnumber>
|
1738
1737
|
<date type='published'>
|
@@ -1787,7 +1786,6 @@ RSpec.describe Metanorma::Standoc do
|
|
1787
1786
|
<uri type='src'>https://www.rfc-editor.org/info/rfc8341</uri>
|
1788
1787
|
<docidentifier type='IETF' primary='true'>RFC 8341</docidentifier>
|
1789
1788
|
<docidentifier type='metanorma'>[1]</docidentifier>
|
1790
|
-
<docidentifier type='IETF' scope='anchor'>RFC8341</docidentifier>
|
1791
1789
|
<docidentifier type='DOI'>10.17487/RFC8341</docidentifier>
|
1792
1790
|
<docnumber>RFC8341</docnumber>
|
1793
1791
|
<date type='published'>
|
@@ -30,7 +30,9 @@ RSpec.describe Metanorma::Standoc do
|
|
30
30
|
[[abc]]
|
31
31
|
== Clause 2
|
32
32
|
INPUT
|
33
|
-
expect
|
33
|
+
expect do
|
34
|
+
Asciidoctor.convert(input, *OPTIONS)
|
35
|
+
end.to raise_error(SystemExit)
|
34
36
|
rescue SystemExit
|
35
37
|
end
|
36
38
|
expect(File.read("test.err"))
|
@@ -387,7 +389,9 @@ RSpec.describe Metanorma::Standoc do
|
|
387
389
|
{{<<def>>,term}}
|
388
390
|
{{<<ghi>>,term}}
|
389
391
|
INPUT
|
390
|
-
expect
|
392
|
+
expect do
|
393
|
+
Asciidoctor.convert(input, *OPTIONS)
|
394
|
+
end.to raise_error(SystemExit)
|
391
395
|
rescue SystemExit
|
392
396
|
end
|
393
397
|
expect(File.read("test.err"))
|
@@ -420,7 +424,9 @@ RSpec.describe Metanorma::Standoc do
|
|
420
424
|
related:see[<<def>>,term]
|
421
425
|
related:see[<<ghi>>,term]
|
422
426
|
INPUT
|
423
|
-
expect
|
427
|
+
expect do
|
428
|
+
Asciidoctor.convert(input, *OPTIONS)
|
429
|
+
end.to raise_error(SystemExit)
|
424
430
|
rescue SystemExit
|
425
431
|
end
|
426
432
|
expect(File.read("test.err"))
|
@@ -448,7 +454,9 @@ RSpec.describe Metanorma::Standoc do
|
|
448
454
|
[[abc]]
|
449
455
|
== Clause 2
|
450
456
|
INPUT
|
451
|
-
expect
|
457
|
+
expect do
|
458
|
+
Asciidoctor.convert(input, *OPTIONS)
|
459
|
+
end.to raise_error(SystemExit)
|
452
460
|
rescue SystemExit
|
453
461
|
end
|
454
462
|
expect(File.read("test.err"))
|
@@ -470,7 +478,9 @@ RSpec.describe Metanorma::Standoc do
|
|
470
478
|
== Normative references
|
471
479
|
* [[[A,1]]]
|
472
480
|
INPUT
|
473
|
-
expect
|
481
|
+
expect do
|
482
|
+
Asciidoctor.convert(input, *OPTIONS)
|
483
|
+
end.to raise_error(SystemExit)
|
474
484
|
rescue SystemExit
|
475
485
|
end
|
476
486
|
expect(File.read("test.err"))
|
@@ -493,7 +503,6 @@ RSpec.describe Metanorma::Standoc do
|
|
493
503
|
[cols="1,1,1,1"]
|
494
504
|
|===
|
495
505
|
3.2+| a | a
|
496
|
-
|
497
506
|
| a
|
498
507
|
| a | a | a | a
|
499
508
|
|===
|
@@ -507,6 +516,37 @@ RSpec.describe Metanorma::Standoc do
|
|
507
516
|
.not_to include "Table exceeds maximum number of columns defined"
|
508
517
|
expect(File.read("test.err"))
|
509
518
|
.not_to include "Table rows in table are inconsistent: check rowspan"
|
519
|
+
expect(File.read("test.err"))
|
520
|
+
.not_to include "Table rows in table cannot go outside thead: check rowspan"
|
521
|
+
end
|
522
|
+
|
523
|
+
it "warns if rowspan goes across thead" do
|
524
|
+
FileUtils.rm_f "test.xml"
|
525
|
+
FileUtils.rm_f "test.err"
|
526
|
+
begin
|
527
|
+
input = <<~INPUT
|
528
|
+
= Document title
|
529
|
+
Author
|
530
|
+
:docfile: test.adoc
|
531
|
+
:nodoc:
|
532
|
+
|
533
|
+
== Clause
|
534
|
+
|
535
|
+
[cols="1,1,1,1",headerrows=2]
|
536
|
+
|===
|
537
|
+
3.3+| a | a
|
538
|
+
|
539
|
+
| a
|
540
|
+
| a | a | a | a
|
541
|
+
|===
|
542
|
+
INPUT
|
543
|
+
expect do
|
544
|
+
Asciidoctor.convert(input, *OPTIONS)
|
545
|
+
end.to raise_error(SystemExit)
|
546
|
+
rescue SystemExit
|
547
|
+
end
|
548
|
+
expect(File.read("test.err"))
|
549
|
+
.to include "Table rows in table cannot go outside thead: check rowspan"
|
510
550
|
end
|
511
551
|
|
512
552
|
xit "warns and aborts if columns out of bounds against colgroup" do
|