metanorma-rsd 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,199 @@
1
+ require "isodoc"
2
+ require_relative "metadata"
3
+ require "fileutils"
4
+
5
+ module IsoDoc
6
+ module Rsd
7
+
8
+ # A {Converter} implementation that generates HTML output, and a document
9
+ # schema encapsulation of the document for validation
10
+ #
11
+ class HtmlConvert < IsoDoc::HtmlConvert
12
+ def initialize(options)
13
+ @libdir = File.dirname(__FILE__)
14
+ super
15
+ #system "cp #{html_doc_path('logo.svg')} logo.svg"
16
+ FileUtils.cp html_doc_path('logo.svg'), "logo.svg"
17
+ @files_to_delete << "logo.svg"
18
+ end
19
+
20
+ def default_fonts(options)
21
+ {
22
+ bodyfont: (options[:script] == "Hans" ? '"SimSun",serif' : '"Overpass",sans-serif'),
23
+ headerfont: (options[:script] == "Hans" ? '"SimHei",sans-serif' : '"Overpass",sans-serif'),
24
+ monospacefont: '"Space Mono",monospace'
25
+ }
26
+ end
27
+
28
+ def default_file_locations(_options)
29
+ {
30
+ htmlstylesheet: html_doc_path("htmlstyle.scss"),
31
+ htmlcoverpage: html_doc_path("html_rsd_titlepage.html"),
32
+ htmlintropage: html_doc_path("html_rsd_intro.html"),
33
+ scripts: html_doc_path("scripts.html"),
34
+ }
35
+ end
36
+
37
+ def metadata_init(lang, script, labels)
38
+ @meta = Metadata.new(lang, script, labels)
39
+ end
40
+
41
+ def html_head
42
+ <<~HEAD.freeze
43
+ <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
44
+
45
+ <!--TOC script import-->
46
+ <script type="text/javascript" src="https://cdn.rawgit.com/jgallen23/toc/0.3.2/dist/toc.min.js"></script>
47
+
48
+ <!--Google fonts-->
49
+ <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i|Space+Mono:400,700" rel="stylesheet">
50
+ <link href="https://fonts.googleapis.com/css?family=Overpass:300,300i,600,900" rel="stylesheet">
51
+ <!--Font awesome import for the link icon-->
52
+ <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/solid.css" integrity="sha384-v2Tw72dyUXeU3y4aM2Y0tBJQkGfplr39mxZqlTBDUZAb9BGoC40+rdFCG0m10lXk" crossorigin="anonymous">
53
+ <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/fontawesome.css" integrity="sha384-q3jl8XQu1OpdLgGFvNRnPdj5VIlCvgsDQTQB6owSOHWlAurxul7f+JpUOVdAiJ5P" crossorigin="anonymous">
54
+ <style class="anchorjs"></style>
55
+ HEAD
56
+ end
57
+
58
+ def make_body(xml, docxml)
59
+ body_attr = { lang: "EN-US", link: "blue", vlink: "#954F72", "xml:lang": "EN-US", class: "container" }
60
+ xml.body **body_attr do |body|
61
+ make_body1(body, docxml)
62
+ make_body2(body, docxml)
63
+ make_body3(body, docxml)
64
+ end
65
+ end
66
+
67
+ def html_toc(docxml)
68
+ docxml
69
+ end
70
+
71
+ def annex_name(annex, name, div)
72
+ div.h1 **{ class: "Annex" } do |t|
73
+ t << "#{get_anchors[annex['id']][:label]} "
74
+ t << "<b>#{name.text}</b>"
75
+ end
76
+ end
77
+
78
+ def annex_name_lbl(clause, num)
79
+ obl = l10n("(#{@inform_annex_lbl})")
80
+ obl = l10n("(#{@norm_annex_lbl})") if clause["obligation"] == "normative"
81
+ l10n("<b>#{@annex_lbl} #{num}</b> #{obl}")
82
+ end
83
+
84
+ def pre_parse(node, out)
85
+ out.pre node.text # content.gsub(/</, "&lt;").gsub(/>/, "&gt;")
86
+ end
87
+
88
+ def term_defs_boilerplate(div, source, term, preface)
89
+ if source.empty? && term.nil?
90
+ div << @no_terms_boilerplate
91
+ else
92
+ div << term_defs_boilerplate_cont(source, term)
93
+ end
94
+ end
95
+
96
+ def i18n_init(lang, script)
97
+ super
98
+ @annex_lbl = "Appendix"
99
+ end
100
+
101
+ def error_parse(node, out)
102
+ # catch elements not defined in ISO
103
+ case node.name
104
+ when "pre"
105
+ pre_parse(node, out)
106
+ when "keyword"
107
+ out.span node.text, **{ class: "keyword" }
108
+ else
109
+ super
110
+ end
111
+ end
112
+
113
+ def fileloc(loc)
114
+ File.join(File.dirname(__FILE__), loc)
115
+ end
116
+
117
+ def cleanup(docxml)
118
+ super
119
+ term_cleanup(docxml)
120
+ end
121
+
122
+ def term_cleanup(docxml)
123
+ docxml.xpath("//p[@class = 'Terms']").each do |d|
124
+ h2 = d.at("./preceding-sibling::*[@class = 'TermNum'][1]")
125
+ h2.add_child("&nbsp;")
126
+ h2.add_child(d.remove)
127
+ end
128
+ docxml
129
+ end
130
+
131
+ def info(isoxml, out)
132
+ @meta.security isoxml, out
133
+ super
134
+ end
135
+
136
+ def annex_name(annex, name, div)
137
+ div.h1 **{ class: "Annex" } do |t|
138
+ t << "#{get_anchors[annex['id']][:label]} "
139
+ t << "<b>#{name.text}</b>"
140
+ end
141
+ end
142
+
143
+ def annex_name_lbl(clause, num)
144
+ obl = l10n("(#{@inform_annex_lbl})")
145
+ obl = l10n("(#{@norm_annex_lbl})") if clause["obligation"] == "normative"
146
+ l10n("<b>#{@annex_lbl} #{num}</b> #{obl}")
147
+ end
148
+
149
+ def pre_parse(node, out)
150
+ out.pre node.text # content.gsub(/</, "&lt;").gsub(/>/, "&gt;")
151
+ end
152
+
153
+ def term_defs_boilerplate(div, source, term, preface)
154
+ if source.empty? && term.nil?
155
+ div << @no_terms_boilerplate
156
+ else
157
+ div << term_defs_boilerplate_cont(source, term)
158
+ end
159
+ end
160
+
161
+ def i18n_init(lang, script)
162
+ super
163
+ @annex_lbl = "Appendix"
164
+ end
165
+
166
+ def error_parse(node, out)
167
+ # catch elements not defined in ISO
168
+ case node.name
169
+ when "pre"
170
+ pre_parse(node, out)
171
+ when "keyword"
172
+ out.span node.text, **{ class: "keyword" }
173
+ else
174
+ super
175
+ end
176
+ end
177
+
178
+ def fileloc(loc)
179
+ File.join(File.dirname(__FILE__), loc)
180
+ end
181
+
182
+ def cleanup(docxml)
183
+ super
184
+ term_cleanup(docxml)
185
+ end
186
+
187
+ def term_cleanup(docxml)
188
+ docxml.xpath("//p[@class = 'Terms']").each do |d|
189
+ h2 = d.at("./preceding-sibling::*[@class = 'TermNum'][1]")
190
+ h2.add_child("&nbsp;")
191
+ h2.add_child(d.remove)
192
+ end
193
+ docxml
194
+ end
195
+
196
+ end
197
+ end
198
+ end
199
+
@@ -0,0 +1,85 @@
1
+ require "isodoc"
2
+
3
+ module IsoDoc
4
+ module Rsd
5
+
6
+ class Metadata < IsoDoc::Metadata
7
+ def initialize(lang, script, labels)
8
+ super
9
+ set(:status, "XXX")
10
+ end
11
+
12
+ def title(isoxml, _out)
13
+ main = isoxml&.at(ns("//title[@language='en']"))&.text
14
+ set(:doctitle, main)
15
+ end
16
+
17
+ def subtitle(_isoxml, _out)
18
+ nil
19
+ end
20
+
21
+ def author(isoxml, _out)
22
+ tc = isoxml.at(ns("//editorialgroup/committee"))
23
+ set(:tc, tc.text) if tc
24
+ end
25
+
26
+ def docid(isoxml, _out)
27
+ docnumber = isoxml.at(ns("//bibdata/docidentifier"))
28
+ docstatus = isoxml.at(ns("//bibdata/status"))
29
+ dn = docnumber&.text
30
+ if docstatus
31
+ set(:status, status_print(docstatus.text))
32
+ abbr = status_abbr(docstatus.text)
33
+ dn = "#{dn}(#{abbr})" unless abbr.empty?
34
+ end
35
+ set(:docnumber, dn)
36
+ end
37
+
38
+ def status_print(status)
39
+ status.split(/-/).map{ |w| w.capitalize }.join(" ")
40
+ end
41
+
42
+ def status_abbr(status)
43
+ case status
44
+ when "working-draft" then "wd"
45
+ when "committee-draft" then "cd"
46
+ when "draft-standard" then "d"
47
+ else
48
+ ""
49
+ end
50
+ end
51
+
52
+ def version(isoxml, _out)
53
+ super
54
+ revdate = get[:revdate]
55
+ set(:revdate_monthyear, monthyr(revdate))
56
+ end
57
+
58
+ MONTHS = {
59
+ "01": "January",
60
+ "02": "February",
61
+ "03": "March",
62
+ "04": "April",
63
+ "05": "May",
64
+ "06": "June",
65
+ "07": "July",
66
+ "08": "August",
67
+ "09": "September",
68
+ "10": "October",
69
+ "11": "November",
70
+ "12": "December",
71
+ }.freeze
72
+
73
+ def monthyr(isodate)
74
+ m = /(?<yr>\d\d\d\d)-(?<mo>\d\d)/.match isodate
75
+ return isodate unless m && m[:yr] && m[:mo]
76
+ return "#{MONTHS[m[:mo].to_sym]} #{m[:yr]}"
77
+ end
78
+
79
+ def security(isoxml, _out)
80
+ security = isoxml.at(ns("//bibdata/security")) || return
81
+ set(:security, security.text)
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,197 @@
1
+ require "isodoc"
2
+ require_relative "metadata"
3
+ require "fileutils"
4
+
5
+ module IsoDoc
6
+ module Rsd
7
+ # A {Converter} implementation that generates PDF HTML output, and a
8
+ # document schema encapsulation of the document for validation
9
+ class PdfConvert < IsoDoc::PdfConvert
10
+ def initialize(options)
11
+ @libdir = File.dirname(__FILE__)
12
+ super
13
+ #system "cp #{html_doc_path('logo.svg')} logo.svg"
14
+ FileUtils.cp html_doc_path('logo.svg'), "logo.svg"
15
+ @files_to_delete << "logo.svg"
16
+ end
17
+
18
+ def default_fonts(options)
19
+ {
20
+ bodyfont: (options[:script] == "Hans" ? '"SimSun",serif' : '"Overpass",sans-serif'),
21
+ headerfont: (options[:script] == "Hans" ? '"SimHei",sans-serif' : '"Overpass",sans-serif'),
22
+ monospacefont: '"Space Mono",monospace'
23
+ }
24
+ end
25
+
26
+ def default_file_locations(options)
27
+ {
28
+ htmlstylesheet: html_doc_path("htmlstyle.scss"),
29
+ htmlcoverpage: html_doc_path("html_rsd_titlepage.html"),
30
+ htmlintropage: html_doc_path("html_rsd_intro.html"),
31
+ scripts: html_doc_path("scripts.html"),
32
+ }
33
+ end
34
+
35
+ def metadata_init(lang, script, labels)
36
+ @meta = Metadata.new(lang, script, labels)
37
+ end
38
+
39
+ def html_head()
40
+ <<~HEAD.freeze
41
+ <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
42
+
43
+ <!--TOC script import-->
44
+ <script type="text/javascript" src="https://cdn.rawgit.com/jgallen23/toc/0.3.2/dist/toc.min.js"></script>
45
+
46
+ <!--Google fonts-->
47
+ <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i|Space+Mono:400,700" rel="stylesheet">
48
+ <link href="https://fonts.googleapis.com/css?family=Overpass:300,300i,600,900" rel="stylesheet">
49
+ <!--Font awesome import for the link icon-->
50
+ <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/solid.css" integrity="sha384-v2Tw72dyUXeU3y4aM2Y0tBJQkGfplr39mxZqlTBDUZAb9BGoC40+rdFCG0m10lXk" crossorigin="anonymous">
51
+ <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/fontawesome.css" integrity="sha384-q3jl8XQu1OpdLgGFvNRnPdj5VIlCvgsDQTQB6owSOHWlAurxul7f+JpUOVdAiJ5P" crossorigin="anonymous">
52
+ <style class="anchorjs"></style>
53
+ HEAD
54
+ end
55
+
56
+ def make_body(xml, docxml)
57
+ body_attr = { lang: "EN-US", link: "blue", vlink: "#954F72", "xml:lang": "EN-US", class: "container" }
58
+ xml.body **body_attr do |body|
59
+ make_body1(body, docxml)
60
+ make_body2(body, docxml)
61
+ make_body3(body, docxml)
62
+ end
63
+ end
64
+
65
+ def html_toc(docxml)
66
+ docxml
67
+ end
68
+
69
+ def annex_name(annex, name, div)
70
+ div.h1 **{ class: "Annex" } do |t|
71
+ t << "#{get_anchors[annex['id']][:label]} "
72
+ t << "<b>#{name.text}</b>"
73
+ end
74
+ end
75
+
76
+ def annex_name_lbl(clause, num)
77
+ obl = l10n("(#{@inform_annex_lbl})")
78
+ obl = l10n("(#{@norm_annex_lbl})") if clause["obligation"] == "normative"
79
+ l10n("<b>#{@annex_lbl} #{num}</b> #{obl}")
80
+ end
81
+
82
+ def pre_parse(node, out)
83
+ out.pre node.text # content.gsub(/</, "&lt;").gsub(/>/, "&gt;")
84
+ end
85
+
86
+ def term_defs_boilerplate(div, source, term, preface)
87
+ if source.empty? && term.nil?
88
+ div << @no_terms_boilerplate
89
+ else
90
+ div << term_defs_boilerplate_cont(source, term)
91
+ end
92
+ end
93
+
94
+ def i18n_init(lang, script)
95
+ super
96
+ @annex_lbl = "Appendix"
97
+ end
98
+
99
+ def error_parse(node, out)
100
+ # catch elements not defined in ISO
101
+ case node.name
102
+ when "pre"
103
+ pre_parse(node, out)
104
+ when "keyword"
105
+ out.span node.text, **{ class: "keyword" }
106
+ else
107
+ super
108
+ end
109
+ end
110
+
111
+ def fileloc(loc)
112
+ File.join(File.dirname(__FILE__), loc)
113
+ end
114
+
115
+ def cleanup(docxml)
116
+ super
117
+ term_cleanup(docxml)
118
+ end
119
+
120
+ def term_cleanup(docxml)
121
+ docxml.xpath("//p[@class = 'Terms']").each do |d|
122
+ h2 = d.at("./preceding-sibling::*[@class = 'TermNum'][1]")
123
+ h2.add_child("&nbsp;")
124
+ h2.add_child(d.remove)
125
+ end
126
+ docxml
127
+ end
128
+
129
+ def info(isoxml, out)
130
+ @meta.security isoxml, out
131
+ super
132
+ end
133
+
134
+ def annex_name(annex, name, div)
135
+ div.h1 **{ class: "Annex" } do |t|
136
+ t << "#{get_anchors[annex['id']][:label]} "
137
+ t << "<b>#{name.text}</b>"
138
+ end
139
+ end
140
+
141
+ def annex_name_lbl(clause, num)
142
+ obl = l10n("(#{@inform_annex_lbl})")
143
+ obl = l10n("(#{@norm_annex_lbl})") if clause["obligation"] == "normative"
144
+ l10n("<b>#{@annex_lbl} #{num}</b> #{obl}")
145
+ end
146
+
147
+ def pre_parse(node, out)
148
+ out.pre node.text # content.gsub(/</, "&lt;").gsub(/>/, "&gt;")
149
+ end
150
+
151
+ def term_defs_boilerplate(div, source, term, preface)
152
+ if source.empty? && term.nil?
153
+ div << @no_terms_boilerplate
154
+ else
155
+ div << term_defs_boilerplate_cont(source, term)
156
+ end
157
+ end
158
+
159
+ def i18n_init(lang, script)
160
+ super
161
+ @annex_lbl = "Appendix"
162
+ end
163
+
164
+ def error_parse(node, out)
165
+ # catch elements not defined in ISO
166
+ case node.name
167
+ when "pre"
168
+ pre_parse(node, out)
169
+ when "keyword"
170
+ out.span node.text, **{ class: "keyword" }
171
+ else
172
+ super
173
+ end
174
+ end
175
+
176
+ def fileloc(loc)
177
+ File.join(File.dirname(__FILE__), loc)
178
+ end
179
+
180
+ def cleanup(docxml)
181
+ super
182
+ term_cleanup(docxml)
183
+ end
184
+
185
+ def term_cleanup(docxml)
186
+ docxml.xpath("//p[@class = 'Terms']").each do |d|
187
+ h2 = d.at("./preceding-sibling::*[@class = 'TermNum'][1]")
188
+ h2.add_child("&nbsp;")
189
+ h2.add_child(d.remove)
190
+ end
191
+ docxml
192
+ end
193
+
194
+ end
195
+ end
196
+ end
197
+