class Ragex RAGEX_VERSION = "0.2.1" def initialize(out = $stdout) @indent = 0 @do_indent = true @out = out @open_tags = [] put '' + "\n\n" end @@elements = { :html => ['xmlns'], # --------------------------------- head :head => [], :title => [], :meta => ['name', 'content'], :link => ['rel', 'href', 'type'], :base => ['href'], :style => ['type', 'media'], :script => ['type', 'src', 'defer'], :noscript => [], # --------------------------------- body :body => ['class'], :object => ['data', 'type'], :div => ['class'], :span => ['class', 'style'], :img => ['src', 'alt', 'style'], :a => ['href', 'target', 'class'], :abbr => ['title'], :acronym => ['title'], :address => [], :bdo => ['dir'], :kbd => [], # --------------------------------- forms :form => ['action', 'method'], :fieldset => ['class'], :select => ['name', 'disabled', 'multiple', 'size'], :optgroup => ['label', 'disabled'], :option => ['label', 'value', 'selected', 'disabled'], :textarea => ['name', 'rows', 'cols', 'readonly', 'disabled'], :button => ['name', 'type', 'value', 'disabled'], :input => ['name', 'type', 'value'], :label => ['for'] } # --------------------------------- simple elements %w{p strong em small big q blockquote b i sub sup samp cite ins del tt code pre br hr ol ul li dl dt dd h1 h2 h3 h4 h5}.each do |elem| @@elements[elem.to_sym] = ['class', 'id'] end # --------------------------------- undef conflicting builtins (HARDCORE! ;)) @@elements.each_key { |k| eval("undef #{k} if defined? #{k}") } # --------------------------------- implementation alias :oldms :method_missing def method_missing(id, *params, &block) id = id.to_s start_only = id.chomp!("_start") || id.chomp!("_s") || id.chomp!("_open") || id.chomp!("_o") end_only = id.chomp!("_end") || id.chomp!("_e") || id.chomp!("_close") || id.chomp!("_c") id = id.to_sym if(@@elements.has_key?(id)) if !end_only put "\n<#{id}" @do_indent = false if id == :pre params.each_with_index do |p, i| if p.kind_of? Hash p.each { |k, v| put " #{k}=\"#{v}\"" } else put " #{@@elements[id][i]}=\"#{p.to_s}\"" if @@elements[id][i] end end else throw "RAGEX ERROR: closed wrong tag!" if @open_tags.pop != id @do_indent = true if id == :pre put "\n" return end @open_tags << id if start_only if block_given? put ">" @indent += 1 put entitize(instance_eval(&block)) @indent -= 1 put "\n" @do_indent = true if id == :pre else put start_only ? ">" : " />" end else oldms id end end def close throw "RAGEX ERROR: called close(), no tags open!" if @open_tags.size < 1 method_missing(@open_tags.last.to_s + "_e") end def close_all @open_tags.size.times { close } end alias :c :close alias :e :close alias :c_a :close_all alias :e_a :close_all def put(str) return unless str str = str.gsub(/\n/, "\n#{" "*@indent}") if @do_indent @out.print str end alias :t :put def entitize(str) str.gsub(/&/n, '&').gsub(/>/n, '>').gsub(/