1#!/usr/bin/env perl 2 3# converts vim documentation to simple html 4# Sirtaj Singh Kang ([email protected]) 5 6# Sun Feb 24 14:49:17 CET 2002 7 8use strict; 9use vars qw/%url $date/; 10 11%url = (); 12$date = `date`; 13chop $date; 14 15sub maplink 16{ 17 my $tag = shift; 18 if( exists $url{ $tag } ){ 19 return $url{ $tag }; 20 } else { 21 #warn "Unknown hyperlink target: $tag\n"; 22 $tag =~ s/\.txt//; 23 $tag =~ s/</</g; 24 $tag =~ s/>/>/g; 25 return "<code class=\"badlink\">$tag</code>"; 26 } 27} 28 29sub readTagFile 30{ 31 my($tagfile) = @_; 32 my( $tag, $file, $name ); 33 34 open(TAGS,"$tagfile") || die "can't read tags\n"; 35 36 while( <TAGS> ) { 37 next unless /^(\S+)\s+(\S+)\s+/; 38 39 $tag = $1; 40 my $label = $tag; 41 ($file= $2) =~ s/.txt$/.html/g; 42 $label =~ s/\.txt//; 43 44 $url{ $tag } = "<a href=\"$file#".escurl($tag)."\">".esctext($label)."</a>"; 45 } 46 close( TAGS ); 47} 48 49sub esctext 50{ 51 my $text = shift; 52 $text =~ s/&/&/g; 53 $text =~ s/</</g; 54 $text =~ s/>/>/g; 55 return $text; 56} 57 58sub escurl 59{ 60 my $url = shift; 61 $url =~ s/"/%22/g; 62 $url =~ s/~/%7E/g; 63 $url =~ s/</%3C/g; 64 $url =~ s/>/%3E/g; 65 $url =~ s/=/%20/g; 66 $url =~ s/#/%23/g; 67 $url =~ s/\//%2F/g; 68 69 return $url; 70} 71 72sub vim2html 73{ 74 my( $infile ) = @_; 75 my( $outfile ); 76 77 open(IN, "$infile" ) || die "Couldn't read from $infile: $!.\n"; 78 79 ($outfile = $infile) =~ s:.*/::g; 80 $outfile =~ s/\.txt$//g; 81 82 open( OUT, ">$outfile.html" ) 83 || die "Couldn't write to $outfile.html: $!.\n"; 84 my $head = uc( $outfile ); 85 86 print OUT<<EOF; 87<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 88<html> 89<head> 90<title>VIM: $outfile</title> 91<link rel="stylesheet" href="vim-stylesheet.css" type="text/css"> 92</head> 93<body> 94<h2>$head</h2> 95<pre> 96EOF 97 98 my $inexample = 0; 99 while( <IN> ) { 100 chop; 101 if ( /^\s*[-=]+\s*$/ ) { 102 print OUT "</pre><hr><pre>"; 103 next; 104 } 105 106 # examples 107 elsif( /^>$/ || /\s>$/ ) { 108 $inexample = 1; 109 chop; 110 } 111 elsif ( $inexample && /^([<\S])/ ) { 112 $inexample = 0; 113 $_ = $' if $1 eq "<"; 114 } 115 116 s/\s+$//g; 117 118 # Various vim highlights. note that < and > have already been escaped 119 # so that HTML doesn't get screwed up. 120 121 my @out = (); 122 # print "Text: $_\n"; 123 LOOP: 124 foreach my $token ( split /((?:\|[^\|]+\|)|(?:\*[^\*]+\*))/ ) { 125 if ( $token =~ /^\|([^\|]+)\|/ ) { 126 # link 127 push( @out, "|".maplink( $1 )."|" ); 128 next LOOP; 129 } 130 elsif ( $token =~ /^\*([^\*]+)\*/ ) { 131 # target 132 push( @out, 133 "<b class=\"vimtag\">\*<a name=\"".escurl($1)."\">".esctext($1)."<\/a>\*<\/b>"); 134 next LOOP; 135 } 136 137 $_ = esctext($token); 138 s/CTRL-(\w+)/<code class="keystroke">CTRL-$1<\/code>/g; 139 # parameter <...> 140 s/<(.*?)>/<code class="special"><$1><\/code>/g; 141 142 # parameter {...} 143 s/\{([^}]*)\}/<code class="special">{$1}<\/code>/g; 144 145 # parameter [...] 146 s/\[(range|line|count|offset|cmd|[-+]?num)\]/<code class="special">\[$1\]<\/code>/g; 147 # note 148 s/(Note:?)/<code class="note">$1<\/code>/gi; 149 150 # local heading 151 s/^(.*)\~$/<code class="section">$1<\/code>/g; 152 push( @out, $_ ); 153 } 154 155 $_ = join( "", @out ); 156 157 if( $inexample == 2 ) { 158 print OUT "<code class=\"example\">$_</code>\n"; 159 } else { 160 print OUT $_,"\n"; 161 } 162 163 $inexample = 2 if $inexample == 1; 164 } 165 print OUT<<EOF; 166</pre> 167<p><i>Generated by vim2html on $date</i></p> 168</body> 169</html> 170EOF 171 172} 173 174sub usage 175{ 176die<<EOF; 177vim2html.pl: converts vim documentation to HTML. 178usage: 179 180 vim2html.pl <tag file> <text files> 181EOF 182} 183 184 185sub writeCSS 186{ 187 open( CSS, ">vim-stylesheet.css" ) || die "Couldn't write stylesheet: $!\n"; 188 print CSS<<EOF; 189body { background-color: white; color: black;} 190:link { color: rgb(0,137,139); } 191:visited { color: rgb(0,100,100); 192 background-color: white; /* should be inherit */ } 193:active { color: rgb(0,200,200); 194 background-color: white; /* should be inherit */ } 195 196B.vimtag { color : rgb(250,0,250); } 197 198h1, h2 { color: rgb(82,80,82); text-align: center; } 199h3, h4, h5, h6 { color: rgb(82,80,82); } 200.headline { color: rgb(0,137,139); } 201.header { color: rgb(164, 32, 246); } 202.section { color: rgb(164, 32, 246); } 203.keystroke { color: rgb(106, 89, 205); } 204.vim { } 205.example { color: rgb(0, 0, 255); } 206.option { } 207.notvi { } 208.special { color: rgb(106, 89, 205); } 209.note { color: blue; background-color: yellow; } 210.sub {} 211.badlink { color: rgb(0,37,39); } 212EOF 213 214} 215 216# main 217usage() if $#ARGV < 1; 218 219print "Processing tags...\n"; 220readTagFile( $ARGV[ 0 ] ); 221 222foreach my $file ( 1..$#ARGV ) { 223 print "Processing ".$ARGV[ $file ]."...\n"; 224 vim2html( $ARGV[ $file ] ); 225} 226print "Writing stylesheet...\n"; 227writeCSS(); 228print "done.\n" 229