[OS X TeX] Bibliography Citations (was: New TeXShop macro: "Insert reference")
Simon Spiegel
simon at simifilm.ch
Tue Aug 24 02:28:46 EDT 2004
Just one thing to add: the next version of BibDesk will feature
Applescript and thus allow a much more improved complete citation
service. It will feature a very RefTeX like function which searches
through your .bib file and looks for author names, citekeys and
keywords. Just use any kind of \cite command, enter the term you want
(e.g. \cite{searchterm}), press F5 and you'll get a popup list of all
matching entries. I already use this combination and it's great. I
don't know when an official release will come out, but everything
needed has already been checked in, so if you're interested in that you
might want to compile a build of BibDesk yourself.
simi
On 24.08.2004, at 06:03, Matthew Hills wrote:
> Interesting to see all of these approaches to citations.
> Here's my rundown on the recent contributions:
>
> Thomas' applescript:
> - clean parsing of BibTeX files (leverages David Kotz's scripts,
> which runs BibTeX with custom style files)
> - grabs all *.bib files in project directory
> - puts a few extra files into /tmp
> - no filtering of output
>
> Joachim's TCLSH script:
> - REGEX search for key definitions in *.bib files
>
> Claus recommended BibDesk's "Complete Citation" service:
> - this seems promising if you are already using BibDesk
> - very fast to lookup entries
> - slow to cut out entries that you don't want
> - lookup is performed by title (and not author,
> although there is another service to lookup by cite key)
> - would also be nice to have some sort of browser pop up instead...
>
> In the recent spirit of the group, I'm appending an applescript that I
> wrote this
> evening while thinking about some of these things:
> - searches the project files to find the included bibliography
> files
> - the current text selection is used to filter the suggested
> BibTeX entries
> (this filtering is case sensitive, but compares against all
> fields)
>
> Any suggestions on the proper search path for the bibtex files?
> (where does
> BibTeX look for files other than the current directory?)
>
> Thanks,
> Matt
>
> PS--anyone following the "software for writing manuals" over on
> scitech at lists.apple.com?
>
>
>
> -- Applescript
> -- ---------------------------------------------------------------
> -- Cite Bibliography
> -- ---------------------------------------------------------------
> -- This script is designed to run from TeXShop
> -- and will try to open the bibliography file and
> -- show the user a list of possible items to cite.
>
> -- ----------------------------------------
> -- Properties
> -- ----------------------------------------
> -- Search Options: (list of strings)
> -- a list of strings, with possible entries:
> -- "sort" -- will sort the output -- "title" -- will
> show both the reference and the title
> property search_options : {"sort", "title"}
>
> -- cite_cmd: (string)
> -- the command that is used when placing text back into TeXShop
> -- using "\\cite" will produce "\cite{tag}" in the editor
> property cite_cmd : "\\cite"
>
> -- limit_by_selection: (true/false)
> -- If this is true, the current selection in TeXShop will
> -- be used to filter the BibTeX entries that are displayed in
> the dialog.
> -- This filtering is case-sensitive, but can match any field in
> the BibTeX -- entry (title, keywords, etc).
> property limit_by_selection : true
>
> -- front_app: (string)
> -- this is used in a number of places to make sure the dialogs
> come up in TeXShop
> property front_app : "TeXShop"
>
> -- title_delim: (string)
> -- if the "title" option is enabled, this string is used to
> separate the
> -- reference from the title displayed in the dialog box.
> property title_delim : " -- "
>
> -- ----------------------------------------
> -- Dev Notes
> -- ----------------------------------------
> -- Original Version: 8/23/2004 - mdh
> -- To-do:
> -- * can improve O() by searching for other tags
> -- while collecting project files
> -- * Should check TeX's search path when searching for files
> -- (currently only looking in project directory)
>
> on run
> try
> set search_pattern to ""
> tell application "TeXShop"
> set f to ((path of front document as string) as POSIX file)
> if limit_by_selection then
> set search_pattern to the content of the selection of the front
> document
> end if
> end tell
> tell application "Finder" to set current_folder to the container of
> (f as alias)
> set rootfile to get_project_root(f)
> set project_files to get_project_files(rootfile, current_folder)
> set bib_files to get_bib_file(project_files, current_folder)
>
> set cite_ref to query_for_citation(bib_files, search_pattern,
> search_options)
> if (cite_ref "") then
> tell application "TeXShop" -- not sure why name is needed here
> explicitly
> set the selection of the front document to (cite_cmd & "{" &
> cite_ref & "}") as string
> end tell
> end if
> on error e
> tell application front_app
> display dialog ("Error: " & e) buttons {"Okay"}
> end tell
> end try
> end run
>
> -- --------------------------------
> -- get_project_root
> -- --------------------------------
> -- given an alias to the current TeX file,
> -- will check if their is a valid *.texshop file
> -- and will return that, otherwise will return the
> -- current file
> on get_project_root(f)
> try
> set root_texshop to (f as string) & "shop"
> tell application "Finder" to set root_texshop_alias to (root_texshop
> as alias)
> set fnum to (open for access root_texshop_alias)
> set texshop_data to (read fnum as text)
> close access fnum
> tell application "Finder" to set current_folder to the container of
> (f as alias) as string
> set new_root to current_folder & texshop_data
> return (new_root as alias)
> on error e
> return f
> end try
> end get_project_root
>
> -- --------------------------------
> -- get_bib_file
> -- --------------------------------
> -- given a list of .tex files, will
> -- search for \bibliography statement(s)
> -- and return a list of aliases to bib files
> on get_bib_file(f_list, project_folder)
> set bib_filenames to {}
> set bib_files to {}
> repeat with tex_file in f_list
> set new_bib_arg to extract_tags(tex_file, "\\\\bibliography")
> -- Note that there can be multiple bib files declared:
> \bibliography{file1,file2}
> -- so we need to split these up:
> set old_delim to AppleScript's text item delimiters
> set AppleScript's text item delimiters to ","
> set new_bib_filenames to (every text item of (new_bib_arg as text))
> set AppleScript's text item delimiters to old_delim
> set bib_filenames to bib_filenames & new_bib_filenames
> end repeat
> repeat with bib_filename in bib_filenames
> try
> set new_file to ((project_folder as string) & bib_filename &
> ".bib") as alias
> if bib_files does not contain new_file then
> set bib_files to bib_files & new_file
> end if
> end try
> end repeat
> return bib_files
> end get_bib_file
>
> -- --------------------------------
> -- get_project_files
> -- --------------------------------
> -- given the head tex file, will return
> -- a list of \input files, descending into
> -- those files as needed
> on get_project_files(root_file, project_folder)
> set file_list to {root_file}
> set file_indx to 1
> repeat while file_indx ² (count (file_list))
> set input_files to extract_tags((item file_indx of file_list),
> "\\\\input")
> set k to 1
> repeat while k ² (count (input_files))
> try
> set new_file to ((project_folder as string) & ((item k of
> input_files) as string) & ".tex") as alias
> if file_list does not contain new_file then
> set file_list to file_list & new_file
> end if
> end try
> set k to k + 1
> end repeat
> set file_indx to file_indx + 1
> end repeat
> return file_list
> end get_project_files
>
> -- --------------------------------
> -- extract_tags
> -- --------------------------------
> -- given a file and a tag to search for,
> -- will return a list of the arguments to
> -- the tag.
> -- Notes:
> -- (1) will not return multi-line argument
> -- (2) does not match optional arguments e.g.,
> \mytag[optional]{arg1}
> -- (3) tag string should be escaped: eg, set tag to "\\\\input"
> -- Explanation of search_cmd:
> -- (1) remove comments
> -- (2) convert internal {}: TAG{ ...{..}...} ==> TAG{
> ...(%...)%...}
> -- (3) convert TAG{...} to "[space]%%"..."[space]%%%"
> -- (4) remove all residual {} tokens
> -- (5) restore %% and %%% to { and }, respectively
> -- (6) remove characters outside of {...} pairs
> -- (7) print out, with one set of contents per line
> on extract_tags(f, tag)
> set esc_newline to "\\
> "
> set search_cmd to " | sed -n -e '/^%/d;s/\\([^\\]\\)%.*/\\1/;/" & tag
> & "{.*}/{' -e ':A' -e 's/\\(" & tag &
> "{[^{}]*\\){\\([^{}]*\\)}/\\1(%\\2)%/g ;t A' -e 's/" & tag &
> "{\\([^}]*\\)}/ %%\\1 %%%/g;s/[}{]//g;s/ %%%/}/g;s/
> %%/{/g;s/^[^{]*{//g;s/}[^{]*$//g;s/}[^{]*{/" & esc_newline &
> "/g;s/(%/{/g;s/)%/}/g;p;}'"
> -- \\([^%]*\\)%)/{\\1}/g;p;}'"
> set fpath to quoted form of (POSIX path of f)
> set search_script to "tr '\\r' '\\n' < " & fpath & search_cmd
> set results to (do shell script search_script)
> if results = "" then
> return {}
> else
> return every paragraph of results
> end if
> end extract_tags
>
>
> -- --------------------------------
> -- query_for_citation
> -- --------------------------------
> -- given a list of bibfile aliases, will
> -- put up a dialog with a list of citations
> -- and ask the user to select an item.
> -- (see notes in parse_bibfile() for
> -- comments on search_pattern and options)
> on query_for_citation(f, search_pattern, options)
> set bib_data to parse_bibfile(f, search_pattern, options)
>
> set citation to ""
> set bib_entry_count to (length of bib_data)
> if (bib_entry_count = 0) then
> tell application "Finder" to set bib_filename to the name of (the
> first item of f)
> tell application front_app
> if search_pattern = "" then
> display dialog ("Sorry, no BibTeX entries were found in the file
> \"" & bib_filename & "\".") buttons {"Okay"}
> else
> display dialog ("Sorry, no BibTeX entries were found in the file
> \"" & bib_filename & "\" that contain the pattern \"" & search_pattern
> & "\".") buttons {"Okay"}
> end if
> end tell
> else
> if search_pattern = "" then
> set my_prompt to "Choose from among the following " &
> bib_entry_count & " BibTeX entries that were found:"
> else
> set my_prompt to "Choose from among the following " &
> bib_entry_count & " BibTeX entries that were found that contain the
> pattern \"" & search_pattern & "\":"
> end if
> tell application front_app
> set user_selection to choose from list bib_data with prompt
> my_prompt with multiple selections allowed
> end tell
>
> if user_selection false then
> set AppleScript's text item delimiters to title_delim
> set output_tags to {}
> repeat with selected_item in user_selection
> set output_tags to output_tags & (the first text item of
> (selected_item as text) as string)
> end repeat
> set AppleScript's text item delimiters to ","
> set citation to output_tags as string
> end if
> end if
> return citation
> end query_for_citation
>
> -- --------------------------------
> -- parse_bibfile
> -- --------------------------------
> -- given an alias to a bibfile, will return bibliography entries
> --
> -- If "search_pattern" is not "", will look for that pattern in
> -- entry fields and will only return matching items. This is
> -- case sensitive, so: parse_bibfile(f,"Smith",{}) will
> -- match an entry with 'Author="J. Smith"', but would
> -- not match against 'Author="J. smith"'
> --
> -- Options is a list of text items:
> -- "sort" - to sort the output
> -- "title" - to show the title
> --
> -- BUGS:
> -- (1) not robust against all bibtex definitions like
> "@string{...}"
> on parse_bibfile(f, search_pattern, options)
> if (class of f is list) then
> set fpath to ""
> repeat with f_item in f
> set fpath to fpath & " " & (quoted form of (POSIX path of f_item))
> end repeat
> else
> set fpath to quoted form of (POSIX path of f)
> end if
>
> if options contains "sort" then
> set sort_cmd to " | sort -df"
> else
> set sort_cmd to ""
> end if
>
> if options contains "title" then
> set set_title_action to "{split($0,line,\"=\");t=\"" & title_delim &
> "\" line[2]}"
> set title_cmd to "/title.*=.*/" & set_title_action & "/Title.*=.*/ "
> & set_title_action & " /TITLE.*=.*/" & set_title_action
> else
> set title_cmd to ""
> end if
>
> if search_pattern "" then
> -- Note that we handle two cases--when the search_pattern occurs
> inside the citation's first line and when it doesn't
> set limit_cmd to "/.*=.*" & search_pattern & "/{if
> (ref!=\"\"){f=1;}}"
> set def_filt_cmd to "/^[ ]*@.*{.*,/ {if(f==1){print ref
> t};split($0,line,\"{\");split(line[2],r2,\",\");ref=r2[1];f=0}/^[
> ]*@.*{.*" & search_pattern & ".*,/ {f=1}"
> else
> set limit_cmd to ""
> set def_filt_cmd to "/^[ ]*@.*{.*,/ {if(f==1){print ref
> t};split($0,line,\"{\");split(line[2],r2,\",\");ref=r2[1];f=1}"
> end if
>
> set parse_cmd to " | awk 'BEGIN { t=\"\"; ref=\"\"; f=0;}" &
> def_filt_cmd & title_cmd & limit_cmd & "END{if(f==1){print ref t}}'"
>
> set search_script to "cat " & fpath & " | tr '\\r' '\\n' " &
> parse_cmd & sort_cmd
> set results to (do shell script search_script)
> if results = "" then return {}
> return every paragraph of results
> end parse_bibfile
>
> --------------------- 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>
>
>
>
--
Simon Spiegel
Mutschellenstr. 97
8038 Zrich
Telephon: ++41 1 481 48 52
Mobophon: ++41 76 459 60 39
http://www.simifilm.ch
--------------------- 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 MacOSX-TeX
mailing list