Class: TagTreeScanner::TagFactory

Inherits:
Object
  • Object
show all
Defined in:
lib/tagtreescanner.rb

Overview

A TagFactory holds the information about a specific kind of tag:

  • the name of the tag

  • what to look for to open and close the tag

  • what genre of tags it may contain

  • whether the tag permits raw text

  • additional code to run when creating the tag

See the documentation about the @tag_genres hash inside the TagTreeScanner class for information on how to add factories for use.

Utilizing :autoclose

Occasionally you will want to create a tag and allow no other tags inside it. An example might be a tag containing preformatted code.

Rather than opening the tag and slowly spinning through all the text, the combination of the :autoclose and :setup options allow you to create the tag, fill it with content, and then immediately continute with the parent tag.

See the #new method for how to use the :setup function, and an example usage.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tag_name, options = {}) ⇒ TagFactory

tag_name

A symbol with the name of the tag to create

__options__

A hash including one or more of :open_match,

:open_requires_bol, :close_match, :close_requires_bol, :autoclose, :allows_text, :allowed_genre, and :setup.

Due to the way the StringScanner class works, placing a ^ (beginning of line) marker in your :open_match or :close_match regular expressions will not behave as desired. Instead, set the :open_requires_bol and/or :close_requires_bol properties to true if desired.

A factory should either be set to :autoclose => true, or supply a :close_match. (Otherwise, it will never close.)

Further, a factory should either be set to :autoclose => true or specify an :allowed_genre. (See below for how to efficiently create a tag that cannot contain other tags.)

The :setup option is used to run code during the tag creation. The value of this option should be a lambda/Proc that accepts three parameters:

  • the Tag being created

  • the StringScanner instance that matched the tag opening

  • the TagTreeScanner instance creating the tag.

Example:

# Shove URLs as HTML anchors, without the protocol prefix shown
@tag_genres[ :inline ] << TagFactory.new( :a,
  :open_match => %r{http://(\S+)},
  :setup => lambda{ |tag, ss, tagtree|
    tag.attributes[ :href ] = ss[0]
    tag << ss[1]
  },
  :autoclose => true
)


109
110
111
112
113
114
115
116
117
118
# File 'lib/tagtreescanner.rb', line 109

def initialize( tag_name, options={} )
  @tag_name = tag_name
  [ :open_match, :close_match,
    :open_requires_bol, :close_requires_bol,
    :allowed_genre, :autoclose,
    :allows_text,
    :setup, :attributes ].each{ |k|
    self.instance_variable_set( "@#{k}".intern, options[ k ] )
  }
end

Instance Attribute Details

#allowed_genreObject

A symbol with the genre of tags that are allowed inside the tag. (See @tag_genres in the TagTreeScanner documentation.)



66
67
68
# File 'lib/tagtreescanner.rb', line 66

def allowed_genre
  @allowed_genre
end

#allows_textObject

May tags created by this factory have text added to them?



69
70
71
# File 'lib/tagtreescanner.rb', line 69

def allows_text
  @allows_text
end

#autocloseObject

Should this tag stay open when created, or automatically close?



62
63
64
# File 'lib/tagtreescanner.rb', line 62

def autoclose
  @autoclose
end

#close_matchObject

The regexp which causes the tag to automatically close.



56
57
58
# File 'lib/tagtreescanner.rb', line 56

def close_match
  @close_match
end

#close_requires_bolObject

Does the #open_match regexp require beginning of line?



59
60
61
# File 'lib/tagtreescanner.rb', line 59

def close_requires_bol
  @close_requires_bol
end

#open_matchObject

A regexp to match (and consume) that causes a new tag to be started.



50
51
52
# File 'lib/tagtreescanner.rb', line 50

def open_match
  @open_match
end

#open_requires_bolObject

Does the #open_match regexp require beginning of line?



53
54
55
# File 'lib/tagtreescanner.rb', line 53

def open_requires_bol
  @open_requires_bol
end

#tag_nameObject

The type of tag this factory produces.



47
48
49
# File 'lib/tagtreescanner.rb', line 47

def tag_name
  @tag_name
end

Instance Method Details

#createObject

Creates a tag from the factory manually



134
135
136
137
138
# File 'lib/tagtreescanner.rb', line 134

def create #:nodoc:
  tag = maketag
  @setup.call( tag, nil, nil ) if @setup
  tag
end

#match(string_scanner, tagtreescanner) ⇒ Object

Creates and returns a new tag if the supplied string_scanner matches the open_match of this factory.

Called by TagTreeScanner during initialization.



124
125
126
127
128
129
130
131
# File 'lib/tagtreescanner.rb', line 124

def match( string_scanner, tagtreescanner ) #:nodoc:
  #puts "Matching #{@open_match.inspect} against #{string_scanner.peek(10)}"
  return nil unless ( !@open_requires_bol || string_scanner.bol? ) && string_scanner.scan( @open_match )
  tag = maketag
  @setup.call( tag, string_scanner, tagtreescanner ) if @setup
  #puts "...created #{tag}"
  tag
end