From 766212f119feefab28546c9b2fabfe276617f840 Mon Sep 17 00:00:00 2001 From: Abdussamet Kocak Date: Sat, 10 Oct 2026 13:02:19 +0200 Subject: [PATCH] fix: Remove unused files --- README.md | 4 +- bitmap.js | 95 ----------------------------------- package.json | 9 ---- renderer.js | 6 +-- serve.mjs | 36 ------------- style.css | 3 -- sw.js | 4 +- tests/figlet.test.mjs | 2 +- tests/renderer.test.mjs | 47 ----------------- tests/service-worker.test.mjs | 2 +- 10 files changed, 7 insertions(+), 201 deletions(-) delete mode 100644 bitmap.js delete mode 100644 package.json delete mode 100644 serve.mjs delete mode 100644 tests/renderer.test.mjs diff --git a/README.md b/README.md index 985230a..af0c508 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Turn text into ASCII art in your browser. Type something, pick a font, and see the result instantly. -- Browse 297 FIGlet fonts and a compact bitmap style with previous/next controls. +- Browse 297 FIGlet fonts with previous/next controls. - Copy your art, download it as a text file, or share a link. - Keep your last-used font and choose light, dark, or system appearance. - Switch between English and Turkish. @@ -15,7 +15,7 @@ use them. ## Run locally ```sh -npm start +python3 -m http.server 8080 ``` Open [localhost:8080](http://localhost:8080). No dependency installation or build diff --git a/bitmap.js b/bitmap.js deleted file mode 100644 index a4c0342..0000000 --- a/bitmap.js +++ /dev/null @@ -1,95 +0,0 @@ -// Original 5×7 bitmap glyphs. All rendering is local; no fonts or API are fetched. -const patterns = { - A: '01110/10001/10001/11111/10001/10001/10001', - B: '11110/10001/10001/11110/10001/10001/11110', - C: '01111/10000/10000/10000/10000/10000/01111', - D: '11110/10001/10001/10001/10001/10001/11110', - E: '11111/10000/10000/11110/10000/10000/11111', - F: '11111/10000/10000/11110/10000/10000/10000', - G: '01111/10000/10000/10111/10001/10001/01111', - H: '10001/10001/10001/11111/10001/10001/10001', - I: '11111/00100/00100/00100/00100/00100/11111', - J: '00111/00010/00010/00010/10010/10010/01100', - K: '10001/10010/10100/11000/10100/10010/10001', - L: '10000/10000/10000/10000/10000/10000/11111', - M: '10001/11011/10101/10101/10001/10001/10001', - N: '10001/11001/10101/10011/10001/10001/10001', - O: '01110/10001/10001/10001/10001/10001/01110', - P: '11110/10001/10001/11110/10000/10000/10000', - Q: '01110/10001/10001/10001/10101/10010/01101', - R: '11110/10001/10001/11110/10100/10010/10001', - S: '01111/10000/10000/01110/00001/00001/11110', - T: '11111/00100/00100/00100/00100/00100/00100', - U: '10001/10001/10001/10001/10001/10001/01110', - V: '10001/10001/10001/10001/10001/01010/00100', - W: '10001/10001/10001/10101/10101/10101/01010', - X: '10001/10001/01010/00100/01010/10001/10001', - Y: '10001/10001/01010/00100/00100/00100/00100', - Z: '11111/00001/00010/00100/01000/10000/11111', - 0: '01110/10001/10011/10101/11001/10001/01110', - 1: '00100/01100/00100/00100/00100/00100/01110', - 2: '01110/10001/00001/00010/00100/01000/11111', - 3: '11110/00001/00001/01110/00001/00001/11110', - 4: '00010/00110/01010/10010/11111/00010/00010', - 5: '11111/10000/10000/11110/00001/00001/11110', - 6: '01110/10000/10000/11110/10001/10001/01110', - 7: '11111/00001/00010/00100/01000/01000/01000', - 8: '01110/10001/10001/01110/10001/10001/01110', - 9: '01110/10001/10001/01111/00001/00001/01110', - ' ': '000/000/000/000/000/000/000', - '!': '1/1/1/1/1/0/1', - '?': '01110/10001/00001/00010/00100/00000/00100', - '.': '0/0/0/0/0/0/1', - ',': '00/00/00/00/00/01/10', - ':': '0/1/0/0/1/0/0', - ';': '00/01/00/00/01/01/10', - '-': '000/000/000/111/000/000/000', - '_': '00000/00000/00000/00000/00000/00000/11111', - '+': '00000/00100/00100/11111/00100/00100/00000', - '=': '00000/00000/11111/00000/11111/00000/00000', - '/': '00001/00001/00010/00100/01000/10000/10000', - '\\': '10000/10000/01000/00100/00010/00001/00001', - '(': '001/010/100/100/100/010/001', - ')': '100/010/001/001/001/010/100', - '[': '111/100/100/100/100/100/111', - ']': '111/001/001/001/001/001/111', - '{': '001/010/010/100/010/010/001', - '}': '100/010/010/001/010/010/100', - '<': '0001/0010/0100/1000/0100/0010/0001', - '>': '1000/0100/0010/0001/0010/0100/1000', - "'": '1/1/0/0/0/0/0', - '"': '101/101/000/000/000/000/000', - '`': '10/01/00/00/00/00/00', - '#': '01010/11111/01010/01010/11111/01010/00000', - '$': '00100/01111/10100/01110/00101/11110/00100', - '%': '11001/11010/00010/00100/01000/01011/10011', - '&': '01100/10010/10100/01000/10101/10010/01101', - '*': '00000/10101/01110/11111/01110/10101/00000', - '@': '01110/10001/10111/10101/10111/10000/01111', - '^': '00100/01010/10001/00000/00000/00000/00000', - '|': '1/1/1/1/1/1/1', - '~': '00000/00000/01001/10110/00000/00000/00000', -}; - -export const styles = ['block', 'banner', 'slant', 'compact']; - -export function normalizeText(text) { - return text.replace(/ı/g, 'i').normalize('NFD').replace(/[\u0300-\u036f]/g, '').toUpperCase(); -} - -export function render(text, style = 'block') { - if (!styles.includes(style)) throw new Error('Unknown lettering style'); - if (text.length > 500) throw new Error('Text is too long'); - return normalizeText(text).replace(/\r\n?/g, '\n').split('\n').map(line => { - const characters = [...line.replace(/\t/g, ' ')]; - const glyphs = characters.map(char => (patterns[char] || patterns['?']).split('/')); - return Array.from({length: 7}, (_, row) => { - const pixels = glyphs.map((glyph, i) => [...glyph[row]].map(pixel => { - if (style === 'banner') return pixel === '1' ? characters[i] : ' '; - if (style === 'compact') return pixel === '1' ? '#' : ' '; - return pixel === '1' ? '##' : ' '; - }).join('')).join(style === 'compact' || style === 'banner' ? ' ' : ' '); - return (style === 'slant' ? ' '.repeat(6 - row) : '') + pixels.trimEnd(); - }).join('\n'); - }).join('\n\n'); -} diff --git a/package.json b/package.json deleted file mode 100644 index 5e05c52..0000000 --- a/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "ascii-pwa", - "private": true, - "type": "module", - "scripts": { - "start": "node serve.mjs", - "test": "node --test tests/*.test.mjs" - } -} diff --git a/renderer.js b/renderer.js index 2fe0504..4849cd2 100644 --- a/renderer.js +++ b/renderer.js @@ -1,14 +1,12 @@ import figlet from './vendor/figlet.js'; import {fonts} from './font-catalog.js'; -import {render as renderBitmap} from './bitmap.js'; -export const styles = [...fonts, 'compact']; +export const styles = fonts; export const FONT_CACHE = `ascii-pwa-fonts-${encodeURIComponent(new URL('./', import.meta.url).href)}-figlet-1.8.2`; const pendingFonts = new Map(); // Keep existing lowercase font links working with the library's font names. export function resolveFont(name) { - if (name === 'compact') return name; return fonts.find(font => font.toLowerCase() === String(name).toLowerCase()) || 'Standard'; } @@ -19,7 +17,6 @@ export function registerFont(name, data) { export function renderLoaded(text, font = 'Standard') { if (text.length > 500) throw new Error('Text is too long'); - if (font === 'compact') return renderBitmap(text, font); if (!fonts.includes(font)) throw new Error('Unknown lettering style'); return figlet.textSync(text, { font, width: 80, whitespaceBreak: true, @@ -28,7 +25,6 @@ export function renderLoaded(text, font = 'Standard') { export async function render(text, font = 'Standard') { if (text.length > 500) throw new Error('Text is too long'); - if (font === 'compact') return renderBitmap(text, font); if (!fonts.includes(font)) throw new Error('Unknown lettering style'); if (!figlet.figFonts[font]) { if (!pendingFonts.has(font)) { diff --git a/serve.mjs b/serve.mjs deleted file mode 100644 index b9d99b0..0000000 --- a/serve.mjs +++ /dev/null @@ -1,36 +0,0 @@ -// Development server only. Deploy the frontend files to any HTTPS static host. -import http from 'node:http'; -import {readFile} from 'node:fs/promises'; -import path from 'node:path'; -import {fileURLToPath} from 'node:url'; - -const root = path.dirname(fileURLToPath(import.meta.url)); -const types = { - '.html': 'text/html; charset=utf-8', '.js': 'application/javascript', - '.css': 'text/css', '.svg': 'image/svg+xml', '.png': 'image/png', - '.webmanifest': 'application/manifest+json', '.woff2': 'font/woff2', -}; -const port = Number(process.env.PORT || 8080); -http.createServer(async (request, response) => { - try { - const url = new URL(request.url, 'http://localhost'); - const filename = decodeURIComponent(url.pathname); - const target = path.resolve(root, `.${filename === '/' ? '/index.html' : filename}`); - if (!target.startsWith(root + path.sep)) { - response.writeHead(403).end(); - return; - } - if (!['GET', 'HEAD'].includes(request.method)) { - response.writeHead(405, {Allow: 'GET, HEAD'}).end(); - return; - } - const content = await readFile(target); - response.writeHead(200, { - 'Content-Type': types[path.extname(target)] || 'application/octet-stream', - 'Cache-Control': 'no-cache', - }); - response.end(request.method === 'HEAD' ? undefined : content); - } catch { - response.writeHead(404).end('Not found'); - } -}).listen(port, '127.0.0.1', () => console.log(`ascii: http://localhost:${port}`)); diff --git a/style.css b/style.css index c4997cf..e4dba70 100644 --- a/style.css +++ b/style.css @@ -16,8 +16,6 @@ --foreground: #c5d5bc; --panel: #29372c; --border: #849979; - --accent: #849979; - --on-accent: #18251c; } :root[data-theme='light'] { color-scheme: light; @@ -50,7 +48,6 @@ button, summary { cursor: pointer; } button:hover { border-color: var(--foreground); } button:disabled { opacity: 0.5; cursor: default; } :focus-visible { outline: 3px solid var(--foreground); outline-offset: 4px; } -.primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); font-weight: bold; } .controls, .font-navigation, .actions, .preferences, .install-controls { display: flex; flex-wrap: wrap; align-items: end; gap: 0.75rem; } .controls { margin-top: 1rem; } .controls label { flex: 1; min-width: 9rem; } diff --git a/sw.js b/sw.js index 6a5b8a6..a4b93a6 100644 --- a/sw.js +++ b/sw.js @@ -1,11 +1,11 @@ // Bump VERSION whenever a shell file changes. New versions wait for approval. -const VERSION = 'v6'; +const VERSION = 'v7'; const BASE = self.registration.scope; const PREFIX = `ascii-pwa-${encodeURIComponent(BASE)}-`; const CACHE = `${PREFIX}${VERSION}`; const SHELL = [ './', './index.html', './style.css', './appearance.js', './app.js', - './renderer.js', './bitmap.js', './font-catalog.js', './vendor/figlet.js', + './renderer.js', './font-catalog.js', './vendor/figlet.js', './translations.js', './pwa.js', './manifest.webmanifest', './fonts/IBMPlexMono-Regular.subset.woff2', './fonts/IBMPlexMono-Bold.subset.woff2', diff --git a/tests/figlet.test.mjs b/tests/figlet.test.mjs index 354ff10..41a8e49 100644 --- a/tests/figlet.test.mjs +++ b/tests/figlet.test.mjs @@ -25,7 +25,7 @@ test('Standard preserves lowercase lettering and the familiar FIGlet shape', () }); test('old lowercase font links resolve to their library names', () => { - for (const [name, expected] of [['standard', 'Standard'], ['slant', 'Slant'], ['block', 'Block'], ['banner', 'Banner'], ['compact', 'compact'], ['unknown', 'Standard']]) { + for (const [name, expected] of [['standard', 'Standard'], ['slant', 'Slant'], ['block', 'Block'], ['banner', 'Banner'], ['compact', 'Standard'], ['unknown', 'Standard']]) { assert.equal(resolveFont(name), expected); } }); diff --git a/tests/renderer.test.mjs b/tests/renderer.test.mjs deleted file mode 100644 index a63ad79..0000000 --- a/tests/renderer.test.mjs +++ /dev/null @@ -1,47 +0,0 @@ -import test from 'node:test'; -import assert from 'node:assert/strict'; -import {normalizeText, render, styles} from '../bitmap.js'; - -test('compact lettering renders a known phrase with correct spacing', () => { - assert.equal(render('HI', 'compact'), [ - '# # #####', '# # #', '# # #', '##### #', - '# # #', '# # #', '# # #####', - ].join('\n')); -}); - -for (const style of styles) { - test(`${style} renders digits, punctuation and multiline input`, () => { - const first = render('Hello 123!', style); - assert.equal(first.split('\n').length, 7); - assert.match(first, /\S/); - assert.equal(render('Hello 123!\r\nWorld?', style), `${first}\n\n${render('World?', style)}`); - }); -} - -for (const [text, expected] of [ - ['çığöşü İ', 'CIGOSU I'], - ['café', 'CAFE'], - ['abc 123!?', 'ABC 123!?'], -]) { - test(`normalizes ${text}`, () => assert.equal(normalizeText(text), expected)); -} - -test('unsupported characters have a visible fallback', () => { - assert.equal(render('🙂'), render('?')); -}); -test('all printable ASCII characters have distinct supported glyphs', () => { - for (let code = 32; code <= 126; code++) { - const char = String.fromCharCode(code); - if (char === '?') continue; - assert.notEqual(render(char), render('?'), `missing ${char}`); - } -}); -test('banner uses the original normalized letter as ink', () => { - assert.match(render('a', 'banner'), /^ AAA\n/); - assert.doesNotMatch(render('a', 'banner'), /#/); -}); -test('rejects invalid styles and overlong text', () => { - assert.throws(() => render('hello', 'unknown'), /Unknown/); - assert.throws(() => render('x'.repeat(501)), /too long/); - assert.doesNotThrow(() => render('x'.repeat(500))); -}); diff --git a/tests/service-worker.test.mjs b/tests/service-worker.test.mjs index 45d96bf..96a21cd 100644 --- a/tests/service-worker.test.mjs +++ b/tests/service-worker.test.mjs @@ -70,7 +70,7 @@ for (const scope of ['https://ascii.example/', 'https://ascii.example/pwa/']) { } assert.equal(sw.claimed, true); assert.equal(sw.activated, false, 'initial install does not force activation'); - assert.equal((await sw.request(`${scope}?text=Hello&font=compact`)).url, scope); + assert.equal((await sw.request(`${scope}?text=Hello&font=Standard`)).url, scope); assert.equal((await sw.request(`${scope}index.html?text=World`)).url, scope); for (const cache of sw.stores.values()) { for (const url of cache.keys()) {