A first draft of a script which (on this system at least) copies both Name and Address from the selection in Accordance.app (for reading Biblia Hebraica, Septuagint, Mishna etc etc).
A couple of notes:
- Paste into the
Get Address
script field (no need for a separateGet Name
script) - Take care to copy the whole script from the opening comment line
//JavaScript
(needed by Hook to identify the language), down to:})();
//JavaScript
(() => {
'use strict';
// Rob Trew 2019
// Ver 0.02
// Use accord:// scheme (better for local links)
// rather than https://accordance.bible/link
// (better for internet sharing)
const blnPreferAccordScheme = true;
// main :: IO ()
const main = () => {
const
se = Object.assign(Application('System Events'), {
includeStandardAdditions: true
}),
procs = se.applicationProcesses.where({
name: 'acord'
});
return either(alert('Accordance link'))(
x => blnPreferAccordScheme ? (
x.replace(
'https://accordance.bible/link/',
'accord://'
)
) : x
)(
bindLR(
0 < procs.length ? (
Right(procs.at(0).windows)
) : Left('Accordance application not found.')
)(ws => bindLR(
0 < ws.length ? (
Right(ws.at(0))
) : Left('No windows found for Accordance')
)(w => Right(
('[' + apList([k => (
menuItemClicked('acord')(['Edit', 'Copy As', k]),
delay(0.1),
se.theClipboard()
)])(['Reference', 'Location URL']).join('](') + ')')
))));
};
// -------------JavaScript for Automation--------------
// alert :: String -> String -> IO String
const alert = title => s => {
const
sa = Object.assign(Application('System Events'), {
includeStandardAdditions: true
});
return (
sa.activate(),
sa.displayDialog(s, {
withTitle: title,
buttons: ['OK'],
defaultButton: 'OK'
}),
s
);
};
// Click an OS X app sub-menu item
// 2nd argument is an array of arbitrary
// length (exact menu item labels, giving full path)
// menuItemClicked :: String -> [String] -> IO Bool
const menuItemClicked = strAppName => lstMenuPath => {
const intMenuPath = lstMenuPath.length;
return intMenuPath > 1 ? (() => {
const
appProcs = Application('System Events')
.processes.where({
name: strAppName
});
return appProcs.length > 0 ? (
Application(strAppName)
.activate(),
lstMenuPath.slice(1, -1)
.reduce(
(a, x) => a.menuItems[x].menus[x],
appProcs[0].menuBars[0].menus.byName(
lstMenuPath[0]
)
)
.menuItems[lstMenuPath[intMenuPath - 1]].click(),
true
) : false;
})() : false;
};
// GENERIC FUNCTIONS ----------------------------
// https://github.com/RobTrew/prelude-jxa
// Left :: a -> Either a b
const Left = x => ({
type: 'Either',
Left: x
});
// Right :: b -> Either a b
const Right = x => ({
type: 'Either',
Right: x
});
// apList (<*>) :: [(a -> b)] -> [a] -> [b]
const apList = fs =>
// The sequential application of each of a list
// of functions to each of a list of values.
xs => fs.flatMap(
f => xs.map(f)
);
// bindLR (>>=) :: Either a -> (a -> Either b) -> Either b
const bindLR = m => mf =>
undefined !== m.Left ? (
m
) : mf(m.Right);
// either :: (a -> c) -> (b -> c) -> Either a b -> c
const either = fl => fr => e =>
'Either' === e.type ? (
undefined !== e.Left ? (
fl(e.Left)
) : fr(e.Right)
) : undefined;
// MAIN ---
return main();
})();