fix: Remove unused files
This commit is contained in:
1 parent
9d65dc3184
commit
766212f119
10 files changed
+7
-201
No files matched your search
@@ -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
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"name": "ascii-pwa",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "node serve.mjs",
|
||||
"test": "node --test tests/*.test.mjs"
|
||||
}
|
||||
}
|
||||
+1
-5
@@ -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)) {
|
||||
|
||||
@@ -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}`));
|
||||
@@ -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; }
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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)));
|
||||
});
|
||||
@@ -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()) {
|
||||
|
||||
Reference in new issue
Block a user