lentejanumerica/gemtext2html.awk

209 lines
4.0 KiB
Awk
Raw Normal View History

2021-05-20 00:06:21 +00:00
# gemtext2html
# convierte un archivo en gemtext a html de acuerdo a la spec
# excepción: enlaces a imagen (jpg, png, gif) se vuelven <img>
#
# modo de uso:
# awk -f gemtext2html.awk archivo.gmi > archivo.html
#
2021-05-20 00:24:20 +00:00
2021-05-20 00:06:21 +00:00
BEGIN{
# para poder abrir y cerrar <ul>, <pre>, <p>:
modo_lista = 0
modo_pre = 0
modo_parrafo = 0
bloque = 0 # para no agregar <br/> después de headers y blockquotes
print "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>"
print "<html xmlns='http://www.w3.org/1999/xhtml' lang='es-MX'>"
print "<head>"
print "<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />"
print "<meta content='initial-scale=1.0, maximum-scale=1.0, user-scalable=yes' name='viewport'/>"
2021-05-20 00:24:20 +00:00
contenido = "<main>"
nav = "<nav><ul>"
}
function appendContenido( t ){
contenido = contenido t
2021-05-20 00:06:21 +00:00
}
2021-05-20 00:24:20 +00:00
function appendNav( t ){
nav = nav t
}
2021-05-20 00:06:21 +00:00
NR == 1{
titulo = $0
sub("#[[:blank:]]+","",titulo) #prefijo
2021-05-20 00:24:20 +00:00
print "<title>"titulo"</title>"
2021-05-20 00:06:21 +00:00
print "</head>"
print "<body>"
2021-05-20 00:24:20 +00:00
print "<header>"
print "<h1>"titulo"</h1>"
print "</header>"
2021-05-20 00:06:21 +00:00
}
$0 !~ /^(=>|```|#{1,3} |* |>|[[:blank:]]*$)/{ # líneas de texto (no "especiales")
if(!modo_pre){
if(!modo_parrafo){
modo_parrafo = 1
2021-05-20 00:24:20 +00:00
appendContenido( "<p>" )
2021-05-20 00:06:21 +00:00
}
else # nueva línea en el mismo párrafo
2021-05-20 00:24:20 +00:00
appendContenido( "<br/>" )
2021-05-20 00:06:21 +00:00
}
2021-05-20 00:24:20 +00:00
appendContenido( $0 )
2021-05-20 00:06:21 +00:00
}
/^[[:blank:]]*$/ { # línea vacía
if( !modo_pre ) {
if( modo_lista ){ # cierra la lista
modo_lista = 0
2021-05-20 00:24:20 +00:00
appendContenido( "</ul>" )
2021-05-20 00:06:21 +00:00
}
else if( modo_parrafo ){ # cierra el párrafo
modo_parrafo = 0
2021-05-20 00:24:20 +00:00
appendContenido( "</p>" )
2021-05-20 00:06:21 +00:00
}
else if( bloque ) # si lo previo fue header o blockquote
bloque = 0;
else
2021-05-20 00:24:20 +00:00
appendContenido( "<br/>" )
2021-05-20 00:06:21 +00:00
}
else
2021-05-20 00:24:20 +00:00
appendContenido( $0 )
2021-05-20 00:06:21 +00:00
}
/^=>/{ # link
if(!modo_pre){
if( modo_lista ){ # cierra la lista
modo_lista = 0
2021-05-20 00:24:20 +00:00
appendContenido( "</ul>" )
2021-05-20 00:06:21 +00:00
}
else if( modo_parrafo ){ # cierra el párrafo
modo_parrafo = 0
2021-05-20 00:24:20 +00:00
appendContenido( "</p>" )
2021-05-20 00:06:21 +00:00
}
# borra flecha del inicio
sub("^=>","",$0)
# ahora $1 es el path, $2 a $NF el texto
# concatena todo el texto
texto = $2
for(i=3; i<=NF; i++){
texto = texto" "$i
}
# si el path es imagen
if( match($1, /(png|jpg|gif)$/) ){
# crea imagen <img>
$0="<img src='"$1"' alt='"texto"'/>"
}
# si el path no es imagen
else{
# convierte enlace de .gmi a .html !
sub(".gmi$",".html",$1)
# crea link <a>
$0="<a href='"$1"'>"texto"</a><br/>"
}
}
2021-05-20 00:24:20 +00:00
appendContenido( $0 )
2021-05-20 00:06:21 +00:00
}
/^* /{ # lista
if(!modo_pre){
if(!modo_lista){ # inicia la lista
if(modo_parrafo){
modo_parrafo = 0
2021-05-20 00:24:20 +00:00
appendContenido( "</p>" )
2021-05-20 00:06:21 +00:00
}
modo_lista = 1
2021-05-20 00:24:20 +00:00
appendContenido( "<ul>" )
2021-05-20 00:06:21 +00:00
}
sub("*[[:blank:]]+","<li>",$0)
sub("$","</li>",$0)
}
2021-05-20 00:24:20 +00:00
appendContenido( $0 )
2021-05-20 00:06:21 +00:00
}
/^```/{ # preformatted
if(modo_pre){
# cierra preformatted
modo_pre = 0
2021-05-20 00:24:20 +00:00
appendContenido( "</pre>" )
2021-05-20 00:06:21 +00:00
}
else{
if( modo_lista ){ # cierra la lista
modo_lista = 0
2021-05-20 00:24:20 +00:00
appendContenido( "</ul>" )
2021-05-20 00:06:21 +00:00
}
else if( modo_parrafo ){ # cierra el párrafo
modo_parrafo = 0
2021-05-20 00:24:20 +00:00
appendContenido( "</p>" )
2021-05-20 00:06:21 +00:00
}
# abre preformatted
modo_pre = 1
2021-05-20 00:24:20 +00:00
appendContenido( "<pre>" )
2021-05-20 00:06:21 +00:00
}
}
/^> /{ # blockquote
if(!modo_pre){
sub(">[[:blank:]]+","<blockquote>",$0)
sub("$","</blockquote>",$0)
bloque = 1
}
2021-05-20 00:24:20 +00:00
appendContenido( $0 )
2021-05-20 00:06:21 +00:00
}
/^# /{ # h1
if(!modo_pre){
2021-05-20 00:24:20 +00:00
sub("#[[:blank:]]+","",$0) #prefijo
sub("$","",$0) #sufijo
2021-05-20 00:06:21 +00:00
bloque = 1
}
2021-05-20 00:25:35 +00:00
appendNav( "<li><a href='#"$0"'>"$0"</a></li>" )
2021-05-20 00:24:20 +00:00
appendContenido( "<h1 id='"$0"'>"$0"</h1>" )
2021-05-20 00:06:21 +00:00
}
/^## /{ # h2
if(!modo_pre){
sub("##[[:blank:]]+","<h2>",$0)
sub("$","</h2>",$0)
bloque = 1
}
2021-05-20 00:24:20 +00:00
appendContenido( $0 )
2021-05-20 00:06:21 +00:00
}
/^### /{ # h3
if(!modo_pre){
sub("###[[:blank:]]+","<h3>",$0)
sub("$","</h3>",$0)
bloque = 1
}
2021-05-20 00:24:20 +00:00
appendContenido( $0 )
2021-05-20 00:06:21 +00:00
}
END{
2021-05-20 00:24:20 +00:00
print nav
print "</ul></nav>"
print contenido
2021-05-20 00:06:21 +00:00
# cierra tags que pudiero n haber quedado abiertas
if(modo_pre)
print "</pre>"
else if(modo_parrafo)
print "</p>"
else if(modo_lista)
print "</ul>"
2021-05-20 00:24:20 +00:00
print "</main>"
print "<footer>"
# TODO footer
print "</footer>"
2021-05-20 00:06:21 +00:00
print "</body>"
print "</html>"
}