1. NodeBox 1
    1. Homepage
    2. NodeBox 3Node-based app for generative design and data visualization
    3. NodeBox OpenGLHardware-accelerated cross-platform graphics library
    4. NodeBox 1Generate 2D visuals using Python code (Mac OS X only)
  2. Gallery
  3. Documentation
  4. Forum
  5. Blog

CSV Data -> Nodebox -> Multiple PDFs?

Posted by Russell Greenwood on Nov 11, 2008

Hi all -

I've got what I think is a tricky task I'd like to try and do.

I'm making nametags for a convention, and I've been using nodebox to generate all the graphics up until now with Pixie tree squiggles randomly generated for each thing.

What I'm wondering is, would there be any way for me to take a CSV (or whatever) of delegate information, eg. first name, surname, and a few other details about the event, and pull them into nodebox to generate a PDF background for each persons name.

Process as I see it,

Nodebox reads CSV line 1,
Generate PDF,
Save PDF using firstname-surname.pdf (or something unique)
nodebox reads csv line 2,
etc.

Then with InDesign I can data merge the names and have a cell in the CSV file that has the background name for that badge.

is there ANY chance this is possible or am I pipe-dreaming?


 
Posted by impiaaa on Nov 11, 2008

Sure! Python comes with a CSV parsing module. Look here:
http://www.python.org/doc/2.5.2/lib/module-csv.html
What you need to do is parse the file and iterate through the rows. Each iteration, draw the canvas, export the file, and clear the canvas. For instructions on that, see here:
http://nodebox.net/code/index.php/Console



Posted by Russell Greenwood on Nov 11, 2008

Awesome - didn't know about the canvas exporting... wicked.

Now the harder question - is there anyone who could help me out or show me an example of already working CSV > nodebox code? I'm not exactly the most fluent of Python people and if there's something I can start from that would be awesome.



Posted by Cedric on Nov 12, 2008

Something like this (I haven't tested it, but it looks reasonable...)?

import csv
from AppKit import NSApplication
NSApplication.sharedApplication().activateIgnoringOtherApps_(0)
from nodebox.graphics import Context
ctx = Context()
ctx.size(200, 100)
 
ctx.align(align=ctx.CENTER)
positionx, positiony = 100, 20
positionx2, positiony2 = 100, 120
 
reader = csv.reader(open("some.csv", "rb"))
for row in reader:
    name, institute = row.split()
    ctx.font("Helvetica", 30)
    ctx.text(name, positionx, positiony)
    ctx.font("Helvetica", 20)
    ctx.text(institute, positionx2, positiony2)
    ctx.save("%s.png"%(name))
    ctx.clear()



Posted by Jim Audette on Nov 12, 2008

I made a few changes to tha above code and it works. The align=CENTER attribute only works if there is a width set in the text attributes.

import csv
from AppKit import NSApplication
NSApplication.sharedApplication().activateIgnoringOtherApps_(0)
from nodebox.graphics import Context
ctx = Context()
ctx.size(400, 100)
 
ctx.align(align=CENTER)
positionx, positiony = 20, 30
positionx2, positiony2 = 20, 60
 
reader = csv.reader(open("some.csv", "rb"))
for name, institute in reader:
    ctx.font("Helvetica", 30)
    ctx.text(name, positionx, positiony,width=360)
    ctx.font("Helvetica", 20)
    ctx.text(institute, positionx2, positiony2,width=360)
    ctx.save("%s.png"%(name))
    ctx.canvas.clear()



Posted by Russell Greenwood on Nov 15, 2008

Hmmm, so I'm trying here, but I can't get Pixie to render out to the PDF's... here's the code I've got - nametag-pixie is the name of the slightly altered pixie library I'm using. All this does it render the pixie stuff to the canvas, and the information from the CSV file goes out to individual PDFs perfectly. Odd.

Any help would be appreciated!

colormode(CMYK)
 
import csv
from AppKit import NSApplication
NSApplication.sharedApplication().activateIgnoringOtherApps_(0)
from nodebox.graphics import Context
ctx = Context()
ctx.size(400, 100)
 
ctx.pixie = ximport("nametag-pixie")
ctx.pixie.color(0,0,0,1) 
 
ctx.align(align=CENTER)
positionx, positiony = 20, 30
positionx2, positiony2 = 20, 60
 
reader = csv.reader(open("names.csv", "rb"))
for name, institute in reader:
    ctx.font("Helvetica", 30)
    ctx.text(name, positionx, positiony,width=360)
    ctx.font("Helvetica", 20)
    ctx.text(institute, positionx2, positiony2,width=360)
 
    root = name
    n1 = (institute, ("experience","discipleship"))
    n2 = ("Diversity", ("risk","vision","crowds", "fun", "learning", "activities", "music"))
    nodes = (n1,n2)
    ctx.pixie.color(0,0,0,1)
    ctx.pixie.tree(root, nodes, positionx, positiony, WIDTH, HEIGHT, pt=35)
 
 
    ctx.save("Names/%s.pdf"%(name))
    ctx.canvas.clear()



Posted by Tom De Smedt on Nov 15, 2008

The Pixie library renders to the current NodeBox canvas, while your script is rendering in your own custom canvas. If you open up the Pixie source code, you'll notice that all drawing commands are preceded by _ctx. This is the canvas in the current NodeBox window.

There are two things you can do: use the current NodeBox canvas, or set Pixie's rendering context to your own canvas.

Option 1: simply use the normal commands in NodeBox without creating your own context:

font("Helvetica", 30)
pixie.color(0,0,0,1)
...
canvas.save("Names/%s.pdf"%(name))
canvas.clear()
OR
_ctx.font("Helvetica", 30)
_ctx.pixie.color(0,0,0,1)
...
_ctx.canvas.save("Names/%s.pdf"%(name))
_ctx.canvas.clear()
Option 2: if for some reason you do need a custom canvas, let Pixie know about this:
from AppKit import NSApplication
NSApplication.sharedApplication().activateIgnoringOtherApps_(0)
from nodebox.graphics import Context
ctx = Context()
ctx.size(400, 100)
pixie = ximport("nametag-pixie")
pixie._ctx = ctx
...
ctx.canvas.save("Names/%s.pdf"%(name))
ctx.canvas.clear()
To wrap it up, below is a script that should work for you:
colormode(CMYK)
 
import csv
size(400, 100)
 
pixie = ximport("nametag-pixie")
pixie.color(0,0,0,1) 
 
align(align=CENTER)
positionx, positiony = 20, 30
positionx2, positiony2 = 20, 60
 
reader = csv.reader(open("names.csv", "rb"))
for name, institute in reader:
    
    canvas.clear()
    
    font("Helvetica", 30)
    text(name, positionx, positiony,width=360)
    font("Helvetica", 20)
    text(institute, positionx2, positiony2,width=360)
 
    root = name
    n1 = (institute, ("experience","discipleship"))
    n2 = ("Diversity", ("risk","vision","crowds", "fun", "learning", "activities", "music"))
    nodes = (n1,n2)
    pixie.color(0,0,0,1)
    pixie.tree(root, nodes, positionx, positiony, WIDTH, HEIGHT, pt=35)
 
 
    canvas.save("Names/%s.pdf"%(name))
Also make sure that the "Names" folder in which you are exporting exists.

Hope that helps.



Posted by Russell Greenwood on Nov 16, 2008

Oh that's AWESOME!

Thanks man, all worked great - I'll be sure to post an example here when we run them off.

Cheers all -



Posted by Russell G on Feb 17, 2009

So, not the best example photo, but I said I'd put a picture here, so go checkout:
http://www.flickr.com/photos/r00kienator/3181797452/in/pool-ncyc

You can just barely see the pixie-library scribbles that were generated based on each persons name and bio details... was awesome for everyone to have a slightly different nametag.

Thanks again for the help.