Actualización

This commit is contained in:
perro tuerto 2023-06-26 12:35:10 -07:00
parent 9dcdebab27
commit ad7c20b0be
7 changed files with 197 additions and 75 deletions

View File

@ -181,11 +181,6 @@ li.link a.anchor {
padding-right: .5rem;
}
li.link summary {
color: #e5582d;
margin-left: -1rem;
}
li.link p.description,
li.link p.tags,
li.link p.dates {
@ -195,6 +190,7 @@ li.link p.dates {
li.link p.description:before,
li.link p.tags:before,
li.link p.dates:before,
li.link p.social:before,
li.link summary:before {
padding-right: .5rem;
}
@ -211,6 +207,14 @@ li.link p.dates:before {
content: "📅";
}
li.link p.social:before {
content: "🪁";
}
li.link summary:before {
content: "👁️";
}
li.link span.created:before {
content: "Creado: ";
}
@ -220,6 +224,21 @@ li.link span.updated:before {
padding-left: 1rem;
}
li.link p.social a:not(:first-of-type) {
padding-left: 1rem;
}
li.link summary {
list-style-type: none;
margin-left: -1rem;
}
li.link p.social a,
li.link summary {
cursor: pointer;
color: blue;
}
li.link div.info {
margin-top: 1rem;
}

View File

@ -29,15 +29,16 @@
<section id="acerca">
<h1>Acerca</h1>
Hola, soy perro tuerto. Mi formación académica es en Filosofía, mi profesión es la edición de publicaciones (libros, fanzines, revistas, etc.) y mi programación se enfoca en el desarrollo de metodologías libres para la publicación. Soy fan de las humanidades, la paleoantropología y las ciencias de la computación, así como soy voluntario en organizaciones sobre edición, <i>software</i> y cultura libres, como Miau, Cuates o Wikipedia. Doy soporte técnico a la Academia Mexicana de la Lengua y puedo ayudarte en tus proyectos. <b>En este espacio comparto enlaces que me parecen chéveres.</b>
<p>Hola, soy perro tuerto. Mi formación académica es en Filosofía, mi profesión es en la edición de publicaciones (libros, fanzines, revistas) y mi programación se enfoca en el desarrollo de metodologías libres para la publicación. Soy fan de las humanidades, la paleoantropología y las ciencias de la computación, así como soy voluntario en organizaciones sobre edición, <i>software</i> y cultura libres, como <a target="_blank" href="https://t.me/miau2018">Miau</a>, <a target="_blank" href="https://cuates.net/">Cuates</a> o <a target="_blank" href="https://wikimedia.mx/">Wikipedia</a>. Doy soporte técnico a la <a target="_blank" href="https://academia.org.mx/">Academia Mexicana de la Lengua</a> y puedo ayudarte en tus proyectos. <b>En este espacio comparto enlaces que me parecen chéveres.</b></p>
</section>
<section id="links">
<h1>Links</h1><ul class="list">
<section id="linkding">
<h1>Linkding</h1><ul class="list">
<li class="link" id="91">
<h1><a target="_blank" class="anchor" href="#91"></a><a class="name" href="https://www.larramendi.es/i18n/consulta/libroselectronicos.do">Biblioteca Virtual de Polígrafos</a></h1>
<p class="description">Obras de Menéndez Pelayo, Hernando de Larramendi y otros en ebook.</p>
<p class="tags"><a><span class="tag">#esteticas</span></a> <a><span class="tag">#historia</span></a> <a><span class="tag">#ideas</span></a></p>
<p class="dates"><span class="created">24/06/2023</span><span class="updated">25/06/2023</span></p>
<h1><a class="anchor" href="#91"></a><a class="name" target="_blank" href="https://www.larramendi.es/i18n/consulta/libroselectronicos.do">Biblioteca Virtual de Polígrafos</a></h1>
<p class="dates"><span class="created">24/06/2023</span><span class="updated">26/06/2023</span></p>
<p class="description">Obras completas de Menéndez Pelayo, Hernando de Larramendi y otros en ebook</p>
<p class="tags"><a>#biblioteca</a> <a>#historia-ideas</a> <a>#acceso-abierto</a></p>
<p class="social"><a target="_blank" href="https://web.archive.org/web/*/https://www.larramendi.es/i18n/consulta/libroselectronicos.do">Ver archivado</a></p>
<details class="info">
<summary>Leer más</summary><h1>Presentación</h1>
<h2>Concepto de polígrafo y poligrafista</h2>
@ -53,24 +54,47 @@ Hola, soy perro tuerto. Mi formación académica es en Filosofía, mi profesión
<p>La Biblioteca Virtual de Polígrafos de la Fundación Ignacio Larramendi, denominada en inglés Polymath Virtual Library por el W3C, ha sido seleccionada por el clúster de Datos Bibliográficos de esta entidad como <a target="_blank" href="http://www.w3.org/2005/Incubator/lld/wiki/Use_Case_Polymath_Virtual_Library">Case Study</a>.</p>
<p>También esta Biblioteca Virtual ha sido elegida por Europeana un <a target="_blank" href="https://pro.europeana.eu/page/polymath-edm">EDM Case Study</a>.</p>
</details>
</li>
<li class="link" id="73">
<h1><a class="anchor" href="#73"></a><a class="name" target="_blank" href="https://directory.doabooks.org/">Directory of Open Access Books</a></h1>
<p class="dates"><span class="created">15/05/2023</span><span class="updated">26/06/2023</span></p>
<p class="description">Directorio de libros en acceso abierto, en su mayoría en inglés pero también varios en español y otros idiomas</p>
<p class="tags"><a>#biblioteca</a> <a>#acceso-abierto</a> <a>#academia</a></p>
<p class="social"><a target="_blank" href="https://web.archive.org/web/*/https://directory.doabooks.org/">Ver archivado</a></p>
<details class="info">
<summary>Leer más</summary><h1>Acerca de DOAB</h1>
<h2>Propósito de DOAB</h2>
<p>El principal objetivo de DOAB (<i>Directory of Open Access Books</i>, por sus siglas en inglés) es el aumento en la visibilidad de libros en acceso abierto. Los editores académicos están invitados a proveer metadata de sus libros en acceso abierto a DOAB. DOAB es una infraestructura abierta comprometida con la ciencia abierta. Funciona con la plataforma de acceso abierto <a target="_blank" href="https://dspace.lyrasis.org/">DSpace 6</a>. Los metadatos pueden recolectarse con el fin de maximizar la diseminación, visiblidad e impacto. Quienes agregar la información pueden integrar los registros en sus servicios comerciales y las bibliotecas pueden integrar el directorio a sus catálogos en línea, lo cual ayuda a académicos y estudiantes a descubrir los libros. El directorio está abierto a cualquier editor que publique libros académicos, revisados por pares y en acceso abierto, así como puede contener tantos libros como sean posibles, siempre y cuando esas publicaciones sean de acceso abierto y se conformen con los estándares académicos.</p>
<h2>¿Quiénes son resposables del DOAB?</h2>
<p>DOAB fue establecido por la <a target="_blank" href="https://oapen.org/">fundación OAPEN</a> en 2012 y en cooperación estrecha con <a target="_blank" href="http://www.doaj.org/">DOAJ</a> (<i>Directory of Open Access Journals</i>, por sus siglas en inglés) y <a target="_blank" href="http://www.sempertool.dk/">SemperTool</a></p>
<p>DOAB es un servicio de la fundación DOAB. Esta fundación es una entidad holandesa sin fines de lucro que fue establecida por ña fundación OAPEN y OpenEdition en 2019. La fundación tiene su sede en la Biblioteca Nacional de los Países Bajos. Los desarrollos y actualizaciones clave del DOAB están disponibles en su reporte anual y en coordinación con OpenEdition.</p>
</details>
</li></ul>
</section>
<footer>
<p><b>perro tuerto</b></p>
<p>Del Pacífico para el mundo: edición, <i>software</i> y culturas libres.</p>
<p>Del Pacífico para el mundo: edición, <i>software</i> y cultura libres.</p>
<p><span class="icon">🤖&nbsp;<a target="_blank" href="https://perrotuerto.blog/perro.json">JSON</a></p>
</footer>
<script>
var nav = document.querySelector("nav > ul"),
li = document.createElement("li"),
input = document.createElement("input"),
options = { valueNames: [ 'name', 'description', 'tag' ] };
const nav = document.querySelector("nav > ul"),
li = document.createElement("li"),
input = document.createElement("input"),
options = { valueNames: [ "name", "description", "tags" ] };
input.id = "search-bar";
input.placeholder = "Filtrar";
input.classList.add("fuzzy-search");
input.classList.add("search");
li.appendChild(input);
nav.appendChild(li);
new List('content', options);
listjs = new List('content', options);
document.querySelectorAll("p.tags a").forEach(tag => {
tag.href = "javascript:void(0)";
tag.addEventListener("click", () => {
const txt = tag.innerText.substring(1).replaceAll("-", " ");
input.value = txt;
listjs.search(txt);
});
});
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -4,18 +4,79 @@ import json
from datetime import datetime
from pathlib import Path
def parse_md(txt):
"""
Implementación mínima con este soporte: párrafos, encabezados, listas,
cita, negrita, itálica y enlaces
"""
# Regex para detectar Markdown
header = r"(#+)\s*(.+)"
quote = r">\s*(.+)"
ulist = r"[\*-]\s*"
olist = r"\d\.\s*"
bolditalic = r"\*\*\*([^\*]+)\*\*\*"
bold = r"\*\*([^\*]+)\*\*"
italic = r"\*([^\*]+)\*"
link = r"\[([^\[]+)\]\(([^\(]+)\)"
# Obtiene los bloques a partir de una cadena de caracteres
blocks = map(lambda x: x.strip(), re.split(r"\n\s*\n", txt))
blocks = list(filter(None, blocks))
# Analiza cada bloque
for i, block in enumerate(blocks):
# Si es encabezado
if re.match(header, block):
groups = re.match(header, block).groups()
tag = "h" + str(len(groups[0]))
block = f"<{tag}>{groups[1]}</{tag}>"
# Si es cita
elif re.match(quote, block):
groups = re.match(quote, block).groups()
block = f"<blockquote><p>{groups[0]}</p></blockquote>"
# Si es lista no ordenada
elif re.match(ulist, block):
items = re.sub(r"^" + ulist, "", block)
items = re.split(r"\n\s*" + ulist, items)
items = "".join(map(lambda x: f"<li><p>{x}</p></li>", items))
block = f"<ul>{items}</ul>"
# Si es lista ordenada
elif re.match(olist, block):
items = re.sub(r"^" + olist, "", block)
items = re.split(r"\n\s*" + olist, items)
items = "".join(map(lambda x: f"<li><p>{x}</p></li>", items))
block = f"<ol>{items}</ol>"
# De lo contrario, se trata como párrafo
else:
block = f"<p>{block}</p>"
# Limpia y aplica los estilos en línea (negritas, itálicas y enlaces)
block = " ".join(block.split())
block = re.sub(bolditalic, r"<b><i>\1</i></b>", block)
block = re.sub(bold, r"<b>\1</b>", block)
block = re.sub(italic, r"<i>\1</i>", block)
block = re.sub(link, r'<a target="_blank" href="\2">\1</a>', block)
blocks[i] = block
# Une los bloques y hace limpiezas
html = "\n".join(blocks)
html = re.sub(r"</blockquote>\n<blockquote>", "", html)
return html
root = Path(__file__).parent.parent
about = re.sub(r'\s+', ' ', """
about = " ".join(
"""
Hola, soy perro tuerto. Mi formación académica es en Filosofía, mi
profesión es la edición de publicaciones (libros, fanzines, revistas, etc.)
profesión es en la edición de publicaciones (libros, fanzines, revistas)
y mi programación se enfoca en el desarrollo de metodologías libres para la
publicación. Soy fan de las humanidades, la paleoantropología y las
ciencias de la computación, así como soy voluntario en organizaciones sobre
edición, <i>software</i> y cultura libres, como Miau, Cuates o Wikipedia.
Doy soporte técnico a la Academia Mexicana de la Lengua y puedo ayudarte
en tus proyectos. <b>En este espacio comparto enlaces que me parecen
chéveres.</b>
""").strip()
edición, *software* y cultura libres, como [Miau](https://t.me/miau2018),
[Cuates](https://cuates.net/) o [Wikipedia](https://wikimedia.mx/). Doy
soporte técnico a la
[Academia Mexicana de la Lengua](https://academia.org.mx/) y puedo ayudarte
en tus proyectos. **En este espacio comparto enlaces que me parecen
chéveres.**
""".split()
)
contact = {
"site": "https://perrotuerto.blog",
"gitlab": "https://gitlab.com/perrotuerto",
@ -26,7 +87,7 @@ contact = {
}
json_file = Path(sys.argv[1])
links = json.loads(json_file.read_text())
data = {"acerca": about, "contacto": contact, "links": links["results"]}
data = {"acerca": about, "contacto": contact, "linkding": links["results"]}
index = root / "public" / "index.html"
template = (root / "src" / "template.html").read_text()
body = ""
@ -34,55 +95,46 @@ body = ""
for key, val in data.items():
if key == "contacto":
for name, url in val.items():
template = re.sub(f'#{name.upper()}#', url, template)
template = re.sub(f"#{name.upper()}#", url, template)
continue
body += f'\n<section id="{key}">'
body += f'\n<h1>{key.capitalize()}</h1>'
body += f"\n<h1>{key.capitalize()}</h1>"
if isinstance(val, str):
body += f'\n{val}'
body += f"\n{parse_md(val)}"
else:
body += '<ul class="list">'
for link in val:
date1 = "%Y-%m-%dT%H:%M:%S.%fZ"
date2 = "%d/%m/%Y"
url = link["url"]
archive = f"https://web.archive.org/web/*/{url}"
created = link["date_added"]
updated = link["date_modified"]
created = datetime.strptime(created, date1).strftime(date2)
updated = datetime.strptime(updated, date1).strftime(date2)
tags = filter(lambda x: x != "blog", link["tag_names"])
tags = map(lambda x: f'<span class="tag">#{x}</span>', tags)
tags = map(lambda x: f'<a>{x}</a>', tags)
tags = map(lambda x: f'<a>#{x}</a>', tags)
body += f'\n<li class="link" id="{link["id"]}">'
body += f'\n<h1><a target="_blank" class="anchor" href="#{link["id"]}">⚓</a>'
body += f'<a class="name" href="{url}">{link["title"]}</a></h1>'
body += f'\n<p class="description">{link["description"]}</p>'
body += f'\n<p class="tags">{" ".join(tags)}</p>'
body += f'\n<h1><a class="anchor" href="#{link["id"]}">⚓</a>'
body += f'<a class="name" target="_blank" href="{url}">'
body += f'{link["title"]}</a></h1>'
body += '\n<p class="dates">'
body += f'<span class="created">{created}</span>'
body += f'<span class="updated">{updated}</span></p>'
body += f'\n<p class="description">{link["description"]}</p>'
body += f'\n<p class="tags">{" ".join(tags)}</p>'
body += '\n<p class="social">'
body += (
f'<a target="_blank" href="{archive}">Ver archivado</a></p>'
)
if "notes" in link.keys():
blocks = map(lambda x: x.strip(), link["notes"].split("\n"))
blocks = list(filter(None, blocks))
for i, block in enumerate(blocks):
block = re.sub(r'\*\*\*(.+)\*\*\*', r'<b><i>\1</i></b>', block)
block = re.sub(r'\*\*(.+)\*\*', r'<b>\1</b>', block)
block = re.sub(r'\*(.+)\*', r'<i>\1</i>', block)
block = re.sub(r'\[(.+)\]\((.+)\)', r'<a target="_blank" href="\2">\1</a>', block)
header = r'(#+)\s*(.+)'
if re.match(header, block):
groups = re.match(header, block).groups()
tag = "h" + str(len(groups[0]))
blocks[i] = f"<{tag}>{groups[1]}</{tag}>"
else:
blocks[i] = f"<p>{block}</p>"
body += '\n<details class="info">'
body += '\n<summary>Leer más</summary>'
body += "\n".join(blocks)
body += '\n</details>'
body += '\n</li>'
body += "\n<summary>Leer más</summary>"
body += parse_md(link["notes"])
body += "\n</details>"
body += "\n</li>"
body += "</ul>"
body += '\n</section>'
body += "\n</section>"
index.write_text(re.sub('#LINKS#', body, template))
index.write_text(re.sub("#LINKS#", body, template))
json_file.write_text(json.dumps(data))

View File

@ -19,9 +19,9 @@ curl --request GET \
python3 ./scripts/make.py $JSON
# Hace commit al repo si hubo cambios
#if [ -n "$(git status --porcelain)" ]; then
# git add .
# git commit -m "Actualización"
# git push origin
# git push cuates
#fi
if [ -n "$(git status --porcelain)" ]; then
git add .
git commit -m "Actualización"
git push origin
git push cuates
fi

View File

@ -181,11 +181,6 @@ li.link a.anchor {
padding-right: .5rem;
}
li.link summary {
color: #e5582d;
margin-left: -1rem;
}
li.link p.description,
li.link p.tags,
li.link p.dates {
@ -195,6 +190,7 @@ li.link p.dates {
li.link p.description:before,
li.link p.tags:before,
li.link p.dates:before,
li.link p.social:before,
li.link summary:before {
padding-right: .5rem;
}
@ -211,6 +207,14 @@ li.link p.dates:before {
content: "📅";
}
li.link p.social:before {
content: "🪁";
}
li.link summary:before {
content: "👁️";
}
li.link span.created:before {
content: "Creado: ";
}
@ -220,6 +224,21 @@ li.link span.updated:before {
padding-left: 1rem;
}
li.link p.social a:not(:first-of-type) {
padding-left: 1rem;
}
li.link summary {
list-style-type: none;
margin-left: -1rem;
}
li.link p.social a,
li.link summary {
cursor: pointer;
color: blue;
}
li.link div.info {
margin-top: 1rem;
}

View File

@ -29,20 +29,28 @@
#LINKS#
<footer>
<p><b>perro tuerto</b></p>
<p>Del Pacífico para el mundo: edición, <i>software</i> y culturas libres.</p>
<p>Del Pacífico para el mundo: edición, <i>software</i> y cultura libres.</p>
<p><span class="icon">🤖&nbsp;<a target="_blank" href="https://perrotuerto.blog/perro.json">JSON</a></p>
</footer>
<script>
var nav = document.querySelector("nav > ul"),
li = document.createElement("li"),
input = document.createElement("input"),
options = { valueNames: [ 'name', 'description', 'tag' ] };
const nav = document.querySelector("nav > ul"),
li = document.createElement("li"),
input = document.createElement("input"),
options = { valueNames: [ "name", "description", "tags" ] };
input.id = "search-bar";
input.placeholder = "Filtrar";
input.classList.add("fuzzy-search");
input.classList.add("search");
li.appendChild(input);
nav.appendChild(li);
new List('content', options);
listjs = new List('content', options);
document.querySelectorAll("p.tags a").forEach(tag => {
tag.href = "javascript:void(0)";
tag.addEventListener("click", () => {
const txt = tag.innerText.substring(1).replaceAll("-", " ");
input.value = txt;
listjs.search(txt);
});
});
</script>
</body>
</html>