Turning a Text List into Inkscape Text Objects

Le Wed 10 June 2015

I quite enjoy board games and story telling games, and have had a crack at designing a few of them including the Nettlebed Caverns game which is available in a draft form on this webpage. One of the hallmarks of my story telling games is that they have a HUGE number of cards....like 300 or so. This gives a lot more scope for variety in the stories and, well actually, it is a heap of fun making up what is going onto the cards.

Writing out the list of cards in a word processor is fun. Writing them out again into a graphics package of some sort to lay them out as cards is a bit of a chore, particularly when you are dealing with 300 or more of them. So I felt there was a need for a simple script to take a list of text, and turn it into a heap of text elements in a vector based graphics program. Once the text was in the graphics program I could then use its tools to lay out the text nicely.

I knew that Inkscape's native file format (SVG) was just an XML so this was an obvious choice for the output. After a couple of tests, I observed that there was a block of unchanging XML at the start, and a convenient XML block for each text element. This meant that creating a quick and dirty python script that took each line in a text file and turned it into a separate text element in an SVG was relatively simple. I did not bother to use the script to position the text elements because I could use the Inkscape Object Distribution tools to spread it out once I had them in Inkscape.

The python script does not use any libraries and so will run on the most basic python installation. As you will see, the vast majority of the script is putting the XML header into the file created.

You can download the python script here: TXT2InkscapeXMLv1.py

You can also download this article as a pdf from here: TXT_to_Inkscape.pdf

Having said all that, I put Inkscape aside and developed an alternative and somewhat better toolset for use with Scribus. The two pages that describe the scripts for distributing text and images can be found on the webpages below;

The Script

# TXT2InkscapeXMLv1.py

# A simple script to look through a list of text and
# turn each line into an xml entry for use in Inkscape.
# in this script we will just dump all of the text
# ontop of itself, irrespective of the actual layout
# then use inkscape to spread it out.

ofilenm = str(input("What is the filename you wish for output?"))
outfile = open(ofilenm,"w")

ListFlm = str(input("What is the name and location of the TXT file to work with?"))

# The block that follows is the Inkscape standard header.
outfile.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n')
outfile.write('<!-- Created with Inkscape (http://www.inkscape.org/) -->\n')
outfile.write('   xmlns:dc="http://purl.org/dc/elements/1.1/"\n')
outfile.write('   xmlns:cc="http://creativecommons.org/ns#"\n')
outfile.write('   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"\n')
outfile.write('   xmlns:svg="http://www.w3.org/2000/svg"\n')
outfile.write('   xmlns="http://www.w3.org/2000/svg"\n')
outfile.write('   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"\n')
outfile.write('   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"\n')
outfile.write('   width="744.09448819"\n')
outfile.write('   height="1052.3622047"\n')
outfile.write('   id="svg2"\n')
outfile.write('   version="1.1"\n')
outfile.write('   inkscape:version="0.48.4 r9939"\n')
outfile.write('   sodipodi:docname="New document 1">\n')
outfile.write('  <defs\n')
outfile.write('     id="defs4" />\n')
outfile.write('  <sodipodi:namedview\n')
outfile.write('     id="base"\n')
outfile.write('     pagecolor="#ffffff"\n')
outfile.write('     bordercolor="#666666"\n')
outfile.write('     borderopacity="1.0"\n')
outfile.write('     inkscape:pageopacity="0.0"\n')
outfile.write('     inkscape:pageshadow="2"\n')
outfile.write('     inkscape:zoom="3.959798"\n')
outfile.write('     inkscape:cx="180.8475"\n')
outfile.write('     inkscape:cy="800.78961"\n')
outfile.write('     inkscape:document-units="px"\n')
outfile.write('     inkscape:current-layer="layer1"\n')
outfile.write('     showgrid="false"\n')
outfile.write('     inkscape:window-width="1280"\n')
outfile.write('     inkscape:window-height="742"\n')
outfile.write('     inkscape:window-x="-2"\n')
outfile.write('     inkscape:window-y="-3"\n')
outfile.write('     inkscape:window-maximized="1" />\n')
outfile.write('  <metadata\n')
outfile.write('     id="metadata7">\n')
outfile.write('    <rdf:RDF>\n')
outfile.write('      <cc:Work\n')
outfile.write('         rdf:about="">\n')
outfile.write('        <dc:format>image/svg+xml</dc:format>\n')
outfile.write('        <dc:type\n')
outfile.write('           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />\n')
outfile.write('        <dc:title></dc:title>\n')
outfile.write('      </cc:Work>\n')
outfile.write('    </rdf:RDF>\n')
outfile.write('  </metadata>\n')
outfile.write('  <g\n')
outfile.write('     inkscape:label="Layer 1"\n')
outfile.write('     inkscape:groupmode="layer"\n')
outfile.write('     id="layer1">\n')

# The section that follows is to build the SVG text elements
f = open(ListFlm,"r")
for line in f:
    TXTLine = line.strip()
    outfile.write('    <text\n')
    outfile.write('        xml:space="preserve"\n')
    outfile.write('        style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"\n')
    outfile.write('        x="93.910118"\n')
    outfile.write('        y="250.56461"\n')
    outfile.write('        id="text2989"\n')
    outfile.write('        sodipodi:linespacing="125%"><tspan\n')
    outfile.write('          sodipodi:role="line"\n')
    outfile.write('          id="tspan2991"\n')
    outfile.write('          x="93.910118"\n')
    outfile.write('          y="250.56461">'+TXTLine+'</tspan></text>\n') #This is the text element from the list

# The next section is the close off for the SVG xml.

outfile.write('  </g>\n')


How to use the script

To use the script follow the steps outlined below:

  • Save your list as a plain TXT file that only contains the list of items you wish to appear in the Inkscape illustration. Start up your python environment. I use Pyzo, but you could equally well use the terminal to run the script if you have an operating system with python already present.

  • Load and run the script.

  • The script will ask you what you want to call the file it produces. Give some name with the .svg suffix. Your file will appear in the User directory for Linux Systems and possibly in the “My Documents” directory in Windows based systems.

  • The script will then ask you to identify the list file that you are wanting processed. You will need to include the pathname, eg /home/user/Documents/junk/List.txt.

  • An instant later it will have the command prompt back up and you will wonder if anything happened. You should see your new .svg file in the User directory.

  • Open the .svg in Inkscape.

  • You will be faced with a black smear of text in the Inkscape document.

The dark smear of many lines ontop of eachother

  • Click on the pile of text to select the topmost one, and drag it somewhere down the page.

Take the top text object and shift it

  • Drag a box around all of the text elements to select them all.

Select all of the text objects

  • Activate the Object >Align and Distribute panel (Shift+Ctrl+A)

Find the object Align and Distribute menu item

  • “Distribute centres equidistantly vertically” button to spread the text elements evenly between the top text element and the text element you dragged down the page.

Distribute the text objects

  • In my case where I wish to create a grid of cards, there is a panel for distributing elements across a grid. You can find this under menu Object > Rows and Columns.

Find the object Row and Columns menu item

Create a grid layout easily

So now the list is a distributed series of text objects in Inkscape without having to retype them in. Yayyy!

And now that you have read all the way down here, here is an even better way of doing this. Check out the following pages doing the same thing in Scibus.

Even bigger Yayyy!

Par Hamish Trolove, Catégorie : Tutorials

Tags : Inkscape / Python / Graphics / Tools /