de666280863078905bb9af53c69b31c1b9d34338
[redact.git] / lib / redact / app.rb
1 #--
2 # $Id: app.rb 1 2005-03-26 01:32:38Z tilman $
3 #
4 # Copyright (c) 2005 Tilman Sauerbeck (tilman at code-monkey de)
5 #
6 # Permission is hereby granted, free of charge, to any person obtaining
7 # a copy of this software and associated documentation files (the
8 # "Software"), to deal in the Software without restriction, including
9 # without limitation the rights to use, copy, modify, merge, publish,
10 # distribute, sublicense, and/or sell copies of the Software, and to
11 # permit persons to whom the Software is furnished to do so, subject to
12 # the following conditions:
13 #
14 # The above copyright notice and this permission notice shall be
15 # included in all copies or substantial portions of the Software.
16 #
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25 require "redact/redact.rb"
26 require "redact/source.rb"
27 require "ftools"
28 require "pathname"
29 require "ostruct"
30 require "optparse"
31
32 SCRIPT_LINES__ = {}
33
34 module Redact
35         class App
36                 def initialize(args)
37                         @filename = nil
38                         @options = OpenStruct.new
39                         @option_parser = parse_args(args)
40
41                         @options.input = args.first
42                         if @options.input.nil?
43                                 puts @option_parser.help
44                                 exit
45                         end
46
47                         @options.output ||= @options.input.sub(/.[^.]+$/, ".edj")
48                 end
49
50                 def run
51                         EDJE.clear
52                         SCRIPT_LINES__.clear
53
54                         begin
55                                 load @options.input
56                         rescue LoadError
57                                 raise("Cannot load '#{@options.input}'")
58                         end
59
60                         @filename = Pathname.new(@options.input).cleanpath.to_s
61
62                         if EDJE.collections.empty?
63                                 raise("No collections found")
64                         end
65
66                         amx = compile_embryo
67
68                         Eet::File.open(@options.output, "w") do |ef|
69                                 dump_amx(amx, ef)
70
71                                 dump_header(ef)
72                                 dump_collections(ef)
73                                 dump_fonts(ef)
74                                 dump_images(ef)
75                                 dump_source(ef)
76                                 dump_fontmap(ef)
77                         end
78                 end
79
80                 private
81                 def parse_args(args)
82                         OptionParser.new do |o|
83                                 o.banner = "Usage: redact [options] INPUT_FILE"
84
85                                 o.separator ""
86                                 o.separator "Specific options:"
87
88                                 o.on("-o", "--output OUTPUT_FILE",
89                                      "Write Edje to OUTPUT_FILE") do |file|
90                                         @options.output = file
91                                 end
92
93                                 o.on("--image_dir IMAGE_DIR",
94                                      "Add IMAGE_DIR to the image lookup path") do |dir|
95                                         @options.image_dir = dir
96                                 end
97
98                                 o.on("--font_dir FONT_DIR",
99                                      "Add FONT_DIR to the font lookup path") do |dir|
100                                         @options.font_dir = dir
101                                 end
102
103                                 o.separator ""
104                                 o.separator "Common options:"
105
106                                 o.on_tail("-h", "--help", "Show this message") do
107                                         puts o
108                                         exit
109                                 end
110
111                                 o.on_tail("--version", "Show version") do
112                                         puts <<EOT
113 redact #{Redact::VERSION}
114
115 Copyright (c) 2005 Tilman Sauerbeck (tilman at code-monkey de)
116 EOT
117                                         exit
118                                 end
119
120                                 o.parse!(args)
121                         end
122                 end
123
124                 def compile_embryo
125                         ret = {}
126
127                         EDJE.collections.each_value do |col|
128                                 next unless col.has_embryo?
129
130                                 File.open("/tmp/redact.sma", "w") do |tf|
131                                         tf.puts "#include <edje>"
132                                         dump_sma(tf, col)
133                                         tf.flush
134
135                                         out = "/tmp/redact.amx"
136                                         File.rm_f(out)
137
138                                         incl = `edje-config --datadir`.strip
139                                         c = "embryo_cc " +
140                                             "-i #{incl}/include " +
141                                             "-o #{out} #{tf.path}"
142                                         system(c)
143
144                                         ret[col.id] = IO.read(out)
145                                         File.rm_f(out)
146                                         File.unlink(tf.path)
147                                 end
148                         end
149
150                         ret
151                 end
152
153                 def dump_sma(tf, col)
154                         if col.has_embryo?(false)
155                                 tf.puts col.script.to_embryo(col)
156                         end
157
158                         col.programs.each_value do |p|
159                                 next unless p.is_a?(ExecScriptProgram)
160
161                                 s = p.script.to_embryo(col).gsub(/^(.+)$/, "\t\\1")
162
163                                 tf.puts <<EOT
164 public _p#{p.id}(sig[], src[])
165 {
166 #{s}
167 }
168 EOT
169                         end
170                 end
171
172                 def dump_amx(amx, ef)
173                         amx.each do |id, code|
174                                 ef.write("scripts/#{id}", code)
175                         end
176                 end
177
178                 def dump_header(ef)
179                         ef.write("edje_file", EDJE.to_eet)
180                 end
181
182                 def dump_collections(ef)
183                         EDJE.collections.each_value do |col|
184                                 ef.write("collections/#{col.id}", col.to_eet)
185                         end
186                 end
187
188                 def dump_fonts(ef)
189                         EDJE.font_dir.each do |entry|
190                                 ef.write("fonts/#{entry.filename}",
191                                          File.read(entry.filename))
192                         end
193                 end
194
195                 def dump_images(ef)
196                         EDJE.image_dir.each do |entry|
197                                 ef.write_image("images/#{entry.id}",
198                                                entry.image.data_for_reading_only,
199                                                entry.image.width, entry.image.height,
200                                                entry.image.has_alpha?)
201                         end
202                 end
203
204                 def dump_source(ef)
205                         s = SourceFiles.new
206
207                         SCRIPT_LINES__.each do |file, value|
208                                 sane = Pathname.new(file).cleanpath.to_s
209                                 method = (sane == @filename) ? :unshift : :push
210                                 s.send(method, SourceFile.new(sane, value.join))
211
212                                 # include files that are with File.read, too
213                                 value.join.grep(/File\.read\(\"(.+)\"\)/) do
214                                         sane = Pathname.new($1).cleanpath.to_s
215                                         s << SourceFile.new(sane, File.read(sane))
216                                 end
217                         end
218
219                         ef.write("edje_sources", s.to_eet)
220                 end
221
222                 def dump_fontmap(ef)
223                         fm = EDJE.font_dir.inject(FontMap.new) do |a, entry|
224                                 a << FontMapEntry.new(entry)
225                         end
226
227                         ef.write("edje_source_fontmap", fm.to_eet)
228                 end
229         end
230 end