Commits

Anonymous committed 84e1dd3

Now supporting to proto-text for sections-p-b-i.

  • Participants
  • Parent commits 5fa2350

Comments (0)

Files changed (5)

perl/modules/XML-Grammar-Fiction/MANIFEST

 t/data/proto-text/nested-s.txt
 t/data/proto-text/scenes-with-titles.txt
 t/data/proto-text/sections-and-paras.txt
+t/data/proto-text/sections-p-b-i.txt
 t/data/proto-text/two-nested-s.txt
 t/data/proto-text/with-brs.txt
 t/data/proto-text/with-comments.txt

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

     {
         $self->_writer->characters($elem);
     }
+    elsif ($elem->isa("XML::Grammar::Fiction::FromProto::Node::Text"))
+    {
+        foreach my $child (@{$elem->_get_childs()})
+        {
+            $self->_write_elem({ elem => $child,},);
+        }
+    }
     elsif ($elem->isa("XML::Grammar::Fiction::FromProto::Node::Paragraph"))
     {
         $self->_output_tag_with_childs(
     {
         if ($elem->name() eq "title")
         {
+            # TODO :
+            # Eliminate the Law-of-Demeter-syndrome here.
             my $list = $elem->_get_childs()->[0];
-            my $p = $list->contents()->[0];
             $self->_output_tag(
                 {
                     start => ["title"],
                     in => sub {
                         $self->_write_elem(
                             {
-                                elem => $p->_get_childs()->[0],
+                                elem => $list,
                             }                            
                         ),
                     },
         {
             $self->_output_tag_with_childs(
                 {
-                    start => ["bold"],
+                    start => ["b"],
                     elem => $elem,
                 }
             );
         }
+        elsif ($elem->name() eq "i")
+        {
+            $self->_output_tag_with_childs(
+                {
+                    start => ["i"],
+                    elem => $elem,
+                }
+            );
+        }        
         elsif ($elem->name() eq "br")
         {
             $self->_writer->emptyTag("br");

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

     );
 }
 
+sub _new_text
+{
+    my $self = shift;
+    my $contents = shift;
+
+    return $self->_new_node(
+        {
+            t => "Text",
+            children => $self->_new_list($contents),
+        }
+    );
+}
+
 sub _parse_opening_tag
 {
     my $self = shift;
     return \@contents;
 }
 
+=begin unused_code
+
 # TODO : _parse_saying_first_para and _parse_saying_other_para are
 # very similar - abstract them into one function.
 sub _parse_saying_first_para
     });
 }
 
+=end unused_code
+
+=cut
+
 sub _parse_non_tag_text_unit
 {
     my $self = shift;
 
     if (pos($$l) < length($$l))
     {
-        my $text = $self->_consume_up_to(qr{\<}ms);
+        my $text = $self->_consume_up_to(qr{(?:\<|^\n?$)}ms);
 
         $l = $self->_curr_line_ref();
+
+        my $ret_elem = $self->_new_text([$text]);
+        my $is_para_end = 0;
+
+        # Demote the cursor to before the < of the tag.
+        #
         if (pos($$l) > 0)
         {
             pos($$l)--;
+            if (substr($$l, pos($$l), 1) eq "\n")
+            {
+                $is_para_end = 1;
+            }
+        }
+        else
+        {
+            $is_para_end = 1;
         }
 
-        my @paras = split(/\n{2,}/, $text);
-        return $self->_new_list(
-            [ map { $self->_new_para([$_]) } @paras]
-        );
+        return
+        {
+            elem => $ret_elem,
+            para_end => $is_para_end,
+        };
     }
     else
     {
 sub _parse_text_unit
 {
     my $self = shift;
+
     my $space = $self->_consume(qr{\s});
 
     my $l = $self->_curr_line_ref();
     }
     else
     {
-        return $self->_parse_non_tag_text_unit();
+        my @ret;
+
+        my $status;
+
+        my $is_para = (pos($$l) == 0);
+
+        PARSE_NON_TAG_TEXT_UNIT:
+        while (my $status = $self->_parse_non_tag_text_unit())
+        {
+            my $elem = $status->{'elem'};
+            my $is_para_end = $status->{'para_end'};
+
+            push @ret, $elem;
+            if ($is_para_end)
+            {
+                last PARSE_NON_TAG_TEXT_UNIT;
+            }
+            else
+            {
+                if (defined(my $text_unit = $self->_parse_text_unit()))
+                {
+                    push @ret, $text_unit;
+                }
+                else
+                {
+                    last PARSE_NON_TAG_TEXT_UNIT;
+                }
+            }
+        }
+        return
+            $is_para 
+            ? $self->_new_para(\@ret)
+            : $self->_new_list(\@ret)
+            ;
     }
 }
 

perl/modules/XML-Grammar-Fiction/t/data/proto-text/sections-p-b-i.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!".
+
+</s>
+
+</s>
+
+</body>
+

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

 use strict;
 use warnings;
 
-use Test::More tests => 2;
+use Test::More tests => 4;
 
 use Test::XML;
 
         with-brs
     ));
 
-@tests = (qw(sections-and-paras));
+@tests = (qw(
+    sections-and-paras
+    sections-p-b-i
+    ));
 
-# TEST:$num_texts=1
+# TEST:$num_texts=2
 
 my $grammar = XML::Grammar::Fiction::FromProto->new({
         parser_class => "XML::Grammar::Fiction::FromProto::Parser::QnD",