aboutsummaryrefslogblamecommitdiffstats
path: root/gemtext2html.awk
blob: 5ffce07b371c24d3bf518f4ce72adcea79fb24b4 (plain) (tree)
1
2
3
4
5
6
7
8
9


                                                               
                              
                 

                                                                

              
                                                    
 
 
      

                      



                                                     
                        
 


                                                               
 


                                                                                                                                         
                                                                           


                                                                                                         
                                                                                                                                          
                                                                  
                                                                                             
 
                                     



                              
                                    
 
                        
                        
                  

 







                                                                
                                                   
 

                                                             
                                                                           





                        





                                                                                       


                                               
                                                           

                       
                        
                                                             
                                                                                                                                                                

                                 


                  
                                      

 

 
                         
                                       

                             

 



                               



                                                   
                                                  


                                                             
                                                 
                 



                                                       

                                                    


                                                                   

            
                                     
            





                                                   
                                                   


                                                             
                                                  
                 

                                                        
 









                                                        



                                                            




                                                                                                 
                         

                                                           

                                                                    
 
                                               
                                                                                    
                         


                                                                                    
                 
                                    
                                                                                                       
                 
         


                                      
            






                                                  
                                                          

                                      
                                                  


                                              
                                               
         

                                      
            





                                     
                                            



                                                   
                                                   


                                                             
                                                  



                                   
                                           
         
            







                                                      
                              
            



                      

                                                   
                          








                                                                            
                                    



                                                                 
                


                                      
            
 



                      



                                                             

                          


                                      
            



                      


                                                             

                          


                                      
















                                                                                      

                                     

                                     


    
                              



                                   

                           
                       
                                                         






                              
                     
                          

                        
                                                             
                                                                                                                                                                                     

                                                            
                           
                    

                                                                
                                                                                                                                              
                         


                       
# gemtext2html
# convierte un archivo en gemtext a html de acuerdo a la spec
# excepción: enlaces a imagen (jpg, png, gif) se vuelven <img>
# TODO actualizar descripción
# TODO h2 en nav?
#
# importante: solo un {wikilink} (con o sin espacios) por línea
#
# modo de uso:
# awk -f gemtext2html.awk archivo.gmo > archivo.html
#

BEGIN{
#	sitio = "🥭"
	sitio = "ln"
	# para poder abrir y cerrar <ul>, <pre>, <p>:
	modo_lista = 0 
	modo_pre = 0
	modo_parrafo = 0 
	modo_galeria = 0

	en_section = 1 #empezamos abriendo una <section> sin h1

	navcount = 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,en'>"
	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'/>"
	print "<meta http-equiv='onion-location' content='http://chhhqibec5pvmyxmdobfdx33xhhtbla5lvrs2fgn7knh7kaaz4kgylad.onion.onion' />"
	print "<link rel='stylesheet' href='./static/estilo.css'>"
	print " <link rel='icon' href='./img/icon_bola.gif' type='image/gif' sizes='16x16'> "

	contenido = "<main><section>"
	nav = "<nav><ul>"
}

function appendContenido( t ){
	contenido = contenido t "\n"
}
function appendNav( t ){
	nav = nav t "\n"
	navcount++
}

function wikiLink( t ){
	i = match( t, /{.+}/)
	if ( i ){
		ifinal = index(t, "}") # índice del } final

		prev = substr(t, 1, i-1) # string previa al link
		link = substr(t, i, ifinal-i+1) # {link}
		nombre = substr(t, i+1, ifinal-i-1) # link	
		nombre = nombre2Link( nombre, "_" )

		post = substr(t, ifinal+1) # string posterior

		return prev "<a href='./" nombre ".html'>" link "</a>" post
	}
	else{
		return t
	}
}

function nombre2Link( t, r ){ # convierte un nombre con espacios, a uno con r (e.g. "_"
	gsub(" ",r,t);
	return t
}


NR == 1{
	titulo = $0
	sub("#[[:blank:]]+","",titulo) #prefijo
	print "<title>" sitio " &mdash; " titulo "</title>"
	print "</head>"
	print "<body>"
	print "<header>"
#	print "<p><a href='./index.html'>{" sitio "}</a></p>"
	print "<p><a href='./index.html' title='lenteja numérica'>{<img src='./img/icon_bola.gif' style='margin:0' alt='icono de lenteja numérica'/>}</a></p>"
	print "<h1>"titulo"</h1>"
	print "</header>"

	bloque = 1

	next # lee la siguiente línea
}



/^\+ /{ # include literal
	sub(/^+ /,"",$0) # elimina el +
	appendContenido( $0 )
	next
}

/^&/{ # include literal gemtext
	next
}

/^[[:blank:]]*$/ { # línea vacía
	if( !modo_pre ) {
		if( modo_lista ){ # cierra la lista
			modo_lista = 0
			appendContenido( "</ul>" )
		}
		else if( modo_parrafo ){ # cierra el párrafo
			modo_parrafo = 0
			appendContenido( "</p>" )
		}
		else if( modo_galeria ){
			modo_galeria = 0
			appendContenido( "</gallery>" )
		}
#		else
#			 appendContenido( "<br/>" ) 
		if( bloque ) # si lo previo fue header o blockquote
			bloque = 0;

	}
	else
		appendContenido( $0 )
	next
}

/^=>/{ # link
	if(!modo_pre){
		if( modo_lista ){ # cierra la lista
			modo_lista = 0
			appendContenido(  "</ul>" )
		}
		else if( modo_parrafo ){ # cierra el párrafo
			modo_parrafo = 0
			appendContenido(  "</p>" )
		}

		bloque = 1 #empieza bloque porque es <p>

		# 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
		}

		if( match($1, /^\.\//)) { # si es link local
			# si el path es imagen
			if( match($1, /(png|jpg|gif)$/) ){
				# crea imagen <img>
				if( !modo_galeria ){
					appendContenido("<gallery>")
					modo_galeria = 1
				}
				appendContenido("<img src='"$1"' alt='"texto"' loading='lazy'/>")
			}
			# si el path no es imagen y es .gmi
			else if( match($1, /gmi$/) ){
				# convierte enlace de .gmi a .html !
				sub(".gmi$",".html",$1)

				# crea link <a>
				appendContenido("<p><a href='"$1"'>"texto"</a></p>")
			}
			else{
				appendContenido("<p><a href='"$1"'>"texto"</a></p>")
			}
		}
		else{ # link externo
			appendContenido("<p><a href='"$1"' rel=external target=_blank>"texto"</a></p>")
		}
	}
	else{
		appendContenido(  $0 )
	}
	next
}

/^* /{ # lista
	if(!modo_pre){
		if(!modo_lista){ # inicia la lista
			if(modo_parrafo){
				modo_parrafo = 0
				appendContenido(  "</p>" )
			}
			modo_lista = 1
			appendContenido(  "<ul>" )
		}	
		sub("*[[:blank:]]+","<li>",$0)
		sub("$","</li>",$0)
		appendContenido( wikiLink($0) )
	}
	else
		appendContenido(  $0 )
	next
}

/^```/{ # preformatted
	if(modo_pre){
		# cierra preformatted
		modo_pre = 0
		appendContenido(  "</pre>" )
	}
	else{
		if( modo_lista ){ # cierra la lista
			modo_lista = 0
			appendContenido(  "</ul>" )
		}
		else if( modo_parrafo ){ # cierra el párrafo
			modo_parrafo = 0
			appendContenido(  "</p>" )
		}

		# abre preformatted
		modo_pre = 1
		appendContenido(  "<pre>" )
	}
	next
}

/^> /{ # blockquote
	if(!modo_pre){
		sub(">[[:blank:]]+","<blockquote>",$0)
		sub("$","</blockquote>",$0)
		bloque = 1
	}	
	appendContenido(  $0 )
	next
}

/^# /{ # h1
	if(!modo_pre){
		sub("#[[:blank:]]+","",$0) #prefijo
		sub("$","",$0) #sufijo
		bloque = 1

		if( !en_section ){ # si no se ha iniciado una sección antes
			appendContenido( "<section>" )
			en_section = 1
		}
		else{
			appendContenido( "</section><section>" )
		}

		# crea header con id
		appendContenido(  "<h1 id='"$0"'>"$0"</h1>" )

		# agrega header a navegación
		appendNav(  "<li><a href='#"$0"'>"$0"</a></li>" )
	}	
	else{
		appendContenido(  $0 )
	}
	next

}

/^## /{ # h2
	if(!modo_pre){
		sub("##[[:blank:]]+","",$0)
		sub("$","",$0)
		# crea header con id
		appendContenido(  "<h2 id='"$0"'>"$0"</h2>" )
		bloque = 1
	}
	else{
		appendContenido(  $0 )
	}
	next
}

/^### /{ # h3
	if(!modo_pre){
		sub("###[[:blank:]]+","",$0)
		sub("$","",$0)
		appendContenido(  "<h3 id='"$0"'>"$0"</h3>" )
		bloque = 1
	}
	else{
		appendContenido(  $0 )
	}
	next
}

#$0 !~ /^(=>|```|#{1,3} |* |\+|>|[[:blank:]]*$)/{ # líneas de texto (no "especiales")
{ # cualquier otra línea de texto
	if(!modo_pre){
		if(!modo_parrafo){
			modo_parrafo = 1
			appendContenido( "<p>" )
		}
		else # nueva línea en el mismo párrafo
			appendContenido( "<br/>" )
		
		# busca y convierte wikiLink (máx uno por línea)
		appendContenido( wikiLink($0) )
	}
	else{
		gsub("<","\\&lt;",$0)
		gsub(">","\\&gt;",$0)
		appendContenido( $0 )
	}
}

END{
	# imprime y cierra nav
	if(navcount){
		print nav
		print "</ul></nav>"
	}

	# imprime contenido
	print contenido
	# cierra tags que pudieron haber quedado abiertas
	if(modo_pre)
		print "</pre>"
	else if(modo_parrafo)
		print "</p>"
	else if(modo_lista)
		print "</ul>"

	# finaliza...
	print "</section>"
	print "</main>"
	print "<footer>"
#	print "<p><a href='./index.html'>{" sitio "}</a></p>"
	print "<p><a href='./index.html' title='lenteja numérica'>{<img src='./img/icon_bola.gif' alt='icono de lenteja numérica' width=8px height=8px style='margin:0'/>}</a></p>"
	print "<p>página actualizada en: " 
	print "<time datetime='"fecha"'>" fechasjm "</time>"
	print " (1"fecha")"
	print "</p>"
#	fecha = system( "date -r " FILENAME " --rfc-3339=date" )
#	print "</p>"
	print "<a href='https://endefensadelsl.org/ppl_deed_es.html' rel=external target=_blank>ppl: licencia de producción de pares</a></p>"
	print "</footer>"
	print "</body>"
	print "</html>"
}
Un proyecto texto-plano.xyz