What constrained writing?

In simplest terms, writing bound by rules. The output doesn’t have to be coherent or even make sense (in the original language). There can be a source text which is converted into the final output upon filtering based on the pre-determined rules.

Why constrained writing?

In techniques where the output actually makes sense, constrained writing can be used to cure writers block. In such cases, I would like to think of constrained writing as alchemy of information. Also, the output can be amusing and fun!

How constrained writing?

Many people have implemented their own versions of constrained writing. Cutting text, rearranging, moving around letters, only including one vowel, replacing nouns with another noun 7 words ahead in the dictionary (N+7), and what not. I personally have always known fibonacci numbers to be the closest connection between real-life art and mathematics, be it snowflakes or leaf vein patterns. Hence as my submission to the first assignment, I attempted to use fibonacci sequence to dictate which words to pick based on the position they are at within a source text.

Assignment1 statement

Using a source text of your choosing, manually perform one of the "constrained writing" techniques described above (or one of your own invention!)

My attempt: ‘Constrained writing – Spacing dictated by the fibonacci sequence’

Preparing for the assignment:

Just thinking about the assignment, I had the following questions:

  1. Does there have to be a source text or can I generate the final output from my imagination?
  • Turns out most of the well known constrained-writing techniques involve filtering out a source text, but it doesn’t necessarily have to be that way.
  1. How can I get something meaningful to evolve from the mix of rules and rule-less-ness?
  2. How can I let the text guide me rather than pre-defining hard rules?
  3. In case of a source text, would constraining each sentence individually make the final output more meaningful?
  4. How can I make it interactive? Get the user to paste text? Allow randomization?
  5. Do I need the knowledge of English grammar rules and parts of speech? How would these vary across languages? Can constrained writing be done for a language with ill-defined grammar and no official dictionary?
  6. Should the constraining technique be revealed to the reader to add to the meaning of the final text?

I could have literally chosen any technique out of the billion possible and having so many choices causes indecisiveness, which overtime turns into decision fatigue. So instead, I chose to let my gut dictate the constraints and I went with the fibonacci sequence based filtering.

I needed to know the basics of html and p5js which the following resources cover nicely:

  1. First three videos of this playlist.
  2. p5js reference

This is my initial code framework:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var textInput, submitButton, resultPara, fileInput;

// Callback function to handle uploaded text file
function handleInputFile(file){
//file contains the uploaded file object
if(file.type == 'text'){
//read the text
} else {
//ask the user to only use text files
}
}

function setup() {
//Elements I need:
// 1. a text box
// 2. a submit button
// 3. a result display div
// 4. a file popup
//functionalities:
// 1. copy-paste text to the text box
// 2. on clicking upload, open a text file accepting popup
// 3. on finishing upload, copy the text to the textbox
// 4. on submit, present the finished text on the display div
//optional functionalities:
// - filter for only text files
// - slider/radio buttons
// - color/audio
}

function draw() {
}

This is what the final code looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
var textInput, submitButton, resultPara, originalPara, fileInput;

var fibonacci_prev, fibonacci_curr, temp;

//Reset fibonacci variables
function resetFibo(){
fibonacci_prev = 1
fibonacci_curr = 1
}

// Callback function to handle uploaded text file
function handleInputFile(file){
//file contains the uploaded file object
if(file.type == 'text'){
textInput.value(file.data)
} else {
alert('Please upload a text file!')
}
}

//To filter words based on index
function filterWordsByIndex(index){
//one-based indexing
if(index + 1 == fibonacci_curr){
//change fibo
temp = fibonacci_prev
fibonacci_prev = fibonacci_curr
fibonacci_curr = temp + fibonacci_prev
return true
}
return false
}

//Callback function to display the constrained text from the input text
function displayConstrainedText(){
resetFibo()
//perform constraining operations
constrainedText = ''
// 1. remove any character which isnt an alphabet
textWords = textInput.value().replaceAll(',',' ').replaceAll('.',' ').replaceAll(':',' ').replaceAll('"',' ').replaceAll('-',' ')
textWordsList = textWords.split(' ')
// 2. apply
textWordsList.forEach((element, index) => {
if(filterWordsByIndex(index)){
constrainedText += element
constrainedText += ' '}
else{
textWordsList[index] = "#".repeat(element.length)}
})

originalWithHashedOutWords = textWordsList.join(' ')
resultPara.html(constrainedText)
originalPara.html(originalWithHashedOutWords)
}

function setup() {
//createCanvas(400, 400);
noCanvas();
resetFibo()
//Elements I need:
// 1. a text box
textInput = createInput("Text goes here");
// 2. a upload/submit button
submitButton = createButton('Submit');
// 3. a result display div
// 4. a file popup
fileInput = createFileInput(handleInputFile);
fileInput.position(0,50)
resultPara = createP('Constrained text is displayed here!');
resultPara.position(0,100)
originalPara = createP('Original text with hashed out words is displayed here!');
originalPara.position(0,200)
//functionalities:
// 1. copy-paste text to the text box
// 2. on clicking upload, open a text file accepting popup
// 3. on finishing upload, copy the text to the textbox
// 4. on submit, present the finished text on the display div
submitButton.mousePressed(displayConstrainedText)
//optional functionalities:
// - filter for only text files
// - slider/radio buttons
// - color/audio
}

function draw() {
}

Things I learnt along the way:

  1. console.log(<variable_name>) is a handy way to debug your p5js (or js in general) code.
  2. For an <input> tag, the html() method is useless. For a <p> tag on the other hand, it can be used to get/set the inner text.
  3. Tag attributes and DOM Node properties are two different things. Tag attributes can be used to attach a default value to a tag, but its corresponding DOM will have a corresponding property which is what stores live value. Use <object>.value(<property_name>) to access DOM node properties.
  4. The split() string method splits a sentences at spaces (and into words) only if you provide ' ' as an additional argument.
  5. If a callback method is tinkering with global variables, make sure that those variables are reset before the callback gets invoked again.
  6. The replace() string method only replaces the first occurrence of a token. Use replaceAll() to replace all occurences.
  7. Even if you don’t include a createCanvas() line, p5 creates a canvas by default. Use noCanvas() in the setup to avoid that.

Open Questions:

  1. Is p5.Element a subclass of Html DOM Element? If so, why is the setAttribute() method not available for p5 objects?

Improvements that can be done to this:

  1. Better relative positioning of elements.
  2. Add horizontal/vertical slider to input text area and make it readable.
  3. Add some pizzaz (audio/color).

Takeaways:

  1. Ask yourself, What’s the bare minimum that needs to be done to get something to work? before thinking about the final form.
  2. p5 reference is not detailed.
  3. p5 web editor could use auto-suggestion plugins or something.
  4. Need to find a way to debug p5 scripts in real time.
  5. Use constrained and iterative thinking to go about solving any problem!

Demo: