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.
128 129 130 |
# File 'lib/bibtex/lexer.rb', line 128 def active?(object) @active_object == object end |
#allow_missing_keys? ⇒ Boolean
137 138 139 |
# File 'lib/bibtex/lexer.rb', line 137 def allow_missing_keys? !!@options[:allow_missing_keys] end |
#analyse(string = nil) ⇒ Object
Start the lexical analysis.
169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/bibtex/lexer.rb', line 169 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.
119 120 121 |
# File 'lib/bibtex/lexer.rb', line 119 def bibtex_mode? MODE[@mode] == :bibtex end |
#data=(data) ⇒ Object
Sets the source for the lexical analysis and resets the internal state.
108 109 110 111 |
# File 'lib/bibtex/lexer.rb', line 108 def data=(data) @scanner = StringScanner.new(data) reset end |
#next_token ⇒ Object
Returns the next token from the parse stack.
116 |
# File 'lib/bibtex/lexer.rb', line 116 def next_token; @stack.shift; end |
#push(value) ⇒ Object
Pushes a value onto the parse stack. Returns the Lexer.
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/bibtex/lexer.rb', line 146 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 105 |
# File 'lib/bibtex/lexer.rb', line 96 def reset @stack, @brace_level, @mode, @active_object = [], 0, :meta, nil @scanner.reset if @scanner # 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.
133 134 135 |
# File 'lib/bibtex/lexer.rb', line 133 def strict? !!@options[:strict] end |
#strip_line_breaks? ⇒ Boolean
141 142 143 |
# File 'lib/bibtex/lexer.rb', line 141 def strip_line_breaks? !![:strip] && !active?(:comment) end |
#symbols ⇒ Object
113 |
# File 'lib/bibtex/lexer.rb', line 113 def symbols; @stack.map(&:first); end |