metanorma-mpfa 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/macos.yml +39 -0
- data/.github/workflows/ubuntu.yml +53 -0
- data/.github/workflows/windows.yml +41 -0
- data/.gitignore +1 -0
- data/.hound.yml +3 -0
- data/.rubocop.yml +10 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +11 -0
- data/LICENSE +25 -0
- data/README.adoc +79 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/manifest +146 -0
- data/bin/rspec +18 -0
- data/bin/setup +8 -0
- data/lib/asciidoctor/mpfa.rb +6 -0
- data/lib/asciidoctor/mpfa/basicdoc.rng +1059 -0
- data/lib/asciidoctor/mpfa/biblio.rng +1237 -0
- data/lib/asciidoctor/mpfa/converter.rb +113 -0
- data/lib/asciidoctor/mpfa/isodoc.rng +1504 -0
- data/lib/asciidoctor/mpfa/mpfd.rng +79 -0
- data/lib/asciidoctor/mpfa/reqt.rng +194 -0
- data/lib/asciidoctor/mpfa/section.rb +61 -0
- data/lib/asciidoctor/mpfa/validate.rb +30 -0
- data/lib/isodoc/mpfa/base_convert.rb +128 -0
- data/lib/isodoc/mpfa/html/header.html +242 -0
- data/lib/isodoc/mpfa/html/html_rsd_intro.html +8 -0
- data/lib/isodoc/mpfa/html/html_rsd_titlepage.html +58 -0
- data/lib/isodoc/mpfa/html/htmlstyle.scss +932 -0
- data/lib/isodoc/mpfa/html/logo.jpg +0 -0
- data/lib/isodoc/mpfa/html/logo.svg +1 -0
- data/lib/isodoc/mpfa/html/mpfa-logo-no-text@4x.png +0 -0
- data/lib/isodoc/mpfa/html/mpfa-logo@4x.png +0 -0
- data/lib/isodoc/mpfa/html/rsd.scss +763 -0
- data/lib/isodoc/mpfa/html/scripts.html +80 -0
- data/lib/isodoc/mpfa/html/word_rsd_intro.html +3 -0
- data/lib/isodoc/mpfa/html/word_rsd_titlepage.html +42 -0
- data/lib/isodoc/mpfa/html/wordstyle.scss +1157 -0
- data/lib/isodoc/mpfa/html_convert.rb +63 -0
- data/lib/isodoc/mpfa/i18n-en.yaml +2 -0
- data/lib/isodoc/mpfa/i18n-zh-Hans.yaml +2 -0
- data/lib/isodoc/mpfa/metadata.rb +74 -0
- data/lib/isodoc/mpfa/presentation_xml_convert.rb +10 -0
- data/lib/isodoc/mpfa/word_convert.rb +62 -0
- data/lib/isodoc/mpfa/xref.rb +102 -0
- data/lib/metanorma-mpfa.rb +11 -0
- data/lib/metanorma/mpfa.rb +7 -0
- data/lib/metanorma/mpfa/processor.rb +49 -0
- data/lib/metanorma/mpfa/version.rb +5 -0
- data/metanorma-mpfd.gemspec +46 -0
- metadata +280 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
require_relative "base_convert"
|
2
|
+
require "isodoc"
|
3
|
+
|
4
|
+
module IsoDoc
|
5
|
+
module MPFA
|
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 initialize(options)
|
12
|
+
@libdir = File.dirname(__FILE__)
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
include BaseConvert
|
17
|
+
|
18
|
+
def default_fonts(options)
|
19
|
+
{
|
20
|
+
bodyfont: (options[:script] == "Hans" ? '"SimSun",serif' : '"Titillium Web",sans-serif'),
|
21
|
+
headerfont: (options[:script] == "Hans" ? '"SimHei",sans-serif' : '"Titillium Web",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 googlefonts
|
36
|
+
<<~HEAD.freeze
|
37
|
+
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i|Space+Mono:400,700" rel="stylesheet">
|
38
|
+
<link href="https://fonts.googleapis.com/css?family=Overpass:300,300i,600,900" rel="stylesheet">
|
39
|
+
<link href="https://fonts.googleapis.com/css?family=Titillium+Web:400,400i,700,700i" rel="stylesheet">
|
40
|
+
HEAD
|
41
|
+
end
|
42
|
+
|
43
|
+
def make_body(xml, docxml)
|
44
|
+
body_attr = { lang: "EN-US", link: "blue", vlink: "#954F72", "xml:lang": "EN-US", class: "container" }
|
45
|
+
xml.body **body_attr do |body|
|
46
|
+
make_body1(body, docxml)
|
47
|
+
make_body2(body, docxml)
|
48
|
+
make_body3(body, docxml)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def make_body3(body, docxml)
|
53
|
+
body.div **{ class: "main-section" } do |div3|
|
54
|
+
preface docxml, div3
|
55
|
+
middle docxml, div3
|
56
|
+
footnotes div3
|
57
|
+
comments div3
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require "isodoc"
|
2
|
+
require "twitter_cldr"
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
module IsoDoc
|
6
|
+
module MPFA
|
7
|
+
|
8
|
+
class Metadata < IsoDoc::Metadata
|
9
|
+
def initialize(lang, script, labels)
|
10
|
+
super
|
11
|
+
here = File.dirname(__FILE__)
|
12
|
+
set(:logo, File.expand_path(File.join(here, "html", "mpfa-logo-no-text@4x.png")))
|
13
|
+
end
|
14
|
+
|
15
|
+
def title(isoxml, _out)
|
16
|
+
main = isoxml&.at(ns("//bibdata/title[@language='en']"))&.text
|
17
|
+
set(:doctitle, main)
|
18
|
+
end
|
19
|
+
|
20
|
+
def subtitle(_isoxml, _out)
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def author(isoxml, _out)
|
25
|
+
publisher = isoxml.at(ns("//bibdata/contributor/organization/name"))
|
26
|
+
set(:publisher, publisher.text) if publisher
|
27
|
+
end
|
28
|
+
|
29
|
+
def docid(isoxml, _out)
|
30
|
+
docnumber = isoxml.at(ns("//bibdata/docidentifier"))
|
31
|
+
set(:docnumber, docnumber&.text)
|
32
|
+
end
|
33
|
+
|
34
|
+
def doctype(isoxml, _out)
|
35
|
+
b = isoxml&.at(ns("//bibdata/ext/doctype"))&.text || return
|
36
|
+
return unless b
|
37
|
+
t = b.split(/[- ]/).
|
38
|
+
map{ |w| w.capitalize unless w == "MPF" }.join(" ")
|
39
|
+
set(:doctype, t)
|
40
|
+
end
|
41
|
+
|
42
|
+
def stage_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
|
+
edition = isoxml.at(ns("//version/edition"))
|
55
|
+
if edition
|
56
|
+
set(
|
57
|
+
:edition,
|
58
|
+
edition.text.to_i.localize.
|
59
|
+
to_rbnf_s("SpelloutRules", "spellout-ordinal").
|
60
|
+
split(/(\W)/).map(&:capitalize).join
|
61
|
+
)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def monthyr(isodate)
|
66
|
+
date = DateTime.parse(isodate)
|
67
|
+
date.strftime('%-d %B %Y') #=> "Sun 04 Feb 2001"
|
68
|
+
rescue
|
69
|
+
# invalid dates get thrown
|
70
|
+
isodate
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require_relative "base_convert"
|
2
|
+
require "isodoc"
|
3
|
+
|
4
|
+
module IsoDoc
|
5
|
+
module MPFA
|
6
|
+
# A {Converter} implementation that generates Word output, and a document
|
7
|
+
# schema encapsulation of the document for validation
|
8
|
+
class WordConvert < IsoDoc::WordConvert
|
9
|
+
def initialize(options)
|
10
|
+
@libdir = File.dirname(__FILE__)
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
include BaseConvert
|
15
|
+
|
16
|
+
def default_fonts(options)
|
17
|
+
{
|
18
|
+
bodyfont: (options[:script] == "Hans" ? '"SimSun",serif' : '"Arial",sans-serif'),
|
19
|
+
headerfont: (options[:script] == "Hans" ? '"SimHei",sans-serif' : '"Arial",sans-serif'),
|
20
|
+
monospacefont: '"Courier New",monospace'
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def default_file_locations(options)
|
25
|
+
{
|
26
|
+
htmlstylesheet: html_doc_path("htmlstyle.scss"),
|
27
|
+
htmlcoverpage: html_doc_path("html_rsd_titlepage.html"),
|
28
|
+
htmlintropage: html_doc_path("html_rsd_intro.html"),
|
29
|
+
scripts: html_doc_path("scripts.html"),
|
30
|
+
wordstylesheet: html_doc_path("wordstyle.scss"),
|
31
|
+
standardstylesheet: html_doc_path("rsd.scss"),
|
32
|
+
header: html_doc_path("header.html"),
|
33
|
+
wordcoverpage: html_doc_path("word_rsd_titlepage.html"),
|
34
|
+
wordintropage: html_doc_path("word_rsd_intro.html"),
|
35
|
+
ulstyle: "l3",
|
36
|
+
olstyle: "l2",
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def make_body(xml, docxml)
|
41
|
+
body_attr = { lang: "EN-US", link: "blue", vlink: "#954F72" }
|
42
|
+
xml.body **body_attr do |body|
|
43
|
+
make_body1(body, docxml)
|
44
|
+
make_body2(body, docxml)
|
45
|
+
make_body3(body, docxml)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def make_body2(body, docxml)
|
50
|
+
body.div **{ class: "WordSection2" } do |div2|
|
51
|
+
info docxml, div2
|
52
|
+
abstract docxml, div2
|
53
|
+
foreword docxml, div2
|
54
|
+
introduction docxml, div2
|
55
|
+
terms_defs docxml, div2, 0
|
56
|
+
div2.p { |p| p << " " } # placeholder
|
57
|
+
end
|
58
|
+
section_break(body)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module IsoDoc
|
2
|
+
module MPFA
|
3
|
+
class Xref < IsoDoc::Xref
|
4
|
+
FRONT_CLAUSE = "//*[parent::preface]".freeze
|
5
|
+
|
6
|
+
def initial_anchor_names(d)
|
7
|
+
d.xpath(ns(self.class::FRONT_CLAUSE)).each do |c|
|
8
|
+
preface_names(c)
|
9
|
+
sequential_asset_names(c)
|
10
|
+
end
|
11
|
+
middle_section_asset_names(d)
|
12
|
+
clause_names(d, 0)
|
13
|
+
termnote_anchor_names(d)
|
14
|
+
termexample_anchor_names(d)
|
15
|
+
end
|
16
|
+
|
17
|
+
def annex_name_lbl(clause, num)
|
18
|
+
l10n("<b>#{@labels['annex']} #{num}</b>")
|
19
|
+
end
|
20
|
+
|
21
|
+
def clause_names(docxml, sect_num)
|
22
|
+
q = "//clause[parent::sections]"
|
23
|
+
@topnum = nil
|
24
|
+
lvl = 0
|
25
|
+
docxml.xpath(ns(q)).each do |c|
|
26
|
+
container_names(c, 0)
|
27
|
+
sect_num, lvl = sect_names(c, nil, sect_num, 0, lvl)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def container_names(clause, lvl)
|
32
|
+
if clause["container"]
|
33
|
+
@anchors[clause["id"]] =
|
34
|
+
{ label: nil, xref: clause.at(ns("./title"))&.text, level: lvl+1 }
|
35
|
+
end
|
36
|
+
clause.xpath(ns("./clause | ./term | ./terms | "\
|
37
|
+
"./definitions")).each do |c|
|
38
|
+
container_names(c, clause["container"] ? lvl+1 : lvl)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def sect_names(clause, num, i, lvl, prev_lvl)
|
43
|
+
return i if clause.nil?
|
44
|
+
curr = i
|
45
|
+
if !clause["container"]
|
46
|
+
retlvl = lvl
|
47
|
+
i+=1
|
48
|
+
curr = i
|
49
|
+
name = num.nil? ? i.to_s : "#{num}.#{i}"
|
50
|
+
@anchors[clause["id"]] = { label: name, level: lvl + 1,
|
51
|
+
xref: l10n("#{@labels['clause']} #{name}") }
|
52
|
+
end
|
53
|
+
prev = lvl
|
54
|
+
j = 0
|
55
|
+
clause.xpath(ns("./clause | ./term | ./terms | "\
|
56
|
+
"./definitions")).each do |c|
|
57
|
+
if clause["container"]
|
58
|
+
i, lvl = sect_names(c, num, i, lvl, lvl)
|
59
|
+
else
|
60
|
+
j, prev = sect_names(c, name, j, lvl+1, prev)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
i = j if j >0
|
64
|
+
i = curr if lvl < prev
|
65
|
+
[i, prev]
|
66
|
+
end
|
67
|
+
|
68
|
+
def annex_naming(c, num, lvl, i)
|
69
|
+
if c["guidance"] then annex_names1(c, "#{num}E", lvl + 1)
|
70
|
+
else
|
71
|
+
i+= 1 unless c["container"]
|
72
|
+
annex_names1(c, "#{num}.#{i}", lvl + 1)
|
73
|
+
end
|
74
|
+
i
|
75
|
+
end
|
76
|
+
|
77
|
+
def annex_names(clause, num)
|
78
|
+
@anchors[clause["id"]] = { label: annex_name_lbl(clause, num),
|
79
|
+
xref: "#{@labels['annex']} #{num}", level: 1 }
|
80
|
+
if a = single_annex_special_section(clause)
|
81
|
+
annex_names1(a, "#{num}", 1)
|
82
|
+
else
|
83
|
+
i = 0
|
84
|
+
clause.xpath(ns("./clause | ./references")).each do |c|
|
85
|
+
container_names(c, 0)
|
86
|
+
i = annex_naming(c, num, 1, i)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
hierarchical_asset_names(clause, num)
|
90
|
+
end
|
91
|
+
|
92
|
+
def annex_names1(clause, num, level)
|
93
|
+
clause["container"] or @anchors[clause["id"]] =
|
94
|
+
{ label: num, xref: "#{@labels['annex']} #{num}", level: level }
|
95
|
+
i = 0
|
96
|
+
clause.xpath(ns("./clause | ./references")).each do |c|
|
97
|
+
i = annex_naming(c, num, level, i)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "asciidoctor" unless defined? Asciidoctor::Converter
|
2
|
+
require_relative "asciidoctor/mpfa/converter"
|
3
|
+
require_relative "isodoc/mpfa/html_convert"
|
4
|
+
require_relative "isodoc/mpfa/word_convert"
|
5
|
+
require_relative "isodoc/mpfa/presentation_xml_convert"
|
6
|
+
require_relative "metanorma/mpfa/version"
|
7
|
+
|
8
|
+
if defined? Metanorma
|
9
|
+
require_relative "metanorma/mpfa"
|
10
|
+
Metanorma::Registry.instance.register(Metanorma::MPFA::Processor)
|
11
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "metanorma/processor"
|
2
|
+
|
3
|
+
module Metanorma
|
4
|
+
module MPFA
|
5
|
+
def self.fonts_used
|
6
|
+
{
|
7
|
+
html: ["Titillium Web", "Space Mono"],
|
8
|
+
doc: ["Arial", "Courier New"],
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
class Processor < Metanorma::Processor
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@short = [:mpfd, :mpfa]
|
16
|
+
@input_format = :asciidoc
|
17
|
+
@asciidoctor_backend = :mpfa
|
18
|
+
end
|
19
|
+
|
20
|
+
def output_formats
|
21
|
+
super.merge(
|
22
|
+
html: "html",
|
23
|
+
doc: "doc"
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def version
|
28
|
+
"Metanorma::MPFA #{Metanorma::MPFA::VERSION}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def input_to_isodoc(file, filename)
|
32
|
+
Metanorma::Input::Asciidoc.new.process(file, filename, @asciidoctor_backend)
|
33
|
+
end
|
34
|
+
|
35
|
+
def output(isodoc_node, inname, outname, format, options={})
|
36
|
+
case format
|
37
|
+
when :html
|
38
|
+
IsoDoc::MPFA::HtmlConvert.new(options).convert(inname, isodoc_node, nil, outname)
|
39
|
+
when :doc
|
40
|
+
IsoDoc::MPFA::WordConvert.new(options).convert(inname, isodoc_node, nil, outname)
|
41
|
+
when :presentation
|
42
|
+
IsoDoc::MPFA::PresentationXMLConvert.new(options).convert(inname, isodoc_node, nil, outname)
|
43
|
+
else
|
44
|
+
super
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "metanorma/mpfa/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "metanorma-mpfa"
|
7
|
+
spec.version = Metanorma::MPFA::VERSION
|
8
|
+
spec.authors = ["Ribose Inc."]
|
9
|
+
spec.email = ["open.source@ribose.com"]
|
10
|
+
|
11
|
+
spec.summary = "metanorma-mpfa lets you write MPFA documents in AsciiDoc."
|
12
|
+
spec.description = <<~DESCRIPTION
|
13
|
+
metanorma-mpfa lets you write MPFA documents in AsciiDoc syntax.
|
14
|
+
|
15
|
+
This gem is in active development.
|
16
|
+
|
17
|
+
Formerly known as metanorma-mpfd
|
18
|
+
DESCRIPTION
|
19
|
+
|
20
|
+
spec.homepage = "https://github.com/metanorma/metanorma-mpfa"
|
21
|
+
spec.license = "BSD-2-Clause"
|
22
|
+
|
23
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
24
|
+
f.match(%r{^(test|spec|features)/})
|
25
|
+
end
|
26
|
+
spec.bindir = "exe"
|
27
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
|
+
spec.require_paths = ["lib"]
|
29
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
|
30
|
+
|
31
|
+
spec.add_dependency "htmlentities", "~> 4.3.4"
|
32
|
+
#spec.add_dependency "nokogiri"
|
33
|
+
spec.add_dependency "metanorma-standoc", "~> 1.4.0"
|
34
|
+
spec.add_dependency "isodoc", "~> 1.1.0"
|
35
|
+
spec.add_dependency "twitter_cldr"
|
36
|
+
|
37
|
+
spec.add_development_dependency "byebug", "~> 9.1"
|
38
|
+
spec.add_development_dependency "equivalent-xml", "~> 0.6"
|
39
|
+
spec.add_development_dependency "guard", "~> 2.14"
|
40
|
+
spec.add_development_dependency "guard-rspec", "~> 4.7"
|
41
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
42
|
+
spec.add_development_dependency "rspec", "~> 3.6"
|
43
|
+
spec.add_development_dependency "rubocop", "= 0.54.0"
|
44
|
+
spec.add_development_dependency "simplecov", "~> 0.15"
|
45
|
+
spec.add_development_dependency "timecop", "~> 0.9"
|
46
|
+
end
|