Krawleb-Book

by any other nameexperiments in synonymous corruption

PDF (600 kb): ./wp-content/uploads/2016/10/krawleb-book.pdf

baon1

baon2

baon3

My book is a collection of 14 pieces of writing that have been transformed and corrupted through a synonym-swapping algorithm. The source text comes from monologues, song lyrics, and poems, each printed in its original form, then recursively synonym-swapped 5 times. The resulting text is a twisted, often out of context, but somewhat related derivative of the original concepts. Inspired by the famous Shakespeare passage “a rose by any other name would smell as sweet”, I explored what happened when we use ‘other names’ for things to the point of destruction.

The software pipeline for this project begins with a Python for Processing program that parses .txt files of both the original source content and a large .txt thesaurus. The program looks at each word, identifies words with synonyms in the thesaurus, and then replaces them. This data is then written to CSV, tagging each word that has been swapped each iteration, as well as tagging ends of lines to preserve the line breaks.

These CSVs are then fed into a Basil.js program that iterates over an array of CSV files, printing the text of each iteration on a new page, and italicizing each swapped word in each recursive iteration.

Ultimately, this project was an interesting experiment, but was a bit unpolished and buggy as I began to run out of time as the deadline approached. Some words are swapped into non-english synonyms, and some synonyms appear nonsensical or unrelated. However, in there chaos there are moments of beauty. Sometimes the text is morphed into new and humorous or beautiful new ideas through the process.

Additionally, the visual form is very minimal, which I would have liked to develop more, but the Basil.js workflow is rather unfriendly to rapid iteration, so I kept things as clean as possible for the final. That being said, I do like the austerity of the small undecorated text on otherwise blank pages.

Github here

PDFs of cover and spreads


Code below:

import random
from random import randrange
import re
import csv
import sys

textName = 'loveCallsUs'

source = open('texts/'+textName+'.txt', 'r')
ts = open('texts/synAntNoHyph.txt', 'r')
ts2 = open('texts/MobyTs.txt', 'r')

export = open('export.txt', 'w')
csvExport = open('exports/'+textName+'.csv', 'wb')

def setup():
    size(100, 100)

    rawTs = ts.readlines()
    rawTs2 = ts2.readlines()
    
    rawlines = source.readlines()
    lines = []
    iterations = []
    numIterations = 5 

    for raw in range(len(rawlines)):
        aLine = rawlines[raw].split()
        lines.append(aLine)
        
    #initialize csv with source
    writer = csv.writer(csvExport)
    writer.writerow( ('word', 'isNew', 'iteration', 'endLine') )
    print lines
    for x in range(len(lines)):
        isEnd = 0 #is it the end of a line?
        for y in range(len(lines[x])):
            word = lines[x][y]
            if y == len(lines[x])-1: #adjusted for index
                isEnd = 1
            writer.writerow( (word, '0' , '0' , isEnd ) )
        
    #first, print original text
    for line in lines:
        joined = ' '.join(line)
        print>>export, joined
    print>>export, '\n'

    for z in range(numIterations):
        # Find Synonyms
        for i in range(len(lines)):  # loop over lines
            for j in range(len(lines[i])):  # loop through words
                
                currentWord = re.sub(r'[^\w\s]','',lines[i][j]).title() #remove punctuation
                # print currentWord
                
                found = False #reset found (in first thesaurus)
                
                for k in range(len(rawTs)):  # loop through ts (first thesaurus)
                    if random.random() > 0.0:
                        if rawTs[k].startswith(currentWord+'.'): #if it's a period, grab the word right after
                                # print rawTs[k]
                                index = random.randint(1,len(rawTs[k].split())-1)
                                synonym = rawTs[k].split()[index]
                                synonym = str('_'+synonym)
                                found = True
                        if rawTs[k].startswith(currentWord+','): #if it's a comma, grab the second word
                                # print rawTs[k]
                                if len(rawTs[k].split())-1 >= 2:
                                    index = random.randint(2,len(rawTs[k].split())-1)
                                else:
                                    index = 1
                                synonym = rawTs[k].split()[index] 
                                synonym = str('_'+synonym)
                                found = True
    
                if found == True:
                    if j > 0:
                        synonym = synonym.lower()
                        synonym = re.sub(r'[^\w\s]','',synonym)
                        synonym = synonym.strip(';')
                    lines[i][j] = synonym
         
        #write to CSV 
        print lines                                     
        for x in range(len(lines)):
            for y in range(len(lines[x])):
                isSyn = 0 #is it a synonym?
                isEnd = 0 #is it the end of a line?
                if lines[x][y].startswith('_'): #detect if its a synonym
                    lines[x][y] = lines[x][y][1:] #strip synonym identifier
                    isSyn = 1
                if y == len(lines[x])-1: #adjusted for index
                    isEnd = 1
                word = lines[x][y]
                writer.writerow( (word, isSyn , (z+1) , isEnd) )
                # print word
                    
            # print str(lines[x])
            joined = ' '.join(lines[x])  
            print>>export, joined
        print>>export, '\n'
            
        iterations.append(lines)
    noStroke()
    fill(0,255,0)
    ellipse(width/2,height/2,80,80)
    
    csvExport.close()

Basil/InDesign code:

#includepath "~/Documents/;%USERPROFILE%Documents";
#include "../../../bundle/basil.js";

var csvArray = [
'rose.csv',
'hammy.csv',
'desire.csv',
'leisure.csv',
'enigmas.csv',
'israfil.csv',
'tooLate.csv',
'aRitual.csv',
'folkMeta.csv',
'sasquach.csv',
'souvenir.csv',
'gazzillion.csv',
'loveCallsUs.csv',
'spottieOttie.csv' ];

var csvData;

var genCover = false;
var reset = true;

//--------------------------------------------------------
function setup() {

  // Clear the document at the very start. 
  if (reset == true){
    b.clear (b.doc());
  }

  if (genCover == true){

  // Make a title page. 
  b.fill(0,0,0);
  b.textSize(24);
  b.textFont("Helvetica","Light"); 
  b.textAlign(Justification.LEFT_ALIGN); 
  b.text("By Any Other Name", 72,72,360,36);
  b.text("Kaleb Crawford, Fall 2016", 72,108,360,36);

  } //end Gen Cover

  //72 points in an inch
  var margin = 72

  var titleX = 72; 
  var titleY = 72;
  var titleW = 72;
  var titleH = 72;

  var passageX = margin + 18;
  var passageY = margin * 2;
  var passageW = margin * 3;
  var passageH = b.height-margin*2;

  var innerText;
  var mainFrame;
  var tempFrame;

  //////////////////////CSV Array Loop//////////////////////
  for (var texts = 0; texts < csvArray.length; texts++){

  var csvString = b.loadString(csvArray[texts]);
  csvData = b.CSV.decode( csvString );
  b.println("Number of elements in CSV: "+csvData.length);

  var totalIterations = parseInt(csvData[csvData.length-1].iteration);
  var currentIteration = 0;

  ////////////////////// Iterations Loop////////////////////
  for (var i = 0; i <= totalIterations; i++) {

    b.addPage(); // Create the next page.

    //Create the frame
    b.fill(0);
    b.textSize(8);
    b.textFont("Garamond","Regular"); 
    b.textAlign(Justification.LEFT_ALIGN, VerticalJustification.TOP_ALIGN );
    mainFrame = b.text("", passageX, passageY, passageW, passageH);

    currentIteration = i;
    innerText = ''; //initialize inner text

    ////////////////////Word Loop///////////////////
    for (var l = 0; l < csvData.length ; l ++ ){
      if (csvData[l].iteration == currentIteration){

        innerText = csvData[l].word+" ";

        if (csvData[l].isNew == 1){
          b.textFont("Garamond","Italic");
        }
        else{ b.textFont("Garamond","Regular"); }

        if (csvData[l].endLine == 1){
          innerText += "\n";
        }

        tempFrame = b.text(innerText, 0, 0, 100, 100);

        // mainFrame.contents += tempFrame.contents;

        tempFrame.paragraphs[0].move(LocationOptions.after,mainFrame.insertionPoints[-1]);

        tempFrame.remove();

      } //end if currentIteration check
    } // end line loop
    b.println('text '+(texts+1)+" iteration "+currentIteration);
  } //end iteration loop
}//end csvArray loop
} // end setup

// This makes it all happen:
b.go(); 

Comments are closed.