diff --git a/pdf.c b/pdf.c
index ad3665452df021c4778568707c182d839446af86..f4183d0244d99ccce4a0f1d217bc4d40782c3a39 100644
--- a/pdf.c
+++ b/pdf.c
@@ -116,7 +116,7 @@ struct Env {
 /*
  * custom token types
  */
-HTokenType TT_XREntry, TT_Ref, TT_Dict;
+HTokenType TT_XREntry, TT_Ref, TT_Dict, TT_DictEntry;
 
 typedef struct {
 	enum {XR_FREE, XR_INUSE, XR_OBJSTM} type;
@@ -131,9 +131,14 @@ typedef struct {
 typedef struct { size_t nr, gen; } Ref;
 
 typedef struct {
-	const HParsedToken *obj;
+	HCountedArray *seq;
 } Dict;
 
+typedef struct {
+	HParsedToken *name;
+	HParsedToken *obj;
+} DictEntry;
+
 void
 pp_xrentry(FILE *stream, const HParsedToken *tok, int indent, int delta)
 {
@@ -165,6 +170,36 @@ pp_ref(FILE *stream, const HParsedToken *tok, int indent, int delta)
 	fprintf(stream, "[%zu,%zu]", r->nr, r->gen);
 }
 
+/* TODO XXX call pretty printer on each seq element */
+void
+pp_dict(FILE *stream, const HParsedToken *tok, int indent, int delta)
+{
+	assert(tok->seq);
+
+	if (tok->seq->used == 0)
+		fprintf(stream, "{ }");
+	else {
+		fprintf(stream, "{%*s", delta - 1, "");
+		/*for (size_t i = 0; i < tok->seq->used; i++) {
+			if (i > 0) fprintf(stream, "\n%*s,%*s", indent, "", delta - 1, "");
+			h_pprint(stream, tok->seq->elements[i], indent + delta, delta); */
+	}
+	if (tok->seq->used > 2)
+		fprintf(stream, "\n%*s}", indent, "");
+	else
+		fprintf(stream, " }");
+	}
+}
+
+void
+pp_dictentry(FILE *stream, const HParsedToken *tok, int indent, int delta)
+{
+	DictEntry *de = H_CAST(DictEntry, tok);
+
+	h_pprint(stream, de->name, indent, delta);
+	fprintf(stream, "\":\"", indent, delta);
+	h_pprint(stream, de->obj, indent, delta);
+}
 
 /*
  * semantic actions