Skip to content

Instantly share code, notes, and snippets.

@naupaka
Last active November 15, 2021 22:15
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save naupaka/3637da8f1449a279a79e643575a7c2e1 to your computer and use it in GitHub Desktop.
Save naupaka/3637da8f1449a279a79e643575a7c2e1 to your computer and use it in GitHub Desktop.
Applescript to export selected groups in the Bookends bibliography management software to bibtex files
#!/usr/bin/osascript
(*
Script written by Naupaka Zimmerman
March 17, 2017
MIT License
Copyright (c) 2017 Naupaka Zimmerman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
##########################################
##########################################
This is an applescript to export a set of groups (static or smart) from Bookends to
bibtex files. The idea is that it could be incorportated into a makefile for building a
manuscript, for example. It is meant to be run from the command line, with
arguments. Bookends needs to be open to the library you want to export from.
Usage:
osascript bookends_to_bibtex.scpt "Text pattern of groups to export" "Path to export .bib files to"
If you want to export all groups in a folder, be sure to use a trailing slash, e.g.:
osascript bookends_to_bibtex.scpt "Manuscripts/" "/Users/steve/Desktop/"
You can also add a debug option to see what groups should be being exported:
osascript bookends_to_bibtex.scpt "Manuscripts/" "/Users/steve/Desktop/" DEBUG
Defaults (if called with no parameters):
osascript bookends_to_bibtex.scpt "Manuscripts/" "Path to script file"
*)
(*
Function to split returned values on a character into an array
and also to parse out only those that match the query string.
E.g. if you have a folder of groups called "Manuscripts/", this will
find all groups with that word in their path and export them.
It will also work with the name of just a single specific group.
Based on code from this page:
http://erikslab.com/2007/08/31/applescript-how-to-split-a-string/
*)
on theSplit(theString, theDelimiter, theExportText)
-- save delimiters to restore old settings
set currentDelimiters to AppleScript's text item delimiters
-- set delimiters to delimiter to be used
set AppleScript's text item delimiters to theDelimiter
-- create the array
set theGroupArray to every text item of theString
-- restore the old setting
set AppleScript's text item delimiters to currentDelimiters
-- return the result
set theSelectedList to {}
repeat with myGroup in theGroupArray
if ((myGroup as string) contains theExportText) then
-- use sed to strip out all folder names from the group name returned from bookends
-- this leaves only group name
set thecommandstring to "echo \"" & myGroup & "\"| sed \"s/.*\\/\\(.*\\)/\\1/\"" as string
set sedResult to do shell script thecommandstring
-- if there's a match, append parsed group name onto end of list
set end of theSelectedList to sedResult
end if
end repeat
return theSelectedList
end theSplit
on run argv
--start time
set originalT to (time of (current date))
-- store default delimiters
set oldDelimiters to AppleScript's text item delimiters
-- default: no DEBUG output
set DEBUG to false
-- crude check for existance of command line arguments
if argv contains "DEBUG" then
set DEBUG to true
end if
if (count of argv) > 1 then
-- this is if there are both groups and path
set myGroupsToExport to item 1 of argv
set myPath to item 2 of argv
else if ((count of argv) > 0 and (count of argv) < 2) then
-- this is if there is only one argument, the groups to match
set myGroupsToExport to item 1 of argv
--Export to folder script is in as default if nothing specified
--http://stackoverflow.com/questions/24152552/relative-file-paths-with-applescript
--from:https://superuser.com/questions/670893/get-path-of-parent-folder-of-script-location-applescript/670898#670898
tell application "Finder"
set myPath to POSIX path of (container of (path to me) as text)
end tell
else
-- this is if there are neither
set myGroupsToExport to "Manuscripts/"
-- Export to folder script is in by default if nothing specified
-- http://stackoverflow.com/questions/24152552/relative-file-paths-with-applescript
--from:https://superuser.com/questions/670893/get-path-of-parent-folder-of-script-location-applescript/670898#670898
tell application "Finder"
set myPath to POSIX path of (container of (path to me) as text)
end tell
end if
tell application "Bookends"
-- get a list of all groups in open library
set allGroups to «event ToySRGPN» given «class PATH»:"true"
-- split up those groups into elements of an array
-- 'return' here, as the middle parameter, is the return or newline character
set myGroupArray to my theSplit(allGroups, return, myGroupsToExport)
end tell
if DEBUG then
-- set output string based on parsed input parameters or defaults
set AppleScript's text item delimiters to ", "
set output to ("Pattern for groups to export: " & myGroupsToExport & "
" & "Path to export to: " & myPath & "
" & "Groups exported: " & myGroupArray as string)
set AppleScript's text item delimiters to oldDelimiters -- change back to default
end if
-- loop over each folder matching the pattern and export each to a bibtex file
repeat with myGroup in myGroupArray
set thisFile to (myPath & (myGroup as string) & ".bib") as POSIX file
set quotedName to quoted form of POSIX path of thisFile
tell application "Finder"
if exists thisFile then
delete thisFile --we have to delete the file first, as open for access does not!
end if
end tell
-- from: http://stackoverflow.com/questions/3780985/how-do-i-write-to-a-text-file-using-applescript
set myFile to open for access thisFile with write permission
try
tell application "Bookends"
-- get a list of all unique reference IDs in the specified group
set myListString to «event ToySRUID» myGroup as string
-- convert to list
set AppleScript's text item delimiters to return
set myList to text items of myListString
-- set up the loop to batch fetch sets of references,
-- in theory this should be more efficient,
-- and saves around 1-2 seconds per 1000 exported
set steps to 25
set listLength to length of myList
set nLoop to round (listLength / steps) rounding up
set thisLoop to 1
-- iterate through list writing each entry
repeat while thisLoop is less than or equal to nLoop
-- set the batch index range
set startindex to (steps * thisLoop) - (steps - 1)
set endindex to (steps * thisLoop)
if endindex is greater than listLength then
set endindex to listLength
end if
-- select current batch of items
set thisListItems to items startindex thru endindex of myList
set thisList to thisListItems as string
-- fetch the BibTeX
set myBibTex to «event ToySGUID» thisList given «class RRTF»:"false", string:"bibtex"
-- write out as UTF-8, from: http://macscripter.net/viewtopic.php?id=24534
write myBibTex to myFile as «class utf8»
-- update the loop number
set thisLoop to thisLoop + 1
end repeat
end tell
on error
try
close access myFile
set AppleScript's text item delimiters to oldDelimiters
end try
return false
end try
close access myFile
--run our special code to enforce case in titles, and fix line endings to \n
set fixCase to ("fixCase.rb " & quotedName)
set ssout to do shell script fixCase
\" > temp.bib; mv temp.bib \"" & (myGroup as string) & ".bib\"" as string)
if DEBUG then
set newT to (time of (current date))
set diffT to newT - originalT
return output & "\n" & ssout & "\n\nBookends BiBTeX export took " & diffT & " seconds in total"
end if
set AppleScript's text item delimiters to oldDelimiters
end repeat
end run
#!/usr/bin/env ruby
#encoding: utf-8
Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8
require 'tempfile'
require 'fileutils'
tstart = Time.now
infilename = ARGV[0]
out = "===> Parsing BiBTeX file #{infilename} "
fail "Please specify an existing file!" unless infilename and File.exist?(infilename)
#only wrap IF it is already uppercase
keepCase = [
"ON",
"OFF",
"M", #magnocellular
"P", #parvocellular
]
# always force to be uppercase
enforceCase = [
"V1",
"V2",
"V3",
"V4",
"V4d",
"V4v",
"V5",
"V6",
"V6a",
"MT",
"MST",
"DNA",
"RNA",
"TRN",
"RTN",
"FEF",
"mPFC",
"VIP",
"mGlu1",
"GluR",
"NMDA",
"AMPA",
"GABA",
"GABAergic",
"LGN",
"dLGN",
"EEG",
"AAV",
"TMS",
"MEG",
"2D",
"3D",
"HMAX"]
temp_file = Tempfile.new('foo')
begin
File.open(infilename, 'r') do |file|
file.each_line("\r") do |line|
if line.match(/^title/)
keepCase.each do | k |
line.gsub!(/\b#{k}\b/,"{#{k}}") #case sensitive
end
enforceCase.each do | e |
line.gsub!(/\b#{e}\b/i,"{#{e}}") #case insensitive
end
end
line.gsub!(/\r+$/, "\n")
temp_file.puts line
end
end
temp_file.close
FileUtils.mv(temp_file.path, infilename)
ensure
temp_file.close
temp_file.unlink
end
tend = Time.now - tstart
out += "... parsing took " + tend.to_s + "s"
puts out
@iandol
Copy link

iandol commented Mar 22, 2017

@naupaka on line 190 you have an if DEBUG to show the fixLineEndings shell command, but I think that is no longer needed right, and will cause different .bib results? You could append the text to the output string, ensuring that do shell script fixLineEndings is run irrespective of the DEBUG state... Debugging Applescript is indeed a pain however!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment