# HG changeset patch
# User Alpar Juttner <alpar@cs.elte.hu>
# Date 1363624879 -3600
# Node ID 1c978b5bcc657cc3c0623b96d72f94cd60ae40a1
# Parent  eb2f9d453070f2251c5c194610f0722d1670df31
Use doxygen's own bibtex support (#456)

diff -r eb2f9d453070 -r 1c978b5bcc65 doc/CMakeLists.txt
--- a/doc/CMakeLists.txt	Sat Mar 16 14:11:32 2013 +0100
+++ b/doc/CMakeLists.txt	Mon Mar 18 17:41:19 2013 +0100
@@ -51,7 +51,6 @@
     COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
     COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
     COMMAND ${CMAKE_COMMAND} -E remove_directory html
-    COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/bib2dox.py ${CMAKE_CURRENT_SOURCE_DIR}/references.bib >references.dox
     COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
     WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
   )
diff -r eb2f9d453070 -r 1c978b5bcc65 doc/Doxyfile.in
--- a/doc/Doxyfile.in	Sat Mar 16 14:11:32 2013 +0100
+++ b/doc/Doxyfile.in	Mon Mar 18 17:41:19 2013 +0100
@@ -77,6 +77,7 @@
 SHOW_NAMESPACES        = YES
 FILE_VERSION_FILTER    = 
 LAYOUT_FILE            = "@abs_top_srcdir@/doc/DoxygenLayout.xml"
+CITE_BIB_FILES         = "@abs_top_srcdir@/doc/references.bib"
 #---------------------------------------------------------------------------
 # configuration options related to warning and progress messages
 #---------------------------------------------------------------------------
diff -r eb2f9d453070 -r 1c978b5bcc65 doc/groups.dox
--- a/doc/groups.dox	Sat Mar 16 14:11:32 2013 +0100
+++ b/doc/groups.dox	Mon Mar 18 17:41:19 2013 +0100
@@ -317,7 +317,7 @@
 
 This group contains the common graph search algorithms, namely
 \e breadth-first \e search (BFS) and \e depth-first \e search (DFS)
-\ref clrs01algorithms.
+\cite clrs01algorithms.
 */
 
 /**
@@ -326,7 +326,7 @@
 \brief Algorithms for finding shortest paths.
 
 This group contains the algorithms for finding shortest paths in digraphs
-\ref clrs01algorithms.
+\cite clrs01algorithms.
 
  - \ref Dijkstra algorithm for finding shortest paths from a source node
    when all arc lengths are non-negative.
@@ -348,7 +348,7 @@
 \brief Algorithms for finding minimum cost spanning trees and arborescences.
 
 This group contains the algorithms for finding minimum cost spanning
-trees and arborescences \ref clrs01algorithms.
+trees and arborescences \cite clrs01algorithms.
 */
 
 /**
@@ -357,7 +357,7 @@
 \brief Algorithms for finding maximum flows.
 
 This group contains the algorithms for finding maximum flows and
-feasible circulations \ref clrs01algorithms, \ref amo93networkflows.
+feasible circulations \cite clrs01algorithms, \cite amo93networkflows.
 
 The \e maximum \e flow \e problem is to find a flow of maximum value between
 a single source and a single target. Formally, there is a \f$G=(V,A)\f$
@@ -373,13 +373,13 @@
 
 LEMON contains several algorithms for solving maximum flow problems:
 - \ref EdmondsKarp Edmonds-Karp algorithm
-  \ref edmondskarp72theoretical.
+  \cite edmondskarp72theoretical.
 - \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm
-  \ref goldberg88newapproach.
+  \cite goldberg88newapproach.
 - \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees
-  \ref dinic70algorithm, \ref sleator83dynamic.
+  \cite dinic70algorithm, \cite sleator83dynamic.
 - \ref GoldbergTarjan !Preflow push-relabel algorithm with dynamic trees
-  \ref goldberg88newapproach, \ref sleator83dynamic.
+  \cite goldberg88newapproach, \cite sleator83dynamic.
 
 In most cases the \ref Preflow algorithm provides the
 fastest method for computing a maximum flow. All implementations
@@ -399,20 +399,20 @@
 \brief Algorithms for finding minimum cost flows and circulations.
 
 This group contains the algorithms for finding minimum cost flows and
-circulations \ref amo93networkflows. For more information about this
+circulations \cite amo93networkflows. For more information about this
 problem and its dual solution, see: \ref min_cost_flow
 "Minimum Cost Flow Problem".
 
 LEMON contains several algorithms for this problem.
  - \ref NetworkSimplex Primal Network Simplex algorithm with various
-   pivot strategies \ref dantzig63linearprog, \ref kellyoneill91netsimplex.
+   pivot strategies \cite dantzig63linearprog, \cite kellyoneill91netsimplex.
  - \ref CostScaling Cost Scaling algorithm based on push/augment and
-   relabel operations \ref goldberg90approximation, \ref goldberg97efficient,
-   \ref bunnagel98efficient.
+   relabel operations \cite goldberg90approximation, \cite goldberg97efficient,
+   \cite bunnagel98efficient.
  - \ref CapacityScaling Capacity Scaling algorithm based on the successive
-   shortest path method \ref edmondskarp72theoretical.
+   shortest path method \cite edmondskarp72theoretical.
  - \ref CycleCanceling Cycle-Canceling algorithms, two of which are
-   strongly polynomial \ref klein67primal, \ref goldberg89cyclecanceling.
+   strongly polynomial \cite klein67primal, \cite goldberg89cyclecanceling.
 
 In general, \ref NetworkSimplex and \ref CostScaling are the most efficient
 implementations.
@@ -430,7 +430,7 @@
 data are required to be integer).
 
 For more details about these implementations and for a comprehensive 
-experimental study, see the paper \ref KiralyKovacs12MCF.
+experimental study, see the paper \cite KiralyKovacs12MCF.
 It also compares these codes to other publicly available
 minimum cost flow solvers.
 */
@@ -471,7 +471,7 @@
 \brief Algorithms for finding minimum mean cycles.
 
 This group contains the algorithms for finding minimum mean cycles
-\ref amo93networkflows, \ref karp78characterization.
+\cite amo93networkflows, \cite karp78characterization.
 
 The \e minimum \e mean \e cycle \e problem is to find a directed cycle
 of minimum mean length (cost) in a digraph.
@@ -487,11 +487,11 @@
 function.
 
 LEMON contains three algorithms for solving the minimum mean cycle problem:
-- \ref KarpMmc Karp's original algorithm \ref karp78characterization.
+- \ref KarpMmc Karp's original algorithm \cite karp78characterization.
 - \ref HartmannOrlinMmc Hartmann-Orlin's algorithm, which is an improved
-  version of Karp's algorithm \ref hartmann93finding.
+  version of Karp's algorithm \cite hartmann93finding.
 - \ref HowardMmc Howard's policy iteration algorithm
-  \ref dasdan98minmeancycle, \ref dasdan04experimental.
+  \cite dasdan98minmeancycle, \cite dasdan04experimental.
 
 In practice, the \ref HowardMmc "Howard" algorithm turned out to be by far the
 most efficient one, though the best known theoretical bound on its running
@@ -647,8 +647,8 @@
 Various LP solvers could be used in the same manner with this
 high-level interface.
 
-The currently supported solvers are \ref glpk, \ref clp, \ref cbc,
-\ref cplex, \ref soplex.
+The currently supported solvers are \cite glpk, \cite clp, \cite cbc,
+\cite cplex, \cite soplex.
 */
 
 /**
diff -r eb2f9d453070 -r 1c978b5bcc65 doc/mainpage.dox.in
--- a/doc/mainpage.dox.in	Sat Mar 16 14:11:32 2013 +0100
+++ b/doc/mainpage.dox.in	Mon Mar 18 17:41:19 2013 +0100
@@ -25,7 +25,7 @@
 and <b>O</b>ptimization in <b>N</b>etworks</i>.
 It is a C++ template library providing efficient implementations of common
 data structures and algorithms with focus on combinatorial optimization
-tasks connected mainly with graphs and networks \ref DezsoJuttnerKovacs11Lemon.
+tasks connected mainly with graphs and networks \cite DezsoJuttnerKovacs11Lemon.
 
 <b>
 LEMON is an <a class="el" href="http://opensource.org/">open&nbsp;source</a>
@@ -37,12 +37,12 @@
 
 The project is maintained by the
 <a href="http://www.cs.elte.hu/egres/">Egerv&aacute;ry Research Group on
-Combinatorial Optimization</a> \ref egres
+Combinatorial Optimization</a> \cite egres
 at the Operations Research Department of the
 <a href="http://www.elte.hu/en/">E&ouml;tv&ouml;s Lor&aacute;nd University</a>,
 Budapest, Hungary.
 LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
-initiative \ref coinor.
+initiative \cite coinor.
 
 \section howtoread How to Read the Documentation
 
diff -r eb2f9d453070 -r 1c978b5bcc65 doc/min_cost_flow.dox
--- a/doc/min_cost_flow.dox	Sat Mar 16 14:11:32 2013 +0100
+++ b/doc/min_cost_flow.dox	Mon Mar 18 17:41:19 2013 +0100
@@ -26,7 +26,7 @@
 The \e minimum \e cost \e flow \e problem is to find a feasible flow of
 minimum total cost from a set of supply nodes to a set of demand nodes
 in a network with capacity constraints (lower and upper bounds)
-and arc costs \ref amo93networkflows.
+and arc costs \cite amo93networkflows.
 
 Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$,
 \f$upper: A\rightarrow\mathbf{R}\cup\{+\infty\}\f$ denote the lower and
diff -r eb2f9d453070 -r 1c978b5bcc65 lemon/capacity_scaling.h
--- a/lemon/capacity_scaling.h	Sat Mar 16 14:11:32 2013 +0100
+++ b/lemon/capacity_scaling.h	Mon Mar 18 17:41:19 2013 +0100
@@ -66,8 +66,8 @@
   ///
   /// \ref CapacityScaling implements the capacity scaling version
   /// of the successive shortest path algorithm for finding a
-  /// \ref min_cost_flow "minimum cost flow" \ref amo93networkflows,
-  /// \ref edmondskarp72theoretical. It is an efficient dual
+  /// \ref min_cost_flow "minimum cost flow" \cite amo93networkflows,
+  /// \cite edmondskarp72theoretical. It is an efficient dual
   /// solution method, which runs in polynomial time
   /// \f$O(e\log U (n+e)\log n)\f$, where <i>U</i> denotes the maximum
   /// of node supply and arc capacity values.
diff -r eb2f9d453070 -r 1c978b5bcc65 lemon/cost_scaling.h
--- a/lemon/cost_scaling.h	Sat Mar 16 14:11:32 2013 +0100
+++ b/lemon/cost_scaling.h	Mon Mar 18 17:41:19 2013 +0100
@@ -91,8 +91,8 @@
   ///
   /// \ref CostScaling implements a cost scaling algorithm that performs
   /// push/augment and relabel operations for finding a \ref min_cost_flow
-  /// "minimum cost flow" \ref amo93networkflows, \ref goldberg90approximation,
-  /// \ref goldberg97efficient, \ref bunnagel98efficient.
+  /// "minimum cost flow" \cite amo93networkflows, \cite goldberg90approximation,
+  /// \cite goldberg97efficient, \cite bunnagel98efficient.
   /// It is a highly efficient primal-dual solution method, which
   /// can be viewed as the generalization of the \ref Preflow
   /// "preflow push-relabel" algorithm for the maximum flow problem.
diff -r eb2f9d453070 -r 1c978b5bcc65 lemon/cycle_canceling.h
--- a/lemon/cycle_canceling.h	Sat Mar 16 14:11:32 2013 +0100
+++ b/lemon/cycle_canceling.h	Mon Mar 18 17:41:19 2013 +0100
@@ -47,8 +47,8 @@
   ///
   /// \ref CycleCanceling implements three different cycle-canceling
   /// algorithms for finding a \ref min_cost_flow "minimum cost flow"
-  /// \ref amo93networkflows, \ref klein67primal,
-  /// \ref goldberg89cyclecanceling.
+  /// \cite amo93networkflows, \cite klein67primal,
+  /// \cite goldberg89cyclecanceling.
   /// The most efficent one is the \ref CANCEL_AND_TIGHTEN
   /// "Cancel-and-Tighten" algorithm, thus it is the default method.
   /// It runs in strongly polynomial time O(n<sup>2</sup>e<sup>2</sup>log(n)),
@@ -131,13 +131,13 @@
       SIMPLE_CYCLE_CANCELING,
       /// The "Minimum Mean Cycle-Canceling" algorithm, which is a
       /// well-known strongly polynomial method
-      /// \ref goldberg89cyclecanceling. It improves along a
+      /// \cite goldberg89cyclecanceling. It improves along a
       /// \ref min_mean_cycle "minimum mean cycle" in each iteration.
       /// Its running time complexity is O(n<sup>2</sup>e<sup>3</sup>log(n)).
       MINIMUM_MEAN_CYCLE_CANCELING,
       /// The "Cancel-and-Tighten" algorithm, which can be viewed as an
       /// improved version of the previous method
-      /// \ref goldberg89cyclecanceling.
+      /// \cite goldberg89cyclecanceling.
       /// It is faster both in theory and in practice, its running time
       /// complexity is O(n<sup>2</sup>e<sup>2</sup>log(n)).
       CANCEL_AND_TIGHTEN
diff -r eb2f9d453070 -r 1c978b5bcc65 lemon/grosso_locatelli_pullan_mc.h
--- a/lemon/grosso_locatelli_pullan_mc.h	Sat Mar 16 14:11:32 2013 +0100
+++ b/lemon/grosso_locatelli_pullan_mc.h	Mon Mar 18 17:41:19 2013 +0100
@@ -40,7 +40,7 @@
   ///
   /// \ref GrossoLocatelliPullanMc implements the iterated local search
   /// algorithm of Grosso, Locatelli, and Pullan for solving the \e maximum
-  /// \e clique \e problem \ref grosso08maxclique.
+  /// \e clique \e problem \cite grosso08maxclique.
   /// It is to find the largest complete subgraph (\e clique) in an
   /// undirected graph, i.e., the largest set of nodes where each
   /// pair of nodes is connected.
diff -r eb2f9d453070 -r 1c978b5bcc65 lemon/hartmann_orlin_mmc.h
--- a/lemon/hartmann_orlin_mmc.h	Sat Mar 16 14:11:32 2013 +0100
+++ b/lemon/hartmann_orlin_mmc.h	Mon Mar 18 17:41:19 2013 +0100
@@ -98,7 +98,7 @@
   ///
   /// This class implements the Hartmann-Orlin algorithm for finding
   /// a directed cycle of minimum mean cost in a digraph
-  /// \ref hartmann93finding, \ref dasdan98minmeancycle.
+  /// \cite hartmann93finding, \cite dasdan98minmeancycle.
   /// This method is based on \ref KarpMmc "Karp"'s original algorithm, but
   /// applies an early termination scheme. It makes the algorithm
   /// significantly faster for some problem instances, but slower for others.
diff -r eb2f9d453070 -r 1c978b5bcc65 lemon/howard_mmc.h
--- a/lemon/howard_mmc.h	Sat Mar 16 14:11:32 2013 +0100
+++ b/lemon/howard_mmc.h	Mon Mar 18 17:41:19 2013 +0100
@@ -98,7 +98,7 @@
   ///
   /// This class implements Howard's policy iteration algorithm for finding
   /// a directed cycle of minimum mean cost in a digraph
-  /// \ref dasdan98minmeancycle, \ref dasdan04experimental.
+  /// \cite dasdan98minmeancycle, \cite dasdan04experimental.
   /// This class provides the most efficient algorithm for the
   /// minimum mean cycle problem, though the best known theoretical
   /// bound on its running time is exponential.
diff -r eb2f9d453070 -r 1c978b5bcc65 lemon/karp_mmc.h
--- a/lemon/karp_mmc.h	Sat Mar 16 14:11:32 2013 +0100
+++ b/lemon/karp_mmc.h	Mon Mar 18 17:41:19 2013 +0100
@@ -98,7 +98,7 @@
   ///
   /// This class implements Karp's algorithm for finding a directed
   /// cycle of minimum mean cost in a digraph
-  /// \ref karp78characterization, \ref dasdan98minmeancycle.
+  /// \cite karp78characterization, \cite dasdan98minmeancycle.
   /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
   ///
   /// \tparam GR The type of the digraph the algorithm runs on.
diff -r eb2f9d453070 -r 1c978b5bcc65 lemon/network_simplex.h
--- a/lemon/network_simplex.h	Sat Mar 16 14:11:32 2013 +0100
+++ b/lemon/network_simplex.h	Mon Mar 18 17:41:19 2013 +0100
@@ -41,8 +41,8 @@
   ///
   /// \ref NetworkSimplex implements the primal Network Simplex algorithm
   /// for finding a \ref min_cost_flow "minimum cost flow"
-  /// \ref amo93networkflows, \ref dantzig63linearprog,
-  /// \ref kellyoneill91netsimplex.
+  /// \cite amo93networkflows, \cite dantzig63linearprog,
+  /// \cite kellyoneill91netsimplex.
   /// This algorithm is a highly efficient specialized version of the
   /// linear programming simplex method directly for the minimum cost
   /// flow problem.
diff -r eb2f9d453070 -r 1c978b5bcc65 lemon/preflow.h
--- a/lemon/preflow.h	Sat Mar 16 14:11:32 2013 +0100
+++ b/lemon/preflow.h	Mon Mar 18 17:41:19 2013 +0100
@@ -102,8 +102,8 @@
   ///
   /// This class provides an implementation of Goldberg-Tarjan's \e preflow
   /// \e push-relabel algorithm producing a \ref max_flow
-  /// "flow of maximum value" in a digraph \ref clrs01algorithms,
-  /// \ref amo93networkflows, \ref goldberg88newapproach.
+  /// "flow of maximum value" in a digraph \cite clrs01algorithms,
+  /// \cite amo93networkflows, \cite goldberg88newapproach.
   /// The preflow algorithms are the fastest known maximum
   /// flow algorithms. The current implementation uses a mixture of the
   /// \e "highest label" and the \e "bound decrease" heuristics.
diff -r eb2f9d453070 -r 1c978b5bcc65 scripts/bib2dox.py
--- a/scripts/bib2dox.py	Sat Mar 16 14:11:32 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,816 +0,0 @@
-#! /usr/bin/env python
-"""
-  BibTeX to Doxygen converter
-  Usage: python bib2dox.py bibfile.bib > bibfile.dox
-
-  This file is a part of LEMON, a generic C++ optimization library.
-
-  **********************************************************************
-
-  This code is the modification of the BibTeX to XML converter
-  by Vidar Bronken Gundersen et al.
-  See the original copyright notices below. 
-
-  **********************************************************************
-
-  Decoder for bibliographic data, BibTeX
-  Usage: python bibtex2xml.py bibfile.bib > bibfile.xml
-
-  v.8
-  (c)2002-06-23 Vidar Bronken Gundersen
-  http://bibtexml.sf.net/
-  Reuse approved as long as this notification is kept.
-  Licence: GPL.
-
-  Contributions/thanks to:
-  Egon Willighagen, http://sf.net/projects/jreferences/
-  Richard Mahoney (for providing a test case)
-
-  Editted by Sara Sprenkle to be more robust and handle more bibtex features.
-  (c) 2003-01-15
-
-  1.  Changed bibtex: tags to bibxml: tags.
-  2.  Use xmlns:bibxml="http://bibtexml.sf.net/"
-  3.  Allow spaces between @type and first {
-  4.  "author" fields with multiple authors split by " and "
-      are put in separate xml "bibxml:author" tags.
-  5.  Option for Titles: words are capitalized
-      only if first letter in title or capitalized inside braces
-  6.  Removes braces from within field values
-  7.  Ignores comments in bibtex file (including @comment{ or % )
-  8.  Replaces some special latex tags, e.g., replaces ~ with '&#160;'
-  9.  Handles bibtex @string abbreviations
-        --> includes bibtex's default abbreviations for months
-        --> does concatenation of abbr # " more " and " more " # abbr
-  10. Handles @type( ... ) or @type{ ... }
-  11. The keywords field is split on , or ; and put into separate xml
-      "bibxml:keywords" tags
-  12. Ignores @preamble
-
-  Known Limitations
-  1.  Does not transform Latex encoding like math mode and special
-      latex symbols.
-  2.  Does not parse author fields into first and last names.
-      E.g., It does not do anything special to an author whose name is
-      in the form LAST_NAME, FIRST_NAME
-      In "author" tag, will show up as
-      <bibxml:author>LAST_NAME, FIRST_NAME</bibxml:author>
-  3.  Does not handle "crossref" fields other than to print
-      <bibxml:crossref>...</bibxml:crossref>
-  4.  Does not inform user of the input's format errors.  You just won't
-      be able to transform the file later with XSL
-
-  You will have to manually edit the XML output if you need to handle
-  these (and unknown) limitations.
-
-"""
-
-import string, re
-
-# set of valid name characters
-valid_name_chars = '[\w\-:]'
-
-#
-# define global regular expression variables
-#
-author_rex = re.compile('\s+and\s+')
-rembraces_rex = re.compile('[{}]')
-capitalize_rex = re.compile('({[^}]*})')
-
-# used by bibtexkeywords(data)
-keywords_rex = re.compile('[,;]')
-
-# used by concat_line(line)
-concatsplit_rex = re.compile('\s*#\s*')
-
-# split on {, }, or " in verify_out_of_braces
-delimiter_rex = re.compile('([{}"])',re.I)
-
-field_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
-data_rex = re.compile('\s*(\w*)\s*=\s*([^,]*),?')
-
-url_rex = re.compile('\\\url\{([^}]*)\}')
-
-#
-# styles for html formatting
-#
-divstyle = 'margin-top: -4ex; margin-left: 10em;'
-
-#
-# return the string parameter without braces
-#
-def transformurls(str):
-    return url_rex.sub(r'<a href="\1">\1</a>', str)
-
-#
-# return the string parameter without braces
-#
-def removebraces(str):
-    return rembraces_rex.sub('', str)
-
-#
-# latex-specific replacements
-# (do this after braces were removed)
-#
-def latexreplacements(line):
-    line = string.replace(line, '~', '&nbsp;')
-    line = string.replace(line, '\\\'a', '&aacute;')
-    line = string.replace(line, '\\"a', '&auml;')
-    line = string.replace(line, '\\\'e', '&eacute;')
-    line = string.replace(line, '\\"e', '&euml;')
-    line = string.replace(line, '\\\'i', '&iacute;')
-    line = string.replace(line, '\\"i', '&iuml;')
-    line = string.replace(line, '\\\'o', '&oacute;')
-    line = string.replace(line, '\\"o', '&ouml;')
-    line = string.replace(line, '\\\'u', '&uacute;')
-    line = string.replace(line, '\\"u', '&uuml;')
-    line = string.replace(line, '\\H o', '&otilde;')
-    line = string.replace(line, '\\H u', '&uuml;')   # &utilde; does not exist
-    line = string.replace(line, '\\\'A', '&Aacute;')
-    line = string.replace(line, '\\"A', '&Auml;')
-    line = string.replace(line, '\\\'E', '&Eacute;')
-    line = string.replace(line, '\\"E', '&Euml;')
-    line = string.replace(line, '\\\'I', '&Iacute;')
-    line = string.replace(line, '\\"I', '&Iuml;')
-    line = string.replace(line, '\\\'O', '&Oacute;')
-    line = string.replace(line, '\\"O', '&Ouml;')
-    line = string.replace(line, '\\\'U', '&Uacute;')
-    line = string.replace(line, '\\"U', '&Uuml;')
-    line = string.replace(line, '\\H O', '&Otilde;')
-    line = string.replace(line, '\\H U', '&Uuml;')   # &Utilde; does not exist
-
-    return line
-
-#
-# copy characters form a string decoding html expressions (&xyz;)
-#
-def copychars(str, ifrom, count):
-    result = ''
-    i = ifrom
-    c = 0
-    html_spec = False
-    while (i < len(str)) and (c < count):
-        if str[i] == '&':
-            html_spec = True;
-            if i+1 < len(str):
-                result += str[i+1]
-            c += 1
-            i += 2
-        else:
-            if not html_spec:
-                if ((str[i] >= 'A') and (str[i] <= 'Z')) or \
-                   ((str[i] >= 'a') and (str[i] <= 'z')):
-                    result += str[i]
-                    c += 1
-            elif str[i] == ';':
-                html_spec = False;
-            i += 1
-    
-    return result
-
-
-# 
-# Handle a list of authors (separated by 'and').
-# It gives back an array of the follwing values:
-#  - num: the number of authors,
-#  - list: the list of the author names,
-#  - text: the bibtex text (separated by commas and/or 'and')
-#  - abbrev: abbreviation that can be used for indicate the
-#    bibliography entries
-#
-def bibtexauthor(data):
-    result = {}
-    bibtex = ''
-    result['list'] = author_rex.split(data)
-    result['num'] = len(result['list'])
-    for i, author in enumerate(result['list']):
-        # general transformations
-        author = latexreplacements(removebraces(author.strip()))
-        # transform "Xyz, A. B." to "A. B. Xyz"
-        pos = author.find(',')
-        if pos != -1:
-            author = author[pos+1:].strip() + ' ' + author[:pos].strip()
-        result['list'][i] = author
-        bibtex += author + '#'
-    bibtex = bibtex[:-1]
-    if result['num'] > 1:
-        ix = bibtex.rfind('#')
-        if result['num'] == 2:
-            bibtex = bibtex[:ix] + ' and ' + bibtex[ix+1:]
-        else:
-            bibtex = bibtex[:ix] + ', and ' + bibtex[ix+1:]
-    bibtex = bibtex.replace('#', ', ')
-    result['text'] = bibtex
-    
-    result['abbrev'] = ''
-    for author in result['list']:
-        pos = author.rfind(' ') + 1
-        count = 1
-        if result['num'] == 1:
-            count = 3
-        result['abbrev'] += copychars(author, pos, count)
-
-    return result
-
-
-#
-# data = title string
-# @return the capitalized title (first letter is capitalized), rest are capitalized
-# only if capitalized inside braces
-#
-def capitalizetitle(data):
-    title_list = capitalize_rex.split(data)
-    title = ''
-    count = 0
-    for phrase in title_list:
-         check = string.lstrip(phrase)
-
-         # keep phrase's capitalization the same
-         if check.find('{') == 0:
-              title += removebraces(phrase)
-         else:
-         # first word --> capitalize first letter (after spaces)
-              if count == 0:
-                  title += check.capitalize()
-              else:
-                  title += phrase.lower()
-         count = count + 1
-
-    return title
-
-
-#
-# @return the bibtex for the title
-# @param data --> title string
-# braces are removed from title
-#
-def bibtextitle(data, entrytype):
-    if entrytype in ('book', 'inbook'):
-        title = removebraces(data.strip())
-    else:
-        title = removebraces(capitalizetitle(data.strip()))
-    bibtex = title
-    return bibtex
-
-
-#
-# function to compare entry lists
-#
-def entry_cmp(x, y):
-    return cmp(x[0], y[0])
-
-
-#
-# print the XML for the transformed "filecont_source"
-#
-def bibtexdecoder(filecont_source):
-    filecont = []
-    file = []
-    
-    # want @<alphanumeric chars><spaces>{<spaces><any chars>,
-    pubtype_rex = re.compile('@(\w*)\s*{\s*(.*),')
-    endtype_rex = re.compile('}\s*$')
-    endtag_rex = re.compile('^\s*}\s*$')
-
-    bracefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
-    bracedata_rex = re.compile('\s*(\w*)\s*=\s*{(.*)},?')
-
-    quotefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
-    quotedata_rex = re.compile('\s*(\w*)\s*=\s*"(.*)",?')
-
-    for line in filecont_source:
-        line = line[:-1]
-
-        # encode character entities
-        line = string.replace(line, '&', '&amp;')
-        line = string.replace(line, '<', '&lt;')
-        line = string.replace(line, '>', '&gt;')
-
-        # start entry: publication type (store for later use)
-        if pubtype_rex.match(line):
-        # want @<alphanumeric chars><spaces>{<spaces><any chars>,
-            entrycont = {}
-            entry = []
-            entrytype = pubtype_rex.sub('\g<1>',line)
-            entrytype = string.lower(entrytype)
-            entryid   = pubtype_rex.sub('\g<2>', line)
-
-        # end entry if just a }
-        elif endtype_rex.match(line):
-            # generate doxygen code for the entry
-
-            # enty type related formattings
-            if entrytype in ('book', 'inbook'):
-                entrycont['title'] = '<em>' + entrycont['title'] + '</em>'
-                if not entrycont.has_key('author'):
-                    entrycont['author'] = entrycont['editor']
-                    entrycont['author']['text'] += ', editors'
-            elif entrytype == 'article':
-                entrycont['journal'] = '<em>' + entrycont['journal'] + '</em>'
-            elif entrytype in ('inproceedings', 'incollection', 'conference'):
-                entrycont['booktitle'] = '<em>' + entrycont['booktitle'] + '</em>'
-            elif entrytype == 'techreport':
-                if not entrycont.has_key('type'):
-                    entrycont['type'] = 'Technical report'
-            elif entrytype == 'mastersthesis':
-                entrycont['type'] = 'Master\'s thesis'
-            elif entrytype == 'phdthesis':
-                entrycont['type'] = 'PhD thesis'
-
-            for eline in entrycont:
-                if eline != '':
-                    eline = latexreplacements(eline)
-
-            if entrycont.has_key('pages') and (entrycont['pages'] != ''):
-                entrycont['pages'] = string.replace(entrycont['pages'], '--', '-')
-
-            if entrycont.has_key('author') and (entrycont['author'] != ''):
-                entry.append(entrycont['author']['text'] + '.')
-            if entrycont.has_key('title') and (entrycont['title'] != ''):
-                entry.append(entrycont['title'] + '.')
-            if entrycont.has_key('journal') and (entrycont['journal'] != ''):
-                entry.append(entrycont['journal'] + ',')
-            if entrycont.has_key('booktitle') and (entrycont['booktitle'] != ''):
-                entry.append('In ' + entrycont['booktitle'] + ',')
-            if entrycont.has_key('type') and (entrycont['type'] != ''):
-                eline = entrycont['type']
-                if entrycont.has_key('number') and (entrycont['number'] != ''):
-                    eline += ' ' + entrycont['number']
-                eline += ','
-                entry.append(eline)
-            if entrycont.has_key('institution') and (entrycont['institution'] != ''):
-                entry.append(entrycont['institution'] + ',')
-            if entrycont.has_key('publisher') and (entrycont['publisher'] != ''):
-                entry.append(entrycont['publisher'] + ',')
-            if entrycont.has_key('school') and (entrycont['school'] != ''):
-                entry.append(entrycont['school'] + ',')
-            if entrycont.has_key('address') and (entrycont['address'] != ''):
-                entry.append(entrycont['address'] + ',')
-            if entrycont.has_key('edition') and (entrycont['edition'] != ''):
-                entry.append(entrycont['edition'] + ' edition,')
-            if entrycont.has_key('howpublished') and (entrycont['howpublished'] != ''):
-                entry.append(entrycont['howpublished'] + ',')
-            if entrycont.has_key('volume') and (entrycont['volume'] != ''):
-                eline = entrycont['volume'];
-                if entrycont.has_key('number') and (entrycont['number'] != ''):
-                    eline += '(' + entrycont['number'] + ')'
-                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
-                    eline += ':' + entrycont['pages']
-                eline += ','
-                entry.append(eline)
-            else:
-                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
-                    entry.append('pages ' + entrycont['pages'] + ',')
-            if entrycont.has_key('year') and (entrycont['year'] != ''):
-                if entrycont.has_key('month') and (entrycont['month'] != ''):
-                    entry.append(entrycont['month'] + ' ' + entrycont['year'] + '.')
-                else:
-                    entry.append(entrycont['year'] + '.')
-            if entrycont.has_key('note') and (entrycont['note'] != ''):
-                entry.append(entrycont['note'] + '.')
-            if entrycont.has_key('url') and (entrycont['url'] != ''):
-                entry.append(entrycont['url'] + '.')
-
-            # generate keys for sorting and for the output
-            sortkey = ''
-            bibkey = ''
-            if entrycont.has_key('author'):
-                for author in entrycont['author']['list']:
-                    sortkey += copychars(author, author.rfind(' ')+1, len(author))
-                bibkey = entrycont['author']['abbrev']
-            else:
-                bibkey = 'x'
-            if entrycont.has_key('year'):
-                sortkey += entrycont['year']
-                bibkey += entrycont['year'][-2:]
-            if entrycont.has_key('title'):
-                sortkey += entrycont['title']
-            if entrycont.has_key('key'):
-                sortkey = entrycont['key'] + sortkey
-                bibkey = entrycont['key']
-            entry.insert(0, sortkey)
-            entry.insert(1, bibkey)
-            entry.insert(2, entryid)
-           
-            # add the entry to the file contents
-            filecont.append(entry)
-
-        else:
-            # field, publication info
-            field = ''
-            data = ''
-            
-            # field = {data} entries
-            if bracedata_rex.match(line):
-                field = bracefield_rex.sub('\g<1>', line)
-                field = string.lower(field)
-                data =  bracedata_rex.sub('\g<2>', line)
-
-            # field = "data" entries
-            elif quotedata_rex.match(line):
-                field = quotefield_rex.sub('\g<1>', line)
-                field = string.lower(field)
-                data =  quotedata_rex.sub('\g<2>', line)
-
-            # field = data entries
-            elif data_rex.match(line):
-                field = field_rex.sub('\g<1>', line)
-                field = string.lower(field)
-                data =  data_rex.sub('\g<2>', line)
-
-            if field == 'url':
-                data = '\\url{' + data.strip() + '}'
-            
-            if field in ('author', 'editor'):
-                entrycont[field] = bibtexauthor(data)
-                line = ''
-            elif field == 'title':
-                line = bibtextitle(data, entrytype)
-            elif field != '':
-                line = removebraces(transformurls(data.strip()))
-
-            if line != '':
-                line = latexreplacements(line)
-                entrycont[field] = line
-
-
-    # sort entries
-    filecont.sort(entry_cmp)
-    
-    # count the bibtex keys
-    keytable = {}
-    counttable = {}
-    for entry in filecont:
-        bibkey = entry[1]
-        if not keytable.has_key(bibkey):
-            keytable[bibkey] = 1
-        else:
-            keytable[bibkey] += 1
-
-    for bibkey in keytable.keys():
-        counttable[bibkey] = 0
-    
-    # generate output
-    for entry in filecont:
-        # generate output key form the bibtex key
-        bibkey = entry[1]
-        entryid = entry[2]
-        if keytable[bibkey] == 1:
-            outkey = bibkey
-        else:
-            outkey = bibkey + chr(97 + counttable[bibkey])
-        counttable[bibkey] += 1
-        
-        # append the entry code to the output
-        file.append('\\section ' + entryid + ' [' + outkey + ']')
-        file.append('<div style="' + divstyle + '">')
-        for line in entry[3:]:
-            file.append(line)
-        file.append('</div>')
-        file.append('')
-
-    return file
-
-
-#
-# return 1 iff abbr is in line but not inside braces or quotes
-# assumes that abbr appears only once on the line (out of braces and quotes)
-#
-def verify_out_of_braces(line, abbr):
-
-    phrase_split = delimiter_rex.split(line)
-
-    abbr_rex = re.compile( '\\b' + abbr + '\\b', re.I)
-
-    open_brace = 0
-    open_quote = 0
-
-    for phrase in phrase_split:
-        if phrase == "{":
-            open_brace = open_brace + 1
-        elif phrase == "}":
-            open_brace = open_brace - 1
-        elif phrase == '"':
-            if open_quote == 1:
-                open_quote = 0
-            else:
-                open_quote = 1
-        elif abbr_rex.search(phrase):
-            if open_brace == 0 and open_quote == 0:
-                return 1
-
-    return 0
-
-
-#
-# a line in the form phrase1 # phrase2 # ... # phrasen
-# is returned as phrase1 phrase2 ... phrasen
-# with the correct punctuation
-# Bug: Doesn't always work with multiple abbreviations plugged in
-#
-def concat_line(line):
-    # only look at part after equals
-    field = field_rex.sub('\g<1>',line)
-    rest = field_rex.sub('\g<2>',line)
-
-    concat_line = field + ' ='
-
-    pound_split = concatsplit_rex.split(rest)
-
-    phrase_count = 0
-    length = len(pound_split)
-
-    for phrase in pound_split:
-        phrase = phrase.strip()
-        if phrase_count != 0:
-            if phrase.startswith('"') or phrase.startswith('{'):
-                phrase = phrase[1:]
-        elif phrase.startswith('"'):
-            phrase = phrase.replace('"','{',1)
-
-        if phrase_count != length-1:
-            if phrase.endswith('"') or phrase.endswith('}'):
-                phrase = phrase[:-1]
-        else:
-            if phrase.endswith('"'):
-                phrase = phrase[:-1]
-                phrase = phrase + "}"
-            elif phrase.endswith('",'):
-                phrase = phrase[:-2]
-                phrase = phrase + "},"
-
-        # if phrase did have \#, add the \# back
-        if phrase.endswith('\\'):
-            phrase = phrase + "#"
-        concat_line = concat_line + ' ' + phrase
-
-        phrase_count = phrase_count + 1
-
-    return concat_line
-
-
-#
-# substitute abbreviations into filecont
-# @param filecont_source - string of data from file
-#
-def bibtex_replace_abbreviations(filecont_source):
-    filecont = filecont_source.splitlines()
-
-    #  These are defined in bibtex, so we'll define them too
-    abbr_list = ['jan','feb','mar','apr','may','jun',
-                 'jul','aug','sep','oct','nov','dec']
-    value_list = ['January','February','March','April',
-                  'May','June','July','August','September',
-                  'October','November','December']
-
-    abbr_rex = []
-    total_abbr_count = 0
-
-    front = '\\b'
-    back = '(,?)\\b'
-
-    for x in abbr_list:
-        abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
-        total_abbr_count = total_abbr_count + 1
-
-
-    abbrdef_rex = re.compile('\s*@string\s*{\s*('+ valid_name_chars +'*)\s*=(.*)',
-                             re.I)
-
-    comment_rex = re.compile('@comment\s*{',re.I)
-    preamble_rex = re.compile('@preamble\s*{',re.I)
-
-    waiting_for_end_string = 0
-    i = 0
-    filecont2 = ''
-
-    for line in filecont:
-        if line == ' ' or line == '':
-            continue
-
-        if waiting_for_end_string:
-            if re.search('}',line):
-                waiting_for_end_string = 0
-                continue
-
-        if abbrdef_rex.search(line):
-            abbr = abbrdef_rex.sub('\g<1>', line)
-
-            if abbr_list.count(abbr) == 0:
-                val = abbrdef_rex.sub('\g<2>', line)
-                abbr_list.append(abbr)
-                value_list.append(string.strip(val))
-                abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
-                total_abbr_count = total_abbr_count + 1
-            waiting_for_end_string = 1
-            continue
-
-        if comment_rex.search(line):
-            waiting_for_end_string = 1
-            continue
-
-        if preamble_rex.search(line):
-            waiting_for_end_string = 1
-            continue
-
-
-        # replace subsequent abbreviations with the value
-        abbr_count = 0
-
-        for x in abbr_list:
-
-            if abbr_rex[abbr_count].search(line):
-                if verify_out_of_braces(line,abbr_list[abbr_count]) == 1:
-                    line = abbr_rex[abbr_count].sub( value_list[abbr_count] + '\g<1>', line)
-                # Check for # concatenations
-                if concatsplit_rex.search(line):
-                    line = concat_line(line)
-            abbr_count = abbr_count + 1
-
-
-        filecont2 = filecont2 + line + '\n'
-        i = i+1
-
-
-    # Do one final pass over file
-
-    # make sure that didn't end up with {" or }" after the substitution
-    filecont2 = filecont2.replace('{"','{{')
-    filecont2 = filecont2.replace('"}','}}')
-
-    afterquotevalue_rex = re.compile('"\s*,\s*')
-    afterbrace_rex = re.compile('"\s*}')
-    afterbracevalue_rex = re.compile('(=\s*{[^=]*)},\s*')
-
-    # add new lines to data that changed because of abbreviation substitutions
-    filecont2 = afterquotevalue_rex.sub('",\n', filecont2)
-    filecont2 = afterbrace_rex.sub('"\n}', filecont2)
-    filecont2 = afterbracevalue_rex.sub('\g<1>},\n', filecont2)
-
-    return filecont2
-
-#
-# convert @type( ... ) to @type{ ... }
-#
-def no_outer_parens(filecont):
-
-    # do checking for open parens
-    # will convert to braces
-    paren_split = re.split('([(){}])',filecont)
-
-    open_paren_count = 0
-    open_type = 0
-    look_next = 0
-
-    # rebuild filecont
-    filecont = ''
-
-    at_rex = re.compile('@\w*')
-
-    for phrase in paren_split:
-        if look_next == 1:
-            if phrase == '(':
-                phrase = '{'
-                open_paren_count = open_paren_count + 1
-            else:
-                open_type = 0
-            look_next = 0
-
-        if phrase == '(':
-            open_paren_count = open_paren_count + 1
-
-        elif phrase == ')':
-            open_paren_count = open_paren_count - 1
-            if open_type == 1 and open_paren_count == 0:
-                phrase = '}'
-                open_type = 0
-
-        elif at_rex.search( phrase ):
-            open_type = 1
-            look_next = 1
-
-        filecont = filecont + phrase
-
-    return filecont
-
-
-#
-# make all whitespace into just one space
-# format the bibtex file into a usable form.
-#
-def bibtexwasher(filecont_source):
-
-    space_rex = re.compile('\s+')
-    comment_rex = re.compile('\s*%')
-
-    filecont = []
-
-    # remove trailing and excessive whitespace
-    # ignore comments
-    for line in filecont_source:
-        line = string.strip(line)
-        line = space_rex.sub(' ', line)
-        # ignore comments
-        if not comment_rex.match(line) and line != '':
-            filecont.append(' '+ line)
-
-    filecont = string.join(filecont, '')
-
-    # the file is in one long string
-
-    filecont = no_outer_parens(filecont)
-
-    #
-    # split lines according to preferred syntax scheme
-    #
-    filecont = re.sub('(=\s*{[^=]*)},', '\g<1>},\n', filecont)
-
-    # add new lines after commas that are after values
-    filecont = re.sub('"\s*,', '",\n', filecont)
-    filecont = re.sub('=\s*([\w\d]+)\s*,', '= \g<1>,\n', filecont)
-    filecont = re.sub('(@\w*)\s*({(\s*)[^,\s]*)\s*,',
-                          '\n\n\g<1>\g<2>,\n', filecont)
-
-    # add new lines after }
-    filecont = re.sub('"\s*}','"\n}\n', filecont)
-    filecont = re.sub('}\s*,','},\n', filecont)
-
-
-    filecont = re.sub('@(\w*)', '\n@\g<1>', filecont)
-
-    # character encoding, reserved latex characters
-    filecont = re.sub('{\\\&}', '&', filecont)
-    filecont = re.sub('\\\&', '&', filecont)
-
-    # do checking for open braces to get format correct
-    open_brace_count = 0
-    brace_split = re.split('([{}])',filecont)
-
-    # rebuild filecont
-    filecont = ''
-
-    for phrase in brace_split:
-        if phrase == '{':
-            open_brace_count = open_brace_count + 1
-        elif phrase == '}':
-            open_brace_count = open_brace_count - 1
-            if open_brace_count == 0:
-                filecont = filecont + '\n'
-
-        filecont = filecont + phrase
-
-    filecont2 = bibtex_replace_abbreviations(filecont)
-
-    # gather
-    filecont = filecont2.splitlines()
-    i=0
-    j=0         # count the number of blank lines
-    for line in filecont:
-        # ignore blank lines
-        if line == '' or line == ' ':
-            j = j+1
-            continue
-        filecont[i] = line + '\n'
-        i = i+1
-
-    # get rid of the extra stuff at the end of the array
-    # (The extra stuff are duplicates that are in the array because
-    # blank lines were removed.)
-    length = len( filecont)
-    filecont[length-j:length] = []
-
-    return filecont
-
-
-def filehandler(filepath):
-    try:
-        fd = open(filepath, 'r')
-        filecont_source = fd.readlines()
-        fd.close()
-    except:
-        print 'Could not open file:', filepath
-    washeddata = bibtexwasher(filecont_source)
-    outdata = bibtexdecoder(washeddata)
-    print '/**'
-    print '\page references References'
-    print
-    for line in outdata:
-        print line
-    print '*/'
-
-
-# main program
-
-def main():
-    import sys
-    if sys.argv[1:]:
-        filepath = sys.argv[1]
-    else:
-        print "No input file"
-        sys.exit()
-    filehandler(filepath)
-
-if __name__ == "__main__": main()
-
-
-# end python script