asciidoctor-iso 0.9.9 → 0.10.0

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +7 -0
  3. data/README.adoc +49 -9
  4. data/asciidoctor-iso.gemspec +3 -3
  5. data/lib/asciidoctor-iso.rb +2 -0
  6. data/lib/asciidoctor/iso/base.rb +14 -0
  7. data/lib/asciidoctor/iso/blocks.rb +1 -1
  8. data/lib/asciidoctor/iso/cleanup.rb +2 -2
  9. data/lib/asciidoctor/iso/cleanup_ref.rb +1 -1
  10. data/lib/asciidoctor/iso/inline.rb +1 -1
  11. data/lib/asciidoctor/iso/macros.rb +54 -0
  12. data/lib/asciidoctor/iso/ref.rb +7 -2
  13. data/lib/asciidoctor/iso/validate.rb +8 -8
  14. data/lib/asciidoctor/iso/validate_requirements.rb +5 -5
  15. data/lib/asciidoctor/iso/version.rb +1 -1
  16. data/lib/isodoc/iso/html/header.html +206 -0
  17. data/lib/isodoc/iso/html/html_iso_intro.html +34 -0
  18. data/lib/isodoc/iso/html/html_iso_titlepage.html +34 -0
  19. data/lib/isodoc/iso/html/htmlstyle.scss +46 -0
  20. data/lib/isodoc/iso/html/isodoc.scss +696 -0
  21. data/lib/isodoc/iso/html/scripts.html +174 -0
  22. data/lib/isodoc/iso/html/style-human.scss +1277 -0
  23. data/lib/isodoc/iso/html/style-iso.scss +1257 -0
  24. data/lib/isodoc/iso/html/word_iso_intro.html +72 -0
  25. data/lib/isodoc/iso/html/word_iso_titlepage.html +62 -0
  26. data/lib/isodoc/iso/html/wordstyle.scss +1175 -0
  27. data/lib/isodoc/iso/html_convert.rb +136 -0
  28. data/lib/isodoc/iso/metadata.rb +107 -0
  29. data/lib/isodoc/iso/word_convert.rb +139 -0
  30. data/spec/asciidoctor-iso/isobib_cache_spec.rb +18 -4
  31. data/spec/asciidoctor-iso/macros_spec.rb +92 -1
  32. data/spec/asciidoctor-iso/validate_spec.rb +173 -144
  33. data/spec/assets/header.html +7 -0
  34. data/spec/assets/html.css +2 -0
  35. data/spec/assets/htmlcover.html +4 -0
  36. data/spec/assets/htmlintro.html +5 -0
  37. data/spec/assets/i18n.yaml +2 -0
  38. data/spec/assets/iso.doc +2312 -0
  39. data/spec/assets/iso.headless.html +33 -0
  40. data/spec/assets/iso.html +1388 -0
  41. data/spec/assets/iso.xml +8 -0
  42. data/spec/assets/rice_image1.png +0 -0
  43. data/spec/assets/scripts.html +3 -0
  44. data/spec/assets/std.css +2 -0
  45. data/spec/assets/word.css +2 -0
  46. data/spec/assets/wordcover.html +3 -0
  47. data/spec/assets/wordintro.html +4 -0
  48. data/spec/examples/103_01_02.html +247 -0
  49. data/spec/isodoc/i18n_spec.rb +642 -0
  50. data/spec/isodoc/iso_spec.rb +168 -0
  51. data/spec/isodoc/metadata_spec.rb +152 -0
  52. data/spec/isodoc/postproc_spec.rb +409 -0
  53. data/spec/isodoc/section_spec.rb +522 -0
  54. data/spec/isodoc/xref_spec.rb +1337 -0
  55. data/spec/spec_helper.rb +45 -0
  56. metadata +45 -9
@@ -0,0 +1,136 @@
1
+ require "isodoc"
2
+ require_relative "metadata"
3
+
4
+ module IsoDoc
5
+ module Iso
6
+ class HtmlConvert < IsoDoc::HtmlConvert
7
+
8
+ def default_fonts(options)
9
+ b = options[:bodyfont] ||
10
+ (options[:script] == "Hans" ? '"SimSun",serif' :
11
+ '"Cambria",serif')
12
+ h = options[:headerfont] ||
13
+ (options[:script] == "Hans" ? '"SimHei",sans-serif' :
14
+ '"Cambria",serif')
15
+ m = options[:monospacefont] || '"Courier New",monospace'
16
+ "$bodyfont: #{b};\n$headerfont: #{h};\n$monospacefont: #{m};\n"
17
+ end
18
+
19
+ def alt_fonts(options)
20
+ b = options[:bodyfont] ||
21
+ (options[:script] == "Hans" ? '"SimSun",serif' :
22
+ '"Lato",sans-serif')
23
+ h = options[:headerfont] ||
24
+ (options[:script] == "Hans" ? '"SimHei",sans-serif' :
25
+ '"Lato",sans-serif')
26
+ m = options[:monospacefont] || '"Space Mono",monospace'
27
+ "$bodyfont: #{b};\n$headerfont: #{h};\n$monospacefont: #{m};\n"
28
+ end
29
+
30
+ def html_doc_path(file)
31
+ File.join(File.dirname(__FILE__), File.join("html", file))
32
+ end
33
+
34
+ def metadata_init(lang, script, labels)
35
+ @meta = Metadata.new(lang, script, labels)
36
+ end
37
+
38
+ def initialize(options)
39
+ super
40
+ if options[:alt]
41
+ css = generate_css(html_doc_path("style-human.scss"), true, alt_fonts(options))
42
+ else
43
+ css = generate_css(html_doc_path("style-iso.scss"), true, default_fonts(options))
44
+ end
45
+ @htmlstylesheet = css
46
+ @htmlcoverpage = html_doc_path("html_iso_titlepage.html")
47
+ @htmlintropage = html_doc_path("html_iso_intro.html")
48
+ @scripts = html_doc_path("scripts.html")
49
+ end
50
+
51
+ def implicit_reference(b)
52
+ isocode = b.at(ns("./docidentifier")).text
53
+ isocode == "IEV"
54
+ end
55
+
56
+ def introduction(isoxml, out)
57
+ f = isoxml.at(ns("//introduction")) || return
58
+ num = f.at(ns(".//clause")) ? "0" : nil
59
+ title_attr = { class: "IntroTitle" }
60
+ page_break(out)
61
+ out.div **{ class: "Section3", id: f["id"] } do |div|
62
+ # div.h1 "Introduction", **attr_code(title_attr)
63
+ clause_name(num, @introduction_lbl, div, title_attr)
64
+ f.elements.each do |e|
65
+ if e.name == "patent-notice"
66
+ e.elements.each { |e1| parse(e1, div) }
67
+ else
68
+ parse(e, div) unless e.name == "title"
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ def foreword(isoxml, out)
75
+ f = isoxml.at(ns("//foreword")) || return
76
+ page_break(out)
77
+ out.div **attr_code(id: f["id"]) do |s|
78
+ s.h1(**{ class: "ForewordTitle" }) { |h1| h1 << @foreword_lbl }
79
+ f.elements.each { |e| parse(e, s) unless e.name == "title" }
80
+ end
81
+ end
82
+
83
+ def initial_anchor_names(d)
84
+ super
85
+ introduction_names(d.at(ns("//introduction")))
86
+ end
87
+
88
+ # we can reference 0-number clauses in introduction
89
+ def introduction_names(clause)
90
+ return if clause.nil?
91
+ clause.xpath(ns("./clause")).each_with_index do |c, i|
92
+ section_names1(c, "0.#{i + 1}", 2)
93
+ end
94
+ end
95
+
96
+ # terms not defined in standoc
97
+ def error_parse(node, out)
98
+ case node.name
99
+ when "appendix" then clause_parse(node, out)
100
+ else
101
+ super
102
+ end
103
+ end
104
+
105
+ def annex_names(clause, num)
106
+ appendix_names(clause, num)
107
+ super
108
+ end
109
+
110
+ def appendix_names(clause, num)
111
+ clause.xpath(ns("./appendix")).each_with_index do |c, i|
112
+ @anchors[c["id"]] = anchor_struct(i + 1, nil, @appendix_lbl)
113
+ @anchors[c["id"]][:level] = 2
114
+ @anchors[c["id"]][:container] = clause["id"]
115
+ end
116
+ end
117
+
118
+ def section_names1(clause, num, level)
119
+ @anchors[clause["id"]] =
120
+ { label: num, level: level, xref: num }
121
+ # subclauses are not prefixed with "Clause"
122
+ clause.xpath(ns("./clause | ./terms | ./term | ./definitions")).
123
+ each_with_index do |c, i|
124
+ section_names1(c, "#{num}.#{i + 1}", level + 1)
125
+ end
126
+ end
127
+
128
+ def annex_names1(clause, num, level)
129
+ @anchors[clause["id"]] = { label: num, xref: num, level: level }
130
+ clause.xpath(ns(".//clause")).each_with_index do |c, i|
131
+ annex_names1(c, "#{num}.#{i + 1}", level + 1)
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,107 @@
1
+ require "isodoc"
2
+
3
+ module IsoDoc
4
+ module Iso
5
+ class Metadata < IsoDoc::Metadata
6
+ def initialize(lang, script, labels)
7
+ super
8
+ end
9
+
10
+ STAGE_ABBRS = {
11
+ "00": "PWI",
12
+ "10": "NWIP",
13
+ "20": "WD",
14
+ "30": "CD",
15
+ "40": "DIS",
16
+ "50": "FDIS",
17
+ "60": "IS",
18
+ "90": "(Review)",
19
+ "95": "(Withdrawal)",
20
+ }.freeze
21
+
22
+ def stage_abbrev(stage, iter, draft)
23
+ stage = STAGE_ABBRS[stage.to_sym] || "??"
24
+ stage += iter.text if iter
25
+ stage = "Pre" + stage if draft&.text =~ /^0\./
26
+ stage
27
+ end
28
+
29
+ def docstatus(isoxml, _out)
30
+ docstatus = isoxml.at(ns("//status/stage"))
31
+ if docstatus
32
+ set(:stage, docstatus.text)
33
+ set(:stage_int, docstatus.text.to_i)
34
+ abbr = stage_abbrev(docstatus.text, isoxml.at(ns("//status/iteration")),
35
+ isoxml.at(ns("//version/draft")))
36
+ set(:stageabbr, abbr)
37
+ end
38
+ end
39
+
40
+ def docid(isoxml, _out)
41
+ dn = docnumber(isoxml)
42
+ docstatus = get[:stage]
43
+ if docstatus
44
+ abbr = get[:stageabbr]
45
+ docstatus = get[:stage]
46
+ (docstatus.to_i < 60) && dn = abbr + " " + dn
47
+ end
48
+ set(:docnumber, dn)
49
+ end
50
+
51
+ # we don't leave this to i18n.rb, because we have both English and
52
+ # French titles in the same document
53
+ def part_label(lang)
54
+ case lang
55
+ when "en" then "Part"
56
+ when "fr" then "Partie"
57
+ end
58
+ end
59
+
60
+ def part_title(part, partnum, subpartnum, lang)
61
+ return "" unless part
62
+ suffix = @c.encode(part.text, :hexadecimal)
63
+ partnum = "#{partnum}&ndash;#{subpartnum}" if partnum && subpartnum
64
+ suffix = "#{part_label(lang)}&nbsp;#{partnum}: " + suffix if partnum
65
+ suffix
66
+ end
67
+
68
+ def compose_title(main, intro, part, partnum, subpartnum, lang)
69
+ main = main.nil? ? "" : @c.encode(main.text, :hexadecimal)
70
+ intro &&
71
+ main = "#{@c.encode(intro.text, :hexadecimal)}&nbsp;&mdash; #{main}"
72
+ if part
73
+ suffix = part_title(part, partnum, subpartnum, lang)
74
+ main = "#{main}&nbsp;&mdash; #{suffix}"
75
+ end
76
+ main
77
+ end
78
+
79
+ def title(isoxml, _out)
80
+ intro = isoxml.at(ns("//title-intro[@language='en']"))
81
+ main = isoxml.at(ns("//title-main[@language='en']"))
82
+ part = isoxml.at(ns("//title-part[@language='en']"))
83
+ partnumber = isoxml.at(ns("//project-number/@part"))
84
+ subpartnumber = isoxml.at(ns("//project-number/@subpart"))
85
+
86
+ set(:doctitlemain, @c.encode(main ? main.text : "", :hexadecimal))
87
+ main = compose_title(main, intro, part, partnumber, subpartnumber, "en")
88
+ set(:doctitle, main)
89
+ set(:doctitleintro, @c.encode(intro ? intro.text : "", :hexadecimal)) if intro
90
+ set(:doctitlepart, part_title(part, partnumber, subpartnumber, "en"))
91
+ end
92
+
93
+ def subtitle(isoxml, _out)
94
+ intro = isoxml.at(ns("//title-intro[@language='fr']"))
95
+ main = isoxml.at(ns("//title-main[@language='fr']"))
96
+ part = isoxml.at(ns("//title-part[@language='fr']"))
97
+ partnumber = isoxml.at(ns("//project-number/@part"))
98
+ subpartnumber = isoxml.at(ns("//project-number/@subpart"))
99
+ set(:docsubtitlemain, @c.encode(main ? main.text : "", :hexadecimal))
100
+ main = compose_title(main, intro, part, partnumber, subpartnumber, "fr")
101
+ set(:docsubtitle, main)
102
+ set(:docsubtitleintro, @c.encode(intro ? intro.text : "", :hexadecimal)) if intro
103
+ set(:docsubtitlepart, part_title(part, partnumber, subpartnumber, "fr"))
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,139 @@
1
+ require "isodoc"
2
+ require_relative "metadata"
3
+
4
+ module IsoDoc
5
+ module Iso
6
+ class WordConvert < IsoDoc::WordConvert
7
+
8
+ def default_fonts(options)
9
+ b = options[:bodyfont] ||
10
+ (options[:script] == "Hans" ? '"SimSun",serif' :
11
+ '"Cambria",serif')
12
+ h = options[:headerfont] ||
13
+ (options[:script] == "Hans" ? '"SimHei",sans-serif' :
14
+ '"Cambria",serif')
15
+ m = options[:monospacefont] || '"Courier New",monospace'
16
+ "$bodyfont: #{b};\n$headerfont: #{h};\n$monospacefont: #{m};\n"
17
+ end
18
+
19
+ def html_doc_path(file)
20
+ File.join(File.dirname(__FILE__), File.join("html", file))
21
+ end
22
+
23
+ def initialize(options)
24
+ super
25
+ @wordstylesheet = generate_css(html_doc_path("wordstyle.scss"), false, default_fonts(options))
26
+ @standardstylesheet = generate_css(html_doc_path("isodoc.scss"), false, default_fonts(options))
27
+ @header = html_doc_path("header.html")
28
+ @wordcoverpage = html_doc_path("word_iso_titlepage.html")
29
+ @wordintropage = html_doc_path("word_iso_intro.html")
30
+ @ulstyle = "l3"
31
+ @olstyle = "l2"
32
+ end
33
+
34
+ def metadata_init(lang, script, labels)
35
+ @meta = Metadata.new(lang, script, labels)
36
+ end
37
+
38
+ def implicit_reference(b)
39
+ isocode = b.at(ns("./docidentifier")).text
40
+ isocode == "IEV"
41
+ end
42
+
43
+ def make_body(xml, docxml)
44
+ body_attr = { lang: "EN-US", link: "blue", vlink: "#954F72" }
45
+ xml.body **body_attr do |body|
46
+ make_body1(body, docxml)
47
+ make_body2(body, docxml)
48
+ make_body3(body, docxml)
49
+ colophon(body, docxml)
50
+ end
51
+ end
52
+
53
+ def colophon(body, docxml)
54
+ body.br **{ clear: "all", style: "page-break-before:left;mso-break-type:section-break" }
55
+ body.div **{ class: "colophon" } do |div|
56
+ end
57
+ end
58
+
59
+ def introduction(isoxml, out)
60
+ f = isoxml.at(ns("//introduction")) || return
61
+ num = f.at(ns(".//clause")) ? "0" : nil
62
+ title_attr = { class: "IntroTitle" }
63
+ page_break(out)
64
+ out.div **{ class: "Section3", id: f["id"] } do |div|
65
+ # div.h1 "Introduction", **attr_code(title_attr)
66
+ clause_name(num, @introduction_lbl, div, title_attr)
67
+ f.elements.each do |e|
68
+ if e.name == "patent-notice"
69
+ e.elements.each { |e1| parse(e1, div) }
70
+ else
71
+ parse(e, div) unless e.name == "title"
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ def foreword(isoxml, out)
78
+ f = isoxml.at(ns("//foreword")) || return
79
+ page_break(out)
80
+ out.div **attr_code(id: f["id"]) do |s|
81
+ s.h1(**{ class: "ForewordTitle" }) { |h1| h1 << @foreword_lbl }
82
+ f.elements.each { |e| parse(e, s) unless e.name == "title" }
83
+ end
84
+ end
85
+
86
+ def initial_anchor_names(d)
87
+ super
88
+ introduction_names(d.at(ns("//introduction")))
89
+ end
90
+
91
+ # we can reference 0-number clauses in introduction
92
+ def introduction_names(clause)
93
+ return if clause.nil?
94
+ clause.xpath(ns("./clause")).each_with_index do |c, i|
95
+ section_names1(c, "0.#{i + 1}", 2)
96
+ end
97
+ end
98
+
99
+ # terms not defined in standoc
100
+ def error_parse(node, out)
101
+ case node.name
102
+ when "appendix" then clause_parse(node, out)
103
+ else
104
+ super
105
+ end
106
+ end
107
+
108
+ def annex_names(clause, num)
109
+ appendix_names(clause, num)
110
+ super
111
+ end
112
+
113
+ def appendix_names(clause, num)
114
+ clause.xpath(ns("./appendix")).each_with_index do |c, i|
115
+ @anchors[c["id"]] = anchor_struct(i + 1, nil, @appendix_lbl)
116
+ @anchors[c["id"]][:level] = 2
117
+ @anchors[c["id"]][:container] = clause["id"]
118
+ end
119
+ end
120
+
121
+ def section_names1(clause, num, level)
122
+ @anchors[clause["id"]] =
123
+ { label: num, level: level, xref: num }
124
+ # subclauses are not prefixed with "Clause"
125
+ clause.xpath(ns("./clause | ./terms | ./term | ./definitions")).
126
+ each_with_index do |c, i|
127
+ section_names1(c, "#{num}.#{i + 1}", level + 1)
128
+ end
129
+ end
130
+
131
+ def annex_names1(clause, num, level)
132
+ @anchors[clause["id"]] = { label: num, xref: num, level: level }
133
+ clause.xpath(ns(".//clause")).each_with_index do |c, i|
134
+ annex_names1(c, "#{num}.#{i + 1}", level + 1)
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
@@ -45,7 +45,9 @@ EOS
45
45
 
46
46
  it "does not activate biblio caches if isobib disabled" do
47
47
  system "mv ~/.relaton-bib.pstore ~/.relaton-bib.pstore1"
48
+ system "mv ~/.iev.pstore ~/.iev.pstore1"
48
49
  system "rm -f test.relaton.pstore"
50
+ system "rm -f test.iev.pstore"
49
51
  Asciidoctor.convert(<<~"INPUT", backend: :iso, header_footer: true)
50
52
  #{ASCIIDOC_BLANK_HDR}
51
53
  [bibliography]
@@ -54,15 +56,21 @@ EOS
54
56
  * [[[iso123,ISO 123:2001]]] _Standard_
55
57
  INPUT
56
58
  expect(File.exist?("#{Dir.home}/.relaton-bib.pstore")).to be false
59
+ expect(File.exist?("#{Dir.home}/.iev.pstore")).to be false
57
60
  expect(File.exist?("test.relaton.pstore")).to be false
61
+ expect(File.exist?("test.iev.pstore")).to be false
58
62
 
59
63
  system "rm ~/.relaton-bib.pstore"
64
+ system "rm ~/.iev.pstore"
60
65
  system "mv ~/.relaton-bib.pstore1 ~/.relaton-bib.pstore"
66
+ system "mv ~/.iev.pstore1 ~/.iev.pstore"
61
67
  end
62
68
 
63
69
  it "does not activate biblio caches if isobib caching disabled" do
64
70
  system "mv ~/.relaton-bib.pstore ~/.relaton-bib.pstore1"
71
+ system "mv ~/.iev.pstore ~/.iev.pstore1"
65
72
  system "rm -f test.relaton.pstore"
73
+ system "rm -f test.iev.pstore"
66
74
  mock_isobib_get_123
67
75
  Asciidoctor.convert(<<~"INPUT", backend: :iso, header_footer: true)
68
76
  #{ISOBIB_BLANK_HDR}
@@ -72,18 +80,22 @@ EOS
72
80
  * [[[iso123,ISO 123:2001]]] _Standard_
73
81
  INPUT
74
82
  expect(File.exist?("#{Dir.home}/.relaton-bib.pstore")).to be false
83
+ expect(File.exist?("#{Dir.home}/.iev.pstore")).to be false
75
84
  expect(File.exist?("test.relaton.pstore")).to be false
85
+ expect(File.exist?("test.iev.pstore")).to be false
76
86
 
77
87
  system "rm ~/.relaton-bib.pstore"
88
+ system "rm ~/.iev.pstore"
78
89
  system "mv ~/.relaton-bib.pstore1 ~/.relaton-bib.pstore"
90
+ system "mv ~/.iev.pstore1 ~/.iev.pstore"
79
91
  end
80
92
 
81
93
  it "flushes biblio caches" do
82
94
  system "cp ~/.relaton-bib.pstore ~/.relaton-bib.pstore1"
95
+ system "cp ~/.iev.pstore ~/.iev.pstore1"
83
96
 
84
- File.open("#{Dir.home}/.relaton-bib.pstore", "w") do |f|
85
- f.write "XXX"
86
- end
97
+ File.open("#{Dir.home}/.relaton-bib.pstore", "w") { |f| f.write "XXX" }
98
+ system "rm ~/.iev.pstore"
87
99
 
88
100
  mock_isobib_get_123
89
101
  Asciidoctor.convert(<<~"INPUT", backend: :iso, header_footer: true)
@@ -94,6 +106,7 @@ EOS
94
106
  * [[[iso123,ISO 123:2001]]] _Standard_
95
107
  INPUT
96
108
  expect(File.exist?("#{Dir.home}/.relaton-bib.pstore")).to be true
109
+ expect(File.exist?("#{Dir.home}/.iev.pstore")).to be true
97
110
 
98
111
  db = Relaton::Db.new "#{Dir.home}/.relaton-bib.pstore", nil
99
112
  entry = db.load_entry("ISO 123:2001")
@@ -101,10 +114,11 @@ EOS
101
114
  expect(entry["bib"].to_xml).to be_equivalent_to(ISOBIB_123_DATED)
102
115
 
103
116
  system "rm ~/.relaton-bib.pstore"
117
+ system "rm ~/.iev.pstore"
104
118
  system "mv ~/.relaton-bib.pstore1 ~/.relaton-bib.pstore"
119
+ system "mv ~/.iev.pstore1 ~/.iev.pstore"
105
120
  end
106
121
 
107
-
108
122
  it "activates global cache" do
109
123
  system "mv ~/.relaton-bib.pstore ~/.relaton-bib.pstore1"
110
124
  system "rm -f test.relaton.pstore"