metanorma-mpfd 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.travis.yml +17 -0
  4. data/CODE_OF_CONDUCT.md +74 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +25 -0
  7. data/README.adoc +1 -0
  8. data/Rakefile +6 -0
  9. data/bin/console +14 -0
  10. data/bin/rspec +18 -0
  11. data/bin/setup +8 -0
  12. data/lib/asciidoctor/mpfd/biblio.rng +836 -0
  13. data/lib/asciidoctor/mpfd/converter.rb +204 -0
  14. data/lib/asciidoctor/mpfd/isodoc.rng +1041 -0
  15. data/lib/asciidoctor/mpfd/isostandard.rng +1001 -0
  16. data/lib/asciidoctor/mpfd/pdf.js +31 -0
  17. data/lib/asciidoctor/mpfd/rsd.rng +212 -0
  18. data/lib/asciidoctor/mpfd/section.rb +94 -0
  19. data/lib/asciidoctor/mpfd/version.rb +5 -0
  20. data/lib/asciidoctor/mpfd.rb +9 -0
  21. data/lib/isodoc/mpfd/html/header.html +184 -0
  22. data/lib/isodoc/mpfd/html/html_rsd_intro.html +8 -0
  23. data/lib/isodoc/mpfd/html/html_rsd_titlepage.html +58 -0
  24. data/lib/isodoc/mpfd/html/htmlstyle.scss +1094 -0
  25. data/lib/isodoc/mpfd/html/logo.jpg +0 -0
  26. data/lib/isodoc/mpfd/html/logo.svg +1 -0
  27. data/lib/isodoc/mpfd/html/mpfa-logo-no-text@4x.png +0 -0
  28. data/lib/isodoc/mpfd/html/mpfa-logo@4x.png +0 -0
  29. data/lib/isodoc/mpfd/html/rsd.scss +564 -0
  30. data/lib/isodoc/mpfd/html/scripts.html +82 -0
  31. data/lib/isodoc/mpfd/html/word_rsd_intro.html +3 -0
  32. data/lib/isodoc/mpfd/html/word_rsd_titlepage.html +42 -0
  33. data/lib/isodoc/mpfd/html/wordstyle.scss +1096 -0
  34. data/lib/isodoc/mpfd/html_convert.rb +370 -0
  35. data/lib/isodoc/mpfd/i18n-en.yaml +1 -0
  36. data/lib/isodoc/mpfd/metadata.rb +98 -0
  37. data/lib/isodoc/mpfd/pdf_convert.rb +367 -0
  38. data/lib/isodoc/mpfd/word_convert.rb +347 -0
  39. data/lib/metanorma/mpfd/processor.rb +43 -0
  40. data/lib/metanorma/mpfd.rb +7 -0
  41. data/lib/metanorma-mpfd.rb +11 -0
  42. data/metanorma-mpfd.gemspec +46 -0
  43. metadata +326 -0
@@ -0,0 +1,367 @@
1
+ require "isodoc"
2
+ require_relative "metadata"
3
+
4
+ module IsoDoc
5
+ module Mpfd
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 rsd_html_path(file)
10
+ File.join(File.dirname(__FILE__), File.join("html", file))
11
+ end
12
+
13
+ def initialize(options)
14
+ super
15
+ @htmlstylesheet = generate_css(rsd_html_path("htmlstyle.scss"), true, default_fonts(options))
16
+ @htmlcoverpage = rsd_html_path("html_rsd_titlepage.html")
17
+ @htmlintropage = rsd_html_path("html_rsd_intro.html")
18
+ @scripts = rsd_html_path("scripts.html")
19
+ system "cp #{rsd_html_path('logo.jpg')} logo.jpg"
20
+ system "cp #{rsd_html_path('mpfa-logo-no-text@4x.png')} mpfa-logo-no-text@4x.png"
21
+ @files_to_delete << "logo.jpg"
22
+ @files_to_delete << "mpfa-logo-no-text@4x.png"
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
+ <link href="https://fonts.googleapis.com/css?family=Titillium+Web:400,400i,700,700i" 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 info(isoxml, out)
118
+ @meta.security isoxml, out
119
+ super
120
+ end
121
+
122
+ def annex_name(annex, name, div)
123
+ div.h1 **{ class: "Annex" } do |t|
124
+ t << "#{get_anchors[annex['id']][:label]} "
125
+ t << "<b>#{name.text}</b>"
126
+ end
127
+ end
128
+
129
+ def annex_name_lbl(clause, num)
130
+ obl = l10n("(#{@inform_annex_lbl})")
131
+ obl = l10n("(#{@norm_annex_lbl})") if clause["obligation"] == "normative"
132
+ l10n("<b>#{@annex_lbl} #{num}</b> #{obl}")
133
+ end
134
+
135
+ def pre_parse(node, out)
136
+ out.pre node.text # content.gsub(/</, "&lt;").gsub(/>/, "&gt;")
137
+ end
138
+
139
+ def term_defs_boilerplate(div, source, term, preface)
140
+ if source.empty? && term.nil?
141
+ div << @no_terms_boilerplate
142
+ else
143
+ div << term_defs_boilerplate_cont(source, term)
144
+ end
145
+ end
146
+
147
+ def i18n_init(lang, script)
148
+ super
149
+ @annex_lbl = "Appendix"
150
+ end
151
+
152
+ def error_parse(node, out)
153
+ # catch elements not defined in ISO
154
+ case node.name
155
+ when "pre"
156
+ pre_parse(node, out)
157
+ when "keyword"
158
+ out.span node.text, **{ class: "keyword" }
159
+ else
160
+ super
161
+ end
162
+ end
163
+
164
+ def fileloc(loc)
165
+ File.join(File.dirname(__FILE__), loc)
166
+ end
167
+
168
+ def i18n_init(lang, script)
169
+ super
170
+ y = if lang == "en"
171
+ YAML.load_file(File.join(File.dirname(__FILE__), "i18n-en.yaml"))
172
+ elsif lang == "zh" && script == "Hans"
173
+ YAML.load_file(File.join(File.dirname(__FILE__),
174
+ "i18n-zh-Hans.yaml"))
175
+ else
176
+ YAML.load_file(File.join(File.dirname(__FILE__), "i18n-zh-Hans.yaml"))
177
+ end
178
+ @labels = @labels.merge(y)
179
+ @clause_lbl = y["clause"]
180
+ end
181
+
182
+ def terms_defs_title(f)
183
+ return f&.at(ns("./title"))&.content
184
+ end
185
+
186
+ TERM_CLAUSE = "//preface/terms | "\
187
+ "//preface/clause[descendant::terms]".freeze
188
+
189
+
190
+ def terms_defs(isoxml, out, num)
191
+ f = isoxml.at(ns(TERM_CLAUSE)) or return num
192
+ out.div **attr_code(id: f["id"]) do |div|
193
+ clause_name(nil, terms_defs_title(f), div, nil)
194
+ f.elements.each do |e|
195
+ parse(e, div) unless %w{title source}.include? e.name
196
+ end
197
+ end
198
+ num
199
+ end
200
+
201
+ FRONT_CLAUSE = "//*[parent::preface]".freeze
202
+ #FRONT_CLAUSE = "//clause[parent::preface] | //terms[parent::preface]".freeze
203
+
204
+ def preface(isoxml, out)
205
+ isoxml.xpath(ns(FRONT_CLAUSE)).each do |c|
206
+ if c.name == "terms" then terms_defs isoxml, out, 0
207
+ else
208
+ out.div **attr_code(id: c["id"]) do |s|
209
+ clause_name(get_anchors[c['id']][:label],
210
+ c&.at(ns("./title"))&.content, s, nil)
211
+ c.elements.reject { |c1| c1.name == "title" }.each do |c1|
212
+ parse(c1, s)
213
+ end
214
+ end
215
+ end
216
+ end
217
+ end
218
+
219
+ def make_body3(body, docxml)
220
+ body.div **{ class: "main-section" } do |div3|
221
+ preface docxml, div3
222
+ middle docxml, div3
223
+ footnotes div3
224
+ comments div3
225
+ end
226
+ end
227
+
228
+ def middle(isoxml, out)
229
+ middle_title(out)
230
+ clause isoxml, out
231
+ annex isoxml, out
232
+ bibliography isoxml, out
233
+ end
234
+
235
+ def termdef_parse(node, out)
236
+ set_termdomain("")
237
+ node.children.each { |n| parse(n, out) }
238
+ end
239
+
240
+ def initial_anchor_names(d)
241
+ #preface_names(d.at(ns("//foreword")))
242
+ #preface_names(d.at(ns("//introduction")))
243
+ #preface_names(d.at(ns("//preface/terms | "\
244
+ #"//preface/clause[descendant::terms]")))
245
+ d.xpath(ns(FRONT_CLAUSE)).each do |c|
246
+ preface_names(c)
247
+ sequential_asset_names(c)
248
+ end
249
+ middle_section_asset_names(d)
250
+ clause_names(d, 0)
251
+ termnote_anchor_names(d)
252
+ termexample_anchor_names(d)
253
+ end
254
+
255
+ def annex_name_lbl(clause, num)
256
+ l10n("<b>#{@annex_lbl} #{num}</b>")
257
+ end
258
+
259
+ def clause_names(docxml, sect_num)
260
+ q = "//clause[parent::sections]"
261
+ @topnum = nil
262
+ lvl = 0
263
+ docxml.xpath(ns(q)).each do |c|
264
+ container_names(c, 0)
265
+ sect_num, lvl = sect_names(c, nil, sect_num, 0, lvl)
266
+ end
267
+ end
268
+
269
+ def container_names(clause, lvl)
270
+ if clause["container"]
271
+ @anchors[clause["id"]] =
272
+ { label: nil, xref: clause.at(ns("./title"))&.text, level: lvl+1 }
273
+ end
274
+ clause.xpath(ns("./clause | ./term | ./terms | "\
275
+ "./definitions")).each do |c|
276
+ container_names(c, clause["container"] ? lvl+1 : lvl)
277
+ end
278
+ end
279
+
280
+ def sect_names(clause, num, i, lvl, prev_lvl)
281
+ return i if clause.nil?
282
+ curr = i
283
+ if clause["container"]
284
+ retlvl = lvl+1
285
+ else
286
+ retlvl = lvl
287
+ i+=1
288
+ curr = i
289
+ name = num.nil? ? i.to_s : "#{num}.#{i}"
290
+ @anchors[clause["id"]] = { label: name, xref: l10n("#{@clause_lbl} #{name}"), level: lvl+1 }
291
+ end
292
+ prev = lvl
293
+ j = 0
294
+ clause.xpath(ns("./clause | ./term | ./terms | "\
295
+ "./definitions")).each do |c|
296
+ if clause["container"]
297
+ i, lvl = sect_names(c, num, i, lvl, lvl)
298
+ else
299
+ j, prev = sect_names(c, name, j, lvl+1, prev)
300
+ end
301
+ end
302
+ i = j if j >0
303
+ i = curr if lvl < prev
304
+ [i, prev]
305
+ end
306
+
307
+ def annex_naming(c, num, lvl, i)
308
+ if c["guidance"] then annex_names1(c, "#{num}E", lvl + 1)
309
+ else
310
+ i+= 1
311
+ annex_names1(c, "#{num}.#{i}", lvl + 1)
312
+ end
313
+ i
314
+ end
315
+
316
+ def annex_names(clause, num)
317
+ @anchors[clause["id"]] = { label: annex_name_lbl(clause, num),
318
+ xref: "#{@annex_lbl} #{num}", level: 1 }
319
+ i = 0
320
+ clause.xpath(ns("./clause")).each do |c|
321
+ i = annex_naming(c, num, 1, i)
322
+ end
323
+ hierarchical_asset_names(clause, num)
324
+ end
325
+
326
+ def annex_names1(clause, num, level)
327
+ @anchors[clause["id"]] = { label: num, xref: "#{@annex_lbl} #{num}",
328
+ level: level }
329
+ i = 0
330
+ clause.xpath(ns("./clause")).each do |c|
331
+ i = annex_naming(c, num, level, i)
332
+ end
333
+ end
334
+
335
+ def clause(isoxml, out)
336
+ isoxml.xpath(ns(MIDDLE_CLAUSE)).each do |c|
337
+ out.div **attr_code(id: c["id"]) do |s|
338
+ clause_name(get_anchors[c['id']][:label],
339
+ c&.at(ns("./title"))&.content, s, class: c["container"] ? "containerhdr" : nil )
340
+ c.elements.reject { |c1| c1.name == "title" }.each do |c1|
341
+ parse(c1, s)
342
+ end
343
+ end
344
+ end
345
+ end
346
+
347
+ def clause_parse_title(node, div, c1, out)
348
+ if node["inline-header"] == "true"
349
+ inline_header_title(out, node, c1)
350
+ else
351
+ attrs = { class: node["container"] ? "containerhdr" : nil }
352
+ div.send "h#{get_anchors[node['id']][:level]}", **attr_code(attrs) do |h|
353
+ lbl = get_anchors[node['id']][:label]
354
+ h << "#{lbl}. " if lbl
355
+ c1&.children&.each { |c2| parse(c2, h) }
356
+ end
357
+ end
358
+ end
359
+
360
+ def ol_depth(node)
361
+ ol_style(node["type"])
362
+ end
363
+
364
+ end
365
+ end
366
+ end
367
+