metanorma-gb 1.3.27 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/macos.yml +0 -1
  3. data/.github/workflows/ubuntu.yml +10 -7
  4. data/.github/workflows/windows.yml +0 -1
  5. data/.gitignore +0 -2
  6. data/Gemfile +0 -1
  7. data/Rakefile +17 -0
  8. data/lib/asciidoctor/gb/cleanup.rb +130 -0
  9. data/lib/asciidoctor/gb/converter.rb +25 -137
  10. data/lib/asciidoctor/gb/front_id.rb +3 -3
  11. data/lib/asciidoctor/gb/isodoc.rng +12 -6
  12. data/lib/asciidoctor/gb/section_input.rb +11 -0
  13. data/lib/asciidoctor/gb/validate.rb +0 -1
  14. data/lib/isodoc/gb/{gbbaseconvert.rb → base_convert.rb} +27 -79
  15. data/lib/isodoc/gb/{gbcleanup.rb → cleanup.rb} +0 -11
  16. data/lib/isodoc/gb/{gbconvert.rb → common.rb} +1 -1
  17. data/lib/isodoc/gb/gb.recommendation.xsl +752 -351
  18. data/lib/isodoc/gb/html/_coverpage.css +193 -0
  19. data/lib/isodoc/gb/html/gb.css +657 -0
  20. data/lib/isodoc/gb/html/htmlcompliantstyle.css +1303 -0
  21. data/lib/isodoc/gb/html/htmlcompliantstyle.scss +0 -1
  22. data/lib/isodoc/gb/html/htmlstyle.css +844 -0
  23. data/lib/isodoc/gb/html/wordstyle.css +2932 -0
  24. data/lib/isodoc/gb/{gbhtmlconvert.rb → html_convert.rb} +17 -14
  25. data/lib/isodoc/gb/i18n.rb +16 -0
  26. data/lib/isodoc/gb/init.rb +29 -0
  27. data/lib/isodoc/gb/metadata.rb +1 -1
  28. data/lib/isodoc/gb/pdf_convert.rb +2 -11
  29. data/lib/isodoc/gb/presentation_xml_convert.rb +26 -0
  30. data/lib/isodoc/gb/{gbwordconvert.rb → word_convert.rb} +21 -16
  31. data/lib/isodoc/gb/xref.rb +6 -0
  32. data/lib/metanorma-gb.rb +3 -3
  33. data/lib/metanorma/gb/processor.rb +13 -10
  34. data/lib/metanorma/gb/version.rb +1 -1
  35. data/metanorma-gb.gemspec +3 -2
  36. metadata +39 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 104fa3b5fc7d3e33240859aef77a0d5f58e5950f48e86e3926eaf0f111f4da2f
4
- data.tar.gz: 96f89d45b2037d39a2eb25eca6c71c1c744462ed722bc84e1fb9ea6506e16938
3
+ metadata.gz: fe9a20b1e4d09c3ed8151c2021f51c1b8e412f823f0363db5bf0b9e4eb182908
4
+ data.tar.gz: 6601454ed383cbb484434deebc8195d280a50f36282e0d84a096c1406751e322
5
5
  SHA512:
6
- metadata.gz: f1d08aeddfba0b2c6898a18a9d98afc55a8b60c8d4a4a5fc2f884c7db4ed3b8cc788579d044da88d77ee5afb19e05e123bb6a1be094c4954b80b360fe3441242
7
- data.tar.gz: bbb429a25e81dabe6e9ff1867d4b2ad0e3f743c827179a405d1439f19bc8e166c267d7a7eea4a323fc04082e5129a3d01dfa3842eeafff09f4337ece8485d02d
6
+ metadata.gz: fd3154c799e5794a5b9a7a13b8cfe3eb2d70a0a1b1bb36ea6e1d85a9b14d8a5658726320734105f5abfcf1f0c8990ce2e9ce681cbc8d600d0702430f8416f048
7
+ data.tar.gz: 8f90f5d26fe2601454ad8f6a27d6103d494443ce9948a25d2b2d697b9eb562018802cb08e529855916f2d8e7b4c0296e1e7001af8201374eda350ee4bf2fece0
@@ -29,7 +29,6 @@ jobs:
29
29
  uses: actions/setup-ruby@v1
30
30
  with:
31
31
  ruby-version: ${{ matrix.ruby }}
32
- architecture: 'x64'
33
32
  - name: Update gems
34
33
  run: |
35
34
  sudo gem install bundler --force
@@ -31,7 +31,6 @@ jobs:
31
31
  uses: actions/setup-ruby@v1
32
32
  with:
33
33
  ruby-version: ${{ matrix.ruby }}
34
- architecture: 'x64'
35
34
  - name: Update gems
36
35
  run: |
37
36
  gem install bundler
@@ -39,15 +38,19 @@ jobs:
39
38
  - name: Run specs
40
39
  run: |
41
40
  bundle exec rake
42
- - name: Trigger dependent repositories
43
- if: github.ref == 'refs/heads/master' && matrix.ruby == '2.6'
41
+ - name: Trigger repositories
42
+ if: matrix.ruby == '2.6'
44
43
  env:
45
- GH_USERNAME: ${{ secrets.PAT_USERNAME }}
46
- GH_ACCESS_TOKEN: ${{ secrets.PAT_TOKEN }}
44
+ GH_USERNAME: metanorma-ci
45
+ GH_ACCESS_TOKEN: ${{ secrets.METANORMA_CI_PAT_TOKEN }}
47
46
  run: |
48
47
  curl -LO --retry 3 https://raw.githubusercontent.com/metanorma/metanorma-build-scripts/master/trigger-gh-actions.sh
49
48
  [[ -f ".github/workflows/dependent_repos.env" ]] && source .github/workflows/dependent_repos.env
50
- for repo in $DEPENDENT_REPOS
49
+ CLIENT_PAYLOAD=$(cat <<EOF
50
+ "{ "ref": "${GITHUB_REF}", "repo": "${GITHUB_REPOSITORY}" }"
51
+ EOF
52
+ )
53
+ for repo in $REPOS
51
54
  do
52
- sh trigger-gh-actions.sh $ORGANISATION $repo $GH_USERNAME $GH_ACCESS_TOKEN $GITHUB_REPOSITORY "{ \"ref\": \"${GITHUB_REF}\" }"
55
+ sh trigger-gh-actions.sh $ORGANISATION $repo $GH_USERNAME $GH_ACCESS_TOKEN $GITHUB_REPOSITORY "$CLIENT_PAYLOAD"
53
56
  done
@@ -29,7 +29,6 @@ jobs:
29
29
  uses: actions/setup-ruby@v1
30
30
  with:
31
31
  ruby-version: ${{ matrix.ruby }}
32
- architecture: 'x64'
33
32
  - name: Update gems
34
33
  shell: pwsh
35
34
  run: |
data/.gitignore CHANGED
@@ -3,7 +3,5 @@ coverage/
3
3
  .rspec_status
4
4
  .tmp.xml
5
5
  gb-issuer-default.gif
6
- gb.css
7
- htmlstyle.css
8
6
  test.html
9
7
  test.xml
data/Gemfile CHANGED
@@ -3,7 +3,6 @@ Encoding.default_internal = Encoding::UTF_8
3
3
 
4
4
  source "https://rubygems.org"
5
5
  git_source(:github) { |repo| "https://github.com/#{repo}" }
6
-
7
6
  gemspec
8
7
 
9
8
  if File.exist? 'Gemfile.devel'
data/Rakefile CHANGED
@@ -1,6 +1,23 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
+ require 'isodoc/gem_tasks'
3
4
 
5
+ module IsoDoc
6
+ module GemTasks
7
+ module_function
8
+
9
+ def fonts_placeholder
10
+ <<~TEXT
11
+ $bodyfont: '{{bodyfont}}';
12
+ $headerfont: '{{headerfont}}';
13
+ $monospacefont: '{{monospacefont}}';
14
+ $titlefont: '{{titlefont}}';
15
+ TEXT
16
+ end
17
+ end
18
+ end
19
+
20
+ IsoDoc::GemTasks.install
4
21
  RSpec::Core::RakeTask.new(:spec)
5
22
 
6
23
  task :default => :spec
@@ -0,0 +1,130 @@
1
+ module Asciidoctor
2
+ module Gb
3
+ class Converter < ISO::Converter
4
+ def termdef_cleanup(xmldoc)
5
+ super
6
+ # TODO this should become variant tag
7
+ localisedstr(xmldoc)
8
+ end
9
+
10
+ ROMAN_TEXT = /\s*[a-z\u00c0-\u00d6\u00d8-\u00f0\u0100-\u0240]/i
11
+ HAN_TEXT = /\s*[\u4e00-\u9fff]+/
12
+
13
+ LOCALISED_ELEMS = "//admitted | //deprecates | //preferred | //prefix | "\
14
+ "//initial | //addition | //surname | //forename | //name | "\
15
+ "//abbreviation | //role/description | //affiliation/description | "\
16
+ "//bibdata/item | //bibitem/title | //bibdata/formattedref | "\
17
+ "//bibitem/formattedref | //bibdata/note | //bibitem/note | "\
18
+ "//bibdata/abstract | //bibitem/note ".freeze
19
+
20
+ MUST_LOCALISE_ELEMS = %w{admitted deprecates preferred}.freeze
21
+
22
+ def localisedstr(xmldoc)
23
+ xmldoc.xpath(LOCALISED_ELEMS).each do |zh|
24
+ if zh.at("./string")
25
+ extract_localisedstrings(zh)
26
+ elsif MUST_LOCALISE_ELEMS.include? zh.name
27
+ duplicate_localisedstrings(zh)
28
+ end
29
+ end
30
+ end
31
+
32
+ # element consists solely of localised strings, with no attributes
33
+ def extract_localisedstrings(elem)
34
+ elem.xpath("./string").each do |s|
35
+ s.name = elem.name
36
+ end
37
+ elem.replace(elem.children)
38
+ end
39
+
40
+ def text_clean(text)
41
+ text.gsub(/^\s*/, "").gsub(/</, "&lt;").gsub(/>/, "&gt;")
42
+ end
43
+
44
+ def duplicate_localisedstrings(zh)
45
+ en = zh.dup.remove
46
+ zh.after(en).after(" ")
47
+ zh["language"] = "zh"
48
+ en["language"] = "en"
49
+ en.traverse do |c|
50
+ c.text? && c.content = text_clean(c.text.gsub(HAN_TEXT, ""))
51
+ end
52
+ zh.traverse do |c|
53
+ c.text? && c.content = text_clean(c.text.gsub(ROMAN_TEXT, ""))
54
+ end
55
+ end
56
+
57
+ def termdef_boilerplate_cleanup(xmldoc)
58
+ return if @keepboilerplate
59
+ super
60
+ end
61
+
62
+ def cleanup(xmldoc)
63
+ lang = xmldoc.at("//language")&.text
64
+ @agencyclass = GbAgencies::Agencies.new(lang, {}, "")
65
+ super
66
+ contributor_cleanup(xmldoc)
67
+ xmldoc
68
+ end
69
+
70
+ def docidentifier_cleanup(xmldoc)
71
+ id = xmldoc.at("//bibdata/docidentifier[@type = 'gb']") or return
72
+ scope = xmldoc.at("//gbscope")&.text
73
+ prefix = xmldoc.at("//gbprefix")&.text
74
+ mand = xmldoc.at("//gbmandate")&.text || "mandatory"
75
+ idtext = @agencyclass.docidentifier(scope, prefix, mand, nil, id.text)
76
+ id.content = idtext&.gsub(/\&#x2002;/, " ")
77
+ id = xmldoc.at("//bibdata/ext/structuredidentifier/"\
78
+ "project-number") or return
79
+ idtext = @agencyclass.docidentifier(scope, prefix, mand, nil, id.text)
80
+ id.content = idtext&.gsub(/\&#x2002;/, " ")
81
+ end
82
+
83
+ def committee_cleanup(xmldoc)
84
+ xmldoc.xpath("//gbcommittee").each do |c|
85
+ xmldoc.at("//bibdata/contributor").next =
86
+ "<contributor><role type='technical-committee'/><organization>"\
87
+ "<name>#{c.text}</name></organization></contributor>"
88
+ end
89
+ end
90
+
91
+ def agency_value(issuer, scope, prefix, mandate)
92
+ agency = issuer.content
93
+ agency == "GB" and
94
+ agency = @agencyclass.standard_agency1(scope, prefix, mandate)
95
+ agency = "GB" if agency.nil? || agency.empty?
96
+ agency
97
+ end
98
+
99
+ def contributor_cleanup(xmldoc)
100
+ issuer = xmldoc.at("//bibdata/contributor[role/@type = 'issuer']/"\
101
+ "organization/name")
102
+ scope = xmldoc.at("//gbscope")&.text
103
+ prefix = xmldoc.at("//gbprefix")&.text
104
+ mandate = xmldoc.at("//gbmandate")&.text || "mandatory"
105
+ agency = agency_value(issuer, scope, prefix, mandate)
106
+ owner = xmldoc.at("//copyright/owner/organization/name")
107
+ owner.content = agency
108
+ issuer.content = agency
109
+ committee_cleanup(xmldoc)
110
+ end
111
+
112
+ def omit_docid_prefix(prefix)
113
+ IsoDoc::Gb::HtmlConvert.new({}).omit_docid_prefix(prefix)
114
+ end
115
+
116
+ def boilerplate_cleanup(xmldoc)
117
+ isodoc = boilerplate_isodoc(xmldoc)
118
+ initial_boilerplate(xmldoc, isodoc)
119
+ return if @keepboilerplate
120
+ xmldoc.xpath(self.class::TERM_CLAUSE).each do |f|
121
+ term_defs_boilerplate(f.at("./title"),
122
+ xmldoc.xpath(".//termdocsource"),
123
+ f.at(".//term"), f.at(".//p"), isodoc)
124
+ end
125
+ f = xmldoc.at(self.class::NORM_REF) and
126
+ norm_ref_preface(f)
127
+ end
128
+ end
129
+ end
130
+ end
@@ -1,13 +1,14 @@
1
1
  require "asciidoctor"
2
2
  require "asciidoctor/iso/converter"
3
- require "metanorma/gb/version"
4
- require "isodoc/gb/gbconvert"
5
- require "isodoc/gb/gbwordconvert"
3
+ require "isodoc/gb/common"
4
+ require "isodoc/gb/word_convert"
6
5
  require "isodoc/gb/pdf_convert"
6
+ require "isodoc/gb/presentation_xml_convert"
7
7
  require "gb_agencies"
8
8
  require_relative "./section_input.rb"
9
9
  require_relative "./front.rb"
10
10
  require_relative "./validate.rb"
11
+ require_relative "cleanup.rb"
11
12
  require "fileutils"
12
13
 
13
14
  module Asciidoctor
@@ -60,77 +61,28 @@ module Asciidoctor
60
61
  end
61
62
 
62
63
  def pdf_converter(node)
64
+ return nil if node.attr("no-pdf")
63
65
  node.nil? ? IsoDoc::Gb::PdfConvert.new({}) :
64
66
  IsoDoc::Gb::PdfConvert.new(doc_extract_attributes(node))
65
67
  end
66
68
 
67
- def document(node)
68
- init(node)
69
- ret = makexml(node).to_xml(indent: 2)
70
- unless node.attr("nodoc") || !node.attr("docfile")
71
- filename = node.attr("docfile").gsub(/\.adoc$/, "").gsub(%r{^.*/}, "")
72
- File.open(filename + ".xml", "w:utf-8") { |f| f.write(ret) }
73
- html_compliant_converter(node).convert(filename + ".xml")
74
- FileUtils.mv "#{filename}.html", "#{filename}_compliant.html"
75
- html_converter(node).convert(filename + ".xml")
76
- doc_converter(node).convert(filename + ".xml")
77
- pdf_converter(node).convert(filename + ".xml")
78
- end
79
- @log.write(@localdir + @filename + ".err") unless @novalid
80
- @files_to_delete.each { |f| FileUtils.rm f }
81
- ret
69
+ def presentation_xml_converter(node)
70
+ node.nil? ? IsoDoc::Gb::PresentationXMLConvert.new({}) :
71
+ IsoDoc::Gb::PresentationXMLConvert.new(html_extract_attributes(node))
82
72
  end
83
73
 
84
- def termdef_cleanup(xmldoc)
85
- super
86
- localisedstr(xmldoc)
87
- end
88
-
89
- ROMAN_TEXT = /\s*[a-z\u00c0-\u00d6\u00d8-\u00f0\u0100-\u0240]/i
90
- HAN_TEXT = /\s*[\u4e00-\u9fff]+/
91
-
92
- LOCALISED_ELEMS = "//admitted | //deprecates | //preferred | //prefix | "\
93
- "//initial | //addition | //surname | //forename | //name | "\
94
- "//abbreviation | //role/description | //affiliation/description | "\
95
- "//bibdata/item | //bibitem/title | //bibdata/formattedref | "\
96
- "//bibitem/formattedref | //bibdata/note | //bibitem/note | "\
97
- "//bibdata/abstract | //bibitem/note ".freeze
98
-
99
- MUST_LOCALISE_ELEMS = %w{admitted deprecates preferred}.freeze
100
-
101
- def localisedstr(xmldoc)
102
- xmldoc.xpath(LOCALISED_ELEMS).each do |zh|
103
- if zh.at("./string")
104
- extract_localisedstrings(zh)
105
- elsif MUST_LOCALISE_ELEMS.include? zh.name
106
- duplicate_localisedstrings(zh)
107
- end
108
- end
109
- end
110
-
111
- # element consists solely of localised strings, with no attributes
112
- def extract_localisedstrings(elem)
113
- elem.xpath("./string").each do |s|
114
- s.name = elem.name
115
- end
116
- elem.replace(elem.children)
117
- end
118
-
119
- def text_clean(text)
120
- text.gsub(/^\s*/, "").gsub(/</, "&lt;").gsub(/>/, "&gt;")
121
- end
122
-
123
- def duplicate_localisedstrings(zh)
124
- en = zh.dup.remove
125
- zh.after(en).after(" ")
126
- zh["language"] = "zh"
127
- en["language"] = "en"
128
- en.traverse do |c|
129
- c.text? && c.content = text_clean(c.text.gsub(HAN_TEXT, ""))
130
- end
131
- zh.traverse do |c|
132
- c.text? && c.content = text_clean(c.text.gsub(ROMAN_TEXT, ""))
133
- end
74
+ def outputs(node, ret)
75
+ File.open(@filename + ".xml", "w:UTF-8") { |f| f.write(ret) }
76
+ presentation_xml_converter(node).convert(@filename + ".xml")
77
+ html_compliant_converter(node).
78
+ convert(@filename + ".presentation.xml",
79
+ nil, false, "#{@filename}_compliant.html")
80
+ html_converter(node).convert(@filename + ".presentation.xml",
81
+ nil, false, "#{@filename}.html")
82
+ doc_converter(node).convert(@filename + ".presentation.xml",
83
+ nil, false, "#{@filename}.doc")
84
+ pdf_converter(node)&.convert(@filename + ".presentation.xml",
85
+ nil, false, "#{@filename}.pdf")
134
86
  end
135
87
 
136
88
  def inline_quoted(node)
@@ -150,11 +102,6 @@ module Asciidoctor
150
102
  super
151
103
  end
152
104
 
153
- def termdef_boilerplate_cleanup(xmldoc)
154
- return if @keepboilerplate
155
- super
156
- end
157
-
158
105
  GBCODE = "((AQ|BB|CB|CH|CJ|CY|DA|DB|DL|DZ|EJ|FZ|GA|GH|GM|GY|HB|HG|"\
159
106
  "HJ|HS|HY|JB|JC|JG|JR|JT|JY|LB|LD|LS|LY|MH|MT|MZ|NY|QB|QC|QJ|"\
160
107
  "QZ|SB|SC|SH|SJ|SN|SY|TB|TD|TJ|TY|WB|WH|WJ|WM|WS|WW|XB|YB|YC|"\
@@ -187,71 +134,12 @@ module Asciidoctor
187
134
  super
188
135
  end
189
136
 
190
- def cleanup(xmldoc)
191
- lang = xmldoc.at("//language")&.text
192
- @agencyclass = GbAgencies::Agencies.new(lang, {}, "")
137
+ def init(node)
138
+ node.attr("language") or node.set_attr("language", "zh")
139
+ node.attr("script") or
140
+ node.set_attr("script", node.attr("language") == "zh" ?
141
+ "Hans" : "Latn")
193
142
  super
194
- contributor_cleanup(xmldoc)
195
- xmldoc
196
- end
197
-
198
- def docidentifier_cleanup(xmldoc)
199
- id = xmldoc.at("//bibdata/docidentifier[@type = 'gb']") or return
200
- scope = xmldoc.at("//gbscope")&.text
201
- prefix = xmldoc.at("//gbprefix")&.text
202
- mand = xmldoc.at("//gbmandate")&.text || "mandatory"
203
- idtext = @agencyclass.docidentifier(scope, prefix, mand, nil, id.text)
204
- id.content = idtext&.gsub(/\&#x2002;/, " ")
205
- id = xmldoc.at("//bibdata/ext/structuredidentifier/"\
206
- "project-number") or return
207
- idtext = @agencyclass.docidentifier(scope, prefix, mand, nil, id.text)
208
- id.content = idtext&.gsub(/\&#x2002;/, " ")
209
- end
210
-
211
- def committee_cleanup(xmldoc)
212
- xmldoc.xpath("//gbcommittee").each do |c|
213
- xmldoc.at("//bibdata/contributor").next =
214
- "<contributor><role type='technical-committee'/><organization>"\
215
- "<name>#{c.text}</name></organization></contributor>"
216
- end
217
- end
218
-
219
- def agency_value(issuer, scope, prefix, mandate)
220
- agency = issuer.content
221
- agency == "GB" and
222
- agency = @agencyclass.standard_agency1(scope, prefix, mandate)
223
- agency = "GB" if agency.nil? || agency.empty?
224
- agency
225
- end
226
-
227
- def contributor_cleanup(xmldoc)
228
- issuer = xmldoc.at("//bibdata/contributor[role/@type = 'issuer']/"\
229
- "organization/name")
230
- scope = xmldoc.at("//gbscope")&.text
231
- prefix = xmldoc.at("//gbprefix")&.text
232
- mandate = xmldoc.at("//gbmandate")&.text || "mandatory"
233
- agency = agency_value(issuer, scope, prefix, mandate)
234
- owner = xmldoc.at("//copyright/owner/organization/name")
235
- owner.content = agency
236
- issuer.content = agency
237
- committee_cleanup(xmldoc)
238
- end
239
-
240
- def omit_docid_prefix(prefix)
241
- IsoDoc::Gb::HtmlConvert.new({}).omit_docid_prefix(prefix)
242
- end
243
-
244
- def boilerplate_cleanup(xmldoc)
245
- isodoc = boilerplate_isodoc(xmldoc)
246
- initial_boilerplate(xmldoc, isodoc)
247
- return if @keepboilerplate
248
- xmldoc.xpath(self.class::TERM_CLAUSE).each do |f|
249
- term_defs_boilerplate(f.at("./title"),
250
- xmldoc.xpath(".//termdocsource"),
251
- f.at(".//term"), f.at(".//p"), isodoc)
252
- end
253
- f = xmldoc.at(self.class::NORM_REF) and
254
- norm_ref_preface(f)
255
143
  end
256
144
  end
257
145
  end
@@ -1,7 +1,7 @@
1
1
  module Asciidoctor
2
2
  module Gb
3
3
  class Converter < ISO::Converter
4
- STAGE_ABBRS_CN = {
4
+ STAGE_ABBRS_CN = {
5
5
  "00": "新工作项目建议",
6
6
  "10": "新工作项目",
7
7
  "20": "标准草案工作组讨论稿",
@@ -15,7 +15,7 @@ module Asciidoctor
15
15
 
16
16
  def stage_name(stage, substage)
17
17
  return "Proof" if stage == "60" && substage == "00"
18
- @language == "en" ?
18
+ @lang == "en" ?
19
19
  STAGE_NAMES[stage.to_sym] : STAGE_ABBRS_CN[stage.to_sym]
20
20
  end
21
21
 
@@ -43,7 +43,7 @@ module Asciidoctor
43
43
 
44
44
  def id_stage_prefix(dn, node)
45
45
  if node.attr("docstage") && node.attr("docstage").to_i < 60
46
- abbr = IsoDoc::Gb::Metadata.new("en", "Latn", {}).
46
+ abbr = IsoDoc::Gb::Metadata.new("en", "Latn", @i18n).
47
47
  status_abbrev(node.attr("docstage"), nil, node.attr("iteration"),
48
48
  node.attr("draft"), node.attr("doctype"))
49
49
  dn = "/#{abbr} #{dn}" # prefixes added in cleanup