rabbit 1.0.9 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. data/GPL +19 -20
  2. data/Rakefile +25 -10
  3. data/bin/rabbit +20 -844
  4. data/bin/rabbit-command +25 -36
  5. data/bin/rabbit-slide +22 -0
  6. data/bin/rabbit-theme +22 -0
  7. data/bin/rabbit-theme-manager +30 -30
  8. data/data/account.kou.gpg +0 -0
  9. data/data/locale/en/LC_MESSAGES/rabbit.mo +0 -0
  10. data/data/locale/fr/LC_MESSAGES/rabbit.mo +0 -0
  11. data/data/locale/ja/LC_MESSAGES/rabbit.mo +0 -0
  12. data/doc/_config.yml +8 -0
  13. data/doc/_includes/en.menu.html +8 -0
  14. data/doc/_includes/ja.menu.html +8 -0
  15. data/doc/_layouts/en.html +19 -16
  16. data/doc/_layouts/ja.html +19 -16
  17. data/doc/_plugins/converters/rd.rb +1 -1
  18. data/doc/_plugins/support_symlink.rb +11 -0
  19. data/doc/en/development.rd +2 -2
  20. data/doc/en/how-to-make/index.rd +5 -5
  21. data/doc/en/how-to-make/rd.rd +1 -1
  22. data/doc/en/index.rd +6 -12
  23. data/doc/en/sample/index.rd +3 -3
  24. data/doc/en/slides.rd +2 -0
  25. data/doc/en/usage.rd +14 -356
  26. data/doc/en/usage/rabbit.rd +360 -0
  27. data/doc/en/users.rd +3 -1
  28. data/doc/images/screenshots/en/blue-circle-raw.png +0 -0
  29. data/doc/images/screenshots/en/blue-circle.png +0 -0
  30. data/doc/images/screenshots/en/clear-blue-raw.png +0 -0
  31. data/doc/images/screenshots/en/clear-blue.png +0 -0
  32. data/doc/images/screenshots/en/cozmixng-raw.png +0 -0
  33. data/doc/images/screenshots/en/cozmixng.png +0 -0
  34. data/doc/images/screenshots/en/dark-gradation-raw.png +0 -0
  35. data/doc/images/screenshots/en/dark-gradation.png +0 -0
  36. data/doc/images/screenshots/en/day-white.png +0 -0
  37. data/doc/images/screenshots/en/debian-raw.png +0 -0
  38. data/doc/images/screenshots/en/debian.png +0 -0
  39. data/doc/images/screenshots/en/green-circle-raw.png +0 -0
  40. data/doc/images/screenshots/en/green-circle.png +0 -0
  41. data/doc/images/screenshots/en/night-black.png +0 -0
  42. data/doc/images/screenshots/en/rabbit-raw.png +0 -0
  43. data/doc/images/screenshots/en/rabbit.png +0 -0
  44. data/doc/images/screenshots/en/ranguba-raw.png +0 -0
  45. data/doc/images/screenshots/en/ranguba.png +0 -0
  46. data/doc/images/screenshots/en/red-frame-raw.png +0 -0
  47. data/doc/images/screenshots/en/red-frame.png +0 -0
  48. data/doc/images/screenshots/en/ruby-gnome2-raw.png +0 -0
  49. data/doc/images/screenshots/en/ruby-gnome2.png +0 -0
  50. data/doc/images/screenshots/en/rubykaigi2011-raw.png +0 -0
  51. data/doc/images/screenshots/en/rubykaigi2011.png +0 -0
  52. data/doc/images/screenshots/ja/blue-circle-raw.png +0 -0
  53. data/doc/images/screenshots/ja/blue-circle.png +0 -0
  54. data/doc/images/screenshots/ja/clear-blue-raw.png +0 -0
  55. data/doc/images/screenshots/ja/clear-blue.png +0 -0
  56. data/doc/images/screenshots/ja/cozmixng-raw.png +0 -0
  57. data/doc/images/screenshots/ja/cozmixng.png +0 -0
  58. data/doc/images/screenshots/ja/dark-gradation-raw.png +0 -0
  59. data/doc/images/screenshots/ja/dark-gradation.png +0 -0
  60. data/doc/images/screenshots/ja/day-white.png +0 -0
  61. data/doc/images/screenshots/ja/debian-raw.png +0 -0
  62. data/doc/images/screenshots/ja/debian.png +0 -0
  63. data/doc/images/screenshots/ja/green-circle-raw.png +0 -0
  64. data/doc/images/screenshots/ja/green-circle.png +0 -0
  65. data/doc/images/screenshots/ja/night-black.png +0 -0
  66. data/doc/images/screenshots/ja/rabbit-raw.png +0 -0
  67. data/doc/images/screenshots/ja/rabbit.png +0 -0
  68. data/doc/images/screenshots/ja/ranguba-raw.png +0 -0
  69. data/doc/images/screenshots/ja/ranguba.png +0 -0
  70. data/doc/images/screenshots/ja/red-frame-raw.png +0 -0
  71. data/doc/images/screenshots/ja/red-frame.png +0 -0
  72. data/doc/images/screenshots/ja/ruby-gnome2-raw.png +0 -0
  73. data/doc/images/screenshots/ja/ruby-gnome2.png +0 -0
  74. data/doc/images/screenshots/ja/rubykaigi2011-raw.png +0 -0
  75. data/doc/images/screenshots/ja/rubykaigi2011.png +0 -0
  76. data/doc/index.html.en +1 -1
  77. data/doc/index.html.ja +1 -1
  78. data/doc/ja/about.rd +3 -3
  79. data/doc/ja/development.rd +2 -2
  80. data/doc/ja/how-to-make/index.rd +5 -5
  81. data/doc/ja/index.rd +10 -16
  82. data/doc/ja/install/macports.rd +1 -1
  83. data/doc/ja/news.rd +4 -4
  84. data/doc/ja/sample/index.rd +3 -3
  85. data/doc/ja/usage.rd +13 -358
  86. data/doc/ja/usage/rabbit.rd +362 -0
  87. data/doc/ja/users.rd +1 -1
  88. data/lib/rabbit/action.rb +2 -2
  89. data/lib/rabbit/author-configuration.rb +73 -0
  90. data/lib/rabbit/canvas.rb +0 -14
  91. data/lib/rabbit/command/rabbit-slide.rb +571 -0
  92. data/lib/rabbit/command/rabbit-theme.rb +381 -0
  93. data/lib/rabbit/command/rabbit.rb +898 -0
  94. data/lib/rabbit/config.rb +40 -0
  95. data/lib/rabbit/console.rb +124 -55
  96. data/lib/rabbit/gem-finder.rb +61 -0
  97. data/lib/rabbit/gettext.rb +6 -79
  98. data/lib/rabbit/html/generator.rb +1 -0
  99. data/lib/rabbit/image.rb +1 -1
  100. data/lib/rabbit/logger.rb +12 -2
  101. data/lib/rabbit/logger/base.rb +33 -32
  102. data/lib/rabbit/logger/stderr.rb +1 -1
  103. data/lib/rabbit/menu.rb +1 -1
  104. data/lib/rabbit/parser.rb +2 -0
  105. data/lib/rabbit/parser/ext/image.rb +14 -20
  106. data/lib/rabbit/path-manipulatable.rb +40 -0
  107. data/lib/rabbit/rabbit.rb +18 -8
  108. data/lib/rabbit/renderer/base.rb +3 -4
  109. data/lib/rabbit/renderer/color.rb +0 -1
  110. data/lib/rabbit/slideshare.rb +116 -0
  111. data/lib/rabbit/source/base.rb +1 -1
  112. data/lib/rabbit/stock.rb +1 -1
  113. data/lib/rabbit/task.rb +18 -0
  114. data/lib/rabbit/task/slide.rb +162 -0
  115. data/lib/rabbit/task/theme.rb +122 -0
  116. data/lib/rabbit/theme-browser/tree.rb +1 -1
  117. data/lib/rabbit/theme/applier.rb +9 -0
  118. data/lib/rabbit/theme/background-image-toolkit/background-image-toolkit.rb +1 -2
  119. data/lib/rabbit/theme/blue-bar/blue-bar.rb +0 -11
  120. data/lib/rabbit/theme/clear-blue/clear-blue.rb +0 -11
  121. data/lib/rabbit/theme/cozmixng/cozmixng.rb +0 -11
  122. data/lib/rabbit/theme/day-white/day-white.rb +0 -6
  123. data/lib/rabbit/theme/default/default.rb +7 -1
  124. data/lib/rabbit/theme/enishi-green/property.rb +2 -2
  125. data/lib/rabbit/theme/entry.rb +85 -27
  126. data/lib/rabbit/theme/image-slide-number/image-slide-number.rb +4 -1
  127. data/lib/rabbit/theme/lightning-monochrome/lightning-monochrome.rb +0 -1
  128. data/lib/rabbit/theme/lightning-simple/lightning-simple.rb +0 -1
  129. data/lib/rabbit/theme/nari/nari.rb +6 -16
  130. data/lib/rabbit/theme/nari/property.rb +3 -0
  131. data/lib/rabbit/theme/night-black/night-black.rb +0 -6
  132. data/lib/rabbit/theme/pdf/pdf.rb +0 -4
  133. data/lib/rabbit/theme/rabbit/rabbit.rb +0 -6
  134. data/lib/rabbit/theme/ranguba/ranguba.rb +0 -12
  135. data/lib/rabbit/theme/ruby-gnome2/ruby-gnome2.rb +7 -4
  136. data/lib/rabbit/theme/rubykaigi2011/rubykaigi2011.rb +2 -9
  137. data/lib/rabbit/theme/searcher.rb +38 -16
  138. data/lib/rabbit/theme/syntax-highlighting/property.rb +2 -2
  139. data/lib/rabbit/version.rb +19 -0
  140. data/po/en/rabbit.po +1605 -1425
  141. data/po/fr/rabbit.po +1756 -1684
  142. data/po/ja/rabbit.po +2198 -2097
  143. data/po/rabbit.pot +1556 -1419
  144. metadata +34 -100
  145. data/bin/rabbirack +0 -99
  146. data/bin/rabbiter +0 -108
  147. data/bin/rabrick +0 -95
  148. data/bin/rabwii +0 -77
  149. data/lib/rabbit/default-config.rb +0 -24
  150. data/lib/rabbit/div/comment-i.erb +0 -7
  151. data/lib/rabbit/div/comment.erb +0 -45
  152. data/lib/rabbit/div/css.erb +0 -1
  153. data/lib/rabbit/div/js.erb +0 -1
  154. data/lib/rabbit/div/log.erb +0 -5
  155. data/lib/rabbit/div/main-i.erb +0 -24
  156. data/lib/rabbit/div/main.css +0 -40
  157. data/lib/rabbit/div/main.erb +0 -33
  158. data/lib/rabbit/div/navi-i.erb +0 -6
  159. data/lib/rabbit/div/navi.erb +0 -6
  160. data/lib/rabbit/div/prototype.js +0 -4320
  161. data/lib/rabbit/div/slide-i.erb +0 -2
  162. data/lib/rabbit/div/slide.erb +0 -5
  163. data/lib/rabbit/div/tofu.rb +0 -309
  164. data/lib/rabbit/middleware/config.ru +0 -42
  165. data/lib/rabbit/middleware/controller.rb +0 -63
  166. data/lib/rabbit/middleware/public/stylesheets/rabbirack.css +0 -12
  167. data/lib/rabbit/middleware/views/index.haml +0 -13
  168. data/lib/rabbit/middleware/views/layout.haml +0 -8
  169. data/lib/rabbit/post-setup.rb +0 -8
  170. data/lib/rabbit/pre-clean.rb +0 -2
  171. data/lib/rabbit/pre-distclean.rb +0 -2
  172. data/lib/rabbit/theme/twitter-comment/property.rb +0 -4
  173. data/lib/rabbit/theme/twitter-comment/twitter-comment.rb +0 -15
  174. data/lib/rabbit/twitter.rb +0 -239
  175. data/sample/theme-bench-en.hiki +0 -100
  176. data/sample/theme-bench-en.rab +0 -127
  177. data/sample/theme-bench.hiki +0 -101
  178. data/sample/theme-bench.rab +0 -128
  179. data/setup.rb +0 -1585
  180. data/update-mo.rb +0 -20
  181. data/update-po.rb +0 -57
@@ -0,0 +1,381 @@
1
+ # Copyright (C) 2012 Kouhei Sutou <kou@cozmixng.org>
2
+ #
3
+ # This program is free software; you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation; either version 2 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License along
14
+ # with this program; if not, write to the Free Software Foundation, Inc.,
15
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
+
17
+ require "yaml"
18
+
19
+ require "rabbit/console"
20
+ require "rabbit/author-configuration"
21
+ require "rabbit/path-manipulatable"
22
+
23
+ module Rabbit
24
+ module Command
25
+ class RabbitTheme
26
+ include GetText
27
+ include PathManipulatable
28
+
29
+ class << self
30
+ def run(*arguments)
31
+ new.run(arguments)
32
+ end
33
+ end
34
+
35
+ def initialize
36
+ @config_yaml_path = "config.yaml"
37
+ @id = nil
38
+ @author_conf = nil
39
+ @logger = nil
40
+ end
41
+
42
+ def run(arguments)
43
+ @options, @logger = parse_command_line_arguments(arguments)
44
+
45
+ validate
46
+ unless @validation_errors.empty?
47
+ messages = (@validation_errors + [_("See --help for example")])
48
+ @logger.error(messages.join("\n"))
49
+ return false
50
+ end
51
+
52
+ generate
53
+ @author_conf.save
54
+ true
55
+ end
56
+
57
+ private
58
+ def parse_command_line_arguments(arguments)
59
+ Rabbit::Console.parse!(ARGV) do |parser, options|
60
+ @logger = options.default_logger
61
+ @author_conf = AuthorConfiguration.new(@logger)
62
+ @author_conf.load
63
+
64
+ format = _("Usage: %s new [options]\n" \
65
+ " e.g.: %s new \\\n" \
66
+ " --id rubykaigi2012 \\\n" \
67
+ " --name \"Kouhei Sutou\" \\\n" \
68
+ " --email kou@cozmixng.org \\\n" \
69
+ " --rubygems-user kou")
70
+
71
+ program = File.basename($0, ".*")
72
+ parser.banner = format % [program, program]
73
+
74
+ parser.separator("")
75
+
76
+ parser.separator(_("Theme information"))
77
+
78
+ parser.on("--id=ID",
79
+ _("Theme ID"),
80
+ _("(e.g.: %s)") % "--id=rubykaigi2012",
81
+ _("(must)")) do |id|
82
+ @id = id
83
+ end
84
+
85
+ parser.separator(_("Your information"))
86
+
87
+ messages = [
88
+ _("Author name of the new slide"),
89
+ _("(e.g.: %s)") % "--name=\"Kouhei Sutou\"",
90
+ ]
91
+ if @author_conf.name
92
+ messages << _("(default: %s)") % @author_conf.name
93
+ end
94
+ messages << _("(optional)")
95
+ parser.on("--name=NAME",
96
+ *messages) do |name|
97
+ @author_conf.name = name
98
+ end
99
+
100
+ messages = [
101
+ _("Author e-mail of the new slide"),
102
+ _("(e.g.: %s)") % "--email=kou@cozmixng.org",
103
+ ]
104
+ if @author_conf.email
105
+ messages << _("(default: %s)") % @author_conf.email
106
+ end
107
+ messages << _("(optional)")
108
+ parser.on("--email=EMAIL",
109
+ *messages) do |email|
110
+ @author_conf.email = email
111
+ end
112
+
113
+ messages = [
114
+ _("Account for %s") % "RubyGems.org",
115
+ _("It is used to publish your slide to %s") % "RubyGems.org",
116
+ _("(e.g.: %s)") % "--rubygems-user=kou",
117
+ ]
118
+ if @author_conf.rubygems_user
119
+ messages << _("(default: %s)") % @author_conf.rubygems_user
120
+ end
121
+ messages << _("(optional)")
122
+ parser.on("--rubygems-user=USER",
123
+ *messages) do |user|
124
+ @author_conf.rubygems_user = user
125
+ end
126
+ end
127
+ end
128
+
129
+ def validate
130
+ @validation_errors = []
131
+ validate_command
132
+ validate_id
133
+ end
134
+
135
+ def validate_command
136
+ if @options.rest.empty?
137
+ @options.rest << "new"
138
+ end
139
+ if @options.rest.size != 1
140
+ message = _("too many commands: %s") % @options.rest.inspect
141
+ @validation_errors << message
142
+ end
143
+ @command = @options.rest[0]
144
+ if @command != "new"
145
+ format = _("invalid command: <%s>: available commands: %s")
146
+ message = format % [@command, "[new]"]
147
+ @validation_errors << message
148
+ end
149
+ end
150
+
151
+ def validate_id
152
+ if @id.nil?
153
+ @validation_errors << (_("%s is missing") % "--id")
154
+ end
155
+ end
156
+
157
+ def generate
158
+ generate_directory
159
+ generate_data_directory
160
+ generate_config_yaml
161
+ generate_readme
162
+ generate_rakefile
163
+ generate_property_rb
164
+ generate_theme_rb
165
+ end
166
+
167
+ def generate_directory
168
+ create_directory(@id)
169
+ end
170
+
171
+ def generate_data_directory
172
+ create_directory(File.join(@id, "data"))
173
+ end
174
+
175
+ def generate_config_yaml
176
+ create_file(@config_yaml_path) do |config_yaml|
177
+ config = {
178
+ "id" => @id,
179
+ "name" => @author_conf.name,
180
+ "email" => @author_conf.email,
181
+ "rubygems_user" => @author_conf.rubygems_user,
182
+ }
183
+ config_yaml.puts(config.to_yaml)
184
+ end
185
+ end
186
+
187
+ def generate_readme
188
+ create_file("README.#{readme_extension}") do |readme|
189
+ readme.puts(readme_content)
190
+ end
191
+ end
192
+
193
+ def readme_content
194
+ markup_language = @author_conf.markup_language || :rd
195
+ syntax = markup_syntax(markup_language)
196
+
197
+ content = ""
198
+ content << (syntax[:heading1] % {:title => _("TODO: THEME TITLE")})
199
+ content << "\n\n"
200
+ content << _("TODO: THEME DESCRIPTION")
201
+ content << "\n\n"
202
+
203
+ content << (syntax[:heading2] % {:title => _("For author")})
204
+ content << "\n\n"
205
+ content << (syntax[:heading3] % {:title => _("Show")})
206
+ content << "\n\n"
207
+ content << (syntax[:preformatted_line] % {:content => "rake"})
208
+ content << "\n\n"
209
+ content << (syntax[:heading3] % {:title => _("Publish")})
210
+ content << "\n\n"
211
+ content << (syntax[:preformatted_line] % {:content => "rake publish"})
212
+ content << "\n\n"
213
+
214
+ content << (syntax[:heading2] % {:title => _("For users")})
215
+ content << "\n\n"
216
+ content << (syntax[:heading3] % {:title => _("Install")})
217
+ content << "\n\n"
218
+ install_command = "gem install #{gem_name}"
219
+ content << (syntax[:preformatted_line] % {:content => install_command})
220
+ content << "\n\n"
221
+ content << (syntax[:heading3] % {:title => _("Show")})
222
+ content << "\n\n"
223
+ theme_benchmark_gem = _("rabbit-theme-benchmark-en.gem")
224
+ show_command = "rabbit -t #{gem_name} #{theme_benchmark_gem}"
225
+ content << (syntax[:preformatted_line] % {:content => show_command})
226
+ content << "\n\n"
227
+ end
228
+
229
+ def generate_rakefile
230
+ create_file("Rakefile") do |rakefile|
231
+ rakefile.puts(<<-EOR)
232
+ require "time"
233
+ require "yaml"
234
+ require "rabbit/task/theme"
235
+
236
+ config = YAML.load(File.read("#{@config_yaml_path}"))
237
+
238
+ theme_id = config["id"]
239
+
240
+ version = "1.0.0"
241
+
242
+ name = config["name"]
243
+ email = config["email"]
244
+ rubygems_user = config["rubygems_user"]
245
+
246
+ readme = File.read(Dir.glob("README*")[0])
247
+
248
+ readme_blocks = readme.split(/(?:\\r?\\n){2,}/)
249
+ summary = (readme_blocks[0] || "TODO").gsub(/\\A(?:[=*!]+|h\\d\\.)\s*/, "")
250
+ description = readme_blocks[1] || "TODO"
251
+
252
+ specification = Gem::Specification.new do |spec|
253
+ prefix = "#{gem_name_prefix}"
254
+ spec.name = "\#{prefix}-\#{theme_id}"
255
+ spec.version = version
256
+ spec.homepage = "http://theme.rabbit-shockers.org/\#{theme_id}/"
257
+ spec.authors = [name]
258
+ spec.email = [email]
259
+ spec.summary = summary
260
+ spec.description = description
261
+ spec.licenses = [] # ["CC BY-SA 3.0"]
262
+
263
+ spec.files = ["#{@config_yaml_path}", "Rakefile"]
264
+ spec.files += Dir.glob("{theme.rb,COPYING,GPL,README*}")
265
+ spec.files += Dir.glob("data/**/*.{svg,png,jpg,jpeg,gif,eps,pdf}")
266
+ spec.files += Dir.glob("locale/**/*.mo")
267
+ spec.files += Dir.glob("po/*/*.po")
268
+
269
+ spec.add_runtime_dependency("rabbit")
270
+ end
271
+
272
+ Rabbit::Task::Theme.new(specification) do |task|
273
+ task.rubygems_user = rubygems_user
274
+ end
275
+ EOR
276
+ end
277
+ end
278
+
279
+ def generate_property_rb
280
+ create_file("property.rb") do |property_rb|
281
+ property_rb.puts(<<-EOP)
282
+ @category = N_("#{category}")
283
+ @title = N_("#{@id}")
284
+ # @abstract = N_("TODO")
285
+ # @description = N_("TODO")
286
+ EOP
287
+ end
288
+ end
289
+
290
+ def generate_theme_rb
291
+ return if image_theme?
292
+ create_file("theme.rb") do |theme_rb|
293
+ theme_rb.puts(<<-EOT)
294
+ include_theme("default")
295
+ EOT
296
+ end
297
+ end
298
+
299
+ def image_theme?
300
+ @id.end_with?("-images")
301
+ end
302
+
303
+ def category
304
+ if image_theme?
305
+ "Image"
306
+ else
307
+ "Theme"
308
+ end
309
+ end
310
+
311
+ def readme_extension
312
+ case @author_conf.markup_language
313
+ when :rd
314
+ "rd"
315
+ when :hiki
316
+ "hiki"
317
+ when :markdown
318
+ "md"
319
+ else
320
+ "rd"
321
+ end
322
+ end
323
+
324
+ def markup_syntax(markup_language)
325
+ case markup_language
326
+ when :rd
327
+ {
328
+ :heading1 => "= %{title}",
329
+ :heading2 => "== %{title}",
330
+ :heading3 => "=== %{title}",
331
+ :definition_list_item => ": %{item}\n %{description}",
332
+ :unorderd_list_item => " * %{item}",
333
+ :image =>
334
+ " # image\n" +
335
+ " # src = %{src}\n" +
336
+ " # relative_height = %{relative_height}",
337
+ :preformatted_line => " %{content}",
338
+ :comment => "# %{content}",
339
+ }
340
+ when :hiki
341
+ {
342
+ :heading1 => "! %{title}",
343
+ :heading2 => "!! %{title}",
344
+ :heading3 => "!!! %{title}",
345
+ :definition_list_item => ":%{item}:%{description}",
346
+ :unorderd_list_item => "* %{item}",
347
+ :image =>
348
+ "{{image(\"%{src}\",\n" +
349
+ " {\n" +
350
+ " :relative_height => %{relative_height},\n" +
351
+ " })}}",
352
+ :preformatted_line => " %{content}",
353
+ :comment => "// %{content}",
354
+ }
355
+ when :markdown
356
+ {
357
+ :heading1 => "# %{title}",
358
+ :heading2 => "## %{title}",
359
+ :heading3 => "### %{title}",
360
+ :definition_list_item => "%{item}\n %{description}",
361
+ :unorderd_list_item => "* %{item}",
362
+ :image =>
363
+ "![](%{src}){:relative_height='%{relative_height}'}",
364
+ :preformatted_line => " %{content}",
365
+ :comment => "",
366
+ }
367
+ else
368
+ nil
369
+ end
370
+ end
371
+
372
+ def gem_name
373
+ "#{gem_name_prefix}-#{@id}"
374
+ end
375
+
376
+ def gem_name_prefix
377
+ "rabbit-theme"
378
+ end
379
+ end
380
+ end
381
+ end
@@ -0,0 +1,898 @@
1
+ #
2
+ # Copyright (C) 2004-2012 Kouhei Sutou <kou@cozmixng.org>
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License along
15
+ # with this program; if not, write to the Free Software Foundation, Inc.,
16
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
+
18
+ require "English"
19
+
20
+ require "rabbit/gettext"
21
+
22
+ module Rabbit
23
+ module Command
24
+ class Rabbit
25
+ include GetText
26
+
27
+ class << self
28
+ def run(*arguments)
29
+ new.run(arguments)
30
+ end
31
+ end
32
+
33
+ def initialize
34
+ @logger = nil
35
+ end
36
+
37
+ def run(arguments)
38
+ GC.disable
39
+ require "rbconfig"
40
+
41
+ require "rabbit/console"
42
+ require "rabbit/source"
43
+ require "rabbit/renderer"
44
+ require "rabbit/front"
45
+
46
+ @options, @logger = parse_command_line_arguments(arguments)
47
+
48
+ require "rabbit/canvas"
49
+ GC.enable
50
+
51
+ if @options.save_as_image
52
+ do_save_as_image
53
+ elsif @options.print
54
+ do_print
55
+ elsif @options.server
56
+ do_server
57
+ else
58
+ do_display
59
+ end
60
+
61
+ ::Rabbit.cleanup
62
+ end
63
+
64
+ private
65
+ def parse_command_line_arguments(arguments)
66
+ Console.parse!(arguments) do |parser, options|
67
+ @logger = options.logger
68
+
69
+ options.after_hooks << lambda do |console, _, _|
70
+ adjust_rest_arguments(console, parser, options)
71
+ end
72
+
73
+ options.options_file = ".rabbit"
74
+ options.theme = "default"
75
+ options.theme_specified = false
76
+ options.comment_theme = nil
77
+ options.allotted_time = ENV["RABBIT_ALLOTTED_TIME"]
78
+ options.base = nil
79
+ options.source_type = :auto
80
+ options.full_screen = false
81
+ options.index_mode = false
82
+ options.geometry = nil
83
+ options.width = 800
84
+ options.height = 600
85
+ options.paper_width = nil
86
+ options.paper_height = nil
87
+ options.save_as_image = false
88
+ options.saved_image_base_name = nil
89
+ options.saved_image_type = "png"
90
+ options.output_html = false
91
+ options.output_index_html = false
92
+ options.rss_base_uri = nil
93
+ options.encoding = nil
94
+ options.print = false
95
+ options.print_out_filename = nil
96
+ options.slides_per_page = 1
97
+ options.draw_scaled_image = true
98
+ options.margin_left = nil
99
+ options.margin_right = nil
100
+ options.margin_top = nil
101
+ options.margin_bottom = nil
102
+ options.page_margin_left = nil
103
+ options.page_margin_right = nil
104
+ options.page_margin_top = nil
105
+ options.page_margin_bottom = nil
106
+ options.use_druby = true
107
+ options.output_druby_uri = false
108
+ options.use_soap = false
109
+ options.soap_host = "0.0.0.0"
110
+ options.soap_port = 10103
111
+ options.use_xmlrpc = false
112
+ options.xmlrpc_host = "0.0.0.0"
113
+ options.xmlrpc_port = 10104
114
+ options.server = false
115
+ options.default_public_level = "all"
116
+ options.public_level = nil
117
+ options.migemo_dictionary_search_path = [
118
+ File.join(RbConfig::CONFIG["prefix"], "share"),
119
+ File.join("", "usr", "local", "share"),
120
+ File.join("", "usr", "share"),
121
+ ].uniq
122
+ options.migemo_dictionary_name = "migemo-dict"
123
+ options.use_gl = false
124
+ options.show_native_window_id = false
125
+ options.keep_above = false
126
+ options.source_filename = nil
127
+
128
+
129
+ parser.banner = "#{parser.banner} [SOURCE_INFOS]"
130
+
131
+ parser.category _("Theme")
132
+
133
+ parser.on("-I", "--include=PATH",
134
+ _("Add [PATH] to load path.")) do |path|
135
+ $LOAD_PATH.unshift(File.expand_path(path))
136
+ end
137
+
138
+ parser.on("-t", "--theme=THEME",
139
+ _("Use [THEME] as theme."),
140
+ "(#{options.theme})") do |theme|
141
+ options.theme = theme
142
+ options.theme_specified = true
143
+ end
144
+
145
+ parser.on("--comment-theme=THEME",
146
+ _("Use [THEME] for comment."),
147
+ "(#{options.comment_theme})") do |theme|
148
+ options.comment_theme = theme
149
+ end
150
+
151
+ parser.on("--allotted-time=TIME",
152
+ _("Use [TIME] as allotted time."),
153
+ "(#{options.allotted_time})") do |time|
154
+ options.allotted_time = time
155
+ end
156
+
157
+
158
+ parser.category _("Source")
159
+
160
+ source_type_names = Source.types.collect do |x|
161
+ Console.get_last_name(x).downcase
162
+ end
163
+ source_type_names.unshift("auto")
164
+ source_type_descs = Source.types.collect do |x|
165
+ message = _("When select %s\nspecify %s\nas [SOURCE_INFOS].")
166
+ type = Console.get_last_name(x)
167
+ message = message % [type, _(x.initial_args_description)]
168
+ message.split(/\n/) + [" "]
169
+ end.flatten
170
+ parser.on("-T", "--type=TYPE",
171
+ source_type_names,
172
+ _("Specify source type as [TYPE]."),
173
+ _("Select from [%s].") % source_type_names.join(', '),
174
+ _("Note: case insensitive."),
175
+ "(auto)",
176
+ " ",
177
+ *source_type_descs) do |source_type|
178
+ if source_type == "auto"
179
+ options.source_type = :auto
180
+ else
181
+ options.source_type = Source.types.find do |t|
182
+ Console.get_last_name(t).downcase == source_type.downcase
183
+ end
184
+ end
185
+ end
186
+
187
+ parser.on("-e", "--encoding=ENCODING",
188
+ _("Specify source encoding as [ENCODING]."),
189
+ _("(auto)")) do |encoding|
190
+ options.encoding = encoding
191
+ end
192
+
193
+ parser.on("-B", "--base=BASE",
194
+ _("Specify base URI or path of source as [BASE]."),
195
+ _("(auto)")) do |base|
196
+ options.base = base
197
+ end
198
+
199
+
200
+ parser.category _("Initial state")
201
+
202
+ parser.on("-f", "--[no-]full-screen",
203
+ _("Toggle full screen mode."),
204
+ "(#{options.full_screen ? 'on' : 'off'})") do |bool|
205
+ options.full_screen = bool
206
+ end
207
+
208
+ parser.on("--[no-]index-mode",
209
+ _("Toggle index mode."),
210
+ "(#{options.index_mode ? 'on' : 'off'})") do |bool|
211
+ options.index_mode = bool
212
+ end
213
+
214
+
215
+ parser.category _("Size")
216
+
217
+ parser.on("-g", "--geometry=GEOMETRY",
218
+ _("Set window geometry [GEOMETRY]."),
219
+ _("Format: WIDTHxHEIGHT+X+Y"),
220
+ "(#{options.geometry.inspect})") do |geometry|
221
+ options.geometry = geometry
222
+ end
223
+
224
+ parser.on("-w", "--width=WIDTH",
225
+ Integer,
226
+ _("Set window width to [WIDTH]."),
227
+ "(#{options.width})") do |width|
228
+ options.width = width
229
+ end
230
+
231
+ parser.on("-h", "--height=HEIGHT",
232
+ Integer,
233
+ _("Set window height to [HEIGHT]."),
234
+ "(#{options.height})") do |height|
235
+ options.height = height
236
+ end
237
+
238
+ message = _("Set window width and height to\n" \
239
+ "[WIDTH] and [HEIGHT].")
240
+ message = message.split(/\n/) +
241
+ ["(#{options.width},#{options.height})"]
242
+ parser.on("-S", "--size=WIDTH,HEIGHT",
243
+ Array,
244
+ *message) do |size|
245
+ width, height = size.collect{|x| Integer(x)}
246
+ options.width = width
247
+ options.height = height
248
+ end
249
+
250
+
251
+ parser.category _("Save")
252
+
253
+ parser.on("-s", "--save-as-image",
254
+ _("Save as image and exit.")) do
255
+ options.save_as_image = true
256
+ end
257
+
258
+ parser.on("-i", "--saved-image-type=TYPE",
259
+ _("Specify saved image type as [TYPE]."),
260
+ "(#{options.saved_image_type})") do |t|
261
+ options.saved_image_type = t
262
+ end
263
+
264
+ parser.on("-b", "--saved-image-base-name=BASE_NAME",
265
+ "--saved-image-basename=BASE_NAME",
266
+ _("Specify saved image base name as [BASE_NAME]."),
267
+ "(" + _("Title of slide") + ")") do |b|
268
+ options.saved_image_base_name = b
269
+ end
270
+
271
+ parser.on("--[no-]output-html",
272
+ _("Output HTML for viewing saved images."),
273
+ "(#{options.output_html})") do |bool|
274
+ options.output_html = bool
275
+ end
276
+
277
+ parser.on("--[no-]output-index-html",
278
+ _("Output index HTML for navigating slides."),
279
+ "(#{options.output_index_html})") do |bool|
280
+ options.output_index_html = bool
281
+ end
282
+
283
+ parser.on("--rss-base-uri=URI",
284
+ _("Specify base URI of RSS as [URI]."),
285
+ _("RSS is generated only when HTML is output."),
286
+ "(#{options.rss_base_uri})") do |uri|
287
+ options.rss_base_uri = uri
288
+ end
289
+
290
+ parser.on("--source-filename=FILENAME",
291
+ _("Specify source filenam as [FILENAME]."),
292
+ "(#{options.source_filename})") do |filename|
293
+ options.source_filename = filename
294
+ end
295
+
296
+ parser.category _("Print")
297
+
298
+ parser.on("-p", "--print",
299
+ _("Print and exit.")) do
300
+ options.print = true
301
+ end
302
+
303
+ parser.on("-o", "--output-filename=FILENAME",
304
+ _("Specify printed out filename as [FILENAME]."),
305
+ "(\#{%s}.pdf)" % _("Title of slide")) do |f|
306
+ options.print_out_filename = f
307
+ end
308
+
309
+ parser.on("--slides-per-page=SLIDES",
310
+ Integer,
311
+ _("Set slides per page."),
312
+ "(1)") do |slides|
313
+ options.slides_per_page = slides
314
+ end
315
+
316
+ parser.on("--[no-]draw-scaled-image",
317
+ _("Draw scaled image."),
318
+ _("Better look for displaying but lesser look for printing."),
319
+ "(#{options.draw_scaled_image})") do |boolean|
320
+ options.draw_scaled_image = boolean
321
+ end
322
+
323
+ parser.category _("Paper")
324
+
325
+ parser.on("--paper-width=WIDTH",
326
+ Integer,
327
+ _("Set paper width to [WIDTH] Pt."),
328
+ _("(landscape A4 width)")) do |width|
329
+ options.paper_width = width
330
+ end
331
+
332
+ parser.on("--paper-height=HEIGHT",
333
+ Integer,
334
+ _("Set paper height to [HEIGHT] Pt."),
335
+ _("(landscape A4 height)")) do |height|
336
+ options.paper_height = height
337
+ end
338
+
339
+ message = _("Set paper width and height to\n" \
340
+ "[WIDTH] Pt and [HEIGHT] Pt.")
341
+ message = message.split(/\n/) + [_("(landscape A4 size)")]
342
+ parser.on("--paper-size=WIDTH,HEIGHT",
343
+ Array,
344
+ *message) do |size|
345
+ width, height = size.collect{|x| Integer(x)}
346
+ options.paper_width = width
347
+ options.paper_height = height
348
+ end
349
+
350
+
351
+ parser.category _("Margin")
352
+
353
+ parser.on("--margin-left=MARGIN",
354
+ Integer,
355
+ _("Set left margin for slides per page mode print."),
356
+ _("(auto)")) do |margin|
357
+ options.margin_left = margin
358
+ end
359
+
360
+ parser.on("--margin-right=MARGIN",
361
+ Integer,
362
+ _("Set right margin for slides per page mode print."),
363
+ _("(auto)")) do |margin|
364
+ options.margin_right = margin
365
+ end
366
+
367
+ parser.on("--margin-top=MARGIN",
368
+ Integer,
369
+ _("Set top margin for slides per page mode print."),
370
+ _("(auto)")) do |margin|
371
+ options.margin_top = margin
372
+ end
373
+
374
+ parser.on("--margin-bottom=MARGIN",
375
+ Integer,
376
+ _("Set bottom margin for slides per page mode print."),
377
+ _("(auto)")) do |margin|
378
+ options.margin_bottom = margin
379
+ end
380
+
381
+ margin1 = _("[ALL]")
382
+ margin2 = _("[TOP_BOTTOM],[LEFT_RIGHT]")
383
+ margin3 = _("[TOP],[LEFT_RIGHT],[BOTTOM]")
384
+ margin4 = _("[TOP],[RIGHT],[BOTTOM],[LEFT]")
385
+ parser.on("--margin={#{margin1}|#{margin2}|#{margin3}|#{margin4}}",
386
+ Array,
387
+ _("Set margin for slides per page mode print.")) do |margins|
388
+ begin
389
+ top, right, bottom, left = Utils.parse_four_way(margins)
390
+ options.margin_top = top
391
+ options.margin_right = right
392
+ options.margin_bottom = bottom
393
+ options.margin_left = left
394
+ rescue ArgumentError
395
+ raise OptionParser::InvalidArgument.new(margins)
396
+ end
397
+ end
398
+
399
+ parser.on("--page-margin-left=MARGIN",
400
+ Integer,
401
+ _("Set left page margin."),
402
+ _("(auto)")) do |margin|
403
+ options.page_margin_left = margin
404
+ end
405
+
406
+ parser.on("--page-margin-right=MARGIN",
407
+ Integer,
408
+ _("Set right page margin."),
409
+ _("(auto)")) do |margin|
410
+ options.page_margin_right = margin
411
+ end
412
+
413
+ parser.on("--page-margin-top=MARGIN",
414
+ Integer,
415
+ _("Set top page margin."),
416
+ _("(auto)")) do |margin|
417
+ options.page_margin_top = margin
418
+ end
419
+
420
+ parser.on("--page-margin-bottom=MARGIN",
421
+ Integer,
422
+ _("Set bottom page margin."),
423
+ _("(auto)")) do |margin|
424
+ options.page_margin_bottom = margin
425
+ end
426
+
427
+ parser.on("--page-margin={#{margin1}|#{margin2}|#{margin3}|#{margin4}}",
428
+ Array,
429
+ _("Set page margin.")) do |margins|
430
+ begin
431
+ top, right, bottom, left = Utils.parse_four_dimensions(margins)
432
+ options.page_margin_top = top
433
+ options.page_margin_right = right
434
+ options.page_margin_bottom = bottom
435
+ options.page_margin_left = left
436
+ rescue ArgumentError
437
+ raise OptionParser::InvalidArgument.new(margins)
438
+ end
439
+ end
440
+
441
+ parser.category _("dRuby")
442
+
443
+ parser.on("--[no-]use-druby",
444
+ _("Specify whether to use dRuby."),
445
+ "(#{options.use_druby})") do |bool|
446
+ options.use_druby = bool
447
+ end
448
+
449
+ parser.on("--druby-uri=URI",
450
+ _("Specify dRuby URI."),
451
+ "(#{options.druby_uri})") do |uri|
452
+ options.druby_uri = uri if uri
453
+ end
454
+
455
+ parser.on("--[no-]output-druby-uri",
456
+ _("Specify whether to output dRuby URI."),
457
+ "(#{options.output_druby_uri})") do |bool|
458
+ options.output_druby_uri = bool
459
+ end
460
+
461
+ parser.category _("SOAP")
462
+
463
+ parser.on("--[no-]use-soap",
464
+ _("Specify whether to use SOAP."),
465
+ "(#{options.use_soap})") do |bool|
466
+ options.use_soap = bool
467
+ end
468
+
469
+ parser.on("--soap-host=HOST",
470
+ _("Specify SOAP host as [HOST]."),
471
+ "(#{options.soap_host})") do |port|
472
+ options.soap_host = host
473
+ end
474
+
475
+ parser.on("--soap-port=PORT",
476
+ Integer,
477
+ _("Specify SOAP port as [PORT]."),
478
+ "(#{options.soap_port})") do |port|
479
+ options.soap_port = port
480
+ end
481
+
482
+ parser.category _("XML-RPC")
483
+
484
+ parser.on("--[no-]use-xmlrpc",
485
+ _("Specify whether to use XML-RPC."),
486
+ "(#{options.use_xmlrpc})") do |bool|
487
+ options.use_xmlrpc = bool
488
+ end
489
+
490
+ parser.on("--xmlrpc-host=HOST",
491
+ _("Specify XML-RPC host as [HOST]."),
492
+ "(#{options.xmlrpc_host})") do |port|
493
+ options.xmlrpc_host = host
494
+ end
495
+
496
+ parser.on("--xmlrpc-port=PORT",
497
+ Integer,
498
+ _("Specify XML-RPC port as [PORT]."),
499
+ "(#{options.xmlrpc_port})") do |port|
500
+ options.xmlrpc_port = port
501
+ end
502
+
503
+ parser.category _("Server")
504
+
505
+ parser.on("--[no-]server",
506
+ _("Specify whether to run as server."),
507
+ "(#{options.server})") do |bool|
508
+ options.server = bool
509
+ end
510
+
511
+ parser.category _("Public level")
512
+
513
+ levels = Front::PublicLevel.constants.sort_by do |const|
514
+ Front::PublicLevel.const_get(const)
515
+ end.collect do |const|
516
+ const.to_s.downcase.gsub(/_/, "-")
517
+ end
518
+ messages = [_("Specify public level.")]
519
+ messages << _("Select from the following:")
520
+ messages << "["
521
+ messages << " "
522
+ levels[0..-2].each do |level|
523
+ messages.last << "#{level}, "
524
+ messages << " " if messages.last.size > 30
525
+ end
526
+ messages.last << levels.last
527
+ messages << "]"
528
+ messages << (_("(%s)") % options.default_public_level)
529
+ parser.on("--public-level=LEVEL", levels, *messages) do |level|
530
+ options.public_level = level
531
+ end
532
+
533
+ parser.category _("Comment")
534
+
535
+ parser.on("--comment-source=FILE",
536
+ _("Deprecated. Just ignored."),
537
+ _("Specify initial comment source."),
538
+ _("(default source)")) do |name|
539
+ end
540
+
541
+ parser.on("--comment-encoding=ENCODING",
542
+ _("Deprecated. Just ignored."),
543
+ _("Specify comment source encoding."),
544
+ _("(auto)")) do |encoding|
545
+ end
546
+
547
+ parser.category _("Migemo")
548
+
549
+ search_path = options.migemo_dictionary_search_path.join(', ')
550
+ parser.on("--migemo-dictionary-search-path=PATH1,PATH2,...",
551
+ Array,
552
+ _("Specify search paths for Migemo static dictionary."),
553
+ _("(%s)") % search_path) do |path|
554
+ options.migemo_dictionary_search_path = path
555
+ end
556
+
557
+ parser.on("--migemo-dictionary-name=NAME",
558
+ Array,
559
+ _("Specify static dictionary name for Migemo."),
560
+ _("(%s)") % options.migemo_dictionary_name) do |name|
561
+ options.migemo_dictionary_name = name
562
+ end
563
+
564
+ parser.category _("3D")
565
+
566
+ parser.on("--[no-]use-gl",
567
+ _("Specify whether to use OpenGL if available."),
568
+ "(#{options.use_gl})") do |bool|
569
+ options.use_gl = bool
570
+ end
571
+
572
+ parser.category _("Display")
573
+
574
+ parser.on("--[no-]keep-above",
575
+ _("Specify whether to keep above window."),
576
+ "(#{options.keep_above})") do |bool|
577
+ options.keep_above = bool
578
+ end
579
+
580
+ parser.category _("Others")
581
+
582
+ parser.on("--[no-]show-native-window-id",
583
+ _("Show a native window ID of the Rabbit window if available."),
584
+ _("e.g. The ID is the ID of X resource on X window system."),
585
+ "(#{options.show_native_window_id})") do |bool|
586
+ options.show_native_window_id = bool
587
+ end
588
+ end
589
+ end
590
+
591
+ def adjust_rest_arguments(console, parser, options)
592
+ return unless options.rest.size == 1
593
+
594
+ source = options.rest[0]
595
+ if /\.gem\z/i =~ source
596
+ gem_name = $PREMATCH
597
+ require "rabbit/gem-finder"
598
+ finder = GemFinder.new(@logger)
599
+ spec = finder.find(gem_name, "rabbit-slide-")
600
+ source = spec.gem_dir if spec
601
+ end
602
+
603
+ options_file = File.join(source, options.options_file)
604
+ if File.exist?(options_file)
605
+ options.rest.clear
606
+ console.read_options_file(parser, options, options_file)
607
+ end
608
+ end
609
+
610
+ def make_canvas(renderer)
611
+ canvas = Canvas.new(@logger, renderer)
612
+ canvas.comment_theme = @options.comment_theme
613
+ canvas.allotted_time = @options.allotted_time
614
+ canvas
615
+ end
616
+
617
+ def add_source_dialog_filter(dialog, name, pattern)
618
+ filter = Gtk::FileFilter.new
619
+ filter.name = "#{name} (#{pattern})"
620
+ filter.add_pattern(pattern)
621
+ dialog.add_filter(filter)
622
+ end
623
+
624
+ def choose_source_file_by_dialog
625
+ dialog = Gtk::FileChooserDialog.new(_("Choose a Rabbit source file"),
626
+ nil,
627
+ Gtk::FileChooser::ACTION_OPEN,
628
+ nil,
629
+ [Gtk::Stock::CANCEL,
630
+ Gtk::Dialog::RESPONSE_CANCEL],
631
+ [Gtk::Stock::OPEN,
632
+ Gtk::Dialog::RESPONSE_ACCEPT])
633
+ dialog.current_folder = @options.base if @options.base
634
+ add_source_dialog_filter(dialog, "Rabbit files", "*.rab")
635
+ add_source_dialog_filter(dialog, "RD files", "*.rd")
636
+ add_source_dialog_filter(dialog, "Hiki files", "*.hiki")
637
+ add_source_dialog_filter(dialog, "PDF files", "*.pdf")
638
+ add_source_dialog_filter(dialog, "All files", "*")
639
+ file_name = nil
640
+ if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
641
+ file_name = dialog.filename
642
+ dialog.destroy
643
+ end
644
+ file_name
645
+ end
646
+
647
+ def make_source
648
+ rest_arguments = @options.rest
649
+ if @options.source_type == :auto
650
+ if rest_arguments.empty?
651
+ file_name = choose_source_file_by_dialog(options)
652
+ exit if file_name.nil?
653
+ rest_arguments = [file_name]
654
+ @options.source_type = Source::File
655
+ elsif rest_arguments.size == 1 and /\Ahttps?:\/\// =~ rest_arguments[0]
656
+ @options.source_type = Source::URI
657
+ else
658
+ @options.source_type = Source::File
659
+ end
660
+ end
661
+ if @options.source_type == Source::ARGF
662
+ rest_arguments = [ARGF]
663
+ end
664
+ source = @options.source_type.new(@options.encoding, @logger,
665
+ *rest_arguments)
666
+ source.base = @options.base if @options.base
667
+ source
668
+ end
669
+
670
+ def make_front(canvas)
671
+ level = @options.public_level
672
+ level ||= @options.default_public_level
673
+ level = level.gsub(/-/, "_").upcase
674
+ canvas.front(Front::PublicLevel.const_get(level))
675
+ end
676
+
677
+ def apply_theme_if_need(target)
678
+ target.apply_theme(@options.theme) if @options.theme_specified
679
+ end
680
+
681
+ def parse(target, source, background=false)
682
+ if background
683
+ callback = Utils.process_pending_events_proc
684
+ else
685
+ callback = nil
686
+ end
687
+ target.parse(source, callback)
688
+ end
689
+
690
+ def setup_image_info(target)
691
+ target.saved_image_type = @options.saved_image_type
692
+ target.saved_image_base_name = @options.saved_image_base_name
693
+ target.output_html = @options.output_html
694
+ target.output_index_html = @options.output_index_html
695
+ target.rss_base_uri = @options.rss_base_uri
696
+ target.source_filename = @options.source_filename
697
+ end
698
+
699
+ def setup_print_info(target)
700
+ target.filename = @options.print_out_filename
701
+ target.slides_per_page = @options.slides_per_page
702
+ target.draw_scaled_image = @options.draw_scaled_image
703
+ end
704
+
705
+ def setup_size(target)
706
+ target.width = @options.width
707
+ target.height = @options.height
708
+ end
709
+
710
+ def setup_paper_size(target)
711
+ target.paper_width = @options.paper_width
712
+ target.paper_height = @options.paper_height
713
+ target.page_margin_left = @options.page_margin_left
714
+ target.page_margin_right = @options.page_margin_right
715
+ target.page_margin_top = @options.page_margin_top
716
+ target.page_margin_bottom = @options.page_margin_bottom
717
+ target.margin_left = @options.margin_left
718
+ target.margin_right = @options.margin_right
719
+ target.margin_top = @options.margin_top
720
+ target.margin_bottom = @options.margin_bottom
721
+ end
722
+
723
+ def setup_migemo_info(target)
724
+ target.migemo_dictionary_search_path =
725
+ @options.migemo_dictionary_search_path
726
+ target.migemo_dictionary_name = @options.migemo_dictionary_name
727
+ end
728
+
729
+ def setup_3d_info(target)
730
+ target.use_gl = @options.use_gl
731
+ end
732
+
733
+ def setup_druby(front)
734
+ require "drb/drb"
735
+ begin
736
+ DRb.start_service(@options.druby_uri, front)
737
+ @logger.info(DRb.uri) if @options.output_druby_uri
738
+ rescue SocketError
739
+ @logger.error($!)
740
+ rescue Errno::EADDRINUSE
741
+ @logger.error(_("dRuby URI <%s> is in use.") % @options.druby_uri)
742
+ end
743
+ end
744
+
745
+ def setup_soap(front)
746
+ require "rabbit/soap/server"
747
+ thread = nil
748
+
749
+ begin
750
+ config = {
751
+ :BindAddress => @options.soap_host,
752
+ :Port => @options.soap_port,
753
+ :AddressFamily => Socket::AF_INET,
754
+ :Logger => @logger,
755
+ }
756
+ server = Rabbit::SOAP::Server.new(front, config)
757
+ prev = trap(:INT) {server.shutdown; trap(:INT, prev)}
758
+ thread = Thread.new {server.start}
759
+ rescue Errno::EADDRINUSE
760
+ @logger.error(_("port <%s> for SOAP is in use.") % @options.soap_port)
761
+ end
762
+
763
+ thread
764
+ end
765
+
766
+ def setup_xmlrpc(front)
767
+ require "rabbit/xmlrpc/server"
768
+ thread = nil
769
+
770
+ begin
771
+ config = {
772
+ :BindAddress => @options.xmlrpc_host,
773
+ :Port => @options.xmlrpc_port,
774
+ :AddressFamily => Socket::AF_INET,
775
+ :Logger => @logger,
776
+ }
777
+ server = Rabbit::XMLRPC::Server.new(front, config)
778
+ prev = trap(:INT) {server.shutdown; trap(:INT, prev)}
779
+ thread = Thread.new {server.start}
780
+ rescue Errno::EADDRINUSE
781
+ @logger.error(_("port <%s> for XML-RPC is in use.") % @options.xmlrpc_port)
782
+ end
783
+
784
+ thread
785
+ end
786
+
787
+ def do_print
788
+ source = make_source
789
+ renderer = Renderer.printable_renderer(@options.slides_per_page)
790
+ canvas = make_canvas(renderer)
791
+ setup_paper_size(canvas)
792
+ setup_print_info(canvas)
793
+ setup_3d_info(canvas)
794
+ apply_theme_if_need(canvas)
795
+ parse(canvas, source)
796
+ canvas.print
797
+ canvas.quit
798
+ rescue Rabbit::NoPrintSupportError
799
+ @logger.error($!.message)
800
+ end
801
+
802
+ def do_save_as_image
803
+ Renderer::Pixmap.init
804
+ ::Rabbit.gui_init
805
+
806
+ source = make_source
807
+ canvas = make_canvas(Renderer::Pixmap)
808
+ setup_size(canvas)
809
+ setup_image_info(canvas)
810
+ setup_print_info(canvas)
811
+ setup_paper_size(canvas)
812
+ setup_3d_info(canvas)
813
+ apply_theme_if_need(canvas)
814
+ parse(canvas, source)
815
+ canvas.activate("ToggleIndexMode") if @options.index_mode
816
+ canvas.save_as_image
817
+ canvas.quit
818
+ end
819
+
820
+ def do_display
821
+ display_init_options = {}
822
+ if @options.use_gl
823
+ display_init_options[:preferred_class_name] = "ClutterEmbed"
824
+ end
825
+ Renderer::Display.init(display_init_options)
826
+ ::Rabbit.gui_init
827
+
828
+ source = make_source
829
+ canvas = make_canvas(Renderer::Display)
830
+ frame = Frame.new(@logger, canvas)
831
+ frame.geometry = @options.geometry
832
+ frame.force_keep_above = @options.keep_above
833
+ setup_paper_size(canvas)
834
+ setup_image_info(canvas)
835
+ setup_print_info(canvas)
836
+ setup_migemo_info(canvas)
837
+ setup_3d_info(canvas)
838
+ frame.init_gui(@options.width, @options.height, true)
839
+ frame.fullscreen if @options.full_screen
840
+ native_window = frame.window.window
841
+ if @options.show_native_window_id and native_window.respond_to?(:xid)
842
+ @logger.info(_("Window ID: %d") % native_window.xid)
843
+ end
844
+ apply_theme_if_need(frame)
845
+ parse(frame, source, !Utils.windows?)
846
+ canvas.activate("ToggleIndexMode") if @options.index_mode
847
+
848
+ front = make_front(canvas)
849
+ setup_druby(front) if @options.use_druby
850
+ setup_soap(front) if @options.use_soap
851
+ setup_xmlrpc(front) if @options.use_xmlrpc
852
+
853
+ Gtk.main
854
+ end
855
+
856
+ def do_server
857
+ ::Rabbit.gui_init
858
+
859
+ # GLib::Log.cancel_handler
860
+ # GLib::Log.set_handler(nil, GLib::Log::LEVEL_ERROR)
861
+
862
+ source = make_source
863
+ canvas = make_canvas(Renderer::Pixmap)
864
+ setup_size(canvas)
865
+ setup_paper_size(canvas)
866
+ setup_image_info(canvas)
867
+ setup_print_info(canvas)
868
+ setup_3d_info(canvas)
869
+ apply_theme_if_need(canvas)
870
+ parse(canvas, source)
871
+
872
+ soap_server_thread = nil
873
+ xmlrpc_server_thread = nil
874
+
875
+ front = make_front(canvas)
876
+ setup_druby(front) if @options.use_druby
877
+ if @options.use_soap
878
+ soap_server_thread = setup_soap(front)
879
+ end
880
+ if @options.use_xmlrpc
881
+ xmlrpc_server_thread = setup_xmlrpc(front)
882
+ end
883
+
884
+ soap_server_thread.join if soap_server_thread
885
+ xmlrpc_server_thread.join if xmlrpc_server_thread
886
+ if @options.use_druby
887
+ prev = trap(:INT) do
888
+ @logger.info(_("going to shutdown..."))
889
+ DRb.thread.exit
890
+ @logger.info(_("DRb.thread done."))
891
+ trap(:INT, prev)
892
+ end
893
+ DRb.thread.join
894
+ end
895
+ end
896
+ end
897
+ end
898
+ end