rabbit 0.6.4 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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