Skip to content

Instantly share code, notes, and snippets.

@thinkerbot
Created October 2, 2009 20:25
Show Gist options
  • Save thinkerbot/200088 to your computer and use it in GitHub Desktop.
Save thinkerbot/200088 to your computer and use it in GitHub Desktop.
Simple Forms in Textile
require 'redcloth'
module SimpleForm
include RedCloth::Formatters::HTML
def form(opts)
content = opts[:text].split("<br />")
definition = content.shift
definition =~ /\A\s*(get|post)(.*?)(?:\[(.*)\])?\z/
request_method = $1
action = $2.strip
attrs = []
$3.split(/\s/).collect do |attribute|
unless attribute =~ /\A(\w+):(\w+)\z/
raise "invalid attribute string: #{attrs} (at: #{attribute})"
end
attrs << "#{$1}=\"#{$2}\""
end unless $3.nil?
content = RedCloth.new(content.join("\n")).to(SimpleForm)
"<form#{pba(opts)} request_method=\"#{request_method}\" action=\"#{action}\" #{attrs.join(" ")}>\n#{content}\n</form>"
end
def input(opts)
opts[:type] = 'text'
opts[:text] =~ /\A(.*?)(?:\[(.*)\])?\z/
label = $1.strip
attrs = []
$2.split(/\s/).collect do |attribute|
case attribute
when /\A(id|type|name):(\w+)\z/
opts[$1.to_sym] = $2
when /\A(\w+)(:|=)(\w+)\z/
if $2 == ":"
attrs << "#{$1}=\"#{$3}\""
else
opts[:name] = $1
opts[:value] = $3
end
else raise "invalid attribute string: #{attrs} (at: #{attribute})"
end
end unless $2.nil?
opts[:id] ||= label.downcase
opts[:name] ||= opts[:id]
"<label for=\"#{opts[:id]}\">#{label}</label>\n<input#{pba(opts)} type=\"#{opts[:type]}\" name=\"#{opts[:name]}\" value=\"#{opts[:value]}\" #{attrs.join(" ")}/>\n\n"
end
def button(opts)
"<input type=\"submit\" value=\"#{opts[:text]}\" #{pba(opts)}/>"
end
end
require 'test/unit'
require 'simple_form'
module Helpers
def assert_output_equal(a, b, msg=nil)
a = a[1..-1] if a[0] == ?\n
if a == b
assert true
else
flunk %Q{
#{msg}
==================== expected output ====================
#{whitespace_escape(a)}
======================== but was ========================
#{whitespace_escape(b)}
=========================================================
}
end
end
def whitespace_escape(str)
str.to_s.gsub(/\s/) do |match|
case match
when "\n" then "\\n\n"
when "\t" then "\\t"
when "\r" then "\\r"
when "\f" then "\\f"
else match
end
end
end
end
class SimpleFormTest < Test::Unit::TestCase
include Helpers
def test_simple_form
input = %q{
form(kls#eyed). get url [attr:value]
input. Simple
input. Standard [key=default]
input(klass#alt). With Attributes [type:hidden _method=update]
button. Submit
}
html = %q{
<form class="kls" id="eyed" request_method="get" action="url" attr="value">
<label for="simple">Simple</label>
<input id="simple" type="text" name="simple" value="" />
<label for="standard">Standard</label>
<input id="standard" type="text" name="key" value="default" />
<label for="alt">With Attributes</label>
<input class="klass" id="alt" type="hidden" name="_method" value="update" />
<input type="submit" value="Submit" />
</form>
}.strip
assert_output_equal html, RedCloth.new(input).to(SimpleForm)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment