Class: Rtml::Rules::DomRuleset

Inherits:
Object
  • Object
show all
Defined in:
lib/rtml/rules/dom_ruleset.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDomRuleset

Returns a new instance of DomRuleset.



2
3
4
5
6
# File 'lib/rtml/rules/dom_ruleset.rb', line 2

def initialize
  @tags = HashWithIndifferentAccess.new
  @root = nil
  @order = HashWithIndifferentAccess.new
end

Class Method Details

.parse(file) ⇒ Object

Loads the ruleset from a file.



23
24
25
# File 'lib/rtml/rules/dom_ruleset.rb', line 23

def self.parse(file)
  self.new.parse(file)
end

Instance Method Details

#all_tag_namesObject



140
141
142
# File 'lib/rtml/rules/dom_ruleset.rb', line 140

def all_tag_names
  tags.collect { |a| a[0] }
end

#children(parent = nil, *children, &block) ⇒ Object

If a parent and children are supplied, the parent element may contain the specified children. This does not enforce order. If a block is supplied, notation can be simplified.

If a parent is supplied, the valid children for that parent are returned. If no parent is supplied, nil is returned.

A few options are also allowed:

:minimum => the minimum number of children, 0 for no minimum
:maximum => the maximum number of children, 0 for no maximum

Examples:

ruleset.children :head, :base, :link, :defaults # [:base, :link, :defaults] are valid children of :head

# Does the same thing:
ruleset.children do
  head :base, :link, :defaults
end

# Retrieve the array of valid children for :head
ruleset.children(:head)


55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/rtml/rules/dom_ruleset.rb', line 55

def children(parent = nil, *children, &block)
  r = nil
  if parent # make sure all tags are registered
    options = children.extract_options!
    tags = tag(parent, *children)
    parent_tag = tags.shift
    parent_tag.child_tags << (children.flatten.collect { |i| i.to_s } + [options]) unless tags.empty?
    r = parent_tag.children
  end
  if block_given?
    proxy_into(:children).new(self).instance_eval &block
  end
  r
end

#freezeObject



8
9
10
11
12
13
14
# File 'lib/rtml/rules/dom_ruleset.rb', line 8

def freeze
  super
  @tags.freeze
  @root.freeze
  @order.freeze
  self
end

#order(parent = nil, *children, &block) ⇒ Object

If parent and children are supplied, the order of the children within the parent element will be enforced. If a block is supplied, notation can be simplified.

If a parent is supplied, then the order of its children is returned. If no parent is supplied, then nil is returned.

Examples:

ruleset.order :head, :base, :link, :defaults # order [:base, :link, :defaults] beneath :head

# Does the same thing:
ruleset.order do
  head :base, :link, :defaults
end

# Retrieve the order of :head
ruleset.order(:head)


113
114
115
116
117
118
119
120
121
122
123
# File 'lib/rtml/rules/dom_ruleset.rb', line 113

def order(parent = nil, *children, &block)
  if parent # make sure all tags are registered
    parent_tag = tag(parent, *children).first
    parent_tag.order.concat children.flatten.collect { |i| i.to_s }
  end
  if block_given?
    proxy_into(:order).new(self).instance_eval &block
  end
  return tag(parent).order if parent
  return nil
end

#parse(file) ⇒ Object

Loads the ruleset from a file.



17
18
19
20
# File 'lib/rtml/rules/dom_ruleset.rb', line 17

def parse(file)
  instance_eval File.read(file), file, 1
  self
end

#proxy_into(method_name) ⇒ Object

Creates a proxy class for the specified method.



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/rtml/rules/dom_ruleset.rb', line 71

def proxy_into(method_name)
  @proxy_classes ||= HashWithIndifferentAccess.new
  return @proxy_classes[method_name] if @proxy_classes[method_name]
  klass = Class.new
  line = __LINE__ + 2
  code = <<-end_code
    def initialize(parent)
      @parent = parent
      # Proxy known tags in case they clash with Ruby methods
      @parent.tags.each do |tag|
        line = __LINE__ + 2
        kode = <<-end_kode
          def \#{tag}(*args, &block)
            @parent.#{method_name} :\#{tag}, *args, &block
          end
        end_kode
        instance_eval kode, __FILE__, line
      end
    end
    def method_missing(name, *args, &block) @parent.#{method_name} name, *args, &block; end
  end_code
  klass.class_eval code, __FILE__, line
  @proxy_classes[method_name] = klass
end

#root(*value) ⇒ Object

Specifies a root tag. If a root tag has already been specified, an error will be raised. If no root tag is specified, the current root tag is returned instead, or nil if there is none.



158
159
160
161
162
163
164
165
# File 'lib/rtml/rules/dom_ruleset.rb', line 158

def root(*value)
  unless value.empty?
    raise Rtml::Errors::MultipleRootsError, "Can only have one root element" if @root
    @root = value.shift.to_s
    tag @root
  end
  @root
end

#root?(name) ⇒ Boolean

Returns true if the specified String or Symbol represents a root tag.

Returns:

  • (Boolean)


147
148
149
# File 'lib/rtml/rules/dom_ruleset.rb', line 147

def root?(name)
  name.to_s == @root
end

#tag(*value) ⇒ Object Also known as: tags

Declares one or more tags. If a tag is used that has not been previously declared, it will be added automatically. Returns an array of all added tags, or the tag itself if there was only one.

If no arguments are specified, nothing happens and an array of all registered tags is returned.



129
130
131
132
133
134
135
136
137
138
# File 'lib/rtml/rules/dom_ruleset.rb', line 129

def tag(*value)
  return @tags if value.empty?
  ts = []
  value.flatten.each do |t|
    if @tags.key?(t) || !frozen?
      ts << (@tags[t] ||= Rtml::Rules::DomTag.new(t.to_s))
    end
  end
  ts.length == 1 ? ts.first : ts
end

#tag?(name) ⇒ Boolean

Returns true if the specified String or Symbol represents a tag.

Returns:

  • (Boolean)


152
153
154
# File 'lib/rtml/rules/dom_ruleset.rb', line 152

def tag?(name)
  tags.collect { |t| t.name }.include?(name.to_s)
end

#tag_rules(name) ⇒ Object

Returns the tag with the specified name, or nil if it can’t be found



28
29
30
31
# File 'lib/rtml/rules/dom_ruleset.rb', line 28

def tag_rules(name)
  return nil unless tags.include?(name)
  tag(name)
end