isodoc 1.0.29 → 1.1.3.pre.alpha2

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/macos.yml +6 -12
  3. data/.github/workflows/ubuntu.yml +18 -20
  4. data/.github/workflows/windows.yml +6 -12
  5. data/Rakefile +3 -1
  6. data/isodoc.gemspec +2 -2
  7. data/lib/isodoc.rb +2 -0
  8. data/lib/isodoc/base_style/all.css +207 -0
  9. data/lib/isodoc/base_style/blocks.css +0 -0
  10. data/lib/isodoc/base_style/coverpage.css +0 -0
  11. data/lib/isodoc/base_style/defaults.css +0 -0
  12. data/lib/isodoc/base_style/metanorma_word.css +34 -0
  13. data/lib/isodoc/base_style/metanorma_word.scss +0 -1
  14. data/lib/isodoc/base_style/nav.css +0 -0
  15. data/lib/isodoc/base_style/reset.css +105 -0
  16. data/lib/isodoc/base_style/reset.scss +3 -3
  17. data/lib/isodoc/base_style/typography.css +0 -0
  18. data/lib/isodoc/common.rb +0 -4
  19. data/lib/isodoc/convert.rb +121 -58
  20. data/lib/isodoc/function/blocks.rb +3 -3
  21. data/lib/isodoc/function/blocks_example_note.rb +2 -2
  22. data/lib/isodoc/function/inline.rb +5 -5
  23. data/lib/isodoc/function/references.rb +29 -34
  24. data/lib/isodoc/function/reqt.rb +1 -1
  25. data/lib/isodoc/function/section.rb +7 -11
  26. data/lib/isodoc/function/table.rb +1 -1
  27. data/lib/isodoc/function/terms.rb +2 -2
  28. data/lib/isodoc/function/to_word_html.rb +2 -2
  29. data/lib/isodoc/function/utils.rb +57 -51
  30. data/lib/isodoc/gem_tasks.rb +117 -0
  31. data/lib/isodoc/headlesshtml_convert.rb +7 -6
  32. data/lib/isodoc/html_convert.rb +2 -1
  33. data/lib/isodoc/html_function/html.rb +1 -1
  34. data/lib/isodoc/html_function/postprocess.rb +1 -1
  35. data/lib/isodoc/metadata.rb +69 -63
  36. data/lib/isodoc/pdf_convert.rb +8 -6
  37. data/lib/isodoc/presentation_xml_convert.rb +29 -0
  38. data/lib/isodoc/sassc_importer.rb +11 -0
  39. data/lib/isodoc/version.rb +1 -1
  40. data/lib/isodoc/word_convert.rb +2 -1
  41. data/lib/isodoc/word_function/body.rb +1 -1
  42. data/lib/isodoc/word_function/postprocess.rb +1 -0
  43. data/lib/isodoc/xref.rb +59 -0
  44. data/lib/isodoc/{function → xref}/xref_anchor.rb +10 -21
  45. data/lib/isodoc/xref/xref_counter.rb +74 -0
  46. data/lib/isodoc/{function → xref}/xref_gen.rb +9 -22
  47. data/lib/isodoc/{function → xref}/xref_gen_seq.rb +34 -26
  48. data/lib/isodoc/{function → xref}/xref_sect_gen.rb +33 -23
  49. data/lib/isodoc/xslfo_convert.rb +16 -4
  50. data/spec/assets/{html.css → html.scss} +0 -0
  51. data/spec/isodoc/footnotes_spec.rb +2 -2
  52. data/spec/isodoc/postproc_spec.rb +1319 -1345
  53. data/spec/isodoc/presentation_xml_spec.rb +20 -0
  54. data/spec/isodoc/ref_spec.rb +1 -1
  55. data/spec/isodoc/section_spec.rb +52 -0
  56. metadata +40 -28
  57. data/lib/isodoc/function/xref_counter.rb +0 -84
@@ -16,10 +16,11 @@ module IsoDoc
16
16
 
17
17
  def initialize(options)
18
18
  @format = :html
19
+ @suffix = "html"
19
20
  super
20
21
  end
21
22
 
22
- def convert(filename, file = nil, debug = false)
23
+ def convert(filename, file = nil, debug = false, output_filename = nil)
23
24
  ret = super
24
25
  Dir.exists?(tmpimagedir) and Dir["#{tmpimagedir}/*"].empty? and
25
26
  FileUtils.rm_r tmpimagedir
@@ -4,7 +4,7 @@ require "base64"
4
4
  module IsoDoc::HtmlFunction
5
5
  module Html
6
6
  def convert1(docxml, filename, dir)
7
- anchor_names docxml
7
+ @xrefs.parse docxml
8
8
  noko do |xml|
9
9
  xml.html **{ lang: "#{@lang}" } do |html|
10
10
  info docxml, nil
@@ -18,7 +18,7 @@ module IsoDoc::HtmlFunction
18
18
  #result = populate_template(result, :html)
19
19
  result = from_xhtml(move_images(to_xhtml(result)))
20
20
  result = html5(script_cdata(inject_script(result)))
21
- File.open("#{filename}.html", "w:UTF-8") { |f| f.write(result) }
21
+ File.open(filename, "w:UTF-8") { |f| f.write(result) }
22
22
  end
23
23
 
24
24
  def html5(doc)
@@ -1,10 +1,15 @@
1
- require_relative "./metadata_date"
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './metadata_date'
2
4
 
3
5
  module IsoDoc
4
6
  class Metadata
5
7
  DATETYPES = %w{published accessed created implemented obsoleted confirmed
6
- updated issued received transmitted copied unchanged circulated vote-started
7
- vote-ended}.freeze
8
+ updated issued received transmitted copied unchanged
9
+ circulated vote-started
10
+ vote-ended}.freeze
11
+
12
+ attr_accessor :fonts_options
8
13
 
9
14
  def ns(xpath)
10
15
  Common::ns(xpath)
@@ -14,13 +19,14 @@ module IsoDoc
14
19
  IsoDoc::Function::I18n::l10n(a, b, c)
15
20
  end
16
21
 
17
- def initialize(lang, script, labels)
22
+ def initialize(lang, script, labels, fonts_options = {})
18
23
  @metadata = {}
19
- DATETYPES.each { |w| @metadata["#{w.gsub(/-/, "_")}date".to_sym] = "XXX" }
24
+ DATETYPES.each { |w| @metadata["#{w.gsub(/-/, '_')}date".to_sym] = 'XXX' }
20
25
  @lang = lang
21
26
  @script = script
22
27
  @c = HTMLEntities.new
23
28
  @labels = labels
29
+ @fonts_options = fonts_options
24
30
  end
25
31
 
26
32
  def get
@@ -36,26 +42,26 @@ module IsoDoc
36
42
  end
37
43
 
38
44
  def extract_person_names(authors)
39
- authors.inject([]) do |ret, a|
40
- if a.at(ns("./name/completename"))
41
- ret << a.at(ns("./name/completename")).text
45
+ authors.reduce([]) do |ret, a|
46
+ if a.at(ns('./name/completename'))
47
+ ret << a.at(ns('./name/completename')).text
42
48
  else
43
49
  fn = []
44
- forenames = a.xpath(ns("./name/forename"))
50
+ forenames = a.xpath(ns('./name/forename'))
45
51
  forenames.each { |f| fn << f.text }
46
- surname = a&.at(ns("./name/surname"))&.text
47
- ret << fn.join(" ") + " " + surname
52
+ surname = a&.at(ns('./name/surname'))&.text
53
+ ret << fn.join(' ') + ' ' + surname
48
54
  end
49
55
  end
50
56
  end
51
57
 
52
58
  def extract_person_affiliations(authors)
53
- authors.inject([]) do |m, a|
54
- name = a&.at(ns("./affiliation/organization/name"))&.text
55
- location = a&.at(ns("./affiliation/organization/address/"\
56
- "formattedAddress"))&.text
57
- m << ((!name.nil? && !location.nil?) ? "#{name}, #{location}" :
58
- (name || location || ""))
59
+ authors.reduce([]) do |m, a|
60
+ name = a&.at(ns('./affiliation/organization/name'))&.text
61
+ location = a&.at(ns('./affiliation/organization/address/'\
62
+ 'formattedAddress'))&.text
63
+ m << (!name.nil? && !location.nil? ? "#{name}, #{location}" :
64
+ (name || location || ''))
59
65
  m
60
66
  end
61
67
  end
@@ -84,99 +90,99 @@ module IsoDoc
84
90
  end
85
91
 
86
92
  def bibdate(isoxml, _out)
87
- isoxml.xpath(ns("//bibdata/date")).each do |d|
88
- set("#{d['type'].gsub(/-/, "_")}date".to_sym, Common::date_range(d))
93
+ isoxml.xpath(ns('//bibdata/date')).each do |d|
94
+ set("#{d['type'].gsub(/-/, '_')}date".to_sym, Common::date_range(d))
89
95
  end
90
96
  end
91
97
 
92
98
  def doctype(isoxml, _out)
93
- b = isoxml&.at(ns("//bibdata/ext/doctype"))&.text || return
94
- t = b.split(/[- ]/).map{ |w| w.capitalize }.join(" ")
99
+ b = isoxml&.at(ns('//bibdata/ext/doctype'))&.text || return
100
+ t = b.split(/[- ]/).map(&:capitalize).join(' ')
95
101
  set(:doctype, t)
96
102
  end
97
103
 
98
104
  def iso?(org)
99
- name = org&.at(ns("./name"))&.text
100
- abbrev = org&.at(ns("./abbreviation"))&.text
101
- (abbrev == "ISO" ||
102
- name == "International Organization for Standardization" )
105
+ name = org&.at(ns('./name'))&.text
106
+ abbrev = org&.at(ns('./abbreviation'))&.text
107
+ (abbrev == 'ISO' ||
108
+ name == 'International Organization for Standardization')
103
109
  end
104
110
 
105
111
  def agency(xml)
106
- agency = ""
112
+ agency = ''
107
113
  publisher = []
108
114
  xml.xpath(ns("//bibdata/contributor[xmlns:role/@type = 'publisher']/"\
109
- "organization")).each do |org|
110
- name = org&.at(ns("./name"))&.text
111
- agency1 = org&.at(ns("./abbreviation"))&.text || name
115
+ 'organization')).each do |org|
116
+ name = org&.at(ns('./name'))&.text
117
+ agency1 = org&.at(ns('./abbreviation'))&.text || name
112
118
  publisher << name if name
113
- agency = iso?(org) ? "ISO/#{agency}" : "#{agency}#{agency1}/"
119
+ agency = iso?(org) ? "ISO/#{agency}" : "#{agency}#{agency1}/"
114
120
  end
115
- set(:agency, agency.sub(%r{/$}, ""))
116
- set(:publisher, multiple_and(publisher, @labels["and"]))
121
+ set(:agency, agency.sub(%r{/$}, ''))
122
+ set(:publisher, multiple_and(publisher, @labels['and']))
117
123
  end
118
124
 
119
125
  def multiple_and(names, andword)
120
- return "" if names.length == 0
126
+ return '' if names.empty?
121
127
  return names[0] if names.length == 1
122
- names.length == 2 and
123
- return l10n("#{names[0]} #{andword} #{names[1]}", @lang, @script)
124
- l10n(names[0..-2].join(", ") + " #{andword} #{names[-1]}", @lang, @script)
128
+ (names.length == 2) &&
129
+ (return l10n("#{names[0]} #{andword} #{names[1]}", @lang, @script))
130
+ l10n(names[0..-2].join(', ') + " #{andword} #{names[-1]}", @lang, @script)
125
131
  end
126
132
 
127
133
  def docstatus(isoxml, _out)
128
- docstatus = isoxml.at(ns("//bibdata/status/stage"))
134
+ docstatus = isoxml.at(ns('//bibdata/status/stage'))
129
135
  set(:unpublished, true)
130
136
  if docstatus
131
137
  set(:stage, status_print(docstatus.text))
132
- i = isoxml&.at(ns("//bibdata/status/substage"))&.text and
138
+ (i = isoxml&.at(ns('//bibdata/status/substage'))&.text) &&
133
139
  set(:substage, i)
134
- i = isoxml&.at(ns("//bibdata/status/iteration"))&.text and
140
+ (i = isoxml&.at(ns('//bibdata/status/iteration'))&.text) &&
135
141
  set(:iteration, i)
136
142
  set(:unpublished, unpublished(docstatus.text))
137
- unpublished(docstatus.text) and
143
+ unpublished(docstatus.text) &&
138
144
  set(:stageabbr, stage_abbr(docstatus.text))
139
145
  end
140
146
  end
141
147
 
142
148
  def stage_abbr(docstatus)
143
- status_print(docstatus).split(/ /).
144
- map { |s| s[0].upcase }.join("")
149
+ status_print(docstatus).split(/ /)
150
+ .map { |s| s[0].upcase }.join('')
145
151
  end
146
152
 
147
153
  def unpublished(status)
148
- !(status.downcase == "published")
154
+ !status.casecmp('published').zero?
149
155
  end
150
156
 
151
157
  def status_print(status)
152
- status.split(/-/).map{ |w| w.capitalize }.join(" ")
158
+ status.split(/-/).map(&:capitalize).join(' ')
153
159
  end
154
160
 
155
161
  def docid(isoxml, _out)
156
- dn = isoxml.at(ns("//bibdata/docidentifier"))
162
+ dn = isoxml.at(ns('//bibdata/docidentifier'))
157
163
  set(:docnumber, dn&.text)
158
164
  end
159
165
 
160
166
  def docnumeric(isoxml, _out)
161
- dn = isoxml.at(ns("//bibdata/docnumber"))
167
+ dn = isoxml.at(ns('//bibdata/docnumber'))
162
168
  set(:docnumeric, dn&.text)
163
169
  end
164
170
 
165
171
  def draftinfo(draft, revdate)
166
- draftinfo = ""
172
+ draftinfo = ''
167
173
  if draft
168
- draftinfo = " (#{@labels["draft_label"]} #{draft}"
174
+ draftinfo = " (#{@labels['draft_label']} #{draft}"
169
175
  draftinfo += ", #{revdate}" if revdate
170
- draftinfo += ")"
176
+ draftinfo += ')'
171
177
  end
172
178
  l10n(draftinfo, @lang, @script)
173
179
  end
174
180
 
175
181
  def version(isoxml, _out)
176
- set(:edition, isoxml&.at(ns("//bibdata/edition"))&.text)
177
- set(:docyear, isoxml&.at(ns("//bibdata/copyright/from"))&.text)
178
- set(:draft, isoxml&.at(ns("//version/draft"))&.text)
179
- revdate = isoxml&.at(ns("//version/revision-date"))&.text
182
+ set(:edition, isoxml&.at(ns('//bibdata/edition'))&.text)
183
+ set(:docyear, isoxml&.at(ns('//bibdata/copyright/from'))&.text)
184
+ set(:draft, isoxml&.at(ns('//version/draft'))&.text)
185
+ revdate = isoxml&.at(ns('//version/revision-date'))&.text
180
186
  set(:revdate, revdate)
181
187
  set(:revdate_monthyear, monthyr(revdate))
182
188
  set(:draftinfo,
@@ -188,7 +194,7 @@ module IsoDoc
188
194
  set(:doctitle, main)
189
195
  end
190
196
 
191
- def subtitle(isoxml, _out)
197
+ def subtitle(_isoxml, _out)
192
198
  nil
193
199
  end
194
200
 
@@ -199,29 +205,29 @@ module IsoDoc
199
205
 
200
206
  def relations_partof(isoxml)
201
207
  std = isoxml.at(ns("//bibdata/relation[@type = 'partOf']")) || return
202
- id = std.at(ns(".//docidentifier"))
208
+ id = std.at(ns('.//docidentifier'))
203
209
  set(:partof, id.text) if id
204
210
  end
205
211
 
206
212
  def relations_obsoletes(isoxml)
207
213
  std = isoxml.at(ns("//bibdata/relation[@type = 'obsoletes']")) || return
208
- locality = std.at(ns(".//locality"))
209
- id = std.at(ns(".//docidentifier"))
214
+ locality = std.at(ns('.//locality'))
215
+ id = std.at(ns('.//docidentifier'))
210
216
  set(:obsoletes, id.text) if id
211
217
  set(:obsoletes_part, locality.text) if locality
212
218
  end
213
219
 
214
220
  def url(xml, _out)
215
- a = xml.at(ns("//bibdata/uri[not(@type)]")) and set(:url, a.text)
216
- a = xml.at(ns("//bibdata/uri[@type = 'html']")) and set(:html, a.text)
217
- a = xml.at(ns("//bibdata/uri[@type = 'xml']")) and set(:xml, a.text)
218
- a = xml.at(ns("//bibdata/uri[@type = 'pdf']")) and set(:pdf, a.text)
219
- a = xml.at(ns("//bibdata/uri[@type = 'doc']")) and set(:doc, a.text)
221
+ (a = xml.at(ns('//bibdata/uri[not(@type)]'))) && set(:url, a.text)
222
+ (a = xml.at(ns("//bibdata/uri[@type = 'html']"))) && set(:html, a.text)
223
+ (a = xml.at(ns("//bibdata/uri[@type = 'xml']"))) && set(:xml, a.text)
224
+ (a = xml.at(ns("//bibdata/uri[@type = 'pdf']"))) && set(:pdf, a.text)
225
+ (a = xml.at(ns("//bibdata/uri[@type = 'doc']"))) && set(:doc, a.text)
220
226
  end
221
227
 
222
228
  def keywords(isoxml, _out)
223
229
  ret = []
224
- isoxml.xpath(ns("//bibdata/keyword")).each { |kw| ret << kw.text }
230
+ isoxml.xpath(ns('//bibdata/keyword')).each { |kw| ret << kw.text }
225
231
  set(:keywords, ret)
226
232
  end
227
233
  end
@@ -24,19 +24,21 @@ module IsoDoc
24
24
 
25
25
  def initialize(options)
26
26
  @format = :pdf
27
+ @suffix = "pdf"
27
28
  super
28
29
  end
29
30
 
30
- def convert(filename, file = nil, debug = false)
31
- file = File.read(filename, encoding: "utf-8") if file.nil?
31
+ def convert(input_filename, file = nil, debug = false, output_filename = nil)
32
+ file = File.read(input_filename, encoding: "utf-8") if file.nil?
32
33
  @openmathdelim, @closemathdelim = extract_delims(file)
33
- docxml, outname_html, dir = convert_init(file, filename, debug)
34
+ docxml, filename, dir = convert_init(file, input_filename, debug)
34
35
  result = convert1(docxml, filename, dir)
35
36
  return result if debug
36
- postprocess(result, filename, dir)
37
+ postprocess(result, filename + ".tmp.html", dir)
37
38
  FileUtils.rm_rf dir
38
- ::Metanorma::Output::Pdf.new.convert("#{filename}.html", outname_html + ".pdf")
39
- FileUtils.rm_rf ["#{filename}.html", tmpimagedir]
39
+ ::Metanorma::Output::Pdf.new.convert("#{filename}.tmp.html",
40
+ output_filename || "#{filename}.#{@suffix}")
41
+ FileUtils.rm_rf ["#{filename}.tmp.html", tmpimagedir]
40
42
  end
41
43
 
42
44
  def xref_parse(node, out)
@@ -0,0 +1,29 @@
1
+ module IsoDoc
2
+ class PresentationXMLConvert < ::IsoDoc::Convert
3
+ def initialize(options)
4
+ @format = :presentation
5
+ @suffix = "presentation.xml"
6
+ super
7
+ end
8
+
9
+ def convert1(docxml, filename, dir)
10
+ @xrefs.parse docxml
11
+ info docxml, nil
12
+ docxml.to_xml
13
+ end
14
+
15
+ def postprocess(result, filename, dir)
16
+ #result = from_xhtml(cleanup(to_xhtml(textcleanup(result))))
17
+ toXML(result, filename)
18
+ @files_to_delete.each { |f| FileUtils.rm_rf f }
19
+ end
20
+
21
+ def toXML(result, filename)
22
+ #result = (from_xhtml(html_cleanup(to_xhtml(result))))
23
+ #result = from_xhtml(move_images(to_xhtml(result)))
24
+ #result = html5(script_cdata(inject_script(result)))
25
+ File.open(filename, "w:UTF-8") { |f| f.write(result) }
26
+ end
27
+ end
28
+ end
29
+
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sassc'
4
+
5
+ class SasscImporter < SassC::Importer
6
+ def imports(path, _parent_path)
7
+ unless path.match?(/(css|scss)$/)
8
+ Import.new("#{path}.scss")
9
+ end
10
+ end
11
+ end
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "1.0.29".freeze
2
+ VERSION = "1.1.3-alpha2".freeze
3
3
  end
@@ -32,10 +32,11 @@ module IsoDoc
32
32
 
33
33
  def initialize(options)
34
34
  @format = :doc
35
+ @suffix = "doc"
35
36
  super
36
37
  end
37
38
 
38
- def convert(filename, file = nil, debug = false)
39
+ def convert(filename, file = nil, debug = false, output_filename = nil)
39
40
  ret = super
40
41
  FileUtils.rm_rf tmpimagedir
41
42
  ret
@@ -156,7 +156,7 @@ module IsoDoc::WordFunction
156
156
  out.div **note_attrs(node) do |div|
157
157
  first = node.first_element_child
158
158
  div.p **{ class: "Note" } do |p|
159
- anchor = get_anchors[node['id']]
159
+ anchor = @xrefs.get[node['id']]
160
160
  p << "#{anchor&.dig(:label) || '???'}: "
161
161
  para_then_remainder(first, node, p, div)
162
162
  end
@@ -32,6 +32,7 @@ xmlns:m="http://schemas.microsoft.com/office/2004/12/omml">
32
32
  end
33
33
 
34
34
  def postprocess(result, filename, dir)
35
+ filename = filename.sub(/\.doc$/, "")
35
36
  header = generate_header(filename, dir)
36
37
  result = from_xhtml(cleanup(to_xhtml(textcleanup(result))))
37
38
  toWord(result, filename, dir, header)
@@ -0,0 +1,59 @@
1
+ require_relative "xref/xref_anchor"
2
+ require_relative "xref/xref_counter"
3
+ require_relative "xref/xref_gen_seq"
4
+ require_relative "xref/xref_gen"
5
+ require_relative "xref/xref_sect_gen"
6
+ require_relative "class_utils"
7
+
8
+ module IsoDoc
9
+ class Xref
10
+ include XrefGen::Anchor
11
+ include XrefGen::Blocks
12
+ include XrefGen::Sections
13
+
14
+ def initialize(lang, script, klass, labels, options = {})
15
+ @anchors = {}
16
+ @lang = lang
17
+ @script = script
18
+ @klass = klass
19
+ @labels = labels
20
+ @options = options
21
+ end
22
+
23
+ def get
24
+ @anchors
25
+ end
26
+
27
+ def anchor(id, lbl, warning = true)
28
+ return nil if id.nil? || id.empty?
29
+ unless @anchors[id]
30
+ if warning
31
+ @seen ||= Seen_Anchor.instance
32
+ @seen.seen(id) or warn "No label has been processed for ID #{id}"
33
+ @seen.add(id)
34
+ return "[#{id}]"
35
+ end
36
+ end
37
+ @anchors.dig(id, lbl)
38
+ end
39
+
40
+ # extract names for all anchors, xref and label
41
+ def parse(docxml)
42
+ initial_anchor_names(docxml)
43
+ back_anchor_names(docxml)
44
+ # preempt clause notes with all other types of note (ISO default)
45
+ note_anchor_names(docxml.xpath(ns("//table | //figure")))
46
+ note_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
47
+ example_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
48
+ list_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
49
+ end
50
+
51
+ def ns(xpath)
52
+ Common::ns(xpath)
53
+ end
54
+
55
+ def l10n(a, lang = @lang, script = @script)
56
+ IsoDoc::Function::I18n::l10n(a, lang, script)
57
+ end
58
+ end
59
+ end