rabbit 2.2.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (177) hide show
  1. checksums.yaml +5 -5
  2. data/data/locale/ja/LC_MESSAGES/rabbit.mo +0 -0
  3. data/doc/_config.yml +2 -2
  4. data/doc/_layouts/en.html +1 -1
  5. data/doc/_layouts/ja.html +1 -1
  6. data/doc/en/news.rd +140 -0
  7. data/doc/en/sample/hiki/rabbit.hiki +2 -2
  8. data/doc/en/sample/markdown/rabbit.md +1 -1
  9. data/doc/en/sample/rd/rabbit.rd +1 -1
  10. data/doc/en/usage/rabbit-slide.rd +3 -3
  11. data/doc/images/screenshots/en/blue-circle-raw.png +0 -0
  12. data/doc/images/screenshots/en/blue-circle.png +0 -0
  13. data/doc/images/screenshots/en/clear-blue-raw.png +0 -0
  14. data/doc/images/screenshots/en/clear-blue.png +0 -0
  15. data/doc/images/screenshots/en/cozmixng-raw.png +0 -0
  16. data/doc/images/screenshots/en/cozmixng.png +0 -0
  17. data/doc/images/screenshots/en/dark-gradation-raw.png +0 -0
  18. data/doc/images/screenshots/en/dark-gradation.png +0 -0
  19. data/doc/images/screenshots/en/day-white-raw.png +0 -0
  20. data/doc/images/screenshots/en/day-white.png +0 -0
  21. data/doc/images/screenshots/en/debian-raw.png +0 -0
  22. data/doc/images/screenshots/en/debian.png +0 -0
  23. data/doc/images/screenshots/en/green-circle-raw.png +0 -0
  24. data/doc/images/screenshots/en/green-circle.png +0 -0
  25. data/doc/images/screenshots/en/night-black-raw.png +0 -0
  26. data/doc/images/screenshots/en/night-black.png +0 -0
  27. data/doc/images/screenshots/en/rabbit-raw.png +0 -0
  28. data/doc/images/screenshots/en/rabbit.png +0 -0
  29. data/doc/images/screenshots/en/ranguba-raw.png +0 -0
  30. data/doc/images/screenshots/en/ranguba.png +0 -0
  31. data/doc/images/screenshots/en/red-frame-raw.png +0 -0
  32. data/doc/images/screenshots/en/red-frame.png +0 -0
  33. data/doc/images/screenshots/en/ruby-gnome2-raw.png +0 -0
  34. data/doc/images/screenshots/en/ruby-gnome2.png +0 -0
  35. data/doc/images/screenshots/en/rubykaigi2011-raw.png +0 -0
  36. data/doc/images/screenshots/en/rubykaigi2011.png +0 -0
  37. data/doc/images/screenshots/ja/blue-circle-raw.png +0 -0
  38. data/doc/images/screenshots/ja/blue-circle.png +0 -0
  39. data/doc/images/screenshots/ja/clear-blue-raw.png +0 -0
  40. data/doc/images/screenshots/ja/clear-blue.png +0 -0
  41. data/doc/images/screenshots/ja/cozmixng-raw.png +0 -0
  42. data/doc/images/screenshots/ja/cozmixng.png +0 -0
  43. data/doc/images/screenshots/ja/dark-gradation-raw.png +0 -0
  44. data/doc/images/screenshots/ja/dark-gradation.png +0 -0
  45. data/doc/images/screenshots/ja/day-white-raw.png +0 -0
  46. data/doc/images/screenshots/ja/day-white.png +0 -0
  47. data/doc/images/screenshots/ja/debian-raw.png +0 -0
  48. data/doc/images/screenshots/ja/debian.png +0 -0
  49. data/doc/images/screenshots/ja/green-circle-raw.png +0 -0
  50. data/doc/images/screenshots/ja/green-circle.png +0 -0
  51. data/doc/images/screenshots/ja/night-black-raw.png +0 -0
  52. data/doc/images/screenshots/ja/night-black.png +0 -0
  53. data/doc/images/screenshots/ja/rabbit-raw.png +0 -0
  54. data/doc/images/screenshots/ja/rabbit.png +0 -0
  55. data/doc/images/screenshots/ja/ranguba-raw.png +0 -0
  56. data/doc/images/screenshots/ja/ranguba.png +0 -0
  57. data/doc/images/screenshots/ja/red-frame-raw.png +0 -0
  58. data/doc/images/screenshots/ja/red-frame.png +0 -0
  59. data/doc/images/screenshots/ja/ruby-gnome2-raw.png +0 -0
  60. data/doc/images/screenshots/ja/ruby-gnome2.png +0 -0
  61. data/doc/images/screenshots/ja/rubykaigi2011-raw.png +0 -0
  62. data/doc/images/screenshots/ja/rubykaigi2011.png +0 -0
  63. data/doc/ja/how-to-make/index.rd +1 -1
  64. data/doc/ja/news.rd +143 -0
  65. data/doc/ja/sample/hiki/rabbit.hiki +2 -2
  66. data/doc/ja/sample/markdown/rabbit.md +1 -1
  67. data/doc/ja/sample/rd/rabbit.rd +1 -1
  68. data/doc/ja/slides.rd +1 -1
  69. data/doc/ja/usage/rabbit-slide.rd +3 -3
  70. data/doc/ja/users.rd +1 -1
  71. data/lib/rabbit/action.rb +23 -4
  72. data/lib/rabbit/canvas.rb +70 -14
  73. data/lib/rabbit/command/rabbit-slide.rb +252 -67
  74. data/lib/rabbit/command/rabbit-slide.ui +180 -0
  75. data/lib/rabbit/command/rabbit.rb +14 -20
  76. data/lib/rabbit/console.rb +9 -3
  77. data/lib/rabbit/dependency-canvas.rb +19 -1
  78. data/lib/rabbit/element.rb +34 -7
  79. data/lib/rabbit/element/poppler-page.rb +1 -2
  80. data/lib/rabbit/element/text-container-element.rb +2 -2
  81. data/lib/rabbit/element/text-renderer.rb +5 -4
  82. data/lib/rabbit/element/title-slide.rb +8 -0
  83. data/lib/rabbit/element/video.rb +1 -2
  84. data/lib/rabbit/filename.rb +39 -0
  85. data/lib/rabbit/formatter.rb +61 -30
  86. data/lib/rabbit/frame.rb +1 -19
  87. data/lib/rabbit/front.rb +23 -2
  88. data/lib/rabbit/gesture/handler.rb +21 -2
  89. data/lib/rabbit/graffiti/config-dialog.rb +15 -18
  90. data/lib/rabbit/gtk.rb +2 -191
  91. data/lib/rabbit/html/generator.rb +38 -30
  92. data/lib/rabbit/image-data-loader.rb +6 -1
  93. data/lib/rabbit/image.rb +22 -4
  94. data/lib/rabbit/image/base.rb +34 -2
  95. data/lib/rabbit/image/default.rb +1 -1
  96. data/lib/rabbit/image/eps.rb +1 -1
  97. data/lib/rabbit/image/gimp.rb +1 -1
  98. data/lib/rabbit/info-window.rb +27 -15
  99. data/lib/rabbit/logger/gui.rb +21 -23
  100. data/lib/rabbit/logger/stderr.rb +1 -1
  101. data/lib/rabbit/pango-markup.rb +44 -0
  102. data/lib/rabbit/parser.rb +20 -3
  103. data/lib/rabbit/parser/ext/image.rb +25 -8
  104. data/lib/rabbit/parser/ext/video.rb +21 -2
  105. data/lib/rabbit/parser/markdown.rb +1 -2
  106. data/lib/rabbit/parser/pdf.rb +23 -7
  107. data/lib/rabbit/parser/rd/rd2rabbit-lib.rb +20 -0
  108. data/lib/rabbit/progress.rb +34 -23
  109. data/lib/rabbit/renderer.rb +17 -23
  110. data/lib/rabbit/renderer/base.rb +31 -57
  111. data/lib/rabbit/renderer/color.rb +46 -53
  112. data/lib/rabbit/renderer/display/base.rb +71 -62
  113. data/lib/rabbit/renderer/display/button-handler.rb +2 -1
  114. data/lib/rabbit/renderer/display/clutter-embed.rb +60 -26
  115. data/lib/rabbit/renderer/display/drawing-area-base.rb +1 -1
  116. data/lib/rabbit/renderer/display/drawing-area-primitive.rb +34 -21
  117. data/lib/rabbit/renderer/display/graffiti.rb +1 -3
  118. data/lib/rabbit/renderer/display/hook-handler.rb +8 -4
  119. data/lib/rabbit/renderer/display/key-handler.rb +7 -2
  120. data/lib/rabbit/renderer/display/magnifier.rb +2 -2
  121. data/lib/rabbit/renderer/display/progress.rb +10 -2
  122. data/lib/rabbit/renderer/display/spotlight.rb +2 -2
  123. data/lib/rabbit/renderer/engine/cairo.rb +0 -3
  124. data/lib/rabbit/renderer/kernel.rb +54 -0
  125. data/lib/rabbit/renderer/offscreen.rb +14 -6
  126. data/lib/rabbit/renderer/print-layout.rb +150 -0
  127. data/lib/rabbit/renderer/printer.rb +236 -0
  128. data/lib/rabbit/renderer/screen.rb +288 -0
  129. data/lib/rabbit/renderer/widget/drawing-area.rb +93 -0
  130. data/lib/rabbit/size.rb +52 -25
  131. data/lib/rabbit/slide-configuration.rb +56 -12
  132. data/lib/rabbit/source.rb +24 -8
  133. data/lib/rabbit/task/slide.rb +1 -1
  134. data/lib/rabbit/theme/applier.rb +26 -9
  135. data/lib/rabbit/theme/base/base.rb +7 -7
  136. data/lib/rabbit/theme/clear-blue/clear-blue.rb +1 -1
  137. data/lib/rabbit/theme/image-timer/image-timer.rb +3 -1
  138. data/lib/rabbit/theme/image-viewer/image-viewer.rb +13 -1
  139. data/lib/rabbit/theme/image/image.rb +4 -4
  140. data/lib/rabbit/theme/lightning-talk-toolkit/lightning-talk-toolkit.rb +3 -1
  141. data/lib/rabbit/theme/tag/tag.rb +12 -4
  142. data/lib/rabbit/version.rb +2 -2
  143. data/lib/rabbit/video-window.rb +75 -89
  144. data/misc/emacs/rabbit-mode.el +11 -7
  145. data/po/en/rabbit.edit.po +189 -185
  146. data/po/en/rabbit.po +15 -12
  147. data/po/fr/rabbit.edit.po +189 -185
  148. data/po/fr/rabbit.po +15 -12
  149. data/po/ja/rabbit.edit.po +190 -186
  150. data/po/ja/rabbit.po +16 -13
  151. data/rabbit.gemspec +34 -16
  152. data/test/command/test-rabbit.rb +100 -0
  153. data/test/{rabbit-test-utils.rb → helper.rb} +7 -4
  154. data/test/{rabbit-test-utils → helper}/fixture.rb +2 -2
  155. data/test/{rabbit-test-utils → helper}/parser.rb +2 -2
  156. data/test/image/test-dia.rb +2 -2
  157. data/test/image/test-eps.rb +2 -2
  158. data/test/parser/test-markdown.rb +3 -5
  159. data/test/parser/test-rd.rb +1 -3
  160. data/test/parser/test-wiki.rb +3 -5
  161. data/test/run-test.rb +3 -3
  162. data/test/test-applier.rb +60 -29
  163. data/test/test-canvas.rb +70 -0
  164. data/test/test-color.rb +18 -9
  165. data/test/test-element.rb +15 -3
  166. data/test/test-size.rb +25 -22
  167. data/test/test-slide-configuration.rb +16 -6
  168. data/test/test-source.rb +15 -5
  169. data/test/test-utils.rb +15 -1
  170. metadata +55 -84
  171. data/lib/rabbit/renderer/print.rb +0 -31
  172. data/lib/rabbit/renderer/print/base.rb +0 -78
  173. data/lib/rabbit/renderer/print/cairo.rb +0 -122
  174. data/lib/rabbit/renderer/print/layout.rb +0 -123
  175. data/lib/rabbit/renderer/print/multiple.rb +0 -202
  176. data/lib/rabbit/source/hiki.rb +0 -36
  177. data/lib/rabbit/source/slide-share.rb +0 -53
@@ -187,10 +187,10 @@ title: "サンプルスライド: Rabbit"
187
187
 
188
188
  URL先の画像をダウンロード
189
189
 
190
- {{image("http://www.cozmixng.org/repos/images/cozmixchu.png",
190
+ {{image("https://raw.githubusercontent.com/rabbit-shocker/rabbit/master/data/rabbit/image/cozmixng-images/cozmixchu.png",
191
191
  :caption => "こずみっくちゅー")}}
192
192
 
193
- // [[こずみっくちゅー|http://www.cozmixng.org/repos/images/cozmixchu.png]]
193
+ // [[こずみっくちゅー|https://raw.githubusercontent.com/rabbit-shocker/rabbit/master/data/rabbit/image/cozmixng-images/cozmixchu.png]]
194
194
  // ↑の書式はまだ使えない
195
195
 
196
196
  ! 数式
@@ -163,7 +163,7 @@ background-image-relative-margin-right
163
163
 
164
164
  URL先の画像をダウンロード
165
165
 
166
- ![](http://www.cozmixng.org/repos/images/cozmixchu.png "こずみっくちゅー")
166
+ ![](https://raw.githubusercontent.com/rabbit-shocker/rabbit/master/data/rabbit/image/cozmixng-images/cozmixchu.png "こずみっくちゅー")
167
167
 
168
168
  # 数式
169
169
 
@@ -194,7 +194,7 @@ title: "サンプルスライド: Rabbit"
194
194
  URL先の画像をダウンロード
195
195
 
196
196
  # image
197
- # src = http://www.cozmixng.org/repos/images/cozmixchu.png
197
+ # src = https://raw.githubusercontent.com/rabbit-shocker/rabbit/master/data/rabbit/image/cozmixng-images/cozmixchu.png
198
198
  # caption = こずみっくちゅー
199
199
 
200
200
  = 数式
@@ -7,7 +7,7 @@ title: スライド
7
7
  Rabbitで作ったスライドがたくさん公開されています。Rabbitで作っ
8
8
  たスライドを公開したら自由に追加してください。
9
9
 
10
- * ((<kou|URL:http://slide.rabbit-shocker.org/authors/kou/>))
10
+ * ((<kou|URL:https://slide.rabbit-shocker.org/authors/kou/>))
11
11
  * ((<zunda|URL:http://zunda.freeshell.org/d/?year=2004;month=3Q;category=rabbit>))さん
12
12
  * ((<oxy|URL:http://mono.kmc.gr.jp/~oxy/d/?date=20041019#p02>))さん
13
13
  * かずひこさん
@@ -19,7 +19,7 @@ RubyGems.orgやSlideShareへの公開をコマンド一発で実行できます
19
19
  Rabbitでよいスライドを作成し、よい発表をし、そして、共有しましょう!
20
20
 
21
21
  RubyGems.orgに公開したスライドは((<Rabbit Slide
22
- Show|URL:http://slide.rabbit-shocker.org/>))で閲覧できます。
22
+ Show|URL:https://slide.rabbit-shocker.org/>))で閲覧できます。
23
23
 
24
24
  == 雛形作成
25
25
 
@@ -203,8 +203,8 @@ RubyGems.orgのユーザー名が((%rabbit%))でスライドIDが
203
203
  % rabbit rabbit-theme-benchmark-ja.gem
204
204
 
205
205
  RubyGems.orgに公開したスライドは((<Rabbit Slide
206
- Show|URL:http://slide.rabbit-shocker.org/>))で閲覧できます。URLは
207
- ((%http://slide.rabbit-shocker.org/authors/#{RubyGems.orgのユーザー
206
+ Show|URL:https://slide.rabbit-shocker.org/>))で閲覧できます。URLは
207
+ ((%https://slide.rabbit-shocker.org/authors/#{RubyGems.orgのユーザー
208
208
  名}/#{スライドID}/%))です。
209
209
 
210
210
  Rabbit Slide ShowはRubyGems.orgに公開されているスライドを自動で収集して
@@ -15,7 +15,7 @@ Rabbitショッカーの主な活動場所はプレゼンテーションの場
15
15
 
16
16
  RabbitショッカーのみなさんはRabbitを使ってプレゼンテーションした後は使っ
17
17
  たスライドを
18
- ((<slide.rabbit-shocker.org|URL:http://slide.rabbit-shocker.org/>))へアッ
18
+ ((<slide.rabbit-shocker.org|URL:https://slide.rabbit-shocker.org/>))へアッ
19
19
  プロードしています。slide.rabbit-shocker.orgへ行けばRabbitでどんなスラ
20
20
  イドを作れるかを確認することができます。
21
21
 
@@ -1,4 +1,22 @@
1
- require 'rabbit/gtk'
1
+ # Copyright (C) 2005-2017 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 "rabbit/gtk"
18
+
19
+ Gtk.init if Gtk.respond_to?(:init)
2
20
 
3
21
  module Gtk
4
22
  class Action
@@ -129,9 +147,6 @@ module Rabbit
129
147
  end
130
148
  end
131
149
 
132
- dir = ::File.join("rabbit", "action")
133
- require_files_under_directory_in_load_path(dir)
134
-
135
150
  module_function
136
151
  def update_processing_action_status(canvas)
137
152
  canvas.action("ToggleIndexMode").sensitive = !canvas.processing?
@@ -141,3 +156,7 @@ module Rabbit
141
156
  end
142
157
  end
143
158
  end
159
+
160
+ require "rabbit/action/basic"
161
+ require "rabbit/action/radio"
162
+ require "rabbit/action/toggle"
@@ -1,10 +1,26 @@
1
+ # Copyright (C) 2004-2019 Sutou Kouhei <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
+
1
17
  require "forwardable"
2
18
  require "rabbit/gtk"
3
19
 
4
20
  require "rabbit/rabbit"
5
- require 'rabbit/frame'
6
- require 'rabbit/renderer'
7
- require 'rabbit/element'
21
+ require "rabbit/filename"
22
+ require "rabbit/frame"
23
+ require "rabbit/element"
8
24
  require "rabbit/parser"
9
25
  require "rabbit/theme/manager"
10
26
  require "rabbit/front"
@@ -18,7 +34,7 @@ module Rabbit
18
34
 
19
35
  include GetText
20
36
 
21
- INTERNAL_DPI = 80.0
37
+ INTERNAL_DPI = 96.0
22
38
 
23
39
  def_delegators(:@frame, :icon, :icon=, :set_icon)
24
40
  def_delegators(:@frame, :icon_list, :icon_list=, :set_icon_list)
@@ -29,7 +45,12 @@ module Rabbit
29
45
  def_delegators(:@frame, :iconify_available?)
30
46
 
31
47
  def_delegators(:@renderer, :width, :height)
32
- def_delegators(:@renderer, :width=, :height=)
48
+ # Deprecated. Use #base_width= instead.
49
+ def_delegator(:@renderer, :base_width=, :width=)
50
+ # Deprecated. Use #base_height= instead.
51
+ def_delegator(:@renderer, :base_height=, :height=)
52
+ def_delegators(:@renderer, :base_width, :base_height)
53
+ def_delegators(:@renderer, :base_width=, :base_height=)
33
54
  def_delegators(:@renderer, :paper_width, :paper_height)
34
55
  def_delegators(:@renderer, :paper_width=, :paper_height=)
35
56
  def_delegators(:@renderer, :margin_left, :margin_left=)
@@ -78,7 +99,7 @@ module Rabbit
78
99
 
79
100
  def_delegators(:@renderer, :z_far, :z_view)
80
101
 
81
- def_delegators(:@renderer, :to_attrs, :flag_size)
102
+ def_delegators(:@renderer, :flag_size)
82
103
 
83
104
  def_delegators(:@renderer, :create_pango_context, :pango_context=)
84
105
 
@@ -328,10 +349,14 @@ module Rabbit
328
349
  @source = source || @source
329
350
  begin
330
351
  index = current_index
352
+ current_allotted_time = allotted_time
331
353
  keep_index do
332
354
  @renderer.pre_parse
333
355
  clear
334
356
  Parser.parse(self, @source)
357
+ new_allotted_time = allotted_time
358
+ reset_timer if new_allotted_time != current_allotted_time
359
+ apply_timer
335
360
  set_current_index(index)
336
361
  reload_theme do
337
362
  if @parse_request_queue.last != id
@@ -413,9 +438,9 @@ module Rabbit
413
438
 
414
439
  def saved_image_base_name
415
440
  if @saved_image_base_name
416
- base_name = GLib.filename_to_utf8(@saved_image_base_name)
441
+ base_name = @saved_image_base_name.encode("UTF-8")
417
442
  else
418
- base_name = title.dup
443
+ base_name = Filename.sanitize(title)
419
444
  end
420
445
  base_name << "-index" if index_mode?
421
446
  base_name
@@ -518,7 +543,9 @@ module Rabbit
518
543
  end
519
544
 
520
545
  def have_previous?
521
- have_previous_slide? or (current_slide and !current_slide.first?)
546
+ return true if have_previous_slide?
547
+ return !current_slide.first? if current_slide
548
+ false
522
549
  end
523
550
 
524
551
  def have_next_slide?
@@ -526,7 +553,9 @@ module Rabbit
526
553
  end
527
554
 
528
555
  def have_next?
529
- have_next_slide? or (current_slide and !current_slide.last?)
556
+ return true if have_next_slide?
557
+ return !current_slide.last? if current_slide
558
+ false
530
559
  end
531
560
 
532
561
  def cache_all_slides
@@ -543,10 +572,11 @@ module Rabbit
543
572
  stop_auto_redraw_timer
544
573
  timer = GLib::Timeout.add(interval * 1000) do
545
574
  if quitted?
546
- false
575
+ @auto_redraw_timer = nil
576
+ GLib::Source::REMOVE
547
577
  else
548
578
  activate("Redraw")
549
- true
579
+ GLib::Source::CONTINUE
550
580
  end
551
581
  end
552
582
  @auto_redraw_timer = timer
@@ -617,7 +647,18 @@ module Rabbit
617
647
 
618
648
  def allotted_time
619
649
  time = @allotted_time
620
- time ||= title_slide.allotted_time if title_slide
650
+ if time.nil? and title_slide
651
+ time = title_slide.allotted_time
652
+ if time.nil?
653
+ start_time = title_slide.start_time
654
+ end_time = title_slide.end_time
655
+ if start_time and end_time
656
+ start_time = Time.parse(start_time)
657
+ end_time = Time.parse(end_time)
658
+ time = end_time - start_time
659
+ end
660
+ end
661
+ end
621
662
  Utils.ensure_time(time)
622
663
  end
623
664
 
@@ -633,6 +674,22 @@ module Rabbit
633
674
  @limit_time = nil
634
675
  end
635
676
 
677
+ def apply_timer
678
+ return unless title_slide
679
+
680
+ start_time = title_slide.start_time
681
+ end_time = title_slide.end_time
682
+ return if start_time.nil?
683
+ return if end_time.nil?
684
+
685
+ start_time = Time.parse(start_time)
686
+ end_time = Time.parse(end_time)
687
+ return unless (start_time..end_time).cover?(Time.now)
688
+
689
+ @allotted_time = end_time - start_time
690
+ @limit_time = end_time
691
+ end
692
+
636
693
  def font_resolution
637
694
  INTERNAL_DPI * @font_resolution_ratio
638
695
  end
@@ -688,7 +745,6 @@ module Rabbit
688
745
 
689
746
  def clear
690
747
  clear_comments
691
- reset_timer
692
748
  stop_auto_redraw_timer
693
749
  clear_slides
694
750
  clear_index_slides
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2012-2013 Kouhei Sutou <kou@cozmixng.org>
1
+ # Copyright (C) 2012-2019 Kouhei Sutou <kou@cozmixng.org>
2
2
  #
3
3
  # This program is free software; you can redistribute it and/or modify
4
4
  # it under the terms of the GNU General Public License as published by
@@ -16,10 +16,10 @@
16
16
 
17
17
  require "yaml"
18
18
 
19
- require "rabbit/console"
20
19
  require "rabbit/author-configuration"
21
- require "rabbit/slide-configuration"
20
+ require "rabbit/console"
22
21
  require "rabbit/path-manipulatable"
22
+ require "rabbit/slide-configuration"
23
23
  require "rabbit/source-generator"
24
24
 
25
25
  module Rabbit
@@ -34,17 +34,45 @@ module Rabbit
34
34
  end
35
35
  end
36
36
 
37
+ class Data < Struct.new(:title,
38
+ :allotted_time,
39
+ :slide_conf,
40
+ :author_conf)
41
+ def available_markup_languages
42
+ {
43
+ :markdown => "Markdown",
44
+ :rd => "RD",
45
+ :hiki => "Hiki",
46
+ :pdf => "PDF",
47
+ }
48
+ end
49
+
50
+ def default_markup_language
51
+ :rd
52
+ end
53
+
54
+ def markup_language
55
+ author_conf.markup_language || default_markup_language
56
+ end
57
+
58
+ def save
59
+ author_conf.save
60
+ end
61
+ end
62
+
37
63
  def initialize
38
- @title = nil
39
- @allotted_time = nil
40
- @slide_conf = nil
41
- @author_conf = nil
64
+ @use_gui = true
65
+ @data = Data.new
42
66
  @logger = nil
43
67
  end
44
68
 
45
69
  def run(arguments)
46
70
  parse_command_line_arguments(arguments)
47
71
 
72
+ if @use_gui
73
+ return false unless show_gui
74
+ end
75
+
48
76
  validate
49
77
  unless @validation_errors.empty?
50
78
  messages = (@validation_errors + [_("See --help for example")])
@@ -53,7 +81,7 @@ module Rabbit
53
81
  end
54
82
 
55
83
  run_command
56
- @author_conf.save
84
+ @data.save
57
85
  true
58
86
  end
59
87
 
@@ -68,10 +96,10 @@ module Rabbit
68
96
  def setup_options(parser, options)
69
97
  @options = options
70
98
  @logger = @options.default_logger
71
- @author_conf = AuthorConfiguration.new(@logger)
72
- @author_conf.load
73
- @slide_conf = SlideConfiguration.new(@logger)
74
- @slide_conf.author = @author_conf
99
+ @data.author_conf = AuthorConfiguration.new(@logger)
100
+ @data.author_conf.load
101
+ @data.slide_conf = SlideConfiguration.new(@logger)
102
+ @data.slide_conf.author = @data.author_conf
75
103
 
76
104
  format = _("Usage: %s COMMAND [OPTIONS]\n" \
77
105
  " e.g.: %s new \\\n" \
@@ -92,6 +120,13 @@ module Rabbit
92
120
  parser.separator(_(" new: create a new slide"))
93
121
  parser.separator(_(" change: change an existing slide"))
94
122
 
123
+ parser.separator("")
124
+ parser.separator(_("User interface"))
125
+ parser.on("--no-use-gui",
126
+ _("Don't use GUI")) do |boolean|
127
+ @use_gui = boolean
128
+ end
129
+
95
130
  parser.separator("")
96
131
  parser.separator(_("Slide information"))
97
132
 
@@ -99,7 +134,7 @@ module Rabbit
99
134
  _("Slide ID"),
100
135
  _("(e.g.: %s)") % "--id=rubykaigi2012",
101
136
  _("(must)")) do |id|
102
- @slide_conf.id = id
137
+ @data.slide_conf.id = id
103
138
  end
104
139
 
105
140
  messages = [
@@ -109,30 +144,38 @@ module Rabbit
109
144
  ]
110
145
  parser.on("--base-name=NAME",
111
146
  *messages) do |base_name|
112
- @slide_conf.base_name = base_name
147
+ @data.slide_conf.base_name = base_name
113
148
  end
114
149
 
115
- available_markup_languages = [:rd, :hiki, :markdown]
116
- label = "[" + available_markup_languages.join(", ") + "]"
150
+ available_markup_languages = @data.available_markup_languages
151
+ label = "[" + available_markup_languages.keys.join(", ") + "]"
117
152
  messages = [
118
153
  _("Markup language for the new slide"),
119
154
  _("(e.g.: %s)") % "--markup-language=rd",
120
155
  _("(available markup languages: %s)") % label,
121
156
  ]
122
- if @author_conf.markup_language
123
- messages << _("(default: %s)") % @author_conf.markup_language
157
+ if @data.author_conf.markup_language
158
+ messages << _("(default: %s)") % @data.author_conf.markup_language
124
159
  end
125
160
  messages << _("(optional)")
126
- parser.on("--markup-language=LANGUAGE", available_markup_languages,
161
+ parser.on("--markup-language=LANGUAGE", available_markup_languages.keys,
127
162
  *messages) do |language|
128
- @author_conf.markup_language = language
163
+ @data.author_conf.markup_language = language
129
164
  end
130
165
 
131
166
  parser.on("--title=TITLE",
132
167
  _("Title of the new slide"),
133
168
  _("(e.g.: %s)") % _("--title=\"Rabbit Introduction\""),
134
169
  _("(optional)")) do |title|
135
- @title = title
170
+ @data.title = title
171
+ end
172
+
173
+ parser.on("--licenses=LICENSE,LICENSE,...",
174
+ Array,
175
+ _("License of the new slide"),
176
+ _("(e.g.: %s)") % "--licenses=CC-BY-SA-4.0,GFDL-1.3-or-later",
177
+ _("(optional)")) do |licenses|
178
+ @data.slide_conf.licenses.concat(licenses)
136
179
  end
137
180
 
138
181
  parser.on("--tags=TAG,TAG,...",
@@ -140,21 +183,39 @@ module Rabbit
140
183
  _("Tags of the new slide"),
141
184
  _("(e.g.: %s)") % "--tags=rabbit,presentation,ruby",
142
185
  _("(optional)")) do |tags|
143
- @slide_conf.tags.concat(tags)
186
+ @data.slide_conf.tags.concat(tags)
144
187
  end
145
188
 
146
189
  parser.on("--allotted-time=TIME",
147
190
  _("Allotted time in presentaion"),
148
191
  _("(e.g.: %s)") % "--allotted-time=5m",
149
192
  _("(optional)")) do |allotted_time|
150
- @allotted_time = allotted_time
193
+ @data.allotted_time = allotted_time
151
194
  end
152
195
 
153
- parser.on("--presentation-date=DATE",
196
+ parser.on("--presentation-date=DATE", Date,
154
197
  _("Presentation date with the new slide"),
155
- _("(e.g.: %s)") % "--presentation-date=2012/06/29",
198
+ _("(e.g.: %s)") % "--presentation-date=2012-06-29",
156
199
  _("(optional)")) do |date|
157
- @slide_conf.presentation_date = date
200
+ @data.slide_conf.presentation_date = date
201
+ end
202
+
203
+ presentation_start_time_example =
204
+ "--presentation-start-time=2012-06-29T10:30:00+0900"
205
+ parser.on("--presentation-start-time=TIME", Time,
206
+ _("Presentation start time"),
207
+ _("(e.g.: %s)") % presentation_start_time_example,
208
+ _("(optional)")) do |time|
209
+ @data.slide_conf.presentation_start_time = time
210
+ end
211
+
212
+ presentation_end_time_example =
213
+ "--presentation-end-time=2012-06-29T11:00:00+0900"
214
+ parser.on("--presentation-end-time=TIME", Time,
215
+ _("Presentation end time"),
216
+ _("(e.g.: %s)") % presentation_end_time_example,
217
+ _("(optional)")) do |time|
218
+ @data.slide_conf.presentation_end_time = time
158
219
  end
159
220
 
160
221
  parser.separator(_("Your information"))
@@ -163,26 +224,26 @@ module Rabbit
163
224
  _("Author name of the new slide"),
164
225
  _("(e.g.: %s)") % "--name=\"Kouhei Sutou\"",
165
226
  ]
166
- if @author_conf.name
167
- messages << _("(default: %s)") % @author_conf.name
227
+ if @data.author_conf.name
228
+ messages << _("(default: %s)") % @data.author_conf.name
168
229
  end
169
230
  messages << _("(optional)")
170
231
  parser.on("--name=NAME",
171
232
  *messages) do |name|
172
- @author_conf.name = name
233
+ @data.author_conf.name = name
173
234
  end
174
235
 
175
236
  messages = [
176
237
  _("Author e-mail of the new slide"),
177
238
  _("(e.g.: %s)") % "--email=kou@cozmixng.org",
178
239
  ]
179
- if @author_conf.email
180
- messages << _("(default: %s)") % @author_conf.email
240
+ if @data.author_conf.email
241
+ messages << _("(default: %s)") % @data.author_conf.email
181
242
  end
182
243
  messages << _("(optional)")
183
244
  parser.on("--email=EMAIL",
184
245
  *messages) do |email|
185
- @author_conf.email = email
246
+ @data.author_conf.email = email
186
247
  end
187
248
 
188
249
  messages = [
@@ -190,13 +251,13 @@ module Rabbit
190
251
  _("It is used to publish your slide to %s") % "RubyGems.org",
191
252
  _("(e.g.: %s)") % "--rubygems-user=kou",
192
253
  ]
193
- if @author_conf.rubygems_user
194
- messages << _("(default: %s)") % @author_conf.rubygems_user
254
+ if @data.author_conf.rubygems_user
255
+ messages << _("(default: %s)") % @data.author_conf.rubygems_user
195
256
  end
196
257
  messages << _("(optional)")
197
258
  parser.on("--rubygems-user=USER",
198
259
  *messages) do |user|
199
- @author_conf.rubygems_user = user
260
+ @data.author_conf.rubygems_user = user
200
261
  end
201
262
 
202
263
  messages = [
@@ -204,13 +265,13 @@ module Rabbit
204
265
  _("It is used to publish your slide to %s") % "SlideShare",
205
266
  _("(e.g.: %s)") % "--slideshare-user=kou",
206
267
  ]
207
- if @author_conf.slideshare_user
208
- messages << _("(default: %s)") % @author_conf.slideshare_user
268
+ if @data.author_conf.slideshare_user
269
+ messages << _("(default: %s)") % @data.author_conf.slideshare_user
209
270
  end
210
271
  messages << _("(optional)")
211
272
  parser.on("--slideshare-user=USER",
212
273
  *messages) do |user|
213
- @author_conf.slideshare_user = user
274
+ @data.author_conf.slideshare_user = user
214
275
  end
215
276
 
216
277
  messages = [
@@ -218,13 +279,13 @@ module Rabbit
218
279
  _("It is used to publish your slide to %s") % "Speaker Deck",
219
280
  _("(e.g.: %s)") % "--speaker-deck-user=kou",
220
281
  ]
221
- if @author_conf.speaker_deck_user
222
- messages << _("(default: %s)") % @author_conf.speaker_deck_user
282
+ if @data.author_conf.speaker_deck_user
283
+ messages << _("(default: %s)") % @data.author_conf.speaker_deck_user
223
284
  end
224
285
  messages << _("(optional)")
225
286
  parser.on("--speaker-deck-user=USER",
226
287
  *messages) do |user|
227
- @author_conf.speaker_deck_user = user
288
+ @data.author_conf.speaker_deck_user = user
228
289
  end
229
290
  end
230
291
 
@@ -240,6 +301,109 @@ module Rabbit
240
301
  ["new", "change"]
241
302
  end
242
303
 
304
+ class TextMapper
305
+ def initialize(data)
306
+ @data = data
307
+ end
308
+
309
+ def attach(entry)
310
+ entry.signal_connect(:notify) do |_widget, param_spec|
311
+ if param_spec.name == "text"
312
+ if valid?(_widget.text)
313
+ _widget.style_context.remove_class(Gtk::STYLE_CLASS_ERROR)
314
+ else
315
+ _widget.style_context.add_class(Gtk::STYLE_CLASS_ERROR)
316
+ end
317
+ end
318
+ end
319
+ entry.text = value if value
320
+ end
321
+
322
+ def apply(entry)
323
+ apply_value(entry.text)
324
+ end
325
+ end
326
+
327
+ class SlideIDMapper < TextMapper
328
+ private
329
+ def valid?(value)
330
+ not value.empty?
331
+ end
332
+
333
+ def value
334
+ @data.slide_conf.id
335
+ end
336
+
337
+ def apply_value(value)
338
+ @data.slide_conf.id = value
339
+ end
340
+ end
341
+
342
+ class SlideBaseNameMapper < TextMapper
343
+ private
344
+ def valid?(value)
345
+ not value.empty?
346
+ end
347
+
348
+ def value
349
+ @data.slide_conf.base_name
350
+ end
351
+
352
+ def apply_value(value)
353
+ @data.slide_conf.base_name = value
354
+ end
355
+ end
356
+
357
+ class SlideMarkupLanguageMapper
358
+ def initialize(data)
359
+ @data = data
360
+ end
361
+
362
+ def attach(combo_box)
363
+ combo_box = combo_box
364
+ @data.available_markup_languages.each do |key, value|
365
+ combo_box.append(key.to_s, value)
366
+ end
367
+ combo_box.active_id = @data.author_conf.markup_language
368
+ end
369
+
370
+ def apply(combo_box)
371
+ id = combo_box.active_id
372
+ id = id.to_sym if id
373
+ @data.author_conf.markup_language = id
374
+ end
375
+ end
376
+
377
+ def build_gui_mappers
378
+ {
379
+ "slide-id" => SlideIDMapper.new(@data),
380
+ "slide-base-name" => SlideBaseNameMapper.new(@data),
381
+ "slide-markup-language" => SlideMarkupLanguageMapper.new(@data),
382
+ }
383
+ end
384
+
385
+ def show_gui
386
+ require "rabbit/gtk"
387
+
388
+ mappers = build_gui_mappers
389
+
390
+ builder = Gtk::Builder.new(path: File.join(__dir__, "rabbit-slide.ui"))
391
+ mappers.each do |id, mapper|
392
+ mapper.attach(builder[id])
393
+ end
394
+
395
+ dialog = builder["dialog"]
396
+ case dialog.run
397
+ when Gtk::ResponseType::CANCEL, Gtk::ResponseType::DELETE_EVENT
398
+ false
399
+ else
400
+ mappers.each do |id, mapper|
401
+ mapper.apply(builder[id])
402
+ end
403
+ true
404
+ end
405
+ end
406
+
243
407
  def validate
244
408
  @validation_errors = []
245
409
  validate_command
@@ -260,13 +424,13 @@ module Rabbit
260
424
  end
261
425
 
262
426
  def validate_id
263
- if @slide_conf.id.nil?
427
+ if @data.slide_conf.id.nil?
264
428
  @validation_errors << (_("%s is missing") % "--id")
265
429
  end
266
430
  end
267
431
 
268
432
  def validate_base_name
269
- if @slide_conf.base_name.nil?
433
+ if @data.slide_conf.base_name.nil?
270
434
  @validation_errors << (_("%s is missing") % "--base-name")
271
435
  end
272
436
  end
@@ -288,9 +452,9 @@ module Rabbit
288
452
  def merge_config_yaml
289
453
  existing_slide_conf = SlideConfiguration.new(@logger)
290
454
  existing_slide_conf.load
291
- existing_slide_conf.merge!(@slide_conf.to_hash)
292
- @slide_conf = existing_slide_conf
293
- @author_conf = @slide_conf.author
455
+ existing_slide_conf.merge!(@data.slide_conf.to_hash)
456
+ @data.slide_conf = existing_slide_conf
457
+ @data.author_conf = @data.slide_conf.author
294
458
  end
295
459
 
296
460
  def generate_directory
@@ -320,8 +484,8 @@ EOD
320
484
  def generate_dot_rabbit
321
485
  create_file(".rabbit") do |dot_rabbit|
322
486
  options = []
323
- if @author_conf.markup_language.nil? and @allotted_time
324
- options << "--allotted-time #{@allotted_time}"
487
+ if @data.author_conf.markup_language.nil? and @data.allotted_time
488
+ options << "--allotted-time #{@data.allotted_time}"
325
489
  end
326
490
  options << slide_path
327
491
  dot_rabbit.puts(options.join("\n"))
@@ -329,7 +493,7 @@ EOD
329
493
  end
330
494
 
331
495
  def generate_slide_configuration
332
- @slide_conf.save(base_directory)
496
+ @data.slide_conf.save(base_directory)
333
497
  end
334
498
 
335
499
  def generate_readme
@@ -339,11 +503,11 @@ EOD
339
503
  end
340
504
 
341
505
  def readme_content
342
- markup_language = @author_conf.markup_language || :rd
506
+ markup_language = @data.markup_language
343
507
  generator = Rabbit::SourceGenerator.find(markup_language)
344
508
 
345
509
  content = ""
346
- title = @title || _("TODO: SLIDE TITLE")
510
+ title = @data.title || _("TODO: SLIDE TITLE")
347
511
  content << generator.heading(1, title)
348
512
  content << "\n\n"
349
513
  content << _("TODO: SLIDE DESCRIPTION")
@@ -364,12 +528,12 @@ EOD
364
528
  content << "\n\n"
365
529
  content << generator.heading(3, _("Install"))
366
530
  content << "\n\n"
367
- install_command = "gem install #{@slide_conf.gem_name}"
531
+ install_command = "gem install #{@data.slide_conf.gem_name}"
368
532
  content << generator.preformatted_line(install_command)
369
533
  content << "\n\n"
370
534
  content << generator.heading(3, _("Show"))
371
535
  content << "\n\n"
372
- show_command = "rabbit #{@slide_conf.gem_name}.gem"
536
+ show_command = "rabbit #{@data.slide_conf.gem_name}.gem"
373
537
  content << generator.preformatted_line(show_command)
374
538
  content << "\n\n"
375
539
  end
@@ -386,7 +550,7 @@ Rabbit::Task::Slide.new do |task|
386
550
  spec = task.spec
387
551
  # spec.files += Dir.glob("doc/**/*.*")
388
552
  # spec.files -= Dir.glob("private/**/*.*")
389
- # spec.add_runtime_dependency("YOUR THEME")
553
+ # spec.add_runtime_dependency("rabbit-theme-YOUR-THEME")
390
554
  end
391
555
 
392
556
  desc "Tag #{spec.version}"
@@ -407,11 +571,11 @@ end
407
571
  end
408
572
 
409
573
  def slide_path
410
- "#{@slide_conf.base_name}.#{slide_source_extension}"
574
+ "#{@data.slide_conf.base_name}.#{slide_source_extension}"
411
575
  end
412
576
 
413
577
  def slide_source_extension
414
- case @author_conf.markup_language
578
+ case @data.author_conf.markup_language
415
579
  when :rd
416
580
  "rab"
417
581
  when :hiki
@@ -424,7 +588,7 @@ end
424
588
  end
425
589
 
426
590
  def readme_extension
427
- case @author_conf.markup_language
591
+ case @data.author_conf.markup_language
428
592
  when :rd
429
593
  "rd"
430
594
  when :hiki
@@ -437,7 +601,7 @@ end
437
601
  end
438
602
 
439
603
  def slide_source
440
- generator = Rabbit::SourceGenerator.find(@author_conf.markup_language)
604
+ generator = Rabbit::SourceGenerator.find(@data.markup_language)
441
605
  return nil if generator.nil?
442
606
 
443
607
  source = ""
@@ -455,15 +619,36 @@ end
455
619
  end
456
620
 
457
621
  def slide_source_metadata(source, generator)
458
- presentation_date = @slide_conf.presentation_date
622
+ presentation_date = @data.slide_conf.presentation_date
623
+ presentation_date_default = Time.now
624
+ allotted_time_default = "5m"
625
+ allotted_time =
626
+ Utils.ensure_time(@data.allotted_time || allotted_time_default)
627
+ start_time = @data.slide_conf.presentation_start_time
628
+ end_time = @data.slide_conf.presentation_end_time
629
+ if presentation_date
630
+ start_time ||= presentation_date
631
+ end_time ||= presentation_date + allotted_time
632
+ presentation_date = presentation_date.strftime("%Y-%m-%d")
633
+ end
634
+ start_time = start_time.iso8601 if start_time
635
+ end_time = end_time.iso8601 if end_time
636
+ start_time_default = presentation_date_default
637
+ end_time_default = start_time_default + allotted_time
459
638
  slide_metadata = [
460
- ["subtitle", nil, _("SUBTITLE")],
461
- ["author", @author_conf.name, _("AUTHOR")],
462
- ["institution", nil, _("INSTITUTION")],
463
- ["content-source", nil, _("EVENT NAME")],
464
- ["date", presentation_date, Time.now.strftime("%Y-%m-%d")],
465
- ["allotted-time", @allotted_time, "5m"],
466
- ["theme", nil, "default"],
639
+ ["subtitle", nil, _("SUBTITLE")],
640
+ ["author", @data.author_conf.name, _("AUTHOR")],
641
+ ["institution", nil, _("INSTITUTION")],
642
+ ["content-source", nil, _("EVENT NAME")],
643
+ [
644
+ "date",
645
+ presentation_date,
646
+ presentation_date_default.strftime("%Y-%m-%d"),
647
+ ],
648
+ ["allotted-time", @data.allotted_time, "5m"],
649
+ ["start-time", start_time, start_time_default.iso8601],
650
+ ["end-time", end_time, end_time_default.iso8601],
651
+ ["theme", nil, "default"],
467
652
  ]
468
653
  slide_metadata.each do |key, value, default_value|
469
654
  item = generator.definition_list_item(key, value || default_value)
@@ -501,7 +686,7 @@ end
501
686
  when "change"
502
687
  "."
503
688
  else
504
- @slide_conf.id
689
+ @data.slide_conf.id
505
690
  end
506
691
  end
507
692