1.1 --- a/doc/CMakeLists.txt Sat Mar 16 14:11:32 2013 +0100
1.2 +++ b/doc/CMakeLists.txt Mon Mar 18 17:41:19 2013 +0100
1.3 @@ -51,7 +51,6 @@
1.4 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
1.5 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
1.6 COMMAND ${CMAKE_COMMAND} -E remove_directory html
1.7 - COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/bib2dox.py ${CMAKE_CURRENT_SOURCE_DIR}/references.bib >references.dox
1.8 COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
1.9 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
1.10 )
2.1 --- a/doc/Doxyfile.in Sat Mar 16 14:11:32 2013 +0100
2.2 +++ b/doc/Doxyfile.in Mon Mar 18 17:41:19 2013 +0100
2.3 @@ -77,6 +77,7 @@
2.4 SHOW_NAMESPACES = YES
2.5 FILE_VERSION_FILTER =
2.6 LAYOUT_FILE = "@abs_top_srcdir@/doc/DoxygenLayout.xml"
2.7 +CITE_BIB_FILES = "@abs_top_srcdir@/doc/references.bib"
2.8 #---------------------------------------------------------------------------
2.9 # configuration options related to warning and progress messages
2.10 #---------------------------------------------------------------------------
3.1 --- a/doc/groups.dox Sat Mar 16 14:11:32 2013 +0100
3.2 +++ b/doc/groups.dox Mon Mar 18 17:41:19 2013 +0100
3.3 @@ -317,7 +317,7 @@
3.4
3.5 This group contains the common graph search algorithms, namely
3.6 \e breadth-first \e search (BFS) and \e depth-first \e search (DFS)
3.7 -\ref clrs01algorithms.
3.8 +\cite clrs01algorithms.
3.9 */
3.10
3.11 /**
3.12 @@ -326,7 +326,7 @@
3.13 \brief Algorithms for finding shortest paths.
3.14
3.15 This group contains the algorithms for finding shortest paths in digraphs
3.16 -\ref clrs01algorithms.
3.17 +\cite clrs01algorithms.
3.18
3.19 - \ref Dijkstra algorithm for finding shortest paths from a source node
3.20 when all arc lengths are non-negative.
3.21 @@ -348,7 +348,7 @@
3.22 \brief Algorithms for finding minimum cost spanning trees and arborescences.
3.23
3.24 This group contains the algorithms for finding minimum cost spanning
3.25 -trees and arborescences \ref clrs01algorithms.
3.26 +trees and arborescences \cite clrs01algorithms.
3.27 */
3.28
3.29 /**
3.30 @@ -357,7 +357,7 @@
3.31 \brief Algorithms for finding maximum flows.
3.32
3.33 This group contains the algorithms for finding maximum flows and
3.34 -feasible circulations \ref clrs01algorithms, \ref amo93networkflows.
3.35 +feasible circulations \cite clrs01algorithms, \cite amo93networkflows.
3.36
3.37 The \e maximum \e flow \e problem is to find a flow of maximum value between
3.38 a single source and a single target. Formally, there is a \f$G=(V,A)\f$
3.39 @@ -373,13 +373,13 @@
3.40
3.41 LEMON contains several algorithms for solving maximum flow problems:
3.42 - \ref EdmondsKarp Edmonds-Karp algorithm
3.43 - \ref edmondskarp72theoretical.
3.44 + \cite edmondskarp72theoretical.
3.45 - \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm
3.46 - \ref goldberg88newapproach.
3.47 + \cite goldberg88newapproach.
3.48 - \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees
3.49 - \ref dinic70algorithm, \ref sleator83dynamic.
3.50 + \cite dinic70algorithm, \cite sleator83dynamic.
3.51 - \ref GoldbergTarjan !Preflow push-relabel algorithm with dynamic trees
3.52 - \ref goldberg88newapproach, \ref sleator83dynamic.
3.53 + \cite goldberg88newapproach, \cite sleator83dynamic.
3.54
3.55 In most cases the \ref Preflow algorithm provides the
3.56 fastest method for computing a maximum flow. All implementations
3.57 @@ -399,20 +399,20 @@
3.58 \brief Algorithms for finding minimum cost flows and circulations.
3.59
3.60 This group contains the algorithms for finding minimum cost flows and
3.61 -circulations \ref amo93networkflows. For more information about this
3.62 +circulations \cite amo93networkflows. For more information about this
3.63 problem and its dual solution, see: \ref min_cost_flow
3.64 "Minimum Cost Flow Problem".
3.65
3.66 LEMON contains several algorithms for this problem.
3.67 - \ref NetworkSimplex Primal Network Simplex algorithm with various
3.68 - pivot strategies \ref dantzig63linearprog, \ref kellyoneill91netsimplex.
3.69 + pivot strategies \cite dantzig63linearprog, \cite kellyoneill91netsimplex.
3.70 - \ref CostScaling Cost Scaling algorithm based on push/augment and
3.71 - relabel operations \ref goldberg90approximation, \ref goldberg97efficient,
3.72 - \ref bunnagel98efficient.
3.73 + relabel operations \cite goldberg90approximation, \cite goldberg97efficient,
3.74 + \cite bunnagel98efficient.
3.75 - \ref CapacityScaling Capacity Scaling algorithm based on the successive
3.76 - shortest path method \ref edmondskarp72theoretical.
3.77 + shortest path method \cite edmondskarp72theoretical.
3.78 - \ref CycleCanceling Cycle-Canceling algorithms, two of which are
3.79 - strongly polynomial \ref klein67primal, \ref goldberg89cyclecanceling.
3.80 + strongly polynomial \cite klein67primal, \cite goldberg89cyclecanceling.
3.81
3.82 In general, \ref NetworkSimplex and \ref CostScaling are the most efficient
3.83 implementations.
3.84 @@ -430,7 +430,7 @@
3.85 data are required to be integer).
3.86
3.87 For more details about these implementations and for a comprehensive
3.88 -experimental study, see the paper \ref KiralyKovacs12MCF.
3.89 +experimental study, see the paper \cite KiralyKovacs12MCF.
3.90 It also compares these codes to other publicly available
3.91 minimum cost flow solvers.
3.92 */
3.93 @@ -471,7 +471,7 @@
3.94 \brief Algorithms for finding minimum mean cycles.
3.95
3.96 This group contains the algorithms for finding minimum mean cycles
3.97 -\ref amo93networkflows, \ref karp78characterization.
3.98 +\cite amo93networkflows, \cite karp78characterization.
3.99
3.100 The \e minimum \e mean \e cycle \e problem is to find a directed cycle
3.101 of minimum mean length (cost) in a digraph.
3.102 @@ -487,11 +487,11 @@
3.103 function.
3.104
3.105 LEMON contains three algorithms for solving the minimum mean cycle problem:
3.106 -- \ref KarpMmc Karp's original algorithm \ref karp78characterization.
3.107 +- \ref KarpMmc Karp's original algorithm \cite karp78characterization.
3.108 - \ref HartmannOrlinMmc Hartmann-Orlin's algorithm, which is an improved
3.109 - version of Karp's algorithm \ref hartmann93finding.
3.110 + version of Karp's algorithm \cite hartmann93finding.
3.111 - \ref HowardMmc Howard's policy iteration algorithm
3.112 - \ref dasdan98minmeancycle, \ref dasdan04experimental.
3.113 + \cite dasdan98minmeancycle, \cite dasdan04experimental.
3.114
3.115 In practice, the \ref HowardMmc "Howard" algorithm turned out to be by far the
3.116 most efficient one, though the best known theoretical bound on its running
3.117 @@ -647,8 +647,8 @@
3.118 Various LP solvers could be used in the same manner with this
3.119 high-level interface.
3.120
3.121 -The currently supported solvers are \ref glpk, \ref clp, \ref cbc,
3.122 -\ref cplex, \ref soplex.
3.123 +The currently supported solvers are \cite glpk, \cite clp, \cite cbc,
3.124 +\cite cplex, \cite soplex.
3.125 */
3.126
3.127 /**
4.1 --- a/doc/mainpage.dox.in Sat Mar 16 14:11:32 2013 +0100
4.2 +++ b/doc/mainpage.dox.in Mon Mar 18 17:41:19 2013 +0100
4.3 @@ -25,7 +25,7 @@
4.4 and <b>O</b>ptimization in <b>N</b>etworks</i>.
4.5 It is a C++ template library providing efficient implementations of common
4.6 data structures and algorithms with focus on combinatorial optimization
4.7 -tasks connected mainly with graphs and networks \ref DezsoJuttnerKovacs11Lemon.
4.8 +tasks connected mainly with graphs and networks \cite DezsoJuttnerKovacs11Lemon.
4.9
4.10 <b>
4.11 LEMON is an <a class="el" href="http://opensource.org/">open source</a>
4.12 @@ -37,12 +37,12 @@
4.13
4.14 The project is maintained by the
4.15 <a href="http://www.cs.elte.hu/egres/">Egerváry Research Group on
4.16 -Combinatorial Optimization</a> \ref egres
4.17 +Combinatorial Optimization</a> \cite egres
4.18 at the Operations Research Department of the
4.19 <a href="http://www.elte.hu/en/">Eötvös Loránd University</a>,
4.20 Budapest, Hungary.
4.21 LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
4.22 -initiative \ref coinor.
4.23 +initiative \cite coinor.
4.24
4.25 \section howtoread How to Read the Documentation
4.26
5.1 --- a/doc/min_cost_flow.dox Sat Mar 16 14:11:32 2013 +0100
5.2 +++ b/doc/min_cost_flow.dox Mon Mar 18 17:41:19 2013 +0100
5.3 @@ -26,7 +26,7 @@
5.4 The \e minimum \e cost \e flow \e problem is to find a feasible flow of
5.5 minimum total cost from a set of supply nodes to a set of demand nodes
5.6 in a network with capacity constraints (lower and upper bounds)
5.7 -and arc costs \ref amo93networkflows.
5.8 +and arc costs \cite amo93networkflows.
5.9
5.10 Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$,
5.11 \f$upper: A\rightarrow\mathbf{R}\cup\{+\infty\}\f$ denote the lower and
6.1 --- a/lemon/capacity_scaling.h Sat Mar 16 14:11:32 2013 +0100
6.2 +++ b/lemon/capacity_scaling.h Mon Mar 18 17:41:19 2013 +0100
6.3 @@ -66,8 +66,8 @@
6.4 ///
6.5 /// \ref CapacityScaling implements the capacity scaling version
6.6 /// of the successive shortest path algorithm for finding a
6.7 - /// \ref min_cost_flow "minimum cost flow" \ref amo93networkflows,
6.8 - /// \ref edmondskarp72theoretical. It is an efficient dual
6.9 + /// \ref min_cost_flow "minimum cost flow" \cite amo93networkflows,
6.10 + /// \cite edmondskarp72theoretical. It is an efficient dual
6.11 /// solution method, which runs in polynomial time
6.12 /// \f$O(e\log U (n+e)\log n)\f$, where <i>U</i> denotes the maximum
6.13 /// of node supply and arc capacity values.
7.1 --- a/lemon/cost_scaling.h Sat Mar 16 14:11:32 2013 +0100
7.2 +++ b/lemon/cost_scaling.h Mon Mar 18 17:41:19 2013 +0100
7.3 @@ -91,8 +91,8 @@
7.4 ///
7.5 /// \ref CostScaling implements a cost scaling algorithm that performs
7.6 /// push/augment and relabel operations for finding a \ref min_cost_flow
7.7 - /// "minimum cost flow" \ref amo93networkflows, \ref goldberg90approximation,
7.8 - /// \ref goldberg97efficient, \ref bunnagel98efficient.
7.9 + /// "minimum cost flow" \cite amo93networkflows, \cite goldberg90approximation,
7.10 + /// \cite goldberg97efficient, \cite bunnagel98efficient.
7.11 /// It is a highly efficient primal-dual solution method, which
7.12 /// can be viewed as the generalization of the \ref Preflow
7.13 /// "preflow push-relabel" algorithm for the maximum flow problem.
8.1 --- a/lemon/cycle_canceling.h Sat Mar 16 14:11:32 2013 +0100
8.2 +++ b/lemon/cycle_canceling.h Mon Mar 18 17:41:19 2013 +0100
8.3 @@ -47,8 +47,8 @@
8.4 ///
8.5 /// \ref CycleCanceling implements three different cycle-canceling
8.6 /// algorithms for finding a \ref min_cost_flow "minimum cost flow"
8.7 - /// \ref amo93networkflows, \ref klein67primal,
8.8 - /// \ref goldberg89cyclecanceling.
8.9 + /// \cite amo93networkflows, \cite klein67primal,
8.10 + /// \cite goldberg89cyclecanceling.
8.11 /// The most efficent one is the \ref CANCEL_AND_TIGHTEN
8.12 /// "Cancel-and-Tighten" algorithm, thus it is the default method.
8.13 /// It runs in strongly polynomial time O(n<sup>2</sup>e<sup>2</sup>log(n)),
8.14 @@ -131,13 +131,13 @@
8.15 SIMPLE_CYCLE_CANCELING,
8.16 /// The "Minimum Mean Cycle-Canceling" algorithm, which is a
8.17 /// well-known strongly polynomial method
8.18 - /// \ref goldberg89cyclecanceling. It improves along a
8.19 + /// \cite goldberg89cyclecanceling. It improves along a
8.20 /// \ref min_mean_cycle "minimum mean cycle" in each iteration.
8.21 /// Its running time complexity is O(n<sup>2</sup>e<sup>3</sup>log(n)).
8.22 MINIMUM_MEAN_CYCLE_CANCELING,
8.23 /// The "Cancel-and-Tighten" algorithm, which can be viewed as an
8.24 /// improved version of the previous method
8.25 - /// \ref goldberg89cyclecanceling.
8.26 + /// \cite goldberg89cyclecanceling.
8.27 /// It is faster both in theory and in practice, its running time
8.28 /// complexity is O(n<sup>2</sup>e<sup>2</sup>log(n)).
8.29 CANCEL_AND_TIGHTEN
9.1 --- a/lemon/grosso_locatelli_pullan_mc.h Sat Mar 16 14:11:32 2013 +0100
9.2 +++ b/lemon/grosso_locatelli_pullan_mc.h Mon Mar 18 17:41:19 2013 +0100
9.3 @@ -40,7 +40,7 @@
9.4 ///
9.5 /// \ref GrossoLocatelliPullanMc implements the iterated local search
9.6 /// algorithm of Grosso, Locatelli, and Pullan for solving the \e maximum
9.7 - /// \e clique \e problem \ref grosso08maxclique.
9.8 + /// \e clique \e problem \cite grosso08maxclique.
9.9 /// It is to find the largest complete subgraph (\e clique) in an
9.10 /// undirected graph, i.e., the largest set of nodes where each
9.11 /// pair of nodes is connected.
10.1 --- a/lemon/hartmann_orlin_mmc.h Sat Mar 16 14:11:32 2013 +0100
10.2 +++ b/lemon/hartmann_orlin_mmc.h Mon Mar 18 17:41:19 2013 +0100
10.3 @@ -98,7 +98,7 @@
10.4 ///
10.5 /// This class implements the Hartmann-Orlin algorithm for finding
10.6 /// a directed cycle of minimum mean cost in a digraph
10.7 - /// \ref hartmann93finding, \ref dasdan98minmeancycle.
10.8 + /// \cite hartmann93finding, \cite dasdan98minmeancycle.
10.9 /// This method is based on \ref KarpMmc "Karp"'s original algorithm, but
10.10 /// applies an early termination scheme. It makes the algorithm
10.11 /// significantly faster for some problem instances, but slower for others.
11.1 --- a/lemon/howard_mmc.h Sat Mar 16 14:11:32 2013 +0100
11.2 +++ b/lemon/howard_mmc.h Mon Mar 18 17:41:19 2013 +0100
11.3 @@ -98,7 +98,7 @@
11.4 ///
11.5 /// This class implements Howard's policy iteration algorithm for finding
11.6 /// a directed cycle of minimum mean cost in a digraph
11.7 - /// \ref dasdan98minmeancycle, \ref dasdan04experimental.
11.8 + /// \cite dasdan98minmeancycle, \cite dasdan04experimental.
11.9 /// This class provides the most efficient algorithm for the
11.10 /// minimum mean cycle problem, though the best known theoretical
11.11 /// bound on its running time is exponential.
12.1 --- a/lemon/karp_mmc.h Sat Mar 16 14:11:32 2013 +0100
12.2 +++ b/lemon/karp_mmc.h Mon Mar 18 17:41:19 2013 +0100
12.3 @@ -98,7 +98,7 @@
12.4 ///
12.5 /// This class implements Karp's algorithm for finding a directed
12.6 /// cycle of minimum mean cost in a digraph
12.7 - /// \ref karp78characterization, \ref dasdan98minmeancycle.
12.8 + /// \cite karp78characterization, \cite dasdan98minmeancycle.
12.9 /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
12.10 ///
12.11 /// \tparam GR The type of the digraph the algorithm runs on.
13.1 --- a/lemon/network_simplex.h Sat Mar 16 14:11:32 2013 +0100
13.2 +++ b/lemon/network_simplex.h Mon Mar 18 17:41:19 2013 +0100
13.3 @@ -41,8 +41,8 @@
13.4 ///
13.5 /// \ref NetworkSimplex implements the primal Network Simplex algorithm
13.6 /// for finding a \ref min_cost_flow "minimum cost flow"
13.7 - /// \ref amo93networkflows, \ref dantzig63linearprog,
13.8 - /// \ref kellyoneill91netsimplex.
13.9 + /// \cite amo93networkflows, \cite dantzig63linearprog,
13.10 + /// \cite kellyoneill91netsimplex.
13.11 /// This algorithm is a highly efficient specialized version of the
13.12 /// linear programming simplex method directly for the minimum cost
13.13 /// flow problem.
14.1 --- a/lemon/preflow.h Sat Mar 16 14:11:32 2013 +0100
14.2 +++ b/lemon/preflow.h Mon Mar 18 17:41:19 2013 +0100
14.3 @@ -102,8 +102,8 @@
14.4 ///
14.5 /// This class provides an implementation of Goldberg-Tarjan's \e preflow
14.6 /// \e push-relabel algorithm producing a \ref max_flow
14.7 - /// "flow of maximum value" in a digraph \ref clrs01algorithms,
14.8 - /// \ref amo93networkflows, \ref goldberg88newapproach.
14.9 + /// "flow of maximum value" in a digraph \cite clrs01algorithms,
14.10 + /// \cite amo93networkflows, \cite goldberg88newapproach.
14.11 /// The preflow algorithms are the fastest known maximum
14.12 /// flow algorithms. The current implementation uses a mixture of the
14.13 /// \e "highest label" and the \e "bound decrease" heuristics.
15.1 --- a/scripts/bib2dox.py Sat Mar 16 14:11:32 2013 +0100
15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
15.3 @@ -1,816 +0,0 @@
15.4 -#! /usr/bin/env python
15.5 -"""
15.6 - BibTeX to Doxygen converter
15.7 - Usage: python bib2dox.py bibfile.bib > bibfile.dox
15.8 -
15.9 - This file is a part of LEMON, a generic C++ optimization library.
15.10 -
15.11 - **********************************************************************
15.12 -
15.13 - This code is the modification of the BibTeX to XML converter
15.14 - by Vidar Bronken Gundersen et al.
15.15 - See the original copyright notices below.
15.16 -
15.17 - **********************************************************************
15.18 -
15.19 - Decoder for bibliographic data, BibTeX
15.20 - Usage: python bibtex2xml.py bibfile.bib > bibfile.xml
15.21 -
15.22 - v.8
15.23 - (c)2002-06-23 Vidar Bronken Gundersen
15.24 - http://bibtexml.sf.net/
15.25 - Reuse approved as long as this notification is kept.
15.26 - Licence: GPL.
15.27 -
15.28 - Contributions/thanks to:
15.29 - Egon Willighagen, http://sf.net/projects/jreferences/
15.30 - Richard Mahoney (for providing a test case)
15.31 -
15.32 - Editted by Sara Sprenkle to be more robust and handle more bibtex features.
15.33 - (c) 2003-01-15
15.34 -
15.35 - 1. Changed bibtex: tags to bibxml: tags.
15.36 - 2. Use xmlns:bibxml="http://bibtexml.sf.net/"
15.37 - 3. Allow spaces between @type and first {
15.38 - 4. "author" fields with multiple authors split by " and "
15.39 - are put in separate xml "bibxml:author" tags.
15.40 - 5. Option for Titles: words are capitalized
15.41 - only if first letter in title or capitalized inside braces
15.42 - 6. Removes braces from within field values
15.43 - 7. Ignores comments in bibtex file (including @comment{ or % )
15.44 - 8. Replaces some special latex tags, e.g., replaces ~ with ' '
15.45 - 9. Handles bibtex @string abbreviations
15.46 - --> includes bibtex's default abbreviations for months
15.47 - --> does concatenation of abbr # " more " and " more " # abbr
15.48 - 10. Handles @type( ... ) or @type{ ... }
15.49 - 11. The keywords field is split on , or ; and put into separate xml
15.50 - "bibxml:keywords" tags
15.51 - 12. Ignores @preamble
15.52 -
15.53 - Known Limitations
15.54 - 1. Does not transform Latex encoding like math mode and special
15.55 - latex symbols.
15.56 - 2. Does not parse author fields into first and last names.
15.57 - E.g., It does not do anything special to an author whose name is
15.58 - in the form LAST_NAME, FIRST_NAME
15.59 - In "author" tag, will show up as
15.60 - <bibxml:author>LAST_NAME, FIRST_NAME</bibxml:author>
15.61 - 3. Does not handle "crossref" fields other than to print
15.62 - <bibxml:crossref>...</bibxml:crossref>
15.63 - 4. Does not inform user of the input's format errors. You just won't
15.64 - be able to transform the file later with XSL
15.65 -
15.66 - You will have to manually edit the XML output if you need to handle
15.67 - these (and unknown) limitations.
15.68 -
15.69 -"""
15.70 -
15.71 -import string, re
15.72 -
15.73 -# set of valid name characters
15.74 -valid_name_chars = '[\w\-:]'
15.75 -
15.76 -#
15.77 -# define global regular expression variables
15.78 -#
15.79 -author_rex = re.compile('\s+and\s+')
15.80 -rembraces_rex = re.compile('[{}]')
15.81 -capitalize_rex = re.compile('({[^}]*})')
15.82 -
15.83 -# used by bibtexkeywords(data)
15.84 -keywords_rex = re.compile('[,;]')
15.85 -
15.86 -# used by concat_line(line)
15.87 -concatsplit_rex = re.compile('\s*#\s*')
15.88 -
15.89 -# split on {, }, or " in verify_out_of_braces
15.90 -delimiter_rex = re.compile('([{}"])',re.I)
15.91 -
15.92 -field_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
15.93 -data_rex = re.compile('\s*(\w*)\s*=\s*([^,]*),?')
15.94 -
15.95 -url_rex = re.compile('\\\url\{([^}]*)\}')
15.96 -
15.97 -#
15.98 -# styles for html formatting
15.99 -#
15.100 -divstyle = 'margin-top: -4ex; margin-left: 10em;'
15.101 -
15.102 -#
15.103 -# return the string parameter without braces
15.104 -#
15.105 -def transformurls(str):
15.106 - return url_rex.sub(r'<a href="\1">\1</a>', str)
15.107 -
15.108 -#
15.109 -# return the string parameter without braces
15.110 -#
15.111 -def removebraces(str):
15.112 - return rembraces_rex.sub('', str)
15.113 -
15.114 -#
15.115 -# latex-specific replacements
15.116 -# (do this after braces were removed)
15.117 -#
15.118 -def latexreplacements(line):
15.119 - line = string.replace(line, '~', ' ')
15.120 - line = string.replace(line, '\\\'a', 'á')
15.121 - line = string.replace(line, '\\"a', 'ä')
15.122 - line = string.replace(line, '\\\'e', 'é')
15.123 - line = string.replace(line, '\\"e', 'ë')
15.124 - line = string.replace(line, '\\\'i', 'í')
15.125 - line = string.replace(line, '\\"i', 'ï')
15.126 - line = string.replace(line, '\\\'o', 'ó')
15.127 - line = string.replace(line, '\\"o', 'ö')
15.128 - line = string.replace(line, '\\\'u', 'ú')
15.129 - line = string.replace(line, '\\"u', 'ü')
15.130 - line = string.replace(line, '\\H o', 'õ')
15.131 - line = string.replace(line, '\\H u', 'ü') # ũ does not exist
15.132 - line = string.replace(line, '\\\'A', 'Á')
15.133 - line = string.replace(line, '\\"A', 'Ä')
15.134 - line = string.replace(line, '\\\'E', 'É')
15.135 - line = string.replace(line, '\\"E', 'Ë')
15.136 - line = string.replace(line, '\\\'I', 'Í')
15.137 - line = string.replace(line, '\\"I', 'Ï')
15.138 - line = string.replace(line, '\\\'O', 'Ó')
15.139 - line = string.replace(line, '\\"O', 'Ö')
15.140 - line = string.replace(line, '\\\'U', 'Ú')
15.141 - line = string.replace(line, '\\"U', 'Ü')
15.142 - line = string.replace(line, '\\H O', 'Õ')
15.143 - line = string.replace(line, '\\H U', 'Ü') # Ũ does not exist
15.144 -
15.145 - return line
15.146 -
15.147 -#
15.148 -# copy characters form a string decoding html expressions (&xyz;)
15.149 -#
15.150 -def copychars(str, ifrom, count):
15.151 - result = ''
15.152 - i = ifrom
15.153 - c = 0
15.154 - html_spec = False
15.155 - while (i < len(str)) and (c < count):
15.156 - if str[i] == '&':
15.157 - html_spec = True;
15.158 - if i+1 < len(str):
15.159 - result += str[i+1]
15.160 - c += 1
15.161 - i += 2
15.162 - else:
15.163 - if not html_spec:
15.164 - if ((str[i] >= 'A') and (str[i] <= 'Z')) or \
15.165 - ((str[i] >= 'a') and (str[i] <= 'z')):
15.166 - result += str[i]
15.167 - c += 1
15.168 - elif str[i] == ';':
15.169 - html_spec = False;
15.170 - i += 1
15.171 -
15.172 - return result
15.173 -
15.174 -
15.175 -#
15.176 -# Handle a list of authors (separated by 'and').
15.177 -# It gives back an array of the follwing values:
15.178 -# - num: the number of authors,
15.179 -# - list: the list of the author names,
15.180 -# - text: the bibtex text (separated by commas and/or 'and')
15.181 -# - abbrev: abbreviation that can be used for indicate the
15.182 -# bibliography entries
15.183 -#
15.184 -def bibtexauthor(data):
15.185 - result = {}
15.186 - bibtex = ''
15.187 - result['list'] = author_rex.split(data)
15.188 - result['num'] = len(result['list'])
15.189 - for i, author in enumerate(result['list']):
15.190 - # general transformations
15.191 - author = latexreplacements(removebraces(author.strip()))
15.192 - # transform "Xyz, A. B." to "A. B. Xyz"
15.193 - pos = author.find(',')
15.194 - if pos != -1:
15.195 - author = author[pos+1:].strip() + ' ' + author[:pos].strip()
15.196 - result['list'][i] = author
15.197 - bibtex += author + '#'
15.198 - bibtex = bibtex[:-1]
15.199 - if result['num'] > 1:
15.200 - ix = bibtex.rfind('#')
15.201 - if result['num'] == 2:
15.202 - bibtex = bibtex[:ix] + ' and ' + bibtex[ix+1:]
15.203 - else:
15.204 - bibtex = bibtex[:ix] + ', and ' + bibtex[ix+1:]
15.205 - bibtex = bibtex.replace('#', ', ')
15.206 - result['text'] = bibtex
15.207 -
15.208 - result['abbrev'] = ''
15.209 - for author in result['list']:
15.210 - pos = author.rfind(' ') + 1
15.211 - count = 1
15.212 - if result['num'] == 1:
15.213 - count = 3
15.214 - result['abbrev'] += copychars(author, pos, count)
15.215 -
15.216 - return result
15.217 -
15.218 -
15.219 -#
15.220 -# data = title string
15.221 -# @return the capitalized title (first letter is capitalized), rest are capitalized
15.222 -# only if capitalized inside braces
15.223 -#
15.224 -def capitalizetitle(data):
15.225 - title_list = capitalize_rex.split(data)
15.226 - title = ''
15.227 - count = 0
15.228 - for phrase in title_list:
15.229 - check = string.lstrip(phrase)
15.230 -
15.231 - # keep phrase's capitalization the same
15.232 - if check.find('{') == 0:
15.233 - title += removebraces(phrase)
15.234 - else:
15.235 - # first word --> capitalize first letter (after spaces)
15.236 - if count == 0:
15.237 - title += check.capitalize()
15.238 - else:
15.239 - title += phrase.lower()
15.240 - count = count + 1
15.241 -
15.242 - return title
15.243 -
15.244 -
15.245 -#
15.246 -# @return the bibtex for the title
15.247 -# @param data --> title string
15.248 -# braces are removed from title
15.249 -#
15.250 -def bibtextitle(data, entrytype):
15.251 - if entrytype in ('book', 'inbook'):
15.252 - title = removebraces(data.strip())
15.253 - else:
15.254 - title = removebraces(capitalizetitle(data.strip()))
15.255 - bibtex = title
15.256 - return bibtex
15.257 -
15.258 -
15.259 -#
15.260 -# function to compare entry lists
15.261 -#
15.262 -def entry_cmp(x, y):
15.263 - return cmp(x[0], y[0])
15.264 -
15.265 -
15.266 -#
15.267 -# print the XML for the transformed "filecont_source"
15.268 -#
15.269 -def bibtexdecoder(filecont_source):
15.270 - filecont = []
15.271 - file = []
15.272 -
15.273 - # want @<alphanumeric chars><spaces>{<spaces><any chars>,
15.274 - pubtype_rex = re.compile('@(\w*)\s*{\s*(.*),')
15.275 - endtype_rex = re.compile('}\s*$')
15.276 - endtag_rex = re.compile('^\s*}\s*$')
15.277 -
15.278 - bracefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
15.279 - bracedata_rex = re.compile('\s*(\w*)\s*=\s*{(.*)},?')
15.280 -
15.281 - quotefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
15.282 - quotedata_rex = re.compile('\s*(\w*)\s*=\s*"(.*)",?')
15.283 -
15.284 - for line in filecont_source:
15.285 - line = line[:-1]
15.286 -
15.287 - # encode character entities
15.288 - line = string.replace(line, '&', '&')
15.289 - line = string.replace(line, '<', '<')
15.290 - line = string.replace(line, '>', '>')
15.291 -
15.292 - # start entry: publication type (store for later use)
15.293 - if pubtype_rex.match(line):
15.294 - # want @<alphanumeric chars><spaces>{<spaces><any chars>,
15.295 - entrycont = {}
15.296 - entry = []
15.297 - entrytype = pubtype_rex.sub('\g<1>',line)
15.298 - entrytype = string.lower(entrytype)
15.299 - entryid = pubtype_rex.sub('\g<2>', line)
15.300 -
15.301 - # end entry if just a }
15.302 - elif endtype_rex.match(line):
15.303 - # generate doxygen code for the entry
15.304 -
15.305 - # enty type related formattings
15.306 - if entrytype in ('book', 'inbook'):
15.307 - entrycont['title'] = '<em>' + entrycont['title'] + '</em>'
15.308 - if not entrycont.has_key('author'):
15.309 - entrycont['author'] = entrycont['editor']
15.310 - entrycont['author']['text'] += ', editors'
15.311 - elif entrytype == 'article':
15.312 - entrycont['journal'] = '<em>' + entrycont['journal'] + '</em>'
15.313 - elif entrytype in ('inproceedings', 'incollection', 'conference'):
15.314 - entrycont['booktitle'] = '<em>' + entrycont['booktitle'] + '</em>'
15.315 - elif entrytype == 'techreport':
15.316 - if not entrycont.has_key('type'):
15.317 - entrycont['type'] = 'Technical report'
15.318 - elif entrytype == 'mastersthesis':
15.319 - entrycont['type'] = 'Master\'s thesis'
15.320 - elif entrytype == 'phdthesis':
15.321 - entrycont['type'] = 'PhD thesis'
15.322 -
15.323 - for eline in entrycont:
15.324 - if eline != '':
15.325 - eline = latexreplacements(eline)
15.326 -
15.327 - if entrycont.has_key('pages') and (entrycont['pages'] != ''):
15.328 - entrycont['pages'] = string.replace(entrycont['pages'], '--', '-')
15.329 -
15.330 - if entrycont.has_key('author') and (entrycont['author'] != ''):
15.331 - entry.append(entrycont['author']['text'] + '.')
15.332 - if entrycont.has_key('title') and (entrycont['title'] != ''):
15.333 - entry.append(entrycont['title'] + '.')
15.334 - if entrycont.has_key('journal') and (entrycont['journal'] != ''):
15.335 - entry.append(entrycont['journal'] + ',')
15.336 - if entrycont.has_key('booktitle') and (entrycont['booktitle'] != ''):
15.337 - entry.append('In ' + entrycont['booktitle'] + ',')
15.338 - if entrycont.has_key('type') and (entrycont['type'] != ''):
15.339 - eline = entrycont['type']
15.340 - if entrycont.has_key('number') and (entrycont['number'] != ''):
15.341 - eline += ' ' + entrycont['number']
15.342 - eline += ','
15.343 - entry.append(eline)
15.344 - if entrycont.has_key('institution') and (entrycont['institution'] != ''):
15.345 - entry.append(entrycont['institution'] + ',')
15.346 - if entrycont.has_key('publisher') and (entrycont['publisher'] != ''):
15.347 - entry.append(entrycont['publisher'] + ',')
15.348 - if entrycont.has_key('school') and (entrycont['school'] != ''):
15.349 - entry.append(entrycont['school'] + ',')
15.350 - if entrycont.has_key('address') and (entrycont['address'] != ''):
15.351 - entry.append(entrycont['address'] + ',')
15.352 - if entrycont.has_key('edition') and (entrycont['edition'] != ''):
15.353 - entry.append(entrycont['edition'] + ' edition,')
15.354 - if entrycont.has_key('howpublished') and (entrycont['howpublished'] != ''):
15.355 - entry.append(entrycont['howpublished'] + ',')
15.356 - if entrycont.has_key('volume') and (entrycont['volume'] != ''):
15.357 - eline = entrycont['volume'];
15.358 - if entrycont.has_key('number') and (entrycont['number'] != ''):
15.359 - eline += '(' + entrycont['number'] + ')'
15.360 - if entrycont.has_key('pages') and (entrycont['pages'] != ''):
15.361 - eline += ':' + entrycont['pages']
15.362 - eline += ','
15.363 - entry.append(eline)
15.364 - else:
15.365 - if entrycont.has_key('pages') and (entrycont['pages'] != ''):
15.366 - entry.append('pages ' + entrycont['pages'] + ',')
15.367 - if entrycont.has_key('year') and (entrycont['year'] != ''):
15.368 - if entrycont.has_key('month') and (entrycont['month'] != ''):
15.369 - entry.append(entrycont['month'] + ' ' + entrycont['year'] + '.')
15.370 - else:
15.371 - entry.append(entrycont['year'] + '.')
15.372 - if entrycont.has_key('note') and (entrycont['note'] != ''):
15.373 - entry.append(entrycont['note'] + '.')
15.374 - if entrycont.has_key('url') and (entrycont['url'] != ''):
15.375 - entry.append(entrycont['url'] + '.')
15.376 -
15.377 - # generate keys for sorting and for the output
15.378 - sortkey = ''
15.379 - bibkey = ''
15.380 - if entrycont.has_key('author'):
15.381 - for author in entrycont['author']['list']:
15.382 - sortkey += copychars(author, author.rfind(' ')+1, len(author))
15.383 - bibkey = entrycont['author']['abbrev']
15.384 - else:
15.385 - bibkey = 'x'
15.386 - if entrycont.has_key('year'):
15.387 - sortkey += entrycont['year']
15.388 - bibkey += entrycont['year'][-2:]
15.389 - if entrycont.has_key('title'):
15.390 - sortkey += entrycont['title']
15.391 - if entrycont.has_key('key'):
15.392 - sortkey = entrycont['key'] + sortkey
15.393 - bibkey = entrycont['key']
15.394 - entry.insert(0, sortkey)
15.395 - entry.insert(1, bibkey)
15.396 - entry.insert(2, entryid)
15.397 -
15.398 - # add the entry to the file contents
15.399 - filecont.append(entry)
15.400 -
15.401 - else:
15.402 - # field, publication info
15.403 - field = ''
15.404 - data = ''
15.405 -
15.406 - # field = {data} entries
15.407 - if bracedata_rex.match(line):
15.408 - field = bracefield_rex.sub('\g<1>', line)
15.409 - field = string.lower(field)
15.410 - data = bracedata_rex.sub('\g<2>', line)
15.411 -
15.412 - # field = "data" entries
15.413 - elif quotedata_rex.match(line):
15.414 - field = quotefield_rex.sub('\g<1>', line)
15.415 - field = string.lower(field)
15.416 - data = quotedata_rex.sub('\g<2>', line)
15.417 -
15.418 - # field = data entries
15.419 - elif data_rex.match(line):
15.420 - field = field_rex.sub('\g<1>', line)
15.421 - field = string.lower(field)
15.422 - data = data_rex.sub('\g<2>', line)
15.423 -
15.424 - if field == 'url':
15.425 - data = '\\url{' + data.strip() + '}'
15.426 -
15.427 - if field in ('author', 'editor'):
15.428 - entrycont[field] = bibtexauthor(data)
15.429 - line = ''
15.430 - elif field == 'title':
15.431 - line = bibtextitle(data, entrytype)
15.432 - elif field != '':
15.433 - line = removebraces(transformurls(data.strip()))
15.434 -
15.435 - if line != '':
15.436 - line = latexreplacements(line)
15.437 - entrycont[field] = line
15.438 -
15.439 -
15.440 - # sort entries
15.441 - filecont.sort(entry_cmp)
15.442 -
15.443 - # count the bibtex keys
15.444 - keytable = {}
15.445 - counttable = {}
15.446 - for entry in filecont:
15.447 - bibkey = entry[1]
15.448 - if not keytable.has_key(bibkey):
15.449 - keytable[bibkey] = 1
15.450 - else:
15.451 - keytable[bibkey] += 1
15.452 -
15.453 - for bibkey in keytable.keys():
15.454 - counttable[bibkey] = 0
15.455 -
15.456 - # generate output
15.457 - for entry in filecont:
15.458 - # generate output key form the bibtex key
15.459 - bibkey = entry[1]
15.460 - entryid = entry[2]
15.461 - if keytable[bibkey] == 1:
15.462 - outkey = bibkey
15.463 - else:
15.464 - outkey = bibkey + chr(97 + counttable[bibkey])
15.465 - counttable[bibkey] += 1
15.466 -
15.467 - # append the entry code to the output
15.468 - file.append('\\section ' + entryid + ' [' + outkey + ']')
15.469 - file.append('<div style="' + divstyle + '">')
15.470 - for line in entry[3:]:
15.471 - file.append(line)
15.472 - file.append('</div>')
15.473 - file.append('')
15.474 -
15.475 - return file
15.476 -
15.477 -
15.478 -#
15.479 -# return 1 iff abbr is in line but not inside braces or quotes
15.480 -# assumes that abbr appears only once on the line (out of braces and quotes)
15.481 -#
15.482 -def verify_out_of_braces(line, abbr):
15.483 -
15.484 - phrase_split = delimiter_rex.split(line)
15.485 -
15.486 - abbr_rex = re.compile( '\\b' + abbr + '\\b', re.I)
15.487 -
15.488 - open_brace = 0
15.489 - open_quote = 0
15.490 -
15.491 - for phrase in phrase_split:
15.492 - if phrase == "{":
15.493 - open_brace = open_brace + 1
15.494 - elif phrase == "}":
15.495 - open_brace = open_brace - 1
15.496 - elif phrase == '"':
15.497 - if open_quote == 1:
15.498 - open_quote = 0
15.499 - else:
15.500 - open_quote = 1
15.501 - elif abbr_rex.search(phrase):
15.502 - if open_brace == 0 and open_quote == 0:
15.503 - return 1
15.504 -
15.505 - return 0
15.506 -
15.507 -
15.508 -#
15.509 -# a line in the form phrase1 # phrase2 # ... # phrasen
15.510 -# is returned as phrase1 phrase2 ... phrasen
15.511 -# with the correct punctuation
15.512 -# Bug: Doesn't always work with multiple abbreviations plugged in
15.513 -#
15.514 -def concat_line(line):
15.515 - # only look at part after equals
15.516 - field = field_rex.sub('\g<1>',line)
15.517 - rest = field_rex.sub('\g<2>',line)
15.518 -
15.519 - concat_line = field + ' ='
15.520 -
15.521 - pound_split = concatsplit_rex.split(rest)
15.522 -
15.523 - phrase_count = 0
15.524 - length = len(pound_split)
15.525 -
15.526 - for phrase in pound_split:
15.527 - phrase = phrase.strip()
15.528 - if phrase_count != 0:
15.529 - if phrase.startswith('"') or phrase.startswith('{'):
15.530 - phrase = phrase[1:]
15.531 - elif phrase.startswith('"'):
15.532 - phrase = phrase.replace('"','{',1)
15.533 -
15.534 - if phrase_count != length-1:
15.535 - if phrase.endswith('"') or phrase.endswith('}'):
15.536 - phrase = phrase[:-1]
15.537 - else:
15.538 - if phrase.endswith('"'):
15.539 - phrase = phrase[:-1]
15.540 - phrase = phrase + "}"
15.541 - elif phrase.endswith('",'):
15.542 - phrase = phrase[:-2]
15.543 - phrase = phrase + "},"
15.544 -
15.545 - # if phrase did have \#, add the \# back
15.546 - if phrase.endswith('\\'):
15.547 - phrase = phrase + "#"
15.548 - concat_line = concat_line + ' ' + phrase
15.549 -
15.550 - phrase_count = phrase_count + 1
15.551 -
15.552 - return concat_line
15.553 -
15.554 -
15.555 -#
15.556 -# substitute abbreviations into filecont
15.557 -# @param filecont_source - string of data from file
15.558 -#
15.559 -def bibtex_replace_abbreviations(filecont_source):
15.560 - filecont = filecont_source.splitlines()
15.561 -
15.562 - # These are defined in bibtex, so we'll define them too
15.563 - abbr_list = ['jan','feb','mar','apr','may','jun',
15.564 - 'jul','aug','sep','oct','nov','dec']
15.565 - value_list = ['January','February','March','April',
15.566 - 'May','June','July','August','September',
15.567 - 'October','November','December']
15.568 -
15.569 - abbr_rex = []
15.570 - total_abbr_count = 0
15.571 -
15.572 - front = '\\b'
15.573 - back = '(,?)\\b'
15.574 -
15.575 - for x in abbr_list:
15.576 - abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
15.577 - total_abbr_count = total_abbr_count + 1
15.578 -
15.579 -
15.580 - abbrdef_rex = re.compile('\s*@string\s*{\s*('+ valid_name_chars +'*)\s*=(.*)',
15.581 - re.I)
15.582 -
15.583 - comment_rex = re.compile('@comment\s*{',re.I)
15.584 - preamble_rex = re.compile('@preamble\s*{',re.I)
15.585 -
15.586 - waiting_for_end_string = 0
15.587 - i = 0
15.588 - filecont2 = ''
15.589 -
15.590 - for line in filecont:
15.591 - if line == ' ' or line == '':
15.592 - continue
15.593 -
15.594 - if waiting_for_end_string:
15.595 - if re.search('}',line):
15.596 - waiting_for_end_string = 0
15.597 - continue
15.598 -
15.599 - if abbrdef_rex.search(line):
15.600 - abbr = abbrdef_rex.sub('\g<1>', line)
15.601 -
15.602 - if abbr_list.count(abbr) == 0:
15.603 - val = abbrdef_rex.sub('\g<2>', line)
15.604 - abbr_list.append(abbr)
15.605 - value_list.append(string.strip(val))
15.606 - abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
15.607 - total_abbr_count = total_abbr_count + 1
15.608 - waiting_for_end_string = 1
15.609 - continue
15.610 -
15.611 - if comment_rex.search(line):
15.612 - waiting_for_end_string = 1
15.613 - continue
15.614 -
15.615 - if preamble_rex.search(line):
15.616 - waiting_for_end_string = 1
15.617 - continue
15.618 -
15.619 -
15.620 - # replace subsequent abbreviations with the value
15.621 - abbr_count = 0
15.622 -
15.623 - for x in abbr_list:
15.624 -
15.625 - if abbr_rex[abbr_count].search(line):
15.626 - if verify_out_of_braces(line,abbr_list[abbr_count]) == 1:
15.627 - line = abbr_rex[abbr_count].sub( value_list[abbr_count] + '\g<1>', line)
15.628 - # Check for # concatenations
15.629 - if concatsplit_rex.search(line):
15.630 - line = concat_line(line)
15.631 - abbr_count = abbr_count + 1
15.632 -
15.633 -
15.634 - filecont2 = filecont2 + line + '\n'
15.635 - i = i+1
15.636 -
15.637 -
15.638 - # Do one final pass over file
15.639 -
15.640 - # make sure that didn't end up with {" or }" after the substitution
15.641 - filecont2 = filecont2.replace('{"','{{')
15.642 - filecont2 = filecont2.replace('"}','}}')
15.643 -
15.644 - afterquotevalue_rex = re.compile('"\s*,\s*')
15.645 - afterbrace_rex = re.compile('"\s*}')
15.646 - afterbracevalue_rex = re.compile('(=\s*{[^=]*)},\s*')
15.647 -
15.648 - # add new lines to data that changed because of abbreviation substitutions
15.649 - filecont2 = afterquotevalue_rex.sub('",\n', filecont2)
15.650 - filecont2 = afterbrace_rex.sub('"\n}', filecont2)
15.651 - filecont2 = afterbracevalue_rex.sub('\g<1>},\n', filecont2)
15.652 -
15.653 - return filecont2
15.654 -
15.655 -#
15.656 -# convert @type( ... ) to @type{ ... }
15.657 -#
15.658 -def no_outer_parens(filecont):
15.659 -
15.660 - # do checking for open parens
15.661 - # will convert to braces
15.662 - paren_split = re.split('([(){}])',filecont)
15.663 -
15.664 - open_paren_count = 0
15.665 - open_type = 0
15.666 - look_next = 0
15.667 -
15.668 - # rebuild filecont
15.669 - filecont = ''
15.670 -
15.671 - at_rex = re.compile('@\w*')
15.672 -
15.673 - for phrase in paren_split:
15.674 - if look_next == 1:
15.675 - if phrase == '(':
15.676 - phrase = '{'
15.677 - open_paren_count = open_paren_count + 1
15.678 - else:
15.679 - open_type = 0
15.680 - look_next = 0
15.681 -
15.682 - if phrase == '(':
15.683 - open_paren_count = open_paren_count + 1
15.684 -
15.685 - elif phrase == ')':
15.686 - open_paren_count = open_paren_count - 1
15.687 - if open_type == 1 and open_paren_count == 0:
15.688 - phrase = '}'
15.689 - open_type = 0
15.690 -
15.691 - elif at_rex.search( phrase ):
15.692 - open_type = 1
15.693 - look_next = 1
15.694 -
15.695 - filecont = filecont + phrase
15.696 -
15.697 - return filecont
15.698 -
15.699 -
15.700 -#
15.701 -# make all whitespace into just one space
15.702 -# format the bibtex file into a usable form.
15.703 -#
15.704 -def bibtexwasher(filecont_source):
15.705 -
15.706 - space_rex = re.compile('\s+')
15.707 - comment_rex = re.compile('\s*%')
15.708 -
15.709 - filecont = []
15.710 -
15.711 - # remove trailing and excessive whitespace
15.712 - # ignore comments
15.713 - for line in filecont_source:
15.714 - line = string.strip(line)
15.715 - line = space_rex.sub(' ', line)
15.716 - # ignore comments
15.717 - if not comment_rex.match(line) and line != '':
15.718 - filecont.append(' '+ line)
15.719 -
15.720 - filecont = string.join(filecont, '')
15.721 -
15.722 - # the file is in one long string
15.723 -
15.724 - filecont = no_outer_parens(filecont)
15.725 -
15.726 - #
15.727 - # split lines according to preferred syntax scheme
15.728 - #
15.729 - filecont = re.sub('(=\s*{[^=]*)},', '\g<1>},\n', filecont)
15.730 -
15.731 - # add new lines after commas that are after values
15.732 - filecont = re.sub('"\s*,', '",\n', filecont)
15.733 - filecont = re.sub('=\s*([\w\d]+)\s*,', '= \g<1>,\n', filecont)
15.734 - filecont = re.sub('(@\w*)\s*({(\s*)[^,\s]*)\s*,',
15.735 - '\n\n\g<1>\g<2>,\n', filecont)
15.736 -
15.737 - # add new lines after }
15.738 - filecont = re.sub('"\s*}','"\n}\n', filecont)
15.739 - filecont = re.sub('}\s*,','},\n', filecont)
15.740 -
15.741 -
15.742 - filecont = re.sub('@(\w*)', '\n@\g<1>', filecont)
15.743 -
15.744 - # character encoding, reserved latex characters
15.745 - filecont = re.sub('{\\\&}', '&', filecont)
15.746 - filecont = re.sub('\\\&', '&', filecont)
15.747 -
15.748 - # do checking for open braces to get format correct
15.749 - open_brace_count = 0
15.750 - brace_split = re.split('([{}])',filecont)
15.751 -
15.752 - # rebuild filecont
15.753 - filecont = ''
15.754 -
15.755 - for phrase in brace_split:
15.756 - if phrase == '{':
15.757 - open_brace_count = open_brace_count + 1
15.758 - elif phrase == '}':
15.759 - open_brace_count = open_brace_count - 1
15.760 - if open_brace_count == 0:
15.761 - filecont = filecont + '\n'
15.762 -
15.763 - filecont = filecont + phrase
15.764 -
15.765 - filecont2 = bibtex_replace_abbreviations(filecont)
15.766 -
15.767 - # gather
15.768 - filecont = filecont2.splitlines()
15.769 - i=0
15.770 - j=0 # count the number of blank lines
15.771 - for line in filecont:
15.772 - # ignore blank lines
15.773 - if line == '' or line == ' ':
15.774 - j = j+1
15.775 - continue
15.776 - filecont[i] = line + '\n'
15.777 - i = i+1
15.778 -
15.779 - # get rid of the extra stuff at the end of the array
15.780 - # (The extra stuff are duplicates that are in the array because
15.781 - # blank lines were removed.)
15.782 - length = len( filecont)
15.783 - filecont[length-j:length] = []
15.784 -
15.785 - return filecont
15.786 -
15.787 -
15.788 -def filehandler(filepath):
15.789 - try:
15.790 - fd = open(filepath, 'r')
15.791 - filecont_source = fd.readlines()
15.792 - fd.close()
15.793 - except:
15.794 - print 'Could not open file:', filepath
15.795 - washeddata = bibtexwasher(filecont_source)
15.796 - outdata = bibtexdecoder(washeddata)
15.797 - print '/**'
15.798 - print '\page references References'
15.799 - print
15.800 - for line in outdata:
15.801 - print line
15.802 - print '*/'
15.803 -
15.804 -
15.805 -# main program
15.806 -
15.807 -def main():
15.808 - import sys
15.809 - if sys.argv[1:]:
15.810 - filepath = sys.argv[1]
15.811 - else:
15.812 - print "No input file"
15.813 - sys.exit()
15.814 - filehandler(filepath)
15.815 -
15.816 -if __name__ == "__main__": main()
15.817 -
15.818 -
15.819 -# end python script