parse art once per request; inline the art font and set a dark color-scheme to stop the load flicker
Deploy / deploy (push) Successful in 3s
Deploy / deploy (push) Successful in 3s
This commit is contained in:
+4
-2
File diff suppressed because one or more lines are too long
+40
-22
@@ -69,6 +69,43 @@ function ansi_html(string $file, bool $mirror = false): string
|
|||||||
return ansi_html_cells($raw, $mirror);
|
return ansi_html_cells($raw, $mirror);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plain-ASCII art as [lines of chars, lines of color-index bytes, color => index],
|
||||||
|
* or null with too many colors for a byte. One regex pass over the whole file;
|
||||||
|
* kept per request so the mirrored side doesn't parse it a second time.
|
||||||
|
*/
|
||||||
|
function ansi_parse_bytes(string $raw): ?array
|
||||||
|
{
|
||||||
|
static $memo = [], $done = [];
|
||||||
|
$key = md5($raw);
|
||||||
|
if (array_key_exists($key, $done)) {
|
||||||
|
return $done[$key];
|
||||||
|
}
|
||||||
|
$index = ['' => 0]; // color hex => byte (0 = uncolored)
|
||||||
|
$chars = [];
|
||||||
|
$masks = [];
|
||||||
|
$c = $m = '';
|
||||||
|
$cur = null;
|
||||||
|
foreach (preg_split('/(\e\[[0-9;]*m|\n)/', rtrim($raw, "\n"), -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY) as $part) {
|
||||||
|
if ($part === "\n") { // colors don't carry across lines
|
||||||
|
$chars[] = $c;
|
||||||
|
$masks[] = $m;
|
||||||
|
$c = $m = '';
|
||||||
|
$cur = null;
|
||||||
|
} elseif ($part[0] === "\e") {
|
||||||
|
// a handful of distinct codes repeated thousands of times: decode each once
|
||||||
|
$cur = $memo[$part . '|' . $cur] ??= ansi_color(explode(';', substr($part, 2, -1)), $cur);
|
||||||
|
} else {
|
||||||
|
$k = $index[$cur ?? ''] ??= count($index);
|
||||||
|
$c .= $part;
|
||||||
|
$m .= str_repeat(chr($k), strlen($part));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$chars[] = $c;
|
||||||
|
$masks[] = $m;
|
||||||
|
return $done[$key] = count($index) > 250 ? null : [$chars, $masks, $index];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fast path for plain-ASCII art (one byte per cell): each line becomes a
|
* Fast path for plain-ASCII art (one byte per cell): each line becomes a
|
||||||
* string of characters plus a parallel string of color indices, and every
|
* string of characters plus a parallel string of color indices, and every
|
||||||
@@ -81,30 +118,11 @@ function ansi_html_bytes(string $raw, bool $mirror): ?string
|
|||||||
$from ??= implode(array_map('chr', range(0, 255)));
|
$from ??= implode(array_map('chr', range(0, 255)));
|
||||||
$to ??= "\xff" . str_repeat("\0", 255);
|
$to ??= "\xff" . str_repeat("\0", 255);
|
||||||
|
|
||||||
static $memo = [];
|
$parsed = ansi_parse_bytes($raw);
|
||||||
$index = ['' => 0]; // color hex => byte (0 = uncolored)
|
if ($parsed === null) {
|
||||||
$chars = [];
|
|
||||||
$masks = [];
|
|
||||||
foreach (explode("\n", rtrim($raw, "\n")) as $line) {
|
|
||||||
$c = '';
|
|
||||||
$m = '';
|
|
||||||
$cur = null;
|
|
||||||
foreach (preg_split('/(\e\[[0-9;]*m)/', $line, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY) as $part) {
|
|
||||||
if ($part[0] === "\e") {
|
|
||||||
// a handful of distinct codes repeated thousands of times: decode each once
|
|
||||||
$cur = $memo[$part . '|' . $cur] ??= ansi_color(explode(';', substr($part, 2, -1)), $cur);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$k = $index[$cur ?? ''] ??= count($index);
|
|
||||||
$c .= $part;
|
|
||||||
$m .= str_repeat(chr($k), strlen($part));
|
|
||||||
}
|
|
||||||
$chars[] = $c;
|
|
||||||
$masks[] = $m;
|
|
||||||
}
|
|
||||||
if (count($index) > 250) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
[$chars, $masks, $index] = $parsed;
|
||||||
|
|
||||||
$width = max(array_map('strlen', $chars) ?: [0]);
|
$width = max(array_map('strlen', $chars) ?: [0]);
|
||||||
foreach ($chars as $i => $c) {
|
foreach ($chars as $i => $c) {
|
||||||
|
|||||||
+1
-1
@@ -6,10 +6,10 @@ require_once __DIR__ . '/../config.php';
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="color-scheme" content="dark">
|
||||||
<title><?= htmlspecialchars($page_title ?? SITE_TITLE) ?></title>
|
<title><?= htmlspecialchars($page_title ?? SITE_TITLE) ?></title>
|
||||||
<link rel="icon" href="/img/favicon.ico" sizes="any">
|
<link rel="icon" href="/img/favicon.ico" sizes="any">
|
||||||
<link rel="stylesheet" href="/css/style.css?v=<?= filemtime(__DIR__ . '/../css/style.css') ?>">
|
<link rel="stylesheet" href="/css/style.css?v=<?= filemtime(__DIR__ . '/../css/style.css') ?>">
|
||||||
<link rel="preload" href="/css/sideart.woff2" as="font" type="font/woff2" crossorigin>
|
|
||||||
<script src="/js/htmx.min.js" defer></script>
|
<script src="/js/htmx.min.js" defer></script>
|
||||||
<script src="/js/idiomorph-ext.min.js" defer></script>
|
<script src="/js/idiomorph-ext.min.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
Reference in New Issue
Block a user