metanorma-m3d 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.travis.yml +15 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/LICENSE +25 -0
- data/README.adoc +170 -0
- data/Rakefile +6 -0
- data/asciidoctor-m3d.gemspec.old +54 -0
- data/bin/console +14 -0
- data/bin/rspec +18 -0
- data/bin/setup +8 -0
- data/lib/asciidoctor-m3d.rb +10 -0
- data/lib/asciidoctor/m3d.rb +7 -0
- data/lib/asciidoctor/m3d/biblio.rng +836 -0
- data/lib/asciidoctor/m3d/converter.rb +188 -0
- data/lib/asciidoctor/m3d/html/dots-w@2x.png +0 -0
- data/lib/asciidoctor/m3d/html/dots@2x.png +0 -0
- data/lib/asciidoctor/m3d/html/header.html +184 -0
- data/lib/asciidoctor/m3d/html/html_m3d_intro.html +8 -0
- data/lib/asciidoctor/m3d/html/html_m3d_titlepage.html +95 -0
- data/lib/asciidoctor/m3d/html/htmlstyle.scss +797 -0
- data/lib/asciidoctor/m3d/html/m3d.scss +549 -0
- data/lib/asciidoctor/m3d/html/scripts.html +68 -0
- data/lib/asciidoctor/m3d/isodoc.rng +1059 -0
- data/lib/asciidoctor/m3d/isostandard.rng +1001 -0
- data/lib/asciidoctor/m3d/m3d.rng +154 -0
- data/lib/asciidoctor/m3d/version.rb +5 -0
- data/lib/isodoc/m3d/html/dots-w@2x.png +0 -0
- data/lib/isodoc/m3d/html/dots@2x.png +0 -0
- data/lib/isodoc/m3d/html/header.html +219 -0
- data/lib/isodoc/m3d/html/html_m3d_intro.html +14 -0
- data/lib/isodoc/m3d/html/html_m3d_titlepage.html +102 -0
- data/lib/isodoc/m3d/html/htmlstyle.scss +1001 -0
- data/lib/isodoc/m3d/html/logo.jpg +0 -0
- data/lib/isodoc/m3d/html/m3-logo.png +0 -0
- data/lib/isodoc/m3d/html/m3d.scss +697 -0
- data/lib/isodoc/m3d/html/scripts.html +82 -0
- data/lib/isodoc/m3d/html/word_m3d_intro.html +10 -0
- data/lib/isodoc/m3d/html/word_m3d_titlepage.html +58 -0
- data/lib/isodoc/m3d/html/wordstyle.scss +1003 -0
- data/lib/isodoc/m3d/m3dhtmlconvert.rb +154 -0
- data/lib/isodoc/m3d/m3dhtmlrender.rb +68 -0
- data/lib/isodoc/m3d/m3dwordconvert.rb +105 -0
- data/lib/isodoc/m3d/m3wordrender.rb +68 -0
- data/lib/isodoc/m3d/metadata.rb +87 -0
- data/lib/metanorma/m3d.rb +7 -0
- data/lib/metanorma/m3d/processor.rb +41 -0
- data/metanorma-m3d.gemspec +55 -0
- 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>© 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(/</, "<").gsub(/>/, ">")
|
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(" ")
|
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(/</, "<").gsub(/>/, ">")
|
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(" ")
|
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 << " " } # 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(/</, "<").gsub(/>/, ">")
|
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(" ")
|
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
|