1#
2# Below is a stripped down version of bib2xhtml used by doxygen.
3# For the full version see http://www.spinellis.gr/sw/textproc/bib2xhtml/
4#
5# Convert from bibtex to XHTML.
6#
7# (C) Copyright 1995, 1996 David Hull.
8# (David Hull / hull@cs.uiuc.edu / http://www.uiuc.edu/ph/www/dlhull)
9#
10# (C) Copyright 2002-2010 Diomidis Spinellis
11# http://www.spinellis.gr
12#
13# This program is free software.  You can redistribute it and/or modify
14# it under the terms of the GNU General Public License.  See the
15# files README and COPYING for details.
16#
17# This source code contains UTF-8 characters.  You might want to use
18# an appropriate editor, if you want to view/modify the LaTeX to Unicode
19# substitution commands.
20#
21
22use Getopt::Std;
23use open IO => ':crlf';
24$label_styles{'numbered'} = 	$LABEL_NUMBERED = 	2;
25$list_start[$LABEL_NUMBERED] = 'dl class="citelist"';
26$list_end[$LABEL_NUMBERED] = "/dl";
27@tmpfiles = ();
28sub html_ent {
29	s/\\i\b/i/g;
30	s/\\\'(\001\d+)\{([AEIOUaeiou])\1\}/&$2acute;/gs;
31	s/\\\'([AEIOUaeiou])/&$1acute;/g;
32	s/\\\`(\001\d+)\{([AEIOUaeiou])\1\}/&$2grave;/gs;
33	s/\\\`([AEIOUaeiou])/&$1grave;/g;
34	s/\\\"(\001\d+)\{([AEIOUaeiouy])\1\}/&$2uml;/gs;
35	s/\\\"([AEIOUaeiouy])/&$1uml;/g;
36	s/\\\~(\001\d+)\{([ANOano])\1\}/&$2tilde;/gs;
37	s/\\\~([ANOano])/&$1tilde;/g;
38	s/\\\^(\001\d+)\{([AEIOUaeiou])\1\}/&$2circ;/gs;
39	s/\\\^([AEIOUaeiou])/&$1circ;/g;
40	s/\\c(\001\d+)\{([Cc])\1\}/&$2cedil;/gs;
41	s/\\u(\001\d+)\{(.)\1\}/$2/gs;
42	s/\\v(\001\d+)\{(.)\1\}/$2/gs;
43	s/\\([lL])\b/$1/g;
44	s/\\\=(\001\d+)\{(.)\1\}/$2/gs;
45	s/\\\=(.)/$1/g;
46	s/\\\.(\001\d+)\{(.)\1\}/$2/gs;
47	s/\\\.(.)/$1/g;
48	s/\\([Oo])\b\s*/&$1slash;/g;
49	s/\\AA\b\s*/Å/g;
50	s/\\aa\b\s*/å/g;
51	s/\\AE\b\s*/Æ/g;
52	s/\\ae\b\s*/æ/g;
53	s/\\ss\b\s*/ß/g;
54	s/\\S\b\s*/§/g;
55	s/\\P\b\s*/¶/g;
56	s/\\pounds\b\s*/£/g;
57	s/\?\`/¿/g;
58	s/\!\`/¡/g;
59	s/\-\-\-/—/g;
60	s/([^\!])\-\-([^\>])/$1–$2/g;
61	s/(CITEREF_[^\!])–([^\>])/$1--$2/g;
62	s/(CITEREF_[^\!])—([^\>])/$1---$2/g;
63	s/\\([aA]lpha)\b/&$1;/g;
64	s/\\([bB]eta)\b/&$1;/g;
65	s/\\([gG]amma)\b/&$1;/g;
66	s/\\([dD]elta)\b/&$1;/g;
67	s/\\varepsilon\b/ε/g;
68	s/\\([eE]psilon)\b/&$1;/g;
69	s/\\([zZ]eta)\b/&$1;/g;
70	s/\\([eE]ta)\b/&$1;/g;
71	s/\\([tT]heta)\b/&$1;/g;
72	s/\\vartheta\b/θ/g;
73	s/\\([iI]ota)\b/&$1;/g;
74	s/\\([kK]appa)\b/&$1;/g;
75	s/\\([lL]ambda)\b/&$1;/g;
76	s/\\([mM]u)\b/&$1;/g;
77	s/\\([nN]u)\b/&$1;/g;
78	s/\\([xX]i)\b/&$1;/g;
79	s/\\([oO]micron)\b/&$1;/g;
80	s/\\([pP]i)\b/&$1;/g;
81	s/\\varpi\b/π/g;
82	s/\\([rR]ho)\b/&$1;/g;
83	s/\\varrho\b/ρ/g;
84	s/\\([sS]igma)\b/&$1;/g;
85	s/\\varsigma\b/ς/g;
86	s/\\([tT]au)\b/&$1;/g;
87	s/\\([uU]psilon)\b/&$1;/g;
88	s/\\([pP]hi)\b/&$1;/g;
89	s/\\varphi\b/φ/g;
90	s/\\([cC]hi)\b/&$1;/g;
91	s/\\([pP]si)\b/&$1;/g;
92	s/\\([oO]mega)\b/&$1;/g;
93	s/\\S\b/§/g;
94	s/^\\circ\b/°/g;
95	s/\\infty\b/∞/g;
96	s/\\emptyset\b/∅/g;
97	s/\\pm\b/±/g;
98	s/\\times\b/×/g;
99	s/\\cdot\b/⋅/g;
100	s/\\partial\b/∂/g;
101	s/\\nabla\b/∇/g;
102	s/\\surd\b/√/g;
103	s/\\perp\b/⊥/g;
104	s/\\sum\b/∑/g;
105	s/\\int\b/∫/g;
106	s/\\prod\b/∏/g;
107	s/\\sim\b/∼/g;
108	s/\\approx\b/≈/g;
109	s/\\ne\b/≠/g;
110	s/\\equiv\b/≡/g;
111	s/\\propto\b/∝/g;
112	s/\\le\b/≤/g;
113	s/\\ge\b/≥/g;
114	s/\\leftarrow\b/←/g;
115	s/\\rightarrow\b/→/g;
116	s/\\in\b/∈/g;
117	s/\\notin\b/∉/g;
118	s/\\lceil\b/⌈/g;
119	s/\\rceil\b/⌉/g;
120	s/\\lfloor\b/⌊/g;
121	s/\\rfloor\b/⌋/g;
122}
123$bdebug = 0;
124foreach (@ARGV) {
125  if (/\.bib$/) {
126    $bibfile = $_;
127    $bibfile =~ s/\.bib$//;
128    push(@bibfiles,$bibfile);
129  } elsif ("$_" eq "-d") {
130    $bdebug = 1;
131  } else {
132    $htmlfile = $_;
133  }
134}
135exit(1) unless defined($htmlfile);
136$bibdatacmd="\\bibdata{".join(',',@bibfiles)."}";
137$label_style = $LABEL_NUMBERED;
138$bstfile = "doxygen";
139umask(077);
140open(HTMLFILE,">$htmlfile$$");
141if (open(OHTMLFILE, "$htmlfile")) {
142    $mode = (stat OHTMLFILE)[2] & 0xfff;
143} else {
144  print "Error opening $htmlfile\n";
145  exit(1);
146}
147$beginstring = "<!-- BEGIN CITATIONS -->";
148$endstring = "<!-- END CITATIONS -->";
149@citations = ();
150loop:
151while (<OHTMLFILE>) {
152  print HTMLFILE;
153  last loop if m/^$beginstring$/;
154}
155loop:
156while (<OHTMLFILE>) {
157  print HTMLFILE;
158  last loop if m/^$endstring$/;
159  push(@citations, $2) if m/^([^\\]*)?(.+\})(.*)?$/;
160}
161push(@citations, $bibdatacmd);
162$auxfile = "bib$$";
163push(@tmpfiles, "$auxfile.aux");
164open(AUXFILE, ">$auxfile" . ".aux");
165print AUXFILE "\\relax\n\\bibstyle{$bstfile}\n";
166foreach $citation (@citations) {
167  print AUXFILE "$citation\n";
168}
169close(AUXFILE);
170push(@tmpfiles, "$auxfile.blg");
171push(@tmpfiles, "$auxfile.bbl");
172`bibtex $auxfile 2>&1`;
173if ($?==-1)
174{
175  print "bibtex command failed: $!\n";
176}
177$beginstring = "<!-- BEGIN BIBLIOGRAPHY -->";
178$endstring = "<!-- END BIBLIOGRAPHY -->";
179loop:
180while (<OHTMLFILE>) {
181  last loop if m/^$beginstring$/;
182  print HTMLFILE;
183}
184loop:
185while (<OHTMLFILE>) {
186  last loop if m/^$endstring$/;
187}
188print HTMLFILE "$beginstring\n";
189$t = $auxfile . ".bbl";
190$/ = "";
191open(BBLFILE, "<$t") || die "error opening $t: $!\n";
192$nentry = 0;
193loop:
194while (<BBLFILE>) {
195    if (($nentry == 0) && (m/^#/)) {
196	if ((m/#\s*label-style:\s*(\S+)/) && (! defined $label_style)) {
197	    $label_style = $label_styles{$1};
198	    if (! defined $label_style) {
199		print STDERR "label style unknown: \n";
200		next loop;
201	    }
202	}
203	next loop;
204    }
205    $nentry++;
206    ($bcite, $blabel) = m:<dt><a\s+name=\"([^\"]*)\">\[([^\]]*)\]</a></dt><dd>:;
207    $blabel = "$nentry";
208    $bibcite{$bcite} = $blabel;
209}
210close(BBLFILE);
211$label_style = $LABEL_DEFAULT if (! defined $label_style);
212$list_start = $list_start[$label_style];
213$list_end = $list_end[$label_style];
214print HTMLFILE "<$list_start>\n\n";
215open(BBLFILE, "<$t") || die "error opening $t: $!\n";
216$nentry = 0;
217loop:
218while (<BBLFILE>) {
219    next loop if (($nentry == 0) && (m/^#/));
220    $nentry++;
221    s/\\\{/\002/g;
222    s/\\\}/\003/g;
223    s/\\\$/\004/g;
224    {
225	local ($c, $l, $z) = (0, 0, ());
226	s/([\{\}])/join("","\001",($1 eq "\{" ? $z[$l++]=$c++ : $z[--$l]),$1)/ge;
227    }
228    s/\%\n//g;
229    s/(\.(<\/cite>|<\/a>|\')+)\./$1/g;
230    s:(<dt><a\s+name=\"[^\"]*\">\[)[^\]]*(\]</a></dt><dd>):$1$nentry$2:;
231    while (m/(\\(cite(label)?)(\001\d+)\{([^\001]+)\4\})/) {
232	$old = $1;
233	$cmd = $2;
234	$doxref = defined($3);
235	$bcite = $5;
236	if (! defined $bibcite{$bcite}) {
237	    $blabel = " [" . $bcite . "]";
238	} elsif ($doxref) {
239	    $blabel = " <a href=\"#$bcite\">[" . $bibcite{$bcite} . "]<\/a>";
240	} else {
241	    $blabel = " [" . $bibcite{$bcite} . "]";
242	}
243	$old =~ s/(\W)/\\$1/g;
244	s/\s*$old/$blabel/g;
245    }
246    s/In (<a href=\"[^\"]*\">)([^\[]+) \[(\2)/In $1\[$2/;
247    s/\\htmladdnormallink(foot)?(\001\d+)\{([^\001]+)\2\}(\001\d+)\{([^\001]+)\4\}/<a href="$5">$3<\/a>/gs;
248    s/\&amp;/\005/g;
249    s/\\?&/&amp;/g;
250    s/\005/&amp;/g;
251    html_ent();
252    while (m/\\char([\'\"]?[0-9a-fA-F]+)/) {
253	$o = $r = $1;
254	if ($r =~ s/^\'//) {
255	    $r = oct($r);
256	} elsif ($r =~ s/^\"//) {
257	    $r = hex($r);
258	}
259	s/\\char$o\s*/&#$r;/g;
260    }
261    s/{\\etalchar\001(\d+)\{(.)}\001\1\}/$2/g;
262    s/\\par\b/<p \/>/g;
263    s/\\url(\001\d+)\{(.*)\1\}/<a href="$2">$2<\/a>/gs;
264    s/\\href(\001\d+)\{(.*)\1\}(\001\d+)\{([^\001]*)\3\}/<a href="$2">$4<\/a>/gs;
265    s/\\href(\001\d+)\{(.*)\1\}/<a href="$2">$2<\/a>/gs;
266    s/(\001\d+)\{\\rm\s+(.*)\1\}/$2/gs;
267    s/\\textrm(\001\d+)\{(.*)\1\}/$2/gs;
268    s/(\001\d+)\{\\em\s+(.*)\1\}/<em>$2<\/em>/gs;
269    s/(\001\d+)\{\\it\s+(.*)\1\}/<i>$2<\/i>/gs;
270    s/(\001\d+)\{\\bf\s+(.*)\1\}/<b>$2<\/b>/gs;
271    s/(\001\d+)\{\\tt\s+(.*)\1\}/<tt>$2<\/tt>/gs;
272    s/\\emph(\001\d+)\{(.*)\1\}/<em>$2<\/em>/gs;
273    s/\\textit(\001\d+)\{(.*)\1\}/<i>$2<\/i>/gs;
274    s/\\textbf(\001\d+)\{(.*)\1\}/<b>$2<\/b>/gs;
275    s/\\texttt(\001\d+)\{(.*)\1\}/<tt>$2<\/tt>/gs;
276    s/\\mathrm(\001\d+)\{(.*)\1\}/$2/gs;
277    s/\\mathnormal(\001\d+)\{(.*)\1\}/$2/gs;
278    s/\\mathsf(\001\d+)\{(.*)\1\}/$2/gs;
279    s/\\mathbf(\001\d+)\{(.*)\1\}/<b>$2<\/b>/gs;
280    s/\\mathcal(\001\d+)\{(.*)\1\}/<i>$2<\/i>/gs;
281    s/\\mathit(\001\d+)\{(.*)\1\}/<i>$2<\/i>/gs;
282    s/\\mathtt(\001\d+)\{(.*)\1\}/<tt>$2<\/tt>/gs;
283    s/\\bibxhtmlname(\001\d+)\{(.*)\1\}/$2/ges;
284    sub domath {
285      local($t) = @_;
286      $t =~ s/\^(\001\d+)\{\\circ\1\}/\&\#176;/gs;
287      $t =~ s/\^\\circ/\&\#176;/g;
288      $t =~ s/\^(\001\d+)\{(.*)\1\}/<sup>$2<\/sup>/gs;
289      $t =~ s/\^(\w)/<sup>$1<\/sup>/g;
290      $t =~ s/\_(\001\d+)\{(.*)\1\}/<sub>$2<\/sub>/gs;
291      $t =~ s/\_(\w)/<sub>$1<\/sub>/g;
292      $t;
293    }
294    s/(\$([^\$]+)\$)/&domath($2)/ge;
295    s/(\\\((([^\\]|\\[^\(\)])+)\\\))/&domath($2)/ge;
296    s/\\mbox(\001\d+)\{(.*)\1\}/$2/gs;
297    while (s/(\<a href\=\"[^"]*?)\~/$1\005/g) { ; }
298    s/([^\\])~/$1&nbsp;/g;
299    s/\\\,/&thinsp;/g;
300    s/\\ldots\b/&hellip;/g;
301    s/\\dots\b/&hellip;/g;
302    s/\005/\~/g;
303    s/\\ / /g;
304    s/\\textasciitilde\b\s*/~/g;
305    s/\\([\#\&\%\~\_\^\|])/$1/g;
306    s/\\\W//g;
307    s/\001(\d+)\{\\[A-Za-z]+\001(\d+)\{([^\001]*)\001\2\}\001\1\}/$3/g;
308    s/\\([A-Za-z]+)/ $1 /g;
309    s+In <a href=\"[^\"]*\"></a>++;
310    s/\001\d+[\{\}]//gs;
311    tr/\002\003\004/{}$/;
312    print HTMLFILE $_;
313}
314close(BBLFILE);
315print HTMLFILE "<$list_end>\n\n$endstring\n";
316while (<OHTMLFILE>) {
317  print HTMLFILE;
318}
319close (OHTMLFILE);
320close(HTMLFILE);
321chmod($mode, "$htmlfile$$");
322rename("$htmlfile$$", $htmlfile);
323if ($bdebug == 0) {
324  unlink(@tmpfiles);
325}
326exit(0);
327