Module: HTree
- Defined in:
- lib/htree/gencode.rb,
lib/htree/doc.rb,
lib/htree/loc.rb,
lib/htree/tag.rb,
lib/htree/elem.rb,
lib/htree/fstr.rb,
lib/htree/leaf.rb,
lib/htree/name.rb,
lib/htree/scan.rb,
lib/htree/text.rb,
lib/htree/parse.rb,
lib/htree/rexml.rb,
lib/htree/output.rb,
lib/htree/context.rb,
lib/htree/display.rb,
lib/htree/encoder.rb,
lib/htree/inspect.rb,
lib/htree/modules.rb,
lib/htree/equality.rb,
lib/htree/htmlinfo.rb,
lib/htree/template.rb,
lib/htree/traverse.rb,
lib/htree/raw_string.rb,
lib/htree/extract_text.rb
Overview
Template Engine
The htree template engine converts HTML and some data to HTML or XML.
Template Method Summary
-
HTree.expand_template(template_pathname) -> $stdout
-
HTree.expand_template(template_pathname, obj) -> $stdout
-
HTree.expand_template(template_pathname, obj, out) -> out
-
HTree.expand_template(template_pathname, obj, out, encoding) -> out
-
HTree.expand_template<em>template_string</em> -> $stdout
-
HTree.expand_template(out) <em>template_string</em> -> out
-
HTree.expand_template(out, encoding) <em>template_string</em> -> out
-
HTree.compile_template(template_string) -> Module
-
HTree<em>template_string</em> -> HTree::Doc
Note that the following method, HTree(), is not a template method.
-
HTree(html_string) -> HTree::Doc
Template Directives.
A template directive is described as a special HTML attribute which name begins with underscore.
The template directives are listed as follows.
-
<elem _attr_name=“expr”>content</elem>
-
<elem _text=“expr”>dummy-content</elem>
-
<elem _text>expr</elem>
-
<elem _tree=“expr”>dummy-content</elem>
-
<elem _tree>expr</elem>
-
<elem _if=“expr” _else=“mod.name(args)”>then-content</elem>
-
<elem _iter=“expr.meth(args)//vars”>content</elem>
-
<elem _iter_content=“expr.meth(args)//vars”>content</elem>
-
<elem _call=“mod.name(args)”>dummy-content</elem>
-
<elem _template=“name(vars)”>body</elem>
Template Semantics
-
attribute substitution
-
<elem _attr_name=“expr”>content</elem>
_attr_name is used for a dynamic attribute.
<elem _attr_xxx="..."/> -> <elem xxx="..."/>
It is expanded to name=“content”. The content is generated by evaluating expr. Usually you don’t need to care escaping: &, <, > and “ are automatically escaped. If you need to output character references, the value of expr should be an object which have a
rcdata
method such as an HTree::Text. If the value has arcdata
method, it is called and the result is used as the content with escaping <, > and ”._attr_name can be used multiple times in single element.
-
-
text substitution
-
<elem _text=“expr”>dummy-content</elem>
-
<elem _text>expr</elem>
_text substitutes the content of the element by the string evaluated from expr. expr is described in the attribute value or the content of the element.
If a result of expr have &, < and/or >, they are automatically escaped. If you need to output character references, the value of expr should be an object which have a
rcdata
method such as an HTree::Text. If the value has arcdata
method, it is called and the result is used as the content with escaping < and >.If the element is span or div, and there is no other attributes, no tags are produced.
<elem _text="...">dummy-content</elem> -> <elem>...</elem>
-
-
tree substitution
-
<elem _tree=“expr”>dummy-content</elem>
-
<elem _tree>expr</elem>
_tree substitutes the content of the element by the htree object evaluated from expr. expr is described in the attribute value or the content of the element.
If the element is span or div, and there is no other attributes, no tags are produced.
<elem _tree="...">dummy-content</elem> -> <elem>...</elem>
-
-
conditional
-
<elem _if=“expr”>then-content</elem>
-
<elem _if=“expr” _else=“name(args)”>then-content</elem>
_if is used for conditional.
If expr is evaluated to true, it expands as follows regardless of existence of _else.
<elem _if="<i>expr</i>">then-content</elem> -> <elem>then-content</elem>
If expr is evaluated to false, it expands using _else. If _else is not given, it expands to empty. If _else is given, it expands as follows.
<elem _if="<i>expr</i>" _else="<i>name(args)</i>">then-content</elem> -> <elem _call="<i>name(args)</i>">then-content</elem> -> see _call for further expansion.
It is expanded to <elem>then-content</elem> if expr is evaluated to a true value. Otherwise, it is replaced by other template specified by _else attribute. If _else attribute is not given, it just replaced by empty.
-
-
iteration
-
<elem _iter=“expr.meth(args)//vars”>content</elem>
-
<elem _iter_content=“expr.meth(args)//vars”>content</elem>
_iter and _iter_content is used for iteration. _iter iterates the element itself but _iter_content iterates the content.
<outer _iter="..."><inner/></outer> -> <outer><inner/></outer><outer><inner/></outer>... <outer _iter_content="..."><inner/></outer> -> <outer><inner/><inner/>...</outer>
expr.meth(args) specifies iterator method call. It is actually called with a block. The block have block parameters vars. vars must be variables separated by comma.
-
-
template call
-
<elem _call=“name(args)”>dummy-content</elem>
-
<elem _call=“mod.name(args)”>dummy-content</elem>
_call is used to expand a template function. The template function is defined by _template.
<d _template="m">...</d> <c _call="m">...</c> -> <d>...</d>
A local template can be called as follows:
HTree.{<<'End'} <a _template=ruby_talk(num) _attr_href='"http://ruby-talk.org/#{num}"' >[ruby-talk:<span _text=num>nnn</span>]</a> Ruby 1.8.0 is released at <span _call=ruby_talk(77946) />. Ruby 1.8.1 is released at <span _call=ruby_talk(88814) />. End
mod should be the result of HTree.compile_template.
M = HTree.compile_template(<<'End') <a _template=ruby_talk(num) _attr_href='"http://ruby-talk.org/#{num}"' >[ruby-talk:<span _text=num>nnn</span>]</a> End HTree.{<<'End'} <html> Ruby 1.8.0 is released at <span _call=M.ruby_talk(77946) />. Ruby 1.8.1 is released at <span _call=M.ruby_talk(88814) />. </html> End
The module can included. In such case, the template function can be called without mod. prefix.
include HTree.compile_template(<<'End') <a _template=ruby_talk(num) _attr_href='"http://ruby-talk.org/#{num}"' >[ruby-talk:<span _text=num>nnn</span>]</a> End HTree.{<<'End'} <html> Ruby 1.8.0 is released at <span _call=ruby_talk(77946) />. Ruby 1.8.1 is released at <span _call=ruby_talk(88814) />. </html> End
-
-
template definition
-
<elem _template=“name(vars)”>body</elem>
_template defines a template function which is usable by _call.
When a template is compiled to a module by HTree.compile_template, the module have a module function for each template function defined by outermost _template attribute.
-
White Space Handling
The htree template engine strips whitespace text nodes in a template except under HTML pre element.
For example the white space text node between two spans in following template is stripped.
<span _text="'a'"/> <span _text="'b'"/> -> "ab"
Character entity references are not stripped.
<span _text="'a'"/> <span _text="'b'"/> -> "a b"
Text nodes generated by _text is not stripped.
<span _text="'a'"/><span _text="' '"> </span><span _text="'b'"/> -> "a b"
HTML and XML
The htree template engine outputs HTML or XML.
If a template has no XML declaration and the top element is HTML, the result is HTML. Otherwise the result is XML.
They differs as follows.
-
XML declaration is (re-)generated for XML.
-
empty elements ends with a slash for XML.
-
script and style element is escaped for XML.
Design Decision on Design/Logic Separation
HTree template engine doesn’t force you to separate design and logic. Any logic (Ruby code) can be embedded in design (HTML).
However the template engine cares the separation by logic refactorings. The logic is easy to move between a template and an application. For example, following tangled template
tmpl.html:
<html>
<head>
<title _text="very-complex-ruby-code">dummy</title>
</head>
...
</html>
app.rb:
HTree.expand_template('tmpl.html', obj)
can be refactored as follows.
tmpl.html:
<html>
<head>
<title _text="title">dummy</title>
</head>
...
</html>
app.rb:
def obj.title
very-complex-ruby-code
end
HTree.expand_template('tmpl.html', obj)
In general, any expression in a template can be refactored to an application by extracting it as a method. In JSP, this is difficult especially for a code fragment of an iteration.
Also HTree encourages to separate business logic (Ruby code in an application) and presentation logic (Ruby code in a template). For example, presentation logic to color table rows stripe can be embedded in a template. It doesn’t need to tangle an application.
Defined Under Namespace
Modules: Container, Leaf, Node, Pat, Tag, Traverse, Util Classes: BogusETag, Comment, Context, Doc, DocType, ETag, Elem, Encoder, Error, GenCode, Location, Name, ProcIns, STag, TemplateCompiler, Text, XMLDecl
Constant Summary collapse
- DefaultContext =
:stopdoc:
Context.new
- HTMLContext =
DefaultContext.subst_namespaces(nil=>"http://www.w3.org/1999/xhtml")
- NamedCharacters =
:stopdoc:
{"AElig"=>198, "Aacute"=>193, "Acirc"=>194, "Agrave"=>192, "Alpha"=>913, "Aring"=>197, "Atilde"=>195, "Auml"=>196, "Beta"=>914, "Ccedil"=>199, "Chi"=>935, "Dagger"=>8225, "Delta"=>916, "ETH"=>208, "Eacute"=>201, "Ecirc"=>202, "Egrave"=>200, "Epsilon"=>917, "Eta"=>919, "Euml"=>203, "Gamma"=>915, "Iacute"=>205, "Icirc"=>206, "Igrave"=>204, "Iota"=>921, "Iuml"=>207, "Kappa"=>922, "Lambda"=>923, "Mu"=>924, "Ntilde"=>209, "Nu"=>925, "OElig"=>338, "Oacute"=>211, "Ocirc"=>212, "Ograve"=>210, "Omega"=>937, "Omicron"=>927, "Oslash"=>216, "Otilde"=>213, "Ouml"=>214, "Phi"=>934, "Pi"=>928, "Prime"=>8243, "Psi"=>936, "Rho"=>929, "Scaron"=>352, "Sigma"=>931, "THORN"=>222, "Tau"=>932, "Theta"=>920, "Uacute"=>218, "Ucirc"=>219, "Ugrave"=>217, "Upsilon"=>933, "Uuml"=>220, "Xi"=>926, "Yacute"=>221, "Yuml"=>376, "Zeta"=>918, "aacute"=>225, "acirc"=>226, "acute"=>180, "aelig"=>230, "agrave"=>224, "alefsym"=>8501, "alpha"=>945, "amp"=>38, "and"=>8743, "ang"=>8736, "apos"=>39, "aring"=>229, "asymp"=>8776, "atilde"=>227, "auml"=>228, "bdquo"=>8222, "beta"=>946, "brvbar"=>166, "bull"=>8226, "cap"=>8745, "ccedil"=>231, "cedil"=>184, "cent"=>162, "chi"=>967, "circ"=>710, "clubs"=>9827, "cong"=>8773, "copy"=>169, "crarr"=>8629, "cup"=>8746, "curren"=>164, "dArr"=>8659, "dagger"=>8224, "darr"=>8595, "deg"=>176, "delta"=>948, "diams"=>9830, "divide"=>247, "eacute"=>233, "ecirc"=>234, "egrave"=>232, "empty"=>8709, "emsp"=>8195, "ensp"=>8194, "epsilon"=>949, "equiv"=>8801, "eta"=>951, "eth"=>240, "euml"=>235, "euro"=>8364, "exist"=>8707, "fnof"=>402, "forall"=>8704, "frac12"=>189, "frac14"=>188, "frac34"=>190, "frasl"=>8260, "gamma"=>947, "ge"=>8805, "gt"=>62, "hArr"=>8660, "harr"=>8596, "hearts"=>9829, "hellip"=>8230, "iacute"=>237, "icirc"=>238, "iexcl"=>161, "igrave"=>236, "image"=>8465, "infin"=>8734, "int"=>8747, "iota"=>953, "iquest"=>191, "isin"=>8712, "iuml"=>239, "kappa"=>954, "lArr"=>8656, "lambda"=>955, "lang"=>9001, "laquo"=>171, "larr"=>8592, "lceil"=>8968, "ldquo"=>8220, "le"=>8804, "lfloor"=>8970, "lowast"=>8727, "loz"=>9674, "lrm"=>8206, "lsaquo"=>8249, "lsquo"=>8216, "lt"=>60, "macr"=>175, "mdash"=>8212, "micro"=>181, "middot"=>183, "minus"=>8722, "mu"=>956, "nabla"=>8711, "nbsp"=>160, "ndash"=>8211, "ne"=>8800, "ni"=>8715, "not"=>172, "notin"=>8713, "nsub"=>8836, "ntilde"=>241, "nu"=>957, "oacute"=>243, "ocirc"=>244, "oelig"=>339, "ograve"=>242, "oline"=>8254, "omega"=>969, "omicron"=>959, "oplus"=>8853, "or"=>8744, "ordf"=>170, "ordm"=>186, "oslash"=>248, "otilde"=>245, "otimes"=>8855, "ouml"=>246, "para"=>182, "part"=>8706, "permil"=>8240, "perp"=>8869, "phi"=>966, "pi"=>960, "piv"=>982, "plusmn"=>177, "pound"=>163, "prime"=>8242, "prod"=>8719, "prop"=>8733, "psi"=>968, "quot"=>34, "rArr"=>8658, "radic"=>8730, "rang"=>9002, "raquo"=>187, "rarr"=>8594, "rceil"=>8969, "rdquo"=>8221, "real"=>8476, "reg"=>174, "rfloor"=>8971, "rho"=>961, "rlm"=>8207, "rsaquo"=>8250, "rsquo"=>8217, "sbquo"=>8218, "scaron"=>353, "sdot"=>8901, "sect"=>167, "shy"=>173, "sigma"=>963, "sigmaf"=>962, "sim"=>8764, "spades"=>9824, "sub"=>8834, "sube"=>8838, "sum"=>8721, "sup"=>8835, "sup1"=>185, "sup2"=>178, "sup3"=>179, "supe"=>8839, "szlig"=>223, "tau"=>964, "there4"=>8756, "theta"=>952, "thetasym"=>977, "thinsp"=>8201, "thorn"=>254, "tilde"=>732, "times"=>215, "trade"=>8482, "uArr"=>8657, "uacute"=>250, "uarr"=>8593, "ucirc"=>251, "ugrave"=>249, "uml"=>168, "upsih"=>978, "upsilon"=>965, "uuml"=>252, "weierp"=>8472, "xi"=>958, "yacute"=>253, "yen"=>165, "yuml"=>255, "zeta"=>950, "zwj"=>8205, "zwnj"=>8204}
- NamedCharactersPattern =
/\A(?-mix:AElig|Aacute|Acirc|Agrave|Alpha|Aring|Atilde|Auml|Beta|Ccedil|Chi|Dagger|Delta|ETH|Eacute|Ecirc|Egrave|Epsilon|Eta|Euml|Gamma|Iacute|Icirc|Igrave|Iota|Iuml|Kappa|Lambda|Mu|Ntilde|Nu|OElig|Oacute|Ocirc|Ograve|Omega|Omicron|Oslash|Otilde|Ouml|Phi|Pi|Prime|Psi|Rho|Scaron|Sigma|THORN|Tau|Theta|Uacute|Ucirc|Ugrave|Upsilon|Uuml|Xi|Yacute|Yuml|Zeta|aacute|acirc|acute|aelig|agrave|alefsym|alpha|amp|and|ang|apos|aring|asymp|atilde|auml|bdquo|beta|brvbar|bull|cap|ccedil|cedil|cent|chi|circ|clubs|cong|copy|crarr|cup|curren|dArr|dagger|darr|deg|delta|diams|divide|eacute|ecirc|egrave|empty|emsp|ensp|epsilon|equiv|eta|eth|euml|euro|exist|fnof|forall|frac12|frac14|frac34|frasl|gamma|ge|gt|hArr|harr|hearts|hellip|iacute|icirc|iexcl|igrave|image|infin|int|iota|iquest|isin|iuml|kappa|lArr|lambda|lang|laquo|larr|lceil|ldquo|le|lfloor|lowast|loz|lrm|lsaquo|lsquo|lt|macr|mdash|micro|middot|minus|mu|nabla|nbsp|ndash|ne|ni|not|notin|nsub|ntilde|nu|oacute|ocirc|oelig|ograve|oline|omega|omicron|oplus|or|ordf|ordm|oslash|otilde|otimes|ouml|para|part|permil|perp|phi|pi|piv|plusmn|pound|prime|prod|prop|psi|quot|rArr|radic|rang|raquo|rarr|rceil|rdquo|real|reg|rfloor|rho|rlm|rsaquo|rsquo|sbquo|scaron|sdot|sect|shy|sigma|sigmaf|sim|spades|sub|sube|sum|sup|sup1|sup2|sup3|supe|szlig|tau|there4|theta|thetasym|thinsp|thorn|tilde|times|trade|uArr|uacute|uarr|ucirc|ugrave|uml|upsih|upsilon|uuml|weierp|xi|yacute|yen|yuml|zeta|zwj|zwnj)\z/
- ElementContent =
{"h6"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "object"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "param", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"], "dl"=>["dd", "dt"], "p"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "acronym"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "code"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "ul"=>["li"], "tt"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "label"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "form"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"], "q"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "thead"=>["tr"], "area"=>:EMPTY, "td"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"], "title"=>[], "dir"=>["li"], "s"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "ol"=>["li"], "hr"=>:EMPTY, "applet"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "param", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"], "table"=>["caption", "col", "colgroup", "tbody", "tfoot", "thead", "tr"], "legend"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "cite"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "a"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "html"=> ["a", "abbr", "acronym", "address", "applet", "b", "base", "basefont", "bdo", "big", "blockquote", "body", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "head", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "title", "tt", "u", "ul", "var"], "u"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "blockquote"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"], "center"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"], "b"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "base"=>:EMPTY, "th"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"], "link"=>:EMPTY, "var"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "samp"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "div"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"], "textarea"=>[], "pre"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "head"=>["base", "isindex", "title"], "span"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "br"=>:EMPTY, "script"=>:CDATA, "noframes"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"], "style"=>:CDATA, "meta"=>:EMPTY, "dt"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "option"=>[], "kbd"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "big"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "tfoot"=>["tr"], "sup"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "bdo"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "isindex"=>:EMPTY, "dfn"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "fieldset"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "legend", "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"], "em"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "font"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "tbody"=>["tr"], "noscript"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"], "li"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"], "col"=>:EMPTY, "small"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "dd"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"], "i"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "menu"=>["li"], "strong"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "basefont"=>:EMPTY, "img"=>:EMPTY, "optgroup"=>["option"], "map"=> ["address", "area", "blockquote", "center", "dir", "div", "dl", "fieldset", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "isindex", "menu", "noframes", "noscript", "ol", "p", "pre", "table", "ul"], "h1"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "address"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "p", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "sub"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "param"=>:EMPTY, "input"=>:EMPTY, "h2"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "abbr"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "h3"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "strike"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "body"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"], "ins"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"], "button"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"], "h4"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "select"=>["optgroup", "option"], "caption"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "colgroup"=>["col"], "tr"=>["td", "th"], "del"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"], "h5"=> ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br", "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img", "input", "kbd", "label", "map", "object", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "textarea", "tt", "u", "var"], "iframe"=> ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big", "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub", "sup", "table", "textarea", "tt", "u", "ul", "var"]}
- ElementInclusions =
{"head"=>["link", "meta", "object", "script", "style"], "body"=>["del", "ins"]}
- ElementExclusions =
{"button"=> ["a", "button", "fieldset", "form", "iframe", "input", "isindex", "label", "select", "textarea"], "a"=>["a"], "dir"=> ["address", "blockquote", "center", "dir", "div", "dl", "fieldset", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "isindex", "menu", "noframes", "noscript", "ol", "p", "pre", "table", "ul"], "title"=>["link", "meta", "object", "script", "style"], "pre"=> ["applet", "basefont", "big", "font", "img", "object", "small", "sub", "sup"], "form"=>["form"], "menu"=> ["address", "blockquote", "center", "dir", "div", "dl", "fieldset", "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "isindex", "menu", "noframes", "noscript", "ol", "p", "pre", "table", "ul"], "label"=>["label"]}
- OmittedAttrName =
{"h6"=> {"center"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir", "right"=>"align", "rtl"=>"dir"}, "object"=> {"bottom"=>"align", "declare"=>"declare", "left"=>"align", "ltr"=>"dir", "middle"=>"align", "right"=>"align", "rtl"=>"dir", "top"=>"align"}, "dl"=>{"compact"=>"compact", "ltr"=>"dir", "rtl"=>"dir"}, "p"=> {"center"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir", "right"=>"align", "rtl"=>"dir"}, "acronym"=>{"ltr"=>"dir", "rtl"=>"dir"}, "code"=>{"ltr"=>"dir", "rtl"=>"dir"}, "ul"=> {"circle"=>"type", "compact"=>"compact", "disc"=>"type", "ltr"=>"dir", "rtl"=>"dir", "square"=>"type"}, "tt"=>{"ltr"=>"dir", "rtl"=>"dir"}, "label"=>{"ltr"=>"dir", "rtl"=>"dir"}, "form"=>{"get"=>"method", "ltr"=>"dir", "post"=>"method", "rtl"=>"dir"}, "q"=>{"ltr"=>"dir", "rtl"=>"dir"}, "thead"=> {"baseline"=>"valign", "bottom"=>"valign", "center"=>"align", "char"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir", "middle"=>"valign", "right"=>"align", "rtl"=>"dir", "top"=>"valign"}, "area"=> {"circle"=>"shape", "default"=>"shape", "ltr"=>"dir", "nohref"=>"nohref", "poly"=>"shape", "rect"=>"shape", "rtl"=>"dir"}, "td"=> {"baseline"=>"valign", "bottom"=>"valign", "center"=>"align", "char"=>"align", "col"=>"scope", "colgroup"=>"scope", "justify"=>"align", "left"=>"align", "ltr"=>"dir", "middle"=>"valign", "nowrap"=>"nowrap", "right"=>"align", "row"=>"scope", "rowgroup"=>"scope", "rtl"=>"dir", "top"=>"valign"}, "title"=>{"ltr"=>"dir", "rtl"=>"dir"}, "dir"=>{"compact"=>"compact", "ltr"=>"dir", "rtl"=>"dir"}, "s"=>{"ltr"=>"dir", "rtl"=>"dir"}, "ol"=>{"compact"=>"compact", "ltr"=>"dir", "rtl"=>"dir"}, "hr"=> {"center"=>"align", "left"=>"align", "ltr"=>"dir", "noshade"=>"noshade", "right"=>"align", "rtl"=>"dir"}, "applet"=> {"bottom"=>"align", "left"=>"align", "middle"=>"align", "right"=>"align", "top"=>"align"}, "table"=> {"above"=>"frame", "all"=>"rules", "below"=>"frame", "border"=>"frame", "box"=>"frame", "center"=>"align", "cols"=>"rules", "groups"=>"rules", "hsides"=>"frame", "left"=>"align", "lhs"=>"frame", "ltr"=>"dir", "none"=>"rules", "rhs"=>"frame", "right"=>"align", "rows"=>"rules", "rtl"=>"dir", "void"=>"frame", "vsides"=>"frame"}, "legend"=> {"bottom"=>"align", "left"=>"align", "ltr"=>"dir", "right"=>"align", "rtl"=>"dir", "top"=>"align"}, "cite"=>{"ltr"=>"dir", "rtl"=>"dir"}, "a"=> {"circle"=>"shape", "default"=>"shape", "ltr"=>"dir", "poly"=>"shape", "rect"=>"shape", "rtl"=>"dir"}, "html"=>{"ltr"=>"dir", "rtl"=>"dir"}, "u"=>{"ltr"=>"dir", "rtl"=>"dir"}, "blockquote"=>{"ltr"=>"dir", "rtl"=>"dir"}, "center"=>{"ltr"=>"dir", "rtl"=>"dir"}, "b"=>{"ltr"=>"dir", "rtl"=>"dir"}, "th"=> {"baseline"=>"valign", "bottom"=>"valign", "center"=>"align", "char"=>"align", "col"=>"scope", "colgroup"=>"scope", "justify"=>"align", "left"=>"align", "ltr"=>"dir", "middle"=>"valign", "nowrap"=>"nowrap", "right"=>"align", "row"=>"scope", "rowgroup"=>"scope", "rtl"=>"dir", "top"=>"valign"}, "link"=>{"ltr"=>"dir", "rtl"=>"dir"}, "var"=>{"ltr"=>"dir", "rtl"=>"dir"}, "samp"=>{"ltr"=>"dir", "rtl"=>"dir"}, "div"=> {"center"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir", "right"=>"align", "rtl"=>"dir"}, "textarea"=> {"disabled"=>"disabled", "ltr"=>"dir", "readonly"=>"readonly", "rtl"=>"dir"}, "pre"=>{"ltr"=>"dir", "rtl"=>"dir"}, "head"=>{"ltr"=>"dir", "rtl"=>"dir"}, "span"=>{"ltr"=>"dir", "rtl"=>"dir"}, "br"=>{"all"=>"clear", "left"=>"clear", "none"=>"clear", "right"=>"clear"}, "script"=>{"defer"=>"defer"}, "noframes"=>{"ltr"=>"dir", "rtl"=>"dir"}, "style"=>{"ltr"=>"dir", "rtl"=>"dir"}, "meta"=>{"ltr"=>"dir", "rtl"=>"dir"}, "dt"=>{"ltr"=>"dir", "rtl"=>"dir"}, "option"=> {"disabled"=>"disabled", "ltr"=>"dir", "rtl"=>"dir", "selected"=>"selected"}, "kbd"=>{"ltr"=>"dir", "rtl"=>"dir"}, "big"=>{"ltr"=>"dir", "rtl"=>"dir"}, "tfoot"=> {"baseline"=>"valign", "bottom"=>"valign", "center"=>"align", "char"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir", "middle"=>"valign", "right"=>"align", "rtl"=>"dir", "top"=>"valign"}, "sup"=>{"ltr"=>"dir", "rtl"=>"dir"}, "bdo"=>{"ltr"=>"dir", "rtl"=>"dir"}, "isindex"=>{"ltr"=>"dir", "rtl"=>"dir"}, "dfn"=>{"ltr"=>"dir", "rtl"=>"dir"}, "fieldset"=>{"ltr"=>"dir", "rtl"=>"dir"}, "em"=>{"ltr"=>"dir", "rtl"=>"dir"}, "font"=>{"ltr"=>"dir", "rtl"=>"dir"}, "tbody"=> {"baseline"=>"valign", "bottom"=>"valign", "center"=>"align", "char"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir", "middle"=>"valign", "right"=>"align", "rtl"=>"dir", "top"=>"valign"}, "noscript"=>{"ltr"=>"dir", "rtl"=>"dir"}, "li"=>{"ltr"=>"dir", "rtl"=>"dir"}, "col"=> {"baseline"=>"valign", "bottom"=>"valign", "center"=>"align", "char"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir", "middle"=>"valign", "right"=>"align", "rtl"=>"dir", "top"=>"valign"}, "small"=>{"ltr"=>"dir", "rtl"=>"dir"}, "dd"=>{"ltr"=>"dir", "rtl"=>"dir"}, "i"=>{"ltr"=>"dir", "rtl"=>"dir"}, "menu"=>{"compact"=>"compact", "ltr"=>"dir", "rtl"=>"dir"}, "strong"=>{"ltr"=>"dir", "rtl"=>"dir"}, "img"=> {"bottom"=>"align", "ismap"=>"ismap", "left"=>"align", "ltr"=>"dir", "middle"=>"align", "right"=>"align", "rtl"=>"dir", "top"=>"align"}, "optgroup"=>{"disabled"=>"disabled", "ltr"=>"dir", "rtl"=>"dir"}, "map"=>{"ltr"=>"dir", "rtl"=>"dir"}, "address"=>{"ltr"=>"dir", "rtl"=>"dir"}, "h1"=> {"center"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir", "right"=>"align", "rtl"=>"dir"}, "sub"=>{"ltr"=>"dir", "rtl"=>"dir"}, "param"=>{"data"=>"valuetype", "object"=>"valuetype", "ref"=>"valuetype"}, "input"=> {"bottom"=>"align", "button"=>"type", "checkbox"=>"type", "checked"=>"checked", "disabled"=>"disabled", "file"=>"type", "hidden"=>"type", "image"=>"type", "ismap"=>"ismap", "left"=>"align", "ltr"=>"dir", "middle"=>"align", "password"=>"type", "radio"=>"type", "readonly"=>"readonly", "reset"=>"type", "right"=>"align", "rtl"=>"dir", "submit"=>"type", "text"=>"type", "top"=>"align"}, "h2"=> {"center"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir", "right"=>"align", "rtl"=>"dir"}, "abbr"=>{"ltr"=>"dir", "rtl"=>"dir"}, "h3"=> {"center"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir", "right"=>"align", "rtl"=>"dir"}, "strike"=>{"ltr"=>"dir", "rtl"=>"dir"}, "body"=>{"ltr"=>"dir", "rtl"=>"dir"}, "ins"=>{"ltr"=>"dir", "rtl"=>"dir"}, "button"=> {"button"=>"type", "disabled"=>"disabled", "ltr"=>"dir", "reset"=>"type", "rtl"=>"dir", "submit"=>"type"}, "h4"=> {"center"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir", "right"=>"align", "rtl"=>"dir"}, "select"=> {"disabled"=>"disabled", "ltr"=>"dir", "multiple"=>"multiple", "rtl"=>"dir"}, "caption"=> {"bottom"=>"align", "left"=>"align", "ltr"=>"dir", "right"=>"align", "rtl"=>"dir", "top"=>"align"}, "colgroup"=> {"baseline"=>"valign", "bottom"=>"valign", "center"=>"align", "char"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir", "middle"=>"valign", "right"=>"align", "rtl"=>"dir", "top"=>"valign"}, "tr"=> {"baseline"=>"valign", "bottom"=>"valign", "center"=>"align", "char"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir", "middle"=>"valign", "right"=>"align", "rtl"=>"dir", "top"=>"valign"}, "del"=>{"ltr"=>"dir", "rtl"=>"dir"}, "h5"=> {"center"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir", "right"=>"align", "rtl"=>"dir"}, "iframe"=> {"0"=>"frameborder", "1"=>"frameborder", "auto"=>"scrolling", "bottom"=>"align", "left"=>"align", "middle"=>"align", "no"=>"scrolling", "right"=>"align", "top"=>"align", "yes"=>"scrolling"}}
- EmptyBindingObject =
:stopdoc:
Object.new
Class Method Summary collapse
- .build_node(structure, is_xml, is_html, inherited_context = DefaultContext) ⇒ Object
-
.compile_template(template_string) ⇒ Object
call-seq: HTree.compile_template(template_string) -> module.
-
.expand_template(*args, &block) ⇒ Object
call-seq: HTree.expand_template(template_pathname, obj=Object.new, out=$stdout, encoding=internal_encoding) -> out HTree.expand_template(out=$stdout, encoding=internal_encoding) { template_string } -> out.
- .fix_element(elem, excluded_tags, included_tags, is_xml, is_html) ⇒ Object
- .fix_structure_list(structure_list, is_xml, is_html) ⇒ Object
- .frozen_string(str) ⇒ Object
-
.parse(input) ⇒ Object
HTree.parse parses input and return a document tree.
-
.parse_as(input, is_xml) ⇒ Object
:stopdoc:.
- .parse_pairs(tokens, is_xml, is_html) ⇒ Object
-
.parse_xml(input) ⇒ Object
HTree.parse_xml parses input as XML and return a document tree represented by HTree::Doc.
- .scan(input, is_xml = false) ⇒ Object
-
.with_frozen_string_hash ⇒ Object
:stopdoc:.
Instance Method Summary collapse
-
#==(other) ⇒ Object
(also: #eql?)
compare tree structures.
- #check_equality(obj1, obj2, equal_object_method) ⇒ Object
- #exact_equal?(other) ⇒ Boolean
- #exact_equal_object ⇒ Object
-
#hash ⇒ Object
hash value for the tree structure.
- #make_exact_equal_object ⇒ Object
- #make_usual_equal_object ⇒ Object
-
#usual_equal_object ⇒ Object
:stopdoc:.
Class Method Details
.build_node(structure, is_xml, is_html, inherited_context = DefaultContext) ⇒ Object
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 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/htree/parse.rb', line 198 def HTree.build_node(structure, is_xml, is_html, inherited_context=DefaultContext) case structure[0] when :text_pcdata Text.parse_pcdata(structure[1]) when :elem _, stag_rawstring, children, etag_rawstring = structure etag = etag_rawstring && ETag.parse(etag_rawstring, is_xml, is_html) stag = STag.parse(stag_rawstring, true, is_xml, is_html, inherited_context) if !children.empty? || etag || stag.element_name.namespace_uri != 'http://www.w3.org/1999/xhtml' || HTree::ElementContent[stag.element_name.local_name] != :EMPTY Elem.new!(stag, children.map {|c| build_node(c, is_xml, is_html, stag.context) }, etag) else Elem.new!(stag) end when :emptytag Elem.new!(STag.parse(structure[1], false, is_xml, is_html, inherited_context)) when :bogus_etag BogusETag.parse(structure[1], is_xml, is_html) when :xmldecl XMLDecl.parse(structure[1]) when :doctype DocType.parse(structure[1], is_xml, is_html) when :procins ProcIns.parse(structure[1]) when :comment Comment.parse(structure[1]) when :text_cdata_content Text.parse_cdata_content(structure[1]) when :text_cdata_section Text.parse_cdata_section(structure[1]) else raise Exception, "[bug] unknown structure: #{structure.inspect}" end end |
.compile_template(template_string) ⇒ Object
call-seq:
HTree.compile_template(template_string) -> module
HTree.compile_template(template_string)
compiles template_string as a template.
HTree.compile_template returns a module. The module has module functions for each templates defined in template_string. The returned module can be used for include
.
M = HTree.compile_template(<<'End')
<p _template=birthday(subj,t)>
<span _text=subj />'s birthday is <span _text="t.strftime('%B %dth %Y')"/>.
</p>
End
M.birthday('Ruby', Time.utc(1993, 2, 24)).display_xml
# <p>Ruby's birthday is February 24th 1993.</p>
The module function takes arguments specifies by a _template
attribute and returns a tree represented as HTree::Node.
417 418 419 420 421 422 423 424 425 426 |
# File 'lib/htree/template.rb', line 417 def HTree.compile_template(template_string) code = HTree::TemplateCompiler.new.compile_template(template_string) Thread.current[:htree_compile_template_code] = code mod = eval(<<-'End', eval(Thread.current[:htree_compile_template_code]) End HTree::EmptyBindingObject.empty_binding, "(eval:#{__FILE__}:#{__LINE__})") Thread.current[:htree_compile_template_code] = nil mod end |
.expand_template(*args, &block) ⇒ Object
call-seq:
HTree.expand_template(template_pathname, obj=Object.new, out=$stdout, encoding=internal_encoding) -> out
HTree.expand_template(out=$stdout, encoding=internal_encoding) { template_string } -> out
HTree.expand_template
expands a template.
The arguments should be specified as follows. All argument except pathname are optional.
-
HTree.expand_template(pathname, obj, out, encoding) -> out
-
HTree.expand_template(out, encoding) <em>template_string</em> -> out
The template is specified by a file or a string. If a block is not given, the first argument represent a template pathname. Otherwise, the block is yielded and its value is interpreted as a template string. So it can be called as follows in simplest case.
-
HTree.expand_template(template_pathname)
-
HTree.expand_template<em>template_string</em>
Ruby expressions in the template file specified by template_pathname are evaluated in the context of the optional second argument obj as follows. I.e. the pseudo variable self in the expressions is bound to obj.
HTree.(template_pathname, obj)
Ruby expressions in the template_string are evaluated in the context of the caller of HTree.expand_template. (binding information is specified by the block.) I.e. they can access local variables etc. We recommend to specify template_string as a literal string without interpolation because dynamically generated string may break lexical scope.
HTree.expand_template has two more optional arguments: out, encoding.
out specifies output target. It should have <<
method: IO and String for example. If it is not specified, $stdout is used. If it has a method charset=
, it is called to set the minimal charset of the result before <<
is called.
encoding specifies output character encoding. If it is not specified, internal encoding is used.
HTree.expand_template returns out or $stdout if out is not specified.
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 |
# File 'lib/htree/template.rb', line 341 def HTree.(*args, &block) if block template = block.call binding = block.binding else pathname = args.fetch(0) { raise ArgumentError, "pathname not given" } args.shift obj = args.fetch(0) { Object.new } args.shift if pathname.respond_to? :read template = pathname.read.untaint if template.respond_to? :charset template = Iconv.conv(HTree::Encoder.internal_charset, template.charset, template) end else template = File.read(pathname).untaint end Thread.current[:htree_expand_template_obj] = obj binding = eval(<<-'End', Thread.current[:htree_expand_template_obj].class.class_eval <<-'EE' Thread.current[:htree_expand_template_obj].instance_eval { binding } EE End HTree::EmptyBindingObject.empty_binding, "(eval:#{__FILE__}:#{__LINE__})") Thread.current[:htree_expand_template_obj] = nil end out = args.shift || $stdout encoding = args.shift || HTree::Encoder.internal_charset if !args.empty? raise ArgumentError, "wrong number of arguments" end HTree::TemplateCompiler.new.(template, out, encoding, binding) end |
.fix_element(elem, excluded_tags, included_tags, is_xml, is_html) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/htree/parse.rb', line 146 def HTree.fix_element(elem, , , is_xml, is_html) stag_raw_string = elem[1] children = elem[2] if etag_raw_string = elem[3] return [:elem, stag_raw_string, fix_structure_list(children, is_xml, is_html), etag_raw_string], [] else tagname = stag_raw_string[Pat::Name] tagname = tagname.downcase if !is_xml && is_html if ElementContent[tagname] == :EMPTY return [:elem, stag_raw_string, []], children else if ElementContent[tagname] == :CDATA = [] else = ElementContent[tagname] end if = ElementExclusions[tagname] = ElementInclusions[tagname] |= if |= if = ( | ) - = ElementContent.keys - else # If the tagname is unknown, it is assumed that any element # except excluded can be contained. = end fixed_children = [] rest = children until rest.empty? if rest[0][0] == :elem elem = rest.shift elem_tagname = elem[1][Pat::Name] elem_tagname = elem_tagname.downcase if !is_xml && is_html if .include? elem_tagname rest.unshift elem break else fixed_elem, rest2 = fix_element(elem, , , is_xml, is_html) fixed_children << fixed_elem rest = rest2 + rest end else fixed_children << rest.shift end end return [:elem, stag_raw_string, fixed_children], rest end end end |
.fix_structure_list(structure_list, is_xml, is_html) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/htree/parse.rb', line 130 def HTree.fix_structure_list(structure_list, is_xml, is_html) result = [] rest = structure_list.dup until rest.empty? structure = rest.shift if structure[0] == :elem elem, rest2 = fix_element(structure, [], [], is_xml, is_html) result << elem rest = rest2 + rest else result << structure end end result end |
.frozen_string(str) ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/htree/fstr.rb', line 18 def HTree.frozen_string(str) if h = Thread.current[:htree_frozen_string_hash] if s = h[str] s else str = str.dup.freeze unless str.frozen? h[str] = str end else str = str.dup.freeze unless str.frozen? str end end |
.parse(input) ⇒ Object
HTree.parse parses input and return a document tree. represented by HTree::Doc.
input should be a String or an object which respond to read or open method. For example, IO, StringIO, Pathname, URI::HTTP and URI::FTP are acceptable. Note that the URIs need open-uri.
HTree.parse guesses input is HTML or not and XML or not.
If it is guessed as HTML, the default namespace in the result is set to www.w3.org/1999/xhtml regardless of input has XML namespace declaration or not nor even it is pre-XML HTML.
If it is guessed as HTML and not XML, all element and attribute names are downcaseed.
If opened file or read content has charset method, HTree.parse decode it according to $KCODE before parsing. Otherwise HTree.parse assumes the character encoding of the content is compatible to $KCODE. Note that the charset method is provided by URI::HTTP with open-uri.
34 35 36 37 38 |
# File 'lib/htree/parse.rb', line 34 def HTree.parse(input) HTree.with_frozen_string_hash { parse_as(input, false) } end |
.parse_as(input, is_xml) ⇒ Object
:stopdoc:
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/htree/parse.rb', line 56 def HTree.parse_as(input, is_xml) input_charset = nil if input.tainted? && 1 <= $SAFE raise SecurityError, "input tainted" end if input.respond_to? :read # IO, StringIO input = input.read.untaint input_charset = input.charset if input.respond_to? :charset elsif input.respond_to? :open # Pathname, URI with open-uri input.open {|f| input = f.read.untaint input_charset = f.charset if f.respond_to? :charset } end if input_charset && input_charset != Encoder.internal_charset input = Iconv.conv(Encoder.internal_charset, input_charset, input) end tokens = [] is_xml, is_html = HTree.scan(input, is_xml) {|token| tokens << token } context = is_html ? HTMLContext : DefaultContext structure_list = parse_pairs(tokens, is_xml, is_html) structure_list = fix_structure_list(structure_list, is_xml, is_html) nodes = structure_list.map {|s| build_node(s, is_xml, is_html, context) } Doc.new(nodes) end |
.parse_pairs(tokens, is_xml, is_html) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/htree/parse.rb', line 85 def HTree.parse_pairs(tokens, is_xml, is_html) stack = [[nil, nil, []]] tokens.each {|token| case token[0] when :stag stag_raw_string = token[1] stagname = stag_raw_string[Pat::Name] stagname = stagname.downcase if !is_xml && is_html stagname = HTree.frozen_string(stagname) stack << [stagname, stag_raw_string, []] when :etag etag_raw_string = token[1] etagname = etag_raw_string[Pat::Name] etagname = etagname.downcase if !is_xml && is_html etagname = HTree.frozen_string(etagname) matched_elem = nil stack.reverse_each {|elem| stagname, _, _ = elem if stagname == etagname matched_elem = elem break end } if matched_elem until matched_elem.equal? stack.last stagname, stag_raw_string, children = stack.pop stack.last[2] << [:elem, stag_raw_string, children] end stagname, stag_raw_string, children = stack.pop stack.last[2] << [:elem, stag_raw_string, children, etag_raw_string] else stack.last[2] << [:bogus_etag, etag_raw_string] end else stack.last[2] << token end } elem = nil while 1 < stack.length stagname, stag_raw_string, children = stack.pop stack.last[2] << [:elem, stag_raw_string, children] end stack[0][2] end |
.parse_xml(input) ⇒ Object
HTree.parse_xml parses input as XML and return a document tree represented by HTree::Doc.
It behaves almost same as HTree.parse but it assumes input is XML even if no XML declaration. The assumption causes following differences.
-
doesn’t downcase element name.
-
The content of <script> and <style> element is PCDATA, not CDATA.
48 49 50 51 52 |
# File 'lib/htree/parse.rb', line 48 def HTree.parse_xml(input) HTree.with_frozen_string_hash { parse_as(input, true) } end |
.scan(input, is_xml = false) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/htree/scan.rb', line 68 def HTree.scan(input, is_xml=false) is_html = false cdata_content = nil cdata_content_string = nil pcdata = '' first_element = true index_otherstring = 1 index_str = 2 index_xmldecl = 3 index_doctype = 4 index_xmlprocins = 5 index_quotedstarttag = 6 index_quotedemptytag = 7 index_starttag = 8 index_endtag = 9 index_emptytag = 10 index_comment = 11 index_cdata = 12 index_end = 13 pat = /\G(.*?)((#{Pat::XmlDecl}) |(#{Pat::DocType}) |(#{Pat::XmlProcIns}) |(#{Pat::QuotedStartTag}) |(#{Pat::QuotedEmptyTag}) |(#{Pat::StartTag}) |(#{Pat::EndTag}) |(#{Pat::EmptyTag}) |(#{Pat::Comment}) |(#{Pat::CDATA}) |(\z)) /oxm input.scan(pat) { match = $~ if cdata_content cdata_content_string << match[index_otherstring] str = match[index_str] if match[index_endtag] && str[Pat::Name] == cdata_content unless cdata_content_string.empty? yield [:text_cdata_content, HTree.frozen_string(cdata_content_string)] end yield [:etag, HTree.frozen_string(str)] cdata_content = nil cdata_content_string = nil elsif match[index_end] cdata_content_string << str unless cdata_content_string.empty? yield [:text_cdata_content, HTree.frozen_string(cdata_content_string)] end cdata_content = nil cdata_content_string = nil else cdata_content_string << str end else pcdata << match[index_otherstring] str = match[index_str] if !pcdata.empty? yield [:text_pcdata, HTree.frozen_string(pcdata)] pcdata = '' end if match[index_xmldecl] yield [:xmldecl, HTree.frozen_string(str)] is_xml = true elsif match[index_doctype] Pat::DocType_C =~ str root_element_name = $1 public_identifier = $2 || $3 system_identifier = $4 || $5 is_html = true if /\Ahtml\z/i =~ root_element_name is_xml = true if public_identifier && %r{\A-//W3C//DTD XHTML } =~ public_identifier yield [:doctype, HTree.frozen_string(str)] elsif match[index_xmlprocins] yield [:procins, HTree.frozen_string(str)] elsif match[index_starttag] || match[index_quotedstarttag] yield stag = [:stag, HTree.frozen_string(str)] tagname = str[Pat::Name] if first_element if /\A(?:html|head|title|isindex|base|script|style|meta|link|object)\z/i =~ tagname is_html = true else is_xml = true end first_element = false end if !is_xml && ElementContent[tagname] == :CDATA cdata_content = tagname cdata_content_string = '' end elsif match[index_endtag] yield [:etag, HTree.frozen_string(str)] elsif match[index_emptytag] || match[index_quotedemptytag] yield [:emptytag, HTree.frozen_string(str)] first_element = false #is_xml = true elsif match[index_comment] yield [:comment, HTree.frozen_string(str)] elsif match[index_cdata] yield [:text_cdata_section, HTree.frozen_string(str)] elsif match[index_end] # pass else raise Exception, "unknown match [bug]" end end } return is_xml, is_html end |
.with_frozen_string_hash ⇒ Object
:stopdoc:
5 6 7 8 9 10 11 12 13 14 15 16 |
# File 'lib/htree/fstr.rb', line 5 def HTree.with_frozen_string_hash if Thread.current[:htree_frozen_string_hash] yield else begin Thread.current[:htree_frozen_string_hash] = {} yield ensure Thread.current[:htree_frozen_string_hash] = nil end end end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
compare tree structures.
10 11 12 |
# File 'lib/htree/equality.rb', line 10 def ==(other) check_equality(self, other, :usual_equal_object) end |
#check_equality(obj1, obj2, equal_object_method) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/htree/equality.rb', line 45 def check_equality(obj1, obj2, equal_object_method) return false unless obj1.class == obj2.class if obj1.class == Array return false unless obj1.length == obj2.length obj1.each_with_index {|c1, i| return false unless c1.class == obj2[i].class } obj1.each_with_index {|c1, i| return false unless check_equality(c1, obj2[i], equal_object_method) } true elsif obj1.respond_to? equal_object_method o1 = obj1.send(equal_object_method) o2 = obj2.send(equal_object_method) check_equality(o1, o2, equal_object_method) else obj1 == obj2 end end |
#exact_equal?(other) ⇒ Boolean
41 42 43 |
# File 'lib/htree/equality.rb', line 41 def exact_equal?(other) check_equality(self, other, :exact_equal_object) end |
#exact_equal_object ⇒ Object
32 33 34 35 |
# File 'lib/htree/equality.rb', line 32 def exact_equal_object return @exact_equal_object if defined? @exact_equal_object @exact_equal_object = make_exact_equal_object end |
#hash ⇒ Object
hash value for the tree structure.
16 17 18 19 |
# File 'lib/htree/equality.rb', line 16 def hash return @hash_code if defined? @hash_code @hash_code = usual_equal_object.hash end |
#make_exact_equal_object ⇒ Object
37 38 39 |
# File 'lib/htree/equality.rb', line 37 def make_exact_equal_object raise NotImplementedError end |
#make_usual_equal_object ⇒ Object
28 29 30 |
# File 'lib/htree/equality.rb', line 28 def make_usual_equal_object raise NotImplementedError end |
#usual_equal_object ⇒ Object
:stopdoc:
23 24 25 26 |
# File 'lib/htree/equality.rb', line 23 def usual_equal_object return @usual_equal_object if defined? @usual_equal_object @usual_equal_object = make_usual_equal_object end |