X-Git-Url: http://www.wagner.pp.ru/gitweb/?p=fiction%2FKate-the-Empress.git;a=blobdiff_plain;f=Tex2fb2;h=96279b391b0062e4b4afdb8b8e21ceddb3366ecd;hp=2fe05809eb85e44e5eadcf554beede9f87138bb3;hb=HEAD;hpb=37b1eefaa8690036f7e07615a62556746c4e91f4 diff --git a/Tex2fb2 b/Tex2fb2 old mode 100644 new mode 100755 index 2fe0580..abc38bb --- a/Tex2fb2 +++ b/Tex2fb2 @@ -1,30 +1,62 @@ -#!/usr/bin/perl +#!/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 (<>) { $environ = undef; if (/\\(begin|end){(\w+)}/) { - $environ = $2; + $environ=$2; $begin=$1 eq "begin"; if ($environ eq 'verbatim') { $verbatim=$begin; @@ -32,64 +64,98 @@ 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; } -#normal mode: -if (!$verbatim) { -#strip TeX comments -s/([^\\])%.*$/$1/; -#replace TeX ligatures ~ --- << >> \% with appropriate unicode symbols -s/~/\xA0/g; -s/---/-/g; -s/<>/»/g; +if (/\\vspace\{/) { + add_to_section(""); + next LINE; } +next LINE if /\\pagebreak\b/; #replace ' and " with entities 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([^\w])/$1/g; +# strip extra space +s/^\s+//; +s/\s+$//; +s/(\s)\s+/$1/g; +#replace TeX ligatures ~ --- << >> \% with appropriate unicode symbols +$_ = fix_ligatures($_); +} if ($poetry) { chomp; - $buffer.=tag($_,'v'); + if ($poetic_buffer) { + $_ = $poetic_buffer." ".$_; + $poetic_buffer = undef; + } + if (/{[^}]+$/) { + $poetic_buffer=$_; + next LINE; + } + s/\s*\\\\$//; + $buffer.=tag(flushbuffer($_),'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 "\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; } @@ -100,9 +166,13 @@ 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)); + add_to_section(tag($content,$tag)."\n"); } else { print tag($content,$tag); } @@ -123,10 +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/\\dots/\x{2026}/g; + s/\\verb(.)(.*)\1/$2<\/code>/; + return $_; +} sub tag { my ($content,$name) = @_; + $content =~s/^\s+//s; + return "" unless $content; return "<$name>$content"; } + +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; +}