isodoc 1.0.27 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/macos.yml +4 -8
  3. data/.github/workflows/ubuntu.yml +18 -16
  4. data/.github/workflows/windows.yml +4 -8
  5. data/Rakefile +3 -1
  6. data/isodoc.gemspec +2 -2
  7. data/lib/isodoc.rb +2 -0
  8. data/lib/isodoc/base_style/metanorma_word.scss +0 -1
  9. data/lib/isodoc/base_style/reset.scss +3 -3
  10. data/lib/isodoc/common.rb +0 -4
  11. data/lib/isodoc/convert.rb +121 -58
  12. data/lib/isodoc/function/blocks.rb +42 -53
  13. data/lib/isodoc/function/blocks_example_note.rb +108 -0
  14. data/lib/isodoc/function/cleanup.rb +8 -4
  15. data/lib/isodoc/function/i18n.rb +1 -0
  16. data/lib/isodoc/function/inline.rb +70 -90
  17. data/lib/isodoc/function/inline_simple.rb +72 -0
  18. data/lib/isodoc/function/lists.rb +12 -6
  19. data/lib/isodoc/function/references.rb +33 -38
  20. data/lib/isodoc/function/reqt.rb +14 -5
  21. data/lib/isodoc/function/section.rb +8 -11
  22. data/lib/isodoc/function/table.rb +4 -4
  23. data/lib/isodoc/function/terms.rb +3 -3
  24. data/lib/isodoc/function/to_word_html.rb +21 -13
  25. data/lib/isodoc/function/utils.rb +57 -50
  26. data/lib/isodoc/gem_tasks.rb +104 -0
  27. data/lib/isodoc/headlesshtml_convert.rb +7 -6
  28. data/lib/isodoc/html_convert.rb +2 -1
  29. data/lib/isodoc/html_function/footnotes.rb +1 -1
  30. data/lib/isodoc/html_function/html.rb +13 -1
  31. data/lib/isodoc/html_function/postprocess.rb +4 -4
  32. data/lib/isodoc/metadata.rb +74 -62
  33. data/lib/isodoc/pdf_convert.rb +8 -6
  34. data/lib/isodoc/presentation_xml_convert.rb +29 -0
  35. data/lib/isodoc/sassc_importer.rb +11 -0
  36. data/lib/isodoc/version.rb +1 -1
  37. data/lib/isodoc/word_convert.rb +2 -1
  38. data/lib/isodoc/word_function/body.rb +14 -48
  39. data/lib/isodoc/word_function/footnotes.rb +1 -1
  40. data/lib/isodoc/word_function/inline.rb +75 -0
  41. data/lib/isodoc/word_function/postprocess.rb +1 -0
  42. data/lib/isodoc/word_function/table.rb +3 -3
  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 +41 -32
  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/assets/i18n.yaml +4 -1
  52. data/spec/assets/odf.emf +0 -0
  53. data/spec/assets/odf.svg +4 -0
  54. data/spec/assets/odf1.svg +4 -0
  55. data/spec/isodoc/blocks_spec.rb +219 -47
  56. data/spec/isodoc/cleanup_spec.rb +135 -6
  57. data/spec/isodoc/footnotes_spec.rb +22 -7
  58. data/spec/isodoc/inline_spec.rb +262 -2
  59. data/spec/isodoc/lists_spec.rb +8 -8
  60. data/spec/isodoc/metadata_spec.rb +110 -3
  61. data/spec/isodoc/postproc_spec.rb +1321 -1351
  62. data/spec/isodoc/presentation_xml_spec.rb +20 -0
  63. data/spec/isodoc/ref_spec.rb +119 -50
  64. data/spec/isodoc/section_spec.rb +84 -18
  65. data/spec/isodoc/table_spec.rb +6 -6
  66. data/spec/isodoc/terms_spec.rb +7 -7
  67. data/spec/isodoc/xref_spec.rb +165 -45
  68. metadata +36 -27
  69. data/lib/isodoc/function/blocks_example.rb +0 -53
  70. data/lib/isodoc/function/xref_counter.rb +0 -50
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module IsoDoc::Function
2
4
  module Utils
3
5
  def date_range(date)
@@ -9,50 +11,50 @@ module IsoDoc::Function
9
11
  end
10
12
 
11
13
  def insert_tab(out, n)
12
- [1..n].each { out << "&nbsp; " }
14
+ [1..n].each { out << '&nbsp; ' }
13
15
  end
14
16
 
15
17
  # add namespaces for Word fragments
16
- NOKOHEAD = <<~HERE.freeze
17
- <!DOCTYPE html SYSTEM
18
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
19
- <html xmlns="http://www.w3.org/1999/xhtml">
20
- <head> <title></title> <meta charset="UTF-8" /> </head>
21
- <body> </body> </html>
18
+ NOKOHEAD = <<~HERE
19
+ <!DOCTYPE html SYSTEM
20
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
21
+ <html xmlns="http://www.w3.org/1999/xhtml">
22
+ <head> <title></title> <meta charset="UTF-8" /> </head>
23
+ <body> </body> </html>
22
24
  HERE
23
25
 
24
26
  # block for processing XML document fragments as XHTML,
25
27
  # to allow for HTMLentities
26
28
  def noko(&block)
27
29
  doc = ::Nokogiri::XML.parse(NOKOHEAD)
28
- fragment = doc.fragment("")
30
+ fragment = doc.fragment('')
29
31
  ::Nokogiri::XML::Builder.with fragment, &block
30
- fragment.to_xml(encoding: "US-ASCII").lines.map do |l|
31
- l.gsub(/\s*\n/, "")
32
+ fragment.to_xml(encoding: 'US-ASCII').lines.map do |l|
33
+ l.gsub(/\s*\n/, '')
32
34
  end
33
35
  end
34
36
 
35
37
  def attr_code(attributes)
36
38
  attributes = attributes.reject { |_, val| val.nil? }.map
37
39
  attributes.map do |k, v|
38
- [k, (v.is_a? String) ? HTMLEntities.new.decode(v) : v]
40
+ [k, v.is_a?(String) ? HTMLEntities.new.decode(v) : v]
39
41
  end.to_h
40
42
  end
41
43
 
42
44
  DOCTYPE_HDR = '<!DOCTYPE html SYSTEM '\
43
- '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'.freeze
45
+ '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
44
46
 
45
47
  def to_xhtml(xml)
46
- xml.gsub!(/<\?xml[^>]*>/, "")
47
- /<!DOCTYPE /.match xml or xml = DOCTYPE_HDR + xml
48
+ xml.gsub!(/<\?xml[^>]*>/, '')
49
+ /<!DOCTYPE /.match(xml) || (xml = DOCTYPE_HDR + xml)
48
50
  xml = xml.split(/(\&[^ \r\n\t#;]+;)/).map do |t|
49
- /^(\&[^ \t\r\n#;]+;)/.match(t) ?
51
+ /^(\&[^ \t\r\n#;]+;)/.match?(t) ?
50
52
  HTMLEntities.new.encode(HTMLEntities.new.decode(t), :hexadecimal) : t
51
- end.join("")
53
+ end.join('')
52
54
  begin
53
- Nokogiri::XML.parse(xml) { |config| config.strict }
55
+ Nokogiri::XML.parse(xml, &:strict)
54
56
  rescue Nokogiri::XML::SyntaxError => e
55
- File.open("#{@filename}.#{@format}.err", "w:UTF-8") { |f| f.write xml }
57
+ File.open("#{@filename}.#{@format}.err", 'w:UTF-8') { |f| f.write xml }
56
58
  abort "Malformed Output XML for #{@format}: #{e} (see #{@filename}.#{@format}.err)"
57
59
  end
58
60
  end
@@ -64,7 +66,7 @@ module IsoDoc::Function
64
66
  end
65
67
 
66
68
  def from_xhtml(xml)
67
- xml.to_xml.sub(%r{ xmlns="http://www.w3.org/1999/xhtml"}, "")
69
+ xml.to_xml.sub(%r{ xmlns="http://www.w3.org/1999/xhtml"}, '')
68
70
  end
69
71
 
70
72
  CLAUSE_ANCESTOR =
@@ -72,7 +74,7 @@ module IsoDoc::Function
72
74
  "local-name() = 'acknowledgements' or local-name() = 'term' or "\
73
75
  "local-name() = 'appendix' or local-name() = 'foreword' or "\
74
76
  "local-name() = 'introduction' or local-name() = 'terms' or "\
75
- "local-name() = 'clause' or local-name() = 'references']/@id".freeze
77
+ "local-name() = 'clause' or local-name() = 'references']/@id"
76
78
 
77
79
  def get_clause_id(node)
78
80
  clause = node.xpath(CLAUSE_ANCESTOR)
@@ -86,7 +88,7 @@ module IsoDoc::Function
86
88
  "local-name() = 'acknowledgements' or local-name() = 'term' or "\
87
89
  "local-name() = 'clause' or local-name() = 'references' or "\
88
90
  "local-name() = 'figure' or local-name() = 'formula' or "\
89
- "local-name() = 'table' or local-name() = 'example']/@id".freeze
91
+ "local-name() = 'table' or local-name() = 'example']/@id"
90
92
 
91
93
  def get_note_container_id(node)
92
94
  container = node.xpath(NOTE_CONTAINER_ANCESTOR)
@@ -94,7 +96,7 @@ module IsoDoc::Function
94
96
  end
95
97
 
96
98
  def sentence_join(array)
97
- return "" if array.nil? || array.empty?
99
+ return '' if array.nil? || array.empty?
98
100
  if array.length == 1 then array[0]
99
101
  else
100
102
  IsoDoc::Function::I18n::l10n("#{array[0..-2].join(', ')} "\
@@ -105,25 +107,25 @@ module IsoDoc::Function
105
107
 
106
108
  # avoid `; avoid {{ (Liquid Templates); avoid [[ (Javascript)
107
109
  def extract_delims(text)
108
- @openmathdelim = "(#("
109
- @closemathdelim = ")#)"
110
+ @openmathdelim = '(#('
111
+ @closemathdelim = ')#)'
110
112
  while text.include?(@openmathdelim) || text.include?(@closemathdelim)
111
- @openmathdelim += "("
112
- @closemathdelim += ")"
113
+ @openmathdelim += '('
114
+ @closemathdelim += ')'
113
115
  end
114
116
  [@openmathdelim, @closemathdelim]
115
117
  end
116
118
 
117
119
  def header_strip(h)
118
- h = h.to_s.gsub(%r{<br\s*/>}, " ").gsub(/<\/?h[123456][^>]*>/, "").
119
- gsub(/<\/?b[^>]*>/, "")
120
+ h = h.to_s.gsub(%r{<br\s*/>}, ' ').gsub(/<\/?h[123456][^>]*>/, '')
121
+ .gsub(/<\/?b[^>]*>/, '')
120
122
  h1 = to_xhtml_fragment(h.dup)
121
123
  h1.traverse do |x|
122
- x.replace(" ") if x.name == "span" && /mso-tab-count/.match(x["style"])
123
- x.remove if x.name == "span" && x["class"] == "MsoCommentReference"
124
- x.remove if x.name == "a" && x["epub:type"] == "footnote"
125
- x.remove if x.name == "span" && /mso-bookmark/.match(x["style"])
126
- x.replace(x.children) if x.name == "a"
124
+ x.replace(' ') if x.name == 'span' && /mso-tab-count/.match(x['style'])
125
+ x.remove if x.name == 'span' && x['class'] == 'MsoCommentReference'
126
+ x.remove if x.name == 'a' && x['class'] == 'FootnoteRef'
127
+ x.remove if x.name == 'span' && /mso-bookmark/.match(x['style'])
128
+ x.replace(x.children) if x.name == 'a'
127
129
  end
128
130
  from_xhtml(h1)
129
131
  end
@@ -135,9 +137,9 @@ module IsoDoc::Function
135
137
  def liquid(doc)
136
138
  # unescape HTML escapes in doc
137
139
  doc = doc.split(%r<(\{%|%\})>).each_slice(4).map do |a|
138
- a[2] = a[2].gsub(/\&lt;/, "<").gsub(/\&gt;/, ">") if a.size > 2
139
- a.join("")
140
- end.join("")
140
+ a[2] = a[2].gsub(/\&lt;/, '<').gsub(/\&gt;/, '>') if a.size > 2
141
+ a.join('')
142
+ end.join('')
141
143
  Liquid::Template.parse(doc)
142
144
  end
143
145
 
@@ -147,36 +149,41 @@ module IsoDoc::Function
147
149
  end
148
150
 
149
151
  def populate_template(docxml, _format = nil)
150
- meta = @meta.get.merge(@labels || {})
152
+ meta = @meta
153
+ .get
154
+ .merge(@labels || {})
155
+ .merge(@meta.labels || {})
156
+ .merge(@meta.fonts_options || {})
151
157
  template = liquid(docxml)
152
- template.render(meta.map { |k, v| [k.to_s, empty2nil(v)] }.to_h).
153
- gsub('&lt;', '&#x3c;').gsub('&gt;', '&#x3e;').gsub('&amp;', '&#x26;')
158
+ template.render(meta.map { |k, v| [k.to_s, empty2nil(v)] }.to_h)
159
+ .gsub('&lt;', '&#x3c;').gsub('&gt;', '&#x3e;').gsub('&amp;', '&#x26;')
154
160
  end
155
161
 
156
- def save_dataimage(uri, relative_dir = true)
162
+ def save_dataimage(uri, _relative_dir = true)
157
163
  %r{^data:image/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ uri
158
- imgtype = "png" unless /^[a-z0-9]+$/.match imgtype
159
- Tempfile.open(["image", ".#{imgtype}"]) do |f|
164
+ imgtype.sub!(/\+[a-z0-9]+$/, '') # svg+xml
165
+ imgtype = 'png' unless /^[a-z0-9]+$/.match imgtype
166
+ Tempfile.open(['image', ".#{imgtype}"]) do |f|
160
167
  f.binmode
161
168
  f.write(Base64.strict_decode64(imgdata))
162
- @tempfile_cache << f #persist to the end
169
+ @tempfile_cache << f # persist to the end
163
170
  f.path
164
171
  end
165
172
  end
166
173
 
167
174
  def image_localfile(i)
168
- if /^data:image/.match i["src"]
169
- save_dataimage(i["src"], false)
170
- elsif %r{^([A-Z]:)?/}.match i["src"]
171
- i["src"]
175
+ if /^data:image/.match? i['src']
176
+ save_dataimage(i['src'], false)
177
+ elsif %r{^([A-Z]:)?/}.match? i['src']
178
+ i['src']
172
179
  else
173
- File.join(@localdir, i["src"])
180
+ File.join(@localdir, i['src'])
174
181
  end
175
182
  end
176
183
 
177
184
  def labelled_ancestor(node)
178
- return !node.ancestors("example, requirement, recommendation, permission, "\
179
- "table, figure, sourcecode").empty?
185
+ !node.ancestors('example, requirement, recommendation, permission, '\
186
+ 'table, figure, sourcecode').empty?
180
187
  end
181
188
  end
182
189
  end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sassc'
4
+ require 'isodoc/sassc_importer'
5
+ require 'rake/clean'
6
+
7
+ module IsoDoc
8
+ module GemTasks
9
+ extend Rake::DSL if defined? Rake::DSL
10
+
11
+ module_function
12
+
13
+ def install
14
+ rule '.css' => [proc { |tn| tn.sub(/\.css$/, '.scss') }] do |current_task|
15
+ begin
16
+ puts(current_task)
17
+ compile_scss_task(current_task)
18
+ rescue StandardError => e
19
+ puts(e.message)
20
+ puts("skiping #{current_task}")
21
+ end
22
+ end
23
+
24
+ scss_files = Rake::FileList['lib/**/*.scss']
25
+ source_files = scss_files.ext('.css')
26
+
27
+ task :comment_out_liquid do
28
+ process_css_files(scss_files) do |file_name|
29
+ comment_out_liquid(File.read(file_name, encoding: 'UTF-8'))
30
+ end
31
+ end
32
+
33
+ task build_scss: [:comment_out_liquid].push(*source_files) do
34
+ process_css_files(scss_files) do |file_name|
35
+ uncomment_out_liquid(File.read(file_name, encoding: 'UTF-8'))
36
+ end
37
+ puts('Built scss!')
38
+ end
39
+
40
+ Rake::Task['build'].enhance [:build_scss] do
41
+ Rake::Task[:clean].invoke
42
+ end
43
+ end
44
+
45
+ def process_css_files(scss_files)
46
+ scss_files.each do |file_name|
47
+ result = yield(file_name)
48
+ File.open(file_name, 'w', encoding: 'UTF-8') do |file|
49
+ file.puts(result)
50
+ end
51
+ end
52
+ end
53
+
54
+ def comment_out_liquid(text)
55
+ text.split("\n").map do |line|
56
+ if line.match?(/{({|%).+(}|%)}/)
57
+ "/* LIQUID_COMMENT#{line}LIQUID_COMMENT */"
58
+ else
59
+ line
60
+ end
61
+ end
62
+ .join("\n")
63
+ end
64
+
65
+ def uncomment_out_liquid(text)
66
+ text
67
+ .gsub('/* LIQUID_COMMENT', '')
68
+ .gsub('LIQUID_COMMENT */', '')
69
+ .gsub('"{{', '{{').gsub('}}"', '}}')
70
+ end
71
+
72
+ def fonts_placeholder
73
+ <<~TEXT
74
+ $bodyfont: '{{bodyfont}}';
75
+ $headerfont: '{{headerfont}}';
76
+ $monospacefont: '{{monospacefont}}';
77
+ TEXT
78
+ end
79
+
80
+ def compile_scss(filename)
81
+ require 'sassc'
82
+ [File.join(Gem.loaded_specs['isodoc'].full_gem_path, 'lib', 'isodoc'),
83
+ File.dirname(filename)].each do |name|
84
+ SassC.load_paths << name
85
+ end
86
+ sheet_content = File.read(filename, encoding: 'UTF-8')
87
+ SassC::Engine.new(fonts_placeholder + sheet_content,
88
+ syntax: :scss,
89
+ importer: SasscImporter)
90
+ .render
91
+ end
92
+
93
+ def compile_scss_task(current_task)
94
+ filename = current_task.source
95
+ basename = File.basename(filename, '.*')
96
+ compiled_path = File.join(File.dirname(filename), "#{basename}.css")
97
+ content = uncomment_out_liquid(compile_scss(filename))
98
+ File.open(compiled_path, 'w:UTF-8') do |f|
99
+ f.write(content)
100
+ end
101
+ CLEAN << compiled_path
102
+ end
103
+ end
104
+ end
@@ -16,18 +16,19 @@ module IsoDoc
16
16
 
17
17
  def initialize(options)
18
18
  @format = :html
19
+ @suffix = "headless.html"
19
20
  super
20
21
  end
21
22
 
22
- def convert(filename, file = nil, debug = false)
23
- file = File.read(filename, encoding: "utf-8") if file.nil?
23
+ def convert(input_filename, file = nil, debug = false, output_filename = nil)
24
+ file = File.read(input_filename, encoding: "utf-8") if file.nil?
24
25
  @openmathdelim, @closemathdelim = extract_delims(file)
25
- docxml, outname_html, dir = convert_init(file, filename, debug)
26
- result = convert1(docxml, outname_html, dir)
26
+ docxml, filename, dir = convert_init(file, input_filename, debug)
27
+ result = convert1(docxml, filename, dir)
27
28
  return result if debug
28
- postprocess(result, filename + ".tmp", dir)
29
+ postprocess(result, filename + ".tmp.html", dir)
29
30
  FileUtils.rm_rf dir
30
- strip_head(filename + ".tmp.html", outname_html + ".headless.html")
31
+ strip_head(filename + ".tmp.html", output_filename || "#{filename}.#{@suffix}")
31
32
  FileUtils.rm_rf ["#{filename}.tmp.html", tmpimagedir]
32
33
  end
33
34
 
@@ -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
@@ -65,7 +65,7 @@ module IsoDoc::HtmlFunction
65
65
  return table_footnote_parse(node, out) if (@in_table || @in_figure) &&
66
66
  !node.ancestors.map {|m| m.name }.include?("name")
67
67
  fn = node["reference"] || UUIDTools::UUID.random_create.to_s
68
- attrs = { "epub:type": "footnote", rel: "footnote", href: "#fn:#{fn}" }
68
+ attrs = { class: "FootnoteRef", href: "#fn:#{fn}" }
69
69
  out.a **attrs do |a|
70
70
  a.sup { |sup| sup << fn }
71
71
  end
@@ -3,6 +3,18 @@ require "base64"
3
3
 
4
4
  module IsoDoc::HtmlFunction
5
5
  module Html
6
+ def convert1(docxml, filename, dir)
7
+ @xrefs.parse docxml
8
+ noko do |xml|
9
+ xml.html **{ lang: "#{@lang}" } do |html|
10
+ info docxml, nil
11
+ populate_css()
12
+ html.head { |head| define_head head, filename, dir }
13
+ make_body(html, docxml)
14
+ end
15
+ end.join("\n")
16
+ end
17
+
6
18
  def make_body1(body, _docxml)
7
19
  body.div **{ class: "title-section" } do |div1|
8
20
  div1.p { |p| p << "&nbsp;" } # placeholder
@@ -90,7 +102,7 @@ module IsoDoc::HtmlFunction
90
102
  def sourcecode_parse(node, out)
91
103
  name = node.at(ns("./name"))
92
104
  class1 = "prettyprint #{sourcecodelang(node&.at(ns('./@lang'))&.value)}"
93
- out.pre **attr_code(id: node["id"], class: class1) do |div|
105
+ out.pre **sourcecode_attrs(node).merge(class: class1) do |div|
94
106
  @sourcecode = true
95
107
  node.children.each { |n| parse(n, div) unless n.name == "name" }
96
108
  @sourcecode = false
@@ -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)
@@ -179,7 +179,7 @@ module IsoDoc::HtmlFunction
179
179
  def html_footnote_filter(docxml)
180
180
  seen = {}
181
181
  i = 1
182
- docxml.xpath('//a[@epub:type = "footnote"]').each do |x|
182
+ docxml.xpath('//a[@class = "FootnoteRef"]').each do |x|
183
183
  fn = docxml.at(%<//*[@id = '#{x['href'].sub(/^#/, '')}']>) || next
184
184
  i, seen = update_footnote_filter(fn, x, i, seen)
185
185
  end
@@ -188,7 +188,7 @@ module IsoDoc::HtmlFunction
188
188
 
189
189
  def footnote_backlinks(docxml)
190
190
  seen = {}
191
- docxml.xpath('//a[@epub:type = "footnote"]').each_with_index do |x, i|
191
+ docxml.xpath('//a[@class = "FootnoteRef"]').each_with_index do |x, i|
192
192
  seen[x["href"]] and next or seen[x["href"]] = true
193
193
  fn = docxml.at(%<//*[@id = '#{x['href'].sub(/^#/, '')}']>) || next
194
194
  xdup = x.dup
@@ -201,7 +201,7 @@ module IsoDoc::HtmlFunction
201
201
  end
202
202
 
203
203
  def footnote_format(docxml)
204
- docxml.xpath("//a[@epub:type = 'footnote']/sup").each do |x|
204
+ docxml.xpath("//a[@class = 'FootnoteRef']/sup").each do |x|
205
205
  footnote_reference_format(x)
206
206
  end
207
207
  docxml.xpath("//a[@class = 'TableFootnoteRef'] | "\
@@ -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,24 +205,30 @@ 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)
226
+ end
227
+
228
+ def keywords(isoxml, _out)
229
+ ret = []
230
+ isoxml.xpath(ns('//bibdata/keyword')).each { |kw| ret << kw.text }
231
+ set(:keywords, ret)
220
232
  end
221
233
  end
222
234
  end