prune 0.0.4

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 (78) hide show
  1. data/CHANGELOG.ja.txt +16 -0
  2. data/CHANGELOG.txt +16 -0
  3. data/MIT-LICENSE.ja.txt +24 -0
  4. data/MIT-LICENSE.txt +20 -0
  5. data/Manifest.txt +77 -0
  6. data/PostInstall.txt +4 -0
  7. data/README.ja.rdoc +39 -0
  8. data/README.rdoc +39 -0
  9. data/Rakefile +28 -0
  10. data/demo/english_fonts.rb +66 -0
  11. data/demo/japanese_encodings_euc_jp.rb +27 -0
  12. data/demo/japanese_encodings_shift_jis.rb +27 -0
  13. data/demo/japanese_fonts.rb +54 -0
  14. data/demo/tables.rb +52 -0
  15. data/demo/text_decoration.rb +55 -0
  16. data/lib/prune.rb +90 -0
  17. data/lib/prune/constants.rb +39 -0
  18. data/lib/prune/document.rb +101 -0
  19. data/lib/prune/elements/base.rb +55 -0
  20. data/lib/prune/elements/catalog.rb +51 -0
  21. data/lib/prune/elements/font.rb +38 -0
  22. data/lib/prune/elements/font_descriptor.rb +38 -0
  23. data/lib/prune/elements/info.rb +44 -0
  24. data/lib/prune/elements/outlines.rb +19 -0
  25. data/lib/prune/elements/page.rb +115 -0
  26. data/lib/prune/elements/pages.rb +29 -0
  27. data/lib/prune/elements/procedure_sets.rb +22 -0
  28. data/lib/prune/elements/stream.rb +34 -0
  29. data/lib/prune/errors.rb +73 -0
  30. data/lib/prune/fonts/base.rb +92 -0
  31. data/lib/prune/fonts/base_en.rb +38 -0
  32. data/lib/prune/fonts/base_ja.rb +129 -0
  33. data/lib/prune/fonts/en/courier.rb +37 -0
  34. data/lib/prune/fonts/en/helvetica.rb +168 -0
  35. data/lib/prune/fonts/en/symbol.rb +60 -0
  36. data/lib/prune/fonts/en/times_roman.rb +168 -0
  37. data/lib/prune/fonts/en/zapf_dingbats.rb +60 -0
  38. data/lib/prune/fonts/ja/ms_gothic.rb +55 -0
  39. data/lib/prune/fonts/ja/ms_mincho.rb +55 -0
  40. data/lib/prune/fonts/ja/ms_p_gothic.rb +55 -0
  41. data/lib/prune/fonts/ja/ms_p_mincho.rb +55 -0
  42. data/lib/prune/fonts/ja/ms_pr_gothic.rb +55 -0
  43. data/lib/prune/fonts/ja/ms_ui_gothic.rb +55 -0
  44. data/lib/prune/functions.rb +18 -0
  45. data/lib/prune/p_objects/aliases.rb +37 -0
  46. data/lib/prune/p_objects/base.rb +45 -0
  47. data/lib/prune/p_objects/p_array.rb +62 -0
  48. data/lib/prune/p_objects/p_dictionary.rb +83 -0
  49. data/lib/prune/p_objects/p_hexadecimal_string.rb +27 -0
  50. data/lib/prune/p_objects/p_literal_string.rb +25 -0
  51. data/lib/prune/p_objects/p_name.rb +45 -0
  52. data/lib/prune/p_objects/p_stream.rb +29 -0
  53. data/lib/prune/parsers/base.rb +13 -0
  54. data/lib/prune/parsers/document/page/table/tr_parser.rb +77 -0
  55. data/lib/prune/parsers/document/page/table_parser.rb +32 -0
  56. data/lib/prune/parsers/document/page_parser.rb +91 -0
  57. data/lib/prune/parsers/document/property_parser.rb +45 -0
  58. data/lib/prune/parsers/document_parser.rb +26 -0
  59. data/lib/prune/shapes/base.rb +52 -0
  60. data/lib/prune/shapes/line.rb +55 -0
  61. data/lib/prune/shapes/rectangle.rb +64 -0
  62. data/lib/prune/shapes/text_box.rb +223 -0
  63. data/prune.gemspec +37 -0
  64. data/script/console +10 -0
  65. data/script/console.cmd +1 -0
  66. data/script/destroy +14 -0
  67. data/script/destroy.cmd +1 -0
  68. data/script/generate +14 -0
  69. data/script/generate.cmd +1 -0
  70. data/spec/prune/p_objects/p_array_spec.rb +46 -0
  71. data/spec/prune/p_objects/p_dictionary_spec.rb +61 -0
  72. data/spec/prune/p_objects/p_stream_spec.rb +29 -0
  73. data/spec/prune_spec.rb +38 -0
  74. data/spec/spec.opts +1 -0
  75. data/spec/spec_helper.rb +11 -0
  76. data/tasks/prune.rake +38 -0
  77. data/tasks/rspec.rake +21 -0
  78. metadata +181 -0
@@ -0,0 +1,52 @@
1
+ # -*- coding:utf-8 -*-
2
+ require "prune"
3
+
4
+ Prune.pdf("tables.pdf"){
5
+ property{
6
+ title "Tables"
7
+ subject "Demonstration document for Prune."
8
+ author "Prune"
9
+ language "ja-JP"
10
+ }
11
+
12
+ page(:A4W, :font => {:name => :ms_gothic, :size => 12}){
13
+ table(:font => {:size => 20}, :border => {:style => :solid}){
14
+ tr{
15
+ text = []
16
+ 5.times do
17
+ text << "num"
18
+ td text.join("\n")
19
+ end
20
+ }
21
+ tr{
22
+ text = []
23
+ 4.times do
24
+ text << "num"
25
+ td text.join("\n"),
26
+ :border => {:style => :dashed, :color => "#FF0000", :width => 2.0}
27
+ end
28
+ }
29
+ }
30
+
31
+ br
32
+
33
+ table(:widths => [30, 40, 50, 60, 70], :font => {:size => 20}, :border => {:style => :solid}){
34
+ tr{
35
+ text = []
36
+ 5.times do
37
+ text << "num"
38
+ td text.join("\n"), :text_align => :center
39
+ end
40
+ }
41
+ tr(:widths => [70, 50, 60, 70]){
42
+ text = []
43
+ 4.times do
44
+ text << "num"
45
+ td text.join("\n"),
46
+ :border => {:style => :dashed, :color => "#FF0000", :width => 2.0},
47
+ :text_align => :right
48
+ end
49
+ }
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,55 @@
1
+ # -*- coding:utf-8 -*-
2
+ require "prune"
3
+
4
+ Prune.pdf("text_decoration.pdf"){
5
+ property{
6
+ title "Text decoration"
7
+ subject "Demonstration document for Prune."
8
+ author "Prune"
9
+ language "ja-JP"
10
+ }
11
+
12
+ page(:A4W, :font => {:name => :ms_gothic, :size => 30}){
13
+ div "青色の文字",
14
+ :font => {:fill_color => "#0000FF"}
15
+ div "赤で縁取られた文字",
16
+ :font => {:mode => :stroke, :stroke_color => "#FF0000"}
17
+ div "緑で縁取られて\n内側が黄色の文字",
18
+ :font => {:mode => :fill_and_stroke,
19
+ :stroke_color => "#00FF00", :fill_color => "#FFFF00"}
20
+ div "赤で縁取られて\n内側が青で太字、斜体な文字",
21
+ :font => {:bold => true, :italic => true,
22
+ :font_mode => :fill_and_stroke,
23
+ :stroke_color => "#FF0000", :fill_color => "#0000FF"}
24
+ span "赤色の文字", :font => {:fill_color => "#FF0000"}
25
+ span "黄色の文字", :font => {:fill_color => "#FFFF00"}
26
+ span "青色の文字", :font => {:fill_color => "#0000FF"}
27
+ br
28
+ span "紫色の文字", :font => {:fill_color => "#800080"}
29
+ span "灰色の文字", :font => {:fill_color => "#808080"}
30
+ span "緑色の文字", :font => {:fill_color => "#008000"}
31
+ br
32
+ div "背景色が設定された文字列", :background_color => "#FFFF00"
33
+ br
34
+ div "左寄せ", :text_align => :left, :background_color => "#FF0000"
35
+ div "センタリング", :text_align => :center, :background_color => "#FFFF00"
36
+ div "右寄せ", :text_align => :right, :background_color => "#0000FF"
37
+ }
38
+ page(:A4W, :font => {:name => :ms_gothic, :size => 30}){
39
+ div "枠をつけてみる", :text_align => :center,
40
+ :border => {:style => :solid}
41
+ br
42
+ div "破線で\n枠をつけてみる", :text_align => :center,
43
+ :border => {:style => :dashed, :width => 2.0, :color => "#00FF00"}
44
+ br
45
+ div "全ての枠に\n違うスタイルを\n適用する", :text_align => :right,
46
+ :border_top => {:style => :solid, :width => 2.0, :color => "#FF0000"},
47
+ :border_left => {:style => :dashed, :width => 1.0, :color => "#00FF00"},
48
+ :border_right => {:style => :solid},
49
+ :border_bottom => {:style => :dashed, :color => "#0000FF"}
50
+ br
51
+ span "30mm", :width => 300, :border_bottom => {:style => :solid}
52
+ span "40mm", :width => 400
53
+ span "50mm", :width => 500, :border_bottom => {:style => :solid}
54
+ }
55
+ }
@@ -0,0 +1,90 @@
1
+ # -*- coding:utf-8 -*-
2
+
3
+ # Path of the library.
4
+ prune_path = File.join(File.dirname(__FILE__), "prune")
5
+ prune_fullpath = File.expand_path(prune_path)
6
+
7
+ # Add to the load path of ruby.
8
+ $:.unshift(prune_path) unless
9
+ $:.include?(prune_path) || $:.include?(prune_fullpath)
10
+
11
+ # Constants.
12
+ require "constants"
13
+
14
+ # Errors.
15
+ require "errors"
16
+
17
+ # PDF functions.
18
+ require "functions"
19
+
20
+ # PDF objects.
21
+ require "p_objects/base"
22
+ require "p_objects/p_hexadecimal_string"
23
+ require "p_objects/p_literal_string"
24
+ require "p_objects/p_name"
25
+ require "p_objects/p_stream"
26
+ require "p_objects/p_array"
27
+ require "p_objects/p_dictionary"
28
+ require "p_objects/aliases"
29
+
30
+ # PDF elements.
31
+ require "elements/base"
32
+ require "elements/catalog"
33
+ require "elements/font"
34
+ require "elements/font_descriptor"
35
+ require "elements/info"
36
+ require "elements/outlines"
37
+ require "elements/page"
38
+ require "elements/pages"
39
+ require "elements/procedure_sets"
40
+ require "elements/stream"
41
+
42
+ # fonts
43
+ require "fonts/base"
44
+ require "fonts/base_en"
45
+ require "fonts/en/courier"
46
+ require "fonts/en/helvetica"
47
+ require "fonts/en/symbol"
48
+ require "fonts/en/times_roman"
49
+ require "fonts/en/zapf_dingbats"
50
+ require "fonts/base_ja"
51
+ require "fonts/ja/ms_gothic"
52
+ require "fonts/ja/ms_mincho"
53
+ require "fonts/ja/ms_p_gothic"
54
+ require "fonts/ja/ms_p_mincho"
55
+ require "fonts/ja/ms_pr_gothic"
56
+ require "fonts/ja/ms_ui_gothic"
57
+
58
+ # PDF document.
59
+ require "document"
60
+
61
+ # Shapes.
62
+ require "shapes/base"
63
+ require "shapes/line"
64
+ require "shapes/rectangle"
65
+ require "shapes/text_box"
66
+
67
+ # DSL parser.
68
+ require "parsers/base"
69
+ require "parsers/document/property_parser"
70
+ require "parsers/document/page/table/tr_parser"
71
+ require "parsers/document/page/table_parser"
72
+ require "parsers/document/page_parser"
73
+ require "parsers/document_parser"
74
+
75
+ module Prune
76
+ def self.pdf(filename = nil, &block)
77
+ # Build document.
78
+ @document = Document.new
79
+ @document_parser = Parsers::DocumentParser.new(@document)
80
+ @document_parser.instance_eval(&block)
81
+
82
+ unless filename.nil?
83
+ filename << ".pdf" unless /\.[pP][dD][fF]\z/ === filename
84
+ @document.save_as(filename)
85
+ else
86
+ @document.to_s
87
+ end
88
+ end
89
+ end
90
+
@@ -0,0 +1,39 @@
1
+ # -*- coding:utf-8 -*-
2
+
3
+ module Prune
4
+ # Version of Prune.
5
+ VERSION = "0.0.4" unless const_defined?(:VERSION)
6
+
7
+ # Application name.
8
+ APPLICATION = self.name unless const_defined?(:APPLICATION)
9
+
10
+ # Line feed code.
11
+ LF = "\n" unless const_defined?(:LF)
12
+
13
+ # Document sizes(width and height in milli-meters).
14
+ DOCUMENT_SIZES = {
15
+ :A1 => [594.0, 841.0], :A1W => [ 841.0, 594.0],
16
+ :A2 => [420.0, 594.0], :A2W => [ 594.0, 420.0],
17
+ :A3 => [297.0, 420.0], :A3W => [ 420.0, 297.0],
18
+ :A4 => [210.0, 297.0], :A4W => [ 297.0, 210.0],
19
+ :A5 => [148.0, 210.0], :A5W => [ 210.0, 148.0],
20
+ :A6 => [105.0, 148.0], :A6W => [ 148.0, 105.0],
21
+ :A7 => [ 74.0, 105.0], :A7W => [ 105.0, 74.0],
22
+ :B1 => [728.0, 1030.0], :B1W => [1030.0, 728.0],
23
+ :B2 => [515.0, 728.0], :B2W => [ 728.0, 515.0],
24
+ :B3 => [364.0, 515.0], :B3W => [ 515.0, 364.0],
25
+ :B4 => [257.0, 364.0], :B4W => [ 364.0, 257.0],
26
+ :B5 => [182.0, 257.0], :B5W => [ 257.0, 182.0],
27
+ :B6 => [128.0, 182.0], :B6W => [ 182.0, 128.0],
28
+ :B7 => [ 91.0, 128.0], :B7W => [ 128.0, 91.0],
29
+ } unless const_defined?(:DOCUMENT_SIZES)
30
+
31
+ # Page layout
32
+ PAGE_LAYOUT = [
33
+ :SinglePage,
34
+ :OneColumn,
35
+ :TwoColumnLeft,
36
+ :TwoColumnRight
37
+ ] unless const_defined?(:PAGE_LAYOUT)
38
+ end
39
+
@@ -0,0 +1,101 @@
1
+ # -*- coding:utf-8 -*-
2
+ require "digest/md5"
3
+
4
+ module Prune
5
+ class Document
6
+ include Errors
7
+ include PObjects
8
+ include Elements
9
+
10
+ attr_reader :catalog, :pages, :outlines, :info, :proc_set
11
+ attr_reader :fonts, :elements
12
+ attr_writer :version
13
+
14
+ # Initialize
15
+ def initialize
16
+ @elements = []
17
+ @fonts = {}
18
+ @version = "1.2"
19
+
20
+ # Initialize PDF infos.
21
+ @info = Info.new(self)
22
+
23
+ # Initialize catalog.
24
+ @catalog = Catalog.new(self)
25
+ @catalog.version = @version
26
+
27
+ # Initialize outlines.
28
+ outlines = Outlines.new(self)
29
+ @catalog.outlines = outlines.reference
30
+
31
+ # Initialize pages.
32
+ @pages = Pages.new(self)
33
+ @catalog.pages = @pages.reference
34
+
35
+ # Initialize ProcSet
36
+ @proc_set = Elements::ProcedureSets.new(self)
37
+ end
38
+
39
+ # Save pdf document to a file.
40
+ def save_as(filename)
41
+ raise DocumentEmptyError if @pages.empty?
42
+ # Write to a file
43
+ File.open(filename, "wb") do |file|
44
+ file.flock(File::LOCK_EX)
45
+ file.write(self.to_s)
46
+ file.flock(File::LOCK_UN)
47
+ end
48
+ end
49
+
50
+ # Convert to String.
51
+ def to_s
52
+ # Write header
53
+ out = []
54
+ out << "%PDF-#{@version}"
55
+ out << "%" + [0xE2, 0xE3, 0xCF, 0xD3].pack("c*")
56
+ # Write objects
57
+ out += @elements.collect{|element| element.to_s}
58
+ # Write cross-reference table
59
+ out += cross_reference_table(@elements.size, out.join(LF))
60
+ # Write trailer
61
+ out += trailer(out.join(LF))
62
+ out << "%%EOF"
63
+ out.join(LF)
64
+ end
65
+
66
+ private
67
+ def cross_reference_table(objects, source)
68
+ out = []
69
+ out << "xref"
70
+ out << "0 %d" % (objects + 1)
71
+ out << "0000000000 65535 f"
72
+ # オフセットの計算
73
+ pos = 0
74
+ while index = source.index(/^\d+ \d+ obj/, pos)
75
+ out << "%010d %05d %s" % [index, 0, "n"]
76
+ pos = index + 1
77
+ end
78
+ out
79
+ end
80
+
81
+ def trailer(source)
82
+ out = []
83
+ id = Digest::MD5.hexdigest(rand.to_s)
84
+ out << "trailer"
85
+ dict = pd(
86
+ pn(:Size) => (@elements.size + 1),
87
+ pn(:Root) => @catalog.reference,
88
+ pn(:Info) => @info.reference,
89
+ pn(:ID) => pa(ph(id), ph(id)))
90
+ out << dict.to_s
91
+ out << "startxref"
92
+ out << source.index("xref")
93
+ out
94
+ end
95
+
96
+ def inspect
97
+ self.to_s
98
+ end
99
+ end
100
+ end
101
+
@@ -0,0 +1,55 @@
1
+ # -*- coding:utf-8 -*-
2
+
3
+ module Prune
4
+ module Elements
5
+ class Base
6
+ include Errors
7
+ include PObjects
8
+ include Functions
9
+
10
+ attr_reader :document
11
+
12
+ # Initialize.
13
+ def initialize(document)
14
+ @document = document
15
+ @element_id = 0
16
+ @revision = 0
17
+ @content = nil
18
+ @stream = nil
19
+ @registered = false
20
+ end
21
+
22
+ # Convert element to String.
23
+ def to_s
24
+ raise ElementNotRegisteredError unless @registered
25
+ out = []
26
+ out << "%d %d obj" % [@element_id, @revision]
27
+ out << @content.to_s
28
+ out << "endobj"
29
+ return out.join(LF)
30
+ end
31
+
32
+ # Get reference id of the element.
33
+ def reference
34
+ raise ObjectNotRegisteredError unless @registered
35
+ "#{@element_id} #{@revision} R"
36
+ end
37
+
38
+ # Register element to document.
39
+ def register
40
+ unless @registered
41
+ @element_id = @document.elements.size + 1
42
+ @document.elements << self
43
+ @registered = true
44
+ end
45
+ end
46
+
47
+ private
48
+ # Set text for "p" method.
49
+ def inspect
50
+ self.to_s
51
+ end
52
+ end
53
+ end
54
+ end
55
+
@@ -0,0 +1,51 @@
1
+ # -*- coding:utf-8 -*-
2
+
3
+ module Prune
4
+ module Elements
5
+ class Catalog < Base
6
+ include Prune
7
+
8
+ # Initialize.
9
+ def initialize(document)
10
+ super(document)
11
+ # Set dictionary.
12
+ @content = pd(
13
+ pn(:Type) => pn(:Catalog),
14
+ pn(:PageLayout) => pn(:SinglePage),
15
+ pn(:Lang) => pl("ja-JP"),
16
+ pn(:ViewerPreferences) => pd(
17
+ pn(:FitWindow) => true))
18
+ # Register element to document.
19
+ register
20
+ end
21
+
22
+ # Set reference to outlines.
23
+ def outlines=(reference)
24
+ @content.update(pn(:Outlines) => reference)
25
+ end
26
+
27
+ # Set page layout.
28
+ def page_layout=(layout)
29
+ if PAGE_LAYOUTS.include?(layout)
30
+ @content.update(pn(:PageLayout) => layout)
31
+ end
32
+ end
33
+
34
+ # Set lang.
35
+ def lang=(lang)
36
+ @content[pn(:Lang)] = lang
37
+ end
38
+
39
+ # Set pdf version.
40
+ def version=(version)
41
+ @content[pn(:Version)] = version
42
+ end
43
+
44
+ # Set reference to pages.
45
+ def pages=(pages)
46
+ @content[pn(:Pages)] = pages
47
+ end
48
+ end
49
+ end
50
+ end
51
+