-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathblackout-poetry.js
More file actions
138 lines (109 loc) · 5.29 KB
/
blackout-poetry.js
File metadata and controls
138 lines (109 loc) · 5.29 KB
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
const examples = [
{
title: "Artists",
text: `<!-- Austin Kleon, via https://austinkleon.com/2022/10/24/comfort-work/ . Based on the New York Times print edition, May 24, 2020 -->
<!-- https://www.nytimes.com/2020/05/23/arts/design/houston-art-museum-reopen-virus.html -->
[Mr. Tinterow has several friends in New York who have died from Covid-19, the disease caused by the coronavirus.“]Artists [galleries, and museums are suffering right now,” he said, “but I have been saying for some time that the contemporary art world has reached a fever pitch.”]
<!-- https://www.nytimes.com/2020/05/24/us/17-year-cicadas-virginia.html -->
[The billions that are left alive can then mate in peace and lay their eggs. The adults] quickly die off after their work is done[. Once their eggs hatch, the nymphs fall to the ground, where they will nestle into the earth for the next 17 years.]
[Entomologists believe that periodical cicadas evolved to emerge every 13 to 17 years to avoid syncing up with the population boom]s o[f their predators.]
[The predictability of the cycle makes it possible for farmers to ]plan ahead,[ he said.]
[For that reason, Professor Pfeiffer recommends that growers] avoid [planting new trees in the year or two leading up to an emergence, he said.]
[Ms. Noonkester said she expected that cicadas would come from other parts of the state and desc]end [soon on her young trees to lay eggs. All she can do, she said, besides hop]ing [that a majority of them will stick to the forest, is prune any twigs that they do damage and keep grabbing and stomping errant cicadas.]
`,
},
{
title: "Excelint (Every Mess)",
text: `<!-- me (Bobbie Chen), based on my blog post "Every app is a messaging app" https://digitalseams.com/blog/every-app-is-a-messaging-app -->
#### Every [app is a] mess[aging app]
[3/23/2025]
[Every application] will be [used for messaging. What do spreadsheets, email dr]a[fts, and system notifications have in common? Inventive people use them in creative] way[s] to [send and] receive [messages. People] love [to talk to each other], and it's [incredibly hard to stop them. [Here are a few examples.]
##### Real[-time chat, through document editing]
[Messaging via] Excel? In t[he music video for "Dilemma" (2002), Kelly Rowland and Nelly were mocked for this [""text message"" in the spreadsheet app on a Nokia 9210 Communicator:]
`,
},
{
title: "Computer sad :(",
text: `<!-- The earliest version of this I found was https://virtualgirladvance.tumblr.com/post/777249377277411328 -->
A COMPUTER CAN NEVER BE HELD [ACCOUNTABLE]
THEREFORE [A] COMPUTER [MU]S[T NEVER M]A[KE A MANAGEMENT]D[ECISION]
-- IBM training manual (1979)`,
},
{
title: "Custom",
text: `Enter your own text here.
Use [brackets] to mark text that will be blacked out.`,
},
]
const inputText = document.getElementById("inputText")
const displayDiv = document.getElementById("display")
const tabsContainer = document.getElementById("tabs")
const tabButtons = []
let customText = examples[3].text
let currentTab = 1
// Function to handle URL query parameters
function getTabFromUrl() {
const params = new URLSearchParams(window.location.search)
const tabIndex = parseInt(params.get("poem"))
return !isNaN(tabIndex) && tabIndex >= 1 && tabIndex <= examples.length
? tabIndex
: 1
}
// Function to update URL with current tab
function updateUrl() {
const url = new URL(window.location)
url.searchParams.set("poem", currentTab)
window.history.pushState({}, "", url)
}
// Create tabs
examples.forEach((example, index) => {
const tab = document.createElement("button")
tab.className = "tab-button"
tab.textContent = example.title
tab.onclick = () => switchExample(index + 1)
tabsContainer.appendChild(tab)
tabButtons.push(tab)
})
function switchExample(index) {
if (currentTab === index) return // Don't switch to same tab
if (currentTab === examples.length) {
customText = inputText.value
}
// Update active tab - more efficient than querySelectorAll
tabButtons[currentTab - 1].classList.remove("active")
tabButtons[index - 1].classList.add("active")
// Update content
inputText.value =
index === examples.length ? customText : examples[index - 1].text
currentTab = index
updateUrl() // Update URL when switching tabs
render(inputText.value)
}
// Debounce the render function for input changes
let renderTimeout
function debouncedRender() {
if (renderTimeout) clearTimeout(renderTimeout)
renderTimeout = setTimeout(() => render(inputText.value), 10)
}
// Modified input handler
inputText.addEventListener("input", () => {
if (currentTab !== examples.length) {
customText = inputText.value
switchExample(examples.length)
} else {
debouncedRender()
}
})
function render(markdownText) {
let renderedHTML = marked.parse(markdownText)
renderedHTML = renderedHTML.replace(
/\[(.*?)\]/g,
'<span class="blackout">$1</span>'
)
displayDiv.innerHTML = renderedHTML
}
// Initial render
currentTab = getTabFromUrl()
tabButtons[currentTab - 1].classList.add("active")
inputText.value = examples[currentTab - 1].text
render(inputText.value)