this is aaronland


Hello, computer.

Or : I've posted version 0.2 of pmPDF.php which adds support for images.

The Pocketnet

Around the same time I wrote about the papernet Aaron Hillegass released PagePacker, a drag and drop OS X application to generate PocketMod booklets.

PocketMod books are insanely cool since all they are is a piece of letter-sized paper, with a single tear that you can do by hand, and folded in to a book. DIY books are nothing new but the thing that makes the PocketMod stand out is how simple it is : All of the folds are no more complicated that folding the page in half a few times. The actual tear happens to be along one of the creases so there's no need to worry about ruler anxiety. You don't even need a printer if all you cared about was having a quick and dirty notebook with pages. Profit!

Their weakness — and this may be by design — is that while their form doesn't limit them to a single sheet of paper a booklet with more than 8 pages requires that the sheets be nested inside one another. Which means you have to keep track of pagination and whether or not page 8 is actually on sheet 1 or sheet 3. The other issue, if you want to generate one of these things using a computer programming device, is that none of the pages on a given sheet flow left to right; one half flow top to bottom and the other half bottom to top.

Which means that if, like me, you are lazy and have built your tools on the backs of people smarter than you you suddenly find yourself up to your arms in someone else's code trying to figure where and when to rotate $x and remembering that page breaks and automagic new lines are a relative thing depending not only on the actual dimension of your piece of paper but also how many sheets you are using and what page you are on.

Which I guess is a really long way of saying thanks to Aaron for goading me into actually doing it :

$args = array('folds' => 1);
$pdf = new pmPDF($args);


foreach (range(1, 16) as $i){
	$pdf->add_text("page {$i}", $i);


Which, let's face it, is not very exciting. But plumbing never is until you realize that this suddently doesn't sound quite so crazy, anymore:

By the end of the trip I was full of ideas for community driven websites where you could build and print your day's (or your week's) journey and fold it all in to a handy little booklet that would fit in your back pocket. Like most of these things, it quickly got crushed by too many ambitions and too many moving parts. And then there's the folding thing which is compounded by lack of consumer grade printers to print on anything but letter-sized paper.

It's not quite there yet. A few more boring details remain : Image support and placement (which is actually in the code, half-baked, if you care to look); positioning text in general; more specifically floating text around images. And formatted text which is probably more important to a lot of people than it is to me. But these are details and shouldn't require anything more than the patience to keep track of who is on first. The exciting part is that this could be the guts (the plumbing) of a system to take the magic of online publishing tools and turn it in to something personal, and maybe even beautiful, that people can hold in their hands unburdened by the weight of technology.

And then Stikkit went and published their API.

Maybe I am a bad person for not liking online note taking services. I like Stikkit and continue to be impressed by it, purely as a web application. Despite the fact that I am often tethered to the computer (either by choice or a lack of imagination about what to do with the day) I really don't want to be reliant on the fuckers when I actually need to do or to remember to do something. If I scribble something down while I am work, do I really need to whip out my laptop while I am standing in line at the bank machine to see what it was? Besides, if there's no wireless connection nearby and there really is a way to get online WITH MY MIND no one has let me in on the secret yet.

So last night, while I waited for dinner to cook, I cranked out a simple library to query Stikkit for my stuff and squirt it in to a booklet. You can use the API itself to filter stikkits by tag and date and all the other crunchy goodness they allow and the PDF library to add page breaks after each note. Or not. Suddenly, the Interweb seemed useful again!

But wait — there's more! Imagine that for every note or todo item, there was a QR (bar) code next to it. The code would encode nothing more than a URL containing a link back to Stikkit which would delete the item, or mark it as done. You can do this today (using a cameraphone with a barcode reader) for stikkits proper but not for todo items since the former action can be done using a plain vanilla HTTP GET request while the latter requires a PUT.

(This is probably the next thing I will do but it means digging out the barcode library I used for aaPDF, which I promise I will release soon, and writing a bare-bones Atom parser to get the various bits for properly addressing items in the Stikkit database.)

Kellan always scowls at me when I say things like The whole REST model, purer than the driven snow, is just dumb because of stuff like this but I am right and he is wrong. There are real security concerns about using GET to modify things on the Interwebs but there are various workarounds (all of dubious quality) and short of encrypted connections and proper crumbs and validation just sending something using the More Better™ HTTP verb strikes me as pedantry. I say this because the street has found its own use for GET; namely, pointers to do something. I can encode a proper POST request in a barcode but until I can invoke a web browser passing that request (instead of a simple URL) we are going to be stuck with problems like this.

In a world where small pieces are loosely joined and programming anything that fits in your pocket continues to be a chore, the built-in web browser will be the only realistic way to talk HTTP. This is further compounded by the lack of addressability in scrumax-y applications. I can't find the post where Stikkit announced that individual notes were made linkable using a GET, but if there's a way to link to an interstitial page to delete an item (for example : then I haven't found it.

Assuming I could log in to a mobile-ified version of site proper, passing my API key as a authentication parameter in the absence of a cookie, and do all the necessary POST-y / PUT-y bits in the browser then I would happy enough to do that. So maybe I don't really have any beef with the RESTonauts other than to ask them to remember that, rightly or wrong, it's still a messy world down here.

Details, details. In the meantime, I have released versions 0.1 of pmPDF.php and pmStikkit.php.

The former accepts one of more chunks of unformatted text (excepting newlines; these things are mostly pointless without the newline love) and generates a PDF file with the text formatted as minty PocketMod pages. The latter uses the former and queries the Stikkit API to generate the text for the final document. Both require the FPDF library as a dependency.

The possibilities are endless if by endless you mean four or five letter-sized sheets of paper because any more and the whole nesting pages thing starts to get ugly...

“Wait, aren't machine tags just RDF?”

Meanwhile, in the town called Patience :

No, machine tags are not RDF; they could play RDF on television, though.

Ladies and gentlemen, machine tags!

Some day it would be fun to publish the internal theory and practice document we had going while we planned and built this, but that can probably never happen. As sloppy seconds, I have started keeping a list of machine tag related pointers on

Update: For the sake of posterity I've included the full text of the comments I wrote on the Flickr API group below:

[Note : I work here and this message was also sent to the API mailing list]

We are rolling out a new feature called "machine tags" that allows users to be more precise in how they tag, and how they search, their photos.

Many of you may already be familiar with machine tags by another name (triple tags) or because you are already using them, informally, in your code (for example, "geo:long=123.456").

"Machine tags" is the technical term for the extra hamsters we've added to the Flickr servers to formalize how these sorts of tags are treated. I've included a "Ceci n'est pas un FAQ" below with all the details.

For the moment, machine tags are principally an API "thing". The photo pages have been updated to display tags a little differently but otherwise all the magic you can perform with machine tags happens here at the API layer. (This includes the special wildcard syntax for searching photos with machine tags.)



# What are machine tags?

Machine tags are tags that use a special syntax to define extra information
about a tag.

Machine tags have a namespace, a predicate and a value. The namespace defines a class or a facet that a tag belongs to ('geo', 'flickr', etc.) The predicate is name of the property for a namespace ('latitude', 'user', etc.) The value is, well, the value.

Like tags, there are no rules for machine tags beyond the syntax to specify the parts of a machine tag. For example, you could tag a photo with :

* flickr:user=straup

* flora:tree=coniferous

* medium:paint=oil

* geo:quartier="plateau mont royal"

* geo:neighbourhood=geo:quartier

Flickr has already used machine tags, informally, on a couple of occasions :

- When we launched Maps, we provided a way for people who had
"geotagged" their photos to import their location data. This was
done using the "geo:lat=..." and "geo:lon=..." tags.

- When a user tags an event with an upcoming ID (for example :
"upcoming:event=81334") we display a link back to the
site. A similar example is the excellent "Flickr Upcoming Event"
greasemonkey script :

Dan Catt wrote a very good piece about machine tags - he called them "triple tags" - last year :

Update : Dan's gone and written another excellent piece about all of this stuff now that we've launched machine tags:


# What is the spec for machine tags?

Machine tags are divided in to three parts :

1) A "namespace" :

Namespaces MUST begin with any character between a - z; remaining
characters MAY be a - z, 0 - 9 and underbars. Namespaces are

2) A "predicate" :

Predicates MUST begin with any character between a - z; remaining
characters MAY be a - z, 0 - 9 and underbars. Namespaces are

3) A "value" :

Values MAY contain any characters that a "plain vanilla" tags
use. Values may also contain spaces but, like regular tags, they
need to wrapped in quotes.

Namespace and predicates are separated by a colon : ":"

Predicates and values are separated by an equals symbol : "="

For example :

* flickr:user=straup

* geo:locality="san francisco"


# Why can't I use non-ASCII characters for namespaces and predicates ?

Simple steps, first.


# Can I define another machine tag as the value of a machine tag?

Sure, but it will not be processed as a machine tag itself.


# How do I add machine tags?

By adding tags! No, really.

Machine tags are added *exactly* the same as any other tag whether it is done through the website or the API.

When the Flickr supercomputer processes your tags, we take a moment to check
whether it is a machine tag. If it is we leverage the powerful Do What I Mean engine to, well, do what you mean.


# How do I query machine tags?

Via the API!

Specifically, using the "machinetags" parameter in the '' method. Like tags, you can specify multiple machine tags as a comma separated list.


# Can I query the various part of a machine tag?

Yes. Aside from passing in a fully formed machine tag, there is a special syntax for searching on specific properties :

* Find photos using the 'dc' namespace :

{"machine_tags" => "dc:"}

* Find photos with a title in the 'dc' namespace :

{"machine_tags" => "dc:title="}

* Find photos titled "mr. camera" in the 'dc' namespace :

{"machine_tags" => "dc:title=\"mr. camera\"}

* Find photos whose value is "mr. camera" :

{"machine_tags" => "*:*=\"mr. camera\""}

* Find photos that have a title, in any namespace :

{"machine_tags" => "*:title="}

* Find photos that have a title, in any namespace, whose value is "mr. camera" :

{"machine_tags" => "*:title=\"mr. camera\""}

* Find photos, in the 'dc' namespace whose value is "mr. camera" :

{"machine_tags" => "dc:*=\"mr. camera\""}


# Is there a limit to the number of machine tags I can query?

Yes. The limit depends on the tag mode (ALL or ANY) that you are querying
with. "ALL" (AND) queries are limited to (16) machine tags. "ANY" (OR) queries are limited to (8).


# Can I do range queries on machine tags?

No. Not yet, anyway.

It is a hard problem for reasons far too dull to get in to here. It's on the list.


# Are machine tag namespaces reserved?

No. Anyone can use a namespace for anything they want.

If you are concerned about colliding namespaces you should consider adding an additional machine tag to define your namespace. For example :


Like tags, in general, we expect (hope?) that the community will develop its own standards by consensus over time.


# What about all the machine tags that are already in the Flickr database?

At the moment, they are still treated as plain old tags.

We have plans to go back and re-import them as machine tags but for now, only new tags will be processed as machine tags.

In the meantime, if you re-save a machine from the 'edit this tag' page it will be re-imported as a machine tag.


# Is the predicate *really* a predicate?

You are in a dark cave. In the corner is a fire and a man making bunny shadows on the wall with his hands. Whether or not it's really a 'predicate' depends on how much time you spend on the semantic-web mailing list. ;-)

It's close enough to being a predicate that it makes for a good short-hand.


# Wait, aren't machine tags just RDF?

No, machine tags are not RDF; they could play RDF on television, though.

See also :


# Huh, what is RDF ?

RDF Describes Flickr. That's really all you need to know about RDF.