Files
basic-computer-games/00_Utilities/build-index.js
2022-04-02 11:38:08 +02:00

156 lines
3.9 KiB
JavaScript

#!/usr/bin/env node
/**
* This script creates an "index.html" file in the root of the directory.
*
* Call this from the root of the project with
* `node ./00_Utilities/build-index.js`
*
* @author Alexander Wunschik <https://github.com/mojoaxel>
*/
const fs = require('fs');
const path = require('path');
const TITLE = 'BASIC Computer Games';
const JAVASCRIPT_FOLDER = 'javascript';
const IGNORE_FOLDERS_START_WITH = ['.', '00_', 'buildJvm', 'Sudoku'];
const IGNORE_FILES = [
// "84 Super Star Trek" has it's own node/js implementation (using xterm)
'cli.mjs', 'superstartrek.mjs'
];
function createGameLinks(game) {
const creatFileLink = (file, name = path.basename(file)) => {
if (file.endsWith('.html')) {
return `
<li><a href="${file}">${name.replace('.html', '')}</a></li>
`;
} else if (file.endsWith('.mjs')) {
return `
<li><a href="./00_Common/javascript/WebTerminal/terminal.html#${file}">${name.replace('.mjs', '')} (node.js)</a></li>
`;
} else {
throw new Error(`Unknown file-type found: ${file}`);
}
}
if (game.files.length > 1) {
const entries = game.files.map(file => {
return creatFileLink(file);
});
return `
<li>
<span>${game.name}</span>
<ul>${entries.map(e => `\t\t\t${e}`).join('\n')}</ul>
</li>
`;
} else {
return creatFileLink(game.files[0], game.name);
}
}
function createIndexHtml(title, games) {
const listEntries = games.map(game =>
createGameLinks(game)
).map(entry => `\t\t\t${entry}`).join('\n');
const head = `
<head>
<meta charset="UTF-8">
<title>${title}</title>
<link rel="stylesheet" href="./00_Utilities/javascript/style_terminal.css" />
</head>
`;
const body = `
<body>
<article id="output">
<header>
<h1>${title}</h1>
</header>
<main>
<ul>
${listEntries}
</ul>
</main>
</article>
</body>
`;
return `
<!DOCTYPE html>
<html lang="en">
${head}
${body}
</html>
`.trim().replace(/\s\s+/g, '');
}
function findJSFilesInFolder(folder) {
// filter folders that do not include a subfolder called "javascript"
const hasJavascript = fs.existsSync(`${folder}/${JAVASCRIPT_FOLDER}`);
if (!hasJavascript) {
throw new Error(`Game "${folder}" is missing a javascript folder`);
}
// get all files in the javascript folder
const files = fs.readdirSync(`${folder}/${JAVASCRIPT_FOLDER}`);
// filter files only allow .html files
const htmlFiles = files.filter(file => file.endsWith('.html'));
const mjsFiles = files.filter(file => file.endsWith('.mjs'));
const entries = [
...htmlFiles,
...mjsFiles
].filter(file => !IGNORE_FILES.includes(file));
console.log(entries);
if (entries.length == 0) {
throw new Error(`Game "${folder}" is missing a HTML or node.js file in the folder "${folder}/${JAVASCRIPT_FOLDER}"`);
}
return entries.map(file => path.join(folder, JAVASCRIPT_FOLDER, file));
}
function main() {
// Get the list of all folders in the current director
let folders = fs.readdirSync(process.cwd());
// filter files only allow folders
folders = folders.filter(folder => fs.statSync(folder).isDirectory());
// filter out the folders that start with a dot or 00_
folders = folders.filter(folder => {
return !IGNORE_FOLDERS_START_WITH.some(ignore => folder.startsWith(ignore));
});
// sort the folders alphabetically (by number)
folders = folders.sort();
// get name and javascript file from folder
const games = folders.map(folder => {
const name = folder.replace('_', ' ');
let files;
try {
files = findJSFilesInFolder(folder);
} catch (error) {
console.warn(`Game "${name}" is missing a javascript implementation: ${error.message}`);
return null;
}
return {
name,
files
}
}).filter(game => game !== null);
// create a index.html file with a list of all games
const htmlContent = createIndexHtml(TITLE, games);
fs.writeFileSync('index.html', htmlContent);
console.log(`index.html successfully created!`);
}
main();