[OS X TeX] New TeXShop macro: "Insert reference"

Thomas Schröder hydrochlorix at gmx.net
Mon Aug 23 22:42:01 CEST 2004


Hi Will,

Am 23.08.2004 um 13:38 schrieb Will Robertson:

> On 23 Aug 2004, at 8:31 PM, Thomas Schršder wrote:
>>
>> That's what I think, too. The difficult bit will be to get the cite 
>> keys because in a .bib file the cite keys are part of different 
>> statements like @article or @book, whilst with other references they 
>> are always inside a \label command.
>
> I reckon bibtool or something must be able to do this -

I read the manual to bibtool and wasn't able to find what I was looking 
for. As far as I can see bibtool only handles complete references. So, 
I googled around a little and found the bibtools (note the extra 's') 
collection by David Kotz on 
http://www.cs.dartmouth.edu/~dfk/bibtools.html. This collection comes 
with the 'citekeys' shell script which will give you all the cite keys 
from a *.bib file. It does this by using BibTeX together with a special 
BibTeX style file internally that only outputs the cite key. Very 
clever, really because it handles all of BibTeX's statements 
automatically and uses its built-in intelligence to handle *.bib files.

> after all, it can't be the hardest thing in the world since LyX and 
> WinEdt can do it...

Maybe so, but it was still a bit difficult for me. Anyways, what I did 
was, I included both the citekeys script and its accompanying *.bst 
file because I had to change the citekeys script a little to get this 
whole thing to work inside TeXShop's Applescript environment and 
therefor couldn't rely on a preinstalled bibtools collection.

The Applescript will write the citekeys script and citekeys.bst to 
/tmp, make citekeys executeable, execute citekeys on all the *.bib 
files in the directory where the current *.tex file resides, present 
the user with a list of all the cite keys it found and finally insert 
the citation the user selects at the cursor. Sounds slow but is pretty 
fast on a G4 450 MHz, to the extent that I didn't bother to optimize it 
for speed.

Still, I guess this could be done in a better way, most probably with 
some sophisticated calls to awk and/or sed to extract the cite keys 
from *.bib files, but I that's beyond what I could do. But my hack 
works and that's the point, eh?

> I think it would be acceptable to make people install bibtools if they 
> want to run the script.

It certainly would have been, had I been able to use it for this.

Anyway, here's the script:
---------------

--Applescript
-- This Applescript will scan all *.bib files in the directory where 
the current *.tex file is residing
-- and present the user with a list of all the cite keys it finds.
-- This Applescript makes heavy use of the INSERT REFERENCE script by 
Will Robertson
-- and the citekey shell script by David Kotz. Since I had to change 
Davdi's script a little to get it
-- to work inside TeXShop's Applescript environment I and couldn't 
therefor use a preinstalled version
-- I decided to recreate the script and the accompanying *.bst file in 
here.
-- Thomas Schršder

-- CUSTOMISE TO YOUR LIKING:

property cite_command : "cite" -- or something else N.B. no backslash!
-- Inserts e.g. "\cite{book1}"
-- Put "" to insert the plain label: e.g. "book1" 

property save_before_run : true
-- The script only finds labels created in saved documents. If you 
don't want this script to save your document before it runs for 
whatever reason, set this to true.

--THE PREAMBLE

-- start create citekeys
-- set up the filename & path
set theCITEKEY to POSIX path of ("/tmp/citekeys")

-- create the file if it doesn't exist, otherwise open it
set myOpenCITEKEY to open for access file theCITEKEY with write 
permission

write ({"#!/bin/csh -f
#
# citekeys - print out all the cite keys in given bib files
#
# usage:
#    citekeys file.bib...
#

onintr cleanup

if ($#argv < 1) then
	   echo 'usage: citekeys file.bib...'
	   exit 1
endif

unset files
foreach i ($*)
	if ($i:e == bib) then
  		set file=$i:r
	else
  		set file=$i
	endif
	
	if ($?files) then
		set files=($files,$i)
	else
		set files=($file)
	endif
end

#echo creating citekeys.aux for $files

cat > citekeys.aux <<EOF
\\relax
\\citation{*}
\\bibstyle{citekeys}
\\bibdata{$files}
EOF

rm -f citekeys.{log,dvi,bbl,blg}

#echo bibtex citekeys
/usr/local/teTeX/bin/powerpc-apple-darwin-current/bibtex citekeys

mv citekeys.bbl citekeys.out

cleanup:
rm -f citekeys.{tex,aux,log,dvi,bbl,blg}
"} as string) to myOpenCITEKEY

-- close the file when finished.
close access myOpenCITEKEY

do shell script "chmod +x /tmp/citekeys" -- make citekeys residing in 
the /tmp directory executable
-- end create citekeys

-- start create .bst
-- set up the filename & path
set theBST to POSIX path  of ("/tmp/citekeys.bst")

-- create the file if it doesn't exist, otherwise open it
set myOpenBST to open for access file theBST with write permission

write ({"% BibTeX bibliography style `citekeys
% by David Kotz dfk at cs.dartmouth.edu
% March 1994
% modified (distantly) from
   %   BibTeX standard bibliography style `alpha'
	% version 0.99a for BibTeX versions 0.99a or later, LaTeX version 2.09.
	% Copyright (C) 1985, all rights reserved.
	% Copying of this file is authorized only if either
	% (1) you make absolutely no changes to your copy, including name, or
	% (2) if you do make changes, you name it something other than
	% btxbst.doc, plain.bst, unsrt.bst, alpha.bst, and abbrv.bst.
	% This restriction helps ensure that all standard styles are identical.
	% The file btxbst.doc has the documentation for this style.

ENTRY { author } {} {}

FUNCTION {article} {}
FUNCTION {book} {}
FUNCTION {booklet} {}
FUNCTION {inbook} {}
FUNCTION {incollection} {}
FUNCTION {inproceedings} {}
FUNCTION {conference} {}
FUNCTION {manual} {}
FUNCTION {mastersthesis} {}
FUNCTION {misc} {}
FUNCTION {phdthesis} {}
FUNCTION {proceedings} {}
FUNCTION {techreport} {}
FUNCTION {unpublished} {}
FUNCTION {default.type} { misc }

MACRO {jan} {\"January\"}
MACRO {feb} {\"February\"}
MACRO {mar} {\"March\"}
MACRO {apr} {\"April\"}
MACRO {may} {\"May\"}
MACRO {jun} {\"June\"}
MACRO {jul} {\"July\"}
MACRO {aug} {\"August\"}
MACRO {sep} {\"September\"}
MACRO {oct} {\"October\"}
MACRO {nov} {\"November\"}
MACRO {dec} {\"December\"}

READ

FUNCTION {presort}
{ cite$
   #1 entry.max$ substring$
   'sort.key$ :=
}

ITERATE {presort}

SORT

FUNCTION {cite.key.only} { cite$ write$ newline$ }

ITERATE {cite.key.only}
"} as string) to myOpenBST


-- close the file when finished.
close access myOpenBST

-- end create .bst

--THE SCRIPT:

if save_before_run then
	tell application "TeXShop" to save the front document
end if

tell application "TeXShop" to set texpath to the path of the front 
document -- the current tex file: "/path/to/docu.tex"

set texloc to POSIX file texpath -- Convert to applescript format: 
"path:to:docu.tex"
tell application "Finder" to set texfolder to the container of (texloc 
as alias) -- Get the folder: "path:to:"
set texdir to the POSIX path of (texfolder as alias) -- Convert to UNIX 
path: "/path/to"
set texfiles_tosearch to the quoted form of texdir & "*.bib" -- search 
all .tex files: "/path/to/*.bib"

tell application "TeXShop"
	
	set current_selection to the content of the selection of the front 
document
	
	-- DO SHELL SCRIPT COMPONENTS:
		set create_out to ("cd /tmp; ./citekeys " & texfiles_tosearch) as 
string
		set find_label_lines to (" >/dev/null ;cat /tmp/citekeys.out") as 
string	
	-- pipe the shell scripts together:
		set get_labels_shell_script to create_out & find_label_lines

	try
		-- filter choices with the current selection:
		set choose_labels to every paragraph of (do shell script 
get_labels_shell_script & filter_selection)
	on error
		-- If it fails (e.g. nothing found) display the whole list:
		set choose_labels to every paragraph of (do shell script 
get_labels_shell_script)
	end try
	
	-- In case the document doesn't contain any labels:
	if choose_labels = {""} then
		display dialog "Sorry, no cite keys have been found." buttons {"No 
worries"} default button "No worries"
		return
	end if
	
	set label_insert to choose from list choose_labels with prompt "Please 
choose the cite key of the reference to insert:"
	if label_insert ­ false then
		if cite_command = "" then
			set cite_insert to label_insert
		else
			set cite_insert to "\\" & cite_command & "{" & label_insert & "}"
		end if
		set the selection of the front document to cite_insert as string
	end if
	
end tell

---------------


I hope this is useful, have fun!

	Ciao, Thomas
--------------------- Info ---------------------
Mac-TeX Website: http://www.esm.psu.edu/mac-tex/
           & FAQ: http://latex.yauh.de/faq/
TeX FAQ: http://www.tex.ac.uk/faq
List Post: <mailto:MacOSX-TeX at email.esm.psu.edu>





More information about the macostex-archives mailing list