#!/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 */ 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 `
  • ${name.replace('.html', '')}
  • `; } else if (file.endsWith('.mjs')) { return `
  • ${name.replace('.mjs', '')} (node.js)
  • `; } else { throw new Error(`Unknown file-type found: ${file}`); } } if (game.files.length > 1) { const entries = game.files.map(file => { return creatFileLink(file); }); return `
  • ${game.name}
  • `; } 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 = ` ${title} `; const body = `

    ${title}

      ${listEntries}
    `; return ` ${head} ${body} `.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)); 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();