X-Git-Url: http://wagner.pp.ru/gitweb/?a=blobdiff_plain;f=Tex2fb2;h=abc38bba4320338ddd5275b28ab8f23b90609fff;hb=0d8570d4ed4c9ac48e577f7a3092bed9abb79332;hp=693149fcdc401644ad80bda7cf08af16a61a47eb;hpb=90f2749e4d60b2700566294a2dc75370dcf356d2;p=fiction%2FKate-the-Empress.git
diff --git a/Tex2fb2 b/Tex2fb2
index 693149f..abc38bb 100755
--- a/Tex2fb2
+++ b/Tex2fb2
@@ -1,26 +1,56 @@
#!/usr/bin/perl -CDS
+
use utf8;
+use POSIX qw(strftime);
+use MIME::Base64;
# 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 "\n";
+print "\n";
print "\n";
my $metadata = shift @ARGV;
open F,"<",$metadata;
+my $pics = "";
while () {
+ # Replace empty date with current date
+ if (// || /\s*<\/date>/) {
+ $_ = "".
+ strftime("%d/%m/%Y",localtime())."\n";
+ }
+ # Add current to date as fractional part to version
+ if (/(\d*)(.\d*)?<\/version>/) {
+ my $ver = $1+time()/1E10;
+ $_=tag(sprintf("%g",$ver),"version")."\n";
+ }
+ # ÐÑли ÑÑÑеÑÑвÑÐµÑ cover.png, добавлÑем coverpage
+ if (//) {
+ $_="";
+ COVER:
+ for $file ("cover.jpg","cover.png") {
+ if (-f $file) {
+ my $id = $file;
+ $id=~tr/./_/;
+ $_ = "\n\n\n";
+ $pics .= mkbinary($file,$id);
+ last COVER;
+ }
+ }
+ }
print $_;
}
close F;
-
+print "\n";
my $header =1;
LINE:
while (<>) {
@@ -46,56 +76,60 @@ if (/\\(begin|end){(\w+)}/) {
next LINE if $header;
if ((/^$/ || $environ) && $buffer) {
#output on empty line (p or stanza) depending on poetry mode
- add_to_section(tag($buffer,$poetry?"stanza":"p")."\n");
+ add_to_section(tag(flushbuffer($buffer),$poetry?"stanza":"p")."\n");
$buffer="";
}
next LINE if $environ;
# Section headings
-if (/\\(part|chapter|section|subsection|subsubsection)\*?{(.*)}/) {
+if (/\\(part|chapter|section|subsection|subsubsection)\*?\{(.*)\}/) {
if ($buffer) {
- add_to_section(tag($buffer,$poetry?"stanza":"p"));
+ add_to_section(tag(flushbuffer($buffer),$poetry?"stanza":"p"));
$buffer="";
}
- pushsection($1,$2);
+ pushsection($1,tag($2,"p"));
next LINE;
}
-if (/\\vspace{/) {
+if (/\\vspace\{/) {
add_to_section("");
next LINE;
}
next LINE if /\\pagebreak\b/;
+#replace ' and " with entities
+s/&/&/g;
+s/'/'/g;
+s/"/"/g;
+s/</g;
+s/>/>/g;
#normal mode:
if (!$verbatim) {
#strip TeX comments
s/([^\\])%.*$/$1/;
s/^%.*$//;
# strip \sloppy
+s/\\(\w+)\\sloppy/\\$1/g;
s/\\sloppy\s+//g;
-s/\\sloppy{}//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/\\dots/\x{2026}/g;
+$_ = fix_ligatures($_);
}
-#replace ' and " with entities
-s/&/&/g;
-s/'/'/g;
-s/"/"/g;
-s/</g;
-s/>/>/g;
if ($poetry) {
chomp;
+ if ($poetic_buffer) {
+ $_ = $poetic_buffer." ".$_;
+ $poetic_buffer = undef;
+ }
+ if (/{[^}]+$/) {
+ $poetic_buffer=$_;
+ next LINE;
+ }
s/\s*\\\\$//;
- $buffer.=tag($_,'v')."\n";
+ $buffer.=tag(flushbuffer($_),'v')."\n";
} elsif ($verbatim) {
add_to_section(tag(tag($_,"code"),"p"));
} else {
@@ -103,7 +137,7 @@ if ($poetry) {
}
}
if ($buffer) {
- add_to_section(tag($buffer,"p"));
+ add_to_section(tag(flushbuffer($buffer),"p"));
$buffer="";
}
@@ -111,12 +145,17 @@ while (@sections) {
flushsection();
}
print "\n";
-## FIXME print footnotes
+## print footnotes
+print "\n$footnotes\n" if $footnotes;
+print $pics;
print "";
sub add_to_section {
my $data = shift;
return if ($#sections<0) ;
+ if ($data =~ /^\s*/ && $sections[$#sections]->{data} !~ /^\s*/) {
+ $sections[$#sections]->{data} = tag($sections[$#sections]->{data},"section")."\n";
+ }
$sections[$#sections]->{data}.=$data;
}
@@ -127,7 +166,11 @@ sub flushsection {
if ($str->{title}) {
$content = tag($str->{title},"title");
}
- $content .= $str->{data};
+ if ($str->{data} =~ /^\s*$/s) {
+ $content .= "\n
";
+ } else {
+ $content .= $str->{data};
+ }
if ($#sections >=0) {
add_to_section(tag($content,$tag)."\n");
} else {
@@ -150,11 +193,54 @@ sub pushsection {
while (scalar(@sections) > $found) {
flushsection;
}
- push @sections,{level=>$level,title=>$title,data=>""};
+ push @sections,{level=>$level,title=>fix_ligatures($title),data=>""};
}
+sub fix_ligatures {
+ local $_=shift;
+ s/~/\xA0/g;
+ s/\\-/\xAD/g;
+ s/---/â/g;
+ s/<«/g;
+ s/>>/»/g;
+ s/\\%/%/g;
+ s/\\dots/\x{2026}/g;
+ s/\\verb(.)(.*)\1/$2<\/code>/;
+ return $_;
+}
sub tag {
my ($content,$name) = @_;
- return "" if $content =~ /^\s*$/s;
+ $content =~s/^\s+//s;
+ return "" unless $content;
return "<$name>$content$name>";
}
+
+sub flushbuffer {
+ local $_ = shift;
+
+ s/\\footnote\{(.*)\}/push_footnote($1)/e;
+ $_.="}" if (/^\s*\{.*?[^}]$/) ;
+ s/\{\\(em|it|bf)(?:\s+| \{\})([^{}]+)}/$2<\/emphasis>/g;
+ s/\{\\(tt)(?:\s+|\{\})([^{}]+)}/$2<\/code>/g;
+ s/\\(emph|textit|textbf)\{([^{}]+)\}/$2<\/emphasis>/g;
+ s/[{}]//g;
+ return $_;
+}
+
+
+sub push_footnote {
+ my $id = "note_".(++$idseq);
+ $footnotes.="".tag(flushbuffer(shift),'p')."\n";
+ return "$idseq";
+}
+
+sub mkbinary {
+ my ($filename,$id) = @_;
+ my $f;
+ open $f,"<",$filename;
+ binmode $f;
+ local $/;
+ my $data = encode_base64(<$f>);
+ return "$data\n";
+ close $f;
+}