[comp.text.tex] Bibliography management tools for BiBTeX

naren@cs.UAlberta.CA (Narendra Ravi) (10/05/90)

Hi,

 Are there tools for creating and managing BiBTeX style
 bibliography databases?
 
 I refer to the tools similar to those provided for the
 refer format in most UNIX systems (addbib, lookbib,
 indxbib, ... ).

 I remember such a discussion took place in this newsgroup
 a few weeks ago. But our site doesn't have those articles
 anymore.

Please email or post.

Naren.
=======================================================================
* Narendra Ravi                  * 615, General Services Building,    *
* Email : naren@cs.ualberta.ca   * Department of Computing Science    *
* Tel   : (403) 492-3520 (Off)   * University of Alberta              *
*         (403) 439-6301 (Res)   * Edmonton, Alberta, CANADA T6G 2H1  *
=======================================================================

skdutta@cs.tamu.edu (Saumen K Dutta) (10/05/90)

In article <naren.655095507@menaik> naren@cs.UAlberta.CA (Narendra Ravi) writes:
->Hi,
->
-> Are there tools for creating and managing BiBTeX style
-> bibliography databases?
-> 
-> I refer to the tools similar to those provided for the
-> refer format in most UNIX systems (addbib, lookbib,
-> indxbib, ... ).
->
-> I remember such a discussion took place in this newsgroup
-> a few weeks ago. But our site doesn't have those articles
-> anymore.
->
->Please email or post.
->
->Naren.
->=======================================================================

Sometime back I wrote and posted a program which works in unix
environment and written in shell script. This does not deal with
styles however. It is a like addbib for TeX/LaTeX. I am not posting
it again to increase the load. If anybody is interested to evaluate it
send me a request.

Thanks


--
     _                                   ||Internet: skdutta@cssun.tamu.edu  
    (   /_     _ /   --/-/- _            ||Bitnet : skd8107@tamvenus.bitnet 
   __)_/(_____(_/_(_/_(_(__(_/_______    ||Uucp : uunet!cssun.tamu.edu!skdutta
                                 ..      ||Yellnet: (409) 846-8803

kolb@itksu5kub.nl (Hans-Peter Kolb) (10/05/90)

In article <naren.655095507@menaik>, naren@cs.UAlberta.CA (Narendra
Ravi) writes:
 |>  Are there tools for creating and managing BiBTeX style
 |>  bibliography databases?
 |>  
 |>  I refer to the tools similar to those provided for the
 |>  refer format in most UNIX systems (addbib, lookbib,
 |>  indxbib, ... ).

Have you ever looked at Tib - "a TeX bibliographic preprocessor" by
J.C.Alexander (last known email address: jca@lakisis.umd.edu)?

It uses a refer-style database rather than bibTeX, so you can just use
addbib (with a prompt-file if you want to have all the nifty niceties
Tib allows you to have). The tib-package itself consists of 
      tib           the preprocessor
      tibdex        the indexmaker
      tiblist       lists the complete database(s)
      tiblook       locate entries

It is at least as powerful, and, IMHO, more flexible and
"user-friendly"
than BibTeX. 

Best..., hap

P.S.: No connection, "just a satisfied user".

------------------------------------------------------------------------
-
 hans-peter kolb                                            kolb@kub.nl
 Computational Linguistics                          kolb@htikub5.bitnet
 Tilburg University (KUB)                                P.O.Box 90 153
 The Netherlands                                     NL-5000 LE Tilburg
------------------------------------------------------------------------
-

panos@db.toronto.edu (Panos Economopoulos) (10/05/90)

naren@cs.UAlberta.CA (Narendra Ravi) writes:

>Hi,

> Are there tools for creating and managing BiBTeX style
> bibliography databases?
> 
> I refer to the tools similar to those provided for the
> refer format in most UNIX systems (addbib, lookbib,
> indxbib, ... ).

>Naren.
----------------------------------------
Kannan Varadhan has written a nice package called ``bibtools''
which allows you to insert/delete/select (using regular expressions)
entries to/from .bib bibliographic databases.

`bibtools' is   v09i046 in any    comp.sources.misc   archive.

The only other thing you need in order to install it is 
a regular expression package like the one written by Henry Spencer.
You can find it in comp.sources.unix in the following volumes:

	comp.sources.unix/volume3/regexp
	comp.sources.unix/volume3/regexp2
	comp.sources.unix/volume4/regexp3
	comp.sources.unix/volume4/regexp4
	comp.sources.unix/volume10/regexp.pch

Kannan's address is (was last spring, as far as I know):
	Kannan Varadhan, Internet Engineer, OARNet
	Ohio Supercomputer Center, Columbus, OH 43212	+1 (614) 292-4137
	email:	kannan@oar.net	|  osu-cis!malgudi.oar.net!kannan

----------------------------
Panos Economopoulos --         panos@csri.toronto.edu      (ARPA/CSNet)
University of Toronto          {uunet, ...}!utcsri!panos   (UUCP)
                               panos@csri.utoronto	      (Bitnet)
                               panos@csri.toronto.cdn      (CDNnet/EAN/X.400)

usenet@nlm.nih.gov (usenet news poster) (10/06/90)

I've written some Gnu Emacs lisp code that parses .BIB files and
could be used to manage them in various ways.  Drop me a line to
get a copy.  

pkarp@ncbi.nlm.nih.gov

usenet@nlm.nih.gov (usenet news poster) (10/09/90)

The Gnu Emacs code that I sent many of you by email was missing the
function "next-word".  Here is the complete version:



;;;;
;;;;    GnuEmacs functions for manipulating Scribe and BibTeX bibliography
;;;;    (.BIB) files.  This package contains functions that:
;;;;    
;;;;      Convert a bibliography (.BIB) file in Scribe format to BibTeX format.
;;;;    
;;;;      Convert a .BIB file in BibTeX format to a more readable text form.
;;;;
;;;;    Peter Karp -- karp@sumex-aim.stanford.edu
;;;;       Nov 1988:  Created
;;;;       June 1990: Revised by pkarp@ncbi.nlm.nih.gov to convert .BIB
;;;;                  files to text form.
;;;;
;;;;    This software may be redistributed freely as long as this leading
;;;;    text is not removed.  Use this software at your own risk.
;;;;
;;;;    Please send bugs, suggestions, improvements to the above address.
;;;;
;;;;    To use:
;;;;
;;;;    m-X load-file cnvtbib.el
;;;;    m-X eval-expression (cvbib "file.bib")   ; Scribe .BIB --> BibTeX .BIB
;;;;    m-X eval-expression (bib2txt "file.bib") ; BibTeX .BIB --> text form
;;;;  
;;;;  BUGS:
;;;;      (Scribe --> BibTeX conversion)
;;;;      BibTex will complain if author names are not separated by
;;;;      "and"; this converter does not add necessary "and"s.  However,
;;;;      the command "^X," will do a query-replace of "," to " and",
;;;;      which you may find helpful.  Note that BibTex will also complain
;;;;      if names are separated by ", and".  This converter does remove
;;;;      these commas.


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  cvbib

; Convert a Scribe-format .bib file to Latex format.

(defun  cvbib  (filename)
  (let  (dpos)

    (find-file-other-window filename)
    (beginning-of-buffer)

; First modify all entries so that the delimiters used for the entry
; are "{}".  So we'd convert  @book< ... >  to @book{ ... }

    (while (search-forward "@" nil t)
        (progn
	  (forward-word 1)
	  (setq dpos (point))
	  (goto-matching-delimiter)
	  (backward-delete-char 1)
	  (insert-string "}")
	  (goto-char dpos)
	  (delete-char 1)
	  (insert-string "{")
	  ))

    (beginning-of-buffer)

; Now convert all key fields from, e.g.,  AUTHOR=<PKARP>  to  AUTHOR="PKARP"
; Note that some key fields aren't delimited by anything, which is ok but
; requires a special check in the code below.

    (while  (search-forward "=" nil t)
      (progn
	(while  (search-forward " " (+ 1 (point)) t)
	  nil)
        (if (assoc (point-char) all_delims)
	    (progn
	      (setq dpos (point))
	      (goto-matching-delimiter)
	      (backward-delete-char 1)
	      (insert-string "\"")
	      (goto-char dpos)
	      (delete-char 1)
	      (insert-string "\"")
	      ))
      ))

    (beginning-of-buffer)

;;;;  Change all ", AND" within AUTHOR and EDITOR strings to " AND"
;;;;  because BibTex complains about the former.

    (while (re-search-forward "AUTHOR\\s-*=\\s-*" nil t)
      (setq dpos (point))
      (goto-matching-delimiter)
      (while (re-search-backward ",\\s-*AND" dpos t)
	(delete-char 1))
      )

    (beginning-of-buffer)

    (while (re-search-forward "EDITORS\\s-*=\\s-*" nil t)
      (setq dpos (point))
      (goto-matching-delimiter)
      (while (re-search-backward ",\\s-*AND" dpos t)
	(delete-char 1))
      )

    (beginning-of-buffer)

    )
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  and-replace

(defun  and-replace  ()
  "Does query-replace conversion of `,' to ` and' for bibliography conversion"
  (interactive)
  (query-replace "," " and")
)

(global-set-key "," 'and-replace)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  bib2txt

; Convert a Latex .BIB file to a more readable text form.  See
; function (entry2txt) for details on how this is done.

(defun bib2txt (filename &optional quiet_flg)
  (let (x)

    (find-file-other-window filename)

; Process @string definitions; for @string{AI="AI"} create a lisp variable
; called AI whose value is "AI".

    (while (search-forward "@string" nil t)
	   (progn
	     (next-word)
	     (setq start (dot))
	     (search-forward "=" nil t)
	     (backward-word 1)
	     (forward-word 1)
	     (setq variable (intern (buffer-substring start (dot))))
	     (search-forward "\"" nil t)
	     (setq start (dot))
	     (search-forward "\"" nil t)
	     (backward-char 1)
	     (setq value (buffer-substring start (dot)))
	     (set variable value)
	     ))

    (search-forward "@" nil t)
    (backward-char 1)
    (kill-region 1 (point))     ; Kill  the @string definitions

; Convert each entry to text form.

    (while (search-forward "@" nil t)
	   (entry2txt))

    (newline)

    (beginning-of-buffer)

; Some entries may still contain extra tabs and spaces at the beginning
; of lines.  Remove this crap and reformat the entries.

    (while (re-search-forward "^[ 	]+" nil t)
      (progn
	(setq x (point))
	(beginning-of-line)
	(kill-region x (point))
	(fill-paragraph nil)
	))

; Some entries may be separated by multiple newlines; change double newlines
; to single newlines.

    (beginning-of-buffer)
    (while (and (not (end-of-buffer-p))
		(re-search-forward "^$" nil t))
      (progn
	(setq x (point))
	(skip-chars " 	" t)
	(kill-region x (point))
	(newline)
	))

    (message "Conversion complete; save buffer to a text file.")
))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  entry2txt

; Convert the current bibliography entry from Latex to text format
; For an entry such as:
;
;    @PhDThesis{ Altman89,
;       Key="Altman",
;       Author="Altman, R.B.",
;       School="Stanford University Medical Information Sciences",
;       Title="Exclusion Methods for the Determination of Protein Structure from Experimental Data",
;       Year=1989,  }
;
; We delete the first and second lines, we make sure that the Author
; and Title fields come first, and we strip off the keyword names in
; each field, as well as unquoting each field (except for the title).
; For some fields we insert leading strings, e.g., for the Pages field
; we insert the leading string "pp".
;
; Assumes we are called with (dot) after the @ of  @BOOK

(defun entry2txt (&optional quiet_flg)
  (let (at-pos next-pos x variable sstart)

    (backward-char 1)
    (setq at-pos (dot))           ; at-pos  <-- start of @BOOK
    (forward-word 1)
    (goto-matching-delimiter)
    (backward-delete-char 1)      ;  delete closing delimiter

    (goto-char at-pos)
    (next-word)
    (next-word)
    (kill-region (point) at-pos)  ; delete  @book{

    (setq x (point))
    (forward-word 1)
; If entry is  @BOOK{JONES80,   display  JONES80
    (if (not quiet_flg)
	(message (buffer-substring x (point))))

    (next-word)
    (kill-region (point) x)   ;;;; delete the citation name

    (setq next-pos (dot))

; Delete the  Key=  field.

    (if (setq b (field-boundary "key" (end-of-entry)))
	(kill-region (car b) (cdr b)))

    (goto-char next-pos)

; Move the Author field to the front of the entry and strip off the
; Author keyword and quotes.

    (if (setq b (field-boundary "author" (end-of-entry)))
	(progn
	  (kill-region (car b) (cdr b))
	  (goto-char next-pos)
	  (yank)
	  (goto-char next-pos)
	  (strip-field t)
	  (insert-string " ")
	  (setq next-pos (dot))))

; Make sure the Title field comes next; strip off the keyword.

    (if (setq b (field-boundary "title" (end-of-entry)))
	(progn
	  (kill-region (car b) (cdr b))
	  (goto-char next-pos)
	  (yank)
	  (goto-char next-pos)
	  (strip-field nil)
	  (insert-string " ")
	  (setq next-pos (dot))))

; Now, for each remaining field of the form  Keyword=Value , if Value
; is not a quoted string then attempt to replace Value with the value
; of a GnuEmacs lisp variable called Value, was was set during 
; processing of @string specifications in the function (bib2txt).
; Then strip off  Keyword=  and strip off the quotes around the value.

    (while (re-search-forward "[a-z]" (end-of-entry) t)
	   (progn
	     (re-search-forward "[ =	]" nil t)
	     (skip-chars " =	")
	     (setq sstart (point))
	     (if (not (char-equal 34 (char-after (point))))
		 (progn

; Value is not a quoted string; try to insert the value of this variable.

		   (re-search-forward "[ ,]" nil t)
		   (backward-word 1)
		   (forward-word 1)
		   (setq variable (intern (buffer-substring sstart (point))))
		   (if (boundp variable)
		       (progn
			 (kill-region sstart (point))
			 (insert-string (eval variable))))
		   ))

; Strip off keyword and quotes.

	     (goto-char sstart)	     
	     (backward-word 1)
	     (kill-region next-pos (point))
	     (strip-field t)
	     (insert-string " ")
	     (setq next-pos (point))))

    (backward-word 1)
    (forward-word 1)
    (skip-chars "\"")
    (kill-region (point) (skip-chars " ,"))
    (insert-string ".")

; Format this entry nicely.

    (fill-paragraph nil)
))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  end-of-entry

; Return the buffer position at the end of the current entry, which we
; define to be either the position of the "@" at the start of the next
; entry, or if we can't find that, then (end-of-buffer).

(defun end-of-entry ()
  (let (pos)
    (save-excursion
      (if (setq pos (search-forward "@" nil t))
	  (point)
	  (progn
	    (end-of-buffer)
	    (point))))
    ))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  field-boundary

; If the current bib entry (whose end is at position Eoe) contains a
; field named Field-Name (such as:  author="Jones",) we return a list
; whose car and cdr are the starting and ending buffer positions of
; this field; else we return NIL.

(defun field-boundary (field-name eoe)
  (let (start (end nil))
    (if (re-search-forward (concat field-name " *=?") eoe t)
	(progn
	  (backward-word 1)
	  (setq start (dot))
	  (if (search-forward "\"" eoe t)
	      (if (re-search-forward "\"" eoe t)
		  (progn
		    (skip-chars " ,	" t)
		    (setq end (min (dot) eoe))
		    )))))

    (if end
	(cons start end)
	nil)
  ))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  strip-field

; Given a line such as:
;
;   author="jim jones",
;
; we strip off the "author=" part , plus the surrounding quotes if
; Delete-Quotes is True.  Also, if the keyword (here author) is in
; the alist word-subs, we insert the associated string.
;
; We leave point at the end of the expression (after the comma (which
; may or may not be present)).


(setq word-subs '(("volume" . "v")
		  ("number" . "#")
		  ("pages" . "pp")))


(defun strip-field (delete-quotes)
 (let ((wordstart (point))
       word)

; Kill keyword and make substitution if appropriate.

  (forward-word 1)
  (setq word (buffer-substring wordstart (point)))
  (backward-kill-word 1)
  (if (assoc (downcase word) word-subs)
      (insert-string (cdr (assoc (downcase word) word-subs))))
  (kill-region (point) (skip-chars " 	="))

; Delete surrounding quotes if requested.  

  (if delete-quotes
      (if (char-equal 34 (char-after (dot))) ; double quote
	  (progn
	    (delete-char 1)
	    (search-forward "\"" nil t)
	    (backward-delete-char 1)
	    (skip-chars " ,	"))
	  (re-search-forward "[,}]" nil t))
      (if (char-equal 34 (char-after (dot))) ; double quote
	  (progn
	    (forward-char 1)
	    (re-search-forward "\" *,?" nil t))
	  (re-search-forward "[,}]")))
))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  goto-matching-delimiter

;  Goes to the character in the buffer which closes the Scribe delimiter
;  where (point) is when this function is called.  I.e., if the buffer is
;  "@book< foo >bar" and we're called with point at "<", we'll leave
;  point at the "b" of "bar".
;

(setq all_delims '(("<" . ">")
		   ("[" . "]")
		   ("\"" . "\"")
		   ("(" . ")")
		   ("{" . "}")))


(defun  goto-matching-delimiter ()
  (let (delim match-char mdelim redelims
	      (nomatch t)
	      (start (point)))

    (setq delim (point-char))
    (setq mdelim (cdr (assoc delim all_delims)))  ; Look up matching delim
    (if (null mdelim)
	(error "Point is not a valid delimiter"))

    (setq redelims (concat "[" mdelim delim "]" ))
    (forward-char)

; Assuming the open-delim was "{", repeatedley search for either "{"
; or "}".  If we find "{", recurse to find its matching delimiter.  If
; we find "}", we're done.

    (while nomatch
      (progn
	(if (not (re-search-forward redelims nil t))
	    (progn
	      (error "No closing delimiter found to match that at point")
	      (goto-char start))
	  (setq match-char (buffer-substring (- (point) 1) (point)))

	  (if (and (not (equal "\"" delim))
		   (equal match-char delim))
	      (progn
		(backward-char)
		(goto-matching-delimiter))
	    (setq nomatch nil))  ; Done!
	  )
	))
    ))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  point-char

;  Return the character at the cursor


(defun  point-char  ()
  (buffer-substring  (point)  (+ 1 (point)))
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  skip-chars

; Scans through the buffer starting at (point) as long as the buffer
; contains chars within String (newline is added to string if Add_Newline
; is T.

; Returns (point)

(defun skip-chars (string &optional add_newline)
  (let (ch i)
    (if add_newline
	(setq string (concat string (char-to-string 10))))

    (while (and (setq ch (char-after (dot)))  ; False if at end of buffer
		(char-in-string ch string))
	   (forward-char 1))
    (point)
    ))

(defun char-in-string (char string)
  (let ((i (length string))
	(found nil))
    (while (and (> i 0)
		(not (setq found (char-equal char
					     (string-to-char string)))))
	   (setq string (substring string 1))
	   (setq i (1- i)))
    found
    ))
		
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  end-of-bufffer-p

(defun end-of-buffer-p ()
  (not (char-after (dot)))
  )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  next-word

(defun  next-word  ()
                   "Move to the start of the next word in the buffer"
		   (interactive)
					
  (let (pos)
        (setq pos (point))
        (forward-word 1)
        (backward-word 1)
        (if (>= pos (point))
            (progn
                (forward-word 2)
                (backward-word 1)
        ))
    ))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  mark-and-hold

;  Debugging routine

(defun  mark-and-hold (mark-char-string)
  (insert-string mark-char-string)
  (read-string "holding...")
  (backward-delete-char 1)
)