]> www.wagner.pp.ru Git - fiction/Kate-the-Empress.git/blobdiff - Tex2fb2
update version and date in the document-info on each compile
[fiction/Kate-the-Empress.git] / Tex2fb2
diff --git a/Tex2fb2 b/Tex2fb2
old mode 100644 (file)
new mode 100755 (executable)
index 2fe0580..22d8343
--- a/Tex2fb2
+++ b/Tex2fb2
@@ -1,30 +1,45 @@
-#!/usr/bin/perl
+#!/usr/bin/perl -CDS
+use utf8;
+use POSIX qw(strftime);
 # char-level modes
 my $poetry = 0;
 my $verbatim = 0;
 my @sections;
 my $buffer;
+my $idseq = 0; # sequentual number of footnotes
+my $footnotes="";
 #
 # TODO italic paragaphs
 # footnotes
 # epigraphs
 #
 # print fictionbook header
-print "<?xml version=\"1.0\" encoding=\"UTF-8\">\n";
+print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
 print "<FictionBook xmlns=\"http://www.gribuser.ru/xml/fictionbook/2.0\"
 xmlns:l=\"http://www.w3.org/1999/xlink\">\n";
 my $metadata = shift @ARGV;
 open F,"<",$metadata;
 while (<F>) {
+       # Replace empty date with current date
+       if (/<date\s+\/>/ || /<date>\s*<\/date>/) {
+               $_ = "<date value=\">".strftime("%Y-%m-%d",localtime())."\">".
+                       strftime("%d/%m/%Y",localtime())."</date>\n";
+       }
+       # Add current to date as fractional part to version
+       if (/<version>(\d*)(.\d*)?<\/version>/) {
+               my $ver = $1+time()/1E10;
+               $_=tag(sprintf("%g",$ver),"version")."\n";
+       }
        print $_;
 }
 close F;
-
+print "<body>\n";
 my $header =1;
+LINE:
 while (<>) {
 $environ = undef;
 if (/\\(begin|end){(\w+)}/) {
-       $environ = $2;
+       $environ=$2;
        $begin=$1 eq "begin";
        if ($environ eq 'verbatim') {
                $verbatim=$begin;
@@ -32,33 +47,56 @@ if (/\\(begin|end){(\w+)}/) {
                if ($begin) {
                pushsection("poem",undef);
                } else {
-               flushsection('poem');
+                       add_to_section(tag($buffer,'stanza')."\n") if $buffer;
+                       $buffer="";
+                       flushsection('poem');
                }
                $poetry = $begin;
-       } elsif($environ = 'document' && $begin) {
+       } elsif($environ eq 'document' && $begin) {
                $header=0;
        }
 }
 next LINE if $header;
-if (/^$/ && $environ && $buffer) {
+if ((/^$/ || $environ) && $buffer) {
 #output on empty line (p or stanza) depending on poetry mode
-       add_to_section(tag($buffer,$poetry?"stanza":"p"));
+       add_to_section(tag(flushbuffer($buffer),$poetry?"stanza":"p")."\n");
        $buffer="";
 }
 next LINE if $environ;
 # Section headings
-if (/\\(part|chapter|section|subsection|subsubsection){(.*)}/) {
-       pushsection($1,$2);
+if (/\\(part|chapter|section|subsection|subsubsection)\*?{(.*)}/) {
+       if ($buffer) {
+               add_to_section(tag(flushbuffer($buffer),$poetry?"stanza":"p"));
+               $buffer="";
+       }
+       pushsection($1,tag($2,"p"));
+       next LINE;
 }
+if (/\\vspace{/) {
+       add_to_section("<empty-line />");
+       next LINE;
+}
+next LINE if /\\pagebreak\b/;
 #normal mode: 
 if (!$verbatim) {
 #strip TeX comments 
 s/([^\\])%.*$/$1/;
+s/^%.*$//;
+# strip \sloppy
+s/\\sloppy\s+//g;
+s/\\sloppy{}//g;
+s/\\sloppy([^\w])/$1/g;
+# strip extra space
+s/^\s+//;
+s/\s+$//;
+s/(\s)\s+/$1/g;
 #replace TeX ligatures ~ --- << >> \% with appropriate unicode symbols
 s/~/\xA0/g;
-s/---/-/g;
+s/---//g;
 s/<</«/g;
 s/>>/»/g;
+s/\\%/%/g;
+s/\\dots/\x{2026}/g;
 }
 #replace ' and " with entities
 s/&/&amp;/g;
@@ -69,27 +107,33 @@ s/>/&gt;/g;
 
 if ($poetry) {
        chomp;
-  $buffer.=tag($_,'v');
+       s/\s*\\\\$//;
+  $buffer.=tag($_,'v')."\n";
 } elsif ($verbatim) {
        add_to_section(tag(tag($_,"code"),"p"));
 } else {
-  $buffer.=$_;
+  $buffer.=" ".$_;
 }
 }
 if ($buffer) {
-       add_to_section(tag($buffer,"p"));
+       add_to_section(tag(flushbuffer($buffer),"p"));
+       $buffer="";
 }
 
 while (@sections) {
        flushsection();
 }
 print "</body>\n";
-## FIXME print footnotes
+## print footnotes
+print "<body>\n$footnotes\n</body>" if $footnotes;
 print "</FictionBook>";
 
 sub add_to_section {
        my $data = shift;
        return if ($#sections<0) ;
+       if ($data =~ /^\s*<section>/ && $sections[$#sections]->{data} !~ /^\s*<section>/) {
+               $sections[$#sections]->{data} = tag($sections[$#sections]->{data},"section")."\n";
+       }       
        $sections[$#sections]->{data}.=$data;
 }
 
@@ -100,9 +144,13 @@ sub flushsection {
        if ($str->{title}) {
                $content = tag($str->{title},"title");
        }
-       $content .=  $str->{data};
+       if ($str->{data} =~ /^\s*$/s) {
+               $content .= "<p>\n</p>";
+       } else {
+               $content .=  $str->{data};
+       }
        if ($#sections >=0) {
-               add_to_section(tag($content,$tag));
+               add_to_section(tag($content,$tag)."\n");
        } else {
                print tag($content,$tag);
        }
@@ -128,5 +176,23 @@ sub pushsection {
 
 sub tag {
        my ($content,$name) = @_;
+       $content =~s/^\s+//s;
+       return "" unless $content;
        return "<$name>$content</$name>";
 }
+
+sub flushbuffer {
+       local $_ = shift;
+       s/{\\(em|it|bf)(?:\s+|{})([^{}]+)}/<emphasis>$2<\/emphasis>/g;
+       s/\\(emph|textit|textbf){([^{}]+)}/<emphasis>$2<\/emphasis>/g;
+       s/\\footnote{(.*)}/push_footnote($1)/e;
+       s/[{}]//g;
+       return $_;
+}
+
+
+sub push_footnote {
+       my $id = "note_".(++$idseq);
+       $footnotes.="<section id=\"$id\">".tag(shift,'p')."</section>\n";
+       return "<a l:href=\"#$id\" type=\"note\">$idseq</a>";
+}