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