3 use POSIX qw(strftime);
9 my $idseq = 0; # sequentual number of footnotes
12 # TODO italic paragaphs
16 # print fictionbook header
17 print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
18 print "<FictionBook xmlns=\"http://www.gribuser.ru/xml/fictionbook/2.0\"
19 xmlns:l=\"http://www.w3.org/1999/xlink\">\n";
20 my $metadata = shift @ARGV;
23 # Replace empty date with current date
24 if (/<date\s+\/>/ || /<date>\s*<\/date>/) {
25 $_ = "<date value=\">".strftime("%Y-%m-%d",localtime())."\">".
26 strftime("%d/%m/%Y",localtime())."</date>\n";
28 # Add current to date as fractional part to version
29 if (/<version>(\d*)(.\d*)?<\/version>/) {
30 my $ver = $1+time()/1E10;
31 $_=tag(sprintf("%g",$ver),"version")."\n";
41 if (/\\(begin|end){(\w+)}/) {
44 if ($environ eq 'verbatim') {
46 } elsif ($environ eq 'verse') {
48 pushsection("poem",undef);
50 add_to_section(tag($buffer,'stanza')."\n") if $buffer;
55 } elsif($environ eq 'document' && $begin) {
60 if ((/^$/ || $environ) && $buffer) {
61 #output on empty line (p or stanza) depending on poetry mode
62 add_to_section(tag(flushbuffer($buffer),$poetry?"stanza":"p")."\n");
65 next LINE if $environ;
67 if (/\\(part|chapter|section|subsection|subsubsection)\*?{(.*)}/) {
69 add_to_section(tag(flushbuffer($buffer),$poetry?"stanza":"p"));
72 pushsection($1,tag($2,"p"));
76 add_to_section("<empty-line />");
79 next LINE if /\\pagebreak\b/;
88 s/\\sloppy([^\w])/$1/g;
93 #replace TeX ligatures ~ --- << >> \% with appropriate unicode symbols
101 #replace ' and " with entities
111 $buffer.=tag($_,'v')."\n";
112 } elsif ($verbatim) {
113 add_to_section(tag(tag($_,"code"),"p"));
119 add_to_section(tag(flushbuffer($buffer),"p"));
128 print "<body>\n$footnotes\n</body>" if $footnotes;
129 print "</FictionBook>";
133 return if ($#sections<0) ;
134 if ($data =~ /^\s*<section>/ && $sections[$#sections]->{data} !~ /^\s*<section>/) {
135 $sections[$#sections]->{data} = tag($sections[$#sections]->{data},"section")."\n";
137 $sections[$#sections]->{data}.=$data;
141 my $tag= shift || 'section';
142 my $str = pop @sections;
145 $content = tag($str->{title},"title");
147 if ($str->{data} =~ /^\s*$/s) {
148 $content .= "<p>\n</p>";
150 $content .= $str->{data};
152 if ($#sections >=0) {
153 add_to_section(tag($content,$tag)."\n");
155 print tag($content,$tag);
160 my ($level,$title)=@_;
161 # Find section of $level in the current stack
162 my $found=scalar(@sections);
164 for (my $i=0;$i<=$#sections;$i++) {
165 if ($sections[$i]->{level} eq $level) {
170 # if found, flush everything below
171 while (scalar(@sections) > $found) {
174 push @sections,{level=>$level,title=>$title,data=>""};
178 my ($content,$name) = @_;
179 $content =~s/^\s+//s;
180 return "" unless $content;
181 return "<$name>$content</$name>";
186 s/{\\(em|it|bf)(?:\s+|{})([^{}]+)}/<emphasis>$2<\/emphasis>/g;
187 s/\\(emph|textit|textbf){([^{}]+)}/<emphasis>$2<\/emphasis>/g;
188 s/\\footnote{(.*)}/push_footnote($1)/e;
195 my $id = "note_".(++$idseq);
196 $footnotes.="<section id=\"$id\">".tag(shift,'p')."</section>\n";
197 return "<a l:href=\"#$id\" type=\"note\">$idseq</a>";