metanorma-acme 0.3.3

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