Splitting PDFs into single pages using Automator

Every quarter at Mozilla managers get an automatically generated PDF report that we need to split into single pages.

The first time, I did that with Preview.app… dragging each page out. Slow, but reliable! It was only two pages, so it’s doable.

The second time, I automated it, using THE AUTOMATOR!

This app was introduced in 2005 in Mac OS X and I’ve never actually used it for good. Well, I’m glad I finally found some good use for it, as these reports are getting longer and I would rather spend my time on something more interesting than dragging thumbnails around 🙂

So, instructions if you don’t like watching videos:

  1. Open Automator
  2. Create a new workflow
  3. Select Library… Ask For Finder Items… double click to add it to the workflow
  4. Select PDFs… Split PDF
  5. And RUN IT, using the bottom on the top right!

It will ask you for the PDF you want to split, then it will split it in pages and place it on the Desktop.

You could get fancier, and you probably still need to rename the individual files, but I haven’t researched that bit yet.

Happy (and fast) splitting!

Google Calendar shortcuts and tricks

Since I started managing people, I spend a lot of time looking at my calendar!

Here’s some shortcuts I use a lot:

  • view:
    • m: month view
    • w: week view
    • d: day view
  • navigation:
    • n: next (if you’re in month view, it jumps to next month, if you’re in week view, it jumps to next week, etc)
    • p: previous
    • t: jump to today

I have the calendar pinned on the first tab, so ⌘+1 always brings me to it (I think it’s CTRL+1 in Windows and Linux).

The first thing I do in the morning is to look at what’s in for today–this way I make sure I don’t forget to attend important meetings because I get deep down into something else and then I forget. So I will press “d” and “t” to get the calendar to ‘day view’ plus ‘today’.

I use the other shortcuts to quickly flip between dates when I’m booking new events or to find what is upcoming.

There are also shortcuts to create and edit events but I found them not very useful as you still have to modify the time and date of event anyway-I find it easier to use the mouse to schedule this.

Copy using the command line without overwriting existing files

I learnt about cp‘s -n (or “no clobber”) option that lets you copy, but not overwrite files that already exist:

cp -Rvn folderA folderB

The above would Recursively copy the contents of folderA into folderB, and print a message per file it copies (with the v option). Great to know when things get stuck or interrupted 🙂

It’s quite useful when trying to copy from something like a folder in a remote drive that keeps disconnecting. So if the network times out you can always run the command again after reconnecting, and it will skip files that are already there.

Note that if a file has been partially copied, then cp will skip it the next time and not complete the download. So don’t use this method for stuff that requires some degree of integrity–you’d better reach for tools such as scp.

Don’t force users to install node modules globally when you can avoid that

How often have you seen instructions for installing a project that are something like this?

git clone https://wherever/the/project/is
cd cloned_folder
npm install -g gulp # <-- 😱

(or, instead of gulp, any other utility that the project requires for development)

This is not a good idea. You’re installing the same version of a utility globally, and perhaps the project has not been tested with that version. Things might break or even worse, work not-so-well in a strange, undebuggable way!

Don’t do it.

A better way is to use npm scripts, which belong to the project, and specify development dependencies in package.json, so when you run npm install, it also installs devDependencies locally to the projects’ node_modules folder. This keeps everything under control and does not pollute other people’s computers global space.

So, for example, if a project was asking users to run npm install -g gulp, they should do this instead:

  1. Install gulp locally as a development dependency, saving it to package.json:
    npm install --save-dev gulp
  2. Add a new entry to the scripts array in package.json:
    "build": "gulp"
  3. Ask users to run
    npm install

    the first time. And

    npm run build

    each time they need to build the project

The reason this works is because when npm runs a script, it modifies the current PATH variable to add node_modules/.bin, which contains any binaries that you installed as part of your modules. So your computer will search for binaries starting in the .bin folder, before searching in any other default location for binaries in your computer (e.g. /usr/bin)

You can find more documentation about this behaviour in the run-script page of the npm manual. I really encourage you to read it as it has lots of good stuff and Things You Wished Had Known Before 🙂

And in case it makes things clearer, this is how a hypothetical package.json would look before:

{
  devDependencies: {}
}

And after:

{
  devDependencies: {
    "gulp": "12.34.56"
  },
  scripts: {
    "build": "gulp"
  }
}

With this, the devDependency is clearly stated on the package.json file, the project developer will be developing with that version, and will not get surprises! (and the users of the module won’t either).

Another advantage of this approach is that you are not tying the project to a specific utility.

If you decide to use grunt instead of gulp later on, you just need to do whatever changes you need (Gruntfile instead of Gulpfile, edit package.json etc), and yet users of the project will still start the build process with npm run build.

It’s invisible to them (except perhaps running npm install again)!

You’re hiding internals that they do not necessarily need to know about, so it’s a good abstraction. Seriously—you won’t even need to update your getting started guide! Good stuff.

Hope that helps!

If you want to learn even more cool npm scripts tricks, I recommend Kate’s talk and accompanying post. Actually, I just realised she explained the same thing I did, so here’s her take, haha!