-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdiscord-vertical-text.html
309 lines (295 loc) · 13.1 KB
/
discord-vertical-text.html
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
<!DOCTYPE html>
<html lang="en">
<head>
<title>discord vertical text generator</title>
<meta property="og:site_name" content="orbit-loona.github.io" />
<meta property="og:type" content="website" />
<meta property="og:title" content="discord vertical text generator" />
<meta property="og:url" content="https://orbit-loona.github.io/tone.html" />
<meta property="og:description" content="Make cursed sideways text in Discord (why)" />
<meta property="og:locale" content="en_US" />
<meta property="og:image" content="https://orbit-loona.github.io/bin/skibidi-toilet.png" />
<meta property="og:image:width" content="44" />
<meta property="og:image:height" content="316" />
<meta property="og:image:alt" content="image" />
<meta name="twitter:image:src" content="https://orbit-loona.github.io/bin/skibidi-toilet.png" />
<meta name="twitter:title" content="discord vertical text generator" />
<meta name="twitter:description" content="Make cursed sideways text in Discord (why)" />
<link rel="stylesheet" href="main.css"/>
<meta name="SKYPE_TOOLBAR" content="SKYPE_TOOLBAR_PARSER_COMPATIBLE">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="author" content="An Orbit">
<meta charset="UTF-8">
<style>
.heck { font-size: 80%; opacity: 0.8; }
div#warnings { color: #ffafaf; font-size: 75%; }
#preOutput { white-space: pre-wrap; background-color: #222528; border: 1px solid #afafaf; }
#lengthWarningSpan { padding: 2px; line-height: 140%; font-size: 110%; }
.warning1 {
color: #ff3f2f;
}
.warning2 {
color: #ff0f0f;
font-weight: bold;
letter-spacing: 1px;
}
</style>
<script>
function arrayToSplit(arr,chunk_size) { //https://stackoverflow.com/a/19679493
var groups = arr.map( function(e,i){
return i%chunk_size===0 ? arr.slice(i,i+chunk_size) : null;
}).filter(function(e){ return e; });
return groups
}
function toTransposed2D(array) { //https://stackoverflow.com/a/17428705
return array[0].map((_, colIndex) => array.map(row => row[colIndex]));
}
function logAndReturn(x) {
console.log(x);
return x
};
function generate(input,maxCharsPerLine) {
letters = {
A:"<⁚⁚I⁚⁚⁚⁚",
B:"/⁚⁚I⁚⁚\\\\",
C:"\\\\\\_\\_/",
D:"/⁚⁚⁚⁚⁚\\\\",
E:"|\\_|\\_|",
F:"|\\_|\\_.",
G:"\\\\\\_⁚⁚/",
H:"⁚⁚⁚⁚I⁚⁚⁚⁚",
I:"|---|",
J:"\"\"\"\")",
K:"⁚⁚⁚v⁚⁚⁚",
L:"\\_\\_\\_|",
M:"|ΞΞΞ",
N:"(⁚⁚⁚⁚⁚⁚⁚",
O:"(⁚⁚⁚⁚⁚⁚)",
P:"/⁚⁚\\\\\\_.",
Q:"(⁚⁚⁚⁚⁚}-'",
R:"/⁚\\\\/⁚⁚",
S:"\\\\./'\\\\",
T:"|----",
U:"⁚⁚⁚⁚⁚⁚⁚)",
V:"⁚⁚⁚⁚⁚⁚>",
W:"ΞΞΞ|",
X:"⁚⁚⁚X⁚⁚⁚",
Y:"⁚>---",
Z:"|\"'-..|",
a:" (\"I⁚I",
b:"\\_\\_O",
c:" \\\\\\_/",
d:"\"\"\"O",
e:" (⁚I.)",
f:"ı\\_ı\\_.",
g:" (⁚⁚I')",
h:"\\_\\_I⁚⁚",
i:" . \\_\\_",
j:"\\- --,",
k:".\\_⁚v⁚",
l:" \\---'",
m:" EΞ",
n:" (⁚⁚⁚⁚",
o:" (⁚⁚⁚⁚)",
p:"O\\_\\_",
q:"O\"\"\"",
r:" ı.\\_",
s:" ı.rı",
t:"\\-I--'",
u:" ⁚⁚⁚⁚)",
v:" ⁚⁚>",
w:" ΞI",
x:" ⁚X⁚",
y:" >-.",
z:" |'-.|",
1:",---I",
2:"/\"\\.I",
3:"/\"ı\"\\\\",
4:"⁚⁚⁚⁚|\"\"'",
5:"I./\"\\\\",
6:"(..I⁚⁚)",
7:"|'`--.",
8:"(⁚X⁚⁚)",
9:"(⁚⁚I\"')",
0:"(⁚⁚\\\\⁚⁚)",
"^":"< ",
"<":" V ",
">":" /\\\\ ",
".":" .",
":":" . . ",
";":" . -",
"/":" ``-.. ",
"\\":" ..-'' ",
"[":"I.....I",
"]":"I\"\"\"\"I",
"(":"·\"\"\"'·",
")":"·.....·",
"{":".-\"-.",
"}":"'-..-'",
"+":" \\-I\\- ",
"$":"-ı.·'ı-",
",":" \\-",
"-":" | ",
"=":" I I ",
"_":" |",
" ":"** **",
"!":"\\_\\_ ..",
"?":"(\\\\. .",
"'":"\\- ",
'"':"= ",
'%':" , \\\\ ' ",
'&':" ı.Ix "
};
var nextMcplIncrement = Math.ceil(input.length / maxCharsPerLine) * maxCharsPerLine;
input = input.padEnd(nextMcplIncrement," ");
var output = "";
var lineJoiner = " ";
result = input.split("").map(x => letters[x] ?? letters["?"]).map(x => x.trim() == "" ? `**${x}**` : x);
var linesNeeded = Math.ceil(result.length / maxCharsPerLine);
for(var i = 0; i < result.length; i++) {
var lineNumber = Math.floor(i / maxCharsPerLine);
var positionInLine = i % maxCharsPerLine;
if(lineNumber < 1) {
output = result[i] + "\n" + output
} else {
var positionComplement = (maxCharsPerLine - 1) - positionInLine;
var outputSplitByNewline = output.split("\n");
var indexOfFinalLetter = (lineNumber * maxCharsPerLine) + positionComplement;
var finalLetter = result[indexOfFinalLetter];
var whileTries = 0;
outputSplitByNewline[positionInLine] = outputSplitByNewline[positionInLine] + lineJoiner + finalLetter;
output = outputSplitByNewline.join("\n");
outputSplitByNewline = null
}
};
var spaceForRegex = letters[" "].replaceAll("*","\\*");
var regex = RegExp(lineJoiner + spaceForRegex + "$","gm");
output = output.replace(regex,"");
if(linesNeeded < 2) { output = output.replace(RegExp("^(" + spaceForRegex + "[\\r\\n]+)*"),"** **") }
if(output.startsWith(" ")) { output = output.replace(" ","** **") };
return output
};
function doGeneration(inputOverride=null,mcplOverride=null) {
var input = inputOverride ?? (document.getElementById("textInput")?.value || ""); //I LOVE PARK JIHYO FROM THE GIRL GROUP \"TWICE\"";
var maxCharsPerLine = mcplOverride ?? (Number(document.getElementById("maxCharsPerLine")?.value ?? "10"));
var generatorResult = generate(input,maxCharsPerLine);
var lengthWarningSpan = document.getElementById("lengthWarningSpan");
console.log(generatorResult.length);
if(lengthWarningSpan) {
if(generatorResult.length <= 2000) {
lengthWarningSpan.innerText = `Length: ${generatorResult.length.toLocaleString()} characters`
if(lengthWarningSpan.classList.contains("warning1")) {
lengthWarningSpan.classList.remove("warning1")
};
if(lengthWarningSpan.classList.contains("warning2")) {
lengthWarningSpan.classList.remove("warning2")
}
} else if(generatorResult.length > 4000) {
lengthWarningSpan.innerText = `Warning: Message is too long for Discord even with Nitro (${generatorResult.length.toLocaleString()} characters)`;
if(lengthWarningSpan.classList.contains("warning1")) {
lengthWarningSpan.classList.remove("warning1")
};
if(!(lengthWarningSpan.classList.contains("warning2"))) {
lengthWarningSpan.classList.add("warning2")
}
} else if(generatorResult.length > 2000) {
lengthWarningSpan.innerText = `Warning: Message is too long for Discord without Nitro (${generatorResult.length.toLocaleString()} characters)`;
if(!(lengthWarningSpan.classList.contains("warning1"))) {
lengthWarningSpan.classList.add("warning1")
};
if(lengthWarningSpan.classList.contains("warning2")) {
lengthWarningSpan.classList.remove("warning2")
}
}
}
var outputDestination = document.getElementById("preOutput");
if(outputDestination) {
outputDestination.innerText = generatorResult
}
return !!outputDestination && !!(input.length > 0)
};
function copyOutputFromOutputDiv() {
var copyText = document.getElementById("preOutput");
if(navigator?.clipboard?.writeText) {
navigator.clipboard.writeText(copyText.innerText);
} else {
copyText.select();
copyText.setSelectionRange(0, copyText.innerText.length);
Document.execCommand("copy")
}
};
function makePermanentLink(input,maxCharsPerLine) {
if(!([null,undefined].includes(maxCharsPerLine)) && typeof(maxCharsPerLine) == "number") {
maxCharsPerLine = maxCharsPerLine.toString()
};
var queryParamInput = encodeURIComponent(input);
var queryParamMCPL = null; if(maxCharsPerLine) { queryParamMCPL = encodeURIComponent(maxCharsPerLine) };
var baseURL = window.location.origin + window.location.pathname;
var finalURL = `${baseURL}?text=${queryParamInput}`;
if(queryParamMCPL) { finalURL += `&mcpl=${queryParamMCPL}` }
return finalURL;
};
function displayPermanentLink(url) {
var newLink = document.createElement("a");
newLink.setAttribute("href",url);
newLink.innerText = url;
newLink.setAttribute("target","_blank");
var linkDestination = document.getElementById("linkOutput");
linkDestination.childNodes.forEach(function(x) { x.parentElement.removeChild(x); x = null });
linkDestination.innerText = "";
linkDestination.appendChild(newLink)
};
function doPermanentLinkGeneration() {
var input = document.getElementById("textInput")?.value; //I LOVE PARK JIHYO FROM THE GIRL GROUP \"TWICE\"";
if(!input || input.length == 0) { return false };
var maxCharsPerLine = document.getElementById("maxCharsPerLine")?.value;
if(!!maxCharsPerLine) { maxCharsPerLine = Number(maxCharsPerLine) } else { maxCharsPerLine = null };
var url = makePermanentLink(input,maxCharsPerLine);
displayPermanentLink(url)
};
</script>
</head>
<body>
<h1>Discord vertical text generator</h1>
<div id="warnings">
<span>Warnings and Disclaimers:</span>
<ol>
<li>Please be mindful of servers' rules, and do not use this when it is not allowed (either for spam or accessibility reasons). If a server moderator asks you to stop posting text generated with this page, then stop using it.</li>
<li>This is not accessible at all. Screen readers may skip over the generated text or read it as a long sequence of symbols; even then, they certainly wouldn't ever be able to <em>understand</em> it since it's not really made of actual letters. Discord's "Speak Message" feature reads outputs of this generator as a long and unintelligible mess of words that may include "slash", "backslash", "underscore", "dash", "I", "X", and "equals".</li>
<li>This can easily flood chats due to its vertical direction. Please minimize disruption by limiting the maximum characters per vertical "line".</li>
<li>This text uses Discord formatting and font rendering quirks that may change in the future, which could make the text generated by this tool distorted or even illegible. Note that this generator makes heavy use of the Unicode "two dots" punctuation character "⁚", so this text will be illegible to users whose systems cannot display the character.</li>
<li>The text made by this generator is formatted for Discord, including escaping of backslashes "\" and underscores "_". It will be illegible until it is parsed by Discord's Markdown-variant text parser.</li>
<li>This page uses code by StackOverflow users <a href="https://stackoverflow.com/a/19679493">Mirodil</a> and <a href="https://stackoverflow.com/a/17428705">Fawad Ghafoor</a>, and is thus licensed under the <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0 license</a>.</li>
<li>This generator does not support manual line breaks in the vertical text.</li>
<li>Characters not programmed into the generator will display as question marks "?".</li>
<li>The amount of spacing between "lines" is not varied and the spacing between "letters" in general may need tweaking or the lines will be crooked.</li>
</ol>
</div>
<input id="textInput" placeholder="Hello, world!"/><br/>
<input id="maxCharsPerLine" type="number" value="10" placeholder="10"/><br/>
<button onclick="doGeneration()">Generate text</button>
<span id="label">Paste the text below into the Discord message bar</span>
<p id="preOutput"> </p>
<button onclick="copyOutputFromOutputDiv()">Copy</button> <span id="lengthWarningSpan"> </span><br/><br/>
<button onclick="doPermanentLinkGeneration()">Get link to these values</button><br/><br/>
<p id="linkOutput"> </p>
<script>
function enterListener(e) {
if(e.key == "Enter") {
doGeneration()
}
};
document.getElementById("textInput").addEventListener("keydown",function(e) { enterListener(e) });
document.getElementById("maxCharsPerLine").addEventListener("keydown",function(e) { enterListener(e) });
urlParams = new URLSearchParams(window.location.search);
var urlText = urlParams.get("text");
var urlMCPL = Number(urlParams.get("mcpl") ?? "10");
if(urlText !== null) {
document.getElementById("textInput").value = urlText;
document.getElementById("maxCharsPerLine").value = urlMCPL.toString();
doGeneration(urlText,urlMCPL);
}
</script>
<br/><br/><a href="index.html"><small>go to main page</small></a>
</body>
</html>