0000: 23 23 23 23 23 0a 23 0a 23 20 22 42 69 62 54 65 #####.#.# "BibTe
0010: 58 20 70 61 72 73 65 72 22 0a 23 20 68 74 74 70 X parser".# http
0020: 3a 2f 2f 77 69 6b 69 2e 74 63 6c 2e 74 6b 2f 31 ://wiki.tcl.tk/1
0030: 33 37 31 39 0a 23 0a 23 20 54 63 6c 20 63 6f 64 3719.#.# Tcl cod
0040: 65 20 68 61 72 76 65 73 74 65 64 20 6f 6e 3a 20 e harvested on:
0050: 20 20 37 20 4d 61 72 20 32 30 30 35 2c 20 32 33 7 Mar 2005, 23
0060: 3a 35 35 20 47 4d 54 0a 23 20 57 69 6b 69 20 70 :55 GMT.# Wiki p
0070: 61 67 65 20 6c 61 73 74 20 75 70 64 61 74 65 64 age last updated
0080: 3a 20 3f 3f 3f 0a 23 0a 23 23 23 23 23 0a 0a 23 : ???.#.#####..#
0090: 20 62 69 62 74 65 78 2e 74 63 6c 20 2d 2d 0a 23 bibtex.tcl --.#
00a0: 0a 23 20 20 20 20 20 20 41 20 62 61 73 69 63 20 .# A basic
00b0: 70 61 72 73 65 72 20 66 6f 72 20 42 69 62 54 65 parser for BibTe
00c0: 58 20 62 69 62 6c 69 6f 67 72 61 70 68 79 20 64 X bibliography d
00d0: 61 74 61 62 61 73 65 73 2e 0a 23 0a 23 20 43 6f atabases..#.# Co
00e0: 70 79 72 69 67 68 74 20 28 63 29 20 32 30 30 35 pyright (c) 2005
00f0: 20 4e 65 69 6c 20 4d 61 64 64 65 6e 2e 0a 23 20 Neil Madden..#
0100: 43 6f 70 79 72 69 67 68 74 20 28 63 29 20 32 30 Copyright (c) 20
0110: 30 35 20 41 6e 64 72 65 61 73 20 4b 75 70 72 69 05 Andreas Kupri
0120: 65 73 2e 0a 23 20 4c 69 63 65 6e 73 65 3a 20 54 es..# License: T
0130: 63 6c 2f 42 53 44 20 73 74 79 6c 65 2e 0a 0a 23 cl/BSD style...#
0140: 23 23 20 4e 4f 54 45 53 0a 23 23 23 0a 23 23 23 ## NOTES.###.###
0150: 20 4e 65 65 64 20 63 6f 6d 6d 61 6e 64 73 20 74 Need commands t
0160: 6f 20 69 6e 74 72 6f 73 70 65 63 74 20 70 61 72 o introspect par
0170: 73 65 72 20 73 74 61 74 65 2e 20 45 73 70 65 63 ser state. Espec
0180: 69 61 6c 6c 79 20 74 68 65 20 73 74 72 69 6e 67 ially the string
0190: 0a 23 23 23 20 6d 61 70 20 28 66 6f 72 20 74 65 .### map (for te
01a0: 73 74 69 6e 67 20 6f 66 20 27 61 64 64 53 74 72 sting of 'addStr
01b0: 69 6e 67 73 27 2c 20 73 68 6f 75 6c 64 20 62 65 ings', should be
01c0: 20 75 73 65 66 75 6c 20 69 6e 20 67 65 6e 65 72 useful in gener
01d0: 61 6c 20 61 73 0a 23 23 23 20 77 65 6c 6c 29 2e al as.### well).
01e0: 0a 0a 23 20 23 23 23 20 23 23 23 20 23 23 23 20 ..# ### ### ###
01f0: 23 23 23 23 23 23 23 23 23 20 23 23 23 23 23 23 ######### ######
0200: 23 23 23 20 23 23 23 23 23 23 23 23 23 0a 23 23 ### #########.##
0210: 20 52 65 71 75 69 73 69 74 65 73 0a 0a 70 61 63 Requisites..pac
0220: 6b 61 67 65 20 72 65 71 75 69 72 65 20 54 63 6c kage require Tcl
0230: 20 38 2e 34 0a 70 61 63 6b 61 67 65 20 72 65 71 8.4.package req
0240: 75 69 72 65 20 63 6d 64 6c 69 6e 65 0a 0a 23 20 uire cmdline..#
0250: 23 23 23 20 23 23 23 20 23 23 23 20 23 23 23 23 ### ### ### ####
0260: 23 23 23 23 23 20 23 23 23 23 23 23 23 23 23 20 ##### #########
0270: 23 23 23 23 23 23 23 23 23 0a 23 23 20 49 6d 70 #########.## Imp
0280: 6c 65 6d 65 6e 74 61 74 69 6f 6e 3a 20 50 75 62 lementation: Pub
0290: 6c 69 63 20 41 50 49 0a 0a 6e 61 6d 65 73 70 61 lic API..namespa
02a0: 63 65 20 65 76 61 6c 20 3a 3a 62 69 62 74 65 78 ce eval ::bibtex
02b0: 20 7b 7d 0a 0a 23 20 62 69 62 74 65 78 3a 3a 70 {}..# bibtex::p
02c0: 61 72 73 65 20 2d 2d 0a 23 0a 23 09 50 61 72 73 arse --.#.#.Pars
02d0: 65 20 61 20 62 69 62 74 65 78 20 66 69 6c 65 2e e a bibtex file.
02e0: 0a 23 0a 23 20 70 61 72 73 65 20 3f 6f 70 74 69 .#.# parse ?opti
02f0: 6f 6e 73 3f 20 3f 62 69 62 74 65 78 3f 0a 0a 70 ons? ?bibtex?..p
0300: 72 6f 63 20 3a 3a 62 69 62 74 65 78 3a 3a 70 61 roc ::bibtex::pa
0310: 72 73 65 20 7b 61 72 67 73 7d 20 7b 0a 20 20 20 rse {args} {.
0320: 20 76 61 72 69 61 62 6c 65 20 64 61 74 61 0a 20 variable data.
0330: 20 20 20 76 61 72 69 61 62 6c 65 20 69 64 0a 0a variable id..
0340: 20 20 20 20 23 20 41 72 67 75 6d 65 6e 74 20 70 # Argument p
0350: 72 6f 63 65 73 73 69 6e 67 0a 20 20 20 20 69 66 rocessing. if
0360: 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 73 {[llength $args
0370: 5d 20 3c 20 31 7d 20 7b 0a 09 73 65 74 20 65 72 ] < 1} {..set er
0380: 72 20 22 5b 6c 69 6e 64 65 78 20 5b 69 6e 66 6f r "[lindex [info
0390: 20 6c 65 76 65 6c 20 30 5d 20 30 5d 20 3f 6f 70 level 0] 0] ?op
03a0: 74 69 6f 6e 73 3f 20 3f 62 69 62 74 65 78 3f 22 tions? ?bibtex?"
03b0: 0a 09 72 65 74 75 72 6e 20 2d 63 6f 64 65 20 65 ..return -code e
03c0: 72 72 6f 72 20 22 77 72 6f 6e 67 20 23 20 61 72 rror "wrong # ar
03d0: 67 73 3a 20 73 68 6f 75 6c 64 20 62 65 20 5c 22 gs: should be \"
03e0: 24 65 72 72 5c 22 22 0a 20 20 20 20 7d 0a 0a 20 $err\"". }..
03f0: 20 20 20 61 72 72 61 79 20 73 65 74 20 73 74 61 array set sta
0400: 74 65 20 7b 7d 0a 20 20 20 20 47 65 74 4f 70 74 te {}. GetOpt
0410: 69 6f 6e 73 20 24 61 72 67 73 20 73 74 61 74 65 ions $args state
0420: 0a 0a 20 20 20 20 23 20 49 6e 69 74 69 61 6c 69 .. # Initiali
0430: 7a 65 20 74 68 65 20 70 61 72 73 65 72 20 73 74 ze the parser st
0440: 61 74 65 20 66 72 6f 6d 20 74 68 65 20 6f 70 74 ate from the opt
0450: 69 6f 6e 73 2c 20 66 69 6c 6c 20 69 6e 20 64 65 ions, fill in de
0460: 66 61 75 6c 74 0a 20 20 20 20 23 20 76 61 6c 75 fault. # valu
0470: 65 73 2c 20 61 6e 64 20 68 61 6e 64 6c 65 20 74 es, and handle t
0480: 68 65 20 69 6e 70 75 74 20 61 63 63 6f 72 64 69 he input accordi
0490: 6e 67 20 74 68 65 20 73 70 65 63 69 66 69 65 64 ng the specified
04a0: 20 6d 6f 64 65 2e 0a 0a 20 20 20 20 73 65 74 20 mode... set
04b0: 74 6f 6b 65 6e 20 62 69 62 74 65 78 5b 69 6e 63 token bibtex[inc
04c0: 72 20 69 64 5d 0a 20 20 20 20 66 6f 72 65 61 63 r id]. foreac
04d0: 68 20 7b 6b 20 76 7d 20 5b 61 72 72 61 79 20 67 h {k v} [array g
04e0: 65 74 20 73 74 61 74 65 5d 20 7b 0a 09 73 65 74 et state] {..set
04f0: 20 64 61 74 61 28 24 74 6f 6b 65 6e 2c 24 6b 29 data($token,$k)
0500: 20 24 76 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 $v. }.. i
0510: 66 20 7b 24 73 74 61 74 65 28 73 74 72 65 61 6d f {$state(stream
0520: 29 7d 20 7b 0a 09 23 20 54 65 78 74 20 6e 6f 74 )} {..# Text not
0530: 20 69 6e 20 6d 65 6d 6f 72 79 0a 09 69 66 20 7b in memory..if {
0540: 21 24 73 74 61 74 65 28 62 67 29 7d 20 7b 0a 09 !$state(bg)} {..
0550: 20 20 20 20 23 20 54 65 78 74 20 66 72 6f 6d 20 # Text from
0560: 61 20 63 68 61 6e 6e 65 6c 2c 20 6e 6f 20 61 73 a channel, no as
0570: 79 6e 63 20 70 72 6f 63 65 73 73 69 6e 67 2e 20 ync processing.
0580: 57 65 20 72 65 61 64 20 65 76 65 72 79 74 68 69 We read everythi
0590: 6e 67 0a 09 20 20 20 20 23 20 69 6e 74 6f 20 6d ng.. # into m
05a0: 65 6d 6f 72 79 20 61 6e 64 20 74 68 65 20 68 61 emory and the ha
05b0: 6e 64 6c 65 20 69 74 20 61 73 20 62 65 66 6f 72 ndle it as befor
05c0: 65 2e 0a 0a 09 20 20 20 20 73 65 74 20 62 6c 6f e.... set blo
05d0: 63 6b 6d 6f 64 65 20 5b 66 63 6f 6e 66 69 67 75 ckmode [fconfigu
05e0: 72 65 20 24 73 74 61 74 65 28 2d 63 68 61 6e 6e re $state(-chann
05f0: 65 6c 29 20 2d 62 6c 6f 63 6b 69 6e 67 5d 0a 09 el) -blocking]..
0600: 20 20 20 20 66 63 6f 6e 66 69 67 75 72 65 20 24 fconfigure $
0610: 73 74 61 74 65 28 2d 63 68 61 6e 6e 65 6c 29 20 state(-channel)
0620: 2d 62 6c 6f 63 6b 69 6e 67 20 31 0a 09 20 20 20 -blocking 1..
0630: 20 73 65 74 20 64 61 74 61 28 24 74 6f 6b 65 6e set data($token
0640: 2c 62 75 66 66 65 72 29 20 5b 72 65 61 64 20 24 ,buffer) [read $
0650: 73 74 61 74 65 28 2d 63 68 61 6e 6e 65 6c 29 5d state(-channel)]
0660: 0a 09 20 20 20 20 66 63 6f 6e 66 69 67 75 72 65 .. fconfigure
0670: 20 24 73 74 61 74 65 28 2d 63 68 61 6e 6e 65 6c $state(-channel
0680: 29 20 2d 62 6c 6f 63 6b 69 6e 67 20 24 62 6c 6f ) -blocking $blo
0690: 63 6b 6d 6f 64 65 0a 0a 09 20 20 20 20 23 20 54 ckmode... # T
06a0: 65 6c 6c 20 75 70 63 6f 6d 69 6e 67 20 70 72 6f ell upcoming pro
06b0: 63 65 73 73 69 6e 67 20 74 68 61 74 20 74 68 65 cessing that the
06c0: 20 74 65 78 74 20 69 73 20 69 6e 20 6d 65 6d 6f text is in memo
06d0: 72 79 2e 0a 09 20 20 20 20 73 65 74 20 73 74 61 ry... set sta
06e0: 74 65 28 73 74 72 65 61 6d 29 20 30 0a 09 7d 20 te(stream) 0..}
06f0: 65 6c 73 65 20 7b 0a 09 20 20 20 20 23 20 54 65 else {.. # Te
0700: 78 74 20 66 72 6f 6d 20 61 20 63 68 61 6e 6e 65 xt from a channe
0710: 6c 2c 20 61 6e 64 20 70 72 6f 63 65 73 73 69 6e l, and processin
0720: 67 20 69 73 20 61 73 79 6e 63 2e 20 43 72 65 61 g is async. Crea
0730: 74 65 20 61 6e 0a 09 20 20 20 20 23 20 65 76 65 te an.. # eve
0740: 6e 74 20 68 61 6e 64 6c 65 72 20 66 6f 72 20 74 nt handler for t
0750: 68 65 20 69 6e 63 6f 6d 69 6e 67 20 64 61 74 61 he incoming data
0760: 2e 0a 0a 09 20 20 20 20 73 65 74 20 64 61 74 61 .... set data
0770: 28 24 74 6f 6b 65 6e 2c 64 6f 6e 65 29 20 30 0a ($token,done) 0.
0780: 09 20 20 20 20 66 69 6c 65 65 76 65 6e 74 20 24 . fileevent $
0790: 73 74 61 74 65 28 2d 63 68 61 6e 6e 65 6c 29 20 state(-channel)
07a0: 72 65 61 64 61 62 6c 65 20 5c 0a 09 09 20 20 20 readable \...
07b0: 20 5b 6c 69 73 74 20 3a 3a 62 69 62 74 65 78 3a [list ::bibtex:
07c0: 3a 52 65 61 64 43 68 61 6e 20 24 74 6f 6b 65 6e :ReadChan $token
07d0: 5d 0a 0a 09 20 20 20 20 23 20 49 6e 69 74 69 61 ]... # Initia
07e0: 6c 69 7a 65 20 74 68 65 20 70 61 72 73 65 72 20 lize the parser
07f0: 69 6e 74 65 72 6e 61 6c 20 72 65 73 75 6c 74 20 internal result
0800: 62 75 66 66 65 72 20 69 66 20 77 65 20 75 73 65 buffer if we use
0810: 20 70 6c 61 69 6e 0a 09 20 20 20 20 23 20 2d 63 plain.. # -c
0820: 6f 6d 6d 61 6e 64 2c 20 61 6e 64 20 6e 6f 74 20 ommand, and not
0830: 74 68 65 20 53 41 58 20 61 70 69 2e 0a 09 20 20 the SAX api...
0840: 20 20 69 66 20 7b 21 24 73 74 61 74 65 28 73 61 if {!$state(sa
0850: 78 29 7d 20 7b 0a 09 09 73 65 74 20 64 61 74 61 x)} {...set data
0860: 28 24 74 6f 6b 65 6e 2c 72 65 73 75 6c 74 29 20 ($token,result)
0870: 7b 7d 0a 09 20 20 20 20 7d 0a 09 7d 0a 20 20 20 {}.. }..}.
0880: 20 7d 0a 0a 20 20 20 20 23 20 49 6e 69 74 69 61 }.. # Initia
0890: 6c 69 7a 65 20 74 68 65 20 73 74 72 69 6e 67 20 lize the string
08a0: 6d 61 70 70 69 6e 67 73 20 28 6e 6f 6e 65 20 6b mappings (none k
08b0: 6e 6f 77 6e 29 2c 20 61 6e 64 20 74 68 65 20 72 nown), and the r
08c0: 65 73 75 6c 74 0a 20 20 20 20 23 20 61 63 63 75 esult. # accu
08d0: 6d 75 6c 61 74 6f 72 2e 0a 20 20 20 20 73 65 74 mulator.. set
08e0: 20 64 61 74 61 28 24 74 6f 6b 65 6e 2c 73 74 72 data($token,str
08f0: 69 6e 67 73 29 20 7b 7d 0a 20 20 20 20 73 65 74 ings) {}. set
0900: 20 64 61 74 61 28 24 74 6f 6b 65 6e 2c 72 65 73 data($token,res
0910: 75 6c 74 29 20 20 7b 7d 0a 0a 20 20 20 20 69 66 ult) {}.. if
0920: 20 7b 21 24 73 74 61 74 65 28 73 74 72 65 61 6d {!$state(stream
0930: 29 7d 20 7b 0a 09 50 61 72 73 65 52 65 63 6f 72 )} {..ParseRecor
0940: 64 73 20 24 74 6f 6b 65 6e 20 31 0a 09 69 66 20 ds $token 1..if
0950: 7b 24 73 74 61 74 65 28 73 61 78 29 7d 20 7b 0a {$state(sax)} {.
0960: 09 20 20 20 20 73 65 74 20 72 65 73 75 6c 74 20 . set result
0970: 24 74 6f 6b 65 6e 0a 09 7d 20 65 6c 73 65 20 7b $token..} else {
0980: 0a 09 20 20 20 20 73 65 74 20 72 65 73 75 6c 74 .. set result
0990: 20 24 64 61 74 61 28 24 74 6f 6b 65 6e 2c 72 65 $data($token,re
09a0: 73 75 6c 74 29 0a 09 20 20 20 20 64 65 73 74 72 sult).. destr
09b0: 6f 79 20 24 74 6f 6b 65 6e 0a 09 7d 0a 09 72 65 oy $token..}..re
09c0: 74 75 72 6e 20 24 72 65 73 75 6c 74 0a 20 20 20 turn $result.
09d0: 20 7d 0a 0a 20 20 20 20 23 20 41 73 73 65 72 74 }.. # Assert
09e0: 3a 20 50 72 6f 63 65 73 73 69 6e 67 20 69 73 20 : Processing is
09f0: 69 6e 20 62 61 63 6b 67 72 6f 75 6e 64 2e 0a 20 in background..
0a00: 20 20 20 72 65 74 75 72 6e 20 24 74 6f 6b 65 6e return $token
0a10: 0a 7d 0a 0a 23 20 43 6c 65 61 6e 75 70 20 61 20 .}..# Cleanup a
0a20: 70 61 72 73 65 72 2c 20 63 61 6e 63 65 6c 6c 69 parser, cancelli
0a30: 6e 67 20 61 6e 79 20 63 61 6c 6c 62 61 63 6b 73 ng any callbacks
0a40: 20 65 74 63 2e 0a 0a 70 72 6f 63 20 3a 3a 62 69 etc...proc ::bi
0a50: 62 74 65 78 3a 3a 64 65 73 74 72 6f 79 20 7b 74 btex::destroy {t
0a60: 6f 6b 65 6e 7d 20 7b 0a 20 20 20 20 76 61 72 69 oken} {. vari
0a70: 61 62 6c 65 20 64 61 74 61 0a 0a 20 20 20 20 69 able data.. i
0a80: 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74 73 f {![info exists
0a90: 20 64 61 74 61 28 24 74 6f 6b 65 6e 2c 73 74 72 data($token,str
0aa0: 65 61 6d 29 5d 7d 20 7b 0a 09 72 65 74 75 72 6e eam)]} {..return
0ab0: 20 2d 63 6f 64 65 20 65 72 72 6f 72 20 22 49 6c -code error "Il
0ac0: 6c 65 67 61 6c 20 62 69 62 74 65 78 20 70 61 72 legal bibtex par
0ad0: 73 65 72 20 5c 22 24 74 6f 6b 65 6e 5c 22 22 0a ser \"$token\"".
0ae0: 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b 24 64 }. if {$d
0af0: 61 74 61 28 24 74 6f 6b 65 6e 2c 73 74 72 65 61 ata($token,strea
0b00: 6d 29 7d 20 7b 0a 09 66 69 6c 65 65 76 65 6e 74 m)} {..fileevent
0b10: 20 24 64 61 74 61 28 24 74 6f 6b 65 6e 2c 2d 63 $data($token,-c
0b20: 68 61 6e 6e 65 6c 29 20 72 65 61 64 61 62 6c 65 hannel) readable
0b30: 20 7b 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 61 {}. }.. a
0b40: 72 72 61 79 20 75 6e 73 65 74 20 64 61 74 61 20 rray unset data
0b50: 24 74 6f 6b 65 6e 2c 2a 0a 20 20 20 20 72 65 74 $token,*. ret
0b60: 75 72 6e 0a 7d 0a 0a 0a 70 72 6f 63 20 3a 3a 62 urn.}...proc ::b
0b70: 69 62 74 65 78 3a 3a 77 61 69 74 20 7b 74 6f 6b ibtex::wait {tok
0b80: 65 6e 7d 20 7b 0a 20 20 20 20 76 61 72 69 61 62 en} {. variab
0b90: 6c 65 20 64 61 74 61 0a 0a 20 20 20 20 69 66 20 le data.. if
0ba0: 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 64 {![info exists d
0bb0: 61 74 61 28 24 74 6f 6b 65 6e 2c 73 74 72 65 61 ata($token,strea
0bc0: 6d 29 5d 7d 20 7b 0a 09 72 65 74 75 72 6e 20 2d m)]} {..return -
0bd0: 63 6f 64 65 20 65 72 72 6f 72 20 22 49 6c 6c 65 code error "Ille
0be0: 67 61 6c 20 62 69 62 74 65 78 20 70 61 72 73 65 gal bibtex parse
0bf0: 72 20 5c 22 24 74 6f 6b 65 6e 5c 22 22 0a 20 20 r \"$token\"".
0c00: 20 20 7d 0a 20 20 20 20 76 77 61 69 74 20 3a 3a }. vwait ::
0c10: 62 69 62 74 65 78 3a 3a 64 61 74 61 28 24 74 6f bibtex::data($to
0c20: 6b 65 6e 2c 64 6f 6e 65 29 0a 20 20 20 20 72 65 ken,done). re
0c30: 74 75 72 6e 0a 7d 0a 0a 23 20 62 69 62 74 65 78 turn.}..# bibtex
0c40: 3a 3a 61 64 64 53 74 72 69 6e 67 73 20 2d 2d 0a ::addStrings --.
0c50: 23 0a 23 09 41 64 64 20 73 74 72 69 6e 67 73 20 #.#.Add strings
0c60: 74 6f 20 74 68 65 20 6d 61 70 20 66 6f 72 20 61 to the map for a
0c70: 20 70 61 72 74 69 63 75 6c 61 72 20 70 61 72 73 particular pars
0c80: 65 72 2e 20 41 6c 6c 20 73 74 72 69 6e 67 73 20 er. All strings
0c90: 61 72 65 0a 23 09 65 78 70 61 6e 64 65 64 20 61 are.#.expanded a
0ca0: 74 20 70 61 72 73 65 20 74 69 6d 65 2e 0a 0a 70 t parse time...p
0cb0: 72 6f 63 20 3a 3a 62 69 62 74 65 78 3a 3a 61 64 roc ::bibtex::ad
0cc0: 64 53 74 72 69 6e 67 73 20 7b 74 6f 6b 65 6e 20 dStrings {token
0cd0: 73 74 72 69 6e 67 73 7d 20 7b 0a 20 20 20 20 76 strings} {. v
0ce0: 61 72 69 61 62 6c 65 20 64 61 74 61 0a 20 20 20 ariable data.
0cf0: 20 65 76 61 6c 20 5b 6c 69 6e 73 65 72 74 20 24 eval [linsert $
0d00: 73 74 72 69 6e 67 73 20 30 20 6c 61 70 70 65 6e strings 0 lappen
0d10: 64 20 64 61 74 61 28 24 74 6f 6b 65 6e 2c 73 74 d data($token,st
0d20: 72 69 6e 67 73 29 5d 0a 20 20 20 20 72 65 74 75 rings)]. retu
0d30: 72 6e 0a 7d 0a 0a 23 20 23 23 23 20 23 23 23 20 rn.}..# ### ###
0d40: 23 23 23 20 23 23 23 23 23 23 23 23 23 20 23 23 ### ######### ##
0d50: 23 23 23 23 23 23 23 20 23 23 23 23 23 23 23 23 ####### ########
0d60: 23 0a 23 23 20 49 6d 70 6c 65 6d 65 6e 74 61 74 #.## Implementat
0d70: 69 6f 6e 3a 20 50 72 69 76 61 74 65 20 75 74 69 ion: Private uti
0d80: 6c 69 74 79 20 72 6f 75 74 69 6e 65 73 0a 0a 70 lity routines..p
0d90: 72 6f 63 20 3a 3a 62 69 62 74 65 78 3a 3a 41 64 roc ::bibtex::Ad
0da0: 64 52 65 63 6f 72 64 20 7b 74 6f 6b 65 6e 20 74 dRecord {token t
0db0: 79 70 65 20 6b 65 79 20 72 65 63 64 61 74 61 7d ype key recdata}
0dc0: 20 7b 0a 20 20 20 20 76 61 72 69 61 62 6c 65 20 {. variable
0dd0: 64 61 74 61 0a 20 20 20 20 6c 61 70 70 65 6e 64 data. lappend
0de0: 20 20 64 61 74 61 28 24 74 6f 6b 65 6e 2c 72 65 data($token,re
0df0: 73 75 6c 74 29 20 5b 6c 69 73 74 20 24 74 79 70 sult) [list $typ
0e00: 65 20 24 6b 65 79 20 24 72 65 63 64 61 74 61 5d e $key $recdata]
0e10: 0a 20 20 20 20 72 65 74 75 72 6e 0a 7d 0a 0a 70 . return.}..p
0e20: 72 6f 63 20 3a 3a 62 69 62 74 65 78 3a 3a 47 65 roc ::bibtex::Ge
0e30: 74 4f 70 74 69 6f 6e 73 20 7b 61 72 67 76 20 73 tOptions {argv s
0e40: 74 61 74 65 76 61 72 7d 20 7b 0a 20 20 20 20 75 tatevar} {. u
0e50: 70 76 61 72 20 31 20 24 73 74 61 74 65 76 61 72 pvar 1 $statevar
0e60: 20 73 74 61 74 65 0a 0a 20 20 20 20 23 20 42 61 state.. # Ba
0e70: 73 69 63 20 70 72 6f 63 65 73 73 69 6e 67 20 6f sic processing o
0e80: 66 20 74 68 65 20 61 72 67 75 6d 65 6e 74 20 6c f the argument l
0e90: 69 73 74 0a 20 20 20 20 23 20 61 6e 64 20 74 68 ist. # and th
0ea0: 65 20 6f 70 74 69 6f 6e 73 20 66 6f 75 6e 64 20 e options found
0eb0: 74 68 65 72 65 69 6e 2e 0a 0a 20 20 20 20 73 65 therein... se
0ec0: 74 20 6f 70 74 73 20 5b 6c 72 61 6e 67 65 20 5b t opts [lrange [
0ed0: 3a 3a 63 6d 64 6c 69 6e 65 3a 3a 47 65 74 4f 70 ::cmdline::GetOp
0ee0: 74 69 6f 6e 44 65 66 61 75 6c 74 73 20 7b 0a 09 tionDefaults {..
0ef0: 7b 63 6f 6d 6d 61 6e 64 2e 61 72 67 20 20 20 20 {command.arg
0f00: 20 20 20 20 20 20 20 20 20 20 7b 7d 7d 0a 09 7b {}}..{
0f10: 63 68 61 6e 6e 65 6c 2e 61 72 67 20 20 20 20 20 channel.arg
0f20: 20 20 20 20 20 20 20 20 20 7b 7d 7d 0a 09 7b 72 {}}..{r
0f30: 65 63 6f 72 64 63 6f 6d 6d 61 6e 64 2e 61 72 67 ecordcommand.arg
0f40: 20 20 20 20 20 20 20 20 7b 7d 7d 0a 09 7b 70 72 {}}..{pr
0f50: 65 61 6d 62 6c 65 63 6f 6d 6d 61 6e 64 2e 61 72 eamblecommand.ar
0f60: 67 20 20 20 20 20 20 7b 7d 7d 0a 09 7b 73 74 72 g {}}..{str
0f70: 69 6e 67 63 6f 6d 6d 61 6e 64 2e 61 72 67 20 20 ingcommand.arg
0f80: 20 20 20 20 20 20 7b 7d 7d 0a 09 7b 63 6f 6d 6d {}}..{comm
0f90: 65 6e 74 63 6f 6d 6d 61 6e 64 2e 61 72 67 20 20 entcommand.arg
0fa0: 20 20 20 20 20 7b 7d 7d 0a 09 7b 70 72 6f 67 72 {}}..{progr
0fb0: 65 73 73 63 6f 6d 6d 61 6e 64 2e 61 72 67 20 20 esscommand.arg
0fc0: 20 20 20 20 7b 7d 7d 0a 09 7b 63 61 73 65 73 65 {}}..{casese
0fd0: 6e 73 69 74 69 76 65 73 74 72 69 6e 67 73 2e 61 nsitivestrings.a
0fe0: 72 67 20 7b 7d 7d 0a 20 20 20 20 7d 20 72 65 73 rg {}}. } res
0ff0: 75 6c 74 5d 20 32 20 65 6e 64 5d 20 3b 23 20 52 ult] 2 end] ;# R
1000: 65 6d 6f 76 65 20 3f 20 61 6e 64 20 68 65 6c 70 emove ? and help
1010: 2e 0a 0a 20 20 20 20 73 65 74 20 61 72 67 63 20 ... set argc
1020: 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 76 5d 0a [llength $argv].
1030: 20 20 20 20 77 68 69 6c 65 20 7b 5b 73 65 74 20 while {[set
1040: 65 72 72 20 5b 3a 3a 63 6d 64 6c 69 6e 65 3a 3a err [::cmdline::
1050: 67 65 74 6f 70 74 20 61 72 67 76 20 24 6f 70 74 getopt argv $opt
1060: 73 20 6f 70 74 20 61 72 67 5d 5d 7d 20 7b 0a 09 s opt arg]]} {..
1070: 69 66 20 7b 24 65 72 72 20 3c 20 30 7d 20 7b 0a if {$err < 0} {.
1080: 09 20 20 20 20 73 65 74 20 6f 6c 69 73 74 20 22 . set olist "
1090: 22 0a 09 20 20 20 20 66 6f 72 65 61 63 68 20 6f ".. foreach o
10a0: 20 5b 6c 73 6f 72 74 20 24 6f 70 74 73 5d 20 7b [lsort $opts] {
10b0: 0a 09 09 69 66 20 7b 5b 73 74 72 69 6e 67 20 6d ...if {[string m
10c0: 61 74 63 68 20 2a 2e 61 72 67 20 24 6f 5d 7d 20 atch *.arg $o]}
10d0: 7b 0a 09 09 20 20 20 20 73 65 74 20 6f 20 5b 73 {... set o [s
10e0: 74 72 69 6e 67 20 72 61 6e 67 65 20 24 6f 20 30 tring range $o 0
10f0: 20 65 6e 64 2d 34 5d 0a 09 09 7d 0a 09 09 6c 61 end-4]...}...la
1100: 70 70 65 6e 64 20 6f 6c 69 73 74 20 2d 24 6f 0a ppend olist -$o.
1110: 09 20 20 20 20 7d 0a 09 20 20 20 20 72 65 74 75 . }.. retu
1120: 72 6e 20 2d 63 6f 64 65 20 65 72 72 6f 72 20 22 rn -code error "
1130: 62 61 64 20 6f 70 74 69 6f 6e 20 5c 22 24 6f 70 bad option \"$op
1140: 74 5c 22 2c 5c 0a 09 09 20 20 20 20 73 68 6f 75 t\",\... shou
1150: 6c 64 20 62 65 20 6f 6e 65 20 6f 66 5c 0a 09 09 ld be one of\...
1160: 20 20 20 20 5b 6c 69 6e 73 65 72 74 20 5b 6a 6f [linsert [jo
1170: 69 6e 20 24 6f 6c 69 73 74 20 22 2c 20 22 5d 20 in $olist ", "]
1180: 65 6e 64 2d 31 20 6f 72 5d 22 0a 09 7d 0a 09 73 end-1 or]"..}..s
1190: 65 74 20 73 74 61 74 65 28 2d 24 6f 70 74 29 20 et state(-$opt)
11a0: 24 61 72 67 0a 20 20 20 20 7d 0a 0a 20 20 20 20 $arg. }..
11b0: 23 20 43 68 65 63 6b 20 74 68 65 20 69 6e 66 6f # Check the info
11c0: 72 6d 61 74 69 6f 6e 20 67 61 69 6e 65 64 20 73 rmation gained s
11d0: 6f 20 66 61 72 0a 20 20 20 20 23 20 66 6f 72 20 o far. # for
11e0: 69 6e 63 6f 6e 73 69 73 74 65 6e 63 69 65 73 20 inconsistencies
11f0: 61 6e 64 2f 6f 72 20 6d 69 73 73 69 6e 67 0a 20 and/or missing.
1200: 20 20 20 23 20 70 69 65 63 65 73 2e 0a 0a 20 20 # pieces...
1210: 20 20 73 65 74 20 73 61 78 20 5b 65 78 70 72 20 set sax [expr
1220: 7b 0a 09 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 {..[info exists
1230: 73 74 61 74 65 28 2d 72 65 63 6f 72 64 63 6f 6d state(-recordcom
1240: 6d 61 6e 64 29 5d 20 20 20 7c 7c 0a 09 5b 69 6e mand)] ||..[in
1250: 66 6f 20 65 78 69 73 74 73 20 73 74 61 74 65 28 fo exists state(
1260: 2d 70 72 65 61 6d 62 6c 65 63 6f 6d 6d 61 6e 64 -preamblecommand
1270: 29 5d 20 7c 7c 0a 09 5b 69 6e 66 6f 20 65 78 69 )] ||..[info exi
1280: 73 74 73 20 73 74 61 74 65 28 2d 73 74 72 69 6e sts state(-strin
1290: 67 63 6f 6d 6d 61 6e 64 29 5d 20 20 20 7c 7c 0a gcommand)] ||.
12a0: 09 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 73 74 .[info exists st
12b0: 61 74 65 28 2d 63 6f 6d 6d 65 6e 74 63 6f 6d 6d ate(-commentcomm
12c0: 61 6e 64 29 5d 20 20 7c 7c 0a 09 5b 69 6e 66 6f and)] ||..[info
12d0: 20 65 78 69 73 74 73 20 73 74 61 74 65 28 2d 70 exists state(-p
12e0: 72 6f 67 72 65 73 73 63 6f 6d 6d 61 6e 64 29 5d rogresscommand)]
12f0: 0a 20 20 20 20 7d 5d 20 3b 20 23 20 7b 7d 0a 0a . }] ; # {}..
1300: 20 20 20 20 73 65 74 20 62 67 20 5b 69 6e 66 6f set bg [info
1310: 20 65 78 69 73 74 73 20 73 74 61 74 65 28 2d 63 exists state(-c
1320: 6f 6d 6d 61 6e 64 29 5d 0a 0a 20 20 20 20 69 66 ommand)].. if
1330: 20 7b 24 73 61 78 20 26 26 20 24 62 67 7d 20 7b {$sax && $bg} {
1340: 0a 09 23 20 53 61 78 20 63 61 6c 6c 62 61 63 6b ..# Sax callback
1350: 73 20 61 6e 64 20 63 68 61 6e 6e 65 6c 20 63 6f s and channel co
1360: 6d 70 6c 65 74 69 6f 6e 20 63 61 6c 6c 62 61 63 mpletion callbac
1370: 6b 20 65 78 63 6c 75 64 65 20 65 61 63 68 0a 09 k exclude each..
1380: 23 20 6f 74 68 65 72 2e 0a 09 72 65 74 75 72 6e # other...return
1390: 20 2d 63 6f 64 65 20 65 72 72 6f 72 20 22 54 68 -code error "Th
13a0: 65 20 6f 70 74 69 6f 6e 73 20 2d 63 6f 6d 6d 61 e options -comma
13b0: 6e 64 20 61 6e 64 20 2d 54 59 50 45 63 6f 6d 6d nd and -TYPEcomm
13c0: 61 6e 64 20 65 78 63 6c 75 64 65 20 65 61 63 68 and exclude each
13d0: 20 6f 74 68 65 72 22 0a 20 20 20 20 7d 0a 0a 20 other". }..
13e0: 20 20 20 73 65 74 20 73 74 72 65 61 6d 20 5b 69 set stream [i
13f0: 6e 66 6f 20 65 78 69 73 74 73 20 73 74 61 74 65 nfo exists state
1400: 28 2d 63 68 61 6e 6e 65 6c 29 5d 0a 0a 20 20 20 (-channel)]..
1410: 20 69 66 20 7b 24 73 74 72 65 61 6d 7d 20 7b 0a if {$stream} {.
1420: 09 23 20 43 68 61 6e 6e 65 6c 20 69 73 20 70 72 .# Channel is pr
1430: 65 73 65 6e 74 2c 20 61 20 74 65 78 74 20 69 73 esent, a text is
1440: 20 6e 6f 74 20 61 6c 6c 6f 77 65 64 2e 0a 09 69 not allowed...i
1450: 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 f {[llength $arg
1460: 76 5d 7d 20 7b 0a 09 20 20 20 20 72 65 74 75 72 v]} {.. retur
1470: 6e 20 2d 63 6f 64 65 20 65 72 72 6f 72 20 22 4f n -code error "O
1480: 70 74 69 6f 6e 20 2d 63 68 61 6e 6e 65 6c 20 61 ption -channel a
1490: 6e 64 20 74 65 78 74 20 65 78 63 6c 75 64 65 20 nd text exclude
14a0: 65 61 63 68 20 6f 74 68 65 72 22 0a 09 7d 0a 0a each other"..}..
14b0: 09 23 20 54 68 65 20 63 68 61 6e 6e 65 6c 20 68 .# The channel h
14c0: 61 73 20 74 6f 20 65 78 69 73 74 20 61 73 20 77 as to exist as w
14d0: 65 6c 6c 2e 0a 09 69 66 20 7b 5b 6c 73 65 61 72 ell...if {[lsear
14e0: 63 68 20 2d 65 78 61 63 74 20 5b 66 69 6c 65 20 ch -exact [file
14f0: 63 68 61 6e 6e 65 6c 73 5d 20 24 73 74 61 74 65 channels] $state
1500: 28 2d 63 68 61 6e 6e 65 6c 29 5d 20 3c 20 30 7d (-channel)] < 0}
1510: 20 7b 0a 09 20 20 20 20 72 65 74 75 72 6e 20 2d {.. return -
1520: 63 6f 64 65 20 65 72 72 6f 72 20 22 49 6c 6c 65 code error "Ille
1530: 67 61 6c 20 63 68 61 6e 6e 65 6c 20 68 61 6e 64 gal channel hand
1540: 6c 65 20 5c 22 24 73 74 61 74 65 28 2d 63 68 61 le \"$state(-cha
1550: 6e 6e 65 6c 29 5c 22 22 0a 09 7d 0a 20 20 20 20 nnel)\""..}.
1560: 7d 20 65 6c 73 65 20 7b 0a 09 23 20 43 68 61 6e } else {..# Chan
1570: 6e 65 6c 20 69 73 20 6e 6f 74 20 70 72 65 73 65 nel is not prese
1580: 6e 74 2c 20 77 65 20 68 61 76 65 20 74 6f 20 68 nt, we have to h
1590: 61 76 65 20 61 20 74 65 78 74 2c 20 61 6e 64 20 ave a text, and
15a0: 6f 6e 6c 79 0a 09 23 20 65 78 61 63 74 6c 79 20 only..# exactly
15b0: 6f 6e 65 2e 20 41 6e 64 20 61 20 67 65 6e 65 72 one. And a gener
15c0: 61 6c 20 2d 63 6f 6d 6d 61 6e 64 20 63 61 6c 6c al -command call
15d0: 62 61 63 6b 20 69 73 20 6e 6f 74 20 61 6c 6c 6f back is not allo
15e0: 77 65 64 2e 0a 0a 09 69 66 20 7b 21 5b 6c 6c 65 wed....if {![lle
15f0: 6e 67 74 68 20 24 61 72 67 76 5d 7d 20 7b 0a 09 ngth $argv]} {..
1600: 20 20 20 20 72 65 74 75 72 6e 20 2d 63 6f 64 65 return -code
1610: 20 65 72 72 6f 72 20 22 4e 65 69 74 68 65 72 20 error "Neither
1620: 2d 63 68 61 6e 6e 65 6c 20 6e 6f 72 20 74 65 78 -channel nor tex
1630: 74 20 73 70 65 63 69 66 69 65 64 22 0a 09 7d 20 t specified"..}
1640: 65 6c 73 65 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 elseif {[llength
1650: 20 24 61 72 67 76 5d 20 3e 20 31 7d 20 7b 0a 09 $argv] > 1} {..
1660: 20 20 20 20 72 65 74 75 72 6e 20 2d 63 6f 64 65 return -code
1670: 20 65 72 72 6f 72 20 22 77 72 6f 6e 67 20 23 20 error "wrong #
1680: 61 72 67 73 3a 20 5b 6c 69 6e 64 65 78 20 5b 69 args: [lindex [i
1690: 6e 66 6f 20 6c 65 76 65 6c 20 31 5d 20 30 5d 20 nfo level 1] 0]
16a0: 3f 6f 70 74 69 6f 6e 73 3f 20 3f 62 69 62 74 65 ?options? ?bibte
16b0: 78 3f 22 0a 09 7d 0a 0a 09 23 20 43 68 61 6e 6e x?"..}...# Chann
16c0: 65 6c 20 63 6f 6d 70 6c 65 74 69 6f 6e 20 63 61 el completion ca
16d0: 6c 6c 62 61 63 6b 20 69 73 20 6e 6f 74 20 61 6c llback is not al
16e0: 6c 6f 77 65 64 20 69 66 20 77 65 20 61 72 65 20 lowed if we are
16f0: 6e 6f 74 0a 09 23 20 72 65 61 64 69 6e 67 20 66 not..# reading f
1700: 72 6f 6d 20 61 20 63 68 61 6e 6e 65 6c 2e 0a 0a rom a channel...
1710: 09 69 66 20 7b 24 62 67 7d 20 7b 0a 09 20 20 20 .if {$bg} {..
1720: 20 72 65 74 75 72 6e 20 2d 63 6f 64 65 20 65 72 return -code er
1730: 72 6f 72 20 22 4f 70 74 69 6f 6e 20 2d 63 6f 6d ror "Option -com
1740: 6d 61 6e 64 20 61 6e 64 20 74 65 78 74 20 65 78 mand and text ex
1750: 63 6c 75 64 65 20 65 61 63 68 20 6f 74 68 65 72 clude each other
1760: 22 0a 09 7d 0a 0a 09 73 65 74 20 73 74 61 74 65 "..}...set state
1770: 28 62 75 66 66 65 72 29 20 5b 6c 69 6e 64 65 78 (buffer) [lindex
1780: 20 24 61 72 67 76 20 30 5d 0a 20 20 20 20 7d 0a $argv 0]. }.
1790: 0a 20 20 20 20 73 65 74 20 73 74 61 74 65 28 73 . set state(s
17a0: 74 72 65 61 6d 29 20 24 73 74 72 65 61 6d 0a 20 tream) $stream.
17b0: 20 20 20 73 65 74 20 73 74 61 74 65 28 73 61 78 set state(sax
17c0: 29 20 20 20 20 24 73 61 78 0a 20 20 20 20 73 65 ) $sax. se
17d0: 74 20 73 74 61 74 65 28 62 67 29 20 20 20 20 20 t state(bg)
17e0: 5b 65 78 70 72 20 7b 24 73 61 78 20 7c 7c 20 24 [expr {$sax || $
17f0: 62 67 7d 5d 0a 0a 20 20 20 20 69 66 20 7b 21 5b bg}].. if {![
1800: 69 6e 66 6f 20 65 78 69 73 74 73 20 73 74 61 74 info exists stat
1810: 65 28 2d 73 74 72 69 6e 67 63 6f 6d 6d 61 6e 64 e(-stringcommand
1820: 29 5d 7d 20 7b 0a 09 73 65 74 20 73 74 61 74 65 )]} {..set state
1830: 28 2d 73 74 72 69 6e 67 63 6f 6d 6d 61 6e 64 29 (-stringcommand)
1840: 20 5b 6c 69 73 74 20 3a 3a 62 69 62 74 65 78 3a [list ::bibtex:
1850: 3a 61 64 64 53 74 72 69 6e 67 73 5d 0a 20 20 20 :addStrings].
1860: 20 7d 0a 20 20 20 20 69 66 20 7b 21 5b 69 6e 66 }. if {![inf
1870: 6f 20 65 78 69 73 74 73 20 73 74 61 74 65 28 2d o exists state(-
1880: 72 65 63 6f 72 64 63 6f 6d 6d 61 6e 64 29 5d 20 recordcommand)]
1890: 26 26 20 28 21 24 73 61 78 29 7d 20 7b 0a 09 73 && (!$sax)} {..s
18a0: 65 74 20 73 74 61 74 65 28 2d 72 65 63 6f 72 64 et state(-record
18b0: 63 6f 6d 6d 61 6e 64 29 20 5b 6c 69 73 74 20 3a command) [list :
18c0: 3a 62 69 62 74 65 78 3a 3a 41 64 64 52 65 63 6f :bibtex::AddReco
18d0: 72 64 5d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 rd]. }. if
18e0: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 73 {[info exists s
18f0: 74 61 74 65 28 2d 63 61 73 65 73 65 6e 73 69 74 tate(-casesensit
1900: 69 76 65 73 74 72 69 6e 67 73 29 5d 20 26 26 0a ivestrings)] &&.
1910: 09 24 73 74 61 74 65 28 2d 63 61 73 65 73 65 6e .$state(-casesen
1920: 73 69 74 69 76 65 73 74 72 69 6e 67 73 29 0a 20 sitivestrings).
1930: 20 20 20 7d 20 7b 0a 09 73 65 74 20 73 74 61 74 } {..set stat
1940: 65 28 63 61 73 65 73 65 6e 73 69 74 69 76 65 73 e(casesensitives
1950: 74 72 69 6e 67 73 29 20 31 0a 20 20 20 20 7d 20 trings) 1. }
1960: 65 6c 73 65 20 7b 0a 09 73 65 74 20 73 74 61 74 else {..set stat
1970: 65 28 63 61 73 65 73 65 6e 73 69 74 69 76 65 73 e(casesensitives
1980: 74 72 69 6e 67 73 29 20 30 0a 20 20 20 20 7d 0a trings) 0. }.
1990: 20 20 20 20 72 65 74 75 72 6e 0a 7d 0a 0a 70 72 return.}..pr
19a0: 6f 63 20 3a 3a 62 69 62 74 65 78 3a 3a 43 61 6c oc ::bibtex::Cal
19b0: 6c 62 61 63 6b 20 7b 74 6f 6b 65 6e 20 74 79 70 lback {token typ
19c0: 65 20 61 72 67 73 7d 20 7b 0a 20 20 20 20 76 61 e args} {. va
19d0: 72 69 61 62 6c 65 20 64 61 74 61 0a 0a 20 20 20 riable data..
19e0: 20 23 70 75 74 73 20 73 74 64 6f 75 74 20 22 43 #puts stdout "C
19f0: 61 6c 6c 62 61 63 6b 20 28 24 74 6f 6b 65 6e 20 allback ($token
1a00: 24 74 79 70 65 20 28 24 61 72 67 73 29 29 22 0a $type ($args))".
1a10: 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 . if {[info e
1a20: 78 69 73 74 73 20 64 61 74 61 28 24 74 6f 6b 65 xists data($toke
1a30: 6e 2c 2d 24 7b 74 79 70 65 7d 63 6f 6d 6d 61 6e n,-${type}comman
1a40: 64 29 5d 7d 20 7b 0a 09 65 76 61 6c 20 24 64 61 d)]} {..eval $da
1a50: 74 61 28 24 74 6f 6b 65 6e 2c 2d 24 7b 74 79 70 ta($token,-${typ
1a60: 65 7d 63 6f 6d 6d 61 6e 64 29 20 5b 6c 69 6e 73 e}command) [lins
1a70: 65 72 74 20 24 61 72 67 73 20 30 20 24 74 6f 6b ert $args 0 $tok
1a80: 65 6e 5d 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 en]. }. re
1a90: 74 75 72 6e 0a 7d 0a 0a 70 72 6f 63 20 3a 3a 62 turn.}..proc ::b
1aa0: 69 62 74 65 78 3a 3a 52 65 61 64 43 68 61 6e 20 ibtex::ReadChan
1ab0: 7b 74 6f 6b 65 6e 7d 20 7b 0a 20 20 20 20 76 61 {token} {. va
1ac0: 72 69 61 62 6c 65 20 64 61 74 61 0a 0a 20 20 20 riable data..
1ad0: 20 23 20 52 65 61 64 20 74 68 65 20 77 61 69 74 # Read the wait
1ae0: 69 6e 67 20 63 68 61 72 61 63 74 65 72 73 20 69 ing characters i
1af0: 6e 74 6f 20 6f 75 72 20 62 75 66 66 65 72 20 61 nto our buffer a
1b00: 6e 64 20 70 72 6f 63 65 73 73 0a 20 20 20 20 23 nd process. #
1b10: 20 74 68 65 6d 2e 20 54 68 65 20 72 65 63 6f 72 them. The recor
1b20: 64 73 20 61 72 65 20 73 61 76 65 64 20 65 69 74 ds are saved eit
1b30: 68 65 72 20 74 68 72 6f 75 67 68 20 61 20 75 73 her through a us
1b40: 65 72 20 73 75 70 70 6c 69 65 64 0a 20 20 20 20 er supplied.
1b50: 23 20 72 65 63 6f 72 64 20 63 61 6c 6c 62 61 63 # record callbac
1b60: 6b 2c 20 6f 72 20 74 68 65 20 73 74 61 6e 64 61 k, or the standa
1b70: 72 64 20 63 61 6c 6c 62 61 63 6b 20 66 6f 72 20 rd callback for
1b80: 6f 75 72 20 6e 6f 6e 2d 73 61 78 0a 20 20 20 20 our non-sax.
1b90: 23 20 70 72 6f 63 65 73 73 69 6e 67 2e 0a 0a 20 # processing...
1ba0: 20 20 20 73 65 74 20 20 20 20 63 68 61 6e 20 24 set chan $
1bb0: 64 61 74 61 28 24 74 6f 6b 65 6e 2c 2d 63 68 61 data($token,-cha
1bc0: 6e 6e 65 6c 29 0a 20 20 20 20 61 70 70 65 6e 64 nnel). append
1bd0: 20 64 61 74 61 28 24 74 6f 6b 65 6e 2c 62 75 66 data($token,buf
1be0: 66 65 72 29 20 5b 72 65 61 64 20 24 63 68 61 6e fer) [read $chan
1bf0: 5d 0a 0a 20 20 20 20 69 66 20 7b 5b 65 6f 66 20 ].. if {[eof
1c00: 24 63 68 61 6e 5d 7d 20 7b 0a 09 23 20 46 69 6e $chan]} {..# Fin
1c10: 61 6c 20 70 72 6f 63 65 73 73 69 6e 67 2e 20 49 al processing. I
1c20: 6e 20 6e 6f 6e 2d 53 41 58 20 6d 6f 64 65 20 77 n non-SAX mode w
1c30: 65 20 68 61 76 65 20 74 6f 20 64 65 6c 69 76 65 e have to delive
1c40: 72 20 74 68 65 0a 09 23 20 63 6f 6d 70 6c 65 74 r the..# complet
1c50: 65 64 20 72 65 73 75 6c 74 20 62 65 66 6f 72 65 ed result before
1c60: 20 64 65 73 74 72 6f 79 69 6e 67 20 74 68 65 20 destroying the
1c70: 70 61 72 73 65 72 2e 0a 0a 09 50 61 72 73 65 52 parser....ParseR
1c80: 65 63 6f 72 64 73 20 24 74 6f 6b 65 6e 20 31 0a ecords $token 1.
1c90: 09 73 65 74 20 64 61 74 61 28 24 74 6f 6b 65 6e .set data($token
1ca0: 2c 64 6f 6e 65 29 20 31 0a 09 69 66 20 7b 21 24 ,done) 1..if {!$
1cb0: 64 61 74 61 28 24 74 6f 6b 65 6e 2c 73 61 78 29 data($token,sax)
1cc0: 7d 20 7b 0a 09 20 20 20 20 43 61 6c 6c 62 61 63 } {.. Callbac
1cd0: 6b 20 24 74 6f 6b 65 6e 20 7b 7d 20 24 64 61 74 k $token {} $dat
1ce0: 61 28 24 74 6f 6b 65 6e 2c 72 65 73 75 6c 74 29 a($token,result)
1cf0: 0a 09 7d 0a 09 72 65 74 75 72 6e 0a 20 20 20 20 ..}..return.
1d00: 7d 0a 0a 20 20 20 20 23 20 50 72 6f 63 65 73 73 }.. # Process
1d10: 69 6e 67 20 6f 66 20 70 61 72 74 69 61 6c 20 64 ing of partial d
1d20: 61 74 61 2e 0a 0a 20 20 20 20 50 61 72 73 65 52 ata... ParseR
1d30: 65 63 6f 72 64 73 20 24 74 6f 6b 65 6e 20 30 0a ecords $token 0.
1d40: 20 20 20 20 72 65 74 75 72 6e 0a 7d 0a 0a 70 72 return.}..pr
1d50: 6f 63 20 3a 3a 62 69 62 74 65 78 3a 3a 54 69 64 oc ::bibtex::Tid
1d60: 79 20 7b 73 74 72 7d 20 7b 0a 20 20 20 20 72 65 y {str} {. re
1d70: 74 75 72 6e 20 5b 73 74 72 69 6e 67 20 74 6f 6c turn [string tol
1d80: 6f 77 65 72 20 5b 73 74 72 69 6e 67 20 74 72 69 ower [string tri
1d90: 6d 20 24 73 74 72 5d 5d 0a 7d 0a 0a 70 72 6f 63 m $str]].}..proc
1da0: 20 3a 3a 62 69 62 74 65 78 3a 3a 50 61 72 73 65 ::bibtex::Parse
1db0: 52 65 63 6f 72 64 73 20 7b 74 6f 6b 65 6e 20 65 Records {token e
1dc0: 6f 66 7d 20 7b 0a 20 20 20 20 23 20 41 20 72 6f of} {. # A ro
1dd0: 75 67 68 20 42 69 62 54 65 58 20 67 72 61 6d 6d ugh BibTeX gramm
1de0: 61 72 20 28 63 61 73 65 2d 69 6e 73 65 6e 73 69 ar (case-insensi
1df0: 74 69 76 65 29 3a 0a 20 20 20 20 23 0a 20 20 20 tive):. #.
1e00: 20 23 20 44 61 74 61 62 61 73 65 20 20 20 20 20 # Database
1e10: 20 3a 3a 3d 20 28 4a 75 6e 6b 20 27 40 27 20 45 ::= (Junk '@' E
1e20: 6e 74 72 79 29 2a 0a 20 20 20 20 23 20 4a 75 6e ntry)*. # Jun
1e30: 6b 20 20 20 20 20 20 20 20 20 20 3a 3a 3d 20 2e k ::= .
1e40: 2a 3f 0a 20 20 20 20 23 20 45 6e 74 72 79 20 20 *?. # Entry
1e50: 20 20 20 20 20 20 20 3a 3a 3d 20 52 65 63 6f 72 ::= Recor
1e60: 64 0a 20 20 20 20 23 20 20 20 20 20 20 20 20 20 d. #
1e70: 20 20 20 20 20 20 7c 20 20 20 43 6f 6d 6d 65 6e | Commen
1e80: 74 0a 20 20 20 20 23 20 20 20 20 20 20 20 20 20 t. #
1e90: 20 20 20 20 20 20 7c 20 20 20 53 74 72 69 6e 67 | String
1ea0: 0a 20 20 20 20 23 20 20 20 20 20 20 20 20 20 20 . #
1eb0: 20 20 20 20 20 7c 20 20 20 50 72 65 61 6d 62 6c | Preambl
1ec0: 65 0a 20 20 20 20 23 20 43 6f 6d 6d 65 6e 74 20 e. # Comment
1ed0: 20 20 20 20 20 20 3a 3a 3d 20 22 63 6f 6d 6d 65 ::= "comme
1ee0: 6e 74 22 20 5b 5e 5c 6e 5d 2a 20 5c 6e 20 20 20 nt" [^\n]* \n
1ef0: 20 20 20 20 20 20 2d 2d 20 69 67 6e 6f 72 65 64 -- ignored
1f00: 0a 20 20 20 20 23 20 53 74 72 69 6e 67 20 20 20 . # String
1f10: 20 20 20 20 20 3a 3a 3d 20 22 73 74 72 69 6e 67 ::= "string
1f20: 22 20 27 7b 27 20 46 69 65 6c 64 2a 20 27 7d 27 " '{' Field* '}'
1f30: 0a 20 20 20 20 23 20 50 72 65 61 6d 62 6c 65 20 . # Preamble
1f40: 20 20 20 20 20 3a 3a 3d 20 22 70 72 65 61 6d 62 ::= "preamb
1f50: 6c 65 22 20 27 7b 27 20 2e 2a 20 27 7d 27 20 20 le" '{' .* '}'
1f60: 20 20 20 20 20 2d 2d 20 28 62 61 6c 61 6e 63 65 -- (balance
1f70: 64 29 0a 20 20 20 20 23 20 52 65 63 6f 72 64 20 d). # Record
1f80: 20 20 20 20 20 20 20 3a 3a 3d 20 54 79 70 65 20 ::= Type
1f90: 27 7b 27 20 4b 65 79 20 27 2c 27 20 46 69 65 6c '{' Key ',' Fiel
1fa0: 64 2a 20 27 7d 27 0a 20 20 20 20 23 20 20 20 20 d* '}'. #
1fb0: 20 20 20 20 20 20 20 20 20 20 20 7c 20 20 20 54 | T
1fc0: 79 70 65 20 27 28 27 20 4b 65 79 20 27 2c 27 20 ype '(' Key ','
1fd0: 46 69 65 6c 64 2a 20 27 29 27 20 2d 2d 20 6e 6f Field* ')' -- no
1fe0: 74 20 68 61 6e 64 6c 65 64 0a 20 20 20 20 23 20 t handled. #
1ff0: 54 79 70 65 20 20 20 20 20 20 20 20 20 20 3a 3a Type ::
2000: 3d 20 4e 61 6d 65 0a 20 20 20 20 23 20 4b 65 79 = Name. # Key
2010: 20 20 20 20 20 20 20 20 20 20 20 3a 3a 3d 20 4e ::= N
2020: 61 6d 65 0a 20 20 20 20 23 20 46 69 65 6c 64 20 ame. # Field
2030: 20 20 20 20 20 20 20 20 3a 3a 3d 20 4e 61 6d 65 ::= Name
2040: 20 27 3d 27 20 56 61 6c 75 65 0a 20 20 20 20 23 '=' Value. #
2050: 20 4e 61 6d 65 20 20 20 20 20 20 20 20 20 20 3a Name :
2060: 3a 3d 20 5b 5e 5c 73 5c 22 23 25 27 28 29 7b 7d := [^\s\"#%'(){}
2070: 5d 2a 0a 20 20 20 20 23 20 56 61 6c 75 65 20 20 ]*. # Value
2080: 20 20 20 20 20 20 20 3a 3a 3d 20 5b 30 2d 39 5d ::= [0-9]
2090: 2b 0a 20 20 20 20 23 20 20 20 20 20 20 20 20 20 +. #
20a0: 20 20 20 20 20 20 7c 20 20 20 27 22 27 20 28 5b | '"' ([
20b0: 5e 27 22 27 5d 7c 5c 5c 27 22 27 29 2a 20 27 22 ^'"']|\\'"')* '"
20c0: 27 0a 20 20 20 20 23 20 20 20 20 20 20 20 20 20 '. #
20d0: 20 20 20 20 20 20 7c 20 20 20 27 7b 27 20 2e 2a | '{' .*
20e0: 20 27 7d 27 20 20 20 20 20 20 20 20 20 20 20 20 '}'
20f0: 20 20 20 20 20 20 2d 2d 20 28 62 61 6c 61 6e 63 -- (balanc
2100: 65 64 29 0a 0a 20 20 20 20 23 20 22 20 2d 20 46 ed).. # " - F
2110: 69 78 75 70 20 65 6d 61 63 73 20 68 69 6c 69 74 ixup emacs hilit
2120: 20 63 6f 6e 66 75 73 69 6f 6e 20 66 72 6f 6d 20 confusion from
2130: 74 68 65 20 67 72 61 6d 6d 61 72 20 61 62 6f 76 the grammar abov
2140: 65 2e 0a 20 20 20 20 76 61 72 69 61 62 6c 65 20 e.. variable
2150: 64 61 74 61 0a 20 20 20 20 73 65 74 20 62 69 62 data. set bib
2160: 74 65 78 20 24 64 61 74 61 28 24 74 6f 6b 65 6e tex $data($token
2170: 2c 62 75 66 66 65 72 29 0a 0a 20 20 20 20 23 20 ,buffer).. #
2180: 53 70 6c 69 74 20 61 74 20 65 61 63 68 20 40 20 Split at each @
2190: 63 68 61 72 61 63 74 65 72 20 77 68 69 63 68 20 character which
21a0: 69 73 20 61 74 20 74 68 65 20 62 65 67 69 6e 6e is at the beginn
21b0: 69 6e 67 20 6f 66 20 61 20 6c 69 6e 65 2c 0a 20 ing of a line,.
21c0: 20 20 20 23 20 6d 6f 64 75 6c 6f 20 77 68 69 74 # modulo whit
21d0: 65 73 70 61 63 65 2e 20 54 68 69 73 20 69 73 20 espace. This is
21e0: 61 20 68 65 75 72 69 73 74 69 63 20 74 6f 20 64 a heuristic to d
21f0: 69 73 74 69 6e 67 75 69 73 68 20 74 68 65 20 40 istinguish the @
2200: 27 73 0a 20 20 20 20 23 20 73 74 61 72 74 69 6e 's. # startin
2210: 67 20 61 20 6e 65 77 20 72 65 63 6f 72 64 20 66 g a new record f
2220: 72 6f 6d 20 74 68 65 20 40 27 73 20 6f 63 63 75 rom the @'s occu
2230: 72 69 6e 67 20 69 6e 73 69 64 65 20 61 20 72 65 ring inside a re
2240: 63 6f 72 64 2c 20 61 73 0a 20 20 20 20 23 20 70 cord, as. # p
2250: 61 72 74 20 6f 66 20 65 6d 61 69 6c 20 61 64 64 art of email add
2260: 72 65 73 73 65 73 2e 20 45 6d 70 74 79 20 70 69 resses. Empty pi
2270: 63 65 73 20 61 74 20 62 65 67 69 6e 6e 69 6e 67 ces at beginning
2280: 20 6f 72 20 65 6e 64 20 61 72 65 0a 20 20 20 20 or end are.
2290: 23 20 73 74 72 69 70 70 65 64 20 62 65 66 6f 72 # stripped befor
22a0: 65 20 74 68 65 20 73 70 6c 69 74 2e 0a 0a 20 20 e the split...
22b0: 20 20 72 65 67 73 75 62 20 2d 6c 69 6e 65 20 2d regsub -line -
22c0: 61 6c 6c 20 7b 5e 5b 5c 6e 5c 72 5c 66 5c 74 20 all {^[\n\r\f\t
22d0: 5d 2a 40 7d 20 24 62 69 62 74 65 78 20 5c 30 30 ]*@} $bibtex \00
22e0: 30 20 62 69 62 74 65 78 0a 20 20 20 20 73 65 74 0 bibtex. set
22f0: 20 64 62 20 5b 73 70 6c 69 74 20 5b 73 74 72 69 db [split [stri
2300: 6e 67 20 74 72 69 6d 20 24 62 69 62 74 65 78 20 ng trim $bibtex
2310: 5c 30 30 30 5d 20 5c 30 30 30 5d 0a 0a 20 20 20 \000] \000]..
2320: 20 69 66 20 7b 24 65 6f 66 7d 20 7b 0a 09 73 65 if {$eof} {..se
2330: 74 20 74 6f 74 61 6c 20 5b 6c 6c 65 6e 67 74 68 t total [llength
2340: 20 24 64 62 5d 0a 09 73 65 74 20 73 74 65 70 20 $db]..set step
2350: 20 5b 65 78 70 72 20 7b 64 6f 75 62 6c 65 28 24 [expr {double($
2360: 74 6f 74 61 6c 29 20 2f 20 31 30 30 2e 30 7d 5d total) / 100.0}]
2370: 0a 09 73 65 74 20 69 73 74 65 70 20 5b 65 78 70 ..set istep [exp
2380: 72 20 7b 24 73 74 65 70 20 3e 20 31 20 3f 20 69 r {$step > 1 ? i
2390: 6e 74 28 24 73 74 65 70 29 20 3a 20 31 7d 5d 0a nt($step) : 1}].
23a0: 09 73 65 74 20 63 6f 75 6e 74 20 30 0a 20 20 20 .set count 0.
23b0: 20 7d 20 65 6c 73 65 20 7b 0a 09 69 66 20 7b 5b } else {..if {[
23c0: 6c 6c 65 6e 67 74 68 20 24 64 62 5d 20 3c 20 32 llength $db] < 2
23d0: 7d 20 7b 0a 09 20 20 20 20 23 20 4e 6f 74 68 69 } {.. # Nothi
23e0: 6e 67 20 74 6f 20 70 72 6f 63 65 73 73 2c 20 6f ng to process, o
23f0: 72 20 64 61 74 61 20 77 68 69 63 68 20 61 79 20 r data which ay
2400: 62 65 20 69 6e 63 6f 6d 70 6c 65 74 65 2e 0a 09 be incomplete...
2410: 20 20 20 20 72 65 74 75 72 6e 0a 09 7d 0a 0a 09 return..}...
2420: 73 65 74 20 64 61 74 61 28 24 74 6f 6b 65 6e 2c set data($token,
2430: 62 75 66 66 65 72 29 20 5b 6c 69 6e 64 65 78 20 buffer) [lindex
2440: 24 64 62 20 65 6e 64 5d 0a 09 73 65 74 20 64 62 $db end]..set db
2450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
2460: 20 20 5b 6c 72 61 6e 67 65 20 24 64 62 20 30 20 [lrange $db 0
2470: 65 6e 64 2d 31 5d 0a 0a 09 23 20 46 61 6b 65 20 end-1]...# Fake
2480: 70 72 6f 67 72 65 73 73 20 6d 65 74 65 72 2e 0a progress meter..
2490: 09 73 65 74 20 63 6f 75 6e 74 20 2d 31 0a 20 20 .set count -1.
24a0: 20 20 7d 0a 0a 20 20 20 20 66 6f 72 65 61 63 68 }.. foreach
24b0: 20 62 6c 6f 63 6b 20 24 64 62 20 7b 0a 09 69 66 block $db {..if
24c0: 20 7b 24 63 6f 75 6e 74 20 3c 20 30 7d 20 7b 0a {$count < 0} {.
24d0: 09 20 20 20 20 43 61 6c 6c 62 61 63 6b 20 24 74 . Callback $t
24e0: 6f 6b 65 6e 20 70 72 6f 67 72 65 73 73 20 2d 31 oken progress -1
24f0: 0a 09 7d 20 65 6c 73 65 69 66 20 7b 28 5b 69 6e ..} elseif {([in
2500: 63 72 20 63 6f 75 6e 74 5d 20 25 20 24 69 73 74 cr count] % $ist
2510: 65 70 29 20 3d 3d 20 30 7d 20 7b 0a 09 20 20 20 ep) == 0} {..
2520: 20 43 61 6c 6c 62 61 63 6b 20 24 74 6f 6b 65 6e Callback $token
2530: 20 70 72 6f 67 72 65 73 73 20 5b 65 78 70 72 20 progress [expr
2540: 7b 69 6e 74 28 24 63 6f 75 6e 74 20 2f 20 24 73 {int($count / $s
2550: 74 65 70 29 7d 5d 0a 09 7d 0a 09 69 66 20 7b 5b tep)}]..}..if {[
2560: 72 65 67 65 78 70 20 2d 6e 6f 63 61 73 65 20 7b regexp -nocase {
2570: 5c 73 2a 63 6f 6d 6d 65 6e 74 28 5b 5e 5c 6e 5d \s*comment([^\n]
2580: 29 2a 5c 6e 28 2e 2a 29 7d 20 24 62 6c 6f 63 6b )*\n(.*)} $block
2590: 20 5c 0a 09 09 2d 3e 20 63 6d 6e 74 20 72 65 73 \...-> cmnt res
25a0: 74 5d 7d 20 7b 0a 09 20 20 20 20 23 20 41 72 65 t]} {.. # Are
25b0: 20 40 63 6f 6d 6d 65 6e 74 73 20 62 6c 6f 63 6b @comments block
25c0: 73 2c 20 6f 72 20 6a 75 73 74 20 31 20 6c 69 6e s, or just 1 lin
25d0: 65 3f 0a 09 20 20 20 20 23 20 44 6f 65 73 20 61 e?.. # Does a
25e0: 6e 79 6f 6e 65 20 63 61 72 65 3f 0a 09 20 20 20 nyone care?..
25f0: 20 43 61 6c 6c 62 61 63 6b 20 24 74 6f 6b 65 6e Callback $token
2600: 20 63 6f 6d 6d 65 6e 74 20 24 63 6d 6e 74 0a 0a comment $cmnt..
2610: 09 7d 20 65 6c 73 65 69 66 20 7b 5b 72 65 67 65 .} elseif {[rege
2620: 78 70 20 2d 6e 6f 63 61 73 65 20 7b 5e 5c 73 2a xp -nocase {^\s*
2630: 73 74 72 69 6e 67 5b 5e 5c 7b 5d 2a 5c 7b 28 2e string[^\{]*\{(.
2640: 2a 29 5c 7d 5b 5e 5c 7d 5d 2a 7d 20 5c 0a 09 09 *)\}[^\}]*} \...
2650: 24 62 6c 6f 63 6b 20 2d 3e 20 72 65 73 74 5d 7d $block -> rest]}
2660: 20 7b 0a 09 20 20 20 20 23 20 73 74 72 69 6e 67 {.. # string
2670: 20 6d 61 63 72 6f 20 64 65 66 73 0a 09 20 20 20 macro defs..
2680: 20 69 66 20 7b 24 64 61 74 61 28 24 74 6f 6b 65 if {$data($toke
2690: 6e 2c 63 61 73 65 73 65 6e 73 69 74 69 76 65 73 n,casesensitives
26a0: 74 72 69 6e 67 73 29 7d 20 7b 0a 09 09 43 61 6c trings)} {...Cal
26b0: 6c 62 61 63 6b 20 24 74 6f 6b 65 6e 20 73 74 72 lback $token str
26c0: 69 6e 67 20 5b 50 61 72 73 65 53 74 72 69 6e 67 ing [ParseString
26d0: 20 24 72 65 73 74 5d 0a 09 20 20 20 20 7d 20 65 $rest].. } e
26e0: 6c 73 65 20 7b 0a 09 09 43 61 6c 6c 62 61 63 6b lse {...Callback
26f0: 20 24 74 6f 6b 65 6e 20 73 74 72 69 6e 67 20 5b $token string [
2700: 50 61 72 73 65 42 6c 6f 63 6b 20 24 72 65 73 74 ParseBlock $rest
2710: 5d 0a 09 20 20 20 20 7d 0a 09 7d 20 65 6c 73 65 ].. }..} else
2720: 69 66 20 7b 5b 72 65 67 65 78 70 20 2d 6e 6f 63 if {[regexp -noc
2730: 61 73 65 20 7b 5c 73 2a 70 72 65 61 6d 62 6c 65 ase {\s*preamble
2740: 5b 5e 5c 7b 5d 2a 5c 7b 28 2e 2a 29 5c 7d 5b 5e [^\{]*\{(.*)\}[^
2750: 5c 7d 5d 2a 7d 20 5c 0a 09 09 24 62 6c 6f 63 6b \}]*} \...$block
2760: 20 2d 3e 20 72 65 73 74 5d 7d 20 7b 0a 09 20 20 -> rest]} {..
2770: 20 20 43 61 6c 6c 62 61 63 6b 20 24 74 6f 6b 65 Callback $toke
2780: 6e 20 70 72 65 61 6d 62 6c 65 20 24 72 65 73 74 n preamble $rest
2790: 0a 0a 09 7d 20 65 6c 73 65 69 66 20 7b 5b 72 65 ...} elseif {[re
27a0: 67 65 78 70 20 7b 28 5b 5e 5c 7b 5d 2b 29 5c 7b gexp {([^\{]+)\{
27b0: 28 5b 5e 2c 5d 2a 29 2c 28 2e 2a 29 5c 7d 5b 5e ([^,]*),(.*)\}[^
27c0: 5c 7d 5d 2a 7d 20 5c 0a 09 09 24 62 6c 6f 63 6b \}]*} \...$block
27d0: 20 2d 3e 20 74 79 70 65 20 6b 65 79 20 72 65 73 -> type key res
27e0: 74 5d 7d 20 7b 0a 09 20 20 20 20 23 20 44 6f 20 t]} {.. # Do
27f0: 61 6e 79 20 40 73 74 72 69 6e 67 20 6d 61 70 70 any @string mapp
2800: 69 6e 67 73 0a 09 20 20 20 20 69 66 20 7b 24 64 ings.. if {$d
2810: 61 74 61 28 24 74 6f 6b 65 6e 2c 63 61 73 65 73 ata($token,cases
2820: 65 6e 73 69 74 69 76 65 73 74 72 69 6e 67 73 29 ensitivestrings)
2830: 7d 20 7b 0a 09 09 23 20 70 75 74 73 20 24 64 61 } {...# puts $da
2840: 74 61 28 24 74 6f 6b 65 6e 2c 73 74 72 69 6e 67 ta($token,string
2850: 73 29 0a 09 09 73 65 74 20 72 65 73 74 20 5b 73 s)...set rest [s
2860: 74 72 69 6e 67 20 6d 61 70 20 24 64 61 74 61 28 tring map $data(
2870: 24 74 6f 6b 65 6e 2c 73 74 72 69 6e 67 73 29 20 $token,strings)
2880: 24 72 65 73 74 5d 0a 09 20 20 20 20 7d 20 65 6c $rest].. } el
2890: 73 65 20 7b 0a 09 09 73 65 74 20 72 65 73 74 20 se {...set rest
28a0: 5b 73 74 72 69 6e 67 20 6d 61 70 20 2d 6e 6f 63 [string map -noc
28b0: 61 73 65 20 24 64 61 74 61 28 24 74 6f 6b 65 6e ase $data($token
28c0: 2c 73 74 72 69 6e 67 73 29 20 24 72 65 73 74 5d ,strings) $rest]
28d0: 0a 09 20 20 20 20 7d 0a 09 20 20 20 20 43 61 6c .. }.. Cal
28e0: 6c 62 61 63 6b 20 24 74 6f 6b 65 6e 20 72 65 63 lback $token rec
28f0: 6f 72 64 20 5b 54 69 64 79 20 24 74 79 70 65 5d ord [Tidy $type]
2900: 20 5b 73 74 72 69 6e 67 20 74 72 69 6d 20 24 6b [string trim $k
2910: 65 79 5d 20 5c 0a 09 09 20 20 20 20 5b 50 61 72 ey] \... [Par
2920: 73 65 42 6c 6f 63 6b 20 24 72 65 73 74 5d 0a 09 seBlock $rest]..
2930: 7d 20 65 6c 73 65 20 7b 0a 09 20 20 20 20 23 23 } else {.. ##
2940: 20 46 55 54 55 52 45 3a 20 55 73 65 20 61 20 6c FUTURE: Use a l
2950: 6f 67 67 65 72 2e 0a 09 20 20 20 20 70 75 74 73 ogger... puts
2960: 20 73 74 64 65 72 72 20 22 53 6b 69 70 70 69 6e stderr "Skippin
2970: 67 3a 20 24 62 6c 6f 63 6b 22 0a 09 7d 0a 20 20 g: $block"..}.
2980: 20 20 7d 0a 7d 0a 0a 70 72 6f 63 20 3a 3a 62 69 }.}..proc ::bi
2990: 62 74 65 78 3a 3a 50 61 72 73 65 53 74 72 69 6e btex::ParseStrin
29a0: 67 20 7b 62 6c 6f 63 6b 7d 20 7b 0a 20 20 20 20 g {block} {.
29b0: 72 65 67 65 78 70 20 7b 28 5c 53 2b 29 5b 5e 3d regexp {(\S+)[^=
29c0: 5d 2a 3d 28 2e 2a 29 7d 20 24 62 6c 6f 63 6b 20 ]*=(.*)} $block
29d0: 2d 3e 20 6b 65 79 20 72 65 73 74 0a 20 20 20 20 -> key rest.
29e0: 72 65 74 75 72 6e 20 5b 6c 69 73 74 20 24 6b 65 return [list $ke
29f0: 79 20 24 72 65 73 74 5d 0a 7d 0a 0a 70 72 6f 63 y $rest].}..proc
2a00: 20 3a 3a 62 69 62 74 65 78 3a 3a 50 61 72 73 65 ::bibtex::Parse
2a10: 42 6c 6f 63 6b 20 7b 62 6c 6f 63 6b 7d 20 7b 0a Block {block} {.
2a20: 20 20 20 20 73 65 74 20 72 65 74 20 20 20 5b 6c set ret [l
2a30: 69 73 74 5d 0a 20 20 20 20 73 65 74 20 69 6e 64 ist]. set ind
2a40: 65 78 20 30 0a 20 20 20 20 77 68 69 6c 65 20 7b ex 0. while {
2a50: 0a 09 5b 72 65 67 65 78 70 20 2d 73 74 61 72 74 ..[regexp -start
2a60: 20 24 69 6e 64 65 78 20 2d 69 6e 64 69 63 65 73 $index -indices
2a70: 20 2d 2d 20 5c 0a 09 09 7b 28 5c 53 2b 29 5b 5e -- \...{(\S+)[^
2a80: 3d 5d 2a 3d 28 2e 2a 29 7d 20 24 62 6c 6f 63 6b =]*=(.*)} $block
2a90: 20 2d 3e 20 6b 65 79 20 72 65 73 74 5d 0a 20 20 -> key rest].
2aa0: 20 20 7d 20 7b 0a 09 66 6f 72 65 61 63 68 20 7b } {..foreach {
2ab0: 6b 73 20 6b 65 7d 20 24 6b 65 79 20 62 72 65 61 ks ke} $key brea
2ac0: 6b 0a 09 73 65 74 20 6b 20 5b 54 69 64 79 20 5b k..set k [Tidy [
2ad0: 73 74 72 69 6e 67 20 72 61 6e 67 65 20 24 62 6c string range $bl
2ae0: 6f 63 6b 20 24 6b 73 20 24 6b 65 5d 5d 0a 09 66 ock $ks $ke]]..f
2af0: 6f 72 65 61 63 68 20 7b 72 73 20 72 65 7d 20 24 oreach {rs re} $
2b00: 72 65 73 74 20 62 72 65 61 6b 0a 09 66 6f 72 65 rest break..fore
2b10: 61 63 68 20 7b 76 20 69 6e 64 65 78 7d 20 5c 0a ach {v index} \.
2b20: 09 09 5b 50 61 72 73 65 42 69 62 53 74 72 69 6e ..[ParseBibStrin
2b30: 67 20 24 72 73 20 5b 73 74 72 69 6e 67 20 72 61 g $rs [string ra
2b40: 6e 67 65 20 24 62 6c 6f 63 6b 20 24 72 73 20 24 nge $block $rs $
2b50: 72 65 5d 5d 20 5c 0a 09 09 62 72 65 61 6b 0a 09 re]] \...break..
2b60: 6c 61 70 70 65 6e 64 20 72 65 74 20 24 6b 20 24 lappend ret $k $
2b70: 76 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 74 75 v. }. retu
2b80: 72 6e 20 24 72 65 74 0a 7d 0a 0a 70 72 6f 63 20 rn $ret.}..proc
2b90: 3a 3a 62 69 62 74 65 78 3a 3a 50 61 72 73 65 42 ::bibtex::ParseB
2ba0: 69 62 53 74 72 69 6e 67 20 7b 69 6e 64 65 78 20 ibString {index
2bb0: 73 74 72 7d 20 7b 0a 20 20 20 20 73 65 74 20 63 str} {. set c
2bc0: 6f 75 6e 74 20 30 0a 20 20 20 20 73 65 74 20 72 ount 0. set r
2bd0: 65 74 73 74 72 20 22 22 0a 20 20 20 20 73 65 74 etstr "". set
2be0: 20 65 73 63 61 70 65 20 30 0a 20 20 20 20 73 65 escape 0. se
2bf0: 74 20 73 74 72 69 6e 67 20 30 0a 20 20 20 20 66 t string 0. f
2c00: 6f 72 65 61 63 68 20 63 68 61 72 20 5b 73 70 6c oreach char [spl
2c10: 69 74 20 24 73 74 72 20 22 22 5d 20 7b 0a 09 69 it $str ""] {..i
2c20: 6e 63 72 20 69 6e 64 65 78 0a 09 69 66 20 7b 24 ncr index..if {$
2c30: 65 73 63 61 70 65 7d 20 7b 0a 09 20 20 20 20 73 escape} {.. s
2c40: 65 74 20 65 73 63 61 70 65 20 30 0a 09 7d 20 65 et escape 0..} e
2c50: 6c 73 65 20 7b 0a 09 20 20 20 20 69 66 20 7b 24 lse {.. if {$
2c60: 63 68 61 72 20 65 71 20 22 5c 7b 22 7d 20 7b 0a char eq "\{"} {.
2c70: 09 09 69 6e 63 72 20 63 6f 75 6e 74 0a 09 09 63 ..incr count...c
2c80: 6f 6e 74 69 6e 75 65 0a 09 20 20 20 20 7d 20 65 ontinue.. } e
2c90: 6c 73 65 69 66 20 7b 24 63 68 61 72 20 65 71 20 lseif {$char eq
2ca0: 22 5c 7d 22 7d 20 7b 0a 09 09 69 6e 63 72 20 63 "\}"} {...incr c
2cb0: 6f 75 6e 74 20 2d 31 0a 09 09 69 66 20 7b 24 63 ount -1...if {$c
2cc0: 6f 75 6e 74 20 3c 20 30 7d 20 7b 69 6e 63 72 20 ount < 0} {incr
2cd0: 69 6e 64 65 78 20 2d 31 3b 20 62 72 65 61 6b 7d index -1; break}
2ce0: 0a 09 09 63 6f 6e 74 69 6e 75 65 0a 09 20 20 20 ...continue..
2cf0: 20 7d 20 65 6c 73 65 69 66 20 7b 24 63 68 61 72 } elseif {$char
2d00: 20 65 71 20 22 2c 22 7d 20 7b 0a 09 09 69 66 20 eq ","} {...if
2d10: 7b 24 63 6f 75 6e 74 20 3d 3d 20 30 7d 20 62 72 {$count == 0} br
2d20: 65 61 6b 0a 09 20 20 20 20 7d 20 65 6c 73 65 69 eak.. } elsei
2d30: 66 20 7b 24 63 68 61 72 20 65 71 20 22 5c 5c 22 f {$char eq "\\"
2d40: 7d 20 7b 0a 09 09 73 65 74 20 65 73 63 61 70 65 } {...set escape
2d50: 20 31 0a 09 09 63 6f 6e 74 69 6e 75 65 0a 09 20 1...continue..
2d60: 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 63 68 } elseif {$ch
2d70: 61 72 20 65 71 20 22 5c 22 22 7d 20 7b 0a 09 09 ar eq "\""} {...
2d80: 23 20 4d 61 6e 61 67 69 6e 67 20 74 68 65 20 63 # Managing the c
2d90: 6f 75 6e 74 20 65 6e 73 75 72 65 73 20 74 68 61 ount ensures tha
2da0: 74 20 63 6f 6d 6d 61 20 69 6e 73 69 64 65 20 6f t comma inside o
2db0: 66 20 61 0a 09 09 23 20 73 74 72 69 6e 67 20 69 f a...# string i
2dc0: 73 20 6e 6f 74 20 63 6f 6e 73 69 64 65 72 65 64 s not considered
2dd0: 20 61 73 20 74 68 65 20 65 6e 64 20 6f 66 20 74 as the end of t
2de0: 68 65 20 66 69 65 6c 64 2e 0a 09 09 69 66 20 7b he field....if {
2df0: 21 24 73 74 72 69 6e 67 7d 20 7b 0a 09 09 20 20 !$string} {...
2e00: 20 20 69 6e 63 72 20 63 6f 75 6e 74 0a 09 09 20 incr count...
2e10: 20 20 20 73 65 74 20 73 74 72 69 6e 67 20 31 0a set string 1.
2e20: 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 20 20 20 ..} else {...
2e30: 20 69 6e 63 72 20 63 6f 75 6e 74 20 2d 31 0a 09 incr count -1..
2e40: 09 20 20 20 20 73 65 74 20 73 74 72 69 6e 67 20 . set string
2e50: 30 0a 09 09 7d 0a 09 09 63 6f 6e 74 69 6e 75 65 0...}...continue
2e60: 0a 09 20 20 20 20 7d 0a 09 20 20 20 20 23 20 65 .. }.. # e
2e70: 6c 73 65 3a 20 4e 6f 74 68 69 6e 67 0a 09 7d 0a lse: Nothing..}.
2e80: 09 61 70 70 65 6e 64 20 72 65 74 73 74 72 20 24 .append retstr $
2e90: 63 68 61 72 0a 20 20 20 20 7d 0a 20 20 20 20 72 char. }. r
2ea0: 65 67 73 75 62 20 2d 61 6c 6c 20 7b 5c 73 2b 7d egsub -all {\s+}
2eb0: 20 24 72 65 74 73 74 72 20 7b 20 7d 20 72 65 74 $retstr { } ret
2ec0: 73 74 72 0a 20 20 20 20 72 65 74 75 72 6e 20 5b str. return [
2ed0: 6c 69 73 74 20 5b 73 74 72 69 6e 67 20 74 72 69 list [string tri
2ee0: 6d 20 24 72 65 74 73 74 72 5d 20 24 69 6e 64 65 m $retstr] $inde
2ef0: 78 5d 0a 7d 0a 0a 0a 23 20 23 23 23 20 23 23 23 x].}...# ### ###
2f00: 20 23 23 23 20 23 23 23 23 23 23 23 23 23 20 23 ### ######### #
2f10: 23 23 23 23 23 23 23 23 20 23 23 23 23 23 23 23 ######## #######
2f20: 23 23 0a 23 23 20 49 6e 74 65 72 6e 61 6c 2e 20 ##.## Internal.
2f30: 50 61 63 6b 61 67 65 20 63 6f 6e 66 69 67 75 72 Package configur
2f40: 61 74 69 6f 6e 20 61 6e 64 20 73 74 61 74 65 2e ation and state.
2f50: 0a 0a 6e 61 6d 65 73 70 61 63 65 20 65 76 61 6c ..namespace eval
2f60: 20 62 69 62 74 65 78 20 7b 0a 20 20 20 20 23 20 bibtex {. #
2f70: 43 6f 75 6e 74 65 72 20 66 6f 72 20 74 68 65 20 Counter for the
2f80: 67 65 6e 65 72 61 74 69 6f 6e 20 6f 66 20 70 61 generation of pa
2f90: 72 73 65 72 20 74 6f 6b 65 6e 73 2e 0a 20 20 20 rser tokens..
2fa0: 20 76 61 72 69 61 62 6c 65 20 69 64 20 30 0a 0a variable id 0..
2fb0: 20 20 20 20 23 20 53 74 61 74 65 20 6f 66 20 61 # State of a
2fc0: 6c 6c 20 70 61 72 73 65 72 73 2e 20 4b 65 79 73 ll parsers. Keys
2fd0: 20 66 6f 72 20 65 61 63 68 20 70 61 72 73 65 72 for each parser
2fe0: 20 61 72 65 20 70 72 65 66 69 78 65 64 20 77 69 are prefixed wi
2ff0: 74 68 20 74 68 65 0a 20 20 20 20 23 20 70 61 72 th the. # par
3000: 73 65 72 20 74 6f 6b 65 6e 2e 0a 20 20 20 20 76 ser token.. v
3010: 61 72 69 61 62 6c 65 20 20 64 61 74 61 0a 20 20 ariable data.
3020: 20 20 61 72 72 61 79 20 73 65 74 20 64 61 74 61 array set data
3030: 20 7b 7d 0a 0a 20 20 20 20 23 20 4b 65 79 73 20 {}.. # Keys
3040: 61 6e 64 20 74 68 65 69 72 20 6d 65 61 6e 69 6e and their meanin
3050: 67 20 28 6c 69 73 74 65 64 20 77 69 74 68 6f 75 g (listed withou
3060: 74 20 74 6f 6b 65 6e 20 70 72 65 66 69 78 29 0a t token prefix).
3070: 20 20 20 20 23 23 0a 20 20 20 20 23 20 62 75 66 ##. # buf
3080: 66 65 72 0a 20 20 20 20 23 20 65 6f 66 0a 20 20 fer. # eof.
3090: 20 20 23 20 63 68 61 6e 6e 65 6c 20 20 20 20 3c # channel <
30a0: 2d 5c 2f 2d 20 44 69 66 66 65 72 65 6e 63 65 20 -\/- Difference
30b0: 3f 0a 20 20 20 20 23 20 73 74 72 69 6e 67 73 20 ?. # strings
30c0: 20 20 20 20 20 7c 0a 20 20 20 20 23 20 2d 61 73 |. # -as
30d0: 79 6e 63 20 20 20 20 20 20 20 7c 0a 20 20 20 20 ync |.
30e0: 23 20 2d 62 6c 6f 63 6b 73 69 7a 65 20 20 20 7c # -blocksize |
30f0: 0a 20 20 20 20 23 20 2d 63 68 61 6e 6e 65 6c 20 . # -channel
3100: 20 20 3c 2d 2f 0a 20 20 20 20 23 20 2d 72 65 63 <-/. # -rec
3110: 6f 72 64 63 6f 6d 6d 61 6e 64 20 20 20 2d 2d 20 ordcommand --
3120: 63 61 6c 6c 62 61 63 6b 20 66 6f 72 20 65 61 63 callback for eac
3130: 68 20 72 65 63 6f 72 64 0a 20 20 20 20 23 20 2d h record. # -
3140: 70 72 65 61 6d 62 6c 65 63 6f 6d 6d 61 6e 64 20 preamblecommand
3150: 2d 2d 20 63 61 6c 6c 62 61 63 6b 20 66 6f 72 20 -- callback for
3160: 40 70 72 65 61 6d 62 6c 65 20 62 6c 6f 63 6b 73 @preamble blocks
3170: 0a 20 20 20 20 23 20 2d 73 74 72 69 6e 67 63 6f . # -stringco
3180: 6d 6d 61 6e 64 20 20 20 2d 2d 20 63 61 6c 6c 62 mmand -- callb
3190: 61 63 6b 20 66 6f 72 20 40 73 74 72 69 6e 67 20 ack for @string
31a0: 6d 61 63 72 6f 73 0a 20 20 20 20 23 20 2d 63 6f macros. # -co
31b0: 6d 6d 65 6e 74 63 6f 6d 6d 61 6e 64 20 20 2d 2d mmentcommand --
31c0: 20 63 61 6c 6c 62 61 63 6b 20 66 6f 72 20 40 63 callback for @c
31d0: 6f 6d 6d 65 6e 74 20 62 6c 6f 63 6b 73 0a 20 20 omment blocks.
31e0: 20 20 23 20 2d 70 72 6f 67 72 65 73 73 63 6f 6d # -progresscom
31f0: 6d 61 6e 64 20 2d 2d 20 63 61 6c 6c 62 61 63 6b mand -- callback
3200: 20 74 6f 20 69 6e 64 69 63 61 74 65 20 70 72 6f to indicate pro
3210: 67 72 65 73 73 20 6f 66 20 70 61 72 73 65 0a 20 gress of parse.
3220: 20 20 20 23 23 0a 7d 0a 0a 23 20 23 23 23 20 23 ##.}..# ### #
3230: 23 23 20 23 23 23 20 23 23 23 23 23 23 23 23 23 ## ### #########
3240: 20 23 23 23 23 23 23 23 23 23 20 23 23 23 23 23 ######### #####
3250: 23 23 23 23 0a 23 23 20 52 65 61 64 79 20 74 6f ####.## Ready to
3260: 20 67 6f 0a 70 61 63 6b 61 67 65 20 70 72 6f 76 go.package prov
3270: 69 64 65 20 62 69 62 74 65 78 20 30 2e 36 0a 23 ide bibtex 0.6.#
3280: 20 45 4f 46 0a EOF.