Class: PDF::Reader::Parser
- Inherits:
-
Object
- Object
- PDF::Reader::Parser
- Defined in:
- lib/pdf/reader/parser.rb
Overview
An internal PDF::Reader class that reads objects from the PDF file and converts them into useable ruby objects (hash's, arrays, true, false, etc)
Constant Summary collapse
- TOKEN_STRATEGY =
: Proc
proc { |parser, token| Token.new(token) }
- INTERNED_TOKENS =
: Hash[String, PDF::Reader::Token]
{}
- STRATEGIES =
{ "/" => proc { |parser, token| parser.send(:pdf_name) }, "<<" => proc { |parser, token| parser.send(:dictionary) }, "[" => proc { |parser, token| parser.send(:array) }, "(" => proc { |parser, token| parser.send(:string) }, "<" => proc { |parser, token| parser.send(:hex_string) }, nil => proc { nil }, "true" => proc { true }, "false" => proc { false }, "null" => proc { nil }, "obj" => TOKEN_STRATEGY, "endobj" => TOKEN_STRATEGY, "stream" => TOKEN_STRATEGY, "endstream" => TOKEN_STRATEGY, ">>" => TOKEN_STRATEGY, "]" => TOKEN_STRATEGY, ">" => TOKEN_STRATEGY, ")" => TOKEN_STRATEGY }
Instance Method Summary collapse
-
#initialize(buffer, operators: {}, objects: nil, relaxed_dictionaries: false) ⇒ Parser
constructor
Create a new parser around a PDF::Reader::Buffer object.
-
#object(id, gen) ⇒ Object
Reads an entire PDF object from the buffer and returns it as a Ruby String.
-
#parse_token ⇒ Object
Reads the next token from the underlying buffer and convets it to an appropriate object.
Constructor Details
#initialize(buffer, operators: {}, objects: nil, relaxed_dictionaries: false) ⇒ Parser
Create a new parser around a PDF::Reader::Buffer object
buffer - a PDF::Reader::Buffer object that contains PDF data objects - a PDF::Reader::ObjectHash object that can return objects from the PDF file operators - a hash of supported operators to read from the underlying buffer. relaxed_dictionaries - quietly skip unexpected operator tokens inside a dictionary. Useful for handling Postscript dictionaries in CMaps
: ( | PDF::Reader::Buffer, | ?operators: Hash[String | PDF::Reader::Token, Symbol], | ?objects: PDF::Reader::ObjectHash?, | ?relaxed_dictionaries: T::Boolean | ) -> void
76 77 78 79 80 81 82 |
# File 'lib/pdf/reader/parser.rb', line 76 def initialize(buffer, operators: {}, objects: nil, relaxed_dictionaries: false) @buffer = buffer @operators = operators @objects = objects @relaxed_dictionaries = relaxed_dictionaries @hex_pack_buffer = [""] #: Array[String] end |
Instance Method Details
#object(id, gen) ⇒ Object
Reads an entire PDF object from the buffer and returns it as a Ruby String. If the object is a content stream, returns both the stream and the dictionary that describes it
id - the object ID to return gen - the object revision number to return : (Integer, Integer) -> ( | PDF::Reader::Reference | | PDF::Reader::Token | | PDF::Reader::Stream | | Numeric | | String | | Symbol | | Array | | Hash[untyped, untyped] | | nil | )
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/pdf/reader/parser.rb', line 135 def object(id, gen) idCheck = parse_token # Sometimes the xref table is corrupt and points to an offset slightly too early in the file. # check the next token, maybe we can find the start of the object we're looking for if idCheck != id Error.assert_equal(parse_token, id) end Error.assert_equal(parse_token, gen) Error.str_assert(parse_token, "obj") obj = parse_token post_obj = parse_token if obj.is_a?(Hash) && post_obj == "stream" stream(obj) else obj end end |
#parse_token ⇒ Object
Reads the next token from the underlying buffer and convets it to an appropriate object
: () -> ( | PDF::Reader::Reference | | PDF::Reader::Token | | Numeric | | String | | Symbol | | Array | | Hash[untyped, untyped] | | nil | )
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/pdf/reader/parser.rb', line 97 def parse_token token = @buffer.token if token.nil? nil elsif token.is_a?(String) && STRATEGIES.has_key?(token) proc = STRATEGIES[token] proc.call(self, token) if proc elsif token.is_a? PDF::Reader::Reference token elsif @operators.has_key? token INTERNED_TOKENS[token] ||= Token.new(token) elsif token.frozen? token elsif match?(token, /\d*\.\d/) token.to_f else token.to_i end end |