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
)


257
258
259
260
261
262
263
264
265
266
# File 'lib/tagtreescanner.rb', line 257

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.)



214
215
216
# File 'lib/tagtreescanner.rb', line 214

def allowed_genre
  @allowed_genre
end

#allows_textObject

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



217
218
219
# File 'lib/tagtreescanner.rb', line 217

def allows_text
  @allows_text
end

#autocloseObject

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



210
211
212
# File 'lib/tagtreescanner.rb', line 210

def autoclose
  @autoclose
end

#close_matchObject

The regexp which causes the tag to automatically close.



204
205
206
# File 'lib/tagtreescanner.rb', line 204

def close_match
  @close_match
end

#close_requires_bolObject

Does the #open_match regexp require beginning of line?



207
208
209
# File 'lib/tagtreescanner.rb', line 207

def close_requires_bol
  @close_requires_bol
end

#open_matchObject

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



198
199
200
# File 'lib/tagtreescanner.rb', line 198

def open_match
  @open_match
end

#open_requires_bolObject

Does the #open_match regexp require beginning of line?



201
202
203
# File 'lib/tagtreescanner.rb', line 201

def open_requires_bol
  @open_requires_bol
end

#tag_nameObject

The type of tag this factory produces.



195
196
197
# File 'lib/tagtreescanner.rb', line 195

def tag_name
  @tag_name
end

Instance Method Details

#createObject

Creates a tag from the factory manually



282
283
284
285
286
# File 'lib/tagtreescanner.rb', line 282

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.



272
273
274
275
276
277
278
279
# File 'lib/tagtreescanner.rb', line 272

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