diff options
author | dakkar <dakkar@luxion> | 2007-07-17 15:27:31 +0000 |
---|---|---|
committer | dakkar <dakkar@luxion> | 2007-07-17 15:27:31 +0000 |
commit | 6baf5b52e18811f2b44d35a5dcc1a51d6071ce8b (patch) | |
tree | 9ec28059c24dd540ab0e5ef6a83a684fc32ed00c /lib/Text/Restructured | |
parent | r2492@narval: dakkar | 2007-07-17 10:42:14 +0200 (diff) | |
download | Text-Restructured-Writer-LibXML-6baf5b52e18811f2b44d35a5dcc1a51d6071ce8b.tar.gz Text-Restructured-Writer-LibXML-6baf5b52e18811f2b44d35a5dcc1a51d6071ce8b.tar.bz2 Text-Restructured-Writer-LibXML-6baf5b52e18811f2b44d35a5dcc1a51d6071ce8b.zip |
r2493@narval: dakkar | 2007-07-17 10:42:29 +0200
importo il modulo ReST-XML
git-svn-id: svn://luxion/repos/Text-Restructured-Writer-LibXML@257 fcb26f47-9200-0410-b104-b98ab5b095f3
Diffstat (limited to 'lib/Text/Restructured')
-rw-r--r-- | lib/Text/Restructured/Writer/LibXML.pm | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/lib/Text/Restructured/Writer/LibXML.pm b/lib/Text/Restructured/Writer/LibXML.pm new file mode 100644 index 0000000..99ef206 --- /dev/null +++ b/lib/Text/Restructured/Writer/LibXML.pm @@ -0,0 +1,118 @@ +package Text::Restructured::Writer::LibXML; +use strict; +use warnings; +use XML::LibXML; + +$Text::Restructured::Writer::LibXML::VERSION='0.01'; + +=head1 NAME + +Text::Restructured::Writer::LibXML + +=head1 SYNOPSIS + + use Text::Restructured; + use Text::Restructured::Writer::LibXML; + + my $parser=Text::Restructured->new($opts,'gino'); + my $dudom=$parser->Parse($input,$filename); + my $xdoc=Text::Restructured::Writer::LibXML->new->ProcessDOM($dudom); + +=head1 DESCRIPTION + +This module implements a "Writer" for L<Text::Restructured>, that +instead of returning a string, returns a L<XML::LibXML> DOM. + +The DOM will have non-namespaced elements according to the docutils +vocabulary, and namespcaed elements according to the MathML +vocabulary. + +This is probably the fastest way to transform a +L<Text::Restructured::DOM> structure into a proper XML DOM. + +=head1 METHODS + +=head2 C<new> + +Returns a new object. + +=cut + +sub new { + my ($class)=@_; + return bless {},$class; +} + +=head2 I<xml_dom>C<= ProcessDOM(>I<docutils_dom>C<)> + +Given an object of type L<Text::Restructured::DOM>, processes it +recursively and builds an XML DOM into a new document. Returns the +document, or dies trying. + +=cut + +sub ProcessDOM { + my ($self,$dudom)=@_; + my $xdoc=XML::LibXML->createDocument(); + $xdoc->setDocumentElement(_docutils2xml($dudom,$xdoc)); + return $xdoc; +} + +my $MATHML='http://www.w3.org/1998/Math/MathML'; + +sub _mathml2xml { + my ($mnode,$xdoc)=@_; + + if ($mnode->isText) { + return $xdoc->createTextNode($mnode->nodeValue); + } + + + my @children=map {_mathml2xml($_,$xdoc)} + $mnode->childNodes(); + + my $elem=$xdoc->createElementNS($MATHML,$mnode->nodeName); + for my $attname ($mnode->attributeList) { + next if $attname eq 'xmlns'; + $elem->setAttribute($attname, + $mnode->attribute($attname)) + } + + $elem->appendChild($_) for @children; + + return $elem; +} + +sub _docutils2xml { + my ($dunode,$xdoc)=@_; + + if ($dunode->{tag} eq '#PCDATA') { + return $xdoc->createTextNode($dunode->{text} || ''); + } + + if ($dunode->{tag} eq 'mathml') { + return _mathml2xml($dunode->{attr}{mathml},$xdoc); + } + + my @children=map {_docutils2xml($_,$xdoc)} + @{ $dunode->{content} || [] }; + + my $elem=$xdoc->createElement($dunode->{tag}); + + if (defined $dunode->{attr}) { + while (my ($attname,$attval)=each %{$dunode->{attr}}) { + if (! defined $attval) { + $attval=''; + } + elsif (ref($attval) eq 'ARRAY') { + $attval=join ' ',@$attval; + } + $elem->setAttribute($attname,$attval); + } + } + $elem->appendChild($_) for @children; + + return $elem; +} + +1; |