Applescript to export selected groups in the Bookends bibliography management software to bibtex files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@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 thatdo shell script fixLineEndings
is run irrespective of the DEBUG state... Debugging Applescript is indeed a pain however!!!