|
From: <sh...@us...> - 2007-08-08 14:22:49
|
Revision: 45
http://fb2-perl-tools.svn.sourceforge.net/fb2-perl-tools/?rev=45&view=rev
Author: shaplov
Date: 2007-08-08 07:22:50 -0700 (Wed, 08 Aug 2007)
Log Message:
-----------
fb2_notes - is a script that allows to convert some XML comments into fb2 footnotes.
Added Paths:
-----------
trunk/fb2-perl-tools/fb2/Footnotes.pm
trunk/fb2-perl-tools/fb2_notes
Added: trunk/fb2-perl-tools/fb2/Footnotes.pm
===================================================================
--- trunk/fb2-perl-tools/fb2/Footnotes.pm (rev 0)
+++ trunk/fb2-perl-tools/fb2/Footnotes.pm 2007-08-08 14:22:50 UTC (rev 45)
@@ -0,0 +1,287 @@
+package fb2::Footnotes;
+
+our $VERSION=0.01;
+
+use strict;
+use XML::LibXML;
+
+=head1 NAME
+
+fb2::Footnotes - manipulates footnotes in fb2 e-book
+
+=head1 SYNOPSIS
+
+ use fb2::Footnotes;
+ use XML::LibXML;
+
+ my $parser = XML::LibXML->new();
+ my $doc = $parser->parse_file($ARGV[0]);
+
+ fb2::Footnotes::ConvertFromComments($doc,{Keyword => 'NOTE', UseNumber => 1});
+
+=head1 DESCRIPTION
+
+fb2::Footnotes provides a set of functions for manipulating footnotes in fb2 e-book.
+
+=head1 METHODS
+
+The following methods are provided in this module.
+
+=cut
+
+=head2 ConvertFromComments
+
+ fb2::Footnotes::ConvertFromComments($document,{Option1 => 'Value1', Option2 => 'Value2'});
+
+Converts specially formated comments to fb2 footnotes. Returns 1 if convertation were successful, and 0 if no changes were
+made.
+
+I<$document> - Fb2 e-book stored as an XML::LibXML Document object
+
+=over 4
+
+=item B<Options>
+
+I<Keyword> - All the comments that begins with the keyword will be converted into footnotes. The default value is 'NOTE';
+
+I<UseNumber> - If this option is true, B<ConvertFromComments> will take a number after Keyword as a number of footnote.
+Default value is 1;
+
+=back
+
+
+=cut
+
+sub ConvertFromComments
+{
+ my $doc = shift;
+ my $opt = shift || {};
+
+ $opt->{'Keyword'}='NOTE' unless $opt->{'Keyword'};
+ $opt->{'UseNumber'}=1 unless $opt->{'UseNumber'};
+
+ my $keyword = $opt->{'Keyword'};
+ my $use_number = $opt->{'UseNumber'};
+
+ my $root = $doc->getDocumentElement();
+ my $changes_flag = 0;
+
+
+ my @NodeList=();
+ foreach ('p','v','subtitle','th', 'td','text-author')
+ {
+ my @l = $doc->getElementsByTagName($_);
+
+ @NodeList=(@NodeList,@l);
+ }
+
+ foreach (@NodeList)
+ {
+ foreach ($_->childNodes)
+ {
+ if ($_->nodeType == XML_COMMENT_NODE)
+ {
+ my $node=$_;
+ if ( $node->data()=~/^\s*$keyword(.*)/ )
+ {
+ my $text=$1;
+ my $number = int(rand(10000));
+ if ($use_number && ($text=~/^(\d+)\s+(.*)$/) )
+ {
+ $text = $2;
+ $number = $1;
+ }
+ Add({'doc'=>$doc, 'Number' => $number, 'Text' => $text, 'InsertBefore' => $node });
+ $node->parentNode->removeChild($node);
+ $changes_flag = 1;
+ }
+ }
+ }
+ }
+ return($changes_flag);
+}
+
+=head2 Add
+
+ fb2::Footnotes::Add($document,{Option1 => 'Value1', Option2 => 'Value2'});
+
+ Adds a new footnote to a fb2 document.
+
+I<$document> - Fb2 e-book stored as an XML::LibXML Document object
+
+=over 4
+
+=item B<Options>
+
+I<Text> - Text of a new footnote
+
+I<Number> - Number of a new footnote
+
+I<InsertBefore> - XML::LibXML Node object. An <A href> link to a new footnote will be inserted
+before that node
+
+=back
+
+
+=cut
+
+sub Add
+{
+ my $opt = shift || {};
+
+ my $doc = $opt->{'doc'};
+ my $number = $opt->{'Number'};
+ my $text = $opt->{'Text'};
+ my $insert_before = $opt->{'InsertBefore'};
+
+
+ my $note_body=undef;
+
+ my ($book) = $doc->getElementsByTagName('FictionBook');
+ die "Cant find FictionBook element" unless $book;
+
+
+ foreach ($doc->getElementsByTagName('body'))
+ {
+ my $node = $_;
+ foreach ($node->attributes())
+ {
+ if ( ($_->nodeName eq 'type') && ($_->value eq 'note'))
+ {
+ # It's assumed that there is only one note-body in the book
+ $note_body = $node;
+ }
+ }
+ }
+ if (! $note_body)
+ {
+ $note_body = $doc->createElement('body');
+ $note_body->setAttribute('type','note');
+ $book->appendChild($doc->createTextNode(' '));
+ $book->appendChild($note_body);
+ $book->appendChild($doc->createTextNode("\n"));
+ }
+
+ my $section_node = $doc->createElement('section');
+ $section_node->setAttribute('id',"note$number");
+
+ # Create Title
+ my $p_node = $doc->createElement('p');
+ $p_node->appendChild($doc->createTextNode($number));
+ my $title_node = $doc->createElement('title');
+ $title_node->appendChild($p_node);
+
+ # Append Title
+ $section_node->appendChild($doc->createTextNode("\n "));
+ $section_node->appendChild($title_node);
+
+ # Create p
+ $p_node = $doc->createElement('p');
+ $p_node->appendChild($doc->createTextNode($text));
+
+ # Append p
+ $section_node->appendChild($doc->createTextNode("\n "));
+ $section_node->appendChild($p_node);
+ $section_node->appendChild($doc->createTextNode("\n "));
+
+
+ $note_body->appendChild($doc->createTextNode("\n "));
+ $note_body->appendChild($section_node);
+ $note_body->appendChild($doc->createTextNode("\n "));
+
+ ### Now will create <a href> tag and insert it...
+
+ my $xlink_namespace=undef;
+
+ foreach ($book->attributes())
+ {
+ # print $_->nodeName," ",$_->value,"\n";
+
+ if ($_->value=~/^http:\/\/www.w3.org\/1999\/xlink$/)
+ {
+ if ($_->nodeName=~/^.*\:(.*)$/)
+ {
+ $xlink_namespace=$1;
+ }
+ }
+ }
+
+# print "NameSpace = $xlink_namespace \n";
+
+ my $a_node = $doc->createElement('a');
+
+ if ($xlink_namespace)
+ {
+ $a_node->setAttribute("$xlink_namespace:href" ,"#note$number" );
+ } else
+ {
+ $a_node->setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href' ,"#note$number" );
+ }
+ $a_node->setAttribute('type','note');
+ $a_node->appendChild($doc->createTextNode("[$number]"));
+
+
+ $note_body->appendChild($a_node);
+ $insert_before->parentNode->insertBefore($a_node,$insert_before);
+
+
+# print $note_body->toString, "\n" if $note_body;
+}
+
+
+1;
+
+=head1 EXAMPLES
+
+=head2 ConvertFromComments
+
+ fb2::Footnotes::ConvertFromComments($doc, {Keyword => 'NOTE', UseNumber => 1});
+ fb2::Footnotes::ConvertFromComments($doc);
+
+Both will transform fb2 document from
+
+ <p>Some text here <!--NOTE112 Here is a text of a footnote--> Some more text</p>
+
+into
+
+ <p>Some text here <a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#note112" type="note">[112]</a>
+ Some more text</p>
+ ...
+ </body>
+ <body type="note">
+ <section id="note112">
+ <title><p>112</p></title>
+ <p>Here is a text of a footnote</p>
+ </section>
+ </body>
+
+
+=head2 Add
+
+ fb2::Footnotes::Add($doc,{Text => "Foot note text", Number => 4, InsertBefore => $some_node });
+
+=head1 SEE ALSO
+
+http://sourceforge.net/projects/fb2-perl-tools - fb2-perl-tools project page
+
+http://www.fictionbook.org/index.php/Eng:FictionBook - fb2 community (site is mostly in Russian)
+
+=head1 AUTHOR
+
+Nikolay Shaplov <N...@Sh...>
+
+=head1 VERSION
+
+0.01
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2007 by Nikolay Shaplov
+
+This library is free software; you can redistribute it and/or modify
+it under the terms of the General Public License (GPL). For
+more information, see http://www.fsf.org/licenses/gpl.txt
+
+=cut
+
+
Added: trunk/fb2-perl-tools/fb2_notes
===================================================================
--- trunk/fb2-perl-tools/fb2_notes (rev 0)
+++ trunk/fb2-perl-tools/fb2_notes 2007-08-08 14:22:50 UTC (rev 45)
@@ -0,0 +1,191 @@
+#!/usr/bin/perl
+
+use strict;
+use fb2::Footnotes;
+use XML::LibXML;
+use Encode;
+use Getopt::Long qw(HelpMessage VersionMessage);
+our $VERSION=0.01;
+
+=head1 NAME
+
+fb2_notes - manipulate footnotes in the fb2 e-book
+
+=head1 SYNOPSIS
+
+B<fb2_notes> B<convert> [B<-k>=I<keyword>] [B<-n>=[I<1>|I<0>]] I<filename.fb2>
+
+B<fb2_notes> B<convert> <I<src_file.fb2> >I<dst_file.fb2>
+
+=head1 DESCRIPTION
+
+This utility allows to convert specifically formated comments info fb2 footnotes
+
+=head1 COMMANDS
+
+=over 4
+
+=item B<convert>
+
+Converts XML comments that starts with B<keyword> into fb2 e-book footnotes. If B<use-number> is set to 1
+then number after B<keyword> will be used as a number of footnote. All other text of a comment will
+be saved as a text of the footnote
+
+=over 8
+
+=item B<-k> I<keyword_value>
+
+=item B<--keyword>=I<keyword_value>
+
+
+
+All XML comments that starts with I<keyword_value> will be
+converted into fb2 e-book footnotes. Default value is 'NOTE'.
+
+=item B<-n> [I<1>|I<0>]
+
+=item B<--use-number>=[I<1>|I<0>]
+
+If B<use-number> is set to 1, than a number after B<keyword> will be used as a number of footnote.
+Default value is 1.
+
+=back
+
+=back
+
+=head1 EXAMPLES
+
+=item B<convert>
+
+=over 4
+
+B<$ cat some_book.fb2>
+ ...
+ <p>Some text here<!--NOTE112 Here is a text of a footnote--> Some more text</p>
+ ...
+
+B<$ fb2_notes convert some_book.fb2>
+
+B<$ cat some_book.fb2>
+ ...
+ <p>Some text here<a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#note112" type="note">[112]</a>
+ Some more text</p>
+ ...
+ </body>
+ <body type="note">
+ <section id="note112">
+ <title><p>112</p></title>
+ <p>Here is a text of a footnote</p>
+ </section>
+ </body>
+
+=back
+
+=head1 SEE ALSO
+
+http://sourceforge.net/projects/fb2-perl-tools - fb2-perl-tools project page
+
+http://www.fictionbook.org/index.php/Eng:FictionBook - fb2 community (site is mostly in Russian)
+
+=head1 AUTHOR
+
+Nikolay Shaplov <N...@Sh...>
+
+=head1 VERSION
+
+0.01
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2007 by Nikolay Shaplov
+
+This library is free software; you can redistribute it and/or modify
+it under the terms of the General Public License (GPL). For
+more information, see http://www.fsf.org/licenses/gpl.txt
+
+=cut
+
+my $Command = shift @ARGV;
+
+do_convert() if $Command eq 'convert';
+HelpMessage() if ! $Command || $Command eq 'help';
+
+
+exit;
+
+
+sub do_convert
+{
+ my $opts={};
+ GetOptions(
+ help => sub {HelpMessage(); },
+ version => sub {VersionMessage(); },
+ "keyword|w=s" => \$opts->{'keyword'},
+ "use-number|n" => \$opts->{'use_number'},
+ );
+
+ my $file_name = $ARGV[0];
+
+ my $doc;
+
+ if ($file_name)
+ {
+ $doc = _parse_file($file_name);
+ } else
+ {
+ $doc = _parse_stdin();
+ }
+
+ my $changes_flag = fb2::Footnotes::ConvertFromComments($doc,{
+ "Keyword" => $opts->{'keyword'},
+ "UseNumber"=>$opts->{'use_number'}
+ });
+ if (! $changes_flag )
+ {
+ print STDERR "No changes were made\n";
+ return 0 unless $changes_flag;
+ }
+
+ if ($file_name)
+ {
+ _update_file($file_name,$doc);
+ } else
+ {
+ print $doc->toString();
+ }
+
+ print STDERR "Comments successfully converted\n";
+}
+
+sub _parse_file
+{
+ my $file_name=shift;
+ my $parser = XML::LibXML->new();
+
+ my $doc = $parser->parse_file($file_name);
+ return $doc;
+}
+
+sub _parse_stdin
+{
+ my $parser = XML::LibXML->new();
+ my $doc = $parser->parse_fh(\*STDIN);
+ return $doc;
+}
+
+sub _update_file
+{
+ my $file_name = shift;
+ my $doc = shift;
+
+ my $backup = $file_name . "~";
+ unlink $backup;
+ rename $file_name, $backup or die("Cannot make backup copy: $!");
+ my $encoding=$doc->encoding();
+ # This call of Encode::decode fixes problem in XML::DOM which do not
+ # mark entire output utf8 correctly.
+ my $data = decode("utf8",$doc->toString);
+ open DST,">:encoding($encoding)",$file_name;
+ print DST $data;
+ close DST;
+}
Property changes on: trunk/fb2-perl-tools/fb2_notes
___________________________________________________________________
Name: svn:executable
+ *
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|