rabbit 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/data/locale/en/LC_MESSAGES/rabbit.mo +0 -0
  3. data/data/locale/ja/LC_MESSAGES/rabbit.mo +0 -0
  4. data/doc/_config.yml +2 -2
  5. data/doc/en/faq.rd +4 -2
  6. data/doc/en/news.rd +91 -0
  7. data/doc/en/sample/hiki/rabbit.hiki +0 -4
  8. data/doc/en/sample/rd/rabbit.rd +0 -4
  9. data/doc/en/usage/rabbit-slide.rd +3 -3
  10. data/doc/index.html.en +1 -1
  11. data/doc/ja/faq.rd +2 -0
  12. data/doc/ja/news.rd +90 -0
  13. data/doc/ja/sample/hiki/rabbit.hiki +0 -4
  14. data/doc/ja/sample/rd/rabbit.rd +0 -4
  15. data/doc/ja/usage/rabbit-slide.rd +3 -3
  16. data/doc/ja/users.rd +7 -0
  17. data/lib/rabbit/action/toggle.rb +7 -0
  18. data/lib/rabbit/author-configuration.rb +3 -4
  19. data/lib/rabbit/canvas.rb +11 -1
  20. data/lib/rabbit/command/rabbit-slide.rb +59 -1
  21. data/lib/rabbit/command/rabbit-slide.ui +127 -49
  22. data/lib/rabbit/command/rabbit.rb +5 -9
  23. data/lib/rabbit/element/image.rb +78 -94
  24. data/lib/rabbit/element/video.rb +3 -11
  25. data/lib/rabbit/error.rb +2 -2
  26. data/lib/rabbit/frame.rb +102 -4
  27. data/lib/rabbit/gem-pusher.rb +28 -6
  28. data/lib/rabbit/image/base.rb +97 -26
  29. data/lib/rabbit/image/dia.rb +21 -6
  30. data/lib/rabbit/image/pdf.rb +1 -4
  31. data/lib/rabbit/image/svg.rb +1 -4
  32. data/lib/rabbit/image.rb +3 -4
  33. data/lib/rabbit/info-window.rb +106 -80
  34. data/lib/rabbit/keys.rb +6 -0
  35. data/lib/rabbit/menu.rb +2 -0
  36. data/lib/rabbit/parser/ext/charty.rb +58 -0
  37. data/lib/rabbit/parser/ext/image.rb +2 -1
  38. data/lib/rabbit/parser/rd/ext/block-verbatim.rb +13 -5
  39. data/lib/rabbit/progress.rb +1 -1
  40. data/lib/rabbit/properties.rb +141 -0
  41. data/lib/rabbit/rabbit.rb +3 -1
  42. data/lib/rabbit/relative-size.rb +28 -0
  43. data/lib/rabbit/renderer/base.rb +6 -0
  44. data/lib/rabbit/renderer/display/drawing-area-base.rb +0 -1
  45. data/lib/rabbit/renderer/display/drawing-area-primitive.rb +1 -0
  46. data/lib/rabbit/renderer/display/info.rb +6 -1
  47. data/lib/rabbit/renderer/display/key-handler.rb +27 -2
  48. data/lib/rabbit/renderer/engine/cairo.rb +24 -3
  49. data/lib/rabbit/renderer/screen.rb +0 -1
  50. data/lib/rabbit/slide-configuration.rb +12 -8
  51. data/lib/rabbit/task/slide.rb +3 -3
  52. data/lib/rabbit/theme/clear-blue/clear-blue.rb +3 -1
  53. data/lib/rabbit/theme/edge-info-toolkit/edge-info-toolkit.rb +12 -2
  54. data/lib/rabbit/theme/image-slide-number/image-slide-number.rb +1 -1
  55. data/lib/rabbit/theme/slide-footer-info/slide-footer-info.rb +2 -0
  56. data/lib/rabbit/theme/tag/tag.rb +9 -2
  57. data/lib/rabbit/theme-configuration.rb +3 -4
  58. data/lib/rabbit/version.rb +1 -1
  59. data/lib/rabbit/video-window.rb +14 -3
  60. data/lib/rabbit/yaml-loader.rb +39 -0
  61. data/po/en/rabbit.edit.po +82 -64
  62. data/po/en/rabbit.po +16 -2
  63. data/po/fr/rabbit.edit.po +81 -63
  64. data/po/fr/rabbit.po +15 -1
  65. data/po/ja/rabbit.edit.po +108 -65
  66. data/po/ja/rabbit.po +19 -3
  67. data/sample/can_rabbit.rd +0 -24
  68. data/sample/rabbit-en.hiki +0 -4
  69. data/sample/rabbit-en.rd +0 -4
  70. data/sample/rabbit.hiki +0 -4
  71. data/sample/rabbit.rd +0 -4
  72. data/test/test-slide-configuration.rb +3 -2
  73. metadata +27 -24
@@ -32,7 +32,12 @@ module Rabbit
32
32
 
33
33
  def post_move(old_index, index)
34
34
  super
35
- @info_window.moved(index)
35
+ @info_window.moved
36
+ end
37
+
38
+ def post_move_in_slide(old_index, index)
39
+ super
40
+ @info_window.moved
36
41
  end
37
42
 
38
43
  def index_mode_on
@@ -19,10 +19,19 @@ module Rabbit
19
19
  @user_accel_group.disconnect_key(keyval, modifier)
20
20
  end
21
21
 
22
+ def pre_terminal
23
+ @window.remove_accel_group(@accel_group)
24
+ end
25
+
26
+ def post_terminal
27
+ @window.add_accel_group(@accel_group)
28
+ end
29
+
22
30
  private
23
31
  def init_key_handler
24
32
  @user_accel_group = nil
25
33
  init_accel_group
34
+ init_toggle_terminal_accel_group
26
35
  end
27
36
 
28
37
  def clear_user_accel_group
@@ -31,10 +40,12 @@ module Rabbit
31
40
 
32
41
  def attach_key(window)
33
42
  window.add_accel_group(@accel_group)
43
+ window.add_accel_group(@toggle_terminal_accel_group)
34
44
  end
35
45
 
36
46
  def detach_key(window)
37
47
  window.remove_accel_group(@accel_group)
48
+ window.remove_accel_group(@toggle_terminal_accel_group)
38
49
  end
39
50
 
40
51
  def clear_keys
@@ -53,10 +64,24 @@ module Rabbit
53
64
  init_alt_keys
54
65
  end
55
66
 
56
- def set_keys(keys, mod, flags=nil, &block)
67
+ def init_toggle_terminal_accel_group
68
+ @toggle_terminal_accel_group = Gtk::AccelGroup.new
69
+ mod = Gdk::ModifierType::SHIFT_MASK |
70
+ Gdk::ModifierType::CONTROL_MASK |
71
+ Gdk::ModifierType::MOD1_MASK
72
+ keys = Keys::ShiftControlAlt::TOGGLE_TERMINAL_KEYS
73
+ set_keys(keys,
74
+ mod,
75
+ nil,
76
+ @toggle_terminal_accel_group) do |group, obj, val, modifier|
77
+ @canvas.activate("ToggleTerminal")
78
+ end
79
+ end
80
+
81
+ def set_keys(keys, mod, flags=nil, accel_group=@accel_group, &block)
57
82
  flags ||= Gtk::AccelFlags::VISIBLE
58
83
  keys.each do |val|
59
- @accel_group.connect(val, mod, flags, &block)
84
+ accel_group.connect(val, mod, flags, &block)
60
85
  end
61
86
  end
62
87
 
@@ -195,6 +195,7 @@ module Rabbit
195
195
  def draw_pixbuf(pixbuf, x, y, params={})
196
196
  x, y = from_screen(x, y)
197
197
  @context.save do
198
+ apply_clip(x, y, pixbuf.width, pixbuf.height, params)
198
199
  @context.translate(x, y)
199
200
  set_source_pixbuf(pixbuf, params)
200
201
  @context.paint(params[:alpha])
@@ -244,11 +245,14 @@ module Rabbit
244
245
  def draw_rsvg_handle(handle, x, y, params={})
245
246
  x, y = from_screen(x, y)
246
247
  dim = handle.dimensions
247
- width = (params[:width] || dim.width).to_f
248
- height = (params[:height] || dim.height).to_f
248
+ w = dim.width
249
+ h = dim.height
250
+ width = (params[:width] || w).to_f
251
+ height = (params[:height] || h).to_f
249
252
  @context.save do
253
+ apply_clip(x, y, w, h, params)
250
254
  @context.translate(x, y)
251
- @context.scale(width / dim.width, height / dim.height)
255
+ @context.scale(width / w, height / h)
252
256
  @context.render_rsvg_handle(handle)
253
257
  end
254
258
 
@@ -262,6 +266,7 @@ module Rabbit
262
266
  width = (params[:width] || w).to_f
263
267
  height = (params[:height] || h).to_f
264
268
  @context.save do
269
+ apply_clip(x, y, w, h, params)
265
270
  @context.translate(x, y)
266
271
  @context.scale(width / w, height / h)
267
272
  @context.render_poppler_page(page)
@@ -396,6 +401,22 @@ module Rabbit
396
401
  end
397
402
  end
398
403
 
404
+ def apply_clip(x, y, w, h, params)
405
+ clip_x = params[:clip_x]
406
+ clip_y = params[:clip_y]
407
+ clip_width = params[:clip_width]
408
+ clip_height = params[:clip_height]
409
+ if clip_x or clip_y or clip_width or clip_height
410
+ @context.rectangle(x,
411
+ y,
412
+ clip_width || w,
413
+ clip_height || h)
414
+ @context.clip
415
+ @context.translate(x - (clip_x || x),
416
+ y - (clip_y || y))
417
+ end
418
+ end
419
+
399
420
  def make_matrix(xx, xy, x0, yx, yy, y0)
400
421
  ::Cairo::Matrix.new(xx, yx, xy, yy, x0, y0)
401
422
  end
@@ -25,7 +25,6 @@ require "rabbit/renderer/display/mask"
25
25
  require "rabbit/renderer/display/search"
26
26
  require "rabbit/renderer/display/gesture"
27
27
  require "rabbit/renderer/display/graffiti"
28
- require "rabbit/renderer/display/menu"
29
28
  require "rabbit/renderer/display/button-handler"
30
29
  require "rabbit/renderer/display/key-handler"
31
30
  require "rabbit/renderer/display/scroll-handler"
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2012-2017 Kouhei Sutou <kou@cozmixng.org>
1
+ # Copyright (C) 2012-2021 Sutou Kouhei <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
@@ -17,12 +17,11 @@
17
17
  require "date"
18
18
  require "time"
19
19
 
20
- require "yaml"
21
-
22
20
  require "rabbit/gettext"
23
21
  require "rabbit/logger"
24
22
  require "rabbit/author-configuration"
25
23
  require "rabbit/path-manipulatable"
24
+ require "rabbit/yaml-loader"
26
25
 
27
26
  module Rabbit
28
27
  class SlideConfiguration
@@ -41,11 +40,12 @@ module Rabbit
41
40
  attr_accessor :licenses
42
41
  attr_accessor :slideshare_id
43
42
  attr_accessor :speaker_deck_id
44
- attr_accessor :ustream_id
45
43
  attr_accessor :vimeo_id
46
44
  attr_accessor :youtube_id
47
45
  attr_writer :version
48
46
  attr_accessor :author
47
+ attr_accessor :width
48
+ attr_accessor :height
49
49
  def initialize(logger=nil)
50
50
  @logger = logger || Logger.default
51
51
  clear
@@ -65,7 +65,7 @@ module Rabbit
65
65
 
66
66
  def load
67
67
  return unless File.exist?(path)
68
- conf = YAML.load(File.read(path))
68
+ conf = YAMLLoader.load(File.read(path))
69
69
  clear
70
70
  merge!(conf)
71
71
  rescue
@@ -94,10 +94,11 @@ module Rabbit
94
94
  @licenses = []
95
95
  @slideshare_id = nil
96
96
  @speaker_deck_id = nil
97
- @ustream_id = nil
98
97
  @vimeo_id = nil
99
98
  @youtube_id = nil
100
99
  @author = nil
100
+ @width = 800
101
+ @height = 600
101
102
  end
102
103
 
103
104
 
@@ -113,7 +114,6 @@ module Rabbit
113
114
  @version = conf["version"] || @version
114
115
  @slideshare_id = conf["slideshare_id"] || @slideshare_id
115
116
  @speaker_deck_id = conf["speaker_deck_id"] || @speaker_deck_id
116
- @ustream_id = conf["ustream_id"] || @ustream_id
117
117
  @vimeo_id = conf["vimeo_id"] || @vimeo_id
118
118
  @youtube_id = conf["youtube_id"] || @youtube_id
119
119
 
@@ -122,6 +122,9 @@ module Rabbit
122
122
 
123
123
  @author ||= AuthorConfiguration.new(@logger)
124
124
  @author.merge!(conf["author"] || {})
125
+
126
+ @width = conf["width"] || @width
127
+ @height = conf["height"] || @height
125
128
  end
126
129
 
127
130
  def to_hash
@@ -136,9 +139,10 @@ module Rabbit
136
139
  "licenses" => @licenses,
137
140
  "slideshare_id" => @slideshare_id,
138
141
  "speaker_deck_id" => @speaker_deck_id,
139
- "ustream_id" => @ustream_id,
140
142
  "vimeo_id" => @vimeo_id,
141
143
  "youtube_id" => @youtube_id,
144
+ "width" => @width,
145
+ "height" => @height,
142
146
  }
143
147
  config["author"] = @author.to_hash if @author
144
148
  config
@@ -174,7 +174,7 @@ module Rabbit
174
174
  end
175
175
 
176
176
  def define_publish_rubygems_task
177
- desc(_("Publish the slide to %s" % "RubyGems.org"))
177
+ desc(_("Publish the slide to %s") % "RubyGems.org")
178
178
  task :rubygems => :gem do
179
179
  pusher = GemPusher.new(gem_path, @slide.author.rubygems_user)
180
180
  pusher.push
@@ -183,7 +183,7 @@ module Rabbit
183
183
 
184
184
  def define_publish_slideshare_task
185
185
  slideshare_user = @slide.author.slideshare_user
186
- desc(_("Publish the slide to %s" % "SlideShare"))
186
+ desc(_("Publish the slide to %s") % "SlideShare")
187
187
  task :slideshare => [:pdf, "gem:validate"] do
188
188
  require "rabbit/slideshare"
189
189
  slideshare = SlideShare.new(@logger)
@@ -207,7 +207,7 @@ module Rabbit
207
207
  end
208
208
 
209
209
  def define_publish_speaker_deck_task
210
- desc(_("Publish the slide to %s" % "Speaker Deck"))
210
+ desc(_("Publish the slide to %s") % "Speaker Deck")
211
211
  task :speaker_deck => :pdf do
212
212
  puts "Not implemented yet."
213
213
  end
@@ -77,8 +77,10 @@ match(Slide, HeadLine) do |heads|
77
77
  end
78
78
 
79
79
  match(Slide, Body) do |bodies|
80
- bodies.vertical_centering = true
81
80
  bodies.each do |body|
81
+ if body.slide["enable-clear-blue-slide-body-vertical-centering"] != "false"
82
+ body.vertical_centering = true
83
+ end
82
84
  next if body.elements.all? {|element| element.is_a?(Image)}
83
85
  next if body.elements.any? {|element| element.is_a?(BlockQuote)}
84
86
  next if body.elements.any? {|element| element.is_a?(PreformattedBlock)}
@@ -13,6 +13,7 @@ match(SlideElement) do |slides|
13
13
  line_color = options[:line_color] || "#666"
14
14
  line_params = options[:line_params] || {}
15
15
  left_text = options[:left_text]
16
+ center_text = options[:center_text]
16
17
  right_text = options[:right_text]
17
18
  text_position = options[:text_position] || :lower
18
19
  text_over_line = options[:text_over_line]
@@ -36,15 +37,20 @@ match(SlideElement) do |slides|
36
37
  "size" => text_size,
37
38
  "color" => text_color,
38
39
  }
39
- left_layout = right_layout = nil
40
+ left_layout = center_layout = right_layout = nil
40
41
  if left_text and !left_text.empty?
41
42
  left_layout = make_formatted_layout.call(props, left_text)
42
43
  end
44
+ if center_text and !center_text.empty?
45
+ center_layout = make_formatted_layout.call(props, center_text)
46
+ center_layout.alignment = :center
47
+ center_layout.width = (w - (x_margin * 2)) * Pango::SCALE
48
+ end
43
49
  if right_text and !right_text.empty?
44
50
  right_layout = make_formatted_layout.call(props, right_text)
45
51
  end
46
52
 
47
- layouts = [left_layout, right_layout].compact
53
+ layouts = [left_layout, center_layout, right_layout].compact
48
54
  unless layouts.empty?
49
55
  max_height = layouts.collect {|layout| layout.pixel_size[1]}.max
50
56
  if text_position == :lower
@@ -63,6 +69,10 @@ match(SlideElement) do |slides|
63
69
  canvas.draw_layout(left_layout, x_margin, text_base_y)
64
70
  end
65
71
 
72
+ if center_layout
73
+ canvas.draw_layout(center_layout, x_margin, text_base_y)
74
+ end
75
+
66
76
  if right_layout
67
77
  text_width, text_height = right_layout.pixel_size
68
78
  right_text_x = canvas.width - text_width - x_margin
@@ -88,7 +88,7 @@ match(Slide) do |slides|
88
88
  margin_bottom = @image_slide_number_margin_bottom || slide.margin_bottom
89
89
  base_x = margin_left
90
90
  base_y = canvas.height - loader.height - margin_bottom
91
- max_width = canvas.width - margin_left - base_x - loader.width
91
+ max_width = canvas.width - margin_right - base_x - loader.width
92
92
  start_base_x = base_x
93
93
  goal_base_x = canvas.width - margin_right - goal_flag_width
94
94
 
@@ -25,6 +25,7 @@ end
25
25
  @slide_footer_info_base_y ||= canvas.height - @margin_bottom
26
26
 
27
27
  @slide_footer_info_left_text ||= nil
28
+ @slide_footer_info_center_text ||= nil
28
29
  @slide_footer_info_right_text ||= nil
29
30
 
30
31
  include_theme("edge-info-toolkit")
@@ -39,6 +40,7 @@ match(SlideElement) do
39
40
  :line_color => @slide_footer_info_line_color,
40
41
  :line_params => @slide_footer_info_line_params,
41
42
  :left_text => @slide_footer_info_left_text,
43
+ :center_text => @slide_footer_info_center_text,
42
44
  :right_text => @slide_footer_info_right_text,
43
45
  :text_position => :lower,
44
46
  :text_over_line => @slide_footer_info_text_over_line,
@@ -61,12 +61,19 @@ match("**", CustomTag) do |tags|
61
61
  find_target.call(tag).prop_set("size", @xx_large_font_size)
62
62
  when /\A(normal|oblique|italic)\z/
63
63
  find_target.call(tag).prop_set("style", $1)
64
- when /\Amargin-(top|bottom|left|right)(?:\s*\*\s*(\d+))?\z/
64
+ when /\Amargin-(top|bottom|left|right)(?:\s*\*\s*([-\d.]+))?\z/
65
65
  target = "margin_#{$1}"
66
- scale = Integer($2 || 1)
66
+ scale = Float($2 || 1)
67
67
  outer_block = find_outer_block.call(tag)
68
68
  current_value = outer_block.send(target)
69
69
  outer_block.send("#{target}=", current_value + (@space * scale))
70
+ when /\Awrap-(.+)\z/
71
+ wrap = $1
72
+ find_target.call(tag).wrap_mode = wrap
73
+ when /\Ajustify?\z/
74
+ find_target.call(tag).justify = true
75
+ when /\Ano-justify?\z/
76
+ find_target.call(tag).justify = false
70
77
  else
71
78
  handler = find_handler.call(tag)
72
79
  if handler
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2012 Kouhei Sutou <kou@cozmixng.org>
1
+ # Copyright (C) 2012-2021 Sutou Kouhei <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
@@ -14,11 +14,10 @@
14
14
  # with this program; if not, write to the Free Software Foundation, Inc.,
15
15
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
16
 
17
- require "yaml"
18
-
19
17
  require "rabbit/gettext"
20
18
  require "rabbit/author-configuration"
21
19
  require "rabbit/path-manipulatable"
20
+ require "rabbit/yaml-loader"
22
21
 
23
22
  module Rabbit
24
23
  class ThemeConfiguration
@@ -42,7 +41,7 @@ module Rabbit
42
41
 
43
42
  def load
44
43
  return unless File.exist?(path)
45
- conf = YAML.load(File.read(path))
44
+ conf = YAMLLoader.load(File.read(path))
46
45
  merge!(conf)
47
46
  rescue
48
47
  format = _("Failed to read slide configuration: %s: %s")
@@ -15,5 +15,5 @@
15
15
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
16
 
17
17
  module Rabbit
18
- VERSION = "3.0.0"
18
+ VERSION = "3.0.1"
19
19
  end
@@ -87,11 +87,11 @@ module Rabbit
87
87
  @window.signal_connect(:key_press_event) do |widget, key|
88
88
  case key.keyval
89
89
  when Gdk::Keyval::KEY_space
90
- @video.toggle
90
+ @player.playing = !@player.playing?
91
91
  when Gdk::Keyval::KEY_plus
92
- @video.seek(10)
92
+ seek(10)
93
93
  when Gdk::Keyval::KEY_minus
94
- @video.seek(-10)
94
+ seek(-10)
95
95
  when *[
96
96
  Keys::MOVE_TO_NEXT_KEYS, Keys::MOVE_TO_PREVIOUS_KEYS,
97
97
  Keys::MOVE_TO_LAST_KEYS, Keys::MOVE_TO_LAST_KEYS,
@@ -104,5 +104,16 @@ module Rabbit
104
104
  true
105
105
  end
106
106
  end
107
+
108
+ def seek(second)
109
+ duration = @player.duration
110
+ progress = @player.progress + (second / duration)
111
+ if progress < 0.0
112
+ progress = 0.0
113
+ elsif progress > 1.0
114
+ progress = 1.0
115
+ end
116
+ @player.progress = progress
117
+ end
107
118
  end
108
119
  end
@@ -0,0 +1,39 @@
1
+ # Copyright (C) 2021 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
+
17
+ require "date"
18
+ require "yaml"
19
+
20
+ module Rabbit
21
+ class YAMLLoader
22
+ class << self
23
+ def load(yaml)
24
+ new(yaml).load
25
+ end
26
+ end
27
+
28
+ def initialize(yaml)
29
+ @yaml = yaml
30
+ end
31
+
32
+ def load
33
+ YAML.safe_load(@yaml,
34
+ permitted_classes: [
35
+ Date, Symbol,
36
+ ])
37
+ end
38
+ end
39
+ end