Class: BibTeX::Lexer
- Inherits:
-
Object
- Object
- BibTeX::Lexer
- Extended by:
- Forwardable
- Defined in:
- lib/bibtex/lexer.rb
Overview
The BibTeX::Lexer handles the lexical analysis of BibTeX bibliographies.
Constant Summary collapse
- MODE =
Hash.new(:meta).merge({ :bibtex => :bibtex, :entry => :bibtex, :string => :bibtex, :preamble => :bibtex, :comment => :bibtex, :meta => :meta, :literal => :literal, :content => :content }).freeze
Class Attribute Summary collapse
-
.defaults ⇒ Object
readonly
Returns the value of attribute defaults.
-
.patterns ⇒ Object
readonly
Returns the value of attribute patterns.
Instance Attribute Summary collapse
-
#mode ⇒ Object
Returns the value of attribute mode.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#scanner ⇒ Object
readonly
Returns the value of attribute scanner.
-
#stack ⇒ Object
readonly
Returns the value of attribute stack.
Instance Method Summary collapse
-
#active?(object) ⇒ Boolean
Returns true if the lexer is currently parsing the given object type.
- #allow_missing_keys? ⇒ Boolean
-
#analyse(string = nil) ⇒ Object
Start the lexical analysis.
-
#bibtex_mode? ⇒ Boolean
Returns true if the lexer is currenty parsing a BibTeX object.
-
#data=(data) ⇒ Object
Sets the source for the lexical analysis and resets the internal state.
-
#initialize(options = {}) ⇒ Lexer
constructor
Creates a new instance.
-
#next_token ⇒ Object
Returns the next token from the parse stack.
-
#push(value) ⇒ Object
Pushes a value onto the parse stack.
- #reset ⇒ Object
-
#strict? ⇒ Boolean
Returns true if the lexer is currently in strict mode.
- #strip_line_breaks? ⇒ Boolean
- #symbols ⇒ Object
Constructor Details
#initialize(options = {}) ⇒ Lexer
Creates a new instance. Possible options and their respective default values are:
-
:include => [:errors] A list that may contain :meta_content, and :errors; depending on whether or not these are present, the respective tokens are included in the parse tree.
-
:strict => true In strict mode objects can start anywhere; therefore the ‘@’ symbol is not possible except inside literals or @comment objects; for a more lenient lexer set to false and objects are expected to start after a new line (leading white space is permitted).
-
:strip => true When enabled, newlines will be stripped from quoted string values.
91 92 93 94 |
# File 'lib/bibtex/lexer.rb', line 91 def initialize( = {}) @options = Lexer.defaults.merge() reset end |
Class Attribute Details
.defaults ⇒ Object (readonly)
Returns the value of attribute defaults.
74 75 76 |
# File 'lib/bibtex/lexer.rb', line 74 def defaults @defaults end |
.patterns ⇒ Object (readonly)
Returns the value of attribute patterns.
74 75 76 |
# File 'lib/bibtex/lexer.rb', line 74 def patterns @patterns end |
Instance Attribute Details
#mode ⇒ Object
Returns the value of attribute mode.
29 30 31 |
# File 'lib/bibtex/lexer.rb', line 29 def mode @mode end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
29 30 31 |
# File 'lib/bibtex/lexer.rb', line 29 def @options end |
#scanner ⇒ Object (readonly)
Returns the value of attribute scanner.
29 30 31 |
# File 'lib/bibtex/lexer.rb', line 29 def scanner @scanner end |
#stack ⇒ Object (readonly)
Returns the value of attribute stack.
29 30 31 |
# File 'lib/bibtex/lexer.rb', line 29 def stack @stack end |
Instance Method Details
#active?(object) ⇒ Boolean
Returns true if the lexer is currently parsing the given object type.
127 128 129 |
# File 'lib/bibtex/lexer.rb', line 127 def active?(object) @active_object == object end |
#allow_missing_keys? ⇒ Boolean
136 137 138 |
# File 'lib/bibtex/lexer.rb', line 136 def allow_missing_keys? !!@options[:allow_missing_keys] end |
#analyse(string = nil) ⇒ Object
Start the lexical analysis.
168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/bibtex/lexer.rb', line 168 def analyse(string = nil) raise(ArgumentError, 'Lexer: failed to start analysis: no source given!') unless string || @scanner self.data = string || @scanner.string until @scanner.eos? send("parse_#{MODE[@mode]}") end push([false, '$end']) end |
#bibtex_mode? ⇒ Boolean
Returns true if the lexer is currenty parsing a BibTeX object.
118 119 120 |
# File 'lib/bibtex/lexer.rb', line 118 def bibtex_mode? MODE[@mode] == :bibtex end |
#data=(data) ⇒ Object
Sets the source for the lexical analysis and resets the internal state.
107 108 109 110 |
# File 'lib/bibtex/lexer.rb', line 107 def data=(data) @scanner = StringScanner.new(data) reset end |
#next_token ⇒ Object
Returns the next token from the parse stack.
115 |
# File 'lib/bibtex/lexer.rb', line 115 def next_token; @stack.shift; end |
#push(value) ⇒ Object
Pushes a value onto the parse stack. Returns the Lexer.
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/bibtex/lexer.rb', line 145 def push(value) case value[0] when :CONTENT, :STRING_LITERAL value[1].gsub!(/\n\s*/, ' ') if strip_line_breaks? if !@stack.empty? && value[0] == @stack[-1][0] @stack[-1][1] << value[1] else @stack.push(value) end when :ERROR @stack.push(value) if @include_errors leave_object when :META_CONTENT @stack.push(value) if @include_meta_content else @stack.push(value) end self end |
#reset ⇒ Object
96 97 98 99 100 101 102 103 104 |
# File 'lib/bibtex/lexer.rb', line 96 def reset @stack, @brace_level, @mode, @active_object = [], 0, :meta, nil # cache options for speed @include_meta_content = @options[:include].include?(:meta_content) @include_errors = @options[:include].include?(:errors) self end |
#strict? ⇒ Boolean
Returns true if the lexer is currently in strict mode.
132 133 134 |
# File 'lib/bibtex/lexer.rb', line 132 def strict? !!@options[:strict] end |
#strip_line_breaks? ⇒ Boolean
140 141 142 |
# File 'lib/bibtex/lexer.rb', line 140 def strip_line_breaks? !![:strip] && !active?(:comment) end |
#symbols ⇒ Object
112 |
# File 'lib/bibtex/lexer.rb', line 112 def symbols; @stack.map(&:first); end |