Automator Workflow To Copy Downloaded Music To iTunes and Then Trash It

Posted on: 2012-02-09 07:27:45

I enjoy being lazy and enjoy listening to podcasts. This allows me to be really lazy!

Download the workflow


  1. Unzip the file.
  2. Copy the contents to \~/Library/Workflows/Applications/Folder Actions
  3. Option-click on the Downloads folder and choose Services -\> Folder Actions Setup…
  4. Select the workflow and make sure it is checked:
Continue reading...

Alfred Scripture Lookup for Bible Translations

Posted on: 2011-11-27 21:40:41

Lately I've had a big appreciation in the number of different translations and often find myself wanting to look up a verse very quickly. Here are a handful of easy to use scripture reference custom searches for use with "Alfred":

<a href="alfredapp://customsearch/NIV%20Scripture%20Reference/niv/ascii/url={query}&qs_version=NIV">NIV <a href="alfredapp://customsearch/The%20Message%20Scripture%20Reference/msg/ascii/url={query}&qs_version=MSG">The Message <a href="alfredapp://customsearch/NKJV%20Scripture%20Reference/nkjv/utf8/url={query}&qs_version=NKJV">New King James <a href="alfredapp://customsearch/KJV%20Scripture%20Reference/kjv/ascii/url={query}&qs_version=KJV">King James <a href="alfredapp://customsearch/ESV%20Bible%20Reference/esv/utf8/url={query}">ESV <a href="alfredapp://customsearch/NASB%20Scripture%20Reference/nasb/utf8/url={query}&qs_version=NASB">NASB

All but the ESV use "": as the search site. Also, if you are as detail-oriented as I am, you may want these handy logos to use as well:

Continue reading...

Finally! An HTML to PDF Workflow That Works

Posted on: 2011-11-05 17:56:27

It is a problem that is as old as computers: making the representation of text and data beautiful. At Classy Llama, we have been searching for a way to make the massive amounts of information we work with accessible, easy to manage, and also beautiful. Here is a workflow that we have started using. Perhaps you might find it useful too.

Some Background

What we want is a system that is three things: accessible, consistent, and easy to use. First, accessible means that the means by which documents can be generated must be easily accessible. Adobe InDesign is not accessible in that it is expensive. Plain Text is accessible because you can produce it on any platform. Consistency refers to the quality and ability to reproduce that quality over and over again. InDesign can produce documents of consistent quality because that is what it was designed to do. So can LaTeX for that matter. Lastly, ease of use is paramount because without it, nobody would use it. LaTeX and Illustrator are great examples of items that are not easy to use at all. While Word & Pages are fairly easy to use.

There are many factors that can affect this, but ultimately we know that we needed to settle on two things:

  1. How documents were going to be generated.
  2. Format of the the finished file.

Ultimately, we know that PDF was the only reasonable answer for #2. The answer to #1 gets a little more interesting. That is why we are here!

I really wanted a reason to do a Venn Diagram. So here it is:


The Software

When starting off, I really knew in the back of my mind that a workflow that started with HTML and ended with PDF was going to be the best one. Why? Simply because it meets all three requirements. There are only a handful of people in the building who do not know HTML. The ones who do not can be worked around. So, with HTML as the source, how do we get to the PDF?

Giving Safari a Spin

The initial idea was to just generate a good looking file and then print it straight to PDF with Safari:


  1. Make sure backgrounds are enabled.
  2. Turn off the headers and footers.
  3. Save as PDF...

In a pinch, Safari can definitely take an HTML document and make it a solid-looking PDF. But the thing is, we did not want it to look like a printed web page. We wanted it to look professional. Safari lacked some some functionality that we really wanted. Control over headers and footers was something we really had to have. It's not as easy to do in Safari as I had hoped.

What about Firefox?

Firefox was about the same as Safari except that Firefox gives you some more control over the header and the footer:


This is fine and good, but still too limiting.

PHP, Web Services, & Scripts to the Rescue?

There are several options for building PDF documents. HTML2PDF converts HTML documents to PDF as a PHP library. Others are web services. There are yet more scripts and libraries that provide PDF building as an API inside of PHP. I found other scripts that also claimed to convert HTML to PDFs in a CLI package. None that I tried seemed to work quite right (or at all). More dead ends. At this point, I was about to give up.

We Need an HTML Renderer

The only thing that would really work is if you could find something that rendered the HTML like a browser could. I remember trying Firefox's “Command Line Print Interface,” but to no avail. Surely there was something else. That something else was wkhtmltopdf.

Finally, a Solution!

wkhtmltopdf actually works: a program that contains the webkit rendering system (just like Safari uses) but has been put into a format that specializes in exporting postscript and PDF output of web pages. It is totally designed for this purpose. Finally, a solution that works! Proper headers and footers. Table of contents inside of the PDF and bookmarks in the file. Full use of CSS to control every aspect of the rendering (including custom fonts via font-family and @font-face). A whole slew of command line options that allow you to control paper size, and set nearly every possible thing you would need. So far, I've found in nearly perfect. There have been a couple of gotchas, though.

Little Square Boxes

One of the first things to catch my eye was that occasionally there were little squares in generated documents. They weren't there when the document was printed, but when viewing in Acrobat or Preview, they were definitely visible. After much sleuthing, I discovered that the square boxes were null glyphs that had somehow managed to make their way into the various strings in the document. With a little help from pdftk, those boxes are no longer a problem:

  1. Use pdftk to uncompress the PDF.
  2. Run the resulting file through sed to remove the null glyphs (lines containing ‘Td <0000> Tj').
  3. Use pdftk once more to compress the PDF.

Here is the shell script snippet:

pdftk output.pdf cat output - uncompress | sed '/Td <0000> Tj/d' | pdftk - cat output output.pdf compress

Easier Headers & Footers

The last nagging bit was that we need to be able to have document versions and potentially other info that can be easily updated. The way that wkhtmltopdf is set up by default is that the headers and footers have a specific set of variables that come to them. Mainly just page number information and information about the current “section” of the document you are in. But versioning the document did not seem to be supported out of the box. What I wanted to be able to do was set the version number of the document in the document itself. That would be ideal.

One of the awesome and super-extensible things about wkhtmltopdf is that the headers and footers can be specified as source files. Source files means URLs. URLs mean request variables. The page number information already gets passed as get variables to the document. Those are then parsed out via JavaScript. So, I gave it a shot:

wkhtmltopdf \\ -s Letter \"untitled.html\" \\ --header-html \"header.html?something=value\" \\ --footer-html \"footer.html?something=value\" output.pdf

Which did not work. Passing the query arguments meant that it wanted a real URI. So since these were local files, why not try:

THISDIR=`pwd` wkhtmltopdf \\ -s Letter \"untitled.html\" \\ --header-html \"file://$THISDIR/header.html?something=value\" \\ --footer-html \"file://$THISDIR/footer.html?something=value\" output.pdf

Which worked perfectly. Still need to get the information about the document from the source HTML into the header and footer files. Now PHP finally comes to the rescue with this little snippet:

EXTRAVARS=`php -r \"echo urldecode(http_build_query(get_meta_tags('untitled.html')));\"`

This little guy takes this (from the source HTML document):

It's important to note that the spaces must stay intact. wkhtmltopdf does not decode them for you. Just escape them in your command line arguments and it will be fine. You will also need to add these variable names into the stock header and footer template that wkhtmltopdf gives you. It will look like this:

<script> function subst() { var vars={}; var'&amp;'); for (var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);} var x=['title','version','project','client','frompage','topage','page','webpage','section','subsection','subsubsection']; /* Added new variables here */ for (var i in x) { var y = document.getElementsByClassName(x[i]); for (var j=0; j
Page of

A little bit of bash scripting and now we have something like this:

#!/bin/bash # EDIT THIS - This points to your source file HTMLFILE=\"my_pretty_file.html\"

Where are we?

THISDIR=$(pwd -P)

Grab the title of the HTML document from the source.

RAW_TITLE=grep -e '' \"$HTMLFILE\" | sed -E 's/<\\/?[^>]+>//g' ENTITY_TITLE=php -r \"echo html_entity_decode('${RAW_TITLE}');\"

Build the extra variables to add to the footer and header.

EXTRAVARS=php -r \"echo urldecode(http_build_query(get_meta_tags('$HTMLFILE')));\" EXTRAVARS="${EXTRAVARS}&title=${RAW_TITLE}"; # Add the title

Generate the document.

wkhtmltopdf -q \ --no-pdf-compression -s Letter \ --header-html "file://$THISDIR/header.html?$EXTRAVARS" \ --footer-html "file://$THISDIR/footer.html?$EXTRAVARS" - | sed '/Td <0000> Tj/d' > "$ENTITY_TITLE.pdf"

Final Thoughts

This is a work in progress, but it is now a viable option for generating beautiful, consistent documents from HTML. You could have a shared server that would host your templates, CSS, fonts, etc and the only tools necessary would be the scripts, wkhtmltopdf, pdftk, and your source file. Not bad for a free setup.

With something like pandoc, you need not be limited to just HTML. You could easily modify the script above to take your source file and push it through pandoc and then pass it on down to wkhtmltopdf. The possiblities are limitless. So, what are you waiting for? Go try it out!


Upon further use, I discovered an unintended side-effect: use of pdftk causes the bookmarks in the file to disappear. However, it turns out that by passing the --no-pdf-compression flag removes the need to decompress the PDF file before removing the extra characters.

I'm still looking for a way to append extra files (PDF, HTML, or otherwise) into the file and utilize bookmarks. Any thoughts?

Continue reading...

Attending x.commerce Innovate Developer Conference

Posted on: 2011-10-10 14:02:09

Tomorrow, several other "Classy Llamas": and I will be heading to San Francisco to attend the "x.commerce": "Innovate Developers Conference":! This is very exciting for a couple of reasons:

The idea of x.commerce is very ambitious. It is the first platform that aims to be first full-spectrum, end-to-end eCommerce platform. It's exciting to be a part of something like that.

Secondly, Magento will be testing their "Beta Developer Certification Exam": I've been a big supporter of this and it will be awesome to be one of the first to take this new exam and become a Certified Magento Developer!

Lastly, it will be great to meet & greet the other Magento developers and partners.

We'll be updating our "Classy Llama blog": with updates as we can!

Continue reading...

God & Us: Father & Son

Posted on: 2011-07-24 15:13:30

Watching my son gives me insight into how our own relationship between our heavenly father and us looks.

It is hard to count the number of times he has done something that I obviously wished him not to do -- even while under constant supervision. He knows that what he does goes against my wishes. When I call him he does not come to me with childlike innocence... he quickly stops what he is doing and looks at me with these eyes that seem to say "I was not doing what you think I was doing!" Whoever says children are full of innocence and good must not have met my child! He knows full that his actions are not what I desire and when caught in the act he quickly tries to hide his actions.

He definitely gets that from me.

How many times have I done something and then half a moment later realized that our Father is watching over me? I'd do good to, like my son, quickly throw the object with which I've taken an interest in as far away as possible. Sadly, the son trumps the father on this one. The one think thankfully he has not yet learned is pride!

I thank God that he disciplines me just like I discipline my son.

Continue reading...

Arrays With UTF-16 Strings Will Give You Headaches

Posted on: 2011-05-19 10:13:38

Today I was working with some CSV files using PHP's "fgetcsv": and "array_search": functions.

I had a row like this:


Looks normal, right?

But when I was running array_search('cus_no', $headerRow) it would return FALSE. What is the deal?

Digging deeper, "print_r()": returned exactly what expected:

    [0] => cus_no
    [1] => first_name
    [2] => last_name
    [3] => full_name
    [4] => fax_no
    [5] => phone_no
    [6] => e_mail

Okay. Scratch head. Sip coffee. Deep breath. What is going on here?!

Lets see what "var_dump()": says:

array(7) {
  string(12) \"cus_no\"
  string(21) \"first_name\"
  string(19) \"last_name\"
  string(19) \"full_name\"
  string(13) \"fax_no\"
  string(17) \"phone_no\"
\" string(15) \"e_mail

Whoa. That is strange. Why is that quote at the beginning of the line? Check eyes. Sip coffee.

"var_export()": had something much different to report:

array (
  0 => 'c' . \"\\0\" . 'u' . \"\\0\" . 's' . \"\\0\" . '_' . \"\\0\" . 'n' . \"\\0\" . 'o' . \"\\0\" . '',
  1 => '' . \"\\0\" . 'f' . \"\\0\" . 'i' . \"\\0\" . 'r' . \"\\0\" . 's' . \"\\0\" . 't' . \"\\0\" . '_' . \"\\0\" . 'n' . \"\\0\" . 'a' . \"\\0\" . 'm' . \"\\0\" . 'e' . \"\\0\" . '',
  2 => '' . \"\\0\" . 'l' . \"\\0\" . 'a' . \"\\0\" . 's' . \"\\0\" . 't' . \"\\0\" . '_' . \"\\0\" . 'n' . \"\\0\" . 'a' . \"\\0\" . 'm' . \"\\0\" . 'e' . \"\\0\" . '',
  3 => '' . \"\\0\" . 'f' . \"\\0\" . 'u' . \"\\0\" . 'l' . \"\\0\" . 'l' . \"\\0\" . '_' . \"\\0\" . 'n' . \"\\0\" . 'a' . \"\\0\" . 'm' . \"\\0\" . 'e' . \"\\0\" . '',
  4 => '' . \"\\0\" . 'f' . \"\\0\" . 'a' . \"\\0\" . 'x' . \"\\0\" . '_' . \"\\0\" . 'n' . \"\\0\" . 'o' . \"\\0\" . '',
  5 => '' . \"\\0\" . 'p' . \"\\0\" . 'h' . \"\\0\" . 'o' . \"\\0\" . 'n' . \"\\0\" . 'e' . \"\\0\" . '_' . \"\\0\" . 'n' . \"\\0\" . 'o' . \"\\0\" . '',
' . \"\\0\" . '',0\" . 'e' . \"\\0\" . '_' . \"\\0\" . 'm' . \"\\0\" . 'a' . \"\\0\" . 'i' . \"\\0\" . 'l' . \"\\0\" . '

Whoa! Now that is strange. Looks like there are two characters per... wait a sec!


Should have known. UTF-16. Friends don't let friends use non-multibyte functions on multibyte datas! It was putting null characters into the string internally? Who knows. I'm sure the PHP source code would probably enlighten me on this. But no time! Those CSV files aren't going to read themselves!

Update: My fellow llama Jonathan Hodges noticed something I failed to see: The length of the strings in var_dump() are double the size they should be:

array(7) {
  string(*12*) \"cus_no\"
Continue reading...

Moving the Cursor in OSX's CLI

Posted on: 2011-05-16 20:58:33

Just found this "great little article over at": about how you can use meta-b and meta-f to use backwords and forwards by words in the CLI. Since there is no meta key, you have to use ?-b and ?-f (escape as meta).

Optionally, you can set the option key as meta in Terminal's settings:


Continue reading...

Easily View Magento Layout with Alan Storm's Layoutviewer

Posted on: 2011-05-16 16:22:56

<a href="">Alan Storm has a great module called <a href="">Layoutviewer that is great for front-end developers.  It allows you to see the layout that Magento will use to render a page. This can be useful to debug what layout updates have been applied to a page.  One way or another, it usually ends up in most of my development sites.

Here is a nice little shell script you can copy-and-paste or download to easily add it to your project:

#/bin/bash VIEWER_HTTP_DOWNLOAD=\"\"

If we are in the root, then we need to go into app/code/local.

if [ -f "index.php" ]; then cd app/code/local; fi

curl -so - $VIEWER_HTTP_DOWNLOAD | tar xvzf -

( cat <<'ConfigFile'

true local

ConfigFile ) > ../../etc/modules/Allanstormdotcom_Layoutviewer.xml

Also, here is a little bookmarklet that you can use to show the formatted XML for a page using the installed module:

<a href="javascript:window.location.href = window.location.protocol + '//' + window.location.hostname + window.location.pathname + ('' ? '?showLayout=page&showLayoutFormat=text' : + '& showLayout=page&showLayoutFormat=text');">Display Layout

Just drag it to your bookmarks bar!

You can also download the attached shell script. It will (from the htdocs folder for your Magento site) download the layoutviewer module.

Continue reading...

Leaps, Blessings, and Springfield, Missouri

Posted on: 2011-01-09 20:52:35

Several months ago I started looking for a new job. Not one of those desperate "i'll-take-the-first-thing-that-looks-great" kind of search. A pleasure search. One of those "where-would-I-absolutely-love-to-work" kind of searches. Applications slowly trickled out. Resumes were written, tweaked, revised, and sent. LinkedIn recommendations were written, etc. I probably sent 2 or 3 resumes per week for several weeks. Only to places that would have been really fun to work (or at least I thought would have been fun to work for.)

The job market here in Temple, TX is not what you'd call "jumpin'" for people in my field. Austin, Dallas, and Houston are really the places to be unless you want to freelance. But freelancing is just not something I could really do. It has never really felt like my calling. It felt like it a couple of times but I honestly suck as a freelancer. I hate asking people for money and I don't like keeping track of hours. My point is that ultimately there were two choices: move some place or commute.

Having commuted something like 4 years for an hour and a half each day, I can easily tell you that commuting is not my first choice. If gas were 50% of what it was... it would be easier to consider. Having a small child at home makes me want to maximize my time even more. There are good things about commuting: audio books, lectures, talk radio, tunes, etc. But all of those pale in comparison to spending time with my family. Commuting is eh.

Moving was something that I was initially opposed to doing. Proximity to friends & family, a wonderful church and small group, along with so many other things that makes roots hard to pull up was definitely a consideration that had to be weighed in the search for a new job. My stepdaughter has a year and a half left of high-school here, my in-laws are 30 minutes away. There were plenty of reasons to stay here.

But there are definitely more reasons for looking. It is a long story, and one that isn't really worth telling in depth. The short of it really is that bonds of trust were broken, great initiatives and ideas were discarded, and the desire to give 110% had slowly waned. Granted, I think we all go into slumps and drop below the 90% mark. It just happens. But when the things you help to build and felt were good and right are stripped away and discarded like last week's leftovers: it hits you like a train. A train that you can see coming but the world is moving in slow motion... and your feet don't want to move.

It leaves you with two choices: stay unhappy and collect that paycheck or get out of the way.

Well, we're getting out the way. It's not easy to look a nice check every month and just say "eh, I can do with you!" Not very easy at all. Especially since Sarah is not gainfully employed. But what is it? A means to an end? Proverbs 11:28 says "Money cannot be trusted in for it will lead to one's downfall." Man. My downfall? The strange thing is, just like that "train" I can see it coming. Bad moods, stress, and all sorts of bad things. They lead to worse things. I had to get out... and trust in the Lord.

Sometime in between all of this I saw an ad on Facebook for a job at "Classy Llama Studios": They were looking for a PHP Expert. Sure, no problem. So the resume got sent, and a couple of days later a call was made to follow-up. Good thing that call was made because apparently someone had overlooked my resume! Next thing I know, I'm driving to Springfield, MO for an interview. I went from not knowing if there was another job out there for me to "Oh man, this could be awesome!" in no time.

I had prayerfully considered the idea that perhaps God had wanted me to stay in my current job. To do good work, to be kind to those who had hurt me, and to carry on what was started by those before me. However, even those around me started picking up on the fact it would be harder to do than we expected. Things kept getting more stressful, and there did not appear to be an end in sight. I felt a little like David being pursued by Saul. But whereas David has a kingdom waiting for him on the other side, more and more it seemed like there was nothing waiting for me on the other side. I had to get out. But in order to get out, a lot of trust was needed because what was coming was not what we expected.

And so trust we did. We had to put our house up for sale, start packing, find a place to live, come up with a new budget, and gracefully leave my current position. From the very start we knew that we could not do all of this on our own. But as we were talking about the offer that Class Llama sent me, I realized that we were not talking about "if" I would take it... but how we could make it work. It was a "yes" the moment we got it. But there was so much we were worried about.

But as this story is unfolding, it is wholly apparent that our trust has been graciously rewarded. The Lord's hands have been felt in our lives since we began this process! The Lord provided someone who really wants to buy our house. The Lord provided free boxes for moving. The Lord provided a wonderful place to move. We have been blessed in finding a home for Fez, my cat. The list goes on and on: support from our small group, families, and friends, plenty of time to finish things here, Sarah being able to do some contract work from home...

To top it all off, I'll get to work with some awesome people, doing awesome things... with a purpose. The icing on the cake is that two of Sarah's kids live near Springfield, so we will get to see them more often as well! The Lord has truly blessed us. I am so excited about this new job and we are excited about starting the next chapter of our lives in Springfield, Missouri.

Continue reading...

Is Sin Binary?

Posted on: 2010-10-03 22:06:36

Tonight while we were walking, I was telling Sarah about some of the things we went over today in our Sunday school class. We went over commandments 5-10. Teach the commandments is easy, but explaining to a bunch of 4th graders why the law was given to Moses and what it means is kind of a stretch. God has blessed me with the ability to be pretty good at describing or analogizing things. It is very useful in my profession and has helped a lot while teaching these guys.

But today it felt like I had a hard time going over the material. Perhaps my understanding of it was underestimated! These are some of the questions/observations that were brought up:

  1. Are the 10 commandments in any particular order? This question seems to lead into the next question, but the only thing that really seems to make sense (to me, at least) is that the 10 commandments are in the order from the "most visible" sins to the least visible sins. There is probably some relatively simple argument that would disagree with that statement, but like I said it leads into the next question...

  2. Murder, stealing, and coveting are all on the same list. If the list is in no particular order, then would it not be safe to assume that all of the sins on this list are of equal weight? Growing up Catholic, we were taught about "mortal and venial sins": But the differentiation between those sins is not biblical. That is, no where else in the bible does it talk about 2 different types or weight of sin. There is just sin: that painful "estrangement from God." It either is or is not sin.

There is something about God's infinite perfectness our and limited flesh that makes no sense for there to be different levels of sin. The only distinction of sin that the bible makes is repented vs. unrepented sin. Romans 2:5 says that because of "stubbornness and an unrepentant heart, you are storing up wrath against yourself on the day of judgement." Not because you committed a "mortal" sin, but because of not repenting! Plus, doesn't saying that the existence of sins that are unforgivable mean that in certain circumstances God's mercy is not limitless for those who might seek his face?

At any rate. All of this to put forth that sin is binary. It either is or is not. Murder, stealing, coveting, are all sin. The punishment for all of those is the same.

What are your thoughts?

Continue reading...