metanorma-iso 1.10.6 → 2.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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +26 -0
  3. data/Makefile +1 -1
  4. data/lib/asciidoctor/iso/base.rb +2 -69
  5. data/lib/asciidoctor/iso/cleanup.rb +2 -175
  6. data/lib/asciidoctor/iso/converter.rb +2 -17
  7. data/lib/asciidoctor/iso/deprecated.rb +5 -0
  8. data/lib/asciidoctor/iso/front.rb +2 -169
  9. data/lib/asciidoctor/iso/front_id.rb +2 -224
  10. data/lib/asciidoctor/iso/section.rb +2 -48
  11. data/lib/asciidoctor/iso/validate.rb +2 -171
  12. data/lib/asciidoctor/iso/validate_image.rb +2 -96
  13. data/lib/asciidoctor/iso/validate_requirements.rb +2 -110
  14. data/lib/asciidoctor/iso/validate_section.rb +2 -246
  15. data/lib/asciidoctor/iso/validate_style.rb +2 -169
  16. data/lib/asciidoctor/iso/validate_title.rb +2 -104
  17. data/lib/isodoc/iso/html/htmlstyle.css +47 -0
  18. data/lib/isodoc/iso/html/isodoc.css +1327 -0
  19. data/lib/isodoc/iso/html/style-human.css +1010 -0
  20. data/lib/isodoc/iso/html/style-iso.css +1036 -0
  21. data/lib/isodoc/iso/html/wordstyle.css +1701 -0
  22. data/lib/isodoc/iso/html_convert.rb +6 -4
  23. data/lib/isodoc/iso/iso.amendment.xsl +96 -154
  24. data/lib/isodoc/iso/iso.international-standard.xsl +96 -154
  25. data/lib/metanorma/iso/base.rb +70 -0
  26. data/lib/{asciidoctor → metanorma}/iso/basicdoc.rng +0 -0
  27. data/lib/{asciidoctor → metanorma}/iso/biblio.rng +0 -0
  28. data/lib/{asciidoctor → metanorma}/iso/boilerplate-fr.xml +0 -0
  29. data/lib/{asciidoctor → metanorma}/iso/boilerplate.xml +0 -0
  30. data/lib/metanorma/iso/cleanup.rb +176 -0
  31. data/lib/metanorma/iso/converter.rb +18 -0
  32. data/lib/metanorma/iso/front.rb +170 -0
  33. data/lib/metanorma/iso/front_id.rb +225 -0
  34. data/lib/{asciidoctor → metanorma}/iso/isodoc.rng +29 -0
  35. data/lib/{asciidoctor → metanorma}/iso/isostandard-amd.rng +0 -0
  36. data/lib/{asciidoctor → metanorma}/iso/isostandard.rnc +0 -0
  37. data/lib/{asciidoctor → metanorma}/iso/isostandard.rng +0 -0
  38. data/lib/{asciidoctor → metanorma}/iso/reqt.rng +0 -0
  39. data/lib/metanorma/iso/section.rb +49 -0
  40. data/lib/metanorma/iso/validate.rb +172 -0
  41. data/lib/metanorma/iso/validate_image.rb +97 -0
  42. data/lib/metanorma/iso/validate_requirements.rb +111 -0
  43. data/lib/metanorma/iso/validate_section.rb +247 -0
  44. data/lib/metanorma/iso/validate_style.rb +170 -0
  45. data/lib/metanorma/iso/validate_title.rb +105 -0
  46. data/lib/metanorma/iso/version.rb +1 -1
  47. data/lib/metanorma-iso.rb +1 -1
  48. data/metanorma-iso.gemspec +1 -1
  49. data/spec/isodoc/ref_spec.rb +4 -2
  50. data/spec/{asciidoctor → metanorma}/amd_spec.rb +1 -1
  51. data/spec/{asciidoctor → metanorma}/base_spec.rb +1 -1
  52. data/spec/{asciidoctor → metanorma}/blank_spec.rb +1 -1
  53. data/spec/{asciidoctor → metanorma}/blocks_spec.rb +1 -1
  54. data/spec/{asciidoctor → metanorma}/cleanup_spec.rb +1 -1
  55. data/spec/{asciidoctor → metanorma}/inline_spec.rb +1 -1
  56. data/spec/{asciidoctor → metanorma}/lists_spec.rb +1 -1
  57. data/spec/{asciidoctor → metanorma}/refs_spec.rb +1 -1
  58. data/spec/{asciidoctor → metanorma}/section_spec.rb +1 -1
  59. data/spec/{asciidoctor → metanorma}/table_spec.rb +1 -1
  60. data/spec/{asciidoctor → metanorma}/validate_spec.rb +1 -1
  61. data/spec/spec_helper.rb +1 -1
  62. metadata +46 -28
@@ -0,0 +1,176 @@
1
+ require "date"
2
+ require "nokogiri"
3
+ require "htmlentities"
4
+ require "json"
5
+ require "pathname"
6
+
7
+ module Metanorma
8
+ module ISO
9
+ class Converter < Standoc::Converter
10
+ PRE_NORMREF_FOOTNOTES = "//preface//fn | "\
11
+ "//clause[@type = 'scope']//fn".freeze
12
+
13
+ NORMREF_FOOTNOTES =
14
+ "//references[@normative = 'true']//fn".freeze
15
+
16
+ POST_NORMREF_FOOTNOTES =
17
+ "//sections//clause[not(@type = 'scope')]//fn | "\
18
+ "//annex//fn | "\
19
+ "//references[@normative = 'false']//fn".freeze
20
+
21
+ def other_footnote_renumber(xmldoc)
22
+ seen = {}
23
+ i = 0
24
+ [PRE_NORMREF_FOOTNOTES, NORMREF_FOOTNOTES,
25
+ POST_NORMREF_FOOTNOTES].each do |xpath|
26
+ xmldoc.xpath(xpath).each do |fn|
27
+ i, seen = other_footnote_renumber1(fn, i, seen)
28
+ end
29
+ end
30
+ end
31
+
32
+ def id_prefix(prefix, id)
33
+ # we're just inheriting the prefixes from parent doc
34
+ return id.text if @amd
35
+
36
+ prefix.join("/") + (id.text.match?(%{^/}) ? "" : " ") + id.text
37
+ end
38
+
39
+ def get_id_prefix(xmldoc)
40
+ prefix = []
41
+ xmldoc.xpath("//bibdata/contributor[role/@type = 'publisher']"\
42
+ "/organization").each do |x|
43
+ x1 = x.at("abbreviation")&.text || x.at("name")&.text
44
+ (x1 == "ISO" and prefix.unshift("ISO")) or prefix << x1
45
+ end
46
+ prefix
47
+ end
48
+
49
+ # ISO as a prefix goes first
50
+ def docidentifier_cleanup(xmldoc)
51
+ prefix = get_id_prefix(xmldoc)
52
+ id = xmldoc.at("//bibdata/docidentifier[@type = 'ISO']") or return
53
+ id.content = id_prefix(prefix, id)
54
+ id = xmldoc.at("//bibdata/ext/structuredidentifier/project-number") and
55
+ id.content = id_prefix(prefix, id)
56
+ id = xmldoc.at("//bibdata/docidentifier[@type = 'iso-with-lang']") and
57
+ id.content = id_prefix(prefix, id)
58
+ id = xmldoc.at("//bibdata/docidentifier[@type = 'iso-reference']") and
59
+ id.content = id_prefix(prefix, id)
60
+ end
61
+
62
+ def format_ref(ref, type)
63
+ ref = ref.sub(/ \(All Parts\)/i, "")
64
+ super
65
+ end
66
+
67
+ TERM_CLAUSE =
68
+ "//sections//terms | "\
69
+ "//sections//clause[descendant::terms][not(descendant::definitions)]"
70
+ .freeze
71
+
72
+ PUBLISHER = "./contributor[role/@type = 'publisher']/organization".freeze
73
+
74
+ OTHERIDS = "@type = 'DOI' or @type = 'metanorma' or @type = 'ISSN' or "\
75
+ "@type = 'ISBN'".freeze
76
+
77
+ def pub_class(bib)
78
+ return 1 if bib.at("#{PUBLISHER}[abbreviation = 'ISO']")
79
+ return 1 if bib.at("#{PUBLISHER}[name = 'International Organization "\
80
+ "for Standardization']")
81
+ return 2 if bib.at("#{PUBLISHER}[abbreviation = 'IEC']")
82
+ return 2 if bib.at("#{PUBLISHER}[name = 'International "\
83
+ "Electrotechnical Commission']")
84
+ return 3 if bib.at("./docidentifier[@type][not(#{OTHERIDS})]")
85
+
86
+ 4
87
+ end
88
+
89
+ def sort_biblio(bib)
90
+ bib.sort do |a, b|
91
+ sort_biblio_key(a) <=> sort_biblio_key(b)
92
+ end
93
+ end
94
+
95
+ # TODO sort by authors
96
+ # sort by: doc class (ISO, IEC, other standard (not DOI &c), other
97
+ # then standard class (docid class other than DOI &c)
98
+ # then docnumber if present, numeric sort
99
+ # else alphanumeric metanorma id (abbreviation)
100
+ # then doc part number if present, numeric sort
101
+ # then doc id (not DOI &c)
102
+ # then title
103
+ def sort_biblio_key(bib)
104
+ pubclass = pub_class(bib)
105
+ num = bib&.at("./docnumber")&.text
106
+ id = bib&.at("./docidentifier[not(#{OTHERIDS})]")
107
+ metaid = bib&.at("./docidentifier[@type = 'metanorma']")&.text
108
+ abbrid = metaid unless /^\[\d+\]$/.match?(metaid)
109
+ /\d-(?<partid>\d+)/ =~ id&.text
110
+ type = id["type"] if id
111
+ title = bib&.at("./title[@type = 'main']")&.text ||
112
+ bib&.at("./title")&.text || bib&.at("./formattedref")&.text
113
+ "#{pubclass} :: #{type} :: "\
114
+ "#{num.nil? ? abbrid : sprintf('%09d', num.to_i)} :: "\
115
+ "#{sprintf('%09d', partid.to_i)} :: #{id&.text} :: #{title}"
116
+ end
117
+
118
+ def sections_cleanup(xml)
119
+ super
120
+ return unless @amd
121
+
122
+ xml.xpath("//*[@inline-header]").each do |h|
123
+ h.delete("inline-header")
124
+ end
125
+ end
126
+
127
+ def boilerplate_file(_xmldoc)
128
+ file = @lang == "fr" ? "boilerplate-fr.xml" : "boilerplate.xml"
129
+ File.join(@libdir, file)
130
+ end
131
+
132
+ def footnote_cleanup(xmldoc)
133
+ unpub_footnotes(xmldoc)
134
+ super
135
+ end
136
+
137
+ def unpub_footnotes(xmldoc)
138
+ xmldoc.xpath("//bibitem/note[@type = 'Unpublished-Status']").each do |n|
139
+ id = n.parent["id"]
140
+ e = xmldoc.at("//eref[@bibitemid = '#{id}']") or next
141
+ fn = n.children.to_xml
142
+ n&.elements&.first&.name == "p" or fn = "<p>#{fn}</p>"
143
+ e.next = "<fn>#{fn}</fn>"
144
+ end
145
+ end
146
+
147
+ def bibitem_cleanup(xmldoc)
148
+ super
149
+ unpublished_note(xmldoc)
150
+ end
151
+
152
+ def unpublished_note(xmldoc)
153
+ xmldoc.xpath("//bibitem[not(note[@type = 'Unpublished-Status'])]")
154
+ .each do |b|
155
+ next if pub_class(b) > 2
156
+ next unless (s = b.at("./status/stage")) && (s.text.to_i < 60)
157
+
158
+ id = b.at("docidentifier").text
159
+ b.at("./language | ./script | ./abstract | ./status")
160
+ .previous = %(<note type="Unpublished-Status">
161
+ <p>#{@i18n.under_preparation.sub(/%/, id)}</p></note>)
162
+ end
163
+ end
164
+
165
+ def termdef_boilerplate_insert(xmldoc, isodoc, once = false)
166
+ once = true
167
+ super
168
+ end
169
+
170
+ def term_defs_boilerplate_cont(src, term, isodoc)
171
+ @vocab and src.empty? and return
172
+ super
173
+ end
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,18 @@
1
+ require "asciidoctor"
2
+ require "metanorma-standoc"
3
+ require "metanorma/iso/version"
4
+ require "metanorma/iso/base"
5
+ require "metanorma/iso/front"
6
+ require "metanorma/iso/section"
7
+ require "metanorma/iso/validate"
8
+ require "metanorma/iso/cleanup"
9
+
10
+ module Metanorma
11
+ module ISO
12
+ # A {Converter} implementation that generates ISO output, and a document
13
+ # schema encapsulation of the document for validation
14
+ class Converter < ::Metanorma::Standoc::Converter
15
+ register_for "iso"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,170 @@
1
+ require "date"
2
+ require "nokogiri"
3
+ require "htmlentities"
4
+ require "json"
5
+ require "pathname"
6
+ require "open-uri"
7
+ require_relative "front_id"
8
+
9
+ module Metanorma
10
+ module ISO
11
+ class Converter < Standoc::Converter
12
+ def metadata_ext(node, xml)
13
+ super
14
+ structured_id(node, xml)
15
+ xml.stagename stage_name(get_stage(node), get_substage(node),
16
+ doctype(node), node.attr("iteration"))
17
+ @amd && a = node.attr("updates-document-type") and
18
+ xml.updates_document_type a
19
+ end
20
+
21
+ def metadata_subdoctype(node, xml)
22
+ super
23
+ a = node.attr("horizontal") and xml.horizontal a
24
+ end
25
+
26
+ def org_abbrev
27
+ { "International Organization for Standardization" => "ISO",
28
+ "International Electrotechnical Commission" => "IEC" }
29
+ end
30
+
31
+ def metadata_author(node, xml)
32
+ publishers = node.attr("publisher") || "ISO"
33
+ csv_split(publishers).each do |p|
34
+ xml.contributor do |c|
35
+ c.role **{ type: "author" }
36
+ c.organization do |a|
37
+ organization(a, p, false, node, !node.attr("publisher"))
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ def metadata_publisher(node, xml)
44
+ publishers = node.attr("publisher") || "ISO"
45
+ csv_split(publishers).each do |p|
46
+ xml.contributor do |c|
47
+ c.role **{ type: "publisher" }
48
+ c.organization do |a|
49
+ organization(a, p, true, node, !node.attr("publisher"))
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ def metadata_copyright(node, xml)
56
+ publishers = node.attr("copyright-holder") || node.attr("publisher") ||
57
+ "ISO"
58
+ csv_split(publishers).each do |p|
59
+ xml.copyright do |c|
60
+ c.from (node.attr("copyright-year") || Date.today.year)
61
+ c.owner do |owner|
62
+ owner.organization do |o|
63
+ organization(
64
+ o, p, true, node,
65
+ !(node.attr("copyright-holder") || node.attr("publisher"))
66
+ )
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ def metadata_status(node, xml)
74
+ stage = get_stage(node)
75
+ substage = get_substage(node)
76
+ xml.status do |s|
77
+ s.stage stage, **attr_code(abbreviation: cover_stage_abbr(node))
78
+ s.substage substage
79
+ node.attr("iteration") && (s.iteration node.attr("iteration"))
80
+ end
81
+ end
82
+
83
+ def metadata_committee(node, xml)
84
+ xml.editorialgroup do |a|
85
+ committee_component("technical-committee", node, a)
86
+ committee_component("subcommittee", node, a)
87
+ committee_component("workgroup", node, a)
88
+ node.attr("secretariat") && a.secretariat(node.attr("secretariat"))
89
+ end
90
+ end
91
+
92
+ def title_intro(node, xml, lang, at)
93
+ return unless node.attr("title-intro-#{lang}")
94
+
95
+ xml.title(**attr_code(at.merge(type: "title-intro"))) do |t1|
96
+ t1 << Metanorma::Utils::asciidoc_sub(node.attr("title-intro-#{lang}"))
97
+ end
98
+ end
99
+
100
+ def title_main(node, xml, lang, at)
101
+ xml.title **attr_code(at.merge(type: "title-main")) do |t1|
102
+ t1 << Metanorma::Utils::asciidoc_sub(node.attr("title-main-#{lang}"))
103
+ end
104
+ end
105
+
106
+ def title_part(node, xml, lang, at)
107
+ return unless node.attr("title-part-#{lang}")
108
+
109
+ xml.title(**attr_code(at.merge(type: "title-part"))) do |t1|
110
+ t1 << Metanorma::Utils::asciidoc_sub(node.attr("title-part-#{lang}"))
111
+ end
112
+ end
113
+
114
+ def title_amd(node, xml, lang, at)
115
+ return unless node.attr("title-amendment-#{lang}")
116
+
117
+ xml.title(**attr_code(at.merge(type: "title-amd"))) do |t1|
118
+ t1 << Metanorma::Utils::asciidoc_sub(
119
+ node.attr("title-amendment-#{lang}"),
120
+ )
121
+ end
122
+ end
123
+
124
+ def title_full(node, xml, lang, at)
125
+ title = node.attr("title-main-#{lang}")
126
+ intro = node.attr("title-intro-#{lang}")
127
+ part = node.attr("title-part-#{lang}")
128
+ amd = node.attr("title-amendment-#{lang}")
129
+ title = "#{intro} -- #{title}" if intro
130
+ title = "#{title} -- #{part}" if part
131
+ title = "#{title} -- #{amd}" if amd && @amd
132
+ xml.title **attr_code(at.merge(type: "main")) do |t1|
133
+ t1 << Metanorma::Utils::asciidoc_sub(title)
134
+ end
135
+ end
136
+
137
+ def title(node, xml)
138
+ ["en", "fr"].each do |lang|
139
+ at = { language: lang, format: "text/plain" }
140
+ title_full(node, xml, lang, at)
141
+ title_intro(node, xml, lang, at)
142
+ title_main(node, xml, lang, at)
143
+ title_part(node, xml, lang, at)
144
+ title_amd(node, xml, lang, at) if @amd
145
+ end
146
+ end
147
+
148
+ def relaton_relations
149
+ super + %w(obsoletes successor-of manifestation-of related annotation-of)
150
+ end
151
+
152
+ def relaton_relation_descriptions
153
+ super.merge(
154
+ "amends" => "updates", "revises" => "updates",
155
+ "replaces" => "obsoletes",
156
+ "supersedes" => "obsoletes",
157
+ "corrects" => "updates",
158
+ "informatively-cited-in" => "isCitedIn",
159
+ "informatively-cites" => "cites",
160
+ "normatively-cited in" => "isCitedIn",
161
+ "normatively-cites" => "cites",
162
+ "identical-adopted-from" => "adoptedFrom",
163
+ "modified-adopted-from" => "adoptedFrom",
164
+ "related-directive" => "related",
165
+ "related-mandate" => "related",
166
+ )
167
+ end
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,225 @@
1
+ require "date"
2
+ require "nokogiri"
3
+ require "htmlentities"
4
+ require "json"
5
+ require "pathname"
6
+ require "open-uri"
7
+ require "twitter_cldr"
8
+
9
+ module Metanorma
10
+ module ISO
11
+ class Converter < Standoc::Converter
12
+ STAGE_ABBRS = {
13
+ "00": "PWI",
14
+ "10": "NP",
15
+ "20": "WD",
16
+ "30": "CD",
17
+ "40": "DIS",
18
+ "50": "FDIS",
19
+ "60": "IS",
20
+ "90": "(Review)",
21
+ "95": "(Withdrawal)",
22
+ }.freeze
23
+
24
+ STAGE_NAMES = {
25
+ "00": "Preliminary work item",
26
+ "10": "New work item proposal",
27
+ "20": "Working draft",
28
+ "30": "Committee draft",
29
+ "40": "Draft",
30
+ "50": "Final draft",
31
+ "60": "International standard",
32
+ "90": "Review",
33
+ "95": "Withdrawal",
34
+ }.freeze
35
+
36
+ def stage_abbr(stage, substage, doctype)
37
+ return nil if stage.to_i > 60
38
+
39
+ ret = STAGE_ABBRS[stage.to_sym]
40
+ ret = "PRF" if stage == "60" && substage == "00"
41
+ ret = "AWI" if stage == "10" && substage == "99"
42
+ if %w(amendment technical-corrigendum technical-report
43
+ technical-specification).include?(doctype)
44
+ ret = "D" if stage == "40" && doctype == "amendment"
45
+ ret = "FD" if stage == "50" && %w(amendment technical-corrigendum)
46
+ .include?(doctype)
47
+ end
48
+ ret
49
+ end
50
+
51
+ def stage_name(stage, substage, _doctype, iteration = nil)
52
+ return "Proof" if stage == "60" && substage == "00"
53
+
54
+ ret = STAGE_NAMES[stage.to_sym]
55
+ if iteration && %w(20 30).include?(stage)
56
+ prefix = iteration.to_i.localize(@lang.to_sym)
57
+ .to_rbnf_s("SpelloutRules", "spellout-ordinal")
58
+ ret = "#{prefix.capitalize} #{ret.downcase}"
59
+ end
60
+ ret
61
+ end
62
+
63
+ def metadata_id(node, xml)
64
+ iso_id(node, xml)
65
+ node&.attr("tc-docnumber")&.split(/,\s*/)&.each do |n|
66
+ xml.docidentifier(n, **attr_code(type: "iso-tc"))
67
+ end
68
+ xml.docnumber node&.attr("docnumber")
69
+ end
70
+
71
+ def iso_id(node, xml)
72
+ (!@amd && node.attr("docnumber")) || (@amd && node.attr("updates")) or
73
+ return
74
+
75
+ dn = iso_id1(node)
76
+ dn1 = id_stage_prefix(dn, node, false)
77
+ dn2 = id_stage_prefix(dn, node, true)
78
+ xml.docidentifier dn1, **attr_code(type: "ISO")
79
+ xml.docidentifier(id_langsuffix(dn1, node),
80
+ **attr_code(type: "iso-with-lang"))
81
+ xml.docidentifier(id_langsuffix(dn2, node),
82
+ **attr_code(type: "iso-reference"))
83
+ end
84
+
85
+ def iso_id1(node)
86
+ if @amd
87
+ dn = node.attr("updates")
88
+ add_amd_parts(dn, node)
89
+ else
90
+ part, subpart = node&.attr("partnumber")&.split(/-/)
91
+ add_id_parts(node.attr("docnumber"), part, subpart)
92
+ end
93
+ end
94
+
95
+ def add_amd_parts(docnum, node)
96
+ case doctype(node)
97
+ when "amendment"
98
+ "#{docnum}/Amd #{node.attr('amendment-number')}"
99
+ when "technical-corrigendum"
100
+ "#{docnum}/Cor.#{node.attr('corrigendum-number')}"
101
+ end
102
+ end
103
+
104
+ def id_langsuffix(docnum, node)
105
+ lang = node.attr("language") || "en"
106
+ suffix = case lang
107
+ when "en" then "(E)"
108
+ when "fr" then "(F)"
109
+ else
110
+ "(X)"
111
+ end
112
+ "#{docnum}#{suffix}"
113
+ end
114
+
115
+ def structured_id(node, xml)
116
+ return unless node.attr("docnumber")
117
+
118
+ part, subpart = node&.attr("partnumber")&.split(/-/)
119
+ xml.structuredidentifier do |i|
120
+ i.project_number(node.attr("docnumber"), **attr_code(
121
+ part: part, subpart: subpart,
122
+ amendment: node.attr("amendment-number"),
123
+ corrigendum: node.attr("corrigendum-number"),
124
+ origyr: node.attr("created-date")
125
+ ))
126
+ end
127
+ end
128
+
129
+ def add_id_parts(docnum, part, subpart)
130
+ docnum += "-#{part}" if part
131
+ docnum += "-#{subpart}" if subpart
132
+ docnum
133
+ end
134
+
135
+ def id_stage_abbr(stage, substage, node, bare = false)
136
+ ret = id_stage_abbr1(stage, substage, node, bare)
137
+ if %w(amendment technical-corrigendum technical-report
138
+ technical-specification).include?(doctype(node)) &&
139
+ !%w(D FD).include?(ret)
140
+ ret = "#{ret} "
141
+ end
142
+ ret
143
+ end
144
+
145
+ def id_stage_abbr1(stage, substage, node, bare)
146
+ if bare
147
+ IsoDoc::Iso::Metadata.new("en", "Latn", @i18n)
148
+ .status_abbrev(stage_abbr(stage, substage, doctype(node)),
149
+ substage, nil, nil, doctype(node))
150
+ else
151
+ IsoDoc::Iso::Metadata.new("en", "Latn", @i18n)
152
+ .status_abbrev(stage_abbr(stage, substage, doctype(node)),
153
+ substage, node.attr("iteration"),
154
+ node.attr("draft"), doctype(node))
155
+ end
156
+ end
157
+
158
+ def cover_stage_abbr(node)
159
+ stage = get_stage(node)
160
+ abbr = id_stage_abbr(get_stage(node), get_substage(node), node, true)
161
+ typeabbr = get_typeabbr(node, true)
162
+ if stage.to_i > 50 || (stage.to_i == 60 && get_substage(node).to_i < 60)
163
+ typeabbr = ""
164
+ end
165
+ "#{abbr}#{typeabbr}".strip
166
+ end
167
+
168
+ def id_stage_prefix(docnum, node, force_year)
169
+ stage = get_stage(node)
170
+ typeabbr = get_typeabbr(node)
171
+ if stage && (stage.to_i < 60)
172
+ docnum = unpub_stage_prefix(docnum, stage, typeabbr, node)
173
+ elsif typeabbr == "DIR " then docnum = "#{typeabbr}#{docnum}"
174
+ elsif typeabbr && !@amd then docnum = "/#{typeabbr}#{docnum}"
175
+ end
176
+ (force_year || !(stage && (stage.to_i < 60))) and
177
+ docnum = id_add_year(docnum, node)
178
+ docnum
179
+ end
180
+
181
+ def unpub_stage_prefix(docnum, stage, typeabbr, node)
182
+ abbr = id_stage_abbr(stage, get_substage(node), node)
183
+ %w(40 50).include?(stage) && i = node.attr("iteration") and
184
+ itersuffix = ".#{i}"
185
+ return docnum if abbr.nil? || abbr.empty? # prefixes added in cleanup
186
+ return "/#{abbr}#{typeabbr} #{docnum}#{itersuffix}" unless @amd
187
+
188
+ a = docnum.split(%r{/})
189
+ a[-1] = "#{abbr}#{a[-1]}#{itersuffix}"
190
+ a.join("/")
191
+ end
192
+
193
+ def id_add_year(docnum, node)
194
+ year = node.attr("copyright-year")
195
+ @amd and year ||= node.attr("updated-date")&.sub(/-.*$/, "")
196
+ docnum += ":#{year}" if year
197
+ docnum
198
+ end
199
+
200
+ def get_stage(node)
201
+ a = node.attr("status")
202
+ a = node.attr("docstage") if a.nil? || a.empty?
203
+ a = "60" if a.nil? || a.empty?
204
+ a
205
+ end
206
+
207
+ def get_substage(node)
208
+ stage = get_stage(node)
209
+ ret = node.attr("docsubstage")
210
+ ret = (stage == "60" ? "60" : "00") if ret.nil? || ret.empty?
211
+ ret
212
+ end
213
+
214
+ def get_typeabbr(node, amd = false)
215
+ case doctype(node)
216
+ when "directive" then "DIR "
217
+ when "technical-report" then "TR "
218
+ when "technical-specification" then "TS "
219
+ when "amendment" then (amd ? "Amd " : "")
220
+ when "technical-corrigendum" then (amd ? "Cor " : "")
221
+ end
222
+ end
223
+ end
224
+ end
225
+ end
@@ -32,6 +32,19 @@
32
32
  <ref name="DocumentType"/>
33
33
  </element>
34
34
  </define>
35
+ <define name="bibitem">
36
+ <element name="bibitem">
37
+ <attribute name="id">
38
+ <data type="ID"/>
39
+ </attribute>
40
+ <optional>
41
+ <attribute name="hidden">
42
+ <data type="boolean"/>
43
+ </attribute>
44
+ </optional>
45
+ <ref name="BibliographicItem"/>
46
+ </element>
47
+ </define>
35
48
  <define name="section-title">
36
49
  <element name="title">
37
50
  <zeroOrMore>
@@ -690,6 +703,7 @@
690
703
  <ref name="terms"/>
691
704
  <ref name="term-clause"/>
692
705
  <ref name="definitions"/>
706
+ <ref name="floating-title"/>
693
707
  </choice>
694
708
  </oneOrMore>
695
709
  </element>
@@ -1680,6 +1694,7 @@
1680
1694
  <ref name="clause-subsection"/>
1681
1695
  <ref name="terms"/>
1682
1696
  <ref name="definitions"/>
1697
+ <ref name="floating-title"/>
1683
1698
  </choice>
1684
1699
  </oneOrMore>
1685
1700
  </choice>
@@ -1722,6 +1737,7 @@
1722
1737
  <ref name="terms"/>
1723
1738
  <ref name="definitions"/>
1724
1739
  <ref name="references"/>
1740
+ <ref name="floating-title"/>
1725
1741
  </choice>
1726
1742
  </zeroOrMore>
1727
1743
  </group>
@@ -2534,4 +2550,17 @@
2534
2550
  </oneOrMore>
2535
2551
  </element>
2536
2552
  </define>
2553
+ <define name="floating-title">
2554
+ <element name="floating-title">
2555
+ <attribute name="id">
2556
+ <data type="ID"/>
2557
+ </attribute>
2558
+ <attribute name="depth">
2559
+ <data type="int"/>
2560
+ </attribute>
2561
+ <zeroOrMore>
2562
+ <ref name="TextElement"/>
2563
+ </zeroOrMore>
2564
+ </element>
2565
+ </define>
2537
2566
  </grammar>
File without changes
File without changes
File without changes