metanorma-iso 2.0.8.1 → 2.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/lib/html2doc/lists.rb +169 -0
  3. data/lib/isodoc/iso/base_convert.rb +11 -1
  4. data/lib/isodoc/iso/html/html_iso_titlepage.html +7 -0
  5. data/lib/isodoc/iso/html/isodoc-dis.css +407 -427
  6. data/lib/isodoc/iso/html/isodoc-dis.scss +482 -438
  7. data/lib/isodoc/iso/html/isodoc.css +38 -13
  8. data/lib/isodoc/iso/html/isodoc.scss +38 -12
  9. data/lib/isodoc/iso/html/style-human.css +14 -1
  10. data/lib/isodoc/iso/html/style-human.scss +10 -1
  11. data/lib/isodoc/iso/html/style-iso.css +35 -23
  12. data/lib/isodoc/iso/html/style-iso.scss +31 -23
  13. data/lib/isodoc/iso/html/word_iso_intro-dis.html +3 -1
  14. data/lib/isodoc/iso/html/word_iso_titlepage-dis.html +26 -13
  15. data/lib/isodoc/iso/html/word_iso_titlepage-prf.html +58 -0
  16. data/lib/isodoc/iso/html/word_iso_titlepage.html +16 -6
  17. data/lib/isodoc/iso/html/wordstyle-dis.css +168 -48
  18. data/lib/isodoc/iso/html/wordstyle-dis.scss +158 -43
  19. data/lib/isodoc/iso/html_convert.rb +7 -2
  20. data/lib/isodoc/iso/i18n-en.yaml +33 -4
  21. data/lib/isodoc/iso/i18n-fr.yaml +30 -3
  22. data/lib/isodoc/iso/i18n-ru.yaml +33 -4
  23. data/lib/isodoc/iso/i18n-zh-Hans.yaml +33 -3
  24. data/lib/isodoc/iso/i18n.rb +1 -1
  25. data/lib/isodoc/iso/init.rb +17 -1
  26. data/lib/isodoc/iso/iso.amendment.xsl +1711 -367
  27. data/lib/isodoc/iso/iso.international-standard.xsl +1711 -367
  28. data/lib/isodoc/iso/metadata.rb +72 -78
  29. data/lib/isodoc/iso/presentation_bibdata.rb +74 -0
  30. data/lib/isodoc/iso/presentation_xml_convert.rb +52 -100
  31. data/lib/isodoc/iso/presentation_xref.rb +132 -0
  32. data/lib/isodoc/iso/sections.rb +3 -3
  33. data/lib/isodoc/iso/word_cleanup.rb +17 -0
  34. data/lib/isodoc/iso/word_convert.rb +32 -12
  35. data/lib/isodoc/iso/word_dis_cleanup.rb +235 -0
  36. data/lib/isodoc/iso/word_dis_convert.rb +122 -0
  37. data/lib/isodoc/iso/xref.rb +78 -29
  38. data/lib/metanorma/iso/base.rb +20 -1
  39. data/lib/metanorma/iso/biblio.rng +69 -42
  40. data/lib/metanorma/iso/boilerplate-fr.xml +4 -1
  41. data/lib/metanorma/iso/boilerplate-ru.xml +4 -3
  42. data/lib/metanorma/iso/boilerplate.xml +4 -3
  43. data/lib/metanorma/iso/cleanup.rb +29 -1
  44. data/lib/metanorma/iso/front.rb +31 -6
  45. data/lib/metanorma/iso/front_id.rb +2 -0
  46. data/lib/metanorma/iso/isodoc.rng +65 -0
  47. data/lib/metanorma/iso/isostandard.rng +30 -12
  48. data/lib/metanorma/iso/macros.rb +29 -0
  49. data/lib/metanorma/iso/version.rb +1 -1
  50. data/lib/metanorma-iso.rb +1 -0
  51. data/lib/relaton/render/config.yml +4 -0
  52. data/lib/relaton/render/general.rb +13 -0
  53. data/metanorma-iso.gemspec +1 -1
  54. data/spec/isodoc/amd_spec.rb +35 -60
  55. data/spec/isodoc/blocks_spec.rb +783 -179
  56. data/spec/isodoc/i18n_spec.rb +331 -100
  57. data/spec/isodoc/inline_spec.rb +35 -42
  58. data/spec/isodoc/iso_spec.rb +51 -170
  59. data/spec/isodoc/metadata_spec.rb +240 -99
  60. data/spec/isodoc/postproc_spec.rb +68 -7
  61. data/spec/isodoc/ref_spec.rb +66 -69
  62. data/spec/isodoc/section_spec.rb +88 -80
  63. data/spec/isodoc/table_spec.rb +2 -2
  64. data/spec/isodoc/terms_spec.rb +2 -2
  65. data/spec/isodoc/word_dis_spec.rb +1886 -0
  66. data/spec/isodoc/xref_spec.rb +138 -64
  67. data/spec/metanorma/amd_spec.rb +53 -1
  68. data/spec/metanorma/base_spec.rb +195 -20
  69. data/spec/metanorma/blocks_spec.rb +54 -0
  70. data/spec/metanorma/lists_spec.rb +2 -2
  71. data/spec/metanorma/section_spec.rb +2 -2
  72. data/spec/spec_helper.rb +23 -4
  73. data/spec/vcr_cassettes/withdrawn_iso.yml +25 -25
  74. metadata +15 -10
  75. data/docs/asciiiso-syntax.adoc +0 -307
  76. data/docs/guidance.adoc +0 -487
  77. data/docs/navigation.adoc +0 -23
  78. data/docs/quickstart.adoc +0 -179
  79. data/spec/vcr_cassettes/docrels.yml +0 -385
@@ -1,7 +1,7 @@
1
1
  module IsoDoc
2
2
  module Iso
3
3
  module BaseConvert
4
- def middle_title(isoxml, out)
4
+ def middle_title(_isoxml, out)
5
5
  middle_title_main(out)
6
6
  middle_title_amd(out)
7
7
  end
@@ -9,9 +9,9 @@ module IsoDoc
9
9
  def middle_title_main(out)
10
10
  out.p(**{ class: "zzSTDTitle1" }) do |p|
11
11
  p << @meta.get[:doctitleintro]
12
- p << " &mdash; " if @meta.get[:doctitleintro] && @meta.get[:doctitlemain]
12
+ p << " &#x2014; " if @meta.get[:doctitleintro] && @meta.get[:doctitlemain]
13
13
  p << @meta.get[:doctitlemain]
14
- p << " &mdash; " if @meta.get[:doctitlemain] && @meta.get[:doctitlepart]
14
+ p << " &#x2014; " if @meta.get[:doctitlemain] && @meta.get[:doctitlepart]
15
15
  end
16
16
  a = @meta.get[:doctitlepart] and out.p(**{ class: "zzSTDTitle2" }) do |p|
17
17
  b = @meta.get[:doctitlepartlabel] and p << "#{b}: "
@@ -44,6 +44,9 @@ module IsoDoc
44
44
  docxml.xpath("//*[@class = 'example']").each do |p|
45
45
  p["class"] = "Example"
46
46
  end
47
+ docxml.xpath("//*[@class = 'zzHelp']/p[not(@class)]").each do |p|
48
+ p["class"] = "zzHelp"
49
+ end
47
50
  end
48
51
 
49
52
  def authority_hdr_cleanup(docxml)
@@ -81,6 +84,7 @@ module IsoDoc
81
84
  p["class"] = "zzCopyright1"
82
85
  end
83
86
  auth and insert and insert.children = auth
87
+ coverpage_note_cleanup(docxml)
84
88
  end
85
89
 
86
90
  def word_cleanup(docxml)
@@ -89,6 +93,19 @@ module IsoDoc
89
93
  style_cleanup(docxml)
90
94
  docxml
91
95
  end
96
+
97
+ # supply missing annex title
98
+ def make_WordToC(docxml, level)
99
+ toc = ""
100
+ xpath = (1..level).each.map { |i| "//h#{i}" }.join (" | ")
101
+ docxml.xpath(xpath).each do |h|
102
+ x = ""
103
+ x = @anchor[h.parent["id"]][:xref] if h["class"] == "ANNEX"
104
+ toc += word_toc_entry(h.name[1].to_i, x + header_strip(h))
105
+ end
106
+ toc.sub(/(<p class="MsoToc1">)/,
107
+ %{\\1#{word_toc_preface(level)}}) + WORD_TOC_SUFFIX1
108
+ end
92
109
  end
93
110
  end
94
111
  end
@@ -2,6 +2,7 @@ require_relative "base_convert"
2
2
  require "isodoc"
3
3
  require_relative "init"
4
4
  require_relative "word_cleanup"
5
+ require_relative "word_dis_convert"
5
6
 
6
7
  module IsoDoc
7
8
  module Iso
@@ -13,6 +14,12 @@ module IsoDoc
13
14
  @wordToClevels = 3 if @wordToClevels.zero?
14
15
  @htmlToClevels = options[:htmltoclevels].to_i
15
16
  @htmlToClevels = 3 if @htmlToClevels.zero?
17
+ init_dis(options)
18
+ end
19
+
20
+ def init_dis(options)
21
+ @wordtemplate = options[:isowordtemplate]
22
+ @dis = ::IsoDoc::Iso::WordDISConvert.new(options)
16
23
  end
17
24
 
18
25
  def font_choice(options)
@@ -45,16 +52,18 @@ module IsoDoc
45
52
  olstyle: "l2" }
46
53
  end
47
54
 
48
- def convert1(docxml, filename, dir)
49
- @dis = /^[45].$/.match?(docxml&.at(ns("//bibdata/status/stage"))&.text)
50
- if @dis
51
- @wordstylesheet_name = html_doc_path("wordstyle-dis.scss")
52
- @standardstylesheet_name = html_doc_path("isodoc-dis.scss")
53
- @wordcoverpage = html_doc_path("word_iso_titlepage-dis.html")
54
- @wordintropage = html_doc_path("word_iso_intro-dis.html")
55
- @header = html_doc_path("header-dis.html")
55
+ def convert(input_filename, file = nil, debug = false,
56
+ output_filename = nil)
57
+ file = File.read(input_filename, encoding: "utf-8") if file.nil?
58
+ docxml = Nokogiri::XML(file) { |config| config.huge }
59
+ stage = docxml&.at(ns("//bibdata/status/stage"))&.text
60
+ if @dis &&
61
+ ((/^[4569].$/.match?(stage) && @wordtemplate != "simple") ||
62
+ (/^[0-3].$/.match?(stage) && @wordtemplate == "dis"))
63
+ @dis.convert(input_filename, file, debug, output_filename)
64
+ else
65
+ super
56
66
  end
57
- super
58
67
  end
59
68
 
60
69
  def make_body(xml, docxml)
@@ -82,8 +91,8 @@ module IsoDoc
82
91
  <span lang="EN-GB"><span
83
92
  style='mso-element:field-begin'></span><span
84
93
  style='mso-spacerun:yes'>&#xA0;</span>TOC
85
- \\o &quot;1-#{level}&quot; \\h \\z \\t &quot;Heading
86
- 1;1;ANNEX;1;Biblio Title;1;Foreword Title;1;Intro Title;1&quot; <span
94
+ \\o "1-#{level}" \\h \\z \\t "Heading
95
+ 1;1;ANNEX;1;Biblio Title;1;Foreword Title;1;Intro Title;1" <span
87
96
  style='mso-element:field-separator'></span></span>
88
97
  TOC
89
98
  end
@@ -171,11 +180,22 @@ module IsoDoc
171
180
 
172
181
  name&.at(ns("./strong"))&.remove # supplied by CSS list numbering
173
182
  div.h1 **{ class: "Annex" } do |t|
174
- name.children.each { |c2| parse(c2, t) }
183
+ annex_name1(name, t)
175
184
  clause_parse_subtitle(name, t)
176
185
  end
177
186
  end
178
187
 
188
+ def annex_name1(name, out)
189
+ name.children.each do |c2|
190
+ if c2.name == "span" && c2["class"] == "obligation"
191
+ out.span **{ style: "font-weight:normal;" } do |s|
192
+ c2.children.each { |c3| parse(c3, s) }
193
+ end
194
+ else parse(c2, out)
195
+ end
196
+ end
197
+ end
198
+
179
199
  include BaseConvert
180
200
  include Init
181
201
  end
@@ -0,0 +1,235 @@
1
+ module IsoDoc
2
+ module Iso
3
+ class WordDISConvert < WordConvert
4
+ def style_cleanup(docxml)
5
+ super
6
+ dis_styles(docxml)
7
+ end
8
+
9
+ STYLESMAP = {
10
+ AltTerms: "AdmittedTerm",
11
+ TableFootnote: "Tablefootnote",
12
+ formula: "Formula",
13
+ note: "Note",
14
+ example: "Example",
15
+ admonition: "Admonition",
16
+ admonitiontitle: "AdmonitionTitle",
17
+ sourcetitle: "SourceTitle",
18
+ tabletitle: "TableTitle",
19
+ titlepagesbhead: "TablePageSubhead",
20
+ NormRef: "RefNorm",
21
+ Biblio: "BiblioEntry",
22
+ MsoNormal: "MsoBodyText",
23
+ FigureTitle: "Figuretitle",
24
+ zzwarning: "zzWarning",
25
+ zzwarninghdr: "zzWarningHdr",
26
+ quoteattribution: "QuoteAttribution",
27
+ Sourcecode: "Code",
28
+ zzSTDTitle1: "zzSTDTitle",
29
+ zzSTDTitle2: "zzSTDTitle",
30
+ zzCopyright1: "zzCopyright",
31
+ }.freeze
32
+
33
+ def dis_styles(docxml)
34
+ STYLESMAP.each do |k, v|
35
+ docxml.xpath("//*[@class = '#{k}']").each { |s| s["class"] = v }
36
+ end
37
+ docxml.xpath("//h1[@class = 'ForewordTitle' or @class = 'IntroTitle']")
38
+ .each { |h| h.name = "p" }
39
+ dis_styles1(docxml)
40
+ docxml.xpath("//p[not(@class)]").each { |p| p["class"] = "MsoBodyText" }
41
+ end
42
+
43
+ def dis_styles1(docxml)
44
+ amd_style(docxml)
45
+ code_style(docxml)
46
+ figure_style(docxml)
47
+ note_style(docxml)
48
+ example_style(docxml)
49
+ quote_style(docxml)
50
+ dis_style_interactions(docxml)
51
+ end
52
+
53
+ def dis_style_interactions(docxml)
54
+ docxml.xpath("//p[@class = 'Code' or @class = 'Code-' or "\
55
+ "@class = 'Code--']"\
56
+ "[following::p[@class = 'Examplecontinued']]").each do |p|
57
+ p["style"] ||= ""
58
+ p["style"] = "margin-bottom:12pt;#{p['style']}"
59
+ end
60
+ end
61
+
62
+ def amd_style(docxml)
63
+ return unless @meta.get[:doctype] == "Amendment"
64
+
65
+ docxml.xpath("//div[@class = 'WordSection3']//h1").each do |h|
66
+ h.name = "p"
67
+ h["style"] = "font-style:italic;page-break-after:avoid;"
68
+ end
69
+ end
70
+
71
+ def quote_style(docxml)
72
+ docxml.xpath("//div[@class = 'Quote' or @class = 'Note' or "\
73
+ "@class = 'Example' or @class = 'Admonition']").each do |d|
74
+ quote_style1(d)
75
+ end
76
+ end
77
+
78
+ def para_style_change(div, class1, class2)
79
+ s = class1 ? "@class = '#{class1}'" : "not(@class)"
80
+ div.xpath(".//p[#{s}]").each do |p|
81
+ p["class"] = class2
82
+ end
83
+ end
84
+
85
+ def quote_style1(div)
86
+ para_style_change(div, nil, "BodyTextindent1")
87
+ para_style_change(div, "Code-", "Code--")
88
+ para_style_change(div, "Code", "Code-")
89
+ if div["class"] != "Example"
90
+ para_style_change(div, "Example", "Exampleindent")
91
+ para_style_change(div, "Examplecontinued", "Exampleindentcontinued")
92
+ end
93
+ if div["class"] != "Note"
94
+ para_style_change(div, "Note", "Noteindent")
95
+ para_style_change(div, "Notecontinued", "Noteindentcontinued")
96
+ end
97
+ div.xpath(".//table[@class = 'dl']").each do |t|
98
+ t["style"] = "margin-left: 1cm;"
99
+ end
100
+ end
101
+
102
+ def remove_note_label(doc)
103
+ doc.xpath("//span[@class = 'note_label' or @class = 'example_label']")
104
+ .each do |s|
105
+ s.replace(s.children)
106
+ end
107
+ end
108
+
109
+ def note_style(docxml)
110
+ remove_note_label(docxml)
111
+ note_continued_style(docxml)
112
+ end
113
+
114
+ def example_style(docxml)
115
+ example_continued_style(docxml)
116
+ end
117
+
118
+ def example_continued_style(docxml)
119
+ docxml.xpath("//div[@class = 'Example']").each do |d|
120
+ d.xpath("./p").each_with_index do |p, i|
121
+ next if p["class"] && p["class"] != "Example"
122
+
123
+ p["class"] = (i.zero? ? "Example" : "Examplecontinued")
124
+ end
125
+ end
126
+ end
127
+
128
+ def note_continued_style(docxml)
129
+ docxml.xpath("//div[@class = 'Note']").each do |d|
130
+ d.xpath("./p").each_with_index do |p, i|
131
+ next if p["class"] && p["class"] != "Note"
132
+
133
+ p["class"] = (i.zero? ? "Note" : "Notecontinued")
134
+ end
135
+ end
136
+ end
137
+
138
+ FIGURE_NESTED_STYLES =
139
+ { Note: "Figurenote", example: "Figureexample" }.freeze
140
+
141
+ def figure_style(docxml)
142
+ docxml.xpath("//div[@class = 'figure']").each do |f|
143
+ FIGURE_NESTED_STYLES.each do |k, v|
144
+ f.xpath(".//*[@class = '#{k}']").each { |n| n["class"] = v }
145
+ end
146
+ f.xpath("./img").each do |i|
147
+ i.replace("<p class='FigureGraphic'>#{i.to_xml}</p>")
148
+ end
149
+ end
150
+ end
151
+
152
+ def code_style(doc)
153
+ span_style((doc.xpath("//tt//b") - doc.xpath("//tt//i//b")),
154
+ "ISOCodebold")
155
+ span_style((doc.xpath("//tt//i") - doc.xpath("//tt//b//i")),
156
+ "ISOCodeitalic")
157
+ span_style((doc.xpath("//b//tt") - doc.xpath("//b//i//tt")),
158
+ "ISOCodebold")
159
+ span_style((doc.xpath("//i//tt") - doc.xpath("//i//b//tt")),
160
+ "ISOCodeitalic")
161
+ span_style(doc.xpath("//tt"), "ISOCode")
162
+ end
163
+
164
+ def span_style(xpath, style)
165
+ xpath.each do |elem|
166
+ elem.name = "span"
167
+ elem["class"] = style
168
+ end
169
+ end
170
+
171
+ def word_annex_cleanup1(docxml, lvl)
172
+ docxml.xpath("//h#{lvl}[ancestor::*[@class = 'Section3']]").each do |h2|
173
+ h2.name = "p"
174
+ h2["class"] = "a#{lvl}"
175
+ end
176
+ end
177
+
178
+ def word_cleanup(docxml)
179
+ word_table_cell_para(docxml)
180
+ super
181
+ word_section_end_empty_para(docxml)
182
+ docxml
183
+ end
184
+
185
+ def authority_cleanup(docxml)
186
+ super
187
+ if @meta.get[:stage_int].to_s[0] == "9" ||
188
+ @meta.get[:stage_int].to_s[0] == "6"
189
+ copyright_prf(docxml)
190
+ else
191
+ copyright_dis(docxml)
192
+ end
193
+ end
194
+
195
+ def copyright_prf(docxml)
196
+ docxml.xpath("//p[@id = 'boilerplate-address']")&.each do |p|
197
+ p["class"] = "zzCopyright"
198
+ p["style"] = "text-indent:20.15pt;"
199
+ p.replace(p.to_xml.gsub(%r{<br/>}, "</p>\n<p class='zzCopyright' "\
200
+ "style='text-indent:20.15pt;'>"))
201
+ end
202
+ docxml.xpath("//p[@class = 'zzCopyrightHdr']")&.each do |p|
203
+ # p["class"] = "zzCopyright"
204
+ p.remove
205
+ end
206
+ end
207
+
208
+ def copyright_dis(docxml)
209
+ docxml.xpath("//p[@id = 'boilerplate-address']")&.each do |p|
210
+ p["class"] = "zzCopyright"
211
+ p.replace(p.to_xml.gsub(%r{<br/>}, "</p>\n<p class='zzCopyright'>"))
212
+ end
213
+ docxml.xpath("//p[@class = 'zzCopyrightHdr']")&.each do |p|
214
+ p.remove
215
+ end
216
+ end
217
+
218
+ def word_section_end_empty_para(docxml)
219
+ docxml.at("//div[@class='WordSection1']/p[last()]").remove
220
+ end
221
+
222
+ def word_table_cell_para(docxml)
223
+ docxml.xpath("//td | //th").each do |t|
224
+ s = t["header"] == "true" ? "Tableheader" : "Tablebody"
225
+ t.delete("header")
226
+ if t.at("./p |./div")
227
+ t.xpath("./p | ./div").each { |p| p["class"] = s }
228
+ else
229
+ t.children = "<div class='#{s}'>#{t.children.to_xml}</div>"
230
+ end
231
+ end
232
+ end
233
+ end
234
+ end
235
+ end
@@ -0,0 +1,122 @@
1
+ require_relative "word_dis_cleanup"
2
+
3
+ module IsoDoc
4
+ module Iso
5
+ class WordDISConvert < WordConvert
6
+ def default_file_locations(_options)
7
+ { wordstylesheet: html_doc_path("wordstyle-dis.scss"),
8
+ standardstylesheet: html_doc_path("isodoc-dis.scss"),
9
+ header: html_doc_path("header-dis.html"),
10
+ wordcoverpage: html_doc_path("word_iso_titlepage-dis.html"),
11
+ wordintropage: html_doc_path("word_iso_intro-dis.html"),
12
+ ulstyle: "l3",
13
+ olstyle: "l2" }
14
+ end
15
+
16
+ def initialize(options)
17
+ @libdir ||= File.dirname(__FILE__) # rubocop:disable Lint/DisjunctiveAssignmentInConstructor
18
+ options.merge!(default_file_locations(options))
19
+ super
20
+ end
21
+
22
+ def init_dis(options); end
23
+
24
+ def convert1(docxml, filename, dir)
25
+ update_coverpage(docxml)
26
+ super
27
+ end
28
+
29
+ def update_coverpage(docxml)
30
+ stage = docxml.at(ns("//bibdata/status/stage"))&.text
31
+ substage = docxml.at(ns("//bibdata/status/substage"))&.text
32
+ if /^9/.match?(stage) || (stage == "60" && substage == "60")
33
+ @wordcoverpage = html_doc_path("word_iso_titlepage.html")
34
+ elsif stage == "60" && substage == "00"
35
+ @wordcoverpage = html_doc_path("word_iso_titlepage-prf.html")
36
+ end
37
+ end
38
+
39
+ def figure_name_attrs(_node)
40
+ { class: "FigureTitle", style: "text-align:center;" }
41
+ end
42
+
43
+ def table_title_attrs(_node)
44
+ { class: "Tabletitle", style: "text-align:center;" }
45
+ end
46
+
47
+ def span_parse(node, out)
48
+ out.span **{ class: node["class"] } do |x|
49
+ node.children.each { |n| parse(n, x) }
50
+ end
51
+ end
52
+
53
+ def word_toc_preface(level)
54
+ <<~TOC.freeze
55
+ <span lang="EN-GB"><span
56
+ style='mso-element:field-begin'></span><span
57
+ style='mso-spacerun:yes'>&#xA0;</span>TOC \\o "2-#{level}" \\h \\z \\t
58
+ "Heading 1,1,ANNEX,1,Biblio Title,1,Foreword Title,1,Intro Title,1,ANNEXN,1,ANNEXZ,1,na2,1,na3,1,na4,1,na5,1,na6,1,Title,1,Base_Heading,1,Box-title,1,Front Head,1,Index Head,1,AMEND Terms Heading,1,AMEND Heading 1 Unnumbered,1"
59
+ <span style='mso-element:field-separator'></span></span>
60
+ TOC
61
+ end
62
+
63
+ def render_identifier(ident)
64
+ ret = super
65
+ ret[:sdo] = std_docid_semantic(ret[:sdo])
66
+ ret
67
+ end
68
+
69
+ def make_tr_attr(cell, row, totalrows, header)
70
+ super.merge(header: header)
71
+ end
72
+
73
+ def toWord(result, filename, dir, header)
74
+ result = from_xhtml(word_cleanup(to_xhtml(result)))
75
+ .gsub(/-DOUBLE_HYPHEN_ESCAPE-/, "--")
76
+ @wordstylesheet = wordstylesheet_update
77
+ ::Html2Doc::IsoDIS.new(
78
+ filename: filename,
79
+ imagedir: @localdir,
80
+ stylesheet: @wordstylesheet&.path,
81
+ header_file: header&.path, dir: dir,
82
+ asciimathdelims: [@openmathdelim, @closemathdelim],
83
+ liststyles: { ul: @ulstyle, ol: @olstyle }
84
+ ).process(result)
85
+ header&.unlink
86
+ @wordstylesheet.unlink if @wordstylesheet.is_a?(Tempfile)
87
+ end
88
+
89
+ def middle_title(_isoxml, out)
90
+ middle_title_dis(out)
91
+ end
92
+
93
+ def middle_title_dis(out)
94
+ out.p(**{ class: "zzSTDTitle" }) do |p|
95
+ p << @meta.get[:doctitleintro]
96
+ @meta.get[:doctitleintro] && @meta.get[:doctitlemain] and p << " &#x2014; "
97
+ p << @meta.get[:doctitlemain]
98
+ @meta.get[:doctitlemain] && @meta.get[:doctitlepart] and p << " &#x2014; "
99
+ if @meta.get[:doctitlepart]
100
+ b = @meta.get[:doctitlepartlabel] and
101
+ p << "<span style='font-weight:normal'>#{b}</span> "
102
+ p << " #{@meta.get[:doctitlepart]}"
103
+ end
104
+ @meta.get[:doctitleamdlabel] || @meta.get[:doctitleamd] ||
105
+ @meta.get[:doctitlecorrlabel] and middle_title_dis_amd(p)
106
+ end
107
+ end
108
+
109
+ def middle_title_dis_amd(para)
110
+ para.span(**{ style: "font-weight:normal" }) do |p|
111
+ if a = @meta.get[:doctitleamdlabel]
112
+ p << " #{a}"
113
+ a = @meta.get[:doctitleamd] and p << ": #{a}"
114
+ end
115
+ if a = @meta.get[:doctitlecorrlabel]
116
+ p << " #{a}"
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -10,36 +10,48 @@ module IsoDoc
10
10
  else
11
11
  initial_anchor_names1(doc)
12
12
  end
13
- introduction_names(doc.at(ns("//introduction")))
13
+ if @parse_settings.empty? || @parse_settings[:clauses]
14
+ introduction_names(doc.at(ns("//introduction")))
15
+ end
14
16
  end
15
17
 
16
18
  def initial_anchor_names_amd(doc)
17
- doc.xpath(ns("//preface/*")).each do |c|
18
- c.element? and preface_names(c)
19
+ if @parse_settings.empty? || @parse_settings[:clauses]
20
+ doc.xpath(ns("//preface/*")).each do |c|
21
+ c.element? and preface_names(c)
22
+ end
23
+ doc.xpath(ns("//sections/clause")).each do |c|
24
+ c.element? and preface_names(c)
25
+ end
19
26
  end
20
- sequential_asset_names(doc.xpath(ns("//preface/*")))
21
- doc.xpath(ns("//sections/clause")).each do |c|
22
- c.element? and preface_names(c)
27
+ if @parse_settings.empty?
28
+ sequential_asset_names(doc.xpath(ns("//preface/*")))
29
+ middle_section_asset_names(doc)
30
+ termnote_anchor_names(doc)
31
+ termexample_anchor_names(doc)
23
32
  end
24
- middle_section_asset_names(doc)
25
- termnote_anchor_names(doc)
26
- termexample_anchor_names(doc)
27
33
  end
28
34
 
29
35
  def initial_anchor_names1(doc)
30
- doc.xpath(ns("//preface/*")).each { |c| c.element? and preface_names(c) }
31
- # potentially overridden in middle_section_asset_names()
32
- sequential_asset_names(doc.xpath(ns("//preface/*")))
33
- n = Counter.new
34
- n = section_names(doc.at(ns("//clause[@type = 'scope']")), n, 1)
35
- n = section_names(doc.at(ns(@klass.norm_ref_xpath)), n, 1)
36
- doc.xpath(ns("//sections/clause[not(@type = 'scope')] | "\
37
- "//sections/terms | //sections/definitions")).each do |c|
38
- n = section_names(c, n, 1)
36
+ if @parse_settings.empty? || @parse_settings[:clauses]
37
+ doc.xpath(ns("//preface/*")).each do |c|
38
+ c.element? and preface_names(c)
39
+ end
40
+ # potentially overridden in middle_section_asset_names()
41
+ sequential_asset_names(doc.xpath(ns("//preface/*")))
42
+ n = Counter.new
43
+ n = section_names(doc.at(ns("//clause[@type = 'scope']")), n, 1)
44
+ n = section_names(doc.at(ns(@klass.norm_ref_xpath)), n, 1)
45
+ doc.xpath(ns("//sections/clause[not(@type = 'scope')] | "\
46
+ "//sections/terms | //sections/definitions")).each do |c|
47
+ n = section_names(c, n, 1)
48
+ end
49
+ end
50
+ if @parse_settings.empty?
51
+ middle_section_asset_names(doc)
52
+ termnote_anchor_names(doc)
53
+ termexample_anchor_names(doc)
39
54
  end
40
- middle_section_asset_names(doc)
41
- termnote_anchor_names(doc)
42
- termexample_anchor_names(doc)
43
55
  end
44
56
 
45
57
  # we can reference 0-number clauses in introduction
@@ -65,10 +77,10 @@ module IsoDoc
65
77
  i = Counter.new
66
78
  clause.xpath(ns("./appendix")).each do |c|
67
79
  i.increment(c)
68
- @anchors[c["id"]] = anchor_struct(i.print, nil, @labels["appendix"],
69
- "clause")
70
- @anchors[c["id"]][:level] = 2
71
- @anchors[c["id"]][:container] = clause["id"]
80
+ @anchors[c["id"]] =
81
+ anchor_struct(i.print, nil, @labels["appendix"],
82
+ "clause").merge(level: 2, subtype: "annex",
83
+ container: clause["id"])
72
84
  j = Counter.new
73
85
  c.xpath(ns("./clause | ./references")).each do |c1|
74
86
  j.increment(c1)
@@ -78,10 +90,11 @@ module IsoDoc
78
90
  end
79
91
  end
80
92
 
93
+ # subclauses are not prefixed with "Clause"
94
+ # retaining subtype for the semantics
81
95
  def section_names1(clause, num, level)
82
96
  @anchors[clause["id"]] =
83
- { label: num, level: level, xref: num }
84
- # subclauses are not prefixed with "Clause"
97
+ { label: num, level: level, xref: num, subtype: "clause" }
85
98
  i = Counter.new
86
99
  clause.xpath(ns("./clause | ./terms | ./term | ./definitions | "\
87
100
  "./references"))
@@ -92,7 +105,8 @@ module IsoDoc
92
105
  end
93
106
 
94
107
  def annex_names1(clause, num, level)
95
- @anchors[clause["id"]] = { label: num, xref: num, level: level }
108
+ @anchors[clause["id"]] = { label: num, xref: num, level: level,
109
+ subtype: "annex" }
96
110
  i = Counter.new
97
111
  clause.xpath(ns("./clause | ./references")).each do |c|
98
112
  i.increment(c)
@@ -166,7 +180,42 @@ module IsoDoc
166
180
 
167
181
  def back_anchor_names(docxml)
168
182
  super
169
- docxml.xpath(ns("//indexsect")).each { |b| preface_names(b) }
183
+ if @parse_settings.empty? || @parse_settings[:clauses]
184
+ docxml.xpath(ns("//indexsect")).each { |b| preface_names(b) }
185
+ end
186
+ end
187
+
188
+ def annex_name_lbl(clause, num)
189
+ super.sub(%r{<br/>(.*)$}, "<br/><span class='obligation'>\\1</span>")
190
+ end
191
+
192
+ def list_anchor_names(sections)
193
+ sections.each do |s|
194
+ notes = s.xpath(ns(".//ol")) - s.xpath(ns(".//clause//ol")) -
195
+ s.xpath(ns(".//appendix//ol")) - s.xpath(ns(".//ol//ol"))
196
+ c = Counter.new
197
+ notes.reject { |n| blank?(n["id"]) }.each do |n|
198
+ @anchors[n["id"]] = anchor_struct(increment_label(notes, n, c), n,
199
+ @labels["list"], "list", false)
200
+ list_item_anchor_names(n, @anchors[n["id"]], 1, "",
201
+ !single_ol_for_xrefs?(notes))
202
+ end
203
+ list_anchor_names(s.xpath(ns(CHILD_SECTIONS)))
204
+ end
205
+ end
206
+
207
+ # all li in the ol in lists are consecutively numbered through @start
208
+ def single_ol_for_xrefs?(lists)
209
+ return true if lists.size == 1
210
+
211
+ start = 0
212
+ lists.each_with_index do |l, i|
213
+ next if i.zero?
214
+
215
+ start += lists[i - 1].xpath(ns("./li")).size
216
+ return false unless l["start"]&.to_i == start + 1
217
+ end
218
+ true
170
219
  end
171
220
  end
172
221
  end