-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHTMLEcho.js
126 lines (107 loc) · 3.31 KB
/
HTMLEcho.js
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
class HTMLEcho {
#source;
#sourceText;
#config = {
lengths: {
'para': 3,
'minHeading': 15,
'maxHeading': 60,
'minList': 20,
'maxList': 80
}
};
constructor(textFile) {
this.#source = textFile;
this.#sourceText = "";
this.textLoaded = this.loadText();
}
async loadText() {
const response = await fetch(this.#source);
this.#sourceText = await response.text();
this.#sourceText = this.#sourceText.replace(/ \t/g, " ").trim();
}
#getRandomSentences(sentenceCount) {
const sentences = this.#sourceText
.split("\n")
.map((line) => line.trim())
.filter((line) => line);
if (sentences.length === 0) return "";
let output = [];
for (let i = 0; i < sentenceCount; i++) {
let sentence = sentences[Math.floor(Math.random() * sentences.length)];
sentence = sentence.charAt(0).toUpperCase() + sentence.slice(1);
output.push(sentence);
}
return output.join(" ");
}
async generateHTML(structure = "p-5") {
await this.textLoaded;
if (!this.#sourceText) {
const outputElem = document.getElementById("output");
if (outputElem)
outputElem.innerHTML = "Loading text... Try again in a moment.";
return "";
}
const tagMap = {
p: (count) =>
Array.from(
{ length: count },
() => `<p>${this.#getRandomSentences(this.#config.lengths.para)}</p>`
).join(""),
ol: (count) => `<ol>${this.#generateListItems(count)}</ol>`,
ul: (count) => `<ul>${this.#generateListItems(count)}</ul>`,
h: (level, count) =>
Array.from(
{ length: count },
() => {
const validLevel = Math.max(1, Math.min(6, level));
return `<h${validLevel}>${this.#getSentenceWithLength(this.#config.lengths.minHeading, this.#config.lengths.maxHeading)}</h${validLevel}>`;
}
),
};
return structure
.split(",")
.map((item) => {
const [tag, count] = item.split("-");
if (tag.startsWith("h")) {
const level = parseInt(tag.substring(1), 10) || 2;
return tagMap.h(level, parseInt(count, 10) || 1);
}
return tagMap[tag] ? tagMap[tag](parseInt(count, 10)) : "";
})
.join("");
}
setConfig(options = {}) {
if (options.lengths) {
Object.keys(options.lengths).forEach((key) => {
if (typeof options.lengths[key] !== "number") {
console.warn(`Ignoring invalid config value for ${key}: Expected a number.`);
delete options.lengths[key];
}
});
}
this.#config = {
...this.#config,
...options,
lengths: {
...this.#config.lengths,
...(options.lengths || {})
}
};
}
#generateListItems(count) {
return Array.from(
{ length: count },
() => `<li>${this.#getSentenceWithLength(this.#config.lengths.minList, this.#config.lengths.maxList)}</li>`
).join("");
}
#getSentenceWithLength(min, max) {
let sentence, attempts = 0;
const maxAttempts = 100;
do {
sentence = this.#getRandomSentences(1);
attempts++;
} while ((sentence.length < min || sentence.length > max) && attempts < maxAttempts);
return sentence.length >= min && sentence.length <= max ? sentence : "I couldn't get anything.";
}
}