Scid  4.6.5
bibliography.tcl
Go to the documentation of this file.
1 ###
2 ### bibliography.tcl: part of Scid.
3 ### Copyright (C) 2010 Alexander Wagner
4 ###
5 ### $Id: bibliography.tcl,v 4.3 2011/02/13 18:12:02 arwagner Exp $
6 ###
7 ### Last change: <Tue, 2010/07/13 23:08:01 arwagner ingata>
8 ###
9 ### Handle Bib pgn headers to show bibliographic references for a
10 ### given game. The bibliographic database should be available in
11 ### BibTeX format. The ref header should be of the form:
12 ###
13 ### [Bib "<bibtexkey>, <additional info> ; <bibtexkey>, <additional info>]
14 ###
15 ### E.g.
16 ### [Bib "Botvinnik:1960, No. 27 p.57"]
17 ###
18 ### Refering to the BibTeX record:
19 ###
20 ### @BOOK{Botvinnik:1960,
21 ### title = {{O}ne hundred selected games},
22 ### publisher = {Dover Pub.},
23 ### year = {1960},
24 ### author = {Botvinnik, M. M.},
25 ### pages = {272},
26 ### address = {New York},
27 ### keywords = {Game Collection},
28 ### refid = {1106902}
29 ### }
30 
31 ###
32 #======================================================================
33 
34 set m .menu.tools
35 
36 # $m add command -label "Database information..." -command {::metadata::show}
37 
38 #======================================================================
39 #
40 #======================================================================
41 namespace eval Bibliography {
42 
43  set literature ""
44 
45  #----------------------------------------------------------------------
46  # Take a ref structure and turn it into a simplified version of
47  # ISBD reference output
48  #----------------------------------------------------------------------
49  proc Ref2ISBD { Ref Biblio} {
50 
51  set w .showRef
52 
53  set key [lindex $Ref 0]
54  set type ""
55  set address ""; set author ""; set editor ""; set number "";
56  set isbn ""; set issn ""; set issue ""; set pages "";
57  set publisher ""; set title ""; set volume ""; set year "";
58  set edition ""; set keywords "";
59 
60  foreach tag { type address author editor number isbn issn issue pages publisher title volume year edition keywords } {
61  set $tag [lindex [lindex $Ref [lsearch -exact -index 0 $Ref $tag]] 1]
62  }
63  regsub -all -nocase { and } $author "; " author
64  set isbd ""
65 
66  $w.f.tree insert {} end -id $key -text "$type: $author ($key)" -open true
67  $w.f.tree insert $key end -id "l2$key" -text "$author" -tags {author}
68  $w.f.tree insert $key end -id "l3$key" -text "$title" -tags {title}
69  $w.f.tree insert $key end -id "l4$key" -text "$Biblio" -tags {reference}
70  if {$editor != ""} {
71  $w.f.tree insert $key end -id "l5$key" -text "Ed. $editor"
72  }
73  if {$edition != ""} {
74  $w.f.tree insert $key end -id "l6$key" -text "$edition"
75  }
76  $w.f.tree insert $key end -id "l7$key" -text "$address : $publisher, $year. - "
77  if {$pages != ""} {
78  $w.f.tree insert $key end -id "l8$key" -text "$pages"
79  }
80  if {$isbn != ""} {
81  $w.f.tree insert $key end -id "l9$key" -text "$isbn"
82  } elseif {$issn != ""} {
83  $w.f.tree insert $key end -id "l9$key" -text "$issn"
84  }
85  if {$keywords != ""} {
86  $w.f.tree insert $key end -id "l0$key" -text "$keywords"
87  }
88 
89  ### set isbd "\[$type\]\n"
90  ### set isbd "$author\n$title / $author.\n"
91  ### if {$editor != ""} {
92  ### set isbd "$isbd Ed. $editor\n"
93  ### }
94  ### set isbd "$isbd $edition\n"
95  ### set isbd "$isbd $address : $publisher, $year. - "
96  ### set isbd "$isbd $pages\n$isbn\n\n$keywords"
97 
98  # Simplified ISBD for book
99  if {$type == "BOOK"} {
100  set isbd "$author:\n$title / $author. Ed. $editor.\n- $edition -\n$address : $publisher, $year. - $pages\n$isbn\n\n$keywords\n"
101  } elseif {$type == "PERIODICAL"} {
102  # Simplified ISBD for journal
103  set isbd "\[Journal\]\n$title / publ. $editor\n$address : $publisher, $year. - $pages\n$issn\n\n$keywords\n"
104  } else {
105  # use book format by default, should be improved
106  set isbd "\[$type\]\n$author:\n$title / $author. Ed. $editor.\n - $edition - $address : $publisher, $year. - $pages\n$isbn ($issn)\n\n$keywords\n"
107  }
108  ### set isbd "$isbd\n------------------------------------------------------------\n";
109 
110  return $isbd
111  }
112 
113  #----------------------------------------------------------------------
114  # Simple BibTeX reader. Does not handle all the funny things of
115  # BibTeX like crossref etc. assumes all tags in a single line
116  #----------------------------------------------------------------------
117  proc ReadBibTeX { bibfile } {
118  set fd [open $bibfile]
119 
120  set Bibentries {}
121 
122  set type ""
123  set key ""
124  set address ""; set author ""; set editor ""; set number "";
125  set isbn ""; set issn ""; set issue ""; set pages "";
126  set publisher ""; set title ""; set volume ""; set year "";
127  set edition ""; set keywords "";
128 
129  while { [gets $fd line] >= 0} {
130  if {[regexp -- "@" $line]} {
131  # begin of dataset
132  lappend Bibentries [list \
133  "$key" \
134  [list "type" $type] \
135  [list "title" $title] \
136  [list "editor" $editor] \
137  [list "author" $author] \
138  [list "publisher" $publisher] \
139  [list "pages" $pages] \
140  [list "address" $address] \
141  [list "isbn" $isbn] \
142  [list "issn" $issn] \
143  [list "volume" $volume] \
144  [list "issue" $issue] \
145  [list "number" $number] \
146  [list "edition" $edition] \
147  [list "keywords" $keywords] \
148  [list "year" $year]]
149 
150  regsub {\{.*} $line "" type
151  regsub {\@} $type "" type
152  ## set type [string lower type]
153  regsub {.*\{} $line "" key
154  regsub {,} $key "" key
155 
156  set key [string trim $key]
157  set type [string trim $type]
158 
159  set address ""; set author ""; set editor ""; set number "";
160  set isbn ""; set issn ""; set issue ""; set pages "";
161  set publisher ""; set title ""; set volume ""; set year ""
162  set edition ""; set keywords "";
163  } else {
164  regsub -all { "} $line {} line
165  regsub -all {" } $line {} line
166  regsub -all {,$} $line {} line
167  regsub -all {[\{\}]} $line {} line
168 
169  }
170  if {[regexp -- {[ \t]title[ \t=]} $line]} {
171  regsub -all {title .*= } $line {} title
172  set title [string trim $title]
173  }
174  if {[regexp -- {[ \t]author[ \t=]} $line]} {
175  regsub -all {author .*= } $line {} author
176  set author [string trim $author]
177  }
178  if {[regexp -- {[ \t]editor[ \t=]} $line]} {
179  regsub -all {editor .*= } $line {} editor
180  set editor [string trim $editor]
181  }
182  if {[regexp -- {[ \t]year[ \t=]} $line]} {
183  regsub -all {year .*= } $line {} year
184  set year [string trim $year]
185  }
186  if {[regexp -- {[ \t]publisher[ \t=]} $line]} {
187  regsub -all {publisher .*= } $line {} publisher
188  set publisher [string trim $publisher]
189  }
190  if {[regexp -- {[ \t]address[ \t=]} $line]} {
191  regsub -all {address .*= } $line {} address
192  set address [string trim $address]
193  }
194  if {[regexp -- {[ \t]isbn[ \t=]} $line]} {
195  regsub -all {isbn.*= } $line {} isbn
196  set isbn [string trim $isbn]
197  }
198  if {[regexp -- {[ \t]issn[ \t=]} $line]} {
199  regsub -all {issn.*= } $line {} issn
200  set issn [string trim $issn]
201  }
202  if {[regexp -- {[ \t]issue[ \t=]} $line]} {
203  regsub -all {issue.*= } $line {} issue
204  set issue [string trim $issue]
205  }
206  if {[regexp -- {[ \t]volume[ \t=]} $line]} {
207  regsub -all {volume.*= } $line {} volume
208  set volume [string trim $volume]
209  }
210  if {[regexp -- {[ \t]number[ \t=]} $line]} {
211  regsub -all {number.*= } $line {} number
212  set number [string trim $number]
213  }
214  if {[regexp -- {[ \t]edition[ \t=]} $line]} {
215  regsub -all {edition.*= } $line {} edition
216  set edition [string trim $edition]
217  }
218  if {[regexp -- {[ \t]keywords[ \t=]} $line]} {
219  regsub -all {keywords.*= } $line {} keywords
220  set keywords [string trim $keywords]
221  }
222  }
223  close $fd
224  return $Bibentries
225  }
226 
227  #----------------------------------------------------------------------
228  # Extract the Ref header from the current game. Uses bibfile as
229  # input for bibliographic information, returns a block of ISBD
230  # formatted entries
231  #----------------------------------------------------------------------
232  proc ExtractRef { bibfile } {
233 
234  set w .showRef
235 
236  set Extra [sc_game tags get Extra]
237  set extraTagsList [split $Extra "\n"]
238 
239  set literature ""
240 
241  foreach i $extraTagsList {
242  if { [string equal -nocase [lindex $i 0] "Bib"] } {
243  set ref [string range $i 5 end-1]
244 
245  regsub -all { ; } $ref {|} ref
246 
247  # Tcl uses a list of split chars as second argument :(
248  set ref [split $ref "|"]
249 
250  set BibEntries [::Bibliography::ReadBibTeX $bibfile]
251 
252  foreach r $ref {
253  regsub -all {, .*} $r {} BibKey
254  regsub -all {.*, } $r {} Biblio
255  set BibKey [string trim $BibKey]
256  set Biblio [string trim $Biblio]
257  set idx [lsearch -exact -index 0 $BibEntries $BibKey]
258  set BibDta [lindex $BibEntries $idx]
259 
260  set isbd [::Bibliography::Ref2ISBD $BibDta $Biblio]
261  set literature "$literature\n$isbd\n$Biblio\n\n"
262  }
263  }
264  }
265  set lit [string trim $literature]
266  return $lit
267  }
268 
269  #----------------------------------------------------------------------
270  # Open a window with an expanded tree widget containing all
271  # referenced entities from the BibTeX file.
272  #----------------------------------------------------------------------
273  proc ShowRef {} {
274  global scidDataDir
275 
276  set w .showRef
277 
278  if { [winfo exists $w] } {
279  # recreate the widget with new data
280  destroy $w
281  }
282 
283  toplevel $w
284  ::setTitle $w "References"
285  setWinLocation $w
286  setWinSize $w
287 
288  ttk::frame $w.f
289  pack $w.f -fill both -expand 1
290 
291  ttk::treeview $w.f.tree -xscrollcommand "$w.f.xbar set" -yscrollcommand "$w.f.ybar set" -show tree -selectmode none
292  ttk::scrollbar $w.f.xbar -command "$w.f.tree xview" -orient horizontal
293  ttk::scrollbar $w.f.ybar -command "$w.f.tree yview" -orient vertical
294  $w.f.tree column #0 -minwidth 1200
295 
296  $w.f.tree tag configure author -foreground blue
297  $w.f.tree tag configure title -foreground blue
298  $w.f.tree tag configure reference -foreground red
299 
300  pack $w.f.xbar -side bottom -fill x
301  pack $w.f.ybar -side right -fill y
302  pack $w.f.tree -side left -expand 1 -fill both
303 
304  # set a global bib file
305  set bibfile [file nativename [file join $scidDataDir "Bookshelf.bib"]]
306  # ... but overwrite it if a bibliography for the base itself exits
307  if {[file readable "[sc_base filename $::curr_db].bib"]} {
308  set bibfile "[sc_base filename $::curr_db].bib"
309  }
310  set ::Bibliography::literature [::Bibliography::ExtractRef $bibfile]
311 
312  bind $w <Escape> { destroy .showRef}
313  bind $w <Configure> {
314  recordWinSize .showRef
315  }
316  # Copy references to clipboard
317  bind $w <Control-Insert> { clipboard clear; clipboard append $::Bibliography::literature }
318  bind $w <Control-c> { clipboard clear; clipboard append $::Bibliography::literature }
319  }
320 
321 }
322 
323 ###
324 ### End of file: bibliography.tcl
325 ###