#!/usr/bin/perl # # Translate Emacs info files into HTML pages, one page per node. # Menus, Notes, and Up/Next/Prev pointers are translated into links. # Other text is left as-is in
 tags.
#
# Option: -d  specifies where to put the output files.
#
# This code is in the public domain.  No warranties, express or implied.
#
# Author: Kian-Tat Lim (ktl@wag.caltech.edu),  Dec 1993.
# Bugfixes by: Wolfram Schneider , Oct 1997.
#
# $Id: info2html,v 1.3 1997/10/09 11:47:38 wosch Exp wosch $


# parent directory
$up = '..';

# Canonicalize a node name by translating any characters that may give problems
# in an HREF into acceptable alternatives.
sub canon {
	local($_) = $_[0];
	s/\&/_and_/g;
	s|[<>/#? ]|_|g;
	s/"/'/g;
	return $_;
}

# Translate HTML special characters into escape sequences
sub html {
	local($_) = $_[0];
	s/\&/&/g;
	s/\/>/g;
	return $_;
}

# Translate escape sequences back to characters
sub dehtml {
	local($_) = $_[0];
	s/\<//g;
	s/\&/\&/g;
	return $_;
}

#
# Main program
#

# Handle -d switch
require 'getopts.pl';
do Getopts('d:');

# Any header stuff in the info file goes to the bit bucket
open(OUT, ">/dev/null");

# Process lines
while (<>) {

# Do this after first <> access so input file can be in original directory
	chdir($opt_d), $done_d = 1 if !$done_d && defined($opt_d);

# If we had a *Note that wrapped, tack it onto the beginning of this line
	$_ = $leftover . $_;
	$leftover = '';

# Start a new node
	if (/^\037/) {

	# Finish off what we were last doing
		if ($menumode) {
			print OUT "\n";
			$menumode = 0;
		}
		else {
			print OUT "\n";
		}

	# ^_^L signals the end of the useful stuff
		exit if /^\037\014/;

	# Get the node header line, done if none left
		$_ = <>;
		exit if eof;

	# ignore tag table
		exit if /^Tag Table:$/;


		($file, $node) = /^File:\s+(\S+)\s+Node:\s+([^,]+),/;
		chop($file) if $file =~ /,$/;
		$cnode = &canon($node);
		$hnode = &html($node);

	# Start a new file
		close OUT;
		open(OUT, ">$file.$cnode.html");
		print OUT "$hnode\n";
		$body = "\n";

	# Split out Up, Next, Prev pointers so we can make them into links
		@items = split(/,/);
		shift(@items);
		for (@items) {
			if (/^\s*Up:\s+(.*)/) {
			    if ($1 eq "(dir)" || $1 eq "(DIR)") {
				$node = $up;
			    } else {
				$node = $file . "." . &canon($1) . ".html";
			    }
				print OUT
				"\n";
				$body .= "Go up to " .
				"$1.
\n"; } if (/^\s*Next:\s+(.*)/) { $node = $file . "." . &canon($1) . ".html"; print OUT "\n"; $body .= "Go forward to " . "$1.
\n"; } if (/^\s*Prev:\s+(.*)/) { if ($1 eq "(dir)" || $1 eq "(DIR)") { $node = $up; } else { $node = $file . "." . &canon($1) . ".html"; } print OUT "\n"; $body .= "Go backward to " . "$1.
\n"; } } # for (@items) # Start the body of the node print OUT $body; # Leave the rest of the text as-is print OUT "
\n";
	} # elsif (/^\037/)

# Start a menu
	elsif (/^\* Menu:/) {
		print OUT "

Menu

\n"; $menumode = 1; } # Process a menu item by turning it into a link elsif ($menumode && /^\*\s+([^:]*)::\s*(.*)/) { $node = &canon($1); $hnode = &html($1); $text = &html($2); print OUT "
$hnode\n"; print OUT "
$text\n"; } # Alternate menu style ("tag: node text"). Tab, comma, period inside brackets. elsif ($menumode && /^\*\s+([^:]*):\s*([^ ,.]+)(.*)/) { $node = &canon($2); $hnode = &html($2); $text = &html($3); $tag = &html($1); print OUT "
"; print OUT "$tag: $hnode\n"; # Trim off termination character and space, if any $text =~ s/^[ ,.]\s*//; print OUT "
$text\n"; } # Process heading text inside menus -- continuation lines are just dumped below elsif ($menumode && /^\S/) { print OUT "

", &html($_); } # Anything else. Look for notes; otherwise, just dump after handling specials. else { # If a *Note wrapped, save it to be prepended to the next line if (/(\*[Nn]ote)\s+$/) { $_ = $` . "\n"; $leftover = $1 . " "; } # Protect HTML special characters $_ = &html($_); # Convert a note into a link while (/\*([Nn])ote\s+([^:]*)::/) { # continue line if ($' eq '') { $backup = <>; $backup =~ s/^\s*//; chop($_); $_ .= " $backup"; next; } $node = &canon(&dehtml($2)); $see = ($1 eq "N") ? "See" : "see"; # ignore links to other info files (emacs)info if (substr($2, 0, 1) eq '(') { $_ = $` . $'; next; } $_ = $` . "$see $2" . $'; } # Alternate note style while (/\*([Nn])ote\s+([^:]*):\s*([^ ,.]+)/) { # continue line if ($' eq '') { $backup = <>; $backup =~ s/^\s*//; chop($_); $_ .= " $backup"; next; } # ignore links to other info files (emacs)info if (substr($3, 0, 1) eq '(') { $_ = $`; next; } $node = &canon(&dehtml($3)); $see = ($1 eq "N") ? "See" : "see"; $_ = $` . "$see $2: $3" . $'; } print OUT; } } # while (<>)