The Cut-Up Technique

If you’re like me and enjoy the occasional (or more than occasional) bout with surrealism, you might like the cut-up technique, which takes an existing text, chops it into small pieces, and rearranges it. As might be expected, the results are about 99% worthless and 1% genius.

I rediscovered the technique tonight, after bumping into it a score of times over the past ten or so years, and simultaneously rediscovered the reason I’ve neglected it – there are very few online scripts that do a good job of it, no Mac programs that I’m aware of, and almost none allow profound configuration of the variables that go into it.

So I wrote myself a little AppleScript that takes a DEVONthink Pro document’s plain text, cuts it up, scrambles it, reassembles it, and creates a new document in the root folder with the results. It seems to work pretty well, so far.

I thought I’d post it on here for anyone who similarly gets a kick/inspiration/comic relief out of this sort of thing. It should compile and run without any problems, and deal with almost any alteration to the initial variables gracefully and efficiently.


with timeout of 900 seconds
	-- Initial Variables
	set theSelectionText to ""
	set theOldDelimiters to AppleScript's text item delimiters
	set theScopeLimitation to 15000
	set theUniqueDelimiter to "15234"
	set theScrambleFactor to 2
	set theCompressionFactor to 1
	set thePhraseLengthFactor to 4
	set theRepetitions to 1
	set theName to ("Cutup -- " & (current date) as string)
	set theItemsToDelete to {" ", "\"", ".", "*", "'s"}
	set theCompressionLimit to 25
	-- Main tell block
	tell application "DEVONthink Pro"
		
		-- Text Extraction
		set theSelection to the selection
		if the selection is {} then error "Please select one or more articles."
		repeat with thisSelection in theSelection
			set thisSelectionText to the plain text of thisSelection
			set theSelectionText to theSelectionText & " " & thisSelectionText
		end repeat
		
		-- Scope Limitation
		set AppleScript's text item delimiters to ""
		if ((count of the characters of theSelectionText) is greater than theScopeLimitation) then set theSelectionText to (characters 1 thru theScopeLimitation of theSelectionText as string)
		
		-- Set up theResultingText for the main loop
		set theResultingText to theSelectionText
		
		-- The main loop begins
		repeat with theRepetitionCounter from 1 to theRepetitions
			
			-- Text Item Extraction
			set AppleScript's text item delimiters to " "
			set theSelectionTextItems to the text items of theResultingText
			
			-- Text Purification
			set AppleScript's text item delimiters to theUniqueDelimiter
			set theSelectionTextItems to theUniqueDelimiter & theSelectionTextItems & theUniqueDelimiter
			repeat with thisItemToDelete in theItemsToDelete
				set AppleScript's text item delimiters to theUniqueDelimiter & thisItemToDelete & theUniqueDelimiter
				set theSelectionTextItems to theSelectionTextItems's text items
				set AppleScript's text item delimiters to theUniqueDelimiter
				set theSelectionTextItems to theSelectionTextItems as text
			end repeat
			set AppleScript's text item delimiters to theUniqueDelimiter
			set theSelectionTextItems to (theSelectionTextItems's texts 6 thru -6)'s text items
			
			-- Random Concatenations
			set AppleScript's text item delimiters to " "
			repeat with theCompressionCounter from 1 to theCompressionFactor
				set theTextItemCount to (count of the text items of theSelectionTextItems)
				repeat with theCompressedTextItem from 1 to theTextItemCount
					if (count of the characters of theSelectionTextItems) is less than theCompressionLimit then
						try
							
							repeat with theCompressorCounter from 1 to (random number from 1 to thePhraseLengthFactor)
								set (text item theCompressedTextItem of theSelectionTextItems) to ((text item theCompressedTextItem of theSelectionTextItems) & " " & (text item (theCompressedTextItem + theCompressorCounter) of theSelectionTextItems))
								set theSelectionTextItems to (items 1 thru (theCompressedTextItem + theCompressorCounter - 1) of theSelectionTextItems) & (items (theCompressedTextItem + theCompressorCounter + 1) thru -1 of theSelectionTextItems)
							end repeat
						end try
					end if
				end repeat
			end repeat
			
			-- Scramble
			repeat with theScrambleCounter from 1 to theScrambleFactor
				repeat with theScramble2Counter from 1 to (count of the text items of theSelectionTextItems)
					set theRandomNumber to (random number from 1 to (count of the text items of theSelectionTextItems))
					set thisSwapItem to text item theScramble2Counter of theSelectionTextItems
					set thePlaceholder to thisSwapItem
					set thisSwapItem to (text item theRandomNumber of theSelectionTextItems)
					set (text item theRandomNumber of theSelectionTextItems) to thePlaceholder
				end repeat
			end repeat
			
			-- Reassemble
			set theResultingText to theSelectionTextItems as text
			
			-- The main loop ends
		end repeat
		
		-- Import into DEVONthink Pro
		create record with {name:theName, type:txt, plain text:theResultingText}
	end tell
end timeout

Notes:

  • I set timeout to fifteen minutes for obvious reasons. It executes quickly, but if you’re going to be cutting up Anna Karenina, you might have to adjust this upwards.
  • theScopeLimitation allows you to truncate the amount of text you actually work with, so that you don’t have to create new documents with partial contents just to mess around with.
  • theUniqueDelimiter is used in the (hopefully optimized) purification scheme. Don’t change it without altering the numbers in the last line of the “Text Purification” section to equal the number of characters in theUniqueDelimiter’s value + 1.
  • theScrambleFactor refers to the number of times (in each repetition of the main routine) that the text items are swapped around. More than one is probably unnecessary, but it’s nice to be able to tweak it.
  • theCompressionFactor refers to the number of times (in each repetition of the main routine) that some of the text items will be concatenated to their adjoining items. Again, more than one might or might not be useful and worth the added processing time.
  • theCompressionLimit refers to the number of characters that should be considered the upper limit for a given text item’s length. If the text item is longer than that, then no more text items are concatenated to it.
  • thePhraseLengthFactor refers to the number of text items that can be concatenated in a single pass. It concatenates from zero to this number of phrases to the original phrase randomly.
  • theRepetitions refers to the number of times you run through the main block of the script. As you can guess, it increases the execution time of the script immensely, and chops the text more finely.
  • theName is the name of the resulting record.
  • theItemsToDelete is an array of useless little words. You can add any that you don’t want to see… conjunctions, articles, and so forth don’t really provide any value.

I hope at least one person is amused by this, because it took a long time to write this post :smiley:

Great!

With a bit of tweaking one can turn Hemingway into James Joyce. :smiley:

You can also do something similar with Tinderbox, using the Explode Note function. It may not be random enough for this technique, but I’ve used it for instance in mind mapping, to cluster similar information from multiple sources.

Katherine