summaryrefslogtreecommitdiff
path: root/biblio/bibtex/utils/bibtools/bib2html
blob: 11cc76176774445abc77dbb1fd4a9ea498eacf1c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
#!/usr/bin/perl
#
# bib2html - make an html file that is equivalent to the bib files,
#   using one of the html bib styles
#
# usage: 
$usage = "usage: $0 {alpha|index|long|longp|long-pario|short|short-pario|cv} [-o <outfile>] file.bib...\
OR \
$0 [ {alpha|index|long|longp|long-pario|short|short-pario|cv} ] [-o <outfile>] -a file.aux";
# Output is to bib.html. 
#    alpha makes a bibliography like bibstyle{alpha}
#    long makes a bibliography like bibstyle{abstract}
#    short makes a bibliography like bibstyle{alpha}, but with citekey for tags
#    cv lists title first, does not print key, does not sort
#	(useful for listing your papers on your home page)
#
# David Kotz 7/94
# dfk@cs.dartmouth.edu

# updated Dan Gildea 1/2003:
#  . now handles nested \bf \em etc correctly
#  . added some more accents
#  . new -a file.aux usage to use existing .aux file, useful to 
#	list only papers cited by a given latex document
# http://www.cs.rochester.edu/~gildea/

# updated 2/2004, thanks to Juergen Vollmer
#  a) allowing \emph{..}, \texttt{...} and \textbf{..}
#  b) setting the environment variable BSTINPUTS to directory from $0
#  c) if run on existing .aux file, bibstyle is now optional on the command line.
#	if not bib style nor specified on command line, uses the html version
#	of bib style from original document.

use File::Basename;
use File::Spec::Functions;

$tmp = "/tmp/bib2html$$";

my $cmd_dir   = catfile (dirname ($0),
			 dirname ((defined readlink($0)) ? readlink($0) : $0));

$ENV{BSTINPUTS} .= ":$cmd_dir";

if ( scalar(@ARGV) < 2 ) {
    die "$usage\n";
}


## pick up the args
my %Opts;			# will hold the option values

if ($ARGV[0] !~ /^-/) {
    $Opts{style} = shift @ARGV;
}
while ($ARGV[0] =~ /^-/) {
    $tmpArg = shift @ARGV;
    if ($tmpArg eq "-o" ) {
	$Opts{outfile} = shift @ARGV;
    } elsif ($tmpArg eq "-a" ) {
   	$Opts{auxfile} = shift @ARGV; 
    }
}

$Opts{outfile} = "bib.html" if ( !defined ($Opts{outfile}) );

$SIG{INT} = \&cleanup;

print "Creating $tmp.aux for $files\n";
open AUX, ">$tmp.aux";

if ($Opts{auxfile}) {
    system "ls";
    open(AUXIN, $Opts{auxfile}) || die "could not open $Opts{auxfile}";
    while (<AUXIN>) {
	# if style not specified on command line, use html version
	# of style specified in .aux file
	s/^\\bibstyle\{([^\}]*)\}/"\\bibstyle{html-".($Opts{style}||$1)."}"/e;
	print AUX;
    }
} else {
    if (!defined $Opts{style}) {
	die "bib style not defined";
    }
    ## get all the remaining file names
    my $files = killSuffix ( shift @ARGV );
    foreach $file ( @ARGV ) {
	$files .= ',';	# make sure the list is comma delimited, bibtex needs it
	$files .= killSuffix ($file);
    }


## need double slashes here to go around slash interpretation
## only one is printed
    print AUX <<EOF;
\\relax 
\\citation{*}
\\bibstyle{html-$Opts{style}}
\\bibdata{$files}
EOF
}
close AUX;
    
unlink <$tmp.{bbl,blg}>;

if (-r "html-split.bst.gz" ) {
    system ( "gunzip html-split.bst.gz" );
}

print "bibtex $tmp\n";

system "bibtex $tmp";

print "Bibtex done\n\n";


## -------------------------------------------------------------------
## the cleanup operation
open BBL, "$tmp.bbl";
open OUT, ">$Opts{outfile}";

## stack of formatted text types that were started and did not finish on teh same line
## elements are em, tt or b or i and when a candidate for a format-closing brace is found
## this stack will be popped to see which format we have to close
my @formatsToClose;

while ( <BBL> ) { 


    ## accent handlers
    ## these are quite definite about their replacemnets and so should
    ## come before the more generic operations later
    ## all braces in the latex constructs are optional
    ## info on the html codes can be found at http://www.w3.org/TR/REC-html40/
    ## \\? is to handle latex \'\i which you do to put acute on i without dot
    s/\\ \` (?: \{ )? \\? ([aeiouAEIOU]) (?: \} )?
          /&$1grave;/gx;	# grave accent
    s/ \\ \' (?: \{ )? \\? ([aeiouAEIOU]) (?: \} )?
          /&$1acute;/gx;	# 'acute accent
    s/ \\ \^ (?: \{ )? \\? ([aeiouAEIOU]) (?: \} )?
          /&$1circ;/gx;		# circumflex
    s/ \\ \" (?: \{ )? \\? ([aeiouyAEIOUY]) (?: \} )?
          /&$1uml;/gx;		# "umlaut
    s/ \\ \~ (?: \{ )? \\? ([anoANO]) (?: \} )?
          /&$1tilde;/gx;	# tilde
    s/ \\ c (?: \{ )? ([cC]) (?: \} )?
          /&$1cedil;/gx;	# cedilla
    s/ \\ [v\'] (?: \{ )? ([cC]) (?: \} )?
          /$1/gx;		# no html code for czech hook
    s/ \{? \\[s\"]s \}?
          /&szlig;/gx;          # german Scharf-S

    ## several weird symbols
    s/ \\copyright
	/&copy;/gx;
    s/ \\pounds
	/&pound;/gx;
    
    ## weirder symbols
    s/ \\ (ae|AE)
	/&$1lig;/gx;
    s/ \\ (o|O)
	/&$1slash;/gx;
    s/ \\ss
	/&szlig;/gx;

    ## greek letters, case insensitive matching, but upper case in latex and
    ## html have the first letter of the english word capitalized
    s/ \\ (?: var )? (alpha|beta|gamma|delta|epsilon|theta|lambda|pi|rho|sigma|omega)
	/&$1;/gxi;

    ## remove any \/ space-increasing symbols
    s+ ([^\\]) \\ \/
	+$1+gx;

    s+ \\ \ + +gx;

    ## deal with \cite stuff, change it to a link to a record the same html file
    s+ ([^\\]) \\cite\{ (.*?) \}
        +$1<a href="#$2">$2</a>+xg;

    ## These rules are to deal with my (DFK) macros
    s/\\ie/i.e./g;
    s/\\eg/e.g./g;
    s/\\etc/etc./g;
    s+\\vs\\+<EM>vs.</EM>+g;
    s/\\usec/usec/g;
    s/\\mbox //g;
    s/\\par / <P> /g;
    s/\\par$/ <P>/g;


    s/\\\&/\&amp;/g;		# ampersand

    s/-{2,3}/-/g;		# multiple dashes

# a few rules are needed to compensate for BibTeXs way of splitting
# long words over two lines by sticking a % (TeX comment character) at
# the end of the line.  This works when one word (usually a URL) is
# split over more than one line. 
    ## if we have an unescaped % at the end of the line, remove it and the newline and
    ## join the next line on
    ## example straight out of the camel book, pg 204. amazing
    if ( s/ ([^\\]) \% \n$ /$1/x and $nextline = <BBL> ) {
	$_ .= $nextline;
	redo;			# back to the top
    }

# hyphenation characters should be removed
    s+\\-++g;

# tildes -
#         tilde not preceded by \ or / is a nbsp
#         \~{} is ~ (likely in a URL)
#         all other tildes left alone, notably /~ (URL)
    s+ ([^\\/]) ~ +$1&nbsp;+xg;	# normal standalone tilde - nbsp
    s/ \\~ \{\} /~/xg;		# \~{} to ~ - do before removing braces below

    ## --------------------------------------------------------
    ## deal with em and tt and bf text surrounded by braces
    ## deal with \emph{..}, \texttt{...} and \textbf{..}

    ## the fancy groupings around the em etc are because in html bold font is not 'bf'
    ## but just b and italic is i not 'it' so we have to pick out only a part of those
    ## latex tags
    ## final |\w+ is to skip over \rm or any other commands we don't handle
    ## also removes braces with no command

    while ( /(text(b)f|text(tt)|(em)ph)?([\{\}])/ ) {
	if (defined $1) {
	    my $cmd = "$1";
	    my $fmt = $2 || $3 || $4;
	    s/\\$cmd\{/<$fmt>/;
	    push ( @formatsToClose, $fmt )
	} elsif ($5 eq '{') {
	    ## beginning of format
	    s/ \{ (?: \\ (?: (em)|(b)f|(tt)|(i)t|\w+ ) )? \s* 
		/ ( $format = $1 or $2 or $3 or $4  ) ? "<$format>" : '' /ex ;
	    ## push the format to be closed onto the stack (may be nothing)
	    push ( @formatsToClose, $format ) 
	} else {
	    ## pop format to close from stack
	    s+ \s*\}
	    + ( $format = pop (@formatsToClose) ) ? "</$format>" : '' +ex  ;
	}
    }

    ## --------------------------------------------------------

    ##retrieve symbols escaped by backslashes
    my $escapedChars = quotemeta ( '#$%&_{}' );
    s/ ([^\\]) \\ ([$escapedChars]) 
        /$1$2/gxo;

    print OUT $_;
}


print "\n";
print "\noutput is in $Opts{outfile}\n";

cleanup();

sub killSuffix {
    $file = shift();
    ( $name, $path ) = fileparse ( $file, '\.[^.]*$' ); # the pattern indicates what a suffix looks like
    return ($path . $name);
}

sub cleanup {
    unlink ( glob ("$tmp.{aux,bbl,blg}") );
}