agregar buscador de la forma más hacky posible
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
Cat /dev/Nulo 2023-07-31 22:15:49 -03:00
parent 02c9e6454c
commit 91fcbf2fa0
5 changed files with 110 additions and 15 deletions

15
buscador.htm Normal file
View file

@ -0,0 +1,15 @@
<script src="_pagefind/pagefind-ui.js" type="text/javascript" defer="defer"></script>
<div id="search"></div>
<script>
window.addEventListener("DOMContentLoaded", (event) => {
new PagefindUI({
element: "#search",
showImages: false,
translations: {
placeholder: "Buscar en todo el sitio...",
clear_search: "Limpiar",
},
debounceTimeoutMs: 100,
});
});
</script>

View file

@ -23,8 +23,14 @@ import {
article,
main,
img,
script,
basicElement,
nav,
source,
} from "@nulo/html.js";
const div = basicElement("div");
const reader = new commonmark.Parser({ smart: true });
const writer = new commonmark.HtmlRenderer({ safe: false, smart: true });
@ -46,6 +52,8 @@ const config: Config = {
buildPath: "build",
};
const buscadorHtml = await readFile("buscador.htm", "utf-8");
const connections = await scanForConnections(config.sourcePath);
await mkdir(config.buildPath, { recursive: true });
@ -69,25 +77,35 @@ await Promise.all(pageList.map(({ src }) => compilePage(config, src)));
await compilePageList(config, pageList);
async function compileFile(
config: Config,
sourceFileName: string
): Promise<{ contentHtml: string; image?: Image }> {
if (extname(sourceFileName) === ".md") {
const { html: contentHtml, image } = await compileMarkdownHtml(config, sourceFileName);
return { contentHtml, image };
} else if (sourceFileName.endsWith(".gen.js")) {
const contentHtml = await compileJavascript(config, sourceFileName);
return { contentHtml };
} else if (sourceFileName.endsWith(".htm"))
return { contentHtml: await readFile(sourceFileName, "utf-8") };
else throw false;
}
async function compilePage(config: Config, sourceFileName: string) {
const name = basename(sourceFileName, extname(sourceFileName));
const isIndex = name === "index";
const title = isIndex ? "nulo.ar" : formatNameToPlainText(name);
const fileConnections = connections.filter(({ linked }) => linked === name);
let contentHtml, image;
if (extname(sourceFileName) === ".md") {
({ html: contentHtml, image } = await compileMarkdownHtml(config, sourceFileName));
} else if (sourceFileName.endsWith(".gen.js"))
contentHtml = await compileJavascript(config, sourceFileName);
else throw false;
const { contentHtml, image } = await compileFile(config, sourceFileName);
const html = render(
const html = renderHtml(
...generateHead(title, name),
article(
{ itemscope: "", itemtype: "https://schema.org/Article" },
...(isIndex ? [] : generateHeader(name, sourceFileName, fileConnections.length > 0, image)),
main({ itemprop: "articleBody" }, raw(contentHtml)),
main({ itemprop: "articleBody", "data-pagefind-body": "" }, raw(contentHtml)),
...generateConnectionsSection(fileConnections)
)
);
@ -143,10 +161,13 @@ async function compileJavascript(config: Config, sourceFileName: string): Promis
// Generated HTML
// ==============================================
function renderHtml(...world: Renderable[]): string {
return `<!doctype html><html lang="es">` + render(...world) + "</html>";
}
function generateHead(titlee: string, outputName: string): Renderable[] {
// TODO: deshardcodear og:url
return [
doctype(),
metaUtf8,
meta({
name: "viewport",
@ -244,7 +265,7 @@ function generateHeader(
): Renderable[] {
const parsedTitle = parseName(name);
return [
a({ href: "." }, "☚ Volver al inicio"),
nav(a({ href: "." }, "☚ Volver al inicio"), raw(buscadorHtml)),
header(
...(image ? [img({ ...image, itemprop: "image" })] : []),
...("title" in parsedTitle
@ -293,7 +314,7 @@ function generateConnectionsSection(fileConnections: Connection[]): Renderable[]
async function compilePageList(config: Config, pageList: { src: string }[]) {
const name = "Lista de páginas";
const outputPath = join(config.buildPath, name + ".html");
const html = render(
const html = renderHtml(
...generateHead(name, name),
...generateHeader(name, "compilar.ts"),
ul(
@ -340,8 +361,7 @@ async function hackilyTransformHtml(html: string): Promise<string> {
.replaceAll("<a h", '<a rel="noopener noreferrer" h')
.replaceAll(wikilinkExp, (_, l) => render(internalLink(l)));
for (const [match, archivo] of html.matchAll(/<nulo-sitio-reemplazar-con archivo="(.+?)" \/>/g)) {
if (!archivo.endsWith(".gen.js")) throw false;
html = html.replace(match, await compileJavascript(config, archivo));
html = html.replace(match, (await compileFile(config, archivo)).contentHtml);
}
return html;
}

View file

@ -2,6 +2,8 @@
> What's bizarre? I mean, we're all pretty bizarre.<br>Some of us are just better at hiding it, that's all.
<nulo-sitio-reemplazar-con archivo="buscador.htm" />
¡Buenas! Este es mi mundo, bienvenidx. ¿Que, [[Quién soy]]? Soy Nulo :)
- Perdete en la [[Lista de páginas]]

View file

@ -5,7 +5,7 @@
"description": "",
"main": "index.js",
"scripts": {
"build": "esbuild compilar.ts *.js --target=node18 --outdir=build-js --sourcemap && node --enable-source-maps --trace-uncaught build-js/compilar.js",
"build": "esbuild compilar.ts *.js --target=node18 --outdir=build-js --sourcemap && node --enable-source-maps --trace-uncaught build-js/compilar.js && pagefind --source build",
"check": "tsc",
"refresh-feeds": "node feeds.js refresh"
},
@ -22,6 +22,7 @@
"@nulo/html.js": "^0.0.8",
"commonmark": "^0.30.0",
"domutils": "^3.0.1",
"htmlparser2": "^8.0.2"
"htmlparser2": "^8.0.2",
"pagefind": "^0.12.0"
}
}

View file

@ -1,5 +1,9 @@
lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
dependencies:
'@nulo/html.js':
specifier: ^0.0.8
@ -13,6 +17,9 @@ dependencies:
htmlparser2:
specifier: ^8.0.2
version: 8.0.2
pagefind:
specifier: ^0.12.0
version: 0.12.0
devDependencies:
'@types/commonmark':
@ -240,6 +247,15 @@ packages:
resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==}
dev: true
/agent-base@6.0.2:
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
engines: {node: '>= 6.0.0'}
dependencies:
debug: 4.3.4
transitivePeerDependencies:
- supports-color
dev: false
/commonmark@0.30.0:
resolution: {integrity: sha512-j1yoUo4gxPND1JWV9xj5ELih0yMv1iCWDG6eEQIPLSWLxzCXiFoyS7kvB+WwU+tZMf4snwJMMtaubV0laFpiBA==}
hasBin: true
@ -250,6 +266,18 @@ packages:
string.prototype.repeat: 0.2.0
dev: false
/debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
dependencies:
ms: 2.1.2
dev: false
/dom-serializer@2.0.0:
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
dependencies:
@ -325,6 +353,16 @@ packages:
entities: 4.5.0
dev: false
/https-proxy-agent@5.0.1:
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
engines: {node: '>= 6'}
dependencies:
agent-base: 6.0.2
debug: 4.3.4
transitivePeerDependencies:
- supports-color
dev: false
/mdurl@1.0.1:
resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==}
dev: false
@ -333,6 +371,25 @@ packages:
resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==}
dev: false
/ms@2.1.2:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
dev: false
/pagefind@0.12.0:
resolution: {integrity: sha512-LHUmlYYweBM6/rK1G+7z2q2WjYeycrB7g5Kuw0w6yMkYztzsEdO2Qj2pJ3z8gsWV8eJsYQyAGOAdqE3SZWlCqA==}
hasBin: true
requiresBuild: true
dependencies:
https-proxy-agent: 5.0.1
proxy-from-env: 1.1.0
transitivePeerDependencies:
- supports-color
dev: false
/proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
dev: false
/string.prototype.repeat@0.2.0:
resolution: {integrity: sha512-1BH+X+1hSthZFW+X+JaUkjkkUPwIlLEMJBLANN3hOob3RhEk5snLWNECDnYbgn/m5c5JV7Ersu1Yubaf+05cIA==}
dev: false