rabbit 2.1.9 → 2.2.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 (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
@@ -60,6 +60,13 @@ module Rabbit
60
60
  include TextContainerElement
61
61
 
62
62
  attr_accessor :to
63
+
64
+ # TODO: This makes paragraph instead of word link.
65
+ def draw_sub_elements(canvas, x, y, w, h)
66
+ canvas.draw_link(to) do
67
+ super
68
+ end
69
+ end
63
70
  end
64
71
 
65
72
  class Subscript
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2004-2015 Kouhei Sutou <kou@cozmixng.org>
1
+ # Copyright (C) 2004-2017 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
@@ -26,7 +26,8 @@ module Rabbit
26
26
  attr_reader :filename
27
27
  def initialize(filename)
28
28
  @filename = filename
29
- super(_("no such file: %s") % filename)
29
+ utf8_filename = GLib.filename_to_utf8(filename)
30
+ super(_("no such file: %s") % utf8_filename)
30
31
  end
31
32
  end
32
33
 
@@ -210,7 +211,7 @@ module Rabbit
210
211
 
211
212
  class UnknownCursorTypeError < Error
212
213
  attr_reader :type
213
- def intialize(type)
214
+ def initialize(type)
214
215
  @type = type
215
216
  super(_("unknown cursor type: %s") % @type)
216
217
  end
@@ -57,14 +57,10 @@ module Rabbit
57
57
  end
58
58
 
59
59
  def fullscreen
60
- @fullscreen_toggled = false
61
- @fullscreen = true
62
60
  @window.fullscreen
63
61
  end
64
62
 
65
63
  def unfullscreen
66
- @fullscreen_toggled = false
67
- @fullscreen = false
68
64
  @window.unfullscreen
69
65
  end
70
66
 
@@ -77,11 +73,7 @@ module Rabbit
77
73
  end
78
74
 
79
75
  def fullscreen?
80
- if @window.respond_to?(:fullscreen?)
81
- @window.fullscreen?
82
- else
83
- @fullscreen
84
- end
76
+ @fullscreen
85
77
  end
86
78
 
87
79
  def main_window?
@@ -94,9 +86,7 @@ module Rabbit
94
86
 
95
87
  def init_gui(width, height, main_window, window_type=nil)
96
88
  init_window(width, height, window_type)
97
- @fullscreen_toggled = false
98
89
  @fullscreen = false
99
- @iconify = false
100
90
  @main_window = main_window
101
91
  if @main_window
102
92
  @window.keep_above = @force_keep_above unless @force_keep_above.nil?
@@ -132,10 +122,10 @@ module Rabbit
132
122
  set_window_signal_destroy
133
123
  end
134
124
 
135
- def update_keep_above(keep_above=nil)
125
+ def update_keep_above(keep_above)
136
126
  if @main_window
137
127
  keep_above = @force_keep_above unless @force_keep_above.nil?
138
- @window.keep_above = keep_above unless keep_above.nil?
128
+ @window.keep_above = keep_above
139
129
  else
140
130
  @window.keep_above = true
141
131
  end
@@ -144,23 +134,21 @@ module Rabbit
144
134
  def set_window_signal_window_state_event
145
135
  @window.signal_connect("window_state_event") do |widget, event|
146
136
  if event.changed_mask.fullscreen?
147
- @fullscreen_toggled = true
148
- if fullscreen?
137
+ @fullscreen = event.new_window_state.fullscreen?
138
+ if @fullscreen
149
139
  @window.keep_above = true
150
140
  @canvas.fullscreened
151
141
  else
152
142
  update_keep_above(false)
153
143
  @canvas.unfullscreened
154
144
  end
155
- @window.present
156
145
  elsif event.changed_mask.iconified?
157
- if @iconify
158
- @iconify = false
159
- else
146
+ if event.new_window_state.iconified?
160
147
  @canvas.iconified
161
- @iconify = true
162
148
  end
163
149
  end
150
+
151
+ false
164
152
  end
165
153
  end
166
154
 
@@ -233,9 +221,7 @@ module Rabbit
233
221
  @window = Gtk::EventBox.new
234
222
  @window.set_size_request(width, height)
235
223
  @canvas.attach_to(self, @window)
236
- @fullscreen_toggled = false
237
224
  @fullscreen = false
238
- @iconify = false
239
225
  @main_window = main_window
240
226
  @window.show
241
227
  @canvas.post_init_gui
@@ -156,8 +156,8 @@ module Rabbit
156
156
  def _check_dirty
157
157
  if dirty?
158
158
  clean
159
- if off_screen_canvas.need_reload_source?
160
- off_screen_canvas.reload_source
159
+ if offscreen_canvas.need_reload_source?
160
+ offscreen_canvas.reload_source
161
161
  synchronize
162
162
  end
163
163
  end
@@ -171,9 +171,9 @@ module Rabbit
171
171
  prev_size = [@previous_width, @previous_height]
172
172
  current_size = [@canvas.width, @canvas.height]
173
173
  if prev_size != current_size
174
- off_screen_canvas.reload_theme
174
+ offscreen_canvas.reload_theme
175
175
  end
176
- pixbuf = off_screen_canvas.to_pixbuf(index)
176
+ pixbuf = offscreen_canvas.to_pixbuf(index)
177
177
  @images[index] = pixbuf.save_to_buffer(@image_type)
178
178
  synchronize
179
179
  end
@@ -183,7 +183,7 @@ module Rabbit
183
183
  def dirty?
184
184
  @dirty or
185
185
  @last_modified < @canvas.last_modified or
186
- off_screen_canvas.need_reload_source?
186
+ offscreen_canvas.need_reload_source?
187
187
  end
188
188
 
189
189
  def synchronize
@@ -233,7 +233,7 @@ module Rabbit
233
233
  end
234
234
 
235
235
  def clean
236
- @off_screen_canvas = nil
236
+ @offscreen_canvas = nil
237
237
  @dirty = false
238
238
  @images = []
239
239
  @last_modified = @canvas.last_modified
@@ -243,8 +243,8 @@ module Rabbit
243
243
  @dirty = true
244
244
  end
245
245
 
246
- def off_screen_canvas
247
- @off_screen_canvas ||= @canvas.off_screen_canvas
246
+ def offscreen_canvas
247
+ @offscreen_canvas ||= @canvas.offscreen_canvas
248
248
  end
249
249
  end
250
250
  end
@@ -0,0 +1,66 @@
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 "rake"
18
+ require "yaml"
19
+ require "open-uri"
20
+
21
+ require "rabbit/gettext"
22
+ require "rabbit/password-reader"
23
+
24
+ module Rabbit
25
+ class GemPusher
26
+ include GetText
27
+ include Rake::DSL
28
+
29
+ def initialize(gem_path, user)
30
+ @gem_path = gem_path
31
+ @user = user
32
+ end
33
+
34
+ def push
35
+ credentials_path = File.expand_path("~/.gem/credentials")
36
+ credentials_path_exist = File.exist?(credentials_path)
37
+ if credentials_path_exist
38
+ credentials = YAML.load(File.read(credentials_path))
39
+ else
40
+ credentials = {}
41
+ end
42
+ unless credentials.key?(@user.to_sym)
43
+ credentials[@user.to_sym] = retrieve_api_key
44
+ File.open(credentials_path, "w") do |credentials_file|
45
+ credentials_file.print(credentials.to_yaml)
46
+ end
47
+ unless credentials_path_exist
48
+ File.chmod(0600, credentials_path)
49
+ end
50
+ end
51
+ ruby("-S", "gem", "push", @gem_path,
52
+ "--key", @user)
53
+ end
54
+
55
+ private
56
+ def retrieve_api_key
57
+ prompt = _("Enter password on RubyGems.org [%{user}]: ") % {:user => @user}
58
+ reader = PasswordReader.new(prompt)
59
+ password = reader.read
60
+ open("https://rubygems.org/api/v1/api_key.yaml",
61
+ :http_basic_authentication => [@user, password]) do |response|
62
+ YAML.load(response.read)[:rubygems_api_key]
63
+ end
64
+ end
65
+ end
66
+ end
@@ -82,6 +82,10 @@ module Gdk
82
82
  alias_method :get_monitor_geometry, :monitor_geometry
83
83
  end
84
84
  end
85
+
86
+ unless const_defined?(:ScrollDirection)
87
+ ScrollDirection = Gdk::EventScroll::Direction
88
+ end
85
89
  end
86
90
 
87
91
  module Gtk
@@ -27,15 +27,15 @@ module Rabbit
27
27
  end
28
28
 
29
29
  def load
30
- loader = Gdk::PixbufLoader.new
30
+ loader = GdkPixbuf::PixbufLoader.new
31
31
  id = loader.signal_connect("size_prepared") do |l, width, height|
32
32
  @width = width
33
33
  @height = height
34
34
  end
35
35
  begin
36
36
  loader.last_write(@data)
37
- rescue Gdk::PixbufError => error
38
- loader.close rescue Gdk::PixbufError
37
+ rescue GdkPixbuf::PixbufError => error
38
+ loader.close rescue GdkPixbuf::PixbufError
39
39
  raise ImageLoadError.new(error.message)
40
40
  end
41
41
  loader.signal_handler_disconnect(id)
@@ -17,13 +17,18 @@ module Rabbit
17
17
  class << self
18
18
  def match?(filename)
19
19
  return true if File.extname(filename).downcase.end_with?(".dia")
20
+
20
21
  File.open(filename) do |f|
21
- first_line = f.gets
22
- second_line = f.gets
23
- return false unless second_line
24
- return false unless first_line.start_with?("<?xml")
25
- return false unless second_line.start_with?("<dia:diagram")
26
- true
22
+ begin
23
+ first_line = f.gets
24
+ second_line = f.gets
25
+ return false unless second_line
26
+ return false unless first_line.start_with?("<?xml")
27
+ return false unless second_line.start_with?("<dia:diagram")
28
+ true
29
+ rescue EncodingError
30
+ false
31
+ end
27
32
  end
28
33
  end
29
34
  end
@@ -15,20 +15,22 @@ module Rabbit
15
15
  class << self
16
16
  def match?(filename)
17
17
  File.open(filename) do |f|
18
- f.each_line do |line|
19
- case line
20
- when /^%!PS-Adobe-\d+.\d+ EPS/i
21
- return true
22
- when /^%%/
23
- # ignore
24
- else
25
- return false
18
+ begin
19
+ f.each_line do |line|
20
+ case line
21
+ when /^%!PS-Adobe-\d+.\d+ EPS/i
22
+ return true
23
+ when /^%%/
24
+ # ignore
25
+ else
26
+ return false
27
+ end
26
28
  end
29
+ false
30
+ rescue EncodingError, ArgumentError
31
+ false
27
32
  end
28
33
  end
29
- false
30
- rescue ArgumentError
31
- false
32
34
  end
33
35
  end
34
36
 
@@ -15,7 +15,7 @@ module Rabbit
15
15
 
16
16
  class << self
17
17
  def match?(filename)
18
- File.open(filename) do |f|
18
+ File.open(filename, "rb") do |f|
19
19
  HEADER == f.read(HEADER_SIZE)
20
20
  end
21
21
  end
@@ -14,15 +14,11 @@ module Rabbit
14
14
  def match?(filename)
15
15
  return true if File.extname(filename) == ".pdf"
16
16
 
17
- File.open(filename) do |file|
18
- line = file.gets
19
- return false if line.nil?
17
+ File.open(filename, "rb") do |file|
18
+ data = file.read(10)
19
+ return false if data.nil?
20
20
 
21
- begin
22
- /\A%PDF-1\.\d\z/ =~ line.chomp
23
- rescue ArgumentError
24
- false
25
- end
21
+ data.start_with?("%PDF-1.")
26
22
  end
27
23
  end
28
24
  end
@@ -70,13 +66,13 @@ module Rabbit
70
66
  end
71
67
 
72
68
  def uri
73
- "file://#{filename}"
69
+ GLib.filename_to_uri(filename)
74
70
  end
75
71
 
76
72
  def to_pixbuf
77
73
  w = original_width
78
74
  h = original_height
79
- pixbuf = Gdk::Pixbuf.new(Gdk::Pixbuf::COLORSPACE_RGB, true, 8, w, h)
75
+ pixbuf = GdkPixbuf::Pixbuf.new(:rgb, true, 8, w, h)
80
76
  page.render(0, 0, w, h, 1.0, 0, pixbuf)
81
77
  pixbuf
82
78
  end
@@ -12,7 +12,11 @@ module Rabbit
12
12
  class << self
13
13
  def match?(filename)
14
14
  File.open(filename) do |f|
15
- /<svg|<!DOCTYPE\s+svg/ =~ f.read(200)
15
+ begin
16
+ /<svg|<!DOCTYPE\s+svg/ =~ f.read(200)
17
+ rescue EncodingError
18
+ false
19
+ end
16
20
  end
17
21
  end
18
22
  end
@@ -86,6 +86,7 @@ module Kramdown
86
86
 
87
87
  private
88
88
  def fix_location(element, base_location)
89
+ return unless element.options.key?(:location)
89
90
  element.options[:location] += base_location - 1
90
91
  element.children.each do |sub_element|
91
92
  fix_location(sub_element, base_location)
@@ -1,3 +1,19 @@
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
+
1
17
  require "English"
2
18
 
3
19
  require "rabbit/gettext"
@@ -156,7 +172,17 @@ module Rabbit
156
172
  if element.options[:transparent] and child_types == [:text]
157
173
  element.children.first.value.chomp!
158
174
  end
159
- create_paragraph(convert_container(element))
175
+ converted_children = apply_class(convert_container(element),
176
+ element.attr["class"])
177
+ create_paragraph(converted_children)
178
+ end
179
+ end
180
+
181
+ def apply_class(children, klass)
182
+ return children if klass.nil?
183
+ classes = klass.split
184
+ classes.inject(children) do |nested_children, klass|
185
+ CustomTag.new(klass, nested_children)
160
186
  end
161
187
  end
162
188
 
@@ -177,7 +203,10 @@ module Rabbit
177
203
  waited_paragraphs = list_item.elements.find_all do |element|
178
204
  element.is_a?(Paragraph) and element.have_wait_tag?
179
205
  end
180
- unless waited_paragraphs.empty?
206
+ if waited_paragraphs.empty?
207
+ list_item.default_visible = true
208
+ list_item.clear_theme
209
+ else
181
210
  waited_paragraphs.each do |paragraph|
182
211
  paragraph.default_visible = true
183
212
  paragraph.clear_theme
@@ -377,6 +406,18 @@ module Rabbit
377
406
  Ext::Inline.note(convert_container(element))
378
407
  end
379
408
 
409
+ def convert_tag(element)
410
+ name = element.attr["name"]
411
+ if name.nil?
412
+ raise ParseError, _("tag name is missing.")
413
+ end
414
+ if element.children.empty?
415
+ CustomTag.new(name)
416
+ else
417
+ CustomTag.new(name, convert_container(element))
418
+ end
419
+ end
420
+
380
421
  def convert_strikethrough(element)
381
422
  DeletedText.new(text(element.value))
382
423
  end