metanorma-mpfa 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/macos.yml +39 -0
  3. data/.github/workflows/ubuntu.yml +53 -0
  4. data/.github/workflows/windows.yml +41 -0
  5. data/.gitignore +1 -0
  6. data/.hound.yml +3 -0
  7. data/.rubocop.yml +10 -0
  8. data/CODE_OF_CONDUCT.md +74 -0
  9. data/Gemfile +11 -0
  10. data/LICENSE +25 -0
  11. data/README.adoc +79 -0
  12. data/Rakefile +6 -0
  13. data/bin/console +14 -0
  14. data/bin/manifest +146 -0
  15. data/bin/rspec +18 -0
  16. data/bin/setup +8 -0
  17. data/lib/asciidoctor/mpfa.rb +6 -0
  18. data/lib/asciidoctor/mpfa/basicdoc.rng +1059 -0
  19. data/lib/asciidoctor/mpfa/biblio.rng +1237 -0
  20. data/lib/asciidoctor/mpfa/converter.rb +113 -0
  21. data/lib/asciidoctor/mpfa/isodoc.rng +1504 -0
  22. data/lib/asciidoctor/mpfa/mpfd.rng +79 -0
  23. data/lib/asciidoctor/mpfa/reqt.rng +194 -0
  24. data/lib/asciidoctor/mpfa/section.rb +61 -0
  25. data/lib/asciidoctor/mpfa/validate.rb +30 -0
  26. data/lib/isodoc/mpfa/base_convert.rb +128 -0
  27. data/lib/isodoc/mpfa/html/header.html +242 -0
  28. data/lib/isodoc/mpfa/html/html_rsd_intro.html +8 -0
  29. data/lib/isodoc/mpfa/html/html_rsd_titlepage.html +58 -0
  30. data/lib/isodoc/mpfa/html/htmlstyle.scss +932 -0
  31. data/lib/isodoc/mpfa/html/logo.jpg +0 -0
  32. data/lib/isodoc/mpfa/html/logo.svg +1 -0
  33. data/lib/isodoc/mpfa/html/mpfa-logo-no-text@4x.png +0 -0
  34. data/lib/isodoc/mpfa/html/mpfa-logo@4x.png +0 -0
  35. data/lib/isodoc/mpfa/html/rsd.scss +763 -0
  36. data/lib/isodoc/mpfa/html/scripts.html +80 -0
  37. data/lib/isodoc/mpfa/html/word_rsd_intro.html +3 -0
  38. data/lib/isodoc/mpfa/html/word_rsd_titlepage.html +42 -0
  39. data/lib/isodoc/mpfa/html/wordstyle.scss +1157 -0
  40. data/lib/isodoc/mpfa/html_convert.rb +63 -0
  41. data/lib/isodoc/mpfa/i18n-en.yaml +2 -0
  42. data/lib/isodoc/mpfa/i18n-zh-Hans.yaml +2 -0
  43. data/lib/isodoc/mpfa/metadata.rb +74 -0
  44. data/lib/isodoc/mpfa/presentation_xml_convert.rb +10 -0
  45. data/lib/isodoc/mpfa/word_convert.rb +62 -0
  46. data/lib/isodoc/mpfa/xref.rb +102 -0
  47. data/lib/metanorma-mpfa.rb +11 -0
  48. data/lib/metanorma/mpfa.rb +7 -0
  49. data/lib/metanorma/mpfa/processor.rb +49 -0
  50. data/lib/metanorma/mpfa/version.rb +5 -0
  51. data/metanorma-mpfd.gemspec +46 -0
  52. 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,2 @@
1
+ clause: Paragraph
2
+ annex: Appendix
@@ -0,0 +1,2 @@
1
+ clause: 段
2
+ annex: 附录
@@ -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,10 @@
1
+ require_relative "base_convert"
2
+ require "isodoc"
3
+
4
+ module IsoDoc
5
+ module MPFA
6
+ class PresentationXMLConvert < IsoDoc::PresentationXMLConvert
7
+ end
8
+ end
9
+ end
10
+
@@ -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 << "&nbsp;" } # 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,7 @@
1
+ require_relative "./mpfa/processor"
2
+
3
+ module Metanorma
4
+ module MPFA
5
+
6
+ end
7
+ 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,5 @@
1
+ module Metanorma
2
+ module MPFA
3
+ VERSION = "0.4.0"
4
+ end
5
+ 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