From 30ed54dfcdbc5fb1d7fb5f7e1d23c61ec1e640c3 Mon Sep 17 00:00:00 2001 From: RattleSN4K3 Date: Sun, 15 Sep 2024 19:40:50 +0200 Subject: [PATCH] fix: generate games list with padded delimiter (#635) * Generate games list with padded table structured (based on defined columns) fixes #607 * Add comment to HeaderDefinition --- GAMES_LIST.md | 3 ++ tools/generate_games_list.js | 68 ++++++++++++++++++++++++++++-------- 2 files changed, 57 insertions(+), 14 deletions(-) diff --git a/GAMES_LIST.md b/GAMES_LIST.md index 2914802..a7f2e4d 100644 --- a/GAMES_LIST.md +++ b/GAMES_LIST.md @@ -1,4 +1,6 @@ ### Supported + + | GameDig Type ID | Name | See Also | |----------------------|--------------------------------------------------|-------------------------------------------------| | a2oa | ARMA 2: Operation Arrowhead | [Valve Protocol](#valve) | @@ -346,6 +348,7 @@ | xpandrally | Xpand Rally | | | zombiemaster | Zombie Master | [Valve Protocol](#valve) | | zps | Zombie Panic: Source | [Valve Protocol](#valve) | + ### Not supported (yet) diff --git a/tools/generate_games_list.js b/tools/generate_games_list.js index 7ec0e0d..65793b6 100644 --- a/tools/generate_games_list.js +++ b/tools/generate_games_list.js @@ -20,13 +20,37 @@ sortedGamesIds.forEach(key => { sortedGames[key] = games[key] }) -let generated = '' -generated += '| GameDig Type ID | Name | See Also\n' -generated += '|---|---|---\n' +const columnDelimiter = '|' +const columnPadLeft = 1 +const columnPadRight = 1 + +const HeaderType = { + ID: 0, + GameName: 1, + Notes: 2 +} +const HeaderNames = { + [HeaderType.ID]: { Name: 'GameDig Type ID' }, + [HeaderType.GameName]: { Name: 'Name' }, + [HeaderType.Notes]: { Name: 'See Also' } +} +// defines the order of columns +const HeaderDefinition = [ + HeaderType.ID, + HeaderType.GameName, + HeaderType.Notes +] + +const headerMap = HeaderDefinition.map(idx => Object.values(HeaderType)[idx]) +const headers = Object.keys(HeaderType).map((x, idx) => HeaderNames[idx].Name) + +const matrix = [] +const maxLength = headers.map(x => x?.length ?? 0) +Object.entries(sortedGames).forEach(([id, game]) => { + const lineArray = Array(headerMap.length).fill('') + lineArray[HeaderType.ID] = id + lineArray[HeaderType.GameName] = game.name -for (const id in sortedGames) { - const game = sortedGames[id] - generated += '| ' + id.padEnd(10, ' ') + ' | ' + game.name const notes = [] if (game?.extra?.doc_notes) { notes.push('[Notes](#' + game.extra.doc_notes + ')') @@ -37,15 +61,31 @@ for (const id in sortedGames) { if (game.options.protocol === 'epic' || game.options.protocol === 'asa' || game.options.protocol === 'theisleevrima') { notes.push('[EOS Protocol](#epic)') } - if (notes.length) { - generated += ' | ' + notes.join(', ') - } - generated += '\n' -} + lineArray[HeaderType.Notes] = notes.join(', ') + + lineArray.forEach((x, index) => { + maxLength[index] = Math.max(maxLength[index], x?.length ?? 0) + }) + matrix.push(lineArray) +}) + +matrix.splice(0, 0, headers) +const padLeft = ' '.repeat(columnPadLeft) +const padRight = ' '.repeat(columnPadRight) +const lines = matrix.map(row => { + const values = headerMap.map((x, idx) => { + return padLeft + row[x].padEnd(maxLength[x], ' ') + padRight + }) + return `${columnDelimiter}${''}${values.join(columnDelimiter)}${columnDelimiter}` +}) +const headerSeps = ['', ...headerMap.map(x => '-'.repeat(maxLength[x] + columnPadLeft + columnPadRight)), ''] +const headerSep = `${headerSeps.join(columnDelimiter)}` +lines.splice(1, 0, headerSep) +const generated = lines.join('\n') let start = readme.indexOf(markerTop) -start += markerTop.length -const end = readme.indexOf(markerBottom) +const end = start >= 0 ? readme.indexOf(markerBottom) : 0 +start = Math.max(0, start) + (start >= 0 ? markerTop.length : 0) -const updated = readme.substring(0, start) + '\n\n' + generated + '\n' + readme.substring(end) +const updated = readme.substring(0, start) + '\n' + generated + '\n' + readme.substring(end) fs.writeFileSync(readmeFilename, updated)