metanorma-m3d 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.travis.yml +15 -0
  4. data/CODE_OF_CONDUCT.md +74 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +25 -0
  7. data/README.adoc +170 -0
  8. data/Rakefile +6 -0
  9. data/asciidoctor-m3d.gemspec.old +54 -0
  10. data/bin/console +14 -0
  11. data/bin/rspec +18 -0
  12. data/bin/setup +8 -0
  13. data/lib/asciidoctor-m3d.rb +10 -0
  14. data/lib/asciidoctor/m3d.rb +7 -0
  15. data/lib/asciidoctor/m3d/biblio.rng +836 -0
  16. data/lib/asciidoctor/m3d/converter.rb +188 -0
  17. data/lib/asciidoctor/m3d/html/dots-w@2x.png +0 -0
  18. data/lib/asciidoctor/m3d/html/dots@2x.png +0 -0
  19. data/lib/asciidoctor/m3d/html/header.html +184 -0
  20. data/lib/asciidoctor/m3d/html/html_m3d_intro.html +8 -0
  21. data/lib/asciidoctor/m3d/html/html_m3d_titlepage.html +95 -0
  22. data/lib/asciidoctor/m3d/html/htmlstyle.scss +797 -0
  23. data/lib/asciidoctor/m3d/html/m3d.scss +549 -0
  24. data/lib/asciidoctor/m3d/html/scripts.html +68 -0
  25. data/lib/asciidoctor/m3d/isodoc.rng +1059 -0
  26. data/lib/asciidoctor/m3d/isostandard.rng +1001 -0
  27. data/lib/asciidoctor/m3d/m3d.rng +154 -0
  28. data/lib/asciidoctor/m3d/version.rb +5 -0
  29. data/lib/isodoc/m3d/html/dots-w@2x.png +0 -0
  30. data/lib/isodoc/m3d/html/dots@2x.png +0 -0
  31. data/lib/isodoc/m3d/html/header.html +219 -0
  32. data/lib/isodoc/m3d/html/html_m3d_intro.html +14 -0
  33. data/lib/isodoc/m3d/html/html_m3d_titlepage.html +102 -0
  34. data/lib/isodoc/m3d/html/htmlstyle.scss +1001 -0
  35. data/lib/isodoc/m3d/html/logo.jpg +0 -0
  36. data/lib/isodoc/m3d/html/m3-logo.png +0 -0
  37. data/lib/isodoc/m3d/html/m3d.scss +697 -0
  38. data/lib/isodoc/m3d/html/scripts.html +82 -0
  39. data/lib/isodoc/m3d/html/word_m3d_intro.html +10 -0
  40. data/lib/isodoc/m3d/html/word_m3d_titlepage.html +58 -0
  41. data/lib/isodoc/m3d/html/wordstyle.scss +1003 -0
  42. data/lib/isodoc/m3d/m3dhtmlconvert.rb +154 -0
  43. data/lib/isodoc/m3d/m3dhtmlrender.rb +68 -0
  44. data/lib/isodoc/m3d/m3dwordconvert.rb +105 -0
  45. data/lib/isodoc/m3d/m3wordrender.rb +68 -0
  46. data/lib/isodoc/m3d/metadata.rb +87 -0
  47. data/lib/metanorma/m3d.rb +7 -0
  48. data/lib/metanorma/m3d/processor.rb +41 -0
  49. data/metanorma-m3d.gemspec +55 -0
  50. metadata +419 -0
@@ -0,0 +1,154 @@
1
+ require "isodoc"
2
+ require_relative "metadata"
3
+ require_relative "m3dhtmlrender"
4
+ require "fileutils"
5
+
6
+ module IsoDoc
7
+ module M3d
8
+ # A {Converter} implementation that generates CSAND output, and a document
9
+ # schema encapsulation of the document for validation
10
+ class HtmlConvert < IsoDoc::HtmlConvert
11
+ def add_image(filenames)
12
+ filenames.each do |filename|
13
+ #system "cp #{html_doc_path(filename)} #{filename}"
14
+ FileUtils.cp html_doc_path(filename), filename
15
+ @files_to_delete << filename
16
+ end
17
+ end
18
+
19
+ def initialize(options)
20
+ @libdir = File.dirname(__FILE__)
21
+ super
22
+ add_image(%w(logo.jpg m3-logo.png))
23
+ end
24
+
25
+ def default_fonts(options)
26
+ {
27
+ bodyfont: (options[:script] == "Hans" ? '"SimSun",serif' : '"Overpass",sans-serif'),
28
+ headerfont: (options[:script] == "Hans" ? '"SimHei",sans-serif' : '"Overpass",sans-serif'),
29
+ monospacefont: '"Space Mono",monospace'
30
+ }
31
+ end
32
+
33
+ def default_file_locations(_options)
34
+ {
35
+ htmlstylesheet: html_doc_path("htmlstyle.scss"),
36
+ htmlcoverpage: html_doc_path("html_m3d_titlepage.html"),
37
+ htmlintropage: html_doc_path("html_m3d_intro.html"),
38
+ scripts: html_doc_path("scripts.html"),
39
+ }
40
+ end
41
+
42
+ def metadata_init(lang, script, labels)
43
+ @meta = Metadata.new(lang, script, labels)
44
+ end
45
+
46
+ def colophon(body, docxml)
47
+ body.div **{ class: "colophon" } do |div|
48
+ div << <<~"COLOPHON"
49
+ <p>As with all M3AAWG documents that we publish, please check the M3AAWG website
50
+ (<a href="http://www.m3aawg.org">www.m3aawg.org</a>) for updates to this paper.</p>
51
+ <p>&copy; 2017 copyright by the Messaging, Malware and Mobile Anti-Abuse Working Group (M3AAWG)</p>
52
+ COLOPHON
53
+ end
54
+ end
55
+
56
+ def html_head()
57
+ <<~HEAD.freeze
58
+ <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
59
+
60
+ <!--TOC script import-->
61
+ <script type="text/javascript" src="https://cdn.rawgit.com/jgallen23/toc/0.3.2/dist/toc.min.js"></script>
62
+
63
+ <!--Google fonts-->
64
+ <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i|Space+Mono:400,700" rel="stylesheet">
65
+ <link href="https://fonts.googleapis.com/css?family=Overpass:300,300i,600,900" rel="stylesheet">
66
+ <!--Font awesome import for the link icon-->
67
+ <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/solid.css" integrity="sha384-v2Tw72dyUXeU3y4aM2Y0tBJQkGfplr39mxZqlTBDUZAb9BGoC40+rdFCG0m10lXk" crossorigin="anonymous">
68
+ <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/fontawesome.css" integrity="sha384-q3jl8XQu1OpdLgGFvNRnPdj5VIlCvgsDQTQB6owSOHWlAurxul7f+JpUOVdAiJ5P" crossorigin="anonymous">
69
+ <style class="anchorjs"></style>
70
+ HEAD
71
+ end
72
+
73
+ def make_body(xml, docxml)
74
+ body_attr = { lang: "EN-US", link: "blue", vlink: "#954F72", "xml:lang": "EN-US", class: "container" }
75
+ xml.body **body_attr do |body|
76
+ make_body1(body, docxml)
77
+ make_body2(body, docxml)
78
+ make_body3(body, docxml)
79
+ colophon(body, docxml)
80
+ end
81
+ end
82
+
83
+ def html_toc(docxml)
84
+ docxml
85
+ end
86
+
87
+ def annex_name(annex, name, div)
88
+ div.h1 **{ class: "Annex" } do |t|
89
+ t << "#{get_anchors[annex['id']][:label]} "
90
+ t << "<b>#{name.text}</b>"
91
+ end
92
+ end
93
+
94
+ def annex_name_lbl(clause, num)
95
+ obl = l10n("(#{@inform_annex_lbl})")
96
+ obl = l10n("(#{@norm_annex_lbl})") if clause["obligation"] == "normative"
97
+ l10n("<b>#{@annex_lbl} #{num}</b> #{obl}")
98
+ end
99
+
100
+ def pre_parse(node, out)
101
+ out.pre node.text # content.gsub(/</, "&lt;").gsub(/>/, "&gt;")
102
+ end
103
+
104
+ def term_defs_boilerplate(div, source, term, preface)
105
+ if source.empty? && term.nil?
106
+ div << @no_terms_boilerplate
107
+ else
108
+ div << term_defs_boilerplate_cont(source, term)
109
+ end
110
+ end
111
+
112
+ def i18n_init(lang, script)
113
+ super
114
+ @annex_lbl = "Appendix"
115
+ end
116
+
117
+ def error_parse(node, out)
118
+ # catch elements not defined in ISO
119
+ case node.name
120
+ when "pre"
121
+ pre_parse(node, out)
122
+ when "keyword"
123
+ out.span node.text, **{ class: "keyword" }
124
+ else
125
+ super
126
+ end
127
+ end
128
+
129
+ def fileloc(loc)
130
+ File.join(File.dirname(__FILE__), loc)
131
+ end
132
+
133
+ def cleanup(docxml)
134
+ super
135
+ term_cleanup(docxml)
136
+ end
137
+
138
+ def term_cleanup(docxml)
139
+ docxml.xpath("//p[@class = 'Terms']").each do |d|
140
+ h2 = d.at("./preceding-sibling::*[@class = 'TermNum'][1]")
141
+ h2.add_child("&nbsp;")
142
+ h2.add_child(d.remove)
143
+ end
144
+ docxml
145
+ end
146
+
147
+ def info(isoxml, out)
148
+ @meta.url isoxml, out
149
+ super
150
+ end
151
+ end
152
+ end
153
+ end
154
+
@@ -0,0 +1,68 @@
1
+ module IsoDoc
2
+ module M3d
3
+ # A {Converter} implementation that generates CSAND output, and a document
4
+ # schema encapsulation of the document for validation
5
+ class HtmlConvert < IsoDoc::HtmlConvert
6
+ def annex_name(annex, name, div)
7
+ div.h1 **{ class: "Annex" } do |t|
8
+ t << "#{get_anchors[annex['id']][:label]} "
9
+ t << "<b>#{name.text}</b>"
10
+ end
11
+ end
12
+
13
+ def annex_name_lbl(clause, num)
14
+ obl = l10n("(#{@inform_annex_lbl})")
15
+ obl = l10n("(#{@norm_annex_lbl})") if clause["obligation"] == "normative"
16
+ l10n("<b>#{@annex_lbl} #{num}</b> #{obl}")
17
+ end
18
+
19
+ def pre_parse(node, out)
20
+ out.pre node.text # content.gsub(/</, "&lt;").gsub(/>/, "&gt;")
21
+ end
22
+
23
+ def term_defs_boilerplate(div, source, term, preface)
24
+ if source.empty? && term.nil?
25
+ div << @no_terms_boilerplate
26
+ else
27
+ div << term_defs_boilerplate_cont(source, term)
28
+ end
29
+ end
30
+
31
+ def i18n_init(lang, script)
32
+ super
33
+ @annex_lbl = "Appendix"
34
+ end
35
+
36
+ def error_parse(node, out)
37
+ # catch elements not defined in ISO
38
+ case node.name
39
+ when "pre"
40
+ pre_parse(node, out)
41
+ when "keyword"
42
+ out.span node.text, **{ class: "keyword" }
43
+ else
44
+ super
45
+ end
46
+ end
47
+
48
+ def fileloc(loc)
49
+ File.join(File.dirname(__FILE__), loc)
50
+ end
51
+
52
+ def cleanup(docxml)
53
+ super
54
+ term_cleanup(docxml)
55
+ end
56
+
57
+ def term_cleanup(docxml)
58
+ docxml.xpath("//p[@class = 'Terms']").each do |d|
59
+ h2 = d.at("./preceding-sibling::*[@class = 'TermNum'][1]")
60
+ h2.add_child("&nbsp;")
61
+ h2.add_child(d.remove)
62
+ end
63
+ docxml
64
+ end
65
+ end
66
+ end
67
+ end
68
+
@@ -0,0 +1,105 @@
1
+ require "isodoc"
2
+ require_relative "m3wordrender"
3
+ require "fileutils"
4
+
5
+ module IsoDoc
6
+ module M3d
7
+ # A {Converter} implementation that generates GB output, and a document
8
+ # schema encapsulation of the document for validation
9
+
10
+ class WordConvert < IsoDoc::WordConvert
11
+ def initialize(options)
12
+ @libdir = File.dirname(__FILE__)
13
+ super
14
+ #system "cp #{html_doc_path('logo.jpg')} logo.jpg"
15
+ FileUtils.cp html_doc_path("logo.jpg"), "logo.jpg"
16
+ end
17
+
18
+ def default_fonts(options)
19
+ {
20
+ bodyfont: (options[:script] == "Hans" ? '"SimSun",serif' : '"Garamond",serif'),
21
+ headerfont: (options[:script] == "Hans" ? '"SimHei",sans-serif' : '"Garamond",serif'),
22
+ monospacefont: '"Courier New",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_m3d_titlepage.html"),
30
+ htmlintropage: html_doc_path("html_m3d_intro.html"),
31
+ scripts: html_doc_path("scripts.html"),
32
+ wordstylesheet: html_doc_path("wordstyle.scss"),
33
+ standardstylesheet: html_doc_path("m3d.scss"),
34
+ header: html_doc_path("header.html"),
35
+ wordintropage: html_doc_path("word_m3d_intro.html"),
36
+ ulstyle: "l3",
37
+ olstyle: "l2",
38
+ }
39
+ end
40
+
41
+ def metadata_init(lang, script, labels)
42
+ @meta = Metadata.new(lang, script, labels)
43
+ end
44
+
45
+ def colophon(body, docxml)
46
+ section_break(body)
47
+ body.div **{ class: "colophon" } do |div|
48
+ end
49
+ end
50
+
51
+ def make_body(xml, docxml)
52
+ body_attr = { lang: "EN-US", link: "blue", vlink: "#954F72" }
53
+ xml.body **body_attr do |body|
54
+ make_body2(body, docxml)
55
+ make_body3(body, docxml)
56
+ colophon(body, docxml)
57
+ end
58
+ end
59
+
60
+ def make_body2(body, docxml)
61
+ body.div **{ class: "WordSection2" } do |div2|
62
+ info docxml, div2
63
+ div2.p { |p| p << "&nbsp;" } # placeholder
64
+ end
65
+ # body.br **{ clear: "all", style: "page-break-before:auto;mso-break-type:section-break;" }
66
+ # apparently that was not intended: enforce page break between ToC and body
67
+ section_break(body)
68
+ end
69
+
70
+ def title(isoxml, _out)
71
+ main = isoxml&.at(ns("//title[@language='en']"))&.text
72
+ set_metadata(:doctitle, main)
73
+ end
74
+
75
+ def generate_header(filename, dir)
76
+ return unless @header
77
+ template = Liquid::Template.parse(File.read(@header, encoding: "UTF-8"))
78
+ meta = @meta.get
79
+ meta[:filename] = filename
80
+ params = meta.map { |k, v| [k.to_s, v] }.to_h
81
+ File.open("header.html", "w") { |f| f.write(template.render(params)) }
82
+ @files_to_delete << "header.html"
83
+ "header.html"
84
+ end
85
+
86
+ def header_strip(h)
87
+ h = h.to_s.gsub(%r{<br/>}, " ").sub(/<\/?h[12][^>]*>/, "")
88
+ h1 = to_xhtml_fragment(h.dup)
89
+ h1.traverse do |x|
90
+ x.replace(" ") if x.name == "span" &&
91
+ /mso-tab-count/.match(x["style"])
92
+ x.remove if x.name == "span" && x["class"] == "MsoCommentReference"
93
+ x.remove if x.name == "a" && x["epub:type"] == "footnote"
94
+ x.replace(x.children) if x.name == "a"
95
+ end
96
+ from_xhtml(h1)
97
+ end
98
+
99
+ def info(isoxml, out)
100
+ @meta.url isoxml, out
101
+ super
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,68 @@
1
+ module IsoDoc
2
+ module M3d
3
+ # A {Converter} implementation that generates CSAND output, and a document
4
+ # schema encapsulation of the document for validation
5
+ class WordConvert < IsoDoc::WordConvert
6
+ def annex_name(annex, name, div)
7
+ div.h1 **{ class: "Annex" } do |t|
8
+ t << "#{get_anchors[annex['id']][:label]} "
9
+ t << "<b>#{name.text}</b>"
10
+ end
11
+ end
12
+
13
+ def annex_name_lbl(clause, num)
14
+ obl = l10n("(#{@inform_annex_lbl})")
15
+ obl = l10n("(#{@norm_annex_lbl})") if clause["obligation"] == "normative"
16
+ l10n("<b>#{@annex_lbl} #{num}</b> #{obl}")
17
+ end
18
+
19
+ def pre_parse(node, out)
20
+ out.pre node.text # content.gsub(/</, "&lt;").gsub(/>/, "&gt;")
21
+ end
22
+
23
+ def term_defs_boilerplate(div, source, term, preface)
24
+ if source.empty? && term.nil?
25
+ div << @no_terms_boilerplate
26
+ else
27
+ div << term_defs_boilerplate_cont(source, term)
28
+ end
29
+ end
30
+
31
+ def i18n_init(lang, script)
32
+ super
33
+ @annex_lbl = "Appendix"
34
+ end
35
+
36
+ def error_parse(node, out)
37
+ # catch elements not defined in ISO
38
+ case node.name
39
+ when "pre"
40
+ pre_parse(node, out)
41
+ when "keyword"
42
+ out.span node.text, **{ class: "keyword" }
43
+ else
44
+ super
45
+ end
46
+ end
47
+
48
+ def fileloc(loc)
49
+ File.join(File.dirname(__FILE__), loc)
50
+ end
51
+
52
+ def cleanup(docxml)
53
+ super
54
+ term_cleanup(docxml)
55
+ end
56
+
57
+ def term_cleanup(docxml)
58
+ docxml.xpath("//p[@class = 'Terms']").each do |d|
59
+ h2 = d.at("./preceding-sibling::*[@class = 'TermNum'][1]")
60
+ h2.add_child("&nbsp;")
61
+ h2.add_child(d.remove)
62
+ end
63
+ docxml
64
+ end
65
+ end
66
+ end
67
+ end
68
+
@@ -0,0 +1,87 @@
1
+ require "isodoc"
2
+
3
+ module IsoDoc
4
+ module M3d
5
+ # A {Converter} implementation that generates CSAND output, and a document
6
+ # schema encapsulation of the document for validation
7
+ class Metadata < IsoDoc::Metadata
8
+ def initialize(lang, script, labels)
9
+ super
10
+ set(:status, "XXX")
11
+ end
12
+
13
+ def title(isoxml, _out)
14
+ main = isoxml&.at(ns("//title[@language='en']"))&.text
15
+ set(:doctitle, main)
16
+ end
17
+
18
+ def subtitle(_isoxml, _out)
19
+ nil
20
+ end
21
+
22
+ def author(isoxml, _out)
23
+ set(:tc, "XXXX")
24
+ tc = isoxml.at(ns("//editorialgroup/technical-committee"))
25
+ set(:tc, tc.text) if tc
26
+ end
27
+
28
+ def docid(isoxml, _out)
29
+ docnumber = isoxml.at(ns("//bibdata/docidentifier"))
30
+ docstatus = isoxml.at(ns("//bibdata/status"))
31
+ dn = docnumber&.text
32
+ if docstatus
33
+ set(:status, status_print(docstatus.text))
34
+ abbr = status_abbr(docstatus.text)
35
+ dn = "#{dn}(#{abbr})" unless abbr.empty?
36
+ end
37
+ set(:docnumber, dn)
38
+ end
39
+
40
+ def status_print(status)
41
+ status.split(/-/).map{ |w| w.capitalize }.join(" ")
42
+ end
43
+
44
+ def status_abbr(status)
45
+ case status
46
+ when "working-draft" then "wd"
47
+ when "committee-draft" then "cd"
48
+ when "draft-standard" then "d"
49
+ else
50
+ ""
51
+ end
52
+ end
53
+
54
+ def version(isoxml, _out)
55
+ super
56
+ revdate = get[:revdate]
57
+ set(:revdate_monthyear, monthyr(revdate))
58
+ end
59
+
60
+ MONTHS = {
61
+ "01": "January",
62
+ "02": "February",
63
+ "03": "March",
64
+ "04": "April",
65
+ "05": "May",
66
+ "06": "June",
67
+ "07": "July",
68
+ "08": "August",
69
+ "09": "September",
70
+ "10": "October",
71
+ "11": "November",
72
+ "12": "December",
73
+ }.freeze
74
+
75
+ def monthyr(isodate)
76
+ m = /(?<yr>\d\d\d\d)-(?<mo>\d\d)/.match isodate
77
+ return isodate unless m && m[:yr] && m[:mo]
78
+ return "#{MONTHS[m[:mo].to_sym]} #{m[:yr]}"
79
+ end
80
+
81
+ def url(isoxml, _out)
82
+ url = isoxml.at(ns("//bibdata/source"))
83
+ set(:url, url.text) if url
84
+ end
85
+ end
86
+ end
87
+ end