Campechana Mental
Textos para llevar o ir comiendo

Generar un sitio web con MK y pandoc

Joshua Haase

2017-02-07

Hemos platicado de la línea de editar contenido usando pandoc he aquí cómo lo materializamos.


mk es un programa para automatizar tareas y pandoc permite transformar a muchos formatos documentos escritos en un formato sencillo llamado markdown.

Pandoc permite generar pdf, epub y una página web a partir del mismo documento.

Hicimos una herramienta campechana para generar este sitio web, que puedes revisar mientras lees el resto del post.

Nuestra herramienta campechana se aprovecha de la capacidad de Pandoc para

Incrustar archivos al documento final

En el repositorio de plantillas de pandoc se indican los lugares donde se agregará a cada uno de los formatos cada archivo indicado en las variables «include»:

---
title: ""
author: ""
date: ""
header-includes:
    - "partes/campechana.nomia.mx/encabezado"
include-before:
    - "partes/campechana.nomia.mx/iniciar"
include-after:
    - "partes/campechana.nomia.mx/terminar"
---

Esto agregará el contenido de los archivos, cuyo contenido debería variar en función del formato de destino, y por eso es más práctico agregarlo en la línea de comandos como sigue:

pandoc \
    --from markdown \
    --to html \
    --header-includes partes/campechana.nomia.mx/encabezado \
    --include-before partes/campechana.nomia.mx/iniciar \
    --inlude-after partes/campechana.nomia.mx/terminar \
    archivo.md

Y se puede abreviar como:

pandoc \
    -f markdown \
    -t html \
    -H partes/campechana.nomia.mx/encabezado \
    -B partes/campechana.nomia.mx/iniciar \
    -A partes/campechana.nomia.mx/terminar \
    archivo.md

Automatizar la tarea con MK

Para convertir un archivo de markdown dentro de la carpeta sitios/ a página web dentro de la carpeta web/, dentro del mkfile se agregan las siguientes instrucciones:

all:VEQ:    indexes static
    bin/targets | xargs mk

clean:VEQ:
    rm -r web

static:VEQ:
    bin/static | xargs mk
    rsync -r static/ web/

indexes:VEQ:
    mk -f indexes.mk

'web/(.*)\.(png|jpe?g|pdf)':RQ: 'sitios/\1\.\2'
    mkdir -p `dirname "$target"`
    cp "$prereq" "$target"

web/%/index.html:Q: sitios/%.md
    mkdir -p `dirname "$target"`
    pandoc \
        --smart \
        -f markdown \
        -t html \
        --standalone \
        -H partes/campechana.nomia.mx/encabezado \
        -B partes/campechana.nomia.mx/iniciar \
        -A partes/campechana.nomia.mx/terminar \
        "$prereq" \
        -o "$target"'.build' \
    && mv "$target"'.build' "$target"

Para indicar qué se va a convertir de markdown a html, yo guardo el siguiente guión como bin/targets:

#!/bin/sh
find -L sitios \
    -type f \
    -name '*.md' \
| sed -r \
    -e 's#^sitios#web#g' \
    -e 's#^(.*)\.md$#\1/index.html#g'

El guión busca dentro de la carpeta sitios los archivos cuyo nombre termina en .md, cambia la carpeta y el nombre para indicar qué páginas web deben hacerse.

Generar índices

Además agregué otro guión que hace los índices en bin/campechana-links de las páginas y los guarda como .md para que se generen las secciones del sitio:

#!/usr/bin/awk -f
/\.md$/ {
    CMD = "bin/pandoc-get title " $1
    CMD | getline title
    CMD = "bin/pandoc-get author " $1
    CMD | getline author
    sub(".md$", "/", $1)
    sub("^sitios/", "https://", $1)
    link = $1
    printf("<a class=\"item\" href=\"" link "\">" \
        "<h2 class=\"ui header\">" \
            "<div class=\"content\">" \
                title \
                "<div class=\"sub header\">" author "</div>" \
            "</div>" \
        "</h2>" \
    "</a>\n")
}

Ese guión depende de que bin/pandoc-get sea un guión con permiso de ejecución que busque la variable solicitada ($WORD) en al menos un archivo ($@):

#!/bin/sh
WORD="$1"; shift
grep -i "$WORD" "$@" \
| sed -r \
    -e 's#^[ \t]*'"$WORD"'[ :=]+##g' \
    -e 's#"##g'

Y por último indexes.mk dice cómo generar los índices:

indexes:VEQ:
    bin/indexes \
    | xargs mk -f indexes.mk

sitios/%.md:Q:  sitios/%/
    bin/sections \
        "$prereq" \
    > "$target"

Depende de bin/sections, que por cada carpeta indicada ($@) genera un índice de contenido en el orden inverso del tiempo de modificación (contenido actualizado primero):

#!/bin/sh
find -L "$@" \
    -type f \
    -name '*.md' \
| xargs mtime \
| sort -nr \
| awk '{print $2}' \
| bin/campechana-links \
| bin/relative-links

Copiar el contenido estático

bin/static indica qué debe copiarse tal cual desde sitios/ hacia web, para manejar las imágenes necesarias como parte del contenido, que se guarda en su propio repositorio:

#!/bin/sh
find -L sitios \
    -type f \
| grep -E \
    -e '\.png$' \
    -e '\.pdf$' \
    -e '\.jpe?g$' \
| sed -r \
    -e 's#^sitios#web#g'

Sólo copia imágenes png, jpg y pdf.

Lo que sigue

La última versión de este código puede encontrarse en:

https://git.nomia.mx/campechana/mk-blog.git/

La Campechana Mental es el proyecto de biblioteca digital del Hackerspace Rancho Electrónico.

Nos reunimos casi todos los lunes de 7 a 10 pm en Lorenzo Boturini #61 esq. Bolívar, Colonia Obrera, Ciudad Monstruo, México.

La banda de CoAAtv grabó una maravillosa charla: edi[tar]nos .