Hugo é um gerador de testes estáticos. Com ele é possível gerar sites utilizando markdown, o que é perfeito para pessoas como eu que não tem muito saco para mexer com CSS ou Javascript no lado do frontend.

Eu uso o Hugo para gerar os posts desse blog, mas uma coisa me incomoda: a estrutura das páginas é feita em markdown. Isso não é um grande problema, markdown oferece muitas facilidades em relação a escrever HTML puro, e para um blog estático não tenho necessidade de usar um framework Javascript como o React. Mas depois que eu conheci o Emacs (e sua funcionalidade mais fascinante, o Org Mode), Markdown parece muito limitante e possui poucas estruturas.

Org mode

Em org, fazer listas aninhadas, blocos de código com syntax highlight, tabelas e muitas outras coisas é muito simples, já que a documentação é bem extensiva. O ponto mais relevante para esse meu pequeno projeto, entretanto, é o org-export. Essa funcionalidade perfeita permite converter arquivos org em markdown.

Infelizmente o formato do Hugo é bem específico, e exige cabeçalhos necessários para a exportação correta. Os cabeçalhos contém título do post, data, autor, palavras-chave, entre outras coisas. Essas configurações não são exportadas por padrão no org-export, então, para manter meu workflow de edição de texto dentro do Emacs e utilizando o Org Mode, resolvi escrever um pequeno programa para exportar o arquivo org para markdown usando os cabeçalhos do Hugo.

Escrita dos cabeçalhos

Para adicionar os cabeçalhos bastou escrever uma função que escreve texto no topo de um buffer recebido como parâmetro, de nome filename, assim como título, autor do post e tags. A parte de tags foi chatinha porque o Hugo não reconhece strings sem aspas delimitantes, mas bastou criar uma função lambda que adiciona aspas em cada elemento da lista de tags

(insert (format "tags = [%s]\n"
		(s-join ","
			(mapcar
			 '(lambda (x) (format "\"%s\"" x))
			 tags))))

As tags são adicionadas no cabeçalho tags do arquivo markdown resultante. Processos semelhantes são executados para cada um dos cabeçalhos. Por fim, o arquivo markdown tem o seguinte conteúdo em seu cabeçalho:

+++
title = "hugo-org-export: Sites estáticos com Hugo e Org Mode"
date = "2021-11-27T20:54:33"
author = "Matheus Lemos"
tags = ["emacs","lisp","org-mode"]
description = "test description"
draft = false
+++

Exportação de arquivos

Finalizada a geração de cabeçalhos, basta gerar um arquivo markdown e enviar para uma pasta destino. O Hugo gera os arquivos HTML resultantes a partir de uma pasta específica, então basta selecionar a pasta de conteúdo como destino da exportação. A função principal do programa executa exatamente esse processo.

(defun mlemosf/hugo-export-to-md-and-move ()
  (interactive)
  (let* (
	 (buffername (buffer-file-name))
	 (title (read-string "Título: "))
	 (author (read-string "Author: "))
	 (tags (split-string (read-string "Tags: ")))
	 (markdown-folder (read-file-name "Pasta de exportação: "))
	 (origin-filename (concat (file-name-sans-extension buffername) ".md"))
	 (destination-filename (concat markdown-folder (file-name-nondirectory (file-name-sans-extension buffername)) ".md")))
    (progn
      (org-md-export-to-markdown)
      (mlemosf/hugo-add-file-headers origin-filename title author tags)
      (rename-file origin-filename destination-filename t)
      (message "Arquivo exportado com sucesso"))))

O código para essa minibiblioteca está no meu github, assim com outros projetos em elisp, como o org-todoist-project, uma biblioteca para interagir com o Todoist usando o Org Agenda.

Até a próxima. Happy hacking ;)