rabbit 0.6.4 → 0.9.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 (51) hide show
  1. data/COPYING +1 -1
  2. data/NEWS.en +157 -2
  3. data/NEWS.ja +153 -1
  4. data/README.en +8 -1
  5. data/README.ja +8 -1
  6. data/Rakefile +4 -1
  7. data/TODO +17 -0
  8. data/bin/rabbiter +96 -0
  9. data/lib/rabbit/element/block-element.rb +0 -2
  10. data/lib/rabbit/element/block.rb +5 -4
  11. data/lib/rabbit/element/container-element.rb +2 -1
  12. data/lib/rabbit/element/description-list.rb +5 -2
  13. data/lib/rabbit/element/enum-list.rb +4 -0
  14. data/lib/rabbit/element/image.rb +41 -1
  15. data/lib/rabbit/element/item-list.rb +3 -0
  16. data/lib/rabbit/element/method-list.rb +2 -2
  17. data/lib/rabbit/element/poppler-page.rb +1 -0
  18. data/lib/rabbit/element/slide-element.rb +1 -0
  19. data/lib/rabbit/element/slide.rb +1 -1
  20. data/lib/rabbit/element/table.rb +7 -2
  21. data/lib/rabbit/element/tag.rb +1 -0
  22. data/lib/rabbit/element/text-block-element.rb +11 -0
  23. data/lib/rabbit/element/text-container-element.rb +4 -0
  24. data/lib/rabbit/element/text.rb +6 -3
  25. data/lib/rabbit/element/title-slide.rb +10 -10
  26. data/lib/rabbit/parser/ext/aafigure.rb +31 -0
  27. data/lib/rabbit/parser/rd.rb +2 -1
  28. data/lib/rabbit/parser/rd/ext/aafigure.rb +18 -0
  29. data/lib/rabbit/parser/rd/ext/block-verbatim.rb +27 -1
  30. data/lib/rabbit/parser/rd/ext/inline-verbatim.rb +16 -22
  31. data/lib/rabbit/parser/rd/rd2rabbit-lib.rb +8 -2
  32. data/lib/rabbit/parser/rd/rt/rt2rabbit-lib.rb +7 -1
  33. data/lib/rabbit/parser/wiki/output.rb +35 -6
  34. data/lib/rabbit/rabbit.rb +7 -1
  35. data/lib/rabbit/renderer/display/clutter-embed.rb +2 -0
  36. data/lib/rabbit/renderer/display/comment-drawing-area.rb +2 -0
  37. data/lib/rabbit/renderer/print/base.rb +6 -1
  38. data/lib/rabbit/theme/applier.rb +1 -1
  39. data/lib/rabbit/theme/background-image-toolkit/background-image-toolkit.rb +85 -0
  40. data/lib/rabbit/theme/body-background-image/body-background-image.rb +8 -0
  41. data/lib/rabbit/theme/clear-blue/clear-blue.rb +1 -1
  42. data/lib/rabbit/theme/default/default.rb +12 -4
  43. data/lib/rabbit/theme/per-slide-background-image/per-slide-background-image.rb +7 -35
  44. data/lib/rabbit/theme/table/table.rb +13 -11
  45. data/lib/rabbit/theme/tag/property.rb +4 -0
  46. data/lib/rabbit/theme/tag/tag.rb +35 -0
  47. data/lib/rabbit/theme/title-background-image/title-background-image.rb +19 -17
  48. data/sample/rabbit-en.rd +89 -1
  49. data/sample/rabbit.rd +91 -2
  50. data/sample/table.hiki +34 -0
  51. metadata +106 -32
@@ -0,0 +1,31 @@
1
+ module Rabbit
2
+ module Parser
3
+ module Ext
4
+ module AAFigure
5
+ module_function
6
+ AVAILABLE_OPTIONS = ["linewidth", "foreground", "fill", "background",
7
+ "option"]
8
+ def make_image_by_aafigure(path, prop, logger)
9
+ image_file = Tempfile.new("rabbit-image-aafigure")
10
+ command = ["aafigure",
11
+ "--type", "svg",
12
+ "--encoding", "utf-8",
13
+ "--output", image_file.path]
14
+ aafigure_options = []
15
+ AVAILABLE_OPTIONS.each do |name|
16
+ command.concat(["--#{name}", prop[name]]) if prop.has_key?(name)
17
+ end
18
+ command << path
19
+ if SystemRunner.run(*command)
20
+ image_file
21
+ else
22
+ format = _("tried aafigure command: %s")
23
+ additional_info = format % command.inspect
24
+ raise AAFigureCanNotHandleError.new(command.join(' '),
25
+ additional_info)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -14,7 +14,8 @@ module Rabbit
14
14
  end
15
15
 
16
16
  def parse
17
- source = "=begin\n#{@source.read}\n=end\n"
17
+ source = @source.read.gsub(/\r\n/, "\n")
18
+ source = "=begin\n#{source}\n=end\n"
18
19
  tree = ::RD::RDTree.new(source)
19
20
  visitor = RD2RabbitVisitor.new(@canvas)
20
21
  visitor.visit(tree)
@@ -0,0 +1,18 @@
1
+ require 'rabbit/parser/ext/aafigure'
2
+
3
+ module Rabbit
4
+ module Parser
5
+ class RD
6
+ module Ext
7
+ module AAFigure
8
+ def make_image_by_aafigure(source, visitor)
9
+ make_image_from_file(source, visitor) do |src_file_path, prop|
10
+ Parser::Ext::AAFigure.make_image_by_aafigure(src_file_path, prop,
11
+ visitor)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -10,6 +10,7 @@ require 'rabbit/parser/rd/ext/base'
10
10
  require 'rabbit/parser/rd/ext/image'
11
11
  require 'rabbit/parser/rd/ext/enscript'
12
12
  require 'rabbit/parser/rd/ext/tex'
13
+ require 'rabbit/parser/rd/ext/aafigure'
13
14
  require 'rabbit/parser/rd/ext/anthy'
14
15
 
15
16
  module Rabbit
@@ -20,6 +21,7 @@ module Rabbit
20
21
  include Image
21
22
  include Enscript
22
23
  include TeX
24
+ include AAFigure
23
25
  include Anthy
24
26
  include GetText
25
27
 
@@ -38,7 +40,26 @@ module Rabbit
38
40
  return nil unless /^(?:image|img)$/i =~ label
39
41
  src, prop = parse_source(source)
40
42
  return nil if prop['src'].nil?
41
- make_image(visitor, prop['src'], prop)
43
+
44
+ if prop['align'] == "right"
45
+ body = visitor.current_body
46
+ if body["background-image"]
47
+ raise ParseError,
48
+ _("multiple 'align = right' isn't supported.")
49
+ end
50
+ prop.each do |name, value|
51
+ name = name.gsub(/_/, '-')
52
+ if name == "src"
53
+ property_name = "background-image"
54
+ else
55
+ property_name = "background-image-#{name}"
56
+ end
57
+ body[property_name] = value
58
+ end
59
+ :no_element
60
+ else
61
+ make_image(visitor, prop['src'], prop)
62
+ end
42
63
  end
43
64
 
44
65
  def ext_block_verb_enscript(label, source, content, visitor)
@@ -62,6 +83,11 @@ module Rabbit
62
83
  make_image_by_mimeTeX(source, visitor)
63
84
  end
64
85
 
86
+ def ext_block_verb_aafigure(label, source, content, visitor)
87
+ return nil unless /^aafigure$/i =~ label
88
+ make_image_by_aafigure(source, visitor)
89
+ end
90
+
65
91
  def ext_block_verb_rt(label, source, content, visitor)
66
92
  return nil unless /^rt$/i =~ label
67
93
  unless defined?(RT2RabbitVisitor)
@@ -16,7 +16,16 @@ module Rabbit
16
16
  Inline = Parser::Ext::Inline
17
17
 
18
18
  def default_ext_inline_verbatim(label, source, content, visitor)
19
- Verbatim.new(Text.new(source))
19
+ Text.new(source)
20
+ end
21
+
22
+ def apply_inline_verbatim(visitor, text)
23
+ visitor.apply_to_Verb(::RD::Verb.new(text))
24
+ end
25
+
26
+ def apply_inline_markup(visitor, text)
27
+ tree = ::RD::RDTree.new("=begin\n#{text}\n=end\n")
28
+ TextContainer.new(tree.root.children[0].accept(visitor).elements)
20
29
  end
21
30
 
22
31
  # def ext_inline_verb_img(label, content, visitor)
@@ -32,49 +41,34 @@ module Rabbit
32
41
  def ext_inline_verb_del(label, source, content, visitor)
33
42
  label = label.to_s
34
43
  return nil unless /^del:(.*)$/ =~ label
35
- DeletedText.new(Text.new(visitor.apply_to_String($1)))
44
+ DeletedText.new(apply_inline_markup(visitor, $1))
36
45
  end
37
46
 
38
47
  def ext_inline_verb_sub(label, source, content, visitor)
39
48
  label = label.to_s
40
49
  return nil unless /^sub:(.*)$/ =~ label
41
- sub_text = $1
42
- if /\A\s*\z/ =~ sub_text
43
- sub_text = Text.new(sub_text)
44
- else
45
- sub_text = visitor.apply_to_Verb(::RD::Verb.new(sub_text))
46
- end
50
+ sub_text = apply_inline_markup(visitor, $1)
47
51
  Inline.sub(sub_text)
48
52
  end
49
53
 
50
54
  def ext_inline_verb_sup(label, source, content, visitor)
51
55
  label = label.to_s
52
56
  return nil unless /^sup:(.*)$/ =~ label
53
- sup_text = $1
54
- if /\A\s*\z/ =~ sup_text
55
- sup_text = Text.new(sup_text)
56
- else
57
- sup_text = visitor.apply_to_Verb(::RD::Verb.new(sup_text))
58
- end
57
+ sup_text = apply_inline_markup(visitor, $1)
59
58
  Inline.sup(sup_text)
60
59
  end
61
60
 
62
61
  def ext_inline_verb_note(label, source, content, visitor)
63
62
  label = label.to_s
64
63
  return nil unless /^note:(.*)$/ =~ label
65
- target = $1
66
- if /^\w+:/ =~ target
67
- target = visitor.apply_to_Verb(::RD::Verb.new(target))
68
- else
69
- target = Text.new(visitor.apply_to_String(target))
70
- end
64
+ target = apply_inline_markup(visitor, $1)
71
65
  Inline.note(target)
72
66
  end
73
67
 
74
68
  def ext_inline_verb_lang(label, source, content, visitor)
75
69
  label = label.to_s
76
70
  return nil unless /^lang:([a-z]{2,2}):(.*)$/ =~ label
77
- Inline.lang($1, Text.new(visitor.apply_to_String($2)))
71
+ Inline.lang($1, apply_inline_markup(visitor, $2))
78
72
  end
79
73
 
80
74
  def ext_inline_verb_wait(label, source, content, visitor)
@@ -89,7 +83,7 @@ module Rabbit
89
83
  name = $1
90
84
  content = $2
91
85
  if content
92
- CustomTag.new(name, Text.new(visitor.apply_to_String(content)))
86
+ CustomTag.new(name, apply_inline_markup(visitor, content))
93
87
  else
94
88
  CustomTag.new(name)
95
89
  end
@@ -59,11 +59,12 @@ module Rabbit
59
59
  mode = :ignore
60
60
  contents.each do |content|
61
61
  case content
62
+ when :no_element
63
+ next
62
64
  when nil
63
65
  mode = :ignore
64
66
  when Slide
65
- target = Body.new
66
- content << target
67
+ target = content.body
67
68
  @canvas << content
68
69
  mode = :display
69
70
  when TitleSlide
@@ -95,6 +96,7 @@ module Rabbit
95
96
  @slide = TitleSlide.new(Title.new(title))
96
97
  else
97
98
  @slide = Slide.new(HeadLine.new(title))
99
+ @slide << Body.new
98
100
  end
99
101
  @foot_texts << []
100
102
  @slides << @slide
@@ -277,6 +279,10 @@ module Rabbit
277
279
  klass.new(content.collect{|x| x.text}.join(""))
278
280
  end
279
281
 
282
+ def current_body
283
+ @slide.body
284
+ end
285
+
280
286
  private
281
287
  def prepare_footnotes(tree)
282
288
  @footnotes = tree.find_all{|i| i.is_a? ::RD::Footnote}
@@ -36,7 +36,13 @@ module Rabbit
36
36
  targets.each do |r|
37
37
  row = Element::TableRow.new
38
38
  each_cell(r) do |c|
39
- cell = cell_class.new(c.value)
39
+ tree = ::RD::RDTree.new("=begin\n#{c.value}\n=end\n")
40
+ if tree.root.children.empty?
41
+ elements = []
42
+ else
43
+ elements = tree.root.children[0].accept(@rd_visitor).elements
44
+ end
45
+ cell = cell_class.new(elements)
40
46
  setup_text_align(cell, c.align)
41
47
  row << cell
42
48
  end
@@ -5,6 +5,7 @@ require 'rabbit/parser/ext/inline'
5
5
  require 'rabbit/parser/ext/image'
6
6
  require 'rabbit/parser/ext/enscript'
7
7
  require 'rabbit/parser/ext/tex'
8
+ require 'rabbit/parser/ext/aafigure'
8
9
  require 'rabbit/parser/ext/anthy'
9
10
  require 'rabbit/parser/ext/entity'
10
11
 
@@ -47,6 +48,9 @@ module Rabbit
47
48
  []
48
49
  end
49
50
 
51
+ def current_body
52
+ @slides.last.body
53
+ end
50
54
 
51
55
  #
52
56
  # Procedures
@@ -223,8 +227,7 @@ module Rabbit
223
227
 
224
228
  @have_table_header = true
225
229
  @table_head << @parent if @parent.parent.nil?
226
- content = item.collect {|e| e.markuped_text}.join
227
- header = TableHeader.new(content)
230
+ header = TableHeader.new(item)
228
231
  def header.default_align
229
232
  Pango::Layout::ALIGN_CENTER
230
233
  end
@@ -236,8 +239,7 @@ module Rabbit
236
239
 
237
240
  @have_table_body = true
238
241
  @table_body << @parent if @parent.parent.nil?
239
- content = item.collect {|e| e.markuped_text}.join
240
- @parent << TableCell.new(content)
242
+ @parent << TableCell.new(item)
241
243
  end
242
244
 
243
245
  def blockquote_open
@@ -288,7 +290,9 @@ module Rabbit
288
290
  def block_plugin(src)
289
291
  return unless @parent
290
292
 
291
- @parent << (evaluate_block_plugin(src) || text("{{#{src}}}"))
293
+ result = evaluate_block_plugin(src)
294
+ return if result == :no_element
295
+ @parent << (result || text("{{#{src}}}"))
292
296
  end
293
297
 
294
298
 
@@ -404,6 +408,7 @@ module Rabbit
404
408
  end
405
409
 
406
410
  class BlockPlugin
411
+ include GetText
407
412
  include Element
408
413
 
409
414
  def initialize(output)
@@ -411,7 +416,23 @@ module Rabbit
411
416
  end
412
417
 
413
418
  def image(source, props={})
414
- Ext::Image.make_image(@output.canvas, source, props)
419
+ if props[:align].to_s == "right"
420
+ body = @output.current_body
421
+ if body["background-image"]
422
+ raise ParseError,
423
+ _("multiple {{image, 'XXX.png', :align => :right}} " + \
424
+ "isn't supported.")
425
+ end
426
+ body["background-image"] = source
427
+ props.each do |name, value|
428
+ name = name.to_s.gsub(/_/, '-')
429
+ value = value.to_s if name == "align"
430
+ body["background-image-#{name}"] = value
431
+ end
432
+ :no_element
433
+ else
434
+ Ext::Image.make_image(@output.canvas, source, props)
435
+ end
415
436
  end
416
437
  alias_method :img, :image
417
438
 
@@ -453,6 +474,14 @@ module Rabbit
453
474
  end
454
475
  end
455
476
  alias_method :mimetex, :mimeTeX
477
+
478
+ def aafigure(source, props={})
479
+ args = [@output.canvas, source]
480
+ Ext::Image.make_image_from_file(*args) do |src_file_path|
481
+ args = [src_file_path, props, @output.canvas]
482
+ [Ext::AAFigure.make_image_by_aafigure(*args), props]
483
+ end
484
+ end
456
485
  end
457
486
  end
458
487
  end
@@ -8,7 +8,7 @@ require "rabbit/gettext"
8
8
 
9
9
  module Rabbit
10
10
 
11
- VERSION = "0.6.4"
11
+ VERSION = "0.9.0"
12
12
 
13
13
  TMP_DIR_NAME = ".tmp"
14
14
 
@@ -84,6 +84,12 @@ module Rabbit
84
84
  end
85
85
  end
86
86
 
87
+ class AAFigureCanNotHandleError < ImageLoadWithExternalCommandError
88
+ def initialize(command, additional_info=nil)
89
+ super("aafigure", command, additional_info)
90
+ end
91
+ end
92
+
87
93
  class UnknownPropertyError < Error
88
94
  attr_reader :name
89
95
  def initialize(name)
@@ -195,9 +195,11 @@ module Rabbit
195
195
  add_widget_to_window(@window)
196
196
  widget.show
197
197
  attach_menu(@window)
198
+ attach_key(@window)
198
199
  end
199
200
 
200
201
  def detach
202
+ detach_key(@window)
201
203
  detach_menu(@window)
202
204
  widget.hide
203
205
  unless @window.destroyed?
@@ -36,6 +36,8 @@ module Rabbit
36
36
 
37
37
  def_delegators(:@pixmap, :x_dpi, :y_dpi)
38
38
 
39
+ def_delegators(:@pixmap, :set_font_resolution)
40
+
39
41
  attr_accessor :direction
40
42
 
41
43
  def width
@@ -51,7 +51,7 @@ module Rabbit
51
51
  end
52
52
 
53
53
  def filename
54
- @filename ||= "#{GLib.filename_from_utf8(@canvas.title)}.pdf"
54
+ @filename ||= default_filename
55
55
  end
56
56
 
57
57
  def draw_slide(slide, simulation)
@@ -67,6 +67,11 @@ module Rabbit
67
67
  end
68
68
  end
69
69
  end
70
+
71
+ private
72
+ def default_filename
73
+ "#{GLib.filename_from_utf8(@canvas.title.gsub(/\n/, ''))}.pdf"
74
+ end
70
75
  end
71
76
  end
72
77
  end
@@ -126,7 +126,7 @@ module Rabbit
126
126
 
127
127
  draw_order = Proc.new do |item, canvas, x, y, w, h, tw, th, layout|
128
128
  first_text = item.elements.first
129
- text_height = first_text.original_height
129
+ text_height = first_text.first_line_height
130
130
  text_height += first_text.padding_top + first_text.padding_bottom
131
131
  adjust_y = ((text_height / 2.0) - (th / 2.0)).ceil
132
132
 
@@ -0,0 +1,85 @@
1
+ def apply_background_image_property(element, options={})
2
+ proc_name = options[:proc_name] || "background-image"
3
+ compute_initial_geometry = options[:compute_initial_geometry]
4
+
5
+ element.delete_pre_draw_proc_by_name(proc_name)
6
+
7
+ if options.has_key?(:file_name)
8
+ background_image = options[:file_name]
9
+ else
10
+ background_image = element["background-image"]
11
+ background_image = canvas.full_path(background_image) if background_image
12
+ end
13
+ return if background_image.nil?
14
+
15
+ if options.has_key?(:properties)
16
+ properties = options[:properties]
17
+ else
18
+ properties = {}
19
+ element.user_property.each do |name, value|
20
+ if /\Abackground-image-/ =~ name
21
+ properties[$POSTMATCH.gsub(/-/, '_')] = value
22
+ end
23
+ end
24
+ end
25
+
26
+ image = Image.new(background_image, properties)
27
+ align = properties["align"] || "center"
28
+ vertical_align = properties["vertical_align"] || "middle"
29
+ assign_box = properties["assign_box"]
30
+ element_margin_right = 0
31
+ case align
32
+ when "center"
33
+ image.horizontal_centering = true
34
+ end
35
+ case vertical_align
36
+ when "middle"
37
+ image.vertical_centering = true
38
+ end
39
+
40
+ element.add_pre_draw_proc(proc_name) do |canvas, x, y, w, h, simulation|
41
+ if simulation
42
+ if compute_initial_geometry
43
+ _x, _y, _w, _h = compute_initial_geometry.call(canvas, x, y, w, h)
44
+ else
45
+ _x, _y, _w, _h = x, y, w, h
46
+ end
47
+
48
+ old_geometry = [_x, _y, _w, _h]
49
+ image.compile(canvas, _x, _y, _w, _h)
50
+ if image.do_vertical_centering?
51
+ adjust_height = ((_h - image.height - image.padding_bottom) / 2.0).ceil
52
+ if _y + adjust_height > 0
53
+ _y += adjust_height
54
+ _h -= adjust_height
55
+ end
56
+ end
57
+
58
+ case align
59
+ when "right"
60
+ if assign_box
61
+ element_margin_right = image.width +
62
+ image.margin_left + image.margin_right +
63
+ element.margin_right + element.padding_right
64
+ element_margin_right += element.parent.margin_right if element.parent
65
+ end
66
+ _x = _w - image.width - image.margin_right
67
+ when "center"
68
+ end
69
+
70
+ if old_geometry != [_x, _y, _w, _h]
71
+ image.compile(canvas, _x, _y, _w, _h)
72
+ end
73
+
74
+ if image.do_horizontal_centering?
75
+ image.do_horizontal_centering(canvas, _x, _y, _w, _h)
76
+ end
77
+ end
78
+ image.draw(simulation)
79
+ [x, y, w - element_margin_right, h]
80
+ end
81
+
82
+ element.add_post_draw_proc(proc_name) do |canvas, x, y, w, h, simulation|
83
+ [x, y, w + element_margin_right, h]
84
+ end
85
+ end