isodoc 2.0.8 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/isodoc.gemspec +4 -2
  3. data/lib/isodoc/convert.rb +13 -5
  4. data/lib/isodoc/css.rb +11 -10
  5. data/lib/isodoc/function/blocks.rb +0 -39
  6. data/lib/isodoc/function/blocks_example_note.rb +36 -1
  7. data/lib/isodoc/function/inline.rb +4 -0
  8. data/lib/isodoc/function/references.rb +4 -17
  9. data/lib/isodoc/function/section.rb +5 -0
  10. data/lib/isodoc/function/to_word_html.rb +7 -11
  11. data/lib/isodoc/html_function/postprocess.rb +16 -2
  12. data/lib/isodoc/metadata.rb +2 -1
  13. data/lib/isodoc/presentation_function/bibdata.rb +50 -4
  14. data/lib/isodoc/presentation_function/block.rb +13 -1
  15. data/lib/isodoc/presentation_function/section.rb +38 -2
  16. data/lib/isodoc/presentation_xml_convert.rb +7 -2
  17. data/lib/isodoc/version.rb +1 -1
  18. data/lib/isodoc/word_function/postprocess.rb +4 -4
  19. data/lib/isodoc/word_function/postprocess_cover.rb +14 -0
  20. data/lib/isodoc/word_function/table.rb +12 -10
  21. data/lib/isodoc/xref/xref_anchor.rb +1 -1
  22. data/lib/isodoc/xref/xref_counter.rb +4 -1
  23. data/lib/isodoc/xref/xref_gen_seq.rb +3 -3
  24. data/lib/isodoc/xref/xref_sect_gen.rb +34 -36
  25. data/lib/isodoc/xref.rb +19 -8
  26. data/lib/isodoc-yaml/i18n-ar.yaml +9 -0
  27. data/lib/isodoc-yaml/i18n-de.yaml +13 -0
  28. data/lib/isodoc-yaml/i18n-en.yaml +5 -0
  29. data/lib/isodoc-yaml/i18n-es.yaml +11 -0
  30. data/lib/isodoc-yaml/i18n-fr.yaml +12 -1
  31. data/lib/isodoc-yaml/i18n-ru.yaml +13 -0
  32. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +5 -0
  33. data/lib/relaton/render/config.yml +4 -0
  34. data/lib/relaton/render/general.rb +35 -0
  35. data/spec/assets/i18n.yaml +6 -0
  36. data/spec/isodoc/blocks_spec.rb +249 -62
  37. data/spec/isodoc/i18n_spec.rb +266 -197
  38. data/spec/isodoc/inline_spec.rb +81 -107
  39. data/spec/isodoc/metadata_spec.rb +5 -3
  40. data/spec/isodoc/postproc_spec.rb +539 -397
  41. data/spec/isodoc/presentation_xml_spec.rb +107 -0
  42. data/spec/isodoc/ref_spec.rb +142 -92
  43. data/spec/isodoc/section_spec.rb +4 -4
  44. data/spec/isodoc/xref_numbering_spec.rb +31 -0
  45. data/spec/isodoc/xref_spec.rb +106 -106
  46. metadata +24 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a7850182b408d69f4ae9de09a385c8813c366a2ffd15122596ac3cd95e1b62f6
4
- data.tar.gz: 2920db0b8a2d7887a326ad5f58f23550c0eb949e33fdbcf7dd7601d805b08e8f
3
+ metadata.gz: 7d8386094c2e6b1ea70008d548b0f0c475242457dcb58152a04bd7e59403cc7b
4
+ data.tar.gz: 4606afd5a06cede44afc418efc3e67267a5f75c615626475df57f6e881f8adcc
5
5
  SHA512:
6
- metadata.gz: e80f26545cd13b3e3bab7624d140cf2844afdf3471a45a8b77102fdaf2ca633e4a80df7a315718f3b35a8e3b95b9706a1e03785a19afef1bb5cf47dcf22a9d0d
7
- data.tar.gz: 4ccdbce4a6e6e854137a938ec3e26361952f355b0cffd3776e646109cff971e0514dd5e222add212be371771e85bd75df5c6a3852800d7b12a07c5a2112a45aa
6
+ metadata.gz: 453d7f0089ed9325a0e1b9fbe49b223365811f3115d3b08cc3862be80e56933a3a229273c84b6c52a153e8b8772b8aab50b06215cff2cba76547e8f6105002f3
7
+ data.tar.gz: a40f39df17dffbd8ef3286d841c1f5e96ff6abcbc1e41433895126217fa77b78cc650e4f7ba8ccea3948d6cb569cd1725b74e8df19d7cd7f608c9c95960b02a9
data/isodoc.gemspec CHANGED
@@ -29,16 +29,17 @@ Gem::Specification.new do |spec|
29
29
  spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
30
30
 
31
31
  spec.add_dependency "asciimath"
32
- spec.add_dependency "html2doc", "~> 1.3.0"
32
+ spec.add_dependency "html2doc", "~> 1.4.0"
33
33
  spec.add_dependency "htmlentities", "~> 4.3.4"
34
34
  spec.add_dependency "isodoc-i18n", "~> 1.0.0"
35
35
  spec.add_dependency "liquid", "~> 4"
36
36
  # spec.add_dependency "metanorma", ">= 1.2.0"
37
- spec.add_dependency "emf2svg", "<= 1.3"
37
+ spec.add_dependency "emf2svg"
38
38
  spec.add_dependency "mathml2asciimath"
39
39
  spec.add_dependency "metanorma-utils"
40
40
  spec.add_dependency "nokogiri", "~> 1.12.0"
41
41
  spec.add_dependency "relaton-cli"
42
+ spec.add_dependency "relaton-render", ">= 0.3.1"
42
43
  spec.add_dependency "roman-numerals"
43
44
  spec.add_dependency "thread_safe"
44
45
  spec.add_dependency "twitter_cldr", ">= 6.6.0"
@@ -56,4 +57,5 @@ Gem::Specification.new do |spec|
56
57
  spec.add_development_dependency "sassc", "~> 2.4.0"
57
58
  spec.add_development_dependency "simplecov", "~> 0.15"
58
59
  spec.add_development_dependency "timecop", "~> 0.9"
60
+ # spec.metadata["rubygems_mfa_required"] = "true"
59
61
  end
@@ -43,6 +43,8 @@ module IsoDoc
43
43
  # tocfigures: add ToC for figures
44
44
  # toctables: add ToC for tables
45
45
  # tocrecommendations: add ToC for rcommendations
46
+ # fonts: fontist fonts to install
47
+ # fontlicenseagreement: fontist font license agreement
46
48
  def initialize(options)
47
49
  @libdir ||= File.dirname(__FILE__) # rubocop:disable Lint/DisjunctiveAssignmentInConstructor
48
50
  options.merge!(default_fonts(options)) do |_, old, new|
@@ -57,10 +59,7 @@ module IsoDoc
57
59
  init_stylesheets(options)
58
60
  init_covers(options)
59
61
  init_toc(options)
60
- @normalfontsize = options[:normalfontsize]
61
- @smallerfontsize = options[:smallerfontsize]
62
- @monospacefontsize = options[:monospacefontsize]
63
- @footnotefontsize = options[:footnotefontsize]
62
+ init_fonts(options)
64
63
  @i18nyaml = options[:i18nyaml]
65
64
  @ulstyle = options[:ulstyle]
66
65
  @olstyle = options[:olstyle]
@@ -96,6 +95,15 @@ module IsoDoc
96
95
  @tmpfilesdir_suffix = tmpfilesdir_suffix
97
96
  end
98
97
 
98
+ def init_fonts(options)
99
+ @normalfontsize = options[:normalfontsize]
100
+ @smallerfontsize = options[:smallerfontsize]
101
+ @monospacefontsize = options[:monospacefontsize]
102
+ @footnotefontsize = options[:footnotefontsize]
103
+ @fontist_fonts = options[:fonts]
104
+ @fontlicenseagreement = options[:fontlicenseagreement]
105
+ end
106
+
99
107
  def init_covers(options)
100
108
  @header = options[:header]
101
109
  @htmlcoverpage = options[:htmlcoverpage]
@@ -173,7 +181,7 @@ module IsoDoc
173
181
  end
174
182
 
175
183
  def i18n_init(lang, script, i18nyaml = nil)
176
- @i18n = I18n.new(lang, script, i18nyaml || @i18nyaml)
184
+ @i18n = I18n.new(lang, script, i18nyaml: i18nyaml || @i18nyaml)
177
185
  end
178
186
 
179
187
  def l10n(expr, lang = @lang, script = @script)
data/lib/isodoc/css.rb CHANGED
@@ -29,10 +29,10 @@ module IsoDoc
29
29
  @wordstylesheet = generate_css(localpath(@wordstylesheet_name), false)
30
30
  @standardstylesheet =
31
31
  generate_css(localpath(@standardstylesheet_name), false)
32
- @htmlstylesheet_override_name and @htmlstylesheet_override =
33
- File.open(localpath(@htmlstylesheet_override_name))
34
- @wordstylesheet_override_name and @wordstylesheet_override =
35
- File.open(localpath(@wordstylesheet_override_name))
32
+ @htmlstylesheet_override_name and
33
+ @htmlstylesheet_override = File.open(localpath(@htmlstylesheet_override_name))
34
+ @wordstylesheet_override_name and
35
+ @wordstylesheet_override = File.open(localpath(@wordstylesheet_override_name))
36
36
  end
37
37
 
38
38
  def default_fonts(_options)
@@ -80,12 +80,12 @@ module IsoDoc
80
80
 
81
81
  [File.join(Gem.loaded_specs["isodoc"].full_gem_path,
82
82
  "lib", "isodoc"),
83
- File.dirname(filename)].each do |name|
84
- SassC.load_paths << name
85
- end
86
- SassC::Engine.new(scss_fontheader(stripwordcss) + stylesheet,
87
- syntax: :scss, importer: SasscImporter)
88
- .render
83
+ File.dirname(filename)].each do |name|
84
+ SassC.load_paths << name
85
+ end
86
+ SassC::Engine.new(scss_fontheader(stripwordcss) + stylesheet,
87
+ syntax: :scss, importer: SasscImporter)
88
+ .render
89
89
  end
90
90
 
91
91
  # stripwordcss if HTML stylesheet, !stripwordcss if DOC stylesheet
@@ -96,6 +96,7 @@ module IsoDoc
96
96
  stylesheet = File.read(filename, encoding: "UTF-8")
97
97
  stylesheet = populate_template(stylesheet, :word)
98
98
  stylesheet.gsub!(/(\s|\{)mso-[^:]+:[^;]+;/m, "\\1") if stripwordcss
99
+ stylesheet.gsub!(/--/, "-DOUBLE_HYPHEN_ESCAPE-") unless stripwordcss
99
100
  if File.extname(filename) == ".scss"
100
101
  stylesheet = convert_scss(filename, stylesheet, stripwordcss)
101
102
  end
@@ -9,12 +9,6 @@ module IsoDoc
9
9
  out.p(**{ class: "zzSTDTitle1" }) { |p| p << @meta.get[:doctitle] }
10
10
  end
11
11
 
12
- def middle_admonitions(isoxml, out)
13
- isoxml.xpath(ns("//sections/note | //sections/admonition")).each do |x|
14
- parse(x, out)
15
- end
16
- end
17
-
18
12
  def figure_name_parse(_node, div, name)
19
13
  return if name.nil?
20
14
 
@@ -74,12 +68,6 @@ module IsoDoc
74
68
  end
75
69
  end
76
70
 
77
- def admonition_name_parse(_node, div, name)
78
- div.p **{ class: "AdmonitionTitle", style: "text-align:center;" } do |p|
79
- name.children.each { |n| parse(n, p) }
80
- end
81
- end
82
-
83
71
  def sourcecode_attrs(node)
84
72
  attr_code(id: node["id"], class: "Sourcecode", style: keep_style(node))
85
73
  end
@@ -109,33 +97,6 @@ module IsoDoc
109
97
  @annotation = false
110
98
  end
111
99
 
112
- def admonition_class(_node)
113
- "Admonition"
114
- end
115
-
116
- def admonition_name(node, type)
117
- name = node&.at(ns("./name")) and return name
118
- name = Nokogiri::XML::Node.new("name", node.document)
119
- return unless type && @i18n.admonition[type]
120
-
121
- name << @i18n.admonition[type]&.upcase
122
- name
123
- end
124
-
125
- def admonition_attrs(node)
126
- attr_code(id: node["id"], class: admonition_class(node),
127
- style: keep_style(node))
128
- end
129
-
130
- def admonition_parse(node, out)
131
- type = node["type"]
132
- name = admonition_name(node, type)
133
- out.div **admonition_attrs(node) do |t|
134
- admonition_name_parse(node, t, name) if name
135
- node.children.each { |n| parse(n, t) unless n.name == "name" }
136
- end
137
- end
138
-
139
100
  def formula_where(dlist, out)
140
101
  return unless dlist
141
102
 
@@ -94,7 +94,8 @@ module IsoDoc
94
94
  end
95
95
 
96
96
  def note_attrs(node)
97
- attr_code(id: node["id"], class: "Note", style: keep_style(node))
97
+ attr_code(id: node["id"], class: "Note", style: keep_style(node),
98
+ coverpage: node["coverpage"])
98
99
  end
99
100
 
100
101
  def note_parse(node, out)
@@ -108,6 +109,40 @@ module IsoDoc
108
109
  end
109
110
  @note = false
110
111
  end
112
+
113
+ def middle_admonitions(isoxml, out)
114
+ isoxml.xpath(ns("//sections/note | //sections/admonition")).each do |x|
115
+ parse(x, out)
116
+ end
117
+ end
118
+
119
+ def admonition_name_parse(_node, div, name)
120
+ div.p **{ class: "AdmonitionTitle", style: "text-align:center;" } do |p|
121
+ name.children.each { |n| parse(n, p) }
122
+ end
123
+ end
124
+
125
+ def admonition_class(_node)
126
+ "Admonition"
127
+ end
128
+
129
+ def admonition_name(node, _type)
130
+ node&.at(ns("./name"))
131
+ end
132
+
133
+ def admonition_attrs(node)
134
+ attr_code(id: node["id"], class: admonition_class(node),
135
+ style: keep_style(node), coverpage: node["coverpage"])
136
+ end
137
+
138
+ def admonition_parse(node, out)
139
+ type = node["type"]
140
+ name = admonition_name(node, type)
141
+ out.div **admonition_attrs(node) do |t|
142
+ admonition_name_parse(node, t, name) if name
143
+ node.children.each { |n| parse(n, t) unless n.name == "name" }
144
+ end
145
+ end
111
146
  end
112
147
  end
113
148
  end
@@ -14,6 +14,10 @@ module IsoDoc
14
14
  end
15
15
  end
16
16
 
17
+ def span_parse(node, out)
18
+ node.children.each { |n| parse(n, out) }
19
+ end
20
+
17
21
  def callout_parse(node, out)
18
22
  out << " &lt;#{node.text}&gt;"
19
23
  end
@@ -10,7 +10,6 @@ module IsoDoc
10
10
  text
11
11
  end
12
12
 
13
- # TODO generate formatted ref if not present
14
13
  def nonstd_bibitem(list, bib, ordinal, biblio)
15
14
  list.p **attr_code(iso_bibitem_entry_attrs(bib, biblio)) do |ref|
16
15
  ids = bibitem_ref_code(bib)
@@ -126,13 +125,6 @@ module IsoDoc
126
125
  { id: bib["id"], class: biblio ? "Biblio" : "NormRef" }
127
126
  end
128
127
 
129
- def iso_title(bib)
130
- bib.at(ns("./title[@language = '#{@lang}' and @type = 'main']")) ||
131
- bib.at(ns("./title[@language = '#{@lang}']")) ||
132
- bib.at(ns("./title[@type = 'main']")) ||
133
- bib.at(ns("./title"))
134
- end
135
-
136
128
  # reference not to be rendered because it is deemed implicit
137
129
  # in the standards environment
138
130
  def implicit_reference(bib)
@@ -145,13 +137,8 @@ module IsoDoc
145
137
  end
146
138
 
147
139
  def reference_format(bib, out)
148
- if ftitle = bib.at(ns("./formattedref"))
149
- ftitle&.children&.each { |n| parse(n, out) }
150
- else
151
- out.i do |i|
152
- iso_title(bib)&.children&.each { |n| parse(n, i) }
153
- end
154
- end
140
+ ftitle = bib.at(ns("./formattedref"))
141
+ ftitle&.children&.each { |n| parse(n, out) }
155
142
  end
156
143
 
157
144
  def standard?(bib)
@@ -171,7 +158,7 @@ module IsoDoc
171
158
  if b.name == "bibitem"
172
159
  next if implicit_reference(b)
173
160
 
174
- i += 1
161
+ i += 1 unless b["hidden"]
175
162
  if standard?(b) then std_bibitem_entry(div, b, i, biblio)
176
163
  else nonstd_bibitem(div, b, i, biblio)
177
164
  end
@@ -190,7 +177,7 @@ module IsoDoc
190
177
  (f = isoxml.at(ns(norm_ref_xpath)) and f["hidden"] != "true") or
191
178
  return num
192
179
  out.div do |div|
193
- num = num + 1
180
+ num += 1
194
181
  clause_name(num, f.at(ns("./title")), div, nil)
195
182
  if f.name == "clause"
196
183
  f.elements.each { |e| parse(e, div) unless e.name == "title" }
@@ -157,6 +157,11 @@ module IsoDoc
157
157
  acknowledgements).include? name
158
158
  end
159
159
 
160
+ def single_term_clause?(elem)
161
+ t = elem.xpath(ns("./clause | ./terms | ./definitions | ./references"))
162
+ t.size == 1 && %w(terms definitions references).include?(t[0].name)
163
+ end
164
+
160
165
  def preface_block(isoxml, out)
161
166
  p = isoxml.at(ns("//preface")) or return
162
167
  p.elements.each do |e|
@@ -183,7 +183,7 @@ module IsoDoc
183
183
  when "formula" then formula_parse(node, out)
184
184
  when "table" then table_parse(node, out)
185
185
  when "figure" then figure_parse(node, out)
186
- when "example" then example_parse(node, out)
186
+ when "example", "termexample" then example_parse(node, out)
187
187
  when "image" then image_parse(node, out, nil)
188
188
  when "sourcecode" then sourcecode_parse(node, out)
189
189
  when "pre" then pre_parse(node, out)
@@ -197,7 +197,6 @@ module IsoDoc
197
197
  when "termsource" then termref_parse(node, out)
198
198
  when "modification" then modification_parse(node, out)
199
199
  when "termnote" then termnote_parse(node, out)
200
- when "termexample" then example_parse(node, out)
201
200
  when "terms" then terms_parse(node, out)
202
201
  when "definitions" then symbols_parse(node, out)
203
202
  when "references" then bibliography_parse(node, out)
@@ -205,15 +204,11 @@ module IsoDoc
205
204
  when "requirement" then requirement_parse(node, out)
206
205
  when "recommendation" then recommendation_parse(node, out)
207
206
  when "permission" then permission_parse(node, out)
208
- when "subject" then requirement_skip_parse(node, out)
209
- when "classification" then requirement_skip_parse(node, out)
210
- when "inherit" then requirement_component_parse(node, out)
211
- when "description" then requirement_component_parse(node, out)
212
- when "specification" then requirement_component_parse(node, out)
213
- when "measurement-target" then requirement_component_parse(node, out)
214
- when "verification" then requirement_component_parse(node, out)
215
- when "import" then requirement_component_parse(node, out)
216
- when "component" then requirement_component_parse(node, out)
207
+ when "subject", "classification"
208
+ requirement_skip_parse(node, out)
209
+ when "inherit", "description", "specification", "measurement-target",
210
+ "verification", "import", "component"
211
+ requirement_component_parse(node, out)
217
212
  when "index" then index_parse(node, out)
218
213
  when "index-xref" then index_xref_parse(node, out)
219
214
  when "termref" then termrefelem_parse(node, out)
@@ -235,6 +230,7 @@ module IsoDoc
235
230
  when "textarea" then textarea_parse(node, out)
236
231
  when "toc" then toc_parse(node, out)
237
232
  when "variant-title" then variant_title(node, out)
233
+ when "span" then span_parse(node, out)
238
234
  else error_parse(node, out)
239
235
  end
240
236
  end
@@ -103,6 +103,20 @@ module IsoDoc
103
103
  %w(copyright license legal feedback).each do |t|
104
104
  authority_cleanup1(docxml, t)
105
105
  end
106
+ coverpage_note_cleanup(docxml)
107
+ end
108
+
109
+ def coverpage_note_cleanup(docxml)
110
+ if dest = docxml.at("//div[@id = 'coverpage-note-destination']")
111
+ auth = docxml.xpath("//*[@coverpage]")
112
+ if auth.empty? then dest.remove
113
+ else
114
+ auth.each do |x|
115
+ dest << x.remove
116
+ end
117
+ end
118
+ end
119
+ docxml.xpath("//*[@coverpage]").each { |x| x.delete("coverpage") }
106
120
  end
107
121
 
108
122
  def html_cover(docxml)
@@ -166,8 +180,8 @@ module IsoDoc
166
180
  FileUtils.rm_rf tmpimagedir
167
181
  FileUtils.mkdir tmpimagedir
168
182
  docxml.xpath("//*[local-name() = 'img']").each do |i|
169
- i["width"], i["height"] = Html2Doc.image_resize(i, image_localfile(i),
170
- @maxheight, @maxwidth)
183
+ i["width"], i["height"] = Html2Doc.new({})
184
+ .image_resize(i, image_localfile(i), @maxheight, @maxwidth)
171
185
  next if /^data:/.match? i["src"]
172
186
 
173
187
  @datauriimage ? datauri(i) : move_image1(i)
@@ -107,7 +107,8 @@ module IsoDoc
107
107
  end
108
108
 
109
109
  def version(isoxml, _out)
110
- set(:edition, isoxml&.at(ns("//bibdata/edition"))&.text)
110
+ set(:edition, isoxml&.at(ns("//bibdata/edition#{NOLANG}"))&.text)
111
+ set(:edition_display, isoxml&.at(ns("//bibdata/edition#{currlang}"))&.text)
111
112
  set(:docyear, isoxml&.at(ns("//bibdata/copyright/from"))&.text)
112
113
  set(:draft, isoxml&.at(ns("//bibdata/version/draft"))&.text)
113
114
  revdate = isoxml&.at(ns("//bibdata/version/revision-date"))&.text
@@ -1,7 +1,10 @@
1
+ require "csv"
2
+
1
3
  module IsoDoc
2
4
  class PresentationXMLConvert < ::IsoDoc::Convert
3
5
  def bibdata(docxml)
4
6
  toc_metadata(docxml)
7
+ fonts_metadata(docxml)
5
8
  docid_prefixes(docxml)
6
9
  a = bibdata_current(docxml) or return
7
10
  address_precompose(a)
@@ -34,6 +37,23 @@ module IsoDoc
34
37
  end
35
38
  end
36
39
 
40
+ def fonts_metadata(xmldoc)
41
+ return unless @fontist_fonts
42
+
43
+ ins = xmldoc.at(ns("//presentation-metadata")) ||
44
+ xmldoc.at(ns("//misc-container")) || xmldoc.at(ns("//bibdata"))
45
+ CSV.parse_line(@fontist_fonts, col_sep: ";").map(&:strip).each do |f|
46
+ ins.next = presmeta("fonts", f)
47
+ end
48
+ @fontlicenseagreement and
49
+ ins.next = presmeta("font-license-agreement", @fontlicenseagreement)
50
+ end
51
+
52
+ def presmeta(name, value)
53
+ "<presentation-metadata><name>#{name}</name><value>#{value}</value>"\
54
+ "</presentation-metadata>"
55
+ end
56
+
37
57
  def address_precompose1(addr)
38
58
  ret = []
39
59
  addr.xpath(ns("./street")).each { |s| ret << s.children.to_xml }
@@ -59,16 +79,42 @@ module IsoDoc
59
79
  hash_translate(bib, @i18n.get["doctype_dict"], "./ext/doctype")
60
80
  hash_translate(bib, @i18n.get["stage_dict"], "./status/stage")
61
81
  hash_translate(bib, @i18n.get["substage_dict"], "./status/substage")
82
+ edition_translate(bib)
62
83
  end
63
84
 
64
85
  def hash_translate(bibdata, hash, xpath, lang = @lang)
65
86
  x = bibdata.at(ns(xpath)) or return
66
- x["language"] = ""
67
87
  hash.is_a? Hash or return
68
88
  hash[x.text] or return
69
- x.next = x.dup
70
- x.next["language"] = lang
71
- x.next.children = hash[x.text]
89
+ tag_translate(x, lang, hash[x.text])
90
+ end
91
+
92
+ # does not allow %Spellout and %Ordinal in the ordinal expression to be mixed
93
+ def edition_translate(bibdata)
94
+ x = bibdata.at(ns("./edition")) or return
95
+ /^\d+$/.match?(x.text) or return
96
+ tag_translate(x, @lang,
97
+ @i18n.edition_ordinal.sub(/%(Spellout|Ordinal)?/,
98
+ edition_translate1(x.text.to_i)))
99
+ end
100
+
101
+ def edition_translate1(num)
102
+ ruleset = case @i18n.edition_ordinal
103
+ when /%Spellout/ then "SpelloutRules"
104
+ when /%Ordinal/ then "OrdinalRules"
105
+ else "Digit"
106
+ end
107
+ ruleset == "Digit" and return num.to_s
108
+ ed = @c.decode(@i18n.edition)
109
+ @i18n.inflect_ordinal(num, @i18n.inflection&.dig(ed) || {},
110
+ ruleset)
111
+ end
112
+
113
+ def tag_translate(tag, lang, value)
114
+ tag["language"] = ""
115
+ tag.next = tag.dup
116
+ tag.next["language"] = lang
117
+ tag.next.children = value
72
118
  end
73
119
 
74
120
  def i18n_tag(key, value)
@@ -71,7 +71,7 @@ module IsoDoc
71
71
 
72
72
  # introduce name element
73
73
  def note1(elem)
74
- return if elem.parent.name == "bibitem"
74
+ return if elem.parent.name == "bibitem" || elem["notag"] == "true"
75
75
 
76
76
  n = @xrefs.get[elem["id"]]
77
77
  lbl = if n.nil? || n[:label].nil? || n[:label].empty?
@@ -82,6 +82,18 @@ module IsoDoc
82
82
  prefix_name(elem, "", lbl, "name")
83
83
  end
84
84
 
85
+ def admonition(docxml)
86
+ docxml.xpath(ns("//admonition")).each do |f|
87
+ admonition1(f)
88
+ end
89
+ end
90
+
91
+ def admonition1(elem)
92
+ return if elem.at(ns("./name")) || elem["notag"] == "true"
93
+
94
+ prefix_name(elem, "", @i18n.admonition[elem["type"]]&.upcase, "name")
95
+ end
96
+
85
97
  def recommendation(docxml)
86
98
  docxml.xpath(ns("//recommendation")).each do |f|
87
99
  recommendation1(f, lower2cap(@i18n.recommendation))
@@ -1,3 +1,5 @@
1
+ require_relative "../../relaton/render/general"
2
+
1
3
  module IsoDoc
2
4
  class PresentationXMLConvert < ::IsoDoc::Convert
3
5
  def clause(docxml)
@@ -40,6 +42,7 @@ module IsoDoc
40
42
  def annex(docxml)
41
43
  docxml.xpath(ns("//annex")).each do |f|
42
44
  annex1(f)
45
+ @xrefs.klass.single_term_clause?(f) and single_term_clause(f)
43
46
  end
44
47
  end
45
48
 
@@ -51,6 +54,16 @@ module IsoDoc
51
54
  prefix_name(elem, "<br/><br/>", lbl, "title")
52
55
  end
53
56
 
57
+ def single_term_clause(elem)
58
+ t = elem.at(ns("./terms | ./definitions | ./references"))
59
+ t.at(ns("./title")).remove
60
+ t.xpath(ns(".//clause | .//terms | .//definitions | .//references"))
61
+ .each do |c|
62
+ tit = c.at(ns("./title")) or return
63
+ tit["depth"] = tit["depth"].to_i - 1
64
+ end
65
+ end
66
+
54
67
  def term(docxml)
55
68
  docxml.xpath(ns("//term")).each do |f|
56
69
  term1(f)
@@ -64,13 +77,36 @@ module IsoDoc
64
77
 
65
78
  def references(docxml)
66
79
  bibliography_bibitem_number(docxml)
80
+ docxml.xpath(ns("//references/bibitem")).each do |x|
81
+ bibitem(x)
82
+ end
83
+ @xrefs.parse_inclusions(refs: true).parse(docxml)
84
+ end
85
+
86
+ def bibitem(xml)
87
+ bibrender(xml)
88
+ end
89
+
90
+ def bibrender(xml)
91
+ if f = xml.at(ns("./formattedref"))
92
+ code = render_identifier(bibitem_ref_code(xml))
93
+ f << " [#{code[:sdo]}] " if code[:sdo]
94
+ else
95
+ xml.children =
96
+ "#{bibrenderer.render(xml.to_xml)}"\
97
+ "#{xml.xpath(ns('./docidentifier | ./uri | ./note')).to_xml}"
98
+ end
99
+ end
100
+
101
+ def bibrenderer
102
+ ::Relaton::Render::IsoDoc::General.new(language: @lang)
67
103
  end
68
104
 
69
105
  def bibliography_bibitem_number_skip(bibitem)
70
106
  @xrefs.klass.implicit_reference(bibitem) ||
71
107
  bibitem.at(ns(".//docidentifier[@type = 'metanorma']")) ||
72
- bibitem.at(ns(".//docidentifier[@type = 'metanorma-ordinal']"))
73
- # || @xrefs.klass.standard?(bibitem)
108
+ bibitem.at(ns(".//docidentifier[@type = 'metanorma-ordinal']")) ||
109
+ bibitem["hidden"] == "true" || bibitem.parent["hidden"] == "true"
74
110
  end
75
111
 
76
112
  def bibliography_bibitem_number(docxml)
@@ -30,11 +30,15 @@ module IsoDoc
30
30
  inline docxml
31
31
  end
32
32
 
33
+ # parse annex after term, references,
34
+ # to deal with single-term and single-ref annexes
33
35
  def section(docxml)
36
+ references docxml
37
+ # triggers xrefs reparse, so put references before all other sections,
38
+ # which alter titles and thus can alter xrefs
34
39
  clause docxml
35
- annex docxml
36
40
  term docxml
37
- references docxml
41
+ annex docxml
38
42
  index docxml
39
43
  clausetitle docxml
40
44
  floattitle docxml
@@ -50,6 +54,7 @@ module IsoDoc
50
54
  formula docxml
51
55
  example docxml
52
56
  note docxml
57
+ admonition docxml
53
58
  ol docxml
54
59
  permission docxml
55
60
  requirement docxml
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "2.0.8".freeze
2
+ VERSION = "2.1.0".freeze
3
3
  end
@@ -39,16 +39,16 @@ module IsoDoc
39
39
 
40
40
  def toWord(result, filename, dir, header)
41
41
  result = from_xhtml(word_cleanup(to_xhtml(result)))
42
+ .gsub(/-DOUBLE_HYPHEN_ESCAPE-/, "--")
42
43
  @wordstylesheet = wordstylesheet_update
43
- Html2Doc.process(
44
- result,
44
+ Html2Doc.new(
45
45
  filename: filename,
46
46
  imagedir: @localdir,
47
47
  stylesheet: @wordstylesheet&.path,
48
48
  header_file: header&.path, dir: dir,
49
49
  asciimathdelims: [@openmathdelim, @closemathdelim],
50
50
  liststyles: { ul: @ulstyle, ol: @olstyle }
51
- )
51
+ ).process(result)
52
52
  header&.unlink
53
53
  @wordstylesheet.unlink if @wordstylesheet.is_a?(Tempfile)
54
54
  end
@@ -71,7 +71,7 @@ module IsoDoc
71
71
  def word_admonition_images(docxml)
72
72
  docxml.xpath("//div[@class = 'Admonition']//img").each do |i|
73
73
  i["width"], i["height"] =
74
- Html2Doc.image_resize(i, image_localfile(i), @maxheight, 300)
74
+ Html2Doc.new({}).image_resize(i, image_localfile(i), @maxheight, 300)
75
75
  end
76
76
  end
77
77
 
@@ -174,6 +174,20 @@ module IsoDoc
174
174
  %w(copyright license legal feedback).each do |t|
175
175
  authority_cleanup1(docxml, t)
176
176
  end
177
+ coverpage_note_cleanup(docxml)
178
+ end
179
+
180
+ def coverpage_note_cleanup(docxml)
181
+ if dest = docxml.at("//div[@id = 'coverpage-note-destination']")
182
+ auth = docxml.xpath("//*[@coverpage]")
183
+ if auth.empty? then dest.remove
184
+ else
185
+ auth.each do |x|
186
+ dest << x.remove
187
+ end
188
+ end
189
+ end
190
+ docxml.xpath("//*[@coverpage]").each { |x| x.delete("coverpage") }
177
191
  end
178
192
 
179
193
  def generate_header(filename, _dir)