Module: Token::Handler

Defined in:
lib/token/handler.rb,
lib/code_object/function.rb

Overview

TODO:

rewrite as default-handler, because this looks a little distracting

Constant Summary collapse

ALL =
/./m
NO_BR =
/((?!\n)\s)/
IDENTIFIER =
/(?:[^\s])*/
TYPELIST =
/\[(?<types>#{IDENTIFIER}(?:,#{NO_BR}*#{IDENTIFIER})*)\]/
TOKEN_W_TYPE =

Token with type and content

/#{NO_BR}*#{TYPELIST}#{NO_BR}*(?<content>#{ALL}*)/
TOKEN_W_TYPE_NAME =

Token with type, name and content

/^#{NO_BR}*
  #{TYPELIST}#{NO_BR}*
  (?<name>#{IDENTIFIER})
  #{NO_BR}*
  (?<content>#{ALL}*)
/x
@@defaults =
{
  :text_only => ->(tokenklass, content) {
      self.add_token tokenklass.new(:content => content)
  },
  
  :typed => ->(tokenklass, content) {
    typestring, content = TOKEN_W_TYPE.match(content).captures
    types = typestring.split /,\s*/
    
    self.add_token tokenklass.new(:types => types, :content => content)
  },
   :typed_with_name => ->(tokenklass, content) {
    typestring, name, content = TOKEN_W_TYPE_NAME.match(content).captures
    types = typestring.split /,\s*/
    
    self.add_token tokenklass.new(:name => name, :types => types, :content => content)
  },
  
  :named_multiline => ->(tokenklass, content) { 
    rows = content.split(/\n/)
          
    # use first row as name
    name = rows.shift.strip
    content = rows.join("\n")
          
    self.add_token tokenklass.new(:name => name, :content => content)
  },
  
  :noop => ->(tokenklass, content) {}
}
@@handlers =
{}

Class Method Summary collapse

Class Method Details

.add_default_handler(name, &block) ⇒ Object



237
238
239
# File 'lib/token/handler.rb', line 237

def self.add_default_handler(name, &block)
  @@defaults[name] = block;
end

.handlersHash<Symbol, Block>

Attribute-Reader for all registered ‘@@handlers`

Returns:

  • (Hash<Symbol, Block>)


106
107
108
# File 'lib/token/handler.rb', line 106

def self.handlers
  @@handlers
end

.self.register(tokenname, type = nil) ⇒ Object .self.register(tokenname) {|tokenklass, stringcontent| ... } ⇒ Object

Registering a new Tokenhandler

It is possible to register your own Tokenhandlers and therefore extend the capabilities of this documentation-program.

There are different types of handlers which can be used:

1. Default-handler
2. A handler for Typed-Token
3. A handler for Named-Typed-Tokens
4. Your custom handler (see second overload)

Overloads:

  • .self.register(tokenname, type = nil) ⇒ Object

    The first three of the handlers above can be registered with this overload.

    The Default Handler


    The Default Header can be used for tokens like the one in the example above. Trying to add a token like ‘@token` without adding a handler, you may get an `exception` like:

    #=> Token::NoTokenHandler: No Tokenhandler for: token
    #     from lib/token/container.rb:41:in process_token
    

    So we better register a handler for that token:

    Token::Handler.register :token
    

    As you can see **the second argument can be ommitted** to use a **default handler**. This default handler cannot parse typelists or tokennames, it only saves the content of the token to the struct Token.

    This Default Handler is enough for tokens like ‘@todo` or `@note`. But for more complex Tokens we need some other handlers.

    Handler for Typed-Tokens


    Typed tokens look like ‘@return [Foo, Bar] This is the description` - Additional to their **default content** they specify the possible Types.

    To register a typed-token, you only need to add a second argument:

    Token::Handler.register :return, :typed
    

    The typed-token struct, pretty much looks like the default one.

    #=> #<struct Token::Handler::TypedToken types=["Foo", "Bar"], content="This is the description\n">
    

    Handler for Typed-Named-Tokens


    They are much like Typed-Token-Handlers. They are needed for Tokenlines like ‘@param [String] my_param This is a param`. They are registered with `:typed_with_name` as the second argument:

    Token::Handler.register :param, :typed_with_name
    

    Parameters:

    • tokenname (String, Symbol)
    • type (:typed, :typed_with_name, nil) (defaults to: nil)
  • .self.register(tokenname) {|tokenklass, stringcontent| ... } ⇒ Object

    Writing your own custom Token-Handler


    By adding a block in the Tokenregistration you easily can build your own Tokenhandler:

    Token::Handler.register(:my_own) do |token_klass, stringcontent|
      # Do something with token_id and stringcontent
      # but don't forget to add the token like:
      self.add_token(token_klass.new(:content => stringcontent)
    end
    

    Because the token processing is done in the **context of the CodeObject** you can easily extend or manipulate the Objects.

    If you want to assure, that the object you are working on has a specific type (for example a Function) add the following line to your handler:

    has_to_be_a CodeObject::Function
    

    Parameters:

    Yields:

    • (tokenklass, stringcontent)

      Your custom tokenhandler



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/token/handler.rb', line 198

def self.register(tokenname, options = {}, &handler)
  
  tokenname = tokenname.to_sym   
  
  # search matching handler
  if block_given?
    # handler is already defined
  elsif options[:handler] and @@defaults.include?(options[:handler])
    handler = @@defaults[options[:handler]]
  elsif options[:handler]
    raise Exception, "#{type} has no registered Tokenhandler"
  else
    handler = @@defaults[:text_only]
  end      
  
  # Dynamically create Class named TokennameToken
  klass = Token.const_set "#{tokenname.to_s.capitalize}Token", Class.new(Token)
  
  klass.process_options options.merge({
  
    :token    => tokenname,
    :handler  => handler
  
  });  
  
  @@handlers[tokenname] = klass
end

.unregister(tokenname) ⇒ Object

Remove a registered handler from the list

Examples:

Token::Handler.register :foo
Token::Handler.unregister :foo

Parameters:



233
234
235
# File 'lib/token/handler.rb', line 233

def self.unregister(tokenname)
  @@handlers.delete(tokenname.to_sym)
end