isodoc 1.0.28 → 1.1.3.pre.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) 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/i18n.rb +1 -0
  15. data/lib/isodoc/function/inline.rb +25 -8
  16. data/lib/isodoc/function/lists.rb +12 -6
  17. data/lib/isodoc/function/references.rb +31 -36
  18. data/lib/isodoc/function/reqt.rb +14 -5
  19. data/lib/isodoc/function/section.rb +7 -11
  20. data/lib/isodoc/function/table.rb +4 -4
  21. data/lib/isodoc/function/terms.rb +3 -3
  22. data/lib/isodoc/function/to_word_html.rb +2 -2
  23. data/lib/isodoc/function/utils.rb +57 -50
  24. data/lib/isodoc/gem_tasks.rb +110 -0
  25. data/lib/isodoc/headlesshtml_convert.rb +7 -6
  26. data/lib/isodoc/html_convert.rb +2 -1
  27. data/lib/isodoc/html_function/html.rb +2 -2
  28. data/lib/isodoc/html_function/postprocess.rb +1 -1
  29. data/lib/isodoc/metadata.rb +69 -63
  30. data/lib/isodoc/pdf_convert.rb +8 -6
  31. data/lib/isodoc/presentation_xml_convert.rb +29 -0
  32. data/lib/isodoc/sassc_importer.rb +11 -0
  33. data/lib/isodoc/version.rb +1 -1
  34. data/lib/isodoc/word_convert.rb +2 -1
  35. data/lib/isodoc/word_function/body.rb +14 -48
  36. data/lib/isodoc/word_function/inline.rb +75 -0
  37. data/lib/isodoc/word_function/postprocess.rb +1 -0
  38. data/lib/isodoc/word_function/table.rb +3 -3
  39. data/lib/isodoc/xref.rb +59 -0
  40. data/lib/isodoc/{function → xref}/xref_anchor.rb +10 -21
  41. data/lib/isodoc/xref/xref_counter.rb +74 -0
  42. data/lib/isodoc/{function → xref}/xref_gen.rb +9 -22
  43. data/lib/isodoc/{function → xref}/xref_gen_seq.rb +41 -32
  44. data/lib/isodoc/{function → xref}/xref_sect_gen.rb +33 -23
  45. data/lib/isodoc/xslfo_convert.rb +16 -4
  46. data/spec/assets/{html.css → html.scss} +0 -0
  47. data/spec/assets/odf.emf +0 -0
  48. data/spec/assets/odf.svg +4 -0
  49. data/spec/assets/odf1.svg +4 -0
  50. data/spec/isodoc/blocks_spec.rb +216 -44
  51. data/spec/isodoc/footnotes_spec.rb +2 -2
  52. data/spec/isodoc/inline_spec.rb +208 -1
  53. data/spec/isodoc/lists_spec.rb +8 -8
  54. data/spec/isodoc/metadata_spec.rb +107 -3
  55. data/spec/isodoc/postproc_spec.rb +1320 -1350
  56. data/spec/isodoc/presentation_xml_spec.rb +20 -0
  57. data/spec/isodoc/ref_spec.rb +5 -5
  58. data/spec/isodoc/section_spec.rb +52 -0
  59. data/spec/isodoc/table_spec.rb +4 -4
  60. data/spec/isodoc/terms_spec.rb +7 -7
  61. data/spec/isodoc/xref_spec.rb +165 -45
  62. metadata +37 -29
  63. data/lib/isodoc/function/blocks_example.rb +0 -53
  64. data/lib/isodoc/function/xref_counter.rb +0 -50
@@ -2,7 +2,7 @@ module IsoDoc::Function
2
2
  module Blocks
3
3
  def recommendation_labels(node)
4
4
  [node.at(ns("./label")), node.at(ns("./title")),
5
- anchor(node['id'], :label, false)]
5
+ @xrefs.anchor(node['id'], :label, false)]
6
6
  end
7
7
 
8
8
  def recommendation_name(node, out, type)
@@ -60,8 +60,12 @@ module IsoDoc::Function
60
60
  %w(label title subject classification tag value inherit).include? n.name
61
61
  end
62
62
 
63
+ def reqt_attrs(node, klass)
64
+ attr_code(class: klass, id: node["id"], style: keep_style(node))
65
+ end
66
+
63
67
  def recommendation_parse(node, out)
64
- out.div **{ class: "recommend" } do |t|
68
+ out.div **reqt_attrs(node, "recommend") do |t|
65
69
  recommendation_name(node, t, @recommendation_lbl)
66
70
  recommendation_attributes(node, out)
67
71
  node.children.each do |n|
@@ -71,7 +75,7 @@ module IsoDoc::Function
71
75
  end
72
76
 
73
77
  def requirement_parse(node, out)
74
- out.div **{ class: "require" } do |t|
78
+ out.div **reqt_attrs(node, "require") do |t|
75
79
  recommendation_name(node, t, @requirement_lbl)
76
80
  recommendation_attributes(node, out)
77
81
  node.children.each do |n|
@@ -81,7 +85,7 @@ module IsoDoc::Function
81
85
  end
82
86
 
83
87
  def permission_parse(node, out)
84
- out.div **{ class: "permission" } do |t|
88
+ out.div **reqt_attrs(node, "permission") do |t|
85
89
  recommendation_name(node, t, @permission_lbl)
86
90
  recommendation_attributes(node, out)
87
91
  node.children.each do |n|
@@ -90,9 +94,14 @@ module IsoDoc::Function
90
94
  end
91
95
  end
92
96
 
97
+ def reqt_component_attrs(node)
98
+ attr_code(class: "requirement-" + node.name,
99
+ style: keep_style(node))
100
+ end
101
+
93
102
  def requirement_component_parse(node, out)
94
103
  return if node["exclude"] == "true"
95
- out.div **{ class: "requirement-" + node.name } do |div|
104
+ out.div **reqt_component_attrs(node) do |div|
96
105
  node.children.each do |n|
97
106
  parse(n, div)
98
107
  end
@@ -11,8 +11,8 @@ module IsoDoc::Function
11
11
  def inline_header_title(out, node, c1)
12
12
  out.span **{ class: "zzMoveToFollowing" } do |s|
13
13
  s.b do |b|
14
- if anchor(node['id'], :label, false) && !@suppressheadingnumbers
15
- b << "#{anchor(node['id'], :label)}#{clausedelim}"
14
+ if @xrefs.anchor(node['id'], :label, false) && !@suppressheadingnumbers
15
+ b << "#{@xrefs.anchor(node['id'], :label)}#{clausedelim}"
16
16
  clausedelimspace(out)
17
17
  end
18
18
  c1&.children&.each { |c2| parse(c2, b) }
@@ -26,8 +26,8 @@ module IsoDoc::Function
26
26
  if node["inline-header"] == "true"
27
27
  inline_header_title(out, node, c1)
28
28
  else
29
- div.send "h#{anchor(node['id'], :level, false) || '1'}" do |h|
30
- lbl = anchor(node['id'], :label, false)
29
+ div.send "h#{@xrefs.anchor(node['id'], :level, false) || '1'}" do |h|
30
+ lbl = @xrefs.anchor(node['id'], :label, false)
31
31
  h << "#{lbl}#{clausedelim}" if lbl && !@suppressheadingnumbers
32
32
  clausedelimspace(out) if lbl && !@suppressheadingnumbers
33
33
  c1&.children&.each { |c2| parse(c2, h) }
@@ -58,14 +58,10 @@ module IsoDoc::Function
58
58
  div.parent.at(".//h1")
59
59
  end
60
60
 
61
- MIDDLE_CLAUSE =
62
- "//clause[parent::sections][not(xmlns:title = 'Scope')]"\
63
- "[not(descendant::terms)]".freeze
64
-
65
61
  def clause(isoxml, out)
66
- isoxml.xpath(ns(self.class::MIDDLE_CLAUSE)).each do |c|
62
+ isoxml.xpath(ns(middle_clause)).each do |c|
67
63
  out.div **attr_code(id: c["id"]) do |s|
68
- clause_name(anchor(c['id'], :label),
64
+ clause_name(@xrefs.anchor(c['id'], :label),
69
65
  c&.at(ns("./title")), s, nil)
70
66
  c.elements.reject { |c1| c1.name == "title" }.each do |c1|
71
67
  parse(c1, s)
@@ -76,7 +72,7 @@ module IsoDoc::Function
76
72
 
77
73
  def annex_name(annex, name, div)
78
74
  div.h1 **{ class: "Annex" } do |t|
79
- t << "#{anchor(annex['id'], :label)}<br/><br/>"
75
+ t << "#{@xrefs.anchor(annex['id'], :label)}<br/><br/>"
80
76
  t.b do |b|
81
77
  name&.children&.each { |c2| parse(c2, b) }
82
78
  end
@@ -3,7 +3,7 @@ module IsoDoc::Function
3
3
 
4
4
  def table_title_parse(node, out)
5
5
  name = node.at(ns("./name"))
6
- lbl = anchor(node['id'], :label, false)
6
+ lbl = @xrefs.anchor(node['id'], :label, false)
7
7
  lbl = nil if labelled_ancestor(node)
8
8
  return if name.nil? && lbl.nil?
9
9
  out.p **{ class: "TableTitle", style: "text-align:center;" } do |p|
@@ -44,12 +44,12 @@ module IsoDoc::Function
44
44
  end
45
45
  end
46
46
 
47
- def make_table_attr(node)
47
+ def table_attrs(node)
48
48
  width = node["width"] ? "width:#{node['width']};" : nil
49
49
  attr_code(
50
50
  id: node["id"],
51
51
  class: "MsoISOTable",
52
- style: "border-width:1px;border-spacing:0;#{width}",
52
+ style: "border-width:1px;border-spacing:0;#{width}#{keep_style(node)}",
53
53
  title: node["alt"]
54
54
  )
55
55
  end
@@ -66,7 +66,7 @@ module IsoDoc::Function
66
66
  def table_parse(node, out)
67
67
  @in_table = true
68
68
  table_title_parse(node, out)
69
- out.table **make_table_attr(node) do |t|
69
+ out.table **table_attrs(node) do |t|
70
70
  tcaption(node, t)
71
71
  thead_parse(node, t)
72
72
  tbody_parse(node, t)
@@ -40,10 +40,10 @@ module IsoDoc::Function
40
40
  end
41
41
 
42
42
  def termnote_parse(node, out)
43
- out.div **{ class: "Note" } do |div|
43
+ out.div **note_attrs(node) do |div|
44
44
  first = node.first_element_child
45
45
  div.p do |p|
46
- p << "#{anchor(node['id'], :label) || '???'}: "
46
+ p << "#{@xrefs.anchor(node['id'], :label) || '???'}: "
47
47
  para_then_remainder(first, node, p, div)
48
48
  end
49
49
  end
@@ -59,7 +59,7 @@ module IsoDoc::Function
59
59
 
60
60
  def termdef_parse(node, out)
61
61
  out.p **{ class: "TermNum", id: node["id"] } do |p|
62
- p << "#{get_anchors[node["id"]][:label]}#{clausedelim}"
62
+ p << "#{@xrefs.get[node["id"]][:label]}#{clausedelim}"
63
63
  end
64
64
  set_termdomain("")
65
65
  node.children.each { |n| parse(n, out) }
@@ -18,7 +18,7 @@ module IsoDoc::Function
18
18
 
19
19
  def init_file(filename, debug)
20
20
  filepath = Pathname.new(filename)
21
- filename = filepath.sub_ext('').to_s
21
+ filename = filepath.sub_ext('').sub(/\.presentation$/, "").to_s
22
22
  dir = "#{filename}_files"
23
23
  unless debug
24
24
  Dir.mkdir(dir, 0777) unless File.exists?(dir)
@@ -45,7 +45,7 @@ module IsoDoc::Function
45
45
  head.style do |style|
46
46
  @standardstylesheet.open
47
47
  stylesheet = @standardstylesheet.read.
48
- gsub("FILENAME", File.basename(filename))
48
+ gsub("FILENAME", File.basename(filename).sub(/\.presentation$/, ""))
49
49
  style.comment "\n#{stylesheet}\n"
50
50
  end
51
51
  end
@@ -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["class"] == "FootnoteRef"
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,110 @@
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
+ CLEAN.each do |css_file|
38
+ sh "git add #{css_file}"
39
+ end
40
+ puts('Built scss!')
41
+ end
42
+
43
+ Rake::Task['build'].enhance [:build_scss] do
44
+ CLEAN.each do |css_file|
45
+ sh "git rm --cached #{css_file}"
46
+ end
47
+ Rake::Task[:clean].invoke
48
+ end
49
+ end
50
+
51
+ def process_css_files(scss_files)
52
+ scss_files.each do |file_name|
53
+ result = yield(file_name)
54
+ File.open(file_name, 'w', encoding: 'UTF-8') do |file|
55
+ file.puts(result)
56
+ end
57
+ end
58
+ end
59
+
60
+ def comment_out_liquid(text)
61
+ text.split("\n").map do |line|
62
+ if line.match?(/{({|%).+(}|%)}/)
63
+ "/* LIQUID_COMMENT#{line}LIQUID_COMMENT */"
64
+ else
65
+ line
66
+ end
67
+ end
68
+ .join("\n")
69
+ end
70
+
71
+ def uncomment_out_liquid(text)
72
+ text
73
+ .gsub('/* LIQUID_COMMENT', '')
74
+ .gsub('LIQUID_COMMENT */', '')
75
+ .gsub('"{{', '{{').gsub('}}"', '}}')
76
+ end
77
+
78
+ def fonts_placeholder
79
+ <<~TEXT
80
+ $bodyfont: '{{bodyfont}}';
81
+ $headerfont: '{{headerfont}}';
82
+ $monospacefont: '{{monospacefont}}';
83
+ TEXT
84
+ end
85
+
86
+ def compile_scss(filename)
87
+ require 'sassc'
88
+ [File.join(Gem.loaded_specs['isodoc'].full_gem_path, 'lib', 'isodoc'),
89
+ File.dirname(filename)].each do |name|
90
+ SassC.load_paths << name
91
+ end
92
+ sheet_content = File.read(filename, encoding: 'UTF-8')
93
+ SassC::Engine.new(fonts_placeholder + sheet_content,
94
+ syntax: :scss,
95
+ importer: SasscImporter)
96
+ .render
97
+ end
98
+
99
+ def compile_scss_task(current_task)
100
+ filename = current_task.source
101
+ basename = File.basename(filename, '.*')
102
+ compiled_path = File.join(File.dirname(filename), "#{basename}.css")
103
+ content = uncomment_out_liquid(compile_scss(filename))
104
+ File.open(compiled_path, 'w:UTF-8') do |f|
105
+ f.write(content)
106
+ end
107
+ CLEAN << compiled_path
108
+ end
109
+ end
110
+ end