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.
- data/CHANGELOG.ja.txt +16 -0
- data/CHANGELOG.txt +16 -0
- data/MIT-LICENSE.ja.txt +24 -0
- data/MIT-LICENSE.txt +20 -0
- data/Manifest.txt +77 -0
- data/PostInstall.txt +4 -0
- data/README.ja.rdoc +39 -0
- data/README.rdoc +39 -0
- data/Rakefile +28 -0
- data/demo/english_fonts.rb +66 -0
- data/demo/japanese_encodings_euc_jp.rb +27 -0
- data/demo/japanese_encodings_shift_jis.rb +27 -0
- data/demo/japanese_fonts.rb +54 -0
- data/demo/tables.rb +52 -0
- data/demo/text_decoration.rb +55 -0
- data/lib/prune.rb +90 -0
- data/lib/prune/constants.rb +39 -0
- data/lib/prune/document.rb +101 -0
- data/lib/prune/elements/base.rb +55 -0
- data/lib/prune/elements/catalog.rb +51 -0
- data/lib/prune/elements/font.rb +38 -0
- data/lib/prune/elements/font_descriptor.rb +38 -0
- data/lib/prune/elements/info.rb +44 -0
- data/lib/prune/elements/outlines.rb +19 -0
- data/lib/prune/elements/page.rb +115 -0
- data/lib/prune/elements/pages.rb +29 -0
- data/lib/prune/elements/procedure_sets.rb +22 -0
- data/lib/prune/elements/stream.rb +34 -0
- data/lib/prune/errors.rb +73 -0
- data/lib/prune/fonts/base.rb +92 -0
- data/lib/prune/fonts/base_en.rb +38 -0
- data/lib/prune/fonts/base_ja.rb +129 -0
- data/lib/prune/fonts/en/courier.rb +37 -0
- data/lib/prune/fonts/en/helvetica.rb +168 -0
- data/lib/prune/fonts/en/symbol.rb +60 -0
- data/lib/prune/fonts/en/times_roman.rb +168 -0
- data/lib/prune/fonts/en/zapf_dingbats.rb +60 -0
- data/lib/prune/fonts/ja/ms_gothic.rb +55 -0
- data/lib/prune/fonts/ja/ms_mincho.rb +55 -0
- data/lib/prune/fonts/ja/ms_p_gothic.rb +55 -0
- data/lib/prune/fonts/ja/ms_p_mincho.rb +55 -0
- data/lib/prune/fonts/ja/ms_pr_gothic.rb +55 -0
- data/lib/prune/fonts/ja/ms_ui_gothic.rb +55 -0
- data/lib/prune/functions.rb +18 -0
- data/lib/prune/p_objects/aliases.rb +37 -0
- data/lib/prune/p_objects/base.rb +45 -0
- data/lib/prune/p_objects/p_array.rb +62 -0
- data/lib/prune/p_objects/p_dictionary.rb +83 -0
- data/lib/prune/p_objects/p_hexadecimal_string.rb +27 -0
- data/lib/prune/p_objects/p_literal_string.rb +25 -0
- data/lib/prune/p_objects/p_name.rb +45 -0
- data/lib/prune/p_objects/p_stream.rb +29 -0
- data/lib/prune/parsers/base.rb +13 -0
- data/lib/prune/parsers/document/page/table/tr_parser.rb +77 -0
- data/lib/prune/parsers/document/page/table_parser.rb +32 -0
- data/lib/prune/parsers/document/page_parser.rb +91 -0
- data/lib/prune/parsers/document/property_parser.rb +45 -0
- data/lib/prune/parsers/document_parser.rb +26 -0
- data/lib/prune/shapes/base.rb +52 -0
- data/lib/prune/shapes/line.rb +55 -0
- data/lib/prune/shapes/rectangle.rb +64 -0
- data/lib/prune/shapes/text_box.rb +223 -0
- data/prune.gemspec +37 -0
- data/script/console +10 -0
- data/script/console.cmd +1 -0
- data/script/destroy +14 -0
- data/script/destroy.cmd +1 -0
- data/script/generate +14 -0
- data/script/generate.cmd +1 -0
- data/spec/prune/p_objects/p_array_spec.rb +46 -0
- data/spec/prune/p_objects/p_dictionary_spec.rb +61 -0
- data/spec/prune/p_objects/p_stream_spec.rb +29 -0
- data/spec/prune_spec.rb +38 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +11 -0
- data/tasks/prune.rake +38 -0
- data/tasks/rspec.rake +21 -0
- metadata +181 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
|
3
|
+
module Prune
|
4
|
+
module PObjects
|
5
|
+
class Base
|
6
|
+
include Errors
|
7
|
+
|
8
|
+
# Indent.
|
9
|
+
@@indent = 0
|
10
|
+
|
11
|
+
def space
|
12
|
+
" " * @@indent
|
13
|
+
end
|
14
|
+
|
15
|
+
def indent!
|
16
|
+
@@indent += 1
|
17
|
+
end
|
18
|
+
|
19
|
+
def outdent!
|
20
|
+
@@indent -= 1
|
21
|
+
end
|
22
|
+
|
23
|
+
def value_to_s(value)
|
24
|
+
case value
|
25
|
+
when String
|
26
|
+
return value
|
27
|
+
when PName, PLiteralString, PHexadecimalString
|
28
|
+
return value.to_s
|
29
|
+
when PArray, PDictionary
|
30
|
+
indent!
|
31
|
+
out = LF + space + value.to_s
|
32
|
+
outdent!
|
33
|
+
return out
|
34
|
+
else
|
35
|
+
if value.is_a?(Prune::Elements::Base)
|
36
|
+
return value.reference_id
|
37
|
+
else
|
38
|
+
return value.to_s
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
|
3
|
+
module Prune
|
4
|
+
module PObjects
|
5
|
+
class PArray < Base
|
6
|
+
# Size to line feed when converted to String.
|
7
|
+
LF_SIZE = 10 unless const_defined?(:LF_SIZE)
|
8
|
+
|
9
|
+
# Initialize.
|
10
|
+
def initialize(*args)
|
11
|
+
@array = args
|
12
|
+
end
|
13
|
+
|
14
|
+
def empty?
|
15
|
+
@array.empty?
|
16
|
+
end
|
17
|
+
|
18
|
+
def <<(value)
|
19
|
+
@array << value
|
20
|
+
end
|
21
|
+
|
22
|
+
def [](key)
|
23
|
+
@array[key]
|
24
|
+
end
|
25
|
+
|
26
|
+
def []=(key, value)
|
27
|
+
@array[key] = value
|
28
|
+
end
|
29
|
+
|
30
|
+
def size
|
31
|
+
@array.size
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
unless self.empty?
|
36
|
+
# 配列が空でない場合
|
37
|
+
if @array.size > LF_SIZE
|
38
|
+
# 配列長がLF_SIZEを越える場合
|
39
|
+
head = @array[0, LF_SIZE]
|
40
|
+
tail = @array[LF_SIZE, @array.size]
|
41
|
+
out = []
|
42
|
+
out << "[ %s" % head.collect{|item| value_to_s(item)}.join(" ")
|
43
|
+
indent!
|
44
|
+
tail.each_slice(LF_SIZE){|slice|
|
45
|
+
out << space + slice.collect{|item| value_to_s(item)}.join(" ")
|
46
|
+
}
|
47
|
+
outdent!
|
48
|
+
out[out.size - 1] += " ]"
|
49
|
+
out.join(LF)
|
50
|
+
else
|
51
|
+
# 配列長がLF_SIZE以下の場合
|
52
|
+
"[ %s ]" % @array.collect{|item| value_to_s(item)}.join(" ")
|
53
|
+
end
|
54
|
+
else
|
55
|
+
# 配列が空の場合
|
56
|
+
"[ ]"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
|
3
|
+
module Prune
|
4
|
+
module PObjects
|
5
|
+
class PDictionary < Base
|
6
|
+
attr_reader :dict
|
7
|
+
|
8
|
+
def initialize(pd = {})
|
9
|
+
@dict = {}
|
10
|
+
@dict.update(pd)
|
11
|
+
end
|
12
|
+
|
13
|
+
def empty?
|
14
|
+
return @dict.empty?
|
15
|
+
end
|
16
|
+
|
17
|
+
def [](key)
|
18
|
+
@dict[key]
|
19
|
+
end
|
20
|
+
|
21
|
+
def []=(key, value)
|
22
|
+
self.update(key => value)
|
23
|
+
end
|
24
|
+
|
25
|
+
def update(pd)
|
26
|
+
case pd
|
27
|
+
when PDictionary
|
28
|
+
raise PDictionaryKeyError unless pd.keys.all?{|key|
|
29
|
+
key.instance_of?(PName)
|
30
|
+
}
|
31
|
+
@dict.update(pd.dict)
|
32
|
+
when Hash
|
33
|
+
raise PDictionaryKeyError unless pd.keys.all?{|key|
|
34
|
+
key.instance_of?(PName)
|
35
|
+
}
|
36
|
+
@dict.update(pd)
|
37
|
+
else
|
38
|
+
raise PDictionaryTypeError
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def has_key?(key)
|
43
|
+
@dict.has_key?(key)
|
44
|
+
end
|
45
|
+
|
46
|
+
def keys
|
47
|
+
keys = @dict.keys.sort_by{|key| key.to_s}
|
48
|
+
type_key = PName.new(:Type)
|
49
|
+
keys.unshift(type_key) if keys.delete(type_key)
|
50
|
+
keys
|
51
|
+
end
|
52
|
+
|
53
|
+
def size
|
54
|
+
@dict.size
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_s
|
58
|
+
case self.size
|
59
|
+
when 0
|
60
|
+
"<< >>"
|
61
|
+
when 1
|
62
|
+
"<< %s >>" % pair_to_s(self.keys.first)
|
63
|
+
else
|
64
|
+
out = []
|
65
|
+
out << "<<"
|
66
|
+
indent!
|
67
|
+
self.keys.each{|key|
|
68
|
+
out << space + pair_to_s(key)
|
69
|
+
}
|
70
|
+
outdent!
|
71
|
+
out << space + ">>"
|
72
|
+
out.join(LF)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
def pair_to_s(key)
|
78
|
+
"%s %s" % [value_to_s(key), value_to_s(self[key])]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
|
3
|
+
module Prune
|
4
|
+
module PObjects
|
5
|
+
class PHexadecimalString < Base
|
6
|
+
attr_reader :string
|
7
|
+
|
8
|
+
def initialize(string)
|
9
|
+
raise PHexadecimalStringTypeError unless
|
10
|
+
string.instance_of?(String)
|
11
|
+
@string = string.upcase
|
12
|
+
raise PHexadecimalStringContentError unless
|
13
|
+
/[0-9A-F]+/ === @string
|
14
|
+
end
|
15
|
+
|
16
|
+
def ==(value)
|
17
|
+
false unless value.instance_of?(self.class)
|
18
|
+
@string == value.string
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
"<#{@string}>"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
|
3
|
+
module Prune
|
4
|
+
module PObjects
|
5
|
+
class PLiteralString < Base
|
6
|
+
attr_reader :string
|
7
|
+
|
8
|
+
def initialize(string)
|
9
|
+
raise PLiteralStringTypeError unless
|
10
|
+
string.instance_of?(String)
|
11
|
+
@string = string
|
12
|
+
end
|
13
|
+
|
14
|
+
def ==(value)
|
15
|
+
false unless value.instance_of?(self.class)
|
16
|
+
@string == value.string
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
"(#{@string})"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
|
3
|
+
module Prune
|
4
|
+
module PObjects
|
5
|
+
class PName < Base
|
6
|
+
attr_reader :name
|
7
|
+
|
8
|
+
# Initialize.
|
9
|
+
def initialize(name)
|
10
|
+
case name
|
11
|
+
when String
|
12
|
+
@name = "/" + name
|
13
|
+
when Symbol
|
14
|
+
@name = "/" + name.to_s
|
15
|
+
else
|
16
|
+
raise PNameTypeError
|
17
|
+
end
|
18
|
+
@name.freeze
|
19
|
+
end
|
20
|
+
|
21
|
+
# Calculate hash value for PName.
|
22
|
+
def hash
|
23
|
+
@name.hash
|
24
|
+
end
|
25
|
+
|
26
|
+
# Compare as a key of hash.
|
27
|
+
def eql?(value)
|
28
|
+
false if value.instance_of?(self.class)
|
29
|
+
@name.eql?(value.name)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Compare the value of string.
|
33
|
+
def ==(value)
|
34
|
+
false if value.instance_of?(self.class)
|
35
|
+
@name == value.name
|
36
|
+
end
|
37
|
+
|
38
|
+
# Convert content to string.
|
39
|
+
def to_s
|
40
|
+
@name
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
|
3
|
+
module Prune
|
4
|
+
module PObjects
|
5
|
+
class PStream < Base
|
6
|
+
# Initialize.
|
7
|
+
def initialize
|
8
|
+
@stream = []
|
9
|
+
end
|
10
|
+
|
11
|
+
# Add content.
|
12
|
+
def <<(text)
|
13
|
+
raise PStreamTypeError unless text.instance_of?(String)
|
14
|
+
@stream << text
|
15
|
+
end
|
16
|
+
|
17
|
+
# Length of the content.
|
18
|
+
def length
|
19
|
+
self.to_s.size
|
20
|
+
end
|
21
|
+
|
22
|
+
# Convert content to string.
|
23
|
+
def to_s
|
24
|
+
["stream", @stream, "endstream"].flatten.join(LF)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
|
3
|
+
module Prune
|
4
|
+
module Parsers
|
5
|
+
# Parser for directive "tr".
|
6
|
+
class TrParser < Base
|
7
|
+
attr_reader :x
|
8
|
+
attr_reader :y
|
9
|
+
attr_reader :width
|
10
|
+
attr_reader :height
|
11
|
+
|
12
|
+
# Initialize.
|
13
|
+
def initialize(table, options = {})
|
14
|
+
@table = table
|
15
|
+
@options = options
|
16
|
+
# Boundary of this object.
|
17
|
+
@x = @table.page.x
|
18
|
+
@y = @table.page.y
|
19
|
+
@width = 0.0
|
20
|
+
@height = 0.0
|
21
|
+
@widths = options[:widths] || @table.options[:widths] || []
|
22
|
+
|
23
|
+
# All td tags inside this tag.
|
24
|
+
@tds = []
|
25
|
+
end
|
26
|
+
|
27
|
+
# Render td tags.
|
28
|
+
def render
|
29
|
+
prev_td = nil
|
30
|
+
orig_x = @table.page.x
|
31
|
+
orig_y = @table.page.y
|
32
|
+
|
33
|
+
# Get width of the table line.
|
34
|
+
@width = @tds.inject(0.0){|result, td| result += td.width}
|
35
|
+
# Get the highest column height and set it to all columns.
|
36
|
+
@height = @tds.sort_by{|td| td.height}[-1].height
|
37
|
+
|
38
|
+
# Render each td tags.
|
39
|
+
@tds.each_with_index do |td, index|
|
40
|
+
# Set td height to highest.
|
41
|
+
td.height = @height
|
42
|
+
# Set x of the page.
|
43
|
+
unless prev_td.nil?
|
44
|
+
td.x = prev_td.x + prev_td.width
|
45
|
+
@table.page.x = td.x
|
46
|
+
end
|
47
|
+
prev_td = td
|
48
|
+
td.render
|
49
|
+
end
|
50
|
+
|
51
|
+
# Set x,y to next line position.
|
52
|
+
@table.page.x = orig_x
|
53
|
+
@table.page.y = orig_y - @height
|
54
|
+
end
|
55
|
+
|
56
|
+
protected
|
57
|
+
# Td tag.
|
58
|
+
def td(string, options = {})
|
59
|
+
# Set width.
|
60
|
+
width = @widths[@tds.size]
|
61
|
+
options[:width] = mm_to_pt(width) unless width.nil?
|
62
|
+
# Set height.
|
63
|
+
unless options[:height].nil?
|
64
|
+
options[:height] = mm_to_pt(options[:height])
|
65
|
+
end
|
66
|
+
|
67
|
+
# Initialize text box.
|
68
|
+
td = Shapes::TextBox.new(@table.page, string, @options.merge(options))
|
69
|
+
|
70
|
+
# Set width and height for tr tag.
|
71
|
+
@tds << td
|
72
|
+
td
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
|
3
|
+
module Prune
|
4
|
+
module Parsers
|
5
|
+
# Parser for directive "table".
|
6
|
+
class TableParser < Base
|
7
|
+
attr_reader :page
|
8
|
+
attr_reader :options
|
9
|
+
|
10
|
+
# Initialize.
|
11
|
+
def initialize(page, options = {})
|
12
|
+
@page = page
|
13
|
+
@options = options
|
14
|
+
@x = @orig_x = @page.x
|
15
|
+
@y = @orig_y = @page.y
|
16
|
+
@width = 0.0
|
17
|
+
@height = 0.0
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
# Tr tag.
|
22
|
+
def tr(options = {}, &block)
|
23
|
+
tr_parser = TrParser.new(self, @options.merge(options))
|
24
|
+
tr_parser.instance_eval(&block)
|
25
|
+
@page.x = @orig_x
|
26
|
+
@page.y -= tr_parser.height
|
27
|
+
tr_parser.render
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|