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)
     
          





