Class: Nagoro::Scanner

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

Defined Under Namespace

Classes: Stuck

Constant Summary collapse

TEXT =
/[^<>#]+/m
HASH_TEXT =
/#[^\{<]#{TEXT}/m
HASH_CHAR =
/#/
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 =
/(?=\})/
RUBY_TAG_INTERP =
/\s*(#\{.*?\})/m
COMMENT =
/<!--.*?-->/m

Instance Method Summary collapse

Constructor Details

#initialize(string, callback) ⇒ Scanner

Returns a new instance of Scanner.



27
28
29
30
# File 'lib/nagoro/scanner.rb', line 27

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

Instance Method Details

#doctype(string) ⇒ Object



110
111
112
# File 'lib/nagoro/scanner.rb', line 110

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

#hash_char(string) ⇒ Object



106
107
108
# File 'lib/nagoro/scanner.rb', line 106

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

#instruction(name) ⇒ Object



52
53
54
55
# File 'lib/nagoro/scanner.rb', line 52

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

#ruby_interp(string) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/nagoro/scanner.rb', line 57

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



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/nagoro/scanner.rb', line 40

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)
  elsif scan(HASH_CHAR        ); hash_char(matched)
  end
end

#streamObject



32
33
34
35
36
37
38
# File 'lib/nagoro/scanner.rb', line 32

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



95
96
97
# File 'lib/nagoro/scanner.rb', line 95

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

#tag_start(name) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/nagoro/scanner.rb', line 73

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

  done = false
  while not done
    if scan(RUBY_TAG_INTERP)
      original_attrs[self[1]] = nil
      value_attrs[self[1]] = nil
    elsif 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'
    elsif scan(TAG_CLOSING_END)
      @callback.tag(name, original_attrs, value_attrs)
      done = true
    elsif scan(TAG_OPEN_END)
      @callback.tag_start(name, original_attrs, value_attrs)
      done = true
    end
  end
end

#text(string) ⇒ Object



99
100
101
102
103
104
# File 'lib/nagoro/scanner.rb', line 99

def text(string)
  if scan(HASH_TEXT)
    string << matched
  end
  @callback.text(string)
end