asciidoctor-gb 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.hound.yml +3 -0
  3. data/.oss-guides.rubocop.yml +1077 -0
  4. data/.rubocop.ribose.yml +65 -0
  5. data/.rubocop.tb.yml +640 -0
  6. data/.rubocop.yml +15 -0
  7. data/CODE_OF_CONDUCT.md +74 -0
  8. data/Gemfile +11 -0
  9. data/README.adoc +77 -0
  10. data/Rakefile +6 -0
  11. data/asciidoctor-gb.gemspec +52 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/lib/asciidoctor/gb/agencies.rb +186 -0
  15. data/lib/asciidoctor/gb/converter.rb +179 -0
  16. data/lib/asciidoctor/gb/front.rb +179 -0
  17. data/lib/asciidoctor/gb/gbconvert.rb +86 -0
  18. data/lib/asciidoctor/gb/gbstandard.rng +297 -0
  19. data/lib/asciidoctor/gb/html/blank.png +0 -0
  20. data/lib/asciidoctor/gb/html/footer.png +0 -0
  21. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-db.gif +0 -0
  22. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-db.png +0 -0
  23. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-db.svg +1 -0
  24. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-gb.gif +0 -0
  25. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-gb.png +0 -0
  26. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-gb.svg +1 -0
  27. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-gjb.gif +0 -0
  28. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-gjb.png +0 -0
  29. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-gjb.svg +1 -0
  30. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-gm.gif +0 -0
  31. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-gm.png +0 -0
  32. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-gm.svg +1 -0
  33. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-jjf.gif +0 -0
  34. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-jjf.png +0 -0
  35. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-jjf.svg +1 -0
  36. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-zb.gif +0 -0
  37. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-zb.png +0 -0
  38. data/lib/asciidoctor/gb/html/gb-logos/gb-standard-zb.svg +13 -0
  39. data/lib/asciidoctor/gb/html/gb.css +642 -0
  40. data/lib/asciidoctor/gb/html/header.html +216 -0
  41. data/lib/asciidoctor/gb/html/html_gb_intro.html +45 -0
  42. data/lib/asciidoctor/gb/html/html_gb_titlepage.html +98 -0
  43. data/lib/asciidoctor/gb/html/htmlstyle.css +187 -0
  44. data/lib/asciidoctor/gb/html/logo.png +0 -0
  45. data/lib/asciidoctor/gb/html/word_gb_intro.html +3 -0
  46. data/lib/asciidoctor/gb/html/word_gb_titlepage.html +234 -0
  47. data/lib/asciidoctor/gb/html/wordstyle.css +2367 -0
  48. data/lib/asciidoctor/gb/isodoc.rng +1563 -0
  49. data/lib/asciidoctor/gb/isostandard.rng +845 -0
  50. data/lib/asciidoctor/gb/metadata.rb +186 -0
  51. data/lib/asciidoctor/gb/section_input.rb +168 -0
  52. data/lib/asciidoctor/gb/section_output.rb +38 -0
  53. data/lib/asciidoctor/gb/version.rb +5 -0
  54. data/lib/asciidoctor/gb/xref_gen.rb +25 -0
  55. data/lib/asciidoctor/gb.rb +7 -0
  56. data/lib/asciidoctor-gb.rb +4 -0
  57. metadata +411 -0
data/.rubocop.yml ADDED
@@ -0,0 +1,15 @@
1
+ # This project follows the Ribose OSS style guide.
2
+ # https://github.com/riboseinc/oss-guides
3
+ # All project-specific additions and overrides should be specified in this file.
4
+
5
+ inherit_from:
6
+ # Thoughtbot's style guide from: https://github.com/thoughtbot/guides
7
+ - ".rubocop.tb.yml"
8
+ # Overrides from Ribose
9
+ - ".rubocop.ribose.yml"
10
+ AllCops:
11
+ DisplayCopNames: false
12
+ StyleGuideCopsOnly: false
13
+ TargetRubyVersion: 2.4
14
+ Rails:
15
+ Enabled: true
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at ronald.tse@ribose.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ribose.gemspec
4
+ gem "isodoc",
5
+ git: "https://github.com/riboseinc/isodoc.git"
6
+ gem "asciidoctor-iso",
7
+ git: "https://github.com/riboseinc/asciidoctor-iso.git"
8
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
9
+
10
+ # Specify your gem's dependencies in asciidoctor-csd.gemspec
11
+ gemspec
data/README.adoc ADDED
@@ -0,0 +1,77 @@
1
+ = asciidoctor-gb
2
+
3
+ image:https://img.shields.io/gem/v/asciidoctor-gb.svg["Gem Version", link="https://rubygems.org/gems/asciidoctor-gb"]
4
+ image:https://img.shields.io/travis/riboseinc/asciidoctor-gb/master.svg["Build Status", link="https://travis-ci.org/riboseinc/asciidoctor-gb"]
5
+ image:https://codeclimate.com/github/riboseinc/asciidoctor-gb/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/riboseinc/asciidoctor-gb"]
6
+
7
+ Gem for generating https://en.wikipedia.org/wiki/Guobiao_standards[Guibiao standards]
8
+ (Chinese national standards), using Asciidoc. This gem inherits from
9
+ https://github.com/riboseinc/asciidoctor-iso, a gem used to generate ISO standards
10
+ using Asciidoc. The two standards formats are closely aligned. Refer to the ISO gem
11
+ for guidance, including https://github.com/riboseinc/asciidoctor-iso/wiki/Guidance-for-authoring
12
+
13
+ The Gem can also be used to generate Chinese local or sector standards, which have the
14
+ same format; the gem formats the title page to have the correct metadata displayed.
15
+
16
+ == Differences from asciidoctor-iso
17
+
18
+ === Document Attributes
19
+
20
+ In the following, "GB standard" should be read to refer to any Chinese national, sector or local standard. Asterisked document attributes are mandatory.
21
+
22
+ `:title-intro-zh:`, `:title-main-zh:`*, `:title-part-zh:`:: These are the title introduction, main title, and part title in Chinese. (They replace their French counterparts in asciidoctor-iso.)
23
+ `:title-intro-en:`, `:title-main-en:`*, `:title-part-en:`:: These are the title introduction, main title, and part title in English. (They form the document subtitle, instead of the document title as in asciidoctor-iso.)
24
+ `:technical-committee-type:`:: The type of the technical committee (`technical` or `provisional`).
25
+ `:iso-standard`: A corresponding ISO standard that the GB standard relates to. Format is full document code, then optionally comma followed by document title; e.g. `ISO/IEC 27001:2013, Information security management systems`
26
+ `:equivalence:`:: The relation of the GB standard to the corresponding ISO standard (`equivalent`, `identical`, `nonequivalent`). Defaults to `equivalent`.
27
+ `:obsoletes`:: A corresponding GB standard that this GB standard obsoletes. Format is full document code, then optionally comma followed by document title; e.g. `GB/T 22080-2008`
28
+ `:obsoletes-parts:`: A list of bibliographic localities in the corresponding GB standard that this GB standard obsoletes. These are formatted the same way as the localities in citations; e.g. `clause 7-9, clause 11`
29
+ `:scope:`:: The scope of the GB standard (`national`, `sector`, `professional`, `local`, `enterprise`). Defaults to `national`.
30
+ `:mandate:`:: The mandate of the GB standard (`mandatory`, `recommended`, `guidelines`). Defaults to `mandatory`.
31
+ `:prefix:*`:: The prefix classifying the GB standard. (Refer to https://github.com/riboseinc/gbdoc/blob/master/models/gb-standard-national-prefix.adoc, https://github.com/riboseinc/gbdoc/blob/master/models/gb-standard-sector-prefix.adoc, https://github.com/riboseinc/gbdoc/blob/master/models/gb-standard-local-prefix.adoc.)
32
+ `:published-date:`* :: The date on which the GB standard was published.
33
+ `:activated-date:`* :: The date on which the GB standard was activated.
34
+ `:library-ics:`* :: The international categorisation number for the GB standard
35
+ `:library-l:`* :: The L-identifier (library) for the GB standard
36
+
37
+ === Language macros
38
+
39
+ In Terms and Definitions, preferred terms, alternate terms and deprecated
40
+ terms are expected to be given in both Chinese and English. By default,
41
+ the gem does this by detecting space-delimited runs of Han or Latin script
42
+ text:
43
+
44
+ [source,asciidoc]
45
+ --
46
+ alt:[rough rice 糙米]
47
+ --
48
+
49
+ [source,xml]
50
+ --
51
+ <admitted language="zh">糙米</admitted> <admitted language="en">rough rice</admitted>
52
+ --
53
+
54
+ However if there is script mixing in a term -- if the Chinese term contains
55
+ a Latin script acronym or a mathematical expression, for example -- the
56
+ Chinese term will not be detected correctly. To address this, the formatting macros
57
+ +`[zh]#...#`+ and +`[en]#...#`+ are used. If they are present, then the content
58
+ of those macros is treated as the Chinese and English equivalents of the
59
+ parent node instead:
60
+
61
+ [source,asciidoc]
62
+ --
63
+ === [en]#XYZ paddy# [zh]#水稻XY#]
64
+ alt:[[en]#rough rice# [zh]#糙米#]
65
+ --
66
+
67
+ [source,xml]
68
+ --
69
+ <preferred language="en">XYZ paddy</preferred> <preferred language="zh">水稻XYZ</preferred>
70
+ <admitted language="zh">糙米</admitted> <admitted language="en">rough rice</admitted>
71
+ --
72
+
73
+ Unfortunately no further markup is permitted within the +`[zh]#...#`+ and +`[en]#...#`+
74
+ macros by Asciidoctor, and Asciidoctor does not correctly nest inline macros within other
75
+ inline macros (so +`alt:[en:[_xyz_] zh:[xyz]`+ would not give correct behaviour either.)
76
+
77
+ The gem also supports +`[zh-Hant]#...#`+ and +`[zh-Hans]#...#`+ to differentiate traditional and simplified script in ISOXML; `zh-Hant` is provisionally supported through changing font in the output.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,52 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "asciidoctor/gb/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "asciidoctor-gb"
7
+ spec.version = Asciidoctor::Gb::VERSION
8
+ spec.authors = ["Ribose Inc."]
9
+ spec.email = ["open.source@ribose.com"]
10
+
11
+ spec.summary = "asciidoctor-gb lets you write GB standards in AsciiDoc."
12
+ spec.description = <<~DESCRIPTION
13
+ asciidoctor-gb lets you write GB standards (Chinese national standards)
14
+ in AsciiDoc syntax.
15
+
16
+ This gem is in active development.
17
+ DESCRIPTION
18
+
19
+ spec.homepage = "https://github.com/riboseinc/asciidoctor-gb"
20
+ spec.license = "MIT"
21
+
22
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
23
+ f.match(%r{^(test|spec|features)/})
24
+ end
25
+ spec.bindir = "exe"
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ["lib"]
28
+
29
+ spec.add_dependency "asciidoctor", "~> 1.5.6"
30
+ spec.add_dependency "asciimath"
31
+ spec.add_dependency "htmlentities", "~> 4.3.4"
32
+ spec.add_dependency "image_size"
33
+ spec.add_dependency "mime-types"
34
+ spec.add_dependency "nokogiri", "~> 1.8.1"
35
+ spec.add_dependency "ruby-jing"
36
+ spec.add_dependency "ruby-xslt"
37
+ spec.add_dependency "thread_safe"
38
+ spec.add_dependency "uuidtools"
39
+ spec.add_dependency "asciidoctor-iso"
40
+ spec.add_dependency "isodoc"
41
+
42
+ spec.add_development_dependency "bundler", "~> 1.15"
43
+ spec.add_development_dependency "byebug", "~> 9.1"
44
+ spec.add_development_dependency "equivalent-xml", "~> 0.6"
45
+ spec.add_development_dependency "guard", "~> 2.14"
46
+ spec.add_development_dependency "guard-rspec", "~> 4.7"
47
+ spec.add_development_dependency "rake", "~> 12.0"
48
+ spec.add_development_dependency "rspec", "~> 3.6"
49
+ spec.add_development_dependency "rubocop", "~> 0.50"
50
+ spec.add_development_dependency "simplecov", "~> 0.15"
51
+ spec.add_development_dependency "timecop", "~> 0.9"
52
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "asciidoctor/gb"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,186 @@
1
+ require "isodoc"
2
+
3
+ module Asciidoctor
4
+ module Gb
5
+ class GbConvert < IsoDoc::Convert
6
+ SECTOR = {
7
+ AQ: { industry: "安全生产", admin: "国家安全生产管理局" },
8
+ BB: { industry: "包装", admin: "国家发改委" },
9
+ CB: { industry: "船舶", admin: "国防科学工业委员会" },
10
+ CH: { industry: "测绘", admin: "国家测绘局" },
11
+ CJ: { industry: "城镇建设", admin: "建设部" },
12
+ CY: { industry: "新闻出版", admin: "国家新闻出版总署" },
13
+ DA: { industry: "档案", admin: "国家档案局" },
14
+ DB: { industry: "地震", admin: "中国地震局" },
15
+ DL: { industry: "电力", admin: "国家发改委" },
16
+ DZ: { industry: "地质矿产", admin: "国土资源部" },
17
+ EJ: { industry: "核工业", admin: "国防科学工业委员会" },
18
+ FZ: { industry: "纺织", admin: "国家发改委" },
19
+ GA: { industry: "公共安全", admin: "公安部" },
20
+ GH: { industry: "供销", admin: "中华全国供销合作总社" },
21
+ GM: { industry: "密码", admin: "国家密码管理局" },
22
+ GY: { industry: "广播电影电视", admin: "国家广播电影电视总局" },
23
+ HB: { industry: "航空", admin: "国防科学工业委员会" },
24
+ HG: { industry: "化工", admin: "国家发改委" },
25
+ HJ: { industry: "环境保护", admin: "国家环境保护总局" },
26
+ HS: { industry: "海关", admin: "海关总署" },
27
+ HY: { industry: "海洋", admin: "国家海洋局" },
28
+ JB: { industry: "机械", admin: "国家发改委" },
29
+ JC: { industry: "建材", admin: "国家发改委" },
30
+ JG: { industry: "建筑工业", admin: "建设部" },
31
+ JR: { industry: "金融", admin: "中国人民银行" },
32
+ JT: { industry: "交通", admin: "交通部" },
33
+ JY: { industry: "教育", admin: "教育部" },
34
+ LB: { industry: "旅游", admin: "国家旅游局" },
35
+ LD: { industry: "劳动和劳动安全", admin: "劳动和社会保障部" },
36
+ LS: { industry: "粮食", admin: "国家粮食局" },
37
+ LY: { industry: "林业", admin: "国家林业局" },
38
+ MH: { industry: "民用航空", admin: "中国民航管理总局" },
39
+ MT: { industry: "煤炭", admin: "国家发改委" },
40
+ MZ: { industry: "民政", admin: "民政部" },
41
+ NY: { industry: "农业", admin: "农业部" },
42
+ QB: { industry: "轻工", admin: "国家发改委" },
43
+ QC: { industry: "汽车", admin: "国家发改委" },
44
+ QJ: { industry: "航天", admin: "国防科学工业委员会" },
45
+ QX: { industry: "气象", admin: "中国气象局" },
46
+ SB: { industry: "国内贸易", admin: "商务部" },
47
+ SC: { industry: "水产", admin: "农业部" },
48
+ SH: { industry: "石油化工", admin: "国家发改委" },
49
+ SJ: { industry: "电子", admin: "信息产业部" },
50
+ SL: { industry: "水利", admin: "水利部" },
51
+ SN: { industry: "商检", admin: "国家质量监督检验检疫总局" },
52
+ SY: { industry: "石油天然气", admin: "国家发改委" },
53
+ TB: { industry: "铁道", admin: "铁道部" },
54
+ TD: { industry: "土地管理", admin: "国土资源部" },
55
+ TJ: { industry: "铁道交通", admin: "铁道部标准所" },
56
+ TY: { industry: "体育", admin: "国家体育总局" },
57
+ WB: { industry: "物资管理", admin: "国家发改委" },
58
+ WH: { industry: "文化", admin: "文化部" },
59
+ WJ: { industry: "兵工民品", admin: "国防科学工业委员会" },
60
+ WM: { industry: "外经贸", admin: "外经贸部科技司" },
61
+ WS: { industry: "卫生", admin: "卫生部" },
62
+ WW: { industry: "文物保护", admin: "国家文物局" },
63
+ XB: { industry: "稀土", admin: "国家发改委稀土办公室" },
64
+ YB: { industry: "黑色冶金", admin: "国家发改委" },
65
+ YC: { industry: "烟草", admin: "国家烟草专卖局" },
66
+ YD: { industry: "通信", admin: "信息产业部" },
67
+ YS: { industry: "有色冶金", admin: "国家发改委" },
68
+ YY: { industry: "医药", admin: "国家食品药品监督管理局" },
69
+ YZ: { industry: "邮政", admin: "国家邮政局" },
70
+ ZY: { industry: "中医药", admin: "国家中医药管理局" },
71
+ }.freeze
72
+
73
+ NATIONAL = {
74
+ GB: { name: "中华人民共和国国家标准",
75
+ admin: ["中华人民共和国国家质量监督检验检疫总局", "中国国家标准化管理委员会"] },
76
+ "GB/T": { name: "中华人民共和国国家标准",
77
+ admin: ["中华人民共和国国家质量监督检验检疫总局", "中国国家标准化管理委员会"] },
78
+ "GB/Z": { name: "中华人民共和国国家标准化指导性技术文件",
79
+ admin: ["中华人民共和国国家质量监督检验检疫总局", "中国国家标准化管理委员会"] },
80
+ GBZ: { name: "中华人民共和国国家职业卫生标准", admin: "中华人民共和国卫生部" },
81
+ GJB: { name: "中华人民共和国国家军用标准", admin: "中国人民解放军装备总部" },
82
+ GBn: { name: "中华人民共和国国家内部标准", admin: "" },
83
+ GHZB: { name: "中华人民共和国国家环境质量标准", admin: "" }, GWKB: { name: "中华人民共和国国家环境保护标准", admin: "环境保护部" },
84
+ GWPB: { name: "中华人民共和国国家污染物排放标准", admin: "" },
85
+ JJF: { name: "中华人民共和国国家计量技术规范", admin: "中华人民共和国国家质量监督检验检疫总局" },
86
+ JJG: { name: "中华人民共和国国家计量检定规程", admin: "中华人民共和国国家质量监督检验检疫总局" },
87
+ }.freeze
88
+
89
+ LOCAL = {
90
+ "11": "北京市",
91
+ "12": "天津市",
92
+ "13": "河北省",
93
+ "14": "山西省",
94
+ "15": "内蒙古自治区",
95
+ "21": "辽宁省",
96
+ "22": "吉林省",
97
+ "23": "黑龙江省",
98
+ "31": "上海市",
99
+ "32": "江苏省",
100
+ "33": "浙江省",
101
+ "34": "安徽省",
102
+ "35": "福建省",
103
+ "36": "江西省",
104
+ "37": "山东省",
105
+ "41": "河南省",
106
+ "42": "湖北省",
107
+ "43": "湖南省",
108
+ "44": "广东省",
109
+ "45": "广西壮族自治区",
110
+ "46": "海南省",
111
+ "50": "重庆市",
112
+ "51": "四川省",
113
+ "52": "贵州省",
114
+ "53": "云南省",
115
+ "54": "西藏自治区",
116
+ "61": "陕西省",
117
+ "62": "甘肃省",
118
+ "63": "青海省",
119
+ "64": "宁夏回族自治区",
120
+ "65": "新疆维吾尔自治区",
121
+ "71": "台湾省",
122
+ "81": "香港特别行政区",
123
+ "82": "澳门特别行政区",
124
+ }.freeze
125
+
126
+ def gb_mandate_suffix(prefix, mandate)
127
+ if prefix == "GB"
128
+ prefix += "/T" if mandate == "recommended"
129
+ prefix += "/Z" if mandate == "guide"
130
+ end
131
+ prefix
132
+ end
133
+
134
+ def mandate_suffix(prefix, mandate)
135
+ prefix += "/T" if mandate == "recommended"
136
+ prefix += "/Z" if mandate == "guide"
137
+ prefix
138
+ end
139
+
140
+ def standard_class(scope, prefix, mandate)
141
+ case scope
142
+ when "national"
143
+ NATIONAL&.dig(gb_mandate_suffix(prefix, mandate).to_sym,
144
+ :name) || "XXXX"
145
+ when "sector"
146
+ "中华人民共和国#{SECTOR&.dig(prefix.to_sym,
147
+ :industry) || 'XXXX'}行业标准"
148
+ when "local"
149
+ "#{LOCAL&.dig(prefix.to_sym) || 'XXXX'}地方标准"
150
+ when "enterprise" then "ENTERPRISE STANDARD" # TODO
151
+ when "professional" then "PROFESSIONAL STANDARD" # TODO
152
+ end
153
+ end
154
+
155
+ def standard_agency(scope, prefix, mandate)
156
+ case scope
157
+ when "national"
158
+ NATIONAL&.dig(gb_mandate_suffix(prefix, mandate).to_sym,
159
+ :admin) || "XXXX"
160
+ when "sector"
161
+ SECTOR&.dig(prefix.to_sym, :admin) || "XXXX"
162
+ when "local"
163
+ "#{LOCAL&.dig(prefix.to_sym) || 'XXXX'}质量技术检测局"
164
+ when "enterprise" then "ENTERPRISE STANDARD" # TODO
165
+ when "professional" then "PROFESSIONAL STANDARD" # TODO
166
+ end
167
+ end
168
+
169
+ def gbtype_validate(root)
170
+ scope = root.at("//gbscope")&.text
171
+ prefix = root.at("//gbprefix")&.text
172
+ case scope
173
+ when "national"
174
+ NATIONAL.has_key?(prefix.to_sym) ||
175
+ warn("GB: #{prefix} is not a recognised national prefix")
176
+ when "sector"
177
+ SECTOR.has_key?(prefix.to_sym) ||
178
+ warn("GB: #{prefix} is not a recognised sector prefix")
179
+ when "local"
180
+ LOCAL.has_key?(prefix.to_sym) ||
181
+ warn("GB: #{prefix} is not a recognised local prefix")
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,179 @@
1
+ require "asciidoctor"
2
+ require "asciidoctor/gb/version"
3
+ require "asciidoctor/gb/gbconvert"
4
+ require "asciidoctor/iso/converter"
5
+ require_relative "./section_input.rb"
6
+ require_relative "./front.rb"
7
+ require "pp"
8
+
9
+ module Asciidoctor
10
+ module Gb
11
+ GB_NAMESPACE = "http://riboseinc.com/gbstandard"
12
+
13
+ # A {Converter} implementation that generates GB output, and a document
14
+ # schema encapsulation of the document for validation
15
+ class Converter < ISO::Converter
16
+
17
+ register_for "gb"
18
+
19
+ def makexml(node)
20
+ result = ["<?xml version='1.0' encoding='UTF-8'?>\n<gb-standard>"]
21
+ @draft = node.attributes.has_key?("draft")
22
+ result << noko { |ixml| front node, ixml }
23
+ result << noko { |ixml| middle node, ixml }
24
+ result << "</gb-standard>"
25
+ result = textcleanup(result.flatten * "\n")
26
+ ret1 = cleanup(Nokogiri::XML(result))
27
+ validate(ret1)
28
+ ret1.root.add_namespace(nil, GB_NAMESPACE)
29
+ ret1
30
+ end
31
+
32
+ def validate(doc)
33
+ content_validate(doc)
34
+ schema_validate(formattedstr_strip(doc.dup),
35
+ File.join(File.dirname(__FILE__), "gbstandard.rng"))
36
+ end
37
+
38
+ def content_validate(doc)
39
+ super
40
+ bilingual_terms_validate(doc.root)
41
+ doc_converter(nil).gbtype_validate(doc.root)
42
+ end
43
+
44
+ def check_bilingual(t, element)
45
+ zh = t.at(".//#{element}[@language = 'zh']")
46
+ en = t.at(".//#{element}[@language = 'en']")
47
+ (en.nil? || en.text.empty?) && !(zh.nil? || zh.text.empty?) &&
48
+ warn("GB: #{element} term #{zh.text} has no English counterpart")
49
+ !(en.nil? || en.text.empty?) && (zh.nil? || zh.text.empty?) &&
50
+ warn("GB: #{element} term #{en.text} has no Chinese counterpart")
51
+ end
52
+
53
+ def bilingual_terms_validate(root)
54
+ root.xpath("//term").each do |t|
55
+ check_bilingual(t, "preferred")
56
+ check_bilingual(t, "admitted")
57
+ check_bilingual(t, "deprecates")
58
+ end
59
+ end
60
+
61
+ def html_doc_path(file)
62
+ File.join(File.dirname(__FILE__), File.join("html", file))
63
+ end
64
+
65
+ def doc_converter(node)
66
+ GbConvert.new(
67
+ htmlstylesheet: html_doc_path("htmlstyle.css"),
68
+ wordstylesheet: html_doc_path("wordstyle.css"),
69
+ standardstylesheet: html_doc_path("gb.css"),
70
+ header: html_doc_path("header.html"),
71
+ htmlcoverpage: html_doc_path("html_gb_titlepage.html"),
72
+ wordcoverpage: html_doc_path("word_gb_titlepage.html"),
73
+ htmlintropage: html_doc_path("html_gb_intro.html"),
74
+ wordintropage: html_doc_path("word_gb_intro.html"),
75
+ i18nyaml: node&.attr("i18nyaml"),
76
+ )
77
+ end
78
+
79
+ def termdef_cleanup(xmldoc)
80
+ super
81
+ termdef_localisedstr(xmldoc)
82
+ end
83
+
84
+ ROMAN_TEXT = /\s*[a-z\u00c0-\u00d6\u00d8-\u00f0\u0100-\u0240]/i
85
+ HAN_TEXT = /\s*[\u4e00-\u9fff]+/
86
+
87
+ def termdef_localisedstr(xmldoc)
88
+ xmldoc.xpath("//admitted | //deprecates | //preferred").each do |zh|
89
+ if zh.at("./string")
90
+ extract_localisedstrings(zh)
91
+ else
92
+ duplicate_localisedstrings(zh)
93
+ end
94
+ end
95
+ end
96
+
97
+ # element consists solely of localised strings, with no attributes
98
+ def extract_localisedstrings(elem)
99
+ elem.xpath("./string").each do |s|
100
+ s.name = elem.name
101
+ end
102
+ elem.replace(elem.children)
103
+ end
104
+
105
+ def duplicate_localisedstrings(zh)
106
+ en = zh.dup.remove
107
+ zh.after(en).after(" ")
108
+ zh["language"] = "zh"
109
+ en["language"] = "en"
110
+ en.traverse do |c|
111
+ c.text? && c.content = c.text.gsub(HAN_TEXT, "").gsub(/^\s*/, "")
112
+ end
113
+ zh.traverse do |c|
114
+ c.text? && c.content = c.text.gsub(ROMAN_TEXT, "").gsub(/^\s*/, "")
115
+ end
116
+ end
117
+
118
+ def inline_quoted(node)
119
+ noko do |xml|
120
+ case node.type
121
+ when :emphasis then xml.em node.text
122
+ when :strong then xml.strong node.text
123
+ when :monospaced then xml.tt node.text
124
+ when :double then xml << "\"#{node.text}\""
125
+ when :single then xml << "'#{node.text}'"
126
+ when :superscript then xml.sup node.text
127
+ when :subscript then xml.sub node.text
128
+ when :asciimath then xml.stem node.text, **{ type: "AsciiMath" }
129
+ else
130
+ case node.role
131
+ when "alt" then xml.admitted { |a| a << node.text }
132
+ when "deprecated" then xml.deprecates { |a| a << node.text }
133
+ when "domain" then xml.domain { |a| a << node.text }
134
+ when "strike" then xml.strike node.text
135
+ when "smallcap" then xml.smallcap node.text
136
+ when "en" then xml.string node.text, **{ language: "en" }
137
+ when "zh" then xml.string node.text, **{ language: "zh" }
138
+ when "zh-Hans"
139
+ xml.string node.text, **{ language: "zh", script: "Hans" }
140
+ when "zh-Hant"
141
+ xml.string node.text, **{ language: "zh", script: "Hant" }
142
+ else
143
+ xml << node.text
144
+ end
145
+ end
146
+ end.join
147
+ end
148
+
149
+ def termdef_boilerplate_cleanup(xmldoc)
150
+ nil
151
+ end
152
+
153
+ GBCODE = "((AQ|BB|CB|CH|CJ|CY|DA|DB|DL|DZ|EJ|FZ|GA|GH|GM|GY|HB|HG|"\
154
+ "HJ|HS|HY|JB|JC|JG|JR|JT|JY|LB|LD|LS|LY|MH|MT|MZ|NY|QB|QC|QJ|"\
155
+ "QZ|SB|SC|SH|SJ|SN|SY|TB|TD|TJ|TY|WB|WH|WJ|WM|WS|WW|XB|YB|YC|"\
156
+ "YD|YS|YY|YZ|ZY|GB|GBZ|GJB|GBn|GHZB|GWKB|GWPB|JJF|JJG)(/Z|/T)?)"
157
+
158
+ ISO_REF = %r{^<ref\sid="(?<anchor>[^"]+)">
159
+ \[(?<code>(ISO|IEC|#{GBCODE})[^0-9]*\s[0-9-]+)(:(?<year>[0-9]+))?\]</ref>,?\s
160
+ (?<text>.*)$}xm
161
+
162
+ ISO_REF_NO_YEAR = %r{^<ref\sid="(?<anchor>[^"]+)">
163
+ \[(?<code>(ISO|IEC|#{GBCODE})[^0-9]*\s[0-9-]+):--\]</ref>,?\s?
164
+ <fn[^>]*>\s*<p>(?<fn>[^\]]+)</p>\s*</fn>,?\s?(?<text>.*)$}xm
165
+
166
+ # TODO: all parts in ZH
167
+ ISO_REF_ALL_PARTS = %r{^<ref\sid="(?<anchor>[^"]+)">
168
+ \[(?<code>(ISO|IEC|#{GBCODE})[^0-9]*\s[0-9]+)\s\(all\sparts\)\]</ref>(<p>)?,?\s?
169
+ (?<text>.*)(</p>)?$}xm
170
+
171
+ def reference1_matches(item)
172
+ matched = ISO_REF.match item
173
+ matched2 = ISO_REF_NO_YEAR.match item
174
+ matched3 = ISO_REF_ALL_PARTS.match item
175
+ [matched, matched2, matched3]
176
+ end
177
+ end
178
+ end
179
+ end