Skip to content

Commit dc8bb27

Browse files
committed
fix html terminal to support linebreaks inside lines
1 parent e97820a commit dc8bb27

File tree

5 files changed

+89
-189
lines changed

5 files changed

+89
-189
lines changed

00_Common/javascript/WebTerminal/HtmlTerminal.js

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,18 @@ class HtmlTerminal {
9696
this.#inputCallback = undefined;
9797
} else if (e.keyCode === 8 /* BACKSPACE */) {
9898
this.#$prompt.innerText = this.#$prompt.innerText.slice(0, -1);
99+
} else if (
100+
e.keyCode == 16 // "Shift"
101+
|| e.keyCode == 17 // "Control"
102+
|| e.keyCode == 20 // "CapsLock"
103+
|| !e.key.match(/^[a-z0-9!"§#$%&'()*+,.\/:;<=>?@\[\] ^_`{|}~-]$/i)
104+
) {
105+
// ignore non-visible characters
106+
return e;
99107
} else {
100108
this.#$prompt.innerHtml = '';
101-
this.#$prompt.innerText = this.#$prompt.innerText + e.key;
109+
const key = e.shiftKey ? e.key.toUpperCase() : e.key;
110+
this.#$prompt.innerText = this.#$prompt.innerText + key;
102111
}
103112
}
104113

@@ -135,27 +144,23 @@ class HtmlTerminal {
135144
* @param {string} text
136145
*/
137146
write(text) {
138-
if (text.match(/^\n*$/)) {
139-
// empty new line
140-
text.match(/\n/g).forEach(() => {
141-
const $br = document.createElement("br");
142-
this.$output.appendChild($br);
143-
});
144-
} else if (text && text.length && text.includes("\n")) {
147+
if (!text || text.length <= 0) {
148+
// empty line
149+
this.$output.appendChild(document.createElement("br"));
150+
} else if (text.endsWith("\n")) {
151+
// single line with linebrank
152+
const $lineNode = this.#newLine(text);
153+
this.$output.appendChild(this.#newLine(text));
154+
this.$output.appendChild(document.createElement("br"));
155+
} else if (text.includes("\n")) {
156+
// multible lines
145157
const lines = text.split("\n");
146158
lines.forEach((line) => {
147-
if (line.length === 0 || line.match(/^\s*$/)) {
148-
this.$output.appendChild(document.createElement("br"));
149-
} else {
150-
const $lineNode = this.#newLine(line);
151-
this.$output.appendChild($lineNode);
152-
//this.$node.appendChild(document.createElement("br"));
153-
}
159+
this.write(line);
154160
});
155-
} else if (text && text.length) {
156-
// simple line
157-
const $lineNode = this.#newLine(text);
158-
this.$output.appendChild($lineNode);
161+
} else {
162+
// single line
163+
this.$output.appendChild(this.#newLine(text));
159164
}
160165

161166
// scroll to the buttom of the page

00_Common/javascript/WebTerminal/terminal_tests.mjs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@
33
import { print, println, tab, input } from '../common.mjs';
44

55
async function main() {
6-
println(tab(20), "Minimal node.js terminal 2");
7-
println("");
6+
println(tab(30), "Minimal node.js terminal emulator");
7+
println();
88
println(tab(0), "tab 0");
99
println(tab(5), "tab 5");
1010
println(tab(10), "tab 10");
1111
println(tab(15), "tab 15");
1212
println(tab(20), "tab 20");
1313
println(tab(25), "tab 25");
14-
println("");
15-
println("1234567890", " ", "ABCDEFGHIJKLMNOPRSTUVWXYZ");
16-
println("");
14+
println();
15+
println("1234567890", " _ ", "ABCDEFGHIJKLMNOPRSTUVWXYZ");
16+
println();
1717
print("\nHallo"); print(" "); print("Welt!\n");
1818
println("");
19-
print("Line 1\nLine 2\nLine 3\nLine 4");
20-
println("");
19+
println("Line 1\nLine 2\nLine 3\nLine 4");
20+
println("----------------------------------------------");
2121

2222
const value = await input("input");
2323
println(`input value was "${value}"`);

00_Common/javascript/common.mjs

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,67 @@
1-
1+
/**
2+
* Print multible strings to the terminal.
3+
* Strings get concatinated (add together) without any space betweent them.
4+
* There will be no newline at the end!
5+
* If you want a linebrak at the end use `println`.
6+
*
7+
* This function is normally used if you want to put something on the screen
8+
* and later add some content to the same line.
9+
* For normal output (similar to `console.log`) use `println`!
10+
*
11+
* @param {...string} messages - the strings to print to the terminal.
12+
*/
213
export function print(...messages) {
3-
process.stdout.write(messages.join(""));
14+
process.stdout.write(messages.join(""));
415
}
516

17+
/**
18+
* Add multible strings as a new line to the terminal.
19+
* Strings get concatinated (add together) without any space betweent them.
20+
* There will be a newline at the end!
21+
* If you want the terminal to stay active on the current line use `print`.
22+
*
23+
* @param {...any} messages - the strings to print to the terminal.
24+
*/
625
export function println(...messages) {
7-
process.stdout.write(messages.join("") + "\n");
26+
process.stdout.write(messages.join("") + "\n");
827
}
928

10-
export function tab(count) {
11-
return " ".repeat(count);
29+
/**
30+
* Create an empty string with a given length
31+
*
32+
* @param {number} length - the length of the string in space-characters.
33+
* @returns {string} returns a string containing only ampty spaces with a length of `count`.
34+
*/
35+
export function tab(length) {
36+
return " ".repeat(length);
1237
}
1338

14-
export async function input(message = "") {
15-
process.stdout.write(message + ' ');
16-
return new Promise(resolve => {
17-
process.stdin.on('data', (input) => {
18-
resolve(input.toString().replace('\n', ''));
19-
});
20-
});
39+
/**
40+
* Read input from the keyboard and return it as a string.
41+
* TODO: to would be very helpfull to only allow a certain class of input (numbers, letters)
42+
* TODO: also we could convert all inputs to uppercase (where it makes sence).
43+
*
44+
* @param {string=''} message - a message or question to print befor the input.
45+
* @returns {Promise<string>} - returns the entered text as a string
46+
* @async
47+
*/
48+
export async function input(message = '') {
49+
/* First we need to print the mesage
50+
* We append a space by default to seperate the message from the imput.
51+
* TODO: If the message already contains a space at the end this is not needed! */
52+
process.stdout.write(message + ' ');
53+
54+
return new Promise(resolve => {
55+
process.stdin.on('data', (input) => {
56+
/* onData returns a Buffer.
57+
* First we need to convert it into a string. */
58+
const data = input.toString();
59+
60+
/* The result fo onData is a string ending with an `\n`.
61+
* We just need the actual content so let's remove the newline at the end: */
62+
const content = data[data.length] === '\n' ? data.slice(0, -1) : data;
63+
64+
resolve(content);
65+
});
66+
});
2167
}

00_Utilities/build-index.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,7 @@ function findJSFilesInFolder(folder) {
103103
...htmlFiles,
104104
...mjsFiles
105105
].filter(file => !IGNORE_FILES.includes(file));
106-
console.log(entries);
107-
108106

109-
110107
if (entries.length == 0) {
111108
throw new Error(`Game "${folder}" is missing a HTML or node.js file in the folder "${folder}/${JAVASCRIPT_FOLDER}"`);
112109
}

96_Word/javascript/word.js

Lines changed: 0 additions & 148 deletions
This file was deleted.

0 commit comments

Comments
 (0)