prune 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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,38 @@
1
+ # -*- coding:utf-8 -*-
2
+
3
+ module Prune
4
+ module Elements
5
+ class Font < Base
6
+ # Initialize.
7
+ def initialize(document, options)
8
+ super(document)
9
+ # Set dictionary.
10
+ @content = pd(pn(:Type) => pn(:Font))
11
+ @content.update(options)
12
+ # Register element to document.
13
+ register
14
+ end
15
+
16
+ # Get name of the font.
17
+ def name
18
+ @content[pn(:Name)]
19
+ end
20
+
21
+ # Set name of the font.
22
+ def name=(name)
23
+ @content[pn(:Name)] = name
24
+ end
25
+
26
+ # Set base font.
27
+ def base_font=(base_font)
28
+ @content[pn(:BaseFont)] = base_font
29
+ end
30
+
31
+ # Get encoding of the font.
32
+ def encoding
33
+ @content[pn(:Encoding)]
34
+ end
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,38 @@
1
+ # -*- coding:utf-8 -*-
2
+
3
+ module Prune
4
+ module Elements
5
+ class FontDescriptor < Base
6
+ # Initialize.
7
+ def initialize(document, options)
8
+ super(document)
9
+ # Set dictionary.
10
+ @content = pd(pn(:Type) => pn(:FontDescriptor))
11
+ @content.update(options)
12
+ # Register element to document.
13
+ register
14
+ end
15
+
16
+ # Set font name.
17
+ def font_name=(name)
18
+ @content[pn(:FontName)] = name
19
+ end
20
+
21
+ # Set italic angle.
22
+ def italic_angle=(angle)
23
+ @content[pn(:ItalicAngle)] = angle
24
+ end
25
+
26
+ # Set flags.
27
+ def flags=(flags)
28
+ @content[pn(:Flags)] = flags
29
+ end
30
+
31
+ # Set stem v.
32
+ def stem_v=(stem_v)
33
+ @content[pn(:StemV)] = stem_v
34
+ end
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,44 @@
1
+ # -*- coding:utf-8 -*-
2
+ require "date"
3
+
4
+ module Prune
5
+ module Elements
6
+ class Info < Base
7
+ # Initialize.
8
+ def initialize(document)
9
+ super(document)
10
+ date = DateTime.now
11
+ creation_date = date.strftime("D:%Y%m%d%H%M%S")
12
+ creation_date << date.zone.sub(/:/, "'") + "'"
13
+ creator = "#{APPLICATION}-#{VERSION}"
14
+ # Set dictionary.
15
+ @content = pd(
16
+ pn(:CreationDate) => pl(creation_date),
17
+ pn(:ModDate) => pl(creation_date),
18
+ pn(:Author) => pl("UNKNOWN"),
19
+ pn(:Title) => pl("UNKNOWN"),
20
+ pn(:Creator) => pl(creator),
21
+ pn(:Producer) => pl(creator),
22
+ pn(:Trapped) => pn(:False))
23
+ # Register element to document.
24
+ register
25
+ end
26
+
27
+ # Set title of the document.
28
+ def title=(title)
29
+ @content[pn(:Title)] = pl(title)
30
+ end
31
+
32
+ # Set subject of the document.
33
+ def subject=(subject)
34
+ @content[pn(:Subject)] = pl(subject)
35
+ end
36
+
37
+ # Set author of the document.
38
+ def author=(author)
39
+ @content[pn(:Author)] = pl(author)
40
+ end
41
+ end
42
+ end
43
+ end
44
+
@@ -0,0 +1,19 @@
1
+ # -*- coding:utf-8 -*-
2
+
3
+ module Prune
4
+ module Elements
5
+ class Outlines < Base
6
+ # Initialize.
7
+ def initialize(document)
8
+ super(document)
9
+ # Set dictionary.
10
+ @content = pd(
11
+ pn(:Type) => pn(:Outlines),
12
+ pn(:Count) => 0)
13
+ # Register element to document.
14
+ register
15
+ end
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,115 @@
1
+ # -*- coding:utf-8 -*-
2
+
3
+ module Prune
4
+ module Elements
5
+ class Page < Base
6
+ attr_reader :default_font
7
+ attr_accessor :shape_ids
8
+ attr_accessor :shapes
9
+ attr_accessor :x
10
+ attr_accessor :y
11
+ attr_accessor :current_font
12
+ attr_accessor :margin_left
13
+ attr_accessor :margin_right
14
+ attr_accessor :margin_top
15
+ attr_accessor :margin_bottom
16
+
17
+ FONT_OPTIONS = [
18
+ :name, # Font name.
19
+ :size, # Font size.
20
+ :bold, # Bold(boolean).
21
+ :italic, # Italic(boolean).
22
+ :mode, # Font color mode.
23
+ :fill_color, # Color inside font.
24
+ :stroke_color, # Color around font.
25
+ ] unless const_defined?(:FONT_OPTIONS)
26
+
27
+ # Initialize.
28
+ def initialize(document, media_box, options = {})
29
+ super(document)
30
+ # Set stream.
31
+ @stream = Stream.new(@document)
32
+
33
+ # Set dictionary.
34
+ @media_box = media_box
35
+ @content = pd(
36
+ pn(:Type) => pn(:Page),
37
+ pn(:Parent) => @document.pages.reference,
38
+ pn(:MediaBox) => pa(*@media_box),
39
+ pn(:Contents) => @stream.reference,
40
+ pn(:Resources) => pd(
41
+ pn(:ProcSet) => @document.proc_set.reference))
42
+
43
+ # Set page margin by option in millimeters(default 10mm).
44
+ %w[top left right bottom].each do |position|
45
+ value = options["margin_#{position}".to_sym] || 10.0
46
+ value = mm_to_pt(value)
47
+ instance_variable_set("@margin_#{position}", value)
48
+ end
49
+
50
+ # Set initial position.
51
+ @x = @margin_left
52
+ @y = @media_box[3] - @margin_top
53
+
54
+ # Set page default font.
55
+ initialize_font(options)
56
+ # Initialize page shapes.
57
+ @shape_ids = []
58
+ @shapes = {}
59
+ # Register element to document.
60
+ register
61
+ end
62
+
63
+ # Get stream object.
64
+ def stream
65
+ @stream.stream
66
+ end
67
+
68
+ # Get width of the page(pt).
69
+ def width
70
+ @media_box[2] - @margin_left - @margin_right
71
+ end
72
+
73
+ # Get height of the page(pt).
74
+ def height
75
+ @media_box[3] - @margin_top - @margin_bottom
76
+ end
77
+
78
+ # Set font to use.
79
+ def set_font(key, font)
80
+ # Add :Font key to content hash unless there is no key
81
+ unless @content[pn(:Resources)].has_key?(pn(:Font))
82
+ @content[pn(:Resources)].update(pn(:Font) => pd)
83
+ end
84
+ # Add font symbol to :Font hash
85
+ unless @content[pn(:Resources)][pn(:Font)].has_key?(key)
86
+ @content[pn(:Resources)][pn(:Font)].update(key => font.reference)
87
+ end
88
+ end
89
+
90
+ private
91
+ # Initialize font.
92
+ def initialize_font(options)
93
+ @current_font = {}
94
+ @default_font = {
95
+ :name => nil,
96
+ :size => 12,
97
+ :bold => false,
98
+ :italic => false,
99
+ :mode => :fill,
100
+ :fill_color => "#000000",
101
+ :stroke_color => "#000000"}
102
+ # Set default and current font from options.
103
+ if options.key?(:font)
104
+ FONT_OPTIONS.each do |sym|
105
+ if options[:font].key?(sym)
106
+ @default_font[sym] = options[:font][sym]
107
+ @current_font[sym] = @default_font[sym]
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+
@@ -0,0 +1,29 @@
1
+ # -*- coding:utf-8 -*-
2
+
3
+ module Prune
4
+ module Elements
5
+ class Pages < Base
6
+ # Initialize.
7
+ def initialize(document)
8
+ super(document)
9
+ @content = pd(
10
+ pn(:Type) => pn(:Pages),
11
+ pn(:Kids) => pa,
12
+ pn(:Count) => 0)
13
+ register
14
+ end
15
+
16
+ # Determine emptyness of pages.
17
+ def empty?
18
+ @content[pn(:Kids)].empty?
19
+ end
20
+
21
+ # Add page.
22
+ def <<(page)
23
+ @content[pn(:Kids)] << page.reference
24
+ @content[pn(:Count)] += 1
25
+ end
26
+ end
27
+ end
28
+ end
29
+
@@ -0,0 +1,22 @@
1
+ # -*- coding:utf-8 -*-
2
+
3
+ module Prune
4
+ module Elements
5
+ class ProcedureSets < Base
6
+ # Initialize.
7
+ def initialize(document)
8
+ super(document)
9
+ # Set dictionary.
10
+ @content = pa(
11
+ pn(:PDF),
12
+ pn(:Text),
13
+ pn(:ImageB),
14
+ pn(:ImageC),
15
+ pn(:ImageI))
16
+ # Register element to document.
17
+ register
18
+ end
19
+ end
20
+ end
21
+ end
22
+
@@ -0,0 +1,34 @@
1
+ # -*- coding:utf-8 -*-
2
+
3
+ module Prune
4
+ module Elements
5
+ class Stream < Base
6
+ attr_reader :stream
7
+
8
+ # Initialize.
9
+ def initialize(document)
10
+ super(document)
11
+ # Set dictionary.
12
+ @content = pd(pn(:Length) => 0)
13
+ # Set stream.
14
+ @stream = ps
15
+ # Register element to document.
16
+ register
17
+ end
18
+
19
+ # Convert stream to String.
20
+ def to_s
21
+ # Update length of the stream.
22
+ @content[pn(:Length)] = @stream.length
23
+ # Convert to String.
24
+ out = []
25
+ out << "#{@element_id} #{@revision} obj"
26
+ out << @content.to_s
27
+ out << @stream.to_s
28
+ out << "endobj"
29
+ return out.join(LF)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,73 @@
1
+ # -*- coding:utf-8 -*-
2
+ module Prune
3
+ module Errors
4
+ #===========================================================================
5
+ # Errors for PObjects
6
+ #===========================================================================
7
+ # PDictionary can update with only PDictionary.
8
+ class PDictionaryTypeError < StandardError;end
9
+ # PDictionary key should be PName.
10
+ class PDictionaryKeyError < StandardError;end
11
+ # PHexadecimalString's content should be a String.
12
+ class PHexadecimalStringTypeError < StandardError;end
13
+ # PHexadeciamlString's content should consist of /[0-9A-F]+/.
14
+ class PHexadecimalStringContentError < StandardError;end
15
+ # PLiteralString's content should be a String.
16
+ class PLiteralStringTypeError < StandardError;end
17
+ # PName's content should be a String or a Symbol.
18
+ class PNameTypeError < StandardError;end
19
+ # PStream's content should be a String.
20
+ class PStreamTypeError < StandardError;end
21
+
22
+ #===========================================================================
23
+ # Errors for Elements
24
+ #===========================================================================
25
+ class ElementNotRegisteredError < StandardError; end
26
+
27
+ #===========================================================================
28
+ # Errors for Fonts
29
+ #===========================================================================
30
+ # Wrong options for font.
31
+ class FontOptionError < StandardError;end
32
+ # Wrong flags for font descriptor.
33
+ class FontDescriptorFlagError < StandardError;end
34
+ # Ascii font used for non-ascii string.
35
+ class NonAsciiStringError < StandardError;end
36
+
37
+ #===========================================================================
38
+ # Errors for Shapes
39
+ #===========================================================================
40
+ class DuplicateIdError < StandardError;end
41
+ # Color format error.
42
+ class ColorFormatError < StandardError;end
43
+ # Line argument error.
44
+ class LineArgumentError < StandardError;end
45
+ # Line style error.
46
+ class LineStyleError < StandardError;end
47
+ # Rectangle argument error.
48
+ class RectangleArgumentError < StandardError;end
49
+ # Rectangle style error.
50
+ class RectangleStyleError < StandardError;end
51
+ # Unexisting font.
52
+ class UnexistingFontError < StandardError;end
53
+ # Font not Specified.
54
+ class FontNotSpecifiedError < StandardError;end
55
+ # Font mode error.
56
+ class FontModeError < StandardError;end
57
+ # Text align should be :left, :center, or :right.
58
+ class TextAlignError < StandardError;end
59
+
60
+ #===========================================================================
61
+ # Errors for Document
62
+ #===========================================================================
63
+ # Document has no pages.
64
+ class DocumentEmptyError < StandardError; end
65
+
66
+ #===========================================================================
67
+ # Errors for Parsers
68
+ #===========================================================================
69
+ # Invalid PDF version.
70
+ class PdfVersionError < StandardError;end
71
+ end
72
+ end
73
+
@@ -0,0 +1,92 @@
1
+ # -*- coding:utf-8 -*-
2
+
3
+ module Prune
4
+ module Fonts
5
+ class Base
6
+ include Errors
7
+ include PObjects
8
+ include Elements
9
+
10
+ class << self
11
+ # Check bold flag.
12
+ def bold?(options)
13
+ raise FontOptionError unless
14
+ [true, false, nil].include?(options[:bold])
15
+ options[:bold] || false
16
+ end
17
+
18
+ # Check italic flag.
19
+ def italic?(options)
20
+ raise FontOptionError unless
21
+ [true, false, nil].include?(options[:italic])
22
+ options[:italic] || false
23
+ end
24
+
25
+ # Get font name.
26
+ def font_name
27
+ class_name = self.to_s.gsub(/\A.*::/, "")
28
+ class_name.gsub(/\A(.)/){$1.downcase}.gsub(/([A-Z])/){"_#{$1.downcase}"}
29
+ end
30
+ end
31
+
32
+ attr_reader :font_name
33
+
34
+ # Initialize.
35
+ def initialize(document)
36
+ @document = document
37
+ @main_element = nil
38
+ @font_name = self.class.font_name
39
+ end
40
+
41
+ # Get reference of the font.
42
+ def reference
43
+ @main_element.reference
44
+ end
45
+
46
+ # Get name of the font.
47
+ def name
48
+ @main_element.name
49
+ end
50
+
51
+ # Get encoding of the font.
52
+ def encoding
53
+ @main_element.encoding
54
+ end
55
+
56
+ # Get font symbol.
57
+ def font_sym
58
+ @font_name.to_sym
59
+ end
60
+
61
+ private
62
+ # Check bold flags.
63
+ def bold?(options)
64
+ self.class.bold?(options)
65
+ end
66
+
67
+ # Check italic flags.
68
+ def italic?(options)
69
+ self.class.italic?(options)
70
+ end
71
+
72
+ # Calculate flags.
73
+ def calculate_flags(options = {})
74
+ raise FontDescriptorFlagError unless options.values.all?{|value|
75
+ [true, false].include?(value)
76
+ }
77
+ flags = 0b00000000000000000000000000000000
78
+ flags |= 0b00000000000000000000000000000001 if options[:fixed_pitch]
79
+ flags |= 0b00000000000000000000000000000010 if options[:serif]
80
+ flags |= 0b00000000000000000000000000000100 if options[:symbolic]
81
+ flags |= 0b00000000000000000000000000001000 if options[:script]
82
+ flags |= 0b00000000000000000000000000100000 if options[:non_symbolic]
83
+ flags |= 0b00000000000000000000000001000000 if options[:italic]
84
+ flags |= 0b00000000000000010000000000000000 if options[:all_cap]
85
+ flags |= 0b00000000000000100000000000000000 if options[:small_cap]
86
+ flags |= 0b00000000000001000000000000000000 if options[:force_bold]
87
+ flags
88
+ end
89
+ end
90
+ end
91
+ end
92
+