rabbit 2.1.9 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/data/locale/ja/LC_MESSAGES/rabbit.mo +0 -0
  3. data/doc/_config.yml +4 -4
  4. data/doc/en/faq.rd +8 -8
  5. data/doc/en/news.rd +105 -1
  6. data/doc/ja/news.rd +104 -1
  7. data/lib/rabbit/canvas.rb +2 -1
  8. data/lib/rabbit/command/rabbit.rb +6 -3
  9. data/lib/rabbit/element/index-slide.rb +2 -2
  10. data/lib/rabbit/element/text-container-element.rb +30 -1
  11. data/lib/rabbit/element/text-renderer.rb +12 -1
  12. data/lib/rabbit/element/text.rb +7 -0
  13. data/lib/rabbit/error.rb +4 -3
  14. data/lib/rabbit/frame.rb +8 -22
  15. data/lib/rabbit/front.rb +8 -8
  16. data/lib/rabbit/gem-pusher.rb +66 -0
  17. data/lib/rabbit/gtk.rb +4 -0
  18. data/lib/rabbit/image-data-loader.rb +3 -3
  19. data/lib/rabbit/image/dia.rb +11 -6
  20. data/lib/rabbit/image/eps.rb +13 -11
  21. data/lib/rabbit/image/gimp.rb +1 -1
  22. data/lib/rabbit/image/pdf.rb +6 -10
  23. data/lib/rabbit/image/svg.rb +5 -1
  24. data/lib/rabbit/parser/markdown.rb +1 -0
  25. data/lib/rabbit/parser/markdown/converter.rb +43 -2
  26. data/lib/rabbit/password-reader.rb +34 -0
  27. data/lib/rabbit/progress.rb +22 -10
  28. data/lib/rabbit/renderer.rb +1 -1
  29. data/lib/rabbit/renderer/base.rb +7 -7
  30. data/lib/rabbit/renderer/color.rb +8 -0
  31. data/lib/rabbit/renderer/display/drawing-area-base.rb +1 -0
  32. data/lib/rabbit/renderer/display/drawing-area-primitive.rb +14 -2
  33. data/lib/rabbit/renderer/display/magnifier.rb +6 -4
  34. data/lib/rabbit/renderer/display/scroll-handler.rb +2 -2
  35. data/lib/rabbit/renderer/display/spotlight.rb +1 -1
  36. data/lib/rabbit/renderer/engine/cairo.rb +16 -1
  37. data/lib/rabbit/renderer/offscreen.rb +120 -0
  38. data/lib/rabbit/search-window.rb +6 -6
  39. data/lib/rabbit/searcher.rb +4 -84
  40. data/lib/rabbit/slideshare.rb +7 -11
  41. data/lib/rabbit/source-generator/markdown.rb +4 -4
  42. data/lib/rabbit/task/slide.rb +4 -2
  43. data/lib/rabbit/task/theme.rb +6 -3
  44. data/lib/rabbit/theme/slide-logo/slide-logo.rb +37 -27
  45. data/lib/rabbit/theme/syntax-highlighting/syntax-highlighting.rb +1 -7
  46. data/lib/rabbit/theme/title-on-image-toolkit/title-on-image-toolkit.rb +6 -0
  47. data/lib/rabbit/utils.rb +0 -5
  48. data/lib/rabbit/version.rb +2 -2
  49. data/po/en/rabbit.edit.po +151 -143
  50. data/po/en/rabbit.po +7 -1
  51. data/po/fr/rabbit.edit.po +151 -143
  52. data/po/fr/rabbit.po +7 -1
  53. data/po/ja/rabbit.edit.po +155 -147
  54. data/po/ja/rabbit.po +11 -5
  55. data/rabbit.gemspec +2 -1
  56. data/sample/rabbit.md +10 -0
  57. data/test/parser/test-markdown.rb +47 -1
  58. data/test/source-generator/test-markdown.rb +2 -2
  59. metadata +21 -9
  60. data/lib/rabbit/renderer/pixmap.rb +0 -1
  61. data/lib/rabbit/renderer/pixmap/base.rb +0 -127
  62. data/lib/rabbit/renderer/pixmap/cairo.rb +0 -15
  63. data/lib/rabbit/renderer/pixmap/gl.rb +0 -46
@@ -0,0 +1,34 @@
1
+ # Copyright (C) 2012-2016 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
+ module Rabbit
18
+ class PasswordReader
19
+ def initialize(prompt)
20
+ @prompt = prompt
21
+ end
22
+
23
+ def read
24
+ print(@prompt)
25
+ system("/bin/stty -echo") if $stdin.tty?
26
+ $stdin.gets.chomp
27
+ ensure
28
+ if $stdin.tty?
29
+ system("/bin/stty echo")
30
+ puts
31
+ end
32
+ end
33
+ end
34
+ end
@@ -9,7 +9,6 @@ module Rabbit
9
9
  @bar = Gtk::ProgressBar.new
10
10
  @bar.show_text = true
11
11
  @window.add(@bar)
12
- @original_style = @bar.style
13
12
  @foreground = nil
14
13
  @background = nil
15
14
  end
@@ -52,16 +51,29 @@ module Rabbit
52
51
 
53
52
  private
54
53
  def setup_progress_color
55
- style = @original_style.copy
56
- if @foreground
57
- rgb = @foreground.to_gdk_rgb
58
- style.set_bg(Gtk::STATE_PRELIGHT, *rgb)
54
+ if Gtk.const_defined?(:CssProvider)
55
+ css = "progressbar {\n"
56
+ if @foreground
57
+ css << " color: #{@foreground.to_css_rgba};\n"
58
+ end
59
+ if @background
60
+ css << " background-color: #{@background.to_css_rgba};\n"
61
+ end
62
+ css << "}\n"
63
+ provider = Gtk::CssProvider.default
64
+ provider.load(:data => css)
65
+ else
66
+ style = @bar.style.copy
67
+ if @foreground
68
+ rgb = @foreground.to_gdk_rgb
69
+ style.set_bg(Gtk::STATE_PRELIGHT, *rgb)
70
+ end
71
+ if @background
72
+ rgb = @background.to_gdk_rgb
73
+ style.set_bg(Gtk::STATE_NORMAL, *rgb)
74
+ end
75
+ @bar.style = style
59
76
  end
60
- if @background
61
- rgb = @background.to_gdk_rgb
62
- style.set_bg(Gtk::STATE_NORMAL, *rgb)
63
- end
64
- @bar.style = style
65
77
  end
66
78
  end
67
79
  end
@@ -2,7 +2,7 @@ require "rabbit/utils"
2
2
 
3
3
  require "rabbit/renderer/color"
4
4
  require "rabbit/renderer/display"
5
- require "rabbit/renderer/pixmap"
5
+ require "rabbit/renderer/offscreen"
6
6
  require "rabbit/renderer/print"
7
7
 
8
8
  module Rabbit
@@ -114,7 +114,7 @@ module Rabbit
114
114
  end
115
115
 
116
116
  def each_slide_pixbuf
117
- canvas = off_screen_canvas
117
+ canvas = offscreen_canvas
118
118
  previous_index = canvas.current_index
119
119
  pre_to_pixbuf(canvas.slide_size)
120
120
  canceled = false
@@ -129,11 +129,11 @@ module Rabbit
129
129
  canvas.activate("Quit") if canvas != @canvas
130
130
  end
131
131
 
132
- def off_screen_canvas
133
- if off_screen_renderer?
132
+ def offscreen_canvas
133
+ if offscreen_renderer?
134
134
  @canvas
135
135
  else
136
- make_canvas_with_off_screen_renderer
136
+ make_canvas_with_offscreen_renderer
137
137
  end
138
138
  end
139
139
 
@@ -258,7 +258,7 @@ module Rabbit
258
258
  end
259
259
 
260
260
  private
261
- def off_screen_renderer?
261
+ def offscreen_renderer?
262
262
  false
263
263
  end
264
264
 
@@ -301,8 +301,8 @@ module Rabbit
301
301
  end
302
302
  end
303
303
 
304
- def make_canvas_with_off_screen_renderer
305
- make_canvas_with_renderer(Pixmap::Cairo) do |canvas|
304
+ def make_canvas_with_offscreen_renderer
305
+ make_canvas_with_renderer(Offscreen) do |canvas|
306
306
  canvas.width = @canvas.width
307
307
  canvas.height = @canvas.height
308
308
  setup_3d(canvas)
@@ -74,6 +74,14 @@ module Rabbit
74
74
  def to_gdk_color
75
75
  Gdk::Color.new(*to_gdk_rgb)
76
76
  end
77
+
78
+ def to_css_rgba
79
+ red_percent = (red * 100).ceil
80
+ green_percent = (green * 100).ceil
81
+ blue_percent = (blue * 100).ceil
82
+ a = alpha || 1.0
83
+ "rgba(#{red_percent}%, #{green_percent}%, #{blue_percent}%, #{a})"
84
+ end
77
85
  end
78
86
  end
79
87
  end
@@ -268,6 +268,7 @@ module Rabbit
268
268
  event_mask |= Gdk::EventMask::BUTTON1_MOTION_MASK
269
269
  event_mask |= Gdk::EventMask::BUTTON2_MOTION_MASK
270
270
  event_mask |= Gdk::EventMask::BUTTON3_MOTION_MASK
271
+ event_mask |= Gdk::EventMask::SCROLL_MASK
271
272
  @area.add_events(event_mask)
272
273
  set_key_press_event(@area)
273
274
  set_button_event(@area)
@@ -171,14 +171,26 @@ module Rabbit
171
171
  end
172
172
 
173
173
  def set_configure_event_after
174
+ prev_x = prev_y = prev_width = prev_height = nil
174
175
  @area.signal_connect_after("configure_event") do |widget, event|
175
- configured_after(widget, event)
176
+ prev_x ||= event.x
177
+ prev_y ||= event.y
178
+ prev_width ||= event.width
179
+ prev_height ||= event.height
180
+ if [prev_x, prev_y, prev_width, prev_height] !=
181
+ [event.x, event.y, event.width, event.height]
182
+ configured_after(widget, event)
183
+ end
184
+ prev_x = event.x
185
+ prev_y = event.y
186
+ prev_width = event.width
187
+ prev_height = event.height
188
+ false
176
189
  end
177
190
  end
178
191
 
179
192
  def configured_after(widget, event)
180
193
  reload_theme if @drawable
181
- false
182
194
  end
183
195
 
184
196
  def reload_theme(&callback)
@@ -93,15 +93,17 @@ module Rabbit
93
93
 
94
94
  w = width / 1.5
95
95
  h = height / 1.5
96
- x = @magnifier_center_x - w / 2
97
- y = @magnifier_center_y - h / 2
96
+ center_x = @magnifier_center_x - size.logical_margin_left
97
+ center_y = @magnifier_center_y - size.logical_margin_top
98
+ x = center_x - w / 2
99
+ y = center_y - h / 2
98
100
  r = w * 0.1
99
101
  save_context do
100
102
  clip_block = Proc.new do
101
103
  draw_rectangle(true, 0, 0, width, height, @background)
102
- translate_context(@magnifier_center_x, @magnifier_center_y)
104
+ translate_context(center_x, center_y)
103
105
  scale_context(@magnifier_ratio, @magnifier_ratio)
104
- translate_context(-@magnifier_center_x, -@magnifier_center_y)
106
+ translate_context(-center_x, -center_y)
105
107
  block.call
106
108
  end
107
109
  draw_rounded_rectangle(false, x, y, w, h, r, nil,
@@ -19,9 +19,9 @@ module Rabbit
19
19
  unless handled
20
20
  handled = true
21
21
  case event.direction
22
- when Gdk::EventScroll::Direction::UP
22
+ when Gdk::ScrollDirection::UP
23
23
  @canvas.activate("PreviousSlide")
24
- when Gdk::EventScroll::Direction::DOWN
24
+ when Gdk::ScrollDirection::DOWN
25
25
  @canvas.activate("NextSlide")
26
26
  else
27
27
  handled = false
@@ -101,7 +101,7 @@ module Rabbit
101
101
  :color_stops => color_stops,
102
102
  }
103
103
  }
104
- draw_rectangle(true, 0, 0, width, height, nil, params)
104
+ draw_rectangle(true, 0, 0, size.real_width, size.real_height, nil, params)
105
105
  end
106
106
 
107
107
  def spotlighting?
@@ -186,7 +186,12 @@ module Rabbit
186
186
  set_source(color, params)
187
187
  set_line_options(params)
188
188
  @context.move_to(x, y)
189
- @context.show_pango_layout(layout)
189
+ if params[:stroke]
190
+ @context.pango_layout_path(layout)
191
+ apply_cairo_action(false, params)
192
+ else
193
+ @context.show_pango_layout(layout)
194
+ end
190
195
  end
191
196
  end
192
197
 
@@ -266,6 +271,16 @@ module Rabbit
266
271
  end
267
272
  end
268
273
 
274
+ def draw_link(uri)
275
+ if @context.respond_to?(:tag)
276
+ @context.tag(::Cairo::Tag::LINK, "uri='#{uri}'") do
277
+ yield
278
+ end
279
+ else
280
+ yield
281
+ end
282
+ end
283
+
269
284
  def make_layout(text)
270
285
  attributes, text = Pango.parse_markup(text)
271
286
  layout = @context.create_pango_layout
@@ -0,0 +1,120 @@
1
+ # Copyright (C) 2016 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/image-data-loader"
18
+ require "rabbit/renderer/base"
19
+ require "rabbit/renderer/engine/cairo"
20
+ require "rabbit/utils"
21
+
22
+ module Rabbit
23
+ module Renderer
24
+ class Offscreen
25
+ include Renderer::Base
26
+ include Engine::Cairo
27
+
28
+ attr_accessor :width, :height, :pango_context
29
+
30
+ def initialize(canvas, width=nil, height=nil)
31
+ super(canvas)
32
+ @width = width
33
+ @height = height
34
+ @pango_context = nil
35
+ end
36
+
37
+ def post_apply_theme
38
+ end
39
+
40
+ def post_move(old_index, index)
41
+ end
42
+
43
+ def post_move_in_slide(old_index, index)
44
+ end
45
+
46
+ def pre_parse
47
+ end
48
+
49
+ def post_parse
50
+ end
51
+
52
+ def index_mode_on
53
+ end
54
+
55
+ def index_mode_off
56
+ end
57
+
58
+ def pre_toggle_index_mode
59
+ end
60
+
61
+ def post_toggle_index_mode
62
+ end
63
+
64
+ def make_layout(text)
65
+ attrs, text = Pango.parse_markup(text)
66
+ layout = Pango::Layout.new(create_pango_context)
67
+ layout.text = text
68
+ layout.set_attributes(attrs)
69
+ layout
70
+ end
71
+
72
+ def to_pixbuf(slide)
73
+ pixbuf = nil
74
+ ::Cairo::ImageSurface.new(@width, @height) do |surface|
75
+ context = ::Cairo::Context.new(surface)
76
+ init_context(context)
77
+ slide.draw(@canvas)
78
+ png = StringIO.new
79
+ surface.write_to_png(png)
80
+ loader = ImageDataLoader.new(png.string)
81
+ pixbuf = loader.load
82
+ finish_context
83
+ end
84
+ pixbuf
85
+ end
86
+
87
+ def create_pango_context
88
+ context = Gtk::Invisible.new.create_pango_context
89
+ set_font_resolution(context)
90
+ context
91
+ end
92
+
93
+ def pre_to_pixbuf(slide_size)
94
+ end
95
+
96
+ def to_pixbufing(i)
97
+ Utils.process_pending_events
98
+ true
99
+ end
100
+
101
+ def post_to_pixbuf(canceled)
102
+ end
103
+
104
+ private
105
+ def init_color
106
+ super
107
+ init_engine_color
108
+ end
109
+
110
+ def offscreen_renderer?
111
+ true
112
+ end
113
+
114
+ def init_dpi
115
+ @x_dpi = ScreenInfo.screen_x_resolution
116
+ @y_dpi = ScreenInfo.screen_y_resolution
117
+ end
118
+ end
119
+ end
120
+ end
@@ -50,7 +50,7 @@ module Rabbit
50
50
 
51
51
  def init_frame
52
52
  @frame = Gtk::Frame.new
53
- @frame.shadow_type = Gtk::ShadowType::ETCHED_IN
53
+ @frame.shadow_type = :etched_in
54
54
  @frame.show
55
55
  @window.add(@frame)
56
56
  end
@@ -70,7 +70,7 @@ module Rabbit
70
70
 
71
71
  def init_direction
72
72
  @direction = Gtk::ToggleButton.new
73
- @arrow = Gtk::Arrow.new(Gtk::Arrow::LEFT, Gtk::SHADOW_NONE)
73
+ @arrow = Gtk::Arrow.new(:left, :none)
74
74
  @arrow.show
75
75
  @direction.add(@arrow)
76
76
  @direction.can_focus = false
@@ -78,18 +78,18 @@ module Rabbit
78
78
  @box.add(@direction)
79
79
  @direction.signal_connect("toggled") do |button|
80
80
  if forward?
81
- type = Gtk::Arrow::RIGHT
81
+ type = :right
82
82
  else
83
- type = Gtk::Arrow::LEFT
83
+ type = :left
84
84
  end
85
- @arrow.set(type, Gtk::SHADOW_NONE)
85
+ @arrow.set(type, :none)
86
86
  end
87
87
  @direction.active = true
88
88
  end
89
89
 
90
90
  def send_focus_change(focus_in)
91
91
  @entry.has_focus = focus_in
92
- event = Gdk::EventFocus.new(Gdk::EventFocus::FOCUS_CHANGE)
92
+ event = Gdk::EventFocus.new(:focus_change)
93
93
  event.window = @entry.window
94
94
  event.in = focus_in
95
95
  @entry.event(event)
@@ -1,17 +1,7 @@
1
1
  require 'rabbit/utils'
2
2
 
3
- Rabbit::Converter.keep_kcode("EUC-JP") do
4
- begin
5
- require 'migemo'
6
- rescue LoadError
7
- end
8
- end
9
-
10
3
  module Rabbit
11
4
  class Searcher
12
- @@migemo_static_dict = nil
13
- @@migemo_static_dict_cache = nil
14
-
15
5
  def initialize(canvas)
16
6
  @canvas = canvas
17
7
  end
@@ -26,81 +16,11 @@ module Rabbit
26
16
 
27
17
  private
28
18
  def internal_regexp
29
- if migemo_available?
30
- migemo_regexp
31
- else
32
- begin
33
- /#{@text}/iu
34
- rescue RegexpError
35
- /#{Regexp.escape(@text)}/iu
36
- end
37
- end
38
- end
39
-
40
- def migemo_regexp
41
- text = Converter.to_eucjp_from_utf8(@text)
42
- segments = migemo_split_text(text)
43
- if segments.size <= 1
44
- regexp_str = migemo_generate_regexp_str(text, false)
45
- else
46
- regexp_str1 = migemo_generate_regexp_str(text, true)
47
- regexp_str2 = segments.collect do |pattern|
48
- migemo_generate_regexp_str(pattern, true)
49
- end.join
50
- regexp_str = [regexp_str1, regexp_str2].join("|")
51
- end
52
- /#{Converter.to_utf8_from_eucjp(regexp_str)}/iu
53
- end
54
-
55
- def migemo_generate_regexp_str(pattern, with_paren)
56
- Converter.keep_kcode("EUC-JP") do
57
- migemo = Migemo.new(@@migemo_static_dict, pattern)
58
- migemo.dict_cache = @@migemo_static_dict_cache
59
- migemo.with_paren = with_paren
60
- migemo.regex
61
- end
62
- end
63
-
64
- def migemo_split_text(text)
65
- text.scan(/[A-Z]?[^A-Z]+|[A-Z]+/e)
66
- end
67
-
68
- def migemo_available?
69
- defined?(::Migemo) and have_migemo_static_dict?
70
- end
71
-
72
- def have_migemo_static_dict?
73
- if @@migemo_static_dict.nil?
74
- dict, dict_cache = search_migemo_static_dict
75
- @@migemo_static_dict, @@migemo_static_dict_cache = dict, dict_cache
76
- end
77
- not @@migemo_static_dict.nil?
78
- end
79
-
80
- def search_migemo_static_dict
81
- @canvas.migemo_dictionary_search_path.each do |target|
82
- if File.directory?(target)
83
- [
84
- File.join(target, @canvas.migemo_dictionary_name),
85
- File.join(target, "migemo", @canvas.migemo_dictionary_name),
86
- ].each do |guess|
87
- return make_migemo_dict(guess) if File.readable?(guess)
88
- end
89
- elsif File.readable?(target)
90
- return make_migemo_dict(target)
91
- end
92
- end
93
- nil
94
- end
95
-
96
- def make_migemo_dict(path)
97
- dict = MigemoStaticDict.new(path)
98
- dict_cache = nil
99
- dict_cache_path = "#{path}.cache"
100
- if File.readable?(dict_cache_path)
101
- dict_cache = MigemoDictCache.new(dict_cache_path)
19
+ begin
20
+ /#{@text}/iu
21
+ rescue RegexpError
22
+ /#{Regexp.escape(@text)}/iu
102
23
  end
103
- [dict, dict_cache]
104
24
  end
105
25
  end
106
26
  end