Converting Author-date formatted citations in Word back to citekeys
Posted: Thu Jun 03, 2021 1:45 am
I had a manuscript in Word which had finalised citations as plain text in author-date format (created by another bibliography system) and I wanted to get them back to temporary citations that could be scanned by Bookends. This ruby script takes selected text like this in Word:
and pastes this over it:
i.e. reformatted into citekeys so Bookend can successfully scan it. It checks if the citekey is present in the bookends database, and also adds multiple possible citekeys if the source is ambiguous. To use it you need to select some text in Word, then trigger the script using something like Alfred and it pastes back the temp citations. This is using my preferred style of [] and ; delimiters. This is a quick and dirty unoptimised script that basically works with one author-date style and you need citekeys for your refs so your milage may vary! It also uses GUI scripting to copy from and paste to the host app like Word, nothing fancy.
Code: Select all
(Zaghloul et al., 2003; Liang and Freed, 2010, 2012; Freed, 2017)
Code: Select all
[zaghloul2003; liang2010; liang2012; freed2017]
Code: Select all
#!/usr/bin/env ruby
# This script copies a selection and converts formatted author-date citations back to LaTeX citekeys for rescanning, e.g. this:
# (Zaghloul et al., 2003; Liang and Freed, 2010, 2012; Freed, 2017)
# gets turned into this:
# [zaghloul2003; liang2010; liang2012; freed2017]
#
# It can handle same name, multiple year citations but cannot handle ambiguous citation; to solve this it
# basically puts all possible citation keys in so (Li et al., 2020) becomes [li2020 li2020a li2020b] - it is up to the
# user to manually solve these, but they will at least be flagged by Bookends scan.
# converts to -e line format so osascript can run, pass in a heredoc
# beware this splits on \n so can't include them in the applescript itself
def osascript(script)
cmd = ['osascript'] + script.split(/\n/).map { |line| ['-e', line] }.flatten
IO.popen(cmd) { |io| return io.read }
end
rec = osascript <<-APPL
tell application "System Events"
keystroke "c" using command down
delay 0.25
end tell
APPL
clip = %x(pbpaste)
return if clip.nil? || clip.empty?
cite = /([^\(\)\;]+)/
final = ""
keys = []
clip.scan(cite) {|c|
c = c[0].chomp.strip
c.gsub!(/ and /, ' ')
c.gsub!(/ et\.? al\.?/, '')
c.gsub!(/[\(\)\[\]\{\}\;]/, '')
parts = c.split(',')
if parts.nil? || parts.empty? || parts.length < 2
next
end
name = []
year = []
for i in 0..parts.length-2 do
parts[0].gsub!(/ \w+/,'')
name[i]= parts[0].downcase.strip.chomp
year[i] = parts[i+1].strip.chomp
end
for i in 0..name.length-1
keys = keys.push("#{name[i]}#{year[i]}")
end
}
return if keys.nil? || keys.empty?
fkeys = []
keys.each {|key|
res = osascript <<-APPL
tell application "Bookends"
set pubList to sql search "user1 REGEX '(?i)^(#{key})'"
set nlist to ""
repeat with aPub in pubList
set nlist to nlist & (citekey of aPub as string) & " "
end repeat
return nlist
end tell
APPL
if res.nil? || res.empty?
fkeys.push("?#{key}?")
else
fkeys.push(res.strip.chomp)
end
}
return if fkeys.nil? || fkeys.empty?
final = "[" + fkeys.join('; ') + "]"
%x(printf "#{final}" | pbcopy)
osascript <<-APPL
tell application "System Events"
keystroke "v" using command down
end tell
APPL