Index: trunk/lib/Text/FormBuilder.pm
===================================================================
--- trunk/lib/Text/FormBuilder.pm	(revision 22)
+++ trunk/lib/Text/FormBuilder.pm	(revision 23)
@@ -11,4 +11,11 @@
 use Text::FormBuilder::Parser;
 use CGI::FormBuilder;
+
+# the default options passed to CGI::FormBuilder->new
+my %DEFAULT_OPTIONS = (
+    method => 'GET',
+    javascript => 0,
+    keepextras => 1,
+);
 
 sub new {
@@ -133,10 +140,4 @@
     
     
-    
-
-    
-    # TODO: use lines instead of fields
-    # TODO: change template to do groups
-    
     # TODO: configurable threshold for this
     foreach (@{ $self->{form_spec}{fields} }) {
@@ -144,10 +145,10 @@
     }
     
+
+
+    
     $self->{form} = CGI::FormBuilder->new(
-        method => 'GET',
-        javascript => 0,
-        keepextras => 1,
+        %DEFAULT_OPTIONS,
         title => $self->{form_spec}{title},
-        #fields => [ map { $$_{name} } @{ $self->{form_spec}{fields} } ],
         template => {
             type => 'Text',
@@ -171,8 +172,4 @@
     $self->{built} = 1;
     
-    # TEMP: dump @lines structure
-    use YAML;
-    warn YAML::Dump($self->{form_spec}->{lines}), "\n";
-    
     return $self;
 }
@@ -215,12 +212,32 @@
     
     my $headings    = Data::Dumper->Dump([$self->{form_spec}{headings}],['headings']);
+    my $lines       = Data::Dumper->Dump([$self->{form_spec}{lines}],['lines']);
     my $fields      = Data::Dumper->Dump([ [ map { $$_{name} } @{ $self->{form_spec}{fields} } ] ],['fields']);
     
-    my %options = %{ $self->{build_options} };
+    my %options = (
+        %DEFAULT_OPTIONS,
+        title => $self->{form_spec}{title},
+        template => {
+            type => 'Text',
+            engine => {
+                TYPE       => 'STRING',
+                SOURCE     => $self->{build_options}{form_only} ? $self->_form_template : $self->_template,
+                DELIMITERS => [ qw(<% %>) ],
+            },
+            data => {
+                lines       => $self->{form_spec}{lines},
+                headings    => $self->{form_spec}{headings},
+                author      => $self->{form_spec}{author},
+                description => $self->{form_spec}{description},
+            },
+        }, 
+        %{ $self->{build_options} },
+    );
+    
     my $source = $options{form_only} ? $self->_form_template : $self->_template;
     
     delete $options{form_only};
     
-    my $form_options = keys %options > 0 ? Data::Dumper->Dump([$self->{build_options}],['*options']) : '';
+    my $form_options = keys %options > 0 ? Data::Dumper->Dump([\%options],['*options']) : '';
     
     my $field_setup = join(
@@ -239,23 +256,5 @@
     my \$cgi = shift;
     my \$cgi_form = CGI::FormBuilder->new(
-        method => 'GET',
         params => \$cgi,
-        javascript => 0,
-        keepextras => 1,
-        title => q[$title],
-        fields => $fields,
-        template => {
-            type => 'Text',
-            engine => {
-                TYPE       => 'STRING',
-                SOURCE     => q[$source],
-                DELIMITERS => [ qw(<% %>) ],
-            },
-            data => {
-                headings => $headings,
-                author   => q[$author],
-                description => q[$description],
-            },
-        },
         $form_options
     );
@@ -269,5 +268,5 @@
 1;
 END
-    
+
     my $outfile = (split(/::/, $package))[-1] . '.pm';
     
@@ -299,7 +298,12 @@
 <% (grep { $_->{required} } @fields) ? qq[<p id="instructions">(Required fields are marked in <strong>bold</strong>.)</p>] : '' %>
 <% $start %>
+<%
+    # drop in the hidden fields here
+    $OUT = join("\n", map { $$_{field} } grep { $$_{type} eq 'hidden' } @fields);
+%>
+
 <table>
 
-<% for my $line (@lines) {
+<% TABLE_LINE: for my $line (@lines) {
 
     if ($$line[0] eq 'head') {
@@ -308,4 +312,7 @@
         #TODO: we only need the field names, not the full field spec in the lines strucutre
         local $_ = $field{$$line[1]{name}};
+        # skip hidden fields in the table
+        next TABLE_LINE if $$_{type} eq 'hidden';
+        
         $OUT .= $$_{invalid} ? qq[  <tr class="invalid">] : qq[  <tr>];
         $OUT .= '<th class="label">' . ($$_{required} ? qq[<strong class="required">$$_{label}:</strong>] : "$$_{label}:") . '</th>';
@@ -402,4 +409,8 @@
     $parser->write_module('My::Form');
 
+=head1 REQUIRES
+
+L<Parse::RecDescent>, L<CGI::FormBuilder>, L<Text::Template>
+
 =head1 DESCRIPTION
 
@@ -596,7 +607,10 @@
     text        # the default
     textarea
+    password
+    file
+    checkbox
+    radio
     select
-    radio
-    checkbox
+    hidden
     static
 
@@ -681,13 +695,30 @@
 =head1 TODO
 
+DWIM for single valued checkboxes (e.g. C<moreinfo|Send me more info:checkbox>)
+
+Use the custom message file format for messages in the built in template
+
+C<!section> directive to split up the table into multiple tables, each
+with their own id and (optional) heading
+
+Optional validated fields; marked like C<//EMAIL?>
+
+Better examples in the docs (maybe a standalone or two as well)
+
+Document the defaults that are passed to CGI::FormBuilder
+
 C<!include> directive to include external formspec files
 
-Field groups all on one line in the generated form
-
 Better tests!
 
+=head1 BUGS
+
 =head1 SEE ALSO
 
 L<CGI::FormBuilder>
+
+=head1 THANKS
+
+Thanks to eszpee for pointing out some bugs in the default value parsing.
 
 =head1 AUTHOR
Index: trunk/lib/Text/FormBuilder/grammar
===================================================================
--- trunk/lib/Text/FormBuilder/grammar	(revision 22)
+++ trunk/lib/Text/FormBuilder/grammar	(revision 23)
@@ -164,6 +164,6 @@
 list_var: /@[A-Z_]+/ { $list_var = $item[1] }
 
-option: value display_text(?)
-    { push @options, { $item{value} => $item{'display_text(?)'}[0] } }
+option: (simple_multiword | quoted_string) display_text(?)
+    { push @options, { $item[1] => $item{'display_text(?)'}[0] } }
 
 value: identifier
