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
@@ -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