class XTemplate::XNode

Constants

DEFAULT_COMMAND
EXPAND_CODE

(1)current data (2)parent data (3)root data (4)plugin object

Attributes

alt[RW]
attrs[RW]
children[RW]
data_path[RW]
name[RW]
option[RW]
parent[RW]
pi[RW]
propagation[RW]

Public Class Methods

new(name = nil, attrs = nil, children = nil, parent = nil, data_path = nil, propagation = true, exname = nil, exattr = nil, expand = nil, alt = nil, opt={}) click to toggle source
# File lib/xtemplate/node.rb, line 16
def initialize(name = nil, attrs = nil, children = nil, parent = nil,
               data_path = nil, propagation = true,
               exname = nil, exattr = nil, expand = nil, alt = nil, opt={})
  @name  = name
  @attrs = attrs || []
  @children = children || []
  @parent = parent
  @data_path = data_path
  @exname = exname
  @exattr = exattr
  @expand = expand # :normal, :strip
  @alt    = alt
  @option = opt
  if( propagation.nil? )
    @propagation = true
  else
    @propagation = propagation
  end
end
use_default_expand() click to toggle source
# File lib/xtemplate/node.rb, line 567
def XNode.use_default_expand()
  XNode.class_eval(EXPAND_CODE)
end
use_simple_expand() click to toggle source
# File lib/xtemplate/node.rb, line 571
def XNode.use_simple_expand()
  code = EXPAND_CODE.sub(/value_by_path2\(@data_path, data, pdata, rdata, plugin\)/,
                         "data[@data_path]")
  XNode.class_eval(code)
end

Public Instance Methods

add_attr(attr) click to toggle source
# File lib/xtemplate/node.rb, line 46
def add_attr(attr)
  @attrs.push([attr,SanitizedString.new("")])
end
add_attrval(val) click to toggle source
# File lib/xtemplate/node.rb, line 54
def add_attrval(val)
  @attrs[-1][1].concat(sanitize(val))
end
add_child(node) click to toggle source
# File lib/xtemplate/node.rb, line 36
def add_child(node)
  case node
  when XNode
    node.parent = self
  else
    node = sanitize(node.to_s)
  end
  @children.push(node)
end
attrval(key)
Alias for: lattrval
deep_dup(p = nil) click to toggle source

also implemented in xt.c.

# File lib/xtemplate/node.rb, line 95
def deep_dup(p = nil)
  node = XNode.new(@name && @name.dup,
                   @attrs && @attrs.dup, nil, p,
                   @data_path && @data_path.dup,
                   @propagation,
                   @exname && @exname.dup,
                   @exattr && @exattr.dup,
                   @expand, @alt, @option.dup)
  node.children = @children.collect{|child|
    if( child.is_a?(XNode) )
      child.deep_dup(node)
    else
      child
    end
  }
  node
end
dump(io) click to toggle source

also implemented in xt.c.

# File lib/xtemplate/node.rb, line 65
    def dump(io)
      if( @name )
        attrs = @attrs.collect{|a,val| "#{a}=\"#{val}\"" }
        if( attrs.size > 0 )
          attrs = " " + attrs.join(" ")
        else
          attrs = ""
        end
        if( @children.empty? )    # experimental
          io << "<#{@name}#{attrs} />"
          return io
        else
          io << "<#{@name}#{attrs}>"
        end
#        io << "<#{@name}#{attrs}>"
      end
      for s in @children
        if( s.is_a?(XNode) )
          s.dump(io)
        else
          io << s
        end
      end
      if( @name )
        io << "</#{@name}>"
      end
      io
    end
expand_attr(data) click to toggle source
# File lib/xtemplate/node.rb, line 398
def expand_attr(data)
  # substituting attribute values.
  @attrs = ([[nil,@exname],[nil,@exattr]]+@attrs).collect{|attr,val|
    [
      attr,
      if( val )
        val.gsub(/(@@?)[\{\(](.+?)[\}\)]/){|str|
          at = $1
          key = $2
          case at.size
          when 1
            if( data.is_a?(Hash) )
              v = data[key]
              case v
              when Hash
                str = v[TextNode] || ''
              else
                str = v.to_s
              end
            else
              str = ''
            end
          when 2
            str[0,1] = ''
          end
          sanitize(str)
        }
      else
        nil
      end
    ]
  }
  @exname = @attrs.shift()[1]
  @exattr = @attrs.shift()[1]
  if( @exname )
    @name   = @exname
    @exname = nil
  end
end
expand_children(data, pdata, rdata, plugin) click to toggle source
# File lib/xtemplate/node.rb, line 438
def expand_children(data, pdata, rdata, plugin)
  for child in @children
    if( child.is_a?(XNode) )
      child.expand(data, pdata, rdata, plugin)
    end
  end
end
expand_with_hash(data, pdata, rdata, plugin) click to toggle source
# File lib/xtemplate/node.rb, line 446
def expand_with_hash(data, pdata, rdata, plugin)
  # insert attributes and elements specified by ID.
  for key,attrval in data
    if( key == TextNode )
      if( attrval )
        @children = []
        add_child(attrval)
      end
    elsif( key[0] == @ )
      attr = key[1..-1]
      if( @name )
        add_attr(attr)
        add_attrval(attrval)
      elsif( @propagation )
        node = @parent
        while( node )
          if( node.name )
            node.add_attr(attr)
            node.add_attrval(attrval)
            break
          end
          node = node.parent
        end
      end
    end
  end
  expand_children(data, pdata, rdata, plugin)
end
lattrval(key) click to toggle source
# File lib/xtemplate/node.rb, line 186
def lattrval(key)
  @attrs.each{|attr,val|
    if( attr == key )
      return val
    end
  }
  nil
end
Also aliased as: attrval
prepare(xmlns = nil, enable = nil, templates = nil) click to toggle source
# File lib/xtemplate/node.rb, line 221
def prepare(xmlns = nil, enable = nil, templates = nil)
  # find xmlns:xxx="..."
  enable ||= DEFAULT_COMMAND
  templates ||= {}
  tmp = []
  @attrs.each_with_index{|elem,idx|
    attr,val, = elem
    if( (attr =~ /^xmlns:(.+)/) && (val == BIND_URI) )
      xmlns = $1
      @attrs.delete_at(idx)
      break
    end
  }

  if( @name )
    if( xmlns )
      if( @name =~ /#{xmlns}:(.+)/ )
        # special tags
        cmd = $1.tr('-','_').intern
        if( enable[cmd] )
          case cmd
          when :template
            t_name = attrval("name") || attrval("#{xmlns}:name")
            @name = nil
            @attrs = []
            if( t_name )
              templates[t_name] = self
            end
          when :expand
            @name = nil
            @data_path = attrval("id") || attrval("#{xmlns}:id")
            with_strip = attrval("strip") || attrval("#{xmlns}:strip")
            case with_strip
            when "yes"
              @expand = :strip
            else
              @expand = :normal
            end
          when :select, :value_of
            @name = nil
            @data_path   = attrval("id") || attrval("#{xmlns}:id")
            if( @propagation = attrval("propagation") || attrval("#{xmlns}:propagation") )
              @propagation = (@propagation == "yes")
            end
          when :copy_of
            @name = nil
            @data_path = attrval("id") || attrval("#{xmlns}:id")
            with_tag   = attrval("with") || attrval("#{xmlns}:with") || ''
            if( @data_path )
              @data_path = @data_path + "{dump(#{with_tag})}"
            end
            if( @propagation = attrval("propagation") || attrval("#{xmlns}:propagation") )
              @propagation = (@propagation == "yes")
            end
          when :each
            @name = nil
            @data_path = attrval("id") || attrval("#{xmlns}:id")
            if( @data_path )
              @data_path = @data_path + "{array()}"
            end
          when :element
            @exname = attrval("name") || attrval("#{xmlns}:name")
            @data_path   = attrval("id") || attrval("#{xmlns}:id")
            @name = nil
            @attrs = []
          when :attribute
            @name = nil
            @exattr = attrval("name") || attrval("#{xmlns}:name")
            @data_path   = attrval("id") || attrval("#{xmlns}:id")
          when :property, :invoke
            @name = nil
            @data_path = attrval("id") || attrval("#{xmlns}:id")
            @data_path += "."
            @data_path += attrval("name") || attrval("#{xmlns}:name") || attrval("method") || attrval("#{xmlns}:method")
            withval = attrval("with") || attrval("#{xmlns}:with") || ''
            if( withval )
              @data_path += "(#{withval})"
            end
          when :import
            src = attrval("src") || attrval("#{xmlns}:src")
            @data_path = "{data(#{src})}"
            @name = nil
          when :include
            src = attrval("src") || attrval("#{xmlns}:src")
            case src
            when /^\$(.+)/
              doc = eval(src)
            when /^file:\/\/(.+)/
              doc = File.open($1){|file| file.read }
            when /^http:\/\/(.+)/
              raise(NotImplementedError, "'#{src}' can not be included.")
            else
              doc = File.open(src){|file| file.read }
            end
            parser = XMLParser.new()
            node = parser.parse(doc)
            node.prepare(xmlns, enable, templates)
            @name = nil
            add_child(node)
          else
            raise(NotImplementedError, "'#{cmd.tr("_","-").to_s}' is not supported.")
          end
          if( @alt = (attrval("alt") || attrval("#{xmlns}:id")) )
            @data_path += "{alt(#{@alt})}"
          end
        else
          raise(RuntimeError, "'#{cmd.tr("_","-").to_s}' is invalid.")
        end
      else
        # parse attribute with xmlns
        tmp = []
        attr_id   = "#{xmlns}:id"
        attr_type = "#{xmlns}:type"
        attr_each = "#{xmlns}:each"
        attr_alt  = "#{xmlns}:alt"
        @attrs.each{|attr,val|
          case attr
          when attr_id
            if( enable[:@id] )
              @data_path = val
            else
              raise(RuntimeError, "'#{attr}' is invalid.")
            end
          when attr_each
            if( enable[:@each] )
              @data_path = val + "{array()}"
            else
              raise(RuntimeError, "'#{attr}' is invalid.")
            end
          when attr_type
            if( enable[:@type] )
              @option[:type] = val
            else
              raise(RuntimeError, "'#{attr}' is invalid.")
            end
          when attr_alt
            @alt = val
          else
            tmp.push([attr,val])
          end
        }
        if( @alt )
          @data_path += "{alt(#{@alt})}"
        end
        @attrs = tmp
      end
    else # xmlns
      # parse attribute
      tmp = []
      @attrs.each{|attr,val|
        case attr
        when 'id'
          if( enable[:@id] )
            @data_path = val
          else
            tmp.push([attr,val])
          end
        when 'each'
          if( enable[:@each] )
            @data_path = @data_path + "{array()}"
          else
            tmp.push([attr,val])
          end
        else
          tmp.push([attr,val])
        end
      }
      @attrs = tmp
    end
  end
  @children.each{|child|
    if( child.is_a?(XNode) )
      child.prepare(xmlns, enable, templates)
    end
  }
end
rattrval(key) click to toggle source
# File lib/xtemplate/node.rb, line 196
def rattrval(key)
  @attrs.reverse.each{|attr,val|
    if( attr == key )
      return val
    end
  }
  nil
end
set_propagation(flag) click to toggle source
# File lib/xtemplate/node.rb, line 50
def set_propagation(flag)
  @propagation = flag
end
strip!(recursive=true) click to toggle source
# File lib/xtemplate/node.rb, line 113
def strip!(recursive=true)
  @children.reject!{|child| child.is_a?(String) && child =~ /\A\s*\z/ }
  if( recursive )
    @children.each{|child|
      if( child.is_a?(XNode) )
        child.strip!(true)
      end
    }
  end
end
to_hash(array = XArray, unsanitize_p = false) click to toggle source
# File lib/xtemplate/node.rb, line 124
def to_hash(array = XArray, unsanitize_p = false)
  if( @hash )
    return @hash
  end
  ary  = array[]
  @children.each{|child|
    if( child.is_a?(XNode) )
      ary.push(child.to_hash(array,unsanitize_p))
    else
      text = child.to_s
      if( ary[-1].is_a?(String) )
        ary[-1].concat(text)
      else
        if( unsanitize_p )
          text = unsanitize(text)
        end
        ary.push(text.dup)
      end
    end
  }
  @attrs.each{|attr,val|
    if( unsanitize_p )
      val = unsanitize(val)
    end
    ary.push({'@'+attr => val})
  }
  if( ary.size == 1 )
    ary = ary[0]
  end
  case @option[:type]
  when 'array'
    ary = Array[*ary]
  when 'hash'
    ary = eval_action("hash()", ary, nil)
  when 'int'
    ary = ary.to_i
  when 'float'
    ary = ary.to_f
  when 'string'
    ary = ary.to_s
  end

  if( @name )
    @hash = {@name => ary}
  else
    case ary
    when Hash
      @hash = ary
    else
      @hash = {}
      ary.each{|h|
        if( h.is_a?(Hash) )
          h.each{|key,val|
            @hash[key] = val
          }
        end
      }
    end
  end
  @hash
end
to_s() click to toggle source
# File lib/xtemplate/node.rb, line 58
def to_s
  s = ""
  dump(s)
  SanitizedString.new(s)
end
to_yaml() click to toggle source
# File lib/xtemplate/yaml.rb, line 20
def to_yaml
  node = deep_dup()
  node.strip!
  node.to_hash(Array,true).to_yaml()
end