#!/usr/bin/perl -w use strict; # states: # 0 - initial state # 1 - inside screen # 2 - inside itemize # 3 - inside enumerate my $state = 0; my @states = []; my $levels = 0; my $table_line = ""; if (scalar @ARGV < 1) { parse_stdin (); } else { while (shift @ARGV) { parse_doc ($_); } } sub parse_stdin { while (<>) { my $res = handle_line ($_); print $res if $res; } } sub parse_doc { my ($doc) = @_; return undef unless open IN,"< $doc"; while () { my $res = handle_line ($_); print $res if $res; } close IN; } sub handle_line { my $line = shift; if ($state == 0) { if (!check_special_begin ($line)) { return handle_normal_line ($line); } } elsif ($state == 1) { if (!check_special_begin ($line) && ! check_special_end ($line)) { return handle_example ($line); } } elsif ($state == 2) { if (!check_special_begin ($line) && ! check_special_end ($line)) { return handle_itemize ($line); } } elsif ($state == 3) { if (!check_special_begin ($line) && ! check_special_end ($line)) { return handle_enumerate ($line); } } elsif ($state == 4) { if (!check_special_begin ($line) && ! check_special_end ($line)) { return handle_multitable ($line); } } return undef; } sub handle_normal_line { my $line = shift; my $preserve_end = shift; # Formattings $line =~ s/\@code{([^}]+)}/**$1**/g; $line =~ s/\@strong{([^}]+)}/**$1**/g; $line =~ s/\@file{([^}]+)}/**$1**/g; $line =~ s/\@var{([^}]+)}/**$1**/g; $line =~ s/\@env{([^}]+)}/**$1**/g; $line =~ s/\@option{([^}]+)}/**$1**/g; $line =~ s/\@emph{([^}]+)}/\/\/$1\/\//g; $line =~ s/\@math{(.+)}/{{{$1}}}/g; # Sections $line =~ s/^\@chapter\s*(.+)$/== $1 ==\n/g; $line =~ s/^\@section\s*(.+)$/=== $1 ===\n/g; $line =~ s/^\@subsection\s*(.+)$/==== $1 ====\n/g; # Urls $line =~ s/\@url{([^},]+),\s*([^}]+)}/[[$1|$2]]/; $line =~ s/\@url{([^}]+)}/[[$1|$1]]/; # Ignores $line =~ s/\\input texinfo//; $line =~ s/\@settitle.*//; $line =~ s/\@contents.*//; $line =~ s/\@author.*//; $line =~ s/\@bye.*//; $line =~ s/\@(?:sub)?title.*//; $line =~ s/^\@noindent$//g; # Strip lines $line =~ s/(.+)\n$/$1 /s unless $preserve_end; return $line; } sub check_special_begin { my $line = shift; if ($line =~ /^\@example/) { print "\n{{{\n"; push @states, $state; $state = 1; $levels ++; return 1; } elsif ($line =~ /^\@itemize/) { push @states, $state; $state = 2; $levels ++; return 1; } elsif ($line =~ /^\@enumerate/) { push @states, $state; $state = 3; $levels ++; return 1; } elsif ($line =~ /^\@multitable/) { push @states, $state; $state = 4; $levels ++; return 1; } return 0; } sub check_special_end { my $line = shift; if ($line =~ /^\@end example/) { print "}}}"; $levels --; $state = pop @states or 0; print "\n\n"; return 1; } elsif ($line =~ /^\@end itemize/) { $state = pop @states or 0; $levels --; print "\n\n"; return 1; } elsif ($line =~ /^\@end enumerate/) { $state = pop @states or 0; $levels --; print "\n\n"; return 1; } elsif ($line =~ /^\@end multitable/) { $state = pop @states or 0; $levels --; finish_multitable (); print "\n\n"; return 1; } return 0; } sub handle_example { my $line = shift; return handle_normal_line ($line, 1); } sub handle_itemize { my $line = shift; my $stars = "*" x $levels; $line =~ s/^\@item/\n$stars/; return handle_normal_line ($line); } sub handle_enumerate { my $line = shift; my $stars = "#" x $levels; $line =~ s/^\@item/\n$stars/; return handle_normal_line ($line); } sub handle_multitable { my $line = shift; my $in_head = 0; if ($line =~ /\@headitem/) { $in_head = 1; } $line =~ s/^\@headitem\s*(\S+)/\n\n|=$1/; $line =~ s/^\@item/\n|/; if ($in_head) { $line =~ s/\@tab\s*(\S+)/|=$1/g; } else { $line =~ s/\@tab\s*(\S+)/| $1/g; } $table_line .= handle_normal_line ($line); undef; } sub finish_multitable { my @lengths; foreach (split /^/, $table_line) { my @items = split /\|/, $_,; my $i; for ($i = 1; $i < scalar(@items); $i++) { if (defined($lengths[$i])) { $lengths[$i] = length $items[$i] if $lengths[$i] < length $items[$i]; } else { $lengths[$i] = length $items[$i]; } } } # Now lengths contains maximum length for each column foreach (split /^/, $table_line) { chomp; my @items = split /\|/, $_,; my $i; for ($i = 1; $i < scalar(@items); $i ++) { if ($lengths[$i] > length $items[$i]) { print "|$items[$i]" . " " x ($lengths[$i] - length $items[$i]); } else { print "|$items[$i]"; } } print "\n" if $i != 1; } $table_line = ""; }