why-hpricot 0.6.201

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. data/CHANGELOG +62 -0
  2. data/COPYING +18 -0
  3. data/README +284 -0
  4. data/Rakefile +259 -0
  5. data/ext/fast_xs/FastXsService.java +1018 -0
  6. data/ext/fast_xs/extconf.rb +4 -0
  7. data/ext/fast_xs/fast_xs.c +200 -0
  8. data/ext/hpricot_scan/HpricotScanService.java +1305 -0
  9. data/ext/hpricot_scan/extconf.rb +6 -0
  10. data/ext/hpricot_scan/hpricot_common.rl +76 -0
  11. data/ext/hpricot_scan/hpricot_css.c +3506 -0
  12. data/ext/hpricot_scan/hpricot_scan.c +6679 -0
  13. data/ext/hpricot_scan/hpricot_scan.h +79 -0
  14. data/ext/hpricot_scan/hpricot_scan.java.rl +373 -0
  15. data/ext/hpricot_scan/hpricot_scan.rl +697 -0
  16. data/extras/mingw-rbconfig.rb +176 -0
  17. data/lib/hpricot.rb +26 -0
  18. data/lib/hpricot/blankslate.rb +63 -0
  19. data/lib/hpricot/builder.rb +215 -0
  20. data/lib/hpricot/elements.rb +510 -0
  21. data/lib/hpricot/htmlinfo.rb +691 -0
  22. data/lib/hpricot/inspect.rb +103 -0
  23. data/lib/hpricot/modules.rb +38 -0
  24. data/lib/hpricot/parse.rb +38 -0
  25. data/lib/hpricot/tag.rb +198 -0
  26. data/lib/hpricot/tags.rb +164 -0
  27. data/lib/hpricot/traverse.rb +838 -0
  28. data/lib/hpricot/xchar.rb +94 -0
  29. data/test/files/basic.xhtml +17 -0
  30. data/test/files/boingboing.html +2266 -0
  31. data/test/files/cy0.html +3653 -0
  32. data/test/files/immob.html +400 -0
  33. data/test/files/pace_application.html +1320 -0
  34. data/test/files/tenderlove.html +16 -0
  35. data/test/files/uswebgen.html +220 -0
  36. data/test/files/utf8.html +1054 -0
  37. data/test/files/week9.html +1723 -0
  38. data/test/files/why.xml +19 -0
  39. data/test/load_files.rb +7 -0
  40. data/test/test_alter.rb +77 -0
  41. data/test/test_builder.rb +37 -0
  42. data/test/test_parser.rb +400 -0
  43. data/test/test_paths.rb +25 -0
  44. data/test/test_preserved.rb +66 -0
  45. data/test/test_xml.rb +28 -0
  46. metadata +107 -0
@@ -0,0 +1,176 @@
1
+
2
+ # This rbconfig.rb corresponds to a Ruby installation for win32 cross-compiled
3
+ # with mingw under i686-linux. It can be used to cross-compile extensions for
4
+ # win32 using said toolchain.
5
+ #
6
+ # This file assumes that a cross-compiled mingw32 build (compatible with the
7
+ # mswin32 builds) is installed under $HOME/ruby-mingw32.
8
+
9
+ module Config
10
+ #RUBY_VERSION == "1.8.5" or
11
+ # raise "ruby lib version (1.8.5) doesn't match executable version (#{RUBY_VERSION})"
12
+
13
+ mingw32 = ENV['MINGW32_RUBY'] || "#{ENV["HOME"]}/ruby-mingw32"
14
+ mingwpre = ENV['MINGW32_PREFIX']
15
+ TOPDIR = File.dirname(__FILE__).chomp!("/lib/ruby/1.8/i386-mingw32")
16
+ DESTDIR = '' unless defined? DESTDIR
17
+ CONFIG = {}
18
+ CONFIG["DESTDIR"] = DESTDIR
19
+ CONFIG["INSTALL"] = "/usr/bin/install -c"
20
+ CONFIG["prefix"] = (TOPDIR || DESTDIR + mingw32)
21
+ CONFIG["EXEEXT"] = ".exe"
22
+ CONFIG["ruby_install_name"] = "ruby"
23
+ CONFIG["RUBY_INSTALL_NAME"] = "ruby"
24
+ CONFIG["RUBY_SO_NAME"] = "msvcrt-ruby18"
25
+ CONFIG["SHELL"] = "/bin/sh"
26
+ CONFIG["PATH_SEPARATOR"] = ":"
27
+ CONFIG["PACKAGE_NAME"] = ""
28
+ CONFIG["PACKAGE_TARNAME"] = ""
29
+ CONFIG["PACKAGE_VERSION"] = ""
30
+ CONFIG["PACKAGE_STRING"] = ""
31
+ CONFIG["PACKAGE_BUGREPORT"] = ""
32
+ CONFIG["exec_prefix"] = "$(prefix)"
33
+ CONFIG["bindir"] = "$(exec_prefix)/bin"
34
+ CONFIG["sbindir"] = "$(exec_prefix)/sbin"
35
+ CONFIG["libexecdir"] = "$(exec_prefix)/libexec"
36
+ CONFIG["datadir"] = "$(prefix)/share"
37
+ CONFIG["sysconfdir"] = "$(prefix)/etc"
38
+ CONFIG["sharedstatedir"] = "$(prefix)/com"
39
+ CONFIG["localstatedir"] = "$(prefix)/var"
40
+ CONFIG["libdir"] = "$(exec_prefix)/lib"
41
+ CONFIG["includedir"] = "$(prefix)/include"
42
+ CONFIG["oldincludedir"] = "/usr/include"
43
+ CONFIG["infodir"] = "$(prefix)/info"
44
+ CONFIG["mandir"] = "$(prefix)/man"
45
+ CONFIG["build_alias"] = "i686-linux"
46
+ CONFIG["host_alias"] = "#{mingwpre}"
47
+ CONFIG["target_alias"] = "i386-mingw32"
48
+ CONFIG["ECHO_C"] = ""
49
+ CONFIG["ECHO_N"] = "-n"
50
+ CONFIG["ECHO_T"] = ""
51
+ CONFIG["LIBS"] = "-lwsock32 "
52
+ CONFIG["MAJOR"] = "1"
53
+ CONFIG["MINOR"] = "8"
54
+ CONFIG["TEENY"] = "4"
55
+ CONFIG["build"] = "i686-pc-linux"
56
+ CONFIG["build_cpu"] = "i686"
57
+ CONFIG["build_vendor"] = "pc"
58
+ CONFIG["build_os"] = "linux"
59
+ CONFIG["host"] = "i586-pc-mingw32msvc"
60
+ CONFIG["host_cpu"] = "i586"
61
+ CONFIG["host_vendor"] = "pc"
62
+ CONFIG["host_os"] = "mingw32msvc"
63
+ CONFIG["target"] = "i386-pc-mingw32"
64
+ CONFIG["target_cpu"] = "i386"
65
+ CONFIG["target_vendor"] = "pc"
66
+ CONFIG["target_os"] = "mingw32"
67
+ CONFIG["CC"] = "#{mingwpre}-gcc"
68
+ CONFIG["CFLAGS"] = "-g -O2 "
69
+ CONFIG["LDFLAGS"] = ""
70
+ CONFIG["CPPFLAGS"] = ""
71
+ CONFIG["OBJEXT"] = "o"
72
+ CONFIG["CPP"] = "#{mingwpre}-gcc -E"
73
+ CONFIG["EGREP"] = "grep -E"
74
+ CONFIG["GNU_LD"] = "yes"
75
+ CONFIG["CPPOUTFILE"] = "-o conftest.i"
76
+ CONFIG["OUTFLAG"] = "-o "
77
+ CONFIG["YACC"] = "bison -y"
78
+ CONFIG["RANLIB"] = "#{mingwpre}-ranlib"
79
+ CONFIG["AR"] = "#{mingwpre}-ar"
80
+ CONFIG["NM"] = "#{mingwpre}-nm"
81
+ CONFIG["WINDRES"] = "#{mingwpre}-windres"
82
+ CONFIG["DLLWRAP"] = "#{mingwpre}-dllwrap"
83
+ CONFIG["OBJDUMP"] = "#{mingwpre}-objdump"
84
+ CONFIG["LN_S"] = "ln -s"
85
+ CONFIG["SET_MAKE"] = ""
86
+ CONFIG["INSTALL_PROGRAM"] = "$(INSTALL)"
87
+ CONFIG["INSTALL_SCRIPT"] = "$(INSTALL)"
88
+ CONFIG["INSTALL_DATA"] = "$(INSTALL) -m 644"
89
+ CONFIG["RM"] = "rm -f"
90
+ CONFIG["CP"] = "cp"
91
+ CONFIG["MAKEDIRS"] = "mkdir -p"
92
+ CONFIG["LIBOBJS"] = " fileblocks$(U).o crypt$(U).o flock$(U).o acosh$(U).o win32$(U).o"
93
+ CONFIG["ALLOCA"] = ""
94
+ CONFIG["DLDFLAGS"] = " -Wl,--enable-auto-import,--export-all"
95
+ CONFIG["ARCH_FLAG"] = ""
96
+ CONFIG["STATIC"] = ""
97
+ CONFIG["CCDLFLAGS"] = ""
98
+ CONFIG["LDSHARED"] = "#{mingwpre}-gcc -shared -s"
99
+ CONFIG["DLEXT"] = "so"
100
+ CONFIG["DLEXT2"] = "dll"
101
+ CONFIG["LIBEXT"] = "a"
102
+ CONFIG["LINK_SO"] = ""
103
+ CONFIG["LIBPATHFLAG"] = " -L\"%s\""
104
+ CONFIG["RPATHFLAG"] = ""
105
+ CONFIG["LIBPATHENV"] = ""
106
+ CONFIG["TRY_LINK"] = ""
107
+ CONFIG["STRIP"] = "strip"
108
+ CONFIG["EXTSTATIC"] = ""
109
+ CONFIG["setup"] = "Setup"
110
+ CONFIG["MINIRUBY"] = "ruby -rfake"
111
+ CONFIG["PREP"] = "fake.rb"
112
+ CONFIG["RUNRUBY"] = "$(MINIRUBY) -I`cd $(srcdir)/lib; pwd`"
113
+ CONFIG["EXTOUT"] = ".ext"
114
+ CONFIG["ARCHFILE"] = ""
115
+ CONFIG["RDOCTARGET"] = ""
116
+ CONFIG["XCFLAGS"] = " -DRUBY_EXPORT"
117
+ CONFIG["XLDFLAGS"] = " -Wl,--stack,0x02000000 -L."
118
+ CONFIG["LIBRUBY_LDSHARED"] = "#{mingwpre}-gcc -shared -s"
119
+ CONFIG["LIBRUBY_DLDFLAGS"] = " -Wl,--enable-auto-import,--export-all -Wl,--out-implib=$(LIBRUBY)"
120
+ CONFIG["rubyw_install_name"] = "rubyw"
121
+ CONFIG["RUBYW_INSTALL_NAME"] = "rubyw"
122
+ CONFIG["LIBRUBY_A"] = "lib$(RUBY_SO_NAME)-static.a"
123
+ CONFIG["LIBRUBY_SO"] = "$(RUBY_SO_NAME).dll"
124
+ CONFIG["LIBRUBY_ALIASES"] = ""
125
+ CONFIG["LIBRUBY"] = "lib$(LIBRUBY_SO).a"
126
+ CONFIG["LIBRUBYARG"] = "$(LIBRUBYARG_SHARED)"
127
+ CONFIG["LIBRUBYARG_STATIC"] = "-l$(RUBY_SO_NAME)-static"
128
+ CONFIG["LIBRUBYARG_SHARED"] = "-l$(RUBY_SO_NAME)"
129
+ CONFIG["SOLIBS"] = "$(LIBS)"
130
+ CONFIG["DLDLIBS"] = ""
131
+ CONFIG["ENABLE_SHARED"] = "yes"
132
+ CONFIG["MAINLIBS"] = ""
133
+ CONFIG["COMMON_LIBS"] = "m"
134
+ CONFIG["COMMON_MACROS"] = ""
135
+ CONFIG["COMMON_HEADERS"] = "windows.h winsock.h"
136
+ CONFIG["EXPORT_PREFIX"] = ""
137
+ CONFIG["MINIOBJS"] = "dmydln.o"
138
+ CONFIG["MAKEFILES"] = "Makefile GNUmakefile"
139
+ CONFIG["arch"] = "i386-mingw32"
140
+ CONFIG["sitearch"] = "i386-msvcrt"
141
+ CONFIG["sitedir"] = "$(prefix)/lib/ruby/site_ruby"
142
+ CONFIG["configure_args"] = "'--host=#{mingwpre}' '--target=i386-mingw32' '--build=i686-linux' '--prefix=#{mingw32}' 'build_alias=i686-linux' 'host_alias=#{mingwpre}' 'target_alias=i386-mingw32'"
143
+ CONFIG["NROFF"] = "/usr/bin/nroff"
144
+ CONFIG["MANTYPE"] = "doc"
145
+ CONFIG["LTLIBOBJS"] = " fileblocks$(U).lo crypt$(U).lo flock$(U).lo acosh$(U).lo win32$(U).lo"
146
+ CONFIG["ruby_version"] = "$(MAJOR).$(MINOR)"
147
+ CONFIG["rubylibdir"] = "$(libdir)/ruby/$(ruby_version)"
148
+ CONFIG["archdir"] = "$(rubylibdir)/$(arch)"
149
+ CONFIG["sitelibdir"] = "$(sitedir)/$(ruby_version)"
150
+ CONFIG["sitearchdir"] = "$(sitelibdir)/$(sitearch)"
151
+ CONFIG["topdir"] = File.dirname(__FILE__)
152
+ MAKEFILE_CONFIG = {}
153
+ CONFIG.each{|k,v| MAKEFILE_CONFIG[k] = v.dup}
154
+ def Config::expand(val, config = CONFIG)
155
+ val.gsub!(/\$\$|\$\(([^()]+)\)|\$\{([^{}]+)\}/) do |var|
156
+ if !(v = $1 || $2)
157
+ '$'
158
+ elsif key = config[v = v[/\A[^:]+(?=(?::(.*?)=(.*))?\z)/]]
159
+ pat, sub = $1, $2
160
+ config[v] = false
161
+ Config::expand(key, config)
162
+ config[v] = key
163
+ key = key.gsub(/#{Regexp.quote(pat)}(?=\s|\z)/n) {sub} if pat
164
+ key
165
+ else
166
+ var
167
+ end
168
+ end
169
+ val
170
+ end
171
+ CONFIG.each_value do |val|
172
+ Config::expand(val)
173
+ end
174
+ end
175
+ RbConfig = Config # compatibility for ruby-1.9
176
+ CROSS_COMPILING = nil unless defined? CROSS_COMPILING
data/lib/hpricot.rb ADDED
@@ -0,0 +1,26 @@
1
+ # == About hpricot.rb
2
+ #
3
+ # All of Hpricot's various part are loaded when you use <tt>require 'hpricot'</tt>.
4
+ #
5
+ # * hpricot_scan: the scanner (a C extension for Ruby) which turns an HTML stream into tokens.
6
+ # * hpricot/parse.rb: uses the scanner to sort through tokens and give you back a complete document object.
7
+ # * hpricot/tag.rb: sets up objects for the various types of elements in an HTML document.
8
+ # * hpricot/modules.rb: categorizes the various elements using mixins.
9
+ # * hpricot/traverse.rb: methods for searching documents.
10
+ # * hpricot/elements.rb: methods for dealing with a group of elements as an Hpricot::Elements list.
11
+ # * hpricot/inspect.rb: methods for displaying documents in a readable form.
12
+
13
+ # If available, Nikolai's UTF-8 library will ease use of utf-8 documents.
14
+ # See http://git.bitwi.se/ruby-character-encodings.git/.
15
+ begin
16
+ require 'encoding/character/utf-8'
17
+ rescue LoadError
18
+ end
19
+
20
+ require 'hpricot_scan'
21
+ require 'hpricot/tag'
22
+ require 'hpricot/modules'
23
+ require 'hpricot/traverse'
24
+ require 'hpricot/inspect'
25
+ require 'hpricot/parse'
26
+ require 'hpricot/builder'
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+ #--
3
+ # Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
4
+ # All rights reserved.
5
+
6
+ # Permission is granted for use, copying, modification, distribution,
7
+ # and distribution of modified versions of this work as long as the
8
+ # above copyright notice is included.
9
+ #++
10
+
11
+ module Hpricot
12
+
13
+ # BlankSlate provides an abstract base class with no predefined
14
+ # methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
15
+ # BlankSlate is useful as a base class when writing classes that
16
+ # depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
17
+ class BlankSlate
18
+ class << self
19
+
20
+ # Hide the method named +name+ in the BlankSlate class. Don't
21
+ # hide +instance_eval+ or any method beginning with "__".
22
+ def hide(name)
23
+ undef_method name if
24
+ instance_methods.include?(name.to_s) and
25
+ name !~ /^(__|instance_eval)/
26
+ end
27
+ end
28
+
29
+ instance_methods.each { |m| hide(m) }
30
+ end
31
+ end
32
+
33
+ # Since Ruby is very dynamic, methods added to the ancestors of
34
+ # BlankSlate <em>after BlankSlate is defined</em> will show up in the
35
+ # list of available BlankSlate methods. We handle this by defining a
36
+ # hook in the Object and Kernel classes that will hide any defined
37
+ module Kernel
38
+ class << self
39
+ alias_method :hpricot_slate_method_added, :method_added
40
+
41
+ # Detect method additions to Kernel and remove them in the
42
+ # BlankSlate class.
43
+ def method_added(name)
44
+ hpricot_slate_method_added(name)
45
+ return if self != Kernel
46
+ Hpricot::BlankSlate.hide(name)
47
+ end
48
+ end
49
+ end
50
+
51
+ class Object
52
+ class << self
53
+ alias_method :hpricot_slate_method_added, :method_added
54
+
55
+ # Detect method additions to Object and remove them in the
56
+ # BlankSlate class.
57
+ def method_added(name)
58
+ hpricot_slate_method_added(name)
59
+ return if self != Object
60
+ Hpricot::BlankSlate.hide(name)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,215 @@
1
+ require 'hpricot/tags'
2
+ require 'fast_xs'
3
+ require 'hpricot/blankslate'
4
+ require 'hpricot/htmlinfo'
5
+
6
+ module Hpricot
7
+ # XML unescape
8
+ def self.uxs(str)
9
+ str.to_s.
10
+ gsub(/\&(\w+);/) { [NamedCharacters[$1] || ??].pack("U*") }.
11
+ gsub(/\&\#(\d+);/) { [$1.to_i].pack("U*") }
12
+ end
13
+
14
+ def self.build(ele = Doc.new, assigns = {}, &blk)
15
+ ele.extend Builder
16
+ assigns.each do |k, v|
17
+ ele.instance_variable_set("@#{k}", v)
18
+ end
19
+ ele.instance_eval(&blk)
20
+ ele
21
+ end
22
+
23
+ module Builder
24
+
25
+ @@default = {
26
+ :indent => 0,
27
+ :output_helpers => true,
28
+ :output_xml_instruction => true,
29
+ :output_meta_tag => true,
30
+ :auto_validation => true,
31
+ :tagset => Hpricot::XHTMLTransitional,
32
+ :root_attributes => {
33
+ :xmlns => 'http://www.w3.org/1999/xhtml', :'xml:lang' => 'en', :lang => 'en'
34
+ }
35
+ }
36
+
37
+ def self.set(option, value)
38
+ @@default[option] = value
39
+ end
40
+
41
+ def add_child ele
42
+ ele.parent = self
43
+ (self.children ||= []) << ele
44
+ ele
45
+ end
46
+
47
+ # Write a +string+ to the HTML stream, making sure to escape it.
48
+ def text!(string)
49
+ add_child Text.new(string.fast_xs)
50
+ end
51
+
52
+ # Write a +string+ to the HTML stream without escaping it.
53
+ def text(string)
54
+ add_child Text.new(string)
55
+ nil
56
+ end
57
+ alias_method :<<, :text
58
+ alias_method :concat, :text
59
+
60
+ # Create a tag named +tag+. Other than the first argument which is the tag name,
61
+ # the arguments are the same as the tags implemented via method_missing.
62
+ def tag!(tag, *args, &block)
63
+ ele_id = nil
64
+ if @auto_validation and @tagset
65
+ if !@tagset.tagset.has_key?(tag)
66
+ raise InvalidXhtmlError, "no element `#{tag}' for #{tagset.doctype}"
67
+ elsif args.last.respond_to?(:to_hash)
68
+ attrs = args.last.to_hash
69
+
70
+ if @tagset.forms.include?(tag) and attrs[:id]
71
+ attrs[:name] ||= attrs[:id]
72
+ end
73
+
74
+ attrs.each do |k, v|
75
+ atname = k.to_s.downcase.intern
76
+ unless k =~ /:/ or @tagset.tagset[tag].include? atname
77
+ raise InvalidXhtmlError, "no attribute `#{k}' on #{tag} elements"
78
+ end
79
+ if atname == :id
80
+ ele_id = v.to_s
81
+ if @elements.has_key? ele_id
82
+ raise InvalidXhtmlError, "id `#{ele_id}' already used (id's must be unique)."
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ # turn arguments into children or attributes
90
+ childs = []
91
+ attrs = args.grep(Hash)
92
+ childs.concat((args - attrs).flatten.map do |x|
93
+ if x.respond_to? :to_html
94
+ Hpricot.make(x.to_html)
95
+ elsif x
96
+ Text.new(x.fast_xs)
97
+ end
98
+ end.flatten)
99
+ attrs = attrs.inject({}) do |hsh, ath|
100
+ ath.each do |k, v|
101
+ hsh[k] = v.to_s.fast_xs if v
102
+ end
103
+ hsh
104
+ end
105
+
106
+ # create the element itself
107
+ tag = tag.to_s
108
+ f = Elem.new(tag, attrs, childs, ETag.new(tag))
109
+
110
+ # build children from the block
111
+ if block
112
+ build(f, &block)
113
+ end
114
+
115
+ add_child f
116
+ f
117
+ end
118
+
119
+ def build(*a, &b)
120
+ Hpricot.build(*a, &b)
121
+ end
122
+
123
+ # Every HTML tag method goes through an html_tag call. So, calling <tt>div</tt> is equivalent
124
+ # to calling <tt>html_tag(:div)</tt>. All HTML tags in Hpricot's list are given generated wrappers
125
+ # for this method.
126
+ #
127
+ # If the @auto_validation setting is on, this method will check for many common mistakes which
128
+ # could lead to invalid XHTML.
129
+ def html_tag(sym, *args, &block)
130
+ if @auto_validation and @tagset.self_closing.include?(sym) and block
131
+ raise InvalidXhtmlError, "the `#{sym}' element is self-closing, please remove the block"
132
+ elsif args.empty? and block.nil?
133
+ CssProxy.new(self, sym)
134
+ else
135
+ tag!(sym, *args, &block)
136
+ end
137
+ end
138
+
139
+ XHTMLTransitional.tags.each do |k|
140
+ class_eval %{
141
+ def #{k}(*args, &block)
142
+ html_tag(#{k.inspect}, *args, &block)
143
+ end
144
+ }
145
+ end
146
+
147
+ def doctype(target, pub, sys)
148
+ add_child DocType.new(target, pub, sys)
149
+ end
150
+
151
+ remove_method :head
152
+
153
+ # Builds a head tag. Adds a <tt>meta</tt> tag inside with Content-Type
154
+ # set to <tt>text/html; charset=utf-8</tt>.
155
+ def head(*args, &block)
156
+ tag!(:head, *args) do
157
+ tag!(:meta, "http-equiv" => "Content-Type", "content" => "text/html; charset=utf-8") if @output_meta_tag
158
+ instance_eval(&block)
159
+ end
160
+ end
161
+
162
+ # Builds an html tag. An XML 1.0 instruction and an XHTML 1.0 Transitional doctype
163
+ # are prepended. Also assumes <tt>:xmlns => "http://www.w3.org/1999/xhtml",
164
+ # :lang => "en"</tt>.
165
+ def xhtml_transitional(attrs = {}, &block)
166
+ # self.tagset = Hpricot::XHTMLTransitional
167
+ xhtml_html(attrs, &block)
168
+ end
169
+
170
+ # Builds an html tag with XHTML 1.0 Strict doctype instead.
171
+ def xhtml_strict(attrs = {}, &block)
172
+ # self.tagset = Hpricot::XHTMLStrict
173
+ xhtml_html(attrs, &block)
174
+ end
175
+
176
+ private
177
+
178
+ def xhtml_html(attrs = {}, &block)
179
+ instruct! if @output_xml_instruction
180
+ doctype(:html, *@@default[:tagset].doctype)
181
+ tag!(:html, @@default[:root_attributes].merge(attrs), &block)
182
+ end
183
+
184
+ end
185
+
186
+ # Class used by Markaby::Builder to store element options. Methods called
187
+ # against the CssProxy object are added as element classes or IDs.
188
+ #
189
+ # See the README for examples.
190
+ class CssProxy < BlankSlate
191
+
192
+ # Creates a CssProxy object.
193
+ def initialize(builder, sym)
194
+ @builder, @sym, @attrs = builder, sym, {}
195
+ end
196
+
197
+ # Adds attributes to an element. Bang methods set the :id attribute.
198
+ # Other methods add to the :class attribute.
199
+ def method_missing(id_or_class, *args, &block)
200
+ if (idc = id_or_class.to_s) =~ /!$/
201
+ @attrs[:id] = $`
202
+ else
203
+ @attrs[:class] = @attrs[:class].nil? ? idc : "#{@attrs[:class]} #{idc}".strip
204
+ end
205
+
206
+ if block or args.any?
207
+ args.push(@attrs)
208
+ return @builder.tag!(@sym, *args, &block)
209
+ end
210
+
211
+ return self
212
+ end
213
+
214
+ end
215
+ end