Class: Nagoro::Scanner

Inherits:
StringScanner
  • Object
show all
Defined in:
lib/nagoro/scanner.rb

Defined Under Namespace

Classes: Stuck

Constant Summary collapse

TEXT =
/[^<>]+/m
DOCTYPE =
/<!DOCTYPE([^>]+)>/m
TAG_START =
/<([^\s>]+)/
TAG_END =
/<\/([^>]*)>/
TAG_OPEN_END =
/\s*>/
TAG_CLOSING_END =
/\s*\/>/
TAG_PARAMETER =
/\s*([^\s]*)=((['"])(.*?)\3)/um
INSTRUCTION_START =
/<\?(\S+)/
INSTRUCTION_END =
/(.*?)(\?>)/um
RUBY_INTERP_START =
/\s*#\{/m
RUBY_INTERP_TEXT =
/[^\{\}]+/m
RUBY_INTERP_NEST =
/\{[^\}]*\}/m
RUBY_INTERP_END =
/(?=\})/
COMMENT =
/<!--.*?-->/m

Instance Method Summary collapse

Constructor Details

#initialize(string, callback) ⇒ Scanner

Returns a new instance of Scanner.



24
25
26
27
# File 'lib/nagoro/scanner.rb', line 24

def initialize(string, callback)
  @callback = callback
  super(string)
end

Instance Method Details

#doctype(string) ⇒ Object



91
92
93
# File 'lib/nagoro/scanner.rb', line 91

def doctype(string)
  @callback.doctype(string)
end

#instruction(name) ⇒ Object



48
49
50
51
# File 'lib/nagoro/scanner.rb', line 48

def instruction(name)
  scan(INSTRUCTION_END)
  @callback.instruction(name, self[1])
end

#ruby_interp(string) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/nagoro/scanner.rb', line 53

def ruby_interp(string)
  done = false

  until done
    if    scan(RUBY_INTERP_TEXT)
      string << matched
    elsif scan(RUBY_INTERP_NEST)
      string << matched
    elsif scan(RUBY_INTERP_END)
      done = true
    end
  end

  @callback.text(string)
end

#runObject



37
38
39
40
41
42
43
44
45
46
# File 'lib/nagoro/scanner.rb', line 37

def run
  if    scan(DOCTYPE          ); doctype(self[1])
  elsif scan(INSTRUCTION_START); instruction(self[1])
  elsif scan(COMMENT          ); text(matched)
  elsif scan(TAG_END          ); tag_end(self[1])
  elsif scan(RUBY_INTERP_START); ruby_interp(matched)
  elsif scan(TAG_START        ); tag_start(self[1])
  elsif scan(TEXT             ); text(matched)
  end
end

#streamObject



29
30
31
32
33
34
35
# File 'lib/nagoro/scanner.rb', line 29

def stream
  until eos?
    pos = self.pos
    run
    raise(Stuck, "Scanner didn't move: %p" % self) if pos == self.pos
  end
end

#tag_end(name) ⇒ Object



83
84
85
# File 'lib/nagoro/scanner.rb', line 83

def tag_end(name)
  @callback.tag_end(name)
end

#tag_start(name) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/nagoro/scanner.rb', line 69

def tag_start(name)
  original_attrs = {}
  value_attrs = {}

  while scan(TAG_PARAMETER)
    original_attrs[self[1]] = self[2] # <a href="foo"> gives 'href'=>'"foo"'
    value_attrs[   self[1]] = self[4] # <a href="foo"> gives 'href'=>'foo'
  end

  @callback.tag_start(name, original_attrs, value_attrs)
  return @callback.tag_end(name) if scan(TAG_CLOSING_END)
  scan(TAG_OPEN_END)
end

#text(string) ⇒ Object



87
88
89
# File 'lib/nagoro/scanner.rb', line 87

def text(string)
  @callback.text(string)
end