Index: trunk/lib/Text/FormBuilder.pm
===================================================================
--- trunk/lib/Text/FormBuilder.pm	(revision 46)
+++ trunk/lib/Text/FormBuilder.pm	(revision 50)
@@ -7,5 +7,5 @@
 use vars qw($VERSION @EXPORT);
 
-$VERSION = '0.07_03';
+$VERSION = '0.07';
 @EXPORT = qw(create_form);
 
@@ -30,4 +30,5 @@
 th.label { font-weight: normal; text-align: right; vertical-align: top; }
 td ul { list-style: none; padding-left: 0; margin-left: 0; }
+.note { background: #eee; }
 .sublabel { color: #999; }
 .invalid { background: red; }
@@ -246,24 +247,27 @@
     }
     
+    # get user-defined lists; can't make this conditional because
+    # we need to be able to fall back to CGI::FormBuilder's lists
+    # even if the user didn't define any
+    my %lists = %{ $self->{form_spec}{lists} || {} };
+    
     # substitute in list names
-    if (my %lists = %{ $self->{form_spec}{lists} || {} }) {
-        foreach (@{ $self->{form_spec}{fields} }) {
-            next unless $$_{list};
-            
-            $$_{list} =~ s/^\@//;   # strip leading @ from list var name
-            
-            # a hack so we don't get screwy reference errors
-            if (exists $lists{$$_{list}}) {
-                my @list;
-                push @list, { %$_ } foreach @{ $lists{$$_{list}} };
-                $$_{options} = \@list;
-            } else {
-                # assume that the list name is a builtin 
-                # and let it fall through to CGI::FormBuilder
-                $$_{options} = $$_{list};
-            }
-        } continue {
-            delete $$_{list};
+    foreach (@{ $self->{form_spec}{fields} }) {
+        next unless $$_{list};
+        
+        $$_{list} =~ s/^\@//;   # strip leading @ from list var name
+        
+        # a hack so we don't get screwy reference errors
+        if (exists $lists{$$_{list}}) {
+            my @list;
+            push @list, { %$_ } foreach @{ $lists{$$_{list}} };
+            $$_{options} = \@list;
+        } else {
+            # assume that the list name is a builtin 
+            # and let it fall through to CGI::FormBuilder
+            $$_{options} = $$_{list};
         }
+    } continue {
+        delete $$_{list};
     }
     
@@ -535,4 +539,6 @@
             if ($$line[0] eq 'head') {
                 $OUT .= qq[  <tr><th class="subhead" colspan="2"><h3>$$line[1]</h3></th></tr>\n]
+            } elsif ($$line[0] eq 'note') {
+                $OUT .= qq[  <tr><td class="note" colspan="2">$$line[1]</td></tr>\n]
             } elsif ($$line[0] eq 'field') {
                 local $_ = $field{$$line[1]};
@@ -959,4 +965,8 @@
     
     !head ...
+    
+    !note {
+        ...
+    }
 
 =head2 Directives
@@ -983,5 +993,9 @@
 =item C<!title>
 
+Title of the form.
+
 =item C<!author>
+
+Author of the form.
 
 =item C<!description>
@@ -1001,5 +1015,14 @@
 next to each other.
 
+=item C<!note>
+
+A text note that can be inserted as a row in the form. This is useful for
+special instructions at specific points in a long form.
+
 =back
+
+B<Known BUG:> If you include an odd number of C<'> or C<"> characters in a
+C<!description> or C<!note>, then that directive will mistakenly be skipped.
+This is a bug casued by me taking a shortcut in the parser C<:-/>
 
 =head2 Fields
@@ -1185,4 +1208,8 @@
 =head1 BUGS
 
+Having a single C<'> or C<"> in a C<!description> or C<!note> directive causes that
+directive to get skipped. This is an issue with the C<perl_codeblock> shortcut in
+Parse::RecDescent.
+
 Creating two $parsers in the same script causes the second one to get the data
 from the first one.
@@ -1194,5 +1221,7 @@
 =head1 SEE ALSO
 
-L<CGI::FormBuilder>
+L<http://textformbuilder.berlios.de>
+
+L<CGI::FormBuilder>, L<http://formbuilder.org>
 
 =head1 THANKS
Index: trunk/lib/Text/FormBuilder/grammar
===================================================================
--- trunk/lib/Text/FormBuilder/grammar	(revision 46)
+++ trunk/lib/Text/FormBuilder/grammar	(revision 50)
@@ -25,5 +25,5 @@
 }
 
-form_spec: (list_def | description_def | validate_def | group_def | line)(s)
+form_spec: (list_def | description_def | validate_def | group_def | note | line)(s)
     {
 	# grab the last section, if there is any
@@ -84,4 +84,11 @@
     }
 
+note: '!note' <perl_codeblock>
+    {   
+	(my $note = $item[2]) =~ s/^{\s*|\s*}$//g;
+	push @lines, [ 'note', $note ];
+    }
+
+
 field_line: <skip:'[ \t]*'> ( field | comment | blank ) "\n"
 line: <skip:'[ \t]*'> ( title | author | pattern_def | section_head | heading | group_field | unknown_directive | field | comment | blank ) "\n"
