Commits

Anonymous committed 834eaba

Add support for <programlisting>

In the process had to fix the handling of entities in XML-Grammar-Fiction.

Comments (0)

Files changed (15)

perl/modules/XML-Grammar-Fiction/Changes

 Revision history for XML-Grammar-Fiction.
 
+    * Add support for the <programinglisting> tag.
+    * Fix the handling of the entities ("&amp;" "&#32;" etc.) in Fiction-Text.
+
 0.4.1       Sat May 21 19:45:56 IDT 2011
     * Properly handling whitespace after a closing tag in the Fiction-Text
     proto-text. Like:

perl/modules/XML-Grammar-Fiction/MANIFEST

 t/fiction/data/docbook/sections-p-b-i-comments.docbook.xml
 t/fiction/data/docbook/with-blockquote.docbook.xml
 t/fiction/data/docbook/with-internal-description.docbook.xml
+t/fiction/data/docbook/with-programlisting.docbook.xml
 t/fiction/data/docbook/with-ul-ol-li.docbook.xml
 t/fiction/data/proto-text/dialogue-with-several-paragraphs.txt
 t/fiction/data/proto-text-invalid/inner-desc-inside-char-addressing.txt
 t/fiction/data/proto-text/with-internal-description.txt
 t/fiction/data/proto-text/with-multi-line-comments.txt
 t/fiction/data/proto-text/with-multi-para-desc.txt
+t/fiction/data/proto-text/with-programlisting.txt
 t/fiction/data/proto-text/with-tags-inside-paragraphs.txt
 t/fiction/data/proto-text/with-ul-ol-li.txt
 t/fiction/data/xml/dialogue-with-several-paragraphs.xml
 t/fiction/data/xml/with-entities.xml
 t/fiction/data/xml/with-multi-line-comments.xml
 t/fiction/data/xml/with-multi-para-desc.xml
+t/fiction/data/xml/with-programlisting.xml
 t/fiction/data/xml/with-tags-inside-paragraphs.xml
 t/fiction/data/xml/with-ul-ol-li.xml
 t/fiction/proto-text-invalid.t

perl/modules/XML-Grammar-Fiction/extradata/fiction-xml-to-docbook.xslt

             </xsl:choose> 
         </title>
     </info>
-        <xsl:apply-templates select="fic:section|fic:blockquote|fic:p|fic:ol|fic:ul" />
+        <xsl:apply-templates select="fic:section|fic:blockquote|fic:p|fic:ol|fic:ul|fic:programlisting" />
     </section>
 </xsl:template>
 
     </itemizedlist>
 </xsl:template>
 
+<xsl:template match="fic:programlisting">
+    <programlisting>
+        <xsl:apply-templates/>
+    </programlisting>
+</xsl:template>
+
 <xsl:template match="fic:li">
     <listitem>
         <xsl:apply-templates/>

perl/modules/XML-Grammar-Fiction/extradata/fiction-xml.rng

                 <ref name="para"/>
                 <ref name="ol"/>
                 <ref name="ul"/>
+                <ref name="programlisting"/>
             </choice>
         </zeroOrMore>
     </define>
             <text />
         </element>
     </define>
+    <define name="programlisting">
+        <element name="fic:programlisting">
+            <text />
+        </element>
+    </define>
 </grammar>
 

perl/modules/XML-Grammar-Fiction/lib/XML/Grammar/Fiction/Err.pm

         {
             isa => "XML::Grammar::Fiction::Err::Parse::LineError",
         },
+        "XML::Grammar::Fiction::Err::Parse::ProgramListingContainsTags" =>
+        {
+            isa => "XML::Grammar::Fiction::Err::Parse::LineError",
+        }
     )
     ;
 1;

perl/modules/XML-Grammar-Fiction/lib/XML/Grammar/Fiction/FromProto.pm

     return;
 }
 
+sub _handle_elem_of_name_programlisting
+{
+    my ($self, $elem) = @_;
+
+    my $throw_found_tag_exception = sub {
+        XML::Grammar::Fiction::Err::Parse::ProgramListingContainsTags->throw(
+            error => "<programlisting> tag cannot contain other tags.",
+            line => $elem->open_line(),
+        );
+    };
+
+    return $self->_output_tag(
+        {
+            start => ['programlisting'],
+            elem => $elem,
+            'in' => sub {
+                foreach my $child (@{ $elem->_get_childs() })
+                {
+                    if ($child->_short_isa("Paragraph"))
+                    {
+                        foreach my $text_node (
+                            @{ $child->children()->contents() }
+                        )
+                        {
+                            if ($text_node->_short_isa("Text"))
+                            {
+                                $self->_write_elem({elem => $text_node});
+                            }
+                            else
+                            {
+                                $throw_found_tag_exception->();
+                            }
+                        }
+                    }
+                    else
+                    {
+                        $throw_found_tag_exception->();
+                    }
+                    # End of paragraph.
+                    $self->_writer->characters("\n\n");
+                }
+
+                return;
+            },
+        }
+    );
+
+    return;
+}
+
 sub _handle_elem_of_name_ol
 {
     my ($self, $elem) = @_;

perl/modules/XML-Grammar-Fiction/lib/XML/Grammar/Fiction/FromProto/Nodes.pm

 
 has 'name' => (isa => 'Str', is => 'rw');
 has 'attrs' => (isa => 'ArrayRef', is => 'rw');
+has 'open_line' => (isa => 'Maybe[Int]', is => 'rw');
 
 sub lookup_attr
 {

perl/modules/XML-Grammar-Fiction/lib/XML/Grammar/Fiction/FromProto/Parser/QnD.pm

 our $VERSION = '0.4.1';
 
 sub _non_tag_text_unit_consume_regex {
-    return qr{(?:\<|^\n?$)}ms;
+    return qr{(?:[\<\&]|^\n?$)}ms;
 }
 
 sub _generate_non_tag_text_event
     my $is_para = ($self->curr_pos() == 0);
 
     my $status = $self->_parse_non_tag_text_unit();
+
+    if (!defined($status))
+    {
+        return;
+    }
+
     my $elem = $status->{'elem'};
     my $is_para_end = $status->{'para_end'};
 
         $in_para = 1;
     }
 
+    # This is an assert / sanity check.
+    if (!defined($elem))
+    {
+        Carp::confess ('$elem is undefined');
+    }
+
     $self->_enqueue_event(
         XML::Grammar::Fiction::Event->new(
             {type => "elem", elem => $elem}

perl/modules/XML-Grammar-Fiction/lib/XML/Grammar/Fiction/FromProto/Parser/XmlIterator.pm

                 name => $open->name(),
                 children => $children,
                 attrs => $open->attrs(),
+                open_line => $open->line(),
             }
         );
 }
         Carp::confess (qq{Para contains a saying.});
     }
 
+    # This is an assert
+    if (List::MoreUtils::any 
+        { !defined($_) }
+        @{$contents || []}
+        )
+    {
+        Carp::confess (qq{Para contains an undef member.});
+    }
+
 
     return $self->_new_node(
         {

perl/modules/XML-Grammar-Fiction/lib/XML/Grammar/Fiction/Struct/Tag.pm

 {
     my ($self, $children) = @_;
 
+    # This is an assert / sanity check.
+    if (List::MoreUtils::any { !defined ($_) } @$children)
+    {
+        Carp::confess("append_children with undef.");
+    }
+
     push @{$self->children()}, @$children;
 
     return;

perl/modules/XML-Grammar-Fiction/t/fiction/data/docbook/with-programlisting.docbook.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<article xmlns="http://docbook.org/ns/docbook" xmlns:fic="http://web-cpan.berlios.de/modules/XML-Grammar-Fortune/fiction-xml-0.2/" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="index" xml:lang="">
+  <info>
+    <title>David vs. Goliath - Part I</title>
+  </info>
+  <section xml:id="top">
+    <info>
+      <title>The Top Section</title>
+    </info>
+    <para>
+    David and Goliath were standing by each other.    
+    </para>
+    <para>
+    David said unto Goliath: "I will shoot you. I <emphasis role="bold">swear</emphasis> I will"
+    </para>
+    <section xml:id="goliath">
+      <info>
+        <title>Goliath's Response</title>
+      </info>
+      <para>
+    Goliath was not amused.
+    </para>
+      <para>
+    He said to David: "Oh, really. <emphasis>David</emphasis>, the red-headed!".
+    </para>
+    <programlisting>
+
+print "Foo Bar Baz\n";
+for (i=0;i&lt;4;i++)
+{
+   print "Foo $i\n";
+}
+
+    </programlisting>
+
+    </section>
+  </section>
+</article>

perl/modules/XML-Grammar-Fiction/t/fiction/data/proto-text/with-programlisting.txt

+<body id="index">
+
+<title>David vs. Goliath - Part I</title>
+
+<s id="top">
+
+<title>The Top Section</title>
+
+David and Goliath were standing by each other.    
+
+David said unto Goliath: "I will shoot you. I <b>swear</b> I will"
+
+<s id="goliath">
+
+<title>Goliath's Response</title>
+
+Goliath was not amused.
+
+He said to David: "Oh, really. <i>David</i>, the red-headed!".
+
+<programlisting>
+
+print "Foo Bar Baz\n";
+for (i=0;i&lt;4;i++)
+{
+&#32;&#32;&#32;&#32;print "Foo $i\n";
+}
+
+</programlisting>
+
+</s>
+
+</s>
+
+</body>
+

perl/modules/XML-Grammar-Fiction/t/fiction/data/xml/with-programlisting.xml

+<?xml version='1.0' encoding='utf-8'?>
+<document xmlns="http://web-cpan.berlios.de/modules/XML-Grammar-Fortune/fiction-xml-0.2/" version="0.2">
+    <head>
+    </head>
+    <body xml:id="index">
+    <title>David vs. Goliath - Part I</title>
+    <section xml:id="top">
+    <title>The Top Section</title>
+    <p>
+    David and Goliath were standing by each other.    
+    </p>
+    <p>
+    David said unto Goliath: "I will shoot you. I <b>swear</b> I will"
+    </p>
+    <section xml:id="goliath">
+    <title>Goliath's Response</title>
+    <p>
+    Goliath was not amused.
+    </p>
+    <p>
+    He said to David: "Oh, really. <i>David</i>, the red-headed!".
+    </p>
+<programlisting>
+
+print "Foo Bar Baz\n";
+for (i=0;i&lt;4;i++)
+{
+   print "Foo $i\n";
+}
+
+</programlisting>
+    </section>
+    </section>
+</body>
+</document>

perl/modules/XML-Grammar-Fiction/t/fiction/proto-text-to-xml-using-custom-parser.t

 use strict;
 use warnings;
 
-use Test::More tests => 13;
+use Test::More tests => 15;
 
 use Test::XML;
 
     sections-a-href
     with-ul-ol-li
     with-blockquote
+    with-programlisting
     ));
 
-# TEST:$num_texts=6
+# TEST:$num_texts=7
 
 my $grammar = XML::Grammar::Fiction::FromProto->new({
         parser_class => "XML::Grammar::Fiction::FromProto::Parser::QnD",

perl/modules/XML-Grammar-Fiction/t/fiction/to-docbook.t

 
 use Test::More;
 
-use Test::XML tests => 15;
+use Test::XML tests => 18;
 
 use File::Spec;
 
         sections-a-href
         with-ul-ol-li
         with-blockquote
+        with-programlisting
     ));
 
 sub load_xml
     return $contents;
 }
 
-# TEST:$num_texts=5
+# TEST:$num_texts=6
 
 my $converter = XML::Grammar::Fiction::ToDocBook->new({
         data_dir => File::Spec->catdir(File::Spec->curdir(), "extradata"),