Notxor tiene un blog: Publicar html con org-mode

En el artículo de hoy hablo de cómo exportar de org-mode a html para utilizarlo en un proyecto con varios ficheros org interconectados entre sí. Al exportar, las referencias org se convierten en sus correspondientes enlaces html guardando la misma estructura de directorios que tengan los ficheros org. Es la forma en la que org-mode publica. Si quieres ahorrarte el suplicio de leer el artículo y como lo cuento, busca el apartado publishing en la documentación de org-mode... pero si prefieres leer un resumen en español y saber cómo lo hago yo: sigue leyendo.

¿De qué va todo esto de publicar html desde org-mode? ¿Para qué lo puedo utilizar? Pues pondré un ejemplo, con un proyecto que estoy empezando. Hace un tiempo puse por aquí una prueba para crear un librojuego con org-mode. Era una prueba pequeña y apenas se utilizaban cuatro ficheros. Como eran tan pocos ficheros, las cabeceras y la exportación se podía hacer a mano. Sin embargo, en un proyecto largo, tener que hacerlo así puede ser un poco complicado, tedioso y sujeto a errores y olvidos.

El caso de uso propuesto es parte de un proyecto más amplio. El problema es que estoy haciendo una especie de MUD para aplicarlo en un proyecto de prevención del acoso escolar para la Asociación PICA1 con la que, los que leéis el blog habitualmente, sabéis que colaboro. El caso es que la parte servidor del mismo está prácticamente finalizada, a la espera de que se llene de contenido y de corregir los fallos y completar las carencias que se encuentren durante el proceso. Para dotar de contenido algo tan interactivo como un MUD, no sirve un guión lineal. Por ello, pensé en escribir guiones más interactivos, en formato librojuego. He probado varios sistemas que automatizan la creación de ese tipo de juegos: he probado Undum, he probado Twine, he probado Squiffy... y ninguno de los tres ha funcionado como esperaba. El primero, que había que escribir el código en puro html y javascript, sin embargo, por alguna razón que no llegué a averiguar algunos enlaces no funcionaban. De los otros dos, además de tener que instalar node y un montón de paquetes, no terminaron de funcionar correctamente. La otra idea que se me ocurrió era montar un wiki enlazando páginas directamente. Sin embargo, para que funcione tienes que tener un servidor y para trabajar en modo monousuario es muy lioso.

Cuando le comenté los problemas que tenía para encontrar una herramienta adecuada a un amigo del CAAD2, me dijo: pensaba que lo harías con algún pichorro de Emacs. Y tenía razón, al final no me tendré que pegar con cosas como electron y node o desperdiciar espacio en disco y en memoria con esas cosas, teniendo suficiente con el texto gestionado por los chismáticos de Emacs y org-mode.

Estructura de ficheros

Para iniciar el proyecto es recomendable tener clara la estructura que le daremos a nuestro contenido. El proyecto lo he llamado, de forma provisional, Kvintero3 y tiene la siguiente estructura de ficheros:

.
├── html
│   └── ... (directorio donde se publicará)
├── kvintero.el
├── org
│   ├── css
│   │   └── ... (hojas de estilo)
│   ├── img
│   │   └── ... (ficheros de imagen)
│   ├── js
│   │   └── ... (ficheros javascript)
│   └── ... (ficheros org)
├── plantillas
│   └── plantilla-base.org
└── README.org

se pueden apreciar algunas cosas así a bote pronto: los directorios org y html serán idénticos, pero mientras el primero está compuesto de los fuentes de org-mode el segundo es el resultado de convertir los fuentes en html. En esos directorios hay otros subdirectorios para la(s) hoja(s) de estilos, las imágenes y los archivos javascript. También hay un directorio que se llama plantillas, donde hay sólo un fichero de momento y más adelante analizaremos su contenido. Además de todo ésto también hay un fichero de código que se llama kvintero.el que contiene un par de formas que definen algunas variables del proyecto para poder exportar cómodamente en tres teclazos.

Es una estructura muy simple, aunque su visualización en árbol, pueda dar una primera impresión de complejidad. En realidad, sólo necesitas crear el directorio org y dentro de él: el css, el img y el js, cada uno con sus cosas, para que no se mezclen.

Para que dicha estructura sea efectiva es recomendable que luego, en los enlaces se utilicen siempre paths relativos. Para que el sitio desplegado o publicado, ─como prefieras llamarlo─, funcione incluso sin un servidor, es siempre recomendable el uso de dichos paths relativos. Además, se pueden utilizar anclas a etiquetas concretas dentro de otros ficheros org4, como veremos después.

El código

Como he dicho antes, el código es muy sencillo, lo pongo aquí y luego lo comentaré un poco:

(require 'ox-publish)

(setq org-publish-project-alist
      '(
        ("fuentes-org"
         :base-directory "~/proyectos/kvintero/org/"
         :base-extension "org"
         :publishing-directory "~/proyectos/kvintero/html/"
         :recursive t
         :publishing-function org-html-publish-to-html
         :headline-levels 4
         :html-preamble t)
        ("org-auxiliares"
         :base-directory "~/proyectos/kvintero/org/"
         :base-extension "css\\|js\\|png\\|ttf"
         :publishing-directory "~/proyectos/kvintero/html/"
         :recursive t
         :publishing-function org-publish-attachment)
        ("kvintero" :components ("fuentes-org" "org-auxiliares"))))

La primera línea no necesita mucho que explicar: nos aseguramos que está en el sistema el paquete que proporciona ox-publish. Después de esa primera forma, nos encontramos con otra que establece la lista de proyectos para publicar. Cada elemento de la lista tiene una forma general tal que:

("nombre-proyecto" ...)

Vamos a analizarlo un poco más despacio.

Proyectos de publicación

El primer elemento de la lista trata con los fuentes. Establece cuál es su directorio base en :base-directory. Vemos que coincide también con el segundo elemento. En él buscará los ficheros con los que debe trabajar. Como se puede observar el valor se establede al lugar donde se encuentran los ficheros que fuentes-org debe tratar o trabajar. En :base-extension se especifica de qué tipo son los ficheros tiene que procesar. Si nos fijamos en la primera forma la extensión es única: org, pero en la segunda se establece una lista de extensiones separadas por \\|. Lo siguiente que se necesita es el lugar donde se depositará el resultado del proceso y se pone en :publishing-directory. En este caso es un directorio local, pero también se puede configurar un path con el formato que entienda tramp, por ejemplo: /ssh:usuario@host:path/al/sitio. También se pueden especificar ficheros que se ignorarán durante el proceso con otras variables, si necesitas esta información: mira en la documentación de org-mode.

Está previsto que se puedan meter otros directorios dentro del directorio base para gestionar diferentes subproyectos y queremos que se procesen todos, guardando la estructura. Para permitir que se publiquen todos esos subproyectos hay que establecer :recursive a t y el sistema analizará también todos los subdirectorios que se encuentren dentro del base.

Por último, en :publish-function se establece qué función procesará los ficheros. En el primer caso se quiere que se convierta el fichero procesado a html y para ello que se utilice la función org-html-publish-to-html. En el segundo caso queremos que copie los ficheros nada más y por eso se establece a org-publish-attachment.

Hay más opciones que configurar si se necesitan: funciones que se ejecuten antes o después de la publicación, por ejemplo, y muchas otras opciones. Vuelvo a recomendar que le echéis un vistazo a la documentación de org-mode.

La tercera de las formas, que antes no la he mencionado, es un conjunto de ambas, especificado por una lista de componentes. Llamando a ésta, se llama a las dos anteriores.

Luego en el texto del proyecto hay que recordar enlazar de forma relativa a la estructura de directorios. Además también se pueden enlazar lugares concretos de un fichero. Ya sé que lo sabéis pero está bien recordarlo. Para hacerlo suelo utilizar las formas:

[[file:cualquier.org::*Título de apartado][Texto mostrado]]
[[file:cualquier.org::#id-definido][Texto mostrado]]
[[file:cualquier.org::mi objetivo][Texto mostrado]]

El formato con *Título de apartado busca entre los títulos de sección que contenga el fichero el que coincida con Título de apartado. Con #id-definido se busca un elemento que en sus propiedades contenga #+name: id-definido. Y por último, si quieres saltar a algún sitio situado en medio de un documento, que no tiene lista de propiedades donde ponerle nombre, se puede utilizar la forma <<mi objetivo>>, en el texto y se enlaza de la tercera forma.

Como digo, supongo que todos esos detalles ya los conocéis, al menos quienes utilizáis habitualmente org-mode, pero, ─como digo─, no está de más repasarlo.

Plantillas y documentos

Una forma de estandarizar y ahorrar tiempo en la publicación de los ficheros org, tanto en html como en pdf es proporcionar al sistema una plantilla que haga las veces de configuración de la página, estableciendo los valores oportunos. En esas plantillas lo que se hace, normalmente, es situar todas las opciones que pondríamos en la cabecera que sean comunes a todas las páginas. Para este proyecto he preparado la siguiente cabecera:

#+author:  Notxor
#+email:   notxor@nueva-actitud.org
#+options: ':t *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline author:t c:nil
#+options: creator:comment d:(not LOGBOOK) date:t e:t email:nil f:t inline:t
#+options: num:t p:nil pri:nil stat:t tags:t tasks:t tex:t timestamp:t toc:t
#+language: es
#+exclude_tags: noexport
#+select_tags:  export

#+options: html-postamble:auto html-postamble:nil tex:t
#+html_container: div
#+html_doctype: xhtml-strict
#+html_head: <link rel="stylesheet" type="text/css" href="css/tus-estilos-favoritos.css" />

Todos esos valores comunes pueden cambiar en un momento dado, porque se quiera mostrar una determinada página con otra hoja de estilos o porque varíen los paths, o por cualquier otro motivo. Estas cosas harán que necesitemos más tipos de cabecera. Por ejemplo, si creamos un subdirectorio dentro de nuestro sitio base y utilizamos la misma cabecera para publicar el sitio, no encontrará el fichero .css, necesitamos cambiar la última línea a:

#+html_head: <link rel="stylesheet" type="text/css" href="../css/style.css" />

Modificando el path en el que debe buscar la hoja de estilos.

Si ya tenemos una plantilla en la que basarnos, generar las demás que nos hagan falta es tan sencillo como copiar la plantilla-base y modificar los valores que queramos cambiar... y llamaremos a dicha plantilla desde el fichero que queramos con el formato:

#+setupfile: ../plantilla/plantilla-base.org
#+title: Este es el Título
#+subtitle: y este el Subtítulo

Como se puede apreciar, la cabecera queda resumida a dos o tres líneas, muchas veces será suficiente establecer el #+setupfile:, o como mucho añadirle un título.

Otro factor a destacar es que establecemos que utilizando la etiqueta noexport se puede eliminar todo un árbol interno del documento cuando lo exportamos.

* Notas    :noexport:

Esta información no se exportará al fichero ~html~

Hoja de estilos

Antes de meternos en un pequeño tutorial, que consistirá en que iré haciendo algunos pasos para la creación de un sitio y, si quieres, puedas irlos siguiendo para comprobar que todo funciona. También necesitas una hoja de estilos que nos sirva de punto de partida. Por Internet ha muchos ficheros css para la exportación de org-mode publicados, puedes utilizar el que más te guste... si eres vago como yo, puedes descargarte el que voy a utilizar en el proyecto de:

http://thomasf.github.io/solarized-css

es el mismo que utilicé en aquella prueba sin hacerle ninguna modificación. Sin embargo, esta vez sí le haré cambios. En la web, el autor, recomienda el uso de un enlace directo al sitio de Internet. Pero, es una hoja destinada a mostrar sólo una estructura org, más como agenda, y no para publicar documentos. Además quiero ajustar las fuentes y otros parámetros. Por eso descargo el fichero y luego iré contando las modificaciones que le haré, según avance el tutorial.

Puedes elegir entre dos temas de color:

solarized-dark

Captura-pantalla_solarized-dark.png

solarized-light

Captura-pantalla_solarized-light.png

Particularmente me gusta más el solarized-light y será el que utilice. No olvidéis modificar en la plantilla el nombre de la hoja de estilo que más te guste. Prefiero siempre partir de una hoja de estilos ya creada y modificarla que crear una desde cero.

Publicación

Yo comenzaré con un pequeño fichero de texto en formato org para empezar el proyecto, cualquier texto vale, yo he preparado estos pequeños párrafos para comenzar:

#+setupfile: ../plantillas/plantilla-base.org
#+title: Kvintero ─ Introducción

Dos campanas tañieron al unísono cuando se abrió el arco iris.  Los
viajeros hubieran podido oír las dos, si hubieran prestado atención.
Pero impactados por el viaje no las escucharon.

La primera sonó escondida, como olvidada, oculta entre el ruido del
tráfico y el ajetreo de la ciudad.

La segunda sonó rotunda bajo las estrellas en una noche silenciosa,
pero fue ignorada por aquellos que pudieron llegar a oírla.  Su sonido
rodó por los tejados de pizarra y paja, rebotó por las calles de
piedra y acero, deshaciéndose en ecos hacia las montañas.

Una tercera quiso sonar con ellas, pero rajada y rota apenas consiguió
emitir un chirrido metálico. Sin embargo, ésta obtuvo más atención
cuando lanzó su desafinado tañido.

El /brujo/ abrió los ojos y sonrió con malicia.

[[file:piedra.org][Continuar...]]

Comenzamos con los cambios:

El autor del css utiliza la carga de fuentes desde la habitual URL de gúguel, una política que no es de mi agrado. Yo, en cambio, he bajado de Internet algunas fuentes de daFont, un sitio donde se pueden encontrar fuentes de todo tipo y desde el que se pueden descargar para uso personal. Cada uno se puede bajar las fuentes que quiera, yo he bajado Feathergraphy, que es gratuita para uso personal5, en los títulos y para el texto utilizaré la habitual Linux Libertine que uso también como fuente principal en este blog, y que tiene una licencia libre y se puede utilizar para cualquier fin.

Los ficheros ttf los he colocado en un directorio llamado fuentes que no aparece en el árbol de directorios anterior, tenéis que crearlo, copiar las fuente ahí e importarlas en el css como sigue:

@font-face {
    font-family: "Libertine Regular";
    src: url('../fuentes/LinLibertine_R.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
}
@font-face {
    font-family: "Feathergraphy";
    src: url('../fuentes/Feathergraphy2.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
}

El paso siguiente es modificar algunos estilos. En las cabeceras, se añade una instrucción font-family: 'Feathergraphy' y en el apartado body se añade font-family: 'Libertine Regular'. Para ver el resultado hay que publicarlo. Sigamos los siguientes pasos:

  1. Cargar el código que hicimos antes con el comando M-x load-file y seleccionado el fichero kvintero.el que habíamos creado para tener la lista de proyectos para publicación.
  2. A partir de este momento, si estamos en un fichero org podemos emplear el comando de exportar C-c C-e, ahora seleccionamos el apartado Publish (P), y choose project (x), elegimos el proyecto kvintero y se realiza la magia.

    Si no estamos en un fichero org, podemos utilizar el comando M-x org-publish-project RET kvintero RET.

  3. Abrir el fichero en un navegador web. Obtendremos algo parecido a:
Captura-pantalla_Cambio-fuentes.png

Vista la imagen, no me gusta cómo queda el título y voy a separarlo en dos. La cabecera del fichero org quedará así:

#+setupfile: ../plantillas/plantilla-base.org
#+title: Kvintero

* Introducción

Tras modificar el org lo guardamos y volvemos a publicar el proyecto, bien con C-c C-e o con M-x org-publish-project. Volvemos a ver cómo ha reaccionado nuestro html. El resultado quedará como:

Captura-pantalla_cabecera-numero.png

Bueno, parece que ha surtido efecto, pero me gusta menos aún: aparece un índice que no quiero y el título me lo numera... algo más hay que cambiar. Y lo que hay que cambiar está en la plantilla. En concreto en la línea:

#+options: num:t p:nil pri:nil stat:t tags:t tasks:t tex:t timestamp:t toc:t

Hay que cambiarla por:

#+options: num:nil p:nil pri:nil stat:t tags:t tasks:t tex:t timestamp:t toc:nil

Volvemos a publicar el proyecto por el método habitual. ¿Qué ha ocurrido? ¿Nada? Pues sí, no ha ocurrido nada, porque hemos modificado un fichero que no está dentro del proceso del proyecto. Para que tenga efecto hay que rehacer todos los ficheros que enlacen la cabecera. Lo que yo hago es entrar en el dired, si tienes activado normalmente, como yo el dired-sidebar lo tienes a mano. Pasas a ese buffer, seleccionas los ficheros, ─si son muchos, puedes seleccionar el directorio entero─, pulsando m para marcar y luego pulsas T (obsérvese la mayúscula). Es lo mismo que hacer un touch en una consola, que es el otro método rápido. Si ahora repites el comando de publicar el proyecto, el resultado será:

Captura-pantalla_cabecera-sin-numero.png

Poniendo una imagen

Voy a poner una imagen en el proyecto, más para ilustrar de otro modo cómo es el proceso de mantener un proyecto completo, el ir haciendo pequeñas modificaciones e ir viendo cómo se van produciendo los resultados.

Lo primero que necesito es encontrar una imagen. Yo me descargué una fotografía de un menhir de Internet y le apliqué algunos filtros con GIMP. Al final, el fichero .png lo he copiado en el directorio img que cuelga del directorio base. Para cargar la imagen, se hace como siempre en org-mode.

#+setupfile: ../plantillas/plantilla-base.org
#+title: Kvintero

* Introducción

[[file:img/menhir.png]]

Una vez introducido el enlace de la imagen, si queremos verla aparecer en nuestro documento html debemos publicar el proyecto. Como seguramente estaremos aún en el fichero org, la pulsación completa será C-c C-e P x kvintero y obtendremos algo así:

Captura-pantalla_imagen-centrada.png

Está bien, pero es un poco soso. Vamos a darle un poco de vidilla con la hoja de estilos, a ver si lo adornamos un poco. Primero, me gustaría que la imagen se desplazara a la izquierda y el texto se ajustara a ella mostrándose a la derecha, y no debajo. Eso es fácil de hacer con css.

.float-left {
    float: left;
    margin-right: 1em;
}
.float-right {
    float: right;
    margin-left: 1em;
}

En principio me bastaba con float-left, pero ya puestos, he creado también float-right para tenerlo disponible en el futuro. Así podré manejar imágenes ajustándolas en uno de los laterales. Además añado un margen en el lado donde irá el texto, para que no se junte en exceso a la imagen.

Ya puestos a hacer cambios, ─y puesto que es un documento que hará las veces de /librojuego/─, me gustaría resaltar más algunos elementos, hacer que la primera letra del párrafo inicial se muestre más grande y remarcar la primera línea destacándola. Para esto he añadido un poco más de código a la hoja de estilos.

.p-inicio::first-line {
    font-weight: bold;
    color: rgba(0,0,0,0.85);
}
.p-inicio::first-letter {
    position: relative;
    padding-top: 0.1em;
    display: block;
    float: left;
    font-family: 'Feathergraphy';
    font-weight: normal;
    font-size: 3.2em;
    line-height: 0.8em;
    color: #d33682;
    margin-right: 0.1em;
}

La primera parte, .p-inicio::first-line, establece que la primera línea del párrafo se escriba en negrita y con un color negro con una transparencia del 15%.

La segunda parte, .p-inicio::first-letter, establece que la primera letra del párrafo se muestre con un tamaña 3.2 veces el tamaño de letra normal y que utilice el tipo de letra y el color del título.

Bueno, hechos los cambios necesitamos visualizarlos en nuestro navegador favorito. Como seguramente seguiremos en el buffer donde hemos hecho los cambios podemos publicar el proyecto utilizando la combinación M-x org-publish-project RET kvintero RET. El resultado que debemos obtener sería algo así:

Captura-pantalla_imagen-fluye.png

¿No? ¿No ha salido bien? Claro, hemos modificado la hoja de estilos, pero no le hemos dicho al documento qué estilos y dónde tiene que aplicarlos. Eso es fácil:

#+setupfile: ../plantillas/plantilla-base.org
#+title: Kvintero

* Introducción

#+attr_html: :class float-left
[[file:img/menhir.png]]

#+attr_html: :class p-inicio
Dos campanas tañieron al unísono cuando se abrió el arco iris.  Los
viajeros hubieran podido oír las dos, si hubieran prestado atención.
Pero impactados por el viaje no las escucharon.

Delante del elemento del documento que queremos aplicar uno de los estilos que acabamos de crear, utilizaremos el comentario especial #+attr_html: para establecer la :class con el nombre que hayamos puesto en la hoja de estilos. Si lo haces como está en el código anterior y publicas el proyecto como venimos haciendo hasta ahora, obtendrás los resultados como se mostraron arriba.

Por supuesto, ajustar todas estas cosas lleva su tiempo y es recomendable utilizar las herramientas de desarrollador web que provea el navegador que utilices. Yo normalmente estoy utilizando Falkon:

Captura-pantalla_poniendo-clases.png

Primero hago los ajustes ahí, probando colores, márgenes, fuentes, etc. y luego lo paso al código definitivo de la hoja de estilos.

Conclusiones

Publicar proyectos es una forma sencilla, pero potente de crear contenido web que se puede emplear para muchas cosas desde org-mode. Una de los usos para desarrolladores es, generar la documentación para colocarla en Internet o distribuirla con el programa. Generar un epub fácilmente. Tener un sitio de Internet estático de una manera sencilla. También, en lugar de enfocar la publicación a html se puede enfocar a pdf con LaTeX, o incluso tener proyectos que generen la documentación en varios formatos: info, html, pdf, etc.

Hay un montón de aspectos que no he utilizado aquí, pero están explicados en la documentación de org.

Nota al pie de página:

1

Protención a la Infancia Contra el Abuso https://asociacionpica.org

2

Club de Aventuras AD en http://www.caad.es/... sí, aún existe el foro.

3

Su significado sería Quinta Tierra: en Esperanto Kvin significa 5 y Tero, Tierra.

4

Hay una explicación completa de dichas anclas en el apartado 4.8 Search Options in File Links del manual de org-mode.

5

Si la vas a emplear para algún proyecto profesional, que no se te olvide pagar los pocos euros que cuesta.

-1:-- Publicar html con org-mode (Post )--L0--C0--January 13, 2021 11:07 AM

Notxor tiene un blog: Rust por encima, comparando con erlang

Durante el 2020 he dedicado tiempo a aprender erlang. Ya he dicho muchas veces que me gustan los lenguajes veteranos y supongo que alguien que lea sólo el título estará pensando que voy a traicionar esos gustos. Sin embargo, estos días encontré en algún sitio un enlace a un artículo que comparaba las características de erlang con las de Rust, lo que me lleva a evaluarlo como próxima adquisición. En este artículo hablaré de lo que he ido cotilleando sobre este lenguaje y por qué me ha interesado. También he leído que es un poco puñetero y que lanza errores constantemente que no te permiten compilar y tienes que retocar el código, pero entiendo que eso forma parte de la seguridad que maneja a la hora de crear los ejecutables, por tanto ¿eso es bueno o es malo?

Después de trabajar un poco y hacer algún que otro proyecto con erlang, le he encontrado algunas características que me han encantado y que me gustaría tener en cualquier otro lenguaje. El caso es que mirando cosas sobre erlang llegué a un artículo que lo comparaba con Rust. La tentación de probar el lenguaje fue grande, porque algunas características de las que me encantan de erlang están presentes en dicho lenguaje. Además cuando me puse a investigar un poco más, todos alaban la seguridad y la velocidad de los ejecutables que genera.

Características

Quizá sea más fácil si enumero las características de erlang que me gustan y vamos a ver cuáles proporciona Rust. Mirando en la documentación encontré una lista de lenguajes que han influido a éste. El caso es que aparecen en ella algunos lenguajes que me resultan gratos:

  • erlang: de éste toman el paso de mensajes y ha influido en otras características.
  • scheme: de él toma los macros.
  • ruby: de aquí viene la sintaxis de closures.

Hay varios lenguajes más que tienen características interesantes: Haskell, OCaml, C++, etc. Pero vamos a ver las cosas que me gustaría encontrar y que erlang me proporciona.

Inmutabilidad

En erlang la asignación de las variables no puede cambiar. De primeras puede parecer complicado de entender que las variables no varíen, pero a la larga es una bendición el que no lo hagan. Cada expresión es siempre idéntica a cuando ha sido definida y se eliminan todos los errores que suceden en otros lenguajes cuando una variable cambia a un valor no esperado.

El caso es que Rust tiene variables que pueden mutar, pero por defecto son inmutables. También supongo que muchos errores de compilación de los que se quejan algunos usuarios pueden venir de este lado: intentar asignar un nuevo valor a una variable inmutable. Por lo tanto, si al final se decide que sea mutable tendrás que pensar por qué, qué ventajas tiene poder modificarla y si el proceso de hacerlo es suficientemente seguro.

Concordancia de patrones

Esta es una de las características que más me han gustado de erlang. Comprobar no sólo los valores, sino la estructura o el tipo de las variables y reaccionar a esos patrones con el código correspondiente es una forma muy potente, sencilla y rápida de escribir código que se comporta de modo polimórfico. Porque además, esa comprobación se puede llevar a cabo en cualquier parte del código: en las llamadas, dentro de las funciones, es igual. Permite una flexibilidad enorme a la hora de escribir código.

Por lo que he visto Rust no llega al mismo nivel y también tiene la posibilidad de utilizar la concordancia de patrones en estructuras de código parecidas a las estructuras case de erlang. Cuando avance un poco más en el uso de este lenguaje veré si es lo que espero. De todas formas, cada lenguaje tiene sus caminos.

Tuples y listas

La manera en la que erlang utiliza las estructuras de datos, no sólo los tuples, pero pincipalmente éstos, es una forma muy inteligente de organizar la información con la que trabaja el programa. Una vez que defines un tuple o una lista, se mantienen inmutables. Pero puedes organizar los datos de cualquier manera que te resulte cómodo y luego descomponerlo con patrones de concordancia de manera rápida, con una asignación.

Por lo que he visto en Rust también hay tuples y equivalentes a las listas tiene vectores y arrays. Uno de esos tipos es inmutable (arrays), más recomendable cuando se conoce el tamaño en tiempo de compilación. Mientras que los vectores son conjuntos de datos que pueden ajustarse en tiempo de ejecución. Veremos cómo se comportan estos tipos de datos.

Registros y ETS1

Los registros son estructuras que pueden almacenar cualquier tipo de dato válido de erlang. Son estructuras fijas que se definen junto al programa y no pueden cambiarse durante la ejecución. No se pueden añadir o quitar campos en medio de la ejecución. Además esos registros se pueden organizar en tablas ETS, ordenados por un campo que funciona como índice de la tabla. Las tablas se pueden compartir entre varios procesos, por lo que funciona como una forma de compartir datos entre los distintos componentes del sistema. Si no quieres que la tabla sea compartida se puede definir un proceso propietario que sea el único encargado de acceder a ella, como lectura/escritura o como escritura, de esta forma se puede garantizar la integridad de los datos. Todo esto, sin mencionar Mnesia que es una base de datos que puedo organizar esas tablas ETS y almacenar datos relacionados en ellas. No es SQL pero se pueden organizar consultas equivalentes.

Parece ser que Rust proporciona structs. Sin embargo, no parece que haya algo similar a ETS. Aunque supongo que un vector de structs puede servirnos también, no es lo mismo que tener tablas con sus índices para encontrar los datos. Espero que la velocidad del lenguaje compense la falta de estructura en este sentido y sea fácil conseguir algo parecido.

Iteración

Como muchos otros lenguajes funcionales, erlang proporciona el mecanismo de iteración como su principal modo para realizar bucles. Además, en la librería lists proporciona algunas funciones iterativas como map, foreach, filter, etc. Además, la potencia de la iteración sobre la estructura cabeza-cola, [H|T], como en otros lenguajes funcionales es algo que se emplea con profusión. Eso sin contar los maravillosos bloques de código, que incluso Python copió para realizar operaciones rápidas, tipo:

%% Devuelve una lista con el doble de los términos impares
[X * 2 || X <- List, (X rem 2) /= 0].

Parece ser que Rust cuenta con las instrucciones de bucle habituales de otros lenguajes como while, for, etc. Parece que está menos enfocado a la iteración, aunque parece que también se puede utilizar, no es su forma óptima. Entiendo, que en este caso será mejor utilizar esas estructuras de bucle en lugar la iteración.

Comunicación entre procesos

Al principio, la forma de comunicarse que tienen los procesos de erlang me pareció liosa. En cuanto comprendes que funciona de manera asíncrona, como enviar un mensaje depositándolo en un buzón y esperar a que te contesten ─o no─, te das cuenta que es lo más simple que hay. Al final, montar un componente es tan sencillo como levantar un proceso, abrir un buzón para él e intercambiar mensajes con los demás procesos.

La concurrencia es una de esas cosas que le dan caché a erlang y es la principal característica que mencionan todos para decantarse en el uso de este lenguaje. Los procesos concurrentes de otros lenguajes, compartiendo memoria, estableciendo semáforos o banderas, bloqueos, etc. es algo mucho más lioso que el mecanismo de erlang.

Por lo que he leído hasta ahora sobre Rust, también está enfocado a la concurrencia. Aún no sé qué mecanismos involucra.

Documentación

La documentación con la que viene erlang es completa y suficiente para consultas rápidas de las distintas librerías con las que puedes trabajar. Además son accesibles desde el propio Emacs para realizar esas consultas.

Por lo que he visto, Rust es bastante agradecido en este aspecto también y viene con una documentación bastante completa. Además en su página web puedes encontrar enlaces donde poder aprender y consultar los distintos aspectos del lenguaje. Además, después de mirar un poco por encima, la ayuda viene en ficheros html y para leerla cómodamente se lanza el navegador.

Rust

El caso es que me he puesto a investigar algo más sobre Rust y a parte de todo lo que se puede encontrar en la wikipedia, donde te explica que es un lenguaje desarrollado por la Fundación Mozilla para el desarrollo de bajo nivel, o de sistemas, superando las dificultades que presenta C, he visto en su página algo más de información.

La curiosidad, antes de meterme en faena, sin tener muy claro por qué merece la pena aprenderlo, me llevó a investigar si a priori el esfuerzo compensaría. Por ejemplo, siendo un lenguaje compilado me pregunté cómo sería su desempeño. Sin tener conocimientos aún suficientes para hacer comparaciones entre lenguajes busqué datos para compararlo en Benchmark Game. Concretamente:

Compararlo con otros lenguajes como Java, Python o erlang me parece injusto, porque no son lenguajes diseñados para lo mismo.

En cuanto a los resultados, como se puede apreciar Rust está codeándose con C y C++ en cuanto a resultados de velocidad. Por ese lado parece un lenguaje interesante si efectivamente alcanza esa velocidad siendo más seguro que C.

Quise probar algunos pequeños programillas, sólo por curiosidad e instalé primero, los paquetes de Rust que hay en OpenSuse, aunque en la documentación prefieren descargar (luego veremos ese método) los programas de su sitio web. De momento me centré en hacer unas pocas pruebas de compilación tomando tiempos con lo que tenía más a mano, cortando y pegando código encontrado en algunas páginas.

Después de esas pruebas, que ya habían aumentado mi curiosidad, también investigué la popularidad de Rust. Lo he encontrado en el puesto 26 en enero de 2021. Sí, sigue sin estar en la cúspide de la popularidad, pero tampoco está de los últimos. No es que me importe mucho la popularidad de un lenguaje cuando me planteo aprender uno. De hecho, como mis motivaciones no son curriculares o económicas, sino que sólo me muevo por la pura curiosidad, puedo elegir aquellos lenguajes que me resultan más llamativos o curiosos y así termino dedicándole horas a lenguajes como smalltalk, lisp, scheme, erlang... Todos lenguajes muy interesantes, pero poco populares o usados en proyectos.

Configurar el entorno de trabajo

El entorno de trabajo, como se puede imaginar cualquiera que haya leído un poco este blog, es Emacs. Pero vamos por partes.

Instalación de Rust

Como he dicho antes, en el manual de Rust realiza la instalación desde su sitio con un simple comando:

$  curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh

En realidad, yo lo he hecho en dos pasos, ─ya me perdonaréis si peco de prudente─, pero no me fío de ejecutar un script bajado de la Internet así como así. Primero lo descargué y después de estudiar el script lo ejecuté:

$ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf > sh.rustup.rs
$ bash sh.rustup.rs

El estudio del script, tampoco ha sido exhaustivo, al final lo que hace es descargar herramientas del sitio de Rust. Por lo menos comprobé que los enlaces son congruentes. Lo demás es confiar que esos ejecutables han sido compilados y se mantienen con las medidas de seguridad esperada. Al menos recomiendan forzar el uso de cifrado TLS en la conexión de descarga que la hace algo más segura. La confianza en este caso sería la misma que puedes depositar en los ejecutables que te bajas de cualquier repositorio de software libre.

Cuando ejecutas el script, aparece un menú preguntando el tipo de instalación con tres alternativas: instalación por defecto, avanzada o cancelar. Elegí la opción 1, la instalación por defecto. Después de unos momentos en que descargó los paquetes informó que la instalación ha tenido éxito. En la pantalla aparece un mensaje completo con información sobre el lugar donde se instala2. Hay que añadir ese directorio al $PATH. Una vez hecho basta comprobar si la instalación es correcta y funciona:

$ rustc --version
rustc 1.49.0 (e1884a8e3 2020-12-29)
$ cargo --version
cargo 1.49.0 (d00d64df9 2020-12-05)

Una vez instalado se puede actualizar la instalación con:

$ rustup update

o desinstalarlo con:

$ rustup uninstall

o llamar a la documentación con:

$ rustup doc

Como se puede apreciar un entorno completo.

Preparar el editor

Aquí llega el momento de instalar paquetes en Emacs y convertirlo en un auténtico IDE para Rust. No lo he probado mucho aún, pero lo que he visto me ha gustado. Los paquetes que he instalado son los siguientes:

  • rustic: proporciona el modo mayor de Emacs. Funciona sin lsp-mode pero si lo tienes instalado mejor.
  • flymake-rust: compilación sobre la marcha buscando errores y avisos que se pueden corregir antes de pedir la compilación.
  • ob-rust: para poder gestionar bloques de código Rust en org-mode.

La configuración que he puesto en mi init.el es muy sencilla. He añadido el paquete rustic al inicio:

(require 'rustic)

También, si usas lsp-mode hay que activar el hook para el lenguaje:

(add-hook 'rustic-mode-hook #'lsp)

Probando todo

Bueno pues vamos a por el Hola mundo correspondiente.

~ $ cd proyectos
~/proyectos $ mkdir hola-mundo
~/proyectos $ cd hola-mundo/
~/proyectos/hola-mundo $ emacs main.rs

en ese fichero el contenido será:

fn main() {
    println!("Hola, mundo!");
}

y compilamos

~/proyectos/hola-mundo $ rustc main.rs
~/proyectos/hola-mundo $ ./main
Hola, mundo!

y todo funciona perfectamente. Ahora a probar... ya iré contando cómo van las cosas.

Nota al pie de página:

1

Erlang Term Storage

2

Por defecto se instala en ~/.cargo/bin

-1:-- Rust por encima, comparando con erlang (Post )--L0--C0--January 06, 2021 09:32 AM

Notxor tiene un blog: Propósitos y despropósitos

Ya hice una declaración de intenciones para el año nuevo, y no utilizo el término propósitos en ese sentido en este artículo. Aunque este sea el primero del 2021, no va de eso. Hoy mi intención es hablar de otros temas, más relacionados con la ética, la informática y la toma de decisiones y también con las herramientas que utilizo. Quizá aclare algo o quizá lo enrede más, nunca es fácil expresar con palabras no sólo los pensamientos, ─lógicos o no─, sino también los sentimientos que llevan aparejados. Parece que cuando elegimos algo, aunque sea una herramienta informática, es como si eligieras bando en el Parlamento Español. Es este artículo intento explicar estas cosas con mi habitual torpeza.

Hay quien lee este blog no porque le interesen los temas de los que hablo, sino porque es un amigo, o incluso un familiar. Ha elegido un bando: el mío. Otros lo leen porque en algún momento buscaban algún tipo de información sobre alguna herramienta en concreto que por casualidad yo comenté y les apareció en la búsqueda que hicieron. El caso es que al final se está creando una pequeñísima comunidad alrededor de él en el grupo de Telegram y casi me asusta. Hay quien ha elegido mi bando. Asustar no es esa la palabra que estoy buscando, pero sorprender se queda corta con lo que quiero expresar. Al fin y al cabo, este blog tiene la intención de ser algo personal, en el que escribo cosas más para mí que para los demás y desde mi punto de vista, está más relacionado con mi individualidad que con un sentimiento colectivo o de conexión. Sin embargo, siempre es bienvenido saber que mis tontás no son exclusivas y le interesan a alguien más. El tema es que parece que los humanos estamos constantemente buscando bandos a los que entregar hasta la última gota de nuestra sangre.

Sobre el software libre

¿Cómo expresar lo que es para mí el SL sin hablar de ética? Porque no puedo hacerlo. Si me he decantado por él ha sido precisamente por algunos aspectos no técnicos, que también los tiene, sino por los aspectos éticos que el software privativo no tiene. Y también, porque como digo en la introducción, genera comunidad. No hay un proyecto interesante de software libre que no mueva a su alrededor una comunidad de usuarios interesados, se abra un foro donde consultar problemas y dudas y donde los propios usuarios se conviertan en el servicio técnico del mismo. Quiero llamar la atención sobre el hecho de que la mayoría de estos proyectos comienzan como algo personal, una necesidad individual de solucionar un problema que se pone a disposición de la comunidad.

Para mí es importante tener en cuenta esos matices porque el alma humana, si existe algo que podamos llamar así, tiene esas dos vertientes. Tenemos la necesidad de expresar nuestra individualidad en un entorno social seguro: somos animales sociales. Lo somos, pero no podemos forzar a la gente a ser comunitario hasta perder su individualidad, y tampoco podemos olvidar el componente social del individuo. Si quieres llevarlo a extremos sólo tienes que pensar en el comunismo y el liberalismo, de la comunidad extrema al individualismo extremo... ambos sistemas fracasados por menospreciar uno de esos componentes del ser humano1.

Como digo, el software libre consigue otorgarme libertades individuales2 a la vez que genera comunidad que aporta algo más: nuevas funcionalidades, código, documentación, apoyo. Luego mi elección no es una elección ciega: tiene un trasfondo ético que se deriva de mi visión particular del ser humano.

Sobre el número de usuarios y la calidad

El que utilice unas herramientas minoritarias para hacer mi trabajo, no debería necesitar mayor explicación. A estas alturas, no creo que la popularidad de un software sea un índice de calidad. Ese razonamiento nos puede llevar a conclusiones tan erradas como que el Seat Panda o el Opel Corsa son mejores coches que el Mercedes 500 SEL, se han vendido más de los primeros.

Hay quien me ha preguntado por qué, si Emacs es tan bueno, no tiene más usuarios con ánimo de echar avispillas, me temo. Si el párrafo anterior no le ha contestado, voy a decirte algunos motivos más que, creo, influyen en la elección de un software u otro.

Mucha gente no se calienta la cabeza con cosas como la ética, la comunidad, la calidad o cualquier otra disquisición paralela. Una herramienta es sólo una herramienta: si encienden el ordenador y arranca Windows no se preguntan más3. Cuentan con la ventaja de que todo en la industria informática está hecho para que así sea; lo utiliza todo el mundo y da la sensación que tienen respuesta ante cualquier problema porque hay una gran empresa detrás y muchos millones de usuarios. Una sensación falsa, porque que haya más usuarios no quiere decir que haya más gente inclinada a ayudar cuando se presentan los problemas y una empresa no ayuda sin un contrato previo que le garantice beneficios.

Oigo también algunas expresiones como no tiene nada que envidiar a... cuando hablamos de algún software libre comparándolo con alguno privativo. Lo cual siempre es un error de concepto y parece, que puesto que no hay grandes multinacionales detrás del software que usamos, hay un problema con su calidad. Si fuera así, GNU/Linux no sería el sistema operativo que mueve 500 de los 500 superordenadores más potentes del mundo. Para mover las mierdecillas que ponemos encima de la mesa para trabajar en casa, cualquier sistema operativo sirve.

Y puestos a comparar, me gustaría poder comparar la calidad de los documentos generados por un usuario medio de LaTeX con los generados por un usuario medio de Word. Sin entrar en más consideraciones esto nos lleva al siguiente apartado: el esfuerzo.

Sobre lo que sabemos y lo que creemos saber

En el software libre es condición necesaria, pero no suficiente, saber qué estás haciendo. Si no sabes el qué, no encontrarás el cómo. Y eso es un problema a la hora de elegir herramientas, porque saber el qué y el cómo implica que antes tienes que estudiar esos aspectos y luego aplicar lo aprendido. Esa es otra diferencia importante del software libre y el privativo. El primero parte de la idea de que el usuario es capaz y sabe lo que está haciendo; el otro utiliza la premisa de que el usuario es tonto, o no sabe nada de informática, y hay que darle las cosas mascadas.

Por otro lado, también conozco muchas personas, excelentes profesionales en otros campos, que creen que saben informática porque le dan a un botón, el ordenador arranca y son capaces de arrancar el programa que necesitan. Incluso, los más temerarios, saben instalar alguna aplicación, para lo que no suelen necesitar leer gordos manuales, ni tampoco los avisos que vayan apareciendo por pantalla. Y al final, estamos abocados a utilizar las herramientas pero nuestro trabajo no consiste en hacerlas. Cada uno aprenderá lo que necesite para hacer su trabajo y no tiene por qué aprender más.

Para la gente curiosa, como es mi caso, el tener que investigar cómo funciona algo o cómo se instala o, incluso, cómo se compila esa herramienta que quiero es una bendición. Pero no es una cuestión de curiosidad pura, también está relacionada con los gustos personales. Un psicólogo puede tener la curiosidad de ver cómo funciona eso de la informática y dedicarle tiempo libre, como una afición, tanto como a un informático pueden parecerle interesantes los procesos cognitivos humanos... o a un historiador las maquetas. Los conocimientos adquiridos y las lecciones aprendidas de forma amateur y autodidacta seguramente terminarán siendo usadas en el trabajo diario.

Pero los conocimientos obtenidos a la fuerza normalmente son desechados a la mínima oportunidad. No todo el mundo estamos dispuestos a gastar nuestro tiempo y nuestros esfuerzos en aprender a utilizar ésta herramienta o la otra. Nos conformamos con lo que viene dado y nos apañamos con el mínimo que nos permita seguir adelante. Por esto, muchos usuarios no quieren ni oír hablar del software libre, tienen la idea de que es complejo, difícil y elitista... y este pensamiento me lleva al siguiente punto del que quería hablar.

Sobre predicar y el elitismo

He tropezado con algunos usuarios que se creen mejores que otros porque utilizan ésta distro o la otra. Algunos, incluso con la pretendida superioridad de pensar que si utilizan tal o cual herramienta, que es dificilísima de configurar o de hacer funcionar, saben más o son mejores usuarios, ─o cualquier otro pensamiento clasista similar─. Otros, lo hacen desde la perspectiva de la superioridad moral, creyendo que utilizar sólo software libre les otorga algún tipo de bula o de una consideración ética superior.

También hay quien al poco tiempo de descubrir el maravilloso mundo del software libre se convierte en el pesao del linux. Sí, yo también he sido un pesao del linux. Es una fase por la que creo que pasamos todos los usuarios convencidos de las bondades, de la calidad, de la ética y la filosofía que hay detrás del software libre. Pero predicar a quien no quiere oír suele conseguir el efecto contrario. De momento, quédate con que basta con que te niegues a ser el servicio técnico gratuito de Micro$oft. Pero no hace falta que mires por encima del hombro a quien no quiere, no puede o no le gusta gastar tiempo en aprender cómo funcionan las herramientas que utiliza.

Por otro lado, hay veces que las distros 100% libres no funcionan. Lamentablemente, hay fabricantes que no publican las características de sus dispositivos como para que se hagan drivers libres. Si te pones límites en el software te encontrarás límites en el hardware, eso lo sabemos: nos lo encontramos casi a diario, y coincide con la filosofía de software-hardware de ápel. No es un demérito utilizar una distro que te facilite la vida reconociendo drivers no 100% libres: hay veces que no puedes elegir. Ni tampoco tiene una ventaja moral o ética, ni eres más inteligente, compilándolo todo. Recuerdo los tiempos cuando tenías que compilarte el kernel monolítico para que anduviera el sistema medianamente suelto. Afortunadamente esos tiempos han pasado y espero que no vuelvan porque era un coñazo. Como es un coñazo pasarte dos días compilando paquetes o arreglando configuraciones de algo que necesitaste utilizar ayer.

Sobre lo que uso

No, esto no es un discurso sobre las bondades de las herramientas que uso. Como he dicho antes no necesito que lo use mucha gente, ni que sea fácil de usar, pero sí me tiene que facilitar el trabajo.

Quizá decir que mi herramienta es Emacs no sea suficiente para expresar todo lo que extraigo de él. No es un editor, es un sistema lisp que sirve para editar archivos de texto. Es el ejemplo de cómo ha ido cambiando mi percepción del software libre con el tiempo. Yo también fui defensor de vim y sigo utilizándolo. Pero han tenido que darse una serie de circunstancias para que fuera migrando de una cosa a la otra hasta alcanzar el momento actual.

En mi trabajo como psicólogo necesito generar documentos de texto, realizar algún que otro cálculo y organizar información de alguna manera más o menos estructurada. Además, doy algunas charlas y tengo que hacer presentaciones. El camino fácil habría sido utilizar un software de oficina, libre como LibreOffice o privativo como la suite de micro$oft. La mayoría de los psicólogos, y otros profesionales, no necesitan más.

Por otro lado, escarmenté hace tiempo de los formatos de ficheros cerrados y poco a poco fui migrando, cada vez más, hacia el formato de texto plano para todo. LaTeX ya era una de las herramientas que utilizaba antes de descubrir Emacs en toda su plenitud. Bueno, descubrir no es el término exacto, ya lo conocía, pero no lo usaba. Era un usuario cómodo y utilizaba un editor de texto muy bueno, por cierto: vim, que estaba instalado en la máquina. No tenía que instalar nada. ¿Cuál fue la inflexión? Descubrir org-mode.

Había oído muchas veces hablar de las bondades de org-mode pero siempre daba un poco de pereza utilizarlo: instalar Emacs, leer documentación en perfecto inglés, etc. Nada te garantiza que hacer todo ese esfuerzo se verá recompensado y ese es el principal problema para la popularización de cualquier herramienta. Sin embargo, un día me puse a ello, por curiosidad. Apareció ante mis ojos la respuesta a todos aquellos aspectos que me faltaban por textualizar. Por fin, todo en texto plano. Además, todo en un mismo entorno sin necesidad de cambiar de aplicación para cada una de las cosas que necesito hacer. Por contra debía repasarme el lisp y lo tenía muy olvidado.

¿Recomiendo eso a todo el mundo? Pues no. Las herramientas que uso no son para toda la gente. Pero no penséis que es porque yo sea más listo o cualquier otra consideración elitista. No es para todo el mundo porque tiene unas desventajas también apreciables: algunas veces es necesario picar algo de código en lisp para adecuar el chismático o para hacerme una funcionalidad nueva. Eso no es un uso para un usuario medio... y eso no me hace ser mejor, cualquiera puede llegar a alcanzar el nivel de usuario avanzado incluso en la mitad de tiempo en que lo he hecho yo. Pero te tiene que gustar trastear, ver cómo funciona, saber algo de programación y que te resulte todo eso entretenido.

Sobre las guerras de software

Es muy cansino asistir a guerras de usuarios de las distintas herramientas, distros, editores siempre con la misma cantinela. No es la primera vez que escribo por aquí que cada uno tiene el sistema operativo que se merece, algo que es muy cierto. Si te lo trabajas un poco tienes un buen sistema a tu alcance, si no estás dispuesto a gastar tiempo en ello tendrás que conformarte con que las decisiones las tomen otros. Al final alguien tiene que hacerse cargo de definir qué debe hacerse, lo puedes decidir tú o lo puede decidir un equipo de expertos y dártelo hecho. Lo primero necesita que investigues, aprendas y manejes con soltura las herramientas que uses, lo segundo conformarte con las herramientas que hagan otros.

Las estériles discusiones de si es mejor tal o cual distro, o si vim o Emacs, o que si es mejor usar un cacharrímetro o un cacharrógrafo no llevan a ningún sitio. La balanza se inclinará hacia un lado o hacia otro según el punto de vista en el que pongas el interés. No voy a entrar en esas guerras, que me parecen un poco pérdida de tiempo, más allá de reírte con los piques y los memes que generan. No necesito convencer a nadie de que use lo mismo que yo, porque no es un esto es así y ya está. Cada uno tenemos nuestras cadaunadas.

Sobre la privacidad, la estadística y la automatización

El problema de la privacidad es otra de las religiones para tecnólogos, o más bien tecnópatas. La idea de que nos están monitorizando de forma constante y que no podemos evadirnos de ese seguimiento aparece cada vez más a nuestro alrededor.

A este respecto, como ocurre con el software libre el salir, o intentar salir, de lo establecido implica también cierta estigmatización: pedir no figurar en un registro o según qué comportamientos, te convierten directamente en el paranoico.

Y sí, la mayoría de la población no está preocupada por el abuso que pueden realizar ciertas compañías con nuestros datos. Hay quien hasta contraargumenta a favor del progreso, la inteligencia artificial y el que no tiene nada que ocultar. Está claro que el progreso no lo podemos detener, pero permitid que haga algunas consideraciones. Por ejemplo, en el futuro la mayor parte del trabajo lo realizarán robots.

Lo mismo ocurre con la inteligencia artificial. Muchas decisiones se están delegando ya a ese tipo de software. Y somos conscientes de que existen problemas de base con ese tipo de programas:

  1. Las inteligencias artificiales sólo reconocen los patrones que tienen como entrada. Si los datos que le pasamos están sesgados, sus resultados serán sesgados.
  2. Al delegar la responsabilidad en «la máquina» pensamos que el resultado del cálculo no puede ser clasista aunque, como hemos visto en el punto uno, sí puede serlo. El que el banco no te conceda el crédito no tiene que ver con que vivas en un determinado barrio o seas de determinada condición social, raza, sexo u otras variables sociales; no te lo da porque lo dice el sistema de inteligencia artificial; y ahora dime ¿con qué variables han realizado el entrenamiento de dicha inteligencia?
  3. Los mecanismos de entrenamiento que se utilizan en la inteligencia artificial sólo tienen en cuenta el valor del acierto y se suelen desprecian los falsos positivos.

Para entender lo que implican los falsos positivos contra los falsos negativos voy a poner un ejemplo deportivo. Si estuviéramos entrenando una inteligencia artificial para seleccionar jugadores de fútbol para el Barça4, podemos imaginar que el sistema nos recomienda fichar a Antoine Greizmann y echar a Luís Suárez. El objetivo es optimizar el resultado goleador de los delanteros del equipo. Tras analizar los resultados obtenidos, nuestra inteligencia artificial sabe que el resultado no ha mejorado por la ficha de Greizmann, así que ajustará sus pesos o valores para seguir aprendiendo. Sin embargo, a Suárez no lo tiene ya en el sistema, los resultados obtenidos nada tienen que ver con él y por tanto, no ajustará sus niveles para poder afinar su capacidad de predicción. Viendo los goles que Suárez ha marcado en el Atlético de Madrid en lo que va de liga, le podríamos advertir a nuestra inteligencia que los tenga en cuenta y de esta forma tendríamos un sistema de IA que tiene en cuenta tanto los falsos positivos como los falsos negativos. Este sería el funcionamiento ideal de toda IA.

Sin embargo, en un banco, si no te dan el crédito porque la IA dice que hay peligro de que no lo devuelvas, no comprobarán si luego pagas a la entidad que sí te lo concedió. Lo malo de todo esto es que, como seguramente se reducirán los falsos negativos, se producirá una mejora en recuperación de fondos suficiente para que los responsables no se preocupen de los falsos negativos, por qué iban a hacerlo si han mejorado los beneficios. Además si esos falsos negativos recaen en colectivos desfavorecidos, o sobre determinados grupos étnicos o raciales, no se podrá achacar al banco racismo o clasismo: lo dice la IA, que siendo un programa informático no puede ser ni una cosa ni otra, por lo que se convertirá en un factor que perpetuará la desigualdad.

No quiero que nada mío, mis datos, mis acciones, mis fotos o lo que sea que esté relacionado conmigo se utilice para entrenar inteligencias artificiales o para extraer información sobre mí, que será sancionada como buena y cierta sin ninguna posibilidad de comprobación posterior. Ni siquiera mis opiniones, porque tengo derecho a equivocarme y a cambiar de opinión si así lo considero.

Conclusiones

Quien ha intentado mandarme avispillas, ya sabe que uso Emacs habiendo sido y siendo usuario de vim, sé cuáles son las ventajas y los inconvenientes de ambos y utilizo los dos. Uso más Emacs que vim, pero uso los dos. Depende de para qué.

Algunos recién llegados al software libre vienen cometiendo los mismos errores que cometí yo cuando empecé con GNU/Linux allá por 1998-1999. A éstos les digo que la arrogancia no es ninguna característica deseable que venga con el software, es una condición humana, ni mejora ni populariza la herramienta. Recuerda siempre que el ego es directamente proporcional a la hostia que te mereces5.

Nota al pie de página:

1

Los liberales aún no se han dado cuenta, pero el neoliberalismo ha fracasado.

2

Las cuatro: libertad para usarlo, libertad para estudiarlo, libertad para modificarlo y también para distribuirlo.

3

Y no tienen por qué hacerlo.

4

Por poner un ejemplo.

5

Algunos comentarios que he leído por las redes sociales se merecen un poco de «hostioporosis»: la terapia alternativa que consiste en la imposición de mano abierta a gran velocidad.

-1:-- Propósitos y despropósitos (Post )--L0--C0--January 02, 2021 08:29 AM

Notxor tiene un blog: lisp, slime y emacs

Este es otro artículo que intenta responder preguntas que me hace la gente. Concretamente hay alguien que me ha preguntado cómo tengo configurado mi entorno de trabajo para trabajar con lisp. Dicho así en genérico sin especificar ninguno de sus sabores. Por las dudas que me planteado, tampoco tiene muy claro si tirar por lisp o seguir por scheme, y para eso yo no tengo respuesta, porque depende de los gustos de cada quien. Él ya ha estado mirando algo de scheme, aunque se declara novato, pero le interesa también saber algo más sobre lisp para comparar y decidir. Intentaré contestar lo mejor que pueda.

Lisp

Lisp no es un único lenguaje o compilador. Ya hay toda una familia de lenguajes como son scheme, clojure, lisp... Además de estos grandes grupos con distintas características, cada uno tiene distintos compiladores o sistemas. Entre los scheme podemos encontrar guile o chicken, por ejemplo, entre los lisp tienes para elegir varios common-lisp, emacs-lisp y otros. Además, entre los common-lisp hay varios sistemas distintos. Puedes leer sus licencias y/o sus características y elegir el que más rabia te dé. Pero como también me preguntas cuál uso yo, pues te lo simplifico: yo utilizo SBCL1.

Las diferencias fundamentales entre scheme y lisp son que scheme sólo tiene una tabla de asignación, y por tanto no puedes llamar de la misma manera a una variable y a una función, y que es case sensitive mientras que lisp no diferencia entre mayúsculas y minúsculas. En cambio, tiene dos tablas de asignación y por tanto, tienes que emplear las instrucciones defvar y defun, para definir variables y funciones. Pero ambos son muy similares y el problema de los paréntesis lo tienes en ambos, pero sólo hasta que te acostumbras a esa sintaxis, con el tiempo casi ni te fijas en ellos.

En mi caso, la instalación de sbcl no tiene ningún misterio. En OpenSuse hay un paquete con dicho nombre y se instala como cualquier paquete de la distro. Según qué sistema o distro uses, seguro que hay algún paquete que te facilite la vida. En mi caso:

sudo zypper install sbcl

En el caso de las derivadas de Debian supongo que la instrucción será alto estilo apt-get install sbcl. Comprueba el nombre del paquete en cuestión.

Libros

Para la documentación que pides te recomiendo dos libros que puedes encontrar por Internet:

Además, si instalas sbcl, al menos en OpenSuse, viene con un manual info que se integra perfectamente con el sistema de ayuda de Emacs, así que allí puedes encontrar también más información sobre cómo funciona sbcl de la que puedo dar yo en un pequeño artículo.

Librerías de quicklisp

Si ya estás trabajando con Emacs, ya conocerás su sistema de paquetes y lo tendrás configurado. Para lisp existe algo similar que se llama quicklisp. Si ya tienes instalado sbcl en el sistema, lo único que tienes que hacer es lo siguiente:

curl -O https://beta.quicklisp.org/quicklisp.lisp
sbcl --load quicklisp.lisp --eval '(quicklisp-quickstart:install)' --quit
sbcl --load ~/quicklisp/setup.lisp --eval '(ql:add-to-init-file)' --quit

La primera línea obtiene el código de quicklisp.lisp de su sitio de Internet. La segunda línea obtiene los paquetes e información que necesita y lo guarda en el directorio ~/quicklisp. Por último, la tercera línea ejecuta el código de configuración para añadirse al fichero ~/.sbclrc.

Esto es totalmente optativo, pero si vas a desarrollar con lisp te puede facilitar un poco la vida, ya decides tú si quieres instalarlo o no. Como digo para empezar no es necesario, pero más adelante es posible que lo eches en falta.

Slime y otros paquetes de Emacs

SLIME2 es una herramienta de Emacs que facilita la vida a los programadores de lisp. Instalarlo es tan fácil como cualquier otro paquete de nuestro editor favorito:

package-install RET slime

Una vez que lo tenemos instalado en nuestro Emacs, tenemos que configurarlo. Es algo sencillo, pues sólo necesita que añadamos una línea en nuestro init.el que le informe qué lisp tiene que correr:

(setq inferior-lisp-program "/usr/bin/sbcl")

Comprueba que en tu caso el path coincide antes de hacer el corta-pega.

Si lo hemos instalado y configurado, podremos utilizarlo directamente si cargamos de nuevo el fichero de configuración con load-file o bien tras reiniciar Emacs. El paquete proporciona un entorno interactivo de lisp y funciones que cargan a dicho entrono con el código que vayamos escribiendo. Nos permite trazar y depurar código, etc.

El paquete paredit

Dices que, en scheme, te atascas con tanto paréntesis y pierdes la cuenta de los que abres y los que debes cerrar. Lo siento, pero en lisp no notarás demasiada mejora, pero no desesperes en ninguno de los dos casos. La solución más rápida y relajada es que actives show-paren-mode, bien en el apartado custom de tu init.el o que en cualquier sitio de ese fichero de configuración tengas algo como:

(setq show-paren-mode t)

Esa opción lo que hace es mostrar el paréntesis pareja del paréntesis sobre el que está situado el cursor. Bueno, no sobre el que está situado, eso es así cuando te sitúas en el de apertura. Para ver el que corresponde a uno de cierre tienes que situarte justo un carácter a la derecha... pero vamos, esto es más fácil de entender viéndolo que de explicarlo así con palabras: activa el modo y observa cómo se comporta. Si no quieres tenerlo activado de manera constante, también lo puedes activar con algún hook para los modos que quieras, o llamando a show-paren-mode cuando lo quieras activar.

Por otro lado, hay otros paquetes que te pueden echar una mano. Por ejemplo, también uso el paquete paredit. Lo que hace este paquete es que te escribe directamente la pareja de cierre de todo paréntesis o corchete que abras. Hay a quien le puede molestar este comportamiento, pero a lo mejor te facilita la vida. En todo caso, es recomendable activarlo sólo cuando programes, principalmente con lisp, scheme o lenguajes similares, aunque nada te impide usarlo siempre. Lo puedes activar mediante hooks:

(add-hook 'emacs-lisp-mode-hook 'enable-paredit-mode)
(add-hook 'lisp-mode-hook 'enable-paredit-mode)

Recuerda poner el hook para cada uno de los modos, porque la de lisp-mode-hook no incluye a emacs-lisp-mode-hook. Son listas y modos independientes y, por tanto, tienes que activar el modo en los dos. Otra opción sería que se activara en prog-mode-hook y así se cargaría en todos los modos de programación, que es otra opción aceptable.

Echa un ojo a la lista de paquetes que hay disponibles porque hay muchos que sirven para destacar los pares de paréntesis. Algunos los colorean, otros los hacen parpadear... en fin, hay muchos paquetes que te pueden ser útiles, elige el que más te guste.

Usando slime

Bien, ya tienes todo instalado y tienes ganas de probarlo escribiendo un poco de código. Pues vamos a ello... prometo ser original con los ejemplos:

  1. Abre Emacs y crea un buffer para los ejemplos:

    C-x C-f ejemplos.lisp
    
  2. Escribe el código del primer ejemplo3:

    (defun hola-mundo ()
      "Escribe un mensaje de «¡Hola Mundo!»"
      (format t "¡Hola mundo!"))
    
  3. Lanza slime con el comando:

    M-x slime
    

    Si tenemos todo bien configurado, debería aparecer un buffer con nombre *slime-repl sbcl* con un mensaje de prompt tal que CL-USER>. Si intentas ejecutar ahí (hola-mundo) te lanzará un error. Vuelve al buffer donde está el código, no te precipites. Primero tienes que cargarle el código que has escrito.

  4. Evaluamos el código: slime tiene varias funciones de evaluación de código, en nuestro caso vamos utilizar M-x slime-eval-buffer, pero también se puede hacer para una función o para una región de texto seleccionado.
  5. Vuelve al buffer de slime y prueba a ejecutar (hola-mundo)

    CL-USER> (hola-mundo)
    ¡Hola mundo!
    NIL
    CL-USER> _
    

Bien ya tienes el sistema funcionando... Ahora a escribir código.

Bueno, vale, lo mismo quieres algún ejemplo más antes de lanzarte tú solo a la aventura. Prueba con el siguiente:

(defun factorial (n)
  "Calcula el factorial del número n."
  (if (= n 0)
      1
      (* n (factorial (- n 1)))))

Vale, ya sé que no estoy siendo muy original con los ejemplos, pero tampoco te pongas muy estupendo, que sólo intento explicarte las herramientas, la programación ya la tienes que poner tú. Bien, al caso. Si has evaluado esta función cargando el buffer completo con slime-eval-buffer, como hicimos antes, es posible (seguro) que te diga que ya existía una función hola-mundo y te lance un warning. En ese caso, lo puedes ignorar, porque estamos trabajando en el mismo código. Si aún no lo has cargado y quieres evitar el warning sitúa el cursor en cualquier línea de la definición de la función y utiliza el comando M-x slime-eval-defun. Como ves, era sólo por mostrar otra función que carga código. A partir de ese momento, ya estará la función factorial también disponible en slime:

CL-USER> (factorial 6)
720
CL-USER> _

Por darle otra vuelta, prueba a hacer un trazado de la función factorial, por ejemplo:

CL-USER> (trace factorial)
(FACTORIAL)
CL-USER> (factorial 5)
  0: (FACTORIAL 5)
    1: (FACTORIAL 4)
      2: (FACTORIAL 3)
        3: (FACTORIAL 2)
          4: (FACTORIAL 1)
            5: (FACTORIAL 0)
            5: FACTORIAL returned 1
          4: FACTORIAL returned 1
        3: FACTORIAL returned 2
      2: FACTORIAL returned 6
    1: FACTORIAL returned 24
  0: FACTORIAL returned 120
120
CL-USER>

Queda bonito ver cómo se desarrolla ─y desenrrolla─ la llamada a una función recursiva y lo que va devolviendo.

Paquetes externos

Si antes de llegar hasta aquí hiciste la instalación de quicklisp y quieres probar cómo va esto de los paquetes externos. Vamos con un ejemplo básico también para que puedas comprobar cómo funcionan. Por ejemplo, hunchentoot es un servidor web hecho enteramente con lisp y queremos ponerlo en marcha en nuestro sistema. Vamos por pasos:

  1. Crea un buffer nuevo con C-x C-f servidor.lisp
  2. En ese buffer teclea el siguiente código:

    (ql:quickload "hunchentoot")
    (hunchentoot:start (make-instance 'hunchentoot:easy-acceptor :port 6969))
    
  3. Evalúa el código anterior con slime. Después de unos segundos bajando y preparando paquetes aparecerá el mensaje de que el servidor está funcionando:

    To load "hunchentoot":
      Load 1 ASDF system:
        hunchentoot
    ; Loading "hunchentoot"
    .....
    

Si apuntamos cualquier navegador a la dirección localhost:6969 obtendremos una ventana como la siguiente:

Captura-pantalla_servidor-lisp.png

Y ya vemos cómo de fácil es obtener todo un servidor

Conclusiones

Estas herramientas están hechas para funcionar conjuntamente, puedes ponerle más cosas: configurarle el modo lsp, o lo que más rabia te dé, pero esto es lo básico, básico, y un poco más que aporta quicklisp.

Si has utilizado Emacs para trastear con scheme verás que slime es a lisp lo que geiser es a scheme. No se trabaja de forma idéntica en ambos, pero sí muy similar.

Nota al pie de página:

1

Steel Bank Common Lisp http://www.sbcl.org

2

Superior Lisp Interaction Mode for Emacs

3

No esperabas tanta originalidad, seguro.

-1:-- lisp, slime y emacs (Post )--L0--C0--December 23, 2020 12:00 AM

Notxor tiene un blog: Krei epub arĥivon

Mi hodiaŭ parolos pri la transformadon de dosiero pdf al dosiero epub por pli bone legi esperante. Mi montros ilon, kiun mi faris, kaj klarigos kiel ĝi funkcias por faciligi, ke iu ajn povos adapti ĝin por si mem. Ni uzos Emacs kaj elisp por kontroli tiun OCR procezon, kiun ni bezonas por tiuj dosieroj, kiuj enhavas bildajn skanadojn de teksto. La celo estas konverti nian pdf dosieron farita de skanitaj bildoj al epub dosieron por pli bone legi en nia inklibro aŭ tabuleto. Mi laboras per Linukso sed la rezulto estas sendependa de la operaciumo kiun ni uzas. Mi iomete parolos pri kiuj programoj mi uzas por tiuj laboroj.

Mi proponis multe pli legi por praktiki Esperanton sed ne ĉiam oni trovas interesan kaj oportunan legadon. Mi parolas precipe pri oportuna. Rete oni trovas multajn dosierojn, kutime je pdf por praktiki la legadon esperante. Kiam la pdf dosieron enhavas veran tekston estas pli facila konverti la dosieron. Eble nur devas transdoni al teksto kaj poste al html, epub aŭ alia ajn speco de dosiero ke ni bezonas.

Ni havas:

Captura-pantalla_pdf.png

sed ni volas:

Captura-pantalla_epub.png

por povi legi tiel:

Foto_lector.jpg

Do, ni bezonas kelkajn ilojn por fari nian laboron:

  1. Konvertilo por bildformato: ni uzos la ilon pdfimages kiu prenas la paĝojn de la pdf kaj skribas en sendependaj bildoj.
  2. OCR ilo: ni uzos tesseract-ocr, kiu permesas traduki per multaj lingvoj, inter ili Esperanto.
  3. Emacs por uzi ĝian skriptan lingvaĵon.

Ankaŭ ni povas fari la laboron sen Emacs nur per bash, sed finfine ni bezonos ajnan skriptan lingvaĵon. Kial mi uzas elisp? Ĉar tiu ilo estas taŭga por labori kun tekstojn kaj havas tre potenca ilo por labori kun dokumentoj: org-mode.

Aliflanke ni devas ankaŭ preni la enajn bildojn por la lasta paŝo de nia procezo.

Konverti dosieron

Mi klarigos kiel mi faras por konverti pezan pdf, farita de skanitaj bildoj, ĝis atingi sufiĉan bonan epub por legi per mia bitlibro. Tiu legado estas pli agrabla ol legi la originan pdf per tiu ilo. La teksto aranĝas al ekrano kaj faciligas bonan sperton de legado.

Ni povas fari la laboron mane:

  1. Preni la bildon de la pdf dosiero:

    pdfimages -png -f 1 -l 10 dosiero.pdf paĝo
    

    Tiu kreas bildoj de la paĝo-001.png al paĝo-010.png.

  2. Konverti la bildoj en teksto:

    tesseract -l epo paĝo-001.png paĝo-001
    

    Tiu metas la teksto legita de la bildo paĝo-001.png en paĝo-001.txt. La formo -l epo por Esperanto. Vi povas scii la lingvojn kiu komprenas tesseract per la komando tesseract --listlangs.

  3. Aranĝi ĉiu la dosieroj txt en unu sola dosiero. Pro tiu ni povas uzi teksredaktilon.

Tio estas teda, paĝo al paĝo kaj ankaŭ ni povas enmeti erarojn, ripeti ajnan paĝon, forgesi alian, ktp. Ankaŭ, finfine ni devas pritrakti la tekston per teksredaktilo... do, kial ni ne uzas teksredaktilon kiu havas skriptan lingvon por aŭtomatigi la taskon. Mi uzas Emacs.

Kodo

Mi skribis la sekvantan kodon por aŭtomatigi la proceson en komandara dosiero nomita konverti-ocr.el:

;;; konverti-ocr.el

;; La variabloj de la procezo.

(defvar dosiero ""
  "Variablo kiu enhavas la nomon de la dosiero por konverti.")
(defvar komenco 0
  "Paĝa numero kie komencas la procezon.")
(defvar fino 0
  "Paĝa numero kie finas la procezon.")
(defvar lingvo ""
  "Lingvo de la listo `tesseract --listlangs`")

(defun komencu ()
  "Sarĝu la variabloj por la procezo."
  (setq dosiero (org-entry-get (point) "dosiero"))
  (setq komenco (string-to-number (org-entry-get (point) "de")))
  (setq fino    (string-to-number (org-entry-get (point) "gxis")))
  (setq lingvo  (org-entry-get (point) "lingvo")))

(defun pritrakti-paĝo (num)
  "Enmeti la tekston kreata en la /punkto/."
  (message "Konverti paĝon %s" num)
  ;; Habigi la bildon
  (call-process-shell-command (format "pdfimages -png -f %d -l %d %s paĝo" num num dosiero))
  ;; Habigi la tekston
  (call-process-shell-command (format "tesseract -l %s paĝo-000.png temporal" lingvo))
  ;; Enmeti la tekston en la /punkto/
  (insert-file-contents "temporal.txt")
  ;; Forigi la temapajn dosierojn
  (shell-command "rm paĝo-000.png temporal.txt"))

(defun pritrakti-ocr ()
  "Lanĉas la taskon por konverti bildan pdf al teksto."
  (interactive)
  (komencu)       ; Establece las variables globales
  (mapc 'pritrakti-paĝo (number-sequence fino komenco -1)))

Mi preparas la dosieron kie ni enmetos la tekston de la konvertado:

* Prologo
  :PROPERTIES:
  :de:       20
  :gxis:     34
  :dosiero:  ./la-mastro-de-la-ringoj.pdf
  :lingvo:   epo
  :END:

Ni devas rimarki ke en la PROPERTIES difinoj ne povas uzi ĉapelitajn literiojn.

Por fari tion, ni devas unue voki nian kodon per load-file konveri-ocr.el. Ĉi tiu komando en Emacs legas la kodon kaj poste ni povos uzi la komandon M-x pritrakti-ocr. Nian kodon komencos leganta de la paĝo 34 ĝis la 20. Tiel ĝi faras por korekte ordigi la paĝon en la dosieron.

La rezulton estas:

Captura-pantalla_konvertado.png

Kiel ni povas vidi, la rezulto estas sufiĉe bona por komenci labori. Ni devas forigi la paĝan numeron inter la teksto, korekti erarajn literojn. Tiu estas la plej teda tasko por konverti librojn. Sed Emacs helpas min ĉar oni povas uzi aŭtokorektadon de teksto por Esperanto. Sed la laboro de purigo neniam finiĝas, kiel ni vidos je la fino.

Kiam la teksto estas sufiĉe purigita (aŭ mi pensas tion) mi konvertas la dosieron, en nia ekzemplo nomita probo-dosieron.org al html aranĝo. Emacs faciligas tiun taskon: mi nur devas uzi la komandon C-c C-e h h kaj ĝi kreos la dosieron probo-dosieon.html. Poste, tiuj html dosieroj poste estos aranĝitaj en la epub dosiero.

Preti fontojn

Captura-pantalla_font-forge.png

Eble, mi povus legi la tekston sen plia laboro, sed mi estas sibarita leganto kaj ne nur volas, sed bezonas, belajn librojn. Do mi devas pli labori por fari ilin.

La tutaj ekzemploj de ĉi tiu artikolo estas prenataj de mia laboro por aranĝi la mastro de la ringoj kiel epub dosiero por plezure legi per mia bitlibro. Por tiu projekto mi serĉis literojn ĉe https://www.dafont.com tiujn tiparojn, kiuj povas taŭgi en ĝi. Sed la tiparo kiu ŝatas al mi ne havas ĉapelitajn literojn kaj tiuj kiuj havas ĉapelitaj literojn ne taŭgas al projekto.

Do, mi elektis miajn plej ŝatatajn literojn kaj uzis fontforge por fari en ĝi la literojn mankantaj. Ne estas komplika afero, mi nur kopiis literojn kaj signojn kiuj jam ekzistas en la fonto por aranĝi la ĉapelitaj. Tiel ni povas krei paĝojn, titolojn kaj tekstojn per ili.

Captura-pantalla_titulo-parte.png

Captura-pantalla_titulo-libro.png

Captura-pantalla_literoj.png

Por tiuj paĝoj estas pli grava nia laboro per css kaj html ol per la fontoj. Pro tio ni atingas la lastan laboron por krei nian bitlibron.

Aranĝi dosieron

Captura-pantalla_sigil.png

Per la pasintaj laboroj ni kreis html dosierojn, pretis bildojn kaj fontojn, kaj nun ni devas aranĝi la epub dosieron. Pro tiu laboro mi uzas la programon sigil, kiel oni povas vidi en la antaŭa bildo.

Antaŭ, kiam ni konvertis la bildojn al tekstoj, ni kreis la diversajn dosierojn html. Nun ni devas porti ene ĉi tiujn dosierojn al epub. Por ordigi la diversajn partojn de la libro ni havas la listo kiu ni povas vidi maldekstre en la bildo. Movi la dosieron supren aŭ suben estas tiel simple kiel treni la etikedon per la muso.

Fine, ni devas krei la metadatumojn, minimune la aŭtoro kaj la titolo sed estas grava kompletigi tiun informon tiom, kiom ni povos. Ankaŭ ni bezonos tabelenhavon, kaj sigil havas ilon por krei tiun tabelon.

La lasta tasko estas malrapide legi kaj repurigi la erarojn. Vortoj kiuj aperas kunigitaj aŭ tiu, kiu aperas apartigita. Erarojn, misaj literoj, strangaj signoj kiujn ni ne vidis antaŭe, ktp.

Konkludo

Finfine, mi havas mian dosieron enmetita en mia bitlibro. Mi nun komencas la legado, la lasta legado kaj mi registros la erarojn kiujn mi trovos. Poste mi plibonigos la eldonon kaj mi gardos ĝin por plezure legi kiam mi volos.

-1:-- Krei epub arĥivon (Post )--L0--C0--December 13, 2020 09:34 AM

MGallego: Comprobado de Faltas de Ortografía en Emacs

your_img

Ahora que estoy con una instalación limpia de Ubuntu/Debian y estoy volviendo a escribir un poco en el blog para documentar lo que voy haciendo tengo que configurar el flyspell para que me compruebe según voy escribiendo, para que no se me escape ninguna falta de ortografía.

Para ejecutarlo es tan sencillo como dentro del buffer que queraos comprobar lanzar el comando con M-x flyspell-mode el problema que me encuentro es que no tengo el diccionario es_ES instalado, así que vamos a ver como lo instalamos en Ubuntu/Debian

El error que nos da es el siguiente: Error enabling Flyspell mode: (Error: No word lists can be found for the language "es_ES".)

Lo único que tenemos que haces es instalar el paquete de lenguaje de aspell en el sistema, en mi caso con sudo apt install aspell-es y volver a cargar el modo flyspell. Con esto emacs ya comenzará a marcarnos los errores en nuestro texto con un subrayado en rojo.

-1:-- Comprobado de Faltas de Ortografía en Emacs (Post )--L0--C0--December 07, 2020 11:01 AM

MGallego: Mostrar Informacion con LSP UI en Emacs - Sideline

your_img

lsp-ui es un paquete que nos ayuda mostrando información útil sobre el servidor de lenguaje en nuestra interfaz. Voy a ver como configurarlo un poco para ver que utilidad nos puede dar.

En los ejemplos veremos imágenes del servidor de lenguaje de Scala que es lo que estoy configurando ahora mismo.

¿Qué es LSP?

LSP es un protocolo que sirve para comunicar servidores de lenguaje con editores, lo cual nos da en los editores las mismas o similares funcionalidades que ya existían en los IDEs, como por ejemplo navegación entre código, resaltado de sintaxis, comprobación de errores en tiempo real, refactorización …

Antiguamente para poder tener estas características teníamos que tener un modo (plugin) para cada uno de los lenguajes que usásemos, con su configuración, atajos de teclado, etc. Con este cambio solo necesitamos tener el modo LSP que se conectará al servidor de lenguaje que corresponda y tendremos todas las funcionalidades que nos de ese servidor, que por cierto, ese servidor será común entre todos los editores que soportan LSP.

Como no es el tema que quiero tratar en este post no voy a entrar mas en detalle, solo añado que LSP es lo mejor que le ha pasado a Emacs en los últimos años y diría que se podría decir lo mismo para otros editores como Vim

Aquí dejo un par de enlaces con mas información, uno de la Wikipedia y otro de la página de Microsoft.

¿Qué es lsp-ui?

lsp-ui es un modo de emacs que nos crea una interfaz, una UI (User Interface) por encima de LSP, dándonos información en tiempo real del código en el que nos encontramos, como firmas de funciones, acciones que podemos realizar sobre el cursor y documentación relacionada.

Esto es mas o menos lo que estamos acostumbrados a ver en los IDEs mas comunes y ahora lo tenemos en emacs con una configuración mínima.

Instalación

Para la instalación lo mejor es ir a la web del proyecto, apenas son 2 líneas, pero estará mas actualizado que este post.

Configuración

Para ir viendo los ejemplos no los voy a meter en mi fichero de configuración, lo que voy a hacer es ir evaluándolos con M-: para ir viendo en tiempo real como funciona y si merece la pena añadirlo a posteriori en mi fichero de configuración.

Toda la configuración está en la web oficial, pero como quiero probarlo yo mismo aprovecho y lo documento.

lsp-ui-sideline

El sideline es la información que se va a mostrar al final de la propia linea en la que estamos trabajando, por defecto cuando programo con PHP lo tengo desconectado porque me resulta un poco incómodo, sobre todo porque aparece demasiado a la derecha, pero en Scala con el tema del tipado creo que mas que útil va a acabar siendo necesario, así que vamos a ver que ofrece y como activarlo o desactivarlo

Para que todo funcione tenemos que tener el modo lsp-ui-sideline activado para ello ejecutamos M-x lsp-ui-sideline-mode

Apunte rápido

Todo lo que voy a ir metiendo son funciones en lisp para setear variables, con algo así como (setq variable valor) este valor puede ser t para true, activar, y nil, nulo, para desactivar. Como ya he dicho antes las voy a evaluar en mi caso directamente en el buffer de scala, si las queréis dejar activas para todos los buffer de Scala tendréis que añadirlo a la configuración de lsp-ui

  • lsp-ui-sideline-show-diagnostics: Nos sirve para mostrar un diagnostico en tiempo real en el caso de que haya fallado algo (setq lsp-ui-sideline-show-diagnostics t)

Este puede ser muy útil y lo voy a activar en mi modo lsp-ui

  • lsp-ui-sideline-show-hover: Muestra información sobre el objeto o la línea en el que se encuentre el cursor, esto es configurable.

También útil, por ahora lo meteré en mi configuración.

  • lsp-ui-sideline-show-code-actions: Muestra las acciones que podemos ejecutar en la posición actual del cursor. (setq lsp-ui-sideline-show-code-actions t)

Este también lo configuraré por defecto.

Hay mas opciones que no voy a cambiar, dejaré las que vienen por defecto, como el delay para que pinte la información o la forma de pintarla. Para mas opciones lo mejor es la leer la documentación oficial.

Y así es como quiero dejarlo:

Apunte rápido

Como podéis ver no he tocado nada de scala, ni modos ni nada, así que este paquete y su configuración nos valdría para cualquier lenguaje que tengamos con su servidor de lenguaje correspondiente.

-1:-- Mostrar Informacion con LSP UI en Emacs - Sideline (Post )--L0--C0--December 07, 2020 10:58 AM

MGallego: Fijar un Repositorio Para un Paquete en Emacs

Estos días estoy configurando mi Emacs para programar en Scala y voy a intentar ir documentando todos los pasos que vaya haciendo y lo que vaya descubriendo, porque la verdad es que la documentación que he encontrado sólo consiste en explicar la instalación, pero el uso tienes que investigarlo tú mismo.

En este post no voy a contar nada de Scala, pero está relacionado con un problema que me he encontrado y quería documentar como lo he solucionado.

Al arrancar Scala Metals flycheck da un problema porque necesita la última versión para funcionar, pero la última versión no está en el repostirio de melpa-stable, así que no hay forma de instalarlo por defecto, aunque lo busques en el listado de paquetes sólo va a aparecer el de melpa-stable. Pues así es como he conseguido solucionarlo.

Fijando un repositorio para un paquete de emacs

Cuando definimos los repositorios que queremos usar para descargar los paquetes de emacs podemos fijarles una prioridad a cada uno, el problema es que cuando encuentra un paquete en el primero ya el resto los ignora, así que como en mi caso, y en el de la mayoría de la gente, el repositorio con mas prioridad es melpa-stable no podremos seleccionar paquetes de melpa porque no los podremos ver en el listado y el instalador de paquetes siempre resolverá en stable

Cuando en nuestra configuración usamos use-package tenemos varios parámetros que podemos definir, uno de ellos es pin. En mi caso el único paquete que quiero poder usar de un repositorio diferente al primero es flycheck así que lo he configurado de la siguiente manera:

     (use-package flycheck
       :ensure t
       :pin melpa
       )
   

Si refrescamos el listado de paquetes ahora podremos ver un nuevo flycheck que no está instalado y si nos fijamos corresponde al del repositorio melpa así que ahora solo nos queda instalarlo y poder usar el paquete en su última version, eso sí, puede que ahora no se estable, pero a veces es un riesgo que hay que correr si queremos que todo funcione correctamente.

-1:-- Fijar un Repositorio Para un Paquete en Emacs (Post )--L0--C0--December 07, 2020 09:31 AM

Blog uGeek: Borrando líneas en blanco de un texto con Emacs

Borrando líneas en blanco de un texto con Emacs

A veces cuando copio un documento en la terminal, lo hace dejando líneas en blanco entre líneas. Para eliminar esto con Emacs es muy sencillo:...

Sigue leyendo el post completo de Borrando líneas en blanco de un texto con Emacs

Visita uGeek Blog

Visita uGeek Podcast

Suscribete al Blog de uGeek

Suscribete al Podcast de uGeek

-1:-- Borrando líneas en blanco de un texto con Emacs (Post )--L0--C0--October 26, 2020 05:45 PM

Blog uGeek: Añadiendo texto al principio de cada línea en Emacs

Añadiendo texto al principio de cada línea en Emacs

Como podéis imaginar, yo creo y edito mis scripts con Emacs. Hay momentos en los que quiero añadir "#" en un bloque de código para que no se ejecute, o...

Sigue leyendo el post completo de Añadiendo texto al principio de cada línea en Emacs

Visita uGeek Blog

Visita uGeek Podcast

Suscribete al Blog de uGeek

Suscribete al Podcast de uGeek

-1:-- Añadiendo texto al principio de cada línea en Emacs (Post )--L0--C0--October 24, 2020 10:30 AM

Blog uGeek: Visualizar aparte una Cabecera de un OrgMode en Emacs

Visualizar aparte una Cabecera de un OrgMode en Emacs

Hay momentos, al menos a mi me pasa, de todas las notas que voy registrando en mi orgmode, quiero exporta una ya sea en formato txt, pdf, markdown,......

Sigue leyendo el post completo de Visualizar aparte una Cabecera de un OrgMode en Emacs

Visita uGeek Blog

Visita uGeek Podcast

Suscribete al Blog de uGeek

Suscribete al Podcast de uGeek

-1:-- Visualizar aparte una Cabecera de un OrgMode en Emacs (Post )--L0--C0--September 03, 2020 05:45 PM

Blog uGeek: Compilar Emacs 27.1 para Ubuntu, Debian, Raspbian y derivadas

Compilar Emacs 27.1 para Ubuntu, Debian, Raspbian y derivadas

En el Artículo anterior compilamos Nano y ahora toca el turno de Emacs. Los que utilizamos Debian, Ubuntu, Raspbian... tenemos el problema que en los repositorios oficiales, no encontramos nunca...

Sigue leyendo el post completo de Compilar Emacs 27.1 para Ubuntu, Debian, Raspbian y derivadas

Visita uGeek Blog

Visita uGeek Podcast

Suscribete al Blog de uGeek

Suscribete al Podcast de uGeek

-1:-- Compilar Emacs 27.1 para Ubuntu, Debian, Raspbian y derivadas (Post )--L0--C0--August 12, 2020 09:10 PM

Blog uGeek: Habilitar el modo-org en Emacs, cuando abras un archivo txt o markdown

Habilitar el modo-org en Emacs, cuando abras un archivo txt o markdown

Es posible que te interese el habilitar el modo org cuando abras un archivos .txt o markdown....

Sigue leyendo el post completo de Habilitar el modo-org en Emacs, cuando abras un archivo txt o markdown

Visita uGeek Blog

Visita uGeek Podcast

Suscribete al Blog de uGeek

Suscribete al Podcast de uGeek

-1:-- Habilitar el modo-org en Emacs, cuando abras un archivo txt o markdown (Post )--L0--C0--June 16, 2020 09:22 PM

La Pipa Plena: La entrada 37 de emacs

Aprovechando el confinamiento en /home hemos terminado la entrada 37 de lo que llamamos el curso de emacs pero más que curso, son nuestros apuntes sobre los temas con los que nos vamos encontrando y en esta ocasión es fill-column-indicator, customize-themes, ffap, free-keys y auto-save-buffers El enlace es: http://lapipaplena.duckdns.org/emacs/ ¡¡Buen confinamiento para todos y excelentes … Sigue leyendo La entrada 37 de emacs
-1:-- La entrada 37 de emacs (Post la pipa plena)--L0--C0--April 12, 2020 02:32 PM

La Pipa Plena: subida la entrada 36 al curso de emacs

Hemos subido más cosas de las que nos vamos encontrando con emacs y las hemos puesto en la entrada número 36 para tenerlas siempre a mano. Recordamos que el archivo org puede descargarse de: http://lapipaplena.duckdns.org/emacs/curs_emacs.org y el curso completo de: http://lapipaplena.duckdns.org/emacs/
-1:-- subida la entrada 36 al curso de emacs (Post la pipa plena)--L0--C0--March 24, 2020 03:22 PM

La Pipa Plena: No estamos durmiendo…

Aunque parezca que tenemos el blog abandonado, cosa no muy descabellada, la verdad es que continuamos a pleno rendimiento pero en aspectos no tan evidentes como son las entradas de un blog. Una muestra del git log del tractatus así lo confirma: Y además hemos revisado y corregido varias cosas del curso de emacs que … Sigue leyendo No estamos durmiendo…
-1:-- No estamos durmiendo… (Post la pipa plena)--L0--C0--February 23, 2020 09:34 AM

Maxxcan's Site: Proyecto Twice3D -- Impresora Recicladora

Presentación del proyecto Twice3D -- Impresora Recicladora
-1:-- Proyecto Twice3D -- Impresora Recicladora (Post )--L0--C0--November 06, 2019 12:00 AM

Maxxcan's Site: Introducción a la programación literaria

Introducción a la programación literaria
-1:-- Introducción a la programación literaria (Post )--L0--C0--October 23, 2019 12:00 AM

Onda Hostil: Mi entorno de trabajo

Me han preguntado bastantes veces cómo me organizo y, aunque hace un tiempo hablé un poco sobre mi entorno de trabajo en Emacs, desde entonces he introducido algunas mejoras así que voy a hablar de mi entorno de trabajo en general. Aprovecho para enlazar otras entradas del blog en las que hablé en concreto de las herramientas que cito para que se note que las uso de verdad y no es (solo) postureo.

La base: acta en Org

La base de mi metodología es un archivo de Org que utilizo como acta y lista de tareas. Org tiene la ventaja de que me permite añadir imágenes, código y enlaces a diferentes documentos y, además, puedo exportar la parte del acta en diferentes formatos según las manías del receptor.

Este archivo se abre directamente cuando abro Emacs por las mañanas para que pueda ver qué me queda por hacer y acceder directamente a los documentos o al código en los que estoy trabajando desde él, que se abrirán o no en el propio Emacs según su formato. Para que esto ocurra he añadido la siguiente líneas a mi archivos de configuración:

; Abrir archivos con programa que corresponda
; Lo privativo!
(add-hook 'org-mode-hook
           '(lambda ()
          (add-to-list 'org-file-apps
               '("\\.m\\'" . default)    ;; Matlab
               '("\\.fig\\'" . default)  ;; Matlab
               '("\\.xlsx\\'" . default) ;; Excel
               )))

; Abrir acta al iniciar Emacs
(find-file (expand-file-name "acta/acta.org" default-directory))

Como toda mi labor investigadora se basa en este archivo tengo, evidentemente, una copia de seguridad.

El soporte auxiliar: diario de Emacs

Aparte de tener apuntadas mis tareas por temática, llevo un diario en el que apunto qué he hecho cada día. Esto tiene una doble función: por una parte, cuando me desmoralizo y creo que no avanzo, tengo evidencia empírica de que no es así; por otra, me sirve para seguir mi proceso mental y recordar qué estaba haciendo antes de irme de vacaciones, por ejemplo. Esto me resulta crucial porque me permite tanto desconectar en cuanto levanto el culo de la silla del trabajo como tener mis ideas hiladas en un lugar que no es mi (variable) cabeza.

Para ello uso el diario de Emacs de manera poco ortodoxa, que es como me gusta a mí usar las cosas. Tengo una copia de seguridad también del diario, claro.

El producto: texto plano y control de versiones

El tercer pilar de mi organización es que todo lo que produzco (los documentos, la bibliografía, las imágenes, el código …) es texto plano. Aparte de que de esta manera podré seguir accediendo a mi información dentro de treinta años1, así puedo tener todo bajo control de versiones. Para el control de versiones uso Magit en Emacs y git en la terminal por la vieja costumbre.

Os detallo un poco más cómo funciono:

  • Documentos: escribo en Org o en LaTeX tanto los artículos como los informes y las presentaciones para clase. Para LaTeX uso el modo AUCTeX con RefTeX para las referencias bibliográficas, CDLaTeX para las ecuaciones y Company para el autocompletado.

  • Bibliografía: la manejo con Jabref y, últimamente, con Helm-bibtex desde el propio Emacs. En este último caso, uso las variables locales para seleccionar el archivo de bibliografía correspondiente a cada documento así como la carpeta donde viven los pdfs.

%%% Local Variables:
%%% eval:(setq bibtex-completion-bibliography '("ruta_a_bib"))
%%% eval:(setq bibtex-completion-library-path '("ruta_a_pdf"))
%%% End:
  • Imágenes: trabajo generalmente con svg en Inkscape, o exporto a eps o svg desde el resto de programas. El motivo es que ambos son formatos vectoriales y eps el favorito de las revistas científicas. Para las gráficas científicas, tengo el código para producir la imagen bajo control de versiones y una función que le da un estilo uniforme a todas las imágenes que exporto.

  • Código: programo en Matlab por obligación y en Julia y últimamente algo en Python por vicio. Con Matlab hago más que suficiente con no caer en las malas prácticas que fomenta. Para programar en los otros dos uso los modos específicos de Emacs y también Org para programación literaria.

Un día en mi vida

Dicho esto, uno de mis días laborales suele tener esta estructura:

  1. Abro Emacs.
  2. Leo en la lista de tareas qué me queda por hacer y en el diario qué hice el día anterior.
  3. Decido qué voy a hacer. Si hay un archivo relacionado, estará enlazado en la propia lista de tareas y se me abrirá en Emacs o en el programa externo correspondiente.
  4. Trabajo. Escribo, programo, busco papers … abro ramas y envío actualizaciones al repo según corresponda con Magit o desde la terminal.
  5. Actualizo la lista de tareas y el diario con lo que vaya terminando y las conclusiones sacadas.
  6. Cierro Emacs.

Esta rutina laboral se irá modificando según vaya aprendiendo cosas nuevas, cuando eso ya os contaré. ¡De momento contadme vosotros qué hacéis!


  1. Dudo que vaya a querer, pero podré↩
-1:-- Mi entorno de trabajo (Post Ondiz)--L0--C0--October 16, 2019 03:00 PM

Maxxcan's Site: Trabajando con R en Emacs

Cómo trabajar con R en Emacs
-1:-- Trabajando con R en Emacs (Post )--L0--C0--October 09, 2019 12:00 AM

Maxxcan's Site: Cómo gestionar tus contraseñas con Emacs y Pass

Como gestionar las contraseñas con Emacs y Pass
-1:-- Cómo gestionar tus contraseñas con Emacs y Pass (Post )--L0--C0--September 30, 2019 12:00 AM

Maxxcan's Site: Racket con Emacs

Como trabajar con Racket en Emacs
-1:-- Racket con Emacs (Post )--L0--C0--September 29, 2019 12:00 AM

Onda Hostil: Lo que he aprendido: manejar referencias bibliográficas en Emacs

Detesto instalar programas, aprender dónde están los botoncillos en un programa nuevo y que luego no me convenza y vuelta a empezar. Supongo que es uno de los motivos por los que me encanta Emacs: mismo programa, miles de tareas diferentes.

Últimamente he estado hurgando un poco en sus habilidades como gestor bibliográfico. Como ya os conté, yo suelo usar Jabref que es el programa que aprendí a usar en su momento y con el que me apaño bien para añadir referencias directamente desde la web, pero hay veces en las que manejar texto plano a pelo me parece más conveniente. ¡Y para eso no hay nada que iguale a Emacs! Os cuento un poco.

El modo BibTeX

La forma más básica para trabajar con bibliografías en Emacs es el modo BibTeX: se carga directamente al abrir un archivo con extensión .bib y nos permite organizar (M-x bibtex-sort-buffer) y adecentar (C-c C-c ) nuestras referencias.

Para insertar entradas tenemos el comando genérico C-c C-b tras el que podemos usar autocompletado, o el grupo de comandos que empiezan por C-c C-e. Por ejemplo, para crear una entrada de tipo artículo podemos hacer lo siguiente:

  • con C-c C-e C-a (o M-x bibtex-Article) creamos una plantilla para artículo;
  • rellenamos los datos necesarios, algunos comienzan por OPT porque son opcionales;
  • al acabar hacemos C-c C-c (o M-x bibtex-clean-entry) para quitar los campos opcionales que no hemos rellenado y que nos corrija el formato;
  • si no le hemos puesto una palabra clave nos sugerirá una y la entrada estará finiquitada y lista para ser citada.

Otro comando interesante es M-x bibtex-fill-entry (generalmente C-c C-q ) para alinear correctamente cada entrada bibliográfica. Y tampoco está mal establecer la variable bibtex-maintain-sorted-entries para tener las referencias en orden alfabético.

Como siempre, podemos recurrir a M-x describe-mode para que Emacs nos explique qué hace el modo. Es un modo chiquitico, pero muy útil para embellecer la lista de referencias ya que ayuda a cambiar de mayúsculas a minúsculas, quitar espacios innecesarios y míticas mierdas que, a las que somos maniáticas, nos ponen muy nerviosas.

Helm-bibtex

Mi modo favorito para gestionar las referencias bibliográficas en Emacs es Helm-bibtex. Lo descubrí intentando abrir los artículos que cito directamente desde Emacs y lo he introducido directamente en mi rutina de escritura científica (que algún día os contaré) junto con AUCTeX y RefTeX.

Es sencillito de usar: una vez instalado, lo llamamos con M-x helm-bibtex. Nos aparecerá entonces una lista de nuestras referencias bibliográficas en la que podremos elegir la entrada que queramos. Dándole a TAB vemos las acciones posibles, que se ejecutan todas en las teclas F1F12.

Como sugieren en su ayuda, he enlazado M-x helm-bibtex a la combinación Menú + b añadiendo esta línea al archivo de configuración:

(global-set-key (kbd "<apps> b") 'helm-bibtex)    

con la idea de configurar el resto de las historietas de Helm también en la tecla Menú y pulsar menos botoncicos.

Evidentemente, aunque sea muy listo este modo, tenemos que decirle dónde tenemos el archivo de bibliografía, los artículos en cuestión y las notas al respecto, si las estamos usando. Yo, como tengo un archivo y una carpeta con referencias para cada tema, establezco unas variables locales para el artículo que esté escribiendo

%%% Local Variables:
%%% eval:(setq bibtex-completion-bibliography '("refs.bib"))
%%% eval:(setq bibtex-completion-library-path  '("references/"))
%%% End:

pero si tuviera todas las referencias juntas, podría añadir ese par de líneas al archivo de configuración directamente con las rutas correspondientes.

ACTUALIZACIÓN (16/10/2019) Por algún motivo que desconozco (Windows), la ruta relativa dejó de funcionar de un día para otro y tuve que poner la ruta absoluta.

Una cosa que me encanta de este modo es que, por medio de RefTeX, localiza la bibliografía local si se usa helm-bibtex-with-local-bibliography en lugar de helm-bibtex. Algo bastante útil sobre todo cuando estamos manejando bibliografías de otras personas.

De esta manera, cuando estoy escribiendo un artículo y quiero citar algo o a alguien, abro mis referencias, busco entre ellas lo que necesito y abro directamente el archivo en el propio Emacs usando pdf-tools. En Windows (sorpresa) esto no me carrula, así que he añadido esto al archivo de configuración

(setq bibtex-completion-pdf-open-function
  (lambda (fpath)
    (call-process "acrobat" nil 0 nil fpath)))

para que me abra los pdfs con al Acrobat Reader. Si, por lo que sea, lo que busco no está entre mis referencias, el cacharro me busca en repositorios online. Me falta investigar cómo funcionan las notas, que hasta ahora no he tenido necesidad de ellas.

Org-ref

Si Helm-bibtex os ha gustado y sois fanáticos de Org como la que escribe, org-ref os va a enamorar. Sirve para gestionar las referencias bibliográficas y cruzadas en Org y nos permite añadir letreros ref, label y cite como los de LaTeX.

Lo que más me gusta de este modo es que su propia ayuda es un archivo Org en el que se usan las funcionalidades del modo. Se abre con M-x org-ref-help y nos cuenta todo lo necesario para jugar con él. Hace cosas molonas como permitir navegar por el documento siguiendo las referencias, mostrar el título y demás de los trabajos citados si ponemos el cursor encima o ser capaz de extraer la información bibliográfica de un pdf (como Jabref). Es muy chulo y lo mejor para entender cómo funciona es abrir el archivo de ayuda y hurgar.

En fin, una cosa más que puedo hacer con Emacs.

Referencias

Managing BibTeX Files with Emacs

BibTeX-Mode for GNU-Emacs

Research Literature Management with Emacs


Suena:

-1:-- Lo que he aprendido: manejar referencias bibliográficas en Emacs (Post Ondiz)--L0--C0--September 25, 2019 11:30 AM

La Pipa Plena: Entradas 33 y 34 del curso de emacs

Hemos añadido al curso de emacs dos nuevas entradas sobre las últimas cosas del curso de emacs que nos han aparecido en las amenas charlas que sobre el tema efectuamos: pass, highlight-changes-mode,  mouse-avoidance-mode, glasses-mode, list-color-display, nov, real-auto-save, transpose-frame, diff-mode, substitute-in-file-name, memento-mori, recenter-positions, pathify-directory y golden-ratio-adjust http://lapipaplena.duckdns.org/emacs/ Y tambien hemos actualizado el org correspondiente: http://lapipaplena.duckdns.org/emacs/curs_emacs.org   … Sigue leyendo Entradas 33 y 34 del curso de emacs
-1:-- Entradas 33 y 34 del curso de emacs (Post la pipa plena)--L0--C0--September 15, 2019 04:53 PM

Onda Hostil: Lo que he aprendido: Julia, Babel y Org

Ya sabéis que me gusta llevar la contraria. También que me gusta el minimalismo y usar el mínimo de herramientas posible. Así que cuando me ha dado por explorar la programación literaria y la investigación reproducible en Julia, en lugar de aprender a utilizar los cuadernos Jupyter como una persona normal, me he puesto a jugar con mi adorado modo Org y su funcionalidad para incluir bloques de código Babel1. Supongo que es lo que tiene ser la única de tu entorno (laboral) que hace estas cosas y no tener por tanto limitaciones en la elección de herramientas. Total, como en la academia no se colabora, no se va a dar el caso de que mi elección me limite. En fin, dejo la academia, que me caliento, y os explicito los motivos:

  • No instalo más software: ya estoy programando en Julia en Emacs así que no necesito mil programas y mi ordenador durará años y años.

  • Utilizo mis atajos de teclado y configuración: como sigo usando el mismo programa, no tengo que aprender dónde están otros botoncillos. Además, tengo definido cómo exportar a pdf desde Org pasando por LaTeX en mi archivo de configuración por lo que el documento final es exactamente como yo quiero.

  • Puedo cambiar de lenguaje de programación: el sistema funciona para una pila de lenguajes de programación. Puedo incluso mezclar código de diferentes lenguajes en un único documento2.

Visto esto, parece que elegir Org es una buena idea, así que paso a contaros en qué consiste la programación literaria, cómo se aplica en Org y qué tiene de especial el caso de Julia.

La idea: escribir para humanos

La idea de la programación literaria, como tantas otras buenas ideas, fue de Donald Knuth. Consiste en cambiar de lector objetivo al escribir un programa: en lugar de una secuencia de instrucciones para una máquina salpicada por algún comentario sobre la implementación, el programa se convierte en una descripción de la lógica detrás de la implementación salpicada por algún fragmento de código. De esta manera, no es necesario descifrar qué hace el programa leyendo el código porque las decisiones de diseño y la lógica se explicitan. Se puede pensar en el programa, entonces, como en una obra literaria.

Como me dedico a los métodos de cálculo, es decir, propongo una manera de calcular algo y luego demuestro mediante un ordenador que mi manera es mejor que la manera anterior, este enfoque me interesa por dos motivos:

  • Investigación reproducible: puedo escribir un artículo científico que incluya mis datos y mi código con lo que quien lo lea puede acompañarme en el proceso, obtener mis mismos resultados y verificar si que mis conclusiones son correctas.

  • Documentación útil: puedo explicar en el propio programa mi proceso mental para implementar numéricamente un cálculo que inicialmente era analítico, incluyendo matemáticas si es preciso.

Solo nos queda responder a una pregunta: ¿cómo demonios se lee esa mezcla de texto y código sin volverse una loca? Pues mediante los procesos de weaving, que deja solo lo humano, y tangling, que deja solo lo que entiende la máquina. ¡A ver si os habíais pensado que el señor Knuth no había pensado en esto! La cuestión aquí es que como tanto la documentación o explicación y el código salen de un mismo documento, ambos crecen juntos y limitamos la típica divergencia de según la documentación esta función tiene dos variables de entrada pero según el código tiene tres.

Programación literaria en Org

Ahora que sabemos qué es lo que queremos hacer, vamos a ver cómo lo hacemos en Org. No puede ser más fácil: cuando queramos meter un cacho de código escribimos

#+BEGIN_SRC lenguaje opciones_cabecera

Código

#+END_SRC

y ya está. Impresionante. Más os voy a decir: los bloques se pueden crear con las plantillas fáciles de Org situándonos en el principio de la línea y haciendo <s TAB.

Para poder ejecutar el trocito de código necesitamos primero decirle a Org que vamos a usar el lenguaje en cuestión y que ese lenguaje sea uno de los soportados. Tan sencillo como ir al archivo de configuración y añadir elementos a la lista de lenguajes:

(org-babel-do-load-languages
(quote org-babel-load-languages)
(quote (
(LENGUAJE1 . t)
(LENGUAJE2 . t)
)))

Ahora si hacemos C-c C-c sobre el trocito, lo ejecutaremos y nos saldrá el resultado debajo. Por seguridad, preguntará si queremos ejecutar y tendremos que contestarle, si somos vagos y nos gusta ver el mundo arder podemos decirle que ejecute todo el código sin preguntar con

(setq org-confirm-babel-evaluate nil)

¡Destrucción! ¡Sí!

Un detallico sobre los resultados: los trocitos de código se ejecutan por defecto como si fueran una función (opción de cabecera :results value) y solo nos devolverán el contenido si se lo pedimos explícitamente, con un return en el caso de Python, por ejemplo. Podemos cambiar la opción a :results output y, entonces, Org nos devolverá el contenido de STDOUT. Para lenguajes interpretados, podemos combinar esta opción con :session, que abre un intérprete y envía allí el código de todos los bloques que contengan dicha opción. Es un poco lío esto, pero jugando un poco con las opciones y leyendo la docu, se entiende.

También usamos las opciones de cabecera para decidir si al crear el documento exportamos el código (:exports code), los resultados (:exports results), el código y los resultados (:exports both) o nada (:exports none); para decirle a Org qué debe hacer con los resultados (:post); o para decir si queremos solo el archivo para la máquina (:tangle ARCHIVO_DESTINO), que por defecto no nos crea.

También podemos configurar cómo exporta el código al documento final. En mi caso, como el documento final es un pdf y eso pasa por LaTeX, quiero que use listingsUTF8 para los bloques de código. Se puede configurar para minted también, claro.

;; Exportar código como listings
(require 'ox-latex)
(setq org-latex-listings t)

;; Paquetes de LaTeX para código
(setq org-latex-default-packages-alist
'((""    "listingsutf8"  t)
("usenames,dvipsnames,svgnames,table"    "xcolor"    t))))

Las cuqueces y los colorinchis no se limitan al documento final, con

(setq org-src-fontify-natively t)

también tendremos colores en nuestro Org.

Ah, por cierto, el trocito de código lo podemos modificar en un buffer especial que se abre con C-c '.

El caso de Julia

Julia es uno de los lenguajes que no tiene soporte directamente en Babel porque su autor no le dio el copyright a la FSF. Por lo tanto, aparte de añadir Julia a la lista de lenguajes que puede usar Org, necesitamos los paquetes ESS y ob-julia.

Luego, hacen falta un par de líneas extra en el archivo de configuración para decirle a ob-julia dónde está el ejecutable de Julia (yo lo tengo en el PATH y por eso no le doy la ruta entera) y decirle a Emacs que use ob-julia:

;; Código Julia en Org
(setq inferior-julia-program-name "julia") ;; nombre o ruta de ejecutable
(require 'ob-julia)

(org-babel-do-load-languages
(quote org-babel-load-languages)
(quote (
(julia . t)
)))

Ale, ya puedo jugar a programar explicándome a mí misma lo que he hecho. Ahora solo me falta aplicar estas ideas al archivo de configuración de Emacs para no romperlo nunca.

Seguiremos informando.

Referencias

Documentación de Babel

Babel: active code in Org-mode

Working with source code en el manual de Org

Introduction to Literate Programming

Emacs para ciencias del dato

Julia with Emacs Org mode

Org-mode and julia: an introduction

Literate Programming Examples

Literate programming with Org-mode

Ten simple rules for writing and sharing computational analyses in Jupyter Notebooks

Drops of Jupyter notebooks: how to keep notes in the information age


Os dejo con música:


  1. También hay un paquete específico para Julia, pero ¿me gusta a mí lo fácil? No. 
  2. Lo digo como su supiese programar en múltiples lenguajes, ¿habéis visto? 
-1:-- Lo que he aprendido: Julia, Babel y Org (Post Ondiz)--L0--C0--September 06, 2019 02:00 PM

Jubilación Efectiva: Spacemacs ¿Editor definitivo?.

Pues, para mí, va a ser que no, aunque en mi lento retorno a estos andurriales, me he visto sorprendido por este entorno. Lo cierto es que este verano me he encontrado con un pequeño problema ya que se me ha oxidado algo el Emacs, por falta de uso y en la búsqueda de vídeos …

Spacemacs ¿Editor definitivo?. Leer más »

La entrada Spacemacs ¿Editor definitivo?. se publicó primero en Jubilación Efectiva.

-1:-- Spacemacs ¿Editor definitivo?. (Post Antonio Simón)--L0--C0--August 22, 2019 05:19 PM

Onda Hostil: Lo que he aprendido: Julia en Emacs

He conseguido por fin poder programar en Julia usando Emacs. Eh, que no ha sido tan fácil: algo tan sencillo como instalar el julia-mode y el ess se convirtió en un infierno. Me pasó de todo.

Primero en GNU/Linux, como no estaba usando la versión más novedosa de elementary, el Emacs de los repositorios era demasiado antiguo y no compatible con los modos que me hacían falta. Me quedaban varias opciones: (i) actualizar el sistema (lo que finalmente hice); (ii) añadir un ppa con un Emacs más moderno (bien, pero prefiero tener los paquetes de mi distro que ya he organizado alguna petarda); o (iii) compilar Emacs desde fuente (ya lo hice alguna vez y no me apetecía repetir).

Luego en Windows, donde sí tenía un Emacs lo suficientemente moderno, parece ser que Julia tiene no sé que bug y se cuelga y hay que darle a C-g para que se reviva.

En fin, que actualicé el sistema operativo y en quince minutos ya tenía un entorno para programar en Julia. Bueno, eso en mi recién estrenado Juno, en Windows me conformo con Atom, ese editor que no es un editor. Qué dura es la vida a veces.

Después de contaros mis desventuras (para eso tengo un blog), paso a resumir qué hice la vez que funcionó todo.

Julia en GNU/Linux

Julia no está en los repos, nos dejan unos binarios genéricos para que descarguemos y ejecutemos sin más. Hay que elegir unos u otros según la arquitectura de nuestro procesador. Yo, como nunca sé qué tengo lo miro así:

ondiz@slimbook:~$ lscpu
Arquitectura:                        x86_64
modo(s) de operación de las CPUs:    32-bit, 64-bit

Descargados los binarios correspondientes, es útil crear un enlace simbólico a algún lugar donde ya estemos buscando ejecutables o añadir la carpeta donde los hemos descargado al PATH, a gusto del consumidor.

Yo he elegido la primera opción, así que he hecho:

sudo ln -s RUTA_A_EJECUTABLE /usr/local/bin/julia

Cuidadín que hay que poner la ruta absoluta al ejecutable bin/julia que si no no carrula.

Julia en Emacs

Pues lo que decía al principio: para tener un entorno chachi para programar en Julia solo hace falta instalar los modos julia-mode y ess. El primero es el modo oficial para editar Julia y el segundo es un paquete que ayuda a trabajar con lenguajes de programación para estadística (ESS viene de Emacs Speaks Statistics) como R, o en este caso, Julia. Se pueden hacer otras cosas, pero esta es la más simple en mi opinión.

Una vez instalados los modos, para activar una terminal juliana inferior solo hay que hacer M-x julia. Luego ya podemos abrir un archivo en la parte superior y jugar con opciones que nos da el modo ESS.

Llevo poco con el tema y solo he memorizado un par de combinaciones útiles (miento, no las he memorizado, las escribo aquí para mirarlas en el futuro):

  • C-c C-l: carga un archivo completo, lo que sería un include("archivo").

  • C-M-x: ejecuta (me encanta esta palabra) un trozo de código en el REPL.

  • C-c C-z: cambia del script al REPL o viceversa.

Hay también una pila de comandos para gestionar errores y para acceder a la documentación que algún día controlaré. O no. También me falta echarle un ojo a imenu anywhere para que me aparezcan opciones de autocompletado en cualquier lugar. Me lo dejo de deberes.

Curiosamente, lo que más trabajo me dio fue acostumbrarme a no darle a la flecha hacia arriba para repetir el último comando en el REPL. Aquí, como las combinaciones de GNU Readline están ya pilladas, hay que usar M-p y M-n (o C-↑ y C-↓) para moverse por la historia. Comint y cosas, ya sabéis, y si no, con hacer C-h b os enteráis.

Y hala, ya tengo un entorno para programar. Contadme qué usáis vosotros para que aprendamos todos, venga.

juliaEmacs

Referencias

Página oficial de Julia

Manual del modo ess

Julia en el modo ess

imenu anywhere en GitHub


Os dejo con un grupo cuyas canciones suelo berrear en los conciertos de las fiestas de los pueblos vecinos y que tiene el mérito de que no me quedase dormida encima del libro de física de primero de carrera. Era abrirlo y bostezar, oigan.

-1:-- Lo que he aprendido: Julia en Emacs (Post Ondiz)--L0--C0--August 08, 2019 12:54 PM

Jubilación Efectiva: Compilando Emacs en Debian Stretch.

Una de las últimas tareas que acometí en mi Debian, antes de pasarme al mundo de Antergos, fue la de compilar GNU Emacs, algo necesario para dispones de su última versión, dado el sistema de gestión de paquetes de esta distribución. La tarea me imponía algo de respeto, porque hacía muchos años que no me …

Compilando Emacs en Debian Stretch. Leer más »

La entrada Compilando Emacs en Debian Stretch. se publicó primero en Jubilación Efectiva.

-1:-- Compilando Emacs en Debian Stretch. (Post Antonio Simón)--L0--C0--April 18, 2019 01:00 PM

Onda Hostil: Lo que he aprendido: el buffer de paquetes de Emacs

Años usando Emacs y no ha sido hasta hace unos meses que he descubierto que el buffer de los paquetes, ese al que entramos con M-x list-packages es mucho más fácil de usar de lo que yo pensaba.

Resulta que si te posicionas en la línea de un paquete sin instalar y le das a la i lo marcas para instalar, si vas a uno instalado y le das a la d lo marca para eliminar (delete) y si le das a la U así en general, marca los paquetes que hay que actualizar con una I (upgrade). ¿Y ahora cómo hacemos efectivas estas órdenes? Pues dándole a la x. Así todo lo que queramos borrar se borrará, lo que queramos instalar se instalará y lo que queramos actualizar se actualizará.

En la imagen se ve la I mágica de la que hablo en la columna de la izquierda del todo.

paquetes

En fin, aquí lo dejo, por si hay otro genio como yo por ahí al que le resulta útil. A cuidarse.

Referencias

48.1 The Package Menu Buffer en el manual de Emacs


Solo del punk no se vive, hoy suenan trompetas.

-1:-- Lo que he aprendido: el buffer de paquetes de Emacs (Post Ondiz)--L0--C0--April 15, 2019 11:00 AM

MGallego: Introduccion a Emacs Lisp: Seteando Variables

Existen dos formas de setear una variable en Lisp:

Usando set

Imaginemos que queremos setear una variable que contenga una lista de lenguajes de programación. Podemos hacerlo de la siguiente manera:

(set 'lenguajes '(c python pascal php java erlang))

Esto setería una variable llamada lenguajes que contendría la lista '(c python pascal php java erlang)

Debemos fijarnos en un par de cosas, una de ellas ya la había explicado en el post anterior.

Si nos fijamos en la lista '(c python pascal php java erlang) podemos ver que la lista comienza con una comilla. Con esto lo que le estamos diciendo al intérprete es que la debe devolver tal y como está, sin evaluar nada.

Por otro lado vemos que hay una comilla simple delante del nombre de la variable. Esto es mas o menos lo mismo, no queremos que la evalúe, solo queremos pasar el elemento a la función set. Si no pusiésemos esa comilla el interprete devolvería un error al tratar de evaluarla.

De esta forma ya tenemos una variable lenguajes que al evaluarla fuera de paréntesis nos devolvería una lista de lenguajes de programación.

Usando setq

Setq es una forma un poco mas sencilla de crear una variable, aunque tampoco mucho mas, ya que lo que nos ayuda setq es en que no tenemos que poner la comilla en la variable que queremos crear. La creación de la variable anterior con setq sería de la siguiente manera:

(setq lenguajes '(c python pascal php java erlang))

La q de setq es de quoted.

Creando un contador sencillo.

Si usamos set o setq de nuevo sobre una variable que ya tiene un valor asignado este se sobrescribe, así que podemos ver un sencillo ejemplo de esto viendo como podemos definir una variable contador en emacs.

  (setq counter 0) ; inicializador
  (setq counter (+ counter 1)) ; incrementador

  counter ; resultado

El "inicializador" lo que hace como su nombre indica es crear la variable y setearla a 0. Inicializarla. El incrementador incrementa el valor de la variable en 1, así que cada vez que ejecutemos la expresión del incrementador el valor de la variable counter se aumentará en 1.

-1:-- Introduccion a Emacs Lisp: Seteando Variables (Post )--L0--C0--April 14, 2019 03:37 PM

MGallego: Introduccion a Emacs Lisp: Listas

He comenazado a leerme el manual de introducción a Emacs Lisp, el cual es gratuito y se puede leer online aquí o descargar desde la misma dirección.

Así que voy a ir apuntando por aquí un breve resumen de lo que vaya aprendiendo, aunque no me gusta demasiado como está organizado el libro y voy a intentar solo anotar las cosas que realmente me resulten interesantes o crea que pueden llegar a aportar algo realmente

Listas

Lisp está basado en listas, un ejemplo de lista es el siguiente

  '(rose
    violet
    daisy
    buttercup)

Átomos

Cada uno de los elementos de las listas, separados por espacios en blanco se llama "atom", átomo. En el caso anterior rose, violet, daisy y buttercup serían átomos de la lista. Como buen átomo que se precie no se puede dividir en ningún elemento mas pequeño.

Pocas veces los programadores llaman átomo a los átomos, ya que se suelen referir a ellos por el tipo de átomo que es, por ejemplo string: '("texto entre comillas dobles") el texto entrecomillado con comillas dobles es un átomo de tipo string.

Listas vacías

Así que una lista en Lisp no es mas que una serie de átomos encerrados entre paréntesis. Aunque también podemos tener listas sin átomos, como por ejemplo () . Esto se llama "lista vacía"

Expresiones simbólicas

La representación de átomos o listas es llamada representación simbólica, Symbol Representation también denominada s-expression

Espacios en blanco

Los espacios en blanco no son tenidos en cuenta dentro de una lista, solo se usan como separados de átomos, pero independientemente del número de ellos. Los ejemplos siguientes representan la misma lista:

  '(atom1 atom2 atom3)

  '(atom1
    atom2
    atom3)

  '(atom1          atom2   atom3)

Ejecución de código

Cualquier lista en Lisp es un programa que se puede ejecutar. En la jerga de Lisp: evaluar.

Al evaluar una lista de lisp pueden ocurrir tres cosas:

  1. No hacer nada salvo devolver la propia lista

  2. Devolver un error

  3. Tratar el primer símbolo de la lista como un comando que realiza algo

En los ejemplos en los que hemos visto antes ponía una comilla simple delante de la lista, de está manera: '(lista de elementos) con esto se le dice al intérprete que debe devolver la lista tal cual. En el caso de no poder la comilla el interprete lo que intenta hacer es ejecutar el primer elemento de lista como una función. Como por ejemplo: (+ 2 2) que lo que haría sería sumar 2 + 2, ya que el primer símbolo + es la función de suma en Lisp.

Evaluando expresiones en Emacs

Para evaluar algo en emacs, lo mas sencillo es poner el cursor justo detrás de lo que queremos evaluar y pulsar la combinación de teclas C-x C-e. si por ejemplo tenemos dos listas una dentro de otra o queremos evaluar solamente un elemento de la lista podemos hacerlo colocando el cursor en el punto justo donde deseemos evaluar.

Por ejemplo con la siguiente lista: (+ 2 (+ 3 4)) si evaluamos después del último cierre de paréntesis el resultado devuelto será 9 pero si lo colocamos detrás del penúltimo cierre, el interprete nos devolverá 7 ya que estaremos evaluando solamente la expresión (+ 3 4) . Es mas, si evaluamos justo después del 4 nos devolverá 4, ya que los números se devuelven a si mismo al evaluarse.

Generar mensajes de error

En el ejemplo anterior, si evaluásemos el símbolo + nos devolvería un error. Emacs abriría un nuevo buffer donde podríamos ver la descripción del error.

Variables

Para ver el contenido de una variable no debemos meterla dentro de una lista, se debe evaluar fuera de la lista, por ejemplo en el caso de la variable fill-column que viene ya definida en emacs, para ver el contenido deberíamos evaluarla así fill-column . En el caso de que la evaluemos de la siguiente manera: (fill-column) obtendríamos un error, ya que estaría intentando ejecutar fill-column como si se tratase de una función.

Un par de ejemplo de errores serían los siguientes:

Evaluar una variable como una función

(fill-column)

Esto devolvería un error del tipo:

---------- Buffer: *Backtrace* ----------
Debugger entered--Lisp error: (void-function fill-column)
(fill-column)
eval((fill-column) nil)
elisp--eval-last-sexp(nil)
eval-last-sexp(nil)
funcall-interactively(eval-last-sexp nil)
call-interactively(eval-last-sexp nil nil)
command-execute(eval-last-sexp)
---------- Buffer: *Backtrace* ----------

Se puede ver que dice algo así como que no es una función.

Evaluar una función como una variable

Este es justo el caso anterior, en el que intentamos evaluar una función fuera de una lista, como por ejemplo evaluar el símbolo +

+
---------- Buffer: *Backtrace* ----------
Debugger entered--Lisp error: (void-variable +)
eval(+)
elisp--eval-last-sexp(nil)
eval-last-sexp(nil)
funcall-interactively(eval-last-sexp nil)
call-interactively(eval-last-sexp nil nil)
command-execute(eval-last-sexp)
---------- Buffer: *Backtrace* ----------

Sería mas o menos que se intenta ejecutar una variable que no lo es o que no está declarada como tal.

Argumentos

Como en muchos lenguajes de programación, a cada elemento que se le pasa a una función se le llama argumento. El numero de elementos puede ser variable y el tipo de elemento también.

Si pasamos un número de elementos erróneo para una función está devolverá un error. Lo mismo pasará cuando el tipo de argumento no sea el correcto. En el caso del tipado el error devolverá el tipo necesario seguido de "-p", esa p viene de predicate. Por ejemplo si requiere una lista dirá "lisp" si debe ser zero nos dirá "zerop"

La función message

Hay una función en emacs llamada message que sirve para pintar en el buffer de echo del editor. Un ejemplo de su uso sería (message "texto a mostrar")

Conclusión

He decidido no publicar mas en este post, no tiene ni todo el capitulo 1 del libro. Personalmente me resulta un tanto caótico, ya que salta de unas cosas a otras y te mete cosas como por ejemplo la función message cuando está hablando de variables, cosa que no comprendo. Así que lo mismo intento publicar posts un poco mas cortos pero mas centrados.

-1:-- Introduccion a Emacs Lisp: Listas (Post )--L0--C0--April 14, 2019 02:41 PM

La Pipa Plena: Tutorial emacs

Entre un montón de elementos linuxeros hemos realizado una traducción del tutorial de emacs de: https://www.computerhope.com/unix/uemacs.htm Seguramente tiene bastantes deficiencias pero ahí queda para quien lo quiera usar. Lo hemos colgado en el apartado emacs de la cabecera i está en: http://lapipaplena.duckdns.org/emacs/emacs_tut.html M-x felices-orgasmos
-1:-- Tutorial emacs (Post la pipa plena)--L0--C0--March 24, 2019 05:15 PM

Podcast uGeek: Notas y Documentos en la nube para compartir, trabajar en equipo,...

Notas y Documentos en la nube para compartir, trabajar en equipo,...

Simplenote, es una aplicación de notas muy conocida de Software Libre, totalmente multiplataforma y gratuita...

Sigue leyendo el post completo de Notas y Documentos en la nube para compartir, trabajar en equipo,...

Visita uGeek Podcast

Visita uGeek Podcast

Suscribete al Blog de uGeek

Suscribete al Podcast de uGeek

-1:-- Notas y Documentos en la nube para compartir, trabajar en equipo,... (Post )--L0--C0--March 11, 2019 04:45 AM

Jubilación Efectiva: GTD con org-mode. Primer intento.

Bueno, pues aquí estamos. Tras la formación GTD, Nivel 1, que os comenté en esta entrada anterior me he encontrado con un sistema GTD funcionando, que hay que aprovechar y sobre el que hoy os quiero hablar. Me parece importante comenzar a explicar los ajustes que, seguro, iré haciendo a mi sistema GTD para ver …

GTD con org-mode. Primer intento. Leer más »

La entrada GTD con org-mode. Primer intento. se publicó primero en Jubilación Efectiva.

-1:-- GTD con org-mode. Primer intento. (Post Antonio Simón)--L0--C0--February 17, 2019 09:55 PM

Jubilación Efectiva: Adquisición de hábitos con ayuda de org-mode.

Introducción. Cuando hablamos de «mejora personal«, utilizar un sistema como GTD es fundamental para realizar un seguimiento de las acciones realizadas, lo que favorece la revisión y el análisis de nuestras buenas o malas prácticas. Dentro de estas acciones hay una serie de ellas, conocidas como hábitos, que son una base fundamental de nuestro día …

Adquisición de hábitos con ayuda de org-mode. Leer más »

La entrada Adquisición de hábitos con ayuda de org-mode. se publicó primero en Jubilación Efectiva.

-1:-- Adquisición de hábitos con ayuda de org-mode. (Post Antonio Simón)--L0--C0--January 27, 2019 07:45 PM

Podcast uGeek: GNU-Linux, Emacs,.. ¿porqué?

GNU-Linux, Emacs,.. ¿porqué?

GNU-Linux, Emacs,.. ¿porqué?...

Sigue leyendo el post completo de GNU-Linux, Emacs,.. ¿porqué?

Visita uGeek Podcast

Visita uGeek Podcast

Suscribete al Blog de uGeek

Suscribete al Podcast de uGeek

-1:-- GNU-Linux, Emacs,.. ¿porqué? (Post )--L0--C0--November 21, 2018 08:53 PM

Podcast uGeek: Sincronización Selectiva en Syncthing, Markdown en Emacs, Blog Jekyll, Escritorio i3

Sincronización Selectiva en Syncthing, Markdown en Emacs, Blog Jekyll, Escritorio i3

Sincronización Selectiva en Syncthing, Markdown en Emacs, Blog Jekyll, Escritorio i3...

Sigue leyendo el post completo de Sincronización Selectiva en Syncthing, Markdown en Emacs, Blog Jekyll, Escritorio i3

Visita uGeek Podcast

Visita uGeek Podcast

Suscribete al Blog de uGeek

Suscribete al Podcast de uGeek

-1:-- Sincronización Selectiva en Syncthing, Markdown en Emacs, Blog Jekyll, Escritorio i3 (Post )--L0--C0--October 29, 2018 07:06 PM

Podcast uGeek: Como gestiono Mis Notas Markdown

Como gestiono Mis Notas Markdown

Como gestiono Mis Notas Markdown...

Sigue leyendo el post completo de Como gestiono Mis Notas Markdown

Visita uGeek Podcast

Visita uGeek Podcast

Suscribete al Blog de uGeek

Suscribete al Podcast de uGeek

-1:-- Como gestiono Mis Notas Markdown (Post )--L0--C0--October 14, 2018 10:34 PM

Podcast uGeek: Podcast: Iniciándonos en Emacs y Org Mode de un Modo muy muy Fácil.

Podcast: Iniciándonos en Emacs y Org Mode de un Modo muy muy Fácil.

Podcast: Iniciándonos en Emacs y Org Mode de un Modo muy muy Fácil....

Sigue leyendo el post completo de Podcast: Iniciándonos en Emacs y Org Mode de un Modo muy muy Fácil.

Visita uGeek Podcast

Visita uGeek Podcast

Suscribete al Blog de uGeek

Suscribete al Podcast de uGeek

-1:-- Podcast: Iniciándonos en Emacs y Org Mode de un Modo muy muy Fácil. (Post )--L0--C0--October 09, 2018 10:26 PM

Jubilación Efectiva: Mis maestros: Drymer, el Emacs en castellano.

Cuando descubrí org-mode y, como consecuencia, me topé con Emacs, me sentía bastante inseguro como para  trabajar en inglés sobre todo ello, y al hacer la recopilación de recursos, que por cierto creo debiera reorganizar :(, el descubrimiento del sitio de Planet Emacses, a día de hoy inactivo, fue una auténtica alegría y se convirtió …

Mis maestros: Drymer, el Emacs en castellano. Leer más »

La entrada Mis maestros: Drymer, el Emacs en castellano. se publicó primero en Jubilación Efectiva.

-1:-- Mis maestros: Drymer, el Emacs en castellano. (Post Antonio Simón)--L0--C0--October 05, 2018 04:19 PM

nba - GNU's Rock: temax

sucede que haciendo una prueba con el vps conectado via ssh queria dejar corriendo un comando

> youtube-dl -f best -ciw -v 'https://www.youtube.com/channel/UCbGYYbuGLFC6wIsyKXXW4cQ'

y salir de la sesion, dejando al vps a su bola, p-e-r-o, p-e-r-o, p-e-r-o si sales de la sesion ssh, tu comando tambien se corta

y esto no se soluciona poniendo un & al final del comando, por que este (supongo y sin idea) “proceso” es un “hijo” de tu shell que es un hijo de tu sesion y si la sesion se muere, el padre mata a todo mundo. Ja, ja, ja, ha

Como solucionar esto? pues teniendo un shell que sea “hijo de un demonio😈” que ande a su bola, e invocarlo cuando nos venga en gana

y todo esto que suena tan complicado y misterioso, es mas facil de lo que parece (creo). Encima podemos hacerlo con emacs, aunque igual, segun la situacion podriamos recurrir a otros dos programitos habitualmente disponibles en cualquier distribucion

emacs

emacs tiene un modo demonio que sirve para dos cosas:

  • cargar emacs una vez y luego lanzar instancias que comparten la misma sesion pero se manifiestan a la velocidad del rayo

  • volver independiente tu sesion de una shell, fuera esta en ssh o en modo texto o grafico

primero, para activar el modo demonio lanzamos el siguiente comando

> emacs --daemon

esto no lanzara ningun emacs, simplemente colocara bajo las sombras una sesion con la que podremos contactar. Para hacer esto necesitamos un comando particular llamado emacsclient. Como la mayoria de las cosas, no es tan sencillo. Si lo lanzamos tal cual

> emacsclient
emacsclient: file name or argument required
Try 'emacsclient --help' for more information

nos dira que intentemos ver la ayuda. Si bien, esta ayuda es basta, podriamos simplificarla a dos opciones utiles

> emacsclient -c

que nos lanza emacs en el buffer scratch.

dejemos una marca en dicho buffer para identificar nuestros pasos. Colocando por ejemplo, la frase "hola soy emacsclient uno"

bien, terminemos emacs como se haria habitualmente C-x C-c e invoquemos de nuevo a nuestro emacs-demonio emacsclient -c -nw

hala, nuestro mensaje sigue hay!

ahora en nuestra terminal (tilix) dividida, lanzamos de nuevo emacsclient -c -nw

de nuevo lo mismo

y si cerramos uno o todos los emacsclient da igual, lo que en ellos hagamos permanecera mientras no se apague el sistema o cerremos el modo demonio

la otra forma en la que podemos lanzar emacsclient, consiste en indicar que ficheros abrir

> emacsclient fichero1 fichero2 ...

y ahora con esto, podriamos resolver el problema inicial. Abrimos una shell, ponemos el comando a ejecutar, salimos (C-x C-c), cerramos el ssh y regresamos cuando lo creamos conveniente. El demonio de emacs con todos sus buffers y demas cosas, seguira realizando su labor!

y ahora? pues para terminar con el modo demonio, desde un emacsclient

M-x server-mode

nos dira que actualmente hay un servidor con clientes, que si lo queremos terminar de todas maneras, a lo que diremos que si.

cosas

emacs es un entorno centrado en el texto, que puede dividirse, expandirse y adaptarse de formas inimaginables, sin embargo, una terminal pura donde ejecutar programas visuales e interactivos escritos cada uno en su lenguaje, con sus propias librerias y forma de entender sus combinaciones de teclado, igual y queda en otra liga mas alla de los fines de emacs

tambien, aunque emacs posee su propia terminal (tonta) eshell, lo mejor es lanzar programas no interactivos. Ademas eshell, sola hay una y solo una, Emacs no es multiproceso, o hace una cosa o hace otra, pero no dos al mismo tiempo. Si lo que necesitamos son varias shell reales, lo mas conveniente seria recurrir a otras herramientas

GNU Screen

esto es un multiplexor de terminal, que segun la wikipedia:

es una aplicación de software que puede utilizarse para varias sesiones de inicio de sesión independientes basadas en seudoterminales dentro de una única pantalla de terminal, una ventana de emulador de terminal, una consola de sistema de PC/puesto de trabajo o una sesión de inicio de sesión remota, o para separar y volver a adjuntar sesiones de un terminal. Es útil para tratar con múltiples programas desde una interfaz de línea de comandos, y para separar programas de la sesión de la shell de Unix que inició el programa, particularmente para que un proceso remoto continúe ejecutándose incluso cuando el usuario está desconectado.

pero que en resumidas palabras, podria resumirse en un “emacs” para las terminales o como “un entorno de escritorio para las terminales”

y que podemos hacer con esto? tras instalar gnu screen (buscarlo como screen en su distribucion) y lanzarlo por primera vez

> screen

nos resivira con un bonito mensaje

tras presionar espacio, aparecera el prompt de nuestra shell de siempre, donde lanzar los comandos de siempre

bien no? pues si… a-u-n-q-u-e, cuando salimos de la terminal, no salimos de la terminal, saldremos de la terminal en screen

[screen is terminating]

volvamos a lanzarla de nuevo y veamos como demonios (ja, ja, que cachondo) utilizar este invento

primero, screen tiene algunas influencias emacseras, y como este, tiene un prefijo para hacer cosas, que por defecto es C-a (Control y a al mismo tiempo) seguido por una (o mas) combinaciones que serian el comando en si, por ejemplo, si presionamos C-a d saldremos de screen pero sin cerrar screen, que seguira en “segundo plano” a su rollo, rollo al que podemos regresar

como hacer esto? no es tan sencillo, primero deberemos averiguar el nombre de nuestra “sesion” y re-enlazar a ella

mientras haciamos el C-a d nos lanzaba la siguiente salida

[detached from 6469.pts-3.tachikoma]

un dato similar podemos obtenerlo con el siguiente comando

> screen -ls
There is a screen on:
	6469.pts-3.tachikoma	(Detached)
1 Socket in /run/screens/S-nasciiboy.

donde el dato importante es ese que va luego del punto del numero, hasta el primer espacio, es decir (y en este caso particular) pts-3.tachikoma. Dicho valor nos servira para recuperar la sesion

> screen -x pts-3.tachikoma

bonito no? ehhhh, mas o menos. Salgamos sin cerrar e iniciemos una nueva sesion con un nombre mas sencillo

> screen -S mi-sesion

de nuevo, tendriamos otra terminal…

repitiendo el listado de sesiones

> screen -ls
There are screens on:
	7832.mi-sesion	(Detached)
	6469.pts-3.tachikoma	(Detached)
2 Sockets in /run/screens/S-nasciiboy.

guaaa, que emocionante…

para contactar a esta nueva sesion

> screen -x mi-sesion

y? pues ahora un par de cosas medio chulas, primero podemos dividir la pantalla ¡en dos! presionando C-a S

luego puedes saltar a esta nueva division con C-a TAB. Ver el cursor en esta nueva seccion, apretar los botones a lo loco y ver que no pasa nada

hasta que invoques una shell en este espacio con el comando magico C-a c

dividir nuevamente la ventana (ahora en vertical) C-a |, saltar a esta C-a TAB, nueva shell C-a c y sonreir locamente

ahora como cerrar este conjunto, si salimos de la shell (C-d o con exit) la seccion no desaparecera, seguira hay hasta que presionemos C-a X

si por alguna razor quisieramos cambiar el prefijo C-a por otro distinto, por ejemplo C-b, tenemos dos opciones crear un fichero .screenrc en nuestro home con el contenido

escape ^Bb

con lo que el comando prefijo quedaria fijado a C-b por siempre jamas, o bien, lanzar screen de la siguiente manera

> screen -e^bB

y pocas cosas mas puedo comentar sobre screen y sus fabulosas cualidades. Para mas informacion dentro de la misma sesion presionar c-a ? invoca a la ayuda. tambien podriamos ver la pagina del manual

tmux

y… tmux es mas o menos como screen, tambien va a su rollo y puede sobrevivir al cuelgue de una sesion ssh, tiene combinaciones “tipo emacs” y sirve de “entorno de escritorio para las terminales”, p-e-r-o, p-e-r-o, p-e-r-o, por defecto es algo mas amigable y 🌈moderno🌈 (1987 vs 2007) aunque ambos estan escritos en c

y cual escogeria screen o tmux? pues, tmux! aunque si hay necesidad, se usar los dos!

y ahora, como usarlo

> tmux

como vemos, a diferencia de screen, tmux se nos comera una fila al final de la pantalla, muy a lo emacs. Otra diferencia particular, empieza por el prefijo, que en lugar de ser C-a pasa a ser C-b (y encuentro mas comodo). Ademas de eso al dividir la pantalla en sus diferentes formas

  • C-b " division horizontal
  • C-b % division vertical

aparecera una shell sin hacer nada mas

podemos deambular por las “divisiones” con

  • C-b o saltar a la siguiente
  • C-b ← saltar a la derecha
  • C-b ↑ saltar arriba
  • C-b → saltar a la derecha
  • C-b ↓ saltar abajo
  • C-b C-← redimencionar hacia la derecha
  • C-b C-↑ redimencionar hacia arriba
  • C-b C-→ redimencionar hacia la derecha
  • C-b C-↓ redimencionar hacia abajo

tambien centrar la atension en la shell actual sin romper la distribucion de las ventanas con C-b z (zoom) y luego restaurar con otro C-b z

o incluso y mas locochon, hacer que las shells cambien de sitio con C-b C-o

o hacer aparecer un reloc ascii gigante con C-b t

u otras cosas mas chulas como agregar “nuevos escritorios” con C-b c

e ir y venir entre escritorios con

  • C-b n siguiente
  • C-b p anterior
  • C-b 0, C-b 1 C-b …, escritorio 0, escritorio 1, …

o C-b w, que nos permite elegir visualmente

salir de esta secion sin cerrarla con C-b d y recuperarla con tmux attach

tambien, podriamos no salir de dicha sesion e ingresar en ella desde otra terminal, repitiendo tmux attach

que hace una cosa muy chula; adaptarse y limitar lo que se ve en la sesion con las dimenciones de la mas pequeña. Ademas, como en screen podemos darle un nombre a una sesion y vincularnos a ella

> tmux new-session -s mi-sesion # lanzar
> tmux attach -t mi-sesion      # conectar
> tmux list-sessions            # listar sesiones

esto y muchas cosas mas que pueden o no ser de interes, empiezan consultando la ayuda incluida C-b ?, su pagina man o si se desea un librillo con comentarios

https://leanpub.com/the-tao-of-tmux/read

aunque creo que el nombre “the tao of” le viene grande, pues no enseñan un flujo o estrategia de trabajo. Solo comandos con imagenes, que puedes descubrir por tu cuenta, como el obscuro proceso para congelar la pantalla, seleccionar texto y pegarlo en donde se nos ocurra aun sin sesion grafica!

en fin, yo estoy utilizando tmux para dejar corriendo en el servidor comandos de prolongado tiempo y tambien para ejecutar weechat “acumulando logs” por dias y dias en salas de irc… mera investigacion de la fauna…

happy hacking!

-1:-- temax (Post )--L0--C0--September 20, 2018 07:03 PM

nba - GNU's Rock: elipo

Recuerda, “No tiene que gustarte Emacs para que te guste”––Emacs puede tener diferentes colores, diferentes comandos y diferentes atajos que el Emacs por defecto. {AItPiEL}

An Introduction to Programming in Emacs Lisp

git clone https://gitlab.com/nasciiboy/elipo.git
# o
git clone https://notabug.org/nasciiboy/elipo.git

para descarga en formato zip, tar, o bien visionar directamente en version web en ingles y español

“Una introducción a la programación en Emacs Lisp” es una guia turistica por los conceptos basicos de la programacion, recorriendo las entrañas mas emblematicas en “las fuentes” de GNU Emacs, el “editor extensible”.

El documento es un primer acercamiento gentil, mas o menos claro y muy reiterativo a Emacs Lisp, que a un iniciado en la programacion deseoso por utilizar el verdadero potencial de emacs le vendra de maravilla. Menciono que a un iniciado, por que asi es mi caso, y me costaria recomendarlo como primer libro de programacion. Aun asi, utiliza buenas analogias e introduce los conceptos base de forma tan gradual como para no descartarlo (por completo) como libro novel.

A lo largo del material, aprenderemos ademas de los fundamentos de la programacion (variables, bucles, recursividad, funciones, …, listas), a crear atajos personalizados para las funciones de Emacs, como tambien a definir las nuestras propias, a manipular y construir listas lisp, visitar buffers, mover el punto, utilizar la region, crear funciones interactivas, a conocer el anillo de la muerte y en ultima instancia a enterarnos con certeza de lo que hacemos con nuestro init.el

…bueno, el texto esta un poco anticuado fue escrito con la version 22 (2007-2008) en mente, pero en la practica (practicamente) todo el codigo aun es aplicable, exeptuando algunas pocas funciones y configuraciones relacionadas con X Window

Antes ya habia realizado otros acercamientos a lisp como “The land of Lisp” (traduciendolo “informalmente” como hasta un 2X%) y tambien con ANSI Common Lisp, pero este ha sido el primer libro que termino y donde (mas o menos) llego a comprender las bases de Lisp… sin masterizarlo a profundidad, pues el libro no abarca conceptos como la metaprogramacion, macros y el potencial de las funciones lambda (quien sabe que signifique todo eso…)

De momento Lisp me continua pareciendo un lenguaje curioso, con algo de elegancia (no demaciada), medianamente “retro” y un poco tosco en lo que a adquirir documentacion y uso de librerias se refiere

Muchos aspectos son forzados a encajar en el molde de las listas y en otros tantos, como las “formas especiales”, simplemente se ignoran en pro de la practicidad

Mi calificacion?

  • No es una perdida de tiempo

  • Necesario si quieres profundizar en emacs o descubrir la superficie de lisp

  • Sin ser una lectura ipnotizante, tampoco es soporifera. En ocaciones cuesta seguir las ideas del autor, pero es apreciable que sin ser un escritor de profesion o vocacion (supongo) se esforza por plasmar su conocimento lo mas claro que le fue posible

porg

No recuerdo si fue en alguna busqueda de Emacs-material, en irc o directamente el la pagina de David Arroyo donde con alegria incontrolable descubri la existencia de una traduccion al español (en apariencia terminada) de este titulo, que ademas de tener una version en PDF y texinfo, contaba con el material impreso.

Con la mayor alegria que puede albelgar un aprendis del silicio y en particular usuario de Emacs que poco entiende del lenguaje ingles, procedi a descargar el PDF para recorrerlo con deseo. Sin embargo, al poco de leer, fue evidente que la version tenia defectos apresiables aun para un completo perdido del engrish.

Incredulo, supuse que la version digital y la impresa tenian algun (compresible) desfase comercial y fui directamente al repositorio donde se albergaba la fuente. Para descubrir que el material era tal cual el del repositorio

No negare que un fuerte sentimiento de desilucion aparecio al ver que habria que hecharle esfuerzo para tener un material compresible. Aunque viendolo desde otro angulo, ya habia personas que habian invertido tiempo y energia preparando el material. Que menos que unirse a la causa para sumar al material, o tan siquiera dejarlo en un punto que fuera util a mis egoistas fines

Segun el repo, la primer contribucion que hice fue el 30-05-16, pero aunque intente mantenerme constante, encontre que traducir mediante un fichero .po que ademas esta documentado en texinfo es bastante engorroso. Sumado a esto, las taras ortograficas y traductorias que cargo que son bastas (e incorregibles…), como resistirme a colocar acentos o a pasar un corrector ortografico y ademas tener en esas fechas algunos experimentos bizarros para un lenguaje de marcas ligero que cumpliera todas mis ridiculas exigencias, condujeron a que hiciera un “fork” del proyecto

“fork” etre comillas, porque no cargue con el material original. Fue una adaptacian express al lenguaje experimental de aquel tiempo (aun sin exportador, ni nada) y tras “corregir” cerca del 30% perdi la motivacion….

el asunto se fue aparcando, el formato de marcado ligero cambiando y poco interes tenia por actualizar

hasta que por diciembre del 2017 lo retome esporadicamente y luego de bastantes seciones, pues lo doy por “usable” y digno de ser compartido bajo unos pobres estandares.

Eso si, no sera ningun logro literario, pero no negare que visualmente tanto las versiones web y en morg, tienen un acabado de puta madre. Ha quedado bien chido y “profecional”

Sin embargo, la parte de la traduccion que no se como inicio, pero creo fue obra del traductor de google (y en un inico continue con la tradicion hasta que aparecio deepl) (por mi parte) consistio apenas en darle sentido a los parrafos

En muchas (por no decir que en todas) las seciones, terminaba por entrar en una face cercana al sueño y dejando presionada una tecla indefinidamente. Iniciaba una alerta de regresar a la consciencia, y… volvia a controlar la somnolencia, unos minutos mas antes de desistir.

Otro de los bellos detalles que inclui, fueron palabras con sus caracteres en posiciones alteradas de sitio. Asi como palabras repetidas y poca atencion al formato

Hay varios sitios donde es necesario hacer mas digerible la transmicion de ideas y otros donde por la falta de conocimiento del engrish solo intuia el sentido e inventaba el resto

Algunas traducciones no son consistentes, otras dificiles de transladar y unas mas se asume que ya se entienden, por ejemplo las funciones y conceptos narrow y widen, que deje como reducir y extender

Donde decia “computer” al principio substitui con computador, pero termino como ordenador, y asi otros tantos detalles

Por el lado del codigo, el proyecto de traduccion original (de libre-manuals) planeaba adaptar el codigo a una version reciente. Por parte mia, y ya que segun la wikipedia el autor de esta obra (y otras mas) Robert J. Chassel murio en 2017, he preferido dejarlo (casi en su mayoria) tal cual. (Alguna cosa cambie pero no recuerdo que exactamente.)

Otra cosa importante, es que todas las regiones de texto en el original dentro de un bloque texinfo ignore, las extripe de las versiones a “morg”. Considere que eran comentarios y ya que estaban inconclusos los quite.

Asocia la tecla ‘Bloq Mayus’ a ‘Control’ (Una interfaz de usuario tan rota, sugiere que los fabricantes de teclados piensan que las computadoras son máquinas de escribir de 1885.) {AItPiEL}

Y luego del momento de monolo, el producto central esta en los siguientes repos

git clone https://gitlab.com/nasciiboy/elipo.git
git clone https://notabug.org/nasciiboy/elipo.git

tambien hay uno en github, pero los repos hay presentes (todos inconclusos) los he congelado y/o estan en proceso de migracion hacia gitlab

Para quien desee intervenir el material, recomendaria primero leer acerca del (cambiante y experimental) lenguaje de marcas ligeras morg y si se quiere profundizar mas, seguir la etiqueta morg en este blog.

El fichero donde deben realizarce las modificaciones tanto en español, como en ingles es emacs-lisp-intro_es.porg

Para facilitar la labor, utilizo org-mode para algunas funcionalidades, como escribir listas y tener outline-mode. Algunas de las configuraciones que se pueden agregar a init.el para ayudar un poco, son:

(add-to-list 'auto-mode-alist '("\\.morg\\'" . org-mode))
(add-to-list 'auto-mode-alist '("\\.porg\\'" . org-mode))

;;; resaltado primitivo y no siempre certero de la sintaxis
(add-hook 'org-mode-hook
          (lambda ()
            (highlight-regexp "@[^[<({]+[[<({][^]>})]+[]>})]" 'hi-green-b)
            (highlight-regexp "@[[<({][^]>})]+[]>})]" 'hi-red-b)
            (highlight-regexp "@[^[<({]+[[<({][]>})]" 'hi-red-b)
            (highlight-regexp "[[:space:]]@[[:space:]]" 'hi-yellow)
            (highlight-regexp "@[a-zA-Z]+[[:space:]]" 'hi-yellow)
            (highlight-regexp "^ *@ +.*" 'hi-pink)
            )
          )

me parece que el programa que esta en los repositorios y el que utilizo en mi sistema para realizar la exportacion, difieren un poco… estaba en proceso de refactorizacion e inesperadamante cai en un bucle de poscastinacion y falta de ideas.

En los planes esta que las versiones finales de ficheros (en|es|..|xx|).morg puedan mesclarze, traducirse automaticamente, compararse, reformatearse y demas. Pero ante mi ineficacia, para este material recurri a simples trucos para generar la versiones finales apartir del fichero .porg

para producir la traduccion en español, solo tienen que borrarse todas las lineas que inicien con #. Para generar la version en ingles, mantener todas las lineas vacias y que inicien con #, y luego eliminar el # inicial mas un caracter en blanco (si lo hubiera)

he colocado unas cripticas instrucciones en el .porg, para generar ambas versiones.

De .porg a en.morg y ademas exportacion a html, seria:

awk 'length == 0 || /^#/' emacs-lisp-intro_es.porg | sed -e 's/^# \?//' | sed '8,11d' > emacs-lisp-intro.morg && morg toHtml emacs-lisp-intro.morg

y de .porg a es.morg con exportacion a html:

morg unPorg emacs-lisp-intro_es.porg && morg toHtml emacs-lisp-intro_es.morg

Si se desea verificar que los enlaces en las exportaciones html apuntan a algun lado, se puede utilizar linkchecker (presente en los repositorios de debian)

linkchecker emacs-lisp-intro_es.html --check-extern

algunas convenciones

cuando despues de un atajo se incluye el nombre de la funcion que invoca “entre parentesis”, utilizo la sintaxis @%c(nombre-de-funcion)

cuando despues de un palabro en español o ingles se coloca su equivalente en el otro idioma, utilizo la sintaxis @%i(traduccion/original)

En el documento origital varias “piezas de codigo” se colocaban entre comillas simples. Cuando lo considere pertinente y que ofrecia un mejor resaltado utilice @'c(pieza-de-codigo)

Por falta de mejora en el exportador, y sombretodo, como un apaño, dentro de los bloques de codigo, deben respetarse los espacios en blanco. Si un bloque de codigo en el original tiene una linea de espacio en blanco, debe intercaralse forzosamente el codigo en ingles, colocando la traduccion al español y que ambos bloques compartan la linea en blanco

En el original, habia condiciones para que al exportar el fuente los enlaces externos a los manuales de Emacs y Emacs Lisp estubieran accesibles desde info y en caso de exportar en un formato diferente, desde la ruta web.

un proposito futuro, es replicar este comportamiento (una vez adaptadas esas dos obras a morg), pero eso puede tardar mucho o nunca suceder. Para mantener la funcionalidad, en principio substitui toda referencia a dichos recursos con la ruta web al manual mono-pagina. Pero para evitar peticiones de varios megas a gnu.org, con la lentinud que ello conlleba, termine por colocar en el repositorio verciones locales de estos en formato web mono-pagina

En el original creo que las citas con comillas dobles y sencillas y ---, se aplicaban mediante sintaxis texinfo. Para mejorar la legibilidad en el fuente, se modificaron a “cosas”, ‘cosas’y ––. El formato morg, tiene comandos para aplicar los mismos efectos: @"(cosas), @'(cosas) y @-(cosas). Sin embargo el ultimo no esta adaptado para casos “especiales” si las cosas tienen llave de apertura pero no de cierre. Aun considero cambiar todas las apariciones “legibles a simple vista” por su version en comando, pero no lo termino de decidir

Disfrut! Bienvenidas las peleas, asesorias programacionales a morg, los exportadores de texinfo a morg, los tenedores, monitores 2K y sobre todo, el sucio dinero!

-1:-- elipo (Post )--L0--C0--July 29, 2018 05:19 PM

nba - GNU's Rock: pwds

Por lo habitual, mi uso de Emacs va emparejado con una terminal y auxiliado por el navegador de ficheros (y firefox). Asi que lo mas conveniente seria poder sincronizar las rutas de trabajo entre Emacs, Tilix (terminal) y Nautilus (navegador grafico de ficheros) sin tener que escribir cada vez la ruta entera, o andar pinchando con el raton en botones visuales

la solucion (quitando el glamour de la frace “sincronizar las rutas de trabajo de …“) consiste simplemente en copiar la ruta actual de cada programa al portapapeles

tilix

la eleccion de este emulador de terminal (ademas de por su gnomero estilo y su personalizacion de atajos profunda) se encuentra fundamentada en incorporar marcadores de fabrica. Sin embargo, optener la ruta actual y copiarla directamente al portapapeles no es una de sus caracteristicas… y por ello la solucion puede aplicarse a cualquier emulador de terminal.

para saldar la limitacion usaremos el programa xclip (buscar en el repositorio de su distribucion), en conjuncion con pwd y tr (para eliminar el salto de linea producido por pwd)

pwd | tr -d '\n' | xclip -sel clip

el comando se explica por si mismo…

otro comando que tambien suelo utilizar habitualmente para “ajustar” las fechas en los post de este blog:

date --iso-8601=seconds | tr -d '\n' | xclip -sel clip

si bien, el recordar estos comandos a primera vista parece (y lo es) una meta imposible, ya que utilizo fish como interprete y como este se encuentra en modo historial permanentemente, solo tengo que ingresar o pwd o data y el solito se encarga de completar el comando. De esa forma evito crear un script especifico para copiar cosas entre el terminal y el resto del entorno grafico

nautilus

pues nada, aunque tiene sus marcadores, si se presiona la combinacion C-l nos muestra y selecciona la ruta actual… Copiar, modificar o pegar!

Emacs

los marcadores en emacs, ademas de diferenciarlo del resto de la “competencia” lo convierten en un asistente muy potente. La cuestion es como comunicar las rutas de trabajo con el portapapeles del entorno

La solucion mas sencilla es entrar en modo dired para seleccionar y matar la ruta actual, y como la ultima entrada en el anillo de la muerte tiene comunicacion directa con el cortapapeles, tendriamos resuelto el problema… pero, ya que emacs se puede adaptar a nuestras necesidades, extendamos su funcionalidad para que copie directamente en el clipboard tanto la ruta de trabajo, como la ruta del buffer actual

(defun pwd-to-kill-ring ()
  "Agrega la ruta actual al kill-ring."
  (interactive)
  (kill-new default-directory))

(defun buffer-path-to-kill-ring ()
  "Agrega la ruta del buffer actual al kill-ring."
  (interactive)
  (if (buffer-file-name)
      (kill-new (buffer-file-name))
    (message "El buffer actual no esta ligado a un fichero")))

(global-set-key "\C-cp" 'pwd-to-kill-ring)
(global-set-key "\C-cf" 'buffer-path-to-kill-ring)

listo! con unas modificaciones minusculas tenemos nuevas funcionalidades y atajos vinculados a estas. C-c p para optener el pwd y C-c f (si el buffer actual esta vinculado a un fichero) para optener la ruta absoluta a la fuente del buffer, o en su defecto un amigable mensaje “El buffer actual no esta ligado a un fichero”

(mencionar que emacs posee el comando cd con el que podemos modificar manualmente el pwd al que apunta, como tambien un comando nativo pwd. Este pwd cambia automagicamente segun el buffer en el que estemos)

ido-mode

como el shell fish tiene un sistema de autocompletado de rutas automagico (fusionado con el historial), emacs no podia ser menos y deberia proveernos ayuda con el autocompletado de las rutas.

el modo ido nos proporciona autocompletado con “busqueda difusa” de patrones y esta disponible para la busqueda de ficheros, directorios y buffers

de inicio, es un poco lioso y si presionas tap sin antes ver que es lo que hace ido puedes verte creando ficheros en rutas inesperadas. Uno llega a cogerle el truco, pero en ultima instancia es posible desactivar sus “ayudas”

ido forma parte de la distribucion estandar, asi que no tenemos que instalar nada, solo configurarlo un poco

(require 'ido)                    ; invocar a ido
(setq ido-enable-flex-matching t) ; activar busqueda difusa
(ido-mode t)                      ; activar ido

con esto (hasta donde he podido percatarme) ido usurpara el lugar de los comandos vinculados a C-x C-f, C-x d, C-x C-d, C-x i, C-x C-w y C-x b.

Para utilizarlo basta con escribir tap para completar automagicamente y usar las flechas derecha e izquierda para navegar entre las opciones.

No hara falta escribir el nombre preciso del siguiente elemento en la ruta, con escribir algunos caracteres, por ejemplo la extencion de lo que buscamos, seguramente sea suficente.

en caso de que queramos desactivar ido y regresar temporalmente al comando que este suplantando, basta con presionar C-f. Si con esto no es suficiente y se desea apagar ido pues M-x ido-mode, o siendo mas radical, (mientras nos habituamos) podemos vincular su activacion/desactivacion a un atajo

(global-set-key (kbd "C-c .") 'ido-mode)

compile

la mayoria de los programas que realizan algun tipo de inspeccion en un fichero, como pueden ser compiladores, exportadores de formatos o programas de busqueda de patrones, suelen lanzar resultados con el formato

ruta-de-fichero:linea: "cosas"

o

ruta-de-fichero:linea:columna: "cosas"

el comando compile de emacs, se aprovecha de esta convencion para permitirnos navegar entre los ficheros que indique nuestro programa, de una forma mas comoda de lo que seria buscar directamente a mano el fichero, su linea y columna.

cuando se invoca al comando compile (M-x compile) nos pedira un comando (del sistema) a ejecutar, este podria ser por ejemplo gcc mis-cosas.c, make o por que no, grep!

Para buscar todas las coincidencias en una ruta!

M-x compile RET grep -Rn patron [ruta-opcional]

(M-x compile RET grep -Rn package ~/nconf/emacsRocks/)

sorprendente!

para navegar, entre las coincidencias podemos cambiar entre ventanas (C-x o) y dar enters en las lineas resaltadas, o, presionar C-h m y averiguar que combinaciones trae por defecto compile.

ja, ja, ja, aunque la utilidad del comando es evidente, a los peresosos emacsers les da mas por laborar una vez y descanzar eternamente. Por ello tenemos dos modos disponibles para hacer busquedas “a lo grep”.

El primero viene incorporado y se llama occur, vinculado a M-s o. El inconveniente es que las busquedas se limitan al buffer actual.

El segundo, basa su funcionalidad en un (nuevo) comando del sistema llamado ag (The Silver Searcher) que es algo asi como un grep super rapido, configurado para actuar recursivamente por defecto

hay un modo para unir en armonia tanto a compile como a ag para ello (como recomiendan en su repositorio) tendriamos que clonar el fuente y agregar lo siguiente a nuestro init:

;; source: git clone https://github.com/philsnow/ag.el
(add-to-list 'load-path "~/ruta/a/carpeta/ag.el")
(require 'ag)
(setq ag-highlight-search t)

para utilizar el comando: M-x ag RET patron RET ruta

… y eso es todo, happy hacking!

-1:-- pwds (Post )--L0--C0--April 26, 2018 09:07 PM

nba - GNU's Rock: Keep Regexp

es muy vergonZoSo sentirse capaz y al enfrentar un reto quedarse congelado al borde del fracaso

El asunto es el siguiente, tenemos un fichero con correos (muchos correos, 79 exactamente). El fichero ademas de los correos incluye nombres y comas y la meta es obtener unicamene los correos.

Empece el reto substituyendo comas por saltos de linea, luego probe una complicada regexp para buscar los correos, pero tras muchos fallidos intentos, abandone la idea… ademas, que esperaba encontrando la regexp? no es como si la coincidencia colocara la region en la coincidencia y luego se pudiera “cortar” y “pegar”

Lo siguiente, fue utilizar el comando flush-lines para borrar las lineas que no coincidieran con el patron [^@], “obviamente” no funciono, auque en mi ignorancia culpe al patron… (risa histerica) y bueno, sucede que no te aclaras y hasta se te olvida utilizar la ayuda del emacs

un par de intentos mas tarde, termine por utilizar una poco elegante macro, que cumplia el objetivo chapuceramente

luego, tras ver la primer solucion, mas simple, conpacta, no del todo “segura”, pero para el caso efectiva

cat lista_correos.txt | tr " " '\n' | grep @ | xargs

e inmediatamente despues un vi-liever solucionaba el asunto con

:%s/  */^M/g
:v/@/d
:%join

como podia evitar la inminente culpa y herida en el orgullo klingon-emacsero?

intetentando superar la frustracion, dio inicio un aprendizage formal y profundo de las regexes en emacs y alguno que otro comando mas. Pero antes de pasar a ello, fue nesesario aminorar el trauma implementando una solucion en awk y otra en C….

# esto a un fichero, por ejemplo a.awk
1 {
    for( i=1; i<=NF; i++ )
        if( $i ~ /@/ ){
            printf( "%s\n", $i)
        }
}

# y luego ejecutar con:
# $ awk -f a.awk lista_correos.txt

aca la solucion con C. Compilar con gcc a.c regexp4.c y ejecutar con $ a.out lista_correos.txt

Un dia despues, con la agonia mental aun fresca, llego la solucion en emacs

M-<
M-x replace-regexp RET " +\|," RET C-o RET
M-<
M-x keep-lines RET "@" RET

(no conocia keep-lines si tu tampoco, te la presento. Ignorar las comillas son para delimitar la cadena de entrada)

ciertamente mas extensa que vi, pero consideremos que emacs no tiene una simbiosis con el comando sed, ni tampoco una implementacion de sus comandos de tal forma que puedan ejecutarse “en bloques”. No esta tan mal, supongo.

aqui es donde se podria iniciar una “guerra santa”. Pero bueno, la naturaleza extensible e ilimitada de emacs para un tema concreto puede ser menos eficiente, es cierto… aunque, nada impide que se implemente un comando interprete tipo sed e incluso otro para aplicar acciones por lineas y de manera global (sin recurrir a macros)

Supongo que los usuarios del modo maligno, han hecho algo asi, mas profanar emacs con tales paganismos, ni utilizar “modos” que fuerzan a presionar ESC de forma inconciente, son algo a contemplar por mi parte, las cosas “modales” son un dolor, ya es suficientemente modal tener que usar el firefox, o el navegador de ficheros y andar presionando ahi teclas de otros “modos”

o, por aca un semi-equivalente en elisp de la solucion

(defun emailtor ()
  "Separa los correos en lista_correos.txt"
  (interactive)
  (goto-char (point-min))
  (while (re-search-forward " +\\|," nil t)
    (replace-match "\n" nil nil))
  (goto-char (point-min))
  (delete-non-matching-lines "@"))

ha, no es lo mas fino, pero para el caso cumple

regexp

  • Conjunto []. Conjunto inverso [^]. Dentro de los conjuntos (con la syntaxis completa [[:clase:]]) se permiten las clases

    • [:alnum:] caracter alfanumerico
    • [:alpha:] una letra, incluidos caracteres unicode
    • [:blank:] espacio y tabulacion
    • [:cntrl:] caracteres ASCII de control
    • [:digit:] numeros ascii del 0 al 9
    • [:graph:] cualquier caracter visible, exepto espacios en blanco
    • [:print:] cualquier caracter visible, incluidos espacios en blanco
    • [:lower:] caracteres en minusculas
    • [:upper:] caracteres en mayusculas
    • [:punct:] signos de puntuacion
    • [:space:] espacios en blanco
    • [:word:]caracteres que formen parte de las palabras
    • [:xdigit:] caracteres hexadecimales (0-9, a-f y A-F)
    • [:ascii:] caracter ASCII
    • [:nonascii:] cualquier caracter no ASCII
    • [:multibyte:] caracteres unicode multibyte
    • [:unibyte:] caracteres codificados en un solo byte (basicamente todo ASCII)
  • punto .

  • metacaracter \

  • agrupacion y captura \(\)

  • coincidencia con la anterior captura \d. (Substituir d por el numero de captura)

  • agrupacion sin captura \(?:\)

  • alternativa \|

  • cuantificadores

    • ? cero o uno
    • * cero o mas
    • + uno o mas
    • \{n\} exactamente n
    • \{n,\} n o mas
    • \{n,m\} entre n y m
  • modificadores

    • $ coincidencia al fin de linea
    • ^ coincidencia al inicio de linea
    • \= coincidencia en la posicion del punto
    • \' coincidencia al final del buffer
    • \` coincidencia al inicio del buffer
  • fin o inicio de palabra \b

  • (deacuerdo al modo) un caracter que forme palabras \w o \sW

  • (deacuerdo al modo) un carac,ter que no forme palabras \W o \Sw

  • espacios \s- o \s (”\s”)

  • symbolos \s_

  • delimitador de apertura \s(

  • delimitador de cierre \s)

  • caracteres de puntuacion \s.

comandos de utilidad

  • (search-forward) busqueda de texto hacia adelante
  • (search-backward) busqueda de texto hacia atras

  • C-s (isearch-forward) busqueda de texto de forma interactiva hacia adelante

  • C-r (isearch-backward) busqueda de texto de forma interactiva hacia atras

  • (search-forward-regexp) busqueda de regexp hacia adelante

  • (search-backward-regexp) busqueda de regexp hacia atras

  • C-M-s (isearch-forward-regexp) busqueda de regexp de forma interactiva hacia adelante

  • C-M-r (isearch-backward-regexp) busqueda de regexp de forma interactiva hacia atras

  • M-s o (occur) listado interactivo de lineas que coinciden con la regexp

  • (replace-string) substitucion de texto

  • (replace-regexp) substitucion de regexp

  • M-% (query-replace) substitucion interactiva de texto

  • C-M-% (query-replace-regexp) substitucion interactiva de regexp

  • (highlight-lines-matching-regexp) resaltar cualquier linea que coincida con una regexp

  • (highlight-regexp) resaltar una regexp

  • (unhighlight-regexp) des-resaltar regexp

  • (flush-lines) eliminar lineas que coincidan con la regexp. (el patron ^$ eliminara todas las lineas en blanco)

  • (keep-lines) se eliminan las lineas que no coincidan con la regexp

  • (align-regexp) alinea (verticalmente la parte en varias lineas que coincida con la regexp

re-builder, isearch, isearch+

De entre las muchas cosas relacionadas con regexes, el modo re-builder es uno muy interesante, pues nos permite escribir y editar una regexp con suma facilidad y luego copiar el resultado.

Supongo que este modo, es una facilidad para los programadores de emacs, basandome en que la expresion esta entrecomillada y al copiar la regexp con el comando reb-copy (C-c C-w) incluye las comillas y ademas el formato de escape de caracteres esta dispuesto a la forma que requiere el codigo fuente en elisp.

Dicho escape de caracteres y metacaracteres, se debe a la naturaleza de las cadenas en C de hay que las cosas suelan requerir escapes para los escapes. Por defecto re-builder viene en modo de syntaxis read que es de la que hablo, pero tambien podemos cambiar a sintaxis string (la que utiliza isearch), bien presionando la combinacion C-c TAB y escribiendo string o directamente colocando lo siguiente en nuestra configuracion

;; re-builder
(setq reb-re-syntax 'string)

pese a la facilidad de edicion y creacion de regexes, me pregunto la razon de no vincular este modo con isearch. Mas adelante (o no) una posible razon y un par de soluciones.

los comandos basicos de utilidad

  • C-c C-w copiar regexp (comillas incluidas)
  • C-c C-q salir del modo
  • C-c TAP cambiar syntaxis de entrada
  • C-c C-r ir a coincidencia previa
  • C-c C-s ir a coincidencia siguiente

isearch en sus modalidades mas conocidas isearch-forward-regexp (C-M-s) e isearch-backward-regexp nos permiten buscar expresiones regulares hacia adelante y hacia atras del punto interactivamente, mas no dejeis que os engañen las funciones basicas de estos comandos, pues no son simples comandos, son modos por si mismos, podemos averiguar sus muchas posibilidades (ya dentro de isearch) presionando C-h m o con la documentacion de la funcion C-h f isearch-forward-regexp

quiza el comando mas conocido de las busquedas interactivas sea C-w que toma la entrada sobre y delante del punto como texto de entrada (dividida por palabras). Pero ademas de esa combinacion tenemos otras muy interesantes

  • M-s e para editar “con papeles” la regexp, aunque no interactivamente
  • C-M-y ingresar a la regexp el caracter del buffer sobre el que esta el punto
  • C-M-w borrar el ultimo caracter de la regexp
  • M-s C-e ingresar a la regexp el resto de la linea apartir de la posicion del punto
  • C-y traer ultima cadena del anillo de la muerte
  • M-y iterar sobre el contenido del anillo de la muerte
  • M-c cambiar la sensivilidad a las mayusculas-minusculas
  • C-s siguiente coincidencia
  • C-r anterior coincidencia

y muchas otras cosas misticas y confusas mas trae el modo. La cuestion problematica tiene que ver con la forma en que isearch incorpora el contenido del anillo de la muerte a la busqueda, pues si por ejemplo matamos la cadena \(group\)[set] al hacer el yank (C-y) en lugan de ingresar \(group\)[set] escapara los caracteres significativos en la regexp, dejando \\(group\\)\[set] lo que obligaria a editar de forma penosa la expresion

preguntando en reddit, el unico lugar donde aparecen respuestas prontas y en ociones con feliz resultado, oantolin proporcionaba el siguiente comando alternativo para hacer el yank con su contenido tal cual dentro de la expresion

(defun isearch-yank-kill-literally ()
  "Pull string from kill ring into search string literally."
  (interactive)
  (setq isearch-yank-flag t)
  (let ((string (current-kill 0)))
    (isearch-process-search-string
     string
     (mapconcat 'isearch-text-char-description string ""))))

(define-key isearch-mode-map (kbd "C-S-y") #'isearch-yank-kill-literally)

como puede verse, se sugiere la vinculacion al atajo Control-Super-y, pero en mi caso me es incompatible con otro comando… lo que sirvio fue suplantar directamente el comando yank de isearch dejando como nombre de la nueva definicion solamente isearch-yank-kill

cabe aclarar, que la copia tal cual del contenido del anillo de la muerte, no es una caracteristica considerada de inicio en isearch, por lo que al hacer un M-y, el demas contenido del anillo seguira siendo modificado con escapes. De hay que otro colega, 00-11, suguiriera el uso del modo isearch+, que si considero esta necesidad en su base

isearch+ (supongo) es una capa sobre el modo isearch que ademas de agregar la posivilidad de hacer yanks sin modificar el contenido, nos colorear la busqueda en secciones y proporciona varios comandos de utilidad extra. Todo esto manteniendo los atajos de isearch (casi) intactos

isearch+, no viene en el repositorio melpa, para instalarlo deberemos copiar directamente su codigo desde emacswiki a un fichero, y luego cargarlo “a mano”.

https://www.emacswiki.org/emacs/download/isearch%2b.el

En el mismo fichero proponen cargar el modo con el comando

(eval-after-load "isearch" '(require 'isearch+))

pero he preferido agregar lo siguiente en mi init

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PACKAGE*: isearch+            ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; source: https://www.emacswiki.org/emacs/download/isearch%2b.el
(load-file "~/.emacs.d/plugins/isearch+.el")

vamos con la justificacion de utilizar isearch+, que era poder hacer yanks.

En la linea 2547, tenemos la variable customizable isearchp-regexp-quote-yank-flag que si la ponemos a nil, asi

    (defcustom isearchp-regexp-quote-yank-flag nil

nos dara el resultado que buscamos.

Si, se puede hacer el cambio de la varible en el init, pero ya que tenemos y vamos a cargar el codigo directamente, mejor dejarse de historias y hacer el cambio in-situ

(nota: al cargar isearch+ substituye automaticamente a isearch. He probado el modo con emacs 25 sin ninguna extencion y funciona sin problemas)

ahora si, despues de tener isearch+ configurado, podemos escribir nuestra funcion en re-builder (modo de syntaxis string) y copiar la regexp (manualmente) ignorando los parentesis, para luego “pegarlo” directamente en isearch(+) con un yank

Enlaces, fuentes y otras cosas

-1:-- Keep Regexp (Post )--L0--C0--April 08, 2018 04:50 PM

nba - GNU's Rock: The Holy War

Post original (04/12/2001) -> https://www.linux.com/news/emacs-vs-vi-endless-geek-holy-war

Author: JT Smith

Ahí van de nuevo. El presidente de nuestro grupo local de usuarios de Linux envió el mensaje de que el tutorial de la semana sería cancelado. El hecho de que el tutorial fuera sobre el uso del editor de texto vi fue suficiente para iniciar una nueva ronda de tiros de última hora.

Greg Menke disparó la primera salva. Usar vi? ¿Qué tan difícil puede ser? Envió por correo electrónico sus propios pasos para usar vi. Fueron estos:

  1. Adquirir un pecado, de cualquier tipo, longitud > 30 cm

  2. Congelarlo durante la noche

  3. Siéntese frente a la PC, ejecute vi

  4. Sosteniendo el pez por la cola, golpéelo repetidamente contra su frente hasta que decida darle una oportunidad a EMACS porque las escamas de pescado están volando alrededor de su cabeza y comienza a doler.

Menke, por supuesto, insinuaba que no sólo vi era insensatamente obstinado sino que los usuarios de vi también lo eran por negarse a admitir cómo se estaban infligiendo a sí mismos brutales golpes en la cabeza con un pescado congelado.

No tardó mucho para que los amantes de vi devolvieran el fuego. Uno sugirió a Menke que agregara esta línea a sus instrucciones: Escriba 'emacs' antes del paso 1, para que cuando el paso 4 esté hecho, finalmente haya terminado de cargarse.

¿Intentaba decir que EMACS es lento?

Al igual que los batallones fatigados por la lucha llegan a una tregua temporal pero se niegan a abandonar la guerra, los usuarios de vi y EMACS mantienen un intranquilo punto muerto en GNU/Linux, SAGE y muchas comunidades virtuales relacionadas con computadoras. Es el tipo de empate que puede permanecer inactivo durante meses, pero sólo se necesita una pizca de vaguedad de un lado para que una vez más las llamas se propaguen por los grupos de noticias y las listas de correo. Porque justo por debajo de su conducta civilizada, cada bando siente que el editor que usa es el mejor de todos los editores posibles y aquellos que usan cualquier otro editor, particularmente ese otro editor, son tontos que se daran cuenta de su erronea forma de pensar aunque sólo sea posible a base de muchas burlas.

Ahora, una escision sobre cual editor de texto en Unix es una construccion del mismisimo Dios puede no parecer significativa dados todos los problemas del mundo, un empate de Coca-Cola vs. Pepsi sin consecuencias, sin motivaciones más allá de la simple unión grupal (¡Vamos Equipo!).

Pero, ¿por qué esta diferencia de puntos de vista ha seguido siendo un divisor de la cultura de los programadores durante más de dos décadas? ¿Por qué ha permanecido intacta en el PC, luego de que las interfaces gráficas de usuario, el ratón, Internet y el código abierto han alteraron el panorama computacional?

Desde que tengo uso de razon, la población de hackers se ha dividido 50/50 [entre] EMACS [y] vi, escribe en un email Eric Raymond, quien tiene varios roles en las comunidades de software de código abierto y hackers como antropólogo observador y participante desde hace mucho tiempo. Pico, Joe, MicroEmacs, y otros editores han estado básicamente abajo en el ruido estadístico durante todo el período. Raymond puede datar personalmente la división vi/EMACS en 1985 y estipula que, con toda probabilidad, fue mucho antes de eso.

Ya en 1991, Raymond registro la guerra santa vi vs. EMACS en el Jargon File, quizás la colección definitiva de la terminología hacker.

Cuando se presiona, la mayoría de la gente familiarizada con ambos editores dirá que la diferencia entre los dos es de velocidad vs. flexibilidad, con los usuarios de vi señalando lo rápido que pueden moverse y los amantes de EMACS pregonando su inmenso número de opciones. Los usuarios de vi se burlan de EMACS por ser innecesariamente ostentosos; los usuarios de EMACS se burlan de vi por ser difícil de aprender y tener un alcance limitado.

Así que el gran debate del editor de textos de nuestro tiempo se reduce al equivalente técnico del gustos menos/o-mas relleno. Bueno, sí, más o menos. Pero como en todos los asuntos relacionados con la religion ––o la guerra––, cuanto más se profundiza, más oscuros se vuelven los temas.

Pero aqui hay algo significativo. Estos editores son la tabula rasa sobre la que se ha construido gran parte del ciberespacio. El hecho de que estas herramientas, cada una diseñada para ser transparente para el usuario final, estén sujetas a lealtades tan feroces y competitivas, revela algo acerca de algunas suposiciones primordiales que la gente tiene acerca de las mejores maneras de hacer las cosas.

Vi: ¿El editor que el tiempo olvidó?

A primera vista, los forasteros podrían ver a vi como el editor que el tiempo olvidó. No es sólo que tienes que abrir una ventana de terminal sólo para usar la cosa. Esa también es la mejor manera de conseguir EMACS. Pero incluso con VIM, la versión actualizada que la mayoría de los usuarios de vi emplean hoy en día, uno no puede evitar maravillarse (o frustrarse) por la falta de intuición sobre su funcionamiento.

Incluso el webmaster de la página de inicio de los Amantes de VI admite que la curva de aprendizaje es empinada. Vi no es mas veloz antes de conocer 25 comandos más o menos, escribe Thomer Gil, oriundo de Ámsterdam, que actualmente trabaja en un doctorado en ciencias de la computación en el Instituto Tecnológico de Massachusetts.

Gil ha sido comparado por sus compañeros de oficina con un cavernícola que blandía un hacha y un garrote por su uso de VIM.

De todas las deficiencias percibidas en vi, tal vez la más notable sea la necesidad de ingresar la tecla de inserción sólo para escribir cualquier cosa en la pantalla. Vi tiene dos modos: Uno es el modo insertar en el que se puede introducir texto. Se accede a este modo pulsando la tecla insertar del teclado. Pero también existe el modo de comando en el que no se puede introducir texto, sino comandos relevantes. Desde el modo de inserción puede llegar a este ultimo pulsando la tecla de escape.

Así que imagínese al usuario desprevenido escribiendo por primera vez y que accidentalmente presiona la tecla de escape, sólo para descubrir que no sólo no puede ingresar más texto, sino que sus pulsaciones envian extrañas instrucciones al programa .

El Jargon File observa secamente que esta característica de vi tiende a frustrar infinitamente a los nuevos usuarios, ya que no toma comandos mientras espera texto de entrada ni viceversa, y la configuración predeterminada no proporciona ninguna indicación del modo en el que se encuentra el editor.

Los múltiples modos asustan a la gente, admite Gil.

Vi fue escrito por Bill Joy en 1976, quien lo forjó a partir de dos herramientas de edición aún más primitivas, ed y ex. Vi significaba interfaz visual, que en 1976 estaba en la vanguardia de la informática, según una entrevista a Joy en la Linux Magazine.

Intentaba hacerlo utilizable con un módem de 300 baudios. Esa también es la razón por la que tienes todos estos comandos divertidos. Apenas funcionaba usar un editor de pantalla sobre un módem, dijo Joy, Así que el editor estaba optimizado para que pudieras editar y sentirte productivo cuando pintaba más lento de lo que pensabas.

En esa entrevista, Joy contrastó el entorno de desarrollo de vi con el de EMACS, dijo que fue escrito para sistemas con enlaces de canales de fibra y un monstruo PDP-10.

Así que podrían tener comandos divertidos con la pantalla brillando y todo eso, y mientras tanto, estoy sentado en casa en una especie de vivienda excedente de la Segunda Guerra Mundial en Berkeley con un módem y un terminal que apenas puede sacar el cursor de la línea de fondo, dijo Joy, tal vez sonando un poco envidioso. La gente no sabe que vi fue escrito para un mundo que ya no existe.

Sin embargo, aunque vi debería haber desaparecido a principios de los años 80 a medida que aumentaba la velocidad de la red y del procesador, ha florecido. Las VI Pages listan cerca de 30 clones vi desde elvis y VIM hasta obscuridades tales como WinVi y vigor.

Tim O'Reilly, autor intelectual de la editorial O'Reilly & Associates, señaló en la columna Ask Tim de su empresa, que su empresa vende el doble de libros de vi que de EMACS. Además, O'Reilly apoya un juego de pintura de vi vs. EMACS en alguna convención, invariablemente el doble de voluntarios se inscriben para defender el honor de vi sobre EMACS.

Entonces, ¿cuál es el atractivo? Esto se describe mejor en el Culto de VI, en el que John Arundel escribe: Al ver a un gurú de vi haciendo una edición intensa en un archivo, mientras sus dedos sobrevuelan las teclas y las transformaciones textuales barren la pantalla, uno podría creer que está en presencia de poderes sobrenaturales.

Gil publica algunos ejemplos de esta magia en su sitio web. Un concepto clave en vi es combinar una determinada acción (borrar, copiar a búfer, escribir en mayúsculas, etc. con un movimiento (ir a la línea 25, ir al final del documento, ir a la siguiente coincidencia de 'foo', ir a la segunda coincidencia del carácter 'x' en esta línea, etc.)).

¿Eh? Le envié un correo electrónico.

Gil devuelve un ejemplo: Si, por ejemplo, un documento contiene las líneas: 'a b c d e f g h' y el cursor está situado en 'b', luego puedo escribir d/f.

La primer d significa borrar, la / es una función de búsqueda, así que lo que hará este comando es borrar de b a f.

No se requieren circunstancias especiales para usar esto... Borrar palabras, oraciones. Vuelve a donde estaba antes. Oh, no, salta de nuevo. Deshacer lo que hice, rehacerlo, escribe Gil.

Gil estipula que también puedes hacer trucos como este en EMACS. Sin embargo, se requiere memorizar combinaciones de teclas apestosas Ctrl-X Ctrl-c Alt-F4 para su ejecución.

Otro truco que Gil revela es cómo VI permite a los usuarios moverse dentro de los ficheros. La manera estúpida es usar las teclas de flecha; hay muchas otras maneras más avanzadas de moverse, escribe Gil. Entre las formas avanzadas de movimiento que ofrece vi se encuentra la opción de saltar a los últimos saltos del cursor, o a la siguiente ocurrencia de una palabra en particular, o a la siguiente oración o párrafo.

Incluso la característica de modo dual se vuelve transparente para los usuarios. Hace un año entrevisté a Jon Lasser para escribir sobre su entonces reciente libro Think Unix, (cuyo manuscrito, me dijo, fue compuesto enteramente en vi). La conversación finalmente llegó a vi, y me quejé de los dos modos.

Lasser explicó que no veía ninguna diferencia entre trabajar en vi y en procesadores de texto como StarOffice o Microsoft Word. En Word, cuando mueve el puntero fuera del área de pantalla, no puede escribir texto. De hecho, pasar del modo de inserción al modo de comando. Es lo mismo, explica.

Como O'Reilly escribió sobre vi: Como muchas cosas sobre UNIX, sólo parece difícil.

Más es más con EMACS?

Cuando el lealista de vi O'Reilly escribió en Ask Tim que primero cambió de EMACS a vi sólo después de que su perfil personalizado de EMACS fue destrozado, fue uno de esos jabs sutiles que a los usuarios de vi les gusta usar en contra de EMACS.

EMACS contrasta con la prístina limitación de comandos de vi, con su personalización casi infinita. Sin embargo, dado que la naturaleza humana es lo que es, tal poder en manos de los usuarios puede no ser siempre lo mejor.

Como dice el Emacs-Beginner-HOWTO, EMACS puede ser un editor de texto, un cliente de correo, un lector de noticias, un procesador de texto, un editor de scripts y un entorno de desarrollo integrado para lenguajes de programación.

La clave para esto son los múltiples modos, cada uno con un conjunto de comandos único, que EMACS ofrece. ¿Quieres comprobar el correo electrónico? Sólo tienes que pasar al modo de correo electrónico. ¿Quieres escribir un programa en C++? Utiliza el modo C++. ¿Necesita crear algunas páginas Web? Salta dentro del modo html-helper.

Y además de todo esto, también puedes personalizar EMACS e incluso añadir nuevas funciones, normalmente modificando su código en Lisp.

Es por todo esto que muchos usuarios de vi lo ven como terriblemente presuntuoso para lo que se supone que es un simple editor de texto, sin mencionar que distrae al usuario. La broma en curso sobre EMACS es que es un sistema operativo con un editor de texto adjunto.

EMACS como tal comenzó como un proyecto de estándares, escribe Guy Steele, uno de los creadores de EMACS, junto con Richard Stallman, quien más tarde fundó la Free Software Foundation.

Tal y como recuerda Steele, Stallman mantuvo un primer editor para el PDP-10 llamado TECO, que significaba Text Editor and COrrector. A pesar de que ciertas pulsaciones de teclas realizaban comandos de edicion, Stallman creo una tabla programable por el usuario, de manera que cada pulsación de tecla realizaba una búsqueda en la tabla que describía qué hacer para esa pulsación, según dice Steele. Una opción era ejecutar una macro TECO especificada por el usuario.

Usando esta funcionalidad de macros, los usuarios estaban programando conjuntos personalizados de macros para ser vinculados a varias pulsaciones de teclas, pero esto se volvió problemático cuando los programadores comenzaron a colaborar en programas y descubrieron que tenían pocas pulsaciones de teclas comunes entre ellos.

La comunidad de usuarios se había fragmentado con respecto a las habilidades de edición de textos (y programas), escribe Steele. Así que Steele, junto con David Moon y Stallman, asumió el proyecto de integrar todas las ideas en un conjunto de comandos unificado.

Inventé una matriz en papel y corrí mucho de un lado a otro entre los implementadores y usuarios de los distintos paquetes de macros, dice Steele en un correo electrónico.

Recuerdo esto muy bien, recuerda Dan Weinreb, quien fue uno de los primeros alfa testers de EMACS. El tipo tenía un portapapeles con un pedazo de papel que mostraba todas los atajos, y recogió cuidadosa y diplomáticamente los comentarios de todo el mundo para unificarlos, en atajos estándar.

Después de unos meses, Steele, ocupado tratando de terminar su tesis de maestría, entregó la obra a Stallman. Y el resto es historia.

El hecho de que la flexibilidad se horneara desde el inicio le da a EMACS su ventaja, dicen los usuarios hardcore.

Pienso en EMACS como la navaja suiza de los editores, menciona en un correo electrónico a Debra Cameron, coautora de Learning GNU Emacs y presidenta de Cameron Consulting. Es un ambiente de trabajo completo, un microcosmos. Si piensas en algo que desearías que hiciera, probablemente descubrirás (después de mirar a tu alrededor) que ya lo hace. Si no lo hace, puedes extenderlo y hacer que haga lo que quieras que haga.

¿No podemos llevarnos todos bien?

Entonces, ¿cómo difiere EMACS de vi?

He visto a usuarios de vi muy hábiles hacer algunos trucos bastante ingeniosos, pero sigo pensando que vi es (sólo) un editor, incluso si para algunos es un gran editor, menciona Cameron. Siempre, siempre funciona de la misma manera. En este sentido, vi es como McDonald's; no importa a donde vayas, es exactamente lo mismo.

¿Quieres un editor que se adapte a tus necesidades y peculiaridades y que haga muchas, muchas cosas o simplemente quieres ser capaz de editar archivos rápidamente en cualquier máquina? pregunta ella. Para la gente que tiene que moverse de un ordenador a otro constantemente, esta consistencia puede ser una ventaja real.

En otras palabras, EMACS = flexibilidad, mientras que vi = uniformidad?

Aquí es donde las cosas se ponen turbias.

EMACS es ciertamente más complejo que vi, pero no creo que sea más poderoso de ninguna manera útil, porque vi fue diseñado para ser parte de un sistema UNIX e interactuar con esas herramientas, replica Jon Lasser.

Tenga en cuenta que, para Lasser, útil significa la forma en que vi le permite leer documentos directamente desde una tubería UNIX desde otro proceso, como lo haría en cualquier otra aplicación UNIX, explica. Así, la cadena arcana de pulsaciones de teclas <esc> :r !ls<enter> introducidas en vi (en modo comando, recuerde) lee en el búfer la salida del programa ls, o una lista de archivos del directorio actual. Y una tubería de cualquier otro programa UNIX también funcionaría.

En cuanto a la edición automática de un gran número de archivos en vi, Lasser dice que es por eso que tenemos sed, awk, y todas las demás herramientas de procesamiento de texto UNIX.

El procesamiento de texto es para lo que UNIX fue diseñado, y vi fue diseñado para ser parte de ese sistema, escribe Lasser.

Tal vez el problema subyacente entre EMACS y vi no es el de la uniformidad frente a la flexibilidad en absoluto. Después de todo, ambos editores ofrecen flexibilidad, es sólo que con vi, lo hace a través del propio UNIX, mientras que EMACS lo logra construyendo sobre el sistema.

Y, para el caso, el único punto de la flexibilidad es hacer que el trabajo vaya más rápido. Si desea un procesamiento de texto sencillo y sin complicaciones, puede optar por Pico, que ofrece sólo una pantalla en blanco y ninguna de las características de vi o EMACS que confunden a los novatos. Lo que ambos editores ofrecen son formas avanzadas de reducir la distancia entre la velocidad de los dedos en el teclado y la velocidad del cerebro del programador.

En otras palabras, ¿podría ser que estos editores ofrezcan lo mismo, pero exijan diferentes maneras de pensar a sus usuarios? Vi requiere la paciencia para aprender sus extravagantes formas, aunque una vez que las dominas, eres libre de llevar tu acto a cualquier sistema UNIX. EMACS te da la libertad de personalizar tu configuración como mejor te parezca, aunque si no eres cuidadoso, te convertirás en prisionero de tu propia configuración.

En algún momento durante la gran caminata de mejora de la auto-eficiencia que todos los buenos programadores toman, los usuarios de vi y EMACS se cruzan, cada uno viniendo de una dirección diferente. Y cuando se encuentran, normalmente se tiran piedras unos a otros.

Pero todo está bien.

No creo que haya una gran diferencia en la funcionalidad. Ambos editores hacen un buen trabajo y todo se reduce a lo que la gente aprende primero, escribe Gil. Ya que la mayoría de las personas conocen EMACS, les enseñarán a otros EMACS. Por lo tanto, la mayoría de la gente usa EMACS, etc.

Y así la disputa continuará...

(Nota: Las mayúsculas de EMACS, UNIX y vi pueden haber sido cambiadas en comillas a sus formas originales, excepto en los títulos directos de libros y páginas Web).

-1:-- The Holy War (Post )--L0--C0--April 08, 2018 03:35 PM