0
0
2
| 1 |
%%%%% Defining LEMON %%%%% |
|
| 2 |
|
|
| 3 |
@misc{lemon,
|
|
| 4 |
key = {LEMON},
|
|
| 5 |
title = {{LEMON} -- {L}ibrary for {E}fficient {M}odeling and
|
|
| 6 |
{O}ptimization in {N}etworks},
|
|
| 7 |
howpublished = {\url{http://lemon.cs.elte.hu/}},
|
|
| 8 |
year = 2009 |
|
| 9 |
} |
|
| 10 |
|
|
| 11 |
@misc{egres,
|
|
| 12 |
key = {EGRES},
|
|
| 13 |
title = {{EGRES} -- {E}gerv{\'a}ry {R}esearch {G}roup on
|
|
| 14 |
{C}ombinatorial {O}ptimization},
|
|
| 15 |
howpublished = {\url{http://www.cs.elte.hu/egres/}},
|
|
| 16 |
year = 2009 |
|
| 17 |
} |
|
| 18 |
|
|
| 19 |
@misc{coinor,
|
|
| 20 |
key = {COIN-OR},
|
|
| 21 |
title = {{COIN-OR} -- {C}omputational {I}nfrastructure for
|
|
| 22 |
{O}perations {R}esearch},
|
|
| 23 |
howpublished = {\url{http://www.coin-or.org/}},
|
|
| 24 |
year = 2009 |
|
| 25 |
} |
|
| 26 |
|
|
| 27 |
|
|
| 28 |
%%%%% Other libraries %%%%%% |
|
| 29 |
|
|
| 30 |
@misc{boost,
|
|
| 31 |
key = {Boost},
|
|
| 32 |
title = {{B}oost {C++} {L}ibraries},
|
|
| 33 |
howpublished = {\url{http://www.boost.org/}},
|
|
| 34 |
year = 2009 |
|
| 35 |
} |
|
| 36 |
|
|
| 37 |
@book{bglbook,
|
|
| 38 |
author = {Jeremy G. Siek and Lee-Quan Lee and Andrew
|
|
| 39 |
Lumsdaine}, |
|
| 40 |
title = {The Boost Graph Library: User Guide and Reference
|
|
| 41 |
Manual}, |
|
| 42 |
publisher = {Addison-Wesley},
|
|
| 43 |
year = 2002 |
|
| 44 |
} |
|
| 45 |
|
|
| 46 |
@misc{leda,
|
|
| 47 |
key = {LEDA},
|
|
| 48 |
title = {{LEDA} -- {L}ibrary of {E}fficient {D}ata {T}ypes and
|
|
| 49 |
{A}lgorithms},
|
|
| 50 |
howpublished = {\url{http://www.algorithmic-solutions.com/}},
|
|
| 51 |
year = 2009 |
|
| 52 |
} |
|
| 53 |
|
|
| 54 |
@book{ledabook,
|
|
| 55 |
author = {Kurt Mehlhorn and Stefan N{\"a}her},
|
|
| 56 |
title = {{LEDA}: {A} platform for combinatorial and geometric
|
|
| 57 |
computing}, |
|
| 58 |
isbn = {0-521-56329-1},
|
|
| 59 |
publisher = {Cambridge University Press},
|
|
| 60 |
address = {New York, NY, USA},
|
|
| 61 |
year = 1999 |
|
| 62 |
} |
|
| 63 |
|
|
| 64 |
|
|
| 65 |
%%%%% Tools that LEMON depends on %%%%% |
|
| 66 |
|
|
| 67 |
@misc{cmake,
|
|
| 68 |
key = {CMake},
|
|
| 69 |
title = {{CMake} -- {C}ross {P}latform {M}ake},
|
|
| 70 |
howpublished = {\url{http://www.cmake.org/}},
|
|
| 71 |
year = 2009 |
|
| 72 |
} |
|
| 73 |
|
|
| 74 |
@misc{doxygen,
|
|
| 75 |
key = {Doxygen},
|
|
| 76 |
title = {{Doxygen} -- {S}ource code documentation generator
|
|
| 77 |
tool}, |
|
| 78 |
howpublished = {\url{http://www.doxygen.org/}},
|
|
| 79 |
year = 2009 |
|
| 80 |
} |
|
| 81 |
|
|
| 82 |
|
|
| 83 |
%%%%% LP/MIP libraries %%%%% |
|
| 84 |
|
|
| 85 |
@misc{glpk,
|
|
| 86 |
key = {GLPK},
|
|
| 87 |
title = {{GLPK} -- {GNU} {L}inear {P}rogramming {K}it},
|
|
| 88 |
howpublished = {\url{http://www.gnu.org/software/glpk/}},
|
|
| 89 |
year = 2009 |
|
| 90 |
} |
|
| 91 |
|
|
| 92 |
@misc{clp,
|
|
| 93 |
key = {Clp},
|
|
| 94 |
title = {{Clp} -- {Coin-Or} {L}inear {P}rogramming},
|
|
| 95 |
howpublished = {\url{http://projects.coin-or.org/Clp/}},
|
|
| 96 |
year = 2009 |
|
| 97 |
} |
|
| 98 |
|
|
| 99 |
@misc{cbc,
|
|
| 100 |
key = {Cbc},
|
|
| 101 |
title = {{Cbc} -- {Coin-Or} {B}ranch and {C}ut},
|
|
| 102 |
howpublished = {\url{http://projects.coin-or.org/Cbc/}},
|
|
| 103 |
year = 2009 |
|
| 104 |
} |
|
| 105 |
|
|
| 106 |
@misc{cplex,
|
|
| 107 |
key = {CPLEX},
|
|
| 108 |
title = {{ILOG} {CPLEX}},
|
|
| 109 |
howpublished = {\url{http://www.ilog.com/}},
|
|
| 110 |
year = 2009 |
|
| 111 |
} |
|
| 112 |
|
|
| 113 |
@misc{soplex,
|
|
| 114 |
key = {SoPlex},
|
|
| 115 |
title = {{SoPlex} -- {T}he {S}equential {O}bject-{O}riented
|
|
| 116 |
{S}implex},
|
|
| 117 |
howpublished = {\url{http://soplex.zib.de/}},
|
|
| 118 |
year = 2009 |
|
| 119 |
} |
|
| 120 |
|
|
| 121 |
|
|
| 122 |
%%%%% General books %%%%% |
|
| 123 |
|
|
| 124 |
@book{amo93networkflows,
|
|
| 125 |
author = {Ravindra K. Ahuja and Thomas L. Magnanti and James
|
|
| 126 |
B. Orlin}, |
|
| 127 |
title = {Network Flows: Theory, Algorithms, and Applications},
|
|
| 128 |
publisher = {Prentice-Hall, Inc.},
|
|
| 129 |
year = 1993, |
|
| 130 |
month = feb, |
|
| 131 |
isbn = {978-0136175490}
|
|
| 132 |
} |
|
| 133 |
|
|
| 134 |
@book{schrijver03combinatorial,
|
|
| 135 |
author = {Alexander Schrijver},
|
|
| 136 |
title = {Combinatorial Optimization: Polyhedra and Efficiency},
|
|
| 137 |
publisher = {Springer-Verlag},
|
|
| 138 |
year = 2003, |
|
| 139 |
isbn = {978-3540443896}
|
|
| 140 |
} |
|
| 141 |
|
|
| 142 |
@book{clrs01algorithms,
|
|
| 143 |
author = {Thomas H. Cormen and Charles E. Leiserson and Ronald
|
|
| 144 |
L. Rivest and Clifford Stein}, |
|
| 145 |
title = {Introduction to Algorithms},
|
|
| 146 |
publisher = {The MIT Press},
|
|
| 147 |
year = 2001, |
|
| 148 |
edition = {2nd}
|
|
| 149 |
} |
|
| 150 |
|
|
| 151 |
@book{stroustrup00cpp,
|
|
| 152 |
author = {Bjarne Stroustrup},
|
|
| 153 |
title = {The C++ Programming Language},
|
|
| 154 |
edition = {3rd},
|
|
| 155 |
publisher = {Addison-Wesley Professional},
|
|
| 156 |
isbn = 0201700735, |
|
| 157 |
month = {February},
|
|
| 158 |
year = 2000 |
|
| 159 |
} |
|
| 160 |
|
|
| 161 |
|
|
| 162 |
%%%%% Maximum flow algorithms %%%%% |
|
| 163 |
|
|
| 164 |
@inproceedings{goldberg86newapproach,
|
|
| 165 |
author = {Andrew V. Goldberg and Robert E. Tarjan},
|
|
| 166 |
title = {A new approach to the maximum flow problem},
|
|
| 167 |
booktitle = {STOC '86: Proceedings of the Eighteenth Annual ACM
|
|
| 168 |
Symposium on Theory of Computing}, |
|
| 169 |
year = 1986, |
|
| 170 |
publisher = {ACM Press},
|
|
| 171 |
address = {New York, NY},
|
|
| 172 |
pages = {136-146}
|
|
| 173 |
} |
|
| 174 |
|
|
| 175 |
@article{dinic70algorithm,
|
|
| 176 |
author = {E. A. Dinic},
|
|
| 177 |
title = {Algorithm for solution of a problem of maximum flow
|
|
| 178 |
in a network with power estimation}, |
|
| 179 |
journal = {Soviet Math. Doklady},
|
|
| 180 |
year = 1970, |
|
| 181 |
volume = 11, |
|
| 182 |
pages = {1277-1280}
|
|
| 183 |
} |
|
| 184 |
|
|
| 185 |
@article{goldberg08partial,
|
|
| 186 |
author = {Andrew V. Goldberg},
|
|
| 187 |
title = {The Partial Augment-Relabel Algorithm for the
|
|
| 188 |
Maximum Flow Problem}, |
|
| 189 |
journal = {16th Annual European Symposium on Algorithms},
|
|
| 190 |
year = 2008, |
|
| 191 |
pages = {466-477}
|
|
| 192 |
} |
|
| 193 |
|
|
| 194 |
@article{sleator83dynamic,
|
|
| 195 |
author = {Daniel D. Sleator and Robert E. Tarjan},
|
|
| 196 |
title = {A data structure for dynamic trees},
|
|
| 197 |
journal = {Journal of Computer and System Sciences},
|
|
| 198 |
year = 1983, |
|
| 199 |
volume = 26, |
|
| 200 |
number = 3, |
|
| 201 |
pages = {362-391}
|
|
| 202 |
} |
|
| 203 |
|
|
| 204 |
|
|
| 205 |
%%%%% Minimum mean cycle algorithms %%%%% |
|
| 206 |
|
|
| 207 |
@article{karp78characterization,
|
|
| 208 |
author = {Richard M. Karp},
|
|
| 209 |
title = {A characterization of the minimum cycle mean in a
|
|
| 210 |
digraph}, |
|
| 211 |
journal = {Discrete Math.},
|
|
| 212 |
year = 1978, |
|
| 213 |
volume = 23, |
|
| 214 |
pages = {309-311}
|
|
| 215 |
} |
|
| 216 |
|
|
| 217 |
@article{dasdan98minmeancycle,
|
|
| 218 |
author = {Ali Dasdan and Rajesh K. Gupta},
|
|
| 219 |
title = {Faster Maximum and Minimum Mean Cycle Alogrithms for
|
|
| 220 |
System Performance Analysis}, |
|
| 221 |
journal = {IEEE Transactions on Computer-Aided Design of
|
|
| 222 |
Integrated Circuits and Systems}, |
|
| 223 |
year = 1998, |
|
| 224 |
volume = 17, |
|
| 225 |
number = 10, |
|
| 226 |
pages = {889-899}
|
|
| 227 |
} |
|
| 228 |
|
|
| 229 |
|
|
| 230 |
%%%%% Minimum cost flow algorithms %%%%% |
|
| 231 |
|
|
| 232 |
@article{klein67primal,
|
|
| 233 |
author = {Morton Klein},
|
|
| 234 |
title = {A primal method for minimal cost flows with
|
|
| 235 |
applications to the assignment and transportation |
|
| 236 |
problems}, |
|
| 237 |
journal = {Management Science},
|
|
| 238 |
year = 1967, |
|
| 239 |
volume = 14, |
|
| 240 |
pages = {205-220}
|
|
| 241 |
} |
|
| 242 |
|
|
| 243 |
@inproceedings{goldberg88cyclecanceling,
|
|
| 244 |
author = {Andrew V. Goldberg and Robert E. Tarjan},
|
|
| 245 |
title = {Finding minimum-cost circulations by canceling
|
|
| 246 |
negative cycles}, |
|
| 247 |
booktitle = {STOC '88: Proceedings of the Twentieth Annual ACM
|
|
| 248 |
Symposium on Theory of Computing}, |
|
| 249 |
year = 1988, |
|
| 250 |
publisher = {ACM Press},
|
|
| 251 |
address = {New York, NY},
|
|
| 252 |
pages = {388-397}
|
|
| 253 |
} |
|
| 254 |
|
|
| 255 |
@article{edmondskarp72theoretical,
|
|
| 256 |
author = {Jack Edmonds and Richard M. Karp},
|
|
| 257 |
title = {Theoretical improvements in algorithmic efficiency
|
|
| 258 |
for network flow problems}, |
|
| 259 |
journal = {Journal of the ACM},
|
|
| 260 |
year = 1972, |
|
| 261 |
volume = 19, |
|
| 262 |
number = 2, |
|
| 263 |
pages = {248-264}
|
|
| 264 |
} |
|
| 265 |
|
|
| 266 |
@inproceedings{goldberg87approximation,
|
|
| 267 |
author = {Andrew V. Goldberg and Robert E. Tarjan},
|
|
| 268 |
title = {Solving minimum-cost flow problems by successive
|
|
| 269 |
approximation}, |
|
| 270 |
booktitle = {STOC '87: Proceedings of the Nineteenth Annual ACM
|
|
| 271 |
Symposium on Theory of Computing}, |
|
| 272 |
year = 1987, |
|
| 273 |
publisher = {ACM Press},
|
|
| 274 |
address = {New York, NY},
|
|
| 275 |
pages = {7-18}
|
|
| 276 |
} |
|
| 277 |
|
|
| 278 |
@article{goldberg90finding,
|
|
| 279 |
author = {Andrew V. Goldberg and Robert E. Tarjan},
|
|
| 280 |
title = {Finding Minimum-Cost Circulations by Successive
|
|
| 281 |
Approximation}, |
|
| 282 |
journal = {Mathematics of Operations Research},
|
|
| 283 |
year = 1990, |
|
| 284 |
volume = 15, |
|
| 285 |
number = 3, |
|
| 286 |
pages = {430-466}
|
|
| 287 |
} |
|
| 288 |
|
|
| 289 |
@article{goldberg97efficient,
|
|
| 290 |
author = {Andrew V. Goldberg},
|
|
| 291 |
title = {An Efficient Implementation of a Scaling
|
|
| 292 |
Minimum-Cost Flow Algorithm}, |
|
| 293 |
journal = {Journal of Algorithms},
|
|
| 294 |
year = 1997, |
|
| 295 |
volume = 22, |
|
| 296 |
number = 1, |
|
| 297 |
pages = {1-29}
|
|
| 298 |
} |
|
| 299 |
|
|
| 300 |
@article{bunnagel98efficient,
|
|
| 301 |
author = {Ursula B{\"u}nnagel and Bernhard Korte and Jens
|
|
| 302 |
Vygen}, |
|
| 303 |
title = {Efficient implementation of the {G}oldberg-{T}arjan
|
|
| 304 |
minimum-cost flow algorithm}, |
|
| 305 |
journal = {Optimization Methods and Software},
|
|
| 306 |
year = 1998, |
|
| 307 |
volume = 10, |
|
| 308 |
pages = {157-174}
|
|
| 309 |
} |
|
| 310 |
|
|
| 311 |
@mastersthesis{kellyoneill91netsimplex,
|
|
| 312 |
author = {Damian J. Kelly and Garrett M. O'Neill},
|
|
| 313 |
title = {The Minimum Cost Flow Problem and The Network
|
|
| 314 |
Simplex Method}, |
|
| 315 |
school = {University College},
|
|
| 316 |
address = {Dublin, Ireland},
|
|
| 317 |
year = 1991, |
|
| 318 |
month = sep, |
|
| 319 |
} |
|
| 320 |
|
|
| 321 |
@techreport{lobel96networksimplex,
|
|
| 322 |
author = {Andreas L{\"o}bel},
|
|
| 323 |
title = {Solving large-scale real-world minimum-cost flow
|
|
| 324 |
problems by a network simplex method}, |
|
| 325 |
institution = {Konrad-Zuse-Zentrum fur Informationstechnik Berlin
|
|
| 326 |
({ZIB})},
|
|
| 327 |
address = {Berlin, Germany},
|
|
| 328 |
year = 1996, |
|
| 329 |
number = {SC 96-7}
|
|
| 330 |
} |
|
| 331 |
|
|
| 332 |
@article{frangioni06computational,
|
|
| 333 |
author = {Antonio Frangioni and Antonio Manca},
|
|
| 334 |
title = {A Computational Study of Cost Reoptimization for
|
|
| 335 |
Min-Cost Flow Problems}, |
|
| 336 |
journal = {INFORMS Journal On Computing},
|
|
| 337 |
year = 2006, |
|
| 338 |
volume = 18, |
|
| 339 |
number = 1, |
|
| 340 |
pages = {61-70}
|
|
| 341 |
} |
| 1 |
#!/usr/bin/env /usr/local/Python/bin/python2.1 |
|
| 2 |
""" |
|
| 3 |
BibTeX to Doxygen converter |
|
| 4 |
Usage: python bib2dox.py bibfile.bib > bibfile.dox |
|
| 5 |
|
|
| 6 |
This code is the modification of the BibTeX to XML converter |
|
| 7 |
by Vidar Bronken Gundersen et al. See the original copyright notices below. |
|
| 8 |
|
|
| 9 |
********************************************************************** |
|
| 10 |
|
|
| 11 |
Decoder for bibliographic data, BibTeX |
|
| 12 |
Usage: python bibtex2xml.py bibfile.bib > bibfile.xml |
|
| 13 |
|
|
| 14 |
v.8 |
|
| 15 |
(c)2002-06-23 Vidar Bronken Gundersen |
|
| 16 |
http://bibtexml.sf.net/ |
|
| 17 |
Reuse approved as long as this notification is kept. |
|
| 18 |
Licence: GPL. |
|
| 19 |
|
|
| 20 |
Contributions/thanks to: |
|
| 21 |
Egon Willighagen, http://sf.net/projects/jreferences/ |
|
| 22 |
Richard Mahoney (for providing a test case) |
|
| 23 |
|
|
| 24 |
Editted by Sara Sprenkle to be more robust and handle more bibtex features. |
|
| 25 |
(c) 2003-01-15 |
|
| 26 |
|
|
| 27 |
1. Changed bibtex: tags to bibxml: tags. |
|
| 28 |
2. Use xmlns:bibxml="http://bibtexml.sf.net/" |
|
| 29 |
3. Allow spaces between @type and first {
|
|
| 30 |
4. "author" fields with multiple authors split by " and " |
|
| 31 |
are put in separate xml "bibxml:author" tags. |
|
| 32 |
5. Option for Titles: words are capitalized |
|
| 33 |
only if first letter in title or capitalized inside braces |
|
| 34 |
6. Removes braces from within field values |
|
| 35 |
7. Ignores comments in bibtex file (including @comment{ or % )
|
|
| 36 |
8. Replaces some special latex tags, e.g., replaces ~ with ' ' |
|
| 37 |
9. Handles bibtex @string abbreviations |
|
| 38 |
--> includes bibtex's default abbreviations for months |
|
| 39 |
--> does concatenation of abbr # " more " and " more " # abbr |
|
| 40 |
10. Handles @type( ... ) or @type{ ... }
|
|
| 41 |
11. The keywords field is split on , or ; and put into separate xml |
|
| 42 |
"bibxml:keywords" tags |
|
| 43 |
12. Ignores @preamble |
|
| 44 |
|
|
| 45 |
Known Limitations |
|
| 46 |
1. Does not transform Latex encoding like math mode and special |
|
| 47 |
latex symbols. |
|
| 48 |
2. Does not parse author fields into first and last names. |
|
| 49 |
E.g., It does not do anything special to an author whose name is |
|
| 50 |
in the form LAST_NAME, FIRST_NAME |
|
| 51 |
In "author" tag, will show up as |
|
| 52 |
<bibxml:author>LAST_NAME, FIRST_NAME</bibxml:author> |
|
| 53 |
3. Does not handle "crossref" fields other than to print |
|
| 54 |
<bibxml:crossref>...</bibxml:crossref> |
|
| 55 |
4. Does not inform user of the input's format errors. You just won't |
|
| 56 |
be able to transform the file later with XSL |
|
| 57 |
|
|
| 58 |
You will have to manually edit the XML output if you need to handle |
|
| 59 |
these (and unknown) limitations. |
|
| 60 |
|
|
| 61 |
""" |
|
| 62 |
|
|
| 63 |
import string, re |
|
| 64 |
|
|
| 65 |
# set of valid name characters |
|
| 66 |
valid_name_chars = '[\w\-:]' |
|
| 67 |
|
|
| 68 |
# |
|
| 69 |
# define global regular expression variables |
|
| 70 |
# |
|
| 71 |
author_rex = re.compile('\s+and\s+')
|
|
| 72 |
rembraces_rex = re.compile('[{}]')
|
|
| 73 |
capitalize_rex = re.compile('({\w*})')
|
|
| 74 |
|
|
| 75 |
# used by bibtexkeywords(data) |
|
| 76 |
keywords_rex = re.compile('[,;]')
|
|
| 77 |
|
|
| 78 |
# used by concat_line(line) |
|
| 79 |
concatsplit_rex = re.compile('\s*#\s*')
|
|
| 80 |
|
|
| 81 |
# split on {, }, or " in verify_out_of_braces
|
|
| 82 |
delimiter_rex = re.compile('([{}"])',re.I)
|
|
| 83 |
|
|
| 84 |
field_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
|
|
| 85 |
data_rex = re.compile('\s*(\w*)\s*=\s*([^,]*),?')
|
|
| 86 |
|
|
| 87 |
url_rex = re.compile('\\\url\{([^}]*)\}')
|
|
| 88 |
|
|
| 89 |
|
|
| 90 |
# |
|
| 91 |
# return the string parameter without braces |
|
| 92 |
# |
|
| 93 |
def transformurls(str): |
|
| 94 |
return url_rex.sub(r'<a href="\1">\1</a>', str) |
|
| 95 |
|
|
| 96 |
# |
|
| 97 |
# return the string parameter without braces |
|
| 98 |
# |
|
| 99 |
def removebraces(str): |
|
| 100 |
return rembraces_rex.sub('', str)
|
|
| 101 |
|
|
| 102 |
# |
|
| 103 |
# latex-specific replacements |
|
| 104 |
# (do this after braces were removed) |
|
| 105 |
# |
|
| 106 |
def latexreplacements(line): |
|
| 107 |
line = string.replace(line, '~', ' ') |
|
| 108 |
line = string.replace(line, '\\\'a', 'á') |
|
| 109 |
line = string.replace(line, '\\"a', 'ä') |
|
| 110 |
line = string.replace(line, '\\\'e', 'é') |
|
| 111 |
line = string.replace(line, '\\"e', 'ë') |
|
| 112 |
line = string.replace(line, '\\\'i', 'í') |
|
| 113 |
line = string.replace(line, '\\"i', 'ï') |
|
| 114 |
line = string.replace(line, '\\\'o', 'ó') |
|
| 115 |
line = string.replace(line, '\\"o', 'ö') |
|
| 116 |
line = string.replace(line, '\\\'u', 'ú') |
|
| 117 |
line = string.replace(line, '\\"u', 'ü') |
|
| 118 |
line = string.replace(line, '\\H o', 'õ') |
|
| 119 |
line = string.replace(line, '\\H u', 'ü') # ũ does not exist |
|
| 120 |
line = string.replace(line, '\\\'A', 'Á') |
|
| 121 |
line = string.replace(line, '\\"A', 'Ä') |
|
| 122 |
line = string.replace(line, '\\\'E', 'É') |
|
| 123 |
line = string.replace(line, '\\"E', 'Ë') |
|
| 124 |
line = string.replace(line, '\\\'I', 'Í') |
|
| 125 |
line = string.replace(line, '\\"I', 'Ï') |
|
| 126 |
line = string.replace(line, '\\\'O', 'Ó') |
|
| 127 |
line = string.replace(line, '\\"O', 'Ö') |
|
| 128 |
line = string.replace(line, '\\\'U', 'Ú') |
|
| 129 |
line = string.replace(line, '\\"U', 'Ü') |
|
| 130 |
line = string.replace(line, '\\H O', 'Õ') |
|
| 131 |
line = string.replace(line, '\\H U', 'Ü') # Ũ does not exist |
|
| 132 |
|
|
| 133 |
return line |
|
| 134 |
|
|
| 135 |
# |
|
| 136 |
# copy characters form a string decoding html expressions (&xyz;) |
|
| 137 |
# |
|
| 138 |
def copychars(str, ifrom, count): |
|
| 139 |
result = '' |
|
| 140 |
i = ifrom |
|
| 141 |
c = 0 |
|
| 142 |
html_spec = False |
|
| 143 |
while (i < len(str)) and (c < count): |
|
| 144 |
if str[i] == '&': |
|
| 145 |
html_spec = True; |
|
| 146 |
if i+1 < len(str): |
|
| 147 |
result += str[i+1] |
|
| 148 |
c += 1 |
|
| 149 |
i += 2 |
|
| 150 |
else: |
|
| 151 |
if not html_spec: |
|
| 152 |
if ((str[i] >= 'A') and (str[i] <= 'Z')) or \ |
|
| 153 |
((str[i] >= 'a') and (str[i] <= 'z')): |
|
| 154 |
result += str[i] |
|
| 155 |
c += 1 |
|
| 156 |
elif str[i] == ';': |
|
| 157 |
html_spec = False; |
|
| 158 |
i += 1 |
|
| 159 |
|
|
| 160 |
return result |
|
| 161 |
|
|
| 162 |
|
|
| 163 |
# |
|
| 164 |
# Handle a list of authors (separated by 'and'). |
|
| 165 |
# It gives back an array of the follwing values: |
|
| 166 |
# - num: the number of authors, |
|
| 167 |
# - list: the list of the author names, |
|
| 168 |
# - text: the bibtex text (separated by commas and/or 'and') |
|
| 169 |
# - abbrev: abbreviation that can be used for indicate the |
|
| 170 |
# bibliography entries |
|
| 171 |
# |
|
| 172 |
def bibtexauthor(data): |
|
| 173 |
result = {}
|
|
| 174 |
bibtex = '' |
|
| 175 |
result['list'] = author_rex.split(data) |
|
| 176 |
result['num'] = len(result['list']) |
|
| 177 |
for i, author in enumerate(result['list']): |
|
| 178 |
# general transformations |
|
| 179 |
author = latexreplacements(removebraces(author.strip())) |
|
| 180 |
# transform "Xyz, A. B." to "A. B. Xyz" |
|
| 181 |
pos = author.find(',')
|
|
| 182 |
if pos != -1: |
|
| 183 |
author = author[pos+1:].strip() + ' ' + author[:pos].strip() |
|
| 184 |
result['list'][i] = author |
|
| 185 |
bibtex += author + '#' |
|
| 186 |
bibtex = bibtex[:-1] |
|
| 187 |
if result['num'] > 1: |
|
| 188 |
ix = bibtex.rfind('#')
|
|
| 189 |
if result['num'] == 2: |
|
| 190 |
bibtex = bibtex[:ix] + ' and ' + bibtex[ix+1:] |
|
| 191 |
else: |
|
| 192 |
bibtex = bibtex[:ix] + ', and ' + bibtex[ix+1:] |
|
| 193 |
bibtex = bibtex.replace('#', ', ')
|
|
| 194 |
result['text'] = bibtex |
|
| 195 |
|
|
| 196 |
result['abbrev'] = '' |
|
| 197 |
for author in result['list']: |
|
| 198 |
pos = author.rfind(' ') + 1
|
|
| 199 |
count = 1 |
|
| 200 |
if result['num'] == 1: |
|
| 201 |
count = 3 |
|
| 202 |
result['abbrev'] += copychars(author, pos, count) |
|
| 203 |
|
|
| 204 |
return result |
|
| 205 |
|
|
| 206 |
|
|
| 207 |
# |
|
| 208 |
# data = title string |
|
| 209 |
# @return the capitalized title (first letter is capitalized), rest are capitalized |
|
| 210 |
# only if capitalized inside braces |
|
| 211 |
# |
|
| 212 |
def capitalizetitle(data): |
|
| 213 |
title_list = capitalize_rex.split(data) |
|
| 214 |
title = '' |
|
| 215 |
count = 0 |
|
| 216 |
for phrase in title_list: |
|
| 217 |
check = string.lstrip(phrase) |
|
| 218 |
|
|
| 219 |
# keep phrase's capitalization the same |
|
| 220 |
if check.find('{') == 0:
|
|
| 221 |
title += removebraces(phrase) |
|
| 222 |
else: |
|
| 223 |
# first word --> capitalize first letter (after spaces) |
|
| 224 |
if count == 0: |
|
| 225 |
title += check.capitalize() |
|
| 226 |
else: |
|
| 227 |
title += phrase.lower() |
|
| 228 |
count = count + 1 |
|
| 229 |
|
|
| 230 |
return title |
|
| 231 |
|
|
| 232 |
|
|
| 233 |
# |
|
| 234 |
# @return the bibtex for the title |
|
| 235 |
# @param data --> title string |
|
| 236 |
# braces are removed from title |
|
| 237 |
# |
|
| 238 |
def bibtextitle(data, entrytype): |
|
| 239 |
if entrytype in ('book', 'inbook'):
|
|
| 240 |
title = removebraces(data.strip()) |
|
| 241 |
else: |
|
| 242 |
title = removebraces(capitalizetitle(data.strip())) |
|
| 243 |
bibtex = title |
|
| 244 |
return bibtex |
|
| 245 |
|
|
| 246 |
|
|
| 247 |
# |
|
| 248 |
# function to compare entry lists |
|
| 249 |
# |
|
| 250 |
def entry_cmp(x, y): |
|
| 251 |
return cmp(x[0], y[0]) |
|
| 252 |
|
|
| 253 |
|
|
| 254 |
# |
|
| 255 |
# print the XML for the transformed "filecont_source" |
|
| 256 |
# |
|
| 257 |
def bibtexdecoder(filecont_source): |
|
| 258 |
filecont = [] |
|
| 259 |
file = [] |
|
| 260 |
|
|
| 261 |
# want @<alphanumeric chars><spaces>{<spaces><any chars>,
|
|
| 262 |
pubtype_rex = re.compile('@(\w*)\s*{\s*(.*),')
|
|
| 263 |
endtype_rex = re.compile('}\s*$')
|
|
| 264 |
endtag_rex = re.compile('^\s*}\s*$')
|
|
| 265 |
|
|
| 266 |
bracefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
|
|
| 267 |
bracedata_rex = re.compile('\s*(\w*)\s*=\s*{(.*)},?')
|
|
| 268 |
|
|
| 269 |
quotefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
|
|
| 270 |
quotedata_rex = re.compile('\s*(\w*)\s*=\s*"(.*)",?')
|
|
| 271 |
|
|
| 272 |
for line in filecont_source: |
|
| 273 |
line = line[:-1] |
|
| 274 |
|
|
| 275 |
# encode character entities |
|
| 276 |
line = string.replace(line, '&', '&') |
|
| 277 |
line = string.replace(line, '<', '<') |
|
| 278 |
line = string.replace(line, '>', '>') |
|
| 279 |
|
|
| 280 |
# start entry: publication type (store for later use) |
|
| 281 |
if pubtype_rex.match(line): |
|
| 282 |
# want @<alphanumeric chars><spaces>{<spaces><any chars>,
|
|
| 283 |
entrycont = {}
|
|
| 284 |
entry = [] |
|
| 285 |
entrytype = pubtype_rex.sub('\g<1>',line)
|
|
| 286 |
entrytype = string.lower(entrytype) |
|
| 287 |
# entryid = pubtype_rex.sub('\g<2>', line)
|
|
| 288 |
|
|
| 289 |
# end entry if just a } |
|
| 290 |
elif endtype_rex.match(line): |
|
| 291 |
# generate doxygen code for the entry |
|
| 292 |
|
|
| 293 |
# enty type related formattings |
|
| 294 |
if entrytype in ('book', 'inbook'):
|
|
| 295 |
entrycont['title'] = '<em>' + entrycont['title'] + '</em>' |
|
| 296 |
if not entrycont.has_key('author'):
|
|
| 297 |
entrycont['author'] = entrycont['editor'] |
|
| 298 |
entrycont['author']['text'] += ', editors' |
|
| 299 |
elif entrytype == 'article': |
|
| 300 |
entrycont['journal'] = '<em>' + entrycont['journal'] + '</em>' |
|
| 301 |
elif entrytype in ('inproceedings', 'incollection', 'conference'):
|
|
| 302 |
entrycont['booktitle'] = '<em>' + entrycont['booktitle'] + '</em>' |
|
| 303 |
elif entrytype == 'techreport': |
|
| 304 |
if not entrycont.has_key('type'):
|
|
| 305 |
entrycont['type'] = 'Technical report' |
|
| 306 |
elif entrytype == 'mastersthesis': |
|
| 307 |
entrycont['type'] = 'Master\'s thesis' |
|
| 308 |
elif entrytype == 'phdthesis': |
|
| 309 |
entrycont['type'] = 'PhD thesis' |
|
| 310 |
|
|
| 311 |
for eline in entrycont: |
|
| 312 |
if eline != '': |
|
| 313 |
eline = latexreplacements(eline) |
|
| 314 |
|
|
| 315 |
if entrycont.has_key('pages') and (entrycont['pages'] != ''):
|
|
| 316 |
entrycont['pages'] = string.replace(entrycont['pages'], '--', '-') |
|
| 317 |
|
|
| 318 |
if entrycont.has_key('author') and (entrycont['author'] != ''):
|
|
| 319 |
entry.append(entrycont['author']['text'] + '.') |
|
| 320 |
if entrycont.has_key('title') and (entrycont['title'] != ''):
|
|
| 321 |
entry.append(entrycont['title'] + '.') |
|
| 322 |
if entrycont.has_key('journal') and (entrycont['journal'] != ''):
|
|
| 323 |
entry.append(entrycont['journal'] + ',') |
|
| 324 |
if entrycont.has_key('booktitle') and (entrycont['booktitle'] != ''):
|
|
| 325 |
entry.append('In ' + entrycont['booktitle'] + ',')
|
|
| 326 |
if entrycont.has_key('type') and (entrycont['type'] != ''):
|
|
| 327 |
eline = entrycont['type'] |
|
| 328 |
if entrycont.has_key('number') and (entrycont['number'] != ''):
|
|
| 329 |
eline += ' ' + entrycont['number'] |
|
| 330 |
eline += ',' |
|
| 331 |
entry.append(eline) |
|
| 332 |
if entrycont.has_key('institution') and (entrycont['institution'] != ''):
|
|
| 333 |
entry.append(entrycont['institution'] + ',') |
|
| 334 |
if entrycont.has_key('publisher') and (entrycont['publisher'] != ''):
|
|
| 335 |
entry.append(entrycont['publisher'] + ',') |
|
| 336 |
if entrycont.has_key('school') and (entrycont['school'] != ''):
|
|
| 337 |
entry.append(entrycont['school'] + ',') |
|
| 338 |
if entrycont.has_key('address') and (entrycont['address'] != ''):
|
|
| 339 |
entry.append(entrycont['address'] + ',') |
|
| 340 |
if entrycont.has_key('edition') and (entrycont['edition'] != ''):
|
|
| 341 |
entry.append(entrycont['edition'] + ' edition,') |
|
| 342 |
if entrycont.has_key('howpublished') and (entrycont['howpublished'] != ''):
|
|
| 343 |
entry.append(entrycont['howpublished'] + ',') |
|
| 344 |
if entrycont.has_key('volume') and (entrycont['volume'] != ''):
|
|
| 345 |
eline = entrycont['volume']; |
|
| 346 |
if entrycont.has_key('number') and (entrycont['number'] != ''):
|
|
| 347 |
eline += '(' + entrycont['number'] + ')'
|
|
| 348 |
if entrycont.has_key('pages') and (entrycont['pages'] != ''):
|
|
| 349 |
eline += ':' + entrycont['pages'] |
|
| 350 |
eline += ',' |
|
| 351 |
entry.append(eline) |
|
| 352 |
else: |
|
| 353 |
if entrycont.has_key('pages') and (entrycont['pages'] != ''):
|
|
| 354 |
entry.append('pages ' + entrycont['pages'] + ',')
|
|
| 355 |
if entrycont.has_key('year') and (entrycont['year'] != ''):
|
|
| 356 |
if entrycont.has_key('month') and (entrycont['month'] != ''):
|
|
| 357 |
entry.append(entrycont['month'] + ' ' + entrycont['year'] + '.') |
|
| 358 |
else: |
|
| 359 |
entry.append(entrycont['year'] + '.') |
|
| 360 |
if entrycont.has_key('note') and (entrycont['note'] != ''):
|
|
| 361 |
entry.append(entrycont['note'] + '.') |
|
| 362 |
|
|
| 363 |
# generate keys for sorting and for the output |
|
| 364 |
sortkey = '' |
|
| 365 |
bibkey = '' |
|
| 366 |
if entrycont.has_key('author'):
|
|
| 367 |
for author in entrycont['author']['list']: |
|
| 368 |
sortkey += copychars(author, author.rfind(' ')+1, len(author))
|
|
| 369 |
bibkey = entrycont['author']['abbrev'] |
|
| 370 |
else: |
|
| 371 |
bibkey = 'x' |
|
| 372 |
if entrycont.has_key('year'):
|
|
| 373 |
sortkey += entrycont['year'] |
|
| 374 |
bibkey += entrycont['year'][-2:] |
|
| 375 |
if entrycont.has_key('title'):
|
|
| 376 |
sortkey += entrycont['title'] |
|
| 377 |
if entrycont.has_key('key'):
|
|
| 378 |
sortkey = entrycont['key'] + sortkey |
|
| 379 |
bibkey = entrycont['key'] |
|
| 380 |
entry.insert(0, sortkey) |
|
| 381 |
entry.insert(1, bibkey) |
|
| 382 |
|
|
| 383 |
# add the entry to the file contents |
|
| 384 |
filecont.append(entry) |
|
| 385 |
|
|
| 386 |
else: |
|
| 387 |
# field, publication info |
|
| 388 |
field = '' |
|
| 389 |
data = '' |
|
| 390 |
|
|
| 391 |
# field = {data} entries
|
|
| 392 |
if bracedata_rex.match(line): |
|
| 393 |
field = bracefield_rex.sub('\g<1>', line)
|
|
| 394 |
field = string.lower(field) |
|
| 395 |
data = bracedata_rex.sub('\g<2>', line)
|
|
| 396 |
|
|
| 397 |
# field = "data" entries |
|
| 398 |
elif quotedata_rex.match(line): |
|
| 399 |
field = quotefield_rex.sub('\g<1>', line)
|
|
| 400 |
field = string.lower(field) |
|
| 401 |
data = quotedata_rex.sub('\g<2>', line)
|
|
| 402 |
|
|
| 403 |
# field = data entries |
|
| 404 |
elif data_rex.match(line): |
|
| 405 |
field = field_rex.sub('\g<1>', line)
|
|
| 406 |
field = string.lower(field) |
|
| 407 |
data = data_rex.sub('\g<2>', line)
|
|
| 408 |
|
|
| 409 |
if field in ('author', 'editor'):
|
|
| 410 |
entrycont[field] = bibtexauthor(data) |
|
| 411 |
line = '' |
|
| 412 |
elif field == 'title': |
|
| 413 |
line = bibtextitle(data, entrytype) |
|
| 414 |
elif field != '': |
|
| 415 |
line = removebraces(transformurls(data.strip())) |
|
| 416 |
|
|
| 417 |
if line != '': |
|
| 418 |
line = latexreplacements(line) |
|
| 419 |
entrycont[field] = line |
|
| 420 |
|
|
| 421 |
|
|
| 422 |
# sort entries |
|
| 423 |
filecont.sort(entry_cmp) |
|
| 424 |
|
|
| 425 |
# count the bibtex keys |
|
| 426 |
keytable = {}
|
|
| 427 |
counttable = {}
|
|
| 428 |
for entry in filecont: |
|
| 429 |
bibkey = entry[1] |
|
| 430 |
if not keytable.has_key(bibkey): |
|
| 431 |
keytable[bibkey] = 1 |
|
| 432 |
else: |
|
| 433 |
keytable[bibkey] += 1 |
|
| 434 |
|
|
| 435 |
for bibkey in keytable.keys(): |
|
| 436 |
counttable[bibkey] = 0 |
|
| 437 |
|
|
| 438 |
# generate output |
|
| 439 |
for entry in filecont: |
|
| 440 |
# generate output key form the bibtex key |
|
| 441 |
bibkey = entry[1] |
|
| 442 |
if keytable[bibkey] == 1: |
|
| 443 |
outkey = bibkey |
|
| 444 |
else: |
|
| 445 |
outkey = bibkey + chr(97 + counttable[bibkey]) |
|
| 446 |
counttable[bibkey] += 1 |
|
| 447 |
|
|
| 448 |
# append the entry code to the output |
|
| 449 |
file.append('<tr valign="top">\n' + \
|
|
| 450 |
'<td>[' + outkey + ']</td>') |
|
| 451 |
file.append('<td>')
|
|
| 452 |
file.append('\\anchor ' + outkey)
|
|
| 453 |
for line in entry[2:]: |
|
| 454 |
file.append(line) |
|
| 455 |
file.append('</td>\n</tr>')
|
|
| 456 |
file.append('')
|
|
| 457 |
|
|
| 458 |
return file |
|
| 459 |
|
|
| 460 |
|
|
| 461 |
# |
|
| 462 |
# return 1 iff abbr is in line but not inside braces or quotes |
|
| 463 |
# assumes that abbr appears only once on the line (out of braces and quotes) |
|
| 464 |
# |
|
| 465 |
def verify_out_of_braces(line, abbr): |
|
| 466 |
|
|
| 467 |
phrase_split = delimiter_rex.split(line) |
|
| 468 |
|
|
| 469 |
abbr_rex = re.compile( '\\b' + abbr + '\\b', re.I) |
|
| 470 |
|
|
| 471 |
open_brace = 0 |
|
| 472 |
open_quote = 0 |
|
| 473 |
|
|
| 474 |
for phrase in phrase_split: |
|
| 475 |
if phrase == "{":
|
|
| 476 |
open_brace = open_brace + 1 |
|
| 477 |
elif phrase == "}": |
|
| 478 |
open_brace = open_brace - 1 |
|
| 479 |
elif phrase == '"': |
|
| 480 |
if open_quote == 1: |
|
| 481 |
open_quote = 0 |
|
| 482 |
else: |
|
| 483 |
open_quote = 1 |
|
| 484 |
elif abbr_rex.search(phrase): |
|
| 485 |
if open_brace == 0 and open_quote == 0: |
|
| 486 |
return 1 |
|
| 487 |
|
|
| 488 |
return 0 |
|
| 489 |
|
|
| 490 |
|
|
| 491 |
# |
|
| 492 |
# a line in the form phrase1 # phrase2 # ... # phrasen |
|
| 493 |
# is returned as phrase1 phrase2 ... phrasen |
|
| 494 |
# with the correct punctuation |
|
| 495 |
# Bug: Doesn't always work with multiple abbreviations plugged in |
|
| 496 |
# |
|
| 497 |
def concat_line(line): |
|
| 498 |
# only look at part after equals |
|
| 499 |
field = field_rex.sub('\g<1>',line)
|
|
| 500 |
rest = field_rex.sub('\g<2>',line)
|
|
| 501 |
|
|
| 502 |
concat_line = field + ' =' |
|
| 503 |
|
|
| 504 |
pound_split = concatsplit_rex.split(rest) |
|
| 505 |
|
|
| 506 |
phrase_count = 0 |
|
| 507 |
length = len(pound_split) |
|
| 508 |
|
|
| 509 |
for phrase in pound_split: |
|
| 510 |
phrase = phrase.strip() |
|
| 511 |
if phrase_count != 0: |
|
| 512 |
if phrase.startswith('"') or phrase.startswith('{'):
|
|
| 513 |
phrase = phrase[1:] |
|
| 514 |
elif phrase.startswith('"'):
|
|
| 515 |
phrase = phrase.replace('"','{',1)
|
|
| 516 |
|
|
| 517 |
if phrase_count != length-1: |
|
| 518 |
if phrase.endswith('"') or phrase.endswith('}'):
|
|
| 519 |
phrase = phrase[:-1] |
|
| 520 |
else: |
|
| 521 |
if phrase.endswith('"'):
|
|
| 522 |
phrase = phrase[:-1] |
|
| 523 |
phrase = phrase + "}" |
|
| 524 |
elif phrase.endswith('",'):
|
|
| 525 |
phrase = phrase[:-2] |
|
| 526 |
phrase = phrase + "}," |
|
| 527 |
|
|
| 528 |
# if phrase did have \#, add the \# back |
|
| 529 |
if phrase.endswith('\\'):
|
|
| 530 |
phrase = phrase + "#" |
|
| 531 |
concat_line = concat_line + ' ' + phrase |
|
| 532 |
|
|
| 533 |
phrase_count = phrase_count + 1 |
|
| 534 |
|
|
| 535 |
return concat_line |
|
| 536 |
|
|
| 537 |
|
|
| 538 |
# |
|
| 539 |
# substitute abbreviations into filecont |
|
| 540 |
# @param filecont_source - string of data from file |
|
| 541 |
# |
|
| 542 |
def bibtex_replace_abbreviations(filecont_source): |
|
| 543 |
filecont = filecont_source.splitlines() |
|
| 544 |
|
|
| 545 |
# These are defined in bibtex, so we'll define them too |
|
| 546 |
abbr_list = ['jan','feb','mar','apr','may','jun', |
|
| 547 |
'jul','aug','sep','oct','nov','dec'] |
|
| 548 |
value_list = ['January','February','March','April', |
|
| 549 |
'May','June','July','August','September', |
|
| 550 |
'October','November','December'] |
|
| 551 |
|
|
| 552 |
abbr_rex = [] |
|
| 553 |
total_abbr_count = 0 |
|
| 554 |
|
|
| 555 |
front = '\\b' |
|
| 556 |
back = '(,?)\\b' |
|
| 557 |
|
|
| 558 |
for x in abbr_list: |
|
| 559 |
abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) ) |
|
| 560 |
total_abbr_count = total_abbr_count + 1 |
|
| 561 |
|
|
| 562 |
|
|
| 563 |
abbrdef_rex = re.compile('\s*@string\s*{\s*('+ valid_name_chars +'*)\s*=(.*)',
|
|
| 564 |
re.I) |
|
| 565 |
|
|
| 566 |
comment_rex = re.compile('@comment\s*{',re.I)
|
|
| 567 |
preamble_rex = re.compile('@preamble\s*{',re.I)
|
|
| 568 |
|
|
| 569 |
waiting_for_end_string = 0 |
|
| 570 |
i = 0 |
|
| 571 |
filecont2 = '' |
|
| 572 |
|
|
| 573 |
for line in filecont: |
|
| 574 |
if line == ' ' or line == '': |
|
| 575 |
continue |
|
| 576 |
|
|
| 577 |
if waiting_for_end_string: |
|
| 578 |
if re.search('}',line):
|
|
| 579 |
waiting_for_end_string = 0 |
|
| 580 |
continue |
|
| 581 |
|
|
| 582 |
if abbrdef_rex.search(line): |
|
| 583 |
abbr = abbrdef_rex.sub('\g<1>', line)
|
|
| 584 |
|
|
| 585 |
if abbr_list.count(abbr) == 0: |
|
| 586 |
val = abbrdef_rex.sub('\g<2>', line)
|
|
| 587 |
abbr_list.append(abbr) |
|
| 588 |
value_list.append(string.strip(val)) |
|
| 589 |
abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) ) |
|
| 590 |
total_abbr_count = total_abbr_count + 1 |
|
| 591 |
waiting_for_end_string = 1 |
|
| 592 |
continue |
|
| 593 |
|
|
| 594 |
if comment_rex.search(line): |
|
| 595 |
waiting_for_end_string = 1 |
|
| 596 |
continue |
|
| 597 |
|
|
| 598 |
if preamble_rex.search(line): |
|
| 599 |
waiting_for_end_string = 1 |
|
| 600 |
continue |
|
| 601 |
|
|
| 602 |
|
|
| 603 |
# replace subsequent abbreviations with the value |
|
| 604 |
abbr_count = 0 |
|
| 605 |
|
|
| 606 |
for x in abbr_list: |
|
| 607 |
|
|
| 608 |
if abbr_rex[abbr_count].search(line): |
|
| 609 |
if verify_out_of_braces(line,abbr_list[abbr_count]) == 1: |
|
| 610 |
line = abbr_rex[abbr_count].sub( value_list[abbr_count] + '\g<1>', line) |
|
| 611 |
# Check for # concatenations |
|
| 612 |
if concatsplit_rex.search(line): |
|
| 613 |
line = concat_line(line) |
|
| 614 |
abbr_count = abbr_count + 1 |
|
| 615 |
|
|
| 616 |
|
|
| 617 |
filecont2 = filecont2 + line + '\n' |
|
| 618 |
i = i+1 |
|
| 619 |
|
|
| 620 |
|
|
| 621 |
# Do one final pass over file |
|
| 622 |
|
|
| 623 |
# make sure that didn't end up with {" or }" after the substitution
|
|
| 624 |
filecont2 = filecont2.replace('{"','{{')
|
|
| 625 |
filecont2 = filecont2.replace('"}','}}')
|
|
| 626 |
|
|
| 627 |
afterquotevalue_rex = re.compile('"\s*,\s*')
|
|
| 628 |
afterbrace_rex = re.compile('"\s*}')
|
|
| 629 |
afterbracevalue_rex = re.compile('(=\s*{[^=]*)},\s*')
|
|
| 630 |
|
|
| 631 |
# add new lines to data that changed because of abbreviation substitutions |
|
| 632 |
filecont2 = afterquotevalue_rex.sub('",\n', filecont2)
|
|
| 633 |
filecont2 = afterbrace_rex.sub('"\n}', filecont2)
|
|
| 634 |
filecont2 = afterbracevalue_rex.sub('\g<1>},\n', filecont2)
|
|
| 635 |
|
|
| 636 |
return filecont2 |
|
| 637 |
|
|
| 638 |
# |
|
| 639 |
# convert @type( ... ) to @type{ ... }
|
|
| 640 |
# |
|
| 641 |
def no_outer_parens(filecont): |
|
| 642 |
|
|
| 643 |
# do checking for open parens |
|
| 644 |
# will convert to braces |
|
| 645 |
paren_split = re.split('([(){}])',filecont)
|
|
| 646 |
|
|
| 647 |
open_paren_count = 0 |
|
| 648 |
open_type = 0 |
|
| 649 |
look_next = 0 |
|
| 650 |
|
|
| 651 |
# rebuild filecont |
|
| 652 |
filecont = '' |
|
| 653 |
|
|
| 654 |
at_rex = re.compile('@\w*')
|
|
| 655 |
|
|
| 656 |
for phrase in paren_split: |
|
| 657 |
if look_next == 1: |
|
| 658 |
if phrase == '(':
|
|
| 659 |
phrase = '{'
|
|
| 660 |
open_paren_count = open_paren_count + 1 |
|
| 661 |
else: |
|
| 662 |
open_type = 0 |
|
| 663 |
look_next = 0 |
|
| 664 |
|
|
| 665 |
if phrase == '(':
|
|
| 666 |
open_paren_count = open_paren_count + 1 |
|
| 667 |
|
|
| 668 |
elif phrase == ')': |
|
| 669 |
open_paren_count = open_paren_count - 1 |
|
| 670 |
if open_type == 1 and open_paren_count == 0: |
|
| 671 |
phrase = '}' |
|
| 672 |
open_type = 0 |
|
| 673 |
|
|
| 674 |
elif at_rex.search( phrase ): |
|
| 675 |
open_type = 1 |
|
| 676 |
look_next = 1 |
|
| 677 |
|
|
| 678 |
filecont = filecont + phrase |
|
| 679 |
|
|
| 680 |
return filecont |
|
| 681 |
|
|
| 682 |
|
|
| 683 |
# |
|
| 684 |
# make all whitespace into just one space |
|
| 685 |
# format the bibtex file into a usable form. |
|
| 686 |
# |
|
| 687 |
def bibtexwasher(filecont_source): |
|
| 688 |
|
|
| 689 |
space_rex = re.compile('\s+')
|
|
| 690 |
comment_rex = re.compile('\s*%')
|
|
| 691 |
|
|
| 692 |
filecont = [] |
|
| 693 |
|
|
| 694 |
# remove trailing and excessive whitespace |
|
| 695 |
# ignore comments |
|
| 696 |
for line in filecont_source: |
|
| 697 |
line = string.strip(line) |
|
| 698 |
line = space_rex.sub(' ', line)
|
|
| 699 |
# ignore comments |
|
| 700 |
if not comment_rex.match(line) and line != '': |
|
| 701 |
filecont.append(' '+ line)
|
|
| 702 |
|
|
| 703 |
filecont = string.join(filecont, '') |
|
| 704 |
|
|
| 705 |
# the file is in one long string |
|
| 706 |
|
|
| 707 |
filecont = no_outer_parens(filecont) |
|
| 708 |
|
|
| 709 |
# |
|
| 710 |
# split lines according to preferred syntax scheme |
|
| 711 |
# |
|
| 712 |
filecont = re.sub('(=\s*{[^=]*)},', '\g<1>},\n', filecont)
|
|
| 713 |
|
|
| 714 |
# add new lines after commas that are after values |
|
| 715 |
filecont = re.sub('"\s*,', '",\n', filecont)
|
|
| 716 |
filecont = re.sub('=\s*([\w\d]+)\s*,', '= \g<1>,\n', filecont)
|
|
| 717 |
filecont = re.sub('(@\w*)\s*({(\s*)[^,\s]*)\s*,',
|
|
| 718 |
'\n\n\g<1>\g<2>,\n', filecont) |
|
| 719 |
|
|
| 720 |
# add new lines after } |
|
| 721 |
filecont = re.sub('"\s*}','"\n}\n', filecont)
|
|
| 722 |
filecont = re.sub('}\s*,','},\n', filecont)
|
|
| 723 |
|
|
| 724 |
|
|
| 725 |
filecont = re.sub('@(\w*)', '\n@\g<1>', filecont)
|
|
| 726 |
|
|
| 727 |
# character encoding, reserved latex characters |
|
| 728 |
filecont = re.sub('{\\\&}', '&', filecont)
|
|
| 729 |
filecont = re.sub('\\\&', '&', filecont)
|
|
| 730 |
|
|
| 731 |
# do checking for open braces to get format correct |
|
| 732 |
open_brace_count = 0 |
|
| 733 |
brace_split = re.split('([{}])',filecont)
|
|
| 734 |
|
|
| 735 |
# rebuild filecont |
|
| 736 |
filecont = '' |
|
| 737 |
|
|
| 738 |
for phrase in brace_split: |
|
| 739 |
if phrase == '{':
|
|
| 740 |
open_brace_count = open_brace_count + 1 |
|
| 741 |
elif phrase == '}': |
|
| 742 |
open_brace_count = open_brace_count - 1 |
|
| 743 |
if open_brace_count == 0: |
|
| 744 |
filecont = filecont + '\n' |
|
| 745 |
|
|
| 746 |
filecont = filecont + phrase |
|
| 747 |
|
|
| 748 |
filecont2 = bibtex_replace_abbreviations(filecont) |
|
| 749 |
|
|
| 750 |
# gather |
|
| 751 |
filecont = filecont2.splitlines() |
|
| 752 |
i=0 |
|
| 753 |
j=0 # count the number of blank lines |
|
| 754 |
for line in filecont: |
|
| 755 |
# ignore blank lines |
|
| 756 |
if line == '' or line == ' ': |
|
| 757 |
j = j+1 |
|
| 758 |
continue |
|
| 759 |
filecont[i] = line + '\n' |
|
| 760 |
i = i+1 |
|
| 761 |
|
|
| 762 |
# get rid of the extra stuff at the end of the array |
|
| 763 |
# (The extra stuff are duplicates that are in the array because |
|
| 764 |
# blank lines were removed.) |
|
| 765 |
length = len( filecont) |
|
| 766 |
filecont[length-j:length] = [] |
|
| 767 |
|
|
| 768 |
return filecont |
|
| 769 |
|
|
| 770 |
|
|
| 771 |
def filehandler(filepath): |
|
| 772 |
try: |
|
| 773 |
fd = open(filepath, 'r') |
|
| 774 |
filecont_source = fd.readlines() |
|
| 775 |
fd.close() |
|
| 776 |
except: |
|
| 777 |
print 'Could not open file:', filepath |
|
| 778 |
washeddata = bibtexwasher(filecont_source) |
|
| 779 |
outdata = bibtexdecoder(washeddata) |
|
| 780 |
print '/**' |
|
| 781 |
print '\page references References' |
|
| 782 |
|
|
| 783 |
print '<table border="0" cellspacing="5px" width="100%">' |
|
| 784 |
|
|
| 785 |
for line in outdata: |
|
| 786 |
print line |
|
| 787 |
print '</table>' |
|
| 788 |
|
|
| 789 |
print '*/' |
|
| 790 |
|
|
| 791 |
|
|
| 792 |
# main program |
|
| 793 |
|
|
| 794 |
def main(): |
|
| 795 |
import sys |
|
| 796 |
if sys.argv[1:]: |
|
| 797 |
filepath = sys.argv[1] |
|
| 798 |
else: |
|
| 799 |
print "No input file" |
|
| 800 |
sys.exit() |
|
| 801 |
filehandler(filepath) |
|
| 802 |
|
|
| 803 |
if __name__ == "__main__": main() |
|
| 804 |
|
|
| 805 |
|
|
| 806 |
# end python script |
0 comments (0 inline)