This commit is contained in:
parent
67dbeae4e9
commit
d95c29bbbc
11 changed files with 212 additions and 108 deletions
|
@ -1,55 +0,0 @@
|
||||||
#!/usr/bin/env lua5.1
|
|
||||||
local m = 1
|
|
||||||
local f = 2
|
|
||||||
|
|
||||||
local tipos = {
|
|
||||||
{"Un collage", m},
|
|
||||||
{"Una intervención contrapublicitaria o contrapropaganda", f},
|
|
||||||
{"Una cerámica", f},
|
|
||||||
{"Un comic", m},
|
|
||||||
}
|
|
||||||
|
|
||||||
local temas = {
|
|
||||||
"destrucción ambiental",
|
|
||||||
"una canción",
|
|
||||||
"otra obra artística",
|
|
||||||
"el mercado inmobiliario",
|
|
||||||
"redes sociales",
|
|
||||||
}
|
|
||||||
|
|
||||||
local adjetivos = {
|
|
||||||
{"", ""},
|
|
||||||
{"feo", "fea"},
|
|
||||||
}
|
|
||||||
|
|
||||||
local random_i = 1
|
|
||||||
local function random(list)
|
|
||||||
math.randomseed((''..os.time()):reverse() + random_i)
|
|
||||||
random_i = random_i + 5
|
|
||||||
return list[math.random(#list)]
|
|
||||||
end
|
|
||||||
|
|
||||||
print("<h2>Algunas obras generadas aleatoriamente</h2><ol>")
|
|
||||||
for i=1,10 do
|
|
||||||
local tipo = random(tipos)
|
|
||||||
local tema = random(temas)
|
|
||||||
local adjetivo = random(adjetivos)[tipo[2]]
|
|
||||||
print("<li>"..tipo[1].." "..adjetivo.." sobre "..tema.."</li>")
|
|
||||||
end
|
|
||||||
print("</ol>")
|
|
||||||
|
|
||||||
print("<h2>Tipos de obra</h2><ol>")
|
|
||||||
for _, tipo in ipairs(tipos) do
|
|
||||||
print("<li>"..tipo[1].."</li>")
|
|
||||||
end
|
|
||||||
print("</ol><h2>Algunas características (opcional)</h2><ol>")
|
|
||||||
for _, adjetivo in ipairs({unpack(adjetivos, 2)}) do
|
|
||||||
print("<li>"..adjetivo[1].."/"..adjetivo[2].."</li>")
|
|
||||||
end
|
|
||||||
print("</ol><h2>Temas para la obra</h2><ol>")
|
|
||||||
for _, tema in ipairs(temas) do
|
|
||||||
print("<li>"..tema.."</li>")
|
|
||||||
end
|
|
||||||
print("</ol>")
|
|
||||||
|
|
||||||
print("<p><a href='https://gitea.nulo.in/Nulo/sitio/src/branch/ANTIFASCISTA/Men%C3%BA%20art%C3%ADstico.gen'>Código</a></p>")
|
|
65
Menú artístico.gen.js
Executable file
65
Menú artístico.gen.js
Executable file
|
@ -0,0 +1,65 @@
|
||||||
|
import { a, h2, li, ol, render } from "@nulo/html.js";
|
||||||
|
|
||||||
|
const [m, f] = [0, 1];
|
||||||
|
|
||||||
|
/** @type {[string, number][]} */
|
||||||
|
const tipos = [
|
||||||
|
["Un collage", m],
|
||||||
|
["Una intervención contrapublicitaria o contrapropaganda", f],
|
||||||
|
["Una cerámica", f],
|
||||||
|
["Un comic", m],
|
||||||
|
];
|
||||||
|
|
||||||
|
const temas = [
|
||||||
|
"destrucción ambiental",
|
||||||
|
"una canción",
|
||||||
|
"otra obra artística",
|
||||||
|
"el mercado inmobiliario",
|
||||||
|
"redes sociales",
|
||||||
|
];
|
||||||
|
|
||||||
|
/** @type {[string, string][]} */
|
||||||
|
const adjetivos = [
|
||||||
|
["", ""],
|
||||||
|
["feo", "fea"],
|
||||||
|
];
|
||||||
|
|
||||||
|
/** @param {number} n */
|
||||||
|
const range = (n) => {
|
||||||
|
let list = [];
|
||||||
|
for (let i = 0; i < n; i++) list.push(i);
|
||||||
|
return list;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template {any} T
|
||||||
|
* @param {T[]} list
|
||||||
|
* @returns {T}
|
||||||
|
*/
|
||||||
|
const random = (list) => list[Math.floor(Math.random() * list.length)];
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
return render(
|
||||||
|
h2("Algunas obras generadas aleatoriamente"),
|
||||||
|
ol(
|
||||||
|
...range(10).map(() => {
|
||||||
|
const tipo = random(tipos);
|
||||||
|
const tema = random(temas);
|
||||||
|
const adjetivo = random(adjetivos)[tipo[1]];
|
||||||
|
return li(tipo[0], " ", adjetivo, " sobre ", tema);
|
||||||
|
})
|
||||||
|
),
|
||||||
|
h2("Tipos de obra"),
|
||||||
|
ol(...tipos.map((t) => li(t[0]))),
|
||||||
|
h2("Algunas características (opcional)"),
|
||||||
|
ol(...adjetivos.map((a) => li(a[0], "/", a[1]))),
|
||||||
|
h2("Temas para la obra"),
|
||||||
|
ol(...temas.map((t) => li(t))),
|
||||||
|
a(
|
||||||
|
{
|
||||||
|
href: "https://gitea.nulo.in/Nulo/sitio/src/branch/ANTIFASCISTA/Men%C3%BA%20art%C3%ADstico.gen.js",
|
||||||
|
},
|
||||||
|
"Código"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
|
@ -1,32 +0,0 @@
|
||||||
#!/usr/bin/env lua
|
|
||||||
|
|
||||||
local template = [[
|
|
||||||
<!-- License-Id: CC0-1.0 -->
|
|
||||||
<section class="webring">
|
|
||||||
<section class="articles">
|
|
||||||
<ul>
|
|
||||||
{{range .Articles}}
|
|
||||||
<li class="article">
|
|
||||||
<a href="{{.Link}}" target="_blank" rel="noopener">{{.Title}}</a>
|
|
||||||
<small class="source">
|
|
||||||
via <a href="{{.SourceLink}}">{{.SourceTitle}}</a>
|
|
||||||
</small>
|
|
||||||
<small class="date">({{.Date | datef "January 2, 2006"}})</small>
|
|
||||||
</li>
|
|
||||||
{{end}}
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
<p class="attribution">
|
|
||||||
Generado usando
|
|
||||||
<a href="https://git.sr.ht/~sircmpwn/openring">openring</a>💕
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
]]
|
|
||||||
|
|
||||||
local code = os.execute("echo '"..template..[[' | openring \
|
|
||||||
-s file:cached-feeds/fauno.xml?url=https://fauno.endefensadelsl.org/feed.xml \
|
|
||||||
-s file:cached-feeds/copiona.xml?url=https://copiona.com/feed.xml
|
|
||||||
]])
|
|
||||||
if code ~= 0 then
|
|
||||||
os.exit(1)
|
|
||||||
end
|
|
82
Mi webring.gen.js
Normal file
82
Mi webring.gen.js
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
import path from "node:path";
|
||||||
|
import { readFile } from "node:fs/promises";
|
||||||
|
import { parseFeed as _parseFeed } from "htmlparser2";
|
||||||
|
import { a, li, raw, render, ul } from "@nulo/html.js";
|
||||||
|
import { parseDocument } from "htmlparser2";
|
||||||
|
import { getElementsByTagName } from "domutils";
|
||||||
|
|
||||||
|
const feeds = {
|
||||||
|
fauno: "https://fauno.endefensadelsl.org/feed.xml",
|
||||||
|
copiona: "https://copiona.com/feed.xml",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async () => {
|
||||||
|
const articles = [];
|
||||||
|
|
||||||
|
for (const [name, baseUrl] of Object.entries(feeds)) {
|
||||||
|
/**
|
||||||
|
* @param {string} link
|
||||||
|
* @returns string
|
||||||
|
*/
|
||||||
|
const relativeLink = (link) => new URL(link, baseUrl).toString();
|
||||||
|
|
||||||
|
const rawFeed = await readFile(
|
||||||
|
path.join("cached-feeds/", name + ".xml"),
|
||||||
|
"utf-8"
|
||||||
|
);
|
||||||
|
const { title, item, link } = parseFeed(rawFeed);
|
||||||
|
|
||||||
|
articles.push(
|
||||||
|
li(
|
||||||
|
{ class: "article" },
|
||||||
|
a(
|
||||||
|
{
|
||||||
|
href: relativeLink(item.link),
|
||||||
|
target: "_blank",
|
||||||
|
rel: "noopener",
|
||||||
|
},
|
||||||
|
item.title
|
||||||
|
),
|
||||||
|
// TODO: format date
|
||||||
|
" via ",
|
||||||
|
a({ href: relativeLink(link), rel: "noopener" }, title)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return render(ul(...articles));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parsea un feed de rss encontrando cosas que htmlparser2 solo no encuentra
|
||||||
|
* @param {string} rawFeed
|
||||||
|
*/
|
||||||
|
function parseFeed(rawFeed) {
|
||||||
|
const feed = _parseFeed(rawFeed);
|
||||||
|
const item = feed?.items[0];
|
||||||
|
|
||||||
|
const dom = parseDocument(rawFeed);
|
||||||
|
const feedDom = getElementsByTagName("feed", dom.childNodes, false)[0];
|
||||||
|
const linksDom = getElementsByTagName("link", feedDom.childNodes, false);
|
||||||
|
const linkDom = linksDom.find((d) => d.attribs.rel === "alternate");
|
||||||
|
|
||||||
|
if (
|
||||||
|
!feed ||
|
||||||
|
!feed.link ||
|
||||||
|
!feed.title ||
|
||||||
|
!item ||
|
||||||
|
!item.link ||
|
||||||
|
!item.title ||
|
||||||
|
!item.pubDate ||
|
||||||
|
!linkDom ||
|
||||||
|
!linkDom.attribs.href
|
||||||
|
) {
|
||||||
|
throw "no pude parsear";
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: feed.title,
|
||||||
|
link: linkDom.attribs.href,
|
||||||
|
item: { title: item.title, link: item.link, pubDate: item.pubDate },
|
||||||
|
};
|
||||||
|
}
|
20
compilar.ts
20
compilar.ts
|
@ -82,7 +82,7 @@ async function compileFile(name: string) {
|
||||||
) {
|
) {
|
||||||
await copyFile(join(config.sourcePath, name), join(config.buildPath, name));
|
await copyFile(join(config.sourcePath, name), join(config.buildPath, name));
|
||||||
}
|
}
|
||||||
if ([".md", ".gen"].includes(extension)) {
|
if ([".md"].includes(extension) || name.endsWith(".gen.js")) {
|
||||||
pageList.push(basename(name, extension));
|
pageList.push(basename(name, extension));
|
||||||
await compilePage(config, name);
|
await compilePage(config, name);
|
||||||
}
|
}
|
||||||
|
@ -100,8 +100,8 @@ async function compilePage(config: Config, sourceFileName: string) {
|
||||||
config,
|
config,
|
||||||
sourceFileName
|
sourceFileName
|
||||||
));
|
));
|
||||||
} else if (extname(sourceFileName) === ".gen")
|
} else if (sourceFileName.endsWith(".gen.js"))
|
||||||
contentHtml = await compileExecutableHtml(config, sourceFileName);
|
contentHtml = await compileJavascript(config, sourceFileName);
|
||||||
else throw false;
|
else throw false;
|
||||||
|
|
||||||
const html = render(
|
const html = render(
|
||||||
|
@ -166,16 +166,12 @@ async function compileMarkdownHtml(
|
||||||
return { html: contentHtml, image };
|
return { html: contentHtml, image };
|
||||||
}
|
}
|
||||||
|
|
||||||
async function compileExecutableHtml(
|
async function compileJavascript(
|
||||||
config: Config,
|
config: Config,
|
||||||
sourceFileName: string
|
sourceFileName: string
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const { stdout, stderr } = await execFile(
|
const fn = await import("./" + join(config.sourcePath, sourceFileName));
|
||||||
"./" + join(config.sourcePath, sourceFileName)
|
return await fn.default();
|
||||||
);
|
|
||||||
if (stderr.length > 0) console.error(`${sourceFileName} stderr: ${stderr}`);
|
|
||||||
|
|
||||||
return stdout;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==============================================
|
// ==============================================
|
||||||
|
@ -409,8 +405,8 @@ async function hackilyTransformHtml(html: string): Promise<string> {
|
||||||
for (const [match, archivo] of html.matchAll(
|
for (const [match, archivo] of html.matchAll(
|
||||||
/<nulo-sitio-reemplazar-con archivo="(.+?)" \/>/g
|
/<nulo-sitio-reemplazar-con archivo="(.+?)" \/>/g
|
||||||
)) {
|
)) {
|
||||||
if (extname(archivo) !== ".gen") throw false;
|
if (!archivo.endsWith(".gen.js")) throw false;
|
||||||
html = html.replace(match, await compileExecutableHtml(config, archivo));
|
html = html.replace(match, await compileJavascript(config, archivo));
|
||||||
}
|
}
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
2
index.md
2
index.md
|
@ -26,7 +26,7 @@ Algunas cosas de las que soy parte:
|
||||||
|
|
||||||
## Mis amigxs ([[Mi webring]])
|
## Mis amigxs ([[Mi webring]])
|
||||||
|
|
||||||
<nulo-sitio-reemplazar-con archivo="Mi webring.gen" />
|
<nulo-sitio-reemplazar-con archivo="Mi webring.gen.js" />
|
||||||
|
|
||||||
## Contacto
|
## Contacto
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nulo/html.js": "^0.0.8",
|
"@nulo/html.js": "^0.0.8",
|
||||||
"commonmark": "^0.30.0"
|
"commonmark": "^0.30.0",
|
||||||
|
"domutils": "^3.0.1",
|
||||||
|
"htmlparser2": "^8.0.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,12 @@ dependencies:
|
||||||
commonmark:
|
commonmark:
|
||||||
specifier: ^0.30.0
|
specifier: ^0.30.0
|
||||||
version: 0.30.0
|
version: 0.30.0
|
||||||
|
domutils:
|
||||||
|
specifier: ^3.0.1
|
||||||
|
version: 3.0.1
|
||||||
|
htmlparser2:
|
||||||
|
specifier: ^8.0.2
|
||||||
|
version: 8.0.2
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@types/commonmark':
|
'@types/commonmark':
|
||||||
|
@ -244,10 +250,42 @@ packages:
|
||||||
string.prototype.repeat: 0.2.0
|
string.prototype.repeat: 0.2.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/dom-serializer@2.0.0:
|
||||||
|
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
|
||||||
|
dependencies:
|
||||||
|
domelementtype: 2.3.0
|
||||||
|
domhandler: 5.0.3
|
||||||
|
entities: 4.5.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/domelementtype@2.3.0:
|
||||||
|
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/domhandler@5.0.3:
|
||||||
|
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
|
||||||
|
engines: {node: '>= 4'}
|
||||||
|
dependencies:
|
||||||
|
domelementtype: 2.3.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/domutils@3.0.1:
|
||||||
|
resolution: {integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==}
|
||||||
|
dependencies:
|
||||||
|
dom-serializer: 2.0.0
|
||||||
|
domelementtype: 2.3.0
|
||||||
|
domhandler: 5.0.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
/entities@2.0.3:
|
/entities@2.0.3:
|
||||||
resolution: {integrity: sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==}
|
resolution: {integrity: sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/entities@4.5.0:
|
||||||
|
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
||||||
|
engines: {node: '>=0.12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/esbuild@0.16.17:
|
/esbuild@0.16.17:
|
||||||
resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==}
|
resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
@ -278,6 +316,15 @@ packages:
|
||||||
'@esbuild/win32-x64': 0.16.17
|
'@esbuild/win32-x64': 0.16.17
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/htmlparser2@8.0.2:
|
||||||
|
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
|
||||||
|
dependencies:
|
||||||
|
domelementtype: 2.3.0
|
||||||
|
domhandler: 5.0.3
|
||||||
|
domutils: 3.0.1
|
||||||
|
entities: 4.5.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/mdurl@1.0.1:
|
/mdurl@1.0.1:
|
||||||
resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==}
|
resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
3
tool
3
tool
|
@ -2,10 +2,11 @@
|
||||||
|
|
||||||
build_ts() {
|
build_ts() {
|
||||||
./node_modules/.bin/esbuild compilar.ts --target=node18 --outdir=build.js --sourcemap || exit $?
|
./node_modules/.bin/esbuild compilar.ts --target=node18 --outdir=build.js --sourcemap || exit $?
|
||||||
|
cp *.js build.js/
|
||||||
}
|
}
|
||||||
build() {
|
build() {
|
||||||
build_ts
|
build_ts
|
||||||
node --enable-source-maps build.js/compilar.js || exit $?
|
node --enable-source-maps --trace-uncaught build.js/compilar.js || exit $?
|
||||||
}
|
}
|
||||||
check() {
|
check() {
|
||||||
./node_modules/.bin/tsc --noEmit || exit $?
|
./node_modules/.bin/tsc --noEmit || exit $?
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
FROM docker.io/alpine:3.17
|
FROM docker.io/alpine:3.17
|
||||||
|
|
||||||
RUN apk add --no-cache nodejs npm lua5.1 icu-data-full \
|
RUN apk add --no-cache nodejs npm icu-data-full \
|
||||||
rsync openssh-client-default
|
rsync openssh-client-default
|
||||||
|
|
||||||
# https://gitea.nulo.in/Nulo/openring/releases/tag/1.0.1-nulo-sitio-2
|
|
||||||
RUN wget -nv -O /bin/openring https://gitea.nulo.in/attachments/3ddb2799-3af7-4239-a7fd-9d31670aefb8 && \
|
|
||||||
chmod +x /bin/openring
|
|
||||||
|
|
||||||
RUN npm install --global pnpm
|
RUN npm install --global pnpm
|
|
@ -4,6 +4,8 @@
|
||||||
"module": "es2022",
|
"module": "es2022",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"strict": true
|
"strict": true,
|
||||||
|
"allowJs": true,
|
||||||
|
"checkJs": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue