--- gvpe/doc/pod2texi 2003/04/13 16:00:31 1.3 +++ gvpe/doc/pod2texi 2008/08/27 22:14:03 1.8 @@ -1,6 +1,8 @@ -#!/usr/bin/perl -p +#!/usr/bin/perl -use Pod::Tree; +# TODO: texinfo fails on @cindex in title elements etc. *sigh* + +use Pod::POM; sub escape_texi($) { local $_ = shift; @@ -11,110 +13,181 @@ sub example { my $text = $_[0]; - print "\n\n\@example\n"; $text =~ s/\n+$//; - $text =~ s/([\@\{\}])/@$1/g; - print $text; - print "\n\@end example\n\n"; -} - -while (<>) { - if (/^\@c INCLUDE-(\S+) (\S+)/) { - my $type = $1; - my $name = $2; - my $path = $2; - - $name =~ s/\.(\d)$/($1)/; - - print "\@chapter $name\n\n"; - - if ($type eq "POD") { - open my $x, "<$path.pod" or die "$path.pod: $!"; - my $data = do { local $/; <$x> }; - - my $pod = new Pod::Tree; - $pod->load_string($data); - - my $walker; $walker = sub { - my $n = $_[0]; - if ($n->is_code) { - # nop - } elsif ($n->is_link) { - my $target = $n->get_target; - my $page = $target->get_page; - my $section = $target->get_section; - - #print ""; - $walker->($_) for @{$n->get_children}; - #print ""; - } elsif ($n->is_text) { - print escape_texi $n->get_text; - } elsif ($n->is_verbatim) { - example $n->get_text; - } elsif ($n->is_sequence) { - if ($n->get_letter eq "C") { - print "\@t{"; - $walker->($_) for @{$n->get_children}; - print "}"; - } elsif ($n->get_letter eq "B") { - print "\@strong{"; - $walker->($_) for @{$n->get_children}; - print "}"; - } elsif ($n->get_letter eq "I" or $n->get_letter eq "F") { - print "\@emph{"; - $walker->($_) for @{$n->get_children}; - print "}"; - } else { - # S would mean to use nbsp - $walker->($_) for @{$n->get_children}; - } - } elsif ($n->is_command) { - if ($n->is_c_head1) { - print "\n\@subsection "; - $walker->($_) for @{$n->get_children}; - print "\n"; - } elsif ($n->is_c_head2) { - print "\n\n\@subsubsection "; - $walker->($_) for @{$n->get_children}; - print "\n"; - } else { - # nop? - } - } elsif ($n->is_ordinary) { - $walker->($_) for @{$n->get_children}; - print "\@refill\n"; - } elsif ($n->is_root) { - $walker->($_) for @{$n->get_children}; - } elsif ($n->is_list) { - print "\n\n\@itemize\n"; - $walker->($_) for @{$n->get_children}; - print "\@end itemize\n\n"; - } elsif ($n->is_item) { - print "\n\n\@item\n"; - print "\@b{"; - $walker->($_) for @{$n->get_children}; - print "}\n\n"; - $walker->($_) for @{$n->get_siblings}; - } else { - die "UNKNOWN NODE $_[0]{type}
"; - $walker->($_) for @{$n->get_children}; + $text =~ s/([\@\{\}])/\@$1/g; + + "\n\n\@example\n" + . $text + . "\n\@end example\n\n"; +} + +my @nodes; # nodelist +my @ctx; # curstack + +sub out { + $ctx[-1]{out} .= join "", @_; +} + +sub TEX::view_seq_code { "\@t{$_[1]}" } +sub TEX::view_seq_bold { "\@strong{$_[1]}" } +sub TEX::view_seq_italic { "\@emph{$_[1]}" } + +sub TEX::view_seq_space { escape_texi $_[1] } +sub TEX::view_seq_text { escape_texi $_[1] } + +sub TEX::view_seq_link { $_[1] } +sub TEX::view_seq_index { + "\n\@cindex $_[1]\n$_[1]" +} + +*TXT::view_seq_code = +*TXT::view_seq_bold = +*TXT::view_seq_italic = +*TXT::view_seq_space = +*TXT::view_seq_text = +*TXT::view_seq_link = +*TXT::view_seq_index = sub { $_[1] }; + +my %ignore = ( + "SEE ALSO" => 1, + "AUTHOR" => 1, +); + +sub parse_pod { + my ($data) = @_; + local $out; + + local $Pod::POM::DEFAULT_VIEW = TEX::; + + my $parser = new Pod::POM; + my $pod = $parser->parse_text ($data) + or die; + + my $walker; $walker = sub { + my $n = $_[0]; + my $t = $n->type; + + if ($t eq "text") { + out $n->text . "\n\@refill\n"; + + } elsif ($t eq "pod") { + $walker->($_) for $n->content; + + } elsif ($t eq "verbatim") { + out example $n->text; + + } elsif ($t eq "head1") { + + return if $ignore{$n->title}; + + out "\n\@section " . $n->title . "\n"; + $walker->($_) for $n->content; + out "\n"; + + } elsif ($t eq "head2") { + out "\n\n\@subsection " . $n->title . "\n"; + $walker->($_) for $n->content; + + } elsif ($t eq "over") { + out "\n\n\@itemize\n"; + $walker->($_) for $n->content; + out "\@end itemize\n\n"; + + } elsif ($t eq "item") { + out "\n\n\@item\n" . $n->title . "\n\n"; + + if ($n->title->present (TXT::) =~ /^\s*([a-zA-Z0-9\-\_]+)\s*=/) { + out "\@cindex $1\n"; + } + $walker->($_) for $n->content; + + } elsif ($t eq "begin") { + local $Pod::POM::DEFAULT_VIEW = Pod::POM::View::Pod; + my $format = $n->format; + + if ($format =~ /texinfo\s+header/) { + $header = $n->content; + } elsif ($format =~ /texinfo\s+footer/) { + $footer = $n->content; + } else { + out $n->content; + } + + } elsif ($t eq "for") { + my $text = $n->text; + + if ($text =~ /^menu-begin/) { + out "\n\@menu\n"; + + push @ctx, {}; # dummy node + + } elsif ($text =~ /^menu-item (.*?)::\s+(.*)/) { + my ($name, $desc) = ($1, $2); + + push @{ $ctx[-2]{menu} }, [$name, $desc]; + $ctx[-2]{width} = length $name if $ctx[-2]{width} < length $name; + + my $ctx = { + name => $name, + up => $ctx[-2]{name}, + }; + push @nodes, $ctx; + $ctx[-1] = $ctx; + + } elsif ($text =~ /^menu-end/) { + pop @ctx; + + for (@{ $ctx[-1]{menu} }) { + out sprintf "* %-*s %s\n", $ctx[-1]{width} + 2, "$_->[0]::", $_->[1]; } - }; - - $walker->($pod->get_root); - } elsif ($type eq "TEXT") { - open my $x, "<$path" or die "$path: $!"; - my $data = do { local $/; <$x> }; - - print $data; - } elsif ($type eq "EXAMPLE") { - open my $x, "<$path" or die "$path: $!"; - my $data = do { local $/; <$x> }; - example $data; + out "\@end menu\n"; + + } elsif ($text =~ /^include (\S+) (.*)/) { + my ($type, $path) = ($1, $2); + + open my $x, "<$path" or die "$path: $!"; + my $data = do { local $/; <$x> }; + + if ($type eq "pod") { + out parse_pod ($data); + } elsif ($type eq "text") { + out $data; + } elsif ($type eq "example") { + out example $data; + } + + } else { + die "UNKNOWN for command <$text>\n"; + } + + } else { + die "UNKNOWN NODE $t\n"; } - } else { - print; - } + }; + + $walker->($pod); } +@ctx = @nodes = { + up => "(dir)", + name => "Top", +}; + +parse_pod do { local $/; <> }; + +print $header; + +for (0 .. $#nodes) { + my $node = $nodes[$_]; + my $prev = $_ > 0 ? $nodes[$_-1] : undef; + my $next = $nodes[$_+1]; + my $chapter = $node->{name} eq "Top" ? "Introduction" : $node->{name}; + + print "\@node $node->{name},$next->{name},$prev->{name},$node->{up}\n\n", + "\@chapter $chapter\n", + "$node->{out}\n\n"; +} + +print $footer; +