#!/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; }