rabbit 1.0.9 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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