Updated the site
Some checks failed
Upload via SSH / build (push) Failing after 1m27s

This commit is contained in:
Bethlenfalvi, Lorinc (ext)
2026-03-23 17:25:03 +01:00
parent 8bafec4821
commit b986001041
4 changed files with 1212 additions and 1388 deletions

2246
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -9,20 +9,20 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/mdx": "^4.3.13", "@astrojs/mdx": "^5.0.2",
"@astrojs/react": "^4.4.2", "@astrojs/react": "^5.0.1",
"@astrojs/rss": "^4.0.14", "@astrojs/rss": "^4.0.17",
"@astrojs/sitemap": "^3.6.0", "@astrojs/sitemap": "^3.7.1",
"@astrojs/svelte": "^7.2.4", "@astrojs/svelte": "^8.0.3",
"@js-temporal/polyfill": "^0.5.1", "@js-temporal/polyfill": "^0.5.1",
"@tailwindcss/vite": "^4.1.18", "@tailwindcss/vite": "^4.2.2",
"astro": "^5.16.6", "astro": "^6.0.8",
"rehype-autolink-headings": "^7.1.0", "rehype-autolink-headings": "^7.1.0",
"rehype-slug": "^6.0.0", "rehype-slug": "^6.0.0",
"remark-toc": "^9.0.0", "remark-toc": "^9.0.0",
"shiki": "^3.20.0", "shiki": "^4.0.2",
"svelte": "^5.46.1", "svelte": "^5.46.1",
"tailwindcss": "^4.1.18", "tailwindcss": "^4.2.2",
"typescript": "^5.9.3" "typescript": "^5.9.3"
} }
} }

View File

@@ -1,160 +1,192 @@
--- ---
import type { JSX } from "astro/jsx-runtime" import type { JSX } from "astro/jsx-runtime";
type LambdaToken = ['lambda', string, Token[], Token[]] type LambdaToken = ["lambda", string, Token[], Token[]];
type Token = type Token =
| ['comment', string] | ["comment", string]
| LambdaToken | LambdaToken
| ['operator', string] | ["operator", string]
| ['name', string] | ["name", string]
| ['whitespace', string] | ["whitespace", string]
| ['placeholder', string] | ["placeholder", string]
| ['macro', string] | ["macro", string]
| ['keyword', string] | ["keyword", string]
| ['string', string] | ["string", string]
| ['number', string] | ["number", string];
function matchParen(expr: string, greedy = false): string { function matchParen(expr: string, greedy = false): string {
for (var i = 0, lvl = 0; for (var i = 0, lvl = 0; 0 <= lvl && i < expr.length; i++) {
0 <= lvl && i < expr.length; if (expr[i] == "(" || expr[i] == "\\") lvl++;
i++) { else if (expr[i] == ")" || expr[i] == ".") lvl--;
if (expr[i] == '(' || expr[i] == '\\') lvl++ else if (greedy && expr[i] == "\n" && lvl == 0) break;
else if (expr[i] == ')' || expr[i] == '.') lvl--
else if (greedy && expr[i] == '\n' && lvl == 0) break
} }
return expr.slice(0, i) return expr.slice(0, i);
} }
function parseLambda(expr: string): LambdaToken { function parseLambda(expr: string): LambdaToken {
expr = expr.slice(1) // Get rid of \ expr = expr.slice(1); // Get rid of \
const nameMatch = /^[\$a-zA-Z0-9_]+\s*/.exec(expr) const nameMatch = /^[\$a-zA-Z0-9_]+\s*/.exec(expr);
if (!nameMatch) throw new Error(`Missing name in "${expr}"`) if (!nameMatch) throw new Error(`Missing name in "${expr}"`);
const name = nameMatch[0].trim() const name = nameMatch[0].trim();
const afterName = nameMatch[0].length const afterName = nameMatch[0].length;
let type: Token[] = [] let type: Token[] = [];
let afterType = afterName let afterType = afterName;
if (expr[afterName] == ':') { if (expr[afterName] == ":") {
const typeStr = matchParen(expr.slice(afterName + 1)).slice(0, -1) const typeStr = matchParen(expr.slice(afterName + 1)).slice(0, -1);
type = tokenizeExp(typeStr) type = tokenizeExp(typeStr);
afterType += typeStr.length + 1 afterType += typeStr.length + 1;
} }
if (expr[afterType] != '.') throw new Error(`Missing dot in "${expr.slice(afterType)}"`) if (expr[afterType] != ".")
const body = tokenizeExp(expr.slice(afterType + 1)) throw new Error(`Missing dot in "${expr.slice(afterType)}"`);
return ['lambda', name, type, body] const body = tokenizeExp(expr.slice(afterType + 1));
return ["lambda", name, type, body];
} }
// Problem // Problem
// \f:\a:a.a.\a:a.a // \f:\a:a.a.\a:a.a
function tokenizeExp(expr: string): Token[] { function tokenizeExp(expr: string): Token[] {
if (expr == '') return [] if (expr == "") return [];
const ws = /^(\s|\n)+/.exec(expr) const ws = /^(\s|\n)+/.exec(expr);
if (ws) return [['whitespace', ws[0]], ...tokenizeExp(expr.slice(ws[0].length))] if (ws)
const keyword = /^(export|import|default|replacing)\s/.exec(expr) return [["whitespace", ws[0]], ...tokenizeExp(expr.slice(ws[0].length))];
if (keyword) return [['keyword', keyword[0]], ...tokenizeExp(expr.slice(keyword[0].length))] const keyword = /^(export|import|default|replacing)\s/.exec(expr);
const macro = /^:=|^=\-?([\d\_a-fA-F]+(\.[\d\_a-fA-F]+)?(p\-?[\d_]+)?)?=>/.exec(expr) if (keyword)
return [
["keyword", keyword[0]],
...tokenizeExp(expr.slice(keyword[0].length)),
];
const macro =
/^:=|^=\-?([\d\_a-fA-F]+(\.[\d\_a-fA-F]+)?(p\-?[\d_]+)?)?=>/.exec(expr);
// const macro = /^[:<]=(([\d_]+(\.[\d_]+)?)?=>?)?/.exec(expr) // const macro = /^[:<]=(([\d_]+(\.[\d_]+)?)?=>?)?/.exec(expr)
if (macro) return [['macro', macro[0]], ...tokenizeExp(expr.slice(macro[0].length))] if (macro)
const number = /^\d\S*/.exec(expr) return [["macro", macro[0]], ...tokenizeExp(expr.slice(macro[0].length))];
if (number) return [['number', number[0]], ...tokenizeExp(expr.slice(number[0].length))] const number = /^\d\S*/.exec(expr);
const name = /^[A-Za-z0-9_]+/.exec(expr) if (number)
if (name) return [['name', name[0]], ...tokenizeExp(expr.slice(name[0].length))] return [
["number", number[0]],
...tokenizeExp(expr.slice(number[0].length)),
];
const name = /^[A-Za-z0-9_]+/.exec(expr);
if (name)
return [["name", name[0]], ...tokenizeExp(expr.slice(name[0].length))];
if (expr.startsWith("--[")) { if (expr.startsWith("--[")) {
let end = expr.indexOf("]--") + "]--".length; let end = expr.indexOf("]--") + "]--".length;
return [ return [["comment", expr.slice(0, end)], ...tokenizeExp(expr.slice(end))];
['comment', expr.slice(0, end)],
...tokenizeExp(expr.slice(end))
]
} }
if (expr.startsWith("--")) { if (expr.startsWith("--")) {
let end = expr.indexOf("\n"); let end = expr.indexOf("\n");
return [ return [["comment", expr.slice(0, end)], ...tokenizeExp(expr.slice(end))];
["comment", expr.slice(0, end)],
...tokenizeExp(expr.slice(end))
]
} }
if (expr.startsWith('\\')) { if (expr.startsWith("\\")) {
const lambda = matchParen(expr) const lambda = matchParen(expr);
return [parseLambda(lambda), ...tokenizeExp(expr.slice(lambda.length))] return [parseLambda(lambda), ...tokenizeExp(expr.slice(lambda.length))];
} }
if (expr.startsWith('"')) { if (expr.startsWith('"')) {
let i = '"'.length; let i = '"'.length;
for (; i <= expr.length; i++) { for (; i <= expr.length; i++) {
if (expr[i] == '\\') i++; if (expr[i] == "\\") i++;
if (expr[i] == '"') break; if (expr[i] == '"') break;
} }
return [ return [
["string", expr.slice(0, i + 1)], ["string", expr.slice(0, i + 1)],
...tokenizeExp(expr.slice(i+1)) ...tokenizeExp(expr.slice(i + 1)),
] ];
} }
const ph = /^\$[a-zA-Z0-9_]+/.exec(expr) const ph = /^\$[a-zA-Z0-9_]+/.exec(expr);
if (ph) return [['placeholder', ph[0]], ...tokenizeExp(expr.slice(ph[0].length))] if (ph)
const opChars = /^[^\sa-zA-Z0-9_\$\\]+/.exec(expr) return [["placeholder", ph[0]], ...tokenizeExp(expr.slice(ph[0].length))];
if (opChars) return [['operator', opChars[0]], ...tokenizeExp(expr.slice(opChars[0].length))] const opChars = /^[^\sa-zA-Z0-9_\$\\]+/.exec(expr);
throw new Error(`Logic error: none of the regices in a complete cover matched "${expr}"`) if (opChars)
return [
["operator", opChars[0]],
...tokenizeExp(expr.slice(opChars[0].length)),
];
throw new Error(
`Logic error: none of the regices in a complete cover matched "${expr}"`,
);
} }
function nameStyle(level: number | undefined): JSX.CSSProperties { function nameStyle(level: number | undefined): JSX.CSSProperties {
return { return {
color: level === undefined color:
level === undefined
? "hsl(30, 50%, 70%)" ? "hsl(30, 50%, 70%)"
: `hsl( : `hsl(
calc(170 - ${level} * 5), calc(170 - ${level} * 5),
calc(50% + ${level} * 10%), calc(50% + ${level} * 10%),
calc(70% - ${level} * 5%) calc(70% - ${level} * 5%)
)`, )`,
} };
} }
interface Props { interface Props {
text?: string, text?: string;
tokens?: Token[], tokens?: Token[];
vlvlv?: Map<string, number> vlvlv?: Map<string, number>;
} }
let { text, tokens, vlvlv = new Map() }: Props = Astro.props; let { text, tokens, vlvlv = new Map() }: Props = Astro.props;
const nextLvl = vlvlv.size + 1 const nextLvl = vlvlv.size + 1;
const outTokens = tokens ? tokens : tokenizeExp(text!.trim()); const outTokens = tokens ? tokens : tokenizeExp(text!.trim());
--- ---
<code style={{ <code
whiteSpace: "pre-wrap", style={{
display: vlvlv.size == 0 ? "inline-block" : "inline",
padding: "unset", padding: "unset",
background: "unset", background: "unset",
borderRadius: "unset", borderRadius: "unset",
border: "unset", border: "unset",
whiteSpace: "pre-line",
fontFamily: '"Droid Sans Mono", monospace', fontFamily: '"Droid Sans Mono", monospace',
fontSize: "small", fontSize: "small",
}}> }}
{outTokens.map(([name, value, ...extras], i) => { switch (name) { >{
case 'comment': return <span style={{ color: "#8f8" }}>{value}</span> outTokens.map(([name, value, ...extras], i) => {
case 'name': return <span style={nameStyle(vlvlv.get(value))}>{value}</span> switch (name) {
case 'operator': return <span style={{ color: "white" }}>{value}</span> case "comment":
case 'whitespace': return <span>{value}</span> return <span style={{ color: "#8f8" }}>{value}</span>;
case 'placeholder': return <span style={{ color: "#bb5" }}>{value}</span> case "name":
case 'macro': return <span style={{ color: "#f55" }}>{value}</span> return <span style={nameStyle(vlvlv.get(value))}>{value}</span>;
case 'keyword': return <span style={{ color: "#39f" }}>{value}</span> case "operator":
case 'string': return <span style={{ color: "#f8b" }}>{value}</span> return <span style={{ color: "white" }}>{value}</span>;
case 'number': return <span style={{ color: "#afa" }}>{value}</span> case "whitespace":
case 'lambda': return <span>{value}</span>;
const sub_vlvlv = new Map(vlvlv) case "placeholder":
sub_vlvlv.set(value, nextLvl) return <span style={{ color: "#bb5" }}>{value}</span>;
return <span data-name={value}> case "macro":
<span style={{ color: "#999" }}>\</span> return <span style={{ color: "#f55" }}>{value}</span>;
case "keyword":
return <span style={{ color: "#39f" }}>{value}</span>;
case "string":
return <span style={{ color: "#f8b" }}>{value}</span>;
case "number":
return <span style={{ color: "#afa" }}>{value}</span>;
case "lambda":
const sub_vlvlv = new Map(vlvlv);
sub_vlvlv.set(value, nextLvl);
return (
<span data-name={value}>
<span>\</span>
<span style={nameStyle(vlvlv.get(value))}>{value}</span> <span style={nameStyle(vlvlv.get(value))}>{value}</span>
{extras[0]!.length? <> {extras[0]!.length ? (
<>
<span style={{ color: "#999" }}>:</span> <span style={{ color: "#999" }}>:</span>
<span> <span>
<Astro.self vlvlv={sub_vlvlv} tokens={extras[0]!} /> <Astro.self vlvlv={sub_vlvlv} tokens={extras[0]!} />
</span> </span>
</> :null} </>
) : null}
<span style={{ color: "#999" }}>.</span> <span style={{ color: "#999" }}>.</span>
<span> <span>
<Astro.self vlvlv={sub_vlvlv} tokens={extras[1]!} /> <Astro.self vlvlv={sub_vlvlv} tokens={extras[1]!} />
</span> </span>
</span> </span>
}})} );
</code> }
})
}</code
>

View File

@@ -7,52 +7,81 @@
font-family: 'Montserrat', sans-serif; font-family: 'Montserrat', sans-serif;
font-weight: 300; font-weight: 300;
} }
* { * {
border-color: default; border-color: default;
} }
.astro-code { .astro-code {
margin: 1ch 0; margin: 1ch 0;
white-space: pre-wrap; white-space: pre-wrap;
} }
pre, code {
pre,
code {
background-color: var(--color-side-bg); background-color: var(--color-side-bg);
padding-left: 1ch; padding-left: 1ch;
padding-right: 1ch; padding-right: 1ch;
} }
pre>code { pre>code {
padding: 0; padding: 0;
} }
p { p {
margin-bottom: 15px; margin-bottom: 15px;
} }
.post-content { .post-content {
a { a {
color: var(--color-link); color: var(--color-link);
&:visited { &:visited {
color: var(--color-link-visited); color: var(--color-link-visited);
} }
} }
pre { pre,
padding-block: .5ch; code {
margin-block: .5ch; display: inline-block;
/* padding-block: .5ch;
margin-block: .5ch; */
line-height: 1.2;
margin: 0;
padding: 0;
} }
h1,h2,h3,h4,h5,h6 { h1,
h2,
h3,
h4,
h5,
h6 {
margin-top: 10px; margin-top: 10px;
margin-bottom: 10px; margin-bottom: 10px;
font-weight: 500; font-weight: 500;
& i { & i {
visibility: hidden; visibility: hidden;
color: #ccc; color: #ccc;
} }
&:hover i { visibility: initial; }
&:hover i {
visibility: initial;
} }
h1 { font-size: x-large; } }
h2 { margin-left: 30px; }
h1 {
font-size: x-large;
}
h2 {
margin-left: 30px;
}
h3 { h3 {
color: #fff7; color: #fff7;
margin-bottom: 0; margin-bottom: 10px;
} }
& i.gg-link { & i.gg-link {
@@ -62,16 +91,39 @@
margin-bottom: 7px; margin-bottom: 7px;
} }
#table-of-contents { display: none } ul {
list-style: ' - ' outside;
margin-bottom: 15px;
li {
margin-left: 2ch;
}
}
ol {
list-style: decimal outside;
margin-bottom: 15px;
li {
margin-left: 2ch;
}
}
#table-of-contents {
display: none
}
#table-of-contents+ul { #table-of-contents+ul {
float: right; float: right;
background-color: var(--color-side-bg); background-color: var(--color-side-bg);
padding: 5px 12px; padding: 5px 12px;
width: 20ch; width: 20ch;
margin: 10px; margin: 10px;
ul { ul {
padding-left: 10px; padding-left: 10px;
} }
li { li {
list-style-type: decimal; list-style-type: decimal;
list-style-position: inside; list-style-position: inside;
@@ -79,6 +131,7 @@
} }
} }
} }
@theme { @theme {
--breakpoint-xs: 25rem; --breakpoint-xs: 25rem;
--tw-border-style: solid; --tw-border-style: solid;
@@ -97,17 +150,20 @@
background-color: var(--color-emph-bg); background-color: var(--color-emph-bg);
border-color: var(--color-emph-bg); border-color: var(--color-emph-bg);
} }
.post-meta { .post-meta {
color: var(--color-faint-fg); color: var(--color-faint-fg);
font-style: italic; font-style: italic;
font-weight: 500; font-weight: 500;
margin-left: 0.3em; margin-left: 0.3em;
} }
.summary { .summary {
font-style: italic; font-style: italic;
color: var(---color-emph-fg); color: var(---color-emph-fg);
letter-spacing: 3px; letter-spacing: 3px;
} }
.gutter { .gutter {
scrollbar-gutter: stable; scrollbar-gutter: stable;
} }