diff options
Diffstat (limited to 'txt2latex.pl')
-rwxr-xr-x | txt2latex.pl | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/txt2latex.pl b/txt2latex.pl new file mode 100755 index 0000000..5732fe5 --- /dev/null +++ b/txt2latex.pl @@ -0,0 +1,184 @@ +#!/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; +} + + |