While organising files in preparation for moving to a shiny new Mac, I wanted to compile a list of all the Safari reading list entires I'd made over the years. The data for this is held in a .plist file - Apple's JSON like text/binary format - and is fairly easy to extract.
To do so, npm init
, then install a plist parser. This translates the plist data into a nice JSON object. I used bplist-parser, which can be installed with npm i bplist-parser
. Then create an index.js file and fill it with the following code:
1 const fs = require("fs");2 const bplist = require("bplist-parser")(async () => {3 const obj = await bplist.parseFile(4 "/Users/YOUR_NAME/Library/Safari/Bookmarks.plist"5 );67 const buildList = (rawList) => {8 const resArr = [];9 rawList[0].Children.map((x) => {10 const resStr = `${x.URIDictionary.title} - ${x.URLString}`;11 resArr.push(resStr);12 });13 return resArr.join("\n");14 };1516 const bookmarksBar = obj[0].Children.filter((x) => x.Title === "BookmarksBar");17 const bookmarksMenu = obj[0].Children.filter((x) => x.Title === "BookmarksMenu");18 const readingList = obj[0].Children.filter(19 (x) => x.Title === "com.apple.ReadingList"20 );2122 // change the argument to one of the three above to change the output23 const list = await buildList(readingList);2425 fs.writeFileSync("./reading_list", list);26 })();27
Make sure to allow your terminal file access (in Settings => Security & Privacy => Privacy), insert your profile name where the 'YOUR NAME' placeholder is, then run node index.js
and your list will be output.