text: """This extension loader can load TagInfo objects which provide implementations
  of HTML/SGML element start/end events.
  """
  __version__ = '$Revision: 1.4 $'
  
  import string
  
  import grailbase.extloader
  from . import SGMLHandler
  
  
  class TagExtensionLoader(grailbase.extloader.ExtensionLoader):
      def find(self, name):
          mod = self.find_module(name)
          taginfo = None
          if mod is not None:
              self.load_tag_handlers(mod)
              return self.get_extension(name)
          else:
              return None
  
      def load_tag_handlers(self, mod):
          as_list = 1
          if hasattr(mod, "ATTRIBUTES_AS_KEYWORDS"):
              as_list = not mod.ATTRIBUTES_AS_KEYWORDS
          handlers = {}
          for name, function in mod.__dict__.items():
              parts = string.split(name, "_")
              if len(parts) != 2:
                  continue
              if not (parts[0] and parts[1]):
                  continue
              [action, tag] = parts
              start = do = end = None
              if handlers.has_key(tag):
                  start, do, end = handlers[tag]
              if action == 'start':
                  start = function
                  if as_list:
                      start = ListAttributesCaller(start)
              elif action == 'end':
                  end = function
              elif action == 'do':
                  do = function
                  if as_list:
                      do = ListAttributesCaller(do)
              handlers[tag] = (start, do, end)
          for tag, (start, do, end) in handlers.items():
              if start or do:
                  taginfo = SGMLHandler.TagInfo(tag, start, do, end)
                  self.add_extension(tag, taginfo)
  
  
  class ListAttributesCaller:
      """Call a tag handler function, translating the attributes dictionary to
      a list.
  
      This is useful for legacy HTML tag extensions.  The SGML & HTML support
      in Grail never has to see attributes as lists; simplifying and supporting
      a number of automatic value normalizations (esp. URI normalization and ID/
      IDREF support).
      """
      def __init__(self, func):
          self.__func = func
  
      def __call__(self, parser, attrs):
          return apply(self.__func, (parser, attrs.items()))
  