isodoc 1.5.5 → 1.6.4

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/.github/workflows/rake.yml +2 -12
  3. data/.hound.yml +3 -1
  4. data/.rubocop.yml +3 -7
  5. data/Gemfile +2 -2
  6. data/Rakefile +2 -2
  7. data/bin/rspec +1 -2
  8. data/isodoc.gemspec +11 -11
  9. data/lib/isodoc-yaml/i18n-ar.yaml +152 -0
  10. data/lib/isodoc-yaml/i18n-de.yaml +149 -0
  11. data/lib/isodoc-yaml/i18n-es.yaml +151 -0
  12. data/lib/isodoc-yaml/i18n-ru.yaml +154 -0
  13. data/lib/isodoc.rb +0 -2
  14. data/lib/isodoc/base_style/all.css +7 -0
  15. data/lib/isodoc/base_style/metanorma_word.css +7 -0
  16. data/lib/isodoc/base_style/metanorma_word.scss +8 -0
  17. data/lib/isodoc/base_style/reset.css +7 -0
  18. data/lib/isodoc/base_style/reset.scss +9 -0
  19. data/lib/isodoc/base_style/scripts.html +187 -0
  20. data/lib/isodoc/class_utils.rb +6 -5
  21. data/lib/isodoc/common.rb +2 -0
  22. data/lib/isodoc/convert.rb +30 -17
  23. data/lib/isodoc/css.rb +43 -34
  24. data/lib/isodoc/function/blocks.rb +21 -4
  25. data/lib/isodoc/function/blocks_example_note.rb +2 -2
  26. data/lib/isodoc/function/cleanup.rb +53 -45
  27. data/lib/isodoc/function/form.rb +51 -0
  28. data/lib/isodoc/function/inline.rb +37 -15
  29. data/lib/isodoc/function/references.rb +55 -42
  30. data/lib/isodoc/function/section.rb +29 -16
  31. data/lib/isodoc/function/table.rb +1 -0
  32. data/lib/isodoc/function/to_word_html.rb +33 -29
  33. data/lib/isodoc/function/utils.rb +180 -159
  34. data/lib/isodoc/gem_tasks.rb +30 -31
  35. data/lib/isodoc/headlesshtml_convert.rb +8 -7
  36. data/lib/isodoc/html_convert.rb +6 -4
  37. data/lib/isodoc/html_function/comments.rb +2 -0
  38. data/lib/isodoc/html_function/footnotes.rb +14 -7
  39. data/lib/isodoc/html_function/form.rb +62 -0
  40. data/lib/isodoc/html_function/html.rb +30 -26
  41. data/lib/isodoc/html_function/postprocess.rb +41 -82
  42. data/lib/isodoc/html_function/postprocess_footnotes.rb +59 -0
  43. data/lib/isodoc/i18n.rb +33 -31
  44. data/lib/isodoc/pdf_convert.rb +12 -16
  45. data/lib/isodoc/presentation_function/bibdata.rb +54 -30
  46. data/lib/isodoc/presentation_function/block.rb +17 -8
  47. data/lib/isodoc/presentation_function/inline.rb +84 -120
  48. data/lib/isodoc/presentation_function/math.rb +84 -0
  49. data/lib/isodoc/presentation_function/section.rb +20 -22
  50. data/lib/isodoc/presentation_xml_convert.rb +2 -1
  51. data/lib/isodoc/sassc_importer.rb +1 -1
  52. data/lib/isodoc/version.rb +1 -1
  53. data/lib/isodoc/word_function/body.rb +28 -24
  54. data/lib/isodoc/word_function/footnotes.rb +22 -15
  55. data/lib/isodoc/word_function/postprocess.rb +50 -36
  56. data/lib/isodoc/xref.rb +9 -10
  57. data/lib/isodoc/xref/xref_counter.rb +32 -17
  58. data/lib/isodoc/xref/xref_gen.rb +33 -21
  59. data/lib/isodoc/xref/xref_gen_seq.rb +60 -35
  60. data/lib/isodoc/xref/xref_sect_gen.rb +37 -35
  61. data/lib/isodoc/xslfo_convert.rb +36 -27
  62. data/spec/assets/scripts_override.html +3 -0
  63. data/spec/isodoc/blocks_spec.rb +2490 -2591
  64. data/spec/isodoc/cleanup_spec.rb +1107 -1109
  65. data/spec/isodoc/footnotes_spec.rb +1 -16
  66. data/spec/isodoc/form_spec.rb +156 -0
  67. data/spec/isodoc/i18n_spec.rb +984 -972
  68. data/spec/isodoc/inline_spec.rb +1129 -912
  69. data/spec/isodoc/lists_spec.rb +316 -315
  70. data/spec/isodoc/postproc_spec.rb +1751 -1540
  71. data/spec/isodoc/presentation_xml_spec.rb +403 -323
  72. data/spec/isodoc/ref_spec.rb +718 -723
  73. data/spec/isodoc/section_spec.rb +910 -902
  74. data/spec/isodoc/table_spec.rb +566 -556
  75. data/spec/isodoc/terms_spec.rb +251 -255
  76. data/spec/isodoc/xref_spec.rb +3041 -2992
  77. data/spec/isodoc/xslfo_convert_spec.rb +39 -0
  78. data/spec/spec_helper.rb +30 -29
  79. metadata +77 -65
@@ -51,6 +51,7 @@ module IsoDoc::Function
51
51
 
52
52
  def tcaption(node, t)
53
53
  return unless node["summary"]
54
+
54
55
  t.caption do |c|
55
56
  c.span **{ style: "display:none" } do |s|
56
57
  s << node["summary"]
@@ -18,15 +18,23 @@ module IsoDoc::Function
18
18
 
19
19
  def init_file(filename, debug)
20
20
  filepath = Pathname.new(filename)
21
- filename = filepath.sub_ext('').sub(/\.presentation$/, "").to_s
21
+ filename = filepath.sub_ext("").sub(/\.presentation$/, "").to_s
22
+ dir = init_dir(filename, debug)
23
+ @filename = filename
24
+ @localdir = "#{filepath.parent}/"
25
+ @sourcedir = @localdir
26
+ @sourcefilename and
27
+ @sourcedir = "#{Pathname.new(@sourcefilename).parent}/"
28
+ [filename, dir]
29
+ end
30
+
31
+ def init_dir(filename, debug)
22
32
  dir = "#{filename}_files"
23
33
  unless debug
24
- Dir.mkdir(dir, 0777) unless File.exists?(dir)
34
+ Dir.mkdir(dir, 0o777) unless File.exists?(dir)
25
35
  FileUtils.rm_rf "#{dir}/*"
26
36
  end
27
- @filename = filename
28
- @localdir = filepath.parent.to_s + '/'
29
- [filename, dir]
37
+ dir
30
38
  end
31
39
 
32
40
  # tmp image dir is same directory as @filename
@@ -40,19 +48,18 @@ module IsoDoc::Function
40
48
 
41
49
  # isodoc.css overrides any CSS injected by Html2Doc, which
42
50
  # is inserted before this CSS.
43
- def define_head(head, filename, _dir)
51
+ def define_head(head, _filename, _dir)
44
52
  if @standardstylesheet
45
53
  head.style do |style|
46
54
  @standardstylesheet.open
47
- stylesheet = @standardstylesheet.read.
48
- gsub("FILENAME", File.basename(filename).sub(/\.presentation$/, ""))
55
+ stylesheet = @standardstylesheet.read
49
56
  style.comment "\n#{stylesheet}\n"
50
57
  end
51
58
  end
52
59
  end
53
60
 
54
61
  def body_attr
55
- { lang: "#{@lang}" }
62
+ { lang: @lang.to_s }
56
63
  end
57
64
 
58
65
  def make_body(xml, docxml)
@@ -70,7 +77,7 @@ module IsoDoc::Function
70
77
  section_break(body)
71
78
  end
72
79
 
73
- def make_body2(body, docxml)
80
+ def make_body2(body, _docxml)
74
81
  body.div **{ class: "prefatory-section" } do |div2|
75
82
  div2.p { |p| p << "&nbsp;" } # placeholder
76
83
  end
@@ -109,46 +116,36 @@ module IsoDoc::Function
109
116
  @meta.get
110
117
  end
111
118
 
112
- def middle_title(_isoxml, out)
113
- out.p(**{ class: "zzSTDTitle1" }) { |p| p << @meta.get[:doctitle] }
114
- end
115
-
116
- def middle_admonitions(isoxml, out)
117
- isoxml.xpath(ns("//sections/note | //sections/admonition")).each do |x|
118
- parse(x, out)
119
- end
120
- end
121
-
122
119
  def middle(isoxml, out)
123
120
  middle_title(isoxml, out)
124
121
  middle_admonitions(isoxml, out)
125
122
  i = scope isoxml, out, 0
126
123
  i = norm_ref isoxml, out, i
127
124
  i = terms_defs isoxml, out, i
128
- i = symbols_abbrevs isoxml, out, i
125
+ symbols_abbrevs isoxml, out, i
129
126
  clause isoxml, out
130
127
  annex isoxml, out
131
128
  bibliography isoxml, out
132
129
  end
133
130
 
134
131
  def boilerplate(node, out)
132
+ return if @bare
133
+
135
134
  boilerplate = node.at(ns("//boilerplate")) or return
136
- out.div **{class: "authority"} do |s|
135
+ out.div **{ class: "authority" } do |s|
137
136
  boilerplate.children.each do |n|
138
137
  if n.name == "title"
139
138
  s.h1 do |h|
140
139
  n.children.each { |nn| parse(nn, h) }
141
140
  end
142
- else
143
- parse(n, s)
141
+ else parse(n, s)
144
142
  end
145
143
  end
146
144
  end
147
145
  end
148
146
 
149
147
  def parse(node, out)
150
- if node.text?
151
- text_parse(node, out)
148
+ if node.text? then text_parse(node, out)
152
149
  else
153
150
  case node.name
154
151
  when "em" then em_parse(node, out)
@@ -225,9 +222,16 @@ module IsoDoc::Function
225
222
  when "passthrough" then passthrough_parse(node, out)
226
223
  when "amend" then amend_parse(node, out)
227
224
  when "tab" then clausedelimspace(out) # in Presentation XML only
228
- when "svg" then svg_parse(node, out) # introduced in Presentation XML only
229
- else
230
- error_parse(node, out)
225
+ when "svg" then svg_parse(node, out) # in Presentation XML only
226
+ when "add" then add_parse(node, out)
227
+ when "del" then del_parse(node, out)
228
+ when "form" then form_parse(node, out)
229
+ when "input" then input_parse(node, out)
230
+ when "select" then select_parse(node, out)
231
+ when "label" then label_parse(node, out)
232
+ when "option" then option_parse(node, out)
233
+ when "textarea" then textarea_parse(node, out)
234
+ else error_parse(node, out)
231
235
  end
232
236
  end
233
237
  end
@@ -1,190 +1,211 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module IsoDoc::Function
4
- module Utils
5
- def date_range(date)
6
- self.class.date_range(date)
7
- end
3
+ module IsoDoc
4
+ module Function
5
+ module Utils
6
+ def date_range(date)
7
+ self.class.date_range(date)
8
+ end
8
9
 
9
- def ns(xpath)
10
- self.class.ns(xpath)
11
- end
10
+ def ns(xpath)
11
+ self.class.ns(xpath)
12
+ end
12
13
 
13
- def insert_tab(out, n)
14
- tab = %w(Hans Hant).include?(@script) ? "&#x3000;" : "&nbsp; "
15
- [1..n].each { out << tab }
16
- end
14
+ def insert_tab(out, count)
15
+ tab = %w(Hans Hant).include?(@script) ? "&#x3000;" : "&nbsp; "
16
+ [1..count].each { out << tab }
17
+ end
17
18
 
18
- # add namespaces for Word fragments
19
- NOKOHEAD = <<~HERE
20
- <!DOCTYPE html SYSTEM
21
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
22
- <html xmlns="http://www.w3.org/1999/xhtml">
23
- <head> <title></title> <meta charset="UTF-8" /> </head>
24
- <body> </body> </html>
25
- HERE
26
-
27
- # block for processing XML document fragments as XHTML,
28
- # to allow for HTMLentities
29
- def noko(&block)
30
- doc = ::Nokogiri::XML.parse(NOKOHEAD)
31
- fragment = doc.fragment('')
32
- ::Nokogiri::XML::Builder.with fragment, &block
33
- fragment.to_xml(encoding: 'US-ASCII').lines.map do |l|
34
- l.gsub(/\s*\n/, '')
19
+ # add namespaces for Word fragments
20
+ NOKOHEAD = <<~HERE
21
+ <!DOCTYPE html SYSTEM
22
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
23
+ <html xmlns="http://www.w3.org/1999/xhtml">
24
+ <head> <title></title> <meta charset="UTF-8" /> </head>
25
+ <body> </body> </html>
26
+ HERE
27
+
28
+ # block for processing XML document fragments as XHTML,
29
+ # to allow for HTMLentities
30
+ def noko(&block)
31
+ doc = ::Nokogiri::XML.parse(NOKOHEAD)
32
+ fragment = doc.fragment("")
33
+ ::Nokogiri::XML::Builder.with fragment, &block
34
+ fragment.to_xml(encoding: "US-ASCII").lines.map do |l|
35
+ l.gsub(/\s*\n/, "")
36
+ end
35
37
  end
36
- end
37
38
 
38
- def attr_code(attributes)
39
- attributes = attributes.reject { |_, val| val.nil? }.map
40
- attributes.map do |k, v|
41
- [k, v.is_a?(String) ? HTMLEntities.new.decode(v) : v]
42
- end.to_h
43
- end
39
+ def attr_code(attributes)
40
+ attributes = attributes.reject { |_, val| val.nil? }.map
41
+ attributes.map do |k, v|
42
+ [k, v.is_a?(String) ? HTMLEntities.new.decode(v) : v]
43
+ end.to_h
44
+ end
44
45
 
45
- DOCTYPE_HDR = '<!DOCTYPE html SYSTEM '\
46
- '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
47
-
48
- def to_xhtml(xml)
49
- xml.gsub!(/<\?xml[^>]*>/, '')
50
- /<!DOCTYPE /.match(xml) || (xml = DOCTYPE_HDR + xml)
51
- xml = xml.split(/(\&[^ \r\n\t#;]+;)/).map do |t|
52
- /^(\&[^ \t\r\n#;]+;)/.match?(t) ?
53
- HTMLEntities.new.encode(HTMLEntities.new.decode(t), :hexadecimal) : t
54
- end.join('')
55
- begin
56
- Nokogiri::XML.parse(xml, &:strict)
57
- rescue Nokogiri::XML::SyntaxError => e
58
- File.open("#{@filename}.#{@format}.err", 'w:UTF-8') { |f| f.write xml }
59
- abort "Malformed Output XML for #{@format}: #{e} (see #{@filename}.#{@format}.err)"
46
+ DOCTYPE_HDR = "<!DOCTYPE html SYSTEM "\
47
+ '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
48
+
49
+ def to_xhtml(xml)
50
+ xml = to_xhtml_prep(xml)
51
+ begin
52
+ Nokogiri::XML.parse(xml, &:strict)
53
+ rescue Nokogiri::XML::SyntaxError => e
54
+ File.open("#{@filename}.#{@format}.err", "w:UTF-8") do |f|
55
+ f.write xml
56
+ end
57
+ abort "Malformed Output XML for #{@format}: #{e} "\
58
+ "(see #{@filename}.#{@format}.err)"
59
+ end
60
60
  end
61
- end
62
61
 
63
- def to_xhtml_fragment(xml)
64
- doc = ::Nokogiri::XML.parse(NOKOHEAD)
65
- fragment = doc.fragment(xml)
66
- fragment
67
- end
62
+ def to_xhtml_prep(xml)
63
+ xml.gsub!(/<\?xml[^>]*>/, "")
64
+ /<!DOCTYPE /.match(xml) || (xml = DOCTYPE_HDR + xml)
65
+ xml.split(/(&[^ \r\n\t#;]+;)/).map do |t|
66
+ if /^(&[^ \t\r\n#;]+;)/.match?(t)
67
+ HTMLEntities.new.encode(HTMLEntities.new.decode(t), :hexadecimal)
68
+ else t
69
+ end
70
+ end.join("")
71
+ end
68
72
 
69
- def from_xhtml(xml)
70
- xml.to_xml.sub(%r{ xmlns="http://www.w3.org/1999/xhtml"}, '')
71
- end
73
+ def to_xhtml_fragment(xml)
74
+ doc = ::Nokogiri::XML.parse(NOKOHEAD)
75
+ doc.fragment(xml)
76
+ end
72
77
 
73
- CLAUSE_ANCESTOR =
74
- ".//ancestor::*[local-name() = 'annex' or "\
75
- "local-name() = 'acknowledgements' or local-name() = 'term' or "\
76
- "local-name() = 'appendix' or local-name() = 'foreword' or "\
77
- "local-name() = 'introduction' or local-name() = 'terms' or "\
78
- "local-name() = 'clause' or local-name() = 'references']/@id"
78
+ def from_xhtml(xml)
79
+ xml.to_xml.sub(%r{ xmlns="http://www.w3.org/1999/xhtml"}, "")
80
+ end
79
81
 
80
- def get_clause_id(node)
81
- clause = node.xpath(CLAUSE_ANCESTOR)
82
- clause&.last&.text || nil
83
- end
82
+ CLAUSE_ANCESTOR =
83
+ ".//ancestor::*[local-name() = 'annex' or "\
84
+ "local-name() = 'definitions' or "\
85
+ "local-name() = 'acknowledgements' or local-name() = 'term' or "\
86
+ "local-name() = 'appendix' or local-name() = 'foreword' or "\
87
+ "local-name() = 'introduction' or local-name() = 'terms' or "\
88
+ "local-name() = 'clause' or local-name() = 'references']/@id"
89
+
90
+ def get_clause_id(node)
91
+ clause = node.xpath(CLAUSE_ANCESTOR)
92
+ clause&.last&.text || nil
93
+ end
84
94
 
85
- NOTE_CONTAINER_ANCESTOR =
86
- ".//ancestor::*[local-name() = 'annex' or "\
87
- "local-name() = 'foreword' or local-name() = 'appendix' or "\
88
- "local-name() = 'introduction' or local-name() = 'terms' or "\
89
- "local-name() = 'acknowledgements' or local-name() = 'term' or "\
90
- "local-name() = 'clause' or local-name() = 'references' or "\
91
- "local-name() = 'figure' or local-name() = 'formula' or "\
92
- "local-name() = 'table' or local-name() = 'example']/@id"
93
-
94
- def get_note_container_id(node)
95
- container = node.xpath(NOTE_CONTAINER_ANCESTOR)
96
- container&.last&.text || nil
97
- end
95
+ NOTE_CONTAINER_ANCESTOR =
96
+ ".//ancestor::*[local-name() = 'annex' or "\
97
+ "local-name() = 'foreword' or local-name() = 'appendix' or "\
98
+ "local-name() = 'introduction' or local-name() = 'terms' or "\
99
+ "local-name() = 'acknowledgements' or local-name() = 'term' or "\
100
+ "local-name() = 'clause' or local-name() = 'references' or "\
101
+ "local-name() = 'figure' or local-name() = 'formula' or "\
102
+ "local-name() = 'table' or local-name() = 'example']/@id"
103
+
104
+ def get_note_container_id(node)
105
+ container = node.xpath(NOTE_CONTAINER_ANCESTOR)
106
+ container&.last&.text || nil
107
+ end
98
108
 
99
- def sentence_join(array)
100
- return '' if array.nil? || array.empty?
101
- if array.length == 1 then array[0]
102
- else
103
- @i18n.l10n("#{array[0..-2].join(', ')} "\
104
- "#{@i18n.and} #{array.last}",
105
- @lang, @script)
109
+ def sentence_join(array)
110
+ return "" if array.nil? || array.empty?
111
+
112
+ if array.length == 1 then array[0]
113
+ else
114
+ @i18n.l10n("#{array[0..-2].join(', ')} "\
115
+ "#{@i18n.and} #{array.last}",
116
+ @lang, @script)
117
+ end
106
118
  end
107
- end
108
119
 
109
- # avoid `; avoid {{ (Liquid Templates); avoid [[ (Javascript)
110
- def extract_delims(text)
111
- @openmathdelim = '(#('
112
- @closemathdelim = ')#)'
113
- while text.include?(@openmathdelim) || text.include?(@closemathdelim)
114
- @openmathdelim += '('
115
- @closemathdelim += ')'
120
+ # avoid `; avoid {{ (Liquid Templates); avoid [[ (Javascript)
121
+ def extract_delims(text)
122
+ @openmathdelim = "(#("
123
+ @closemathdelim = ")#)"
124
+ while text.include?(@openmathdelim) || text.include?(@closemathdelim)
125
+ @openmathdelim += "("
126
+ @closemathdelim += ")"
127
+ end
128
+ [@openmathdelim, @closemathdelim]
116
129
  end
117
- [@openmathdelim, @closemathdelim]
118
- end
119
130
 
120
- def header_strip(h)
121
- h = h.to_s.gsub(%r{<br\s*/>}, ' ').gsub(/<\/?h[123456][^>]*>/, '')
122
- .gsub(/<\/?b[^>]*>/, '')
123
- h1 = to_xhtml_fragment(h.dup)
124
- h1.traverse do |x|
125
- x.replace(' ') if x.name == 'span' && /mso-tab-count/.match(x['style'])
126
- x.remove if x.name == 'span' && x['class'] == 'MsoCommentReference'
127
- x.remove if x.name == 'a' && x['class'] == 'FootnoteRef'
128
- x.remove if x.name == 'span' && /mso-bookmark/.match(x['style'])
129
- x.replace(x.children) if x.name == 'a'
130
- end
131
- from_xhtml(h1)
132
- end
131
+ def header_strip(hdr)
132
+ h1 = to_xhtml_fragment(hdr.to_s.gsub(%r{<br\s*/>}, " ")
133
+ .gsub(/<\/?h[123456][^>]*>/, "").gsub(/<\/?b[^>]*>/, "").dup)
134
+ h1.traverse do |x|
135
+ if x.name == "span" && /mso-tab-count/.match(x["style"])
136
+ x.replace(" ")
137
+ elsif header_strip_elem?(x) then x.remove
138
+ elsif x.name == "a" then x.replace(x.children)
139
+ end
140
+ end
141
+ from_xhtml(h1)
142
+ end
133
143
 
134
- def liquid(doc)
135
- self.class.liquid(doc)
136
- end
144
+ def header_strip_elem?(elem)
145
+ elem.name == "img" ||
146
+ elem.name == "span" && elem["class"] == "MsoCommentReference" ||
147
+ elem.name == "a" && elem["class"] == "FootnoteRef" ||
148
+ elem.name == "span" && /mso-bookmark/.match(elem["style"])
149
+ end
137
150
 
138
- def liquid(doc)
139
- # unescape HTML escapes in doc
140
- doc = doc.split(%r<(\{%|%\})>).each_slice(4).map do |a|
141
- a[2] = a[2].gsub(/\&lt;/, '<').gsub(/\&gt;/, '>') if a.size > 2
142
- a.join('')
143
- end.join('')
144
- Liquid::Template.parse(doc)
145
- end
151
+ =begin
152
+ def liquid(doc)
153
+ self.class.liquid(doc)
154
+ end
155
+ =end
156
+
157
+ def liquid(doc)
158
+ # unescape HTML escapes in doc
159
+ doc = doc.split(%r<(\{%|%\})>).each_slice(4).map do |a|
160
+ a[2] = a[2].gsub(/&lt;/, "<").gsub(/&gt;/, ">") if a.size > 2
161
+ a.join("")
162
+ end.join("")
163
+ Liquid::Template.parse(doc)
164
+ end
146
165
 
147
- def empty2nil(v)
148
- return nil if !v.nil? && v.is_a?(String) && v.empty?
149
- v
150
- end
166
+ def empty2nil(str)
167
+ return nil if !str.nil? && str.is_a?(String) && str.empty?
151
168
 
152
- def populate_template(docxml, _format = nil)
153
- meta = @meta
154
- .get
155
- .merge(@labels ? {labels: @labels} : {})
156
- .merge(@meta.labels ? {labels: @meta.labels} : {})
157
- .merge(fonts_options || {})
158
- template = liquid(docxml)
159
- template.render(meta.map { |k, v| [k.to_s, empty2nil(v)] }.to_h)
160
- .gsub('&lt;', '&#x3c;').gsub('&gt;', '&#x3e;').gsub('&amp;', '&#x26;')
161
- end
169
+ str
170
+ end
162
171
 
163
- def save_dataimage(uri, _relative_dir = true)
164
- %r{^data:(image|application)/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ uri
165
- imgtype.sub!(/\+[a-z0-9]+$/, '') # svg+xml
166
- imgtype = 'png' unless /^[a-z0-9]+$/.match imgtype
167
- Tempfile.open(['image', ".#{imgtype}"]) do |f|
168
- f.binmode
169
- f.write(Base64.strict_decode64(imgdata))
170
- @tempfile_cache << f # persist to the end
171
- f.path
172
+ def populate_template(docxml, _format = nil)
173
+ meta = @meta
174
+ .get
175
+ .merge(@labels ? { labels: @labels } : {})
176
+ .merge(@meta.labels ? { labels: @meta.labels } : {})
177
+ .merge(fonts_options || {})
178
+ template = liquid(docxml)
179
+ template.render(meta.map { |k, v| [k.to_s, empty2nil(v)] }.to_h)
180
+ .gsub("&lt;", "&#x3c;").gsub("&gt;", "&#x3e;").gsub("&amp;", "&#x26;")
172
181
  end
173
- end
174
182
 
175
- def image_localfile(i)
176
- if /^data:/.match? i['src']
177
- save_dataimage(i['src'], false)
178
- elsif %r{^([A-Z]:)?/}.match? i['src']
179
- i['src']
180
- else
181
- File.join(@localdir, i['src'])
183
+ def save_dataimage(uri, _relative_dir = true)
184
+ %r{^data:(image|application)/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ uri
185
+ imgtype.sub!(/\+[a-z0-9]+$/, "") # svg+xml
186
+ imgtype = "png" unless /^[a-z0-9]+$/.match? imgtype
187
+ Tempfile.open(["image", ".#{imgtype}"]) do |f|
188
+ f.binmode
189
+ f.write(Base64.strict_decode64(imgdata))
190
+ @tempfile_cache << f # persist to the end
191
+ f.path
192
+ end
193
+ end
194
+
195
+ def image_localfile(img)
196
+ if /^data:/.match? img["src"]
197
+ save_dataimage(img["src"], false)
198
+ elsif %r{^([A-Z]:)?/}.match? img["src"]
199
+ img["src"]
200
+ else
201
+ File.join(@localdir, img["src"])
202
+ end
182
203
  end
183
- end
184
204
 
185
- def labelled_ancestor(node)
186
- !node.ancestors('example, requirement, recommendation, permission, '\
187
- 'note, table, figure, sourcecode').empty?
205
+ def labelled_ancestor(node)
206
+ !node.ancestors("example, requirement, recommendation, permission, "\
207
+ "note, table, figure, sourcecode").empty?
208
+ end
188
209
  end
189
210
  end
190
211
  end