Catlu – Book

MythMash is a whimsical mashup of the styles of major world mythologies. It pulls from a list of 9 Mythologies: African, Arabian, Asian, Celtic, Classical, Egyptian, Native American, Icelandic, and Polynesian. Each page contains a small myth generated using Markov chains and 2 random mythologies. The idea is to think about the place of stories and mythology in the world. The different mythologies all have many similarities, while also retaining individuality and cultural flavor. I encourage the reader to think about this while enjoying fun and entertaining newly generated stories.


The idea of this book came to me as I was thinking about how to incorporate something I really loved and cared about into this generative book project. I think mythology is fascinating, beautiful, and amazing in scope. As I was thinking about it, I thought about how certain stories carry across cultures and regions: hero stories, creation myths, god figures, etc. This made me think about how storytelling is universal in the world, and is a vessel for creativity and empathy. Eventually, I decided to mash mythology styles together to show these similarities in an interesting and whimsical way, while hoping they still retained enough individual flavor to make them recognizable within the whole. Starting this book, I read a bit on Markov code. Eventually I decided to use RiTa.js’ Markov functions. For each mythology, I went through online sources and our school library to find texts of myths, and compiled about 60 pages in MS Word for each. I made it so that my program would randomly select two different mythologies for each page and mash them together. For pictures to accompany the words, at first I thought I could use patterns (also universal), but Golan suggested this could be cliche and I agreed. He then suggested that I choose random images that had to do vaguely with my myths, and that this might add a humorous and mysterious element. I liked the idea so Golan gave my a file with 1 million Flickr photos and their captions. With these pictures, I picked a random noun from the first 15 or so words, and looked for it in the captions that Golan provided me, saving everything to a JSON. I had a lot of problems with the million image file, which took 2 hours to transfer every time I had to move it. In the million images, a small percentage of them were missing (and way more missing photos got pulled than I really expected), and I had to go in and manually add existent images in when I was importing them into inDesign. Eventually, as I was checking through, I found out that some of the caption numbers were offset by 1, while others were not, and that this was completely random. Very frustrated at this point, I really looked at the pictures and decided they weren’t relevant enough to really be all that funny or merit being in the book. In the end, it turned out to be just the text. I was very excited about this project to be begin with, and wish it had turned out a little better. I couldn’t find how to make my own Markov code so had to use RiTa’s with little choice of personalization. Dan Shiffman released videos explaining how to write Markov when I was rushing and struggling to get the pictures to work with the Markov I already had. As for the pictures, I spent maybe 25-30 hours trying to transfer the files several times(8 hours), figure out the code, and work out all the little insidious bugs and how to deal with all the shifting zeros in the 1000 folders of 1000 pictures in the million file. In the end, I was very disappointed that I didn’t love the effect of the pictures as much as I would have liked, and that I spent so long on them and didn’t use them. I definitely really like the idea of the generative book, and how the myths came out, but I may revisit this project again when I have more time to really invest in getting everything right. The content of this book is important to me, and in the future I definitely plan on coming back and making the book every bit as good as it can be, writing the Markov myself and thinking through the right way to illustrate the myths.

MythMash PDF:


The code can be found in the below Github links:
Github Code:


import processing.pdf.*;
import rita.*;

String captions[];

int rand1;
int rand2;
String myth1;
String myth2;

String mythsTitlePart1;
String mythsTitlePart2; 
String mythsTitle;

//lexicon initialization
RiLexicon lexicon = new RiLexicon();

//markov initialization
RiMarkov markov;
String mythText = "click to (re)generate!";
int x = 160, y = 240;

//array of myth types
String[] mythTypes = {"africanMyths.txt", "nativeAmericanMyths.txt", "asianMyths.txt", "arabianMyths.txt", 
  "celticMyths.txt", "egyptianMyths.txt", "norseIcelandicMyths.txt", "polynesianMyths.txt", "classicalMyths.txt"};

String[] mythTypesText = {"African", "Native American", "Asian", "Arabian", 
  "Celtic", "Egyptian", "Icelandic", "Polynesian", "Classical"};

//caption stuff
String captionPull;
//caption stuff try 2
String mythCaption1;
String mythCaption2;

String searchNoun;

int foundCount = 0;
IntList picNumbers;

//JSON stuff
JSONArray bookStuff;
String jsonFinal;

void setup()
  size(500, 800);

  beginRecord(PDF, "everything.pdf");

  textFont(createFont("times", 16));
  bookStuff = new JSONArray();

void captions() {
  //caption stuff//Golan

  picNumbers = new IntList();

  String captionsFilename = "SBU_captioned_photo_dataset_captions.txt"; 
  String captions[] = loadStrings(captionsFilename); 

  int answerCount = 0; 
  String wordsIWant[] = { searchNoun }; 
  for (int i=0; i

Basil.js JavaScript for InDesign (.jsx):

#includepath "~/Documents/;%USERPROFILE%Documents";
#includepath "D:\\Documents";
#include "basiljs/bundle/basil.js";

// Load a data file containing your book's content. This is expected
// to be located in the "data" folder adjacent to your .indd and .jsx. 
var jsonString = b.loadString("book.json");
var jsonData;
var imageFolder;
var anImageFilename;
var anImage;

function setup() {

  // Clear the document at the very start. 
  b.clear (b.doc());
  // Make a title page. 
  b.text("MythMash", 72,72,360,36);
  b.text("Is a journey into the many mythologies of our world; a whimsical examination of their similarities and differences through generative mashup myth.", 72,108,360,300);

  // Parse the JSON file into the jsonData array
  jsonData = b.JSON.decode( jsonString );
  b.println("Number of elements in JSON: " + jsonData.length);

  // Initialize some variables for element placement positions.
  // Remember that the units are "points", 72 points = 1 inch.
  var titleX = 320; 
  var titleY = 415;
  var titleW = 150;
  var titleH = 50;

  var captionX = 54; 
  var captionY = 54;
  var captionW = 396;
  var captionH =396;

  var imageX = 72; 
  var imageY = 72-30; 
  var imageW = 72*3; 
  var imageH = 72*3;

  // Loop over every element of the book content array
  // (Here assumed to be separate pages)
  for (var i = 0; i < jsonData.length; i++) {

    // Create the next page. 

    // Load an image from the "images" folder inside the data folder;
    // Display the image in a large frame, resize it as necessary. 
    b.noStroke();  // no border around image, please.
    //6 digits (hundreds of thousands)
    if (b.floor((jsonData[i].image/1000000)) == 0) {
        imageFolder = "00" + b.floor((jsonData[i].image/1000));
    //5 digits (tens of thousands)
    if (b.floor((jsonData[i].image/100000)) == 0) {
        imageFolder = "000" + b.floor((jsonData[i].image/1000));
    //4 digits (thousands)
    if (b.floor((jsonData[i].image/10000)) == 0) {
        imageFolder = "0000" + b.floor((jsonData[i].image/1000));
    //first 1000
    if (b.floor((jsonData[i].image/1000)) == 0) {
        imageFolder = "0000" + b.floor((jsonData[i].image/10000));

    var anImageFilename = "images/" + imageFolder + "/" + jsonData[i].image + ".jpg";
    var anImage = b.image(anImageFilename, imageX, imageY, imageW, imageH);;

    // Create textframes for the "title" field.
    // Draw an ellipse with a random color behind the title letter.
    //b.ellipse (titleX,titleY,titleW,titleH);
    b.textAlign(Justification.CENTER_ALIGN, VerticalJustification.CENTER_ALIGN );
    b.text(jsonData[i].title, titleX,titleY,titleW,titleH);

    // Create textframes for the "caption" fields
    b.textAlign(Justification.LEFT_ALIGN, VerticalJustification.TOP_ALIGN );
    b.text(jsonData[i].caption, captionX,captionY,captionW,captionH);


// This makes it all happen:

Here's a video of Golan flipping through my book:

Comments are closed.