| #!/usr/bin/perl |
| |
| use strict; |
| |
| my @depth2latex = ( |
| '\chapter', |
| '\section', |
| '\subsection', |
| '\subsubsection', |
| '\paragraph', |
| '\subparagraph' |
| ); |
| |
| my $skip_depth = 1; |
| |
| sub find_footnotes { |
| my @text = @_; |
| my @notes = (); |
| my $found = 0; |
| my $l; |
| |
| for ($l = 0; $l <= $#text; $l++) { |
| if ($text[$l] =~ m/^FOOTNOTES:$/) { |
| $found = 1; |
| } |
| next unless $found; |
| if ($text[$l] =~ m/^\[[0-9]+\]\s/) { |
| push @notes, $l; |
| } |
| } |
| return @notes; |
| }; |
| |
| sub find_sections { |
| my @text = @_; |
| my @sections = (); |
| my $l; |
| |
| for ($l = 0; $l <= $#text - 1; $l++) { |
| next unless (($text[$l + 1] =~ m/^=======*$/) or |
| ($text[$l + 1] =~ m/^-------*$/)); |
| |
| next unless ($text[$l] =~ m/^(([0-9]+\.)+) /); |
| |
| push @sections, $l; |
| |
| } |
| return @sections; |
| }; |
| |
| my @text = (); |
| while (<>) { |
| push @text, $_; |
| } |
| |
| my @footnotes = find_footnotes(@text); |
| my @sections = find_sections(@text); |
| |
| #Format footnotes |
| my %footnote_by_number = (); |
| my $f; |
| for ($f = 0; $f <= $#footnotes; $f++) { |
| my $l = $footnotes[$f]; |
| die unless ($text[$l] =~ m/^\[([0-9]+)\]\s+(.*)/); |
| my $footnote = $1; |
| my $text = $2; |
| die "duplicate footnote number $footnote" if defined($footnote_by_number{$footnote}); |
| $footnote_by_number{$footnote} = "$text\n"; |
| my $next; |
| if ($f < $#footnotes) { |
| $next = $footnotes[$f + 1]; |
| } else { |
| $next = $#text + 1; |
| } |
| for ($l = $footnotes[$f] + 1; $l < $next; $l++) { |
| next if ($text[$l] =~ m/^$/); |
| $footnote_by_number{$footnote} .= $text[$l]; |
| } |
| } |
| |
| #Format sections |
| my %label_by_section = (); |
| my $s; |
| |
| my %latest_by_depth = (); |
| |
| for ($s = 0; $s <= $#sections; $s++) { |
| my $l = $sections[$s]; |
| die unless ($text[$l] =~ m/^(([0-9]+\.)+)\s+(.+)\s*/); |
| my $section = $1; |
| my $name = $3; |
| my @path = split(/\./, $section); |
| my $depth = $#path - $skip_depth; |
| if ($depth < 0) { |
| $depth = 0; |
| } |
| if ($depth > $#depth2latex) { |
| $depth = $#depth2latex; |
| } |
| $latest_by_depth{$#path} = $name; |
| my $type = $depth2latex[$depth]; |
| my $label = $name; |
| #Prepend hierarchical path to make name unique |
| for (my $i = 1; $i <= $#path - $skip_depth; $i++) { |
| last if (not defined $latest_by_depth{$#path - $i}); |
| $label = "$latest_by_depth{$#path - $i} / $label"; |
| } |
| #It's best to avoid underscore in labels |
| $label =~ s/_/-/g; |
| $text[$l] = $type . "{$name}\\label{sec:$label}\n"; |
| $label_by_section{$section} = $label; |
| } |
| |
| my $ifndef = 0; |
| my $listing = 0; |
| my $table = 0; |
| my $buffer = ""; |
| for my $line (@text) { |
| last if ($line =~ m/^FOOTNOTES:$/); |
| next if (($line =~ m/^=======*$/) or |
| ($line =~ m/^-------*$/)); |
| |
| if ($line =~ m/^#if/) { |
| print "\\begin{lstlisting}\n"; |
| $ifndef++; |
| } |
| if ($ifndef) { |
| if ($line =~ m/^#endif/) { |
| $ifndef--; |
| } |
| $buffer .= $line; |
| if (not $ifndef) { |
| print $buffer; |
| print "\\end{lstlisting}\n"; |
| $buffer = ""; |
| } |
| next; |
| } |
| if (not $table and $line =~ m/^\+\-/) { |
| print "\\begin{verbatim}\n"; |
| $table = 1; |
| } |
| if ($table and not $line =~ m/^(\+\-|\|)/) { |
| print "\\end{verbatim}\n"; |
| $table = 0; |
| } |
| if (not $listing and $line =~ m/^\t/) { |
| print "\\begin{lstlisting}\n"; |
| $listing = 1; |
| } |
| if ($listing and $line =~ m/^$/) { |
| $buffer .= $line; |
| next; |
| } |
| if ($listing and not $line =~ m/^\t/) { |
| print "\\end{lstlisting}\n"; |
| $listing = 0; |
| } |
| |
| if (not $table and not $listing) { |
| if ($line =~ m/\S+\s*\^\s*\S+/) { |
| $line =~ s/(\S+\s*\^\s*)(\S+)/\$$1\{$2\}\$/g; |
| } else { |
| $line =~ s/\^/\\^/go; |
| } |
| $line =~ s/#/\\#/go; |
| $line =~ s/&/\\&/go; |
| if ($line =~ m/\[[0-9]+\]/) { #premature optimization |
| for my $n (keys(%footnote_by_number)) { |
| my $txt = $footnote_by_number{$n}; |
| $line =~ s/\[$n\]/\n\\footnote{$txt}/g; |
| } |
| } |
| } |
| if ($line =~ m/"(([0-9]+\.)+)[^"]*"/) { |
| my $section = $1; |
| $line =~ s/"(([0-9]+\.)+)[^"]*"/\\ref{sec:$label_by_section{$section}}~\\nameref{sec:$label_by_section{$section}}/g; |
| } |
| print $buffer; |
| $buffer = ""; |
| print $line; |
| } |
| |
| |