class Infoboxer::Parser::Context

Attributes

inline_eol_sign[R]
lineno[R]
next_lines[R]
traits[R]

Public Class Methods

new(text, traits = nil) click to toggle source
# File lib/infoboxer/parser/context.rb, line 11
def initialize(text, traits = nil)
  @lines = text
           .gsub(/<!--.*?-->/m, '') # FIXME: will also kill comments inside <nowiki> tag
           .split(/[\r\n]/)
  @lineno = -1
  @traits = traits || MediaWiki::Traits.default
  @scanner = StringScanner.new('')
  next!
end

Public Instance Methods

check(re) click to toggle source
# File lib/infoboxer/parser/context.rb, line 71
def check(re)
  res = @scanner.check(re)
  @matched = nil
  @rest = nil
  res
end
colno() click to toggle source
# File lib/infoboxer/parser/context.rb, line 23
def colno
  @scanner&.pos || 0
end
current()
Alias for: rest
eat_matched?(str) click to toggle source

check which works only once

# File lib/infoboxer/parser/context.rb, line 32
def eat_matched?(str)
  return false unless matched == str

  @matched = 'DUMMY'
  true
end
eof?() click to toggle source
# File lib/infoboxer/parser/context.rb, line 54
def eof?
  !next_lines || # we are after the file end
    next_lines.empty? && eol?
end
eol?() click to toggle source
# File lib/infoboxer/parser/context.rb, line 147
def eol?
  !current || current.empty?
end
fail!(text) click to toggle source

basic services

# File lib/infoboxer/parser/context.rb, line 152
def fail!(text)
  fail(ParsingError, "#{text} at line #{@lineno}:\n\t#{current}")
end
inline_eol?(exclude = nil) click to toggle source
# File lib/infoboxer/parser/context.rb, line 103
def inline_eol?(exclude = nil)
  # not using StringScanner#check, as it will change #matched value
  eol? ||
    (
      (current =~ %r[^(</ref>|}})] || @inline_eol_sign && current =~ @inline_eol_sign) &&
      (!exclude || Regexp.last_match(1) !~ exclude)
    ) # FIXME: ugly, but no idea of prettier solution
end
inspect() click to toggle source
# File lib/infoboxer/parser/context.rb, line 59
def inspect
  "#<Context(line #{lineno} of #{@lines.count}: #{current})>"
end
matched() click to toggle source
# File lib/infoboxer/parser/context.rb, line 27
def matched
  @matched ||= @scanner&.matched
end
matched?(re) click to toggle source
# File lib/infoboxer/parser/context.rb, line 143
def matched?(re)
  re && matched =~ re
end
matched_inline?(re) click to toggle source

state inspection

# File lib/infoboxer/parser/context.rb, line 133
def matched_inline?(re)
  if re.nil?
    matched.empty? && eol?
  elsif re.inspect.start_with?('/^') # was it REALLY at the beginning of the line?..
    @scanner.pos == matched.length && matched =~ re
  else
    matched =~ re
  end
end
next!() click to toggle source

lines navigation

# File lib/infoboxer/parser/context.rb, line 46
def next!
  shift(+1)
end
pop_eol_sign() click to toggle source
# File lib/infoboxer/parser/context.rb, line 97
def pop_eol_sign
  @inline_eol_sign = nil
end
prev!() click to toggle source
# File lib/infoboxer/parser/context.rb, line 50
def prev!
  shift(-1)
end
push_eol_sign(re) click to toggle source
# File lib/infoboxer/parser/context.rb, line 93
def push_eol_sign(re)
  @inline_eol_sign = re
end
rest() click to toggle source
# File lib/infoboxer/parser/context.rb, line 39
def rest
  @rest ||= @scanner&.rest
end
Also aliased as: current
scan(re) click to toggle source

scanning

# File lib/infoboxer/parser/context.rb, line 64
def scan(re)
  res = @scanner.scan(re)
  @matched = nil
  @rest = nil
  res
end
scan_continued_until(re, leave_pattern = false) click to toggle source
# File lib/infoboxer/parser/context.rb, line 112
def scan_continued_until(re, leave_pattern = false)
  res = +''

  loop do
    chunk = _scan_until(re)
    case matched
    when re
      res << chunk
      break
    when nil
      res << rest << "\n"
      next!
      eof? && fail!("Unfinished scan: #{re} not found")
    end
  end

  res[/#{re}\Z/] = '' unless leave_pattern
  res
end
scan_until(re, leave_pattern = false) click to toggle source
# File lib/infoboxer/parser/context.rb, line 85
def scan_until(re, leave_pattern = false)
  guard_eof!

  res = _scan_until(re)
  res[matched] = '' if res && !leave_pattern
  res
end
skip(re) click to toggle source
# File lib/infoboxer/parser/context.rb, line 78
def skip(re)
  res = @scanner.skip(re)
  @matched = nil
  @rest = nil
  res
end
unscan_matched!() click to toggle source
# File lib/infoboxer/parser/context.rb, line 156
def unscan_matched!
  return unless @matched

  @scanner.pos -= @matched.size
  @rest = nil
end

Private Instance Methods

_scan_until(re) click to toggle source

we do hard use of matched and rest, its wiser to memoize them

# File lib/infoboxer/parser/context.rb, line 166
def _scan_until(re)
  res = @scanner.scan_until(re)
  @matched = nil
  @rest = nil
  res
end
guard_eof!() click to toggle source
# File lib/infoboxer/parser/context.rb, line 173
def guard_eof!
  @scanner or fail!('End of input reached')
end
shift(amount) click to toggle source
# File lib/infoboxer/parser/context.rb, line 177
def shift(amount)
  @lineno += amount
  current = @lines[lineno]
  @next_lines = @lines[(lineno + 1)..]
  if current
    @scanner.string = current
    @rest = current
  else
    @scanner = nil
    @rest = nil
  end
  @matched = nil
end