A subroutine – example of use below – for obtaining a JSON representation of a given .plist file (supplied as a file path).
(The .plist may be a serialization of an Array or a Dict)
JSON from plist path SUBROUTINE.kmmacros (5.0 KB)
Expand disclosure triangle to view JS source
// MAIN :: IO ()
const main = () =>
either(
alert("JSON from Plist Path")
)(
jsObject => JSON.stringify(jsObject, null, 2)
)(
jsoFromPlistPathLR(kmvar.local_Plist_Path)
);
// ----------------------- JXA -----------------------
// 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
);
};
// jsoFromPlistPathLR :: FilePath -> Either String JSObject
const jsoFromPlistPathLR = fp =>
either(
() => either(
() => Left(
`Not legible as plist Dict or Array:\n\n\t${fp}`
)
)(Right)(
arrayFromPlistPathLR(fp)
)
)(Right)(
dictFromPlistPathLR(fp)
);
// dictFromPlistPathLR :: FilePath -> Either String Dict
const dictFromPlistPathLR = fp => {
const
maybeDict = $.NSDictionary
.dictionaryWithContentsOfFile(
$(fp).stringByStandardizingPath
);
return maybeDict.isNil()
? Left(`Not legible as plist Dict:\n\t${fp}`)
: Right(ObjC.deepUnwrap(maybeDict));
};
// arrayFromPlistPathLR :: FilePath -> Either String Array
const arrayFromPlistPathLR = fp => {
const
maybeArray = $.NSMutableArray
.arrayWithContentsOfFile(
$(fp).stringByStandardizingPath
);
return maybeArray.isNil()
? Left(`Not legible as plist Array:\n\t${fp}`)
: Right(ObjC.deepUnwrap(maybeArray));
};
// --------------------- GENERIC ---------------------
// Left :: a -> Either a b
const Left = x => ({
type: "Either",
Left: x
});
// Right :: b -> Either a b
const Right = x => ({
type: "Either",
Right: x
});
// either :: (a -> c) -> (b -> c) -> Either a b -> c
const either = fl =>
// Application of the function fl to the
// contents of any Left value in e, or
// the application of fr to its Right value.
fr => e => "Left" in e
? fl(e.Left)
: fr(e.Right);
// bindLR (>>=) :: Either a ->
// (a -> Either b) -> Either b
const bindLR = lr =>
// Bind operator for the Either option type.
// If lr has a Left value then lr unchanged,
// otherwise the function mf applied to the
// Right value in lr.
mf => "Left" in lr
? lr
: mf(lr.Right);
// ---
return main();
Example
JSON from plist path TEST.kmmacros (3.0 KB)


