<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title><![CDATA[Notxor tiene un blog]]></title>
<description><![CDATA[Notxor tiene un blog]]></description>
<link>https://notxor.nueva-actitud.org/</link>
<lastBuildDate>Tue, 03 Mar 2026 19:24:08 +0100</lastBuildDate>
<item>
  <title><![CDATA[Primer artículo del año]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2026-01-24</div>
<p>
No quería dejar pasar el mes sin publicar algo en el <i>blog</i>. He pasado
unos meses de diciembre y enero llenos de sobresaltos y viajes
sorpresivos debidos a la salud de mis padres, muy mayores ya y con la
afectación típica de la edad. No es excusa para no haber escrito, he
tenido también un montón de momentos muertos incluidas las largas
noches de insomnio de hospital. Pero en ese momento la verdad es que
no me apetecía ponerme a pensar y lo gastaba rellenando sudokus, una
actividad intrascendente pero que me ayudaba a enfocar mi atención en
algo lo suficiente interesante para distraer la realidad, pero no
hacerme pensar demasiado. Por otro lado, el equipo con el contaba no
era lo suficientemente adecuado, también por exceso de longevidad,
como para aguantar el trabajo normal.
</p>

<p>
En este mes de enero me llegó una nueva tableta que, aunque no es la
que a mí me gustaría, cumple mucho mejor con esas funciones. La tableta
en cuestión es una <a href="https://www.tcl.com/es/es/tablets/tcl-nxtpaper-14">TCL NXTpaper 14</a>, y presenta algunos problemas que
la hacen incómoda para el uso que yo le vengo dando a las tabletas:
</p>

<ol class="org-ol">
<li>El <b>tamaño</b>: Una pantalla de 14" es muy aparatosa. Teniendo en cuenta
que la suelo usar más para leer que para otras actividades, tirarme
en el sofá con semejante mamotreto en las manos es bastante
incómodo.</li>
<li>La <b>configuración</b>: No se está dejando configurar tan mansamente como
debiera. Pero esto necesita una explicación más larga.</li>
</ol>
<div id="outline-container-orgd81efcb" class="outline-2">
<h2 id="orgd81efcb">Configuración de la tableta</h2>
<div class="outline-text-2" id="text-orgd81efcb">
<p>
Hay que contar que tengo bloqueadas (inhabilitadas) todas las
aplicaciones de <i>Google</i>. Algunas sustituidas por otras libres
descargadas de <a href="https://f-droid.org/es/">F-Droid</a> y otras simplemente ignoradas, inhabilitadas (y
bien que se queja el cacharro de que tengo aplicaciones importantes
paradas... en fin).
</p>
</div>
<div id="outline-container-org0dc5998" class="outline-3">
<h3 id="org0dc5998">Aplicaciones imprescindibles</h3>
<div class="outline-text-3" id="text-org0dc5998">
<p>
Además de tener todas esas aplicaciones inhabilitadas hay algunas que
instalo siempre y me ayudan a blindar un poco más las comunicaciones
del dispositivo.
</p>
</div>
<div id="outline-container-orgdc00822" class="outline-4">
<h4 id="orgdc00822">NetGuard</h4>
<div class="outline-text-4" id="text-orgdc00822">
<p>
La aplicación <a href="https://f-droid.org/es/packages/eu.faircode.netguard/">NetGuard</a> determina qué aplicaciones pueden conectarse a
internet y por qué medio: <i>Wifi</i> o <i>datos móviles</i>. Con esto bien
gestionado, ya te ahorras un montón de conexiones de aplicaciones que
no lo necesitan. Por ejemplo, <a href="https://f-droid.org/es/packages/at.bitfire.davdroid/">DAVx^5</a> tiene acceso a red, por ambos
canales, <i>Wifi</i> y datos móviles, lo que permite que la <a href="https://f-droid.org/es/packages/org.fossify.contacts/">aplicación de
contactos</a> o la de <a href="https://f-droid.org/es/packages/org.fossify.calendar/">calendario</a>, no lo necesiten, pero yo siga teniendo
acceso a mis contactos y mi calendario de mi <i>Nextcloud</i>.
</p>
</div>
</div>
<div id="outline-container-org7f92edc" class="outline-4">
<h4 id="org7f92edc">NextDNS</h4>
<div class="outline-text-4" id="text-org7f92edc">
<p>
También utilizo un filtro VPN mediante <a href="https://f-droid.org/es/packages/com.doubleangels.nextdnsmanagement/">DNS privado</a> para la trasmisión
de datos. La aplicación me permite establecer una <i>lista negra</i> (o una
<i>lista blanca</i>) bloqueando o permitiendo conexiones a dominios
particulares. No hace falta advertir que tengo bloqueados los
principales de las <i>GAFAM</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, pero además otros dominios a los que,
por ejemplo, el móvil chino, envía información en segundo plano sin
que lo sepa el usuario.
</p>
</div>
</div>
<div id="outline-container-orgda8a9d1" class="outline-4">
<h4 id="orgda8a9d1">NextCloud y KDE Connect</h4>
<div class="outline-text-4" id="text-orgda8a9d1">
<p>
Para sincronizar dispositivos utilizo un servidor <i>NextCloud</i>
unipersonal propio instalado en un servidor mío y que administro yo
para mí, aunque algunas veces le ha dado servicio a algún amigo o
compañero que ha necesitado un poco de espacio temporalmente. El
sistema me habilita el uso de agenda secundaria<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>, la lista de
contactos, o lo más importante, los datos de los repositorios de
proyectos, notas y agenda que trabajo con <i>Emacs</i>. Los repositorios van
en un servidor <a href="https://fossil-scm.org">fossil</a> más adelante explico cómo.
</p>

<p>
Para cuestiones más puntuales utilizo <a href="https://f-droid.org/es/packages/org.kde.kdeconnect_tp/">KDE Connect</a>. Me permite enviar
directamente archivos entre dispositivos: móvil, ordenador,
tableta... además de otros servicios para compartir periféricos o
utilizar el móvil como mando a distancia para presentaciones y varias
fricadas más.
</p>
</div>
</div>
</div>
<div id="outline-container-org0790318" class="outline-3">
<h3 id="org0790318">Bloqueo de sensores</h3>
<div class="outline-text-3" id="text-org0790318">
<p>
Otra de las cosas que hago en mis dispositivos Android™ es desactivar
todos los sensores del aparato. Una de las cosas que Google® descarga
en nuestros perfiles<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> cuándo coges el teléfono, cuándo andas con
él en el bolsillo, cuánto tiempo está «abandonado» sobre una mesa, su
localización, la velocidad a la que te mueves y extrapola con esos
datos, datos de salud o de costumbres y hábitos.
</p>

<p>
Si nunca has bloqueado los sensores te recomiendo que lo hagas, cuanta
menos información tengan sobre nosotros las multinacionales
estadounidenses<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup> mejor.
</p>

<p>
Si no sabes cómo hacerlo te lo cuento en unos pocos pasos:
</p>

<ol class="org-ol">
<li>Activa las <b>opciones de desarrollador</b>: Ajustes → Información del
dispositivo y pulsa <b>siete veces</b> el <b>número de versión</b>.</li>
<li>Ve a Sistema y actualización → Opciones de desarrollador →
Recuadros para desarrolladores en ajustes rápidos</li>
<li>Pulsa en <b>Sensores desactivados</b>. Éste <i>switch</i> mostrará un botón en
los ajustes rápidos que nos permitirá desactivar y activar los
sensores a voluntad</li>
</ol>

<p>
Es posible que en tu versión de Android® los menús sean diferentes,
son cambiantes de una versión a otra o de un modelo de teléfono a
otro, así que, buena suerte con la búsqueda. ¡Ah! Recuerda que cada
vez que apagues el móvil, al encenderlo tendrás que bloquear
manualmente los sensores.
</p>

<p>
La pena, es que la tableta nueva no muestra las opciones de
desarrollador en ningún sitio. Se activan normalmente, incluso si lo
vuelves a intentar te dice que ya estaban activadas, pero no se
muestran en ningún lado. Supongo que estará supeditado a alguna mierda
de aplicación del propio Android®, como por ejemplo los <i>servicios de
android</i> que tengo deshabilitados que en el móvil protesta dos veces
cuando arranca, pero la tableta protesta seis y repite esas protestas a
lo largo del tiempo que la tengo encendida... muestra mensajes de
aviso de que algunas aplicaciones o el sistema operativo pueden no
funcionar y efectivamente es así, lo que ayuda a localizar qué
aplicaciones hay que borrar o inhabilitar. En resumen, cuanto más
moderno es un aparato más mierda lleva dentro.
</p>
</div>
</div>
<div id="outline-container-orgb3a9a56" class="outline-3">
<h3 id="orgb3a9a56">Ventajas de la nueva tableta</h3>
<div class="outline-text-3" id="text-orgb3a9a56">
<p>
No todo son inconvenientes, tiene también alguna cosa buena, por
ejemplo:
</p>

<p>
El tamaño de la pantalla, que para leer es incómoda, se hace muy
cómoda para otras tareas. Además cuenta con un sistema de
configuración e iluminación que me permite utilizarla cómodamente en
exteriores donde las pantallas normales son complicadas de leer.
</p>

<p>
Cuenta además con un lápiz como dispositivo de escritura manual,
sensible a la presión y que es una delicia utilizar con <a href="https://f-droid.org/es/packages/org.krita/">Krita</a> para
dibujar. Aunque he de confesar que he perdido <i>mucha mano</i> para el
dibujo, después de años sin coger un lápiz. Aunque está bien esto del
dibujo digital, sigo encontrándome más cómodo con el papel y el lápiz
analógicos.
</p>
</div>
</div>
<div id="outline-container-org9f9d101" class="outline-3">
<h3 id="org9f9d101">Proyectos</h3>
<div class="outline-text-3" id="text-org9f9d101">
<p>
Actualmente mantengo un servidor con varios servicios para
esperantistas, <a href="https://notxor.nueva-actitud.org/2025/11/27/ludu-cxe-la-esperanta-servilo-de-luanti.html">para jugar en Luanti</a><sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup> y además también se
proporciona soporte de conexión de audio <a href="https://notxor.nueva-actitud.org/2025/11/30/interparoli-vocxe-en-nia-servilo-de-luanti.html">por un servicio de mumble</a>. De
vez en cuando, organizamos quedadas virtuales para encontrarnos allí y
jugar y charlar entre personas repartidas por varios países y
continentes. Además, estoy planteándome el crear una radio en línea y
ofrecerla de manera gratuita a aquellos esperantistas que quieran
tener su propio <i>Podcast</i> o programa de radio, con emisiones «en
directo» y/o diferidas.  Aunque de momento tampoco está teniendo mucha
acogida entre los grupos donde lo he planteado, así que veré si
termino haciéndolo o no.
</p>

<p>
Otro proyecto, en este caso personal, que acabo de poner en marcha es
la confección de un <i>libro-juego</i>. Hablaré de él un poco más adelante.
Para realizarlo pienso utilizar tanto el ordenador como la tableta. La
potencia de la nueva me permite trabajar como si estuviera en el
ordenador. Por ejemplo, si arranco <i>Emacs</i> en el ordenador aparece más o
menos así:
</p>


<figure id="org3b88562">
<img src="./imagenes/Captura_komputilo.png" alt="Captura_komputilo.png">

</figure>

<p>
Es decir, carga 127 paquetes que utilizo en poco más de 3 segundos.
</p>

<p>
En la nueva tableta, el equivalente es:
</p>


<figure id="orgb650ec6">
<img src="./imagenes/Captura_tablet.png" alt="Captura_tablet.png">

</figure>

<p>
Es decir, tarda unos 7,5 segundos en cargar 121 paquetes, para
trabajar de manera equiparable al ordenador en modo texto dentro de
<a href="https://f-droid.org/es/packages/com.termux/">Termux</a>. Lo que no es una velocidad destacable pero es mucho más rápida
que los 30-40 segundos que tardaba en cargar la antigua tableta 103
paquetes. También hay diferencias en el desempeño: con el teclado
<i>bluetooth</i> en la nueva no hay <i>lag</i> y en la antigua sí, a veces tecleaba
con tres o cuatro letras de adelanto y si dudaba de alguna pulsación,
al no aparecer de inmediato, tenía que parar de escribir. Lo que no es
mucha pérdida de tiempo, pero sí de paciencia.
</p>
</div>
<div id="outline-container-orgfad7260" class="outline-4">
<h4 id="orgfad7260">Flujo de trabajo</h4>
<div class="outline-text-4" id="text-orgfad7260">
<p>
Como ya dije antes, la sincronización entre los dispositivos la
realizo mediante una nube <i>Nextcloud</i> en un servidor propio y del que
soy el único usuario. Concretamente, mantengo sincronizados dos
directorios, uno contiene páginas <a href="https://tiddlywiki.com/">TiddlyWiki,</a> y que en Android® trabajo
con <a href="https://f-droid.org/es/packages/top.donmor.tiddloid/">Tiddloid</a>, y otro que contiene repositorios <a href="https://fossil-scm.org">fossil</a>, que manejo
desde dentro de <i>Termux</i>.
</p>

<p>
Para poder acceder a los datos de <i>Nextcloud</i> en Android® desde otras
aplicaciones, recuerda que debes activar el <i>switch</i> de <i>«Permitir acceso
desde otras aplicaciones»</i> en la configuración de la aplicación de
<i>Nextcloud</i> instalada. Mira en Configuración → General → Ubicación del
almacenamiento de datos y actívalo.
</p>

<p>
También debes habilitar en <i>Termux</i> el acceso a esos datos:
</p>

<div class="org-src-container">
<pre class="src src-shell">termux-setup-storage
</pre>
</div>

<p>
Tras ese comando tendrás un directorio <code>~/storage</code> y tendrás acceso al
resto de datos «públicos» del sistema. Por último, por comodidad,
también he creado un enlace simbólico a los repositorios, pues se
encuentran en el incómodo <i>PATH</i>:
</p>

<div class="org-src-container">
<pre class="src src-nil">storage/shared/Android/media/com.nextcloud.android.beta/nextcloud/Notxor@[url a mi nube]/repos
</pre>
</div>

<p>
El crear el enlace también es opcional, pues puedes escribir todo el
churro ese, en un <i>script</i> que levante el servidor de repositorios, pero
queda más legible con el enlace. Además, si el nombre del directorio
cambia, sólo hay que modificar el enlace y todo seguirá funcionando
igual. El <i>script</i> que utilizo para levantarlo es:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #6272a4;">#</span><span style="color: #6272a4;">!/data/data/com.termux/files/usr/bin/</span><span style="color: #ff79c6; font-weight: bold;">sh</span><span style="color: #6272a4;">
</span>
termux-wake-lock
fossil server --port 6969 ~/repos &amp;
</pre>
</div>

<p>
El <code>termux-wake-lock</code> hace que la sesión de <i>Termux</i> se mantenga activa
aunque la cierres de manera que siempre están disponibles las
interfaces gráficas de los repositorios, aún con la consola cerrada.
Éstos se pueden acceder escribiendo la dirección en la barra del
navegador, <a href="https://f-droid.org/es/packages/org.mozilla.fennec_fdroid/">fennec</a> en mi caso, o –si está la consola abierta–
lanzándolo desde la línea de comandos:
</p>

<div class="org-src-container">
<pre class="src src-bash">xdg-open http://localhost:6969/[nombre del repositorio]
</pre>
</div>

<p>
automáticamente abrirá el navegador, que esté configurado por defecto,
en el repositorio pedido:
</p>


<figure id="org3b4ff4c">
<img src="./imagenes/Captura_repos_tableta.png" alt="Captura_repos_tableta.png">

</figure>

<p>
La ventaja de <i>fossil-scm</i>, para proyectos pequeños, es que lleva
incorporadas herramientas interesantes, como <i>wiki</i> para la
documentación y permite la edición de archivos de texto plano con un
simple editor si fuera necesario. También visualiza formateados los
archivos <i>MarkDown</i> y cuenta con un editor de gráficos <i>pikchr</i> para
realizar esquemas simples. Es todo un servicio de <i>Forgejo</i> pero dentro
de una base de datos SQLite.
</p>

<p>
Como todo <i>scm</i> que se precie, procura no machacar el trabajo de nadie.
Lo que es muy de agradecer porque al no contar con repositorio remoto
activo 100% y constantemente actualizado, sino que depende de que me
acuerde de activarlos o actualizarlos, a veces me encuentro con algún
problemilla de descoordinación entre los repositorios locales y el
«general». Afortunadamente basta hacer un <i>merge</i> cuando está el
repositorio «activado« para poner todo en su sitio de nuevo:
</p>


<figure id="org2b1d86b">
<img src="./imagenes/Captura_timeline.png" alt="Captura_timeline.png">

</figure>
</div>
</div>
<div id="outline-container-orgf9f3a44" class="outline-4">
<h4 id="orgf9f3a44">Trabajando en el libro-juego</h4>
<div class="outline-text-4" id="text-orgf9f3a44">
<p>
Dada mi afición a utilizar herramientas para usos para los que no
fueron diseñados, decidí utilizar <code>org-roam</code> para el proyecto del libro
juego. ¿Por qué? Pues básicamente porque un libro-juego está compuesto
de trozos de texto enlazados –algo para lo que sí fue diseñado
<code>org-roam</code>​–, además proporciona un gráfico de cómo se relacionan unos
textos (notas) con otros mediante su <i>UI</i>. Para ello, he tenido que
hacer unos mínimos cambios a la configuración de mi
<i>Emacs</i>. Concretamente:
</p>

<p>
Se necesita habilitar, como dependencia de <code>org-roam</code>, el <code>sqlite</code>
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> emacsql
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t)
</pre>
</div>

<p>
Y ahora cargar el paquete de notas y configurarlo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> org-roam
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:custom</span>
  (org-roam-directory (file-truename <span style="color: #f1fa8c;">"~/Notas"</span>))
  (define-key map (kbd <span style="color: #f1fa8c;">"C-c n"</span>) 'org-roam-map)
  <span style="color: #8be9fd; font-style: italic;">:bind</span> ((<span style="color: #f1fa8c;">"C-c n c"</span> . org-roam-capture)
         (<span style="color: #f1fa8c;">"C-c n f"</span> . org-roam-node-find)
         (<span style="color: #f1fa8c;">"C-c n g"</span> . org-roam-graph)
         (<span style="color: #f1fa8c;">"C-c n i"</span> . org-roam-node-insert)
         (<span style="color: #f1fa8c;">"C-c n l"</span> . org-roam-buffer-toggle)
         (<span style="color: #f1fa8c;">"C-c n r"</span> . org-roam-find-file-hook)
         (<span style="color: #f1fa8c;">"C-c n u"</span> . org-roam-ui-mode)
  <span style="color: #8be9fd; font-style: italic;">:map</span> org-mode-map
  (<span style="color: #f1fa8c;">"C-M-i"</span> . completion-at-point)
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Dailies
</span>  (<span style="color: #f1fa8c;">"C-c n j"</span> . org-roam-dailies-capture-today))
  <span style="color: #8be9fd; font-style: italic;">:config</span>
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> org-roam-node-display-template (concat <span style="color: #f1fa8c;">"${title:*} "</span> (propertize <span style="color: #f1fa8c;">"${tags:10}"</span> 'face 'org-tag)))
  (org-roam-db-autosync-mode)
  (<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">org-roam-protocol</span>))
</pre>
</div>

<p>
También tengo una función que permita cambiar el conjunto de notas que
se empleará, para no mezclar la base de datos de las anotaciones, con
las entradas del proyecto y establecerle una tecla para hacerlo
cómodamente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Cambio de directorio org-roam
</span>(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">roam-cambio-dir</span> (dir)
  <span style="color: #6272a4;">"Cambiar de directorio de `</span><span style="color: #bd93f9;">org-roam</span><span style="color: #6272a4;">' al `</span><span style="color: #bd93f9;">DIR</span><span style="color: #6272a4;">' de forma interactiva."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span> <span style="color: #f1fa8c;">"DNuevo directorio de Notas: "</span>)

  (message (format <span style="color: #f1fa8c;">"Se cambia org-roam-directory a: %s"</span> dir))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> org-roam-directory (expand-file-name dir))
  (org-roam-db-sync))

(global-set-key (kbd <span style="color: #f1fa8c;">"C-S-&lt;f5&gt;"</span>) #'roam-cambio-dir)
</pre>
</div>

<p>
Por último, monto la interface gráfica para el paquete de <code>org-roam</code>,
que necesita <i>websockets</i> para sincronizarse con el navegador:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> websocket
  <span style="color: #8be9fd; font-style: italic;">:after</span> org-roam)

(<span style="color: #ff79c6; font-weight: bold;">use-package</span> org-roam-ui
  <span style="color: #8be9fd; font-style: italic;">:after</span> org-roam
  <span style="color: #8be9fd; font-style: italic;">:config</span>
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> org-roam-ui-sync-theme t
        org-roam-ui-follow t
        org-roam-ui-update-on-save t
        org-roam-ui-open-on-start t))
</pre>
</div>

<p>
y con estas cosas, ya puedes disfrutar de pichorros gráficos que se
mueven e interactúan en una interface molona.
</p>


<figure id="orge10d68a">
<img src="./imagenes/Captura_org-roam_falkon.png" alt="Captura_org-roam_falkon.png">

</figure>

<p>
En Android®, desde <i>Termux</i>, al lanzar la interface con
<code>org-roam-ui-mode</code> no lanza automáticamente el navegador. Lo solvento
abriendo el puerto <code>35901</code> de <code>localhost</code> desde el navegador o desde la
línea de comandos lanzando el comando
</p>

<div class="org-src-container">
<pre class="src src-bash">xdg-open http://localhost:35901
</pre>
</div>

<p>
También mantengo el paquete (para notas) <code>Deft</code>, que me las presenta en
formato de lista y filtra las notas de manera muy sencilla e
intuitiva. En fin, vamos al proyecto con el que ando trasteando
últimamente.
</p>
</div>
</div>
<div id="outline-container-orga2ef30d" class="outline-4">
<h4 id="orga2ef30d">El tema del libro-juego</h4>
<div class="outline-text-4" id="text-orga2ef30d">
<p>
Aún no hay nada cerrado en cuanto al contenido del mismo. Sí me
gustaría mantener un poco la cordura y no lanzarme a un proyecto tan
amplio que quede abandonado, como en otros proyectos me ha pasado. Iré
rellenando etapas, escribiendo algunos textos, montando algunas
escenas, releyendo, corrigiendo y, cuando sea oportuno, ampliándolo
con otro par de escenas o una nueva trama. La idea original era que
sirviera de guión para una aventura conversacional multijugador, o
para un MUD. Sin embargo, son cosas muy alejadas técnicamente en
ciertos aspectos. En un libro-juego prima el texto y el desarrollo de
una historia y queda en un segundo plano el aspecto lúdico de
juego. Si quieres hacer el contenido para varios personajes, el número
de textos se multiplica exponencialmente. En una conversacional, en
cambio, prima la estructura y los puzles y siendo los textos, más allá
de las descripciones de los personajes, compartidos.
</p>

<p>
El centro de la historia, como proyecto inicial, me planteé recorrer
una parte (espero que interesante) de un mundo imaginario, donde la
magia aún es posible pero donde está desapareciendo y/o haciéndose
cada vez más difícil y enrevesada gracias a los sueños de dominación
de algunos pocos poderosos que intentan acotarla para beneficio
propio. Esto, desde el punto de vista de la ambientación. Desde el
punto de vista del jugador, tendrá que iniciar una búsqueda para
procurar que no lo consigan... cualquier analogía con la situación de
la tecnología actual será pura coincidencia, ¡lo prometo! :-þ.
</p>
</div>
</div>
</div>
</div>
<div id="outline-container-org2ba3d36" class="outline-2">
<h2 id="org2ba3d36">Conclusión</h2>
<div class="outline-text-2" id="text-org2ba3d36">
<p>
Espero que a estas alturas hayamos pasado la mala racha de viajes
continuos y enfermedades varias, para poder dedicarme a otras cosas.
De momento, como siempre, seguiré con mis trasteos e iré, poco a poco,
avanzando en la realización de la historia o el libro-juego. No me he
puesto plazo para publicar lo que será un <i>epub</i> con el contenido. Según
cómo quede la historia, incluso me planteo gastarme algo de dinero en
algún(a) ilustrador(a) que me haga unas pocas ilustraciones para
acompañar al texto. Pero eso ya cuenta en el ámbito de los <i>futuribles</i>.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Google®</i>, <i>Amazon®</i>, <i>Facebook®</i>, <i>Apple®</i> y <i>Microsoft®</i>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Como agenda principal mantengo <code>org-mode</code> con <i>Emacs</i>, pero hay
ocasiones que con el teléfono es engorroso y es más sencillo utilizar
la aplicación de calendario. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Sí, aunque no tengas cuenta de Google®, como es mi caso, la
gran G tiene un perfil tuyo.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Te recuerdo que se han perfilado por méritos propios como las
mayores enemigas de la <b>Democracia</b> y perteneces a un Estado que se ha
erigido, también por méritos propios, como el principal enemigo de <i>El
Mundo Libre</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Dos juegos habilitados: Mineclonia (un clon de Minecraft) y
otro de «captura la bandera».
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/aventuras/index.html">aventuras</a> <a href="/tags/conversacionales/index.html">conversacionales</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[aventuras]]></category>
  <category><![CDATA[conversacionales]]></category>
  <link>https://notxor.nueva-actitud.org/2026/01/24/primer-artículo-del-año.html</link>
  <pubDate>Sat, 24 Jan 2026 09:34:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Interparoli voĉe en nia servilo de Luanti]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2025-11-30</div>
<p>
La lastaj semajnoj ni elstaris servilon por ludi <i>Luanti</i> per du
manieroj: «Mineclonia» kaj «Kaptu la flagon». Vi povas legi la
antaŭajn artikolojn: <a href="https://notxor.nueva-actitud.org/2025/11/20/nova-projekto.html">la prezentado de la projekto</a>, <a href="https://notxor.nueva-actitud.org/2025/11/25/projekto-ludejo-ii.html">pri la unuaj provoj</a>
kaj <a href="https://notxor.nueva-actitud.org/2025/11/27/ludu-cxe-la-esperanta-servilo-de-luanti.html">starigo de du serviloj</a>. Mi hodiaŭ parolos pri alian ilon kiun ni
elstarantas por niaj ludantoj: la eblon por paroli voĉe inter la
diversaj homoj. Ni uzos <i>mumble</i> servilon. Se vi ne scias kion tiu ilo
estas, iru al <a href="https://www.mumble.info/">https://www.mumble.info/</a>, kie vi trovos pli da informon
ol mi povos aldoni per ĉi tiu simpla artikolo.
</p>

<p>
Por konekti vin al nia servilo, vi bezonas elŝuti de la reta paĝo de
<i>Mumble</i> la taŭgan klienton por nia operaciumo kaj instali ĝin en via
maŝino.
</p>

<p>
Kiam vi ŝaltos la klienton, ĝi petos eniri servilon. Do vi devas krei
(aŭ aldoni) novan al la listo:
</p>


<figure id="org9cb5c72">
<img src="./imagenes/aldoni-novan.png" alt="aldoni-novan.png">

</figure>

<p>
Poste aperos fenestro por la datumoj de konektado:
</p>


<figure id="orgd53f86c">
<img src="./imagenes/nova-servilo.png" alt="nova-servilo.png">

</figure>

<ol class="org-ol">
<li>La loko de la servilo, kiu estas nia <b>IP</b>: <b>217.182.65.135</b></li>
<li>La <b>pordo</b> por nia babilejo estas: <b>65432</b></li>
<li>La <b>kromnomo</b> kiun vi ŝatas por vi (rilate al mi, Notxor)</li>
<li><p>
<b>Etikedo</b>: nomo uzata en la listo de servilojn, kiu al vi montros
rekte la eniron. Ekzemple, vi povas nomi ĝin <b>Ludejo</b>.
</p>

<p>
Se ĉiu datumo estas korekta, la servilo demandos pasvorton al vi:
</p>


<figure id="org150bd23">
<img src="./imagenes/pasvorto.png" alt="pasvorto.png">

</figure></li>

<li>La <b>pasvorto</b> estas: <code>Babilejo65432</code>.<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup></li>
</ol>

<p>
Se ĉio estas en ordo, vi eniros al servilon. Poste, mi rekomendas ke
vi registru vian kromnomon por certigi ke vi estas la sola uzanto de
tiu kromnomo, sed tio ne estas deviga. Por tio, vi trovos ĉe la menuo
«mia uzanto» butonon por la registrado.
</p>

<p>
Se vi demandas kial ni uzas pasvorton, la respondo estas por certigi
al ni ke ne eniras hazarda ulo kiu trovis konektadon kaj eniras nur
por esplori scivoleme. La rimedoj ne estas senfinaj, kaj ni devas ne
malŝpari ilin.  Al ĉi tiu servo devas eniri ĉiuj kiuj volonte ŝatus
interparoli kaj ludi esperante. Do, pro tio, la pasvorto estas publika
kaj facile memorebla, sed la hazardaj uzantoj ne konvenas al ni.
</p>
<div id="outline-container-org0454627" class="outline-2">
<h2 id="org0454627">Uzado</h2>
<div class="outline-text-2" id="text-org0454627">

<figure id="org46e3e94">
<img src="./imagenes/uzado.png" alt="uzado.png">

</figure>

<p>
La ilo havas ankaŭ tekstan babiladon. Tiu kiu vi skribos, iros al
kanalo kien vi enestas tiel, kiel voĉe.
</p>

<p>
La <i>Mumblea</i> servilo estos daŭre starigita. Vi povas uzi kiel vi plej
ŝatos. Ĝian celon estas, certe, por ludi, sed ĝi estas sendependa
servilo, kaj oni povas uzi ĝin ankaŭ por renkontiĝi kaj interparoli
esperante se vi ne bezonas montri bildojn aŭ la intervidado.
</p>
</div>
</div>
<div id="outline-container-org6f89a78" class="outline-2">
<h2 id="org6f89a78">Fine</h2>
<div class="outline-text-2" id="text-org6f89a78">
<p>
Mi rekomendas la uzon de tiu ilo, ĉar la babilado en <i>Luanti</i> ne estas
ĉifrata kaj transiras la reton klare montrata, ne nur por la ludantoj
konektataj, sed ankaŭ por tiuj, kiuj povas interkapti la konektadon.
</p>

<p>
Se vi volas privatecon, uzu tiun ilon por paroli voĉe.
</p>

<p>
Ĉar la servilo estos daŭre starigita, kiel mi diris antaŭe, oni povas
uzi por renkonti aliajn esperantojn kaj por praktiki la paroladon, sen
ludi. Sed por tiuj aferoj mi petas, ĉar la unua celo de la servo estas
por la ludantoj, ke vi kreos nedaŭran kanalon por ne ĝeni la aliajn
uzantoj kiuj povos eniri la ludon aŭ krei sian propran kanalon. La
kanalojn estos publikaj por tiu, kiu eniros la servon, do oni povas
eniri iu ajn, memoru ke vi povas esti aŭskultata ne nur por tiuj, kiuj
vi esperas<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ne tro zorgu pri la <i>pasvorto</i> la plejparto el la klientoj
memorigas la pasvortojn kaj ne ĝenas la uzantojn pri la afero. Post la
unua eniro, la sekvantaj estos starigitaj rekte, sed tio dependas de
la kliento uzata.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Precipe se vi uzas la ilon, kiel fona servo, sen atento, dum vi
faras alian taskon, kiel ludi, dum la parolado. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <link>https://notxor.nueva-actitud.org/2025/11/30/interparoli-vocxe-en-nia-servilo-de-luanti.html</link>
  <pubDate>Sun, 30 Nov 2025 11:10:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Ludu ĉe la esperanta servilo de Luanti]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2025-11-27</div>
<p>
Ni komencas la ludon. Ĉi tiu artikolo temas pri la elstarigo de
serviloj por ludi <i>«Luanti»</i>. Jes, serviloj ĉar ni elstaras du ludojn
unu el ili daŭranta kaj senfine staranta kaj alia por ludi kune sed
dum okazaj eventoj.
</p>

<p>
Se vi estas kutima ludanto de «Luanti» vi povos konekti niajn
servilojn tiel:
</p>

<ul class="org-ul">
<li><i>Mineclonia</i>: daŭranta. IP: 217.182.65.135 -- Pordo: 30000</li>
<li><i>Kaptu la flagon</i>: okaza. IP: 217.182.65.135 -- Pordo: 30001</li>
</ul>

<p>
Por la okazaj ludoj, ni anoncos ilin ĉe <a href="https://eventaservo.org/">Eventa Servo</a> por renkontiĝado.
Se vi estas kutima ludanto de <i>Luanti</i> vi nur bezonas la superajn
datumojn lude libere.
</p>

<p>
Sugestioj kaj petoj oni povas elsendi al retpoŝto <b>esperanto</b> ĉe
<b>nueva-actitud.org</b>.
</p>
<div id="outline-container-orgf94b437" class="outline-2">
<h2 id="orgf94b437"><i>Luanti</i></h2>
<div class="outline-text-2" id="text-orgf94b437">
</div>
<div id="outline-container-orgea4161a" class="outline-3">
<h3 id="orgea4161a">Mineclonia</h3>
<div class="outline-text-3" id="text-orgea4161a">
<p>
La servilo estos daŭre elstara, krom por administraj laboroj de la
servilo, kiujn ni esperas nur bezonos restarigojn dum neniu ludanto
estos ludanta.
</p>

<p>
Ni ŝatos ludi kun malmultaj reguloj kaj ni alvokas al via bonvolo, nur
konsideri:
</p>

<ul class="org-ul">
<li>Ĝentile respektu la aliajn ludantojn, sian laboron, sian ludon,
siajn aĵojn, siajn bestojn. Cetere estas modulo por protekti viajn
lokojn kaj laborojn per protektanta bloko.</li>
<li>La servilo estas por esperante ludi kaj lokon kie trovi aliajn
esperantistajn ludantojn. <i>Ne tro krokodilu!</i></li>
<li>La centra parto de la mondo, kubo de (-100,-100,-100) al
(100,100,100) estas rezervita por la komunaj lokoj. Kaj tie ni
konstruos <i>«La Babelan Turon»</i> por ni ĉiuj.</li>
</ul>
</div>
</div>
<div id="outline-container-org6de2a2b" class="outline-3">
<h3 id="org6de2a2b">Kio estas <i>Luanti</i>?</h3>
<div class="outline-text-3" id="text-org6de2a2b">
<p>
<i>Luanti</i> estas ilo, kubara luda motoro<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, libera kaj malfermitkoda.
</p>

<p>
Tiel, oni povas trovi multajn diversajn ludojn ĉe la retpaĝo
<a href="https://content.luanti.org">https://content.luanti.org</a> ... La kreantoj de tiu ilo faciligis la
kreadon de la propra kodo por programi ludojn kaj modulojn.
</p>
</div>
</div>
<div id="outline-container-orgce94819" class="outline-3">
<h3 id="orgce94819">Kiel ludi?</h3>
<div class="outline-text-3" id="text-orgce94819">
<p>
Vi bezonas klienton por ludi. Tiun vi povos trovi ĉe la retpaĝo
<a href="https://www.luanti.org/downloads/">https://www.luanti.org/downloads/</a> ... libere elŝutu la klienton por
via operaciumo.
</p>

<p>
Kiam vi plenumigos la ilon vi havos liston de publikajn servilojn kie
vi povos ludi libere.
</p>


<figure id="org2b9881b">
<img src="./imagenes/Captura_20251127_104955.png" alt="Captura_20251127_104955.png">

</figure>

<p>
Niaj servilojn ne aperos en tiu listo. Nia celo estas elstarigi lokon
kie ludi kaj havos eblon por trovi aliajn esperantistojn.
</p>

<p>
Kiam vi komencas ludi kaj volas eniri nian servilon sekvu tiujn
paŝojn:
</p>


<figure id="org30042b4">
<img src="./imagenes/Eniro.png" alt="Eniro.png">

</figure>

<ol class="org-ol">
<li>Skribu la adreson IP.</li>
<li>Skribu la pordon.</li>
<li><p>
Klaku la butonon <i>Registriĝi</i>.
</p>

<p>
La fenestro kiu aperos estas tiu:
</p>


<figure id="orga87d3e0">
<img src="./imagenes/Registrado.png" alt="Registrado.png">

</figure></li>

<li>Skribu vian ludantan nomon.</li>
<li>Skribu pasvorton por via konto.</li>
<li>Retajpu la pasvorton.</li>
<li>Klaku denove la butonon <i>Registriĝi</i>.</li>
</ol>

<p>
Tiu servila adreso estos memorita pro la kliento de Luanti, pro tio,
la venontaj okazoj vi nur devas selekti la servilon de la listo, tajpi
vian pasvorton kaj klaki la butonon <i>Saluti</i>.
</p>
</div>
</div>
<div id="outline-container-orgadc0779" class="outline-3">
<h3 id="orgadc0779"><i>Mineclonia</i></h3>
<div class="outline-text-3" id="text-orgadc0779">
<p>
Tiu ludo estas libera klono de <i>Minecraft</i> kaj tre simila. Se vi neniam
ludis tiujn ludojn konsideru:
</p>

<ul class="org-ul">
<li>En tiu ludo ne estas celoj, estas malferma mondo por esplori,
konstrui kaj supervivi.</li>
<li>Vi batalos kontraŭ monstroj kaj la malsato.</li>
<li>Fosu por mineraloj kaj trezoroj.</li>
<li>Magio, gajnu sperton por sorĉi viajn iloj</li>
<li>Serĉu semojn kaj plantu ilin por kultivado de viajn manĝaĵojn.</li>
<li>Kaptu bestojn kaj bredu ilin.</li>
<li>Konstruu grandajn strukturojn kaj domojn.</li>
<li>Kaptu florojn por tinti viajn teksaĵojn.</li>
<li>...</li>
</ul>

<p>
Se vi neniam ludis tiujn ludojn unue vi povas sekvi ĉi tiujn pasojn
por ekludi kaj bone komenci viajn aventurojn:
</p>

<ul class="org-ul">
<li><b>Pri la <i>interfaco</i>:</b>
<ul class="org-ul">
<li>Premu <code>&lt;F5&gt;</code>, super maldekstre montrus al vi informon pri la
ludado. Estas tre gravaj la koordinatoj kie vi estas.</li>
<li>Premo litero <code>&lt;v&gt;</code>, por malfermi etan mapon super dekstre de la
ekrano.</li>
</ul></li>
<li><b>Pri la unuaj paŝoj:</b>
<ul class="org-ul">
<li>Frapu arban trunkon ĝis rompiĝo kaj kaptu lignaĵon.</li>
<li>Premu litero <code>&lt;i&gt;</code> kaj en la kadraĵo 2x2 metu lignon. Ĝi alportos al
vi kvar tabulojn.</li>
<li>Metu kvar tabulojn en la kadraĵo 2x2 kaj vi havos laboran tablon.</li>
<li>Metu la tablon sur la planko kaj uzu ĝin (dekstra butono de la
muso), aperon kadraĵon 3x3 por fabriki pli malsimplan aĵojn.</li>
<li>Premu la maldekstran butonon (kun la libro) por vidi receptojn por
fabriki aliajn aferojn.</li>
<li>Vi bezonas lignan fosilon por fosi ŝtonon (kun ŝtono vi povos
fabriki ŝtonan ilojn por fosi mineralojn, kiel fero, ktp.) Ankaŭ
ŝoveliloj... diversaj iloj taŭgas por diversaj materialoj. Provu!</li>
<li>Ankaŭ vi bezonas manĝaĵojn. Vi bezonos ŝpaton por kultivi vian
terenon.</li>
<li>Konstruu fornon (serĉu la recepton en la libro), multaj aĵon
bezonos bakadon.</li>
<li>Por uzi la forno: En la supra loko metos bakonta aĵon, en la
malsupra bruleman aĵon. (Fosu karbon, estas la plej brulema
materialo).</li>
</ul></li>
</ul>

<p>
Se ludante vi havas problemojn petu helpon al aliaj ludantoj. Demandu
viajn dubojn kaj ĝuu la ludon.
</p>

<p>
Memoru, nia servilo kun <i>Mineclonia</i> estos daŭre ŝaltita por ke vi povos
ludi kiam vi volos.
</p>
</div>
</div>
<div id="outline-container-org76959c8" class="outline-3">
<h3 id="org76959c8">Kaptu la flagon</h3>
<div class="outline-text-3" id="text-org76959c8">
<p>
Estas konkura ludo por teamoj. La batalado celas <b>kapti la flagojn</b> de
la aliaj teamoj antaŭ alia ludanto kaptus la vian. Do, defendu vian
flagon kaj kaptu la aliajn, organizu la teamon por la du taskoj.
</p>

<p>
La etoso ŝanĝiĝas de batalo al batalo por ne estu enua. Memoru, nia
servilo de <i>«kaptu la flagon»</i> nur funkcios, kiam ni renkontiĝos por
ludi kune kaj tiuj okazaĵoj estos anoncitaj ĉe <i>eventa servo</i>.
</p>
</div>
</div>
</div>
<div id="outline-container-org880b5c1" class="outline-2">
<h2 id="org880b5c1">Konludo</h2>
<div class="outline-text-2" id="text-org880b5c1">
<p>
Pro vi estas tiuj serviloj. Se vi havas sugestiojn aŭ problemojn
elsendu retmesaĝon al retpoŝto <i>esperanto</i> ĉe <i>nueva-actitud.org</i>. Ankaŭ
skribu nin se vi volas partopreni en la laboro pri la subtenado de la
ludojn kaj la servilojn.
</p>

<p>
La ludado estas libera (ene de la respektanta kutima agado) kaj tute
senpaga. Ni ne petos al vi monon pro neniu servo, kiun ni elstarigis.
Do, ni petas al vi, respektu nian laboron kaj ne insidos la ludon de
la ceteraj uzantoj.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En la angla <i>voxel game engine</i>... mi ne trovis taŭgan tradukon. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <link>https://notxor.nueva-actitud.org/2025/11/27/ludu-cxe-la-esperanta-servilo-de-luanti.html</link>
  <pubDate>Thu, 27 Nov 2025 09:41:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Projekto Ludejo II]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2025-11-25</div>
<p>
Ĉi tiun pasintan dimanĉon ni renkontiĝis por paroli pri la intereso
(aŭ ne) de <a href="https://notxor.nueva-actitud.org/2025/11/20/nova-projekto.html">nova projekto luda-esperanta</a>, kiun mi pensis elstari. Ni
eniris la renkontiĝon ses interesitaj homoj, kiuj konkludis, ke la
afero interesas.
</p>

<p>
Ni iomete ludis kaj interagis en etan <i>Luantian</i> servilon, kiun mi
elstarigis por la okazo. Ankaŭ interparolis pri kion ni bezonos, pri
la laborojn de tradukado de la ludo, kaj pri aliajn aferojn rilatajn.
Inter la lastaj, propono por elvolvi manieron por ludi parolante voĉe.
</p>

<p>
Do, mi tiam pensis pro la elstarigo de servilo de <a href="https://www.mumble.info/">Mumble</a> paralele al
servilo de Luanti dediĉita nur ekskluzive por tiu tasko. Ni studos la
eblon por programi modulon por Luanti, pro konekti ambaŭ servilojn.
Sed unue, la ludantojn devos instali klienton por <i>Mumble</i> ankaŭ, se ili
volas paroli voĉe kun la kunuloj en la ludo.
</p>

<p>
La servilo uzita por la pruvo ne plu funkcias. Por la vera luda
servilo mi pensis krei <i>novan mondon</i> sed finfine mi konsideris ke la
provojn ne difektis ĝin, kaj translokis tiun uzitan mondon al nova
servilo, en pli potenca maŝino kaj pli ampleksa memoro. Se iu, el tiuj
kiuj jam ludis dum la renkontiĝo volas eniri denove, sendu al mia
retpoŝto mesaĝon kaj mi resendos la novan IP de la servilo (ankoraŭ
prova).
</p>

<p>
Do, kio ja estas farita?
</p>

<ul class="org-ul">
<li>La projekto komencis kaj oni prenis decidon por elstari servilon.</li>
<li>La ludo jam funkcias en sufiĉe potenca servilo por komenci la
ludado.</li>
<li>La tradukado jam komencis kaj iom post iom la ludo estos plene
tradukita al Esperanto.</li>
</ul>

<p>
Do, kio mankas?
</p>

<ul class="org-ul">
<li>Elstari paralelan servilon de <i>Mumbre</i> por la interparolado voĉe.</li>
<li>Krei en la luda mondo diversajn komunajn aferojn por la ludantoj.</li>
<li>Krei modulon specifan por la lernado de Esperanto ene de la ludo.</li>
<li>Aĉeti domajnon por ne ludi nur per la IP.</li>
<li>Aldoni <i>blogon/retforumon</i> por montri novaĵojn, interagi kaj kontribui
al evoluo de la ludo.</li>
<li>Malfermi la ludadon.</li>
</ul>

<p>
Jen la afero: ankoraŭ mankas pli ol ni havas sed... <b>Atentu la novaĵojn!</b>
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <link>https://notxor.nueva-actitud.org/2025/11/25/projekto-ludejo-ii.html</link>
  <pubDate>Tue, 25 Nov 2025 10:54:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Nova projekto]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2025-11-20</div>
<p>
Ni komencas novan projekton. Mi diras <i>ni</i>, ĉar la projekton ne estas
nur <i>mia</i>. En la babilejo de XMPP<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, kelkajn tagojn antaŭe la
parolado estis pri ludado kaj retaj ludoj. Tiam mi proponis komenci la
aferon por elstari servilon de <a href="https://www.luanti.org/en/">«Luanti»</a>. Tiu ludo estas tre simila al
fama <i>Minecraft</i>, sed plene libera. Mi tre ŝatas tiun ludon, kutime
ludas en hispana servilo kaj bone interagas kun aliuloj. Ne nur
hispanaj, nek per hispana lingvo: kutime eniras homoj kiuj ne parolas
la hispanan, eĉ iuj el ili, lernantoj de la hispana, kiuj volas ludi
hispane por plibonigi sian scipovon de la lingvo.
</p>

<p>
Do, mi pensis fari samon, sed por Esperanto. Elstari servilon ne estas
komplika, sed aliaj taskoj necesas pli atenton por fari bone la
sperton de la ludantoj. Mi provis kelkajn ludojn faritajn por <i>Luanti</i>,
kiuj estas similaj al <i>Minecraft</i>. Inter ili, mi estas pli interesa la
ludon <a href="https://content.luanti.org/packages/ryvnf/mineclonia/">Mineclonia</a>, ĝi estas stabila kaj vere pli kompleta kaj moderna
ol la aliaj.
</p>


<figure id="org9f59a98">
<img src="./imagenes/screenshot_20251120_180221.png" alt="screenshot_20251120_180221.png">

</figure>


<figure id="orge6bf0ba">
<img src="./imagenes/screenshot_20251120_180744.png" alt="screenshot_20251120_180744.png">

</figure>

<p>
La antaŭaj bildoj estas ekrankopioj faritaj dum miaj provoj.
</p>

<p>
Do: Kion mi provis aŭ faris?
</p>

<ul class="org-ul">
<li>Mi havigis VPS-on por fari la provojn.</li>
<li>Mi sukcesis elstari servilon kaj konekti klienton por ludi.</li>
<li>Bedaŭrinde, la tradukado al Esperanto de Luanti ne estas plena,
mankas ankoraŭ multan laboron.</li>
</ul>

<p>
Do: Kion ni bezonas?
</p>

<ul class="org-ul">
<li>Plenumi la tradukadon, ne nur de Luanti, ankaŭ mankas tradukado de
la ludo <i>Mineclonia</i>. Ĉi tiun ĵaŭdon 20 mi komencis la tradukadon de
tiu ludo. Se iu el vi volas kunlabori, eniru en la ligilo:
<a href="https://translate.codeberg.org/projects/mineclonia/">https://translate.codeberg.org/projects/mineclonia/</a></li>
<li>Konstrui komunajn, ene de la luda mondo, lokojn por la
ludantoj. Inter ili, <i>lernejon</i> por lerni Esperanton, se iu ajn
homo eniras la ludon kaj volas lerni.</li>
<li>Ĝis nun, mi faris provojn sola... sed ni devas provi kun diversaj
ludantoj (prefere kunlaborantoj) de la projekto.</li>
</ul>

<p>
En la babilejo, antaŭe menciita, mi diros al (eblaj) kunlaborantoj
kiel oni povas eniri la servilon por preti la <i>Ludejo</i> antaŭ malfermi al
ĉiuj. Se vi volas partopreni en ĉi tiu projekto, bonvole atentu la
babilejon por la diskutado de la sekvantaj paŝoj. Mi esperas fari la
unuajn provojn publikajn ĉi tiu dimanĉo 23 de novembro, eble la sabato
22 sed nur por du-tri homoj. Nun la servilo estas malmulte potenca kaj
mi ne certas kiom da homoj povas ludi kune. En la estonteco, se la
projekto sukcesos, eble ni devos pagi por havi pli grandan servilon.
</p>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Se vi uzas XMPP, vi povas trovi nin ĉe esperanto@salas.suchat.org
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <link>https://notxor.nueva-actitud.org/2025/11/20/nova-projekto.html</link>
  <pubDate>Thu, 20 Nov 2025 17:58:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Sigo con Cuis-Smalltalk]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2025-11-15</div>
<p>
En los últimos tiempos estoy trayendo, quizá demasiado según algunas
voces discrepantes, <i>Smalltalk</i> al blog. Y lo seguiré trayendo, aunque
hay quien me haya hecho llegar su oposición a la <i>turra del Smalltalk</i>.
Hablándolo con un amigo, me dice que no tengo que explicar nada, que
el blog es mío y puedo escribir en él lo que a mí me apetezca. No le
falta razón. Sin embargo, terminaré de dar mis motivos y lo que busco.
</p>

<p>
Si no quieres otra <i>turra</i> sobre <i>Cuis-Smalltalk</i>, salta directamente a la
conclusión. Encontrarás sólo mis motivos.
</p>

<p>
Quien se queja, llegó a este blog buscando información sobre <i>Emacs</i>, y
es cierto que he escrito mucho sobre mi editor favorito, pero si
hubiera rascado un poco en el contenido del blog, se habría dado
cuenta de que el contenido no es monotemático y hay muchas otras cosas
que encontrar por aquí. El blog va de cosas que me llaman la atención,
de cosas que aprendo, de cosas de las que me parece importante hablar
y de cosas que anoto para no olvidar.
</p>

<p>
Últimamente decidí prestarle atención de nuevo al <i>Smalltalk</i>, porque es
un lenguaje/entorno que siempre me ha llamado la atención desde que lo
descubrí a finales del siglo pasado. Junta algunas de las
características que hacen que me pique el gusanillo:
</p>

<ul class="org-ul">
<li>Tecnología rompedora en su momento.
<ul class="org-ul">
<li>Primer entorno gráfico en utilizar ratón en su <i>interface</i> de manejo.</li>
<li>Primer lenguaje <b>puro</b> siguiendo el paradigma de la <i>Programación
Orientada a Objetos</i>.</li>
<li>Entorno completo para ejecución y programación.</li>
<li>Entorno diseñado con ánimo de incrementar las capacidades
cognitivas de los usuarios.</li>
</ul></li>
<li>Tecnología <i>viejuna</i> alejada del <i>mainstream</i> de la programación actual.</li>
<li>Paradigma simple y consistente: <i>Todo valor es un objeto y el
sistema funciona sólo con objetos enviándose mensajes</i>.</li>
</ul>

<p>
Por otro lado, en los principios que formuló Dan Ingalls<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>
se expresa:
</p>

<blockquote>
<p>
<b>Personal Mastery</b>: <i>If a system is to serve the creative spirit, it
must be entirely comprehensible to a single individual</i>.
</p>

<p>
-- <i>Daniel H. H. Ingalls</i> 
</p>
</blockquote>

<p>
Que viene a decir, en una traducción libre: <i>Si un sistema es para
servir al espíritu creativo, debe ser completamente comprensible por
un individuo.</i>
</p>

<p>
Pues bien, lo del <i>espíritu creativo</i> me pone y mi <i>espíritu creativo</i>
necesita un sistema que lo aliente, o lo sirva, y, puesto que dicen
que es posible, me propongo hacer comprensible para mis cortas
entendederas, de psicólogo usuario de informática, todo el sistema.
</p>

<p>
Por concretar un poco más, las cosas que me gustaría poder manejar
perfectamente con <i>Cuis-Smalltalk</i> son las siguientes:
</p>

<ul class="org-ul">
<li><p>
<b>I/O</b>: <i>Lectura y escritura de archivos externos al entorno</i>.
</p>

<p>
<i>Smalltalk</i> es un sistema bastante cerrado y la <i>persistencia de
datos</i> suele realizarse directamente en la <i>imagen del entorno</i> y no en
archivos externos.
</p></li>

<li><p>
<b>Interacción con el S.O.</b>: <i>Interactuar con el Sistema Operativo,
lanzar aplicaciones, obtener datos</i>.
</p>

<p>
Abundando en el punto anterior, y siendo un sistema bastante
completo y redondo, la interacción con el Sistema Operativo en
muchos casos no es necesaria, pero siempre es útil saber cómo
realizar esta interacción.
</p></li>

<li><p>
<b>Cliente/Servidor</b>: <i>Generar una aplicación Cliente/Servidor con Cuis</i>.
</p>

<p>
Como he dicho antes, <i>Smalltalk</i> tiende a ser un sistema cerrado. Me
gustaría aprender a abrirlo en algún tipo de servicio de red.
</p></li>

<li><p>
<b>GUI</b>: <i>Manejar con soltura todo el entorno gráfico Morphic de
Smalltalk</i>.
</p>

<p>
<i>Cuis-Smalltalk</i> proporciona un entorno gráfico maduro para la
realización de <i>interfaces</i> de usuario.
</p></li>

<li><p>
<b>Paquetes</b>: <i>Manejo de paquetes y control de versiones</i>.
</p>

<p>
El sistema de <i>Cuis-Smalltalk</i> proporciona un completo sistema de
gestión de paquetes desde código fuente. El objetivo aquí sería
conocer cómo se podría gestionar un proyecto mediante algún sistema
de control de versiones, si fuera posible con varios programadores.
</p>

<p>
Además <i>Cuis-Smalltalk</i> tiene el sistema de <i>Features</i> que se sostiene
en el manejo de paquetes.
</p></li>

<li><p>
<b>Librerías externas</b>: <i>Interacción con librerías escritas en C
mediante FFI</i>.
</p>

<p>
La ampliación de las posibilidades del entorno de <i>Cuis-Smalltalk</i>
pasa por la utilización de otras librerías del sistema, que
principalmente están escritas, o son compatibles, con el lenguaje
C/C++. Me gustaría trastear lo suficiente para encontrarme cómodo
utilizando librerías externas y/o programando mis propias librerías
en C/C++ para acelerar la ejecución de mi sistema.
</p></li>

<li><p>
<b>Kernel de Smalltalk</b>: <i>Comprender cómo funciona internamente el
propio sistema de Smalltalk</i>.
</p>

<p>
<i>Smalltalk-80</i> fue la última definición del lenguaje y el entorno, del
que <i>Cuis-Smalltalk</i> es un heredero directo. Cuenta con todo un
sistema de clases, y <i>metaclases</i>, que determina finalmente el
comportamiento y las capacidades del sistema.
</p></li>
</ul>

<p>
Todos esos puntos me propongo aprender a manejar con el único objetivo
de aprender a manejarlos. ¿Haré alguna aplicación concreta? Pues no lo
sé, ahora mismo no se me ocurre en qué podría invertir todo este
esfuerzo de aprendizaje. Supongo que según avance en la comprensión
del sistema y sus posibilidades, se me ocurrirá algún proyecto loco
que hacer con él<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.
</p>

<p>
Pero sí, respondiendo a otra pregunta, hay algo que me <i>frustresa</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>
del entorno <i>Cuis-Smalltalk</i>: sólo puedes programar en <i>Smalltalk</i>. Aunque
tiene otros puntos en común con <i>Emacs</i> que te resultarán familiares:
</p>

<ul class="org-ul">
<li><i>Interface de usuario</i>: <i>Emacs</i> orientado a texto, <i>Cuis</i> gráfico.</li>
<li><i>Lenguaje de extensión</i>: <i>Lisp</i> para <i>Emacs</i>, <i>Smalltalk</i> para <i>Cuis</i>.</li>
<li><i>Ampliación mediante paquetes</i>: Paquetes que se distribuyen mediante
código fuente.</li>
<li><i>Sistema accesible</i>: Todo el código está a la vista y es modificable.</li>
<li><i>Casi un Sistema Operativo</i>: Ambos sistemas son casi un Sistema
Operativo en sí mismos.</li>
</ul>

<p>
Mientras trasteo iré tomando notas. Me he montado un <i>wiki</i> de
<i>TiddlyWiki</i> para ello. Lo podéis encontrar en esta misma página en el
enlace <a href="https://notxor.nueva-actitud.org/cuis/apuntesCuisSmalltalk.html">https://notxor.nueva-actitud.org/cuis/apuntesCuisSmalltalk.html</a>
Si te interesa dicho trasteo, puedes seguir mis avances, si no, no lo
hagas. Estos apuntes son fundamentalmente para mi propio uso. Los
pongo en un lugar público por si a alguien más le son útiles o le
interesan.
</p>

<p>
Además también podéis encontrar al lado mi traducción del libro de
<i>Cuis-Smalltalk</i>, si lo que buscas es introducirte en este entorno:
</p>

<ul class="org-ul">
<li>La versión pdf: <a href="https://notxor.nueva-actitud.org/cuis/TheCuisBook.pdf">https://notxor.nueva-actitud.org/cuis/TheCuisBook.pdf</a></li>
<li>La versión html: <a href="https://notxor.nueva-actitud.org/cuis/html/index.html">https://notxor.nueva-actitud.org/cuis/html/index.html</a></li>
<li>La versión Tiddlywiki: <a href="https://notxor.nueva-actitud.org/cuis/TheCuisBook.html">https://notxor.nueva-actitud.org/cuis/TheCuisBook.html</a></li>
<li>El código fuente de la traducción: <a href="https://notxor.nueva-actitud.org/TheCuisBook-es.zip">https://notxor.nueva-actitud.org/TheCuisBook-es.zip</a></li>
</ul>
<div id="outline-container-org0fcfa73" class="outline-2">
<h2 id="org0fcfa73">Conclusión</h2>
<div class="outline-text-2" id="text-org0fcfa73">
<p>
En resumen: <i>Si no te gustan estos temas, no leas estos artículos</i>. Si
sólo buscas documentación sobre <i>Emacs</i>, te recuerdo que <i>Emacs</i> provee un
completo manual de uso y también otro completo manual de programación.
Todos los artículos que he escrito, y los que escribiré, sobre <i>Emacs</i>
están sacados de esos manuales o de la documentación del paquete
concreto sobre el que trata el artículo.  Seguro que tú también
puedes, incluso mejor que yo, extraer esa información de esas fuentes.
</p>

<p>
Este blog es <i>mi</i> blog. Trato temas sobre tecnologías, sobre psicología,
sobre juegos, sobre Esperanto... temas que a <i>mí</i> me interesan. Y
además, está escrito sin ánimo de lucro, ni siquiera de
reconocimiento, no busca ser leído por nadie en concreto, salvo por
<i>mí</i>, pues suelo usarlo con frecuencia para recordarme a <i>mí mismo</i> cómo
hacer ciertas cosas.  Está abierto al espacio público, porque algunas
cosas pueden ser útiles a otras personas, pero no necesito lectores,
no verás anuncios, ni ningún otro sistema de monetización estándar.
Este es un espacio libre, donde ejerzo mi libertad de escribir sobre
lo que quiero, desde mi punto de vista, desde el respeto. Si te
gustaría que fuera de <i>esta</i> o de <i>aquella</i> manera, no necesitas
contármelo a mí: escribe tú en el tuyo según tus gustos y monetiza lo
que hagas como tú quieras. No apeles a una avaricia que no tengo para
influir los temas que debería tratar.
</p>

<p>
El primer post de <i>Notxor tiene un blog</i> se publicó el 1 de febrero de
2016, este próximo febrero, el blog cumplirá 10 años. En los casi 10
años que lleva en funcionamiento, el sistema de donaciones ha
recaudado la magnífica suma de 5€ en total<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>. Antes escribí en otro
blog, que se perdió en las memorias del tiempo y que en sus seis años
de funcionamiento recaudó la abultada suma de 0€. Si mantengo el blog,
es evidente que no es por razones económicas. De él sólo obtengo
facturas y gastos.
</p>

<p>
Hace bastante cerré los comentarios del blog, entre otras cosas, para
evitar mensajes de <i>trolls</i> dispuestos a criticar hasta lo no
criticable. Aunque el motivo fundamental fue que hubo ataques
malintencionados, de <i>script kiddies</i><sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>, que me hacían tener que estar
limpiando el espacio de comentarios varias horas al día. No voy a
abrirlos porque lo pida nadie o porque harían más <i>monetizable</i> el blog,
no insistas.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://www.cs.virginia.edu/~evans/cs655/readings/smalltalk.html">https://www.cs.virginia.edu/~evans/cs655/readings/smalltalk.html</a> 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Me apetece algún tipo de juego, pero ya veremos hacia donde
giran las necesidades.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Me frustra y me estresa.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Que como puedes suponer no llegan a cubrir los gastos de ningún
año ni de <i>host</i> ni de <i>dominio</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Me niego a llamarlos <i>hackers</i>. Un <i>hacker</i> hubiera visto a la
primera que no había una base de datos a la que hacerle una inyección
de códico SQL en el formulario de comentarios, no necesitaría enviar
300 variaciones de lo mismo a lo largo de una hora, o 1500 consultas
SQL de usuarios y correos.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/cuis/index.html">cuis</a> <a href="/tags/smalltalk/index.html">smalltalk</a> ]]></description>
  <category><![CDATA[cuis]]></category>
  <category><![CDATA[smalltalk]]></category>
  <link>https://notxor.nueva-actitud.org/2025/11/15/sigo-con-cuis-smalltalk.html</link>
  <pubDate>Sat, 15 Nov 2025 19:55:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Traducción del libro de Cuis-Smalltalk]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2025-11-02</div>
<p>
Estos días he terminado la traducción del libro <i>The Cuis Smalltalk</i> al
español. Me hubiera gustado enviárselo a los autores originales, pero
no encuentro ningún correo electrónico al que hacerlo y es imposible
sin cuenta de GitHub. Cuenta que hace años cerré y que no pienso
volver a abrir<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>

<p>
Así, esta nota rápida trata de que podáis encontrar la traducción de
forma sencilla.
</p>

<ul class="org-ul">
<li>Formato <code>html</code>: <a href="https://notxor.nueva-actitud.org/cuis/html">https://notxor.nueva-actitud.org/cuis/html</a></li>
<li>Formato <code>pdf</code>: <a href="https://notxor.nueva-actitud.org/cuis/TheCuisBook.pdf">https://notxor.nueva-actitud.org/cuis/TheCuisBook.pdf</a></li>
<li>Formato <i>wiki</i> de <i>TiddlyWiki</i>: <a href="https://notxor.nueva-actitud.org/cuis/TheCuisBook.html">https://notxor.nueva-actitud.org/cuis/TheCuisBook.html</a></li>
<li>Fuentes de la traducción: <a href="https://notxor.nueva-actitud.org/cuis/TheCuisBook-es.zip">https://notxor.nueva-actitud.org/cuis/TheCuisBook-es.zip</a></li>
</ul>

<p>
Otra opción que me había planteado era montar un <i>fork</i> del repositorio
en <a href="https://codeberg.org/">Codeberg</a>. Pero tampoco tiene mucho sentido, para un trabajo tan
puntual.
</p>

<p>
El código no es libre si los repositorios sobre los que se asienta no
lo son. Y una de las cosas que me están echando para atrás de
<i>Cuis-Smalltalk</i> es su enfermiza dependencia de <i>GitHub</i> para sus
paquetes. Y digo enfermiza, porque sería muy sencillo evitarla,
bastaría con poner los repositorios en otro sitio.
</p>

<p>
En fin, aquí dejo la traducción para todo el que la quiera utilizar.
</p>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Aunque me consta que sigue abierta y nunca se cerró. Porque
para qué va a hacer una corporación como Micro$oft, caso a lo que le
pida un usuario pudiendo hacer su voluntad sin ninguna consecuencia.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/cuis/index.html">cuis</a> <a href="/tags/smalltalk/index.html">smalltalk</a> ]]></description>
  <category><![CDATA[cuis]]></category>
  <category><![CDATA[smalltalk]]></category>
  <link>https://notxor.nueva-actitud.org/2025/11/02/traduccion-del-libro-de-cuis-smalltalk.html</link>
  <pubDate>Sun, 02 Nov 2025 10:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Un avance con Cuis-Smalltalk]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2025-10-18</div>
<p>
Hoy toca artículo cortito. Llevo unos días trasteando un poco con
<i>Cuis-Smalltalk</i> y he conseguido terminar de traducir su libro de
introducción a la programación, que podéis encontrar y descargar de
<a href="https://notxor.nueva-actitud.org/TheCuisBook.html">https://notxor.nueva-actitud.org/TheCuisBook.html</a>
</p>

<p>
Siguiendo el libro hay toda una serie de explicaciones que te van
llevando a la programación del clásico <i>Spacewar!</i>. En realidad, al
final tuve que mirar el código fuente, que viene completo en el libro,
porque durante el desarrollo hubo algunos puntos que no estaban claros
y faltaban algunos detalles para hacerlo funcionar.
</p>


<figure id="orged3e96f">
<img src="./imagenes/Captura_inicio.png" alt="Captura_inicio.png">

</figure>

<p>
Sin embargo, el objetivo principal del libro, que es mostrar un
abanico básico de la sintaxis y el entorno de <i>Cuis-Smalltalk</i> está
conseguido. De abordaje sencillo y progresivo va introduciendo
conceptos y explicando las idiosincrasias de Smalltalk.
</p>

<p>
Como veis en la imagen anterior, como el tema del juego me estaba
viniendo todo un poco torcido, terminé de torcerlo yo aún un poco más.
Mi idea original era modificar la forma de dibujar el fondo, hacerlo
circular como en el juego original. Al final me contenté con dejarlo
girado 45º. No tenía ganas de ponerme a calcular cuándo salen los
objetos del círculo que delimita el juego, complicándome las fórmulas
con varios cálculos.
</p>
<div id="outline-container-org19023fd" class="outline-2">
<h2 id="org19023fd">Conclusión</h2>
<div class="outline-text-2" id="text-org19023fd">
<p>
Ha sido un interesante repaso de los pocos conocimientos que tengo de
Smalltalk. El cacharreo ha sido interesante. Por lo que he visto
<i>Morphic</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> es ligeramente diferente a como lo recordaba de cuando
utilicé <i>Squeak</i>.
</p>

<p>
El objetivo ahora es conseguir hacer algún proyecto interesante, quizá
deba darme un repaso a los dos librillos que tienen sobre la UI para
manejarme con más soltura.
</p>

<p>
¡Seguiremos informando!
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
El entornos gráfico que hace de UI del sistema 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/smalltalk/index.html">smalltalk</a> <a href="/tags/cuis/index.html">cuis</a> ]]></description>
  <category><![CDATA[smalltalk]]></category>
  <category><![CDATA[cuis]]></category>
  <link>https://notxor.nueva-actitud.org/2025/10/18/un-avance-con-cuis-smalltalk.html</link>
  <pubDate>Sat, 18 Oct 2025 07:40:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[¿Cuándo perdimos el norte?]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2025-10-04</div>
<p>
A raíz de <a href="https://notxor.nueva-actitud.org/2025/09/20/cacharreo-nostalgico.html">mi anterior artículo</a> donde hablaba de <i>Smalltalk</i> y contaba
algunas batallitas sobre él y lo que me llegó a interesar ese
lenguaje, también hay quien me ha pedido que profundizara un poco en
el asunto. Pero al empezar a profundizar y documentar este artículo de
hoy he vuelto a recaer en la idea de que con la tecnología nos están
desviando del camino correcto. <b>¿Cuándo perdimos el norte?</b> No voy a
contestarlo, porque no encuentro una respuesta satisfactoria, pero
está claro que no estamos donde deberíamos.
</p>

<p>
Por otro lado, en <i>Mastodon</i>, <a href="https://mamot.fr/@drgeo">DrGeo</a>, me recomendó usar <i>Cuis</i> y me dije
«¿por qué no?». Aquí van las reflexiones de un psicólogo
informatizado.
</p>
<div id="outline-container-org54a8220" class="outline-2">
<h2 id="org54a8220">Un poco de historia</h2>
<div class="outline-text-2" id="text-org54a8220">
<p>
Después de tantos años he vuelto a trastear con <i>Smalltalk</i>, lo
confieso. Como he dicho, llevo semanas en ello con
<span id="nota">Cuis-Smalltalk<span class="nota"> <a href="https://cuis.st/">https://cuis.st/</a> un <i>Smalltalk</i> que conocía</span></span> <sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.  Concretamente siguiendo el libro <i><span id="nota">The Cuis Book<span class="nota"> <a href="https://drcuis.github.io/TheCuisBook/">https://drcuis.github.io/TheCuisBook/</a></span></span></i>, sobre el cual me
estoy tomando la tarea de <span id="nota">traducir al español<span class="nota">Mis avances, aunque lentos, los podréis encontrar en <a href="https://notxor.nueva-actitud.org/TheCuisBook.html">este enlace</a>.</span></span><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. En
principio, sería para uso personal, pero si al final queda bien, se
podría enviar a los autores del libro, en formato <i>texinfo</i> para que
puedan añadirlo al repositorio. En fin, ya se verá.
</p>

<p>
Lo que me ha hecho retomarlo es el mismo sentimiento que me llevó a él
en un primer momento. Proviene de una época donde se pensaba en la
tecnología como un complemento a lo humano. El sistema de <i>Smalltalk</i>
nació con la idea de ser un apoyo, una ayuda que le facilitara a las
personas expresar sus pensamientos e ideas. Ahora nos venden que el
futuro es que las máquinas piensen por nosotros. En algún momento,
está claro, que perdimos el norte. Cuando <i>Alan Kay</i> decía que «una
computadora sólo es un instrumento cuya música son ideas» o que son
«bicicletas para la mente», estaba poniendo en el centro el desarrollo
humano, las ideas humanas, no las de la máquina. Pero me estoy
adelantando, regreso a los orígenes a ver si consigo hacerme entender.
</p>

<p>
Cuando la electrónica se desarrolla y se generan los primeros inicios
de la computación. El pensamiento que regía el proceso central
<span id="nota">era el pensamiento humano<span class="nota">lo sigue siendo, a pesar de que haya mucha gente empeñada en vendernos humo con la IA.</span></span>, las
máquinas se limitaban a procesar muchos datos más rápido de lo que
podemos hacer las personas. Sin embargo, ya se planteaban maneras en
que se podrían utilizar esas máquinas para ayudar al desarrollo
cognitivo humano.
</p>

<p>
Para esto, podemos encontrar varios predecesores de esto, incluso
antes de la computación<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup><sup>, </sup><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>, durante los años 40 del siglo
pasado.
</p>

<p>
Durante esos años y posteriores, la psicología desarrollaba su teoría
<i>constructivista</i> del aprendizaje<sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>, cuyos postulados nacen de los
trabajos de algunos exponentes principales como Lev Vygotski,
<span id="nota">Jean Piaget<span class="nota">en realidad era biólogo</span></span>, <span id="nota">Seymur Paper<span class="nota">fue un matemático pionero en la IA, creador del lenguaje <i>Logo</i>.</span></span> o Albert Bandura, por poner sólo unos ejemplos. No voy a
entrar tampoco en profundizar en esta teoría, ni en las polémicas de
seguidores y detractores que aún colean en el ámbito de la psicología.
Aún recuerdo una conferencia de <a href="https://es.wikipedia.org/wiki/Paul_Watzlawick">Paul Watzlawick</a>, sobre <i>el arte de
amargarse la vida</i> durante mis años en la Universidad.
</p>

<p>
Lo menciono porque el desarrollo de <i>Smalltalk</i> está imbricado con esta
teoría y es un intento de proporcionar una herramienta que ayude al
desarrollo cognitivo humano. Especialmente para Alan
Kay <sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup> <sup>, </sup><sup><a id="fnr.7" class="footref" href="#fn.7" role="doc-backlink">7</a></sup> <sup>, </sup><sup><a id="fnr.8" class="footref" href="#fn.8" role="doc-backlink">8</a></sup> <sup>, </sup><sup><a id="fnr.9" class="footref" href="#fn.9" role="doc-backlink">9</a></sup>.
</p>

<p>
Pero avanzando un poco más, podemos encontrar algunos principios de
diseño interesantes, según los plantea Dan Ingalls<sup><a id="fnr.10" class="footref" href="#fn.10" role="doc-backlink">10</a></sup>. Para
empezar define el propósito del lenguaje como un marco para la
comunicación. Para la comunicación interpersonal, no sólo la
comunicación de ordenadores o sistemas dentro de un ordenador.
</p>

<p>
También, en su principio de <b>metáfora única</b>, propone que un lenguaje
debería ser diseñado alrededor de una única potente metáfora que se
pueda aplicar en todas las áreas. Por ello, en <i>Smalltalk</i>, todo es un
objeto que interactúa con los objetos de su entorno enviándoles
mensajes. A partir de esta metáfora se construye todo. Ocurre, en ese
sentido podríamos pensar lo mismo sobre <i>Lisp</i>, donde todo son listas,
los datos y el código pertenecen a <i>la misma metáfora</i>. Es decir, los
sistemas deberían simplificarnos todo lo posible la manera en que
pensamos sobre ellos, especialmente en los sistemas complejos.
</p>

<p>
Además, establece un principio, que desde mi punto de vista está muy
relacionado con los principios del <i>software libre</i>. Este es el
<i>principio reactivo</i>, que afirma que todo componente accesible debería
estar presente de manera comprensible para el usuario de manera que le
permita manipularlo y observarlo.
</p>

<p>
Pero de manera más general, lo que más me atrajo en su día, el autor
lo expresa en su primer principio, que viene a decir que «si un
sistema debe servir para la creatividad humana, debería ser
perfectamente comprensible para una persona».
</p>
</div>
</div>
<div id="outline-container-org93f9f80" class="outline-2">
<h2 id="org93f9f80">¿Por qué Cuis?</h2>
<div class="outline-text-2" id="text-org93f9f80">
<p>
Hasta ahora había trabajado principalmente con los tres <i>Smalltalk</i> que
nombré en el artículo anterior. <i>Cuis</i> lo conocía de nombre, pero nunca
me había puesto a trabajar con él. Lo concebía como un <i>fork</i> del
original <i>Squeak</i> y, puestos a trastear, hasta ahora me había quedado
con el original.
</p>

<p>
La historia del <i>software</i> pasó por encima a <i>Smalltalk</i>, que nació con la
pretensión fundamental de ampliar las capacidades humanas en una época
donde el <i>hardware</i> estaba tan limitado que cerró las posibilidades del
ese <i>software</i>. La tecnología se metió en una vorágine evolutiva
primando eficiencia, velocidad, máquina sobre lo humano y
<i>Smalltalk</i> no se destaca en esos aspectos. Aunque algunos de esos
sistemas lo intentaron, fueron rápidamente adelantados por otros
lenguajes más complicados, más confusos, pero más <i>«eficientes»</i>.
</p>

<p>
Estos días he vuelto a trastear con <i>Cuis</i> y me vuelvo a sentir
implicado con él. <i>Cuis</i> es un intento de prolongar esa filosofía que
creó <i>Smalltalk</i>, la de poner en el centro el pensamiento humano y
continuar el legado del Smalltalk-80. Más allá de las demás
consideraciones he vuelto a encontrar un poco de paz en mi confuso
cerebro. Quizá porque es realmente un sistema de programación
orientada a objetos y no un <i>engendro con clases</i>, que también aprovecha
algunos principios de la programación funcional, maneja las
colecciones de manera clara y sencilla, como lo podría hacer <i>Lisp</i>. El
código externo no modifica las variables, es el propio objeto el
responsable de su estado. Los elementos del lenguaje son mínimos:
objetos, menajes y <span id="nota">bloques de código<span class="nota">que consisten en más objetos enviándose mensajes</span></span>. Todo se monta así, <span id="nota">bucles<span class="nota">el resultado de enviar los mensajes adecuados a un número entero</span></span>,
<span id="nota">control de flujo<span class="nota">el resultado de enviarle mensajes a un objeto de clase Boolean</span></span>. Además cuenta con un entorno completo que
permite no sólo programar, sino también el acceso completo al
lenguaje, ver cómo está implementado, herramientas para el depurado,
las pruebas unitarias, un completo sistema gráfico de presentación de
la información. Todo ello accesible, programable, modificable.
</p>

<p>
He podido percibir también, que <i>Cuis</i> elimina la necesidad de algunos
aspectos complejos de su sistema padre <i>Squeak</i>. La exploración se me
está haciendo más sencilla. Aunque tampoco puedo afirmar que sea por
esto, porque siempre es más sencillo retomar algo ya conocido que
iniciarse de cero. Es posible que me autoengañe y perciba una mayor
sencillez porque lo entiendo mejor por mis conocimientos previos y no
porque lo sea realmente. Pero esa sensación la tengo.
</p>
</div>
</div>
<div id="outline-container-org47e3a65" class="outline-2">
<h2 id="org47e3a65">Conclusión</h2>
<div class="outline-text-2" id="text-org47e3a65">
<p>
En fin, estos días he vuelto a pensar en lo errado del desarrollo de
<i>software</i> y cómo las buenas ideas, aquellas que ponían al ser humano en
el centro del proceso, han sido desplazadas por otras que ponen la
eficiencia en tiempo y dinero. Más últimamente con la IA, que nos
promete que el futuro de las máquinas es sustituir el pensamiento
humano, no ayudarlo a formarse, a evolucionar sino eliminarlo por
completo. ¿De verdad alguien cree que no vamos a necesitar pensar,
tener ideas y desarrollarlas?
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://cuis.st/">https://cuis.st/</a> 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
El desarrollo de la traducción lo podéis seguir en
<a href="https://notxor.nueva-actitud.org/TheCuisBook.html">https://notxor.nueva-actitud.org/TheCuisBook.html</a>. Es una <i>wiki</i> hecha
con <i>TiddlyWiki</i> —otro melón que ya traje del huerto y que no voy a
abrir aquí—.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
El artículo de Vannevar Bush en 1945 <i>«As we may thing»</i>, donde
hace un alegato para el desarrollo de un sistema —Memex—, para ayudar
a las personas a acceder, desarrollar y capturar conocimientos.
<a href="http://iibi.unam.mx/~voutssasmt/documentos/Vannevar_Bush_Como%20podriamos%20_Pensar_JV.pdf">Traduccion al español</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
La enciclopedia mecánica de <a href="https://es.wikipedia.org/wiki/%C3%81ngela_Ruiz_Robles">Ángela Ruiz Robles</a> aquí en España.
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://es.wikipedia.org/wiki/Constructivismo_(pedagog%C3%ADa)">https://es.wikipedia.org/wiki/Constructivismo_(pedagog%C3%ADa)</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i><a href="https://tinlizzie.org/VPRIPapers/hc_pers_comp_for_children.pdf">A Personal Computer for Children of All Ages</a></i>
</p></div></div>

<div class="footdef"><sup><a id="fn.7" class="footnum" href="#fnr.7" role="doc-backlink">7</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i><a href="https://tinlizzie.org/VPRIPapers/m1977001_dynamedia.pdf">Personal Dynamic Media</a></i>
</p></div></div>

<div class="footdef"><sup><a id="fn.8" class="footnum" href="#fnr.8" role="doc-backlink">8</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i><a href="https://tinlizzie.org/VPRIPapers/hc_what_Is_a_dynabook.pdf">Afterword: What is a Dynabook?</a></i>
</p></div></div>

<div class="footdef"><sup><a id="fn.9" class="footnum" href="#fnr.9" role="doc-backlink">9</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i><a href="https://raw.githubusercontent.com/worrydream/EarlyHistoryOfSmalltalk/master/SmalltalkHistoryHOPL-scanned-2015-07-16.pdf">The Early History Of Smalltalk</a></i>
</p></div></div>

<div class="footdef"><sup><a id="fn.10" class="footnum" href="#fnr.10" role="doc-backlink">10</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i><a href="https://www.cs.virginia.edu/~evans/cs655/readings/smalltalk.html">Design Principles Behind Smalltalk</a></i>
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/smalltalk/index.html">Smalltalk</a> <a href="/tags/cuis/index.html">Cuis</a> <a href="/tags/programación/index.html">programación</a> ]]></description>
  <category><![CDATA[Smalltalk]]></category>
  <category><![CDATA[Cuis]]></category>
  <category><![CDATA[programación]]></category>
  <link>https://notxor.nueva-actitud.org/2025/10/04/cuando-perdimos-el-norte.html</link>
  <pubDate>Sat, 04 Oct 2025 09:46:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Cacharreo nostálgico]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2025-09-20</div>
<p>
Llevo un tiempo sin cacharrear demasiado, no es que no me apetezca (o
sí), también puede ser que no encuentro ningún proyecto que me motive.
He comenzado tres o cuatro de ellos y los he abandonado al poco tiempo
por aburrimiento.  La cuestión se alarga en el tiempo y empiezo a
estar preocupado. Hasta hace poco contaba siempre con ese motivo para
pensar y darle vueltas a algo saliéndome del aburrido <i>«comer, dormir,
trabajar»</i>. El otro día, hablando con mi viejo amigo Giuseppe, salió a
relucir nuestra época de proyectos con <i>Smalltalk</i>. Un lenguaje que no
es sólo un lenguaje, es un sistema; que es antiguo, sin ser el más
antiguo; que es el primero completamente <i>orientado a objetos</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>,
aunque no sea el primer lenguaje <i>POO</i>... y me entró la nostalgia. En
aquellos entonces asistimos al nacimiento de <i>Pharo</i>, al de <i>GNU
Smalltalk</i>, al de <a href="https://amber-lang.net/">Amber</a>... Es decir, se iba imponiendo el <i>software
libre</i> en lo que, hasta entonces, eran plataformas <i>Smalltalk</i>
propietarias.
</p>

<p>
Estos días, llámalo nostalgia o aburrimiento, he estado cacharreando
dándole un repaso a las viejas herramientas que utilicé en aquellos
años para ver cómo han evolucionado.
</p>

<p>
Para no meterme en demasiados temas colaterales hablaré de unas pocas
herramientas. Principalmente utilicé tres, aunque es cierto que le
eché un ojo a muchas otras:
</p>

<ul class="org-ul">
<li><p>
<b>Squeak</b>: <a href="https://squeak.org/">https://squeak.org/</a>
</p>

<p>
Una evolución del <i>ST-80</i> de finales de los años 70 del siglo pasado,
pero enfocado a la educación infantil, que se quedó como el único
<i>Smalltalk</i> de código abierto en su momento.
</p></li>

<li><p>
<b>Pharo</b>: <a href="https://pharo.org/">https://pharo.org/</a>
</p>

<p>
Un <i>fork</i> de <i>Squeak</i> que eliminaba el enfoque más <i>infantil</i> para
proporcionar un entorno de programación <i>Smalltalk</i> profesional dentro
del <i>software libre</i>.
</p></li>

<li><p>
<b>Smalltalk/X</b>: <a href="https://www.exept.de/en/products/smalltalk-x-en.html">https://www.exept.de/en/products/smalltalk-x-en.html</a>
</p>

<p>
Un desarrollo de la compañía alemana <i>Exept</i> que se distribuía con una
licencia gratuita. La mayoría de la misma bajo una licencia <i>MIT</i>,
pero también había partes o librerías desarrolladas con ésta que
eran código propietario.
</p></li>
</ul>
<div id="outline-container-orgca01f8a" class="outline-2">
<h2 id="orgca01f8a">Un repaso (nostálgico) a <i>Smalltalk</i></h2>
<div class="outline-text-2" id="text-orgca01f8a">

<figure id="org04f48ec">
<img src="./imagenes/syntax-postcard.png" alt="syntax-postcard.png">

</figure>

<p>
Seguramente has oído hablar de <i>Smalltalk</i>. Posiblemente, y puesto que
uno de los nichos donde se ha quedado encerrado es el educativo, si
has estudiado programación, incluso puede que lo hayas estudiado. Pero
no trato de hacer una presentación aséptica, completa y exhaustiva del
lenguaje y sus herramientas, sino que voy a dar mis puntos de vista,
subjetivos, evidentemente, sobre este asunto. Me gustó su sencillez:
en la imagen de arriba tenéis resumida todos los elementos de la
sintaxis del lenguaje en una postal.
</p>

<p>
Cuando me llegó información concreta sobre <i>Smalltalk</i> ya conocía otros
lenguajes y programaba con cierta soltura con algunos de ellos, bajo
la égida de la POO<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. En general, la <i>POO</i> me parece una buena
abstracción como psicólogo<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>, aunque para resolver problemas puede
haber otros procedimientos tan válidos o, incluso, más eficientes. De
hecho, en líneas generales, considero que la <i>POO</i> puede también
entorpecer u ofuscar una solución, cuando las <i>clases</i> empiezan a ser
más etéreas y menos tangibles. Los conceptos, menos tangibles, o más
abstractos si lo prefieres, son más complicados de manejar por la
mente humana y, por tanto, de llevar a una estructura virtual,
paralela en <i>POO</i>.
</p>

<p>
Éste enfoque, <i>Smalltalk</i> lo resume en dos aspectos: cosas y acciones,
nombrándolas como <i>objetos</i> y <i>llamadas</i><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>. En este lenguaje todo dato
es un objeto, una clase es un objeto, y todo lo que no es un objeto,
es una llamada. Por ejemplo, los operadores aritméticos son llamadas
definidas en la clase numérica correspondiente, igual que las
funciones trigonométricas. Llegando al extremo, de que no hay <i>palabras
clave</i> como <code>if</code>, operadores o bucles como <code>for</code>. Pero en la clase <i>Boolean</i>
encontrarás llamadas como <code>IfTrue:</code>, <code>IfFalse</code>, <code>or:</code> o <code>and:</code>, por poner
algunos ejemplos. La estructura no cambia y se puede resumir, en
general como:
</p>

<div class="org-src-container">
<pre class="src src-smalltalk">objeto llamada [par&#225;metros]
</pre>
</div>

<p>
El problema de este enfoque es que necesitarías muchas horas de
trabajo para levantar cualquier tipo de entorno que resuelva algún
problema sólo con esas premisas y partiendo de cero. Para ello, otra
característica de <i>Smalltalk</i> es la cantidad de código que ya nos
proporciona hecho, funcionando y probado y, por tanto, podemos
encontrarnos dos partes bien diferenciadas de <i>Smalltalk</i>: la <i>máquina
virtual</i> (vm) y la <i>imagen</i><sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>. La <i>vm</i> suele coincidir con un
ejecutable, que dependerá de cada sistema operativo, pero cuya función
es hacer que los objetos contenidos en el código y las librerías
dentro de la <i>imagen</i> cobren vida y se envíen mensajes unos a otros para
funcionar.
</p>

<p>
Este modelo es su principal fuerza y su principal desventaja. Por un
lado, tenemos que una imagen es una <i>base de datos</i> del estado de los
objetos que contine. Cuando guardamos una <i>imagen</i>, guardamos en un
archivo de disco estático el estado de todos los objetos que contiene
nuestro entorno de trabajo. Por el otro, las imágenes tienen bastante
peso y son un inconveniente en el proceso de distribución de nuestra
aplicación. Es decir, nos da resuelto el problema de la <i>serialización</i>
del contenido, pero a cambio de dificultarnos la distribución.
</p>

<p>
Cuando está en funcionamiento se convierte en un sistema <i>REPL</i><sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup>
con esteroides. Mientras estás programando puedes <i>evaluar</i> cualquier
código, no hay nada oculto en librerías, todo está a la vista. Puedes
crear clases, dotarlas de nuevos mensajes, modificar el código que ya
existe evaluando su adecuación al proyecto sin detener en ningún
momento el proceso. Si se produce algún error, aparecerá un mensaje
junto con una ventana de depuración, donde podrás modificar el código
o escribir nuevo sobre la marcha. Puedes inspeccionar cualquier objeto
del sistema e incluso modificarlo mientras se ejecuta.  Es el sistema
más interactivo y flexible que he utilizado jamás y este fue el
principal motivo que me enganchó durante aquellos años.
</p>
</div>
</div>
<div id="outline-container-orgc84ab75" class="outline-2">
<h2 id="orgc84ab75">Squeak</h2>
<div class="outline-text-2" id="text-orgc84ab75">
<p>
Éste fue mi primer entorno <i>Smalltalk</i>, aunque no llegué a él buscándolo
como herramienta de programación, sino como herramienta educativa. En
aquel entonces me dedicaba a dar clases y <i>Squeak</i> fue un juguete muy
útil. Por él me metí en el mundo de <i>Smalltalk</i>, aprendí el lenguaje y
algunas cosas más sobre programación en general.
</p>

<p>
Cuando empecé a trastear con él, lo hice por los <i>eToys</i>. En el entorno
de <i>Squeak</i> puedes hacer cualquier dibujo a mano alzada (un <i>eToy</i>) y
luego programarle comportamientos como que se desplace, que rote, que
cambie de color, etc. Puedes ponerle sensores que detecten otros <i>eToys</i>
y que interactúen entre sí, etc. Si has trabajado alguna vez con
<a href="https://scratch.mit.edu/">Scratch</a><sup><a id="fnr.7" class="footref" href="#fn.7" role="doc-backlink">7</a></sup>, ese sistema basó su idea en esta herramienta.
</p>


<figure id="org70cc56c">
<img src="./imagenes/Captura-etoys.png" alt="Captura-etoys.png">

</figure>

<p>
Los menús, herramientas de programación y demás elementos se articulan
desde un sistema de ventanas <i>Morphic</i>, basado en <i>Self</i>. Por lo demás, es
un <i>Smalltalk</i> completo y como tal todo el sistema se puede visualizar
(y modificar) en el <i>Browser</i>. Su principal impulsor fue Alan Kay, uno
de los creadores de <i>ST-80</i>, y por tanto mantiene herramientas como el
famoso <i>Browser</i> para visualizar el código mediante el árbol de
paquetes, clases, protocolos y llamadas.
</p>


<figure id="orgcd487bd">
<img src="./imagenes/Captura-squeak.png" alt="Captura-squeak.png">

</figure>

<p>
Cuando yo empecé a trastearlo todavía se utilizaban en el código
<i>Smalltalk</i> el símbolo <code>←</code> para hacer las asignaciones y <code>↑</code> para hacer una
devolución desde una llamada<sup><a id="fnr.8" class="footref" href="#fn.8" role="doc-backlink">8</a></sup>. La separación del código entre
clases (en el archivo <code>.changes</code>) venía delimitado por un carácter de
salto de página y de fin de archivo para separar paquetes. Esto hacía
complicado la edición en otros editores que no fueran los propios del
entorno.
</p>

<p>
Al poco tiempo apareció <i>GNU Smalltalk</i> como herramienta de <i>scripting</i> y
por tanto debía utilizar una codificación <i>ASCII</i> sin caracteres
no imprimibles. <i>Squeak</i> también comenzó derivó a utilizar el código más de
texto plano.
</p>

<p>
En resumen: me lo pasé muy bien con <i>Squeak</i>. Mis alumnos aún
más. Recuerdo aún algunos ejercicios, el primero consistía en dibujar
un <i>eToy</i> similar a un coche y otro similar a una carretera y programar
el primero para siguiera el segundo. Recuerdo otro ejercicio donde
programábamos una caja de Skinner para ilustrar los distintos tipos de
<i>aprendizaje animal</i>, con sus refuerzos positivos y negativos mediante
un esquema de <i>palancas, sonidos y luces</i> simuladas con <i>eToys</i>.
</p>
</div>
</div>
<div id="outline-container-org51d8a92" class="outline-2">
<h2 id="org51d8a92">Pharo</h2>
<div class="outline-text-2" id="text-org51d8a92">
<p>
Pharo se inició como un <i>fork</i> de <i>Squeak</i>. El objetivo perseguido, y
conseguido desde mi punto de vista, era proporcionar un entorno más
profesional para programar en <i>Smalltalk</i>. Por tanto, eliminó los <i>eToys</i>
y le dio un aspecto más formal en la interface con <i>Morphics</i>.
</p>


<figure id="org3714885">
<img src="./imagenes/Captura_pharo.png" alt="Captura_pharo.png">

</figure>

<p>
Su mayor aportación, desde mi punto de vista fue el desarrollo de las
herramientas <i>Monticello</i> y <i>Metacello</i><sup><a id="fnr.9" class="footref" href="#fn.9" role="doc-backlink">9</a></sup>, que se adoptaron también
rápidamente en <i>Squeak</i>. Proporcionando un sistema de control de
versiones y facilitando el trabajo en equipo.
</p>

<p>
Por otro lado, al ser <i>Pharo</i> un <i>fork</i> de <i>Squeak</i> su imagen sigue siendo
heredera en su <i>kernel</i> más profundo del estándar <i>ST-80</i> que definió
<i>Smalltalk</i> a finales de los años 70. Este <i>kernel</i> lleva funcionando y
depurándose muchos años, por lo que se puede confiar en la estabilidad
y afinación del sistema.
</p>

<p>
A la vez que se desarrollaba <i>Pharo</i>, aparecieron entornos <i>web</i> y de
servidor como <a href="https://www.aidaweb.si/">Aidaweb</a> o <a href="https://github.com/SeasideSt/Seaside">Seaside</a>. Que permiten desarrollos de
aplicaciones concurrentes y accesibles sin necesidad de instalar
ninguna infraestructura.
</p>

<p>
Aunque <i>Squeak</i> siempre será mi favorito, por haber sido el primer
entorno <i>Smalltalk</i> libre con el que trasteé. Si estás pensando en un
entorno más profesional, <i>Pharo</i> es el más aconsejable. Especialmente
por su herramienta <code>pharo-launcher</code>.
</p>


<figure id="org453545d">
<img src="./imagenes/Captura_pharo-launcher.png" alt="Captura_pharo-launcher.png">

</figure>

<p>
Esta herramienta nos permite descargar distintas imágenes y máquinas
virtuales. De esta manera, podemos gestionar fácilmente los proyectos
aún con versiones de <i>Pharo</i> antiguas.
</p>
</div>
</div>
<div id="outline-container-org5132355" class="outline-2">
<h2 id="org5132355">Smalltalk/X</h2>
<div class="outline-text-2" id="text-org5132355">
<p>
<a href="https://www.exept.de/en/products/smalltalk-x-en.html">Smalltalk/X</a> es un entorno <i>Smalltalk</i> completo desarrollado por la
empresa alemana <i>eXept software AG</i> y que se distribuye gratuitamente,
sólo hay que registrarse como usuario. En su día lo estuve, pero el
correo electrónico con que lo hice ya no lo tengo y por tanto he
perdido la posibilidad de volver a descargarlo sin volver a
registrarme. Podría hacerlo de nuevo, sí, pero a estas alturas no creo
que lo utilizara mucho y puede la pereza. Además, cuando me registré
eran años en los que la paranoia no estaba tan asentada como ahora 😜.
</p>

<p>
Pero también he encontrado un <i>fork</i> que se puede descargar libremente
desde <a href="https://jan.vrany.io/stx/">https://jan.vrany.io/stx/</a>. Así que me puse a probarlo y he
comprobado que faltan algunas partes (supongo que las propietarias) y
al intentar acceder a ellas lanza un inevitable error.
</p>


<figure id="org6464868">
<img src="./imagenes/Captura_smalltalk-x.png" alt="Captura_smalltalk-x.png">

</figure>

<p>
Lo primero que salta a la vista de esta herramienta es que las
ventanas de las herramientas son independientes. En los dos entornos
anteriores no era así, porque <i>Squeak</i> nació con pretensiones de sistema
operativo para el proyecto <a href="https://es.wikipedia.org/wiki/Dynabook">Dynabook</a> de Alan Kay. Integraba
herramientas de gestión de archivos, sonido, gráficos, presentación,
etc. Es decir, todo en una ventana con ánimo hacer de escritorio.
</p>

<p>
Otro de los puntos interesantes de <i>Smalltalk/X</i>, al menos en su día,
era la facilidad para adecuar la <i>interface</i> imitando las ventanas del
Sistema Operativo anfitrión y el que detecte el idioma configurado en
el mismo para mostrar menús y <i>widgets</i>.
</p>

<p>
Pero la ventaja principal, por lo menos desde mi punto de vista,
cuando lo llegué a utilizar de manera profesional, es que puede
generar ejecutables independientes y evita el modelo de <i>vm+imagen</i> de
los otros sistemas <i>Smalltalk</i>. Además podías escribir código <i>C</i>
directamente en las clases y la integración con <i>C</i> era fácil y
fluida. He visto que el <i>fork</i> que enlazo también tiene soporte para
<i>Java</i>.
</p>

<p>
Llegué a <i>Smalltalk/X</i> un poco de rebote. Me apunté, joven yo, a una de
esas, ahora llamadas, <i>startups</i> que prometen mucho y pagan poco. La
idea inicial era desarrollar una aplicación de escritorio. El <i>jefe</i>
prefería éste sistema a <i>Java</i>. La historia es larga y con
ramificaciones legales que no vienen al caso. El asunto es que,
conseguimos poner en marcha una beta del programa y comenzar con las
pruebas en producción con algunas pequeñas empresas cliente. Durante
las primeras pruebas se llegó a la conclusión de que se necesitaba un
acceso concurrente y aprovechando que teníamos funcionando de manera
suficientemente estable el modelo de negocio en <i>Smalltalk/X</i>, lo
pasamos fácilmente a <i>Pharo</i> sobre un servidor <i>web Aida</i>. En un par de
meses conseguimos hacer el cambio y conseguir otra decena de empresas
cliente... todo parecía ir correctamente hasta que el <i>jefe</i> recibió una
oferta y vendió la empresa. Los que la compraron ni habían oído hablar
de <i>Smalltalk</i> ni les importaba, nos despidieron a todos de un día para
otro, y se pusieron con una evolución que creían que podían hacer en
tres días con PHP. Y así terminó mi única incursión profesional
programando en <i>Smalltalk</i>. A la semana de ser despedidos nos llamaron
para que regresáramos a mantener lo que ya teníamos funcionando
mientras hacían su aplicación. Yo no regresé, en ese tiempo era un
segundo trabajo y no lo necesitaba para pagar la hipoteca. Luego me
enteré de que no volvimos nadie del equipo <i>ST</i>, hubo bastantes
reclamaciones y tuvieron que pagar varias indemnizaciones y la empresa
quebró.
</p>
</div>
</div>
<div id="outline-container-org0bdce24" class="outline-2">
<h2 id="org0bdce24">Conclusiones</h2>
<div class="outline-text-2" id="text-org0bdce24">
<p>
Las cosas han evolucionado bastante desde que abandoné <i>Smalltalk</i>. Por
ejemplo, en el aspecto del trabajo en equipo. Cuando lo dejé existía
<i>Monticelo</i> y nada más. Ahora veo que estas tres herramientas cuentan
con soporte para <i>Git</i>.
</p>

<p>
Los sistemas se han mostrado bastante ligeros. No puedo asegurar si es
por una mejora en la ejecución de <i>Smalltalk</i> o que ahora mi máquina es
más capaz, pero la velocidad percibida es bastante más fluida de lo
que la recordaba. Pero no debe ser sólo eso: en su día <i>Smalltalk/X</i> era
más ágil que <i>Squeak</i> o <i>Pharo</i>, pero esta vez, éstos dos se han mostrado
bastante más rápidos, especialmente <i>Squeak</i>.
</p>

<p>
En estos momentos había pensado darle otro tiento a <i>Pharo</i>, aprender
cómo va el tema de gestionar respositorios <i>Git</i> y hacer algún ejercicio
sencillo. Ahora mismo supongo que me costará más retomarlo, mis
esquemas mentales se han ido orientando más la programación funcional
que a la POO, pero supongo que todo es ponerse. Aunque a estas alturas
tampoco garantizo que llegaré a nada concreto, lo mismo me empieza a
aburrir a los dos días como todos los proyectos que empiezo
últimamente.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Todo en <i>Smalltalk</i> es un <i>objeto</i>, hasta las <i>clases</i>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>POO</i> → Programación Orientada a Objetos. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
La <i>Psicología Cognitiva</i> considera que una de las maneras
naturales del pensamiento humano se refleja en el uso de <i>categorías</i> o
<i>clases</i> y por tanto la <i>POO</i> es un estilo de programación cercano a cómo
pensamos.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
También encontrarás explicaciones donde las llamadas se
denominan <i>métodos</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Una <i>imagen</i> en <i>Smalltalk</i> es un reflejo <i>congelado</i> de un sistema
de objetos que se encuentran en ejecución.
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Un sistema <i>REPL</i> (Read-Eval-Print-Loop) permite realizar
evaluaciones de código sobre la marcha sin necesidad de compilación,
lo que acelera el desarrollo de código.
</p></div></div>

<div class="footdef"><sup><a id="fn.7" class="footnum" href="#fnr.7" role="doc-backlink">7</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Scratch</i> se basó en los <i>eToys</i> de <i>Squeak</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.8" class="footnum" href="#fnr.8" role="doc-backlink">8</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Al poco tiempo (y hasta el momento) se pasó a utilizar la
combinación <code>:=</code> y <code>^</code>. Que no dejan de ser una representación textual de
dichos símbolos.
</p></div></div>

<div class="footdef"><sup><a id="fn.9" class="footnum" href="#fnr.9" role="doc-backlink">9</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Monticello</i> es un sistema de control de versiones de código para
<i>Smalltalk</i>, funciona tanto en <i>Squeak</i> como <i>Pharo</i>. <i>Metacello</i> es un
sistema de paquetes que nos permite gestionar los repositorios
<i>Monticello</i>, importar código, compartirlo, etc.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/smalltalk/index.html">SmallTalk</a> <a href="/tags/squeak/index.html">Squeak</a> <a href="/tags/pharo/index.html">Pharo</a> <a href="/tags/smalltalk/x/index.html">Smalltalk/X</a> ]]></description>
  <category><![CDATA[SmallTalk]]></category>
  <category><![CDATA[Squeak]]></category>
  <category><![CDATA[Pharo]]></category>
  <category><![CDATA[Smalltalk/X]]></category>
  <link>https://notxor.nueva-actitud.org/2025/09/20/cacharreo-nostalgico.html</link>
  <pubDate>Sat, 20 Sep 2025 08:26:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[La red social de org-mode]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2025-08-31</div>
<p>
Hace mucho tiempo que no escribo una entrada en este <i>blog</i>. Supongo que
los pocos seguidores que queden por aquí despistados, se sorprenderán.
No, no he abandonado, pero algunas circunstancias de la vida me
dificultan la continuidad de la escritura. ¡Pero vamos al tema!
</p>

<p>
Hoy me decidí a probar <code>org-social</code>. Un paquete —aún no oficial— que
permite gestionar una red social a través de un sencillo archivo de
texto plano formateado mediante <code>org-mode</code>. Podéis encontrar más
información en <a href="https://github.com/tanrax/org-social">https://github.com/tanrax/org-social</a>. Y el código lo
podéis descargar de <a href="https://github.com/tanrax/org-social.el">https://github.com/tanrax/org-social.el</a>, Todo lo
que os cuento está sacado de ahí.
</p>
<div id="outline-container-org07d932d" class="outline-2">
<h2 id="org07d932d">Instalación en <i>Emacs</i></h2>
<div class="outline-text-2" id="text-org07d932d">
<p>
Si ya estás utilizando algún paquete <i>experimental</i> cargándolo desde
fuera de la lista de MELPA, simplemente tendrás que añadir la URL al
repositorio de código en el código de <code>use-package</code>. Si no lo estás
haciendo, antes debes descargar el paquete <code>request</code> para poder
hacerlo. El código, como se muestra en las instrucciones de
instalación quedaría así:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> request)
(<span style="color: #ff79c6; font-weight: bold;">use-package</span> org-social
  <span style="color: #8be9fd; font-style: italic;">:vc</span> ( <span style="color: #8be9fd; font-style: italic;">:url</span> <span style="color: #f1fa8c;">"https://github.com/tanrax/org-social.el"</span>
        <span style="color: #8be9fd; font-style: italic;">:rev</span> <span style="color: #8be9fd; font-style: italic;">:newest</span>))
</pre>
</div>

<p>
Si recibes algún error al abrir <i>Emacs</i> después de haber escrito esas
líneas, es posible que esté intentando cargar el paquete <code>org-social</code>
antes de que esté instalado <code>request</code>. Cierra <i>Emacs</i> y vuelve a abrirlo.
</p>

<p>
El código se actualizará <i>automágicamente</i>, pero comprobará en cada
arranque si está actualizado, lo que ralentizará un poco el inicio. Lo
podéis evitar prescindiendo de automatismos y descargando el código
por vuestra cuenta. Para configurarlo así tenéis que poner un enlace
al directorio donde lo hayáis descargado y llamarlo de forma directa
con la forma <code>require</code> habitual. Para ello utilizad el código:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-to-list 'load-path <span style="color: #f1fa8c;">"/path/al/paquete/org-social.el"</span>)
(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">org-social</span>)
</pre>
</div>

<p>
Con esto, ya has terminado con lo mínimo imprescindible para tener el
paquete instalado y funcionando. Sin embargo, aún no es de mucha
utilidad y seguramente no podrás ver nada.
</p>
</div>
</div>
<div id="outline-container-orgecb65a2" class="outline-2">
<h2 id="orgecb65a2">El uso</h2>
<div class="outline-text-2" id="text-orgecb65a2">
<p>
Configurarlo en <i>Emacs</i>, como habéis visto, es muy sencillo y lo haces
en dos patadas, pero necesitas algunas condiciones previas:
</p>

<ol class="org-ol">
<li>Crear un archivo <code>org</code> con la información.</li>
<li>Subirlo a un servidor HTTP.</li>
<li>Interactuar con alguien.</li>
</ol>

<p>
Ahora toca configurarlo para su funcionamiento.
</p>
</div>
<div id="outline-container-org4a46f3b" class="outline-3">
<h3 id="org4a46f3b">Crear nuestro archivo</h3>
<div class="outline-text-3" id="text-org4a46f3b">
<p>
Toda la información referente a nuestra <i>red social</i> se encuentra
almacenada en un fichero <code>org-mode</code>. El mío lo podéis encontrar en la
dirección <a href="https://notxor.nueva-actitud.org/social.org">https://notxor.nueva-actitud.org/social.org</a>. De momento, y
puesto que sólo cuento con las pruebas que he hecho para escribir este
artículo el contenido es muy sencillo, lo transcribo aquí:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">#+TITLE: Notxor tiene un blog
#+NICK: Notxor
#+DESCRIPTION: Mi blog personal sobre muchos temas, especialmente sobre /Emacs/.
#+AVATAR: https://notxor.nueva-actitud.org/medios/img/abatar.png
#+LINK: https://notxor.nueva-actitud.org
#+CONTACT: mailto:notxor@nueva-actitud.org
#+CONTACT: xmpp:notxor@suchat.org
#+CONTACT: https://tuiter.rocks/deck/@Notxor
</pre>
</div>

<p>
Esa es la cabecera que he utilizado para empezar. Contiene los datos
del <i>blog</i>, pues la red la utilizaría principalmente como <i>feed</i> para el
mismo.
</p>

<p>
No creo que haga falta explicar las etiquetas de <code>#+TITLE</code>, <code>#+NICK</code>,
<code>#+DESCRIPTION</code>, etc. son todas información nuestra. Más adelante
completaremos esa cabecera.
</p>

<p>
Además hay que tener en cuenta que hay etiquetas que se pueden repetir
y contar con varias entradas, como el caso de <code>#+CONTACT</code>, de <code>#+LINK</code> o
de <code>#+FOLLOW</code>, pero otras que deben ser únicas, como <code>#+TITLE</code>, <code>#+NICK</code> o
<code>#+DESCRIPTION</code>. Si dudas de cuáles sí y cuáles no, es mejor consultarlo
directamente en el sitio de <a href="https://github.com/tanrax/org-social">org-social</a>, por si cambian las cosas.
</p>

<p>
Una vez creado el archivo, lo coloqué en el <i>espejo local</i> que tengo del
<i>blog</i> para subirlo al sitio e informarle al paquete dónde lo he
guardado para que acceda a él directamente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Establece el path del archivo compartido
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-social-file <span style="color: #f1fa8c;">"~/public_html/social.org"</span>)
</pre>
</div>

<p>
También he preparado en la configuración de <i>Emacs</i> algunos atajos
directos a las acciones del paquete más básicas:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Algunas teclas de acceso directo
</span>(global-set-key (kbd <span style="color: #f1fa8c;">"C-c x m"</span>) 'org-social-mention-user)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c x n"</span>) 'org-social-new-post)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c x o"</span>) 'org-social-open-file)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c x t"</span>) 'org-social-timeline)
</pre>
</div>

<p>
En el sitio del <i>chismático</i> se propone la combinación <code>"C-c s"</code>, sin embargo,
esa combinación la tengo ocupada para otras tareas en mi
configuración, por lo que decidí cambiarla.
</p>

<p>
Con esta configuración, al pulsar <code>C-c x t</code> me aparecerá un <i>buffer</i>
marcado como <code>*Org Social Timeline*</code>, en el que de momento no hay nada.
Para eso, primero, necesitas seguir a alguien. Aquí es donde empieza
la interacción, por lo que debes añadir a tu cabecera líneas con la
etiqueta <code>#+FOLLOW</code>. De momento no conozco a mucha gente, pero en el
sitio del paquete encontré un archivo <code>txt</code> con los enlaces de la gente
del paquete y decidí seguirlos a todos para probar. Además, a Andros
Fenollosa, el principal desarrollador de esta red social ya lo
conozco, puedo interactuar con él por <i>Mastodon</i> y hemos coincidido en
algún encuentro de <a href="https://hispa-emacs.org/">Hispa-Emacs</a>. Resumiendo, he añadido al final de la
cabecera:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">#+FOLLOW: https://andros.dev/static/social.org
#+FOLLOW: https://rossabaker.com/social.org
#+FOLLOW: https://omidmash.de/social.org
#+FOLLOW: https://johnhame.link/social.org
#+FOLLOW: https://eoin.site/social.org
#+FOLLOW: https://adsan.dev/social.org
#+FOLLOW: https://emillo.net/social.org
#+FOLLOW: https://cmdln.org/social.org
</pre>
</div>

<p>
Una vez escritas estas pocas líneas en el fichero <code>social.org</code>,
tendremos un lista de post más larga. Como se puede apreciar:
</p>


<figure id="orgd88c4e5">
<img src="./imagenes/Captura_timeline.png" alt="Captura_timeline.png">

</figure>

<p>
En ese <i>buffer</i>, tenemos varias teclas para facilitarnos la interacción:
</p>


<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Tecla</th>
<th scope="col" class="org-left">Acción</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">g</td>
<td class="org-left">org-social-timeline-refresh</td>
</tr>

<tr>
<td class="org-left">n</td>
<td class="org-left">org-social-next-post</td>
</tr>

<tr>
<td class="org-left">p</td>
<td class="org-left">org-social-previous-post</td>
</tr>

<tr>
<td class="org-left">q</td>
<td class="org-left">quit-window</td>
</tr>

<tr>
<td class="org-left">r</td>
<td class="org-left">org-social-reply-to-post</td>
</tr>
</tbody>
</table>

<p>
Las teclas <code>n</code> y <code>p</code> nos permiten navegar el <i>buffer</i> hacia adelante y hacia
atrás, saltando de entrada a entrada. Para actualizar el <i>buffer</i>
debemos utilizar la tecla <code>g</code>. Para contestar a un <i>post</i> podemos pulsar
la tecla <code>r</code> estando situados en la entrada a la que queremos
contestar. Y para abandonar la red, sólo tenemos que pulsar <code>q</code>. Todo
muy básico y sencillo.
</p>
</div>
</div>
<div id="outline-container-orga3237ff" class="outline-3">
<h3 id="orga3237ff">Crear <i>posts</i></h3>
<div class="outline-text-3" id="text-orga3237ff">
<p>
La función básica de una red social es la interacción con otros
usuarios de la misma. Para ello necesitamos darnos a conocer a través
de lo que escribimos, es decir, debemos escribir <i>posts</i> y esperar ser
leídos, seguidos y contestados.
</p>

<p>
Para crear un nuevo <i>post</i> tecleé el comando <code>C-c x n</code>, pero recuerda que
debes utilizar la combinación de teclas que hayas configurado o llamar
directamente a <code>M-x org-social-new-post</code>. Esto abrirá un <i>buffer</i> con tu
archivo <code>social.org</code> local cargado e insertará una entrada parecida a:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">**
:PROPERTIES:
:ID: 2025-08-31T09:25:18+0200
:LANG:
:TAGS:
:CLIENT: org-social.el
:MOOD:
:END:
</pre>
</div>

<p>
Para mi primera entrada en esta red social, he escrito lo siguiente:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">**
:PROPERTIES:
:ID: 2025-08-31T09:25:18+0200
:TITLE: Post inaugural
:LANG: es
:TAGS: org-social emacs
:CLIENT: org-social.el
:MOOD: 🙂
:END:

Primer post de ~org-social~, para las pruebas de funcionamiento.
</pre>
</div>

<p>
El <code>ID</code> y el <i>cliente</i> los proporciona la misma herramienta y no tenemos
que preocuparnos por ellos, pero también hay una serie de etiquetas
que podemos añadir, además de las que por defecto que te proporciona
el comando <code>org-social-new-post</code>. Por ejemplo, añadí un título al <i>post</i>
(porque se puede), utilizando la propiedad <code>:TITLE:</code>.
</p>

<p>
También podemos, si la entrada que hemos escrito es una encuesta,
establecer la finalización de la misma mediante la etiqueta
<code>POLL_END</code> o si estamos contestando a una encuesta formulada por otra
persona, utilizaremos la etiqueta <code>POLL_OPTION</code>. Y, por supuesto,
también podemos contestar a otro post utilizando la etiqueta
<code>REPLY_TO</code><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>
</div>
</div>
</div>
<div id="outline-container-org8c219b3" class="outline-2">
<h2 id="org8c219b3">Encontrar gente con la que interactuar</h2>
<div class="outline-text-2" id="text-org8c219b3">
<p>
Es complicado encontrar gente en esta red. Primero porque acaba de
nacer prácticamente y segundo, porque es una red descentralizada en la
que cada uno tiene su archivo y no hay más infraestructura que
facilite la interacción. Para minimizar un poco este hecho, en la web
de <code>org-social</code> hay un archivo <code>txt</code> con un listado con las URL de algunos
usuarios. He tomado esa lista de usuarios y he añadido a la cabecera de
mi archivo <code>social.org</code> los siguientes <i>follows</i>:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">#+FOLLOW: https://andros.dev/static/social.org
#+FOLLOW: https://rossabaker.com/social.org
#+FOLLOW: https://omidmash.de/social.org
#+FOLLOW: https://johnhame.link/social.org
#+FOLLOW: https://eoin.site/social.org
#+FOLLOW: https://adsan.dev/social.org
#+FOLLOW: https://emillo.net/social.org
#+FOLLOW: https://cmdln.org/social.org
</pre>
</div>

<p>
De momento los sigo todos mientras voy descubriendo otros usuarios y
amplío el espectro y temáticas. Si quieres seguirme a mí añade en tu
cabecera el código:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">#+FOLLOW: https://notxor.nueva-actitud.org/social.org
</pre>
</div>

<p>
No voy a darme de alta en ese archivo, al menos todavía. Por varios
motivos:
</p>

<ol class="org-ol">
<li>Para añadirte tienes que hacer un <i>pull request</i> a dicho fichero en
<code>Github</code>. Creo que hace como 10 u 11 años que no uso dicha plataforma
y prefiero seguir sin usarla.<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup></li>
<li>Todos los <i>posts</i>, de la gente que está en la lista, están en inglés,
lo mismo les mato alguna neurona <i>posteando</i> en español o les frío
medio cerebro cuando lo haga en <i>Esperanto</i>.</li>
<li>Aún no estoy seguro de cuánto usaré esta red social o si la
terminaré abandonando, estoy de pruebas.</li>
</ol>
</div>
</div>
<div id="outline-container-org653a5ad" class="outline-2">
<h2 id="org653a5ad">Mi punto de vista y conclusiones</h2>
<div class="outline-text-2" id="text-org653a5ad">
<p>
Los seres humanos somos seres sociales que necesitamos interactuar en
comunidades para desarrollarnos plenamente. La expresión de nuestra
individualidad no es individual, sino que se manifiesta dentro de la
comunidad. En esta red social veo ambas vertientes complementándose:
puedes interactuar con la comunidad, pero mantienes tu individualista
archivo <code>social.org</code> bajo control.
</p>

<p>
Tus datos son tuyos y los tienes bajo control. Para establecer
contacto, o más bien, para permitir que establezcan contacto contigo,
debes situar dicho archivo <code>org</code> en un lugar accesible desde la <i>web</i>.
Una solución sencilla y práctica. Cualquier servidor HTTP te servirá.
En mi caso, puesto que tengo el <i>blog</i>, lo más rápido es ponerlo en el
directorio raíz del mismo.
</p>

<p>
Las opciones de momento son muy básicas, te permiten crear entradas,
responder las de otra gente y poco más. Sin embargo, al hacerlo sobre
un archivo <code>org-mode</code> te proporciona toda la potencia que tiene éste
para interactuar con la información. Por esto, si <code>org-mode</code> no tiene
límites, <code>org-social</code> tampoco los tendrá.
</p>

<p>
Como conclusión, y por lo que veo en las entradas de mi <i>timeline</i>,
estamos en una red social un poco <i>de nicho</i>, especialmente de
seguidores de <i>Emacs</i> y de <i>Org</i>. Tengo mucha curiosidad por ver cómo
evoluciona.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Es aconsejable, que en lugar de escribir la etiqueta
directamente, se utilice el comando <code>org-social-reply-to-post</code>, para que
nos proporcione automáticamente la URL de la entrada que queremos
contestar y evitar errores.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Vale, tampoco me acuerdo cómo hacer un <i>pull request</i> allí, así
que no lo haré —al menos de momento—.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/org/index.html">org</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[org]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2025/08/31/la-red-social-de-org-mode.html</link>
  <pubDate>Sun, 31 Aug 2025 10:01:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Un revuelto de cosas mías]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2025-04-27</div>
<p>
Llevo un tiempo sin escribir y la verdad que no es por falta de ganas,
sino porque me enfrasco en mis cosas y no termino de encontrar temas
que piense que son interesantes para el resto del <i>mundo mundial</i>. ¿En
qué ando enfrascado? y ¿qué me he decidido a contar hoy aquí?. Pues
veamos:
</p>

<ul class="org-ul">
<li>Continuar con el aprendizaje de <b>Lua</b>. En concreto, desarrollar un
sistema en el que dicho lenguaje esté embebido en <span id="nota">una aplicación<span class="nota"> En concreto en una aplicación escrita en <b>C</b>.</span></span>.</li>
<li>Probando <code>eglot</code> en más profundidad para uso personal.</li>
<li>De manera tangencial probando el desempeño de varios lenguajes,
subjetivamente.</li>
</ul>
<div id="outline-container-orgacde10d" class="outline-2">
<h2 id="orgacde10d">Lua y C</h2>
<div class="outline-text-2" id="text-orgacde10d">
<p>
Para aprender el lenguaje y sus interacciones, estando embebido en una
aplicación escrita en otro lenguaje, necesitaba una aplicación que
hospedara un intérprete de <b>Lua</b> para hacer funcionar algo. Debía ser
una aplicación suficientemente compleja como para poner a prueba el
asunto, pero que no me distrajera del objetivo último, que es aprender
<b>Lua</b> y sus idiosincrasias.
</p>

<p>
Elegí un proyecto con el que estoy ya familiarizado, un <i>raytracer</i>. El
objetivo es hacer una <span id="nota">aplicación<span class="nota">En C.</span></span> que genere una
imagen que venga descrita en un <i>script</i> escrito en <b>Lua</b>.
</p>

<p>
El primer paso consistió en programar en <b>Lua</b> el mismo <i>raytracer</i> que se
desarrollará en <b>C</b> hasta alcanzar un punto en que hubiera más de un
objeto (en concreto dos esferas) y una abstracción de cámara para
hacer la imagen. Además, también con el objeto de aprender, implementé
un sistema de <i>corrutinas</i> que remedaban un proceso paralelo. En
realidad, <b>Lua</b> no implementa ese paralelismo, por mucho que llame
<i>thread</i> al proceso que realiza una corrutina, no es un hilo
independiente. Me sirvió para aprender cómo gestionarlas y si lo
necesitara más adelante, bastaría con lanzar la corrutina en un nuevo
intérprete.
</p>

<p>
Llegados a este punto, me puse a desarrollar lo mismo en <b>C</b>. La primera
impresión fue el cambio en velocidad. No quiere decir que <b>Lua</b> sea
lento, sino que <b>C</b> es rapidísimo. Por poner un sencillo ejemplo:
</p>

<p>
El código en <b>Lua</b>:
</p>

<div class="org-src-container">
<pre class="src src-lua"><span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #8be9fd; font-style: italic;">math</span> = <span style="color: #8be9fd; font-style: italic;">require</span>(<span style="color: #f1fa8c;">"math"</span>)
<span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #8be9fd; font-style: italic;">string</span> = <span style="color: #8be9fd; font-style: italic;">require</span>(<span style="color: #f1fa8c;">"string"</span>)

<span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #ff79c6; font-weight: bold;">function</span> <span style="color: #50fa7b; font-weight: bold;">main</span>()
   <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">Imagen
</span>   <span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">ancho_imagen</span> = 256
   <span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">alto_imagen</span> = 256

   <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">Render
</span>
   <span style="color: #8be9fd; font-style: italic;">print</span>(<span style="color: #f1fa8c;">"P3\n"</span> .. ancho_imagen .. <span style="color: #f1fa8c;">" "</span> .. alto_imagen .. <span style="color: #f1fa8c;">"\n255\n"</span>)

    <span style="color: #ff79c6; font-weight: bold;">for</span> <span style="color: #f8f8f2; font-weight: bold;">j</span> = 1, ancho_imagen <span style="color: #ff79c6; font-weight: bold;">do</span>
        <span style="color: #8be9fd; font-style: italic;">io</span>.<span style="color: #8be9fd; font-style: italic;">stderr</span>:write(<span style="color: #f1fa8c;">"."</span>) <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">muestra un punto por cada l&#237;nea dibujada
</span>        <span style="color: #ff79c6; font-weight: bold;">for</span> <span style="color: #f8f8f2; font-weight: bold;">i</span> = 1, alto_imagen <span style="color: #ff79c6; font-weight: bold;">do</span>
            <span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">r</span> = i / ancho_imagen
            <span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">g</span> = j / alto_imagen
            <span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">b</span> = 0.0

            <span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">er</span> = <span style="color: #8be9fd; font-style: italic;">math</span>.<span style="color: #8be9fd; font-style: italic;">modf</span>(255.99999 * r)
            <span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">eg</span> = <span style="color: #8be9fd; font-style: italic;">math</span>.<span style="color: #8be9fd; font-style: italic;">modf</span>(255.99999 * g)
            <span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">eb</span> = <span style="color: #8be9fd; font-style: italic;">math</span>.<span style="color: #8be9fd; font-style: italic;">modf</span>(255.99999 * b)

            <span style="color: #8be9fd; font-style: italic;">print</span>(<span style="color: #8be9fd; font-style: italic;">string</span>.<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"%d %d %d"</span>, er, eg, eb))
        <span style="color: #ff79c6; font-weight: bold;">end</span>
    <span style="color: #ff79c6; font-weight: bold;">end</span>
    <span style="color: #8be9fd; font-style: italic;">io</span>.<span style="color: #8be9fd; font-style: italic;">stderr</span>:write(<span style="color: #f1fa8c;">" Hecho.\n"</span>)
<span style="color: #ff79c6; font-weight: bold;">end</span>

main()
</pre>
</div>

<p>
Ejecución y desempeño:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #ff79c6; font-weight: bold;">time</span> lua .ejemplo.lua &gt; ejemplo_lua.ppm
</pre>
</div>

<pre class="example" id="org9993b1e">
________________________________________________________
Executed in  331.23 millis    fish           external
   usr time   69.97 millis    0.00 millis   69.97 millis
   sys time  260.53 millis    1.64 millis  258.89 millis
</pre>

<p>
Si comparamos este código con el equivalente de <b>C</b>:
</p>

<div class="org-src-container">
<pre class="src src-c"><span style="color: #ffb86c;">#include</span> <span style="color: #f1fa8c;">&lt;stdio.h&gt;</span>

<span style="color: #8be9fd; font-style: italic;">int</span> <span style="color: #50fa7b; font-weight: bold;">main</span>() {
  <span style="color: #8be9fd; font-style: italic;">int</span> <span style="color: #f8f8f2; font-weight: bold;">ancho_imagen</span> = 256;
  <span style="color: #8be9fd; font-style: italic;">int</span> <span style="color: #f8f8f2; font-weight: bold;">alto_imagen</span> = 256;

  printf(<span style="color: #f1fa8c;">"P3 %d %d 255\n"</span>, ancho_imagen, alto_imagen);
  <span style="color: #ff79c6; font-weight: bold;">for</span> (<span style="color: #8be9fd; font-style: italic;">int</span> <span style="color: #f8f8f2; font-weight: bold;">j</span> = 0; j &lt;= alto_imagen - 1; j++) {
    fprintf(stderr, <span style="color: #f1fa8c;">"."</span>);
    <span style="color: #ff79c6; font-weight: bold;">for</span> (<span style="color: #8be9fd; font-style: italic;">int</span> <span style="color: #f8f8f2; font-weight: bold;">i</span> = 0; i &lt;= ancho_imagen - 1; i++) {
      <span style="color: #8be9fd; font-style: italic;">double</span> <span style="color: #f8f8f2; font-weight: bold;">r</span> = (<span style="color: #8be9fd; font-style: italic;">double</span>) i / ((<span style="color: #8be9fd; font-style: italic;">double</span>) ancho_imagen - 1);
      <span style="color: #8be9fd; font-style: italic;">double</span> <span style="color: #f8f8f2; font-weight: bold;">g</span> = (<span style="color: #8be9fd; font-style: italic;">double</span>) j / ((<span style="color: #8be9fd; font-style: italic;">double</span>) alto_imagen - 1);
      <span style="color: #8be9fd; font-style: italic;">double</span> <span style="color: #f8f8f2; font-weight: bold;">b</span> = 0.0;

      <span style="color: #8be9fd; font-style: italic;">int</span> <span style="color: #f8f8f2; font-weight: bold;">ir</span> = (<span style="color: #8be9fd; font-style: italic;">int</span>) 255.9999 * r;
      <span style="color: #8be9fd; font-style: italic;">int</span> <span style="color: #f8f8f2; font-weight: bold;">ig</span> = (<span style="color: #8be9fd; font-style: italic;">int</span>) 255.9999 * g;
      <span style="color: #8be9fd; font-style: italic;">int</span> <span style="color: #f8f8f2; font-weight: bold;">ib</span> = (<span style="color: #8be9fd; font-style: italic;">int</span>) 255.9999 * b;
      printf(<span style="color: #f1fa8c;">"%d %d %d\n"</span>, ir, ig, ib);
    }
  }
  fprintf(stderr, <span style="color: #f1fa8c;">"-&gt; Hecho.\n"</span>);
}
</pre>
</div>

<p>
Compilado, ejecución y desempeño:
</p>

<div class="org-src-container">
<pre class="src src-shell">gcc -o ejemplo_c ejemplo.c
<span style="color: #ff79c6; font-weight: bold;">time</span> ./ejemplo_c &gt; ejemplo_c.ppm
</pre>
</div>

<pre class="example" id="org0551b05">
________________________________________________________
Executed in   15.85 millis    fish           external
   usr time   10.19 millis    0.00 millis   10.19 millis
   sys time    4.53 millis    1.48 millis    3.06 millis
</pre>

<div class="info"><h1>Comparaciones odiosas</h1>
<p>
Sí, soy consciente de que no son comparables, uno es un lenguaje
interpretado y otro un lenguaje compilado... para ser más odioso aún,
implementé el mismo ejemplo en <b>Rust</b> con el siguiente resultado:
</p>

<pre class="example" id="org19072eb">
________________________________________________________
Executed in  277.37 millis    fish           external
   usr time   17.41 millis    1.41 millis   15.99 millis
   sys time  260.06 millis    0.16 millis  259.90 millis
</pre>

<p>
O dicho de otro modo:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Lenguaje</th>
<th scope="col" class="org-right"><code>usr</code></th>
<th scope="col" class="org-right"><code>sys</code></th>
<th scope="col" class="org-right">total</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><b>Lua</b></td>
<td class="org-right">69.97</td>
<td class="org-right">260.53</td>
<td class="org-right">331.23</td>
</tr>

<tr>
<td class="org-left"><b>C</b></td>
<td class="org-right">10.19</td>
<td class="org-right">4.53</td>
<td class="org-right">15.85</td>
</tr>

<tr>
<td class="org-left"><b>Rust</b></td>
<td class="org-right">17.41</td>
<td class="org-right">260.06</td>
<td class="org-right">260.06</td>
</tr>
</tbody>
</table>

<p>
Es decir, <b>Rust</b> se acerca más a <b>C</b> en el tiempo dedicado en <code>usr</code> pero
gasta el mismo tiempo que <b>Lua</b> en <code>sys</code>. Será también mucho más rápido
que <b>Lua</b> en un proceso de cálculo más largo y exigente, pero en este
ejemplo corto, apenas consigue ventaja.
</p>

</div>

<p>
No le daré más vueltas de momento a estos temas, que dejaré para más
adelante, porque puestos a mirar el asunto, añadí algún lenguaje
compilado más, como <b>nim</b> y <b>zig</b>.
</p>

<p>
El proyecto de aprendizaje aún está en desarrollo y me estoy
divirtiendo un montón con él. Si consigo una buena integración entre
ambos lenguajes no me extrañaría que lo siguiera desarrollando un
poco, para conseguir mayor complejidad. Me refiero a verdadera
multitarea, más tipos de objetos que simples esferas, otros formatos
de salida (PNG, JPEG...) y, en fin, un <i>raytracer</i> más completo.
</p>
</div>
</div>
<div id="outline-container-orgf0e8343" class="outline-2">
<h2 id="orgf0e8343">Usando <i>Emacs</i> para programar</h2>
<div class="outline-text-2" id="text-orgf0e8343">
<p>
Como he dicho antes estoy en fase de pruebas más profundas de <code>eglot</code>
aprovechando este proyecto. Lo tengo activado tanto en <b>Lua</b> como <b>C</b>.  Si
tienes curiosidad por conocer qué configuración estoy usando, el
código está en su repositorio: <a href="https://codeberg.org/Notxor/init-emacs">https://codeberg.org/Notxor/init-emacs</a>.
</p>

<p>
En el caso del lenguaje <b>C</b> estoy probando las dos herramientas <i>LSP</i> que
tengo disponibles: <code>clangd</code> y <code>ccls</code>. Ambos cuentan con paquetes propios
para <i>OpenSuse Tumbleweed</i> y se instalan sin problemas. El primero viene
integrado en los paquetes de desarrollo de <code>clang</code> y <i>LLVM</i>, y el segundo
viene en un paquete aparte.
</p>

<p>
El desempeño de ambos es correcto, con sus puntos fuertes y débiles.
Por ejemplo, la información que ofrece <code>clangd</code> me está pareciendo más
completa, pero a cambio de tocar un poco más las gónadas con cosas que
aparecen (y desaparecen) según le parece a él durante la edición. De
vez en cuando, con el ánimo de probar ambos, cambio entre ellos y como
resumen puedo decir que me gusta más <code>ccls</code> por su sencillez y por no
molestarme con demasiados desplegables o introduciendo elementos
visuales entre el código. Una costumbre que sí tiene <code>clangd</code>, que
inserta visualmente en las llamadas a una función el nombre de los
parámetros que se encuentran en su definición... es información
relevante, pero me resulta incómodo leer el código así.
</p>
</div>
<div id="outline-container-orgc7aadb8" class="outline-3">
<h3 id="orgc7aadb8">Depurando el código con <code>gdb</code></h3>
<div class="outline-text-3" id="text-orgc7aadb8">
<p>
Durante la programación me he encontrado con algunos errores para los
que he necesitado utilizar un depurador. Recuerdo que años atrás,
antes de descubrir las capacidades de <i>Emacs</i>, utilizaba herramientas
como <code>ddd</code> para depurar. En la actualidad me encuentro más cómodo con el
depurador integrado en <i>Emacs</i>.
</p>


<figure id="orga4b899f">
<img src="./imagenes/Captura_gdb.png" alt="Captura_gdb.png">

</figure>

<p>
Esta ventana aparece cuando lanzamos <code>projectile-run-gdb</code> si tenemos
activado <code>gdb-many-windows</code>. Vemos seis ventanas:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<tbody>
<tr>
<td class="org-left"><code>gud</code></td>
<td class="org-left">VV locales</td>
</tr>

<tr>
<td class="org-left">código</td>
<td class="org-left">Entrada-Salida</td>
</tr>

<tr>
<td class="org-left">pila llamadas</td>
<td class="org-left">Breakpoints</td>
</tr>
</tbody>
</table>

<p>
La ventana superior izquierda nos permite interactuar con <code>gdb</code>. Si no
lo has utilizado frecuentemente los comandos más habituales son:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left"><code>gdb</code></th>
<th scope="col" class="org-left"><code>gud</code></th>
<th scope="col" class="org-left">Acción</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>b</code></td>
<td class="org-left"><code>C-x C-a C-b</code></td>
<td class="org-left">Establece un <i>breakpoint</i>.</td>
</tr>

<tr>
<td class="org-left"><code>d N</code></td>
<td class="org-left"><code>C-x C-a C-d</code></td>
<td class="org-left">Elimina el <i>breakpoint</i> N.</td>
</tr>

<tr>
<td class="org-left"><code>r</code></td>
<td class="org-left"><code>C-x C-a C-v</code></td>
<td class="org-left">Ejecuta el programa hasta encontrar un <i>breakpoint</i> o un error.</td>
</tr>

<tr>
<td class="org-left"><code>c</code></td>
<td class="org-left"><code>C-x C-a C-r</code></td>
<td class="org-left">Continúa la ejecución hasta encontrar el siguiente <i>breakpoint</i> o un error.</td>
</tr>

<tr>
<td class="org-left"><code>f</code></td>
<td class="org-left">&#xa0;</td>
<td class="org-left">Ejecuta el programa hasta finalizar la función en curso.</td>
</tr>

<tr>
<td class="org-left"><code>s</code></td>
<td class="org-left"><code>C-x C-a C-s</code></td>
<td class="org-left">Ejecuta la siguiente línea de código.</td>
</tr>

<tr>
<td class="org-left"><code>s N</code></td>
<td class="org-left">&#xa0;</td>
<td class="org-left">Ejecuta las siguientes <i>N</i> líneas.</td>
</tr>

<tr>
<td class="org-left"><code>n</code></td>
<td class="org-left"><code>C-x C-a C-n</code></td>
<td class="org-left">Como <code>s</code> pero sin entrar en las funciones llamadas.</td>
</tr>

<tr>
<td class="org-left"><code>u N</code></td>
<td class="org-left"><code>C-x C-a C-u</code></td>
<td class="org-left">Ejecuta el código hasta que se encuentra a <i>N</i> líneas de la actual.</td>
</tr>

<tr>
<td class="org-left"><code>p var</code></td>
<td class="org-left"><code>C-x C-a C-p</code></td>
<td class="org-left">Muestra el valor de la variable <code>var</code>.</td>
</tr>

<tr>
<td class="org-left"><code>u</code></td>
<td class="org-left"><code>C-x C-a &lt;</code></td>
<td class="org-left">Sube un nivel en la pila de ejecución.</td>
</tr>

<tr>
<td class="org-left"><code>d</code></td>
<td class="org-left"><code>C-x C-a &gt;</code></td>
<td class="org-left">Desciende un nivel en la pila de ejecución.</td>
</tr>

<tr>
<td class="org-left"><code>q</code></td>
<td class="org-left">&#xa0;</td>
<td class="org-left">Sale del depurador.</td>
</tr>
</tbody>
</table>

<p>
Se puede utilizar tanto el comando de <code>gdb</code> como el de <code>gud</code>.
</p>

<p>
A pesar de estar en las primeras fases del proyecto, me he visto ya en
la necesidad de utilizarlo y es una de esas joyas de las que no se
suele hablar. Según vas ejecutando puedes ir viendo cómo cambia la
pila de llamadas, las variables locales y demás información.
</p>

<p>
Por ejemplo, al principio no me preocupaba la gestión de memoria.
Apenas abría unas cuantas variables y no me producía ningún problema
que se quedaran activos algunos punteros hasta que terminara la
ejecución del programa y el S.O. liberara los recursos reservados por
el programa. Para ser sincero, tampoco me crea muchos problemas de
memoria en su estado actual, sin embargo, el uso de la memoria ha
crecido exponencialmente. Todo el <i>raytracer</i> está basado en vectores
3D, incluso los colores son vectores de tres posiciones. Y cada
posición es un <i>double</i>, por lo que un vector, un punto del espacio o un
color, consumen 24 bytes. Por otro lado, un rayo está formado por un
punto y un vector de dirección, por lo que consume 48 bytes. Por cada
pixel de una imagen hay que lanzar al menos un rayo. Con el
<i>antialising</i>, esto se multiplica, que pueden ser 100 rayos por
pixel... con unos sencillos cálculos te darás cuenta que además de los
24bytes del color del pixel, necesitas 4.8Kb para calcularlo. Aún
siendo una imagen pequeña, gastar 4.824 bytes en cada pixel, es un
gasto considerable. Por ejemplo, una prueba de 400x225 pixeles son
434.160.000 bytes que son 414Mb. La solución es liberar cada rayo,
cada punto, cada vector cuando deja de ser necesario.
</p>
</div>
</div>
</div>
<div id="outline-container-org8c7b02c" class="outline-2">
<h2 id="org8c7b02c">Pruebas con distintos lenguajes</h2>
<div class="outline-text-2" id="text-org8c7b02c">
<p>
Como ya apunté antes, cuando me puse a trabajar con <b>C</b>, me encontré
haciendo pruebas con distintos lenguajes <b>Lua</b>, <b>C</b>, <b>Rust</b>... y añadí
también otro par de los lenguajes compilados: <b>nim</b> y <b>Zig</b>. ¿Para qué?
Pues para probar, simplemente. Soy consciente de que estas pruebas no
están optimizadas, es un bucle pequeño, por lo que no esperaba
encontrar muchas diferencias entre ellos. Para comenzar, colocaré aquí
el código.
</p>

<p>
Rust:
</p>

<div class="org-src-container">
<pre class="src src-rust">fn main() {
    // imagen

    let ancho_imagen: i32 = 256;
    let alto_imagen: i32 = 256;

    println!("P3 {} {} 255", ancho_imagen, alto_imagen);

    for j in 0..alto_imagen {
        eprint!(".");
        for i in 0..ancho_imagen {
            let r: f64 = (i as f64) / ((ancho_imagen as f64) - 1.0);
            let g: f64 = (j as f64) / ((alto_imagen as f64) - 1.0);
            let b: f64 = 0.0;

            let ir: i32 = (255.9999 * r) as i32;
            let ig: i32 = (255.9999 * g) as i32;
            let ib: i32 = b as i32;
            println!("{} {} {}", ir, ig, ib);
        }
    }
    eprintln!("-&gt;Hecho.");
}
</pre>
</div>

<p>
Compilación con el comando:
</p>

<div class="org-src-container">
<pre class="src src-shell">rustc -o ejemplo_rust -O ejemplo.rs
</pre>
</div>

<p>
Nim:
</p>

<div class="org-src-container">
<pre class="src src-nim">proc main():void =
  var ancho_imagen: int = 256
  var alto_imagen: int = 256

  echo "P3 ", ancho_imagen, " ", alto_imagen, " 255"

  for j in 0..alto_imagen-1:
    for i in 0..ancho_imagen-1:
      var r: float = float(i) / (float(ancho_imagen) - 1)
      var g: float = float(j) / (float(alto_imagen) - 1)
      var b: float = 0.0

      var ir: int = int(255.9999 * r)
      var ig: int = int(255.9999 * g)
      var ib: int = int(255.9999 * b)
      echo ir, " ", ig, " ", ib
main()
</pre>
</div>

<p>
Compilación:
</p>

<div class="org-src-container">
<pre class="src src-shell">nim c --opt:speed ejemplo.nim
</pre>
</div>

<p>
Zig:
</p>

<div class="org-src-container">
<pre class="src src-zig">const std = @import("std");

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    const ancho_imagen: i32 = 256;
    const alto_imagen: i32 = 256;

    try stdout.print("P3 {} {} 255\n", .{ ancho_imagen, alto_imagen });
    for (0..alto_imagen) |j| {
        for (0..ancho_imagen) |i| {
            const r: f64 = @as(f64, @floatFromInt(i)) / (ancho_imagen - 1);
            const g: f64 = @as(f64, @floatFromInt(j)) / (alto_imagen - 1);
            const b: f64 = 0.0;

            const ir: i32 = @as(i32, @intFromFloat(255.9999 * r));
            const ig: i32 = @as(i32, @intFromFloat(255.9999 * g));
            const ib: i32 = @as(i32, @intFromFloat(255.9999 * b));

            try stdout.print("{} {} {}\n", .{ ir, ig, ib });
        }
    }
}
</pre>
</div>

<p>
Compilación:
</p>

<div class="org-src-container">
<pre class="src src-shell">zig build-exe ejemplo.zig
</pre>
</div>


<p>
Los resultado son los siguientes:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Lenguaje</th>
<th scope="col" class="org-right"><code>usr</code></th>
<th scope="col" class="org-right"><code>sys</code></th>
<th scope="col" class="org-right">total</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><b>C</b></td>
<td class="org-right">10.19</td>
<td class="org-right">4.53</td>
<td class="org-right">15.85</td>
</tr>

<tr>
<td class="org-left"><b>Rust</b></td>
<td class="org-right">17.41</td>
<td class="org-right">260.06</td>
<td class="org-right">260.06</td>
</tr>

<tr>
<td class="org-left">nim</td>
<td class="org-right">39.48</td>
<td class="org-right">523.69</td>
<td class="org-right">563.03</td>
</tr>

<tr>
<td class="org-left">Zig</td>
<td class="org-right">160.00</td>
<td class="org-right">2980.00</td>
<td class="org-right">3140.00</td>
</tr>
</tbody>
</table>

<p>
No son pruebas definitivas. Es decir, llama la atención que un
lenguaje compilado, como <i>Zig</i> se vaya a los 3,14 segundos en la
ejecución obteniendo peores resultados incluso que <i>Lua</i>.
</p>

<p>
Seguramente, cualquier lenguaje de esos puede compilarse más
optimizado y por desconocimiento no lo hice.
</p>
</div>
</div>
<div id="outline-container-orgbb7af8d" class="outline-2">
<h2 id="orgbb7af8d">Conclusiones</h2>
<div class="outline-text-2" id="text-orgbb7af8d">
<p>
La principal es que ando con mis cosas. No me olvido del <i>blog</i>, pero
cada vez me cuesta más encontrar temas interesantes. Para mí era más
fácil escribir cuando escribía sólo para mí. Desde que me di cuenta
que había gente que lo leía pienso más en qué puede interesar a otros
que en lo que me interesa a mí. Pero normalmente ando haciendo algún
proyecto personal, que me parece interesante pero que no termino
decidirme a contarlo por aquí.
</p>

<p>
Otro tema tangencial son los lenguajes. Para hacer los ejemplos he
tenido que hacer uno en <i>Zig</i>, un lenguaje por completo desconocido. Es
el primer código que escribo en él. Me ha llamado la atención lo
complejo que puede ser su compilador. Parece un lenguaje bastante
expresivo y no descarto aprender más sobre él en el futuro.
</p>

<p>
De momento estoy disfrutando bastante con el <i>raytracer</i> en <b>C</b> y <b>Lua</b>, es
posible que lo alargue en sus capacidades.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/lua/index.html">Lua</a> <a href="/tags/c/index.html">C</a> <a href="/tags/eglot/index.html">eglot</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[Lua]]></category>
  <category><![CDATA[C]]></category>
  <category><![CDATA[eglot]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2025/04/27/un-revuelto-de-cosas-mias.html</link>
  <pubDate>Sun, 27 Apr 2025 09:18:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Un poco sobre Lua]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2025-03-21</div>
<p>
Llevo sin escribir nada por aquí desde el año pasado. Cada vez me
cuesta más encontrar un tema del que hablar, de los que me interesan,
del que no haya hablado ya. Por ello, quizá, me concentro en otras
cosas y tengo el <i>blog</i> hecho un erial. No quiero decir que esté
abandonado, porque a estas alturas y después de tantos años, no creo
que lo cierre o lo abandone del todo nunca. Me dedico a mis
<i>investigaciones</i>, a estudiar y a aprender, y se me pasa el escribirme
mi resumen. También, porque este <i>blog</i> se inició como una forma de
recordarme a mí mismo lo que iba aprendiendo y mis herramientas para
la toma de notas han evolucionado al punto en que no necesito tanto
contarme qué he hecho para guardarlo en la <i>memoria externa</i>. Pero hoy,
vengo a hablar sobre <b>Lua</b>, un lenguaje de <i>script</i> incrustable y
minimalista al que le estoy dedicando un poco más de atención
últimamente.
</p>

<p>
El objetivo no es otro que aprender. Supongo que habrá quien lea esto,
que si es de los que leen de manera habitual, piense: «si ya he visto
por este <i>blog</i> código escrito en Lua...». Es cierto, aquí ya he hablado
de algunos temas y traído código en este lenguaje. Es minimalista, así
que no cuesta nada escribir algunas cosas sencillas sabiendo poco de
cómo funciona. Sin embargo, mi intención últimamente ha sido
profundizar en esos detalles para los que sueles decir: <i>«otro día lo
miro»</i> y no vuelves a mirar nunca.
</p>

<p>
Liándome la manta a la cabeza decidí leer uno de los libros que tengo
descargado desde hace tiempo y que he consultado de vez en cuando para
escribir algunos <i>scripts</i>. Me refiero a <a href="https://www.lua.org/pil/"> <i>Programming in Lua</i> </a>, el libro
escrito por uno de sus creadores y principales mantenedores. Mis
apuntes, los voy poniendo <a href="https://notxor.nueva-actitud.org/lua/index.html#ProgrammingInLua">en un <i>Tiddlywiki</i> en este mismo sitio</a>.
</p>
<div id="outline-container-orgcb8b91f" class="outline-2">
<h2 id="orgcb8b91f">Sobre Lua</h2>
<div class="outline-text-2" id="text-orgcb8b91f">
<p>
Como lenguaje es bastante simple. Nada que no esté implementado en el
ANSI C, lo encontrarás en Lua. En el libro se hace mucho hincapié en
el ANSI C y en su ejecución en cualquier sistema que tenga un
compilador de ANSI C que compilará la librería sin problema. Su
desempeño también es alto, lleva incorporado el <i>luajit</i> para acelerar
la ejecución y, por tanto, lo más destacable de Lua es la sencillez,
la presencia en cualquier sistema y la velocidad de ejecución.
</p>

<p>
Está diseñado, al menos originalmente, para estar incrustado como
lenguaje auxiliar en otras aplicaciones. Por ello, Lua es una librería
de funciones escritas en C. Puede haber confusión con que cuente con
su propio REPL, pero éste no deja de ser una aplicación de consola con
la librería de intérprete incrustada.
</p>

<p>
A pesar de todas las ventajas hay algunas cosas que no terminan de
cuadrarme por diversos motivos. La primera es que en la época de los
procesadores multihilo, Lua no tenga algún mecanismo que permita la
ejecución en paralelo. De hecho, en el propio <i>PiL</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, el autor
descarga en la aplicación que hospede el intérprete de Lua estos
asuntos y sugiere que para la ejecución en paralelo le basta con
lanzar varios intérpretes a la vez.
</p>

<p>
Otra de las cosas que me resultan <i>un poco marcianas</i>, y que me ha dado
alguna que otra patada en el trasero mientras hacía los ejercicios, es
que los índices se empiecen a numerar en 1 y no en 0 como en la
mayoría, por no decir todos, los lenguajes que conozco. Quizá sea
sencillo para la gente que no es programadora, pero a los que
programamos en otros lenguajes, nos resulta, cuando menos, chocante.
</p>

<p>
Por otro lado, el otro día hablando con un amigo me llamó la atención
sobre un punto que al que yo no le había echado mucha cuenta pero que
es otra de las cosas un <i>poco marcianas</i> que tiene Lua: la limitación de
que sólo se puede utilizar la instrucción <code>return</code> como la última de un
bloque, por lo que en algunos casos donde se necesita un <code>return</code> hay
que proporcionar un bloque tal que <code>do return end</code>.
</p>

<p>
Otro de los tropezones que me he encontrado por la diferencia entre C
y Lua, es que pare éste el 0 es un valor verdadero. No siempre me ha
pasado, porque viene avisado en su manual, pero cuando he estado
lidiando con algún ejemplo que mezclara C y Lua, me ha ocurrido en
alguna ocasión, desconcertándome un poco al principio, el que una
misma expresión sea falsa en C y no en Lua. En Lua sólo tienen valor
falso los valores booleanos <code>false</code> y <code>nil</code>, el resto de expresiones, como
por ejemplo <code>""</code> o <code>{}</code> o <code>0</code>, son todas verdaderas.
</p>

<p>
Cabe destacar la existencia de las <i>metatablas</i>, un mecanismo que
permite algo de magia a la hora de flexibilizar el lenguaje. Se
merecen ellas solas todo un artículo por las posibilidades que ofrecen
para adecuar el lenguaje a nuestras necesidades. Permiten crear nuevos
tipos, hacer de Lua un lenguaje, por poner un ejemplo, orientado a
objetos o lo que quieras, pues definen el comportamiento de las
<i>tablas</i>. Además, vienen acompañadas de <i>metamétodos</i>, lo que nos permite
ajustar esos comportamientos según los tipos que creemos con las
<i>metatablas</i>, estableciendo operadores para nuestros tipos o métodos de
acceso a los índices de las tablas.
</p>

<p>
Si alguien pregunta por mi opinión subjetiva personal, es que Lua en
general es un lenguaje eficiente y sencillo, pero que mantener esa
sencillez y eficiencia le lleva a tener otras <i>cadaunadas</i> con las que
lidiar. Algo que no importa demasiado, porque todos los lenguajes
tienen de eso.
</p>
</div>
</div>
<div id="outline-container-org0cedc7a" class="outline-2">
<h2 id="org0cedc7a">Proyectos de aprendizaje</h2>
<div class="outline-text-2" id="text-org0cedc7a">
<p>
Como es habitual, cuando me pongo a aprender algún lenguaje en serio,
me gusta utilizarlo para algún proyecto más complejo que hacer un par
de ejemplos. Para eso ya he ido haciendo la mayoría de los ejercicios
que se proponen en el libro y aprendiendo esos detalles. Pero
desarrollar algo desde cero es bastante más complejo.
</p>

<p>
En un ejercicio no tienes que tomar muchas decisiones, lo haces
amparándote en la teoría explicada en el capítulo correspondiente y no
hay un esfuerzo intelectual que requiera mucho más. El verdadero
<i>problema</i> no es el que te ponga un libro, sino el que te encontrarás en
un proyecto de desarrollo desde cero.
</p>

<p>
Sin embargo, este aprendizaje estaba dirigido a un proyecto en
concreto o algo que me ronda la cabeza desde hace algún tiempo y que
quería desarrollar. Pero también por el camino se me han pasado por la
cabeza algunas ideas más. Al final, me ha surgido la pretensión de
hacer algunas cosillas con Lua. Primero, después de quejarme de la
falta de ejecución paralela, la idea loca es <i>«pues hazlo tú mismo»</i>. La
segunda una evolución de la idea original, que era hacer una aventura
gráfica (isométrica) de las de <i>point &amp; click</i> con Lua y Löve2D. Al
final es básicamente lo mismo pero en 3D.
</p>
</div>
<div id="outline-container-org148ddf5" class="outline-3">
<h3 id="org148ddf5">Procesos en paralelo</h3>
<div class="outline-text-3" id="text-org148ddf5">
<p>
En este sentido, mi referencia son los procesos de <i>erlang</i> y sus
capacidades de intercomunicación. Está claro que ahora mismo, antes de
empezar a escribir una línea de código, todo parece cuadrar
perfectamente y que será todo maravilloso. Pero me temo que será uno
de esos proyectos que me llevarán al límite de mis capacidades de
programación a una velocidad que pueden plantarme delante de un muro
infranqueable.
</p>

<p>
¿Qué me gustaría tener en este proyecto? Pues como mínimo algunas
cosillas:
</p>

<ul class="org-ul">
<li>Intercomunicación entre procesos. En <i>erlang</i> cada proceso maneja su
propia memoria, pero puede recibir mensajes desde otros procesos.
Estos mensajes los encola en el buzón si está ocupado y va
ejecutándolos a su ritmo.</li>
<li>Un proceso puede levantar otro y controlar que sigue en ejecución.
En este principio se basa todo OTP y sus árboles de supervisión que
permiten al sistema recuperarse ante un error o problema relanzando
los procesos muertos por alguna razón.</li>
</ul>

<p>
No estoy proponiendo crear un OTP completo. El OTP de <i>erlang</i> se basa
fuertemente en cómo funciona su máquina virtual <i>BEAM</i> y puede mantener
miles de procesos paralelos, algo que creo que una máquina física no
puede hacer con las limitadas decenas de hilos que maneja.
</p>

<p>
Mirando la documentación y otras implementaciones encontré algunas
soluciones al multihilo, como <a href="https://lualanes.github.io/lanes/">lanes</a>, que tiene muy buena pinta y que,
seguramente, estará mejor implementado de lo que yo podré hacer. Pero
como dije antes, mi objetivo es aprender.
</p>
</div>
</div>
<div id="outline-container-orgda63505" class="outline-3">
<h3 id="orgda63505">Jugar</h3>
<div class="outline-text-3" id="text-orgda63505">
<p>
El juego es sano. Envejecemos cuando dejamos de jugar y no me gusta la
idea de dejar las actividades lúdicas.
</p>

<p>
En este blog <a href="https://notxor.nueva-actitud.org/2024/09/03/perspectiva-isometrica.html">ya hablé sobre löve2d</a>, ese artículo incluía un poco de
explicación sobre la programación de gráficos isométricos y cómo
capturar entrada de ratón y cómo dibujar una rejilla que serviría de
«terreno de juego». La idea original era hacer un jueguecillo en plan
aventura gráfica de <i>point &amp; click</i> con múltiples puzles al estilo del
mítico <i>Myst</i>.
</p>

<p>
Sin embargo, por el camino me acordé también de aquella vez que
programé un <i>mod</i> para <i>Luanti</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>, <a href="https://notxor.nueva-actitud.org/2021/05/28/programando-un-m%C3%B3dulo-para-minetest.html">que también lo conté por aquí</a>. La
idea se me cruzó porque alguien me habló de <a href="https://cubicodyssey.game/"> <i>Cubic Odyssey</i> </a> y tras ver
el <i>trailer</i> y mirarlo un poco detenidamente pensé... <i>«y si hago un
juego completo»</i>. Por supuesto, será mucho más modesto, porque me
encuentro con algunos problemas:
</p>

<ul class="org-ul">
<li>No puedo hacerlo desde cero porque necesitaría tres vidas para
acabarlo. Tendría que aprender (bien) <i>pixelart</i>, entre otras cosas.
Pero todo es ponerme, así que no lo descarto.</li>
<li>Tendría que modelar todo el mundo y los objetos que aparezcan en él.
Además, el motor de Luanti, admite objetos en el formato <code>.b3d</code>, un
formato binario de <i>Blitz3D</i>. He visto que han actualizado el
exportador para <a href="https://blender.org">Blender3D</a>; la última vez que lo intenté no
funcionaba bien en <i>Linux</i> y no conseguí hacer un modelo para
importarlo en <i>Luanti</i>.</li>
</ul>

<p>
Otra alternativa es hacer algo a medio camino: sería un módulo, que se
integraría en un juego, con sus propios elementos e historia. Algo que
haría la función de <i>aventura</i> o <i>quest</i> dentro de un juego más general.
Como crear <i>otra dimensión</i> dentro del juego, al estilo de como lo hace
<a href="https://minecraft.fandom.com/es/wiki/El_End">El End</a> en Minecraft.
</p>

<p>
Aún no tengo nada decidido, se admiten sugerencias. Habría que hacer
que fuera interesante, con <i>algún premio</i> especial, como por ejemplo,
conseguir una capa que le permita al PJ propietario –y sólo a él, para
que no se pueda transferir sin haber pasado las pruebas– volar o
cualquier otra acción que se encuentre limitada en el juego general a
modo de privilegio. Programar un <i>mod</i> para un juego ya hecho plantea la
posibilidad de chocar con otros elementos ya presentes en el juego,
incompatibilidades del módulo o de sus herramientas, comandos, etc.
Por lo que también hay que ser cuidadoso, quizá más que haciendo el
juego desde cero, porque en ese caso no se conocen todos los
entresijos del <i>juego</i> –que programaron otros–. Pero a cambio, obtienes
todo un entorno donde desarrollar tus ideas.
</p>
</div>
</div>
</div>
<div id="outline-container-orge235088" class="outline-2">
<h2 id="orge235088">Conclusiones</h2>
<div class="outline-text-2" id="text-orge235088">
<p>
Lua parece un lenguaje potente y sencillo. Como todos los lenguajes
tiene sus <i>cadaunadas</i> e incluso en el <i>PiL</i> habla de <i>Luaismos</i>,
expresiones y cosas propias de Lua. Es muy rápido, pero como lenguaje
para estar embebido en una aplicación sigo prefiriendo <i>Scheme</i> (<a href="https://github.com/ashinn/chibi-scheme">Chibi</a>,
por poner un ejemplo) o incluso <i>Lisp</i> (<a href="https://ecl.common-lisp.dev/">ecl</a>, <i>Embeddable Common Lisp</i>).
</p>

<p>
Con respecto a los proyectos, me atrae más el lúdico <i>Luanti</i> que los
demás. Hacerlo sería la manera de obligarme a pensar en <i>Lua</i>, pues es
el lenguaje embebido en dicha aplicación. Desarrollar un juego desde
cero me lo plantearía si encontrara quien ayudara en algunas tareas.
Supongo que texturas y modelos podrían aprovecharse de algunos módulos
que los proporcionan con licencias libres, por lo que ese trabajo lo
tendría al alcance y podría concentrarme en otros aspectos, como crear
un mundo original, poblarlo de criaturas y <i>PnJ</i> con quienes
interactuar e invitar a jugadores a que lo habiten.
</p>

<p>
Quizá sea más alcanzable para un programador sólo el desarrollo de una
<i>aventura</i> completa, dentro de un juego ya creado. Aunque si contara con
ayuda dicha aventura podría ser en sí misma un juego completo. Imagino
una dimensión completa, con estructuras y <i>mobs</i> propios que pongan las
cosas difíciles al jugador, que lo hagan pensar, le permitan moverse e
interactuar, incluso colaborar con otros jugadores para resolverlo o
conseguir <i>un premio conjunto</i>.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Programming in Lua</i>, libro de referencia sobre Lua. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Antes llamado Minetest: <a href="https://luanti.org">https://luanti.org</a> 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/lua/index.html">Lua</a> ]]></description>
  <category><![CDATA[Lua]]></category>
  <link>https://notxor.nueva-actitud.org/2025/03/21/un-poco-sobre-lua.html</link>
  <pubDate>Fri, 21 Mar 2025 08:39:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Dibujando figuras con Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2024-12-26</div>
<p>
Llevo unos días aprendiendo un poco más sobre <i>SVG</i> y cómo generar
gráficos escribiendo texto. Tengo entre manos un proyecto cuya salida
debería generar algún que otro gráfico, principalmente son
estadísticas y resultados de algunos cálculos. No son, por tanto,
gráficos complicados, más allá de dibujar <i>cuatro figuras</i>: como
establecer los ejes y una rejilla de fondo y sobre ellos dibujar unas
líneas o unos gráficos de barras.  También es posible que haya que
dibujar alguna <i>tarta</i> con la distribución de porcentajes y poco más.
Mi primer impulso fue utilizar algo sencillo como <a href="https://notxor.nueva-actitud.org/tags/pikchr/index.html"> <i>Pikchr</i> </a> pero,
puesto que los informes que iba a generar el <i>chismático</i> saldrán de la
churrera directamente en <i>HTML</i>, por qué no utilizar una salida a <i>SVG</i>
directa, como si fuera una etiqueta <i>HTML</i> más. Investigando sobre <i>SVG</i> y
sus cosas, me tropecé con <code>svg.el</code>, <i>un paquete</i> que viene incluido en
<i>Emacs</i> y puesto que ya tengo parte del proyecto <i>prototipado</i> en <code>elisp</code>,
me puse a investigarlo. De estas cosas vengo a hablar en este
artículo.
</p>
<div id="outline-container-orgc23caed" class="outline-2">
<h2 id="orgc23caed">Sobre el gráfico <i>SVG</i></h2>
<div class="outline-text-2" id="text-orgc23caed">
<p>
Lo primero que hay que comprender es cómo funcionan las dimensiones
del gráfico. Éstas se determinan en la misma etiqueta que envuelve
nuestro gráfico, la <code>&lt;svg&gt;...&lt;/svg&gt;</code>. El eje de coordenadas comienza por
la esquina superior izquierda como punto \((0,0)\). Puesto que mi
intención inicial es que cada gráfico se pueda visualizar para
imprimirse en un <code>A4</code> apaisado, las dimensiones físicas serán de
\(297mm \times 210mm\).
</p>

<p>
El código quedaría como:
</p>

<div class="org-src-container">
<pre class="src src-xml"><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">svg</span> <span style="color: #f8f8f2; font-weight: bold;">width</span>=<span style="color: #f1fa8c;">"297mm"</span> <span style="color: #f8f8f2; font-weight: bold;">height</span>=<span style="color: #f1fa8c;">"210mm"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span><span style="color: #f8f8f2; background-color: #282a36;">
  ...
</span><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">svg</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
</pre>
</div>

<p>
Por defecto, las dimensiones dentro de un <code>.svg</code> se cuentan por
<i>píxeles</i> o <code>px</code>, por tanto hay que añadir <code>mm</code> para que las unidades se
tengan en cuenta. Faltaría indicarle las dimensiones internas con
<code>viewBox</code>. Puesto que no necesito demasiada precisión, me bastaría con
dividir cada milímetro en tres puntos teóricos lo que serían
\(891 \times 630\), por lo que la definición quedará así:
</p>

<div class="org-src-container">
<pre class="src src-xml"><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">svg</span> <span style="color: #f8f8f2; font-weight: bold;">width</span>=<span style="color: #f1fa8c;">"297mm"</span> <span style="color: #f8f8f2; font-weight: bold;">height</span>=<span style="color: #f1fa8c;">"210mm"</span> <span style="color: #f8f8f2; font-weight: bold;">viewBox</span>=<span style="color: #f1fa8c;">"0 0 891 630"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span><span style="color: #f8f8f2; background-color: #282a36;">
  ...
</span><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">svg</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
</pre>
</div>

<p>
Ya, son unas medidas un tanto raras y seguramente no las más fáciles
de gestionar. Pero, en general, todos los gráficos llevarán estas
dimensiones. En todo caso, si hay que cambiar algo, el valor de
<code>viewBox</code> debería mantener la relación \(ancho \times alto\) para no
deformar el gráfico y que las escalas, tanto \(x\) como \(y\), sean
idénticas.
</p>
</div>
<div id="outline-container-orgb926843" class="outline-3">
<h3 id="orgb926843">Elementos básicos de dibujo</h3>
<div class="outline-text-3" id="text-orgb926843">
<p>
En general, cualquier elemento <i>SVG</i> puede dibujarse con el más general
<code>path</code>. Sin embargo, tanta flexibilidad acarrea una definición mucho más
compleja que no necesito desentrañar en este momento, teniendo en
cuenta además, que todo lo que quiero dibujar son algunos elementos
muy simples, como líneas, rectángulos y círculos. Prefiero, por tanto
ponerle un poco de atención a estos elementos simples, dejando el
citado elemento <code>path</code> para otro momento cuando necesite complicar las
cosas.
</p>
</div>
<div id="outline-container-org1c60daf" class="outline-4">
<h4 id="org1c60daf">Líneas y polilíneas</h4>
<div class="outline-text-4" id="text-org1c60daf">
<p>
La forma más sencilla que se puede dibujar en <i>SVG</i> es una línea recta
que va del punto 1 al punto 2. La etiqueta <i>SVG</i> tiene la siguiente
forma:
</p>

<div class="org-src-container">
<pre class="src src-xml"><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">line</span> <span style="color: #f8f8f2; font-weight: bold;">x1</span>=<span style="color: #f1fa8c;">"n&#250;m"</span> <span style="color: #f8f8f2; font-weight: bold;">y1</span>=<span style="color: #f1fa8c;">"n&#250;m"</span> <span style="color: #f8f8f2; font-weight: bold;">x2</span>=<span style="color: #f1fa8c;">"n&#250;n"</span> <span style="color: #f8f8f2; font-weight: bold;">y2</span>=<span style="color: #f1fa8c;">"num"</span> <span style="color: #f8f8f2; font-weight: bold;">stroke</span>=<span style="color: #f1fa8c;">"color"</span> <span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
</pre>
</div>

<p>
Dibujar algunas líneas escribiendo directamente las etiquetas no es
muy complicado. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-xml"><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">svg</span> <span style="color: #f8f8f2; font-weight: bold;">width</span>=<span style="color: #f1fa8c;">"200"</span> <span style="color: #f8f8f2; font-weight: bold;">height</span>=<span style="color: #f1fa8c;">"200"</span> <span style="color: #f8f8f2; font-weight: bold;">viewBox</span>=<span style="color: #f1fa8c;">"0 0 200 200"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">line</span> <span style="color: #f8f8f2; font-weight: bold;">x1</span>=<span style="color: #f1fa8c;">"50"</span> <span style="color: #f8f8f2; font-weight: bold;">y1</span>=<span style="color: #f1fa8c;">"25"</span> <span style="color: #f8f8f2; font-weight: bold;">x2</span>=<span style="color: #f1fa8c;">"175"</span> <span style="color: #f8f8f2; font-weight: bold;">y2</span>=<span style="color: #f1fa8c;">"25"</span> <span style="color: #f8f8f2; font-weight: bold;">stroke</span>=<span style="color: #f1fa8c;">"blue"</span> <span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">line</span> <span style="color: #f8f8f2; font-weight: bold;">x1</span>=<span style="color: #f1fa8c;">"50"</span> <span style="color: #f8f8f2; font-weight: bold;">y1</span>=<span style="color: #f1fa8c;">"50"</span> <span style="color: #f8f8f2; font-weight: bold;">x2</span>=<span style="color: #f1fa8c;">"175"</span> <span style="color: #f8f8f2; font-weight: bold;">y2</span>=<span style="color: #f1fa8c;">"175"</span> <span style="color: #f8f8f2; font-weight: bold;">stroke</span>=<span style="color: #f1fa8c;">"black"</span> <span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">line</span> <span style="color: #f8f8f2; font-weight: bold;">x1</span>=<span style="color: #f1fa8c;">"25"</span> <span style="color: #f8f8f2; font-weight: bold;">y1</span>=<span style="color: #f1fa8c;">"50"</span> <span style="color: #f8f8f2; font-weight: bold;">x2</span>=<span style="color: #f1fa8c;">"25"</span> <span style="color: #f8f8f2; font-weight: bold;">y2</span>=<span style="color: #f1fa8c;">"175"</span> <span style="color: #f8f8f2; font-weight: bold;">stroke</span>=<span style="color: #f1fa8c;">"red"</span> <span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">svg</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
</pre>
</div>

<p>
Se visualizará como<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>:
</p>

<svg width="200" height="200" viewBox="0 0 200 200">
  <rect x="0" y="0" width="200" height="200" style="fill:white;stroke:black;" />
  <line x1="50" y1="25" x2="175" y2="25" stroke="blue" />
  <line x1="50" y1="50" x2="175" y2="175" stroke="black" />
  <line x1="25" y1="50" x2="25" y2="175" stroke="red" />
</svg>

<p>
Por supuesto, también se pueden especificar colores por sus valores
<code>rgb(rojo, verde, azul)</code> y <code>rgba(rojo, verde, azul, opacidad)</code>, o mediante
los formatos hexadecimales <code>#rrggbb</code> y <code>#rgb</code> o <code>#rrggbbaa</code> y <code>#rgba</code>.
También podríamos haber establecido el valor de <code>stroke</code> dentro de un
parámetro de <code>style</code>, igual que se puede hacer en <i>HTML</i>.
</p>

<p>
Las polilíneas son más complejas, en el sentido de que conllevan
definir una lista de puntos, que se unirán mediante líneas rectas por
estricto orden de definición:
</p>

<div class="org-src-container">
<pre class="src src-xml"><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">polyline</span> <span style="color: #f8f8f2; font-weight: bold;">points</span>=<span style="color: #f1fa8c;">"lista de puntos"</span> <span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
</pre>
</div>

<p>
La <i>lista de puntos</i> consiste en una lista de pares de coordenadas,
separadas por espacios o comas. Como ambos separadores se pueden
mezclar, <span id="nota">me gusta<span class="nota"> o debería decir <b>me resulta más legible</b> a mí en particular.</span></span> separar un punto de otro con espacios y la
coordenada \(x\) de la coordenada \(y\) mediante una coma.
</p>

<p>
Es importante establecer el valor de <code>fill</code> a <code>none</code>, pues por defecto,
<i>SVG</i> rellenará la figura y quizá no de la manera que nos gustaría.  Por
ejemplo, el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-xml"><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">svg</span> <span style="color: #f8f8f2; font-weight: bold;">width</span>=<span style="color: #f1fa8c;">"200"</span> <span style="color: #f8f8f2; font-weight: bold;">height</span>=<span style="color: #f1fa8c;">"200"</span> <span style="color: #f8f8f2; font-weight: bold;">viewBox</span>=<span style="color: #f1fa8c;">"0 0 200 200"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">polyline</span> <span style="color: #f8f8f2; font-weight: bold;">points</span>=<span style="color: #f1fa8c;">"0,0 25,100 50,0 75,100 100,0 125,100"</span> <span style="color: #f8f8f2; font-weight: bold;">style</span>=<span style="color: #f1fa8c;">"fill:none; stroke:#0000ff; stroke-width:2;"</span> <span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">polyline</span> <span style="color: #f8f8f2; font-weight: bold;">points</span>=<span style="color: #f1fa8c;">"0,100 25,200 50,100 75,200 100,100 125,200"</span> <span style="color: #f8f8f2; font-weight: bold;">style</span>=<span style="color: #f1fa8c;">"stroke:#ff0000; stroke-width:2;"</span> <span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">svg</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
</pre>
</div>

<p>
se visualizará como:
</p>

<svg width="200" height="200" viewBox="0 0 200 200">
  <rect x="0" y="0" width="200" height="200" style="fill:white;stroke:black;" />
  <polyline points="0,0 25,100 50,0 75,100 100,0 125,100" style="fill:none; stroke:#0000ff; stroke-width:2;" />
  <polyline points="0,100 25,200 50,100 75,200 100,100 125,200" style="stroke:#ff0000; stroke-width:2;" />
</svg>

<p>
ambas polilíneas son idénticas, salvo que la segunda está desplazada
en \(y\) para visualizarla más abajo y no se ha especificado <code>none</code> como
relleno. La visualización es, por tanto, un poco más extraña, pues
como se puede observar, une el primer punto y el último y rellena los
espacios generados con el color negro, que es el color por defecto.
</p>
</div>
</div>
</div>
<div id="outline-container-org26ed016" class="outline-3">
<h3 id="org26ed016">Rectángulos y círculos</h3>
<div class="outline-text-3" id="text-org26ed016">
<p>
Otras figuras básicas que voy a necesitar son los <i>rectángulos</i> y los
<i>círculos</i>. Una diferencia básica entre ellos es que mientras que en el
círculo debes proporcionar las coordenadas del centro de la figura, en
el rectángulo, la coordenada que estableces es la posición de la
esquina superior izquierda.
</p>

<p>
Además, en el caso del rectángulo, se pueden especificar dos radios
para definir la curvatura de las esquinas, tanto en el eje \(x\) como en
el eje \(y\). La definición por tanto sería:
</p>

<div class="org-src-container">
<pre class="src src-xml"><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">rect</span> <span style="color: #f8f8f2; font-weight: bold;">x</span>=<span style="color: #f1fa8c;">"n&#250;m"</span> <span style="color: #f8f8f2; font-weight: bold;">y</span>=<span style="color: #f1fa8c;">"n&#250;m"</span> <span style="color: #f8f8f2; font-weight: bold;">width</span>=<span style="color: #f1fa8c;">"n&#250;m"</span> <span style="color: #f8f8f2; font-weight: bold;">height</span>=<span style="color: #f1fa8c;">"n&#250;m"</span> <span style="color: #f8f8f2; font-weight: bold;">rx</span>=<span style="color: #f1fa8c;">"n&#250;m"</span> <span style="color: #f8f8f2; font-weight: bold;">ry</span>=<span style="color: #f1fa8c;">"n&#250;m"</span> <span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">circle</span> <span style="color: #f8f8f2; font-weight: bold;">cx</span>=<span style="color: #f1fa8c;">"n&#250;m"</span> <span style="color: #f8f8f2; font-weight: bold;">cy</span>=<span style="color: #f1fa8c;">"n&#250;m"</span> <span style="color: #f8f8f2; font-weight: bold;">r</span>=<span style="color: #f1fa8c;">"n&#250;m"</span> <span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
</pre>
</div>

<p>
Como decía, los dos radios(<code>rx</code> y <code>ry</code>) son opcionales, si no se
proporcionan, se entiende que su valor es \(0\). Sin embargo, si
sólamente se especifica uno, se entiende que el otro tiene un radio
idéntico.
</p>

<p>
Por ejemplo, el código
</p>

<div class="org-src-container">
<pre class="src src-xml"><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">svg</span> <span style="color: #f8f8f2; font-weight: bold;">width</span>=<span style="color: #f1fa8c;">"200"</span> <span style="color: #f8f8f2; font-weight: bold;">height</span>=<span style="color: #f1fa8c;">"200"</span> <span style="color: #f8f8f2; font-weight: bold;">viewBox</span>=<span style="color: #f1fa8c;">"0 0 200 200"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">rect</span> <span style="color: #f8f8f2; font-weight: bold;">x</span>=10 <span style="color: #f8f8f2; font-weight: bold;">y</span>=10 <span style="color: #f8f8f2; font-weight: bold;">width</span>=95 <span style="color: #f8f8f2; font-weight: bold;">height</span>=95 <span style="color: #f8f8f2; font-weight: bold;">rx</span>=10 <span style="color: #f8f8f2; font-weight: bold;">style</span>=<span style="color: #f1fa8c;">"fill:#c8c9ff;stroke:black;stroke-width:2"</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">rect</span> <span style="color: #f8f8f2; font-weight: bold;">x</span>=35 <span style="color: #f8f8f2; font-weight: bold;">y</span>=120 <span style="color: #f8f8f2; font-weight: bold;">width</span>=40 <span style="color: #f8f8f2; font-weight: bold;">height</span>=40 <span style="color: #f8f8f2; font-weight: bold;">style</span>=<span style="color: #f1fa8c;">"stroke:blue;fill:none"</span> <span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">rect</span> <span style="color: #f8f8f2; font-weight: bold;">x</span>=120 <span style="color: #f8f8f2; font-weight: bold;">y</span>=120 <span style="color: #f8f8f2; font-weight: bold;">width</span>=40 <span style="color: #f8f8f2; font-weight: bold;">height</span>=40 <span style="color: #f8f8f2; font-weight: bold;">rx</span>=10 <span style="color: #f8f8f2; font-weight: bold;">ry</span>=5 <span style="color: #f8f8f2; font-weight: bold;">style</span>=<span style="color: #f1fa8c;">"stroke:blue;fill:none"</span> <span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">circle</span> <span style="color: #f8f8f2; font-weight: bold;">cx</span>=100 <span style="color: #f8f8f2; font-weight: bold;">cy</span>=100 <span style="color: #f8f8f2; font-weight: bold;">r</span>=25 <span style="color: #f8f8f2; font-weight: bold;">style</span>=<span style="color: #f1fa8c;">"fill:#ffc9ff;stroke:red;stroke-width:2"</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">svg</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
</pre>
</div>

<p>
se visualizará como:
</p>

<svg width="200" height="200" viewBox="0 0 200 200">
  <rect x="0" y="0" width="200" height="200" style="fill:white;stroke:black;" />
  <rect x=10 y=10 width=95 height=95 rx=10 style="fill:#c8c9ff;stroke:black;stroke-width:2"/>
  <rect x=35 y=120 width=40 height=40 style="stroke:blue;fill:none" />
  <rect x=120 y=120 width=40 height=40 rx=10 ry=5 style="stroke:blue;fill:none" />
  <circle cx=100 cy=100 r=25 style="fill:#ffc9ff;stroke:red;stroke-width:2"/>
</svg>

<p>
Con estos <i>mimbres</i> ya puedo hacer mi <i>cesto</i>.
</p>
</div>
</div>
</div>
<div id="outline-container-org4c6c5a1" class="outline-2">
<h2 id="org4c6c5a1">Usando <i>Emacs</i></h2>
<div class="outline-text-2" id="text-org4c6c5a1">
<p>
Tengo una prueba de concepto algo avanzada y bastante funcional que se
ejecuta sobre <i>Emacs</i>. Para dibujar la salida, me he encontrado con que
nuestro editor favorito cuenta, de manera <i>innata</i> con el paquete
<code>svg.el</code>, que permite generar código <i>SVG</i> desde el código <code>elisp</code>, sin
despeinarse mucho.
</p>

<p>
La ayuda que <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/SVG-Images.html">he encontrado</a> es un poco escasa, se circunscribe a un
apartado del manual de <code>elisp</code> y, además, he notado que algunas cosas
que <i>SVG</i> soporta, no están implementadas en <code>svg.el</code>. Pero para lo
básico, que es lo que necesito, sí me sirve dicha herramienta.
</p>

<p>
Un poco de código para poner un ejemplo, generando la misma salida que
el último ejemplo de <i>SVG</i>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">svg</span>)
(<span style="color: #ff79c6; font-weight: bold;">let</span> ((mi-svg (svg-create 200 200 <span style="color: #8be9fd; font-style: italic;">:stroke-width</span> 2)))
  (svg-rectangle mi-svg 10 10 95 95 <span style="color: #8be9fd; font-style: italic;">:rx</span> 10
                 <span style="color: #8be9fd; font-style: italic;">:fill-color</span> <span style="color: #f1fa8c;">"#c8c9ff"</span> <span style="color: #8be9fd; font-style: italic;">:stroke-color</span> <span style="color: #f1fa8c;">"black"</span>)
  (svg-rectangle mi-svg 35 120 40 40
                 <span style="color: #8be9fd; font-style: italic;">:stroke-color</span> <span style="color: #f1fa8c;">"blue"</span> <span style="color: #8be9fd; font-style: italic;">:fill-color</span> <span style="color: #f1fa8c;">"none"</span> <span style="color: #8be9fd; font-style: italic;">:stroke-width</span> 1)
  (svg-rectangle mi-svg 120 120 40 40 <span style="color: #8be9fd; font-style: italic;">:rx</span> 10 <span style="color: #8be9fd; font-style: italic;">:ry</span> 5
                 <span style="color: #8be9fd; font-style: italic;">:stroke-color</span> <span style="color: #f1fa8c;">"blue"</span> <span style="color: #8be9fd; font-style: italic;">:fill-color</span> <span style="color: #f1fa8c;">"none"</span> <span style="color: #8be9fd; font-style: italic;">:stroke-width</span> 1)
  (svg-circle mi-svg 100 100 25
              <span style="color: #8be9fd; font-style: italic;">:stroke-color</span> <span style="color: #f1fa8c;">"red"</span> <span style="color: #8be9fd; font-style: italic;">:fill-color</span> <span style="color: #f1fa8c;">"#ffc9ff"</span>)
  (<span style="color: #ff79c6; font-weight: bold;">with-temp-buffer</span>
    (svg-print mi-svg)
    (buffer-string)))
</pre>
</div>


<figure id="org7d8a429">
<img src="./imagenes/toqueteo.svg" alt="toqueteo.svg" class="org-svg">

<figcaption><span class="figure-number">Figura 1: </span>La imagen generada con el código anterior.</figcaption>
</figure>

<p>
Analicemos un poco el código:
</p>

<ol class="org-ol">
<li>La primera línea es una llamada a que vamos a necesitar el módulo
<code>svg.el</code> para que lo vaya cargando.</li>
<li>La definición del <i>SVG</i> se realiza con la función <code>svg-create</code> que
devuelve un objeto, en este caso <code>mi-svg</code> donde el siguiente código
irá dibujando. Además podemos establecer un valor de ancho de línea
por defecto. Allá donde no se especifique <code>:stroke-width</code> ese valor
será 2.</li>
<li>Por otra parte, en el bloque de código se ha especificado el
fichero donde se guardará el resultado. Una vez dibujada cada forma
establecemos un <i>buffer</i> temporal donde guardaremos el resultado
mediante la función <code>svg-print</code>.</li>
</ol>

<p>
Si se quiere visualizar de una manera más interactiva, podemos ir
haciéndolo paso a paso en el <i>REPL</i>. Si lanzamos el comando <code>ielm</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">ELISP&gt; (<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">svg</span>)
svg
</pre>
</div>

<p>
<i>Visitar</i> un <i>buffer</i> temporal.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">ELISP&gt; (find-file <span style="color: #f1fa8c;">"buffer-temporal"</span>)
#&lt;buffer buffer-temporal&gt;
</pre>
</div>

<p>
Al hacerlo, nos llevará directamente al nuevo <i>buffer</i>. Podemos dividir
el marco para tenerlo a la vista mientras escribimos en <code>ielm</code>.
</p>

<p>
Lo siguiente que debemos hacer es crear el objeto <i>SVG</i> en el que dibujaremos:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">ELISP&gt; (<span style="color: #ff79c6; font-weight: bold;">setf</span> mi-svg (svg-create 200 200 <span style="color: #8be9fd; font-style: italic;">:stroke-width</span> 2))
(svg
 ((width . 200) (height . 200) (version . <span style="color: #f1fa8c;">"1.1"</span>)
  (xmlns . <span style="color: #f1fa8c;">"http://www.w3.org/2000/svg"</span>)
  (xmlns:xlink . <span style="color: #f1fa8c;">"http://www.w3.org/1999/xlink"</span>) (stroke-width . 2)))
</pre>
</div>

<p>
Una vez que lo hemos creado, podemos asociarlo con nuestro <i>buffer
temporal</i>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">ELISP&gt; (svg-insert-image mi-svg)
((<span style="color: #8be9fd; font-style: italic;">:image</span> . #&lt;marker at 1 in buffer-temporal&gt;) (width . 200)
 (height . 200) (version . <span style="color: #f1fa8c;">"1.1"</span>)
 (xmlns . <span style="color: #f1fa8c;">"http://www.w3.org/2000/svg"</span>)
 (xmlns:xlink . <span style="color: #f1fa8c;">"http://www.w3.org/1999/xlink"</span>) (stroke-width . 2))
</pre>
</div>

<p>
A partir de aquí, cuando modifiquemos algo desde el <code>ielm</code> lo iremos
visualizando directamente en nuestro <i>buffer</i>.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">ELISP&gt; (svg-rectangle mi-svg 10 10 95 95 <span style="color: #8be9fd; font-style: italic;">:rx</span> 10 <span style="color: #8be9fd; font-style: italic;">:fill-color</span> <span style="color: #f1fa8c;">"#c8c9ff"</span> <span style="color: #8be9fd; font-style: italic;">:stroke-color</span> <span style="color: #f1fa8c;">"black"</span>)
nil
</pre>
</div>

<p>
Como ilustración del modo de trabajo, se puede observar la siguiente
imagen:
</p>


<figure id="org540cb19">
<img src="./imagenes/Captura_dibujando-con-ielm.png" alt="Captura_dibujando-con-ielm.png">

<figcaption><span class="figure-number">Figura 2: </span>Captura de la ventana de <i>Emacs</i> con tres <i>buffers</i> abiertos. El texto del borrador de este artículo a la izquierda, el <i>buffer temporal</i> arriba a la derecha y abajo a la derecha el <code>ielm</code> donde se introducen todos los comandos.</figcaption>
</figure>

<p>
Para dibujos temporales, no necesitamos más, pero si lo que queremos
es guardar nuestro dibujo, tenemos que conseguir la cadena <i>SVG</i>
generada por el módulo. La forma más rápida que he encontrado es
escribir el <i>SVG</i> en el <i>buffer temporal</i> mediante:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">ELISP&gt; (svg-print mi-svg)
nil
</pre>
</div>

<p>
Luego iremos a dicho <i>buffer</i> y guardaremos el archivo con <code>C-x C-w</code>
poniéndole el nombre que queramos.
</p>
</div>
</div>
<div id="outline-container-orgd4ed4a8" class="outline-2">
<h2 id="orgd4ed4a8">Conclusiones</h2>
<div class="outline-text-2" id="text-orgd4ed4a8">
<p>
No es una forma cómoda de dibujar y si lo que quieres conseguir son
dibujos mucho más complejos, te recomiendo que utilices <a href="https://inkscape.app/es/"> <i>Inkscape</i> </a>
para hacerlo, ganarás en tiempo y en salud.
</p>

<p>
Sin embargo, para generar gráficos sencillos desde <i>Emacs</i>, el paquete
<code>svg.el</code>, que por otro lado ya está instalado con nuestro editor, nos
sirve para realizar algunas imágenes o programar alguna salida visual
para nuestros datos.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En la visualización he añadido un marco blanco de fondo para
facilitar mejor la visualización. El código <i>SVG</i> está directamente
escrito en el <i>HTML</i> y se visualiza sin necesidad de enlazar una imagen.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/svg/index.html">svg</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[svg]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2024/12/26/dibujando-figuras-con-emacs.html</link>
  <pubDate>Thu, 26 Dec 2024 18:44:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Breve tutorial sobre TiddlyWiki]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2024-12-18</div>
<p>
Este artículo no tiene el propósito de ser un tutorial completo sobre
<a href="https://tiddlywiki.com/">TiddlyWiki</a>, pero sí de proporcionar un vistazo amplio sobre las
posibilidades que brinda. Para trastear sin peligro
<a href="./notas.html">proporciono un archivo de <i>notas</i> </a>con las anotaciones que he hecho para
escribir el presente artículo. Contiene no sólo la información, sino
también <i>plugins</i> de funcionamiento, como <a href="https://tiddlymap.org/">TiddlyMap</a> para aquellos que
necesiten visualizar los <i>tiddlers</i> como un mapa mental de nodos y
enlaces, y también varios <i>themes</i> para distintos usos, desde mejorar la
visualización en dispositivos móviles como otros enfocados a la
posibilidad de utilizar esta herramienta como página <i>web</i> o <i>blog</i>. Por
supuesto, intentaré proporcionar la información de la manera más
gráfica y sencilla para que esta compleja herramienta no se te haga
demasiado enrevesada.
</p>

<p>
Como digo, es una herramienta compleja y posiblemente pienses que sólo
es adecuada para <i>gurús informáticos</i> con conocimientos arcanos. Pero no
es cierto, a no ser que lo que quieras sea programar <i>plugins</i> o
extensiones, en cuyo caso necesitarás algo más de conocimiento sobre
programación y sobre cómo funciona <i>TiddlyWiki</i>. Si sólo quieres hacer
tus anotaciones y gestionarlas no necesitas programar nada.
</p>
<div id="outline-container-orgb119538" class="outline-2">
<h2 id="orgb119538">El uso normal de <i>TiddlyWiki</i></h2>
<div class="outline-text-2" id="text-orgb119538">
<p>
Un archivo <i>TiddlyWiki</i> es un archivo <code>.html</code> que contiene tanto los datos
como el <i>JavaScript</i> que los visualiza. Tiene la limitación, cuando lo
abres en un navegador, de no dejarte escribir el archivo de nuevo. Al
darle a guardar lo que hará será <i>descargarte</i> una copia a tu
ordenador. Si has modificado un archivo de <i>TiddlyWiki</i> desde el
navegador y cuando vuelves a abrir el archivo ves que no se ha
guardado, échale un ojo al <i>directorio de descargas</i>.
</p>

<p>
Por ello, si vas a hacer un uso intensivo de este sistema, es
recomendable que descargues e instales <a href="https://github.com/TiddlyWiki/TiddlyDesktop">TiddlyDesktop</a>. Esta aplicación
te permitirá guardar tus cambios directamente a disco. Por defecto,
cuando le añades un <i>wiki</i> guardará copias de seguridad o versiones en
el mismo directorio –o en donde tú configures–, pero también puedes
evitarlo, depende de lo que te guste el riesgo.
</p>

<p>
Todo en <i>TiddlyWiki</i> se encuentra dentro de un <i>tiddler</i> y se muestra como
tal. Incluyendo la configuración. Muchos <i>tiddlers</i> dentro de <i>Core</i> se
refieren a parámetros y opciones de la configuración. En su
organización interna funciona casi como un sistema de archivos y se
organizan en directorios. Por ejemplo, los <i>plugins</i> se encuentran
dentro de <code>$:/plugins</code>. Si estás trasteando con el <i>wiki</i> que preparé para
este artículo, podrás encontrar el <i>plugin</i> de prueba que he hecho, como
<code>$:/plugins/notxor/basico</code>. Y dentro de él, encontrarás algunos
<i>tiddlers ocultos</i> como <code>$:/plugins/notxor/basico/macros</code> o
<code>$:/plugins/notxor/basico/estilos</code> donde se encuentra el código del
mismo.
</p>

<p>
Si estás empezando con tu proyecto de notas, te aconsejo que
descargues un <i>wiki</i> vacío, le instales el <i>plugin</i> de español y comiences
desde ahí. También <a href="https://tiddlywiki.com/languages/es-ES/index.html#GettingStarted:%5B%5BCreating%20and%20editing%20tiddlers%5D%5D%20HelloThere%20GettingStarted%20Community">puedes descargarte un <i>wiki</i> vacío ya con dicho
<i>plugin</i> ya instalado</a>. También un <i>wiki</i> que contiene la ayuda en inglés y
una versión traducida parcialmente al español, por si necesitas
referencia de cómo funciona.
</p>
</div>
<div id="outline-container-org91145c6" class="outline-3">
<h3 id="org91145c6">Escribir notas y anotaciones de <i>diario</i></h3>
<div class="outline-text-3" id="text-org91145c6">
<p>
La tarea más habitual es escribir información. Toda la información que
creemos estará almacenada en <i>tiddlers</i>. Un <i>tiddler</i> es un conjunto de
texto que guarda el contenido en <i>campos</i>. Los campos principales son
<code>title</code> que ejercerá de <i>nombre único</i> del <i>tiddler</i> y <code>text</code> que es el
contenido del mismo. Son muy importantes también el campo de <code>type</code> y el
de <code>tags</code>. Como sus nombres indican, el primero informa de qué tipo de
contenido se trata –si no se especifica se entenderá que es un <i>tiddler</i>
de tipo <code>text/vnd.tiddlywiki</code>, es decir, de texto normal–.  Además se
crearán otros campos importantes como <code>created</code> que guardará el momento
exacto cuando se creó o <code>modified</code> que guardará el momento exacto de la
última modificación.
</p>

<p>
Si miras a la derecha de la ventana aparece lo que en <i>TiddlyWiki</i> se
llama <code>SideBar</code>. Verás algo parecido a:
</p>


<figure id="org7740b71">
<img src="./imagenes/sidebar.png" alt="sidebar.png">

<figcaption><span class="figure-number">Figura 1: </span>Controles del <i>wiki</i></figcaption>
</figure>

<p>
Podríamos decir que esa zona corresponde a los controles del <i>wiki</i>. Es
decir, con esa parte podremos acceder a toda la información que
contiene el archivo y también a la configuración. No te preocupes si
no te aparecen los mismos elementos. Son configurables, puedes
seleccionar cuáles aparecen y cuáles no, añadir pestañas a la parte
inferior, hacer que algunas herramientas aparezcan o no, si prefieres
que se vea un marco para los botones o no, etc.
</p>

<p>
En la imagen remarco dos botones, el de crear una nueva anotación (o
<i>tiddler</i>) o el de crear una nueva entrada de diario. Son acciones muy
parecidas, solo que las anotaciones de diario suelen tener como
<code>title</code> una fecha. Por ejemplo, en mis anotaciones de diario, además de
utilizar la fecha del día cuando se hizo la anotación, añade
automáticamente una etiqueta (<code>tag</code>) de «diario», de esa manera puedo
acceder rápidamente a todas las anotaciones del mismo para pasarlas a
permanentes o borrarlas.
</p>

<p>
Al pulsar sobre el botón para crear una nueva nota o una nueva entrada
del diario, nos aparecerá un <i>tiddler</i> como el siguiente:
</p>


<figure id="orgdbbd34e">
<img src="./imagenes/modo-edicion.png" alt="modo-edicion.png">

<figcaption><span class="figure-number">Figura 2: </span><i>Tiddler</i> en modo edición</figcaption>
</figure>

<p>
La diferencia entre entradas de notas y de diario, como digo es el
título y las etiquetas que tengas configuradas para que se añadan por
defecto. Pero en ambos casos la ventana de edición es idéntica. Es
importante que el campo <code>title</code> sea un identificador único. Además, por
defecto, si se utiliza el modo <b>CamelCase</b>, <i>TiddlyWiki</i> reconocerá esos
títulos como enlaces, cuando los escribas en medio del texto.
</p>

<p>
En el contenido puedes utilizar los siguientes caracteres para
formatear el texto:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Texto</th>
<th scope="col" class="org-left">Tecla</th>
<th scope="col" class="org-left">Resultado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">texto <code>''negrita''</code></td>
<td class="org-left"><code>C-b</code></td>
<td class="org-left">texto <b>negrita</b></td>
</tr>

<tr>
<td class="org-left">texto  <code>//itálica//</code></td>
<td class="org-left"><code>C-i</code></td>
<td class="org-left">texto <i>itálica</i></td>
</tr>

<tr>
<td class="org-left">texto <code>__subrayado__</code></td>
<td class="org-left"><code>C-u</code></td>
<td class="org-left">texto <span class="underline">subrayado</span></td>
</tr>

<tr>
<td class="org-left">texto <code>^^super^^</code></td>
<td class="org-left"><code>C-S-p</code></td>
<td class="org-left">texto<sup>super</sup></td>
</tr>

<tr>
<td class="org-left">texto <code>,,sub,,</code></td>
<td class="org-left"><code>C-S-b</code></td>
<td class="org-left">texto<sub>sub</sub></td>
</tr>

<tr>
<td class="org-left">texto <code>~~tachado~~</code></td>
<td class="org-left"><code>C-t</code></td>
<td class="org-left">texto <del>tachado</del></td>
</tr>

<tr>
<td class="org-left">texto <code>`código`</code></td>
<td class="org-left"><code>C-m</code></td>
<td class="org-left">texto <code>código</code></td>
</tr>

<tr>
<td class="org-left">texto <code>@@destacado@@</code></td>
<td class="org-left">-</td>
<td class="org-left">texto <span style="background-color:#ffa">destacado</span></td>
</tr>
</tbody>
</table>

<p>
La columna central muestra los atajos de teclado dentro del editor. Se
entiende que <code>C-</code> se refiere a tener la tecla <code>Ctrl</code> y <code>S-</code> a mantener
pulsada la tecla de mayúsculas.
</p>

<p>
Otros aspectos a tener en cuenta son los bloques, como las citas, los
bloques de código, etc.
</p>

<ul class="org-ul">
<li>Cabeceras: las cabeceras se marcan iniciando la línea con el
carácter <code>!</code> las de primer nivel, <code>!!</code> las de segundo, <code>!!!</code> las de
tercero, etc. Si utilizas alguna clase <code>css</code> especial para alguna
cabecera, la puedes utilizar como <code>!!.mi-clase-especial</code>, para que la
utilice.</li>
<li>Para el primer nivel de una lista se utiliza el <code>*</code> si es de puntos y
el carácter <code>#</code> para las listas numeradas. Los siguientes niveles
serán <code>**</code> y <code>##</code> respectivamente. También se pueden anidar distintos
tipos de lista en distintos niveles utilizando una mezcla de ambos
caracteres <code>*#</code>.</li>
<li><p>
Las listas de definiciones se marcan utilizando los caracteres <code>;</code>
para el término definido y <code>:</code> para la definición. Así el texto:
</p>

<div class="org-src-container">
<pre class="src src-nil">; Definición
: Esto es la definición definida.
</pre>
</div>

<p>
Se mostrará como:
</p>

<dl class="org-dl">
<dt>Definición</dt><dd>Esto es la definición definida.</dd>
</dl></li>
<li><p>
Los enlaces se realizan utilizando el formato:
</p>

<p>
<code>[[texto mostrado|url-al-objeto]]</code>.
</p>

<p>
Es posible que <i>TiddlyWiki</i> marque enlaces directamente sin preguntar.
Por ejemplo, cuando encontramos un término que utiliza <i>CamelCase</i> o
cuando comienza por <code>http</code>. En caso de que no queramos que se marque
dicho término como un enlace, lo podemos preceder con el carácter
<code>~</code>. Por ejemplo: <code>~TiddlyWiki</code> o <code>~http://mi-web.org</code>.
</p></li>
<li><p>
Las imágenes se introducen como enlaces:
</p>

<p>
<code>[img[nombre-imagen]]</code>
</p>

<p>
Normalmente se guardan en otro <i>tiddler</i> y se les llama de esa manera.
También se pueden utilizar <i>URL</i> para enlazar imágenes externas u
otros recursos.
</p></li>
</ul>

<p>
Los bloques para citas podemos establecerlos entre dos líneas con <code>&lt;&lt;&lt;</code>.
Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-nil">&lt;&lt;&lt;
Esto es una ''cita''.
&lt;&lt;&lt;
</pre>
</div>

<p>
se mostrará como
</p>

<blockquote>
<p>
Esto es una <b>cita</b>.
</p>
</blockquote>

<p>
Si necesitamos marcar la autoría lo podemos hacer de la siguiente
manera:
</p>

<div class="org-src-container">
<pre class="src src-nil">&lt;&lt;&lt;
Esto es una ''cita''.
&lt;&lt;&lt; Notxor
</pre>
</div>

<p>
Que se visualizará como:
</p>

<blockquote>
<p>
Esto es una <b>cita</b>.
</p>

<p>
<i>Notxor</i>
</p>
</blockquote>

<p>
También podemos utilizar bloques de código, que funcionan de manera
idéntica a como funcionan en <i>MarkDown</i>:
</p>

<div class="org-src-container">
<pre class="src src-nil">```lenguaje
Este es el código
```
</pre>
</div>

<p>
Si ponemos el lenguaje en la línea de la definición del bloque y
tenemos instalado el <i>plugin</i> de <code>Highlight</code> el código nos lo mostrará con
resaltado de sintaxis.
</p>
</div>
<div id="outline-container-orgf046bba" class="outline-4">
<h4 id="orgf046bba">Tablas</h4>
<div class="outline-text-4" id="text-orgf046bba">
<p>
Las tablas merecen su apartado completo porque tienen muchas
opciones. Para marcar las tablas se utiliza el carácter <code>|</code>, cada fila
de la tabla en un línea. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-nil">|Celda 1 | Celda 2 | Celda 3|
| Celda 4|Celda 5 |Celda 6 |
</pre>
</div>

<p>
La alineación del texto se puede especificar para cada celda.  La
<code>Celda 1</code> estará alineada a la izquierda, pues no hay espacio entre el
carácter <code>|</code> de inicio y el texto. Al contrario, la <code>Celda 3</code> estará
alineada a la derecha, pues hay un espacio al principio, pero no al
final del texto. La <code>Celda 2</code> aparecerá centrada.
</p>

<p>
También podemos especificar la alineación vertical de las celdas:
</p>

<div class="org-src-container">
<pre class="src src-nil">|^arriba izda. |^ arriba centrado |^ arriba dcha.|
|medio izda. | medio centrado | medio dcha.|
|,abajo izda. |, abajo centrado |, abajo dcha.|
</pre>
</div>

<p>
Es decir, si no se usa ningún carácter el contenido de la celda se
centrará verticalmente y se utiliza el carácter <code>^</code> para alinear arriba
y el carácter <code>,</code> para alinear abajo.
</p>

<p>
Para unir celdas se marcará con un carácter en la celda vacía que se
unirá con otra:
</p>

<ul class="org-ul">
<li><code>&gt;</code>: Une la celda donde aparece como único contenido a la celda de su
derecha.</li>
<li><code>&lt;</code>: Une la celda donde aparece como único contenido a la celda de su
izquierda.</li>
<li><code>~</code>: Une la celda donde aparece como único contenido con la celda
superior.</li>
</ul>

<p>
También podemos especificar cabeceras, pies, textos explicativos o
clases <i>CSS</i> para <i>renderizar</i> la tabla con el aspecto que queramos.  Por
ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-nil">|mi-clase otraClase|k
|Esto es una etiqueta para caption |c
|Celda1 |Celda2 |
|Celda3 |Celda4 |
|Cabecera|Cabecera|h
|Pie|Pie|f
</pre>
</div>

<p>
Además de marcar una fila completa con <code>h</code> para que la convierta en
<i>cabecera</i>, podemos remarcar una celda concreta si el texto comienza con
un carácter <code>!</code>. Lo que es bastante socorrido cuando las cabeceras
queremos colocarlas en una columna.
</p>
</div>
</div>
</div>
<div id="outline-container-org8cb93b5" class="outline-3">
<h3 id="org8cb93b5">Listas</h3>
<div class="outline-text-3" id="text-org8cb93b5">
<p>
Una forma muy habitual de ordenar la información es a través de
listas. En <i>TiddlyWiki</i> una lista es tan sencilla como una serie de
<i>títulos</i> de <i>tiddlers</i> separados por espacios. Si un título contiene
espacios en blanco hay que enmarcarlo en <code>[[...]]</code>.
</p>

<p>
Un sitio donde hacer ese tipo de listas en el campo <code>list</code> de cada
<i>tiddler</i>. Además de poder enlazar así distintos <i>tiddlers</i> que no
compartan etiquetas o cualquier otro campo que les haga estar
relacionados, nos proporciona un manera sencilla de ordenarlos.
</p>

<p>
Además, utilizar dicho campo nos podría permitir utilizar el método
<i>Zettelkasten</i> sin hacer ningún tipo de modificación a la herramienta,
sin meternos en instalación de <i>plugins</i> o de programación.
</p>

<p>
Al pulsar el icono de información, nos proporciona toda la información
sobre el <i>tiddler</i>:
</p>


<figure id="orgd6f4248">
<img src="./imagenes/Captura-campo-list.png" alt="Captura-campo-list.png">

<figcaption><span class="figure-number">Figura 3: </span>Visualización de la lista de <i>tiddlers</i> del campo <code>list</code>.</figcaption>
</figure>

<p>
Como podemos ver, al pulsar el botón de información, nos proporciona
toda la información del <i>tiddler</i> sin necesidad de abrirlo para edición.
Ahí remarco las pestañas del campo <code>list</code> y de qué <i>tiddlers</i> apuntan al
actual.
</p>


<figure id="org3bad52b">
<img src="./imagenes/Captura-back-list.png" alt="Captura-back-list.png">

<figcaption><span class="figure-number">Figura 4: </span>Información de los <i>tiddlers</i> que enlazan a este</figcaption>
</figure>
</div>
</div>
<div id="outline-container-org9195636" class="outline-3">
<h3 id="org9195636">Filtros</h3>
<div class="outline-text-3" id="text-org9195636">
<p>
Otra forma de obtener <i>listas</i> de <i>tiddlers</i> es utilizar los filtros. Por
ejemplo, utilizando un <i>widget</i>. Uno de los más utilizados es el <i>widget
lista</i>. Como podemos ver en:
</p>


<figure id="orgbf8d088">
<img src="./imagenes/Captura-widget-lista.png" alt="Captura-widget-lista.png">

<figcaption><span class="figure-number">Figura 5: </span>En la imagen vemos cómo se visualiza el código de un widget list</figcaption>
</figure>

<p>
En esa imagen tenemos una referencia de cómo podemos obtener una
lista, que manejamos con el <i>widget</i> <code>$list</code> para visualizarla.
</p>

<p>
También podemos utilizar los filtros en los <i>macros</i>. Por ejemplo, si la
lista anterior la queremos consultar de una lista de pestañas, podemos
utilizar el macro <code>tabs</code> de la siguiente manera:
</p>


<figure id="org8f85791">
<img src="./imagenes/Captura-macro-tabs.png" alt="Captura-macro-tabs.png">

<figcaption><span class="figure-number">Figura 6: </span>Lista de <i>tabs</i> para importar la información de varios <i>tiddlers</i> dentro de otro</figcaption>
</figure>
</div>
</div>
<div id="outline-container-org54aa1c8" class="outline-3">
<h3 id="org54aa1c8">Transclusión</h3>
<div class="outline-text-3" id="text-org54aa1c8">
<p>
La <a href="https://es.wikipedia.org/wiki/Transclusi%C3%B3n">wikipedia define transclusión</a> como:
</p>

<blockquote>
<p>
En la ciencia de la computación, <b>transclusión</b> es la inclusión de un
documento o parte del mismo dentro de otro documento.
</p>
</blockquote>

<p>
En <i>TiddlyWiki</i> nos referimos a la transclusión como la capacidad de
mostrar el contenido de un <i>tiddler</i> dentro de otro. El formato general
para hacerlo es:
</p>

<div class="org-src-container">
<pre class="src src-nil">{{TituloTiddler!!campo}}
</pre>
</div>

<p>
Si se omite <code>TituloTiddler</code> se entiende que nos referimos al propio
<i>tiddler</i> en uso y si se omite <code>campo</code>, se entenderá que nos referimos al
campo <code>test</code> que es el contenido principal de un <i>tiddler</i> normal.
</p>

<p>
El efecto de visualización es:
</p>


<figure id="org307c7bf">
<img src="./imagenes/Captura-transclusion.png" alt="Captura-transclusion.png">

<figcaption><span class="figure-number">Figura 7: </span>Efecto de la transclusión de un <i>tiddler</i> dentro de otro.</figcaption>
</figure>

<p>
Esto nos permite formar <i>tiddlers</i> que compendien distinta información
sin repetirla, simplemente unificándola en un mismo espacio desde
fuentes diseminadas dentro de nuestro <i>wiki</i>.
</p>
</div>
</div>
<div id="outline-container-orga692eda" class="outline-3">
<h3 id="orga692eda">Manejo de datos</h3>
<div class="outline-text-3" id="text-orga692eda">
<p>
Como podemos ver, una vez tenemos en nuestro <i>wiki</i> cualquier tipo de
dato, podemos visualizarlo allá donde lo necesitemos. Esto nos permite
realizar consultas, capturar datos con plantillas y un sin fin de
tareas de gestión de datos que no presentan una estructura homogénea.
</p>

<p>
<i>TiddlyWiki</i> se convierte así en una base de datos, donde los propios
datos no presentan una estructura fija que se pueda adecuar al
paradigma de <i>tabla</i>, <i>registro</i> y <i>campo</i>, o que se visualice fácilmente en
una hoja de cálculo.
</p>

<p>
Si utilizamos los <i>tiddlers</i> como almacenes de datos, podemos crearnos
nuestras plantillas de capturas de datos y utilizarlas para agilizar
el proceso de tomar datos. En el <i>wiki</i> de pruebas que he enlazado
arriba he creado un par de plantillas para capturar datos personales y
de empresa. La captura de datos es sencilla:
</p>

<ol class="org-ol">
<li>Crear un nuevo <i>tiddler</i> y cuando aparezca el editor, pulsamos en la
herramienta de <i>snippers</i> para abrirla.</li>
<li>Seleccionamos la plantilla que deseamos utilizar.
<img src="./imagenes/Captura-de-datos-plantilla.png" alt="Captura-de-datos-plantilla.png"></li>
<li>Nos aparecerá la <i>transclusión</i> de la plantilla que teníamos
diseñada.</li>
<li>Como dicha plantilla trabaja con <i>widgets</i> de edición,
podemos cerrar la edición del <i>tiddler</i> y trabajar sobre la
visualización.
<img src="./imagenes/Captura-plantilla-datos-personales.png" alt="Captura-plantilla-datos-personales.png"></li>
<li>Es decir, los campos los podemos modificar mediante los <i>widgets</i> de
edición:
<img src="./imagenes/Captura-rellenar-campos.png" alt="Captura-rellenar-campos.png"></li>
<li>Podemos apreciar, que los <i>widgets</i> están enlazados con los <i>campos</i>
del <i>tiddler</i>. Da igual si editas el dato en el <i>widget</i> o en el <i>campo</i>.
<img src="./imagenes/Captura-datos-campos.png" alt="Captura-datos-campos.png"></li>
</ol>

<p>
Además de utilizar los <i>campos</i> de los <i>tiddlers</i> para guardar información
en ellos, también existen lo que se conocen como <b>tiddlers de datos</b>,
que son unos <i>tiddlers</i> especiales cuyo único fin es contener datos.
Pueden ser de dos tipos:
</p>

<dl class="org-dl">
<dt><b>Tiddler diccionario</b></dt><dd>Un <i>tiddler</i> diccionario será de tipo
<code>application/x-tiddler-dictionary</code> y en su contenido tendrá una lista
de valores con el formato <code>clave: valor</code>. Por ejemplo, los <i>tiddlers</i>
de paletas de colores son de este tipo.</dd>
<dt><b>Tiddler JSON</b></dt><dd>Si el contenido de los datos es más complejo que un
simple par <i>clave</i> y <i>valor</i>, podemos utilizar un <i>tiddler JSON</i>. Deben
ser de tipo <code>application/json</code>.</dd>
</dl>

<p>
Para acceder a los datos mediante transclusión en lugar de utilizar la
notación <code>!!</code> se debe utilizar la notación <code>##</code>, es decir, obtendríamos el
valor con el siguiente formato: <code>{{TituloTiddler##índice}}</code>.
</p>
</div>
</div>
<div id="outline-container-org87f729b" class="outline-3">
<h3 id="org87f729b">Widgets, macros y pragmas</h3>
<div class="outline-text-3" id="text-org87f729b">
<p>
Hasta ahora has leído varias veces los términos <i>widget</i> y <i>macro</i>.
Posiblemente no sepas muy bien a qué me refiero o para qué sirven,
pero para explicarlo mejor, necesito también hablar un poco sobre los
<i>pragmas</i>. Los <i>pragmas</i> son las estructuras que nos sirven para definir
nuestros propios <i>widgets</i> y <i>macros</i>. Su uso es bastante avanzado ya y no
son necesarios, a no ser que quieras ampliar la funcionalidad de
<i>TiddlyWiki</i> o adecuarlo para alguna tarea en concreto, más allá del
simple hecho de almacenar y mostrar información. Lo veremos con un
par de ejemplos. En ellos crearemos un par de <i>macros</i>, aún no se me ha
dado el caso de necesitar crear un <i>widget</i>. Hay una larga lista de
ellos para infinidad de tareas.
</p>

<p>
Todas las salidas se deben hacer a texto. Las más avanzadas vienen con
sus correspondientes etiquetas <code>HTML</code> que ayuden a dar formato a dicho
texto.
</p>

<p>
Los <b>widgets</b> guardan cierto parecido a las etiquetas <i>HTML</i>. Tienen
etiqueta de inicio y de final, para distinguirse de las etiquetas
<i>HTML</i> a primera vista, utiliza la notación <code>&lt;$etiqueta&gt;</code> y su
correspondiente cierre <code>&lt;/$etiqueta&gt;</code>. Hay <i>widgets</i> para un montón de
funciones, te permiten mostrar imágenes, botones, llamar a <i>macros</i>,
transcluir texto de cualquier otro sitio, etc.
</p>

<p>
Se pueden definir tus propios <i>widgets</i> utilizando el <i>pragma</i> <code>\widget</code>,
pero es bastante más habitual definir <i>macros</i>. En el <i>wiki</i> de ejemplo,
hay varios ejemplos en el <i>plugin Básico</i>, que he creado para mostrar
algunas características de <i>TiddlyWiki</i>. Observemos el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-nil">\procedure .posit(text, cont)
  &lt;span id="posit"&gt;
    &lt;$transclude $tiddler="$:/core/images/quote" size="0.85em"/&gt; &lt;&lt;text&gt;&gt;
    &lt;div class="posit"&gt;
      &lt;&lt;cont&gt;&gt;
    &lt;/div&gt;
  &lt;/span&gt;
\end

\procedure posit(texto:"", contenido:"")
  &lt;$transclude $variable=".posit" text=&lt;&lt;texto&gt;&gt; cont=&lt;&lt;contenido&gt;&gt;/&gt;
\end
</pre>
</div>

<p>
Se definen dos macros. El primero, con nombre <code>.posit</code> recibe dos
parámetros <code>text</code> y <code>cont</code>. Como vemos en el cuerpo de dicho macro se
define mediante el <i>pragma</i> <code>\procedure</code>. El cuerpo del mismo se extiende
hasta el <i>pragma</i> <code>\end</code>. En dicho <i>cuerpo</i> se añaden etiquetas <i>HTML</i> que se
<i>rellenan</i> con los parámetros <code>&lt;&lt;text&gt;&gt;</code> y <code>&lt;&lt;cont&gt;&gt;</code>. Cuando se llama a ese
<i>macro</i> se sustituirá la llamada por su contenido. Ese macro es auxiliar
del macro <code>posit</code> que lo llama mediante un <i>widget</i> <code>&lt;$transclude&gt;</code>.
</p>

<p>
Para visualizarse correctamente, en el propio <i>plugin</i>, se encuentra el
código <i>CSS</i> en otro <i>tiddler</i>, que le proporciona aspecto:
</p>

<div class="org-src-container">
<pre class="src src-css">  <span style="color: #6272a4;">/* </span><span style="color: #6272a4;">A&#241;ade notas emergentes visuales</span><span style="color: #6272a4;"> */</span>
<span style="color: #50fa7b; font-weight: bold;">.posit</span> {
  <span style="color: #ff79c6; font-weight: bold;">display</span>:none;
  <span style="color: #ff79c6; font-weight: bold;">padding</span>:5px;
  <span style="color: #ff79c6; font-weight: bold;">border</span>:1px solid <span style="color: #000000; background-color: #cc5;">#cc5</span>;
  <span style="color: #ff79c6; font-weight: bold;">border-radius</span>: 5px;
  <span style="color: #ff79c6; font-weight: bold;">background-color</span>:<span style="color: #000000; background-color: #ffa;">#ffa</span>;
  <span style="color: #ff79c6; font-weight: bold;">font-size</span>: 0.9em;
  <span style="color: #ff79c6; font-weight: bold;">position</span>:relative;
  <span style="color: #ff79c6; font-weight: bold;">width</span>:350px;
  <span style="color: #ff79c6; font-weight: bold;">min-height</span>:150px;
  <span style="color: #ff79c6; font-weight: bold;">max-height</span>:350px;
  <span style="color: #ff79c6; font-weight: bold;">overflow</span>:auto;
  <span style="color: #ff79c6; font-weight: bold;">z-index</span>:1;
}
<span style="color: #50fa7b; font-weight: bold;">.posit p</span>  {
  <span style="color: #ff79c6; font-weight: bold;">font-size</span>: 1em;
}
<span style="color: #6272a4;">/* </span><span style="color: #6272a4;">Al pasar el mouse por encima del div mostramos el div con la
   clase ".posit". Esta clase, tiene que estar dentro del id
   "posit" para que pueda funcionar
</span><span style="color: #6272a4;">*/</span>
<span style="color: #50fa7b; font-weight: bold;">#posit</span> {
  <span style="color: #ff79c6; font-weight: bold;">text-decoration-line</span>: none;
  <span style="color: #ff79c6; font-weight: bold;">text-decoration-style</span>: wave;
  <span style="color: #ff79c6; font-weight: bold;">background-color</span>: <span style="color: #000000; background-color: #ffa;">#ffa</span>;
}
<span style="color: #50fa7b; font-weight: bold;">#posit:hover .posit</span> {
  <span style="color: #ff79c6; font-weight: bold;">display</span>:inline-block;
  <span style="color: #ff79c6; font-weight: bold;">position</span>:absolute;
}
</pre>
</div>

<p>
Posteriormente, cuando lo llamemos tenemos que hacerlo llamando al
<i>macro</i> con dos parámetros. Cuando lo visualizamos se verá:
</p>


<figure id="orgf9b5716">
<img src="./imagenes/Captura_posit1.png" alt="Captura_posit1.png">

</figure>

<p>
Al pasar el cursor sobre la etiqueta mostrará la anotación:
</p>


<figure id="org40813f2">
<img src="./imagenes/Captura_posit2.png" alt="Captura_posit2.png">

</figure>

<p>
Otro ejemplo, es la utilización del <i>pragma</i> <code>\define</code>, que funciona de
forma similar a <code>\procedure</code>.
</p>

<div class="org-src-container">
<pre class="src src-nil">\define special-button(caption:"Click me")
  \define actions()
    &lt;$action-sendmessage $message="tm-notify" $param="GuardarDatos"/&gt;
  \end actions
  &lt;$button actions=&lt;&lt;actions&gt;&gt;&gt;
  $caption$
  &lt;/$button&gt;
\end special-button

&lt;&lt;special-button&gt;&gt;
</pre>
</div>

<p>
Si pulsamos el botón que aparece en nuestro <i>tiddler</i> nos mostrará una
notificación, como vemos en la imagen:
</p>


<figure id="orgca20a24">
<img src="./imagenes/Captura_boton_macro.png" alt="Captura_boton_macro.png">

<figcaption><span class="figure-number">Figura 8: </span>Botón de notificación en acción</figcaption>
</figure>

<p>
Una notificación es una acción que permite mostrar información
temporal o reactiva al usuario. Por ejemplo, cuando guardamos los
cambios de nuestro <i>wiki</i> suele notificárnoslo por este método.
</p>
</div>
</div>
</div>
<div id="outline-container-org878afc6" class="outline-2">
<h2 id="org878afc6">Conclusiones</h2>
<div class="outline-text-2" id="text-org878afc6">
<p>
Apenas he arañado un poco las posibilidades de tiene <i>TiddlyWiki</i>. Se
pueden hacer cosas muy complejas. En el <i>wiki</i> de muestra puedes
encontrar un pequeño <i>tiddler</i> creando un <i>macro</i> utilizando <i>JavaScript</i>
para ello.
</p>

<p>
Toda la <i>interface</i> es configurable. Hay <i>plugins</i> que nos proporcionan
<i>temas</i> para visualizar el <i>wiki</i> de otros modos:
</p>


<figure id="orge2d9ca5">
<img src="./imagenes/Captura_tema-normal.png" alt="Captura_tema-normal.png">

<figcaption><span class="figure-number">Figura 9: </span>Tema normal</figcaption>
</figure>


<figure id="org8aa427f">
<img src="./imagenes/Captura_tema-mono.png" alt="Captura_tema-mono.png">

<figcaption><span class="figure-number">Figura 10: </span>Tema mono</figcaption>
</figure>


<figure id="org05f0a32">
<img src="./imagenes/Captura_tema-ghostwriter.png" alt="Captura_tema-ghostwriter.png">

<figcaption><span class="figure-number">Figura 11: </span>Tema Gostwriter</figcaption>
</figure>


<figure id="orgbb7d63b">
<img src="./imagenes/Captura_tema-moments.png" alt="Captura_tema-moments.png">

<figcaption><span class="figure-number">Figura 12: </span>Tema Moments</figcaption>
</figure>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/tiddlywiki/index.html">tiddlywiki</a> ]]></description>
  <category><![CDATA[tiddlywiki]]></category>
  <link>https://notxor.nueva-actitud.org/2024/12/18/breve-tutorial-sobre-tiddlywiki.html</link>
  <pubDate>Wed, 18 Dec 2024 11:18:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Tareas intelectuales y toma de notas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2024-12-06</div>
<p>
Algunos me habéis hecho preguntas sobre <i>Zettelkasten</i> y las
herramientas que utilizo para tomar notas. Han sido preguntas bastante
heterogéneas y de difícil respuesta, si no se entra en detalles.
Además, se añade que tampoco soy un experto en el asunto y mis
respuestas pueden ser inexactas.  Algunas de las preguntas van
dirigidas hacia el método y otras hacia las herramientas.  También
sobre cómo usar el método o la herramienta. Y, por último también, he
tenido algunas sobre si merece la pena pagar por aplicaciones que se
ofrecen en el mercado como la <i>encarnación del método</i>.
</p>

<p>
Puesto que las preguntas van tanto sobre el método como sobre
herramientas, dividiré el contenido en dichos apartados, te puedes
saltar el que no se corresponda con tus inquietudes, aunque nunca se
sabe, lo mismo también te ayudan a ti.
</p>

<p>
Iré poniendo preguntas que me han hecho para responderlas dentro de
mi limitado conocimiento sobre el asunto.
</p>
<div id="outline-container-orgebad1b5" class="outline-2">
<h2 id="orgebad1b5">El método Zettelkasten</h2>
<div class="outline-text-2" id="text-orgebad1b5">
<p>
Ya he hablado sobre esto en varias ocasiones y quizá por eso puede dar
la impresión de que domino el tema. Algunas de las preguntas me hacen
pensar que no me he explicado correctamente sobre qué es y cómo
funciona el método de <i>tomar notas y guardarlas en una caja</i>, que es lo
que significa el término alemán<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. ¿Por qué en alemán?  Pues
porque todo viene de un método muy personal que utilizaba el que
demostró ser el sociólogo más productivo hasta la fecha: el alemán
<i>Niklas Luhmann</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. Este hombre, con su método, publicó 50 libros y
cientos de artículos, dejando a su muerte más de 150 borradores
inacabados. Lo que le hace ser considerado el autor más prolífico de
la historia de la Sociología.
</p>

<p>
Una vez descubierto su método de trabajo, la propia universidad donde
ejerció de catedrático ha empleado mucho tiempo en analizarlo y ha
dado acceso al archivo de Luhmann<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>. Poco a poco, dicho método se
ha ido extendiendo de boca a oreja y aparecen defensores –y también
detractores– debajo de cada piedra que levantes en la Internet en
sitios dedicados a productividad y herramientas. Hay gente que afirma
que les funciona y otra que afirma que no. Los defensores argumentan
que si no te funciona es porque quizá no lo estás empleando bien y los
detractores que dicen que sí, pero que no merece la pena el esfuerzo.
</p>

<p>
Yendo al grano, los dos principios básicos del sistema son muy
sencillos:
</p>

<ol class="org-ol">
<li><i>Principio de atomicidad</i>: consiste en que cada nota exprese una
idea.<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup></li>
<li><i>Principio de enlace</i>: consiste en que las notas están relacionadas
mediante enlaces entre ellas.</li>
</ol>

<p>
¿Sencillo? Sí, pero se olvidan de un aspecto aún más importante y que
la gente suele pasar por alto: la <b>dedicación y el tiempo</b> que se deben
emplear para que tu <i>archivo</i> sea verdaderamente útil.
</p>

<p>
Durante su carrera, Luhmann, llegó a almacenar más de 60.000 fichas de
tamaño A6. En realidad, llevaba <b>dos ficheros</b>: uno <b>bibliográfico</b> con
referencias y notas breves sobre el contenido bibliográfico y otro, el
<b>principal</b>, donde guardaba las ideas y las relaciones entre las mismas.
A partir del mismo fichero de Luhmann nos encontraremos que los
defensores afirman que el método funciona, a Luhmann le funcionó y los
detractores dicen que no especialmente, nadie ha podido generar nada
nuevo a partir del archivo del autor  que conserva la universidad.
</p>

<p>
¿Cómo lo hago yo? ¿Estoy utilizando el método? Pues no y sí. Es decir,
el archivo llega un momento que debe alcanzar <i>una masa crítica</i> en la
que comience a hacer su magia. Pero su magia es muy personal, porque
no puedes sacar nada de donde no has metido antes. ¿Qué es lo que
metes? No estás introduciendo sólo información, estás introduciendo
<i>conocimiento</i>. Las ideas sueltas no sirven de mucho, son las relaciones
entre ellas las que generan conocimiento.  Por tanto, montar <i>tu
archivo</i> es un ejercicio intelectual que posteriormente funcionará
ayudándote a descargar tu mente de las tareas habituales porque ya las
has hecho antes... con la ventaja adicional de que <i>las fichas</i> no
olvidan nada.
</p>

<p>
El proceso, sobre el papel, es muy sencillo: introduces ideas y cómo
se relacionan entre ellas, mediante tus fichas y los enlaces, y cuando
decides escribir o repensar algún tema, tiras de las fichas de cuando
ya lo habías pensaste. Si no lo has pensado con antelación, has usado
el método del corta-pega o copiado directamente alguna idea que no has
entendido, el método no te funcionará. Por eso, los consejos son muy
sencillos:
</p>

<ol class="org-ol">
<li>Toma notas de todo, a ser posible escribiendo a mano<sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>.</li>
<li>Lo importante no es guardar sólo el contenido de la idea que te ha
generado, lo importante es cómo lo relacionas con el conocimiento
que ya tienes. Deberías tener en cuenta si la idea corrobora o
contradice a alguna otra que ya tengas, la cercanía o distancia de
ambas ideas, etc. Para esto está el principio de <i>atomicidad</i>, cada
ficha representa una idea.</li>
<li>De nada sirve una idea aislada que se puede quedar en el fondo del
cajón para siempre sin volver a salir. Tienes que asegurarte de que
eres capaz de alcanzar, de algún modo dicha idea cuando abras el
cajón. Para sirve el principio de <i>enlace</i>.</li>
</ol>

<p>
Podemos distinguir también tres tipos de notas según su temporalidad
o ciclo de vida:
</p>

<ol class="org-ol">
<li><i>Las notas temporales</i> son recordatorios de información, en uno o dos
días terminarán en la papelera.</li>
<li><i>Las notas permanentes</i> son aquellas que contienen una idea que se
mantendrá de manera más o menos permanente<sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup> y se guardarán para
siempre en el archivo.</li>
<li><i>Las notas de proyecto</i> son aquellas que son relevantes durante la
realización de algún tipo de tarea o proyecto y que al finalizar
pueden pasar a ser permanentes o a ser descartadas.</li>
</ol>

<p>
Habría un cuarto tipo de notas, <i>las notas de enlace</i><sup><a id="fnr.7" class="footref" href="#fn.7" role="doc-backlink">7</a></sup>, que son
necesarias si tu archivo está formado por tarjetas físicas guardadas
en cajas. Estas notas consisten en aportar enlaces, por ejemplo, para
agrupar una lista de notas dispersas por el archivador y que
aglutinarían un tema, o para enlazar una nota con la que
correspondería ir a continuación, pero que físicamente es imposible
por razones de espacio u otras limitaciones que estén juntas. Si
utilizas alguna aplicación o medio electrónico para llevar el
registro, estas notas se pueden obviar.
</p>

<p>
¿Por qué le funcionaba a Luhmann y a mí no? El trabajo intelectual del
amigo Niklas, estaba descargado sobre su valioso fichero. Todos los
días leía, tomaba notas, las clasificaba, ordenaba y enlazaba buscando
relaciones entre ellas, intentando acomodarlas en su estructura
mental, cuyo reflejo era su archivo físico. Al escribirlo y guardarlo
lo fijaba en la memoria y además podía dejar de gastar energía en
recordarlo, porque lo conservaba, si necesitaba algún dato concreto
podía volver a leer la tarjeta que escribió y así descargar su mente.
Mantener algo en la <b>memoria a corto plazo</b> es un ejercicio bastante
agotador, sólo tienes que pensar en aquellas ocasiones en que vas a
comprar algo en la tienda, y te vas repitiendo la lista, <b>es
información desechable</b>, mentalmente: confías en la repetición, no en
tu memoria. Sin embargo, al escribir la nota y guardarla estás dando a
esa información la suficiente relevancia como para que pase a <b>la
memoria a largo plazo</b> y se fije en ella. En la memoria a largo plazo
no se guardan datos puros aislados, para que se fijen tienen que estar
relacionados con lo que ya tenemos almacenado allí, es decir, se forma
y <b>es conocimiento, no mera información</b>. Es posible que te aprendas una
lista de números para algo en concreto, pero si esa lista no se
relaciona con algo, los olvidarás más temprano que tarde.
</p>

<p>
Otro de los motivos para que el archivo no termine de alcanzar la masa
crítica en la que comienza a ser efectivo es la costumbre que tenemos
y desarrollamos desde nuestra edad escolar a <i>compartimentar temas</i>. El
conocimiento que hemos adquirido no está en compartimentos o
almacenajes distintos en nuestra mollera, está todo mezclado y unido
formando nuestro <i>cuerpo de conocimiento</i>.  Si no se mezcla y une a
nuestra mente una idea resulta mucho más difícil hacer que quede
fijada en la memoria a largo plazo. Pero en la escuela nos enseñan a
guardar los contenidos de matemáticas separados de los de física o
lengua, como si los físicos no usaran las matemáticas para sus cosas
ni utilizaran la lengua para expresarse. La separación no genera
conocimiento, sólo consigue que tengamos un montón de ideas
inconexas. Si no funciona en tu mente, ¿por qué debería hacerlo fuera
de ella?
</p>

<p>
Otra de las preguntas que ha aparecido varias veces: ¿Qué forma tiene
una nota? ¿Qué debo apuntar? Pues depende de qué herramienta estés
utilizando para tu archivo personal. Especialmente si es físico,
porque dependerá del tipo de tarjetas y fichero que utilices. Si es
digital, dependerá de la herramienta que utilices para gestionar tu
fichero. Para hacernos una idea general, vamos a pensar en una nota,
como si fuera una tarjeta física. Veamos un pequeño esquema de su
distribución física:
</p>


<figure id="orgaeaf515">
<img src="./imagenes/nota.svg" alt="nota.svg" class="org-svg">

</figure>

<p>
Podemos observar tres tipos de información en esa hipotética ficha de
nuestro archivo:
</p>

<ol class="org-ol">
<li><b>Identificación</b>: Cada ficha debe tener un identificador único.
Luhmann utilizaba un sistema de numeración que mezclaba letras
dígitos y signos de puntuación como la coma (<code>,</code>) o la barra (<code>/</code>) para
formar cadenas estilo <code>22a1,1</code>. Al hacer el archivado físico
almacenaba las notas relacionadas unas junto a otras físicamente y
las iba numerando, pero cuando aparecía una nota que debía ir tras
la <code>22</code> y ya existía previamente una nota <code>23</code>, la numeraba como <code>22a</code> y
la metía entre ambas, pudiendo crear así una gran ramificación de
temas y subtemas.  Con medios electrónicos el identificador puede
ser cualquiera, siempre que sea único. Bastantes programas y
sistemas recurren a establecer una cadena a partir de la fecha y
hora de la creación de la nota o a utilizar <code>UUID</code> o una combinación
de ambas.<sup><a id="fnr.8" class="footref" href="#fn.8" role="doc-backlink">8</a></sup></li>
<li><b>Nota</b>: la parte principal de la nota está destinada a albergar la
idea central de la misma. Se debe redactar con tus propias palabras
y debe ser lo más breve posible, manteniendo la completa
información. Como <i>prueba de fuego</i>: si comprendo algo puedo
expresarlo de manera sencilla y completa, si no soy capaz de
resumirlo, no lo he entendido lo suficientemente bien. Si necesito
darle vueltas es mejor darlas en la cabeza y que la nota vaya
redactada de manera que no me obligue a pensar, cuando la lea, qué
quise decir, en lugar de poder leerla directamente y ya. No es raro
que también puedas enlazar en el cuerpo otras notas relacionadas.</li>
<li><b>Referencias</b>: El otro pilar del método Zettelkasten es la relación
entre las anotaciones. En la parte inferior de nuestra ficha
debemos anotar las otras notas que tienen relación con ésta, cuáles
enlazan con ella. En el espacio de la nota ya podemos haber
enlazado otras notas a las que ésta haga referencia, pero en este
apartado deberían situarse enlaces a las notas que hacen referencia
a ésta. Por supuesto, también se pondrán en este apartado las
referencias bibliográficas, que sean necesarias.</li>
</ol>

<p>
¿Cómo encuentro y reúno la bibliografía? En realidad, como dije antes,
Luhmann tenía dos archivos o <i>zettekasten</i>, uno con las notas y
referencias bibliográficas, y otro el general que ya venimos
conociendo.
</p>

<p>
¿Y luego qué? Pues si ya tomas nota de todo y no consigues hacerlo
funcionar replanteate si estás tomándolas para recordar o para generar
conocimiento. Tomar nota de todo no sirve de nada, si no hay un
trabajo de elaboración posterior. De nada sirve anotar algo para no
olvidarlo, si luego no lo vuelves a leer. Puedes llenar cuadernos y
cuadernos, agendas y/o servilletas, con todas las ideas habidas y por
haber, que para lo único que servirán es para manchar el papel.  El
método se centra, no en el procedimiento de guardar notas, sino en el
proceso de reflexionar sobre las ideas y cómo éstas se acomodarán
dentro de nuestro <i>cuerpo de conocimiento</i>.
</p>

<p>
Tomar notas, se convierte así, en <b>la tarea intelectual fundamental</b>, no
sólo es escribir, es redactar con las palabras justas, pensar sobre el
contenido, reflexionar sobre la idea que queremos anotar y ver cómo
encaja en nuestro conocimiento. Según vayamos encajando ideas en él,
es posible que éstas cambien o se maticen, respecto a su significado o
respecto a las relaciones entre ellas. Por lo que deberemos modificar
las anotaciones, eliminar referencias o añadirlas según nuestro
conocimiento, y con él nuestro archivo, haciendo que crezca y se vaya
afinando.
</p>
</div>
</div>
<div id="outline-container-org853fdc2" class="outline-2">
<h2 id="org853fdc2">Las herramientas</h2>
<div class="outline-text-2" id="text-org853fdc2">
<p>
Puesto que estamos hablando de una técnica que lleva unos años en boca
de todos –y podríamos decir que se ha puesto de moda–, han ido
apareciendo varias herramientas para tomar notas dirigidas
expresamente a utilizar dicho método o, cuando menos, se anuncian
compatibles con el mismo.
</p>

<p>
¿Qué necesito? Pues si tienes sitio en casa y te gusta escribir a
mano, necesitarás papel para las notas, bolígrafo para escribirlas y
algún sistema de cajones o cajas donde guardar la fichas físicas...
Pero supongo que a estas alturas la pregunta se refiere a programas,
aplicaciones o sistemas informáticos en general.
</p>

<p>
Como decía antes hay un montón de programas específicos y/o
compatibles con el <i>método zettelkasten</i>. Algunos son de pago otro son
libres. Elegir es tan complicado como elegir cualquier otra cosa y
además entran los gustos y ataduras personales que suelen sesgar todas
nuestras decisiones sobre tecnología:
</p>

<ol class="org-ol">
<li>¿Tiene que ser software libre o no?</li>
<li>¿Tengo reparo a las ventanas negras con letras blancas o no?</li>
<li>¿Lo voy a usar desde un único dispositivo o desde varios?</li>
<li>¿Para qué sistema operativo lo necesito? ¿Pueden ser varios?</li>
<li>¿Necesito acceso <i>online</i> u <i>offline</i>?</li>
</ol>
</div>
<div id="outline-container-org6e15556" class="outline-3">
<h3 id="org6e15556">Lo que yo utilizo</h3>
<div class="outline-text-3" id="text-org6e15556">
<p>
Mi consejo general es que guardes tus anotaciones en archivos de texto
plano, a ser posible, con algo de formato que te permita enlazar
sintácticamente con otras notas. Es lo que hago y para ello utilizo
<i>Emacs</i>, concretamente <a href="https://github.com/kaorahi/howm">el paquete de notas howm</a>. He utilizado y hablado
en este <i>blog</i> sobre otros paquetes. El texto plano tiene la ventaja de
que si el <i>software</i> que estás utilizando, por lo que sea, deja de
funcionar, mantienes toda tu información accesible a una infinidad de
herramientas con las que puedes abrir los archivos, modificarlos,
guardarlos o convertirlos entre formatos cuando decides cambiar la
herramienta.
</p>

<p>
Para no hablar en abstracto, y ver cómo lo trabajo yo, permitidme un
pequeño ejemplo tomado de <i>mi vida profesional</i>, por si te sirve de
orientación.  Hace unos meses me ofrecieron encargarme de un curso de
formación para una empresa que tratara sobre el <i>conflicto y la
negociación</i> en el ámbito laboral, especialmente a las relaciones
personales entre compañeros y también entre cliente-trabajador y no en
cuanto a conflictividad sindical, que es otra historia. Al recurrir a
mi archivo de notas veo que la mayoría de la información ya la tengo
más o menos localizada y con un par de consultas puedo establecer un
hilo de ideas que puede cubrir todo el contenido solicitado.
</p>

<p>
La redacción del contenido, como casi toda documentación que genero,
irá en \(\LaTeX\). Mis notas bibliográficas las guardo aparte en un
archivo que se llama <code>referencias.bib</code> con el formato adecuado para
crear bibliografías en \(\LaTeX\). En este sentido, lo tengo como el
propio Luhmann, tengo un archivo general con notas y referencias
bibliográficas y luego tengo mis anotaciones. Puesto que los archivos
<code>.bib</code> son texto plano con formato, lo puedo abrir con el propio editor
y añadir, modificar y gestionar toda la base de datos bibliográfica.
Aunque es cierto que a veces utilizo <a href="https://www.jabref.org/">JabRef</a> para gestionarlo de manera
más gráfica y/o tener una idea más clara cuando quiero echar sólo un
vistazo a parte de la información que el archivo tiene.
</p>

<p>
El archivo general está situado en un directorio <code>~/Notas</code> con varios
subdirectorios y con cientos de archivos de texto plano (<code>.txt</code>, <code>.md</code> y
<code>.org</code>). En dicha base de datos cada «subdirectorio» se refiere a un
<i>proyecto</i> y contiene las notas para documentar algún proyecto personal
o profesional. Habiendo sido <i>notas de proyecto</i>, después, me ha
parecido oportuno conservar algunas en el conjunto general de mis
anotaciones, desechando el resto.
</p>

<p>
Para algunos usuarios de <i>Emacs</i> ya he hablado en suficientes ocasiones
en este <i>blog</i> sobre tomar notas y no creo que haga falta más
aclaraciones sobre ello. También he hablado de ello otras veces y hay
prueba fehaciente en el canal de <a href="https://hispa-emacs.org/">hispa-emacs</a> en <code>fediverse.tv</code>:
</p>

<iframe title="Tomando Notas con Emacs  ~ encuentro/taller" width="560" height="315" src="https://fediverse.tv/videos/embed/5e1d1439-defc-416f-9ef8-5e485c45a3e2" frameborder="0" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups"></iframe>
</div>
</div>
<div id="outline-container-org42abb38" class="outline-3">
<h3 id="org42abb38">Lo que puedes utilizar</h3>
<div class="outline-text-3" id="text-org42abb38">
<p>
Puedes utilizar lo mismo que yo, sin duda, para mí, es la mejor
solución. Pero me preguntas por herramientas y no quieres oír
alabanzas a <i>Linux</i> y loas a <i>Emacs</i>. Dices que quieres utilizar algo
sencillo, según tú, y fácil de usar, según tú. Pues te recuerdo que
<i>Linux</i> hace fácil las cosas fáciles y difíciles las cosas difíciles, el
<i>güindón</i> del <i>Billy Puertas</i> hace fáciles las cosas fáciles e imposibles
las difíciles, pero es a lo que te han acostumbrado. No usas para nada
la consola y todo tiene que ir manejado por ventanitas. Nada de
\(\LaTeX\), quieres <i>office</i>... bien, pues estas limitaciones me llevan a
recomendar otros programas, ya perdonarás si todas las recomendaciones
que hago se refieren a software libre, es algo que ya tengo alojado en
las tripas y va a ser complicado que me saquen de ahí.
</p>
</div>
<div id="outline-container-orgd5b3e18" class="outline-4">
<h4 id="orgd5b3e18">Para el archivo bibliográfico</h4>
<div class="outline-text-4" id="text-orgd5b3e18">
<p>
Como dije antes, me apaño bastante bien escribiendo las referencias
bibliográficas en un archivo <code>.bib</code> que puedo enlazar directamente con
el documento que genere. Y también mencioné que a veces utilizaba la
aplicación <a href="https://jabref.org">JabRef</a> cuando quería hacerlo de manera más visual. Esta
aplicación la recomiendo, además de interacción con varios editores
–entre ellos <i>Emacs</i>, pero varios más–, provee soporte para otro tipo de
herramientas como <i>LibreOffice/OpenOffice</i> y también el <i>güor</i> de
<i>Micro$oft</i>.
</p>

<p>
Otra aplicación a tener en cuenta, especialmente si manejas mucha
documentación en <code>pdf</code> y otros formatos, o necesitas gestionar
documentos adjuntos, anotaciones, resúmenes, o enlazar unas
referencias con otras es <a href="https://www.zotero.org/">Zotero</a>. Zotero no es <i>software libre</i> es <i>Open
Source</i>. Proporciona almacenamiento (de pago) en la red, pero también
lo puedes descargar y utilizarlo de manera local para tu archivo
bibliográfico. Permite también mantener y visualizar archivos adjuntos
<code>pdf</code>, <code>epub</code> y demás. Exportar información lo puede hacer a un montón de
formatos también: además del <code>RDF</code> propio de Zotero, puede hacerlo <code>bib</code>,
a <code>csv</code> o <code>json</code>, por poner algunos ejemplos.
</p>

<p>
Tanto <i>JabRef</i> como <i>Zotero</i> son buenas herramientas y te facilitan la
vida a la hora de generar bibliografías. La elección de una u otra
dependerá de en qué vas a escribir. Si vas a utilizar un paquete de
<i>Office</i> es más recomendable la segunda, pero si vas a utilizar
\(\LaTeX\), a mi modo de ver sería más recomendable la primera.  Pero,
también está sujeto a subjetividades.
</p>
</div>
</div>
<div id="outline-container-orgb98816a" class="outline-4">
<h4 id="orgb98816a">Para el archivo general</h4>
<div class="outline-text-4" id="text-orgb98816a">
<p>
Como dije antes, el único requisito de la herramienta es que puedas
enlazar las notas entre ellas. Hay herramientas enfocadas a la toma de
notas: <a href="https://evernote.com/es-es">evernote</a>, <a href="https://obsidian.md/">obsidian</a>, <a href="https://roamresearch.com/">Roam</a> y una infinidad de herramientas más.
Como digo, si lo importante es poder enlazar las notas entre sí,
también te servirá cualquier herramienta que te permita hacerlo, como
cualquier <i>wiki</i>. Podrías utilizar cosas como <a href="https://zim-wiki.org/index.html">Zim</a>, <a href="https://www.dokuwiki.org/es:dokuwiki">DokuWiki</a> o <a href="https://tiddlywiki.com/languages/es-ES/index.html">TiddlyWiki</a>
o como digo, cualquiera, de los cualquiera sistemas de <i>Wiki</i> que hay
por el mundo, incluyendo los wikis que te proporcionan herramientas
como <code>gitea</code>, <code>github</code>, <code>codebert</code>, <code>gitlab</code> o cualquier repositorio <code>fossil</code>.
De hecho en su día me planté la opción de escribir archivos <code>html</code>
haciendo <i>a mano</i> las funciones de <i>wiki</i>, pero no merece la pena el
esfuerzo, contando con herramientas que lo facilitan.
</p>

<p>
<i>DokuWiki</i> es una buena herramienta, sólo necesitas un navegador para
acceder a ella. El problema es que necesitas montarlo en un servidor
que esté alcanzable en la red.  Si ya tienes uno, por ejemplo, para tu
página <i>web</i> no te llevará mucho tiempo porque no necesitas montar una
base de datos y la instalación es sencilla. Sin embargo, está abierto
a la red. Cuando lo usé para temas personales, limitando el acceso
mediante usuario y contraseña, llegué a estar aburrido de borrar
intentos de acceso ilegítimos, inyección de código <i>SQL</i>, etc.
</p>

<p>
Si me preguntas a mí, te recomendaría <i>TiddlyWiki</i>, ¿por qué?:
</p>

<ol class="org-ol">
<li>Es un <i>wiki</i> personal, podrá acceder a él quien pueda acceder a tus
archivos. Pero lo puedes sincronizar en cualquier herramienta de
<i>nube</i> que utilices: NextCloud, Dropbox, Mega...<sup><a id="fnr.9" class="footref" href="#fn.9" role="doc-backlink">9</a></sup></li>
<li>Está todo encapsulado en un archivo <code>.html</code>, tanto el código
<i>javascript</i> como los datos.</li>
<li>Tiene muchas opciones y lo puedes ampliar si quieres: es software
libre, es tuyo y no de una empresa.</li>
<li>Puedes crear tus propias plantillas de toma de datos.</li>
<li>No necesitas montar un servidor para utilizarlo.</li>
<li>Tampoco necesitas ningún software para acceder a él. Lo puedes
abrir con cualquier navegador web.</li>
<li>Puedes cifrar el contenido y acceder con contraseña para proteger
aún más tus pensamientos.</li>
<li>Tiene un sistema de búsqueda interno muy bueno: rápido y con
garantías.</li>
<li>Te permite crear tarjetas, completamente interactivas, que
contengan otras tarjetas ordenadas en listas, pestañas o tablas que
permiten tener de un vistazo toda la información relacionada con un
asunto.</li>
<li>Tiene un sistema de filtros muy potente que junto con <code>macros</code>
permite crear tarjetas con listados de otras tarjetas o de
cualquier contenido <code>json</code> y que el visualizado se actualice de
manera automática<sup><a id="fnr.10" class="footref" href="#fn.10" role="doc-backlink">10</a></sup> igual que se actualizan las celdas
relacionadas de una hoja de cálculo.</li>
<li><a href="https://f-droid.org/es/packages/top.donmor.tiddloid/">Hay aplicación para Android®</a> y si tienes tus archivos
sincronizados mediante nube o cualquier otro medio, puedes
trabajar con casi cualquier dispositivo que tengas a mano.</li>
</ol>

<p>
Por supuesto, tiene algunos inconvenientes. Por ejemplo, si lo
utilizas desde tu navegador web, no podrás guardar cambios. Al darle a
guardar, lo que hará será «descargarte» una copia en tu directorio de
«descargas». Como sabes, el navegador bloquea que el javascript
modifique archivos locales por seguridad. Si lo quieres utilizar como
una aplicación de escritorio normal, tendrás que descargar el programa
<i>TiddlyDesktop</i> y abrir los <i>wikis</i> con él.
</p>

<p>
Otro problema es el formato. En otras herramientas se utiliza un tipo
de marcado más estándar como <i>MarkDown</i>, u <code>org-mode</code>, que pueden
convertirse a un montón de formatos de texto. Sin embargo, en
<i>TiddlyWiki</i> el formato es propio, aunque muy parecido al <a href="https://en.wikipedia.org/wiki/Creole_(markup)">creole</a>. La
conversión directa a otros formatos se complica. Aunque te queda la
opción de exportar las tarjetas a <code>HTML</code> y desde ahí a otros formatos.
</p>
</div>
</div>
</div>
</div>
<div id="outline-container-org5534dad" class="outline-2">
<h2 id="org5534dad">Conclusiones</h2>
<div class="outline-text-2" id="text-org5534dad">
<p>
Según se desprende del trabajo de Luhmann, la toma de notas es una
actividad más importante de lo que suponemos cuando nos enseñan a
hacerlo siendo niños.  Hay que prestarle una dedicación especial que
pocas veces tenemos en cuenta. Lo que he visto con respecto al
<i>Zettelkasten</i> es que hay, en general, una tendencia a quedarse en la
superficie, en el proceso de la escritura y se obvia el proceso
importante que es cómo se relaciona la nota que estamos escribiendo
con todo nuestro conocimiento anterior. Si tenemos dificultad para
situar una nota en nuestra <i>caja</i>, lo mismo es porque no hemos terminado
de entender bien la idea o no sabemos cómo se relaciona con otras
ideas que ya conocemos. En este caso, la idea puede quedar aislada e
inaccesible desde otras.
</p>

<p>
Y recuerda que no necesitas pagar o comprar nada para ponerlo en
marcha. Todo está a tu alcance y necesita tan sólo un poco de ingenio,
no de ingeniería, personal.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Zettelkasten</i> significa literalmente <b>caja de notas</b>, lo que en
español llamamos <b>fichero</b>.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Catedrático en la Universidad de Bielefeld. Reconocido
académicamente por su formulación de la teoría general de los sistemas
sociales.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Los curiosos podéis acceder al fichero o <i>zettelkasten</i> de
Luhmann y cotillear ficha por ficha –o <i>zettel</i> por <i>zettel</i> – en la
dirección de internet:
<a href="https://niklas-luhmann-archiv.de/bestand/zettelkasten/zettel/ZK_1_NB_1_1_V">https://niklas-luhmann-archiv.de/bestand/zettelkasten/zettel/ZK_1_NB_1_1_V</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Por eso el tamaño de las fichas debe ser pequeño: expresar una
sola idea, lo más resumidamente que puedas y con tus propias palabras,
para que entre en el espacio de una ficha. Si utilizas algún tipo de
<i>software</i> el límite sería lo que quepa en un vistazo de pantalla.
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Hay bastantes estudios realizados que determinan un mejor
desempeño de las notas tomadas con papel y bolígrafo sobre las notas
realizadas mediante teclado y pantalla.
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Tus ideas pueden evolucionar y cambiar con el tiempo, pueden
aparecer nuevas conexiones y/o perder otras. Se pueden matizar o
necesitar más explicación, etc.
</p></div></div>

<div class="footdef"><sup><a id="fn.7" class="footnum" href="#fnr.7" role="doc-backlink">7</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
La información de estas notas no está referida a contenido,
sino a soporte estructural del archivo y por eso las nombro aparte. 
</p></div></div>

<div class="footdef"><sup><a id="fn.8" class="footnum" href="#fnr.8" role="doc-backlink">8</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En este punto, creo que utilizar un sistema en donde el
identificador lo debas generar tú y no la máquina, también te ayudará
a situar las ideas con respecto a otras. Sin embargo, la comodidad de
hacer <i>click</i> es muy tentadora. 
</p></div></div>

<div class="footdef"><sup><a id="fn.9" class="footnum" href="#fnr.9" role="doc-backlink">9</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Sí también por las cosas esas de <i>gúguel</i>, el <i>micro$oft</i> y el
<i>amazon web services</i> que utiliza la mayoría de la gente.
</p></div></div>

<div class="footdef"><sup><a id="fn.10" class="footnum" href="#fnr.10" role="doc-backlink">10</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Por ejemplo, tengo un <i>wiki</i> para llevar referencia de mis
facturas. Guardo la información de clientes y enlazo a las facturas en
<code>pdf</code>. Cuando marco la tarjeta de una factura como «pagada» desaparece
automáticamente del listado de «pendientes» de cobro.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/zettelkasten/index.html">zettelkasten</a> <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/tiddlywiki/index.html">tiddlywiki</a> <a href="/tags/zotero/index.html">zotero</a> ]]></description>
  <category><![CDATA[zettelkasten]]></category>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[tiddlywiki]]></category>
  <category><![CDATA[zotero]]></category>
  <link>https://notxor.nueva-actitud.org/2024/12/06/tareas-intelectuales-y-toma-de-notas.html</link>
  <pubDate>Fri, 06 Dec 2024 15:02:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Resumen de mis últimas herramientas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2024-11-10</div>
<p>
Llevo unos días alejado un poco de las tareas del <i>blog</i>, pero no por
gusto.  Ciertos problemas de salud me han impedido escribir y ya lo
echaba de menos. El artículo de hoy viene a resumir un poco las cosas
que vengo haciendo últimamente. Con el amigo Fénix de <a href="https://hispa-emacs.org/">Hispa Emacs</a> ya
estuvimos hablando un poco sobre estas cosas y después de ese par de
charlas decidí dedicar una entrada del <i>blog</i> a explicar un poco más
detenidamente estas cosas.
</p>

<p>
Son cosas que podríamos pensar que están deslavazadas, sin embargo,
están más unidas de lo que parece. Un buen amigo se refiere a este
conjunto de útiles como <i>la secta</i>. Sin embargo, para los proyectos que
tengo en mente, se ajustan muy bien.
</p>

<p>
El último personal, de hace unos pocos días, es un proyecto cuyo
principal objetivo es obligarme a aprender vocabulario informático en
<i>Esperanto</i>. Me da mucha rabia cuando me preguntan sobre algún aspecto
informático en esa lengua y me faltan las palabras para expresar lo
que quiero de una manera clara y rápida. Siempre tengo que echar mano
de expresiones y vueltas lingüísticas que ofuscan, más que aclaran, lo
que quiero decir. Para ello, he comenzado un proyecto de programación
de un <i>raytracer</i>, como el que ya hice en <i>erlang</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. En este caso,
para no tener repetido el contenido de los <i>raytracer</i>, lo situé en un
repositorio externo de las siguientes características:
</p>

<ul class="org-ul">
<li>Repositorio <code>fossil-scm</code> en un lugar público.
<a href="https://chiselapp.com/user/Notxor/repository/tclray/index">Este repositorio es público</a> y se puede cacharrear por allí si
quieres. El idioma de desarrollo es el <i>Esperanto</i>, por lo que si no
controlas dicha lengua se te hará un poco difícil seguir las
explicaciones.</li>
<li>Tcl/Tk es un lenguaje de programación del que ya he hablado en
varias ocasiones. En este caso, me interesa aprender todo lo
referente a la <span id="nota">/POO/<span class="nota">Programación Orientada a Objetos.</span></span> con
él y también el tema de aplicaciones multihilo y, por último, sobre
la posibilidad de expandirlo utilizando librearías C/C++ externas.</li>
<li><i>Pikchr</i>: la mayoría de las imágenes para explicaciones las realizaré
con este lenguaje de descripción de esquemas. El motivo principal es
que está embebido en la propia herramienta de <code>fossil</code> y por tanto lo
tengo muy a mano.</li>
</ul>
<div id="outline-container-org38cc9a5" class="outline-2">
<h2 id="org38cc9a5">Fossil-scm</h2>
<div class="outline-text-2" id="text-org38cc9a5">
<p>
Fossil-scm es una herramienta de control de versiones creada para la
gestión del código de <i>SQLite</i> por el mismo creador de <i>SQLite</i>. Como
sabéis <i>SQLite</i> nació inicialmente para proporcionar una herramienta de
bases de datos a los usuarios de Tcl/Tk. De <i>la secta</i>, como lo llama mi
colega, es el <i>chismático</i> más exitoso. A estas alturas es conocido por
todos y una de las librerías más descargadas. Puedes encontrar
<i>SQLite</i> en casi cualquier sitio, para usos muy diversos. Por ejemplo,
un repositorio <code>.fossil</code> es un archivo <i>SQLite</i>, que se despliega desde el
ejecutable <code>fossil</code>.
</p>


<figure id="orgb6e655e">
<img src="./imagenes/Captura-archivos.png" alt="Captura-archivos.png">

</figure>

<p>
Ya he contado más veces en este <i>blog</i> que el repositorio lleva
incorporadas algunas herramientas útiles para los equipos de trabajo:
<i>wiki</i>, gestión de errores y muchas cosas más. Para resumirlo de algún
modo sería (casi) como tener un <code>gitea</code> en el propio ejecutable <code>fossil</code> y
cada repositorio se beneficiará de esas herramientas.
</p>

<p>
Una de las cosas que descubrí recientemente es que se pueden editar
los archivos del repositorio desde el
<span id="nota">/GUI/<span class="nota">Graphical User Interface.</span></span> web de la aplicación. Tan
sólo hay que establecer qué tipo de archivos se pueden editar.
</p>


<figure id="orgfdd9a8d">
<img src="./imagenes/Captura-config.png" alt="Captura-config.png">

</figure>

<p>
También se podría establecer un editor externo para hacer la edición,
pues aunque cuenta con una herramienta interna para hacerlo, es
bastante sencilla y espartana. El repositorio, al visualizar un
archivo <code>.md</code> lo visualizará <i>renderizándolo</i> y mostrándolo como si fuera
una página web. Si hemos activado la edición, como veíamos antes, nos
aparecerá un submenú <code>Edit</code>.
</p>


<figure id="org619b96d">
<img src="./imagenes/Captura-edicion-activada.png" alt="Captura-edicion-activada.png">

</figure>

<p>
Al pulsar en <code>Edit</code> nos aparecerá el editor:
</p>


<figure id="org9e1cdf4">
<img src="./imagenes/Captura-del-editor.png" alt="Captura-del-editor.png">

</figure>

<p>
Es un editor de texto muy sencillo, aunque suficiente para escribir
<i>MarkDown</i>, permitiéndonos previsualizar los cambios. Una vez hemos
terminado con la edición, para guardar debemos hacer un <code>commit</code>.
</p>


<figure id="org6e32d79">
<img src="./imagenes/Captura-servidor-commit.png" alt="Captura-servidor-commit.png">

</figure>

<p>
La desventaja es que no es un editor potente y la ventaja principal es
que se pueden hacer modificaciones desde cualquier sitio, si el
repositorio es accesible con cualquier navegador web. Algo que me
vendrá muy bien para escribir en aquel sitio mediante la tablet, o
incluso el teléfono móvil, si, por lo que fuera, no tengo en ese
momento mi portátil a mano.
</p>
</div>
</div>
<div id="outline-container-org7b25e84" class="outline-2">
<h2 id="org7b25e84">Pikchr</h2>
<div class="outline-text-2" id="text-org7b25e84">
<p>
Ya he hablado con anterioridad en este <i>blog</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> de este lenguaje de
descripción de diagramas, que junto con <a href="https://graphviz.org/">graphviz</a>, es la herramienta
que más estoy utilizando para realizar mis gráficos.
</p>

<p>
Sabía que dentro de <code>fossil</code> se encontraba un intérprete de <code>pikchr</code>, cada
vez que se encuentra un bloque de código marcado así, visualiza el
gráfico y no el código. Lo que no sabía es que además cuenta con una
herramienta para escribir y modificar este tipo de gráficos.
</p>


<figure id="org5c420b8">
<img src="./imagenes/Captura-help.png" alt="Captura-help.png">

</figure>

<p>
Si seleccionamos el <i>sandbox</i> de <code>pickchr</code> nos aparecerá la siguiente
herramienta:
</p>


<figure id="orgdbdd95a">
<img src="./imagenes/Captura-pikshr-sandbox.png" alt="Captura-pikshr-sandbox.png">

</figure>

<p>
Esta forma de hacer diagramas ya la venía empleando para realizar
<i>genogramas</i>, algo que difícilmente se puede dibujar con <i>graphviz</i>:
</p>


<figure id="org6f1b563">
<img src="./imagenes/Captura-genogramas.png" alt="Captura-genogramas.png">

</figure>

<p>
En mi caso también, me bajé los fuentes de <a href="https://pikchr.org">su página web</a> y lo compilé
para mi máquina. Al compilar simplemente crea un ejecutable que puedes
copiar a cualquier parte de tu máquina donde lo pueda encontrar el
sistema cuando busca el ejecutable. En mi caso, lo copié a un
directorio local mío: <code>~/opt/bin</code>. Desde ese mismo momento y con la
ayuda del paquete <code>pikchr-mode</code> de <i>Emacs</i> puedo realizar mis diagramas
desde mi editor favorito e incluirlos en bloques de código dentro de
<code>org-mode</code>.
</p>
</div>
</div>
<div id="outline-container-org9abc701" class="outline-2">
<h2 id="org9abc701">Tcl/Tk</h2>
<div class="outline-text-2" id="text-org9abc701">
<p>
Cada vez me encuentro más cómodo con este lenguaje y cuando necesito
hacer un <i>script</i> se ha convertido en mi primera opción. Sin embargo,
apenas he arañado un poco la superficie haciendo un par de proyectos
antes, alguno de los cuales aún no está terminado. Por lo menos, uno
de ellos alcanzó su versión <i>alfa</i>, a la espera de que haga algunas
pruebas de <i>producción</i> que seguramente destaparán cientos de errores.
</p>

<p>
El objetivo del proyecto que conté al principio del artículo no sólo
consiste en aprender vocabulario técnico en Esperanto. También quiero
aprender más cosas sobre Tcl/Tk:
</p>

<ul class="org-ul">
<li>Su sistema de POO: <code>TclOO</code>. Hasta ahora todo lo que he hecho con este
lenguaje ha tenido un enfoque más a procedimiento o incluso en
cierto modo <i>funcional</i>. Sin embargo, quiero ver hasta qué punto me
manejaré con la POO que trae incorporada.</li>
<li>Expandir el lenguaje mediante un módulo C/C++. Al elegir el
<i>raytracer</i> la intención es que la parte de cálculos intensiva se
dirija a una librería que se programará en C/C++ para acelerar el
<i>render</i>. Quiero aprender, por tanto, a programar dicha extensión. No
sé si es fácil o difícil ni si lo lograré o no, pero me parece
interesante.</li>
<li>Aprender cómo se realizan aplicaciones <i>multihilo</i>. Aunque ya lo toqué
por encima en uno de los proyectos, me limité a levantar un servidor
que escuchaba en un puerto y además ese código lo copié de algún
otro ejemplo que encontré por la red... así que no aprendí nada.</li>
</ul>
</div>
</div>
<div id="outline-container-org318cf45" class="outline-2">
<h2 id="org318cf45">Zen browser</h2>
<div class="outline-text-2" id="text-org318cf45">
<p>
Fuera de lo que es estrictamente <i>la secta</i>, llevo un tiempo probando
con bastante asiduidad el <a href="https://zen-browser.app/">zen browser</a> como navegador de trabajo. Aún
no lo tengo como <i>navegador por defecto</i> pero no me extrañaría que en
un futuro no muy lejano lo sea.
</p>

<p>
<i>Zen</i> es un navegador que proviene de un <i>fork</i> de <i>FireFox</i> y que tiene una
serie de herramientas que mejoran la experiencia de la navegación. Por
ejemplo:
</p>


<figure id="org231a424">
<img src="./imagenes/Captura-zen-browser.png" alt="Captura-zen-browser.png">

</figure>

<p>
En esa captura podemos ver que tengo cargado el editor de texto del
repositorio <code>fossil</code> y puesto que estoy escribiendo en <i>Esperanto</i> tengo
un diccionario <i>online</i>, cargado en lo que llaman <i>Zen sidebar</i>. Esto me
facilita enormemente el trabajo sin estar saltando de pestaña a
pestaña. Como se puede ver en los botones que hay bajo el <i>sidebar</i> le
he puesto acceso a la <i>wipedia</i>, a varios diccionarios y otras páginas
de consulta habituales. No sólo está el <i>sidebar</i>, también tiene la
capacidad de distribuir distintas pestañas en la ventana de trabajo,
lo que hace que sea muy fácil tener una mitad del navegador para
buscar documentación mientras la otra parte la puedes utilizar para
cualquier otra tarea (ahora que muchas aplicaciones corren sobre web).
</p>

<p>
Aún le faltan algunas cosas por pulir. La apariencia por defecto es
muy espartana y los temas no parecen estar muy afinados. Los de
<i>FireFox</i> no funcionan, porque la estructura de la ventana es distinta.
Sin embargo, me parece mucho más acertado en cuanto a funcionalidad de
lo que está <i>FF</i>. Más en la línea de lo que podría ser <i>Opera</i> o <i>vivaldi</i>,
pero siendo un digno heredero de <i>FireFox</i> y no de <i>Chrome</i>.
</p>
</div>
</div>
<div id="outline-container-org63e6b04" class="outline-2">
<h2 id="org63e6b04">Conclusiones</h2>
<div class="outline-text-2" id="text-org63e6b04">
<p>
Después de mis problemas de salud decidí tomarme la vida con más calma
y dedicarme tiempo. La idea es no estresarme demasiado, pero
mantenerme activo lo suficiente para no aburrirme, dedicándome a cosas
que me gustan y/o me parecen interesantes. Me podría haber dado por el
ganchillo o la papiroflexia, pero no es el caso. Así que me dedicaré a
escribir más (código y otros cuentos), a leer y a traducir cosas al
<i>Esperanto</i>. 
</p>

<p>
Si alguien de los que lee esto se encuentra con ánimo, controla de
<i>Esperanto</i> y quiere ayudar o colaborar en el proyecto puede entrar en
el enlace del repositorio que puse arriba y crearse una cuenta. A
partir de ese momento podrá acceder a escribir también en el <i>foro</i> del
repositorio. A hacer comentarios y sugerencias y lo que le venga en
gana. Aunque, evidentemente, el foro estará moderado por mí.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Artículos de la serie <i>raytracer</i>:
<a href="https://notxor.nueva-actitud.org/2020/10/21/un-pequeno-raytracer.html">Un pequeño raytracer</a>, <a href="https://notxor.nueva-actitud.org/2020/10/24/trazando-rayos.html">Trazando rayos</a>, <a href="https://notxor.nueva-actitud.org/2020/11/16/rayos-y-centellas.html">Rayos y centellas</a>,
<a href="https://notxor.nueva-actitud.org/2020/11/20/material-difuso-y-correccion-gamma.html">Material difuso y corrección gamma</a>, <a href="https://notxor.nueva-actitud.org/2020/12/01/materiales.html">Materiales</a>, <a href="https://notxor.nueva-actitud.org/2020/12/06/camara.html">Cámara</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://notxor.nueva-actitud.org/2022/07/05/pikchr.html">Pikchr</a> y <a href="https://notxor.nueva-actitud.org/2024/09/30/graficos-con-pikchr.html">Gráficos con pikchr</a>.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/tcl/index.html">tcl</a> <a href="/tags/fossil/index.html">fossil</a> <a href="/tags/pikchr/index.html">pikchr</a> <a href="/tags/zen-browser/index.html">zen-browser</a> ]]></description>
  <category><![CDATA[tcl]]></category>
  <category><![CDATA[fossil]]></category>
  <category><![CDATA[pikchr]]></category>
  <category><![CDATA[zen-browser]]></category>
  <link>https://notxor.nueva-actitud.org/2024/11/10/resumen-de-mis-ultimas-herramientas.html</link>
  <pubDate>Sun, 10 Nov 2024 12:29:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[¿Preparando la NaNoWriMo?]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2024-10-06</div>
<p>
También podría haberlo titulado <i>poniéndole los cuernos a Emacs</i>, pero
no es cierto. <i>Emacs</i> sigue estando en el ajo, aunque sólo sea como
editor. Pero vamos al grano: Algunas veces hablo de mis proyectos
<i>vaporware</i> como si fueran realizables o casi. En este caso, este <i>vapor</i>
silba desde hace ya unos cuatro años. Por aquí, ya había comentado que
<a href="https://notxor.nueva-actitud.org/2024/08/25/trokola-en-version-alfa.html">trokola alcanzaba su versión alfa</a>, y quería usarlo para generar
aventuras conversacionales multijugador para utilizarlas en un <i>Plan de
Prevención del Acoso Escolar</i> que ando <i>perpetrando</i> para la Asociación
con la que colaboro como voluntario. Hecho el programa, necesito
historias que faciliten la ambientación de las <i>aventuras</i>. Y ¿cómo
consigo esas historias?  Pues no me queda más remedio que escribirlas
yo.
</p>

<p>
No me malinterpretes, me gusta escribir, si no fuera así, por qué iba
a mantener un <i>blog</i>.  Otra cosa es que lo haga bien, mal o regular.
Que supongo que irá en gustos, esto es, si tienes mal gusto a lo mejor
te gusta lo que escribo, no sé.  Hasta ahora, las cosas que he ido
escribiendo me las he ido guardando. Algunas de ellas, esas de las que
<i>el escritor</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> parece sentirse orgulloso, las he enseñado a los
amigos y allegados. Pero dicho que me gusta escribir, debería
contestar también si voy a hacer la <i>NaNoWriMo</i>, porque al menos, la
menciono en el título del artículo, y la respuesta es <b>no</b>, no voy a
meterme esa <i>pechá</i> de escribir para nada. Además no necesito una
historia larga, sino varias más cortas en las que aparezcan <i>puzles</i> y
retos que superar con un poco de inteligencia y un bastante de
colaboración de grupo.
</p>

<p>
Necesito organizarme, y de esto va hoy el artículo, de contaros cómo
me voy a apañar el trabajo.
</p>
<div id="outline-container-org48712a0" class="outline-2">
<h2 id="org48712a0">Organización</h2>
<div class="outline-text-2" id="text-org48712a0">
<p>
La verdad es que soy muy desorganizado cuando escribo. Algo que no es
un problema cuando haces cuentos cortos, de tramas simples. Está todo
controlado dentro de mi cabeza y sale más o menos del tirón, con
alguna revisita para corrección. Sin embargo, en esta ocasión me he
dado cuenta que debo ser algo más ordenado y llevo un tiempo
rompiéndome la cabeza de cómo organizar el <i>cotarro</i> para no perderme en
el intento.
</p>

<p>
Aunque hay quien me recomendó que utilizara alguna de esas
herramientas esotéricas, no cuento con ningún <i>software específico</i> que
me auxilie en estas tareas. Mi solución, como casi siempre la más
difícil, es ponerme a retorcer otro <i>no específico</i> que pueda cumplir la
misma tarea, pero seguramente con más trabajo. Seguro, que si me
conoces estarás pensando en <i>Emacs</i>... y sí, lo voy a usar, pero como
editor simple y llanamente, porque la herramienta que ha venido a
rescatarme es <i>Fossil</i>.
</p>

<p>
<i>Fossil</i> es la herramienta de control de versiones que utilizo para
muchos de mis repositorios privados.  En estos he aprendido que
<i>Fossil</i> muestra «renderizados» los archivos <i>MarkDown</i> (<code>M↓</code>) y los de
<i>Pikchr</i>. Teniendo en cuenta que el contenido y el trabajo lo voy a leer
más veces que a escribir, prefiero navegar por el repositorio viendo
el «resultado» en lugar del código y además, me puedo permitir hacer
tantos esquemas gráficos como necesite sin preocuparme de generar el
archivo <code>SVG</code>.
</p>

<p>
De momento, he cogido un archivo <code>.fossil</code> en blanco y me he puesto a
retocarlo para dejarlo más agradable de ver que he sido capaz,
metiéndole algo de <code>CSS</code> para los renderizados, y sobre todo información
y plantillas que me serán útiles cuando me ponga a trabajar. Eso
gracias a que <i>Fossil</i> proporciona un <i>Wiki</i> sencillo (pero funcional) que
me está siendo muy útil.
</p>


<figure id="orgc616256">
<img src="./imagenes/Captura_repo.png" alt="Captura_repo.png">

</figure>

<p>
Es decir: el único <i>commit</i> que tiene el repositorio es el de creación.
Por supuesto, no hay ningún archivo aún en él. ¿Dónde está la
información? En el <i>Wiki</i>:
</p>


<figure id="orgb486b5f">
<img src="./imagenes/Captura_wiki.png" alt="Captura_wiki.png">

</figure>

<p>
Esa información consiste en cuatro anotaciones sobre cómo escribir
historias y una serie de plantillas que me serán útiles.
</p>
</div>
<div id="outline-container-org6188dd9" class="outline-3">
<h3 id="org6188dd9">Plantillas</h3>
<div class="outline-text-3" id="text-org6188dd9">
<p>
Las plantillas están escritas en <code>M↓</code> así que, en general, el proyecto
irá en ese lenguaje de marcas. Cuando necesite crear un elemento de la
historia, accederé al <i>Wiki</i> y copiaré el contenido de la página en un
archivo que luego irá al repositorio.
</p>

<p>
Al inicio de escribir la historia generaré unos pocos documentos que
se irán actualizando según avance el trabajo. Por ejemplo, el cuadro
resumen que me permitirá de un vistazo ver cómo va el desarrollo:
</p>


<figure id="org8e1d20e">
<img src="./imagenes/Captura_cuadro_desarrollo.png" alt="Captura_cuadro_desarrollo.png">

</figure>

<p>
También será interesante tener la <i>ambientación</i>, aunque aún no tengo
claro si esto irá en el mismo fichero, o saldrá más a cuenta tenerla
en un directorio y cada aspecto relevante tratarlo en un archivo
independiente:
</p>


<figure id="orgdfdaede">
<img src="./imagenes/Captura_plantilla_ambientacion.png" alt="Captura_plantilla_ambientacion.png">

</figure>

<p>
Por supuesto, para las <i>tramas</i>, las <i>escenas</i> y los <i>personajes</i> cada una
irá en su ficha correspondiente.
</p>


<figure id="org51403b4">
<img src="./imagenes/Captura_plantilla_trama.png" alt="Captura_plantilla_trama.png">

</figure>


<figure id="org26a13b6">
<img src="./imagenes/Captura_plantilla_escena.png" alt="Captura_plantilla_escena.png">

</figure>


<figure id="orgf9a6e63">
<img src="./imagenes/Captura_plantilla_personaje.png" alt="Captura_plantilla_personaje.png">

</figure>

<p>
Cada uno de estos tres grupos de <i>fichas</i> irán en su correspondiente
directorio para que no se me mezclen las <i>churras con las merinas</i>.
Además de esas <i>fichas</i> había pensado en utilizar el <i>foro</i> incorporado en
<i>Fossil</i> para anotar, en <i>hilos</i> específicos para cada asunto, ideas o
inspiraciones que vayan surgiendo según trabajo, para nuevos
personajes, para nuevas tramas o escenas, para nuevas historias.
</p>

<p>
En el caso de los personajes, además pueden ir complementados con
algunos detalles que les den algo de <i>profundidad</i>. No sólo porque
utilizaré también la herramienta <i>Pikchr</i> para generar su <i>genograma</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>,
sino también otro tipo de información menos habitual.
</p>


<figure id="org6ba54c0">
<img src="./imagenes/Captura_personaje_profundidad.png" alt="Captura_personaje_profundidad.png">

</figure>
</div>
</div>
<div id="outline-container-org023f333" class="outline-3">
<h3 id="org023f333">Contenido</h3>
<div class="outline-text-3" id="text-org023f333">
<p>
Evidentemente, el contenido irá aparte, en su directorio. Aún no he
decidido si irá todo junto o habrá subdirectorios por capítulos.
Además en el <code>CSS</code> he añadido alguna funcionalidad para que la
visualización sea más agradable. En las capturas anteriores podéis
observar <i>notas</i> explicativas de cómo hacer algo, pero también hay
<i>avisos</i>, que aparecerán en rojo para advertir de <i>peligros</i> o <i>errores</i> que
hay que corregir. Otro tipo de notas aparecerán en gris y pueden ser
sugerencias o ejemplos de texto que hay que considerar si incluirlo o
no.
</p>

<p>
Por último, también a través de <code>CSS</code> se ha implementado un método de
marcado de texto, como si lo subrayáramos con el clásico <i>iluminador
fosforito</i> que puede llevar aparejado, o no, una nota al estilo <i>pósit</i>.
Esto, creo que me será útil cuando esté haciendo la revisión de los
textos.
</p>
</div>
</div>
</div>
<div id="outline-container-org4b5e0b6" class="outline-2">
<h2 id="org4b5e0b6">¿Cómo funcionará el asunto?</h2>
<div class="outline-text-2" id="text-org4b5e0b6">
<p>
En realidad, el archivo <code>.fossil</code> no deja de ser una plantilla. El
proceso será más o menos el siguiente: cuando tenga que iniciar una
historia, copiaré dicho fichero desde mi directorio <code>~/Plantillas</code> a mi
directorio <code>~/Nextcloud/repos</code> con un nuevo nombre para el proyecto.
</p>

<p>
A partir de ahí, será un repositorio que puedo clonar, pues tengo un
servidor local que me hace el apaño:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #8be9fd; font-style: italic;">cd</span> proyectos
fossil clone http://notxor@localhost:6969/nuevo-repositorio.fossil
</pre>
</div>

<p>
Esto creará una copia de <code>nuevo-repositorio.fossil</code> en el directorio
<code>~/proyectos</code> y un directorio llamado <code>nuevo-repositorio</code> con todo el
contenido actualizado del mismo. En la <code>URL</code> especifico el usuario y que
lo haga por <code>http</code> porque así directamente lo toma como el repositorio
<i>remote</i>, siendo el repositorio local el <code>.fossil</code> que ha descargado.  Por
supuesto, en <i>la plantilla</i> está ya introducido el usuario <code>notxor</code> con
una contraseña válida que me dejará autenticarme. Si hubiera algún
problema, siempre queda la opción de abrir el local con
</p>

<div class="org-src-container">
<pre class="src src-shell">fossil ui
</pre>
</div>

<p>
Luego ir al menú <code>Admin</code> → <code>Users</code> e introducir el nombre del usuario,
modificar la contraseña del mismo por una de la que me acuerde y luego
<i>pegar el cambiazo</i> de archivo en el directorio <code>~/Nextcloud/repos</code>.  Si
por algún motivo se niega a sincronizarse con el remoto (algunas veces
me ha ocurrido), borras el local y lo vuelves a clonar. Esto funciona
bien, porque tengo acceso a ambos archivos, el que funciona de
<i>remote</i> lo tengo también a mano.
</p>
</div>
<div id="outline-container-orgd8224bd" class="outline-3">
<h3 id="orgd8224bd">Generar el contenido</h3>
<div class="outline-text-3" id="text-orgd8224bd">
<p>
Para la generación del contenido seguramente utilizaré <i>Pandoc</i> para la
conversión de los archivos <code>M↓</code> en <code>html</code>. Pero hay un problema: El
intérprete de <code>M↓</code> que viene integrado en <i>Fossil</i> no es del todo
estándar, tiene algunos añadidos que no están en otros intérpretes,
algo que suele ocurrir con estas herramientas. Aún no tengo claro si
esto me hará añorar mi amado <code>org-mode</code> o no, a unas malas, no deja de
ser texto plano y lo mismo puedo hacer algún <i>script</i> que coja las
partes no estándar y las convierta. En principio, en los archivos
definitivos no debería ir nada que no sea texto sencillo.
</p>

<p>
La idea primigenia es hacerme un <code>Makefile</code> que genere los <code>html</code> por
capítulos o un <i>script</i> en otro lenguaje que lo haga llamando a <i>Pandoc</i>.
</p>
</div>
</div>
</div>
<div id="outline-container-org2679a8a" class="outline-2">
<h2 id="org2679a8a">Conclusión</h2>
<div class="outline-text-2" id="text-org2679a8a">
<p>
Yo sigo con mi manía de emplear herramientas que no son las típicas
para cosas que no son las tópicas.  Cuando he hablado sobre el asunto
con algún amigo, la recomendación es que utilice algo como <i>Manuskript</i>
o alguna otra. Pero <i>Fossil</i> me proporciona algunas cosas que otros
<i>chismáticos</i> no tienen a bien hacerlo, por ejemplo:
</p>

<ul class="org-ul">
<li>Repositorio incluido en la herramienta. Además siendo unipersonal no
habrá conflictos, ni <i>forks</i> ni ninguna de esas cosas raras (y será
todo maravilloso y ... ¡bah!).</li>
<li><i>Wiki</i> para cargarlo de información de lo más variopinta que me pueda
ser útil. Lo que sea interesante para varios proyectos lo pasaré
también a la plantilla para que esté para las historias nuevas.</li>
<li>Un <i>foro</i>, que será unipersonal, pero que me permitirá abrir <i>un hilo</i>
para anotar algo y sopesar distintas posibilidades, sin embarrar el
<i>Wiki</i> o el contenido; para anotar ideas para nuevas historias,
personajes o tramas, además de para los personajes, tramas y
ambientación de la historia en curso.</li>
<li>Si, por algún azar encontrase alguien quiera echar una mano será tan
fácil como abrirle una cuenta de «desarrollador» en el repositorio,
poner el <i>remote</i> en algún servidor que podamos alcanzar ambos y
sincronizar nuestros repositorios locales de vez en cuando.</li>
</ul>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Obsérvese al <b>pedante</b> hablando de sí en tercera
persona... ¡Ejem! ¡Lo hice de nuevo! 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Un <i>genograma</i> es una representación gráfica de la estructura
familiar de una persona donde se pueden añadir informaciones
relevantes sobre eventos importantes para la familia y mediante
códigos gráficos, mostrar las relaciones entre sus miembros. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/fossil/index.html">fossil</a> <a href="/tags/escribir/index.html">escribir</a> ]]></description>
  <category><![CDATA[fossil]]></category>
  <category><![CDATA[escribir]]></category>
  <link>https://notxor.nueva-actitud.org/2024/10/06/preparando-la-nanowrimo.html</link>
  <pubDate>Sun, 06 Oct 2024 17:37:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Gráficos con pikchr]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2024-09-30</div>
<p>
En el blog ya he hablado de <code>pikchr</code> y <a href="https://notxor.nueva-actitud.org/2022/07/05/pikchr.html">en ese artículo</a> podéis ver lo
básico del sistema. Lo traigo de nuevo porque escribiendo unos apuntes
para impartir un curso lo he utilizado con profusión y estoy
maravillado de sus posibilidades. Es una de esas herramientas que me
encontré buceando por el mundillo<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> de <i>Tcl/Tk</i>, <i>SQLite</i> y <i>Fossil</i>.
</p>

<p>
Como sabéis, porque lo he contado innumerables veces, suelo generar
mis cosas siempre a partir de <i>texto plano</i>. Concretamente, utilizo el
<code>org-mode</code> de <i>Emacs</i> para ello. Los bloques de código que proporciona
dicho modo son una herramienta increíble para realizar también los
gráficos utilizando texto plano con herramientas como <i>GraphViz-Dot</i> o
<i>PlantUML</i>. Sin embargo, con dichas herramientas no puedo hacer todos
los gráficos que necesito. En muchas ocasiones recurría a <i>Inkscape</i>
para generar un archivo <code>SVG</code> e incrustarlo en el documento. Lo que era
un incordio, porque tenía que abrir dicho programa para dibujar y
echaba de menos la agilidad que me proporcionan <code>graphviz</code> y <code>plantuml</code>.
Conocía <code>pikchr</code>, pero no había pasado de hacer algunas pruebas y poco
más.
</p>

<p>
Por ejemplo, estoy con la documentación de un curso sobre
<i>conflicto y negociación</i>. El resumen gráfico en el tema de las
<i>fases de un conflicto</i> es el siguiente<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>:
</p>

<div id="svg-1" onclick="toggleHidden('svg-1')" class="figure">
<div style='width:100%;margin:auto;max-width:649px;'>
<svg xmlns='http://www.w3.org/2000/svg' style='font-size:initial;' class="pikchr" viewBox="0 0 649.325 904.32">
<path d="M2.16,182.16L569.089,182.16L569.089,2.16L2.16,2.16Z"  style="fill:rgb(172,201,227);stroke-width:2.16;stroke:rgb(0,0,0);" />
<path d="M2.16,362.16L569.089,362.16L569.089,182.16L2.16,182.16Z"  style="fill:rgb(197,216,239);stroke-width:2.16;stroke:rgb(0,0,0);" />
<path d="M2.16,542.16L569.089,542.16L569.089,362.16L2.16,362.16Z"  style="fill:rgb(172,201,227);stroke-width:2.16;stroke:rgb(0,0,0);" />
<path d="M2.16,722.16L569.089,722.16L569.089,542.16L2.16,542.16Z"  style="fill:rgb(197,216,239);stroke-width:2.16;stroke:rgb(0,0,0);" />
<path d="M2.16,902.16L569.089,902.16L569.089,722.16L2.16,722.16Z"  style="fill:rgb(172,201,227);stroke-width:2.16;stroke:rgb(0,0,0);" />
<path d="M30.96,182.16L30.96,2.16"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="30.96" y="80.46" text-anchor="middle" fill="rgb(0,0,0)" transform="rotate(-90 30.96,92.16)" dominant-baseline="central">Fase I</text>
<path d="M30.96,362.16L30.96,182.16"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="30.96" y="260.46" text-anchor="middle" fill="rgb(0,0,0)" transform="rotate(-90 30.96,272.16)" dominant-baseline="central">Fase II</text>
<path d="M30.96,542.16L30.96,362.16"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="30.96" y="440.46" text-anchor="middle" fill="rgb(0,0,0)" transform="rotate(-90 30.96,452.16)" dominant-baseline="central">Fase III</text>
<path d="M30.96,722.16L30.96,542.16"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="30.96" y="620.46" text-anchor="middle" fill="rgb(0,0,0)" transform="rotate(-90 30.96,632.16)" dominant-baseline="central">Fase IV</text>
<path d="M30.96,902.16L30.96,722.16"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="30.96" y="800.46" text-anchor="middle" fill="rgb(0,0,0)" transform="rotate(-90 30.96,812.16)" dominant-baseline="central">Fase V</text>
<path d="M68.76,81.36L237.96,81.36A9 9 0 0 0 246.96 72.36L246.96,47.16A9 9 0 0 0 237.96 38.16L68.76,38.16A9 9 0 0 0 59.76 47.16L59.76,72.36A9 9 0 0 0 68.76 81.36Z"  style="fill:rgb(255,255,255);stroke-width:1.5;stroke:rgb(0,0,0);" />
<text x="153.36" y="59.76" text-anchor="middle" fill="rgb(0,0,0)" font-size="125%" dominant-baseline="central">Antecedentes</text>
<polygon points="318.96,59.76 307.44,64.08 307.44,55.44" style="fill:rgb(0,0,0)"/>
<path d="M246.96,59.76L313.2,59.76"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="402.422" y="59.76" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Condición germen</text>
<path d="M477.605,156.96L638.165,156.96A9 9 0 0 0 647.165 147.96L647.165,122.76A9 9 0 0 0 638.165 113.76L477.605,113.76A9 9 0 0 0 468.605 122.76L468.605,147.96A9 9 0 0 0 477.605 156.96Z"  style="fill:rgb(170,146,239);stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="557.885" y="125.28" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Condición necesaria</text>
<text x="557.885" y="145.44" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">No suficiente</text>
<polygon points="557.885,113.76 553.099,107.048 558.693,105.556" style="fill:rgb(136,136,136)"/>
<path d="M485.885,59.76 L 514.685,59.76 Q 543.485,59.76 550.188,84.8956 L 556.89,110.031"  style="fill:none;stroke-width:1.4472;stroke:rgb(136,136,136);" />
<path d="M68.76,257.108L237.96,257.108A9 9 0 0 0 246.96 248.108L246.96,222.908A9 9 0 0 0 237.96 213.908L68.76,213.908A9 9 0 0 0 59.76 222.908L59.76,248.108A9 9 0 0 0 68.76 257.108Z"  style="fill:rgb(255,255,255);stroke-width:1.5;stroke:rgb(0,0,0);" />
<text x="153.36" y="235.508" text-anchor="middle" fill="rgb(0,0,0)" font-size="125%" dominant-baseline="central">Personalización</text>
<polygon points="244.324,216.544 250.021,205.639 255.786,212.074" style="fill:rgb(136,136,136)"/>
<path d="M248.614,212.7L402.422,74.88"  style="fill:none;stroke-width:2.16;stroke:rgb(136,136,136);" />
<text x="323.373" y="134.012" text-anchor="middle" fill="rgb(136,136,136)" transform="rotate(-41.86192169 323.373,145.712)" dominant-baseline="central">percepción</text>
<text x="323.373" y="157.412" text-anchor="middle" fill="rgb(136,136,136)" transform="rotate(-41.86192169 323.373,145.712)" dominant-baseline="central">conflicto</text>
<path d="M477.605,332.708L638.165,332.708A9 9 0 0 0 647.165 323.708L647.165,298.508A9 9 0 0 0 638.165 289.508L477.605,289.508A9 9 0 0 0 468.605 298.508L468.605,323.708A9 9 0 0 0 477.605 332.708Z"  style="fill:rgb(170,146,239);stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="557.885" y="301.028" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Delimita los temas</text>
<text x="557.885" y="321.188" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">del conflicto</text>
<text x="402.422" y="225.428" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Emociones</text>
<text x="402.422" y="245.588" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Sentimientos</text>
<polygon points="341.654,235.508 330.134,239.828 330.134,231.188" style="fill:rgb(0,0,0)"/>
<path d="M246.96,235.508L335.894,235.508"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<polygon points="557.885,289.508 552.226,283.514 557.563,281.271" style="fill:rgb(136,136,136)"/>
<path d="M463.19,235.508 L 499.19,235.508 Q 535.19,235.508 545.79,260.729 L 556.39,285.95"  style="fill:none;stroke-width:1.4472;stroke:rgb(136,136,136);" />
<path d="M68.76,432.856L237.96,432.856A9 9 0 0 0 246.96 423.856L246.96,398.656A9 9 0 0 0 237.96 389.656L68.76,389.656A9 9 0 0 0 59.76 398.656L59.76,423.856A9 9 0 0 0 68.76 432.856Z"  style="fill:rgb(255,255,255);stroke-width:1.5;stroke:rgb(0,0,0);" />
<text x="153.36" y="411.256" text-anchor="middle" fill="rgb(0,0,0)" font-size="125%" dominant-baseline="central">Intenciones cta.</text>
<polygon points="244.324,392.292 250.415,381.602 255.942,388.243" style="fill:rgb(136,136,136)"/>
<path d="M248.751,388.607L402.422,260.708"  style="fill:none;stroke-width:2.16;stroke:rgb(136,136,136);" />
<text x="323.373" y="314.8" text-anchor="middle" fill="rgb(136,136,136)" transform="rotate(-39.77034247 323.373,326.5)" dominant-baseline="central">generan</text>
<path d="M494.751,407.032L620.751,407.032A9 9 0 0 0 629.751 398.032L629.751,387.232A9 9 0 0 0 620.751 378.232L494.751,378.232A9 9 0 0 0 485.751 387.232L485.751,398.032A9 9 0 0 0 494.751 407.032Z"  style="fill:rgb(170,202,255);stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="557.751" y="392.632" text-anchor="middle" fill="rgb(0,0,0)" font-size="80%" dominant-baseline="central">Intención de competir</text>
<path d="M494.751,435.832L620.751,435.832A9 9 0 0 0 629.751 426.832L629.751,416.032A9 9 0 0 0 620.751 407.032L494.751,407.032A9 9 0 0 0 485.751 416.032L485.751,426.832A9 9 0 0 0 494.751 435.832Z"  style="fill:rgb(170,202,255);stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="557.751" y="421.432" text-anchor="middle" fill="rgb(0,0,0)" font-size="80%" dominant-baseline="central">Intención de colaborar</text>
<path d="M494.751,464.632L620.751,464.632A9 9 0 0 0 629.751 455.632L629.751,444.832A9 9 0 0 0 620.751 435.832L494.751,435.832A9 9 0 0 0 485.751 444.832L485.751,455.632A9 9 0 0 0 494.751 464.632Z"  style="fill:rgb(170,202,255);stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="557.751" y="450.232" text-anchor="middle" fill="rgb(0,0,0)" font-size="80%" dominant-baseline="central">Intención de ceder</text>
<path d="M494.751,493.432L620.751,493.432A9 9 0 0 0 629.751 484.432L629.751,473.632A9 9 0 0 0 620.751 464.632L494.751,464.632A9 9 0 0 0 485.751 473.632L485.751,484.432A9 9 0 0 0 494.751 493.432Z"  style="fill:rgb(170,202,255);stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="557.751" y="479.032" text-anchor="middle" fill="rgb(0,0,0)" font-size="80%" dominant-baseline="central">Intención de evadirse</text>
<path d="M494.751,522.232L620.751,522.232A9 9 0 0 0 629.751 513.232L629.751,502.432A9 9 0 0 0 620.751 493.432L494.751,493.432A9 9 0 0 0 485.751 502.432L485.751,513.232A9 9 0 0 0 494.751 522.232Z"  style="fill:rgb(170,202,255);stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="557.751" y="507.832" text-anchor="middle" fill="rgb(0,0,0)" font-size="80%" dominant-baseline="central">Intención de compromiso</text>
<polygon points="485.751,392.632 478.436,396.434 477.74,390.687" style="fill:rgb(136,136,136)"/>
<path d="M246.96,411.256 L 289.48,411.256 Q 331.999,411.256 406.959,402.176 L 481.919,393.097"  style="fill:none;stroke-width:1.4472;stroke:rgb(136,136,136);" />
<polygon points="485.751,421.432 477.858,423.811 478.24,418.035" style="fill:rgb(136,136,136)"/>
<path d="M246.96,411.256 L 289.48,411.256 Q 331.999,411.256 406.95,416.217 L 481.9,421.178"  style="fill:none;stroke-width:1.4472;stroke:rgb(136,136,136);" />
<polygon points="485.751,450.232 477.558,451.141 478.98,445.53" style="fill:rgb(136,136,136)"/>
<path d="M246.96,411.256 L 289.48,411.256 Q 331.999,411.256 407.005,430.27 L 482.01,449.284"  style="fill:none;stroke-width:1.4472;stroke:rgb(136,136,136);" />
<polygon points="485.751,479.032 477.52,478.568 479.855,473.271" style="fill:rgb(136,136,136)"/>
<path d="M246.96,411.256 L 289.48,411.256 Q 331.999,411.256 407.109,444.366 L 482.219,477.476"  style="fill:none;stroke-width:1.4472;stroke:rgb(136,136,136);" />
<polygon points="485.751,507.832 477.675,506.178 480.754,501.276" style="fill:rgb(136,136,136)"/>
<path d="M246.96,411.256 L 289.48,411.256 Q 331.999,411.256 407.241,458.518 L 482.483,505.78"  style="fill:none;stroke-width:1.4472;stroke:rgb(136,136,136);" />
<text x="345.62" y="497.752" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Comportamiento de</text>
<text x="345.62" y="517.912" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">las partes</text>
<polygon points="345.62,482.632 333.403,481.175 337.373,473.502" style="fill:rgb(0,0,0)"/>
<path d="M244.324,430.22L340.504,479.985"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<path d="M68.76,608.604L237.96,608.604A9 9 0 0 0 246.96 599.604L246.96,574.404A9 9 0 0 0 237.96 565.404L68.76,565.404A9 9 0 0 0 59.76 574.404L59.76,599.604A9 9 0 0 0 68.76 608.604Z"  style="fill:rgb(255,255,255);stroke-width:1.5;stroke:rgb(0,0,0);" />
<text x="153.36" y="587.004" text-anchor="middle" fill="rgb(0,0,0)" font-size="125%" dominant-baseline="central">Gestión</text>
<polygon points="244.324,568.04 253.801,560.194 256.623,568.36" style="fill:rgb(136,136,136)"/>
<path d="M249.768,566.159L345.62,533.032"  style="fill:none;stroke-width:2.16;stroke:rgb(136,136,136);" />
<text x="294.972" y="538.836" text-anchor="middle" fill="rgb(136,136,136)" transform="rotate(-19.06508645 294.972,550.536)" dominant-baseline="central">regula</text>
<path d="M494.751,574.673L620.751,574.673A9 9 0 0 0 629.751 565.673L629.751,554.873A9 9 0 0 0 620.751 545.873L494.751,545.873A9 9 0 0 0 485.751 554.873L485.751,565.673A9 9 0 0 0 494.751 574.673Z"  style="fill:rgb(170,202,255);stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="557.751" y="560.273" text-anchor="middle" fill="rgb(0,0,0)" font-size="80%" dominant-baseline="central">Ignorar</text>
<path d="M494.751,603.473L620.751,603.473A9 9 0 0 0 629.751 594.473L629.751,583.673A9 9 0 0 0 620.751 574.673L494.751,574.673A9 9 0 0 0 485.751 583.673L485.751,594.473A9 9 0 0 0 494.751 603.473Z"  style="fill:rgb(170,202,255);stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="557.751" y="589.073" text-anchor="middle" fill="rgb(0,0,0)" font-size="80%" dominant-baseline="central">Ceder</text>
<path d="M494.751,632.273L620.751,632.273A9 9 0 0 0 629.751 623.273L629.751,612.473A9 9 0 0 0 620.751 603.473L494.751,603.473A9 9 0 0 0 485.751 612.473L485.751,623.273A9 9 0 0 0 494.751 632.273Z"  style="fill:rgb(170,202,255);stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="557.751" y="617.873" text-anchor="middle" fill="rgb(0,0,0)" font-size="80%" dominant-baseline="central">Imponer</text>
<path d="M494.751,661.073L620.751,661.073A9 9 0 0 0 629.751 652.073L629.751,641.273A9 9 0 0 0 620.751 632.273L494.751,632.273A9 9 0 0 0 485.751 641.273L485.751,652.073A9 9 0 0 0 494.751 661.073Z"  style="fill:rgb(170,202,255);stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="557.751" y="646.673" text-anchor="middle" fill="rgb(0,0,0)" font-size="80%" dominant-baseline="central">Colaborar</text>
<path d="M494.751,689.873L620.751,689.873A9 9 0 0 0 629.751 680.873L629.751,670.073A9 9 0 0 0 620.751 661.073L494.751,661.073A9 9 0 0 0 485.751 670.073L485.751,680.873A9 9 0 0 0 494.751 689.873Z"  style="fill:rgb(170,202,255);stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="557.751" y="675.473" text-anchor="middle" fill="rgb(0,0,0)" font-size="80%" dominant-baseline="central">Arbitraje</text>
<path d="M494.751,718.673L620.751,718.673A9 9 0 0 0 629.751 709.673L629.751,698.873A9 9 0 0 0 620.751 689.873L494.751,689.873A9 9 0 0 0 485.751 698.873L485.751,709.673A9 9 0 0 0 494.751 718.673Z"  style="fill:rgb(170,202,255);stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="557.751" y="704.273" text-anchor="middle" fill="rgb(0,0,0)" font-size="80%" dominant-baseline="central">Negociación</text>
<polygon points="485.751,560.273 478.642,564.447 477.65,558.744" style="fill:rgb(136,136,136)"/>
<path d="M246.96,587.004 L 289.48,587.004 Q 331.999,587.004 406.974,573.969 L 481.948,560.934"  style="fill:none;stroke-width:1.4472;stroke:rgb(136,136,136);" />
<polygon points="485.751,589.073 477.994,591.864 478.072,586.075" style="fill:rgb(136,136,136)"/>
<path d="M246.96,587.004 L 289.48,587.004 Q 331.999,587.004 406.946,588.013 L 481.892,589.021"  style="fill:none;stroke-width:1.4472;stroke:rgb(136,136,136);" />
<polygon points="485.751,617.873 477.613,619.192 478.753,613.516" style="fill:rgb(136,136,136)"/>
<path d="M246.96,587.004 L 289.48,587.004 Q 331.999,587.004 406.983,602.059 L 481.967,617.114"  style="fill:none;stroke-width:1.4472;stroke:rgb(136,136,136);" />
<polygon points="485.751,646.673 477.508,646.579 479.602,641.183" style="fill:rgb(136,136,136)"/>
<path d="M246.96,587.004 L 289.48,587.004 Q 331.999,587.004 407.076,616.141 L 482.153,645.277"  style="fill:none;stroke-width:1.4472;stroke:rgb(136,136,136);" />
<polygon points="485.751,675.473 477.617,674.133 480.504,669.115" style="fill:rgb(136,136,136)"/>
<path d="M246.96,587.004 L 289.48,587.004 Q 331.999,587.004 407.202,630.276 L 482.406,673.549"  style="fill:none;stroke-width:1.4472;stroke:rgb(136,136,136);" />
<polygon points="485.751,704.273 477.858,701.894 481.369,697.291" style="fill:rgb(136,136,136)"/>
<path d="M246.96,587.004 L 289.48,587.004 Q 331.999,587.004 407.341,644.469 L 482.682,701.933"  style="fill:none;stroke-width:1.4472;stroke:rgb(136,136,136);" />
<path d="M68.76,784.352L237.96,784.352A9 9 0 0 0 246.96 775.352L246.96,750.152A9 9 0 0 0 237.96 741.152L68.76,741.152A9 9 0 0 0 59.76 750.152L59.76,775.352A9 9 0 0 0 68.76 784.352Z"  style="fill:rgb(255,255,255);stroke-width:1.5;stroke:rgb(0,0,0);" />
<text x="153.36" y="762.752" text-anchor="middle" fill="rgb(0,0,0)" font-size="125%" dominant-baseline="central">Resultados</text>
<path d="M494.751,769.697L620.751,769.697A9 9 0 0 0 629.751 760.697L629.751,749.897A9 9 0 0 0 620.751 740.897L494.751,740.897A9 9 0 0 0 485.751 749.897L485.751,760.697A9 9 0 0 0 494.751 769.697Z"  style="fill:rgb(170,202,255);stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="557.751" y="755.297" text-anchor="middle" fill="rgb(0,0,0)" font-size="80%" dominant-baseline="central">Perder -- Perder</text>
<path d="M494.751,826.617L620.751,826.617A9 9 0 0 0 629.751 817.617L629.751,806.817A9 9 0 0 0 620.751 797.817L494.751,797.817A9 9 0 0 0 485.751 806.817L485.751,817.617A9 9 0 0 0 494.751 826.617Z"  style="fill:rgb(170,202,255);stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="557.751" y="812.217" text-anchor="middle" fill="rgb(0,0,0)" font-size="80%" dominant-baseline="central">Ganar -- Perder</text>
<path d="M494.751,883.536L620.751,883.536A9 9 0 0 0 629.751 874.536L629.751,863.736A9 9 0 0 0 620.751 854.736L494.751,854.736A9 9 0 0 0 485.751 863.736L485.751,874.536A9 9 0 0 0 494.751 883.536Z"  style="fill:rgb(170,202,255);stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="557.751" y="869.136" text-anchor="middle" fill="rgb(0,0,0)" font-size="80%" dominant-baseline="central">Ganar -- Ganar</text>
<polygon points="485.751,755.297 478.181,758.562 477.901,752.78" style="fill:rgb(136,136,136)"/>
<path d="M246.96,762.752 L 289.48,762.752 Q 331.999,762.752 406.948,759.118 L 481.896,755.484"  style="fill:none;stroke-width:1.4472;stroke:rgb(136,136,136);" />
<polygon points="485.751,812.217 477.517,812.608 479.289,807.098" style="fill:rgb(136,136,136)"/>
<path d="M246.96,762.752 L 289.48,762.752 Q 331.999,762.752 407.038,786.893 L 482.077,811.035"  style="fill:none;stroke-width:1.4472;stroke:rgb(136,136,136);" />
<polygon points="485.751,869.136 477.757,867.125 481.05,862.364" style="fill:rgb(136,136,136)"/>
<path d="M246.96,762.752 L 289.48,762.752 Q 331.999,762.752 407.288,814.846 L 482.577,866.941"  style="fill:none;stroke-width:1.4472;stroke:rgb(136,136,136);" />
<path d="M153.36,202.569L210.053,145.877L195.88,145.877L181.706,145.877L181.706,77.845L125.014,77.845L125.014,145.877L96.6671,145.877Z"  style="fill:rgb(250,175,193);stroke-width:2.16;stroke-linejoin:round;stroke:rgb(0,0,0);" />
<path d="M153.36,378.317L210.053,321.625L195.88,321.625L181.706,321.625L181.706,253.593L125.014,253.593L125.014,321.625L96.6671,321.625Z"  style="fill:rgb(250,175,193);stroke-width:2.16;stroke-linejoin:round;stroke:rgb(0,0,0);" />
<path d="M153.36,554.066L210.053,497.373L195.88,497.373L181.706,497.373L181.706,429.341L125.014,429.341L125.014,497.373L96.6671,497.373Z"  style="fill:rgb(250,175,193);stroke-width:2.16;stroke-linejoin:round;stroke:rgb(0,0,0);" />
<path d="M153.36,729.814L210.053,673.121L195.88,673.121L181.706,673.121L181.706,605.089L125.014,605.089L125.014,673.121L96.6671,673.121Z"  style="fill:rgb(250,175,193);stroke-width:2.16;stroke-linejoin:round;stroke:rgb(0,0,0);" />
</svg>
</div>
<pre class='hidden'>$fase = 1.25
define flecha {
line up 1cm right 1cm \
     left 0.25cm up 0cm \
     left 0.25cm left 0 \
     up 1.2cm left 1cm \
     up 0 down 1.2cm left 0 \
     up 0 left 0.5cm \
     close fill 0xfaafc1
}
# Marcos para las fases
down
box width 10cm height $fase fill 0xacc9e3
box same fill 0xc5d8ef
box same as first box
box same as 2nd box
box same as first box
line from 1st box.sw+(0.2,0) up until even with 1st box.n "Fase I" above aligned
line from 2nd box.sw+(0.2,0) up until even with 2nd box.n "Fase II" above aligned
line from 3rd box.sw+(0.2,0) up until even with 3rd box.n "Fase III" above aligned
line from 4th box.sw+(0.2,0) up until even with 4th box.n "Fase IV" above aligned
line from 5th box.sw+(0.2,0) up until even with 5th box.n "Fase V" above aligned
# Rellenar la Fase I
up; move 4.6
right; move 0.2
F1a: box ht 0.3 wid 1.3 rad 6px fill white thickness 1px "Antecedentes" big
     arrow right 100%
F1b: "Condición germen"
     move 100%; down; move 75%
F1c: box ht 0.3 wid 1.24 rad 6px fill 0xaa92ef "Condición necesaria" "No suficiente"
     spline thin right 0.4 -&gt; from F1b.e to F1c.n color 0x888888
# Rellenar la Fase II
F2a: box same as F1a at 3.1cm south of F1a "Personalización" big
     arrow &lt;- from F2a.ne to F1b.s "percepción" aligned "conflicto" aligned color 0x888888
F2b: box same as F1c at 3.1cm south of F1c "Delimita los temas" "del conflicto"
F2c: "Emociones" "Sentimientos" at 3.1cm south of F1b
     arrow from F2a.e to F2c.w
     spline thin right 0.5 -&gt; from F2c.e to F2b.n color 0x888888
# Rellenar la Fase III
F3a: box same as F2a at 3.1cm south of F2a "Intenciones cta." big
     arrow &lt;- from F3a.ne to F2c.s "generan" above aligned color 0x888888
F3b: box rad 6px ht 0.2 wid 1 fill 0xaacaff with .c at (4.8cm, -5.3cm) "Intención de competir" small
     down
F3c: box same as F3b "Intención de colaborar" small
F3d: box same as F3b "Intención de ceder" small
F3e: box same as F3b "Intención de evadirse" small
F3f: box same as F3b "Intención de compromiso" small
     spline -&gt; thin right 1.5cm from F3a.e to F3b.w color 0x888888
     spline -&gt; thin right 1.5cm from F3a.e to F3c.w color 0x888888
     spline -&gt; thin right 1.5cm from F3a.e to F3d.w color 0x888888
     spline -&gt; thin right 1.5cm from F3a.e to F3e.w color 0x888888
     spline -&gt; thin right 1.5cm from F3a.e to F3f.w color 0x888888
     left; move 0.9cm
Cta: "Comportamiento de" "las partes"
     arrow -&gt; from F3a.se to Cta.n
# Rellenar la Fase IV
F4a: box same as F3a at 3.1cm south of F3a "Gestión" big
     arrow &lt;- from F4a.ne to Cta.s  "regula" above aligned color 0x888888
F4b: box same as F3b at 0.925cm south of F3f "Ignorar" small
down
F4c: box same as F4b "Ceder" small
F4d: box same as F4b "Imponer" small
F4e: box same as F4b "Colaborar" small
F4f: box same as F4b "Arbitraje" small
F4g: box same as F4b "Negociación" small
     spline -&gt; thin right 1.5cm from F4a.e to F4b.w color 0x888888
     spline -&gt; thin right 1.5cm from F4a.e to F4c.w color 0x888888
     spline -&gt; thin right 1.5cm from F4a.e to F4d.w color 0x888888
     spline -&gt; thin right 1.5cm from F4a.e to F4e.w color 0x888888
     spline -&gt; thin right 1.5cm from F4a.e to F4f.w color 0x888888
     spline -&gt; thin right 1.5cm from F4a.e to F4g.w color 0x888888
# Rellenar la Fase V
F5a: box same as F4a at 3.1cm south of F4a  "Resultados" big
F5b: box same as F4b at 0.9cm south of F4g "Perder -- Perder" small
     down
F5c: box same as F5b at .75cm south of F5b.s "Ganar -- Perder" small
F5d: box same as F5b at .75cm south of F5c.s "Ganar -- Ganar" small
    spline -&gt; thin right 1.5cm from F5a.e to F5b.w color 0x888888
    spline -&gt; thin right 1.5cm from F5a.e to F5c.w color 0x888888
    spline -&gt; thin right 1.5cm from F5a.e to F5d.w color 0x888888
# Colocar flechas gordas
# Utilizo un punto invisible para mover el dibujo de la flecha
dot at 0.2cm north of F2a.n invisible; flecha
dot at 0.2cm north of F3a.n invisible; flecha
dot at 0.2cm north of F4a.n invisible; flecha
dot at 0.2cm north of F5a.n invisible; flecha
</pre>
</div>

<p>
Este gráfico no podría haberlo hecho con <code>graphviz</code> o con <code>plantuml</code>.
Incluso con <i>Inkscape</i> me hubiera costado colocar elementos, alinearlos,
poner guías, etc.  Sin embargo, con un poco de ayuda de <i>Emacs</i> –sí,
tiene un modo <i>pikchr</i> incluido– he podido ir dibujando, elemento a
elemento todo el dibujo.
</p>
<div id="outline-container-org2d1000e" class="outline-2">
<h2 id="org2d1000e">Situar elementos en el dibujo</h2>
<div class="outline-text-2" id="text-org2d1000e">
<p>
Cuando empecé con <code>pikchr</code> me resultaba complicado situar elementos en
el dibujo. El modo en que <i>fluye</i> el dibujo limitaba mi forma de
trabajar. Acostumbrado a otras herramientas, donde es la propia
herramienta la que elige dónde situar un elemento u otro, esperaba de
ésta la misma funcionalidad. La tiene, pero ponía a prueba mi
capacidad espacial a la hora de dibujar. El acostumbrarme a situar las
cosas donde quiero, a guiar las líneas y los textos, a utilizar
elementos invisibles para colocarlos y otros truquillos han hecho que
me resulte una herramienta mucho más completa de lo que me pareció al
principio. Puedes ser tan preciso como quieras, puedes dejar que fluya
o forzar la posición, tú eliges.
</p>

<div class="org-src-container">
<pre class="src src-pikchr"><span style="color: #8be9fd; font-style: italic;">box</span> <span style="color: #f1fa8c;">"Hola"</span>; <span style="color: #8be9fd; font-style: italic;">arrow</span>; <span style="color: #8be9fd; font-style: italic;">box</span> <span style="color: #f1fa8c;">"Mundo"</span>
</pre>
</div>


<p>
Ese código da como resultado:
</p>

<div id="svg-2" onclick="toggleHidden('svg-2')" class="figure">
<div style='width=100%;margin:auto;max-width:292px;'>
<svg xmlns='http://www.w3.org/2000/svg' style='font-size:initial;' class="pikchr" viewBox="0 0 292.32 76.32">
<path d="M2.16,74.16L110.16,74.16L110.16,2.16L2.16,2.16Z"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="56.16" y="38.16" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Hola</text>
<polygon points="182.16,38.16 170.64,42.48 170.64,33.84" style="fill:rgb(0,0,0)"/>
<path d="M110.16,38.16L176.4,38.16"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<path d="M182.16,74.16L290.16,74.16L290.16,2.16L182.16,2.16Z"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="236.16" y="38.16" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Mundo</text>
</svg>
</div>
<pre class='hidden'>  box "Hola"; arrow; box "Mundo"
</pre>
</div>

<p>
Si cambiamos hacia dónde fluye:
</p>

<div class="org-src-container">
<pre class="src src-pikchr"><span style="color: #ff79c6; font-weight: bold;">down</span>
<span style="color: #8be9fd; font-style: italic;">box</span> <span style="color: #f1fa8c;">"Hola"</span>; <span style="color: #8be9fd; font-style: italic;">arrow</span>; <span style="color: #8be9fd; font-style: italic;">box</span> <span style="color: #f1fa8c;">"Mundo"</span>
<span style="color: #8be9fd; font-style: italic;">move</span>
<span style="color: #ff79c6; font-weight: bold;">right</span>
<span style="color: #8be9fd; font-style: italic;">box</span> <span style="color: #f1fa8c;">"Hola"</span>; <span style="color: #8be9fd; font-style: italic;">arrow</span>; <span style="color: #8be9fd; font-style: italic;">box</span> <span style="color: #f1fa8c;">"Mundo"</span>
<span style="color: #8be9fd; font-style: italic;">move</span>
<span style="color: #ff79c6; font-weight: bold;">up</span>
<span style="color: #8be9fd; font-style: italic;">box</span> <span style="color: #f1fa8c;">"Hola"</span>; <span style="color: #8be9fd; font-style: italic;">arrow</span>; <span style="color: #8be9fd; font-style: italic;">box</span> <span style="color: #f1fa8c;">"Mundo"</span>
</pre>
</div>

<div id="svg-3" onclick="toggleHidden('svg-3')" class="figure">
<div style='width:100%;margin:auto;max-width:472px;'>
<svg xmlns='http://www.w3.org/2000/svg' style='font-size:initial;' class="pikchr" viewBox="0 0 472.32 328.32">
<path d="M2.16,74.16L110.16,74.16L110.16,2.16L2.16,2.16Z"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="56.16" y="38.16" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Hola</text>
<polygon points="56.16,146.16 51.84,134.64 60.48,134.64" style="fill:rgb(0,0,0)"/>
<path d="M56.16,74.16L56.16,140.4"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<path d="M2.16,218.16L110.16,218.16L110.16,146.16L2.16,146.16Z"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="56.16" y="182.16" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Mundo</text>
<path d="M56.16,326.16L164.16,326.16L164.16,254.16L56.16,254.16Z"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="110.16" y="290.16" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Hola</text>
<polygon points="236.16,290.16 224.64,294.48 224.64,285.84" style="fill:rgb(0,0,0)"/>
<path d="M164.16,290.16L230.4,290.16"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<path d="M236.16,326.16L344.16,326.16L344.16,254.16L236.16,254.16Z"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="290.16" y="290.16" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Mundo</text>
<path d="M362.16,290.16L470.16,290.16L470.16,218.16L362.16,218.16Z"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="416.16" y="254.16" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Hola</text>
<polygon points="416.16,146.16 420.48,157.68 411.84,157.68" style="fill:rgb(0,0,0)"/>
<path d="M416.16,218.16L416.16,151.92"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<path d="M362.16,146.16L470.16,146.16L470.16,74.16L362.16,74.16Z"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="416.16" y="110.16" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Mundo</text>
</svg>
</div>
<pre class='hidden'>down
box "Hola"; arrow; box "Mundo"
move
right
box "Hola"; arrow; box "Mundo"
move
up
box "Hola"; arrow; box "Mundo"
</pre>
</div>

<p>
Como vemos, dejar el alineamiento al propio flujo de dibujo de
<code>pikchr</code> presenta algunos inconvenientes, que eran los que me volvía
loco al principio de utilizar la herramienta.
</p>

<div class="org-src-container">
<pre class="src src-pikchr"><span style="color: #ff79c6; font-weight: bold;">down</span>
<span style="color: #8be9fd; font-style: italic;">box</span> <span style="color: #f1fa8c;">"Hola"</span>; <span style="color: #8be9fd; font-style: italic;">arrow</span>; <span style="color: #8be9fd; font-style: italic;">box</span> <span style="color: #f1fa8c;">"Mundo"</span>
<span style="color: #ff79c6; font-weight: bold;">right</span>
<span style="color: #8be9fd; font-style: italic;">box</span> <span style="color: #f1fa8c;">"Hola"</span> <span style="color: #ff79c6; font-weight: bold;">at</span> <span style="color: #bd93f9;">1.5cm</span> <span style="color: #ff79c6; font-weight: bold;">east</span> <span style="color: #ff79c6; font-weight: bold;">of</span> <span style="color: #8be9fd; font-style: italic;">2nd</span> <span style="color: #8be9fd; font-style: italic;">box</span>.<span style="color: #ff79c6; font-weight: bold;">e</span>; <span style="color: #8be9fd; font-style: italic;">arrow</span>; <span style="color: #8be9fd; font-style: italic;">box</span> <span style="color: #f1fa8c;">"Mundo"</span>
<span style="color: #ff79c6; font-weight: bold;">up</span>
<span style="color: #8be9fd; font-style: italic;">box</span> <span style="color: #f1fa8c;">"Hola"</span> <span style="color: #ff79c6; font-weight: bold;">at</span> <span style="color: #bd93f9;">15mm</span> <span style="color: #ff79c6; font-weight: bold;">east</span> <span style="color: #ff79c6; font-weight: bold;">of</span> <span style="color: #8be9fd; font-style: italic;">4nd</span> <span style="color: #8be9fd; font-style: italic;">box</span>.<span style="color: #ff79c6; font-weight: bold;">e</span>; <span style="color: #8be9fd; font-style: italic;">arrow</span>; <span style="color: #8be9fd; font-style: italic;">box</span> <span style="color: #f1fa8c;">"Mundo"</span>
</pre>
</div>

<p>
Podemos apreciar que se puede hacer referencia a los elementos por su
orden de aparición para situar el siguiente. Vemos que en el segundo
grupo de elementos se hace referencia a la segunda caja para situar la
tercera a 1.5cm <i>al este</i> de la misma. Para acotar mejor las distancias y
visualizar mejor el espacio, en el resultado he añadido acotaciones:
</p>

<div id="svg-4" onclick="toggleHidden('svg-4')" class="figure">
<div style='width:100%;margin:auto;max-width:570px;'>
<svg xmlns='http://www.w3.org/2000/svg' style='font-size:initial;' class="pikchr" viewBox="0 0 570.399 267.659">
<path d="M2.16,74.16L110.16,74.16L110.16,2.16L2.16,2.16Z"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="56.16" y="38.16" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Hola</text>
<polygon points="56.16,146.16 51.84,134.64 60.48,134.64" style="fill:rgb(0,0,0)"/>
<path d="M56.16,74.16L56.16,140.4"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<path d="M2.16,218.16L110.16,218.16L110.16,146.16L2.16,146.16Z"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="56.16" y="182.16" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Mundo</text>
<path d="M141.199,218.16L249.199,218.16L249.199,146.16L141.199,146.16Z"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="195.199" y="182.16" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Hola</text>
<polygon points="321.199,182.16 309.679,186.48 309.679,177.84" style="fill:rgb(0,0,0)"/>
<path d="M249.199,182.16L315.439,182.16"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<path d="M321.199,218.16L429.199,218.16L429.199,146.16L321.199,146.16Z"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="375.199" y="182.16" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Mundo</text>
<path d="M460.239,218.16L568.239,218.16L568.239,146.16L460.239,146.16Z"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="514.239" y="182.16" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Hola</text>
<polygon points="514.239,74.16 518.559,85.68 509.919,85.68" style="fill:rgb(0,0,0)"/>
<path d="M514.239,146.16L514.239,79.92"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<path d="M460.239,74.16L568.239,74.16L568.239,2.16L460.239,2.16Z"  style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" />
<text x="514.239" y="38.16" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">Mundo</text>
<path d="M110.16,229.499L110.16,265.499"  style="fill:none;stroke-width:1.4472;stroke:rgb(128,128,128);" />
<path d="M195.199,229.499L195.199,265.499"  style="fill:none;stroke-width:1.4472;stroke:rgb(128,128,128);" />
<polygon points="110.16,256.499 117.878,253.604 117.878,259.393" style="fill:rgb(128,128,128)"/>
<polygon points="195.199,256.499 187.481,259.393 187.481,253.604" style="fill:rgb(128,128,128)"/>
<path d="M114.019,256.499L191.34,256.499"  style="fill:none;stroke-width:1.4472;stroke:rgb(128,128,128);" />
<text x="152.68" y="245.333" text-anchor="middle" fill="rgb(128,128,128)" dominant-baseline="central">1.5cm</text>
<path d="M429.199,229.499L429.199,265.499"  style="fill:none;stroke-width:1.4472;stroke:rgb(128,128,128);" />
<path d="M514.239,229.499L514.239,265.499"  style="fill:none;stroke-width:1.4472;stroke:rgb(128,128,128);" />
<polygon points="429.199,256.499 436.918,253.604 436.918,259.393" style="fill:rgb(128,128,128)"/>
<polygon points="514.239,256.499 506.52,259.393 506.52,253.604" style="fill:rgb(128,128,128)"/>
<path d="M433.059,256.499L510.38,256.499"  style="fill:none;stroke-width:1.4472;stroke:rgb(128,128,128);" />
<text x="471.719" y="245.333" text-anchor="middle" fill="rgb(128,128,128)" dominant-baseline="central">15mm</text>
</svg>
</div>
<pre class='hidden'>down
box "Hola"; arrow; box "Mundo"
right
box "Hola" at 1.5cm east of 2nd box.e; arrow; box "Mundo"
up
box "Hola" at 15mm east of 4nd box.e; arrow; box "Mundo"

# Acotamientos para visualizar mejor las medidas

X1: line thin color gray down 50% from 2mm south of 2nd box.se
X2: line same as X1 from (3nd box, X1.start)
    arrow &lt;-&gt; from 3/4&lt;X1.start,X1.end&gt; right until even with X2 "1.5cm" above thin color gray
    assert( last arrow.width == 1.5cm )

X3: line thin color gray down 50% from 2mm south of 4nd box.se
X4: line same as X3 from (5nd box, X3.start)
    arrow &lt;-&gt; from 3/4&lt;X3.start,X3.end&gt; right until even with X4 "15mm" above thin color gray
    assert( last arrow.width == 15mm )
</pre>
</div>

<p>
Si habéis mirado el código para ver las acotaciones, veréis que
también me aseguro que las medidas son correctas con una instrucción
<code>assert</code>.
</p>

<p>
Cada elemento dentro del gráfico tiene una serie de propiedades. Las
que más vas a utilizar son los puntos de referencia:
</p>

<div class="org-src-container">
<pre class="src src-pikchr"><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Puntos de situaci&#243;n
</span><span style="color: #50fa7b; font-weight: bold;">B1</span>: <span style="color: #8be9fd; font-style: italic;">box</span> <span style="color: #ff79c6; font-weight: bold;">rad</span> <span style="color: #bd93f9;">5mm</span> <span style="color: #8be9fd; font-style: italic;">color</span> blue <span style="color: #ff79c6; font-weight: bold;">thin</span> <span style="color: #ff79c6; font-weight: bold;">width</span> <span style="color: #bd93f9;">5cm</span> <span style="color: #ff79c6; font-weight: bold;">height</span> <span style="color: #bd93f9;">3.5cm</span>
    <span style="color: #8be9fd; font-style: italic;">dot</span> <span style="color: #ff79c6; font-weight: bold;">at</span> B1.<span style="color: #ff79c6; font-weight: bold;">c</span> <span style="color: #8be9fd; font-style: italic;">color</span> red <span style="color: #f1fa8c;">"c"</span> <span style="color: #ff79c6; font-weight: bold;">above</span>
    <span style="color: #8be9fd; font-style: italic;">dot</span> <span style="color: #ff79c6; font-weight: bold;">at</span> B1.<span style="color: #ff79c6; font-weight: bold;">nw</span> <span style="color: #f1fa8c;">"nw"</span> <span style="color: #ff79c6; font-weight: bold;">above</span> <span style="color: #8be9fd; font-style: italic;">color</span> red
    <span style="color: #8be9fd; font-style: italic;">dot</span> <span style="color: #ff79c6; font-weight: bold;">at</span> B1.<span style="color: #ff79c6; font-weight: bold;">n</span> <span style="color: #f1fa8c;">"n"</span> <span style="color: #ff79c6; font-weight: bold;">above</span> <span style="color: #8be9fd; font-style: italic;">color</span> red
    <span style="color: #8be9fd; font-style: italic;">dot</span> <span style="color: #ff79c6; font-weight: bold;">at</span> B1.<span style="color: #ff79c6; font-weight: bold;">ne</span> <span style="color: #f1fa8c;">"ne"</span> <span style="color: #ff79c6; font-weight: bold;">above</span> <span style="color: #8be9fd; font-style: italic;">color</span> red
    <span style="color: #8be9fd; font-style: italic;">dot</span> <span style="color: #ff79c6; font-weight: bold;">at</span> B1.<span style="color: #ff79c6; font-weight: bold;">w</span> <span style="color: #f1fa8c;">"w"</span> <span style="color: #ff79c6; font-weight: bold;">rjust</span> <span style="color: #8be9fd; font-style: italic;">color</span> red
    <span style="color: #8be9fd; font-style: italic;">dot</span> <span style="color: #ff79c6; font-weight: bold;">at</span> B1.<span style="color: #ff79c6; font-weight: bold;">e</span> <span style="color: #f1fa8c;">"e"</span> <span style="color: #ff79c6; font-weight: bold;">ljust</span> <span style="color: #8be9fd; font-style: italic;">color</span> red
    <span style="color: #8be9fd; font-style: italic;">dot</span> <span style="color: #ff79c6; font-weight: bold;">at</span> B1.<span style="color: #ff79c6; font-weight: bold;">sw</span> <span style="color: #f1fa8c;">"sw"</span> <span style="color: #ff79c6; font-weight: bold;">rjust</span> <span style="color: #8be9fd; font-style: italic;">color</span> red
    <span style="color: #8be9fd; font-style: italic;">dot</span> <span style="color: #ff79c6; font-weight: bold;">at</span> B1.<span style="color: #ff79c6; font-weight: bold;">s</span> <span style="color: #f1fa8c;">"s"</span> <span style="color: #ff79c6; font-weight: bold;">below</span> <span style="color: #8be9fd; font-style: italic;">color</span> red
    <span style="color: #8be9fd; font-style: italic;">dot</span> <span style="color: #ff79c6; font-weight: bold;">at</span> B1.<span style="color: #ff79c6; font-weight: bold;">se</span> <span style="color: #f1fa8c;">"se"</span> <span style="color: #ff79c6; font-weight: bold;">ljust</span> <span style="color: #8be9fd; font-style: italic;">color</span> red

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">Acotaciones de ancho, alto y radio
</span><span style="color: #50fa7b; font-weight: bold;">X1</span>: <span style="color: #8be9fd; font-style: italic;">line</span> <span style="color: #ff79c6; font-weight: bold;">thin</span> <span style="color: #8be9fd; font-style: italic;">color</span> gray <span style="color: #ff79c6; font-weight: bold;">down</span> <span style="color: #bd93f9;">100</span>% <span style="color: #ff79c6; font-weight: bold;">from</span> <span style="color: #bd93f9;">20mm</span> <span style="color: #ff79c6; font-weight: bold;">south</span> <span style="color: #ff79c6; font-weight: bold;">of</span> B1.<span style="color: #ff79c6; font-weight: bold;">w</span>
<span style="color: #50fa7b; font-weight: bold;">X2</span>: <span style="color: #8be9fd; font-style: italic;">line</span> <span style="color: #ff79c6; font-weight: bold;">same</span> <span style="color: #ff79c6; font-weight: bold;">as</span> X1 <span style="color: #ff79c6; font-weight: bold;">from</span> <span style="color: #bd93f9;">20mm</span> <span style="color: #ff79c6; font-weight: bold;">south</span> <span style="color: #ff79c6; font-weight: bold;">of</span> B1.<span style="color: #ff79c6; font-weight: bold;">e</span>
    <span style="color: #8be9fd; font-style: italic;">arrow</span> &lt;-&gt; <span style="color: #ff79c6; font-weight: bold;">dashed</span> <span style="color: #ff79c6; font-weight: bold;">thin</span> <span style="color: #8be9fd; font-style: italic;">color</span> gray <span style="color: #ff79c6; font-weight: bold;">from</span> <span style="color: #bd93f9;">3</span>/<span style="color: #bd93f9;">4</span>&lt;X1.<span style="color: #ff79c6; font-weight: bold;">start</span>,X1.<span style="color: #ff79c6; font-weight: bold;">end</span>&gt; <span style="color: #ff79c6; font-weight: bold;">right</span> <span style="color: #ff79c6; font-weight: bold;">until</span> <span style="color: #ff79c6; font-weight: bold;">even</span> <span style="color: #ff79c6; font-weight: bold;">with</span> X2 <span style="color: #f1fa8c;">"width o wid"</span> <span style="color: #ff79c6; font-weight: bold;">above</span>
<span style="color: #50fa7b; font-weight: bold;">X3</span>: <span style="color: #8be9fd; font-style: italic;">line</span> <span style="color: #ff79c6; font-weight: bold;">thin</span> <span style="color: #8be9fd; font-style: italic;">color</span> gray <span style="color: #ff79c6; font-weight: bold;">left</span> <span style="color: #bd93f9;">100</span>% <span style="color: #ff79c6; font-weight: bold;">from</span> <span style="color: #bd93f9;">30mm</span> <span style="color: #ff79c6; font-weight: bold;">west</span> <span style="color: #ff79c6; font-weight: bold;">of</span> B1.<span style="color: #ff79c6; font-weight: bold;">n</span>
<span style="color: #50fa7b; font-weight: bold;">X4</span>: <span style="color: #8be9fd; font-style: italic;">line</span> <span style="color: #ff79c6; font-weight: bold;">same</span> <span style="color: #ff79c6; font-weight: bold;">as</span> X3 <span style="color: #ff79c6; font-weight: bold;">from</span> <span style="color: #bd93f9;">30mm</span> <span style="color: #ff79c6; font-weight: bold;">west</span> <span style="color: #ff79c6; font-weight: bold;">of</span> B1.<span style="color: #ff79c6; font-weight: bold;">s</span>
    <span style="color: #8be9fd; font-style: italic;">arrow</span> &lt;-&gt; <span style="color: #ff79c6; font-weight: bold;">dashed</span> <span style="color: #ff79c6; font-weight: bold;">thin</span> <span style="color: #8be9fd; font-style: italic;">color</span> gray <span style="color: #ff79c6; font-weight: bold;">from</span> <span style="color: #bd93f9;">3</span>/<span style="color: #bd93f9;">4</span>&lt;X3.<span style="color: #ff79c6; font-weight: bold;">start</span>,X3.<span style="color: #ff79c6; font-weight: bold;">end</span>&gt; <span style="color: #ff79c6; font-weight: bold;">down</span> <span style="color: #ff79c6; font-weight: bold;">until</span> <span style="color: #ff79c6; font-weight: bold;">even</span> <span style="color: #ff79c6; font-weight: bold;">with</span> X4 <span style="color: #f1fa8c;">"height o ht"</span> <span style="color: #ff79c6; font-weight: bold;">above</span> <span style="color: #ff79c6; font-weight: bold;">aligned</span>
<span style="color: #50fa7b; font-weight: bold;">X5</span>: <span style="color: #8be9fd; font-style: italic;">line</span> <span style="color: #ff79c6; font-weight: bold;">thin</span> <span style="color: #8be9fd; font-style: italic;">color</span> gray <span style="color: #ff79c6; font-weight: bold;">right</span> <span style="color: #bd93f9;">100</span>% <span style="color: #ff79c6; font-weight: bold;">from</span> <span style="color: #bd93f9;">30mm</span> <span style="color: #ff79c6; font-weight: bold;">east</span> <span style="color: #ff79c6; font-weight: bold;">of</span> B1.<span style="color: #ff79c6; font-weight: bold;">n</span>
<span style="color: #50fa7b; font-weight: bold;">X6</span>: <span style="color: #8be9fd; font-style: italic;">line</span> <span style="color: #ff79c6; font-weight: bold;">thin</span> <span style="color: #8be9fd; font-style: italic;">color</span> gray <span style="color: #ff79c6; font-weight: bold;">right</span> <span style="color: #bd93f9;">100</span>% <span style="color: #ff79c6; font-weight: bold;">from</span> <span style="color: #bd93f9;">5mm</span> <span style="color: #ff79c6; font-weight: bold;">south</span> <span style="color: #ff79c6; font-weight: bold;">of</span> X5.<span style="color: #ff79c6; font-weight: bold;">start</span>
    <span style="color: #8be9fd; font-style: italic;">arrow</span> &lt;-&gt; <span style="color: #ff79c6; font-weight: bold;">dashed</span> <span style="color: #ff79c6; font-weight: bold;">thin</span> <span style="color: #8be9fd; font-style: italic;">color</span> gray <span style="color: #ff79c6; font-weight: bold;">from</span> X5 <span style="color: #ff79c6; font-weight: bold;">down</span> <span style="color: #ff79c6; font-weight: bold;">until</span> <span style="color: #ff79c6; font-weight: bold;">even</span> <span style="color: #ff79c6; font-weight: bold;">with</span> X6 <span style="color: #f1fa8c;">"radius o rad"</span> <span style="color: #ff79c6; font-weight: bold;">ljust</span>
</pre>
</div>

<p>
El resultado del código anteriores es:
</p>

<div id="svg-5" onclick="toggleHidden('svg-5')" class="figure">
<div style='width:100%;margin:auto;max-width:554px;'>
<svg xmlns='http://www.w3.org/2000/svg' style='font-size:initial;' class="pikchr" viewBox="0 0 554.314 309.078">
<path d="M130.853,220.745L357.625,220.745A28.3465 28.3465 0 0 0 385.971 192.399L385.971,50.6665A28.3465 28.3465 0 0 0 357.625 22.32L130.853,22.32A28.3465 28.3465 0 0 0 102.506 50.6665L102.506,192.399A28.3465 28.3465 0 0 0 130.853 220.745Z"  style="fill:none;stroke-width:1.4472;stroke:rgb(0,0,255);" />
<circle cx="244.239" cy="121.533" r="2.16" style="fill:rgb(255,0,0);stroke-width:2.16;stroke:rgb(255,0,0);" />
<text x="244.239" y="111.453" text-anchor="middle" fill="rgb(255,0,0)" dominant-baseline="central">c</text>
<circle cx="110.809" cy="30.6225" r="2.16" style="fill:rgb(255,0,0);stroke-width:2.16;stroke:rgb(255,0,0);" />
<text x="110.809" y="20.5425" text-anchor="middle" fill="rgb(255,0,0)" dominant-baseline="central">nw</text>
<circle cx="244.239" cy="22.32" r="2.16" style="fill:rgb(255,0,0);stroke-width:2.16;stroke:rgb(255,0,0);" />
<text x="244.239" y="12.24" text-anchor="middle" fill="rgb(255,0,0)" dominant-baseline="central">n</text>
<circle cx="377.669" cy="30.6225" r="2.16" style="fill:rgb(255,0,0);stroke-width:2.16;stroke:rgb(255,0,0);" />
<text x="377.669" y="20.5425" text-anchor="middle" fill="rgb(255,0,0)" dominant-baseline="central">ne</text>
<circle cx="102.506" cy="121.533" r="2.16" style="fill:rgb(255,0,0);stroke-width:2.16;stroke:rgb(255,0,0);" />
<text x="102.506" y="121.533" text-anchor="end" fill="rgb(255,0,0)" dominant-baseline="central">w</text>
<circle cx="385.971" cy="121.533" r="2.16" style="fill:rgb(255,0,0);stroke-width:2.16;stroke:rgb(255,0,0);" />
<text x="385.971" y="121.533" text-anchor="start" fill="rgb(255,0,0)" dominant-baseline="central">e</text>
<circle cx="110.809" cy="212.443" r="2.16" style="fill:rgb(255,0,0);stroke-width:2.16;stroke:rgb(255,0,0);" />
<text x="110.809" y="212.443" text-anchor="end" fill="rgb(255,0,0)" dominant-baseline="central">sw</text>
<circle cx="244.239" cy="220.745" r="2.16" style="fill:rgb(255,0,0);stroke-width:2.16;stroke:rgb(255,0,0);" />
<text x="244.239" y="230.825" text-anchor="middle" fill="rgb(255,0,0)" dominant-baseline="central">s</text>
<circle cx="377.669" cy="212.443" r="2.16" style="fill:rgb(255,0,0);stroke-width:2.16;stroke:rgb(255,0,0);" />
<text x="377.669" y="212.443" text-anchor="start" fill="rgb(255,0,0)" dominant-baseline="central">se</text>
<path d="M102.506,234.918L102.506,306.918"  style="fill:none;stroke-width:1.4472;stroke:rgb(128,128,128);" />
<path d="M385.971,234.918L385.971,306.918"  style="fill:none;stroke-width:1.4472;stroke:rgb(128,128,128);" />
<polygon points="102.506,288.918 110.225,286.024 110.225,291.813" style="fill:rgb(128,128,128)"/>
<polygon points="385.971,288.918 378.253,291.813 378.253,286.024" style="fill:rgb(128,128,128)"/>
<path d="M106.366,288.918L382.112,288.918"  style="fill:none;stroke-width:1.4472;stroke:rgb(128,128,128);stroke-dasharray:7.2,7.2;" />
<text x="244.239" y="277.753" text-anchor="middle" fill="rgb(128,128,128)" dominant-baseline="central">width o wid</text>
<path d="M74.16,22.32L2.16,22.32"  style="fill:none;stroke-width:1.4472;stroke:rgb(128,128,128);" />
<path d="M74.16,220.745L2.16,220.745"  style="fill:none;stroke-width:1.4472;stroke:rgb(128,128,128);" />
<polygon points="20.16,22.32 23.0544,30.0384 17.2656,30.0384" style="fill:rgb(128,128,128)"/>
<polygon points="20.16,220.745 17.2656,213.027 23.0544,213.027" style="fill:rgb(128,128,128)"/>
<path d="M20.16,26.1792L20.16,216.886"  style="fill:none;stroke-width:1.4472;stroke:rgb(128,128,128);stroke-dasharray:7.2,7.2;" />
<text x="20.16" y="110.367" text-anchor="middle" fill="rgb(128,128,128)" transform="rotate(90 20.16,121.533)" dominant-baseline="central">height o ht</text>
<path d="M414.317,22.32L486.317,22.32"  style="fill:none;stroke-width:1.4472;stroke:rgb(128,128,128);" />
<path d="M414.317,50.6665L486.317,50.6665"  style="fill:none;stroke-width:1.4472;stroke:rgb(128,128,128);" />
<polygon points="450.317,22.32 453.212,30.0384 447.423,30.0384" style="fill:rgb(128,128,128)"/>
<polygon points="450.317,50.6665 447.423,42.9481 453.212,42.9481" style="fill:rgb(128,128,128)"/>
<path d="M450.317,26.1792L450.317,46.8073"  style="fill:none;stroke-width:1.4472;stroke:rgb(128,128,128);stroke-dasharray:7.2,7.2;" />
<text x="450.317" y="36.4932" text-anchor="start" fill="rgb(128,128,128)" dominant-baseline="central">radius o rad</text>
</svg>
</div>
<pre class='hidden'># Puntos de situación
B1: box rad 5mm color blue thin width 5cm height 3.5cm
    dot at B1.c color red "c" above
    dot at B1.nw "nw" above color red
    dot at B1.n "n" above color red
    dot at B1.ne "ne" above color red
    dot at B1.w "w" rjust color red
    dot at B1.e "e" ljust color red
    dot at B1.sw "sw" rjust color red
    dot at B1.s "s" below color red
    dot at B1.se "se" ljust color red

# Acotaciones de ancho, alto y radio
X1: line thin color gray down 100% from 20mm south of B1.w
X2: line same as X1 from 20mm south of B1.e
    arrow &lt;-&gt; dashed thin color gray from 3/4&lt;X1.start,X1.end&gt; right until even with X2 "width o wid" above
X3: line thin color gray left 100% from 30mm west of B1.n
X4: line same as X3 from 30mm west of B1.s
    arrow &lt;-&gt; dashed thin color gray from 3/4&lt;X3.start,X3.end&gt; down until even with X4 "height o ht" above aligned
X5: line thin color gray right 100% from 30mm east of B1.n
X6: line thin color gray right 100% from 5mm south of X5.start
    arrow &lt;-&gt; dashed thin color gray from X5 down until even with X6 "radius o rad" ljust
</pre>
</div>

<p>
Y como se puede apreciar para dibujar se utilizan comandos como <code>right</code>,
<code>up</code>, <code>down</code>, <code>left</code>, es decir: derecha, abajo, arriba, izquierda. Y las
cosas se sitúan <code>south</code>, <code>north</code>, <code>east</code>, <code>west</code>, es decir: al sur, al norte,
al este o al oeste de un punto. También podemos situarnos en
fracciones de la distancia entre dos puntos utilizando la notación:
</p>

<pre class="example" id="orgd4806c6">
fracción&lt;punto1,punto2&gt;
</pre>
</div>
</div>
<div id="outline-container-org5232093" class="outline-2">
<h2 id="org5232093">Conclusiones</h2>
<div class="outline-text-2" id="text-org5232093">
<p>
No hay nada como leerse la documentación y mirar todos los ejemplos
que he podido encontrar. Creo que aún no he conseguido sacar toda la
chicha que tiene el asunto.
</p>

<p>
En fin, <code>pikchr</code> me parece una herramienta bastante completa. Se asemeja
a poder dibujar un <code>SVG</code> a partir de instrucciones simples, aunque no
tiene todas las cosas que permite un <code>SVG</code>. Por ejemplo, no soporta
gradientes o colores con canal alfa. Para la muchas de las cosas que
debo dibujar me facilita la vida y si necesito esas otras cosas que no
me proporciona, siempre puedo modificar el resultado desde <i>Inkscape</i>,
por ejemplo, para añadirle fórmulas <i>LaTeX</i>.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Tengo un amigo que lo llama <b>secta</b>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Si pinchas en el gráfico verás el código fuente que lo ha generado. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/pikchr/index.html">pikchr</a> <a href="/tags/gráficos/index.html">gráficos</a> ]]></description>
  <category><![CDATA[pikchr]]></category>
  <category><![CDATA[gráficos]]></category>
  <link>https://notxor.nueva-actitud.org/2024/09/30/graficos-con-pikchr.html</link>
  <pubDate>Mon, 30 Sep 2024 09:19:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Tcl/Tk alcanza su versión mayor 9.0]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2024-09-27</div>
<p>
Pues nada, esto será una entrada muy cortita. Ya he comentado por este
<i>blog</i> que suelo utilizar <i>Tcl/Tk</i> como mi lenguaje de <i>script</i> favorito,
por razones que no vienen al caso. Lo  importante hoy es que con ficha
de 26 de septiembre de 2024, <i>Tcl</i> ha sacado la versión 9.0 anunciándolo
en su página web <a href="https://wiki.tcl-lang.org/">https://wiki.tcl-lang.org/</a>
</p>

<p>
Las mejoras que anuncia la versión 9.0 sobre la 8.6 (la anterior
versión) son las siguientes:
</p>

<ul class="org-ul">
<li><b>Tcl 9.0</b>:

<ul class="org-ul">
<li><b>Capacidad de 64 bits</b>: Los datos pueden alcanzar los 2Gb.</li>
<li><b>Unicode y Encodings</b>: soporte completo para Unicode.</li>
<li><b>Sistema de archivos en Zip</b>: soporta montar archivos <i>Zip</i> como
sistemas de ficheros.</li>
<li><b>Distribución de ejecutables</b>: Facilidad para la distribución
binaria de ejecutables que funcionen sin necesidad de instalar o
tener instalado <i>Tcl/Tk</i> en la máquina cliente; tanto para <code>tclsh</code> en
ejecutables para consola como para ejecutables <code>wish</code> de entornos
gráficos.</li>
<li><b>Notificadores nuevos</b>: El sistema de manejo de eventos de <i>Tcl</i> ahora
está construido encima del sistema de llamadas.</li>
</ul></li>

<li><b>Tk 9.0</b>:

<ul class="org-ul">
<li><b>Acceso a utilidades del SO</b>: notificaciones, impresora, <i>tray icon</i>,
etc.</li>
<li><b>Scalable Vector Graphics</b>: soporte parcial para imágenes <code>svg</code>,
extendiendo su uso a <i>widgets</i> escalables en la apariencia de los
temas de <i>Tk</i>.</li>
<li><b>Imágenes</b>: Acceso total a metadatos y al canal alfa.</li>
<li><b>Características y propiedades según la plataforma</b>: soporte, al
menos parcial, para pantallas táctiles, para gestos con dos dedos,
etc.</li>
</ul></li>
</ul>

<p>
A modo de resumen, si no te suena qué es el lenguaje <i>Tcl/Tk</i> te puedo
contar que es un lenguaje de <i>script</i>, bastante potente. Si alguna vez
te has preguntado por qué <i>SQLite</i> guarda todos los datos como cadenas,
te diré que esa base de datos nació para ser utilizada en <i>Tcl/Tk</i> y
sigue la misma filosofía: todos los datos en <i>Tcl</i> son cadenas de texto.
También es posible que te suene <i>Tkinter</i> como el entorno gráfico que
viene en las librerías de <i>Python</i> o en las de <i>Perl</i>, que no dejan de ser
<i>Tk</i>.
</p>

<p>
Y por terminar con el <i>ecosistema</i> del <i>chismático</i>. El creador de <i>SQLite</i>
también creó un sistema de control de versiones para <i>SQLite</i> que se
llama <i>Fossil</i>. Un sistema de control de versiones del que ya he hablado
por aquí también, que proporciona <i>wiki</i>, foro, seguimiento de etiquetas
y errores, <i>chat</i>, documentación, y que te permite utilizar un
subconjunto del lenguaje <i>Tcl</i> en los repositorios, para que añadas lo
que te falte.
</p>

<p>
Si tienes curiosidad por cómo es el código de dicho lenguaje, puedes
ver en este <i>blog</i> un ejemplo completo de la implementación del
algoritmo <i>RSA</i> con dicho lenguaje, mira en la etiqueta <a href="https://notxor.nueva-actitud.org/tags/criptografia/index.html">Criptografia</a>.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/tcl/index.html">tcl</a> <a href="/tags/tk/index.html">tk</a> ]]></description>
  <category><![CDATA[tcl]]></category>
  <category><![CDATA[tk]]></category>
  <link>https://notxor.nueva-actitud.org/2024/09/27/tcl-tk-alcanza-su-version-mayor-9-0.html</link>
  <pubDate>Fri, 27 Sep 2024 13:05:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Perspectiva isométrica]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2024-09-03</div>
<p>
Hace tiempo que los juegos dieron el salto al 3D cada vez más juegos,
cada vez más realistas. Antes de eso, debíamos conformarnos con
simulaciones hechas sobre 2D: me refiero a los juegos a base de
<i>mosaicos isométricos</i>. O lo que tradicionalmente se ha llamado
<i>isométrico</i>, pues en realidad no lo es y lo veremos en adelante. Los
juegos de estrategia de la época utilizaban este tipo de
representación para dar la sensación de tener un despliegue de lo que
fuera en perspectiva. Hay juegos modernos, que aun siendo verdaderos
juegos 3D utilizan una cámara ortográfica situada de manera que
proporcionan una sensación equiparable a los juegos tradicionales.
</p>

<p>
Hoy vengo a <i>cansinar</i> con el tema y traigo algo de código para
trastear.  Primero veremos un poco sobre perspectivas, aunque no sea
de manera exhaustiva, sí me gustaría explicar cuatro tipos de
perspectiva<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>
<div id="outline-container-org161fdc0" class="outline-2">
<h2 id="org161fdc0">Perspectivas</h2>
<div class="outline-text-2" id="text-org161fdc0">
<table><tr><td>


<figure id="org6b84035">
<img src="./imagenes/Perspectiva_01.svg" alt="Perspectiva_01.svg" class="org-svg">

<figcaption><span class="figure-number">Figura 1: </span>Imagen de proyección oblicua <i>caballera</i>.</figcaption>
</figure>

</td><td>


<figure id="org7a5ccc9">
<img src="./imagenes/Perspectiva_08.svg" alt="Perspectiva_08.svg" class="org-svg">

<figcaption><span class="figure-number">Figura 2: </span>Imagen de proyección isométrica.</figcaption>
</figure>

</td></tr><tr><td>


<figure id="org6e997b4">
<img src="./imagenes/Perspectiva_10.svg" alt="Perspectiva_10.svg" class="org-svg">

<figcaption><span class="figure-number">Figura 3: </span>Imagen de proyección dimétrica.</figcaption>
</figure>

</td><td>


<figure id="org10f3660">
<img src="./imagenes/Perspectiva_17.svg" alt="Perspectiva_17.svg" class="org-svg">

<figcaption><span class="figure-number">Figura 4: </span>Imagen de proyección trimétrica.</figcaption>
</figure>

</td></tr></table>

<p>
Las <i>vistas</i> en cada perspectiva tratan de representar los objetos de
una forma más o menos realista. No hace falta decir que la perspectiva
más realista para nuestro ojo es la <i>perspectiva cónica</i> o <i>3D</i> pura. Sin
embargo, el problema de esta representación es que es complicado
establecer una escala fácilmente dimensionable. Por eso, en la
representación de sólidos más técnica se suelen utilizar aquellas
otras representaciones que permiten acomodar una escala para poder
<i>medir</i> correctamente las dimensiones del objeto. Es decir, se utilizan
las proyecciones <i>ortométricas</i> como las cuatro que vemos arriba.
</p>

<p>
En la <a href="#org6b84035">Figura 1</a> podemos observar una <i>perspectiva oblicua</i>, se llaman así
porque presentan una vista desde un lado, manteniendo la escala fija
en dos ejes. En la figura podemos observar que los ejes <code>y</code> y <code>z</code> se han
colocado a 90°. Ambos mantendrán una escala proporcional a lo largo de
todo el eje. El oblicuo <code>x</code> se representa con una escala proporcional.
En este caso, se presenta a 135° con respecto a los otros dos, pero
también pueden utilizarse ángulos múltiplos de 30° y 45°, dejando de
lado los 90°, 180°, 270° y 360° (por razones obvias). La escala de
reducción en el eje <code>x</code> dependerá también del ángulo seleccionado, los
valores habituales son 1:2, 2:3 ó 3:4.
</p>

<p>
La ventaja de la <i>perspectiva isométrica</i> (<a href="#org7a5ccc9">Figura 2</a>) es que al repartir
el espacio en tres ángulos de manera equitativa (120º), todos los
desplazamientos en cualquiera de los ejes tiene la misma escala.  Este
tipo de proyección es bastante utilizada en representaciones de
instalaciones de fontanería, de gas, eléctricas, donde se puede
representar toda la habitación a escala.  Tradicionalmente ha dado
nombre a la representación gráfica de algunos juegos donde se simula
un mundo 3D en la pantalla.
</p>

<p>
Sin embargo, la realidad es que este tipo de juegos utilizan una
<i>perspectiva dimétrica</i> (<a href="#org6e997b4">Figura 3</a>). En general, esta perspectiva
mantiene equivalente la escala en dos ejes, teniendo un factor de
reducción para el tercero. La utilización de este tipo de perspectiva
en los videojuegos es por una razón de cálculo y vistosidad. Los
ángulos que se muestran en la figura pueden variar, sin embargo,
manteniendo esos que aparecen en la figura, tenemos un desplazamiento
en horizontal que es el doble del desplazamiento en vertical. Es
decir, desplazarse en <code>x</code> o en <code>y</code> sobre la pantalla mantiene una
proporción de 2:1. En pantalla, por cada <i>pixel</i> que se avance en
vertical, se deberán avanzar dos en horizontal para un desplazamiento
equivalente. Para los cálculos también es una escala adecuada: todos
sabemos lo rápido que es para un ordenador (<i>binario</i>) multiplicar o
dividir por 2.
</p>

<p>
Por último, el la <a href="#org10f3660">Figura 4</a> se representa una perspectiva en la que los
tres ejes mantienen proporciones distintas y por lo tanto hay que
aplicarle a cada uno su factor de reducción correspondiente.
</p>
</div>
</div>
<div id="outline-container-org26ff6b2" class="outline-2">
<h2 id="org26ff6b2">Texturas y píxeles</h2>
<div class="outline-text-2" id="text-org26ff6b2">
<p>
Para no perder mucho tiempo haciendo texturas para las pruebas, he
hecho algunas muy básicas, aunque también podría haber descargado <a href="https://www.kenney.nl/assets/isometric-blocks">un
paquete de texturas ya hecho</a>, he preferido hacerlo yo todo. Para ello
he utilizado como editor <a href="https://krita.org/es/">Krita</a>, que cada vez que lo abro me gusta más
y prácticamente me ha hecho replantearme el desinstalar <i>Gimp</i>.
</p>


<figure id="orgd255889">
<img src="./imagenes/captura-pixelart.png" alt="captura-pixelart.png">

<figcaption><span class="figure-number">Figura 5: </span>Captura de pantalla de <i>Krita</i> haciendo de editor <i>Pixelart</i>. Se puede apreciar la ratio 2:1 de los mosaicos.</figcaption>
</figure>

<p>
He creado dos teselas básicas, una verde y otra ocre, para hacer las
pruebas. Sobre las dimensiones básicas de 128 \(\times\) 64 he añadido
10 de alto, para dar un poco de profundidad.
</p>


<figure id="orgc3802c8">
<img src="./imagenes/tesela-dimensiones.svg" alt="tesela-dimensiones.svg" class="org-svg">

<figcaption><span class="figure-number">Figura 6: </span>Tesela verde con sus dimensiones.</figcaption>
</figure>

<p>
Además, en los laterales he dejado a propósito un píxel de margen por
cada lado, para que al dibujarlos los límites de cada tesela sean más
evidentes. En muchos juegos se intenta eliminar ese efecto de rombos
para mejorar la sensación de continuidad del mundo, pero en este caso
prefiero mostrar las separaciones de manera didáctica.
</p>

<p>
Antes de nada comenzaremos con una representación de texturas en un
mundo plano con vista cenital.
</p>
</div>
<div id="outline-container-orga0d591b" class="outline-3">
<h3 id="orga0d591b">Sobre los ejes</h3>
<div class="outline-text-3" id="text-orga0d591b">
<p>
En un mundo plano, en 2D, hacer coincidir los puntos del mundo virtual
con los puntos de la pantalla, pasa por un simple cambio de
coordenadas. Debemos cambiar el origen y también el signo o sentido
de los desplazamientos en el eje <code>y</code>. Sin embargo, las direcciones
seguirán siendo las mismas: <i>horizontal</i> y <i>vertical</i>. Por tanto, la
representación de algo 2D en pantalla es sencillo.
</p>


<figure id="org2d5f467">
<img src="./imagenes/ejes-coordenadas.svg" alt="ejes-coordenadas.svg" class="org-svg">

<figcaption><span class="figure-number">Figura 7: </span>Ejes de coordenadas. El sistema cartesiano a la izquierda y la representación en pantalla a la derecha.</figcaption>
</figure>

<p>
En los sistemas de coordenadas cartesianas podemos representar puntos
del plano mediante el eje horizontal <code>x</code>, que crece hacia la derecha y
decrece hacia la izquierda, y el eje <code>y</code>, que crece hacia arriba y
decrece hacia abajo. Este sistema permite representar también con
coordenadas negativas. Por otro lado, en la pantalla del ordenador,
los puntos vienen representados por coordenadas siempre positivas, que
en <code>x</code> crecen en horizontal hacia la derecha, como en las cartesianas,
pero en vertical, en <code>y</code>, crecen hacia abajo, al contrario que en las
cartesianas.
</p>

<p>
Si dibujamos un mosaico cuadrado, donde cada tesela tenga un lado de,
digamos, 64 píxeles, las coordenadas de pantalla se pueden calcular de
manera fácil a partir de las coordenadas de las teselas.
</p>


<figure id="orge17ff71">
<img src="./imagenes/mosaico-cuadrado.svg" alt="mosaico-cuadrado.svg" class="org-svg">

<figcaption><span class="figure-number">Figura 8: </span>Mosaico cuadrado con teselas de 64×64 píxeles.</figcaption>
</figure>

<p>
Por ejemplo, para saber dónde debe iniciarse el dibujo de la tesela
<code>(3, 2)</code>, basta multiplicar cada valor, por el ancho de la textura, –en
nuestro ejemplo 64–, de manera que debemos colocar la imagen a partir
del punto <code>(192, 128)</code> o expresado como:
</p>

<p>
\[x_p = x_t \times w_t\]
\[y_p = y_t \times h_t\]
</p>

<p>
donde:
</p>
<ul class="org-ul">
<li>\(x_p\) es la coordenada <code>x</code> en pantalla.</li>
<li>\(x_t\) es la coordenada <code>x</code> de la tesela.</li>
<li>\(y_p\) es la coordenada <code>y</code> en pantalla.</li>
<li>\(y_t\) es la coordenada <code>y</code> de la tesela.</li>
<li>\(w_t\) es el ancho de la tesela, y</li>
<li>\(h_t\) es el alto de la tesela.</li>
</ul>

<p>
Un mosaico de este tipo tiene la utilidad de servir de fondo para
dibujar encima de él otras texturas, <i>sprites</i> o animaciones. Para ello
es bastante habitual que necesitemos conocer otras posiciones o
desplazamientos en la pantalla, una de las más frecuentes es su punto
medio. Si queremos saber cuál es el punto medio de una tesela, el
cálculo será el siguiente:
</p>

<p>
\[x_p = x_t \cdot w_t + \frac{w_t}{2}\]
\[y_p = y_t \cdot h_t + \frac{h_t}{2}\]
</p>

<p>
donde:
</p>
<ul class="org-ul">
<li>\(x_p\) es la coordenada <code>x</code> en pantalla.</li>
<li>\(x_t\) es la coordenada <code>x</code> de la tesela.</li>
<li>\(y_p\) es la coordenada <code>y</code> en pantalla.</li>
<li>\(y_t\) es la coordenada <code>y</code> de la tesela.</li>
<li>\(w_t\) es el ancho de la tesela, y</li>
<li>\(h_t\) es el alto de la tesela.</li>
</ul>

<p>
El orden natural de dibujo es de izquierda a derecha y de arriba hacia
abajo. Por lo que podemos crear una <i>matriz</i> de teselas con la
información de qué textura debo cargar en cada una de ellas y con un
bucle anidado para <code>x</code> dentro de un bucle para <code>y</code>, se dibujarán todas en
el orden correcto.
</p>

<p>
Por ejemplo, utilizando <a href="https://love2d.org/">löve2D</a> podemos hacer una prueba rápida. Dejo
también el código para que lo podáis descargar de la página, lo
encontraréis el enlace más abajo al final del apartado de <b>Otras
consideraciones</b>.
</p>


<figure id="org362603d">
<img src="./imagenes/Captura_mosaico_plano.png" alt="Captura_mosaico_plano.png">

<figcaption><span class="figure-number">Figura 9: </span>Dibujo del mosaico en pantalla con löve2D</figcaption>
</figure>

<p>
Todos esos cálculos sencillos son algo más complejos cuando se trata
de echar una mirada a cómo resulta la misma matriz desde la
perspectiva isométrica. Veamos primero un esquema y haré
consideraciones a partir de esta gráfica:
</p>


<figure id="orgb406392">
<img src="./imagenes/mosaico-iso.svg" alt="mosaico-iso.svg" class="org-svg">

<figcaption><span class="figure-number">Figura 10: </span>Mosaico con teselas «isométricas»</figcaption>
</figure>

<p>
El punto <code>(0, 0)</code> ya no se encuentra en la esquina superior izquierda,
como en el modelo anterior, sino arriba, ni siquiera en el centro,
sino desplazada hacia la izquierda. ¿Cuánto? la mitad del ancho de la
tesela multiplicado por el número de filas menos uno.  Por expresarlo,
matemáticamente:
</p>

<p>
\[ x_p = (filas - 1) \times \frac{w_t}{2} \]
</p>

<p>
donde:
</p>
<ul class="org-ul">
<li>\(x_p\) es la coordenada <code>x</code> en pantalla</li>
<li>\(filas\) es el número de filas del mosaico</li>
<li>\(w_t\) es el ancho de nuestra tesela.</li>
</ul>

<p>
Es decir, la posición horizontal de una tesela, también depende del
eje <code>y</code> del mosaico y de la mitad del ancho de cada tesela ( \(w_t/2\)
). Expresado de otra manera: según se avanza la fila, para una misma
columna, la coordenada <code>x</code> en pantalla disminuye medio ancho de tesela
por cada fila.
</p>

<p>
Para dibujar el resto, a partir de ese punto inicial, si nos fijamos
en el esquema de la <a href="#orgb406392">figura 10</a>, podemos comprobar que la siguiente
tesela, la <code>(1,0)</code> se encuentra situada con un desplazamiento de medio
ancho de la textura hacia la derecha y medio alto de la textura hacia
abajo. La posición general en <code>x</code> será:
</p>

<p>
\[ x_p = x_{inicio} + \frac{w_t}{2} \]
\[ y_p = y_{inicio} + \frac{h_t}{2} \]
</p>

<p>
donde:
</p>
<ul class="org-ul">
<li>\(x_p\) es la coordenada <code>x</code> en pantalla</li>
<li>\(y_p\) es la coordenada <code>y</code> en pantalla</li>
<li>\(x_{inicio}\) es la coordenada <code>x</code> donde empezamos a dibujar</li>
<li>\(y_{inicio}\) es la coordenada <code>y</code> donde comenzamos a dibujar</li>
<li>\(w_t\) es el ancho de nuestra tesela y</li>
<li>\(h_t\) es el alto de la tesela.</li>
</ul>

<p>
Para el punto <code>(2,0)</code> nos encontramos que la fórmula quedaría:
</p>

<p>
\[ x_p = x_{inicio} + 2 \times \frac{w_t}{2} \]
\[ y_p = y_{inicio} + 2 \times \frac{h_t}{2} \]
</p>

<p>
y para el punto <code>(3, 0)</code> será:
</p>

<p>
\[ x_p = x_{inicio} + 3 \times \frac{w_t}{2} \]
\[ y_p = y_{inicio} + 3 \times \frac{h_t}{2} \]
</p>

<p>
Podríamos concluir que para la primera fila, cuya coordenada en el
mosaico es <code>0</code>, la fórmula general sería:
</p>

<p>
\[ x_p = x_{inicio} + x \times \frac{w_t}{2} \]
\[ y_p = y_{inicio} + x \times \frac{h_t}{2} \]
</p>

<p>
donde:
</p>
<ul class="org-ul">
<li>\(x_p\) es la coordenada <code>x</code> en pantalla</li>
<li>\(y_p\) es la coordenada <code>y</code> en pantalla</li>
<li>\(x_{inicio}\) es la coordenada <code>x</code> donde empezamos a dibujar</li>
<li>\(y_{inicio}\) es la coordenada <code>y</code> donde comenzamos a dibujar</li>
<li>\(x\) es el valor de la columna en el mosaico</li>
<li>\(w_t\) es el ancho de nuestra tesela y</li>
</ul>

<p>
En la fórmula anterior falta algo, ya habíamos visto que para la
primera columna, los valores de <code>x</code> disminuían. Si nos centramos en las
coordenadas de la primera tesela de la siguiente fila, el cálculo será
distinto. Para empezar, el valor de \(x_p\) disminuye, según observamos
en la <a href="#orgb406392">Figura 10</a>. Concretamente, las coordenadas de la tesela <code>(0,1)</code>
son:
</p>

<p>
\[ x_p = x_{inicio} - \frac{w_t}{2} \]
\[ y_p = y_{inicio} + \frac{h_t}{2} \]
</p>

<p>
donde:
</p>
<ul class="org-ul">
<li>\(x_p\) es la coordenada <code>x</code> en pantalla</li>
<li>\(y_p\) es la coordenada <code>y</code> en pantalla</li>
<li>\(x_{inicio}\) es la coordenada <code>x</code> donde empezamos a dibujar</li>
<li>\(y_{inicio}\) es la coordenada <code>y</code> donde comenzamos a dibujar</li>
<li>\(w_t\) es el ancho de nuestra tesela y</li>
<li>\(h_t\) es el alto de la tesela.</li>
</ul>

<p>
Como ya mostré antes, las posiciones disminuirán en su valor <code>x</code> según
aumenten las filas. La fórmula completa será:
</p>

<p>
\[ x_p = x_{inicio} + x\left(\frac{w_t}{2}\right) - y\left(\frac{w_t}{2}\right) \]
\[ y_p = y_{inicio} + x\left(\frac{h_t}{2}\right) + y\left(\frac{h_t}{2}\right) \]
</p>

<p>
Si sacamos factor común para ahorrarnos una operación de
multiplicación:
</p>

<p>
\[ x_p = x_{inicio} + (x - y) \frac{w_t}{2} \]
\[ y_p = y_{inicio} + (x + y) \frac{h_t}{2} \]
</p>

<p>
Modificando ligeramente el código que ya tenemos hecho, podemos
convertir el dibujo del mosaico plano en su representación
<i>isométrica</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.  Concretamente, para ahorrar cálculos, se han
declarado las variables globales <code>Wt2</code> que representa la mitad del ancho
de la tesela y <code>Ht2</code> que representa la mitad del alto de la
tesela. Además se declaran también las variables <code>x_inicio</code> e
<code>y_inicio</code>. En el mundo plano no hacía falta un punto de inicio, porque
se asume que era <code>(0,0)</code>.  Por supuesto, también cambian las imágenes de
las teselas:
</p>

<div class="org-src-container">
<pre class="src src-lua"><span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">x_inicio</span> = Wt2 * (ANCHO_MALLA - 1)
<span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">y_inicio</span> = 0
</pre>
</div>

<p>
Por supuesto, también se ha modificado el código para dibujar una
tesela:
</p>

<div class="org-src-container">
<pre class="src src-lua"><span style="color: #6272a4;">-- </span><span style="color: #6272a4;">Dibujar la tesela
</span><span style="color: #ff79c6; font-weight: bold;">function</span> <span style="color: #50fa7b; font-weight: bold;">dibuja_tesela</span>(<span style="color: #f8f8f2; font-weight: bold;">imagen</span>, <span style="color: #f8f8f2; font-weight: bold;">x</span>, <span style="color: #f8f8f2; font-weight: bold;">y</span>)
   <span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">xp</span> = x_inicio + (x - y) * Wt2
   <span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">yp</span> = y_inicio + (x + y) * Ht2
   love.graphics.draw(IMAGENES[imagen], xp, yp)
<span style="color: #ff79c6; font-weight: bold;">end</span>
</pre>
</div>

<p>
Un pantallazo confirma que todo marcha según lo esperado:
</p>


<figure id="org37b3472">
<img src="./imagenes/captura-mosaico-iso.png" alt="captura-mosaico-iso.png">

<figcaption><span class="figure-number">Figura 11: </span>Captura de la pantalla de löve2D dibujando el mosaico.</figcaption>
</figure>
</div>
</div>
</div>
<div id="outline-container-org406b212" class="outline-2">
<h2 id="org406b212">Otras consideraciones</h2>
<div class="outline-text-2" id="text-org406b212">
<p>
Esta es la versión muy simplificada de cómo dibujar mosaicos
«isométricos» en juegos 2D. Podemos complicar un poco más las cosas y
trabajar también en el eje <code>z</code> o para detectar el cursor:
</p>

<video width="90%" controls>
    <source src="./imagenes/mosaico-en-accion.webm" type="video/webm">
    Tu navegador no soporta la etiqueta video, comprueba que soporta el formato webm.
</video>

<p>
La detección del cursor implica otro poco de cálculo. Disculpad si no
me alargo con las explicaciones de esta fórmula, seguro que encontráis
por internet explicaciones mejores que la mía. El código añadido para
manejar el cursor es el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-lua"><span style="color: #6272a4;">-- </span><span style="color: #6272a4;">Detectar rat&#243;n
</span><span style="color: #ff79c6; font-weight: bold;">function</span> <span style="color: #50fa7b; font-weight: bold;">detecta_raton</span>()
   <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">obtener las coordenadas del cursor
</span>   <span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">xr</span> = love.mouse.getX()
   <span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">yr</span> = love.mouse.getY()
   <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">convertir las coordenadas de pantalla a tesela
</span>   <span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">xt</span> = <span style="color: #8be9fd; font-style: italic;">math</span>.<span style="color: #8be9fd; font-style: italic;">floor</span>((yr / Ht) + (xr / Wt)) - 2
   <span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">yt</span> = <span style="color: #8be9fd; font-style: italic;">math</span>.<span style="color: #8be9fd; font-style: italic;">floor</span>((yr / Ht) - (xr / Wt)) + 2
   <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">dibujar la textura de tesela seleccionada
</span>   dibuja_tesela(tesela_cursor, xt, yt)
<span style="color: #ff79c6; font-weight: bold;">end</span>
</pre>
</div>

<p>
Después en la función <code>love.draw()</code> se añade una llamada a esta función
al final, tras haber dibujado el mosaico.
</p>

<p>
Lo único que puedo aconsejaros es que juguéis un poco, si queréis
profundizar. Instalar <i>Löve2D</i> y retorcer el código fuente junto con las
imágenes utilizadas, que podéis encontrar en <a href="./imagenes/perspectivas.zip">este archivo</a>. Quizá
incluso decidiros a hacer un pequeño proyecto a partir de esa base. O
si preferís otro lenguaje u os da pereza el instalar <i>Lua</i> y <i>Löve</i>, el
código es tan sencillo que seguro podéis adaptarlo a cualquier otra
herramienta o lenguaje.
</p>

<p>
Descargar fuentes pinchando aquí → <a href="./imagenes/perspectivas.zip">perspectivas.zip</a>
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Imágenes de las proyecciones obtenidas de la wikipedia. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ya he dicho que no es <i>isométrica</i> sino <i>dimétria</i>, pero se entiende.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/juegos/index.html">juegos</a> <a href="/tags/perspectiva/index.html">perspectiva</a> ]]></description>
  <category><![CDATA[juegos]]></category>
  <category><![CDATA[perspectiva]]></category>
  <link>https://notxor.nueva-actitud.org/2024/09/03/perspectiva-isometrica.html</link>
  <pubDate>Tue, 03 Sep 2024 09:18:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Trokola en versión alfa]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2024-08-25</div>
<p>
Dije en el pasado artículo que estaba quemado con la programación y
que sentía que no volvería a programar. No mentí en ese momento, pero
al final he seguido programando. Debe ser que <i>la cabra tira al monte</i> y
no puedo evitar meterme en esos berengenales. El tema es que decidí,
al menos, alcanzar el estado alfa de la herramienta de <i>aventuras
conversacionales</i> que estaba desarrollando. Hoy cuento un poco el
asunto.
</p>
<div id="outline-container-org51cb2ea" class="outline-2">
<h2 id="org51cb2ea">¿Por qué este proyecto?</h2>
<div class="outline-text-2" id="text-org51cb2ea">
<p>
La respuesta a esta pregunta tiene varias vertientes. Por un lado, está
el hecho de la elección del lenguaje. Por otro, también podemos
preguntarnos por la necesidad de una nueva herramienta de creación de
aventuras de texto. Por último, también nos podemos preguntar por qué
hacer «aventuras de texto» y no otro tipo de juegos.
</p>

<p>
El motivo para elegir las <i>aventuras de texto</i>, también llamadas
<i>ficción interactiva</i> o <i>aventuras conversacionales</i>, obedece
a varias causas. Es necesario recordar, que la creación de esta
herramienta, aunque puede ser utilizada de manera genérica, está
enfocada a proporcionar actividades lúdico-formativas en planes de
prevención del acoso escolar. Las aventuras de texto nos proporcionan
las siguientes ventajas en ese ámbito:
</p>

<ul class="org-ul">
<li><b>Fomenta la inclusión</b>: Podemos encontrar personas con algún tipo de
déficit visual o auditivo que tienen problemas a la hora de realizar
actividades lúdicas, como un videojuego convencional. Sin embargo,
un juego basado en texto puede integrarlas, simplemente utilizando
las herramientas de accesibilidad que cualquier sistema operativo
trae ya incluidas.</li>

<li><b>Fomenta la comprensión lectora</b>: Toda la aventura se basa en
interacciones de texto, los participantes deben leer y comprender
qué está sucediendo para responder adecuadamente a las acciones de
los otros jugadores y a los eventos acaecidos en el <i>mundo virtual</i>
que se presenta.</li>

<li><b>Fomenta la imaginación</b>: Una aventura conversacional, si está bien
diseñada, produce una inmersión completa en un mundo virtual que
estando basado en descripciones de texto, es un completo ejercicio
de imaginación para los jugadores.</li>

<li><b>Crear simulaciones</b>: La <i>ficción interactiva</i> genera entornos virtuales
que pueden ser utilizados para <i>simular</i> situaciones peligrosas de la
vida real sin exponer a los jugadores al peligro.</li>
</ul>

<p>
Existen en la actualidad un montón de herramientas para la creación de
este tipo de <i>aventuras</i> y quizá se podría haber utilizado otra
cualquiera con los mismos objetivos. Sin embargo, se nos presentarían
problemas de difícil solución:
</p>

<ul class="org-ul">
<li><b>Ficción interactiva</b>: La mayor parte de las herramientas de ficción
interactiva están enfocadas al juego individual. Algunas, como
<i>AGE</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, sí tienen en cuenta el modo multijugador, pero se
encuentra abandonada desde hace años y no se puede asegurar que su
funcionamiento sea correcto.</li>

<li><b>MUD</b>: Un <i>MUD</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>, es un tipo de juego de texto, precursor de los
actuales <i>MMORPG</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>. La utilización de este tipo de juegos como
herramienta es compleja, ya que están pensados para la creación de
un mundo virtual estable que debe ser mantenida y desarrollada en el
tiempo.</li>
</ul>

<p>
En ese sentido <i>Trokola</i> proporciona un sistema que se equilibra
entre ambos aspectos. No necesita un mundo virtual infinito, sino tan
sólo lo mínimo para poder crear una aventura específica.
</p>

<p>
Por último, para la elección del lenguaje de programación se han tenido
en cuenta algunos otros aspectos:
</p>

<ul class="org-ul">
<li><p>
<b>Sencillez</b>: Se buscaba un lenguaje sencillo que pudiera ser utilizado
por cualquier persona, incluso los no programadores. La máxima de
<i>Tcl/Tk</i> es <b>«todo es texto»</b>. Cualquier expresión se trata como
texto. Tanto el código como los datos son texto puro, lo que los
hace también intercambiables.
</p>

<p>
Otra de las características del lenguaje es la <i>homoiconicidad</i> es
decir, toda la sintaxis del mismo presenta una
estructura idéntica, en el formato:
</p>

<div class="org-src-container">
<pre class="src src-tcl">comando arg1 arg2 ... argN
</pre>
</div></li>

<li><b>Multiparadigma</b>: Es un lenguaje que puede ser utilizado de diversas
maneras, tanto desde un enfoque <i>funcional</i>, como desde un enfoque de
lenguaje orientado a objetos o <i>procedural</i>.</li>

<li><b>Gráfica</b>: El lenguaje <i>Tcl</i>, proporciona a su vez un conjunto de
instrucciones gráficas mediante <i>Tk</i>, (el <i>Tool Kit</i> de <i>Tcl</i><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>) que
permite la creación de <i>GUIs</i><sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>. Un posible proyecto futuro sería
alejar a los usuarios de <i>la temida</i> consola de comandos y de otros
detalles como las conexiones a través de la red. O proporcionar una
herramienta gráfica que permita crear un mundo básico rellenando
algunos formularios en una ventana.</li>

<li><b>Multiplataforma</b>: El lenguaje y sus librerías se pueden instalar en
cualquier sistema operativo: <i>GNU/Linux</i>, <i>Windows®</i>, <i>MacOS®</i> o, incluso,
<i>Android®</i> a través de <i>Termux</i>. En el primero es bastante habitual
encontrárselo ya instalado, y el los demás es muy sencillo de
instalar.</li>
</ul>

<p>
Toda la herramienta se ha programado sin recurrir a dependencias de
librerías externas, de tal manera que teniendo instalado el lenguaje y
teniendo el código fuente de <i>Trokola</i>, no se necesita instalar más.
</p>

<p>
<i>Trokola</i> proporciona dos elementos principales. Por un lado,
tenemos el <i>servidor</i> y por otro la <i>simulación de mundo</i>.
</p>

<ul class="org-ul">
<li><b>El servidor</b>: Este es un programa centralizado en la red que
proporciona interacción a través de comandos de los usuarios. Por
tanto, su función principal es responder a las peticiones de los
usuarios conectados según el modelo de mundo cargado.</li>

<li><p>
<b>El mundo</b>: Es una abstracción generada por código, de hecho toda la
información está contenida en un <i>diccionario</i>, que es un tipo de
conjunto de datos que se expresa mediante pares <code>clave</code>-<code>valor</code>. El
<i>modelo de mundo</i> que proporciona <i>Trokola</i> es muy básico. Permite
separar el mundo en <i>localidades</i>, es decir, son entidades que
representan porciones de espacio que pueden contener otras entidades
en su interior. Las interacciones básicas con las localidades es la
posibilidad de desplazar a los personajes por ellas, creando la
sensación de movimiento.
</p>

<p>
Otro de los elementos básicos que proporciona el modelo básico de
mundo virtual es la representación de <i>objetos</i>, que son entidades con
diversas características. El subtipo más destacable son los
<i>contenedores</i>, que son entidades que pueden tener otras entidades
subordinadas.
</p>

<p>
Por último, estarían los personajes. Aunque se pueden crear
personajes por código, en <i>Trokola</i> se espera que los personajes estén
jugados por personas reales. De estos personajes podemos distinguir
dos tipos fundamentales: los jugadores base y los
administradores. La diferencia entre ambos, es la posibilidad que
tienen los administradores de interactuar con el <i>servidor</i> y no sólo
con el <i>mundo</i>.
</p>

<p>
La creación de un <i>juego</i> consiste en sobrescribir las
características del <i>mundo virtual básico</i> creando comportamientos
nuevos o modificando los ya existentes.
</p></li>
</ul>

<p>
Es complejo decidir qué acciones o características incluir en el mundo
básico. Un mundo básico, más básico, permite una mayor flexibilidad a
la hora de programar las aventuras, pero también implicará que
necesitarás picar más código para hacerlas.
</p>
</div>
</div>
<div id="outline-container-org32317af" class="outline-2">
<h2 id="org32317af">Planes futuros</h2>
<div class="outline-text-2" id="text-org32317af">
<ol class="org-ol">
<li>Creación de una <b>aventura básica</b> para probar el sistema. Consistirá
en una aventura multijugador para 3 ó 4 jugadores que sirva para
probar a fondo todas las características del sistema. Además, se
utilizará como ejemplo de programación en la documentación que
estoy escribiendo sobre cómo crear aventuras con <i>Trokola</i>.</li>
<li>Escribir la <b>documentación</b> de la herramienta. Consistirá en dos
documentos fundamentales: primero el <i>manual de usuario</i> enfocado a
la programación de aventuras sencillas a partir del mundo básico
implementado y a cómo explicar el mecanismo de juego a posibles
participantes; segundo un <i>manual del programador</i> que explique cómo
funciona la herramienta y permita a los más avanzados crear sus
propios mundos básicos o modificar el existente para completarlo o
hacer que se comporte de una manera diferente.</li>
<li>Facilitar el acceso. Siendo un servidor remoto, me planteo crear
una herramienta, bien <i>web</i> o bien mediante <i>Tk</i> para conectarse a un
juego. De manera que se pueda realizar la actividad lúdica sin
recurrir a <i>intimidantes</i><sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup> consolas de texto.</li>
</ol>
</div>
</div>
<div id="outline-container-org4496dd4" class="outline-2">
<h2 id="org4496dd4">Conclusiones</h2>
<div class="outline-text-2" id="text-org4496dd4">

<figure id="org1f8fbac">
<img src="./imagenes/Captura_repositorio-trokola.png" alt="Captura_repositorio-trokola.png">

<figcaption><span class="figure-number">Figura 1: </span>Captura de pantalla del repositorio `fossil` del proyecto.</figcaption>
</figure>

<p>
Aún queda mucho trabajo por hacer y este proyecto se lleva muchas
horas de trabajo, pero está resultando gratificante. Ahora mismo toca
ir implementando una aventura sencilla y buscar probadores que quieran
<i>jugarla</i> conmigo para ayudarme a depurar errores, corregir
<i>sorderas</i><sup><a id="fnr.7" class="footref" href="#fn.7" role="doc-backlink">7</a></sup> del mundo básico, aumentar la cantidad y calidad de los
mensajes de respuesta y, en fin, un montón de tareas que aún faltan o
son manifiestamente mejorables.
</p>

<p>
Otro proyecto futuro, que no depende sólo de mí aunque resulta
imprescindible desde mi punto de vista para esta herramienta, es su
utilización en educación/prevención en el ámbito escolar como comenté
más arriba. Me gustaría poder estudiar si esos efectos de su
utilización, que espero, son ciertos o no. Por tanto, en el futuro me
propongo hacer algunos estudios objetivos sobre su funcionalidad y
cómo podemos ajustar su uso para maximizar la efectividad del cambio
que queremos provocar en adquisición de conocimientos, hábitos
saludables o conducta ajustada.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Aetheria Game Engine</i> 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Multi-User Dungeon</i> 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Massively Multiplayer Online Rol-Playing Game</i>
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Lo utilizan otros lenguajes, como <i>Python</i> o <i>Perl</i> para programar
<i>GUIs</i>, pero es original de <i>Tcl</i>. De hecho al lenguaje se lo conoce más
como <i>Tcl/Tk</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Interfaz Gráfica de Usuario, por sus siglas en inglés. 
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
La consola de texto puede ser algo intimidante para el usuario
actual. 
</p></div></div>

<div class="footdef"><sup><a id="fn.7" class="footnum" href="#fnr.7" role="doc-backlink">7</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En una aventura conversacional se denomina <i>sordera</i> o también
<i>«síndrome de la palabra única»</i> a situaciones en las que una
determinada acción sólo puede ser disparada con una palabra, que suele
ser la más habitual para el programador. Utilizar sinónimos hasta
superar el escollo suele ser bastante frustrante para el jugador y
debería ser cubierto por el programa.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/aventuras/index.html">aventuras</a> <a href="/tags/conversacionales/index.html">conversacionales</a> <a href="/tags/tcl/index.html">tcl</a> <a href="/tags/programación/index.html">programación</a> ]]></description>
  <category><![CDATA[aventuras]]></category>
  <category><![CDATA[conversacionales]]></category>
  <category><![CDATA[tcl]]></category>
  <category><![CDATA[programación]]></category>
  <link>https://notxor.nueva-actitud.org/2024/08/25/trokola-en-version-alfa.html</link>
  <pubDate>Sun, 25 Aug 2024 10:35:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Renuncias y planteamientos]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2024-08-02</div>
<p>
Llevo unos días de <i>ganduleo</i> replanteándome algunas cosas. Hace unos
días mandé al garete el <i>proyecto serio</i> en el que estaba trabajando con
un amigo. ¿El motivo? Empecé a odiar la programación, empecé a odiar a
mi amigo y me empecé a odiar a mí mismo. ¿El motivo? Todo empezó mal,
debería haberlo cortado mucho antes. Este artículo es un intento de
expulsar demonios que aún quedan agazapados en algunos rincones de mi
mente.
</p>

<p>
Desde un punto de vista técnico, todo empezó bien. Se me había
ocurrido una idea para hacer una aplicación móvil para <i>Android®</i> que
podría incluso generar algo de dinero. Aunque el modelo de negocio no
estaba claro y no está claro aún cómo se podría ganar dinero con ello,
nos pusimos manos a la obra. Contratamos unos servicios de VPN a buen
precio y comenzamos con algunas pruebas de concepto. También adquirí
algunos <i>chismáticos hardware</i> para lo mismo.  Instalé en mi máquina el
<i>Sdk</i> de <i>Android®</i> y también el <i>Android Studio</i>, que en nuestra jerga era
llamado <i>La Mostra</i> por su avidez de tragarse todos los recursos y más
de cualquier máquina. Empezamos mirando código de cierto <i>protocolo</i> que
pensábamos utilizar para nuestra aplicación... y ahí comenzaron los
males. Me encontré fuera de lugar, en lo que se podría denominar un
<i>fuerte síndrome del intruso</i>. No me creía capaz de hacer nada con
ello. Me refugié en la lectura de documentación sobre desarrollo de
aplicaciones para móviles. Toqueteé aquí y allá con <i>la mostra</i>. ¿Era un
intruso? Quizá no, todo lo que me proponía hacer lo iba haciendo con
más o menos dificultad, como añadir algo más de funcionalidad a una
<i>ventanita</i> de una aplicación ya hecha, o estudiar cómo funcionaba el
código y (creo que) entendiéndolo.  Sin embargo, el sentimiento de
estar fuera de lugar no disminuía, sino todo lo contrario.
</p>

<p>
Todo parecía fluir hacia donde queríamos, avanzábamos ya superando las
pruebas de concepto y comenzábamos a implementar nuestro modelo.  Mi
mente comenzó a adelantar hacia dónde pensaba yo, eran las directrices
de futuro de la aplicación, lo que podrían demandar los usuarios de la
misma en el futuro y la estructura que se podría añadir a lo que
teníamos para desarrollarla en el futuro. Esas ideas las expresaba con
cierta timidez y eran recibidas con expresiones del tipo «eso no tiene
sentido ahora», «céntrate en lo importante» o «no veo que eso sea
útil». Estoy seguro de que la otra persona no lo hacía a propósito,
pero consiguió que mi <i>síndrome del intruso</i> se disparara a niveles
estratosféricos. A veces sentía, y sé que eso no era así y que se
debía a un producto residual de mis propias inseguridades, que me
trataba como si yo fuera gilipollas.  No recuerdo, en todo el
proyecto, que se aceptara una sola propuesta de las que hiciera
yo. Nada era importante, muchas veces expresado así directa y
crudamente, mis propuestas no eran útiles ni para ahora ni para el
futuro. O eso es lo que yo sentí.
</p>

<p>
Todo el proyecto comenzó a agobiarme. Me decía a mí mismo que eran
ideaciones mías, que las cosas estaban saliendo más o menos como se
esperaba, que el código que yo generaba no era especialmente malo
aunque sí manifiestamente mejorable y que con tiempo y práctica
mejoraría con <i>Java</i> y <i>Android®</i>. Lo iba capeando. Cuando estaba en los
momentos bajos, dejaba la mesa de trabajo y me sentaba en el sofá, a
relajarme, a pensar, a darle tiempo a la sensación de frustración para
que pasara y me dejara concentrarme un poco. En esos momentos me ponía
a leer o a hacer cosas que nada tuvieran que ver con programar
aplicaciones intentando encontrar la paz que me robaban <i>la mostra</i> y el
<i>Android®</i>. Cada vez me costaba más volver a sentarme a programar.
</p>

<p>
Intenté también alternar con otro proyecto personal que está(ba) a punto
de alcanzar su primera versión <i>alfa</i>. A estas alturas no sé si lo
acabaré, he empezado a rechazar la programación. Me siento dispuesto a
trabajar un poco, pero es abrir el editor y comienza la desazón.
</p>

<p>
El otro día, en un momento de esos de bajón, mi colega me hizo una
pregunta, no recuerdo ni cuál, y aunque estoy seguro que no lo hizo
con esa intención, la interpreté como una evidencia de que dudaba de
mi capacidad intelectual. Mi respuesta fue: «no quiero seguir con
esto». Podría haber dicho más, pero era un momento tan de bajón que no
hubiera sido justo con la otra persona.
</p>

<p>
¿Cómo me planteo las cosas a partir de ahora? No lo tengo claro.
Llevo unos días sin escribir una línea de código y no sé si volveré a
hacerlo. Supongo que sí, pero ahora mismo, me gusta más cacharrear y
aprender o investigar. Supongo que seguiré haciendo algunas cosas como
hasta ahora, mis <i>scripts</i>, mis programitas para mis cosas. De momento,
no me planteo nada más: seguir cacharreando, seguir investigando,
seguir aprendiendo sin agobiarme con proyectos cerrados, y mucho menos
intentando estar a la altura, de lo que creo que otros pueden esperar.
</p>

<p>
No creo que vuelva a retomar el proyecto, la idea creo que es buena y
seguramente la veremos implementada en el futuro por otras personas,
con otras herramientas o de otra manera. Desde luego, lo que tengo
claro es que la vida es muy corta para vivirla agobiado porque un día
tuviste una buena idea y no has conseguido llevarla a cabo.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2024/08/02/renuncias-y-planteamientos.html</link>
  <pubDate>Fri, 02 Aug 2024 09:39:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Configurando Emacs para trabajar en un proyecto para android]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2024-07-06</div>
<p>
Llevo tiempo desaparecido y es el momento de dar algunas explicaciones
sobre el porqué y de paso contar algo más sobre lo que estoy haciendo
y, de paso, sobre mis esfuerzos por ajustar el entorno de desarrollo
para trabajar más a mi gusto. Empezando, pues, por poner algo de
cordura en mi actividad, ahora prácticamente diaria, como programador
para <i>Android®</i>. Y sí, no nos vamos a engañar, el <i>Android
Studio®</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> trae integrado todo lo que necesita un programador para
crear aplicaciones para este S.O. y <i>Emacs</i> se queda corto en
funcionalidades. Sin embargo, la gran cantidad de recursos necesarios
para ejecutar <i>«la mostra»</i>, te obligan a estar muy actualizado en
<i>hardware</i>. Hoy contaré cómo podemos ahorrarnos un poco de máquina con
la línea de comandos y nuestro editor favorito. He hecho pruebas con
<i>Emacs</i> sin, y con, <code>eglot</code>, encontrando algunas diferencias en el
método de trabajo de ambos modos.
</p>
<div id="outline-container-org2bf5065" class="outline-2">
<h2 id="org2bf5065">Tareas fundamentales</h2>
<div class="outline-text-2" id="text-org2bf5065">
<p>
Podemos desglosar las tareas fundamentales en las básicas para
cualquier proyecto de <i>software</i>:
</p>

<ul class="org-ul">
<li>Escribir código</li>
<li>Compilar</li>
<li>Probar el resultado</li>
</ul>

<p>
¿Podemos hacerlo todo sin recurrir a <i>«la mostra»</i>? eeeeeh, nos vamos
apañando, sí. Desde luego es mucho más cómodo entrar por el aro, mirar
a otro lado y arrancar la devoradora de recursos infinitos. Pero,
tenemos que recordar que copará, en poco rato un montón de <i>Gigas</i> de
memoria, la <code>swap</code> y lo que se tercie. De momento mi máquina aguanta
el asalto, mueve <i>la mostra</i> con soltura, pero soy consciente de que
en una o dos versiones más, no podrá con todo eso. Tirar del <i>Studio</i>
pronto será inviable y me voy curando en salud tirando más
directamente del <i>Sdk</i> desde línea de comandos.
</p>

<p>
En la lista anterior he obviado el asunto de mantener un repositorio
de código o depurar y perfilar la aplicación para hacerla más
eficiente y carente de errores. Sin olvidar tampoco todo lo referido a
documentación. Es decir, me voy a centrar en las tareas de
programación pura y dura. Para alguna de estas tareas, <i>Emacs</i> tiene
herramientas muy superiores a las que proporciona <i>«la mostra»</i>, como
<code>Magit</code> para trabajar el repositorio de código u <code>org-mode</code> para
trabajar la documentación.
</p>

<p>
Muchas otras herramientas vienen a ayudar también, como <code>projectile</code>
para la gestión de proyectos, o <code>ivy</code> + <code>company</code> para el completado,
o <code>flymake</code> para la comprobación de errores, o <code>xref</code> para saltar a la
definición de variables y funciones, o <code>yasnippet</code> para la creación
asistida de módulos, clases y métodos. Por último, las pruebas con
<code>eglot</code> y <code>eglot-java</code>, para tener a mano las características tan <i>de
moda</i> de <code>LSP</code>.
</p>
</div>
<div id="outline-container-org00909ab" class="outline-3">
<h3 id="org00909ab">Escribir código</h3>
<div class="outline-text-3" id="text-org00909ab">
<p>
Para escribir código sólo se necesita un buen editor con unas pocas
características. La fundamental: el coloreado de sintaxis, para que
las características del texto nos salten a la vista. Otras cosas como
autocompletado, búsqueda de expresiones en el proyecto de trabajo,
búsqueda rápida de expresiones en el documento, varios cursores para
modificar el nombre de los elementos sólo una vez y sin errores. En
fin, toda una serie de herramientas que nos proporciona <i>Emacs</i> que
nos facilitan mucho la vida.
</p>
</div>
</div>
<div id="outline-container-orgb02edb2" class="outline-3">
<h3 id="orgb02edb2">Compilar</h3>
<div class="outline-text-3" id="text-orgb02edb2">
<p>
Sin <code>eglot</code> podemos tirar de línea de comandos gracias a la
funcionalidad que nos proporciona <code>Gradle</code> para estos entornos.
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; ./gradlew assembleOfficial
</pre>
</div>

<p>
O si quieres depurar el código:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; ./gradlew assembleDebug
</pre>
</div>

<p>
Luego veremos que con <code>eglot</code> podemos lanzar estos comandos desde
dentro de <i>Emacs</i>.
</p>
</div>
</div>
<div id="outline-container-org9418453" class="outline-3">
<h3 id="org9418453">Probar el resultado</h3>
<div class="outline-text-3" id="text-org9418453">
<p>
La forma de probar la aplicación es poder instalarla en algún
dispositivo externo para hacerlo. El emulador que viene con el <code>Sdk</code>
de  <i>Android®</i>, también necesita recursos para su ejecución.
</p>

<p>
Lanzar el emulador:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; cd ~/Android/Sdk/emulator
&gt; ./emulator -list-avids
INFO    | Storing crashdata<span style="color: #ff79c6; font-weight: bold;"> in</span>: /tmp/android-notxor/emu-crash-34.2.15.db, detection is enabled for process: 35006
Mi_cacharro_virtual_API_33
Pixel_8_API_34
&gt; ./emulator -change-language es -avd Mi_cacharro_virtual_API_33
</pre>
</div>

<p>
En el emulador podemos ver qué dispositivos tenemos preparados. En mi
caso, tengo emulados dos dispositivos, con <i>Android®</i> 13 uno (la API 33)
y con <i>Android®</i> 14 el otro (la API 34). Después, le puedes decir
qué dispositivo quieres cargar. Es recomendable que miréis en la
documentación qué parámetros se pueden ajustar, como el que utilizo de
<code>-change-language es</code> para cambiar el idioma del aparato.
</p>

<p>
Una vez arrancado el emulador, podemos cargar la aplicación en el
aparato emulado con otras sencillas instrucciones:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; cd ~/Android/Sdk/platform-tools
&gt; ./adb devices
List of devices attached
emulator-5554   device
&gt; ./adb install ~/Path/a/tu/aplicacion/mi-aplicacion-beta-debug.apk
Performing Streamed Install
Success
&gt;
</pre>
</div>

<p>
El resultado:
</p>


<figure id="org88ce560">
<img src="./imagenes/Captura_emulador_android.png" alt="Captura_emulador_android.png">

</figure>

<p>
Un inconveniente, en lo que respecta al uso de recursos, es que,
muchas veces, <i>Java</i> se queda cargado en memoria. Si no lo vas a
utilizar más veces y necesitas memoria, puedes liberar las 2GiB y
pico, casi tres, que puede llegar a ocupar con estas herramientas.
</p>

<p>
Durante la ejecución también podemos consultar los <i>logs</i> que genera
el dispositivo para seguir un poco más detalladamente qué está
haciendo. Normalmente, en el código añadimos una instrucción del
estilo:
</p>

<div class="org-src-container">
<pre class="src src-java">Log.v(<span style="color: #8be9fd; font-style: italic;">TAG</span>, <span style="color: #f1fa8c;">"@@@ Aqu&#237; el mensaje que quieras"</span>);
</pre>
</div>

<p>
Después, cuando estamos ejecutando la aplicación desde la línea de
comandos podemos hacer un seguimiento del <i>logcat</i> de la siguiente
forma:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; adb logcat -e <span style="color: #f1fa8c;">"@@@"</span>
</pre>
</div>

<p>
Filtrando por ese tipo de etiquetas nos evitamos un montón de mensajes
que el dispositivo envía al <i>log</i> y que no están relacionadas con
nuestra actividad directamente.
</p>

<p>
El proyecto aún está en fases muy preliminares y aún no ha sido
necesario el uso del depurador para cazar algún <i>bug</i>.
</p>
</div>
</div>
</div>
<div id="outline-container-org6c93cc8" class="outline-2">
<h2 id="org6c93cc8">Instalación de <code>eglot</code> y <code>eglot-java</code></h2>
<div class="outline-text-2" id="text-org6c93cc8">
<p>
Para trabajar con <i>Java</i> podemos utilizar <i>Emacs</i> como un simple
editor, es decir, coloreado de sintaxis y poco más. Sin embargo,
muchos usuarios prefieren utilizar las funcionalidades que proporciona
<i>LSP</i>.
</p>

<p>
<code>eglot</code> es un paquete interno que viene con <i>Emacs</i>, no necesitas
instalar nada para utilizarlo, pero siempre es bueno tenerlo
actualizado. Por ello, lo añadí a mi <code>init.el</code> junto con <code>eglot-java</code>
para trabajar.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> eglot
<span style="color: #8be9fd; font-style: italic;">:defer</span> t)
</pre>
</div>

<p>
Como digo, <code>eglot</code> es uno de los paquetes <i>built-in</i> de <i>Emacs</i>. Sin
embargo, el avisar de su uso en nuestro fichero de inicio hace que se
actualice y se mantenga actualizado. Este paquete funciona en
conjunción con otros que ya tienes instalados como <code>flymake</code>,
<code>yastnippets</code>, <code>eldoc</code>, <code>xref</code> o <code>project</code>.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> eglot-java
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t
  <span style="color: #8be9fd; font-style: italic;">:after</span> eglot)
</pre>
</div>

<p>
Al instalar este paquete cuando lo inicies por primera vez realiza
también la descarga del servidor <i>LSP</i> correspondiente. Si ya lo
tienes instalado, conviene que leas la documentación y que
proporciones un <code>PATH</code> válido para evitar que la realice.
</p>

<p>
No hay mucho más que detallar, a partir de ese momento lo único que
debes hacer es proporcionar un <code>hook</code> para que al abrir el modo para
<i>Java</i> se active también el <code>eglot-java-mode</code>. Y algunas combinaciones
de teclas para tener todas las funcionalidades a mano.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-hook 'java-mode-hook 'eglot-java-mode)
(<span style="color: #ff79c6; font-weight: bold;">with-eval-after-load</span> 'eglot-java
  (define-key eglot-java-mode-map (kbd <span style="color: #f1fa8c;">"C-c l n"</span>) #'eglot-java-file-new)
  (define-key eglot-java-mode-map (kbd <span style="color: #f1fa8c;">"C-c l x"</span>) #'eglot-java-run-main)
  (define-key eglot-java-mode-map (kbd <span style="color: #f1fa8c;">"C-c l t"</span>) #'eglot-java-run-test)
  (define-key eglot-java-mode-map (kbd <span style="color: #f1fa8c;">"C-c l N"</span>) #'eglot-java-project-new)
  (define-key eglot-java-mode-map (kbd <span style="color: #f1fa8c;">"C-c l T"</span>) #'eglot-java-project-build-task)
  (define-key eglot-java-mode-map (kbd <span style="color: #f1fa8c;">"C-c l R"</span>) #'eglot-java-project-build-refresh))
</pre>
</div>

<p>
Antes señalé cómo se podía compilar desde la línea de comandos
utilizando <code>gradle</code>. No estaría de más que instalaras también el
paquete <code>flymake-gradle</code>. Para llamar la compilación desde <i>Emacs</i>
teniendo <code>eglot-java</code> activado debemos llamar a
<code>eglot-java-project-build-task</code>, con la combinación <code>C-c l T</code> que
vemos en las definiciones de teclas anteriores. Cuando pregunte qué
<i>tarea</i> debe hacer, añadimos la misma coletilla que se añadía en la
línea de comandos: <code>assembleDebug</code>, <code>assembleRelease</code>... etc.
</p>

<p>
Entre la documentación recomiendan la instalación de un depurador de
<i>Emacs</i> llamado <code>dape</code>, que, como he dicho antes, no he
probado. Cuando lo haga, ya comentaré por aquí la experiencia.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> dape
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t)
</pre>
</div>
</div>
</div>
<div id="outline-container-org2c48616" class="outline-2">
<h2 id="org2c48616">Conclusiones</h2>
<div class="outline-text-2" id="text-org2c48616">
<p>
He instalado <code>eglot-java</code> más con la intención de probarlo y escribir
este artículo que con la de dejarlo. Ya he comentado en este <i>blog</i> lo
poco que me gusta <code>LSP</code> y todo lo relacionado con él. Sin embargo, son
muchos los que me preguntan por ello y cómo configurarlo. Quieren
tener <i>«la mostra»</i> pero dentro de unos límites y no les culpo.  Lo
que me gusta de <i>Emacs</i> es que todo es uniforme, todos los paquetes
funcionan de manera similar y se complementan, meter una herramienta
extraña para hacer lo que ya hacen otros paquetes, meterla con
calzador, depender de terceros, para que acabe utilizando los mismos
paquetes que ya están disponibles para <i>Emacs</i> me parece un
despilfarro de recursos, pare eso utilizas esos paquetes directamente
y te evitas <code>LSP</code>. Pero bueno, mantendré durante un tiempo <code>eglot</code>
para probarlo a fondo y si fuera el caso, ya os contaré cómo sale
todo.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Con mi socio hemos dado en llamarlo <i>«la mostra»</i> por la gran
cantidad de recursos que se necesitan para ponerlo en marcha. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/android/index.html">android</a> <a href="/tags/java/index.html">java</a> <a href="/tags/eglot/index.html">eglot</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[android]]></category>
  <category><![CDATA[java]]></category>
  <category><![CDATA[eglot]]></category>
  <link>https://notxor.nueva-actitud.org/2024/07/06/configurando-emacs-para-trabajar-en-un-proyecto-para-android.html</link>
  <pubDate>Sat, 06 Jul 2024 09:28:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[En qué ando metido, que apenas escribo en el blog]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2024-05-21</div>
<p>
Llevo unos cuantos días sin publicar nada y no es que esté ocioso. Al
contrario, me estoy saturando de proyectos a los que tengo que ir
prestando atención a ratos. Tengo varios frentes abiertos y tengo que
ir rotando los mismos para no dejar ninguno abandonado:
</p>

<ul class="org-ul">
<li>Edición de libros digitales, especialmente en <i>Esperanto</i>.</li>
<li>Programación de una herramienta para crear aventuras
conversacionales multijugador.</li>
<li>Proyecto de aplicación de gestión de grupos de motoristas para
android®.</li>
<li>Servidor de varias aplicaciones <i>corporativas</i> para <a href="https://asociacionpica.org">PICA</a>: NextCloud,
Collabora, Mastodon, XMPP, Big Blue Button, Moodle...</li>
<li>Este <i>blog</i>.</li>
</ul>

<p>
Para poner en marcha algunos de estos proyectos contraté hace poco, en
compañía de mi amigo <i>deesix</i>, tres servidores <code>vps</code> básicos para
experimentos con gaseosa.
</p>

<p>
Veamos unos pocos más de detalles.
</p>
<div id="outline-container-org5a90441" class="outline-2">
<h2 id="org5a90441">Edición de libros digitales</h2>
<div class="outline-text-2" id="text-org5a90441">
<p>
Llevo un tiempo, algunos años, editando libros digitales en
<i>Esperanto</i>. Me gusta poder leer en formato <code>epub</code> en mi <i>tablet</i> o en
mi lector de libros electrónicos, pero la oferta que hay es poca. La
mayoría los encuentras en <code>pdf</code> y los pocos que encuentras en <code>epub</code>
no están demasiado cuidados, contienen múltiples errores, e incluso,
muchas veces, el archivo no cumple con los estándares <code>epub</code>.
</p>

<p>
Lo último que estoy intentando editar es una obra de Antonio Marco
Botella sobre el movimiento esperantista en España. Un completo
resumen histórico de unas 800 páginas que la <i>Hispana Esperanta
Federacio</i> escaneó. También han trasladado mediante <code>OCR</code> esos
contenidos a un archivo <code>.doc</code>, monolítico y plagado de errores que no
ayuda a su edición. De hecho pedí que me pasaran los archivos
escaneados originales para hacer yo la conversión a algo más legible.
Las imágenes además son de una calidad pésima. Algunas se han podido
arreglar un poco con mucha paciencia, pero la mayoría son intratables,
pues parecen un escaneo de una fotocopia. En fin, si consigo toda la
información tardaré unas dos semanas en tener un libro <code>epub</code> decente.
</p>

<p>
Mientras espero, le doy a otros proyectos.
</p>
</div>
</div>
<div id="outline-container-org6bcd8b8" class="outline-2">
<h2 id="org6bcd8b8">Trókola</h2>
<div class="outline-text-2" id="text-org6bcd8b8">
<p>
Creo que ya hablé por aquí de este proyecto y debo añadir que voy
avanzando poco a poco. Para ir cumpliendo tareas, me planteé el
utilizar el clásico juego básico de Vampiro<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. En este momento
están implementadas todas las acciones necesarias para completar el
juego, excepto la corrección de un <i>bug</i> persistente en la interacción
con objetos contenedores cerrados con llave o que necesiten un objeto
para ser abiertos. Una vez arreglado ese <i>bug</i> el juego se podrá
completar.
</p>

<p>
Posteriormente, la idea es consolidar lo que ya está hecho sobre
interacción entre jugadores y la creación de una aventura sencilla
para varios jugadores. Mis primeras ideas son crear una especie de
<i>scape room</i> para tres o cuatro jugadores. Por ejemplo, estar en una
nave dañada por choque contra un asteroide que inicia la cuenta atrás
para autodestrucción y los pocos supervivientes tienen que alcanzar la
cápsula de salvamento. También lo había pensado con un barco
hundiéndose después de un ataque pirata o un pueblo en las faldas de
un volcán que entra en erupción y la lava se acerca al mismo. En todos
los casos, los puzles pueden ser muy similares, aunque la historia de
fondo sea algo distinta.
</p>

<p>
El proyecto va avanzando, aunque entre temas de trabajo y otros
proyectos se está quedando un poco rezagado. Me falta muy poco para
tener una base ya funcional —aunque supongo que plagada de errores y
<i>bugs</i> que corregir— para iniciar las pruebas. Espero encontrar
probadores para el juego conjunto y que podamos coordinar una sesión
de tres o cuatro jugadores simultáneos. No debería haber mucho
problema en montar un servidor en alguno de los <code>vps</code> que hemos
contratado.
</p>

<p>
Todo está programado en <i>Tcl</i>, e incluso los juegos que se creen irán
en este lenguaje. Estoy intentando que sea un sistema flexible, con
bastantes opciones de configuración para ajustar el comportamiento del
servidor a los gustos y/o necesidades del creador de la aventura... y
eso también está siendo una fuente de sorpresas que es necesario
desenmarañar cuando estoy intentando depurar un <i>bug</i> o un error.
</p>

<p>
De momento, está todo en un repositorio <code>fossil</code> privado. En el
futuro, cuando ya esté la cosa más avanzada, seguramente haré público
el repositorio autoalojándolo en el mismo sitio del servidor para que
se pueda descargar el código o informar de <i>bugs</i> o acceder al manual
de funcionamiento y creación de aventuras. Además de proporcionar
mecanismos para alojar aventuras de otros posibles creadores o
usuarios de la herramienta que quieran utilizarla. Aunque en principio
se pensó para montar pequeños servidores en redes locales, creo que
sería bueno que se pudieran jugar a través de Internet.
</p>
</div>
</div>
<div id="outline-container-orgeeb04ff" class="outline-2">
<h2 id="orgeeb04ff">Aplicación para motoristas</h2>
<div class="outline-text-2" id="text-orgeeb04ff">
<p>
Es otro proyecto en el que ando metido con <i>deesix</i>. Uno de los
asuntos que más gustan en el ámbito motorista es salir de vez en
cuando a <i>cazar unos huevos fritos con algo</i>. La mayor parte del
tiempo cada uno va en su moto con sus pensamientos y la interacción
suele ser por gestos, más o menos establecidos ya por la costumbre.
</p>

<p>
De un tiempo a esta parte, es muy habitual ver a bastantes motoristas
que llevan caros <i>intercomunicadores</i> para poder hablar unos con
otros. El más popular es el varato <code>v6</code>, del que yo mismo tengo un
par. Sin embargo, esas comunicaciones son limitadas por número de
intercomunicadores que se pueden sincronizar (máximo de 6), hay que
apretar el botón asignado a cada motorista con el que quieres hablar
(lo que no siempre es posible y suele ser complicado con los guantes
puestos) y a menudo se pierde la comunicación por las limitaciones de
distancia del <i>bluetooth</i>.
</p>

<p>
Mi idea es proporcionar una aplicación para el teléfono que cree un
<i>chat vozIP</i> que permita grupos más grandes y sin limitación de
distancia. Además, bastaría para conectarse un manos-libres de los que
hay para moto, que son más baratos que los <i>intercom</i>. Ya estamos
haciendo algunas pruebas con mi <i>intercom</i> cuando salgo en moto,
aunque aún no hemos podido escalarlo a grupos. La desventaja será que
gasta <i>datos</i> de la cuenta del móvil.
</p>

<p>
Otra de las funcionalidades pensada es la geolocalización de los
miembros de los grupos. Algo que puede ocurrir —de hecho ocurre muchas
veces cuando el grupo es heterogéneo—, es que los más rápidos pierdan
a los más lentos, o que algún miembro se quede descolgado por algún
problema en la moto o en el motorista. La idea es proporcionar una
manera de buscar dónde está el grupo, para que el miembro descolgado
los alcance, o que el grupo vaya a apoyar a quien se ha tenido que
detener por una avería o lo que sea que le impida continuar. Para ello
se contempla también que se puedan cargar <i>trazas</i> de la ruta desde
otras aplicaciones para que todo el mundo conozca el plan.
</p>

<p>
Todo esto, de momento, está en mantillas y esta reseña es el
<i>vaporware</i> habitual. Aunque nuestra intención es ponerla en la tienda
y sacar algo de dinero, si es posible.
</p>
</div>
</div>
<div id="outline-container-orgdb4d7c9" class="outline-2">
<h2 id="orgdb4d7c9">Servidor para PICA</h2>
<div class="outline-text-2" id="text-orgdb4d7c9">
<p>
En la <a href="https://asociacionpica.org">Asociación PICA</a>, de la que soy socio de número y para la que
colaboro en un montón de frentes, se ha planteado la necesidad de
unificar algunas cosas. Como asociación ha ido creciendo en varios
ámbitos geográficos, pero eso lo que hace es que aparezca la necesidad
de unificar criterios de formación de los miembros, de gestión de
eventos, de comunicación entre miembros del mismo capítulo e
inter-capítulos, por ejemplo para coordinar cursos, charlas
informativas, charlas formativas, etc.
</p>

<p>
En la próxima asamblea nacional, donde nos reuniremos un fin de semana
para tratar todos esos temas, la Sra. Vicepresidenta de PICA Aragón,
presentará la propuesta de montar estas herramientas, especialmente un
nodo de <i>Mastodon</i>, gestionado por nosotros, que podamos ofertar como
una <i>red social segura</i> para los menores. Si la propuesta es aceptada,
se contratará un <code>vps</code>, al que se mudará el dominio actual y en el que
se montarán bastantes más servicios de los que ahora tenemos.
</p>

<p>
De momento, estoy en la redacción de la propuesta y la presentación
para su aprobación en asamblea.
</p>
</div>
</div>
<div id="outline-container-orga03fcbf" class="outline-2">
<h2 id="orga03fcbf">Este <i>blog</i></h2>
<div class="outline-text-2" id="text-orga03fcbf">
<p>
De vez en cuando encuentro temas interesantes que se podrían tratar en
el <i>blog</i>, pero no termino de ponerme a hacerlo. Todo lo que llevo
investigado últimamente sobre estadística y <i>Análisis Big Data</i>
estaría bien recogerlo. Algunas veces con <i>R</i>, pero también con otras
herramientas... incluso con <i>Tcl/Tk</i>, al que últimamente le estoy
dando más en serio.
</p>

<p>
Otra de las cosas que me estoy planteando, después de tener contratado
tres <code>vps</code> es mudar este <i>blog</i> a un dominio propio, abandonando el
subdominio donde se encuentra en la actualidad. Supongo que romperá
algunos enlaces, aunque mi idea inicial sería que el subdominio actual
redirija al dominio que cree. Aún no tengo decidido nada, pero es
posible que en un futuro ocurra, si consigo encontrar tiempo para
hacerlo.
</p>
</div>
</div>
<div id="outline-container-orged4b37d" class="outline-2">
<h2 id="orged4b37d">Conclusiones</h2>
<div class="outline-text-2" id="text-orged4b37d">
<ol class="org-ol">
<li>No me da la vida...</li>
<li>No me da la vida...</li>
<li>Uff, no me da la vida...</li>
</ol>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Vampiro es un juego muy básico creado en 1998 por Jaume Alcazo
Castellarnau, pero que cuenta con todos los elementos básicos que se
esperan en una aventura conversacional. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2024/05/21/en-que-ando-metido,-que-apenas-escribo-en-el-blog.html</link>
  <pubDate>Tue, 21 May 2024 10:46:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Tomar notas con howm en Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2024-04-02</div>
<p>
Si pensabais que se habían acabado los paquetes de notas en <i>Emacs</i>,
estabais bastante equivocados. Hoy os traigo otro de esos paquetes
escondidos que encuentras rebuscando por <i>Melpa</i>. Esta vez, con otro
enfoque totalmente distinto, en cierto modo minimalista, o con ánimo
de minimalismo, pero bastante más visual. Un sistema completo a base
de menús y <i>buffers</i> de listados que te permiten navegar por toda la
información que guardes.
</p>

<p>
Ya he hablado muchas veces de la importancia que tiene para cualquier
actividad humana el tomar notas. La propuesta de hoy viene desde
Japón, gracias a Kazuyuki Hiraoka, que es profesor en la Universidad
de Asia (Japón), en la Facultad de Administración de Empresas,
Departamento de Ciencias de Datos. El proyecto lo comenzó en 2002, y
lo mantiene al día, por lo que cuenta con más de veinte años de
desarrollo.
</p>

<p>
El nombre de la herramienta (<code>howm</code>) proviene de la frase japonesa
<i>«Hitori Otegaru Wiki Modoki»</i> que dado mi avanzado japonés, no tengo
idea de qué significa más allá de que va sobre algo de un <i>wiki</i>. Si
atendemos a una traducción libre del inglés haciendo una traducción
aún más libre al español, sería algo así como <i>«una especie de wiki
personal útil»</i>.
</p>

<p>
El autor del <i>chismático</i> se puso a reflexionar sobre el asunto de
tomar notas y llegó a algunas conclusiones que le hicieron tomar la
resolución de ponerse a programar este paquete. Las reflexiones
vienen a ser:
</p>

<ul class="org-ul">
<li>Si no organizas las notas, leerlas es complicado.</li>
<li>Si intentas organizarlas, escribirlas es complicado.</li>
<li>La necesidad de equilibrio entre ambos es necesario.</li>
<li>«Complicado» es una clave importante. Hay una gran diferencia entre
«puedo hacerlo» y «puedo hacerlo fácilmente».</li>
</ul>

<p>
Después escribió:
</p>

<blockquote>
<p>
El punto de compromiso puede variar de una persona a otra, pero
priorizo la facilidad de escritura. He diseñado una herramienta de
notas que crea un ambiente donde uno puede anotar sin sentir la
presión de «organizarlas» y que mantiene la coherencia.
</p>
</blockquote>

<p>
Hiraoka afirma que una estructura y categorización rígidas se
convierten rápidamente en un impedimento. <b>Escribe fraccionadamente,
lee colectivamente</b> es el lema de <i>howm</i>. Partiendo de esa filosofía,
cada nota estará escrita en un archivo de texto plano, da igual si
prefieres usar <code>.txt</code>, <code>.org</code> o <code>.md</code>. Si el archivo está en el
directorio de trabajo de <i>howm</i> será accesible por él.
</p>

<p>
Lamentablemente, la herramienta está traducida sólo al francés y al
inglés y no cuenta con traducción al español.
</p>
<div id="outline-container-orgb76582a" class="outline-2">
<h2 id="orgb76582a">Instalación</h2>
<div class="outline-text-2" id="text-orgb76582a">
<p>
El código utilizado para las pruebas con algunas modificaciones
opcionales, que luego contaré, es el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> howm
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:config</span>
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> howm-home-directory <span style="color: #f1fa8c;">"~/howm/"</span>)
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> howm-directory <span style="color: #f1fa8c;">"~/howm/"</span>)
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> howm-keyword-file (expand-file-name <span style="color: #f1fa8c;">".howm-keys"</span> howm-home-directory))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> howm-history-file (expand-file-name <span style="color: #f1fa8c;">".howm-history"</span> howm-home-directory))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> howm-file-name-format <span style="color: #f1fa8c;">"%Y/%m/%Y-%m-%d-%H%M%S.txt"</span>))
</pre>
</div>

<p>
Todo muy sencillo de entender: se pide el paquete <code>howm</code> y se
establece un directorio de trabajo, en mi caso <code>~/howm/</code>. También un
archivo con las claves o etiquetas y otro archivo con el
histórico. Ambos archivos ocultos en el directorio de trabajo, para
que <code>howm</code> los ignore en las búsquedas y los utilice sólo cando pides
las claves o el histórico. La última línea es el formato del nombre
del fichero cuando se crea una nota.  Si te fijas, las quiero
organizadas por años y meses. Es decir, cuando creo una nota lo hará
en el directorio de su año <code>%Y/</code> y de su mes <code>%m/</code>, luego el nombre de
la nota será el habitual de <code>howm</code>. Además le doy la extensión <code>.txt</code>.
Las creo en <code>.txt</code> por defecto, porque en <code>org-mode</code> la tecla <code>C-c ,</code>
está habilitada para asignar la prioridad a un encabezado y choca, en
este caso, con <code>howm</code>. Para compensar, estoy intentando adquirir el
hábito de tener una perspectiva de <i>notas</i> abierta, con el menú
principal de <code>howm</code> abierto.
</p>

<p>
Siguiendo con la configuración, otra función que puede ser interesante
es la de nombrar los <i>buffers</i> al abrirlos con el título del mismo, en
lugar del nombre del archivo, que suele ser el numérico de la fecha,
como acabamos de ver. Para ello, se puede añadir en la configuración:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-hook 'howm-mode-hook 'howm-mode-set-buffer-name)
(add-hook 'after-save-hook 'howm-mode-set-buffer-name)
</pre>
</div>

<p>
Por mi parte, de momento mantengo los nombres numéricos. Algunas
veces, cuando hay varios apartados o encabezados en la nota, en lugar
de poner el primer título, me pone el segundo o el tercero y eso me
desconcierta más que la fecha de creación.
</p>

<p>
También se puede buscar información en otros directorios, no sólo el
de <code>howm</code> que hemos visto arriba. Ahora mismo yo lo tengo configurado
para que busque también en el directorio donde tengo las notas de
<code>denote</code> y en toda la base de datos de artículos de este <i>blog</i>.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> howm-search-path '(<span style="color: #f1fa8c;">"~/Notas"</span> <span style="color: #f1fa8c;">"~/blog/articulos"</span>))
(<span style="color: #ff79c6; font-weight: bold;">setq</span> howm-search-other-dir t)
</pre>
</div>

<p>
Las búsquedas tardan unos segundos por las miles de entradas que debe
manejar, sin embargo, la capacidad de centralizar toda la información
relevante de mi máquina hace que valga la pena esperar un momento.
</p>
</div>
</div>
<div id="outline-container-org73e2828" class="outline-2">
<h2 id="org73e2828">Ejecución y manejo</h2>
<div class="outline-text-2" id="text-org73e2828">
<p>
Primero un listado de teclas y funciones, para después meternos con
otras explicaciones sobre cómo usarlo.
</p>

<table>
<caption class="t-above"><span class="table-number">Tabla 1</span> Tabla incompleta de funciones de <code>howm</code>.</caption>

<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">tecla</th>
<th scope="col" class="org-left">función</th>
<th scope="col" class="org-left">significado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>C-c , ,</code></td>
<td class="org-left"><code>howm-menu</code></td>
<td class="org-left">Llama al menú principal.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , c</code></td>
<td class="org-left"><code>howm-create</code></td>
<td class="org-left">Crea una nota nueva.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , e</code></td>
<td class="org-left"><code>howm-remember</code></td>
<td class="org-left">Crea una nota rápida.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , I</code></td>
<td class="org-left"><code>howm-create-interactivly</code></td>
<td class="org-left">Selecciona nombre y lugar.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , D</code></td>
<td class="org-left"><code>howm-dup</code></td>
<td class="org-left">Duplica una nota.<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup></td>
</tr>

<tr>
<td class="org-left"><code>C-c , a</code></td>
<td class="org-left"><code>howm-list-all</code></td>
<td class="org-left">Lista todas las notas.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , l</code></td>
<td class="org-left"><code>howm-list-recent</code></td>
<td class="org-left">Lista las notas recientes.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , .</code></td>
<td class="org-left"><code>howm-find-today</code></td>
<td class="org-left">Lista las notas de hoy.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , :</code></td>
<td class="org-left"><code>howm-find-yesterday</code></td>
<td class="org-left">Lista las notas de ayer.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , A</code></td>
<td class="org-left"><code>howm-list-around</code></td>
<td class="org-left">Muestra la nota en contexto temporal.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , K</code></td>
<td class="org-left"><code>howm-keyword-to-kill-ring</code></td>
<td class="org-left">Copia el título de una nota.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , s</code></td>
<td class="org-left"><code>howm-list-grep-fixed</code></td>
<td class="org-left">Busca palabras clave.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , g</code></td>
<td class="org-left"><code>howm-list-grep</code></td>
<td class="org-left">Busca mediante regexp.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , o</code></td>
<td class="org-left"><code>howm-occur</code></td>
<td class="org-left">Busca dentro de una nota.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , h</code></td>
<td class="org-left"><code>howm-history</code></td>
<td class="org-left">Muestra el historial de búsquedas.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , i</code></td>
<td class="org-left"><code>howm-insert-keyword</code></td>
<td class="org-left">Inserta una clave en una nota.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , t</code></td>
<td class="org-left"><code>howm-list-todo</code></td>
<td class="org-left">Lista las cosas por hacer.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , s</code></td>
<td class="org-left"><code>howm-list-shedule</code></td>
<td class="org-left">Lista la agenda.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , T</code></td>
<td class="org-left"><code>howm-insert-dtime</code></td>
<td class="org-left">Inserta la fecha y hora actuales.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , d</code></td>
<td class="org-left"><code>howm-insert-date</code></td>
<td class="org-left">Inserta la fecha actual.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , C</code></td>
<td class="org-left"><code>howm-create-here</code></td>
<td class="org-left">Crea un encabezado con la fecha en una nota.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , r</code></td>
<td class="org-left"><code>howm-refresh</code></td>
<td class="org-left">Activa los enlaces de claves en el texto.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , R</code></td>
<td class="org-left"><code>howm-menu-refresh</code></td>
<td class="org-left">Actualiza el menú principal.</td>
</tr>

<tr>
<td class="org-left"><code>C-c , M</code></td>
<td class="org-left"><code>howm-open-named-file</code></td>
<td class="org-left">Abre un fichero (sin el modo <code>howm</code>)</td>
</tr>
</tbody>
</table>

<p>
No están todas las funciones. Por ejemplo, me he saltado las de
navegación entre notas como <code>howm-last-memo</code> o <code>howm-next-memo</code>.
Veremos mejor cómo crear notas y cómo listarlas. El sistema es
bastante visual y si, al final, necesitas las teclas de movimiento,
terminas aprendiéndotelas. Otra función que me está gustando mucho y
que no tiene tecla asignada es <code>howm-simulate-todo</code>, que permite
<i>navegar</i> la vista de tareas por hacer posicionándote en otros días
distintos a la fecha actual.
</p>


<figure id="orga284c6e">
<img src="./imagenes/Captura_primera-entrada.png" alt="Captura_primera-entrada.png">

<figcaption><span class="figure-number">Figura 1: </span>El menú principal, nada más arrancar.</figcaption>
</figure>

<p>
En la imagen se muestra el menú principal (<code>C-c , ,</code> o <code>M-x
howm-menu</code>) nada más instalar la herramienta. Al abrir este menú por
primera vez, <code>howm</code> crea un archivo en el directorio de trabajo que se
llama <code>0000-00-00-000000.txt</code>. Éste contiene el menú principal, aunque
podemos configurar otro a nuestro gusto o modificar éste para
adaptarlo a nosotros. En el mismo archivo se encuentran instrucciones
de cómo hacerlo.
</p>

<p>
Si te despista tanta cosa por el <i>buffer</i> aquí va una pequeña
descripción de lo que significa cada parte:
</p>

<ul class="org-ul">
<li>La primera línea es el título de menú. Lo vemos marcado con la
sucesión <code>&lt;&lt;&lt;</code> que indica que es una etiqueta.</li>
<li><b>Botonera</b>: Inmediatamente debajo hay una serie de botones (el texto
marcado como <code>[xxx]</code>) con su tecla rápida justo al lado.<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup></li>
<li><b>Agenda</b>: Muestra una lista de las cosas que se encuentren marcadas
como pendientes (<i>To do</i>) o como tareas de la agenda (<i>Schedule</i>).</li>
<li><b>Recientes</b>: Una lista de las notas recientes.</li>
<li><b>Aleatorias</b>: Una lista aleatoria de notas... puede que nos muestre
alguna nota que tomamos sin haberla enlazado y que no hemos vuelto a
abrir.<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup></li>
<li><b>Leyenda</b> o <b>ayuda</b>: El bloque inferior muestra instrucciones del
formato de las fechas en las notas, para que se muestren en el
bloque de <i>agenda</i> y una manera de cómo recordar más fácilmente
dicho formato.</li>
</ul>

<p>
Si quieres utilizar este ingenioso método de agenda, te sugiero que
pienses en las fechas como «peces» que nadan en las ominosas aguas del
olvido. Algunas veces, se dejan ver en la superficie y otras se
hunden. Según sea su prioridad, cuanto más alta la prioridad más
arriba nadará nuestro pez... digo mostrará el recordatorio.
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-right">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">caracter</th>
<th scope="col" class="org-right">valor</th>
<th scope="col" class="org-left">significado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>@</code></td>
<td class="org-right">1</td>
<td class="org-left">Se muestra en la agenda.<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup></td>
</tr>

<tr>
<td class="org-left"><code>+</code></td>
<td class="org-right">7</td>
<td class="org-left">Flota lentamente desde la fecha.</td>
</tr>

<tr>
<td class="org-left"><code>!</code></td>
<td class="org-right">7</td>
<td class="org-left">Se muestra con prioridad alta desde días antes de la fecha.</td>
</tr>

<tr>
<td class="org-left"><code>-</code></td>
<td class="org-right">1</td>
<td class="org-left">Aparece el día de la fecha y se hunde lentamente.</td>
</tr>

<tr>
<td class="org-left"><code>~</code></td>
<td class="org-right">30</td>
<td class="org-left">Aparece con periodicidad.</td>
</tr>

<tr>
<td class="org-left"><code>.</code></td>
<td class="org-right">&#xa0;</td>
<td class="org-left">Hundido para siempre, es el <i>punto final</i>.</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="outline-container-org067f5b1" class="outline-2">
<h2 id="org067f5b1">Escribir notas</h2>
<div class="outline-text-2" id="text-org067f5b1">
<p>
El sistema hace distinción entre «notas» y «recordatorios». Las notas
se espera que sean más extensas, tengan un título y un contenido. Se
pueden crear mediante la combinación de teclas <code>C-c , c</code> o pulsando la
<code>c</code> en el <i>buffer</i> del menú que vimos antes.
</p>


<figure id="org8844c0c">
<img src="./imagenes/Captura_crear-nota.png" alt="Captura_crear-nota.png">

<figcaption><span class="figure-number">Figura 2: </span>Ventana con la nueva nota creada.</figcaption>
</figure>

<p>
El cursor nos aparece en la primera línea que comienza con un signo
<code>=</code>. Toda línea que comience con ese signo se considerará una cabecera
y es posible crear notas con varias de esas líneas para que se
muestren de manera independiente... pero estoy adelantando
acontecimientos.
</p>

<p>
La estructura de la nota se puede modificar en la configuración
estableciendo otra plantilla, pero de momento, para las pruebas no he
modificado nada. El día de la fecha actual aparece remarcado en color
naranja y a continuación hay un enlace (remarcado en azul) a la nota
desde la que se creó esta, en el ejemplo la hemos creado desde el menú
y por tanto enlaza esta.
</p>

<p>
En el título he escrito un lacónico «Primera nota», puesto que es un
ejemplo y he añadido una frase bajo. La nota ya debería aparecer en el
apartado de <i>recientes</i> del menú<sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>.
</p>
</div>
<div id="outline-container-org8d885f3" class="outline-3">
<h3 id="org8d885f3">Lista de notas</h3>
<div class="outline-text-3" id="text-org8d885f3">
<p>
Si desde el menú mismo o con la configuración de teclas globales de
<code>howm</code> lanzamos <code>howm-list-all</code>, nos aparecerá una ventana similar a
la siguiente:
</p>


<figure id="org3b4cbf1">
<img src="./imagenes/Captura_lista-notas.png" alt="Captura_lista-notas.png">

<figcaption><span class="figure-number">Figura 3: </span>Ventana de la lista de notas</figcaption>
</figure>

<p>
Vemos que la ventana se ha dividido en dos <i>buffers</i>, el de arriba
muestra una lista con las notas que hay en nuestro sistema con el
nombre del archivo y el título al lado. El <i>buffer</i> interior muestra
el contenido de la nota y nos permite editarla, o como en este caso,
crear una nueva nota enlazando la abierta igual que hicimos antes.
</p>

<p>
Los enlaces pueden ir a títulos o a archivos completos. Para enlazar a
un título puedes colocarte en él y utilizar la combinación <code>C-c , K</code>,
eso meterá el título en el anillo de borrado (<code>kill-ring</code>), luego te
colocas donde quieras poner el enlace y teclear <code>&gt;&gt;&gt;[SPC]C-y</code> y ya lo
tienes enlazado.
</p>

<p>
Los bueno de esta visualización es que puedes navegar por las notas
del <i>buffer</i> superior con las teclas <code>n</code> y <code>p</code>. Al cambiar de nota se
visualiza en el <i>buffer</i> inferior el contenido de la nota donde te
encuentras y si ese contenido fuera muy grande, lo puedes leer sin
cambiar el cursor pulsando las teclas <code>j</code> y <code>k</code> para subir y bajar el
texto.
</p>

<p>
Si te preguntas qué significa <code>&lt;&lt;&lt;</code>, algo que seguro que te ha llamado
la atención, la respuesta es que marca una etiqueta o <i>key</i>. Es decir,
el conjunto <code>&gt;&gt;&gt;</code> marca enlaces y el conjunto <code>&lt;&lt;&lt;</code> marca etiquetas.
Una vez tienes una etiqueta, cada vez que aparezca en el texto lo
mostrará subrayado y pulsando <code>RET</code> en cualquiera de esos términos,
abrirá el listado de notas filtradas por la etiqueta.
</p>


<figure id="orgb215f40">
<img src="./imagenes/Captura_creando-etiqueta.png" alt="Captura_creando-etiqueta.png">

<figcaption><span class="figure-number">Figura 4: </span>Creando varias notas e introducciendo una etiqueta <i>Emacs</i>.</figcaption>
</figure>

<p>
Si ahora visualizamos el menú, podemos observar que cada vez que
aparece la palabra <code>Emacs</code>, ésta está subrayada con una línea
azul... lo que indica que es un enlace. Si sobre la palabra pulsamos
<i>intro</i>, nos aparecerá la lista de notas que contienen dicha etiqueta.
Si un fichero la contiene varias veces, aparecerá varias veces en el
listado.
</p>


<figure id="org9bb745a">
<img src="./imagenes/Captura_lista-por-etiqueta.png" alt="Captura_lista-por-etiqueta.png">

<figcaption><span class="figure-number">Figura 5: </span>Listado de la etiqueta <i>Emacs</i>.</figcaption>
</figure>
</div>
</div>
<div id="outline-container-org90e2e7e" class="outline-3">
<h3 id="org90e2e7e">Filtrar notas</h3>
<div class="outline-text-3" id="text-org90e2e7e">
<p>
No tenemos por qué pasar siempre por el menú. Podemos acceder
directamente a los distintos tipos de listado que proporciona <code>howm</code>.
Particularmente, el que encuentro más cómodo es el de todas las
etiquetas. Si tenemos muchas notas puede ser un listado muy largo, sin
embargo, podemos filtrar las entradas simplemente pulsando <code>f</code> en la
lista, nos aparecerá el menú de opciones de filtrado: por nombre, por
fecha, por contenido...
</p>

<p>
O más sencillamente, podemos pulsar la tecla <code>g</code> (<code>grep</code>) y tras
escribir una cadena nos mostrará las notas que contengan dicha cadena.
</p>
</div>
</div>
<div id="outline-container-orged7e822" class="outline-3">
<h3 id="orged7e822">Notas rápidas</h3>
<div class="outline-text-3" id="text-orged7e822">
<p>
Las notas rápidas son anotaciones al vuelo. Las puedes lanzar desde el
menú, pulsando <code>e</code> o desde cualquier sitio con la combinación <code>C-c ,
e</code>. Eso abrirá un <i>buffer</i> en blanco. El sistema nos añadirá un título
y la fecha cuando se creó, simplemente es algo que quieres recordar
para volver a ello más tarde y poder desarrollarlo en una nota más
elaborada. O quizá no, simplemente quieres hacer la anotación para que
lo meta en la agenda.
</p>

<p>
Por ejemplo, he abierto un <i>recordatorio</i>, en el <i>buffer</i> vacío que ha
aparecido he escrito lo siguiente:
</p>

<pre class="example" id="org5395072">
Eclipse

[2024-04-08]@ Observar un eclipse total de sol en México.
</pre>

<p>
después, he pulsado <code>C-c C-c</code> para guardarlo<sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup>. Si navegamos en la
lista de notas hasta ella veremos que a la primera línea le ha añadido
el signo <code>=</code> y ha añadido la fecha y hora cuando fue creada.
</p>


<figure id="orge1cb86b">
<img src="./imagenes/Captura_captura-recordatorio.png" alt="Captura_captura-recordatorio.png">

<figcaption><span class="figure-number">Figura 6: </span>Vista de la nota de recordatorio recién creada.</figcaption>
</figure>

<p>
Como vimos en el apartado donde hablé sobre el menú, hay un espacio
abierto para las tareas. Al añadir el recordatorio, y ser la fecha
cercana, la tarea, debería aparecer en dicho espacio.
</p>


<figure id="orgf3e4a08">
<img src="./imagenes/Captura_menu-con-recordatorio.png" alt="Captura_menu-con-recordatorio.png">

<figcaption><span class="figure-number">Figura 7: </span>Menú con la nueva tarea <i>«flotando»</i> en el mar del olvido.</figcaption>
</figure>

<p>
También podemos visualizar las anotaciones de tareas o agenda
(<i>schedule</i>) pulsando <code>y</code> en cualquier ventana de listado o menú de
<code>howm</code> o utilizando la combinación <code>C-c , y</code> desde cualquier otro
sitio. Nos mostrará todos los eventos que tengamos en la agenda
ordenados por prioridad. Más interesante que esa visualización, me
parece la que realiza llamando al comando <code>M-x howm-simulate-todo</code>.
</p>


<figure id="org55d52f5">
<img src="./imagenes/Captura_navegar-dias.png" alt="Captura_navegar-dias.png">

<figcaption><span class="figure-number">Figura 8: </span>Vista de <code>howm-simulate-todo</code>.</figcaption>
</figure>

<p>
Esta vista, ofrece más información que el simple listado de la agenda,
pues también podemos ver el valor interno de prioridad asignada por
<code>howm</code> a nuestros eventos, según la proximidad que tienen. Además se
puede navegar por los días pulsando <code>&lt;</code> y <code>&gt;</code> para retroceder y
avanzar los días y ver cómo se visualizará el listado de cosas por
hacer en dicha fecha. Para volver al día en curso, basta con pulsar
<code>=</code>.
</p>
</div>
</div>
</div>
<div id="outline-container-org0160ad7" class="outline-2">
<h2 id="org0160ad7">Conclusiones</h2>
<div class="outline-text-2" id="text-org0160ad7">
<p>
Aún no he terminado de probarlo, he hecho una importación de notas
desde <code>denote</code> a este sistema, en otro directorio y adaptando el
formato.
</p>


<figure id="org4a8cec9">
<img src="./imagenes/Captura_importacion-notas.png" alt="Captura_importacion-notas.png">

<figcaption><span class="figure-number">Figura 9: </span>El listado con más notas que visualizar.</figcaption>
</figure>

<p>
De momento, no me aclaro con la agenda... mi cerebro no procesa bien
el sistema de prioridades que utiliza el <i>chismático</i>. Aún así, ofrece
una vista completa y permite verlo todo en un simple <i>buffer</i>, acceder
a la nota donde está el asunto anotado y hacer las modificaciones de
manera rápida y sencilla.
</p>

<p>
Otra cosa que debo vigilar es mi tendencia a dejarme todos los
<i>buffers</i> abiertos. En <code>howm</code>, sin casi darme cuenta, puedo tener
cientos de ellos abiertos por mi despiste. Supongo que cuando me
acostumbre a que se visualiza todo sin necesidad de pulsar <code>RET</code>, el
número de <i>buffers</i> disminuirá significativamente. De momento, he
cogido la costumbre de abrir una <i>perspectiva</i> con el nombre de
<i>notas</i> y el menú de <code>howm</code> preparado para las consultas, aunque aún
tengo muy automatizado el acceso a las notas de <code>denote</code>. De momento,
mantengo las dos herramientas y ya decidiré en el futuro cuando tenga
más claro con cuál me es más fácil trabajar.
</p>

<p>
Pues ahí os lo dejo para que lo trasteéis.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Se puede utilizar para tener plantillas: duplicas una nota y
luego la modificas.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Para realizar una acción, podemos seleccionar el botón pulsando
<code>RET</code> sobre él, o tecleando directamente la letra resaltada junto a él. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Por darle alguna utilidad a esto, porque no alcanzo a pensar
para qué querría yo que me muestre notas al azar. De hecho, en el
mismo bloque advierte que si no lo quieres que edites el menú y lo
quites.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Es decir, si anotamos la fecha tal que <code>[2024-04-13]@3</code>, la
anotación aparecerá en el apartado de la agenda del día de la fecha al
16 del mismo mes... y luego se hundirá en el mar del olvido...
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Si no es así utiliza el comando de refrescar el menú.
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Para salir sin guardarlo, la combinación es <code>C-c C-k</code>. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/notas/index.html">notas</a> <a href="/tags/howm/index.html">howm</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[notas]]></category>
  <category><![CDATA[howm]]></category>
  <link>https://notxor.nueva-actitud.org/2024/04/02/tomar-notas-con-howm-en-emacs.html</link>
  <pubDate>Tue, 02 Apr 2024 18:01:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Visualización de iconos con nerd-icons]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2024-03-23</div>
<p>
¿Alguna vez te has preguntado por qué en modo texto los iconos no se
corresponden con los que se visualizan en la <i>GUI</i> de <i>Emacs</i>?  ¿Hay
alguna manera de aproximar la experiencia en los dos entornos: texto y
<i>GUI</i>? Pues de eso voy a hablar en este artículo, que espero que te
sea útil. Para abrir boca vamos a ver una comparativa de capturas de
pantalla de <code>all-the-icons</code> y <code>nerd-icons</code> en los dos modos señalados.
</p>

<p>
La versión <i>GUI</i>:
</p>


<figure id="orgc725d3f">
<img src="./imagenes/Captura_gui-all-the-icons.png" alt="Captura_gui-all-the-icons.png">

<figcaption><span class="figure-number">Figura 1: </span>Vista de la <i>GUI</i> utilizando <code>all-the-icons</code></figcaption>
</figure>


<figure id="orgcf11ba0">
<img src="./imagenes/Captura_gui-nerd-icons.png" alt="Captura_gui-nerd-icons.png">

<figcaption><span class="figure-number">Figura 2: </span>Vista de la /GUI utilizando <code>nerd-icons</code></figcaption>
</figure>

<p>
Y la versión <i>TTY</i>:
</p>


<figure id="orgd82a14d">
<img src="./imagenes/Captura_texto-all-the-icons.png" alt="Captura_texto-all-the-icons.png">

<figcaption><span class="figure-number">Figura 3: </span>Vista del modo consola con <code>all-the-icons</code></figcaption>
</figure>


<figure id="org7a0076f">
<img src="./imagenes/Captura_texto-nerd-icons.png" alt="Captura_texto-nerd-icons.png">

<figcaption><span class="figure-number">Figura 4: </span>Vista del modo consola con <code>nerd-icons</code></figcaption>
</figure>

<p>
Puedes apreciar que utilizar <code>nerd-icons</code> tampoco es perfecto.
Dependes, como con <code>all-the-icons</code> de fuentes externas. En el modo
<i>GUI</i> ambas se muestran perfectamente, cada una con sus <i>cadaunadas</i>.
En la consola, aunque flaquean ambas, <code>nerd-icons</code> parece comportarse
mejor que su homólogo.
</p>
<div id="outline-container-org562454f" class="outline-2">
<h2 id="org562454f">Configuración de <code>nerd-icons</code></h2>
<div class="outline-text-2" id="text-org562454f">
<p>
En el momento de escribir este artículo aún estoy de pruebas. La idea
es sustituir los paquetes de iconos, por sus equivalentes:
</p>

<ul class="org-ul">
<li><code>all-the-icons</code> por <code>nerd-icons</code></li>
<li><code>all-the-icons-dired</code> por <code>nerd-icons-dired</code></li>
<li><code>all-the-icons-ivy</code> y <code>all-the-icons-ivy-rich</code> por
<code>nerd-icons-ivy-rich</code></li>
<li><code>all-the-icons-ibuffer</code> por <code>nerd-icons-ibuffer</code></li>
</ul>

<p>
Es decir, los paquetes se corresponden unos a otros según los
utilices. Si en lugar de utilizar <code>dired-sidebar</code> para ver los
directorios, utilizar <code>treemacs</code> tendrás que configurar
<code>treemacs-nerd-icons</code> en lugar de <code>treemacs-all-the-icons</code>.
</p>

<p>
Puesto que en mi caso sólo utilizo los paquetes citados en la lista
anterior he escrito la siguiente configuración siguiendo las
instrucciones de sus repositorios:
</p>

<ul class="org-ul">
<li><p>
Configuración del paquete principal <code>nerd-icons</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> nerd-icons
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t)
</pre>
</div></li>

<li><p>
Configuración de iconos para <code>ivy</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> nerd-icons-ivy-rich
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:init</span>
  (nerd-icons-ivy-rich-mode 1)
  (ivy-rich-mode 1))

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Visualizar iconos
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> nerd-icons-ivy-rich-icon t)

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Visualiza los iconos en color
</span><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">respetando `</span><span style="color: #bd93f9;">nerd-icons-color-icons</span><span style="color: #6272a4;">'.
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> nerd-icons-ivy-rich-color-icon t)

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Tama&#241;o del icono
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> nerd-icons-ivy-rich-icon-size 1.0)

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Soporte para project
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> nerd-icons-ivy-rich-project t)

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Definitions for ivy-rich transformers.
</span><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">See `</span><span style="color: #bd93f9;">ivy-rich-display-transformers-list</span><span style="color: #6272a4;">' for details."
</span>nerd-icons-ivy-rich-display-transformers-list
</pre>
</div></li>

<li><p>
Configuración para <code>dired</code> (lo que incluye también <code>dired-sidebar</code>
como hemos visto en las imágenes del principio del artículo):
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> nerd-icons-dired
  <span style="color: #8be9fd; font-style: italic;">:hook</span>
  (dired-mode . nerd-icons-dired-mode))
</pre>
</div></li>

<li><p>
Configuración para <code>ibuffer</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> nerd-icons-ibuffer
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:hook</span> (ibuffer-mode . nerd-icons-ibuffer-mode))
</pre>
</div></li>
</ul>
</div>
</div>
<div id="outline-container-orga8f4c0b" class="outline-2">
<h2 id="orga8f4c0b">Instalación de fuentes</h2>
<div class="outline-text-2" id="text-orga8f4c0b">
<p>
Al igual que ocurría con los iconos de <code>all-the-icons</code>, necesitas
tener instaladas las fuentes para poder visualizarlos. En este caso se
utilizan los iconos que proporcionan las <a href="https://www.nerdfonts.com">fuentes de <i>Nerd fonts</i></a>. En
esa misma página encontrarás fuentes que puedes descargarte para
usarlas, por ejemplo, para configurar tu terminal. Esto lo hice, y lo
recomiendo, para mejorar la experiencia en modo texto. Para instalar
las fuentes necesarias para el modo <i>GUI</i>, la forma más cómoda es
utilizar el comando <code>nerd-icons-install-fonts</code>. Si quieres utilizar
otra fuente que no sea la que instala por defecto, deberías configurar
el paquete de la siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> nerd-icons
  (nerd-icons-font-family <span style="color: #f1fa8c;">"Fuente Nerd Icons Mono que te guste"</span>))
</pre>
</div>
</div>
</div>
<div id="outline-container-org4391ddf" class="outline-2">
<h2 id="org4391ddf">Incompatibilidades</h2>
<div class="outline-text-2" id="text-org4391ddf">
<p>
Es posible, si utilizas <code>dired-git</code> para visualizar información de los
repositorios <code>git</code> en el modo <code>dired</code> que tengas algún problema.  Esto
es porque <code>dired-git</code> depende de <code>all-the-icons</code> y es posible que al
entrar en <code>dired</code> a un repositorio se peguen un poco
<code>all-the-icons-dired</code> y <code>nerd-icons-dired</code>. Si no dependes mucho de
esa información y te gustan más los iconos de <code>nerd-icons</code> pues
desinstala <code>dired-git</code>. Si por el contrario dependes de la información
que te proporciona <code>dired-git</code> pues no instales <code>nerd-icons-dired</code>.
Es una decisión totalmente personal.
</p>
</div>
</div>
<div id="outline-container-orgf2631c2" class="outline-2">
<h2 id="orgf2631c2">Conclusiones</h2>
<div class="outline-text-2" id="text-orgf2631c2">
<p>
Como siempre, en <i>Emacs</i> no hay una sola manera de hacer las cosas:
siempre encuentras paquetes que hacen cosas parecidas y que te
permiten las mismas funciones desde <i>otro punto de vista</i>, desde <i>otra
forma de hacer las cosas</i>.
</p>

<p>
De momento seguiré probando <code>nerd-icons</code>, aunque seguramente termina
cambiando algo de su configuración. Me despistan los colores y lo
mismo encuentro alguna manera de que sea más amable para mis ojos.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2024/03/23/visualizacion-de-iconos-con-nerd-icons.html</link>
  <pubDate>Sat, 23 Mar 2024 11:22:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Texinfo: el sistema de ayuda de Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2024-03-09</div>
<p>
Los usuarios de <i>Emacs</i> están, o deberían estar, acostumbrados a
utilizar el sistema de ayuda que trae incorporado. Cuando pulsamos
<code>C-h r</code> accedemos al manual de <i>Emacs</i> en su versión <code>info</code>. Si lo
cargáramos en <code>PDF</code> sería un manual de 768 páginas. Pero no es el
único manual que viene con este editor, hay muchos más. Podemos
acceder al manual de <code>org-mode</code> (323 págs.), a una introducción a la
programación en <code>emacs-lisp</code> (286 págs.), también está el manual de
referencia de <code>emacs-lisp</code> (1.522 págs.) y muchas otras herramientas
que vienen con el propio <i>Emacs</i>, como <code>calc</code>, cuya documentación en
<code>PDF</code>, son 505 páginas. Toda esta información viene anexada como
documentación de en archivos <code>.texi</code>, es decir, en formato <i>Texinfo</i>.
En este artículo te cuento un poco qué aspecto tiene y cómo funciona,
por si lo quieres utilizar para documentar tu proyecto.
</p>
<div id="outline-container-orge365955" class="outline-2">
<h2 id="orge365955">Historia y primer vistazo al sistema de documentación</h2>
<div class="outline-text-2" id="text-orge365955">
<p>
Siempre lo he visto escrito con la «T» mayúscula y también sé, que
como ocurre con <i>TeX</i>, la letra «x» no es una equis, sino una «χ»
griega. Pero como los sonidos guturales «g» o «j» se les atraviesa a
los <i>guiris</i> en la garganta, suelen preferir pronunciar el nombre tal
que <i>TeKinfo</i>.
</p>

<p>
El sistema <i>Texinfo</i>, en la actualidad, es independiente de <i>Emacs</i>,
aunque nació para hacer la documentación de nuestro editor favorito.
Comenzó como el sistema de ayuda de <i>hipertexto</i> que incluyó Stallman
en el año 1975–1976 para documentar <i>Emacs</i> y que sirviera de ayuda al
usuario. Después, en los primeros años de la década de los 90 del
siglo pasado, se tradujo al sistema a lenguaje <code>C</code>, en dos comandos: el
<code>makeinfo</code>, que generaba la documentación y el <code>info</code>, que permitía
navegar el contenido sin necesitar un <i>buffer</i> de <i>Emacs</i>.
</p>

<p>
En 2012, se sustituyó <code>makeinfo</code> por una versión en <code>Perl</code> llamada
<code>texi2any</code>, que derivó de una implementación anterior llamada
<code>texi2html</code>, que generaba la documentación en <code>HTML</code> para poder leerla
en cualquier navegador y no depender de <code>info</code> ni de <i>Emacs</i>.
</p>

<p>
En la actualidad, los formatos que se pueden generar son los
siguientes:
</p>

<ul class="org-ul">
<li>Info: el formato de hipertexto original.</li>
<li>Texto plano.</li>
<li><code>HTML</code>: En dos formatos. El primero es una sola página con enlaces
internos, pero también podemos generarlo con una página para cada
<i>nodo</i> de documentación.</li>
<li><code>epub 3</code>: Es un formato diseñado para documentos que deben leerse en
dispositivos electrónicos.</li>
<li><code>DVI</code>: Este formato es el de salida por defecto de <i>TeX</i>. Es un
formato binario destinado a imprimir en papel, aunque también puede
visualizarse en pantalla.</li>
<li><code>PostScript</code>: es un lenguaje de descripción de página, muy popular
hace unos años gracias a las impresoras <code>postscript</code> que realizaban
la impresión mediante dicho lenguaje. También se puede visualizar en
pantalla.</li>
<li><code>PDF</code>: junto con <code>dvi</code> y <code>postscript</code> completa el trío de documentos
para <i>impresión</i>. Este es un formato popularizado por Adobe®
Systems.</li>
<li><i>LaTeX</i>: es un lenguaje de descripción de documentos. Puede
utilizarse como paso intermedio para modificar luego el aspecto de
la documentación generada.</li>
<li>DocBook: se genera un archivo <code>XML</code> compatible con el sistema
<code>DocBook</code>, que sirve para crear manuales en varios formatos.</li>
<li><code>XML</code>: al contrario que en el formato anterior, se generan unos
archivos <code>.xml</code> que no se pueden visualizar con navegadores o para
generar otro tipo de formato de documento. Se utiliza un
<code>texinfo.dtd</code> incluido en la distribución de <i>Texinfo</i> para utilizar
otras herramientas de lectura de <code>XML</code> para acceder a ellos.</li>
</ul>
</div>
</div>
<div id="outline-container-org7723f59" class="outline-2">
<h2 id="org7723f59">¿Cómo se escribe la documentación?</h2>
<div class="outline-text-2" id="text-org7723f59">
<p>
Si has utilizado con anterioridad <i>TeX</i> o <i>LaTeX</i> sabrás que cuando
quieres introducir alguna instrucción o comando utilizas el carácter
especial «\». En <i>Texinfo</i> el carácter que marca un comando es <code>@</code>.
</p>

<p>
Pongo un ejemplo simple para que se vea el formato y ahora lo comento
todo un poco más despacio. El documento que he preparado para la
prueba se llama <a href="./ejemplo.texi"><code>ejemplo.texi</code></a> (lo podéis descargar para <i>trastearlo</i>)
y el archivo generado es <a href="./ejemplo.info"><code>ejemplo.info</code></a> (también lo podéis descargar).
</p>

<div class="org-src-container">
<pre class="src src-texinfo">\input texinfo
@<span style="color: #ff79c6; font-weight: bold;">setfilename</span> ejemplo.info
@<span style="color: #ff79c6; font-weight: bold;">documentencoding</span> UTF-8
@<span style="color: #ff79c6; font-weight: bold;">documentlanguage</span> es_ES

@<span style="color: #ff79c6; font-weight: bold;">set</span> version 1.0
@<span style="color: #ff79c6; font-weight: bold;">set</span> actualizado 9 de marzo de 2024

@<span style="color: #ff79c6; font-weight: bold;">settitle</span> Mi fantabuloso manual @<span style="color: #ff79c6; font-weight: bold;">value</span>{<span style="color: #8be9fd; font-style: italic;">version</span>}

@<span style="color: #ff79c6; font-weight: bold;">copying</span>
Esto es un ejemplo cortito de un archivo Texinfo.

Copyright @<span style="color: #ff79c6; font-weight: bold;">copyright</span>{} 2024 Free Software Foundation, Inc.
@<span style="color: #ff79c6; font-weight: bold;">end</span> <span style="color: #ff79c6; font-weight: bold;">copying</span>

@<span style="color: #ff79c6; font-weight: bold;">titlepage</span>
@<span style="color: #ff79c6; font-weight: bold;">title</span> El t&#237;tulo de la documentaci&#243;n

@<span style="color: #ff79c6; font-weight: bold;">page</span>
@<span style="color: #ff79c6; font-weight: bold;">vskip</span> 0pt plus 1filll
@<span style="color: #ff79c6; font-weight: bold;">insertcopying</span>
@<span style="color: #ff79c6; font-weight: bold;">end</span> <span style="color: #ff79c6; font-weight: bold;">titlepage</span>

@<span style="color: #ff79c6; font-weight: bold;">contents</span>
@<span style="color: #ff79c6; font-weight: bold;">node</span> Top
<span style="color: #50fa7b; font-weight: bold;">@top Ejemplo
</span>Este es el manual que quiero escribir
(versi&#243;n @<span style="color: #ff79c6; font-weight: bold;">value</span>{<span style="color: #8be9fd; font-style: italic;">version</span>}, @<span style="color: #ff79c6; font-weight: bold;">value</span>{<span style="color: #8be9fd; font-style: italic;">actualizado</span>}).

@<span style="color: #ff79c6; font-weight: bold;">menu</span>
*<span style="color: #50fa7b; font-weight: bold;"> Primer cap&#237;tulo</span>::           Primer cap&#237;tulo del manual.
*<span style="color: #50fa7b; font-weight: bold;"> Segundo cap&#237;tulo</span>::          Otro cap&#237;tulo para rellenar.
@<span style="color: #ff79c6; font-weight: bold;">end</span> <span style="color: #ff79c6; font-weight: bold;">menu</span>

@<span style="color: #ff79c6; font-weight: bold;">node</span> Primer cap&#237;tulo
<span style="color: #50fa7b; font-weight: bold;">@chapter Primer cap&#237;tulo
</span>
Ahora mismo no tengo muy claro qu&#233; deber&#237;a escribir para hacer el ejemplo

Un bloque con una lista numerada:

@<span style="color: #ff79c6; font-weight: bold;">enumerate</span>
@<span style="color: #ff79c6; font-weight: bold;">item</span>
El primer &#237;tem de la lista.

@<span style="color: #ff79c6; font-weight: bold;">item</span>
El segundo &#237;tem de la lista
@<span style="color: #ff79c6; font-weight: bold;">end</span> <span style="color: #ff79c6; font-weight: bold;">enumerate</span>

@<span style="color: #ff79c6; font-weight: bold;">node</span> Primera secci&#243;n
<span style="color: #50fa7b; font-weight: bold;">@section Primera secci&#243;n
</span>
Primera secci&#243;n del primer capitulo.

Enlaces a otro nodo:

@<span style="color: #ff79c6; font-weight: bold;">itemize</span>
@<span style="color: #ff79c6; font-weight: bold;">item</span>
@<span style="color: #ff79c6; font-weight: bold;">@</span>ref@<span style="color: #ff79c6; font-weight: bold;">{</span>Segunda secci&#243;n@<span style="color: #ff79c6; font-weight: bold;">}</span> @<span style="color: #ff79c6; font-weight: bold;">result</span>{} @<span style="color: #ff79c6; font-weight: bold;">ref</span>{<span style="color: #bd93f9;">Segunda secci&#243;n</span>}

@<span style="color: #ff79c6; font-weight: bold;">item</span>
@<span style="color: #ff79c6; font-weight: bold;">@</span>xref@<span style="color: #ff79c6; font-weight: bold;">{</span>Segunda secci&#243;n@<span style="color: #ff79c6; font-weight: bold;">}</span> @<span style="color: #ff79c6; font-weight: bold;">result</span>{} @<span style="color: #ff79c6; font-weight: bold;">xref</span>{<span style="color: #bd93f9;">Segunda secci&#243;n</span>}

@<span style="color: #ff79c6; font-weight: bold;">item</span>
@<span style="color: #ff79c6; font-weight: bold;">@</span>pxref@<span style="color: #ff79c6; font-weight: bold;">{</span>Segunda secci&#243;n@<span style="color: #ff79c6; font-weight: bold;">}</span> @<span style="color: #ff79c6; font-weight: bold;">result</span>{} @<span style="color: #ff79c6; font-weight: bold;">pxref</span>{<span style="color: #bd93f9;">Segunda secci&#243;n</span>}
@<span style="color: #ff79c6; font-weight: bold;">end</span> <span style="color: #ff79c6; font-weight: bold;">itemize</span>

@<span style="color: #ff79c6; font-weight: bold;">node</span> Segunda secci&#243;n
<span style="color: #50fa7b; font-weight: bold;">@section Segunda secci&#243;n
</span>
La segunda secci&#243;n del primer cap&#237;tulo.

@<span style="color: #ff79c6; font-weight: bold;">node</span> Segundo cap&#237;tulo
<span style="color: #50fa7b; font-weight: bold;">@chapter Segundo cap&#237;tulo
</span>
Esto es el segundo cap&#237;tulo... es corto &#191;no?

@<span style="color: #ff79c6; font-weight: bold;">bye</span>
</pre>
</div>

<p>
Visionando el archivo generado a través de la ayuda de <i>Emacs</i>, la
apariencia sería así:
</p>


<figure id="org0b720ce">
<img src="./imagenes/Captura_top-ejemplo.png" alt="Captura_top-ejemplo.png">

</figure>


<figure id="org8a38043">
<img src="./imagenes/Captura_chap1-ejemplo.png" alt="Captura_chap1-ejemplo.png">

</figure>
</div>
<div id="outline-container-orge525ae0" class="outline-3">
<h3 id="orge525ae0">El formato</h3>
<div class="outline-text-3" id="text-orge525ae0">
<p>
No creo que haga falta decir que un párrafo está separado de otro
mediante una línea en blanco (o que sólo contenga espacios en blanco).
Además vemos que hay algunos comandos que son <i>entornos</i>, como en el
caso de las listas que tienen una instrucción de final, <code>@end</code>. Por
ejemplo, una lista numerada tiene la siguiente estructura:
</p>

<div class="org-src-container">
<pre class="src src-texinfo">@<span style="color: #ff79c6; font-weight: bold;">enumerate</span>

@<span style="color: #ff79c6; font-weight: bold;">item</span>
...

@<span style="color: #ff79c6; font-weight: bold;">end</span> <span style="color: #ff79c6; font-weight: bold;">enumerate</span>
</pre>
</div>

<p>
La mayoría de los comandos son familiares si has utilizado <i>LaTeX</i>.
Nos puede llamar, quizá, la atención el comando <code>@node</code>, que en este
caso no es un entorno.  Un nodo en el documento es aquella información
que se mostrará junta en la misma pantalla del <code>info</code>, <i>buffer</i> de
<i>Emacs</i>, o en la misma página del <code>HTML</code>.  En los formatos que no sean
<code>info</code> o <code>HTML</code>, no tendrá ningún efecto.
</p>

<p>
Si miramos el código, que he puesto en el listado de arriba, el
documento está contenido todo en el mismo listado<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, pero se separa
lógicamente mediante algunos comandos <code>@node</code>. Cada nodo comienza con
dicho comando y finaliza donde comience otro nodo.
</p>

<p>
En el ejemplo, podemos encontrar otros comandos, más fáciles de
digerir, como <code>@chapter</code> o <code>@section</code>, que considero que no es
necesario explicar para qué se utilizan.
</p>

<p>
Los principales comandos de estructura del documento son:
</p>

<ul class="org-ul">
<li><code>@node</code></li>
<li><code>@part</code></li>
<li><code>@chapter</code>, <code>@unnumbered</code>, <code>@appendix</code></li>
<li><code>@section</code></li>
<li><code>@subsection</code></li>
<li><code>@subsubsection</code></li>
</ul>

<p>
Hay algunos más, y también hay otros muchos detalles.  Como por
ejemplo, el comando <code>@section</code> <i>sabe</i> si está en un capítulo numerado
(<code>@chapter</code>), no numerado (<code>@unnumbered</code>) o en un apéndice
(<code>@appendix</code>).
</p>

<p>
También se pueden establecer referencias cruzadas dentro del documento
o manual; como vemos en el código anterior, que generan unos enlaces
como se puede ver en la siguiente imagen:
</p>


<figure id="orgd5b3b61">
<img src="./imagenes/Captura_ventana-info.png" alt="Captura_ventana-info.png">

</figure>

<p>
Los comandos más habituales para formatear el texto, y que creo que
tampoco necesitan mucha explicación son:
</p>

<ul class="org-ul">
<li><code>@strong{texto}</code></li>
<li><code>@emph{texto}</code></li>
<li><code>@code{texto}</code></li>
<li><code>@sub{texto}</code></li>
<li><code>@sup{texto}</code></li>
</ul>

<p>
O seleccionando la fuente:
</p>

<ul class="org-ul">
<li><code>@b{bold-negrita}</code></li>
<li><code>@i{italica}</code></li>
<li><code>@r{roman}</code></li>
<li><code>@sansserif{texto}</code></li>
<li><code>@sc{small-caps}</code></li>
<li><code>@slanted{oblicua}</code></li>
<li><code>@t{paso-fijo}</code></li>
</ul>

<p>
Con algún formateo más especializado:
</p>

<ul class="org-ul">
<li><code>@file{nombre-fichero}</code></li>
<li><code>@command{comando}</code></li>
<li><code>@email{dirección}</code></li>
<li><code>@abbr{abreviatura, [significado]}</code></li>
<li><code>@acronym{siglas, [significado]}</code></li>
<li><code>@kbd{secuencia-de-teclado}</code></li>
<li><code>@key{tecla-del-teclado}</code></li>
</ul>

<p>
También existen otros entornos, además de las listas, que pueden
sernos útiles:
</p>

<ul class="org-ul">
<li><code>@cartouche</code><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> dibuja un rectángulo de esquinas redondeadas alrededor
del texto.</li>
<li><code>@quotation</code></li>
<li><code>@example</code></li>
<li><code>@verbatim</code></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org06f0fd1" class="outline-2">
<h2 id="org06f0fd1">Conclusiones</h2>
<div class="outline-text-2" id="text-org06f0fd1">
<p>
No quiero enrollarme mucho: Es una herramienta interesante y merece la
pena echarle un ojo si necesitas escribir documentación, porque se
creó para eso: <i>Texinfo</i> es, realmente, un sistema potente de
documentación.  El compilador <code>texi2any</code> y el visualizador <code>info</code> son
fáciles de instalar, si no los tienes ya instalados en tu máquina.
Ocupan poco espacio y pueden ser verdaderamente útiles.
</p>

<p>
Por ejemplo, uno de los libros que suelo recomendar para aprender a
programar en <i>LISP</i> es <a href="https://media.githubusercontent.com/media/sarabander/sicp-pdf/master/sicp.pdf">Structure and Interpretation of Computer
Programs</a>, cuyo repositorio (no oficial) podéis encontrar en
<a href="https://media.githubusercontent.com/media/sarabander/sicp-pdf">https://media.githubusercontent.com/media/sarabander/sicp-pdf</a> y veréis
que utiliza una mezcla de <i>Texinfo</i> y <i>LaTeX</i>, que da como resultado
un <code>pdf</code> bastante agradable a la vista. El <code>sicp.texi</code> necesita una
limpieza antes de generar el <code>info</code> si lo quieres consultar desde
<i>Emacs</i> (que poder, se puede).
</p>

<p>
Como propósito personal, voy a documentar el proyecto en el que ando
programando a ratos con esta herramienta, en lugar de <i>LaTeX</i>, que
suele ser mi elección más habitual. Si no me encuentro cómodo, no me
costará nada generar el <i>LaTeX</i> con lo que haya escrito hasta entonces
y continuar a partir de ahí.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Se puede dividir en varios archivos, que suele ser lo habitual
en un manual grande, para luego incluir estos en el fichero <i>maestro</i>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Hay que recordar que estos comandos deben ir emparejados con un
comando de finalización, como en este caso <code>@end cartouche</code>.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/texinfo,/index.html">texinfo,</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[texinfo,]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2024/03/09/texinfo-el-sistema-de-ayuda-de-emacs.html</link>
  <pubDate>Sat, 09 Mar 2024 11:37:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Aventuras conversacionales y simulación de espacios virtuales]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2024-02-25</div>
<p>
Con anterioridad he hablado sobre <a href="https://notxor.nueva-actitud.org/tags/conversacionales/index.html">conversacionales</a>, aventuras de
texto, o quizá recuerdes que durante la pandemia me entretuve en
programar un MUD<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> con erlang<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. Pues, rehaciendo lo rehecho,
en este artículo, hablaré sobre otro proyecto relacionado y que esta
vez, espero, no se convertirá en otro <i>vaporware</i> sin finalizar. Lo
estoy realizando para utilizarlo en un ambiente muy concreto: la
prevención del acoso escolar en las aulas y sólo por esto, creo que lo
terminaré. Te lo cuento a continuación.
</p>
<div id="outline-container-org410a0c4" class="outline-2">
<h2 id="org410a0c4">Antecedentes: el proyecto y de dónde surge</h2>
<div class="outline-text-2" id="text-org410a0c4">
<p>
Como algunos que pasan por este <i>blog</i> ya sabréis, colaboro con una
Asociación sin ánimo de lucro que trabaja con menores que sufren
cualquier tipo de abuso. Lo que más nos piden es atención para
víctimas del acoso escolar. Por eso, vamos por los centros educativos
dando charlas de prevención... No me interpretéis mal, las charlas
están bien: hablamos de muchas cosas relacionadas e informamos a los
chavales de esos hechos que pasan «desapercibidos» en el acoso
escolar, como que cualquiera de nosotros puede ser un abusador o una
víctima. O, de manera más habitual, un consentidor si lo ven y no se
lo dicen a algún adulto.
</p>

<p>
Quiero elaborar algo más formal y estandarizado que ir un par de
mañanas a soltar una charlita. En su día ya hicimos un plan más
ambicioso para fomentar la educación emocional en los Centros
Educativos. Pero quedó en el cajón de <i>posibles</i>. Así que mi batalla
continúa.
</p>

<p>
Después de analizar muchos planes (formales) de prevención del acoso
escolar me he encontrado con un montón de ellos que utilizan cuentos o
cómics para introducir los temas a tratar en las sesiones de
prevención dirigidas por el tutor o personal especializado. Todos
estos planes hablan de las características que hacen del <b>cuento</b> una
herramienta muy interesante para estas actividades. Destacan, entre
otras:
</p>

<ul class="org-ul">
<li>El valor <i>propedéutico</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> de la narrativa.</li>
<li>El valor intrínseco de los cuentos para:
<ul class="org-ul">
<li>Fomentar la imaginación</li>
<li>Expresar sentimientos y emociones</li>
<li>Educar valores</li>
</ul></li>
</ul>

<p>
Hay muchas más, pero las más comunes sobre las que he encontrado
referencia a distintos estudios son los que afirman esto.
Lamentablemente, en muchas de las referencias no he podido seguir el
enlace a los estudios en sí. Y en los estudios que sí he podido leer,
no me queda claro en qué análisis de datos científicos se basan para
tales afirmaciones. De momento, y a falta de otras pruebas más
contundentes, debo fiarme del consenso científico que parece existir
entre todos los autores especializados que he consultado.
</p>

<p>
Mi intención es darle al asunto un pequeño giro y añadir interacción
en la narrativa: que los menores interactúen entre ellos y la historia
la hará más suya.  Para eso, una <i>aventura conversacional</i> puede ser,
a mi modo de ver, una herramienta interesante.
</p>
</div>
</div>
<div id="outline-container-org4aa21e9" class="outline-2">
<h2 id="org4aa21e9">Reinventando la rueda</h2>
<div class="outline-text-2" id="text-org4aa21e9">
</div>
<div id="outline-container-orgc173093" class="outline-3">
<h3 id="orgc173093">Por motivos generales</h3>
<div class="outline-text-3" id="text-orgc173093">
<p>
Existen muchas herramientas que sirven para crear aventuras
conversacionales, pero me he encontrado que ninguna termina de
ajustarse a mis necesidades. Así que, permíteme explicar por qué estoy
reinventando la rueda.
</p>

<p>
La primera característica que debía cumplir es que debería estar
programada para soportar la conjugación verbal y la concordancia de
número y género de las expresiones, como en español. La mayoría de las
herramientas están escritas y pensadas para inglés. Sus adaptaciones
al español suelen ser farragosas, incompletas y dejan mucho que
desear, pues son <i>añadidos</i> para herramientas con visiones muy
limitadas de la lingüística.
</p>

<p>
La segunda especificación es que debería poder soportar <i>«aventuras
multijugador»</i>. La mayoría de las herramientas de creación de
narrativa interactiva están pensadas para aventuras unipersonales.
</p>

<p>
Las dos características anteriores las cubre AGE<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>, pero presenta
otro problema: está realizado en <i>Java</i>. Hace tiempo que no se
actualiza y es posible que esté abandonado (hace tiempo que no hablo
con su desarrollador) y, por otro lado, los <i>applets</i> de java están
considerados <i>malware</i> por defecto, desde que Micro$oft® quiso
arrebatarle a <i>Java</i> su preponderancia con <code>.Net</code>.
</p>

<p>
Lo pensé algunos días. Lo consulté con algunos amigos del ambiente de
la ficción interactiva, y finalmente me decidí a hacerlo desde cero.
Las opciones que tenía era hacerlo a partir del MUD que ya había
programado en <code>erlang</code> o retomar el proyecto de <i>Trókola</i><sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>. He
optado por lo segundo.
</p>
</div>
</div>
<div id="outline-container-org84edaf3" class="outline-3">
<h3 id="org84edaf3">Otras consideraciones</h3>
<div class="outline-text-3" id="text-org84edaf3">
<p>
Cuando inicié el proyecto de <i>Trókola</i> tenía previstos algunos puntos
que me parecían mejorables a la hora de simular el mundo. Al diseñar
este tipo de herramientas es delicado determinar qué cosas debe hacer
el modelo y qué otras cosas se dejan para que decida el programador de
la aventura. Si te pasas implementando características en <i>el mundo</i>,
tu modelo puede ser demasiado rígido. Si no llegas, obligas al
programador de aventuras a programar casi desde cero cada aventura.
</p>

<p>
El modelo espacial de mundo, en la mayoría de las aventuras
conversacionales y MUD's, se basan en el concepto de <i>room</i>: una
localización donde el jugador puede realizar algunas acciones. Puede
examinar los objetos que hay en ella, coger y soltar objetos, examinar
cada uno de ellos o utilizar alguna de las salidas, para cambiar de
<i>room</i>. Son suficientes sólo para simular habitaciones no muy grandes.
</p>

<p>
El modelo temporal de mundo, en la mayoría de los casos, se basa en el
concepto de «turnos». Cada turno viene determinado por cada comando
que escribe el jugador. Aunque hay algunas herramientas que soportan
el tiempo real, lo habitual es que en las aventuras conversacionales
esté suspendido el tiempo entre comandos del usuario y éste pueda
reflexionar cuál será su siguiente paso sin presiones de tiempo.
</p>

<p>
El modelo de interrelación con los objetos, se basa en el
<i>inventario</i>. Cada jugador tiene un inventario, muchas veces infinito,
de cosas que puede portar, sin especificar si en la mano o dónde. Un
objeto pasa a su inventario o sale de su inventario cuando lo obtiene
o cuando lo suelta. Se obvia dónde se guardan los objetos y pocas
veces, a no ser que sea importante para la resolución de algún puzle,
se tiene en cuenta si lo lleva en la mano o no, a la hora de
utilizarlo, o cuántos objetos sostiene en la misma mano. Algunos
sistemas implementan también la cuestión por pesos, pero raramente he
visto usarlo y la mayoría de autores prefiere seguir ignorándolo.
</p>

<p>
Cuando inicié el proyecto de <i>Trókola</i> tenía estos tres aspectos en
mente, con la intención de mejorar el modelo de mundo. Al modelo
espacial quería añadirle el concepto de <i>zona</i>. El modelo cerrado, es
ideal para simular cuevas, calabozos o entornos cerrados pasando de
una localidad a otra, siendo estas independientes y generalmente
pequeñas. Simular un patio, un jardín o un gran espacio con múltiples
posiciones o lugares, es complejo en estos sistemas, porque son
espacios abiertos, por los que te puedes desplazar, que te permiten
ver e interactuar con lo que haya en distintos lugares del mismo. En
mi proyecto, quiero que las zonas puedan agrupar distintas localidades
y que lo que haya en esa zona sea visible para toda la zona abierta.
También puede haber localidades cerradas en la misma zona. Por
ejemplo, en un jardín donde hay una caseta para el perro, no puedes
ver lo que hay dentro de la caseta, a no ser que te asomes, pero sí lo
que hay en el porche de la casa: la caseta sería una localidad cerrada
mientras el porche sería una localidad abierta aunque las dos
pertenezcan a la misma <i>zona</i>.
</p>

<p>
Con respecto al modelo temporal, quería implementar la elección entre
«turnos» y «tiempo real» a elección del programador de la aventura.
Incluso que se pudieran mezclar y que se pueda aplicar uno u otro
dependiendo de la acción. Mi intención sigue siendo esa, aunque al
añadirle la opción multijugador, veo más factible la implementación de
juegos en «tiempo real», porque si no, cada turno dependerá de que
todos los jugadores hayan hecho o no, su acción... aunque supongo que
será algo que deba decidir y programar el que implemente la aventura.
</p>

<p>
Por último, la gestión del <i>inventario</i> era otra de las
consideraciones que tenía en mente cuando inicié el proyecto. Si
pensamos que lo que llevamos lo portamos en el sitio más habitual: las
manos; no es factible llevar quince cosas... o dos. O imagina que
quieres atornillar algo y en la mano tienes un destornillador y
un huevo de gallina... ¿podrías hacerlo sin romper el huevo o lo
soltarías? En fin, el sistema que había pensado era establecer una
variable de <i>manejabilidad</i> a las cosas y otra a los personajes.  Por
ejemplo, un personaje con <i>manejabilidad</i> 4, podrá portar cuatro
objetos de <i>manejabilidad</i> 1; o uno de 3 y otro de 1; o dos de 2; y no
podrá llevar objetos de <i>manejabilidad</i> 5 salvo en condiciones
especiales. Por supuesto, será el programador de la aventura el que
pueda seguir o ignorar esta herramienta.
</p>
</div>
</div>
<div id="outline-container-org8e3a81a" class="outline-3">
<h3 id="org8e3a81a">Consideraciones técnicas</h3>
<div class="outline-text-3" id="text-org8e3a81a">
<p>
Por qué elegí <i>Tcl</i><sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup> es otra cuestión. Hay que tener en cuenta
que es un lenguaje minoritario, incluso desconocido para muchos, a
pesar de ser bastante antiguo. Posiblemente sea más conocido su
<i>toolkit</i> gráfico, <i>Tk</i>, porque lo utilizan otros lenguajes como
<i>Python</i> o <i>Perl</i>. En mi caso, <i>Tcl</i> me gustó porque me gustan los
lenguajes simples y éste lo es. En él, todo es una cadena de
caracteres, no hay tipos todo son cadenas, el código es una cadena,
todos los datos son cadenas. Además, si evalúas una cadena, se
comporta como código.  De hecho, la descripción del modelo de mundo
del proyecto es una cadena, con estructura de diccionario, se carga
como código y se escribe como cadena. La acción de guardar partida es,
literalmente, escribir en un archivo la cadena y recuperar la partida
es leer el archivo como código.
</p>

<p>
Esta característica, por tanto, permite que la <i>metaprogramación</i> sea
sencilla: un procedimiento puede devolver una cadena que sea
código. El lenguaje es <i>homoicónico</i>, como <i>LISP</i>, es decir: todas
las instrucciones tienen la misma estructura:
</p>

<pre class="example" id="orgab61bcd">
nombreComando [argumentos]
</pre>

<p>
Por ejemplo, para definir un procedimiento se utiliza el comando
<code>proc</code>, que tiene la siguiente forma:
</p>

<pre class="example" id="org6fe5004">
proc nombreProcedimiento {argumentos} {código}
</pre>

<p>
Esta característica me recuerda mucho a <i>Scheme</i> o <i>LISP</i>. Por
ejemplo, la asignación no utiliza un operador, sino el comando <code>set</code>:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">x</span> 12
</pre>
</div>

<p>
El añadido de metaprogramación es importante, para dar la oportunidad
al creador de las aventuras a añadir y/o modificar el código que hace
funcionar el <i>modelo de mundo</i>. Por ejemplo, para poder añadir
acciones a determinados objetos o personajes. En otros sistemas como
<i>AGE</i>, que mencioné con anterioridad, se utiliza el método
<code>parseCommand()</code>. Y aunque aún no está desarrollado, pues estoy en las
fases iniciales del proyecto, sí espero que sea relativamente fácil
implementar un sistema afín.
</p>

<p>
El sistema que estoy programando no está orientado a objetos, aunque
también lo soporta <i>Tcl</i>. Desde la versión mayor 8.6 el módulo <code>TclOO</code>
es de los que vienen en la distribución base. De momento, me parece
más sencillo mantener el modelo de mundo como un diccionario. Las
entidades que representas los objetos, los personales, las
localidades, etc. se guardan en pares <code>key</code> / <code>value</code>, donde el valor
es también un diccionario que contiene las características de la
entidad que representa. Las peticiones del jugador se recogen y el
sistema reacciona, modificando y/o mostrando parte de la información
del diccionario.
</p>
</div>
</div>
</div>
<div id="outline-container-orgc343870" class="outline-2">
<h2 id="orgc343870">Estado del proyecto</h2>
<div class="outline-text-2" id="text-orgc343870">
<p>
Como puedes ver, efectivamente, estoy reinventando la rueda, incluso
una que ya reinventé una vez. Supongo que habrá quien piense que
podría haber utilizado el <code>erlmud</code> que ya tengo programado para el
proyecto.  Tendría que haberle hecho algunas modificaciones, para
permitir escribir las aventuras, o haberlas escrito directamente en
<code>erlang</code> y ya. Sin embargo, la idea es proporcionar la herramienta y
que la gente tenga la posibilidad de utilizarla con sus propias
aventuras, incluso que los chavales, con ayuda de algún profesor
puedan hacer las suyas. No creo que <code>erlang</code> sea un lenguaje amable
para iniciarse en la programación.
</p>

<p>
Con el proyecto de <i>Trókola</i> apenas había empezado, comprendía un par
de comandos y quedó en barbecho: siempre me falta tiempo para todo lo
que quiero hacer. Después de retomarlo, hace apenas unas semanas,
sigue comprendiendo un par de instrucciones, pero he añadido el que se
ejecute en modo servidor y responda vía <code>telnet</code>, el guardar/cargar
partidas y el germen para el sistema de <code>log</code>. También he cambiado la
licencia a una <a href="https://www.gnu.org/licenses/agpl-3.0.html">Affero GPL 3.0</a>, para permitir su ejecución libre en un
servidor.
</p>

<p>
Para la utilización en las aulas, puesto que me gustaría que fuera una
herramienta educativa además de lúdica, el contar con el registro de
todo lo que hacen los jugadores, y cuándo, para evaluar la actividad.
De hecho, he pensado en hacer, cuando el proyecto esté más avanzado,
una herramienta para analizar el <code>log</code> generado.
</p>
</div>
<div id="outline-container-org6140f2e" class="outline-3">
<h3 id="org6140f2e">¿Qué espero conseguir?</h3>
<div class="outline-text-3" id="text-org6140f2e">
<p>
Lo primero: <b>lo que aprendo haciéndolo</b>, eso no me lo quitará nadie
aunque el proyecto termine estrellándose por otros motivos<sup><a id="fnr.7" class="footref" href="#fn.7" role="doc-backlink">7</a></sup>.  Lo
segundo y más importante: <b>añadir al valor propedéutico de la
narrativa el trabajo en equipo</b> con una actividad que puede ser
divertida si está bien dirigida, fomentará la comprensión lectora,
fomentará la imaginación, fomentará la colaboración.
</p>

<p>
A unas malas, lo que espero es que, al menos, pueda programar una o
dos aventuras y jugarlas con los colegas.
</p>
</div>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Multi-User Dungeon</i> o, según otros también <i>Multi-User
Dimension</i> y/o <i>Multi-User Domain</i>... juegos de rol en línea en modo
texto que hacen que el «calabozo multiusuario» sea el antecesor de los
modernos juegos en red MMORPG.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Podéis encontrar todo el código fuente en el repositorio de
Codeberg: <a href="https://codeberg.org/Notxor/erlmud">https://codeberg.org/Notxor/erlmud</a>. «Sólo» le falta toda la
definición del mundo virtual donde poder jugar.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Se entiende como <i>propedéutica</i> la capacidad de alguna
herramienta para preparar con antelación las acciones formativas.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Aetheria Game Engine</i>, que podéis encontrar en
<a href="https://github.com/komoku/aetheria/tree/master">https://github.com/komoku/aetheria/tree/master</a>. En su día colaboré con
la generación de la documentación en PDF con <i>LaTeX</i>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ese era un proyecto de creación de una herramienta para
aventuras conversacionales, con el objetivo sólo de aprender y de
hacer algún juego rápido. Se puede encontrar el artículo en
<a href="https://notxor.nueva-actitud.org/2022/05/06/trokola.html">https://notxor.nueva-actitud.org/2022/05/06/trokola.html</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Tool Command Language</i>, <i>TCL</i> pronunciado comúnmente como
<i>tickle</i>. Es un lenguaje de <i>script</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.7" class="footnum" href="#fnr.7" role="doc-backlink">7</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Que seguramente será lo que ocurra: la falta de financiación
para planes de prevención que lo usen, será el escollo que desfondará
esta barca.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/conversacionales/index.html">conversacionales</a> <a href="/tags/tcl/index.html">tcl</a> <a href="/tags/programación/index.html">programación</a> ]]></description>
  <category><![CDATA[conversacionales]]></category>
  <category><![CDATA[tcl]]></category>
  <category><![CDATA[programación]]></category>
  <link>https://notxor.nueva-actitud.org/2024/02/25/aventuras-conversacionales-y-simulacion-de-espacios-virtuales.html</link>
  <pubDate>Sun, 25 Feb 2024 10:28:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Emacs, configuraciones básicas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2024-02-02</div>
<p>
Aprovechando que estaba dando un repaso a mi configuración de <i>Emacs</i>
me he propuesto contar un poco qué paquetes uso y por qué. De paso,
espero que a alguien le sirva de inspiración para configurar su
entorno. Me repito, puesto que ya indiqué en <a href="https://notxor.nueva-actitud.org/2022/08/31/programacion-literaria-y-la-configuracion-de-emacs.html">otro artículo</a> cómo tengo
la configuración, que por otro lado puedes consultar en su
repositorio: <a href="https://codeberg.org/Notxor/init-emacs">https://codeberg.org/Notxor/init-emacs</a>. Al final, la
configuración de cualquier sistema es una toma de decisiones, si hay
alternativas. En un sistema como <i>Emacs</i>, donde hay muchas
alternativas y, por tanto, decisiones, la tarea de configurarlo puede
parecer abrumador al principio.
</p>

<p>
<i>Emacs</i> es un entorno complejo, no es un editor, es un entorno <i>LISP</i>
enfocado a trabajar con texto. Ajustarlo a tus necesidades suele ser
el principal quebradero de cabeza de quien empieza a adentrarse en su
uso. Por ello han ido apareciendo a lo largo del tiempo algunos
paquetes que distribuyen el sistema, con un aspecto más vistoso y con
la configuración prácticamente hecha. Me refiero a distribuciones como
<i>Doom</i>, <i>Spacemacs</i>, <i>Prelude</i> o <i>Centaur</i>. Además, por supuesto, de
la <i>Vanilla</i>: la más básica (y oficial). ¿Cuál recomiendo? Ninguna y
todas. En el artículo de hoy voy a hacer un repaso de las
herramientas, tanto funcionales como de aspecto, que utilizo en mi día
a día y cómo las tengo configuradas en mi <code>init.el</code>. Sí, necesitarás
entender algo de <i>LISP</i> para hacer las tuyas.
</p>

<p>
En mi caso utilizo una instalación básica (<i>Vanilla</i> si lo queréis
llamar así), a partir de una compilación de <i>Emacs</i> que hago desde el
código fuente, es decir: descargo el código fuente y lo compilo para
mi ordenador cada vez que me entero de alguna actualización importante
(lo que viene a ser una o dos veces al mes).
</p>
<div id="outline-container-org42465da" class="outline-2">
<h2 id="org42465da">Aspecto visual</h2>
<div class="outline-text-2" id="text-org42465da">
<p>
Debería ser lo último. Es decir, una vez que lo tienes todo
funcionando haz que sea bonito. Sin embargo, a muchos les importa qué
aspecto tiene la herramienta tanto más que su funcionamiento. Para
muestra, un botón:
</p>


<figure id="org867806e">
<img src="./imagenes/Captura_ventana-emacs.png" alt="Captura_ventana-emacs.png">

</figure>

<p>
El aspecto visual es subjetivo y por tanto está sujeto más a gustos
que a otras consideraciones. Las líneas generales, las mías, serían
las siguientes:
</p>

<ul class="org-ul">
<li>Simplicidad de la <i>interface</i>: sin menús ni barras de
desplazamiento, mucho menos barra de herramientas.</li>
<li>Tema oscuro de edición, pero con posibilidad de cambiar a uno claro
para visualizar mejor en ambientes más luminosos, como la calle.</li>
<li>Modificación de la línea de estado: información y diseño.</li>
<li>Directorios, archivos, número de línea e iconos.</li>
</ul>

<p>
Por supuesto, se pueden añadir otros aspectos o eliminar algunos de
éstos, como digo estas decisiones son cuestión de gustos. Por ejemplo,
no me gustan las <i>tabs</i> para agrupar <i>buffers</i>, rompen el minimalismo
de la <i>interface</i> y en su lugar utilizo el paquete <code>perspective</code>. Ya
hablé sobre <a href="https://notxor.nueva-actitud.org/2020/11/25/organizacion-del-espacio-de-trabajo-en-emacs.html">cómo organizar el espacio</a> en una ventana de <i>Emacs</i> y
también sobre <a href="https://notxor.nueva-actitud.org/2022/04/06/algunos-ajustes-para-emacs.html">algunos otros ajustes visuales</a>. Puedes ir a esos
artículos para tener más detalles.
</p>

<p>
La configuración de <code>perspective</code> es muy simple:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> perspective
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:init</span>
  (persp-mode t))
</pre>
</div>

<p>
Con <code>perspective</code> puedo cambiar entre distintas configuraciones de
pantalla. Normalmente lo divido por tareas: en la perspectiva <code>main</code>
suelo tener activas algunas tareas, como la agenda, la toma de notas,
contabilidad y cualquier asunto más o menos trasversal. Luego, en
otras perspectivas suelo cargar proyectos o tareas más específicas.
</p>


<figure id="orgda08c07">
<img src="./imagenes/Captura_perspective_main.png" alt="Captura_perspective_main.png">

</figure>

<p>
Más adelante en el apartado <code>custom-set-faces</code> modifico también el
tipo de letra para resaltar la perspectiva con:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(custom-set-faces
 ...
 'persp-selected-face ((t (<span style="color: #8be9fd; font-style: italic;">:foreground</span> <span style="color: #f1fa8c;">"yellow"</span> <span style="color: #8be9fd; font-style: italic;">:weight</span> normal)))))
</pre>
</div>

<p>
El cambio de perspectivas me permite tener varias configuraciones de
pantalla sin los <i>tabs</i>, que estéticamente me parecen horribles.
</p>
</div>
<div id="outline-container-org6cfecb1" class="outline-3">
<h3 id="org6cfecb1">Simplificar la interface</h3>
<div class="outline-text-3" id="text-org6cfecb1">
<p>
Cuando utilizas <i>GTK</i> fuera de un escritorio <i>Gnome</i> el resultado
visual deja mucho que desear. Feo, es feo, muy feo. Para mejorar el
aspecto de <i>Emacs</i> en otros escritorios la opción más a mano es
eliminar cualquier <i>widget GTK</i> de la ventana. A ser posible todos.
</p>

<p>
Como digo, las barras de desplazamiento, la barra de herramientas y
los menús me sobran. La ventana sin ellas se convierte en algo
minimalista, sólo está el texto y la línea de estado, lo cual resulta
más agradable que el aspecto que proporcionan los <i>widgets GTK</i>.
</p>

<p>
En mi archivo de configuración <code>mi-custom-var.el</code> se pueden encontrar
las siguientes expresiones que eliminan algunos aspectos de la ventana:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">'(column-number-mode t)                 <span style="color: #6272a4;">;</span><span style="color: #6272a4;">Muestra en l&#237;nea de estado la columna adem&#225;s de la l&#237;nea
</span>'(custom-enabled-themes '(dracula))     <span style="color: #6272a4;">;</span><span style="color: #6272a4;">Permite cargar el tema oscuro `</span><span style="color: #bd93f9;">Dracula</span><span style="color: #6272a4;">'.
</span>
'(inhibit-startup-screen t)             <span style="color: #6272a4;">;</span><span style="color: #6272a4;">No muestra la pantalla de inicio por defecto de `</span><span style="color: #bd93f9;">Emacs</span><span style="color: #6272a4;">'
</span>'(scroll-bar-mode nil)                  <span style="color: #6272a4;">;</span><span style="color: #6272a4;">Elimina las barras de scroll
</span>'(tool-bar-mode nil)                    <span style="color: #6272a4;">;</span><span style="color: #6272a4;">Elimina la barra de herramientas
</span>'(menu-bar-mode nil)                    <span style="color: #6272a4;">;</span><span style="color: #6272a4;">Elimina el men&#250; (accesible desde `</span><span style="color: #bd93f9;">&lt;f10&gt;</span><span style="color: #6272a4;">')
</span>'(global-prettify-symbols-mode t)       <span style="color: #6272a4;">;</span><span style="color: #6272a4;">Activa la sustituci&#243;n de s&#237;mbolos de manera global
</span>
'(electric-pair-mode t)                 <span style="color: #6272a4;">;</span><span style="color: #6272a4;">Activar el modo de autocierre de par&#233;ntesis
</span>'(truncate-lines t)                     <span style="color: #6272a4;">;</span><span style="color: #6272a4;">Las l&#237;neas en una l&#237;nea sin saltos
</span>'(show-paren-mode t)                    <span style="color: #6272a4;">;</span><span style="color: #6272a4;">Remarca la pareja de un par&#233;ntesis (corchete, llave)
</span>'(which-key-mode t)                     <span style="color: #6272a4;">;</span><span style="color: #6272a4;">Activa la sugerencia de teclas
</span>'(word-wrap t)
'(org-fontify-emphasized-text t))       <span style="color: #6272a4;">;</span><span style="color: #6272a4;">Activar la visualizaci&#243;n de estilos de fuente</span>
</pre>
</div>

<p>
No sólo menciono las líneas de simplificación, sino también algunos
aspectos y funcionalidades adicionales. Podríamos considerar también
algunas cosas más:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(save-place-mode t)                <span style="color: #6272a4;">;</span><span style="color: #6272a4;">Guarda la posici&#243;n del cursor al cerrar un archivo
</span>(global-auto-revert-mode t)        <span style="color: #6272a4;">;</span><span style="color: #6272a4;">Recarga el contenido de un buffer si ha cambiado el archivo en disco
</span><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Desplazar los archivos temporales y de backup a directorio temporal
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> backup-directory-alist
      `((<span style="color: #f1fa8c;">".*"</span> . ,temporary-file-directory)))
(<span style="color: #ff79c6; font-weight: bold;">setq</span> auto-save-file-name-transforms
      `((<span style="color: #f1fa8c;">".*"</span> ,temporary-file-directory t)))
</pre>
</div>

<p>
En la imagen anterior, se puede observar en la línea de estado las
perspectivas abiertas marcadas como <code>[blog|main]</code>. Marca amarilla para
la perspectiva en uso (<code>blog</code>), <code>main</code> es la única que está siempre
activa y es donde suelo tener cargadas herramientas como la agenda y
las notas.
</p>
</div>
</div>
<div id="outline-container-org4755c6b" class="outline-3">
<h3 id="org4755c6b">Temas</h3>
<div class="outline-text-3" id="text-org4755c6b">
<p>
Muchos afirman que con un buen tema oscuro es suficiente para todo. En
mi caso, llevo el ordenador (o la <i>tablet</i>) a sitios donde las
condiciones ambientales dificultan la lectura de la pantalla en
colores oscuros. Si has trabajado al aire libre alguna vez, sabes de
lo que estoy hablando. Por eso, hace tiempo que tengo un método para
cambiar de tema oscuro a tema claro y viceversa, pulsando tan sólo una
tecla. Ya lo conté en otro artículo, ya enlazado, pero me voy a repetir.
</p>

<p>
Como se vio antes, como tema oscuro utilizo <code>Dracula</code>. Pero el cambio
a una visualización clara utilizo el tema <code>tsdh-light</code>. Para el
intercambio, utilizo el paquete <code>heaven-and-hell</code> que permite hacerlo
de manera sencilla.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> heaven-and-hell
<span style="color: #8be9fd; font-style: italic;">:ensure</span> t
<span style="color: #8be9fd; font-style: italic;">:init</span>
(<span style="color: #ff79c6; font-weight: bold;">setq</span> heaven-and-hell-theme-type 'dark) <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">usa el oscuro por defecto
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> heaven-and-hell-themes
      '((light . tsdh-light)
        (dark . dracula))) <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Se puede sustituir por (dark . (tsdh-dark wombat))
</span><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Opcional, carga el tema sin pedir confirmaci&#243;n
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> heaven-and-hell-load-theme-no-confirm t)
<span style="color: #8be9fd; font-style: italic;">:hook</span> ((after-init . heaven-and-hell-init-hook)))
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">configuraci&#243;n de la tecla de cambio
</span>(global-set-key (kbd <span style="color: #f1fa8c;">"&lt;f6&gt;"</span>) 'heaven-and-hell-toggle-theme)
</pre>
</div>

<p>
En mi caso es algo más complejo, puesto que utilizo también el paquete
<code>powerline</code> para embellecer un poco la línea de estado. No es una
configuración compleja:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Mejorando la visualizaci&#243;n de la l&#237;nea de estado
</span>(<span style="color: #ff79c6; font-weight: bold;">use-package</span> powerline
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:config</span>
  (powerline-default-theme)
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> powerline-default-separator 'rounded))
</pre>
</div>

<p>
Cuando cambia el tema, los caracteres de adorno de la línea de estado
no cambien y queden con el tema que ya no corresponde.  Por eso añadí
un par de funciones extra para el cambio de temas:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">ajuste-powerline-theme</span> ()
  <span style="color: #6272a4;">"Hace un reset de la powerline tras cambiar el tema."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (heaven-and-hell-toggle-theme)
  (powerline-reset))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">ajuste-powerline-default-theme</span> ()
  <span style="color: #6272a4;">"Hace un reset de la powerline tras cambiar al tema por defecto."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (heaven-and-hell-load-default-theme)
  (powerline-reset))

(global-set-key (kbd <span style="color: #f1fa8c;">"C-c &lt;f6&gt;"</span>) 'ajuste-powerline-default-theme)
(global-set-key (kbd <span style="color: #f1fa8c;">"&lt;f6&gt;"</span>)     'ajuste-powerline-theme)
</pre>
</div>
</div>
</div>
<div id="outline-container-org848a730" class="outline-3">
<h3 id="org848a730">Pijotadas varias</h3>
<div class="outline-text-3" id="text-org848a730">
<p>
Otro paquete que puede ser útil nos permite visualizar de manera
rápida dónde está el cursor en un <i>buffer</i> cuando cambiamos a él y
obligar a nuestros ojos a dirigirse al punto:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Resalte de la posici&#243;n del cursor al cambiar de `</span><span style="color: #bd93f9;">buffer</span><span style="color: #6272a4;">'
</span>(<span style="color: #ff79c6; font-weight: bold;">use-package</span> beacon
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:config</span>
  (beacon-mode t))
</pre>
</div>

<p>
Otra configuración especial es el número de la línea. Cuando estoy
programando se me hace un modo fundamental, pero algunas veces me
estorba. Por ello tengo algunas consideraciones previas, teclas que me
permiten activarlo o desactivarlo y algún aspecto más. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> display-line-numbers-type 'visual)    <span style="color: #6272a4;">;</span><span style="color: #6272a4;">Muestra el n&#250;mero de l&#237;nea y la distancia de anteriores y posteriores
</span>(add-hook 'prog-mode-hook 'display-line-numbers-mode)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c l"</span>) 'display-line-numbers-mode)
</pre>
</div>

<p>
El modo <code>visual</code> de los números de línea no se limita a mostrar la
línea y ya. Muestra el número de línea donde se encuentra el cursos y
las demás las numera por la distancia con la actual. De esa manera, se
facilitan saltar varias líneas mediante un sólo comando.
</p>

<p>
Por último, también utilizo un modo de <code>dired</code> que me muestra una
barra lateral con directorios y archivos. Además de toda la
funcionalidad de un <i>buffer</i> <code>dired</code> permite navegar por los
directorios y abrir archivos, tanto con ratón como con teclado. Si le
añades los iconos, tienes una buena herramienta de navegación y
edición.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Ajustes de dired-sidebar
</span>(<span style="color: #ff79c6; font-weight: bold;">use-package</span> dired-sidebar
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t
  <span style="color: #8be9fd; font-style: italic;">:commands</span> (dired-sidebar-toggle-sidebar)
  <span style="color: #8be9fd; font-style: italic;">:init</span>
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> dired-sidebar-theme 'nerd)
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> dired-sidebar-use-term-integration t)
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> dired-sidebar-use-custom-font t))

(<span style="color: #ff79c6; font-weight: bold;">use-package</span> dired-git
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t)

(<span style="color: #ff79c6; font-weight: bold;">use-package</span> all-the-icons
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t)
(<span style="color: #ff79c6; font-weight: bold;">use-package</span> all-the-icons-dired
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t)
(<span style="color: #ff79c6; font-weight: bold;">use-package</span> all-the-icons-ibuffer
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:init</span> (all-the-icons-ibuffer-mode t))
</pre>
</div>

<p>
También puedes establecer una combinación de teclas para activar esa
barra. En mi caso:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(global-set-key (kbd <span style="color: #f1fa8c;">"C-c s"</span>) 'dired-sidebar-toggle-sidebar)
</pre>
</div>

<p>
Si después de instalar estos paquetes, no consigues ver correctamente
los iconos, es porque te faltan las fuentes. Acuérdate de instalarlas
con <code>M-x all-the-icons-install-fonts</code>.
</p>

<p>
Hay otros paquetes como <code>dashboard</code> para sustituir el <i>buffer</i> de
inicio por algo más vistoso. Pero eso lo dejamos para otros momentos.
Es mucho más interesante la funcionalidad del editor y, por tanto,
vamos a ello.
</p>
</div>
</div>
</div>
<div id="outline-container-orgf8fa744" class="outline-2">
<h2 id="orgf8fa744">Funcionalidad: ivy, counsel, swiper y yasnippet</h2>
<div class="outline-text-2" id="text-orgf8fa744">
<p>
Estos paquetes forman un conjunto imprescindible para mí.  El primero
de ellos es <code>ivy</code>. Proporciona un sistema de búsqueda y completado en
el <i>minibuffer</i> que facilita la edición de comandos de <i>Emacs</i> y junto
con los otros, especialmente <code>counsel</code> y <code>swiper</code> nos permite una
flexibilidad maravillosa. La alternativa a <code>ivy</code> es <code>helm</code>, que sirve
básicamente para lo mismo. Yo me encuentro más cómodo con <code>ivy</code>, pero
es bueno saber que existen alternativas.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Configurar ivy
</span>(<span style="color: #ff79c6; font-weight: bold;">use-package</span> ivy
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:init</span>
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> ivy-use-virtual-buffers t
        ivy-height 15                             <span style="color: #6272a4;">; </span><span style="color: #6272a4;">muestra 15 l&#237;neas de informaci&#243;n (por defecto son 10)
</span>        ivy-count-format <span style="color: #f1fa8c;">""</span>                       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">no mostrar el contador
</span>        ivy-initial-inputs-alist nil)
  <span style="color: #8be9fd; font-style: italic;">:config</span>
  (ivy-mode t))
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Para utilizar iconos
</span>(<span style="color: #ff79c6; font-weight: bold;">use-package</span> all-the-icons-ivy
  <span style="color: #8be9fd; font-style: italic;">:init</span> (add-hook 'after-init-hook 'all-the-icons-ivy-setup))
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Completa la informaci&#243;n mostrada en forma de tablas
</span>(<span style="color: #ff79c6; font-weight: bold;">use-package</span> all-the-icons-ivy-rich
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:init</span> (all-the-icons-ivy-rich-mode t))
(<span style="color: #ff79c6; font-weight: bold;">use-package</span> ivy-rich
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:config</span>
  (ivy-rich-mode t))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">ivy-rich-switch-buffer-icon</span> (candidate)
  (<span style="color: #ff79c6; font-weight: bold;">with-current-buffer</span>
      (get-buffer candidate)
    (<span style="color: #ff79c6; font-weight: bold;">let</span> ((icon (all-the-icons-icon-for-mode major-mode)))
      (<span style="color: #ff79c6; font-weight: bold;">if</span> (symbolp icon)
          (all-the-icons-icon-for-mode 'fundamental-mode)
        icon))))
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Modifica la visualizaci&#243;n de `</span><span style="color: #bd93f9;">ivy</span><span style="color: #6272a4;">' en columnas
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> ivy-rich-display-transformers-list
      '(ivy-switch-buffer
        (<span style="color: #8be9fd; font-style: italic;">:columns</span>
         ((ivy-rich-switch-buffer-icon (<span style="color: #8be9fd; font-style: italic;">:width</span> 2))
          (ivy-rich-candidate (<span style="color: #8be9fd; font-style: italic;">:width</span> 30))
          (ivy-rich-switch-buffer-size (<span style="color: #8be9fd; font-style: italic;">:width</span> 7))
          (ivy-rich-switch-buffer-indicators (<span style="color: #8be9fd; font-style: italic;">:width</span> 4 <span style="color: #8be9fd; font-style: italic;">:face</span> error <span style="color: #8be9fd; font-style: italic;">:align</span> right))
          (ivy-rich-switch-buffer-major-mode (<span style="color: #8be9fd; font-style: italic;">:width</span> 12 <span style="color: #8be9fd; font-style: italic;">:face</span> warning))
          (ivy-rich-switch-buffer-project (<span style="color: #8be9fd; font-style: italic;">:width</span> 15 <span style="color: #8be9fd; font-style: italic;">:face</span> success))
          (ivy-rich-switch-buffer-path (<span style="color: #8be9fd; font-style: italic;">:width</span> (<span style="color: #ff79c6; font-weight: bold;">lambda</span> (x) (ivy-rich-switch-buffer-shorten-path x (ivy-rich-minibuffer-width 0.3))))))
         <span style="color: #8be9fd; font-style: italic;">:predicate</span>
         (<span style="color: #ff79c6; font-weight: bold;">lambda</span> (cand) (get-buffer cand)))))
(<span style="color: #ff79c6; font-weight: bold;">setq</span> all-the-icons-ivy-rich-icon t)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> all-the-icons-ivy-rich-color-icon t)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> all-the-icons-ivi-rich-icon-size 1.0)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> all-the-icons-ivy-rich-field-width 80)
</pre>
</div>

<p>
El paquete <code>counsel</code> nos permite sustituir algunos comandos por
homólogos. Sin embargo, puesto que lo utiliza <code>ivy</code> no tengo ninguna
configuración especial para él, sólo me aseguro de que esté instalado
y le añado una combinación de teclas para moverme por los documentos
gracias a <code>counsel-imenu</code> o realizar un búsqueda en el <i>buffer</i>
mediante <code>grep</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> counsel
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c g"</span>) 'counsel-grep)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c m"</span>) 'counsel-imenu)
</pre>
</div>

<p>
<code>counsel</code> proporciona bastantes comandos de sustitución, además de
para <code>grep</code> o <code>imenu</code>, también puede gustarte el <code>counsel-find-file</code> u
otros, es cuestión de probarlos y ver si te va bien asignarles
combinación de tecla o no.
</p>

<p>
Como se muestra en la configuración, yo utilizo para buscar en el
<i>buffer</i> que estoy editando con <code>counsel-grep</code>, para realizar la
búsqueda (lo que es más rápido si es en un <i>buffer</i> grande) pero
también, si el <i>buffer</i> es más pequeño, puedo utilizar la
funcionalidad <code>swiper</code>.
</p>

<p>
<code>swiper</code> ni siquiera lo configuro. Se instala como dependencia de
<code>counsel</code> de hecho. Lo descubrí por el comando
<code>counsel-grep-or-swiper</code>, que utiliza una búsqueda u otra dependiendo
del <i>buffer</i> abierto.
</p>

<p>
Por otro lado, hablando sobre búsquedas, hay veces que necesitas
buscar en varios <i>buffers</i>. Para eso, suelo utilizar <code>projectile-grep</code>
o bien <code>project-find-regexp</code>, pero esto lo hablaré en el apartado de
programación, porque son herramientas enfocadas a esa actividad.
</p>

<p>
Otro paquete que utilizo bastante es <code>yasnippet</code>. Muchas de las tareas
de edición presentan estructuras repetitivas, especialmente en
programación, pero no sólo ahí y este paquete me proporciona, de
manera sencilla <i>plantillas</i> que me ahorran bastante tecleo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">gesti&#243;n de plantillas `</span><span style="color: #bd93f9;">yasnippet</span><span style="color: #6272a4;">'
</span>(<span style="color: #ff79c6; font-weight: bold;">use-package</span> yasnippet
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t)

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">para que se entiendan `</span><span style="color: #bd93f9;">ivy</span><span style="color: #6272a4;">' y `</span><span style="color: #bd93f9;">yasnippet</span><span style="color: #6272a4;">'.
</span>(<span style="color: #ff79c6; font-weight: bold;">use-package</span> ivy-yasnippet
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t)

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">colecci&#243;n de plantillas para `</span><span style="color: #bd93f9;">yasnippet</span><span style="color: #6272a4;">'
</span>(<span style="color: #ff79c6; font-weight: bold;">use-package</span> yasnippet-snippets
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t)

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">activar `</span><span style="color: #bd93f9;">yasnippet</span><span style="color: #6272a4;">' autom&#225;ticamente donde lo necesito
</span>(add-hook 'org-mode-hook 'yas-minor-mode)
(add-hook 'prog-mode-hook 'yas-minor-mode)

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">asociar combinaci&#243;n de teclas para mostrar lista de snippets
</span>(global-set-key (kbd <span style="color: #f1fa8c;">"C-c y"</span>) 'ivy-yasnippet)
</pre>
</div>

<p>
Otro paquete importante para mí es <code>which-key</code>. Uso <i>Emacs</i> a diario y,
aún así, no consigo acordarme de todas las combinaciones de teclas que
lanzan comandos en el editor. Sólo recuerdo algunas decenas de las que
utilizo <i>todos los días</i>. A otras, de uso menos frecuente, accedo
mediante la llamada a <code>M-x &lt;comando&gt;</code> y otras, me resulta más cómodo
que <i>Emacs</i> (<code>ivy</code> en mi caso) me vaya soplando qué funciones tengo
accesibles según la combinación que voy tecleando. Esa es la función
del paquete <code>which-key</code>. Su configuración es sencilla, me aseguro de
que está y lo tengo activado siempre:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> which-key
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:init</span>
  (which-key-setup-minibuffer)
  (which-key-mode))
</pre>
</div>

<p>
Hasta aquí, la funcionalidad general de <i>Emacs</i> para ejecutar comandos
del editor, realizar búsquedas de texto o de comando y trabajar con
plantillas que nos ahorran tiempo.
</p>
</div>
</div>
<div id="outline-container-org2171ac2" class="outline-2">
<h2 id="org2171ac2">Programación: alternativas</h2>
<div class="outline-text-2" id="text-org2171ac2">
<p>
Hablo de alternativas porque últimamente se ha extendido entre los
programadores la utilización de servidores <i>LSP</i> para la diversas
funcionalidades implicadas en la escritura de código, convirtiendo el
editor en un mero <i>cliente</i> de ese servidor. <i>Emacs</i> también
proporciona entre los paquetes internos un cliente para este tipo de
servidores: <code>eglot</code>. También existe otro paquete llamado <code>lsp-mode</code>
que realiza funciones similares a <code>eglot</code><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>

<p>
Si esa es tu forma de programar, descarga los <i>LSP</i> para los lenguajes
que utilices habitualmente y configura <code>eglot</code> (para los lenguajes más
habituales, seguramente no tendrás que hacer nada) y ponte a trabajar.
En este <i>blog</i> <a href="https://notxor.nueva-actitud.org/2023/08/14/eglot-lsp-para-emacs.html">también puedes encontrar información sobre <code>eglot</code>.</a>
</p>

<p>
He probado <i>LSP</i>, pero al final no me ha convencido: dependes de una
aplicación externa, que no siempre funciona porque tiene sus
configuraciones y sus <i>cadaunadas</i> que me suelen molestar más que
ayudar. Al final siempre vuelvo a modo clásico: configurar el editor
para el trabajo. Por otro lado, tanto <code>eglot</code> como <code>lsp-mode</code> terminan
tirando de los paquetes tradicionales: <code>projectile</code> o <code>project</code> para
la gestión de proyectos, modos para coloreado de sintaxis e indentado,
<code>company</code> o <code>auto-complete</code> para el autocompletado de términos,
<code>eldoc</code> para mostrar la ayuda, etc. Es decir, si al final voy a
utilizar esos mismos paquetes, ¿para qué voy necesito meter una
aplicación externa haciendo de intermediaria?
</p>

<p>
Lo que me lleva a pensar: ¿Qué funcionalidades necesito en mi editor
para programar?:
</p>

<ul class="org-ul">
<li>Gestión de proyectos</li>
<li>Coloreado de sintaxis</li>
<li>Completado</li>
<li>Ayuda en línea</li>
<li>Comprobación de errores</li>
</ul>
</div>
<div id="outline-container-org2f7904b" class="outline-3">
<h3 id="org2f7904b">Gestión de proyectos</h3>
<div class="outline-text-3" id="text-org2f7904b">
<p>
Si vienes de la utilización de algún <i>IDE</i>, puede parecerte escaso el
arsenal de herramientas de un <i>simple</i> editor. La desventaja de un
<i>IDE</i> es que suele estar diseñado o acondicionado para un determinado
lenguaje o tipo de proyectos. Es decir, proporciona toda la
funcionalidad necesaria para <i>su nicho</i> de programación pero abandona
el resto. La funcionalidad del <i>IDE</i> en estos tiempos modernos se ha
delegado en programas externos, los servidores <i>LSP</i> y convirtiendo el
<i>IDE</i> en un mero cliente de esos programas. Como he dicho antes,
puedes convertir <i>Emacs</i> en un cliente <i>LSP</i>, pero hay otras
alternativas.
</p>

<p>
Entre los paquetes <i>built-in</i> hay un par que nos facilitan la gestión
de proyectos: <code>EDE</code> y <code>project</code>. El objetivo del primero es convertir
<i>Emacs</i> en un <i>IDE</i>. Funciona, como otros <i>IDE</i>, creando un archivo de
proyecto donde guarda información sobre el mismo. Por el contrario,
<code>project</code> es mucho menos ambicioso y entiende que un proyecto está
donde haya un repositorio de código.
</p>

<p>
Sin embargo, me decanté por <code>projectile</code>. Es un paquete similar a
<code>project</code> pero con más funcionalidades
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Configuraci&#243;n para projectile
</span>(<span style="color: #ff79c6; font-weight: bold;">use-package</span> projectile
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:bind-keymap</span> ((<span style="color: #f1fa8c;">"C-c p"</span> . projectile-command-map))
  <span style="color: #8be9fd; font-style: italic;">:init</span>
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> projectile-project-search-path '(<span style="color: #f1fa8c;">"~/proyectos/"</span>))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> projectile-completion-system 'ivy)
  (projectile-mode t))
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">comprobaci&#243;n de sintaxis para `</span><span style="color: #bd93f9;">projectile</span><span style="color: #6272a4;">'
</span>(<span style="color: #ff79c6; font-weight: bold;">use-package</span> flycheck-projectile
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t)
</pre>
</div>

<p>
Sin ser exhaustivo, las principales funciones que esperas de un <i>IDE</i>
las puedes encontrar en ese paquete:
</p>

<ul class="org-ul">
<li>Búsqueda de archivos del proyecto.</li>
<li>Búsqueda de términos, funciones, variables en los archivos del
proyecto.</li>
<li>Reemplazo de términos a lo largo de los archivos del proyecto.</li>
<li>Gestión de directorios y archivos (con <code>dired</code>).</li>
<li>Acceso a una <i>shell</i> para el proyecto (con <code>eshell</code>).</li>
<li>Compilar el proyecto, ejecutarlo...</li>
<li>Ejecutar comandos de <i>shell</i> en el directorio del proyecto.</li>
<li>Acceso al repositorio de código del proyecto.</li>
</ul>

<p>
En fin, toda esa funcionalidad que necesitamos cuando estamos programando.
</p>
</div>
</div>
<div id="outline-container-org5b4dc24" class="outline-3">
<h3 id="org5b4dc24">Con los modos hemos topado</h3>
<div class="outline-text-3" id="text-org5b4dc24">
<p>
Efectivamente, para el resto de funciones necesarias para programar,
necesitamos tener claro en qué lenguaje(s) lo vamos a hacer. Por
defecto, <i>Emacs</i> viene con bastantes lenguajes de fábrica, <code>c/c++</code>,
<code>asm</code>, <code>emacs-lisp</code>, <code>scheme</code>, <code>java</code>... 
</p>

<p>
Otros lenguajes necesitarán que instales su correspondiente modo. ¿Qué
proporciona un modo?:
</p>

<ul class="org-ul">
<li>Coloreado de sintaxis.</li>
<li>Indentado del código siguiendo la costumbre generalizada del
lenguaje.</li>
<li>Comandos habituales del lenguaje, junto con sus combinaciones de
teclas y menús gráficos.</li>
</ul>

<p>
Como se puede apreciar es bastante escaso, añadiendo además la
historia de las indentaciones forzadas por el modo. Algo, que
descoloca mucho a usuarios nuevos que vienen de otros editores donde
tienen la costumbre de hacer de su capa un sayo e indentar como a
ellos les parece.
</p>

<p>
Si alguien tiene curiosidad sobre los modos y cómo se programa uno, en
este <i>blog</i> puede encontrar <a href="https://notxor.nueva-actitud.org/2019/02/15/creando-un-modo-menor-sencillo-y-sin-muchas-pretensiones.html">cómo programar un modo menor</a> y
su continuación <a href="https://notxor.nueva-actitud.org/2019/02/20/variables-de-modo-keymaps-y-menus.html">sobre teclas y menús</a>, aunque también sobre la
<a href="https://notxor.nueva-actitud.org/2019/03/14/creacion-de-un-modo-mayor-para-emacs.html">programación de un modo mayor</a>... por si alguna vez le hiciera falta.
</p>
</div>
</div>
<div id="outline-container-org28c4ab2" class="outline-3">
<h3 id="org28c4ab2">Autocompletado</h3>
<div class="outline-text-3" id="text-org28c4ab2">
<p>
Mientras programamos es muy útil que el sistema nos vaya sugiriendo
alternativas de lo que podemos o no escribir: no sólo nos ahorra unas
pocas pulsaciones de teclas, sino que, además, nos evita errores de
tecleo, algo inevitable cuando escribes deprisa.
</p>

<p>
De nuevo tienes que elegir entre dos alternativas: <code>company</code> y
<code>auto-complete</code>. La mayoría de lenguajes están soportado por ambas.
Aunque puedes encontrar algunos lenguajes que sólo están soportados
por una de las opciones y, en ese caso, te ahorras tener que elegir.
En mi caso utilizo <code>company</code>. Además de los paquetes generales hay que
instalar su correspondiente <code>company-&lt;lenguaje&gt;</code> o <code>ac-&lt;lenguaje&gt;</code>
para dar mejor soporte al autocompletado. En mi caso utilizo <code>company</code>
y lo tengo activado de manera general.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">paquete de autocompletado
</span>(<span style="color: #ff79c6; font-weight: bold;">use-package</span> company
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:init</span>
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> company-tooltip-align-annotations t)
  <span style="color: #8be9fd; font-style: italic;">:config</span>
  (global-company-mode t))
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">para utilizar iconos en los desplegables de autocompletado
</span>(<span style="color: #ff79c6; font-weight: bold;">use-package</span> company-box
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t
  <span style="color: #8be9fd; font-style: italic;">:after</span> company
  <span style="color: #8be9fd; font-style: italic;">:hook</span> 'company-mode-hook 'company-box-mode)
</pre>
</div>
</div>
</div>
<div id="outline-container-org73e42ce" class="outline-3">
<h3 id="org73e42ce">Documentación en línea</h3>
<div class="outline-text-3" id="text-org73e42ce">
<p>
Otra de las herramientas que son muy útiles, sobre todo a la hora de
programar, es contar con un <i>chivato</i> que nos indique qué parámetros
tiene una función o incluso qué es lo que hace. Para realizar estas
funciones contamos con el paquete <code>eldoc</code>, que es otro de esos
paquetes que no necesitas hacer nada, porque vienen con la
distribución por defecto de <i>Emacs</i>, sólo activarlo cuando lo
utilices. Si es como en mi caso, que quiero que esté activo siempre,
puedes activarlo de manera global:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(global-eldoc-mode t)
</pre>
</div>

<p>
De este modo mostrará, bajo la línea de estado la información con la
que cuente el sistema. Por ejemplo, trabajando en <code>org-mode</code> al situar
el cursor en la primera línea de un bloque de código, nos muestra en
el <i>minibuffer</i> la información de las alternativas.
</p>


<figure id="org812c81f">
<img src="./imagenes/Captura_eldoc.png" alt="Captura_eldoc.png">

</figure>

<p>
Si prefieres que dicha información la muestre en un marco junto al
cursor, puedes instalar también el paquete <code>eldoc-box</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> eldoc-box
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t
  <span style="color: #8be9fd; font-style: italic;">:init</span> (<span style="color: #ff79c6; font-weight: bold;">setq</span> eldoc-box-hover-mode t))
</pre>
</div>
</div>
</div>
<div id="outline-container-org204a3d1" class="outline-3">
<h3 id="org204a3d1">Comprobación de errores</h3>
<div class="outline-text-3" id="text-org204a3d1">
<p>
En este caso hablaré de dos vertientes: la primera está relacionada
con la escritura de textos y la segunda con la escritura de código.
Ambos casos <i>al vuelo</i> (<code>fly</code>): <code>flyspell</code> y <code>flycheck</code>.
</p>

<p>
En el caso de la escritura de textos, como los artículos de este
<i>blog</i>, tener activado el <i>diccionario al vuelo</i> que me avise de
errores de tecleo es una ayuda extraordinaria. El modo <code>flyspell</code>
viene también entre las utilidades incluidas en la distribución por
defecto de <i>Emacs</i>. Los únicos ajustes que hago son los del idioma y
la aplicación de corrección. Puesto que utilizo más frecuentemente el
español, lo configuro a ese idioma, aunque luego también se podrá
cambiar el diccionario, según la lengua en la que estés trabajando.
Por tanto, en el archivo de <code>mi-custom-var.el</code> tengo las siguientes
entradas:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">'(ispell-dictionary <span style="color: #f1fa8c;">"espanol"</span>)
'(ispell-program-name <span style="color: #f1fa8c;">"aspell"</span>)
'(ispell-list-command <span style="color: #f1fa8c;">"--list"</span>)
</pre>
</div>

<p>
Por supuesto, lo utilizo principalmente cuando escribo texto, así que
tengo también configurado un gancho para que al entrar en cualquier
modo de texto se active <code>flyspell</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-hook 'text-mode-hook 'turn-on-flyspell)
</pre>
</div>

<p>
En el caso de la escritura de código mi elección personal ha sido
utilizar <code>flycheck</code>. Hay otro paquete, <code>flymake</code>, que viene por
defecto con <i>Emacs</i>, sin embargo, soporta muchos menos lenguajes de
programación que <code>flycheck</code> y sus explicaciones sobre errores son
inexistentes. En ese sentido, la información que brinda <code>flycheck</code> es
mucho más completa y te ayuda en la corrección de errores.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">configuraci&#243;n para flycheck
</span>(<span style="color: #ff79c6; font-weight: bold;">use-package</span> flycheck
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t)
(add-hook 'prog-mode-hook 'flycheck-mode)
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-orgaa8ba94" class="outline-2">
<h2 id="orgaa8ba94">Conclusiones</h2>
<div class="outline-text-2" id="text-orgaa8ba94">
<p>
Hecho el repaso general, como digo, muchos aspectos dependen de
gustos. Cuando llevas un tiempo trabajando con un sistema tienes más
oportunidades para hacer pruebas, ver si te convence más o menos una
determinada herramienta. Al final son decisiones personales que tomas
por motivos también personales.
</p>

<p>
Espero que este artículo pueda servir a quien se introduce en <i>Emacs</i>
a tener una perspectiva general sobre la configuración. Algo que a
muchos puede parecer abrumador, dada la cantidad de opciones, detalles
y aspectos que se pueden ajustar.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Podéis encontrar la información aquí <a href="https://emacs-lsp.github.io/lsp-mode/">https://emacs-lsp.github.io/lsp-mode/</a> 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2024/02/02/emacs-configuraciones-basicas.html</link>
  <pubDate>Fri, 02 Feb 2024 12:02:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Introducción a PicoLisp]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-12-31</div>
<p>
Llevo unas semanas trasteando ya con <i>PicoLisp</i> y he querido poner por
escrito las primeras impresiones este final de año. Como propósito del
año nuevo, ya comenté que la idea es hacer algún proyecto para
aprender cómo funciona y estas son las primeras impresiones.
</p>

<p>
He de confesar que se me está atragantando un poco, quizá por <i>el
ansia viva</i> de intentar tragar más de lo que puedo masticar. Quiero
decir, que me las daba de <i>esto está controlao</i> y no, no lo está.
Después de un par de guantazos propinados por el sistema para
despertarme de mi error, tuve que volver a la documentación, tratar de
poner en orden mis ideas, olvidar algunos prejuicios, formados por el
conocimiento previo de <i>Lisp</i> y <i>Scheme</i>, y mejorar la concentración
en lo que estoy haciendo.
</p>

<p>
Torpe de mí, pensé que siendo un <i>Lisp</i> la cosa iba a ser fácil,
porque muchos conceptos los tengo ya asumidos e interiorizados. El
problema es que no es un <i>common lisp</i>, ni tampoco un <i>Scheme</i>.
Mantiene la sintaxis de la familia, pero es otra cosa completamente
distinta.
</p>

<p>
En teoría, <i>PicoLisp</i> es una herramienta que proporciona todo lo que,
generalmente, se necesita para hacer una aplicación, pero de manera
minimalista, para no tomar excesivas decisiones de diseño. Sin
embargo, sí hay muchas decisiones tomadas, que pueden ser vistas como
limitaciones, pero a la vez proporciona una flexibilidad
extraordinaria que permite hacer cualquier cosa.
</p>

<p>
Por ejemplo, en 28 líneas de <i>script</i> tienes un mínimo ejemplo de
<i>chat</i> funcional, <i>multihilo</i>.
</p>

<div class="org-src-container">
<pre class="src src-plisp">#!/usr/bin/picolisp /usr/lib/picolisp/lib.l

(de chat Lst
    (out *Sock
         (mapc prin Lst)
         (prinl) ) )

(setq *Port (port 4004))

(loop
  (setq *Sock (listen *Port))
  (NIL (fork) (close *Port))
  (close *Sock) )

(out *Sock
     (prin "Please enter your name: ")
     (flush) )

(in *Sock (setq *Name (line T)))

(tell 'chat "+++ " *Name " arrived +++")

(task *Sock
      (in @
       (ifn (eof)
            (tell 'chat *Name "&gt; " (line T))
            (tell 'chat "--- " *Name " left ---")
            (bye) ) ) )
</pre>
</div>

<p>
¿Interesante? Pues vamos a ver cómo trabajar en <i>Emacs</i> con él. Luego
ya me meteré en los aspectos más desconcertantes para mí.
</p>
<div id="outline-container-org5f6457c" class="outline-2">
<h2 id="org5f6457c">Configurar <i>Emacs</i> para <i>PicoLisp</i></h2>
<div class="outline-text-2" id="text-org5f6457c">
<p>
Seré breve. Encontré un paquete en <i>Melpa</i> que se llama <code>plisp-mode</code> y
otro para autocompletado <code>company-plisp</code>. Los instalé los dos
siguiendo sus correspondientes documentaciones. El código es sencillo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> plisp-mode
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t
  <span style="color: #8be9fd; font-style: italic;">:init</span>
  (<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">inferior-plisp</span>)
  <span style="color: #8be9fd; font-style: italic;">:custom</span>
  (plisp-documentation-unavailable t))
(<span style="color: #ff79c6; font-weight: bold;">use-package</span> company-plisp
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t
  <span style="color: #8be9fd; font-style: italic;">:after</span> company)
(add-to-list 'auto-mode-alist '(<span style="color: #f1fa8c;">"\\.l$"</span> . plisp-mode))
</pre>
</div>

<p>
Hay que tener en cuenta las siguientes aclaraciones. Tengo la
instalación de <i>PicoLisp</i> de manera local. El paquete <code>plisp-mode</code>
busca la documentación de manera global así que me aparecía
constantemente un error por no encontrarla y desactivé la búsqueda de
la misma activando la variable <code>plisp-documentation-unavailable</code>.
También hice otras pruebas creando los enlaces necesarios para
convertir la instalación local en global y seguía sin encontrar la
documentación. Sin embargo, en la línea de comandos la documentación
está disponible cuando inicias <i>PicoLisp</i> en modo <i>debug</i>.
</p>

<p>
Para leer la documentación desde línea de comandos, por tanto, hay que
lanzar el <i>REPL</i> en modo depuración. El sistema leerá los <code>html</code> que
componen la documentación utilizando el navegador <code>w3m</code>. Por ejemplo,
llamando a la función <code>(doc 'de)</code>, nos mostrará el contenido de la
documentación de dicha función, llamando a dicho navegador de modo
texto. <code>w3m</code> es, por tanto, una dependencia si quieres acceder a la
documentación desde <code>pil</code>.
</p>

<p>
Por último, la convención dice que el código de <i>PicoLisp</i> se
encuentra en archivos con extensión <code>.l</code> y añado dicha extensión,
asociándola a <code>plisp-mode</code> en la lista de modos.
</p>
</div>
</div>
<div id="outline-container-org3f5c625" class="outline-2">
<h2 id="org3f5c625">Choques para programadores <i>Lisp</i></h2>
<div class="outline-text-2" id="text-org3f5c625">
<p>
Es evidente la sintaxis de tipo <i>Lisp</i> con sus paréntesis en danza,
pero para un programador de este tipo de lenguajes tiene pocas más
semejanzas y hacerse una idea de lo que hace le obliga a utilizar su
imaginación. Algunas funciones parecen sonar <code>setq</code>, <code>loop</code>... pero
<code>de</code> en lugar de <code>define</code>, que admite una lista de parámetros con el
formato <code>Lst</code> en lugar del habitual <code>(...)</code>. Variables que comienzan
con <code>*</code>, como <code>*Name</code>, mientras que otras no, como <code>Lst</code>. Es decir,
hay un montón de idiosincrasias que hay que tener en cuenta.
</p>

<p>
La primera bofetada fue por su forma de establecer las variables. Lo
de utilizar la primera letra en mayúsculas, por convención, pues
tampoco es que me llame mucho la atención, o utilizar <code>*</code> para señalar
las variables globales mediante un prefijo simple. Pero quizá algún
programador de <i>Lisp</i> o <i>Scheme</i> entenderá mejor lo que quiero decir
con este código:
</p>

<div class="org-src-container">
<pre class="src src-plisp">: (setq A '(Este es su valor))
-&gt; (Este es su valor)
: (put 'A 'clave1 'valor1)
-&gt; valor1
: (put 'A 'clave2 'valor2)
-&gt; valor2
: (show 'A)
A (Este es su valor)
   clave2 valor2
   clave1 valor1
-&gt; A 
</pre>
</div>

<p>
Sí, se pueden meter pares <i>clave-valor</i> como parte de cualquier
«variable». Se introducen con <code>put</code> y se extraen con <code>get</code>. Más
adelante veremos que tiene que ver con cómo se definen los símbolos
dentro de la máquina virtual. Pero de primeras me sonó <i>marciano</i>.
</p>

<p>
Se puede apreciar que la definición de variables se utiliza <code>setq</code>,
también las podemos definir con <code>de</code>, aunque con su propia
idiosincrasia:
</p>

<div class="org-src-container">
<pre class="src src-plisp">: (de ho "hola")
-&gt; ho
: ho
-&gt; ("hola")
: (ho)
-&gt; NIL
: (de ho . "hola")
# ho redefined
-&gt; ho
: ho
-&gt; "hola"
</pre>
</div>

<p>
La primera versión de <code>ho</code>, en ese código, puede no ser la deseada.
De momento me ciño a utilizar <code>setq</code> para las variables y <code>de</code> para
las funciones, para no liarme.
</p>

<p>
Luego me llevé otra bofetada aún más gorda con los números. Leí, así
de pasada, que soportaba sólo operaciones de <i>coma fija</i>, por lo que
hay que especificar el número de decimales cuando los necesitas.
Bueno, no es algo extraño y ya lo había vivido en otro tipo de
sistemas, como la calculadora de línea de comandos <code>bc</code>, pero el
choque con la realidad fue un poco más traumático.
</p>

<div class="org-src-container">
<pre class="src src-plisp">? (+ (* 3 4) 1)
-&gt; 13
? 
: (/ @ 3)
-&gt; 4
: (scl 3)
-&gt; 3
: (+ (* 3.0 4.0) 1)
-&gt; 12000001
</pre>
</div>

<p>
¿Cómo? ¿Qué está ocurriendo? Pues sí, a los números hay que darles un
poco más de cariño.
</p>

<p>
La cantidad de decimales se almacena en una variable global que se
llama <code>*Scl</code> y podemos establecerlos con la función <code>scl</code>, como se
aprecia en el código anterior. Pero se puede ver que internamente
<code>3.0</code> se convierte en <code>3000</code> y <code>4.0</code> en <code>4000</code>, al establecerse tres
posiciones decimales. Y, por esto mismo, al multiplicar los números el
resultado es <code>12.000.000</code>, o expresado de otro modo: al multiplicar \(3
\cdot 10^3 \times 4 \cdot 10^3\) el resultado es \(12 \cdot 10^6\). Es
decir, <i>PicoLisp</i> no tiene en cuenta automáticamente los decimales,
sino que mantiene los enteros, pero escalados.
</p>

<p>
Con las sumas y restas no hay problema, porque los números cuando
tienen una escala, se mantienen dentro de la <i>escala</i>, pero en las
multiplicaciones y divisiones hay que compensar la escala. Para ello
se utiliza la función <code>*/</code>, que recibe tres parámetros numéricos y
multiplica los dos primeros para luego dividir el resultado por el
tercero. Por lo tanto, se utiliza la multiplicación o división por
<code>1.0</code> para mantener la escala en orden:
</p>

<div class="org-src-container">
<pre class="src src-plisp">: (+ (*/ 3.0 4.0 1.0) 1.0)
-&gt; 13000
: (*/ 1.0 13.0 4.0)
-&gt; 3250
: (format (*/ 1.0 13.0 4.0))
-&gt; "3250"
: (format (*/ 1.0 13.0 4.0) *Scl)
-&gt; "3.250"
: (format "3.25" *Scl)
-&gt; 3250
: 
</pre>
</div>

<p>
Después, se puede contar con la función <code>format</code> para convertir
números en cadenas y cadenas en números.
</p>

<p>
Al principio, toda esta movida me parecía un <i>sindiós</i>. Luego, me puse
a mirar cómo funciona el <i>chismático</i> y encontré los porqués y las
explicaciones a todas estas idiosincrasias. Aunque estuvieron a punto
de echarme para atrás.
</p>
</div>
</div>
<div id="outline-container-orgf05bce2" class="outline-2">
<h2 id="orgf05bce2">Tipos de datos</h2>
<div class="outline-text-2" id="text-orgf05bce2">
<p>
Puesto que las primeras aproximaciones fueron un poco frustrantes, lo
siguiente que hice es echar un vistazo a la documentación buscando por
qué estaba pasando lo que pasaba. Os hago un resumen de lo que
encontré y cómo funciona la máquina virtual de <i>PicoLisp</i>, que soporta
los siguientes tipos de datos:
</p>


<figure id="org1455fff">
<img src="./imagenes/jerarquita-tipos-picolisp.svg" alt="jerarquita-tipos-picolisp.svg" class="org-svg">

</figure>

<p>
En base a la definición básica de <code>cell</code>, soporta:
</p>

<ul class="org-ul">
<li>Los tres tipos de datos básicos: Números, símbolos y listas.</li>
<li>Los tres tipos de símbolos: <i>Internal</i>, <i>Transient</i> y <i>External</i>.</li>
<li>El símbolo especial <code>NIL</code>.</li>
</ul>

<p>
Un tipo de dato <code>cell</code> se define, como se ve en la siguiente imagen,
en un conjunto de <code>CAR</code> y <code>CDR</code>. Algo que es común en los lenguajes
<i>Lisp</i>.
</p>


<figure id="orgadb8694">
<img src="./imagenes/cell.svg" alt="cell.svg" class="org-svg" width="100px">

</figure>
</div>
<div id="outline-container-org60a2a40" class="outline-3">
<h3 id="org60a2a40">Los números</h3>
<div class="outline-text-3" id="text-org60a2a40">
<p>
Hay dos tipos de números, los cortos y los largos. Ambos serán siempre
enteros. Un número corto cabe en 60 bits, e internamente, tiene la
forma:
</p>

<pre class="example" id="org698e8a7">
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxS010
</pre>

<p>
donde las <code>x</code> representan el valor numérico. Se pone el bit 1 a 1 para
señalar que es un número corto y <code>S</code> representa el signo. Si en lugar
de tener marcado el bit 1 tiene marcado el bit dos, es decir:
</p>

<pre class="example" id="orge1b9b57">
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxS100
</pre>

<p>
estaremos ante un número largo y las <code>x</code> se interpretan como un
puntero al siguiente dígito:
</p>


<figure id="org8c0d0fb">
<img src="./imagenes/bignum-picolisp.svg" alt="bignum-picolisp.svg" class="org-svg" width="200px">

</figure>

<p>
Es decir un <code>bignum</code> se convierte en una lista de dígitos, marcada
internamente como número largo.
</p>
</div>
</div>
<div id="outline-container-orgc0d269a" class="outline-3">
<h3 id="orgc0d269a">Los símbolos</h3>
<div class="outline-text-3" id="text-orgc0d269a">
<p>
Un símbolo es más complejo que un número. Cada símbolo tiene un valor
y opcionalmente tendrá un nombre y un número arbitrario de
propiedades. El más sencillo sería un símbolo sin nombre ni
propiedades, por lo que podría contenerse en una sola <code>cell</code>:
</p>


<figure id="orgc23510d">
<img src="./imagenes/simbolo-minimo-picolisp.svg" alt="simbolo-minimo-picolisp.svg" class="org-svg" width="100px">

</figure>

<p>
Internamente, para indicar que es un símbolo se activará el bit 3,
de la siguiente forma:
</p>

<pre class="example" id="orgc37229e">
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1000
</pre>

<p>
Por ejemplo, si tenemos definido un símbolo con el nombre
<code>"abcdefghijklmno"</code> que tenga tres propiedades además de su
correspondiente <i>valor</i>, podríamos tener el siguiente esquema:
</p>


<figure id="org54109df">
<img src="./imagenes/simbolo-ejemplo-picolisp.svg" alt="simbolo-ejemplo-picolisp.svg" class="org-svg" width="450px">

</figure>

<p>
Una propiedad es un par <i>clave-valor</i>, si sólo aparece una <i>clave</i> se
toma el valor de dicha propiedad como un <code>T</code> booleano.
</p>
</div>
</div>
<div id="outline-container-org10ca9bc" class="outline-3">
<h3 id="org10ca9bc">Las listas</h3>
<div class="outline-text-3" id="text-org10ca9bc">
<p>
Mientras los números y los símbolos se consideran <code>atom</code> dentro de
<i>PicoLisp</i>, las listas son consideradas un tipo complejo a partir del
cual se pueden implementar otras estructuras como arrays, colas, pilas
o árboles.
</p>

<p>
Normalmente el <code>CDR</code> de cada célula apunta a la célula siguiente:
</p>


<figure id="orgfa50fef">
<img src="./imagenes/listas-picolisp.svg" alt="listas-picolisp.svg" class="org-svg" width="150px">

</figure>

<p>
La última célula de una lista puede tener un valor <code>NIL</code> o apuntar a
un <code>atom</code>. En este último caso se le llama <i>dotted pair</i>, pues la
notación en texto es marcarlo con un punto de separación, como se hace
en el resto de sus primos <i>Lisp</i> y <i>Scheme</i>. Dejo para el lector el
tema de las listas circulares, que también se pueden generar llamando
a la función <code>circ</code>, pero que son un caso especial que hay que manejar
con cuidado pues podemos generar bucles infinitos en funciones que las
recorran y se utilizan con menos frecuencia.
</p>

<p>
Podemos tener listas de un sólo elemento. Por ejemplo <code>(A)</code> es una
lista que tendrá una sola célula con el carácter <code>A</code> en el <code>CAR</code> y
<code>NIL</code> en el <code>CDR</code>.
</p>
</div>
</div>
<div id="outline-container-orga5721d9" class="outline-3">
<h3 id="orga5721d9">Tipos de símbolos</h3>
<div class="outline-text-3" id="text-orga5721d9">
<p>
<i>PicoLisp</i> es <i>case sensitive</i>, no como <i>CLisp</i>. Es decir, los
símbolos <i>Dato</i> y <i>dato</i> no son el mismo. Además, por convención, las
variables utilizan la primera letra en mayúscula, mientras que las
funciones son todo minúsculas. Esto evita también el choque de nombres
y pueden existir en el mismo sistema una variable <code>Foo</code> y una función
<code>foo</code>.
</p>

<p>
Además se utilizan las siguientes convenciones para los nombres de los
símbolos:
</p>

<ul class="org-ul">
<li>Las variables globales comienzan con un asterisco, por ejemplo:
<code>*Foo</code>.</li>
<li>Las constantes globales se escriben en mayúsculas todo: <code>FOO</code></li>
<li>Las funciones y otros símbolos globales comienzan con minúsculas:
<code>foo</code>.</li>
<li>Los símbolos locales comienzan con la primera letra mayúscula:
<code>Foo</code>.</li>
<li>Las funciones locales comienzan con un carácter de subrayado:
<code>_foo</code>.</li>
<li>Las clases comienzan con un signo <code>+</code>: <code>+Foo</code> o <code>+foo</code>.
<ul class="org-ul">
<li>en minúscula para marcar clases abstractas,</li>
<li>en mayúscula para el resto de clases.</li>
</ul></li>
<li>Los métodos terminan con un símbolo <code>&gt;</code>: <code>foo&gt;</code>.</li>
<li>Las variables de clase se indican también con la primera letra
mayúscula, como las variables locales: <code>Foo</code>.</li>
</ul>

<p>
Estas convenciones son voluntarias, pero deseables. Sin embargo, es
obligatorio identificar algunos casos, como el <i>tipo</i> de símbolo:
</p>

<ul class="org-ul">
<li>Los símbolos temporales o <i>transient</i> se marcan con el símbolo de
dobles comillas <code>"</code>.</li>
<li>Los símbolos externos se marcan utilizando el par <code>{...}</code>.</li>
<li><p>
Los patrones se marcan con un carácter <code>@</code>:
</p>

<div class="org-src-container">
<pre class="src src-plisp">: (match '(@A es @B) '(Esto es una prueba))
-&gt; T
: @A
-&gt; (Esto)
: @B
-&gt; (una prueba)
: 
</pre>
</div></li>

<li>Los símbolos provenientes de librerías contienen un sigo <code>:</code>, con la
forma <code>lib:simb</code>.</li>
</ul>

<p>
Hay tres tipos fundamentales de símbolos, además del símbolo especial
<code>NIL</code>:
</p>

<dl class="org-dl">
<dt><i>Internal</i></dt><dd>Los símbolos <i>internal</i> son símbolos normales, que
pueden ser definiciones de variables o funciones. Se indexan en una
estructura y por lo tanto no puede haber dos símbolos con el mismo
nombre. El valor inicial de un símbolo de este tipo, cuando se crea
es <code>NIL</code>.</dd>
<dt><i>Transient</i></dt><dd>Los símbolos <i>transitorios</i> se guardan temporalmente
en su propio índice, —como cuando se lee el código fuente desde un
archivo— y se liberan después.</dd>
<dt><i>External</i></dt><dd>Los <i>símbolos externos</i> residen en un fichero de base
de datos o en otros recursos que se cargan en memoria. Los símbolos
externos se mantienen en un índice y mientras están cargados en
memoria no puede haber dos con el mismo nombre. Además tienen
codificada su dirección externa junto al nombre, para poder guardar
los cambios.</dd>
<dt><code>NIL</code></dt><dd>Este símbolo es especial, sólo existe uno en todo el
sistema de <i>PicoLisp</i> y, además de señalar el final de las listas y
ser el inicio de la jerarquía de clases, se puede utilizar como
valor booleano <i>falso</i>, o como cadena de largo cero, o como valor
<code>NaN</code>, final de fichero, etc.</dd>
</dl>
</div>
</div>
</div>
<div id="outline-container-org73f611a" class="outline-2">
<h2 id="org73f611a">El código</h2>
<div class="outline-text-2" id="text-org73f611a">
<p>
El código se guarda en símbolos internos. Una definición de una
función lo que hace es crear un símbolo cuyo valor es el código. No
hay, por tanto, diferencia entre el tratamiento del código y de los
datos, son equivalentes.
</p>

<p>
Para definir una función se utiliza normalmente una llamada a la
función <code>de</code>:
</p>

<div class="org-src-container">
<pre class="src src-plisp">: (de hola ()
   (prinl "¡Hola Mundo!"))
-&gt; hola
: (hola)
¡Hola Mundo!
-&gt; "¡Hola Mundo!"
: 
</pre>
</div>

<p>
Pero el resultado sería idéntico si utilizamos <code>setq</code>:
</p>

<div class="org-src-container">
<pre class="src src-plisp">: (setq hola '(() (prinl "¡Hola Mundo!")))
-&gt; (NIL (prinl "¡Hola Mundo!"))
: (hola)
¡Hola Mundo!
-&gt; "¡Hola Mundo!"
: 
</pre>
</div>

<p>
Otro de los problemas, que me encuentro frecuentemente al escribir
código, es el interpretar el <code>'</code> como en <i>Lisp</i> o en <i>Scheme</i>. En
<i>PicoLisp</i> el <code>quote</code> se aplica a toda la lista, no sólo al primer
elemento.  Esto me desconcertó un poco al principio y aún no me he
acostumbrado del todo. Aunque también he aprendido que se puede forzar
la evaluación de alguna expresión interna utilizando el carácter <code>~</code>.
</p>

<div class="org-src-container">
<pre class="src src-plisp">: '(1 (+ 2 3) 4)
-&gt; (1 (+ 2 3) 4)
: '(1 ~(+ 2 3) 4)
-&gt; (1 5 4)
: 
</pre>
</div>

<p>
No hay <i>macros</i> explícitas, porque cualquier función puede devolver
una cadena de texto, que si mantiene la sintaxis de <i>PicoLisp</i>, está
generando código como lo haría una <i>macro</i>. Si vas a utilizar
<i>metaprogramación</i> es conveniente que le eches un ojo antes a cómo
evalúa el código la máquina virtual de <i>PicoLisp</i>.
</p>

<p>
Tampoco hay una expresión <code>lambda</code>, pues, como hemos visto al utilizar
una función <code>setq</code> para definir una <i>lambda</i>, se puede generar una
función anónima simplemente con <code>quote</code>:
</p>

<div class="org-src-container">
<pre class="src src-plisp">(setq hola (quote () (prinl "¡Hola Mundo!")))
</pre>
</div>

<p>
O por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-plisp">: ('((X) (* X X)) 3)
-&gt; 9
: ((quote (X) (* X X)) 9)
-&gt; 81
: (setq f '((X) (* X X) ) )
-&gt; ((X) (* X X))
: (f 3)
-&gt; 9
: 
</pre>
</div>

<p>
Si te molestan mucho los paréntesis los puedes agrupar utilizando <code>[</code>
y <code>]</code>. Por ejemplo, la definición anterior la podríamos haber definido
también como:
</p>

<div class="org-src-container">
<pre class="src src-plisp">: (setq f '((X) (* X X]
-&gt; ((X) (* X X))
: (f 3)
-&gt; 9
</pre>
</div>
</div>
<div id="outline-container-org5ad0355" class="outline-3">
<h3 id="org5ad0355">Funciones con un número indeterminado de parámetros</h3>
<div class="outline-text-3" id="text-org5ad0355">
<p>
Para las ocasiones, en que no sabemos cuántos parámetros puede recibir
una función se utiliza el <i>comodín</i> <code>@</code> y se utilizan las variables
<code>args</code>, <code>next</code> y <code>rest</code> para evaluar elemento a elemento la lista de
parámetros:
</p>

<div class="org-src-container">
<pre class="src src-plisp">: (de foo @
   (while (args)
     (println (next) (args) (rest)) ) )
-&gt; foo
: (foo 1 2 3 4)
1 T (2 3 4)
2 T (3 4)
3 T (4)
4 NIL NIL
-&gt; NIL
: 
</pre>
</div>

<p>
En el código anterior:
</p>

<ul class="org-ul">
<li><code>args</code> es un booleano que indica si hay más argumentos que evaluar.</li>
<li><code>next</code> devuelve el siguiente argumento a evaluar.</li>
<li><code>rest</code> devuelve una lista con los argumentos que faltan por evaluar.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org3ab300b" class="outline-2">
<h2 id="org3ab300b">Conclusiones</h2>
<div class="outline-text-2" id="text-org3ab300b">
<p>
Estos son los ladrillos básicos de <i>PicoLisp</i>. Algunos me ha costado
cierto trabajo <i>digerirlos</i>, sin embargo, ha sido más por tener los
procesos mentales acostumbrados a otro tipo de sistemas. Aún cometo
muchos errores cuando escribo código, precisamente por esto. Aunque
comencé estrellándome, confiado en mi conocimiento de <i>Common Lisp</i> y
de <i>Scheme</i>, al mirar cómo está hecha la máquina virtual y «los
ladrillos» de este sistema, me fue más fácil interiorizar cómo
funcionan la cosas y cometer menos errores.
</p>

<p>
A partir de estos <i>chismáticos</i> básicos, <i>PicoLisp</i> proporciona
algunas características interesantes, que dejo para futuros artículos:
</p>

<ul class="org-ul">
<li>Soporte nativo de <i>Programación Orientada a Objetos</i>.</li>
<li>Base de Datos orientada a almacenar objetos POO.</li>
<li>Lenguaje de consulta de la BD basado en <i>Prolog</i>.</li>
<li>GUI basado en <code>html</code> y su correspondiente servidor de aplicaciones.</li>
<li>Sistema de <i>debug</i> incorporado</li>
<li>Editor de código interno basado en <code>vi</code>.</li>
</ul>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/picolisp/index.html">picolisp</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[picolisp]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2023/12/31/introduccion-a-picolisp.html</link>
  <pubDate>Sun, 31 Dec 2023 10:45:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Resumen anual y futuro]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-12-18</div>
<p>
Atravesamos el solsticio de invierno. Momento en el que los
calendarios marcan la época de reflexión y renovación. En este
artículo vengo a hacer un poco de resumen del año pasado y dar unas
pinceladas sobre lo que me espero que llegue en el 2024.
</p>
<div id="outline-container-org87cc414" class="outline-2">
<h2 id="org87cc414">Lo pasado, pasado está</h2>
<div class="outline-text-2" id="text-org87cc414">
<p>
Este año empezó con bastante actividad por este <i>blog</i>, tenía bastante
tiempo y hubo meses con más de un artículo semanal. Sin embargo,
después de verano mis otras obligaciones me desaparecieron
prácticamente el tiempo libre o las ganas de sentarme a escribir.
Mucha reunión, mucho desplazamiento y mucho desgaste intelectual
hicieron que cuando llegaba a casa no me apeteciera sentarme a
estrujarme la sesera para trastear con algo y ponerlo por escrito en
este <i>blog</i>.
</p>

<p>
Como resumen general queda el trasteo de un poco de <i>vaporware</i> con
algún lenguaje de programación minoritario (de los que me gustan a
mí), como el programa de ajedrez, que al final se quedó en proyecto
inconcluso. Pero también está, esta vez sí cumplido, mi propósito de
ampliar mis conocimientos de <i>LISP</i> y sus derivados, como <i>Scheme</i>. No
sólo eso, sino que también he probado algunas otras herramientas que
debo profundizar. De momento, entre los <i>LISP</i> tengo el «corazón
partío» entre <code>SBCL</code> y <code>ECL</code>, aunque entre los <i>Scheme</i> sí me he
decantado por <i>Chicken Scheme</i>.
</p>
</div>
</div>
<div id="outline-container-org66cbbd8" class="outline-2">
<h2 id="org66cbbd8">El futuro está por verse</h2>
<div class="outline-text-2" id="text-org66cbbd8">
<p>
Este año que viene se plantea algo más movido aún en otros ámbitos y
no sé cuánto tiempo me quedará para el <i>blog</i>. A través del proyecto
de <a href="https://hispa-emacs.org/">Hispa-Emacs</a> se quiere aglutinar en lo posible la información sobre
<i>Emacs</i> que se realice en español. Junto con Fénix y Maxxcan espero la
resurrección del perdido <i>planet-emacs.es</i>. Maxxcan tiene ya comprado
el dominio y solicitó ayuda para ponerlo en marcha, así que mi
intención es poder echar una mano también con ese proyecto de
relanzamiento.
</p>

<p>
Con respecto a <i>Hispa-Emacs</i> la idea es generar una página web
estática con información, cursos y una colección de vídeos, en
<a href="https://fediverse.tv/c/hispa_emacs/videos">Fediverse.tv</a>, sobre <i>Emacs</i>. También, para realizar todo el código que
necesitemos, se ha creado <a href="https://codeberg.org/hispa-emacs">un grupo en Codeberg</a> para alojar los
repositorios necesarios de <i>Hispa-Emacs</i>. De momento Fénix y yo somos
los dos únicos voluntarios, pero si estás interesado en participar
ponte en contacto con nosotros para ver si conseguimos montar un buen
grupo de trabajo.
</p>

<p>
Por supuesto, está por ver dónde acaba toda esta iniciativa, pero mi
intención es dedicar tiempo (y código) a ello. Pero, sobre todo, sin
abandonar este <i>blog</i>, aunque quizá encontréis contenido cruzado y
alguna repetición de trasteos si sigues ambas iniciativas. Mi tiempo
no es infinito.
</p>

<p>
También, para el año venidero tengo pensado profundizar un poco más en
una herramienta que ya he mencionado en el <i>blog</i>: <a href="https://picolisp.com">PicoLisp</a>. ¿Por qué?
Pues básicamente porque aunque no es un <i>LISP</i> —al menos, no un
<i>Common Lisp</i> como <code>sbcl</code> o <code>ecl</code> lo son—, tiene una sintaxis parecida
a la familia. Además cuenta con algunas otras características que lo
hacen interesante para mí: tiene un montón de <i>chismáticos</i> con los
que me gusta trastear:
</p>

<ul class="org-ul">
<li>Sintaxis: estilo <i>LISP</i>, que ya lo he comentado, aunque me parece un
<i>chismático</i> más parecido a <i>Scheme</i>.</li>
<li>Multiparadigma: tanto <i>POO</i>, funcional, características de <i>Prolog</i></li>
<li>Base de datos integrada: sí, tiene una base de datos integrada en su
máquina virtual (lo que me recuerda a la que tiene también
<i>erlang</i>).</li>
<li>No es multihilo pero los procesos se pueden comunicar entre ellos
(¿será parecido a como lo hacía <i>erlang</i>?)</li>
<li>Aunque no cumple, estrictamente, con las características de los
lenguajes funcionales, como la inmutabilidad de las variables, sí
provee todo el <i>armamento</i> de acceso, mapeo y trabajo con listas que
tienen los familiares de <i>LISP</i>.</li>
<li>Interoperatividad con otros lenguajes como <code>c</code> o <code>java</code>.</li>
<li><i>GUI</i> incluido en la especificación del mismo lenguaje. En sus
primeras versiones el <i>GUI</i> estaba proporcionado por <code>java</code>, pero en
la actualidad se utiliza <code>html</code> montando un servidor local. Por lo
que se convierte en un candidato a tener en cuenta si lo que quieres
es hacer una aplicación web, proporcionando base de datos y servidor
dentro de la misma máquina virtual.</li>
<li><i>REPL</i>, interactividad. Ya sabéis lo que me gustan a mí los
lenguajes «repelentes».</li>
</ul>

<p>
Por tanto, amenazo, como tantas otras veces que me he puesto a
aprender alguna de estas tecnologías <i>rarunas</i>, en buscarme una
aplicación que desarrollar y <i>cansinaros</i> con el desarrollo, mientras
aprendo cómo funciona el <i>chismático</i>.
</p>

<p>
Si estás interesado en <i>Emacs</i> y su mundo, sigue atento a este <i>blog</i>
y a <i>Hispa-Emacs</i>.  Cuando haya algo más concreto con <i>planet-emacs</i>
avisaremos en ambos espacios. Y no olvides, que también puedes
participar: para ello, ponte en contacto con nosotros y entra en
nuestras reuniones virtuales. Cuantos más seamos, más nos
divertiremos. Si eres usuario de <i>Telegram</i> puedes entrar también en
el <a href="https://t.me/emacsorgmode">grupo de <i>Emacs-orgmode</i> en dicha red</a> para poder enterarte de las
cosas cuando se están produciendo.
</p>

<p>
Nos vemos este año que viene.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/blog/index.html">blog</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[blog]]></category>
  <link>https://notxor.nueva-actitud.org/2023/12/18/resumen-anual-y-futuro.html</link>
  <pubDate>Mon, 18 Dec 2023 10:22:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Una mirada a la toma de notas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-12-07</div>
<p>
Una tarea fundamental de mi trabajo es tomar notas. Puede parecer una
tarea sencilla: coges un papel, un bolígrafo o una estilográfica y
escribes lo que necesites recordar más adelante. Probando ese sistema
todo termina en un montón de garabatos esparcidos por papeles que
acaban perdiéndose o mezclándose de tal modo que puedes tener un dato
anotado, saber que lo anotaste y nunca volver a encontrarlo.
Frustración es lo que consigues a lo largo del tiempo.  Para evitar
esto pasé a cuadernos o agendas que no permitieran el ir perdiendo
hojas. Pero nada impide que añadas múltiples papeles sueltos y
<i>posits</i> con anotaciones entre las páginas del cuaderno (o de la
agenda) o que arranques alguna. Luego me pasé a las tarjetas de notas
y ocurrió más o menos lo mismo. Viendo la precariedad del sistema, lo
intenté también con medios electrónicos, pero el problema se mantuvo,
lo que conseguí cambiar es un montón de papeles por tener un montón de
archivos de texto con anotaciones mezclándose como sus equivalentes
analógicos dentro del cajón.
</p>

<p>
La parte fundamental que me faltaba era tomarme en serio la tarea de
tomar notas. Algo que es fundamental para el desarrollo de mi
profesión pero que nunca nadie me explicó, ni se le dio importancia
alguna mientras estudiaba la carrera. Lo que nunca nadie me explicó es
que tomar notas no consiste sólo en anotar ese dato que sabes que
luego te hará falta, sino tener un sistema por el que buscar dicho
dato después. Una nota olvidada en el rincón de un cajón tiene el
mismo efecto que si nunca la hubieras tomado, o peor aún, pues sabes
que lo anotaste y no puedes encontrarlo. Después, conocí el método
<i>Zettelkasten</i> y me conciencié que un buen sistema de notas requiere
dedicar un tiempo a ordenar y relacionar la información, para luego
poder encontrarla. Podía volver al cajón con tarjetas de notas o
continuar con un directorio lleno de archivos <code>org</code> con las más
variadas anotaciones dentro: anotaciones de datos personales de
clientes, de datos de sesiones, de consultas a libros, de temas para
el <i>blog</i>, de curiosidades que me llaman la atención o de cosas que
estoy estudiando. En fin, un sindiós al que había que disciplinar y
meter en vereda y <i>Zettelkasten</i> exponía un método congruente.
</p>

<p>
Así me pasé algo de tiempo jugueteando con <code>org-roam</code>, procesando las
notas que antes estaban en un directorio y que consultaba con <code>deft</code>.
El cambio funcionó un tiempo hasta que <code>org-roam</code> cambió de versión y
comenzó a tirar de una base de datos <code>squlite</code> externa. Perdió
bastante flexibilidad. Con <code>deft</code> tenía mis notas en diferentes
directorios, podía buscar en uno u otro, cambiar de directorio al
cambiar de actividad, separando las notas <i>profesionales</i> de las del
<i>blog</i>, por ejemplo, o tenerlas todas en un vistazo. Por eso, en lugar
de migrar mis notas de <code>org-roam</code> v.1 a v.2, pasé las notas a
<code>zetteldeft</code> y lo he estado utilizando durante algún tiempo.  Hace
poco me preguntaron por <code>org-roam</code> de nuevo y volví a probarlo, sólo
para poder hablar con propiedad. No podía criticar el sistema sin
probarlo de nuevo. Mis conclusiones las podéis leer en este mismo
blog, <a href="https://notxor.nueva-actitud.org/2023/10/23/probando-de-nuevo-org-roam.html">en el artículo anterior</a>. Pero para resumirlo diré, que cambiar
el directorio de notas al vuelo, en <code>org-roam</code> significa la renovación
de la base de datos. Algo que no sería muy pesado haciendo pruebas,
pero cuando aumenté el número de notas —tan sólo a una cuarta parte de
las que tengo— el tiempo de espera se incrementó bastante y decidí
continuar con <code>zetteldeft</code>. Lo único que me aportaba <code>org-roam</code> era la
vistosidad de <code>org-roam-ui</code>, que es cierto que es espectacular, pero
que finalmente no resulta tampoco una herramientas demasiado flexible,
porque depende de <code>org-roam</code>.
</p>

<p>
Buscando más información y conversando por la <i>Internet</i> sobre
<code>zetteldeft</code> me comentaron que el propio autor de <code>zetteldeft</code> había
descontinuado el mismo y se había pasado a <code>denote</code>. Pasé a probarlo
para decidir con cuál me quedo. Mi conclusión final es que,
efectivamente, me pareció un sistema mucho más sencillo de utilizar:
</p>

<ol class="org-ol">
<li>No reinventa la rueda: utiliza otros paquetes que están hechos para
hacer alguna de las tareas. Por ejemplo, para las búsquedas puedes
utilizar <code>deft</code>, <code>grep</code>, <code>consult</code>, cualquiera, lo que te sea más
cómodo o a lo que estés ya acostumbrado.</li>
<li>Soporte nativo para el cambio de directorios con
<code>denote-silos-extras.el</code>.  Puedo seguir jugando con el cambio de
directorios sin tener que esperar a que se rehaga una base de datos
externa.</li>
<li>La captura de notas es muy rápida y permite tener diferentes
plantillas para hacerlo. También a través de <code>org-capture</code>.</li>
<li>Permite la utilización de notas <code>.org</code>, <code>.md</code>, <code>.txt</code> y conviviendo
en el mismo <i>silo</i>.</li>
</ol>

<p>
Ahora bien, si me preguntas si estoy contento al 100%, mi respuesta
es: <i>me falta poco</i>. De hecho, llevo pensando un tiempo que debería
hacer mi propio sistema de notas para ajustarlo a todo aquello que
hecho en falta en los que he probado hasta ahora.
<a href="https://notxor.nueva-actitud.org/2021/11/23/tiddlywiki.html">Hace un tiempo ya hablé de TiddlyWiki</a> y lo sigo utilizando, pero no
como un sistema de notas, sino como un <i>wiki</i> que me permite tener
páginas <i>web</i> como la <a href="https://asociacionpica.org/radio/">de la radio</a> sin mucho esfuerzo. También utilicé
<a href="https://zim-wiki.org/">Zim</a> en su día.
</p>
<div id="outline-container-org2178319" class="outline-2">
<h2 id="org2178319">Pruebas y más pruebas</h2>
<div class="outline-text-2" id="text-org2178319">
<p>
Ahora mismo tengo instalados tres sistemas de notas en <i>Emacs</i>, que
están conviviendo de aquella manera y que mantendré hasta una charla
que tengo prometida para un vídeo de los de <a href="https://hispa-emacs.org/">hispa-emacs</a> sobre la toma
de notas. La convivencia de los tres paquetes se hace un poco pesada a
estas alturas y estoy deseando eliminar el lastre en la configuración.
</p>

<p>
Mantendré <code>deft</code>, porque la visualización en tabla y la búsqueda
rápida de contenido me parecen bastante buenas. He probado el paquete
<code>denote-menu</code>, pero la funcionalidad del mismo es bastante pobre.
</p>

<p>
El ingenioso arte de mantener los tres sistemas va de la siguiente
manera:
</p>
</div>
<div id="outline-container-orgb56bbc6" class="outline-3">
<h3 id="orgb56bbc6"><code>deft</code> y <code>zetteldeft</code></h3>
<div class="outline-text-3" id="text-orgb56bbc6">
<p>
El código a continuación permite mantener las notas en directorios
separados y cambiar entre ellos.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Tomar notas
</span>(<span style="color: #ff79c6; font-weight: bold;">use-package</span> deft
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:bind</span> (<span style="color: #f1fa8c;">"&lt;f5&gt;"</span> . deft)
  <span style="color: #8be9fd; font-style: italic;">:commands</span> (deft deft-refresh)
  <span style="color: #8be9fd; font-style: italic;">:config</span> (<span style="color: #ff79c6; font-weight: bold;">setq</span> deft-directory <span style="color: #f1fa8c;">"~/Nextcloud/Notes"</span>
                deft-extensions '(<span style="color: #f1fa8c;">"org"</span> <span style="color: #f1fa8c;">"md"</span> <span style="color: #f1fa8c;">"txt"</span>)
                deft-use-filename-as-title t))

(<span style="color: #ff79c6; font-weight: bold;">use-package</span> zetteldeft
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:after</span> deft
  <span style="color: #8be9fd; font-style: italic;">:config</span> (zetteldeft-set-classic-keybindings))

(<span style="color: #ff79c6; font-weight: bold;">setq</span> zetteldeft-title-suffix <span style="color: #f1fa8c;">"\n#+tags: #"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> deft-default-extension <span style="color: #f1fa8c;">"org"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> zetteldeft-backlink-prefix <span style="color: #f1fa8c;">"- Backlink: "</span>)

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Cambio de directorio Deft
</span>(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">deft-cambio-dir</span> (dir)
  <span style="color: #6272a4;">"Cambiar de directorio Deft al `</span><span style="color: #bd93f9;">DIR</span><span style="color: #6272a4;">' de forma interactiva."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span> <span style="color: #f1fa8c;">"DNuevo directorio Deft: "</span>)

  (message (format <span style="color: #f1fa8c;">"Se cambia def-directory a: %s"</span> dir))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> deft-directory (expand-file-name dir))
  (deft-refresh))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">deft-recursivo</span> ()
  <span style="color: #6272a4;">"Establece que `</span><span style="color: #bd93f9;">deft</span><span style="color: #6272a4;">' busque tambi&#233;n en subdirectorios."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> deft-recursive t)
  (deft-refresh))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">deft-no-recursivo</span> ()
  <span style="color: #6272a4;">"Hace que `</span><span style="color: #bd93f9;">deft</span><span style="color: #6272a4;">' no busque en subdirectorios."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> deft-recursive nil)
  (deft-refresh))

(global-set-key (kbd <span style="color: #f1fa8c;">"C-&lt;f5&gt;"</span>) #'deft-cambio-dir)
(global-set-key (kbd <span style="color: #f1fa8c;">"M-&lt;f5&gt;"</span>) #'deft-recursivo)
(global-set-key (kbd <span style="color: #f1fa8c;">"S-&lt;f5&gt;"</span>) #'deft-no-recursivo)
</pre>
</div>

<p>
Como veis he asignado a la tecla <code>&lt;f5&gt;</code> el acceso a <code>deft</code> y también
he programado un cambio de directorio, asignado a <code>C-&lt;f5&gt;</code> y la
posibilidad de hacer que busque en subdirectorios con <code>M-&lt;f5&gt;</code> o que
deje de hacerlo con <code>S-&lt;f5&gt;</code>. Por defecto, las notas las tengo
sincronizadas a una nube <i>Nextcloud</i> particular y de esa manera son
accesibles desde distintos dispositivos, como <i>tablet</i> y móvil.
</p>

<p>
Con <code>org-roam</code> sólo hice unas pocas pruebas, como ya he comentado.
Trasladé algunas de las notas a este sistema, hice las pruebas y sigue
instalado temporalmente.
</p>
</div>
</div>
<div id="outline-container-orgebd97a7" class="outline-3">
<h3 id="orgebd97a7"><code>denote</code></h3>
<div class="outline-text-3" id="text-orgebd97a7">
<p>
Configurar este paquete hubiera sido más sencillo si no hubiera tenido
que modificar todo el <code>key-map</code> del paquete, para que no se pegara con el
<code>org-roam</code> ya instalado cambié todas las teclas a la combinación base
<code>C-c z</code>... aunque para acceder a las notas, me gustaría más <code>C-c n</code>
(ahora asignado a <code>org-roam</code>).
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">instalaci&#243;n de denote
</span>
(<span style="color: #ff79c6; font-weight: bold;">use-package</span> denote
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t
  <span style="color: #8be9fd; font-style: italic;">:config</span>
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> denote-directory (expand-file-name <span style="color: #f1fa8c;">"~/denotas/"</span>)
        denote-known-keywords '(<span style="color: #f1fa8c;">"emacs"</span> <span style="color: #f1fa8c;">"cie-11"</span> <span style="color: #f1fa8c;">"blog"</span>)
        denote-infer-keywords t
        denote-sort-keywords t
        denote-prompts '(title keywords)
        denote-date-prompt-use-org-read-date t
        denote-backlinks-show-context t))

(add-hook 'find-file-hook #'denote-link-buttonize-buffer)

<span style="color: #6272a4;">;;</span><span style="color: #6272a4;">(require 'denote-journal-extras.el)
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> denote-journal-extras-directory <span style="color: #f1fa8c;">"~/denotas/diario"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> denote-journal-extras-title-format 'day-date-month-year)

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Keybindings para denote
</span>(<span style="color: #ff79c6; font-weight: bold;">let</span> ((map global-map))
  (define-key map (kbd <span style="color: #f1fa8c;">"C-c z j"</span>) #'denote-journal-extras-new-or-existing-entry) <span style="color: #6272a4;">; </span><span style="color: #6272a4;">entrada a diario
</span>  (define-key map (kbd <span style="color: #f1fa8c;">"C-c z n"</span>) #'denote)
  (define-key map (kbd <span style="color: #f1fa8c;">"C-c z N"</span>) #'denote-type)
  (define-key map (kbd <span style="color: #f1fa8c;">"C-c z o"</span>) #'denote-open-or-create)
  (define-key map (kbd <span style="color: #f1fa8c;">"C-c z d"</span>) #'denote-date)
  (define-key map (kbd <span style="color: #f1fa8c;">"C-c z z"</span>) #'denote-signature) <span style="color: #6272a4;">; </span><span style="color: #6272a4;">"zettelkasten" mnemonic
</span>  (define-key map (kbd <span style="color: #f1fa8c;">"C-c z s"</span>) #'denote-subdirectory)
  (define-key map (kbd <span style="color: #f1fa8c;">"C-c z t"</span>) #'denote-template)
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">If you intend to use Denote with a variety of file types, it is
</span>  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">easier to bind the link-related commands to the `</span><span style="color: #bd93f9;">global-map</span><span style="color: #6272a4;">', as
</span>  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">shown here.  Otherwise follow the same pattern for `</span><span style="color: #bd93f9;">org-mode-map</span><span style="color: #6272a4;">',
</span>  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">`</span><span style="color: #bd93f9;">markdown-mode-map</span><span style="color: #6272a4;">', and/or `</span><span style="color: #bd93f9;">text-mode-map</span><span style="color: #6272a4;">'.
</span>  (define-key map (kbd <span style="color: #f1fa8c;">"C-c z i"</span>) #'denote-link) <span style="color: #6272a4;">; </span><span style="color: #6272a4;">"insert" mnemonic
</span>  (define-key map (kbd <span style="color: #f1fa8c;">"C-c z l"</span>) #'denote-link-or-create)
  (define-key map (kbd <span style="color: #f1fa8c;">"C-c z I"</span>) #'denote-add-links)
  (define-key map (kbd <span style="color: #f1fa8c;">"C-c z b"</span>) #'denote-backlinks)
  (define-key map (kbd <span style="color: #f1fa8c;">"C-c z f f"</span>) #'denote-find-link)
  (define-key map (kbd <span style="color: #f1fa8c;">"C-c z f b"</span>) #'denote-find-backlink)
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Note that `</span><span style="color: #bd93f9;">denote-rename-file</span><span style="color: #6272a4;">' can work from any context, not just
</span>  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Dired bufffers.  That is why we bind it here to the `</span><span style="color: #bd93f9;">global-map</span><span style="color: #6272a4;">'.
</span>  (define-key map (kbd <span style="color: #f1fa8c;">"C-c z r"</span>) #'denote-rename-file)
  (define-key map (kbd <span style="color: #f1fa8c;">"C-c z R"</span>) #'denote-rename-file-using-front-matter))

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Key bindings specifically for Dired.
</span>(<span style="color: #ff79c6; font-weight: bold;">let</span> ((map dired-mode-map))
  (define-key map (kbd <span style="color: #f1fa8c;">"C-c C-d C-i"</span>) #'denote-link-dired-marked-notes)
  (define-key map (kbd <span style="color: #f1fa8c;">"C-c C-d C-r"</span>) #'denote-dired-rename-marked-files)
  (define-key map (kbd <span style="color: #f1fa8c;">"C-c C-d C-R"</span>) #'denote-dired-rename-marked-files-using-front-matter))
</pre>
</div>

<p>
He añadido también el paquete <code>denote-menu</code>, que muestra las notas en
forma de tabla, sin embargo, no proporciona filtros y la ordenación se
restringe a la fecha, tanto ascendente como descendente.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> denote-menu
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t)

(global-set-key (kbd <span style="color: #f1fa8c;">"C-c z m"</span>) #'denote-menu-list-notes)
</pre>
</div>

<p>
En este sentido, me resulta más práctico acceder a <code>deft</code> y cambiar el
directorio al correspondiente a <code>denote</code>.
</p>
</div>
</div>
</div>
<div id="outline-container-orgd032244" class="outline-2">
<h2 id="orgd032244">¿Qué necesito en mi toma de notas?</h2>
<div class="outline-text-2" id="text-orgd032244">
<p>
Debo reconocer que <code>org-mode</code> me ha malacostumbrado, con él puedes
hacer de todo y algunas herramientas se me hacen, a estas alturas
imprescindibles. Tanto, que el <i>proyecto</i> de crear mi propio sistema
de notas se percibe tan complejo como el propio <code>org-mode</code> y por
tanto, tan desafiante y lleno de aprendizajes que me estoy planteando
seriamente hacerlo.
</p>

<p>
De momento se podría decir que con estos sistemas tengo la mayoría de
mis necesidades cubiertas. Sin embargo, para algunas cosas he de tirar
de herramientas externas al propio <i>Emacs</i> y <code>org-mode</code>... como decía
<i>Extremoduro</i>: salir, entrar, el royo de siempre.
</p>

<p>
Lo que necesito, son unas pocas cosas:
</p>

<ol class="org-ol">
<li><b>Gestión de calendario</b>. Algo que para concertar citas es
fundamental, y una vez me he acostumbrado a la <i>agenda</i> de
<code>org-mode</code> y a cambiar de vista con una tecla, me resultan
innecesariamente complejos otros sistemas.</li>
<li><b>Gestión de tareas periódicas</b>. Como autónomo, la presentación de
IVA e impuestos trimestrales u otras tareas periódicas, como el
programa de radio, el repaso semanal a la contabilidad, etc.
Aparecen en mi agenda de forma automática y además las puedo marcar
cuándo las hago y llevar un registro de cuándo hice qué cosa.</li>
<li><b>Control de tiempos</b>. Algunas de las tareas que realizo las cobro
por horas, por lo tanto, el cronometrar cuánto tiempo invierto en
ello me facilita luego la facturación. Esto es algo que
<a href="https://notxor.nueva-actitud.org/2020/06/27/control-de-tiempos-con-org-mode.html">ya apareció en este <i>blog</i> y no hace falta repetirlo</a>. Lo hace
<code>org-mode</code> de una manera sencilla.</li>
<li><b>Notas cifradas</b>. En mi trabajo la confidencialidad es una de las
necesidades básicas del día a día. Poder tener notas cifradas sobre
mis clientes y sus problemas, es básico para mí. Basta con terminar
el nombre del archivo de la nota con <code>.gpg</code> para que se cifre
<i>automágicamente</i>.</li>
<li><b>No sólo texto</b>. Las anotaciones, efectivamente, suelen ser de
texto, sin embargo, algunas veces necesito adjuntar algún gráfico,
como los perfiles de <i>tests</i> y otros adjuntos, como archivos <code>pdf</code>,
por poner un ejemplo. <i>Emacs</i> además proporciona las suficientes
herramientas para visualizar casi todos los tipos de adjuntos.</li>
<li><b>Separación de notas</b>. Cuando te dedicas a una sola cosa, parece
buena idea tener todas las notas en el mismo sitio. Sin embargo, me
dedico a varias actividades independientes y por tanto necesito que
no se me mezclen las anotaciones. Especialmente las que se refieren
a facturación, pues unas llevan IVA y otras —las clínicas y las
educativas— están exentas de ese impuesto. Además, las notas sobre
las sesiones con clientes están en un disco duro externo cifrado y
no se deben mezclar con otro tipo de notas.</li>
<li><b>Accesible desde distintos dispositivos</b>. El problema viene,
normalmente, de acceder con otros sistemas operativos, como por
ejemplo, <i>Android/®. Cuando salgo por ahí, no suelo llevar el
ordenador más que contadas veces, como cuando voy a hacer el
programa de radio, y es más cómodo trasladarme con una /Tablet</i>
barata que no me supondrá demasiada pérdida si se estropea o le
pasa algo.</li>
</ol>

<p>
De todos estos puntos —seguro que ahora mismo no caigo en algún
requisito más—, el más complejo es el 7. El resto (y mucho más) lo
hace <code>org-mode</code> por nosotros sin despeinarse. El asunto de tener
varios dispositivos con las notas sincronizadas es lo complicado y he
utilizado varias aplicaciones y métodos para hacerlo, como
aplicaciones de sincronización, <i>nube</i>.  En la actualidad estoy
optando por tener un repositorio, al fin y al cabo, las notas en su
mayoría son texto plano. Además, sigo teniendo mi nube prsonal, en mi
sitio web, mediante <i>NextCloud</i> y me permite compartir datos, como el
repositorio, porque es un fichero <code>fossil</code>.
</p>

<p>
Si te preguntas por qué utilizo <code>fossil</code> y no <code>git</code> la respuesta tiene
varias vertientes. La primera es que un repositorio <code>fossil</code> es
monolítico —un fichero <code>sqlite</code> con todo dentro— y eso nos da alguna
ventaja al compartirlo por <i>NextCloud</i>. O dicho de otro modo: uno de
los problemas que me encontré cuando lo intenté con <code>git</code> es que los
cambios de un repositorio <code>git</code> se almacenan en archivos sueltos
dentro de un directorio oculto del sistema. Además <i>NextCloud</i> se
lleva mal con los archivos y directorios ocultos y no siempre
sincroniza correctamente, sin contar con las ocasiones en las que hay
colisión entre las versiones de los distintos dispositivos.  Alguna
vez me encontré el repositorio totalmente inservible por efecto de una
mala sincronización, pues cuando hay conflicto en <i>NextCloud</i> suele
añadir archivos duplicados para no borrar nada. Si no estaba atento a
los errores de sincronización y abría <code>git</code>, la aplicación se
encontraba con que el repositorio tenía elementos extraños que no
sabía cómo manejar.
</p>

<p>
Por otro lado, aunque con <code>fossil</code> también hay conflictos, pero, el
resultado es mucho más manejable. Si ha habido algún choque de
versiones se mantiene el archivo anterior y añade el elemento extraño.
El efecto resultante es que el repositorio no se ha actualizado, no
hay error ni se corrompe el <i>log</i>. Simplemente, vas a <i>NextCloud</i>
solucionas el error y actualizas de nuevo con <code>fossil update</code>.
</p>
</div>
</div>
<div id="outline-container-org8e7340a" class="outline-2">
<h2 id="org8e7340a">Planes futuros</h2>
<div class="outline-text-2" id="text-org8e7340a">
<p>
Lo dije antes: llevo tiempo queriendo hacer una aplicación sencilla
que cumpla con todas mis necesidades en el ámbito de la toma de
notas. ¿Para qué?  Pues para aprender. A eso se le juntan las ganas de
aprender <i>PicoLisp</i>, un lenguaje minimalista de la familia de los
<i>LISP</i>.  Aunque no hay necesidad a estas alturas, porque tengo montado
un sistema de mínimo esfuerzo juntando distintas piezas de terceros:
<i>Emacs</i>, <code>org-mode</code>, <code>denote</code>, <code>deft</code>, <i>NextCloud</i>, <i>Termux</i> (para
Android®) y <code>fossil</code>.
</p>

<p>
¿Por qué <i>PicoLisp</i>? A parte de que es un lenguaje similar a <i>LISP</i> o
<i>Scheme</i>, tiene unas características minimalistas de las que siempre
me resultan interesantes: integra, en una máquina virtual muy
reducida, una base de datos y soporte para <i>GUI</i>.  Además, para
Android® existe una aplicación llamada <i>PilBox</i> que ejecuta <i>scripts</i>
de <i>PicoLisp</i> directamente en ese sistema operativo. Por otro lado,
también puedes usarlo desde <i>Termux</i>, porque es uno de los paquetes
que puedes instalar en esa maravillosa <i>«minidistro»</i> integrada en
Android®.
</p>

<p>
El objetivo, como he dicho antes, no es crear el más maravilloso
sistema de notas, sino aprender. Necesitaré bajar a definir qué es una
anotación, de qué partes se compone, cuáles son sus características y
comprender así un poco mejor algunos algoritmos básicos y manejar
<i>listas</i>, <i>árboles</i>, <i>propiedades</i> y, por supuesto, sus <i>enlaces</i> y
<i>valores</i>.
</p>

<p>
Tardaría menos haciendo un pequeño paquete de <i>Emacs</i>, que subiéndose
a hombros de gigantes, consiguiera realizar aquello (poco) que echo a
faltar en el sistema que tengo montado ahora, pero con <code>elisp</code> ya me
manejo y no aprendería demasiado.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> <a href="/tags/org-roam/index.html">org-roam</a> <a href="/tags/denote/index.html">denote</a> <a href="/tags/zettelkasten/index.html">Zettelkasten</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <category><![CDATA[org-roam]]></category>
  <category><![CDATA[denote]]></category>
  <category><![CDATA[Zettelkasten]]></category>
  <link>https://notxor.nueva-actitud.org/2023/12/07/una-mirada-a-la-toma-de-notas.html</link>
  <pubDate>Thu, 07 Dec 2023 10:33:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Probando de nuevo org-roam]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-10-23</div>
<p>
El otro día hablando con Jordi (de <a href="https://hispa-emacs.org/">hispa-emacs</a>) me emplazaba para un
nuevo encuentro virtual y proponía como tema que explicara cómo
utilizo <code>org-roam</code>. <a href="https://notxor.nueva-actitud.org/2020/07/17/tomar-notas-con-org-roam.html">Había leído en el <i>blog</i> un artículo</a> que hablaba
sobre ello. El problema es que dicho artículo versa sobre <code>org-roam</code>,
en su primera versión, y en la actualidad, la <i>v2</i> es ligeramente
distinta y no la he probado. Hace años que no utilizo <code>org-roam</code>, pero
dado que parece ser el <i>chismático</i> de notas que utiliza la mayor
parte de los usuarios de <i>Emacs</i> me decidí a volver a probarlo y ver
si ha mejorado con respecto a lo que recordaba.
</p>

<p>
El asunto pasa por volver a instalarlo, crear nuevas notas, probar
cómo funciona y (poder) contarlo. Vamos a ello.
</p>
<div id="outline-container-orgc2e6c3a" class="outline-2">
<h2 id="orgc2e6c3a">Instalación</h2>
<div class="outline-text-2" id="text-orgc2e6c3a">
<p>
Lo primero es lo primero y hay que empezar por la instalación y, por
tanto, hay que tener en cuenta algunas dependencias. La mayoría
seguramente ya las tienes instaladas, si haces un uso habitual de
<i>Emacs</i>, como es mi caso. Pero por si acaso, la dependencia más
importante es a <code>sqlite</code>. Algo que no termina de gustarme, pero que
parece que al resto de la gente le da igual.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> emacsql
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t)
(<span style="color: #ff79c6; font-weight: bold;">use-package</span> emacsql-sqlite
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:after</span> 'emacsql)
</pre>
</div>

<p>
Después, hay que instalar el paquete <code>org-roam</code> y configurarlo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> org-roam
<span style="color: #8be9fd; font-style: italic;">:ensure</span> t
<span style="color: #8be9fd; font-style: italic;">:custom</span>
(org-roam-directory (file-truename <span style="color: #f1fa8c;">"~/Notas"</span>))
<span style="color: #8be9fd; font-style: italic;">:bind</span> ((<span style="color: #f1fa8c;">"C-c n l"</span> . org-roam-buffer-toggle)
       (<span style="color: #f1fa8c;">"C-c n f"</span> . org-roam-node-find)
       (<span style="color: #f1fa8c;">"C-c n g"</span> . org-roam-graph)
       (<span style="color: #f1fa8c;">"C-c n i"</span> . org-roam-node-insert)
       (<span style="color: #f1fa8c;">"C-c n c"</span> . org-roam-capture)
       <span style="color: #8be9fd; font-style: italic;">:map</span> org-mode-map
       (<span style="color: #f1fa8c;">"C-M-i"</span> . completion-at-point)
       <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Dailies
</span>       (<span style="color: #f1fa8c;">"C-c n j"</span> . org-roam-dailies-capture-today))
<span style="color: #8be9fd; font-style: italic;">:config</span>
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">If you're using a vertical completion framework, you might want a more informative completion interface
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-roam-node-display-template (concat <span style="color: #f1fa8c;">"${title:*} "</span> (propertize <span style="color: #f1fa8c;">"${tags:10}"</span> 'face 'org-tag)))
(org-roam-db-autosync-mode)
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">If using org-roam-protocol
</span>(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">org-roam-protocol</span>))
</pre>
</div>

<p>
Posiblemente, y si tu objetivo es utilizar con asiduidad este paquete,
necesitarás cambiar la variable <code>org-roam-node-display-template</code> para
adecuarla más a tus necesidades. Yo de momento me limito a hacer
pruebas y después decidiré si se queda o si vuelvo a como me estaba
apañando hasta ahora.
</p>

<p>
Uno de los fuertes de <code>org-roam</code> no es en sí el mismo <i>chismático</i>,
sino el adicional <i>UI</i>: una <i>interface</i> web que permite visualizar las
notas en una nube de nodos y relaciones que hay entre ellas.
</p>

<p>
Tanto en su versión plana:
</p>


<figure id="orgfa76cdc">
<img src="./imagenes/Captura_org-roam-ui-2d.png" alt="Captura_org-roam-ui-2d.png">

</figure>

<p>
Como en su versión tridimensional:
</p>


<figure id="org58fdf9f">
<img src="./imagenes/Captura_org-roam-ui-3d.png" alt="Captura_org-roam-ui-3d.png">

</figure>

<p>
Puesto que es un paquete que hará una representación gráfica de las
relaciones de nuestras notas basándose en <i>web</i>, necesitará, como
dependencia del mismo a <code>websocket</code>. Además teniendo cuidado de
cargarlo después de <code>org-roam</code>, pero antes de <code>org-roam-ui</code>.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> websocket
  <span style="color: #8be9fd; font-style: italic;">:after</span> org-roam)

(<span style="color: #ff79c6; font-weight: bold;">use-package</span> org-roam-ui
  <span style="color: #8be9fd; font-style: italic;">:after</span> org-roam
  <span style="color: #8be9fd; font-style: italic;">:config</span>
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> org-roam-ui-sync-theme t
        org-roam-ui-follow t
        org-roam-ui-update-on-save t
        org-roam-ui-open-on-start t))
</pre>
</div>

<p>
La configuración es sencilla estableciendo algunas variables para
sincronizar los cambios entre el editor y el <i>UI</i> y... iba a decir
«viceversa», pero en este caso es un <i>UI</i> en el que no se pueden
modificar las notas. Pero sí es cierto que se situará en aquella nota
que tengamos abierta en primer plano de <i>Emacs</i> o podremos abrir en el
editor aquella que abramos en la <i>interface</i>.
</p>
</div>
<div id="outline-container-org476e474" class="outline-3">
<h3 id="org476e474">¿Qué diferencias hay con la versión anterior?</h3>
<div class="outline-text-3" id="text-org476e474">
<p>
Las notas siguen siendo <code>org-mode</code>, los cambios se producen en las
cabeceras, de manera que:
</p>

<ul class="org-ul">
<li><code>#+roam_tags:</code> pasa a ser <code>#+filetags:</code></li>
<li><code>#+roam_key:</code> pasa a ser una propiedad <code>:ID:</code></li>
</ul>

<p>
Si no has utilizado con anterioridad <code>org-roam</code>, te darán igual estos
cambios. Si estás utilizando la <i>v1</i>, algo que ya debería estar
superado tras varios años de estar en uso y actualizada la <i>v2</i>,
también puedes migrar notas con <code>org-roam-migrate-wizard</code>, que hará
todo el proceso por ti. Yo lo he hecho para convertir algunas notas
viejas.
</p>
</div>
</div>
</div>
<div id="outline-container-org5f02421" class="outline-2">
<h2 id="org5f02421">Zettelkasten, pruebas y primeras impresiones</h2>
<div class="outline-text-2" id="text-org5f02421">
<p>
Evidentemente no son mis primeras impresiones sobre <code>org-roam</code>, que ya
probé su primera versión. Sin embargo, no terminó de gustarme la <i>v2</i>,
quizá por estar acostumbrado a la versión anterior, cambiaron las
combinaciones de teclas y me obligaron a hacer una migración, que en
su día me fallaba, obligándome a elegir si empezar de cero o cambiar a
otro procedimiento de tomar notas.
</p>

<p>
Toda esta historia viene de implementar el método <a href="https://es.wikipedia.org/wiki/Zettelkasten">Zettelkasten</a>, que es
una forma de tomar notas y relacionarlas entre sí. Por ahí podrás
encontrar una descripción más clara y más detallada de en qué consiste
el método e incluso aplicaciones que lo soportan y te permiten
utilizarlo. Pero, en resumen, para mí la potencia de este método
consiste en los enlaces entre los nodos de información, donde no hay
jerarquías y donde termina emergiendo una estructura propia.
</p>

<p>
Consejos:
</p>

<ol class="org-ol">
<li>Las notas deben ser todo lo modulares que se pueda. Si se puede
resumir todo a una sola idea mejor.</li>
<li>Todas las notas deben estar relacionadas con otras. Las notas
sueltas no aportan nada al sistema y son difíciles de encontrar.</li>
<li>Escribe los conceptos con tus propias palabras, son tus notas
personales, no un manual de perfección.</li>
<li>Cuantas más notas tomas más aprendes y mejor funciona el sistema,
así que si eres constante terminarás teniendo un segundo cerebro en
tus notas.</li>
</ol>

<p>
El creador del método Zettelkasten distinguía entre distintos tipos de
notas. Veamos:
</p>

<ul class="org-ul">
<li><b>Notas rápidas</b>: Son notas que se toman rápidamente en el momento.
Se hacen sin precisión y sin encajarlas en ningún sitio. Con
posterioridad se estudiarán para enlazarlas con otras o para generar
notas permanentes.</li>
<li><b>Notas permanentes</b>: Son las anotaciones normales que están
relacionadas con otras notas. Estas son las notas más importantes.</li>
<li><b>Notas bibliográficas</b>: Son notas destinadas a recoger la
bibliografía y las fuentes externas.</li>
<li><b>Notas literatura</b>: Son notas donde se cita literalmente alguna
fuente. El creador del sistema solía utilizar el reverso de una nota
bibliográfica para introducir las citas.</li>
<li><b>Notas índice</b>: Son notas que, con respecto a una palabra clave o
concepto, contienen una lista de referencias a otros nodos
relacionados.</li>
</ul>

<p>
Si quieres seguir el método, tendrás que crear este tipo de nodos en
<code>org-roam</code>, porque el sistema no contempla mucha diferencia entre unas
y otras. Quizá las notas rápidas estén cubiertas con las notas a
través de <code>dailies</code>, que es una forma de capturar notas por
días. Estas notas se guardan en otro directorio, dentro del de notas
generales. Cada día escribe en un archivo cuyo nombre es la fecha
correspondiente, aunque también se puede escribir en los
correspondientes a otros días.
</p>

<p>
Para realizar las pruebas del <i>pichorro</i> lo que he hecho ha sido
rescatar de una vieja copia de seguridad algunas notas que tenía de la
versión 1 y convertirlas a la versión 2. He de decir que, por contra a
cuando intenté hacerlo en su día, en esta ocasión no me he encontrado
con ningún tipo de problema.
</p>

<p>
Como eran pocas, las notas rescatadas, decidí también incorporar a la
base de datos de notas, los artículos de este <i>blog</i>. Que ya sé que
incumplen la mayoría de los principios del sistema, es decir: no son
ideas modulares y la poca relación que tienen entre sí es a través de
las etiquetas e, incluso de ese modo, hay algunas de ellas que están
relacionadas por los pelos. Pero en fin, por ser algo más didáctico,
mostraré cómo he hecho la conversión de <i>artículo del blog</i> a <i>nota</i>
de <code>org-roam</code>. El resultado es que pululan bastantes notas sueltas por
ahí, pero para hacer pruebas me sirve.
</p>
</div>
</div>
<div id="outline-container-orgfc2e575" class="outline-2">
<h2 id="orgfc2e575">Conversión a <code>org-roam</code></h2>
<div class="outline-text-2" id="text-orgfc2e575">
<p>
La historia era pasar los artículos, tal como están almacenados en su
repositorio, pero cumpliendo con la estructura esperada de una nota de
<code>org-roam</code>.
</p>

<p>
Para no romper nada, lo primero que hice fue copiar todos los
artículos, en formato <code>org-mode</code>, a otro directorio, por aquello de no
estropear nada. Aunque están en un repositorio <code>git</code>, tampoco es
cuestión de andar rompiendo cosas. Además, el objetivo era generar
notas en archivos nuevos que no machaquen los antiguos, por si acaso.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">dir-origen</span> <span style="color: #f1fa8c;">"~/proyectos/pasar-blog-roam/origen"</span>)
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">dir-destino</span> <span style="color: #f1fa8c;">"~/proyectos/pasar-blog-roam/resultado"</span>)
</pre>
</div>

<p>
Por eso, creé dos directorios nuevos y guardé el nombre en sendas
variables: <code>dir-origen</code>, que guarda los artículos en su versión
original y <code>dir-destino</code>, que será donde se guarden las notas antes de
pasarlas al directorio de notas (también por si acaso).
</p>

<p>
Las dos características fundamentales de una nota que hacen que
<code>org-roam</code> las reconozca como propias, son:
</p>

<ul class="org-ul">
<li>El <code>ID</code> como propiedad del archivo: El <i>id</i> se puede crear con el
comando <code>uuidgen</code>.</li>
<li>El nombre del archivo. Normalmente comienza con una cadena de año,
mes, día, hora, minuto y segundo en el que se creó, seguido por el
título, separando las palabras con símbolos <code>_</code> en lugar de los
espacios.</li>
</ul>

<p>
La cabecera con el <i>ID</i> lo genera la siguiente función:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">generar-cabecera-id</span> ()
  <span style="color: #6272a4;">"Genera un ID y devuelve una cabecera para `</span><span style="color: #bd93f9;">org-roam</span><span style="color: #6272a4;">'."</span>
  (concat <span style="color: #f1fa8c;">":PROPERTIES:\n"</span>
          <span style="color: #f1fa8c;">":ID:       "</span> (shell-command-to-string <span style="color: #f1fa8c;">"uuidgen"</span>)
          <span style="color: #f1fa8c;">":END:\n"</span>))
</pre>
</div>

<p>
El nombre del archivo se obtiene mediante la función:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">dame-nombre</span> (nombre-archivo fecha-post)
  <span style="color: #6272a4;">"Dado el NOMBRE-ARCHIVO y la FECHA-POST genera uno compatible con org-roam."</span>
  (concat (format-time-string <span style="color: #f1fa8c;">"%Y%m%d%H%M%S-"</span> fecha-post)
          (string-join (split-string nombre-archivo <span style="color: #f1fa8c;">"-"</span>) <span style="color: #f1fa8c;">"_"</span>)))
</pre>
</div>

<p>
Esa función toma el nombre del archivo que contiene un artículo, que
tiene los espacios convertidos en <code>-</code>, y una fecha, para generar el
nombre de la nota. Para procesar la creación de una nueva nota sólo
necesitamos el nombre del archivo que contiene el artículo, se busca
la fecha de publicación en la cabecera del mismo y se pide el nombre
de la nota.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">procesar-archivo</span> (nombre-archivo)
  <span style="color: #6272a4;">"Dado un NOMBRE-ARCHIVO genera uno nuevo v&#225;lido para org-roam."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (<span style="color: #ff79c6; font-weight: bold;">let</span> ((case-fold-search t)
        (nombre-destino <span style="color: #f1fa8c;">""</span>)
        (fecha-post (time-since 0)))
    (<span style="color: #ff79c6; font-weight: bold;">with-temp-buffer</span>                         <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Abro un buffer temporal
</span>      (insert (generar-cabecera-id))          <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Inserto cabecera `</span><span style="color: #bd93f9;">org-roam</span><span style="color: #6272a4;">'
</span>      (insert-file-contents nombre-archivo)   <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Inserto el contenido del art&#237;culo
</span>      (<span style="color: #ff79c6; font-weight: bold;">progn</span>
        (goto-char 0)
        (search-forward <span style="color: #f1fa8c;">"&lt;:t"</span>)                <span style="color: #6272a4;">; </span><span style="color: #6272a4;">caracteres finales de la cabecera de un art&#237;culo
</span>        (insert (enlace-root-blog)))          <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Inserto un enlace al nodo `</span><span style="color: #bd93f9;">blog</span><span style="color: #6272a4;">'
</span>      (<span style="color: #ff79c6; font-weight: bold;">setq</span> fecha-post                        <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Obtengo la fecha del art&#237;culo
</span>            (<span style="color: #ff79c6; font-weight: bold;">progn</span>
              (goto-char 0)                   <span style="color: #6272a4;">; </span><span style="color: #6272a4;">desde el inicio busco la fecha
</span>              (<span style="color: #ff79c6; font-weight: bold;">if</span> (search-forward-regexp <span style="color: #f1fa8c;">"^\\#\\+date:[ ]*&lt;</span><span style="color: #8be9fd;">\\</span><span style="color: #bd93f9;">(</span><span style="color: #f1fa8c;">[</span><span style="color: #8be9fd;">^</span><span style="color: #f1fa8c;">]&gt;]+</span><span style="color: #8be9fd;">\\</span><span style="color: #bd93f9;">)</span><span style="color: #f1fa8c;">&gt;$"</span> nil t)
                  (date-to-time (match-string 1))
                (time-since 0))))
      (<span style="color: #ff79c6; font-weight: bold;">setq</span> nombre-destino (concat dir-destino <span style="color: #f1fa8c;">"/"</span>
                                   (dame-nombre nombre-archivo fecha-post)))
      (write-file nombre-destino))))
</pre>
</div>

<p>
Se crea un <i>buffer</i> temporal donde se insertan, por orden:
</p>

<ul class="org-ul">
<li>La cabecera con el <i>ID</i> del nuevo artículo</li>
<li>Un aviso de que es un artículo del <i>blog</i> y no una nota real.</li>
<li>El contenido, tal cual, del artículo.</li>
</ul>

<p>
Todo eso se guarda en un nuevo archivo que se puede utilizar como
nota. El asunto, también, es que lo hiciera <i>automágicamente</i> para los
<i>sienes y sienes</i> de artículos. Para ello primero tenemos que obtener
la lista de artículos:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">lista-archivos</span> ()
  <span style="color: #6272a4;">"Devuelve la lista de archivos a convertir."</span>
  (directory-files-recursively dir-origen <span style="color: #f1fa8c;">".*\\.org$"</span>))
</pre>
</div>

<p>
Este código devuelve una lista con el nombre de los archivos. Ahora la
podemos llamar desde un bucle y que procese todos los nombres que
haya en ella:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">pasa-los-archivos</span>()
  <span style="color: #6272a4;">"Procesa todos los archivos `</span><span style="color: #bd93f9;">.org</span><span style="color: #6272a4;">' que est&#233;n en el `</span><span style="color: #bd93f9;">dir-origen</span><span style="color: #6272a4;">'."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span> <span style="color: #f1fa8c;">"P"</span>)
  (<span style="color: #ff79c6; font-weight: bold;">let</span> ((nombre-archivo <span style="color: #f1fa8c;">""</span>))
    (<span style="color: #ff79c6; font-weight: bold;">dolist</span> (archivo (lista-archivos))
      (<span style="color: #ff79c6; font-weight: bold;">setq</span> nombre-archivo (file-name-nondirectory archivo))
      (procesar-archivo nombre-archivo))))
</pre>
</div>
</div>
</div>
<div id="outline-container-orgd84eb63" class="outline-2">
<h2 id="orgd84eb63">Conclusiones (provisionales)</h2>
<div class="outline-text-2" id="text-orgd84eb63">
<p>
De momento, en esta ocasión está comportándose mejor el lío con la
base de datos. Sigue siendo un poco incordio cuando cambio de
dispositivo y actualizo el repositorio. Al actualizar, tarda un rato
en regenerar la base de datos <code>sqlite</code>. También hay que decir que
luego la búsqueda se agiliza, mientras en <code>Zetteldeft</code> las búsquedas
pueden ser un poco más lentas, pero no se retarda el cargar las notas.
</p>

<p>
Por otro lado, la manera de navegar entre enlaces en <code>Zetteldeft</code> es
rapidísimo, algo de lo que carece <code>org-roam</code> y navegar hasta una
determinada nota pude ser tedioso. Además los enlaces de <code>org-roam</code> es
idéntico a cualquier enlace de <code>org-mode</code>, por lo que se visualiza
como cualquier otro. Sin embargo, el destino que se enlaza se refiere
al <i>UUID</i> y dichos enlaces sólo funcionan dentro de <code>org-roam</code>.
</p>

<p>
Sobre el <i>UI</i>, cuando cuentas con cientos de entradas, como es mi
caso, el verlas de un pantallazo no ayuda especialmente a nada. Eso
sí, cuando tienes mirones, quedan muy vistosas las bolitas danzando
por la ventana. O quizá es que no le he encontrado aún un uso más
interesante.
</p>

<p>
Como apunte para el futuro, me tengo que poner un poco con el tema de
cómo poder separar notas que no quiero que se mezclen con el
<i>noterío principal</i>. Por ejemplo, para las que realizo con
<code>Zetteldeft</code> tengo un par de funciones y teclas que cambian el
directorio de almacenado. Si solvento de algún modo este pequeño
problema, es posible que se quede <code>org-roam</code> en mi caja de
herramientas, si no... pues seguiré como hasta ahora.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2023/10/23/probando-de-nuevo-org-roam.html</link>
  <pubDate>Mon, 23 Oct 2023 10:03:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Mi (primera) intervención en un taller de hispa-emacs]]></title>
  <description><![CDATA[
<div class="post-author">hispa-emacs</div>
<div class="post-date">2023-10-08</div>
<p>
Os traigo un enlace a mi (primera) intervención en uno de los talleres
de <a href="https://hispa-emacs.org/">hispa-emacs</a> donde hablamos sobre cómo está construido este <i>blog</i>,
vimos el código fuente por encima y realizamos un ejemplo de cómo se
publicaría un artículo en él. El vídeo generado se puede encontrar a
continuación.
</p>

<div style="text-align:center">
  <iframe title="Los mimbres Emacs Lisp de Notxor y su Blog" width="720" height="405" src="https://fediverse.tv/videos/embed/5aa63441-3dbe-4a86-8aa2-c69a6b1afa36" frameborder="0" allowfullscreen="yes" sandbox="allow-same-origin allow-scripts allow-popups"></iframe>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/elisp/index.html">elisp</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[elisp]]></category>
  <link>https://notxor.nueva-actitud.org/2023/10/08/mi-intervencion-en-un-taller-de-hispa-emacs.html</link>
  <pubDate>Sun, 08 Oct 2023 09:34:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Introducción a Chicken Scheme]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-09-07</div>
<p>
En este artículo quiero contar de manera rápida y sin entrar en
demasiado detalle, cómo estoy utilizando <i>Chicken Scheme</i> y por qué me
gusta tanto, por encima de otros <i>Scheme</i> más populares, o incluso por
delante de <i>Common Lisp</i>. Lo haré contando paso a paso un ejemplo de
programación sencillo, nada complicado de entender o con algoritmos
complejos. Desde los primeros pasos en la línea de <i>REPL</i> hasta la
compilación en un ejecutable independiente.
</p>

<p>
Sin embargo, esto no es un curso de <i>Scheme</i>, ni de programación.
Entiendo, desde el principio, que quien lea esto está interesado en el
tema de la programación y sabe algo sobre el tema. Encontrarás, por
tanto, que muchas cosas las daré por sabidas. También supongo que
sabes cómo instalar el <i>Chicken Scheme</i> y cómo configurar tu editor
favorito para trabajar con <i>Scheme</i>.
</p>

<p>
El intérprete se puede utilizar también para programar pequeños
<i>scripts</i> para ejecutarlos sin necesidad de compilación. Por ejemplo,
para levantar un servidor local que me sirva hacer pruebas utilizo el
siguiente <i>script</i> que está en el <code>PATH</code> como <code>start-server</code>
</p>

<div class="org-src-container">
<pre class="src src-scheme">#! /home/notxor/opt/bin/csi -s

(<span style="color: #ff79c6; font-weight: bold;">import</span> spiffy
        simple-directory-handler)

(handle-directory simple-directory-handler)
(root-path <span style="color: #f1fa8c;">"."</span>)
(start-server)
</pre>
</div>
<div id="outline-container-orgbe2f3ca" class="outline-2">
<h2 id="orgbe2f3ca">Invocando el intérprete</h2>
<div class="outline-text-2" id="text-orgbe2f3ca">
<p>
Al instalar <i>Chicken Scheme</i> nos encontraremos dos binarios
fundamentales<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> y algunos otros auxiliares.  El comando <code>csi</code>
llama al intérprete de <i>Chicken Scheme</i>:
</p>

<pre class="example" id="org92eb354">
&gt; csi
CHICKEN
(c) 2008-2021, The CHICKEN Team
(c) 2000-2007, Felix L. Winkelmann
Version 5.3.0 (rev e31bbee5)
linux-unix-gnu-x86-64 [ 64bit dload ptables ]

Type ,? for help.
#;1&gt; 42
42
#;2&gt; e

Error: unbound variable: e
#;2&gt; 
</pre>
</div>
<div id="outline-container-org73d4010" class="outline-3">
<h3 id="org73d4010">Evaluando expresiones</h3>
<div class="outline-text-3" id="text-org73d4010">
<p>
Al ejecutarse en modo interactivo, nos muestra un breve mensaje con
información sobre el <i>copyright</i> y la versión. Nos avisa de que
podemos acceder a la ayuda si en el <i>prompt</i> tecleamos <code>,?</code> y nos
muestra el <i>prompt</i>: <code>#;1&gt;</code>. Pulsamos la secuencia de teclas <code>4</code>, <code>2</code>,
<code>ENTER</code>. Al pulsar esta última tecla, el sistema entiende que tiene
que evaluar la línea y eso hace. Al evaluar un número o una variable
cualquiera, nos devuelve su valor. Además, tras haber evaluado la
primera línea, vemos que la numeración del <i>prompt</i> avanza.
</p>

<p>
Sin embargo, al escribir la secuencia <code>e</code>, <code>ENTER</code>, nos devuelve la
frase <code>Error: unbound variable: e</code> y el contador del <i>prompt</i> no
avanza. Lo que ocurre es que el sistema entiende que queremos evaluar
una variable <code>e</code> que no está definida y nos advierte de ello.
</p>

<p>
Todo esto es muy básico y funciona de la manera esperada para quien
haya utilizado otros sistemas <i>REPL</i> de otros lenguajes de
programación.
</p>

<p>
Para salir del intérprete podemos evaluar la combinación <code>,q</code> en el
<i>prompt</i> o pulsar <code>C-d</code> como en la mayoría de terminales.
</p>
</div>
</div>
</div>
<div id="outline-container-org7002b5f" class="outline-2">
<h2 id="org7002b5f">Primer archivo de código</h2>
<div class="outline-text-2" id="text-org7002b5f">
<p>
Además de poder trabajar directamente en el <i>prompt</i> interactivo,
podemos escribir el código en un archivo de texto plano con nuestro
editor favorito. Tradicionalmente, los archivos de código de <i>Scheme</i>
llevan la extensión <code>.scm</code>. También es tradicional, para crear el
primer programa, utilizar el famoso <i>hola mundo</i>, pero como estoy un
poco harto de él, vamos a hacer otra cosa: ¡vamos a jugar a la
ruleta!<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. Para ello creamos un nuevo fichero con el nombre
<code>ruleta.scm</code> en el editor y escribimos el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-scheme">(<span style="color: #ff79c6; font-weight: bold;">import</span> (chicken random))

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">ruleta</span>)
  (pseudo-random-integer 37))
</pre>
</div>

<p>
Hay algunos puntos que, supongo, necesitan un poco más de aclaración:
<code>import</code> nos permite importar a nuestro programa paquetes, módulos o
librerías que nos simplifican el trabajo.  Aquellos módulos que vienen
junto con <i>Chicken</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> se importan mediante la forma <code>(chicken
[módulo])</code>. En el caso de nuestro ejemplo: <code>(chicken random)</code> importa
un módulo que nos permite generar números pseudoaleatorios.  Es decir,
nos va a permitir utilizar la función <code>pseudo-random-integer</code>, que nos
devolverá un número entero entre 0 y el rango máximo especificado (37
en nuestro caso).
</p>

<p>
La macro <code>define</code> permite definir tanto variables como funciones. No
hay distinción entre ambas cosas, pues para <i>Scheme</i> no hay distinción
entre código y datos<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>. Es decir, el sistema, al evaluar <code>ruleta</code>
evaluará lo que contenga, que puede ser un valor o algo que se evalúe
hasta encontrar un valor.
</p>

<p>
En el código se puede apreciar, que los nombres de entidades
compuestos por varias palabras, dichas palabras se separan mediante un
guión simple. Es una costumbre de todos los <i>Lisp</i> y derivados, no
utilizar el <i>CamelCase</i>, puesto que para <i>Lisp</i> en origen todos los
nombres se traducen a mayúsculas, y tampoco se utiliza el guión bajo
—o la barra baja, si prefieres llamarlo así—.
</p>
</div>
<div id="outline-container-org957145c" class="outline-3">
<h3 id="org957145c">Evaluar nuestro código en el intérprete</h3>
<div class="outline-text-3" id="text-org957145c">
<p>
Una vez hemos escrito el código, es posible que queramos evaluar cómo
funciona en el intérprete. Para ello debemos seguir estos sencillos
pasos<sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>:
</p>

<ol class="org-ol">
<li>Lanzar el intérprete con el comando <code>csi</code>.</li>
<li>Cargar nuestro código</li>
<li>Evaluarlo</li>
</ol>

<pre class="example" id="org93d3394">
#;1&gt; (load "ruleta.scm")
; loading ruleta.scm ...
; loading /[path al directorio]/lib/chicken/11/chicken.random.import.so ...
#;2&gt; (ruleta)
11
#;3&gt; 
</pre>

<p>
La forma <code>load</code> nos permite cargar el código contenido en un archivo
<code>.scm</code>. También se puede utilizar desde el modo interactivo la
abreviatura o comando interno <code>,l</code>. Es decir, podríamos haber hecho
lo mismo de la siguiente manera:
</p>

<pre class="example" id="orge83d5a5">
#;1&gt; ,l ruleta.scm
; loading ruleta.scm ...
; loading /[path al directorio]/lib/chicken/11/chicken.random.import.so ...
#;1&gt; (ruleta)
32
</pre>

<p>
La única diferencia entre los dos métodos es que utilizando el comando
interno de <code>csi</code>, no se actualiza el contador del <i>prompt</i>, porque no
ha habido evaluación de código <i>Scheme</i>. Pero en ambos casos, se
evalúa el archivo <code>ruleta.scm</code> y se carga el módulo interno <code>random</code>
como librería dinámica. Una vez cargado, podemos interactuar con
nuestro código evaluando la forma <code>(ruleta)</code>.
</p>
</div>
</div>
<div id="outline-container-org088297d" class="outline-3">
<h3 id="org088297d">Jugar en la ruleta</h3>
<div class="outline-text-3" id="text-org088297d">
<p>
Para poder jugar en la ruleta, aún nos falta un poco de código. Lo
primero sería, poder decirle a nuestro programa a qué número queremos
apostar. Para ello, deberíamos definir alguna forma que admita un
parámetro. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-scheme">(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">apostar-ruleta</span> num-apostado)
  (comparar-apuesta (ruleta) num-apostado))
</pre>
</div>

<p>
A la macro <code>define</code> se le pasa una lista con el nombre de la función
seguida de los parámetros que necesita. En este primer ejemplo, sólo
se necesita un parámetro: el <code>num-apostado</code>. A continuación se
encuentra el cuerpo de la función, que lo único que hace es llamar a
otra función —que aún no está programada— que necesitará dos
parámetros.
</p>

<div class="org-src-container">
<pre class="src src-scheme">(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">comparar-apuesta</span> resultado num-apostado)
  (<span style="color: #ff79c6; font-weight: bold;">if</span> (= resultado num-apostado)
      (display <span style="color: #f1fa8c;">"&#161;Has ganado! Ha salido el "</span>)
      (display <span style="color: #f1fa8c;">"&#161;Has perdido! Ha salido el "</span>))
  resultado)
</pre>
</div>

<p>
En ésta última llamada, el primer parámetro es <code>resultado</code>, que, según
hacemos la llamada en la función anterior, será el número obtenido en
<code>(ruleta)</code>. El segundo parámetro es, directamente, el que pasamos
desde <code>apostar-ruleta</code>.  El condicional <code>if</code> comprueba si ambos
números en los parámetros son iguales. Para explicarlo un poco más, la
forma <code>if</code> tiene tres argumentos:
</p>

<ol class="org-ol">
<li>Una comparación que devuelve un <i>booleano</i>.</li>
<li>El bloque de código que evaluará si ese booleano es <code>#t</code>.</li>
<li>El bloque de código que evaluará si es <code>#f</code>.</li>
</ol>

<p>
Por último, la función <code>comparar-apuesta</code> también devuelve
<code>resultado</code>, que como dije antes es el número obtenido en la ruleta.
No hay una instrucción tipo <code>return</code> o similares, una función devuelve
siempre el valor de la última evaluación que realiza y como sabemos,
el nombre de una variable se evalúa con su valor.
</p>
</div>
</div>
<div id="outline-container-org32ded3a" class="outline-3">
<h3 id="org32ded3a">Compilación a librería binaria</h3>
<div class="outline-text-3" id="text-org32ded3a">
<p>
Si queremos que nuestro código se ejecute más rápido, podemos
compilarlo en una librería dinámica. Ese código binario, se puede
cargar también en el <i>REPL</i>, como ya hemos visto que hace <i>Chicken</i>
cuando carga algún módulo interno. Por hacerlo brevemente:
</p>

<pre class="example" id="orgbce125c">
&gt; csc -s ruleta.scm
&gt; csi
csi
CHICKEN
(c) 2008-2021, The CHICKEN Team
(c) 2000-2007, Felix L. Winkelmann
Version 5.3.0 (rev e31bbee5)
linux-unix-gnu-x86-64 [ 64bit dload ptables ]

Type ,? for help.
#;1&gt; ,l ruleta.scm
; loading ruleta.scm ...
; loading /home/notxor/opt//lib/chicken/11/chicken.random.import.so ...
#;1&gt; (apostar-ruleta 13)
¡Has perdido! Ha salido el 2
#;2&gt; 
</pre>

<p>
Explicándolo un poco más: <code>csc</code> es el compilador de <i>Chicken Scheme</i>.
Con esta herramienta podemos compilar código proporcionando salida a
<code>.o</code>, a ejecutable directamente o a librearías estáticas y dinámicas.
En nuestro caso, como el código lo queremos cargar desde el modo
interactivo, lo podríamos compilar como una librería dinámica de la
siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; csc -s ruleta.scm
</pre>
</div>

<p>
Como digo, <code>csc</code> es el compilador de <i>Chicken Scheme</i>. En el ejemplo,
la opción <code>-s</code> (o la opción <code>-shared</code>, o <code>-dynamic</code>) genera una
librería dinámica en nuestro sistema (<code>ruleta.so</code> en <i>GNU/Linux</i>, o
<code>.dll</code> en <i>Windows</i>, o <code>.dylib</code> en <i>Mac OS</i>).
</p>

<p>
Esta nueva librería la podemos cargar también en el intérprete. Antes,
vimos cómo cargar un módulo de los que vienen junto con <i>Chicken</i> al
hacer una importación. Automáticamente se hacía un <code>load</code> y cargaba un
archivo <code>.so</code>. Para cargar el nuestro, podemos hacerlo directamente:
</p>

<pre class="example" id="orga290328">
#;1&gt; ,l ruleta.so
; loading ruleta.so ...
#;1&gt; (ruleta)
28
#;2&gt; 
</pre>

<p>
Lo podemos importar no sólo con la instrucción <code>,l</code>, sino también con
la forma equivalente <code>(load "ruleta.so")</code>.
</p>
</div>
</div>
</div>
<div id="outline-container-orgb2e1c8d" class="outline-2">
<h2 id="orgb2e1c8d">Compilar ejecutable</h2>
<div class="outline-text-2" id="text-orgb2e1c8d">
<p>
El código de nuestro primer ejemplo está pidiendo poder ejecutarse
como un programa independiente desde un terminal. Para convertirlo en
un ejecutable, necesitamos dos cosas:
</p>

<ol class="org-ol">
<li>Recibir parámetros desde la línea de comandos.</li>
<li>Establecer una función que será la entrada de la ejecución del
binario. Tradicionalmente en <i>C</i> y otros lenguajes de programación,
esta función se llama <code>main</code>.</li>
</ol>

<p>
Para cumplir con el primer requisito necesitamos importar un módulo
interno de <i>Chicken</i> que se llama <code>process-context</code>. En este módulo se
define <code>commond-line-arguments</code>, que devuelve una lista de cadenas que
representan los parámetros que se escriben en la línea de comandos.
</p>

<p>
Empecemos por lo fácil. La función principal, la podemos escribir de
la siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-scheme">(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">principal</span> args)
  (print (apostar-ruleta (string-&gt;number (car args)))))
</pre>
</div>

<p>
A los que tienen un poco de reparo con los paréntesis, quizá les
resultaría más fácil de entender la función si la escribimos así:
</p>

<div class="org-src-container">
<pre class="src src-scheme">(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">principal</span> args)
  (print
   (apostar-ruleta
    (string-&gt;number
     (car args)
    )
   )
  )
)
</pre>
</div>

<p>
Evaluando el código de dentro hacia afuera nos encontramos:
</p>

<ol class="org-ol">
<li><code>(car args)</code> devuelve el primer parámetro recibido en la función.</li>
<li>Puesto que el parámetro es una cadena y <code>apostar-ruleta</code> está
pidiendo un número, debemos convertir la cadena en número con la
función <code>string-&gt;number</code>.</li>
<li><code>apostar-ruleta</code> toma el número que le pasamos con el parámetro y
lo compara con el número que ha salido en la ruleta.</li>
<li><code>print</code> muestra por pantalla el número obtenido en la ruleta al
llamar a <code>apostar-ruleta</code>.</li>
</ol>

<p>
Lo que nos falta es decirle al compilador qué función es la que debe
tomar como entrada del ejecutable. Eso lo hacemos con el siguiente
código:
</p>

<div class="org-src-container">
<pre class="src src-scheme">(<span style="color: #ff79c6; font-weight: bold;">cond-expand</span>
  ((<span style="color: #ff79c6; font-weight: bold;">and</span> chicken compiling)
   (principal (command-line-arguments)))
  (<span style="color: #ff79c6; font-weight: bold;">else</span> #f))
</pre>
</div>

<p>
<code>cond-expand</code> es un condicional, como indica su nombre. Lo que hace es
que mientras se ejecuta el compilador de <i>Chicken</i> se añada una
llamada a <code>principal</code> con la lista de argumentos y que no haga nada en
caso contrario.
</p>

<p>
Al compilarlo desde la línea de comandos comprobamos si funciona.
</p>

<pre class="example" id="org3ff8e49">
&gt; csc ruleta.scm
&gt; ./ruleta 13
¡Has perdido! Ha salido el 2
&gt;  
</pre>

<p>
En este caso, al compilador <code>csc</code> lo llamo sólo pasándole el archivo
que debe compilar sin ningún parámetro adicional. Eso genera el
binario <code>ruleta</code> y se le llama desde línea de comandos como a
cualquier otro programa.
</p>

<p>
El código completo del ejemplo es el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-scheme">(<span style="color: #ff79c6; font-weight: bold;">import</span> (chicken random)
        (chicken process-context))

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">ruleta</span>)
  (pseudo-random-integer 37))

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">comparar-apuesta</span> resultado num-apostado)
  (<span style="color: #ff79c6; font-weight: bold;">if</span> (= resultado num-apostado)
      (display <span style="color: #f1fa8c;">"&#161;Has ganado! Ha salido el "</span>)
      (display <span style="color: #f1fa8c;">"&#161;Has perdido! Ha salido el "</span>))
  resultado)

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">apostar-ruleta</span> num-apostado)
  (comparar-apuesta (ruleta) num-apostado))

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">principal</span> args)
  (print (apostar-ruleta (string-&gt;number (car args)))))

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Ejecutar 'principal' cuando se compila como ejecutable
</span>(<span style="color: #ff79c6; font-weight: bold;">cond-expand</span>
  ((<span style="color: #ff79c6; font-weight: bold;">and</span> chicken compiling)
   (principal (command-line-arguments)))
  (<span style="color: #ff79c6; font-weight: bold;">else</span> #f))
</pre>
</div>

<p>
Igualmente podemos seguir compilando este código como si fuera una
librería. Lo único que sucederá es que al cargar la librería binaria
en el intérprete, éste se quejará porque no le pasamos un parámetro
por línea de comandos. Sin embargo el código sigue funcionando:
</p>

<pre class="example" id="org1f927cf">
&gt; csc -s ruleta.scm
&gt; csi
CHICKEN
(c) 2008-2021, The CHICKEN Team
(c) 2000-2007, Felix L. Winkelmann
Version 5.3.0 (rev e31bbee5)
linux-unix-gnu-x86-64 [ 64bit dload ptables ]

Type ,? for help.
#;1&gt; ,l ruleta.so
; loading ruleta.so ...

Error: (car) bad argument type: ()

        Call history:

        ruleta.scm:22: chicken.process-context#command-line-arguments	 
        ruleta.scm:22: principal	 
        ruleta.scm:17: scheme#string-&gt;number	 	&lt;--
#;1&gt; (apostar-ruleta 13)
¡Has perdido! Ha salido el 30
#;2&gt; 
</pre>
</div>
</div>
<div id="outline-container-orgefcc1db" class="outline-2">
<h2 id="orgefcc1db">Depuración</h2>
<div class="outline-text-2" id="text-orgefcc1db">
<p>
<i>Chicken Scheme</i> proporciona también una aplicación que nos ayuda a
depurar el código. Dicha aplicación depende de <i>Tcl/Tk</i> y debes tener
instalado en tu sistema dicho entorno. Además, cuando compilamos,
debemos establecer también el nivel de depurado:
</p>

<pre class="example" id="org8b65931">
&gt; csc -d3 ruleta.scm
&gt; feathers ruleta 13
</pre>


<figure id="orgf873e41">
<img src="./imagenes/Captura_debugger.png" alt="Captura_debugger.png">

</figure>

<p>
Habitualmente se abre sólo la ventana de código, pero al pulsar
<code>&lt;F3&gt;</code>, como se aprecia en la imagen, también podemos inspeccionar el
valor de las variables.
</p>
</div>
</div>
<div id="outline-container-orgca62260" class="outline-2">
<h2 id="orgca62260">Conclusiones</h2>
<div class="outline-text-2" id="text-orgca62260">
<p>
<i>Chicken Scheme</i> es un sistema muy flexible y rápido. Proporciona
herramientas sencillas de manejar y de poner a prueba y cuenta con una
documentación bastante amplia. Muchas veces, mi forma de trabajar es
ir haciendo pruebas al estilo <i>REPL</i>.
</p>

<p>
Mi entorno de trabajo es <i>Emacs</i> con el paquete <i>Geiser</i> y con eso me
es suficiente. Pero hay quien necesita herramientas externas y un
<code>lsp</code><sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup> que llevarse al editor. <i>Chicken Scheme</i> cuenta con la
posibilidad de instalar su <code>lsp</code>. Sólo hay que ejecutar el comando:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; chicken-install lsp-server
</pre>
</div>

<p>
Una vez instalado el servidor debes configurarlo para que funcione en
tu editor favorito.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
El compilador <code>csc</code> y el intérprete <code>csi</code>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Abstenerse los ludópatas, o al menos, no realizar apuestas con
el código. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Los llamados <i>módulos internos</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ocurren también en más sistema de la familia <i>Lisp</i>. No hay una
marcada frontera entre datos y código. 
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En <i>Emacs</i> el paquete <code>geiser</code> nos facilita todos estos asuntos
permitiéndonos comunicarnos con el <i>REPL</i> mientras escribimos código
en él. 
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Language Server Protocol</i>
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/scheme/index.html">scheme</a> <a href="/tags/chicken/index.html">chicken</a> ]]></description>
  <category><![CDATA[scheme]]></category>
  <category><![CDATA[chicken]]></category>
  <link>https://notxor.nueva-actitud.org/2023/09/07/introduccion-a-chicken-scheme.html</link>
  <pubDate>Thu, 07 Sep 2023 12:38:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[PicoLisp]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-09-01</div>
<p>
Hoy traigo un poco de información sobre <i>PicoLisp</i> y por qué no lo
puedo calificar o situar ni entre los <i>Lisp</i> ni entre los <i>Scheme</i>.
Son unas primeras impresiones y por tanto puedo estar equivocado, pues
me baso, fundamentalmente, en su documentación y lo que me han
mostrado unos pocos ejemplos que he ido probando, con alguna
dificultad, pero también con algún logro. En este artículo traigo lo
más básico: instalación, entorno de programación y algunas pruebas de
rendimiento.
</p>

<p>
Pero, antes de nada: ¿qué es <i>PicoLisp</i>? Después de unos días
investigando y probando tampoco lo tengo yo muy claro, pero diría que
es un <i>framework</i> para la creación de aplicaciones, a través de una
máquina virtual programada en <code>clang</code> (LLVM) que proporciona un
lenguaje interpretado de la familia de <i>Lisp</i>, bastante eficiente.
Proporciona todas las características para poder montar cualquier tipo
de aplicación:
</p>

<ul class="org-ul">
<li>Entorno <i>REPL</i> y depuración.</li>
<li>Editor integrado estilo <code>vi</code><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.</li>
<li>POO integrada en la base<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.</li>
<li>Base de datos propia integrada en el lenguaje: Una base de datos
<i>No-SQL</i>, orientada a almacenar objetos, con un marcado
funcionamiento <i>entidad-relación</i>.</li>
<li><i>GUI</i> integrada en el lenguaje y congruente con la <i>BD</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>.</li>
</ul>

<p>
Su máquina virtual está diseñada como un montón de <i>células</i> o celdas
(<i>cells</i>), que consisten en dos palabras de 64bits, que pueden
contener un valor o un puntero a otra célula:
</p>


<figure id="orgef1b29f">
<img src="./imagenes/celula.svg" alt="celula.svg" class="org-svg" width="25%">

</figure>

<p>
Los tipos de datos complejos se montan en base a estas células o
celdas. Por ejemplo, un <code>bignum</code> o una <code>string</code> se montan encadenando
dígitos o caracteres en una lista de celdas enlazadas. En este
aspecto, es un sistema muy congruente.
</p>
<div id="outline-container-org89571e3" class="outline-2">
<h2 id="org89571e3">Instalación</h2>
<div class="outline-text-2" id="text-org89571e3">
<p>
En algunas distribuciones de <i>GNU/Linux</i> está el paquete de <i>PicoLisp</i>
listo para ser instalado. Por lo que se dice en la documentación sólo
en las derivadas de <i>Debian</i>: Ubuntu, Mint, ... En mi caso, utilizo
<i>OpenSuse Tumbleweed</i> y no hay paquete <i>PicoLisp</i> ̣—ni se le espera—.
La instalación, por tanto, pasa por el compilado desde el código
fuente, que se distribuye con una licencia <i>MIT/X11</i>.
</p>
</div>
<div id="outline-container-org062a52e" class="outline-3">
<h3 id="org062a52e">Compilado</h3>
<div class="outline-text-3" id="text-org062a52e">
<p>
Lo primero es comprobar que están todas las dependencias necesarias
para la compilación. En las instrucciones de instalación pide las
siguientes:
</p>

<ul class="org-ul">
<li><code>binutils</code></li>
<li><code>make</code></li>
<li><code>clang</code></li>
<li><code>llvm</code></li>
<li><code>libreadline-dev</code></li>
<li><code>libfii-dev</code></li>
<li><code>libssl-dev</code></li>
<li><code>pkg-config</code></li>
</ul>

<p>
Una vez tenemos esas dependencias instaladas, necesitaremos también el
código fuente, que lo podemos descargar y descomprimir de la siguiente
manera:
</p>

<pre class="example" id="org00608a2">
$ wget https://software-lab.de/pil21.tgz
$ tar xfz pil21.tgz
</pre>

<p>
La compilación, también es sencilla:
</p>

<pre class="example" id="orgd470a8d">
$ cd pil21/src
$ make
</pre>

<p>
Si lo has compilado sin errores la instalación manual consiste nada
más que en dar la situación de los paquetes con enlaces:
</p>

<pre class="example" id="orge641e6b">
# ln -s /&lt;path completo&gt;/pil21 /usr/lib/picolisp
# ln -s /usr/lib/picolisp/bin/picolisp /usr/bin
# ln -s /usr/lib/picolisp/bin/pil /usr/bin

# ln -s /&lt;path completo&gt;/pil21/man/man1/picolisp.1 /usr/share/man/man1
# ln -s /&lt;path completo&gt;/pil21/man/man1/pil.1 /usr/share/man/man1
# ln -s /&lt;path completo&gt;/pil21 /usr/share/picolisp
# ln -s /&lt;path completo&gt;/pil21/lib/bash_completion /usr/share/bash-completion/completions/pil
</pre>

<p>
Obsérvese que los enlaces se deben crear con permisos de <code>root</code>.
</p>
</div>
</div>
<div id="outline-container-org6e2ffa8" class="outline-3">
<h3 id="org6e2ffa8">Preparación del entorno: <i>Emacs</i></h3>
<div class="outline-text-3" id="text-org6e2ffa8">
<p>
Para <i>Emacs</i> he encontrado dos paquetes que pueden servir para
configurar nuestro editor favorito para desarrollar código con
<i>PicoLisp</i>. Uno es <a href="https://github.com/tj64/picolisp-mode">el recomendado en la documentación</a> del
sistema<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup> y otro es <a href="https://github.com/flexibeast/plisp-mode">el que está en ELPA</a>.
</p>

<p>
Por comodidad, y puesto que lo que estoy haciendo son pruebas para
determinar si me gusta o no esta herramienta, he instalado el sistema
que viene en la lista de paquetes y, además, añado un paquete de
<i>autocompletado</i>.:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> plisp-mode
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t
  <span style="color: #8be9fd; font-style: italic;">:init</span>
  (<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">inferior-plisp</span>))
(<span style="color: #ff79c6; font-weight: bold;">use-package</span> company-plisp
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t
  <span style="color: #8be9fd; font-style: italic;">:after</span> plisp-mode)
(add-to-list 'auto-mode-alist '(<span style="color: #f1fa8c;">"\\.l$"</span> . plisp-mode))
</pre>
</div>

<p>
Quizá sea más efectivo el paquete recomendado en la documentación,
pero hay que descargar los fuentes, añadir los directorios a la lista
de directorios fuente y es más lioso que utilizar el paquete del
repositorio.
</p>
</div>
</div>
</div>
<div id="outline-container-org8156ed6" class="outline-2">
<h2 id="org8156ed6">Comparación entre hermanos</h2>
<div class="outline-text-2" id="text-org8156ed6">
<p>
Dicen que comparar entre hermanos no debería hacerse por aquello de
que cada uno somos un mundo, pero esto no se aplica a herramientas de
trabajo. En este caso, la familia <i>Lisp</i> se encuentra dividida en un
par de ramas principales <i>Common Lisp</i> y <i>Scheme</i> con algunas ovejas
descarriadas como <code>elisp</code> o <i>PicoLisp</i>. El primero más cercano a la
rama <i>CL</i> y el segundo, desde mi punto de vista, más cercano a la rama
<i>Scheme</i>.
</p>

<p>
<i>CL</i> proporciona una estandarización compleja, mientras que la de
<i>Scheme</i> es mucho más sencilla, lo que hace que no todos los <i>scheme</i>
sean compatibles aunque van apareciendo aspectos que estandarizar cada
poco tiempo y evolucionan <code>R5RS</code>, <code>R7RS</code> ... Los que yo llamo
descarriados son sistemas relacionados que no cumplen los estándares.
</p>

<p>
Entre los <i>Lisp</i> es algo habitual saltarse los estándares por algún
motivo. Este motivo suele ser adaptar el lenguaje a una tarea
concreta, algo que hacen <i>Maxima</i>, <i>AutoCAD</i> y <i>emacs-lisp</i>. Entre los
<i>Scheme</i> es más pronunciado, porque al final cada uno va a su rollo,
aunque tiendan a la estandarización. En algunos casos, como <i>Racket</i>,
se puede forzar utilizando <code># Lang r7rs</code> como primera línea del
<i>script</i>. Con otros las cosas no son tan sencillas.
</p>

<p>
La diferencia fundamental entre los <i>Lisp</i> y los <i>Scheme</i> se basa en
las tablas de símbolos internas. <i>Lisp</i> cuenta con dos y por tanto las
variables y las funciones tienen cada una su tabla y puede ocurrir, y
ocurre, que una variable y una función compartan nombre. A cambio,
deben tener dos palabras distintas para definir unas u otras. Por el
contrario, los <i>Scheme</i> tienen una sola tabla y por tanto, no pueden
compartir nombre las variables y las funciones. A cambio, sólo hay una
clase de <code>define</code>. En este sentido, <i>PicoLisp</i> es de la familia de los
<i>Scheme</i> y sólo tiene una tabla interna.
</p>

<p>
Un aspecto común a todos es el modo <i>repelente</i>... digo <i>REPL</i>. Todos
ellos pueden funcionar con la secuencia <i>read</i>, <i>eval</i>, <i>print</i>,
<i>loop</i>. En el paso de <i>eval</i>, tanto los <i>Lisp</i> como los <i>Scheme</i>
realizan en realidad dos: 1) convierte las macros definidas en
instrucciones ejecutables y 2) ejecuta dichas instrucciones. En este
caso <i>PicoLisp</i> se desmarca de todos ellos y no hay un paso <i>macro</i> en
el proceso. En cambio, se pueden realizar las mismas cosas, o muy
parecidas, con un poco de sintaxis alienígena en el paso <i>read</i>.
</p>

<p>
En este sentido tengo que recordar que me costó, al principio,
comprender las <i>macros</i> en <i>Lisp</i>, que permiten redefinir el sistema
para adaptarlo a problema creando, en la práctica, un lenguaje propio
para el mismo. Le he echado un vistazo al modo en que se haría en
<i>PicoLisp</i> y no termino de pillar toda la funcionalidad. Supongo que
es una de esas cosas que las vas pillando a base de usarlas. Para los
más puristas el resumen es que no hay <i>macros</i> como en <i>Lisp</i>, pero sí
mecanismos que proporcionan una funcionalidad equivalente.
</p>

<p>
Una característica única que he podido apreciar en <i>PicoLisp</i> es la
capacidad de que las variables tengan <i>propiedades</i>. Pongo un ejemplo
para no hablar en vacío:
</p>

<div class="org-src-container">
<pre class="src src-plisp">: (setq variable "Este es el valor")
-&gt; "Este es el valor"
: (put 'variable 'propiedad1 "Una propiedad")
-&gt; "Una propiedad"
: (put 'variable 'propiedad2 27)
-&gt; 27
: (show 'variable)
variable "Este es el valor"
   propiedad2 27
   propiedad1 "Una propiedad"
-&gt; variable
: (get 'variable 'propiedad2)
-&gt; 27
: 
</pre>
</div>

<p>
Se puede apreciar que las propiedades son pares <i>key-value</i> y que una
variable puede tener tantas como hagan falta sin límite <i>a priori</i>.
</p>
</div>
<div id="outline-container-org572e5a9" class="outline-4">
<h4 id="org572e5a9">Eficiencia</h4>
<div class="outline-text-4" id="text-org572e5a9">
<p>
En la mayoría de los casos la eficiencia, entendida como la velocidad
de ejecución, no es uno de nuestros problemas centrales. Sin embargo,
para la ocasión he preparado una pequeña prueba de velocidades,
comparando el tiempo de ejecución.
</p>

<p>
El código es equivalente en los tres sistemas:
</p>

<ol class="org-ol">
<li><p>
<i>Lisp</i>:
</p>

<div class="org-src-container">
<pre class="src src-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">archivo factorial.lisp
</span>
(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">factorial</span> (x)
  (<span style="color: #ff79c6; font-weight: bold;">if</span> (= x 0)
      1
      (* x (factorial (- x 1)))))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">main</span> ()
  (print (factorial 2000)))

(main)
</pre>
</div>

<p>
Para llamarlo interpretado desde la línea de comandos se utiliza:
</p>

<div class="org-src-container">
<pre class="src src-shell">sbcl --script factorial.lisp
</pre>
</div>

<p>
Para compilar en un ejecutable el anterior archivo abro una sesión
<i>SBCL</i> y hago lo siguiente:
</p>

<pre class="example" id="org66b53e5">
* (load "./factorial.lisp")
[...]
* (sb-ext:save-lisp-and-die "factorial" :toplevel #'main :executable t)
[...]
$
</pre></li>

<li><p>
<i>Scheme</i>:
</p>

<div class="org-src-container">
<pre class="src src-scheme"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">fichero factorial.scm
</span>
(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">factorial</span> x)
  (<span style="color: #ff79c6; font-weight: bold;">if</span> (= x 0)
      1
      (* x (factorial (- x 1)))))

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">main</span>)
  (print (factorial 2000)))

(main)
</pre>
</div>

<p>
Para llamarlo interpretado desde la línea de comandos utilizo:
</p>

<div class="org-src-container">
<pre class="src src-shell">csi -s factorial.scm
</pre>
</div>

<p>
Para compilar el archivo en un ejecutable desde línea de comandos:
</p>

<div class="org-src-container">
<pre class="src src-shell">csc -o fact-scheme factorial.scm
</pre>
</div></li>

<li><p>
<i>PicoLisp</i>:
</p>

<div class="org-src-container">
<pre class="src src-plisp"># fichero factorial.l

(de factorial (N)
    (if (=0 N)
        1
        (* N (factorial (dec N)))))

(de main ()
    (prinl (factorial 2000)))

(main)
</pre>
</div>

<p>
Para llamarlo desde la línea de comandos utilizo:
</p>

<div class="org-src-container">
<pre class="src src-shell">pil factorial.l -bye
</pre>
</div></li>
</ol>

<p>
Al hacer las llamadas anteriores con la instrucción <code>time</code> delante, me
arrojó los siguientes resultados
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Herramienta</th>
<th scope="col" class="org-left">Interpretado</th>
<th scope="col" class="org-left">Compilado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">SBCL</td>
<td class="org-left">28,89ms</td>
<td class="org-left">10,16ms</td>
</tr>

<tr>
<td class="org-left">Chicken</td>
<td class="org-left">11,50ms</td>
<td class="org-left">8,12ms</td>
</tr>

<tr>
<td class="org-left">PicoLisp</td>
<td class="org-left">14,13ms</td>
<td class="org-left">----</td>
</tr>
</tbody>
</table>

<p>
<i>PicoLisp</i> no tiene modo compilado, sólo interpretado, por lo que no
se puede comparar. En realidad no debería poderse comparar de ningún
modo o habría que hacer muchos otros bancos de pruebas con ello para
poder determinar en qué aspectos unos superan a otros. Sin embargo, se
puede afirmar que <i>PicoLisp</i> se desempeña bastante bien, comparado con
el <i>Lisp</i> y el <i>Scheme</i> más rápidos.
</p>
</div>
</div>
</div>
<div id="outline-container-orge94861f" class="outline-2">
<h2 id="orge94861f">Conclusiones</h2>
<div class="outline-text-2" id="text-orge94861f">
<p>
<i>PicoLisp</i> es un <i>framework</i> digno de tener en cuenta y al que,
después de haberle dedicado unos buenos ratos estos días para escribir
este artículo, puedo afirmar que le he ido cogiendo rápido las
maneras. Aunque hay que admitir, que también tengo ya un cierto bagaje
con las herramientas de la familia <i>Lisp</i>.  Sin embargo, apenas he
podido arañar un poco la superficie de <i>PicoLisp</i>.
</p>

<p>
Como resumen puedo decir que me ha gustado lo que he visto hasta
ahora, pero tampoco es una sorpresa que me guste un <i>chismático</i> de la
familia <i>Lisp</i>.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
También he visto en la documentación que se puede establecer el
editor en modo <i>Emacs</i>, pero he sido incapaz de hacerlo. No sé si
falta alguna librería o se tiene que hacer alguna otra cosa que no
estoy haciendo.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Hay que recordar que tanto en <i>Lisp</i> (CLOS) como en <i>Scheme</i>
(SOS) hay que cargar librerías externas.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En la documentación más antigua he visto alguna captura de
pantalla con los <i>widgets</i> clásicos de las <i>X11</i>, pero parece que en
la actualidad han migrado hacia una <i>GUI</i> basada en <code>html</code>.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
No está en <i>ELPA</i> como paquete. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/lisp/index.html">lisp</a> <a href="/tags/pico-lisp/index.html">pico-lisp</a> <a href="/tags/scheme/index.html">scheme</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[lisp]]></category>
  <category><![CDATA[pico-lisp]]></category>
  <category><![CDATA[scheme]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2023/09/01/picolisp.html</link>
  <pubDate>Fri, 01 Sep 2023 09:18:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[A vueltas con ecl]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-08-29</div>
<p>
El otro día <a href="https://notxor.nueva-actitud.org/2023/08/12/lisp-y-scheme-embebidos.html">hablé sobre un par de sistemas embebibles</a>, <code>chibi-scheme</code>
y <code>ecl</code>. Hay quien se ha interesado en el tema, pero por las preguntas
que me han hecho creo que no me expliqué bien en ese artículo. Hoy
intentaré aclarar algunos puntos que gracias a mi torpeza habitual
quedaron un tanto confusos... será un artículo cortito.
</p>

<p>
Los aspectos que trataré serán los siguientes:
</p>

<ol class="org-ol">
<li><i>Embebible</i> no significa que no funcionen si no están embebidos.</li>
<li>Compilables: pueden generar binarios ejecutables directamente.</li>
<li>Cuáles uso y por qué.</li>
</ol>

<p>
Porque soy así de congruente, comenzaré por el tercer y último punto.
La razón, además de mi habitual desorden, es que es la más fácil de
redactar, puesto que está más relacionado con mis gustos que con
aspectos técnicos.
</p>
<div id="outline-container-orgdbb3fc9" class="outline-2">
<h2 id="orgdbb3fc9">Qué uso y por qué</h2>
<div class="outline-text-2" id="text-orgdbb3fc9">
<p>
Mis herramientas, o chismáticos/, para trabajar son sencillas.
Habitualmente cuento con un ordenador portátil, una tableta y un
móvil. El portátil tiene instalada una <i>distro</i> GNU/Linux <i>OpenSuse
Tumbleweed</i>. Hasta hace no mucho, tanto el móvil como la tableta
tenían instalado como SO <i>Ubuntu Touch</i>. Sin embargo, la vida de los
aparatos electrónicos es efímera y ambos pasaron a mejor vida después
de unos cuantos años de uso. Actualmente, tanto mi móvil como mi
tableta corren con <i>Android®</i>.
</p>

<p>
En mi trabajo debo generar bastantes documentos, lo que me obliga a un
uso intensivo de <i>Emacs</i>. No sólo esto, además utilizo <code>org-mode</code> para
la agenda, toma de notas, etc. La mayor parte de las herramientas que
me he tenido que hacer para automatizar mi día a día, están hechas con
<code>emacs-lisp</code>, pero algunas pocas están programadas en otros lenguajes.
Es decir, cuando he necesitado crearme alguna herramienta más,
especialmente para cálculos o acceder a bases de datos he utilizado
otros lenguajes. De esta manera tengo <i>scripts</i> hechos en <i>Python</i>, en
<i>erlang</i>, uno o dos en <i>Tcl/Tk</i> y otros pocos en <i>scheme</i>.
</p>

<p>
Llevo tiempo queriendo unificar todos esos <i>scripts</i> y tareas en una
aplicación que se convertiría en una especie de gestor de historias
clínicas y otras tareas propias del (psicólogo) autónomo, como puede
ser la facturación. Dicha aplicación debe correr en el portátil y
también en la tableta y, posiblemente, el teléfono. En estos dos
últimos con <a href="https://termux.dev/en/">Termux</a> podría desarrollar dichas propias herramientas. No
necesitaría <i>GUI</i>, aunque sería de agradecer, y por tanto, estoy un
poco sujeto a qué puede correr en dicha aplicación de <i>Android®</i>.
</p>

<p>
Al elegir herramientas, como digo, estoy limitado. Podría haber
elegido <i>erlang</i>, que también corre en <i>Termux</i>, pero <i>erlang</i>
demuestra su potencia en aplicaciones de red, que no es el caso.
Además llevo tiempo haciendo mis pinitos con <a href="https://www.sbcl.org/">SBCL</a> y me encuentro más
cómodo con <i>Common Lisp</i>. Sin embargo en <i>Termux</i> el <i>CL</i> que se puede
encontrar es <i>ECL</i>, por lo que comencé a echarle un ojo... y me gusta.
</p>

<p>
El <i>scheme</i> que más utilizo es <a href="https://call-cc.org/">Chicken Scheme</a> principalmente por sus
huevos... los <i>eggs</i> forman el sistema de paquetería. En <i>Termux</i> hay
varios <i>Scheme</i> instalables:
</p>

<ul class="org-ul">
<li>Chicken</li>
<li>gauche</li>
<li>guile</li>
<li>racket</li>
<li>tinyscheme</li>
</ul>

<p>
Sin embargo, las opciones con <i>Lisp</i> son más escasas y tan sólo <i>ECL</i>
es un <i>Common Lisp</i>:
</p>

<ul class="org-ul">
<li><i>ECL</i></li>
<li><i>fennel</i>: genera código <i>Lua</i></li>
<li><i>ol</i>: Dialecto de <i>Lisp</i></li>
<li><i>PicoLisp</i>: intérprete de <i>Lisp</i> no estándar</li>
</ul>

<p>
Miré por encima <code>picolisp</code>, y a primera vista tiene también muy buena
pinta, pero el que no cumpla estándares me hecha un poco para atrás.
Sin embargo, es un sistema que tengo que echarle un ojo más despacio.
</p>

<p>
Después de todo este rollo, podría haber resumido con una respuesta
mucho más escueta: <i>«uso <code>chicken</code> y <code>ecl</code> en android® y <code>sbcl</code> en
GNU/Linux»</i>.
</p>
</div>
</div>
<div id="outline-container-org61162c8" class="outline-2">
<h2 id="org61162c8">Embebido y compilación</h2>
<div class="outline-text-2" id="text-org61162c8">
<p>
Dichas herramientas tienen la capacidad de funcionar como una librería
que podemos añadir a nuestros programas y que funcionar como un
lenguaje de extensión para la aplicación. Pero que tengan dicha
capacidad no significa que sólo funcionen de dicha manera. Al
contrario: ambos cuentan con herramienta <i>REPL</i>, capacidad de
ejecución como <i>script</i> interpretado y, además, capacidad de
compilado.
</p>

<p>
Dicho de otro modo: que tengan la capacidad de <i>«funcionar como»</i> no
implica que las tengas que utilizar sólamente de ese modo. En ambas
herramientas, tanto en <i>Chicken</i> como en <i>ECL</i> puedes compilar a
binario un <i>script</i>, pero raramente utilizo esa característica, porque
no lo necesito. Es decir, entiendo que la compilación está bien para
darle a alguien un binario y que no necesite instalarse el sistema.
Pero en mi caso, ya tengo instalado el sistema y raramente hago
cálculos tan intensivos que necesite compilar para ahorrarme uno o dos
segundos de tiempo.
</p>

<p>
Sin embargo, para responder a otra pregunta que me han hecho,
explicaré cómo compilar un <i>script</i> o programa con estos sistemas. En
el caso de <i>Chicken</i> es sencillo, tan sólo tienes que utilizar el
compilador que proporciona: <code>csc</code> y se pueden generar archivos <code>.o</code>,
llamar al compilador desde <code>make</code>, etc. Desde <i>ECL</i>, las cosas son
algo distintas: el compilador está embebido en el intérprete y por
tanto, para compilar debes crearte un <i>script</i> que genere el
ejecutable.
</p>

<p>
Vamos a poner un ejemplo para no hablar en vacío. Para no liarme a
programar más allá de lo estrictamente necesario, parto del mismo
código que calcula el factorial de un número. Bueno, el mismo no, pero
muy parecido al código del otro día:
</p>

<div class="org-src-container">
<pre class="src src-common-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">archivo factorial.lisp
</span>
(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">factorial</span> (x)
  (<span style="color: #ff79c6; font-weight: bold;">labels</span> ((itera (n total)
             (<span style="color: #ff79c6; font-weight: bold;">if</span> (= n 0)
                 total
                 (itera (- n 1) (* total n)))))
    (itera x 1)))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">principal</span> ()
  (print (factorial 2000))
  (quit))

(principal)
</pre>
</div>

<p>
El código para generar el binario ejecutable sería:
</p>

<div class="org-src-container">
<pre class="src src-common-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">generar &#171;factorial.o&#187;
</span>(compile-file <span style="color: #f1fa8c;">"factorial.lisp"</span>
              <span style="color: #8be9fd; font-style: italic;">:system-p</span> t)

<span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">generar el binario &#171;fact&#187;
</span>(c:build-program <span style="color: #f1fa8c;">"fact"</span>
                 <span style="color: #8be9fd; font-style: italic;">:lisp-files</span> '(<span style="color: #f1fa8c;">"factorial.o"</span>))
</pre>
</div>

<p>
La forma <code>compile-file</code> genera binarios <code>.o</code> a partir de los fuentes
<i>Lisp</i>. Para hacerlo es importante tener activada la opción
<code>:system-p</code>, porque si no es así, compilará el archivo a <i>byte-code</i>
<code>fasl</code>. El parámetro que recibe es el nombre del archivo.
</p>

<p>
Para generar el ejecutable se llama a <code>c:build-program</code>. El parámetro
que recibe es el nombre del ejecutable. <code>:lisp-files</code> es una lista de
los ficheros <code>.o</code> necesarios para armarlo.
</p>

<p>
Igual que se pueden generar ejecutables, también se pueden hacer
librerías con las formas <code>c:build-static-library</code> y
<code>c:build-shared-library</code>. Pero eso es otra historia que ahora mismo no
viene al caso.
</p>
</div>
</div>
<div id="outline-container-org0799f18" class="outline-2">
<h2 id="org0799f18">Otras consideraciones</h2>
<div class="outline-text-2" id="text-org0799f18">
<p>
En general, los sistemas de la familia <i>Lisp</i> se pueden considerar los
padres de la programación funcional, pero la mayoría soportan la
programación orientada a objetos (POO). <i>CLOS</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> para unos y
<i>SOS</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> para otros. En este sentido, me llamó la atención de
<i>PicoLisp</i> el que lleve dicho sistema ya embebido y que las variables
puedan tener <i>propiedades</i> con valor. Esto hace que las estructuras de
datos puedan ser realmente complejas y es algo que tengo que
investigar un poco más antes de decidirme por algo.
</p>

<p>
De momento, no puedo clasificar a <i>PicoLisp</i> ni entre los <i>Lisp</i>, ni
entre los <i>Scheme</i>, pero debo estudiarlo un poco más antes de decidir,
incluso, si me gusta o no. He visto que es un sistema en desarrollo
desde 1988, lo que da garantía de estabilidad. He visto que es rápido
para ser únicamente interpretado. Le tengo que trastear un poco más y
ya contaré aquí en el <i>blog</i> mis impresiones.
</p>
</div>
</div>
<div id="outline-container-org3720c8a" class="outline-2">
<h2 id="org3720c8a">Conclusión</h2>
<div class="outline-text-2" id="text-org3720c8a">
<p>
Utilizar estas herramientas u otras está más relacionado con la
comodidad del usuario, o con la moda, muchas veces, que con otras
consideraciones. Nos movemos por gustos y costumbres, nos mantenemos
en nuestra <i>zona de confort</i> porque, generalmente, somos más
productivos en ella. Una herramienta nos puede ayudar más o menos pero
siempre nos va a costar más cambiar, dando un salto a lo desconocido,
donde no sabemos cómo nos saldrán los planes.
</p>

<p>
En este sentido, por ejemplo, cuando estuve mirando <i>PicoLisp</i>, me
pareció un sistema bastante interesante y prometedor, como ya dije
antes. Si hubiera seguido un estándar como <i>CL</i> o como <i>Scheme</i>,
seguramente lo hubiera probado más a fondo de lo que lo he hecho hasta
ahora y tendría una opinión más formada sobre ello.
</p>

<p>
En estos aspectos, no tengo muchos reparos a salir de mi <i>zona de
confort</i> para probar cosas nuevas. Eso lo aprendí cuando siendo un
usuario convencido de <i>Vim</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> probé, dedicándole el suficiente
tiempo, <i>Emacs</i> y me encontré un sistema mucho mejor para mis
necesidades. No descarto, por tanto, el investigar otros derroteros,
para <i>mis cosas</i> y no tengo una fecha límite de entrega de ningún
trabajo. Por tanto, me puedo dedicar a aprender lenguajes, a
cacharrear y ampliar <i>mi caja</i> de herramientas.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Common Lisp Object System</i> 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Scheme Object System</i> 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Sigo siéndolo, pero ya no es el editor por defecto en mis
entornos.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/lisp/index.html">lisp</a> ]]></description>
  <category><![CDATA[lisp]]></category>
  <link>https://notxor.nueva-actitud.org/2023/08/29/a-vueltas-con-ecl.html</link>
  <pubDate>Tue, 29 Aug 2023 09:59:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[eglot: lsp para Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-08-14</div>
<p>
En las últimas versiones de <i>Emacs</i> se ha añadido <i>eglot</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> a los
paquetes instalados por defecto. En este artículo hablaré sobre esto y
sobre <i>LSP</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.
</p>


<figure id="orgb15c3ad">
<img src="./imagenes/eglot-built-in.png" alt="eglot-built-in.png">

</figure>

<p>
Hace unos días en el grupo de XMPP donde comentamos cosas, no sólo
hablamos sobre el <i>blog</i>, <i>Mester</i> lanzó una pregunta sobre la
configuración de <code>eglot</code>, sobre si es mejor que <code>lsp-mode</code> y prometí
probar el primero y comentarlo en un artículo. Ya lo adelanté en el
grupo, en su día <code>lsp-mode</code> no terminó de convencerme y <code>eglot</code> está
siguiendo los mismos pasos.
</p>
<div id="outline-container-org93e4797" class="outline-2">
<h2 id="org93e4797">Por qué no me llaman la atención eglot y lsp</h2>
<div class="outline-text-2" id="text-org93e4797">
<p>
De momento me encuentro cómodo con la flexibilidad que proporcionan
las herramientas que he venido utilizando empleando hasta ahora y me
parece que depender de <i>un servicio externo</i> al editor, no tiene por
qué mejorar la experiencia de uso. Al contrario, me encontré cuando
probé <code>lsp-mode</code> que al levantar el modo <i>LSP</i> para <code>erlang</code> se caía
el modo <i>LSP</i> para <i>Python</i>. Se puede solventar reiniciando el
<i>servidor lsp</i> o utilizando sólo un lenguaje en la misma sesión o como
en mi caso, no utilizando <i>LSP</i>, porque <i>Emacs</i> ya proporciona todas
esas herramientas sin necesidad de contar con un servidor externo.
</p>

<p>
Por otro lado, por lo que vi en <code>lsp-mode</code> y por lo que veo en
<code>eglot</code>, las herramientas que utilizan para hacer su trabajo son las
mismas que utilizan los modos de <i>Emacs</i>: <code>ElDoc</code>, <code>Flymake</code>, <code>Xref</code>,
<code>Imenu</code>...  Es decir, tampoco me ahorra espacio en disco. Y si
comparamos la información que ofrece, por ejemplo la documentación que
muestran <code>eldoc</code> y <code>elpy</code>:
</p>


<figure id="org00f7ea0">
<img src="./imagenes/Captura_eldoc-elpy.png" alt="Captura_eldoc-elpy.png">

</figure>

<p>
con la correspondiente con <code>eglot</code>:
</p>


<figure id="org95b60e9">
<img src="./imagenes/Captura_eldoc-eglot.png" alt="Captura_eldoc-eglot.png">

</figure>

<p>
... no sé si rinden las ganancias o no. El que se muestre en el
<code>mini-buffer</code> o en un <i>frame</i> depende del paquete <code>eldoc-box</code>, que no
lo uso habitualmente, porque me he acostumbrado a <code>eldoc</code> sin él.
</p>

<p>
Si alguien tiene curiosidad, para hacer las pruebas he instalado en mi
<i>OpenSuse Tumbleweed</i> el paquete <code>pylsp</code> para que estuviera disponible
y he cambiado la configuración para que en <code>python-mode</code>, cargue
<code>eglot</code>. Por esto, toda la disertación la haré sobre las pruebas que
he hecho en ese lenguaje y sus herramientas de edición en <i>Emacs</i>.
</p>

<p>
Las pruebas las he metido en un archivo de configuración muy escueto y
básico: <code>inicio.el</code>, para no estropear mi <code>init.el</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-to-list 'load-path <span style="color: #f1fa8c;">"~/.emacs.d/site-packages"</span>)
(add-to-list 'load-path <span style="color: #f1fa8c;">"~/.emacs.d/elpa"</span>)
(add-to-list 'load-path <span style="color: #f1fa8c;">"~/.emacs.d/elpa/ivy-20230714.751"</span>)
(add-to-list 'load-path <span style="color: #f1fa8c;">"~/.emacs.d/elpa/swiper-20230410.1815"</span>)
(add-to-list 'load-path <span style="color: #f1fa8c;">"~/.emacs.d/elpa/counsel-20230619.1623"</span>)
(add-to-list 'load-path <span style="color: #f1fa8c;">"~/.emacs.d/elpa/company-20230703.2021"</span>)
(add-to-list 'load-path <span style="color: #f1fa8c;">"~/.emacs.d/elpa/eldoc-box-20230810.503"</span>)
(add-to-list 'load-path <span style="color: #f1fa8c;">"~/.emacs.e/elpa/eglot-1.15"</span>)

(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">ivy</span>)
(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">swiper</span>)
(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">counsel</span>)
(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">company</span>)
(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">eldoc-box</span>)
(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">eglot</span>)

(ivy-mode 1)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> global-company-mode t)

(add-hook 'python-mode 'eglot)
(add-hook 'eglot-managed-mode-hook #'eldoc-box-hover-mode t)
</pre>
</div>

<p>
Primero le doy todos los <i>paths</i> a los paquetes que utilizo y después
los cargo y configuro mínimamente.
</p>

<p>
Después, para arrancar <i>Emacs</i> con ese fichero lo llamo desde línea de
comandos, en el directorio donde se encuentra el fichero de inicio:
</p>

<div class="org-src-container">
<pre class="src src-shell">emacs -q -l inicio.el
</pre>
</div>
</div>
</div>
<div id="outline-container-orgdb75f39" class="outline-2">
<h2 id="orgdb75f39">Lenguajes soportados por eglot</h2>
<div class="outline-text-2" id="text-orgdb75f39">
<p>
Sin configurar nada, <code>eglot</code>, soporta la siguiente lista de servidores
<i>LSP</i>:
</p>


<ul class="org-ul">
<li>Ada: <a href="https://github.com/AdaCore/ada_language_server">ada_language_server</a></li>
<li>Bash: <a href="https://github.com/mads-hartmann/bash-language-server">bash-language-server</a></li>
<li>C/C++: <a href="https://clang.llvm.org/extra/clangd.html">clangd</a> o <a href="https://github.com/MaskRay/ccls">ccls</a></li>
<li>C#: <a href="https://github.com/OmniSharp/omnisharp-roslyn">omnisharp</a></li>
<li>Clojure: <a href="https://clojure-lsp.io">clojure-lsp</a></li>
<li>CMake: <a href="https://github.com/regen100/cmake-language-server">cmake-language-server</a></li>
<li>CSS: <a href="https://github.com/hrsh7th/vscode-langservers-extracted">css-languageserver</a></li>
<li>Dart: <a href="https://github.com/dart-lang/sdk/blob/master/pkg/analysis_server/tool/lsp_spec/README.md">analysis_server</a></li>
<li>Dockerfile: <a href="https://github.com/rcjsuen/dockerfile-language-server-nodejs">docker-langserver</a></li>
<li>Elixir: <a href="https://github.com/elixir-lsp/elixir-ls">elixir-ls</a></li>
<li>Elm: <a href="https://github.com/elm-tooling/elm-language-server">elm-language-server</a></li>
<li>Erlang: <a href="https://github.com/erlang-ls/erlang_ls">erlang_ls</a></li>
<li>Fortran: <a href="https://github.com/hansec/fortran-language-server">fortls</a></li>
<li>Futhark: <a href="https://futhark-lang.org">futhark lsp</a></li>
<li>Go: <a href="https://github.com/golang/tools/tree/master/gopls">gopls</a></li>
<li>Godot Engine: <a href="https://godotengine.org">built-in LSP</a></li>
<li>HTML <a href="https://github.com/hrsh7th/vscode-langservers-extracted">html-languageserver</a></li>
<li>Haskell: <a href="https://github.com/haskell/haskell-language-server">haskell-language-server</a></li>
<li>JSON: <a href="https://github.com/hrsh7th/vscode-langservers-extracted">vscode-json-languageserver</a></li>
<li>Java: <a href="https://github.com/eclipse/eclipse.jdt.ls">Eclipse JDT Language Server</a></li>
<li>Javascript: <a href="https://github.com/theia-ide/typescript-language-server">TS &amp;amp; JS Language Server</a></li>
<li>Kotlin: <a href="https://github.com/fwcd/KotlinLanguageServer">kotlin-language-server</a></li>
<li>Lua: <a href="https://github.com/Alloyed/lua-lsp">lua-lsp</a></li>
<li>Markdown: <a href="https://github.com/artempyanykh/marksman">marksman</a></li>
<li>Mint: <a href="https://www.mint-lang.com/">mint-ls</a></li>
<li>Nix: <a href="https://github.com/nix-community/rnix-lsp">rnix-lsp</a></li>
<li>Ocaml: <a href="https://github.com/ocaml/ocaml-lsp/">ocaml-lsp</a></li>
<li>Perl: <a href="https://github.com/richterger/Perl-LanguageServer">Perl::LanguageServer</a></li>
<li>PHP: <a href="https://github.com/felixfbecker/php-language-server">php-language-server</a></li>
<li>PureScript: <a href="https://github.com/nwolverson/purescript-language-server">purescript-language-server</a></li>
<li>Python: <a href="https://github.com/python-lsp/python-lsp-server">pylsp</a>, <a href="https://github.com/palantir/python-language-server">pyls</a> <a href="https://github.com/microsoft/pyright">pyright</a>, o <a href="https://github.com/pappasam/jedi-language-server">jedi-language-server</a></li>
<li>R: <a href="https://cran.r-project.org/package=languageserver">languageserver</a></li>
<li>Racket: <a href="https://github.com/jeapostrophe/racket-langserver">racket-langserver</a></li>
<li>Ruby: <a href="https://github.com/castwide/solargraph">solargraph</a></li>
<li>Rust: <a href="https://github.com/rust-analyzer/rust-analyzer">rust-analyzer</a></li>
<li>Scala: <a href="https://scalameta.org/metals/">metals</a></li>
<li>TeX/LaTeX: <a href="https://github.com/astoff/digestif">Digestif&lt;/a&gt; ot [[https://github.com/latex-lsp/texlab][texlab</a></li>
<li>VimScript: <a href="https://github.com/iamcco/vim-language-server">vim-language-server</a></li>
<li>YAML: <a href="https://github.com/redhat-developer/yaml-language-server">yaml-language-server</a></li>
<li>Zig: <a href="https://github.com/zigtools/zls">zls</a></li>
</ul>

<p>
Con estos lenguajes no hace falta hacer nada más que lanzar <code>eglot</code> en
el modo correspondiente (y tener instalado el servidor externo, claro).
</p>

<p>
Por ejemplo, para configurar el modo de <i>Python</i>, como vimos antes,
podemos utilizar sólamente el <code>hook</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-hook 'python-mode 'eglot-ensure)
</pre>
</div>
</div>
</div>
<div id="outline-container-org1efa83a" class="outline-2">
<h2 id="org1efa83a">Características</h2>
<div class="outline-text-2" id="text-org1efa83a">
<ul class="org-ul">
<li>Documentación en el punto: cuando el cursor se encuentra sobre un
identificador se muestra información del mismo en el <code>mini-buffer</code>,
para ello utiliza el paquete <code>eldoc</code>. Si además tenemos instalado el
paquete <code>markdown-mode</code> nos mostrará dicha documentación con
negritas, cursivas y demás. Si no te acostumbras a que la
información se muestre en el <code>mini-buffer</code> y quieres que lo muestre
en un desplegable, puedes descargarte el paquete <code>eldoc-box</code> y
configurarlo para que muestre la información junto al cursos o
arriba a la izquierda o arriba a la derecha.</li>
<li>Comprobación al vuelo de errores: En este caso utiliza el paquete
<code>flymake</code>. Es decir, la comprobación de errores la hace este paquete
y no <code>eglot</code>.</li>
<li>Buscar definiciones o implementación del código: En este caso
utiliza el paquete <code>xref</code>. Si lo tienes bien configurado basta con
pulsar <code>M-.</code> para ir a la definición y <code>M-,</code> para regresar al punto
anterior. Como ocurre con las características anteriores, es <code>xref</code>
quien hace el trabajo.</li>
<li>Navegar por el fichero por los nombres de función, de clase, de
métodos, etc. lo realiza con el paquete <code>imenu</code>. En mi caso, está
configurado en <code>M-p i</code>, muestra la lista en el <code>mini-buffer</code> y
permite saltar rápidamente entre funciones, clases, métodos... no
sólo eso. También lo tengo activado en <code>org-mode</code> y me permite
saltar entre las cabeceras del documento de una manera bastante
cómoda.</li>
<li><i>Completion</i>. En este caso <code>eglot</code> utiliza el paquete de <i>Emacs</i>,
<i>Symbol Completion</i>, que es la versión de completado mediante
<i>buffer</i> que viene por defecto con el editor. Pero si encuentra
instalado algún tipo de paquete de completado como <code>company-mode</code>,
lo utilizará para mostrar la lista de alternativas, en lugar del
otro paquete más básico.</li>
<li>Para insertar plantillas de código utiliza <code>yasnippet</code>. En mi caso
además tengo instalado <code>ivy-yasnippet</code> que le proporciona más
interactividad a la hora de seleccionar el <i>snippet</i> que quieres
cargar.</li>
<li>Para gestión de proyectos utiliza el paquete <i>built-in</i> <code>project</code>.</li>
</ul>

<p>
Muchos de estos paquetes son internos y básicos para la programación,
algunos no los he traído al <i>blog</i>, pero sobre otros ya he hablado
aquí.
</p>

<p>
De todas las funciones o comandos que he estado mirando y probando con
<code>eglot</code> sólo no he encontrado alguna función ya instalada para el
comando <code>eglot-rename</code>, que renombra la variable o función en todos
los archivos del proyecto que se gestionen con el servidor <i>LSP</i>. Lo
más parecido que tengo instalado y utilizo habitualmente es el paquete
<code>iedit</code> o <i>cursor múltiple</i>, que modifica el nombre en todas las
apariciones de un archivo. Supongo que para esta función se podría
utilizar el paquete <code>emr</code>, el <i>Emacs refactoring system</i>, que no tengo
instalado, pero sí ganas de probarlo.
</p>
</div>
</div>
<div id="outline-container-org1e76e1c" class="outline-2">
<h2 id="org1e76e1c">Conclusiones</h2>
<div class="outline-text-2" id="text-org1e76e1c">
<p>
He intentado también configurar un servidor que no viniera en la lista
de los configurados por defecto. Elegí el <code>alive-lsp</code> para <i>Common
Lisp</i>, pero he sido incapaz. Tampoco lo pude configurar para <i>Kate</i>,
otro editor que soporta <i>LSP</i>. También puedes observar que hay un
puñado de paquetes <code>lsp-[lenguaje]</code> para configurar otros servidores
que no vienen por defecto.
</p>

<p>
De momento, para mí, <i>Emacs</i> provee todas las herramientas necesarias
para programar sin necesidad de <i>LSP</i>. Los modos de <i>Emacs</i>, como
<code>slime</code> (para <i>Common Lisp</i>), <code>cider</code> (para <i>Clojure</i>), <code>geiser</code> (para
<i>Scheme</i>), <code>edts</code> (para <code>erlang</code>), <code>elpy</code> (para <i>Python</i>) son
suficientes para lo que hago yo y además me proporcionan ayuda con
<code>C-h i</code> en la mayoría de los casos.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Resumen de <i>Emacs polyGLOT</i>, <i>Emacs políglota</i> en inglés.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Language Server Protocol</i>. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/eglot/index.html">eglot</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[eglot]]></category>
  <link>https://notxor.nueva-actitud.org/2023/08/14/eglot-lsp-para-emacs.html</link>
  <pubDate>Mon, 14 Aug 2023 11:39:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Lisp y scheme embebidos]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-08-12</div>
<p>
Hablar de <i>Lisp</i> y de <i>Scheme</i> es hablar de dos dialectos del mismo
lenguaje. Un lenguaje que necesita media tarde para aprender su
sintaxis y media vida para aprender realmente a usarlo; aunque,
afortunadamente, rinde desde el minuto uno. En este artículo voy a
hablar de dos dialectos diseñados para ser <i>embebidos</i> en programas,
aplicaciones y sistemas más grandes. Si estás buscando un lenguaje
para dotar a tu sistema de mecanismos para programarle extensiones,
deberías valorar alguno de estos dialectos. Aplicaciones como <a href="https://es.wikipedia.org/wiki/AutoCAD">AutoCAD</a>
(<a href="https://es.wikipedia.org/wiki/Autolisp">AutoLisp</a>), Maxima y <i>Emacs</i> (<i>elisp</i>), Audacity (<i>Nyquist</i>), utilizan
versiones embebidas de <i>Lisp</i>, o también <i>GIMP</i> utiliza <i>Scheme</i> en su
sistema de <i>plug-ins</i>. Hablaré de un <i>Lisp</i> y de un <i>Scheme</i>, en
concreto, sobre <i>embeddable common-lisp</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, <code>ecl</code>, y sobre
<code>chibi-scheme</code><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.
</p>

<p>
Cuando hablo con algún programador sobre las virtudes de <i>Emacs</i>, pero
también sobre <i>Lisp</i>, es habitual que aparezca la crítica de <i>es un
sistema viejuno</i>, como algo negativo. Es cierto, lleva más de 40 años
funcionando, evolucionando y puliendo errores ¿eso es malo? Desde mi
punto de vista <i>Lisp</i>, en cualquiera de sus sabores, incluido <i>Emacs</i>
ha conseguido una gran estabilidad.
</p>

<p>
Muchas de mis herramientas del <i>día a día</i> las tengo hechas en
<i>elisp</i>, como <a href="https://codeberg.org/Notxor/notxor-blog">el código que sustenta este <i>blog</i> estático</a>. <i>Emacs</i> me
sirve para casi todo: escribir informes con <code>org-mode</code>, corregir
<i>tests</i> con herramientas propias, gestionar historias clínicas
cifradas, llevar la contabilidad junto con <i>Ledger-cli</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>, leer
los <i>blogs</i> que me mantienen informado mediante <i>RSS</i>. Para algunas
pocas herramientas independientes he utilizado varios lenguajes
independientes, pero últimamente estoy moviendo la mayoría a
<i>common-lisp</i>, concretamente <code>sbcl</code>.
</p>
<div id="outline-container-org40955e8" class="outline-2">
<h2 id="org40955e8">Diferencias entre Common-Lisp y Scheme</h2>
<div class="outline-text-2" id="text-org40955e8">
<p>
Siendo dos dialectos de <i>Lisp</i> no se entienden entre ellos, de hecho
las podríamos considerar también como <i>familias</i> de sistemas <i>Lisp</i>.
Por un lado la familia <i>common</i> y por otro la familia <i>scheme</i>.  En el
documento ANSI INCITS 226-1994 (R2004) está descrito el lenguaje
<code>common-lisp</code>, aunque también existen varios dialectos <i>Lisp</i> que no
se ajustan a ese estándar, como el <code>elisp</code> de <i>Emacs</i>, por ejemplo.
</p>

<p>
Tradicionalmente se dice que <i>CL</i> es un <i>Lisp-2</i> mientras que <i>Scheme</i>
es un <i>Lisp-1</i>. Eso quiere decir que <i>CL</i> tiene dos listas de
definiciones, una para funciones y otra para variables. Por tanto en
<i>Lisp</i> se utilizan macros como <code>defun</code>, para definir las funciones y
<code>defvar</code>, o <code>defparameter</code>, para definir variables. Además, en <i>Lisp</i>
las expresiones no son <i>case-sensitive</i>, toda expresión se traduce
internamente a mayúsculas. Así ocurre, que mientras en <i>Scheme</i>
podemos hacer:
</p>

<pre class="example" id="org16de5f2">
~ &gt; chibi-scheme
&gt; (define x 1)
&gt; (define X 12)
&gt; x
1
&gt; X
12
&gt;
</pre>

<p>
En <i>CL</i> esto no ocurre:
</p>

<pre class="example" id="orgf370b9e">
~ &gt; ecl
ECL (Embeddable Common-Lisp) 21.2.1 (git:UNKNOWN)
Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya
Copyright (C) 1993 Giuseppe Attardi
Copyright (C) 2013 Juan J. Garcia-Ripoll
Copyright (C) 2018 Daniel Kochmanski
Copyright (C) 2021 Daniel Kochmanski and Marius Gerbershagen
ECL is free software, and you are welcome to redistribute it
under certain conditions; see file 'Copyright' for details.
Type :h for Help.  
Top level in: #&lt;process TOP-LEVEL 0x65bf80&gt;.
&gt; (defvar x 1)

X
&gt; (defvar X 12)

X
&gt; x

1
&gt; X

1
&gt; 
</pre>

<p>
Por otro lado <i>CL</i> es un estándar prolijo e incluye, entre otras
muchas cosas y detalles, la descripción de <i>CLOS</i> (<i>Common Lisp Object
System</i>) que le permite a <i>CL</i> soportar la programación orientada a
objetos.
</p>

<p>
Por el contrario, <i>Scheme</i> parte de una descripción minimalista cuyo
objetivo no es acumular funcionalidades sino evitar las debilidades
que las hacen necesarias. Esto hace que escribir un compilador o
intérprete de <i>Scheme</i> sea más sencillo que uno de <i>CL</i>, pero
dificulta la estandarización. Sin embargo, no está dejada de la mano
la estandarización y para evitar el descontrol se establecieron las
<i>SRFI</i><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>, que vienen a poner un poco de <i>estándar</i> entre todos los
<i>scheme</i>.
</p>

<p>
Como punto negativo extra, en <i>Scheme</i> es menos intuitivo el uso de
las macros y me obliga a que me fije mejor en lo que estoy haciendo,
en comparación con <i>CL</i> donde las macros me facilitan a primera vista
qué es lo que se está definiendo.
</p>

<p>
Más allá de las características generales de las familias a los que
estas dos herramientas pertenecen, ambas permiten interaccionar con
código <i>C</i>. De hecho, permiten exportar nuestro programa a dicho
lenguaje y utilizar un compilador como <code>gcc</code> para generar un
ejecutable. También ambos traen las herramientas habituales en
sistemas <i>Lisp</i>: <i>REPL</i>, intérprete para <i>scripts</i>, compilador de
<i>byte-code</i>.
</p>
</div>
</div>
<div id="outline-container-org05d4792" class="outline-2">
<h2 id="org05d4792">embeddable common-lisp</h2>
<div class="outline-text-2" id="text-org05d4792">
<p>
En su web (<a href="https://ecl.common-lisp.dev/">https://ecl.common-lisp.dev/</a>) se puede descargar el código
fuente en un fichero <i>tar-ball</i>. Una vez descargado lo compilamos:
</p>

<div class="org-src-container">
<pre class="src src-bash">&gt; ./configure --prefix=/path/local/opt
&gt; make
&gt; make install
</pre>
</div>

<p>
El último comando, dependiendo de dónde quieras instalar la
aplicación, debe contar con los permisos de ejecución de <i>root</i> si
fuera necesario.
</p>

<p>
Para probar que todo funciona, he escrito el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">factorial</span> (x)
  (<span style="color: #ff79c6; font-weight: bold;">if</span> (= x 0)
      1
      (* x (factorial (- x 1)))))

(print (factorial 2000))
</pre>
</div>

<p>
La ejecución desde la línea de comandos:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; time ecl --load factorial.lisp --eval <span style="color: #f1fa8c;">"(quit)"</span>
;;; Loading <span style="color: #f1fa8c;">"/home/notxor/blog/borradores/factorial.lisp"</span>

331627509245063324117539338057632403828111720810578039457193543706038077905600822400273230859732592255402352941225834109258084817415293796131386633526343688905634058556163940605117252571870647856393544045405243957467037674108722970434684158343752431580877533645127487995436859247408032408946561507233250652797655757179671536718689359056112815871601717232657156110004214012420433842573712700175883547796899921283528996665853405579854903657366350133386550401172012152635488038268152152246920995206031564418565480675946497051552288205234899995726450814065536678969532101467622671332026831552205194494461618239275204026529722631502574752048296064750927394165856283531779574482876314596450373991327334177263608852490093506621610144459709412707821313732563831572302019949914958316470942774473870327985549674298608839376326824152478834387469595829257740574539837501585815468136294217949972399813599481016556563876034227312912250384709872909626622461971076605931550201895135583165357871492290916779049702247094611937607785165110684432255905648736266530377384650390788049524600712549402614566072254136302754913671583406097831074945282217490781347709693241556111339828051358600690594619965257310741177081519922564516778571458056602185654760952377463016679422488444485798349801548032620829890965857381751888619376692828279888453584639896594213952984465291092009103710046149449915828588050761867924946385180879874512891408019340074625920057098729578599643650655895612410231018690556060308783629110505601245908998383410799367902052076858669183477906558544700148692656924631933337612428097420067172846361939249698628468719993450393889367270487127172734561700354867477509102955523953547941107421913301356819541091941462766417542161587625262858089801222443890248677182054959415751991701271767571787495861619665931878855141835782092601482071777331735396034304969082070589958701381980813035590160762908388574561288217698136182483576739218303118414719133986892842344000779246691209766731651433494437473235636572048844478331854941693030124531676232745367879322847473824485092283139952509732505979127031047683601481191102229253372697693823670057565612400290576043852852902937606479533458179666123839605262549107186663869354766108455046198102084050635827676526589492393249519685954171672419329530683673495544004586359838161043059449826627530605423580755894108278880427825951089880635410567917950974017780688782869810219010900148352061688883720250310665922068601483649830532782088263536558043605686781284169217133047141176312175895777122637584753123517230990549829210134687304205898014418063875382664169897704237759406280877253702265426530580862379301422675821187143502918637636340300173251818262076039747369595202642632364145446851113427202150458383851010136941313034856221916631623892632765815355011276307825059969158824533457435437863683173730673296589355199694458236873508830278657700879749889992343555566240682834763784685183844973648873952475103224222110561201295829657191368108693825475764118886879346725191246192151144738836269591643672490071653428228152661247800463922544945170363723627940757784542091048305461656190622174286981602973324046520201992813854882681951007282869701070737500927666487502174775372742351508748246720274170031581122805896178122160747437947510950620938556674581252518376682157712807861499255876132352950422346387878954850885764466136290394127665978044202092281337987115900896264878942413210454925003566670632909441579372986743421470507213588932019580723064781498429522595589012754823971773325722910325760929790733299545056388362640474650245080809469116072632087494143973000704111418595530278827357654819182002449697761111346318195282761590964189790958117338627206088910432945244978535147014112442143055486089639578378347325323595763291438925288393986256273242862775563140463830389168421633113445636309571965978466338551492316196335675355138403425804162919837822266909521770153175338730284610841886554138329171951332117895728541662084823682817932512931237521541926970269703299477643823386483008871530373405666383868294088487730721762268849023084934661194260180272613802108005078215741006054848201347859578102770707780655512772540501674332396066253216415004808772403047611929032210154385353138685538486425570790795341176519571188683739880683895792743749683498142923292196309777090143936843655333359307820181312993455024206044563340578606962471961505603394899523321800434359967256623927196435402872055475012079854331970674797313126813523653744085662263206768837585132782896252333284341812977624697079543436003492343159239674763638912115285406657783646213911247447051255226342701239527018127045491648045932248108858674600952306793175967755581011679940005249806303763141344412269037034987355799916009259248075052485541568266281760815446308305406677412630124441864204108373119093130001154470560277773724378067188899770851056727276781247198832857695844217588895160467868204810010047816462358220838532488134270834079868486632162720208823308727819085378845469131556021728873121907393965209260229101477527080930865364979858554010577450279289814603688431821508637246216967872282169347370599286277112447690920902988320166830170273420259765671709863311216349502171264426827119650264054228231759630874475301847194095524263411498469508073390080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 
________________________________________________________
Executed<span style="color: #ff79c6; font-weight: bold;"> in</span>   65.03 millis    fish           external
   usr time   80.18 millis  454.00 micros   79.73 millis
   sys time   15.14 millis  194.00 micros   14.95 millis
</pre>
</div>

<p>
En otra ocasión <a href="https://notxor.nueva-actitud.org/2023/01/19/lisp-y-familia.html">ya hice algunas pruebas de ejecución</a> de diversos
intérpretes de <i>Lisp</i>, por eso añado los tiempos de ejecución.  Y con
ánimo de comparar, también he hecho una versión <i>tail-recursive</i>. Si
alguien tiene dudas de qué es eso, lo expliqué mejor en el <i>curso de
<code>elisp</code> para no programadores</i> en el artículo de <a href="https://notxor.nueva-actitud.org/2019/01/24/funciones-recursivas.html">funciones recursivas</a>,
especialmente porque en ese artículo se utiliza la función auxiliar
externa, mientras que en el siguiente código la función auxiliar es
interna y puede despistar un poco a los no habituales de <i>Lisp</i> al
utilizar la forma <code>labels</code> para definir una función.
</p>

<div class="org-src-container">
<pre class="src src-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">factorial</span> (x)
  (<span style="color: #ff79c6; font-weight: bold;">labels</span> ((itera (n total)
             (<span style="color: #ff79c6; font-weight: bold;">if</span> (= n 0)
                 total
                 (itera (- n 1) (* total n)))))
    (itera x 1)))

(print (factorial 2000))
</pre>
</div>

<p>
Llamada desde línea de comandos con <code>ecl</code>:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; time ecl --load factorial.lisp --eval <span style="color: #f1fa8c;">"(quit)"</span>
;;; Loading <span style="color: #f1fa8c;">"/home/notxor/blog/borradores/factorial.lisp"</span>

331627509245063324117539338057632403828111720810578039457193543706038077905600822400273230859732592255402352941225834109258084817415293796131386633526343688905634058556163940605117252571870647856393544045405243957467037674108722970434684158343752431580877533645127487995436859247408032408946561507233250652797655757179671536718689359056112815871601717232657156110004214012420433842573712700175883547796899921283528996665853405579854903657366350133386550401172012152635488038268152152246920995206031564418565480675946497051552288205234899995726450814065536678969532101467622671332026831552205194494461618239275204026529722631502574752048296064750927394165856283531779574482876314596450373991327334177263608852490093506621610144459709412707821313732563831572302019949914958316470942774473870327985549674298608839376326824152478834387469595829257740574539837501585815468136294217949972399813599481016556563876034227312912250384709872909626622461971076605931550201895135583165357871492290916779049702247094611937607785165110684432255905648736266530377384650390788049524600712549402614566072254136302754913671583406097831074945282217490781347709693241556111339828051358600690594619965257310741177081519922564516778571458056602185654760952377463016679422488444485798349801548032620829890965857381751888619376692828279888453584639896594213952984465291092009103710046149449915828588050761867924946385180879874512891408019340074625920057098729578599643650655895612410231018690556060308783629110505601245908998383410799367902052076858669183477906558544700148692656924631933337612428097420067172846361939249698628468719993450393889367270487127172734561700354867477509102955523953547941107421913301356819541091941462766417542161587625262858089801222443890248677182054959415751991701271767571787495861619665931878855141835782092601482071777331735396034304969082070589958701381980813035590160762908388574561288217698136182483576739218303118414719133986892842344000779246691209766731651433494437473235636572048844478331854941693030124531676232745367879322847473824485092283139952509732505979127031047683601481191102229253372697693823670057565612400290576043852852902937606479533458179666123839605262549107186663869354766108455046198102084050635827676526589492393249519685954171672419329530683673495544004586359838161043059449826627530605423580755894108278880427825951089880635410567917950974017780688782869810219010900148352061688883720250310665922068601483649830532782088263536558043605686781284169217133047141176312175895777122637584753123517230990549829210134687304205898014418063875382664169897704237759406280877253702265426530580862379301422675821187143502918637636340300173251818262076039747369595202642632364145446851113427202150458383851010136941313034856221916631623892632765815355011276307825059969158824533457435437863683173730673296589355199694458236873508830278657700879749889992343555566240682834763784685183844973648873952475103224222110561201295829657191368108693825475764118886879346725191246192151144738836269591643672490071653428228152661247800463922544945170363723627940757784542091048305461656190622174286981602973324046520201992813854882681951007282869701070737500927666487502174775372742351508748246720274170031581122805896178122160747437947510950620938556674581252518376682157712807861499255876132352950422346387878954850885764466136290394127665978044202092281337987115900896264878942413210454925003566670632909441579372986743421470507213588932019580723064781498429522595589012754823971773325722910325760929790733299545056388362640474650245080809469116072632087494143973000704111418595530278827357654819182002449697761111346318195282761590964189790958117338627206088910432945244978535147014112442143055486089639578378347325323595763291438925288393986256273242862775563140463830389168421633113445636309571965978466338551492316196335675355138403425804162919837822266909521770153175338730284610841886554138329171951332117895728541662084823682817932512931237521541926970269703299477643823386483008871530373405666383868294088487730721762268849023084934661194260180272613802108005078215741006054848201347859578102770707780655512772540501674332396066253216415004808772403047611929032210154385353138685538486425570790795341176519571188683739880683895792743749683498142923292196309777090143936843655333359307820181312993455024206044563340578606962471961505603394899523321800434359967256623927196435402872055475012079854331970674797313126813523653744085662263206768837585132782896252333284341812977624697079543436003492343159239674763638912115285406657783646213911247447051255226342701239527018127045491648045932248108858674600952306793175967755581011679940005249806303763141344412269037034987355799916009259248075052485541568266281760815446308305406677412630124441864204108373119093130001154470560277773724378067188899770851056727276781247198832857695844217588895160467868204810010047816462358220838532488134270834079868486632162720208823308727819085378845469131556021728873121907393965209260229101477527080930865364979858554010577450279289814603688431821508637246216967872282169347370599286277112447690920902988320166830170273420259765671709863311216349502171264426827119650264054228231759630874475301847194095524263411498469508073390080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 
________________________________________________________
Executed<span style="color: #ff79c6; font-weight: bold;"> in</span>   70.60 millis    fish           external
   usr time   67.38 millis  482.00 micros   66.90 millis
   sys time   18.84 millis  255.00 micros   18.58 millis
</pre>
</div>

<p>
Por comparar la eficiencia con otro <i>CL</i>, que utilizo habitualmente,
lo he ejecutado con <code>sbcl</code>. Llamada desde línea de comandos con
<code>sbcl</code>:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; time sbcl --script factorial.lisp

331627509245063324117539338057632403828111720810578039457193543706038077905600822400273230859732592255402352941225834109258084817415293796131386633526343688905634058556163940605117252571870647856393544045405243957467037674108722970434684158343752431580877533645127487995436859247408032408946561507233250652797655757179671536718689359056112815871601717232657156110004214012420433842573712700175883547796899921283528996665853405579854903657366350133386550401172012152635488038268152152246920995206031564418565480675946497051552288205234899995726450814065536678969532101467622671332026831552205194494461618239275204026529722631502574752048296064750927394165856283531779574482876314596450373991327334177263608852490093506621610144459709412707821313732563831572302019949914958316470942774473870327985549674298608839376326824152478834387469595829257740574539837501585815468136294217949972399813599481016556563876034227312912250384709872909626622461971076605931550201895135583165357871492290916779049702247094611937607785165110684432255905648736266530377384650390788049524600712549402614566072254136302754913671583406097831074945282217490781347709693241556111339828051358600690594619965257310741177081519922564516778571458056602185654760952377463016679422488444485798349801548032620829890965857381751888619376692828279888453584639896594213952984465291092009103710046149449915828588050761867924946385180879874512891408019340074625920057098729578599643650655895612410231018690556060308783629110505601245908998383410799367902052076858669183477906558544700148692656924631933337612428097420067172846361939249698628468719993450393889367270487127172734561700354867477509102955523953547941107421913301356819541091941462766417542161587625262858089801222443890248677182054959415751991701271767571787495861619665931878855141835782092601482071777331735396034304969082070589958701381980813035590160762908388574561288217698136182483576739218303118414719133986892842344000779246691209766731651433494437473235636572048844478331854941693030124531676232745367879322847473824485092283139952509732505979127031047683601481191102229253372697693823670057565612400290576043852852902937606479533458179666123839605262549107186663869354766108455046198102084050635827676526589492393249519685954171672419329530683673495544004586359838161043059449826627530605423580755894108278880427825951089880635410567917950974017780688782869810219010900148352061688883720250310665922068601483649830532782088263536558043605686781284169217133047141176312175895777122637584753123517230990549829210134687304205898014418063875382664169897704237759406280877253702265426530580862379301422675821187143502918637636340300173251818262076039747369595202642632364145446851113427202150458383851010136941313034856221916631623892632765815355011276307825059969158824533457435437863683173730673296589355199694458236873508830278657700879749889992343555566240682834763784685183844973648873952475103224222110561201295829657191368108693825475764118886879346725191246192151144738836269591643672490071653428228152661247800463922544945170363723627940757784542091048305461656190622174286981602973324046520201992813854882681951007282869701070737500927666487502174775372742351508748246720274170031581122805896178122160747437947510950620938556674581252518376682157712807861499255876132352950422346387878954850885764466136290394127665978044202092281337987115900896264878942413210454925003566670632909441579372986743421470507213588932019580723064781498429522595589012754823971773325722910325760929790733299545056388362640474650245080809469116072632087494143973000704111418595530278827357654819182002449697761111346318195282761590964189790958117338627206088910432945244978535147014112442143055486089639578378347325323595763291438925288393986256273242862775563140463830389168421633113445636309571965978466338551492316196335675355138403425804162919837822266909521770153175338730284610841886554138329171951332117895728541662084823682817932512931237521541926970269703299477643823386483008871530373405666383868294088487730721762268849023084934661194260180272613802108005078215741006054848201347859578102770707780655512772540501674332396066253216415004808772403047611929032210154385353138685538486425570790795341176519571188683739880683895792743749683498142923292196309777090143936843655333359307820181312993455024206044563340578606962471961505603394899523321800434359967256623927196435402872055475012079854331970674797313126813523653744085662263206768837585132782896252333284341812977624697079543436003492343159239674763638912115285406657783646213911247447051255226342701239527018127045491648045932248108858674600952306793175967755581011679940005249806303763141344412269037034987355799916009259248075052485541568266281760815446308305406677412630124441864204108373119093130001154470560277773724378067188899770851056727276781247198832857695844217588895160467868204810010047816462358220838532488134270834079868486632162720208823308727819085378845469131556021728873121907393965209260229101477527080930865364979858554010577450279289814603688431821508637246216967872282169347370599286277112447690920902988320166830170273420259765671709863311216349502171264426827119650264054228231759630874475301847194095524263411498469508073390080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 

________________________________________________________
Executed<span style="color: #ff79c6; font-weight: bold;"> in</span>   27.22 millis    fish           external
   usr time    0.00 millis    0.00 micros    0.00 millis
   sys time   16.03 millis  728.00 micros   15.30 millis
</pre>
</div>

<p>
La diferencia entre las dos ejecuciones es significativa, en torno a
una tercera parte de tiempo que <code>ecl</code>. La diferencia se la achaco no
solo a que <code>sbcl</code> sea, según se dice, el <i>CL</i> más rápido, también a
que durante la primera ejecución compila el script a <i>byte-code</i>. Las
siguientes llamadas reducen su tiempo de ejecución al ejecutar el
binario. Luego volveré un poco sobre esta explicación.
</p>
</div>
</div>
<div id="outline-container-org0839a9c" class="outline-2">
<h2 id="org0839a9c">chibi-scheme</h2>
<div class="outline-text-2" id="text-org0839a9c">
<p>
Éste lo bajé de su repositorio y lo compilé. Viene con un archivo
<code>configure</code> y yo piqué. Las instrucciones de compilación están en el
<code>README.md</code> y son muy sencillas:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; make --prefix=path/local/opt
&gt; make --prefix=path/local/opt install
</pre>
</div>

<p>
No me pidió ninguna dependencia ni dio ningún error, por lo que
supongo que mi sistema ya las cumplía todas. Para probarlo escribí el
código equivalente al anterior para <i>Scheme</i>.
</p>

<div class="org-src-container">
<pre class="src src-scheme">(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">factorial</span> x)
  (<span style="color: #ff79c6; font-weight: bold;">if</span> (= x 0)
      1
      (* x (factorial (- x 1)))))

(display (factorial 2000))
</pre>
</div>

<p>
También cabe utilizar <code>chibi-scheme</code> como lenguaje de <i>script</i>, para
eso hay que añadir un <i>shebang</i> al fichero <code>.scm</code> y, puesto que está
diseñado para ser minimalista, hay que <i>importar</i> las librerías
básicas. Sería algo así como:
</p>

<div class="org-src-container">
<pre class="src src-scheme">#!/home/notxor/opt/bin/chibi-scheme

(<span style="color: #ff79c6; font-weight: bold;">import</span> (scheme base) (chibi))
</pre>
</div>

<p>
Dándole permiso de ejecución al <i>script</i> lo podemos llamar
directamente. La instrucción <code>import</code> no es necesaria si lo llamamos
desde la línea de comandos. Me pareció que al ejecutar desde el
inicio con esos paquetes cargados, la siguiente forma de ejecutar el
código era ligeramente más rápida que la versión <i>script</i>:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #ff79c6; font-weight: bold;">time</span> chibi-scheme -q factorial.scm -p <span style="color: #f1fa8c;">"(factorial 2000)"</span>
</pre>
</div>

<p>
La opción <code>-q</code> carga el módulo de código y la opción <code>-p</code> evalúa y
muestra el resultado de una expresión. El código del módulo lo muestro
a continuación dejando como comentarios el <i>shebang</i> y la importación
de módulos sólo a modo de muestra. Como dije antes, utilizándolo de
esa otra manera, la carga de los módulos, me pareció que penaliza el
tiempo de ejecución total del <i>script</i>.
</p>

<div class="org-src-container">
<pre class="src src-scheme"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">#!/usr/local/bin/chibi-scheme
</span>
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">(import (scheme base) (chibi))
</span>
(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">factorial</span> x)
  (<span style="color: #ff79c6; font-weight: bold;">if</span> (= x 0)
      1
      (* x (factorial (- x 1)))))

(display (factorial 200))
</pre>
</div>

<p>
De la misma manera que hice una versión <i>tail-recursive</i> para <i>CL</i>,
la hice para <i>Scheme</i>:
</p>

<div class="org-src-container">
<pre class="src src-scheme">(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">factorial</span> x)
  (<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">itera</span> n total)
    (<span style="color: #ff79c6; font-weight: bold;">if</span> (= n 0)
        total
        (itera (- n 1) (* total n))))
  (itera x 1))

(display (factorial 2000))
</pre>
</div>

<p>
Veamos los resultados de las pruebas.
</p>
</div>
</div>
<div id="outline-container-org46141b9" class="outline-2">
<h2 id="org46141b9">Comparación de tiempos de ejecución</h2>
<div class="outline-text-2" id="text-org46141b9">
<p>
Utilizando ambas herramientas como <i>shell scripts</i> los tiempos medios
de ejecución obtenidos son:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Lenguaje</th>
<th scope="col" class="org-left">tiempo</th>
<th scope="col" class="org-left"><i>tail-recursive</i></th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>chibi-scheme</code></td>
<td class="org-left">74,46 ms</td>
<td class="org-left">79,90 ms</td>
</tr>

<tr>
<td class="org-left">" <i>script</i></td>
<td class="org-left">204,87 ms</td>
<td class="org-left">210,34 ms</td>
</tr>

<tr>
<td class="org-left"><code>ecl</code></td>
<td class="org-left">77,33 ms</td>
<td class="org-left">72,70 ms</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left"><code>guile</code><sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup></td>
<td class="org-left">17,48 ms</td>
<td class="org-left">18,45 ms</td>
</tr>

<tr>
<td class="org-left"><code>sbcl</code><sup><a id="fnr.5.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup></td>
<td class="org-left">28,82 ms</td>
<td class="org-left">27,80 ms</td>
</tr>
</tbody>
</table>

<p>
¿Por qué son tan rápidos <code>guile</code> y <code>sbcl</code>? En realidad, tanto el
<i>scheme</i> como el <i>clisp</i> son tan rápidos porque durante la primera
ejecución generan <i>byte-code</i> que acelera las posteriores ejecuciones.
Si eliminas el fichero compilado, en cada ejecución, los tiempos no
muestran una mejora tan radical en comparación a sus primos
embebibles.
</p>

<p>
Por otro lado vemos que la versión recursiva pura, en general, es
ligeramente más rápida que la versión <i>tail-recursive</i>. Por
contrapartida, la versión recursiva necesita más memoria porque tiene
que <i>desenrollar la madeja</i> de la recursión para volver a enrollarla
después. La versión <i>tail-recursive</i> gasta más tiempo en llamadas
entre funciones pero el gasto de memoria es mínimo. Sabiendo esto,
podemos elegir una función u otra dependiendo de las necesidades de
nuestro sistema. En resumen, hay que tener cuidado con las iteraciones
puras, con especial atención a los datos que se iteran, porque es
posible que ocupen más memoria de la que nos podemos permitir, sobre
todo si escasea y nuestra iteración se hace sobre listas enormes.
</p>
</div>
</div>
<div id="outline-container-orgf6ab222" class="outline-2">
<h2 id="orgf6ab222">Conclusiones</h2>
<div class="outline-text-2" id="text-orgf6ab222">
<p>
Tanto <code>chibi-scheme</code> como <code>ecl</code> me han parecido unas magníficas
herramientas, especialmente la segunda, pues no hay muchos <i>CL</i> que
puedan utilizarse de manera embebida en aplicaciones, mientras
<i>Scheme</i> hay varios que pueden utilizarse de ese modo.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://ecl.common-lisp.dev/">https://ecl.common-lisp.dev/</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://github.com/ashinn/chibi-scheme">https://github.com/ashinn/chibi-scheme</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://notxor.nueva-actitud.org/2018/10/30/ledger-cli-y-el-ledger-mode-de-emacs.html">https://notxor.nueva-actitud.org/2018/10/30/ledger-cli-y-el-ledger-mode-de-emacs.html</a> 
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Scheme Requests for Implementation</i>. En el caso de
<code>chibi-scheme</code>, reconoce estos estándares: <a href="https://synthcode.com/scheme/chibi/#h2_StandardModules">https://synthcode.com/scheme/chibi/#h2_StandardModules</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Tiempo de ejecución por la generación de <i>byte-code</i> intermedio
la primera ejecución. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/lisp/index.html">lisp</a> <a href="/tags/scheme/index.html">scheme</a> ]]></description>
  <category><![CDATA[lisp]]></category>
  <category><![CDATA[scheme]]></category>
  <link>https://notxor.nueva-actitud.org/2023/08/12/lisp-y-scheme-embebidos.html</link>
  <pubDate>Sat, 12 Aug 2023 10:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Compilar Emacs desde el código fuente]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-08-05</div>
<p>
Como la mayoría sabéis, he estado utilizando el mejor editor de código
del mundo, durante bastante tiempo<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> y lo seguiré haciendo durante
mucho tiempo más, aunque la única ventaja que le quede en el futuro,
sea el impagable ejercicio (fisio)terapéutico para prevenir la
artrosis en mis manos y dedos.  ¿De qué vengo a hablar hoy? Pues hay
quien me ha preguntado <i>qué sabor uso</i>: <i>doomemacs</i>, <i>spacemacs</i> o
<i>vanilla</i>. Mi respuesta es siempre que la mejor configuración para ti,
te la haces tú mismo.
</p>

<p>
Mi archivo de configuración está accesible en <a href="https://codeberg.org/Notxor/init-emacs">un repositorio de
codeberg</a>, ya he hablado de ello en el <i>blog</i>. Utilizo, como versión
de trabajo, el paquete de <i>Emacs</i> que proporciona la <i>distro</i> que
utilizo (<i>OpenSuse Tumbleweed</i>). A día de hoy ya tiene el paquete
actualizado a la versión 29.1. Pero si utilizas otras distribuciones
de GNU/Linux y no se actualiza el paquete con tanta rapidez, tienes la
opción de compilarlo tú mismo. Este artículo cuenta cómo en dos
sencillos pasos: descargar y compilar.
</p>
<div id="outline-container-org6302353" class="outline-2">
<h2 id="org6302353">Descargar</h2>
<div class="outline-text-2" id="text-org6302353">
<p>
Descargar fuentes de versiones antiguas puede hacerse desde el <code>ftp</code>
de <i>GNU</i>:
</p>

<p>
<a href="https://ftp.gnu.org/gnu/emacs/">https://ftp.gnu.org/gnu/emacs/</a>
</p>

<p>
La última versión que podemos encontrar a día de hoy es la <code>29.1</code> con
fecha de 30 de julio de 2023. Éste paquete es el más recomendable si
quieres un ejecutable más estable. Los pasos de compilación son los
mismos, exceptuando que la versión empaquetada ya viene con su
correspondiente archivo <code>configure</code>, mientras que en la versión del
repositorio (<code>emacs 30.0.50</code>) debes generarlo tú lanzando
<code>autogen.sh</code>.
</p>

<p>
El <i>repositorio</i> de <i>Emacs</i> se encuentra en
<a href="https://savannah.gnu.org/projects/emacs">https://savannah.gnu.org/projects/emacs</a>. Ahí mismo se puede encontrar
cómo descargar los archivos fuentes del programa:
</p>

<div class="org-src-container">
<pre class="src src-shell">git clone -b master git://git.sv.gnu.org/emacs.git
</pre>
</div>
</div>
</div>
<div id="outline-container-org495ce8c" class="outline-2">
<h2 id="org495ce8c">Compilar</h2>
<div class="outline-text-2" id="text-org495ce8c">
<p>
Hay que estar atento a las dependencias y a lo que tienes instalado.
Algunas de dichas dependencias son bloqueantes. Es decir, si no se
satisfacen lanzan un error e informan sobre falta de algún paquete y
que es obligatorio cumplir con la dependencia o especificar que el
ejecutable no soporte esa determinada característica desde la
configuración.
</p>

<p>
En otros casos, como pueden ser las capacidades gráficas, o por
ejemplo, también, en el soporte para <i>XML</i>, etc., el sistema no avisa
de que determinada librería (o el paquete de desarrollo) no se
encuentra, sencillamente se generará un ejecutable sin soporte para
ello. El editor funcionará, pero no podrás visualizar algún tipo de
fichero, bien gráfico o <code>.xml</code> o de tipos de fuentes o de cualquier
otra característica.
</p>

<p>
De primeras, necesitas tener instalado <code>autoconf</code> y las cabeceras de
<code>GTK</code>. En mi caso, en <i>OpenSuse Tumbleweed</i>, el paquete
<code>gtk3-devel</code>. Se puede compilar para que sólo funcione en consola,
pero no lo recomiendo.  Hay que echarle un ojo a cómo configurar la
compilación para ajustarla a nuestras necesidades, incluyendo la
posibilidad de deshabilitar la mayoría de funcionalidades para dejar
el editor sólo, en un ejecutable compacto y sin la mayoría de
dependencias.
</p>

<p>
Si has descargado el código del repositorio de desarrollo, antes de la
configuración debes utilizar <code>autogen.sh</code> para que genere el archivo
de configuración. Si has descargado un paquete de versión del <code>ftp</code>,
ya viene con el <code>configure</code> preparado.
</p>

<div class="org-src-container">
<pre class="src src-shell">./autogen.sh
./configure --help
</pre>
</div>

<p>
La compilación desde el repositorio la he hecho a un directorio local
de mi usuario para no machacar los ejecutables de la <i>distro</i>, que son
los que utilizo principalmente. Dejando la versión compilada para
hacer pruebas.
</p>

<div class="org-src-container">
<pre class="src src-shell">./configure --prefix=/home/notxor/opt
</pre>
</div>

<p>
Tarda un rato en comprobar todas las dependencias. Si ocurre algún
error es porque te faltará instalar alguna de ellas o, al menos,
faltan las cabeceras de desarrollo. Los paquetes de desarrollo suelen
encontrarse con el añadido <code>dev</code> o <code>devel</code> (según la distribución que
estés utilizando) y al instalarla desaparecerá el error. Otra opción,
si no se quiere instalar la dependencia, es compilar <i>Emacs</i> si esa
característica. Para ello, se puede desactivar desde el mismo
<code>configure</code> con la opción <code>--withow-OPCION</code> o <code>--with-OPCION=no</code>.
</p>

<p>
Si no hay errores de configuración, la compilación es sencilla:
</p>

<div class="org-src-container">
<pre class="src src-shell">make
make install
</pre>
</div>

<p>
Después de un rato de generar los binarios e instalarlos, lo único que
te falta es crearte un enlace de algún tipo para lanzar el nuevo
ejecutable. Para esto, hay quien se pone un icono en el escritorio o
quien se hace un <i>script</i> de lanzamiento (o las dos cosas).
</p>
</div>
</div>
<div id="outline-container-orgd5e16ab" class="outline-2">
<h2 id="orgd5e16ab">Conclusión</h2>
<div class="outline-text-2" id="text-orgd5e16ab">
<p>
Es <i>Emacs</i> en estado salvaje: funcionar, lo que se dice funcionar,
funciona, pero no puedes estar seguro de que no fallará o se producirá
un error. Por tanto, es recomendable no utilizarlo como único editor:
recuerda al compilar, hacerlo en un sitio donde no machaques la
versión estable. Puesto que es una versión de desarrollo puede
contener errores y sería conveniente utilizarla sólo para trastear y
cotillear el código fuente, o para hacernos de cero o ajustar algún
paquete que necesitemos.
</p>

<p>
Es tan sencillo como parece.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Si no estás de acuerdo con esta afirmación es que no lo has
probado lo suficiente para ser consciente de lo que es capaz. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2023/08/05/compilar-emacs-desde-el-codigo-fuente.html</link>
  <pubDate>Sat, 05 Aug 2023 09:26:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Edición y exportación desde org-mode a html]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-07-12</div>
<p>
Hay veces que tengo que consultar mi propio <i>blog</i> para recordar cómo
hacer algo y en este <span id="nota">artículo<span class="nota">me niego a llamarlo <i>post</i>. Estoy desanglificando mi forma de hablar —y escribir—.</span></span>
voy a contar una de esas veces. La historia no es de ahora, llevo
algunos meses pensando en dedicar un poco de mi tiempo a editar libros
para poder leerlos tranquilamente con mi lector. Generar <i>epubs</i> de
calidad es bastante complejo, sobre todo porque no todos los lectores
cargan los archivos igual y el <code>html+css</code> que utilizan está, en
algunos casos, muy limitado.
</p>

<p>
Ya hice en su día una edición de <i>«La mastro de l' ringoj»</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> en
<code>epub</code>. Se lee bien en las aplicaciones de lectura de la <i>tablet</i>, se
leía bien en mi antiguo lector, pero éste se estropeó y al cargar el
libro en uno viejo que ya no utilizábamos y andaba dando vueltas por
casa, pues me di cuenta de cuántos errores de edición había
cometido. No sólo de edición, sino de corrección, ortografía y un
montón de detalles.
</p>

<p>
Tenía aún los archivos <code>pdf</code> de los que partí y me decidí a hacer una
buena edición. Por tanto, parto de la misma base y, esta vez, espero
hacer un mejor trabajo, poniendo más atención a los detalles. Pero
primero veamos qué inconvenientes me voy a encontrar:
</p>

<ol class="org-ol">
<li>Los archivos <code>pdf</code> de los que parto están compuestos de imágenes
escaneadas directamente desde el libro físico, página a página. Es
decir, cada página del archivo es la imagen de una página escaneada
del libro físico.</li>
<li>Las fuentes que más se ajustan a este proyecto —sobre todo las más
vistosas para emplearlas en títulos y funciones decorativas—, no
soportan las <i>«ĉapelitaj literoj»</i> del Esperanto.</li>
<li><i>Sigil</i>, el programa de edición de archivos <code>epub</code> viene sin
diccionario para Esperanto.</li>
</ol>

<p>
Menciono esos tres, pero seguro que me voy a encontrar más. Al menos,
estos tres los tengo identificados y puedo hacer algo al respecto.
Para empezar, en lugar de lanzarme directamente con la edición del
<code>epub</code>, esta vez, voy a hacer un paso intermedio. Voy a generar el
contenido en un remedo de libro <i>web</i>, que me permita navegarlo y
comprobar errores. Para todo el proyecto utilizaré <i>Emacs</i> y
<code>org-mode</code>.
</p>
<div id="outline-container-org1463552" class="outline-2">
<h2 id="org1463552">Publicar html desde org-mode</h2>
<div class="outline-text-2" id="text-org1463552">
<p>
Hace algunos meses ya comenté cómo, pero hacía tanto tiempo que no lo
utilizaba que tuve que repasármelo antes de acometer este
proyecto. Como <a href="https://notxor.nueva-actitud.org/2021/01/13/publicar-html-con-org-mode.html">ya lo conté en otro artículo</a> no voy a extenderme mucho
en cómo hacerlo y me centraré en qué hago.
</p>
</div>
<div id="outline-container-orgb8bf3ad" class="outline-3">
<h3 id="orgb8bf3ad">Estructura de directorios</h3>
<div class="outline-text-3" id="text-orgb8bf3ad">
<pre class="example" id="org6aab65d">
.
├── du-turegoj
│   └── ( ... ) Equivalente a kunularo
├── kunularo
│   ├── html
│   │   └── ( ... ) Directorio espejo del org pero con los archivos html
│   ├── kunularo.el
│   └── org
│       ├── antauparolo-dua.org
│       ├── chapitro01.org
│       ├── ( ... )
│       ├── compartido
│       │   ├── css
│       │   │   ├── estilos.css
│       │   │   ├── style.css
│       │   │   └── style-rust.css
│       │   ├── fonts
│       │   │   ├── AngerthasMoria.ttf
│       │   │   ├── P052_Roman.ttf
│       │   │   ├── RingbearerMedium.ttf
│       │   │   ├── TengwarAnnatar.ttf
│       │   │   └── Hobbitonbrush.ttf
│       │   └── imagenes
│       │       ├── firma-metal.svg
│       │       ├── firma-negro.svg
│       │       ├── firma.svg
│       │       ├── kunularo-ringo.svg
│       │       ├── mapo-mez-tero.svg
│       │       ├── mastro-ringoj.svg
│       │       ├── portada-kunularo.svg
│       │       ├── provinca-mapo.svg
│       │       ├── provinca-mapo-vektoro.svg
│       │       ├── runoj_2.svg
│       │       └── runoj.svg
│       ├──  ( ... ) Más archivos .org
│       └── unua-libro.org
├── plantilla.org
├── plantillas
│   ├── du-turegoj.org
│   ├── kunularo.org
│   └── reveno-rego.org
├── procesar-ocr.el
├── reveno-rego
│   └── ( ... ) Equivalente a kunularo
├── Tolkien-la-du-turegoj.pdf
├── Tolkien-la-kunularo-de-la-ringoj.pdf
└── Tolkien-la-reveno-de-la-regxo.pdf
</pre>

<p>
Es una estructura un poco compleja, dado que hay tres libros y voy a
hacerlos uno a uno, empezando por el primero <i>La kunularo de l'
Ringo</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.
</p>

<p>
Otro de los inconvenientes que me encontré es la poca calidad que en
la edición original se puso en las imágenes. Mi solución es
vectorizarlo todo y rehacer, dentro de mis posibilidades. Por ejemplo,
el mapa de <i>«La Provinco»</i> tiene unos <i>píxeles</i> del tamaño de una
piscina olímpica.
</p>


<figure id="orgc29f07e">
<img src="./imagenes/provinca-mapo.png" alt="provinca-mapo.png">

</figure>

<p>
Mi solución es vectorizarlo en una imagen <code>svg</code>:
</p>


<figure id="orgf20fa78">
<img src="./imagenes/provinca-mapo-vektoro.svg" alt="provinca-mapo-vektoro.svg" class="org-svg">

</figure>

<p>
Además de las imágenes, he vectorizado otros elementos y me permite
montar algunas páginas de referencia, como la de <i>«La Unua
Libro»</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>. El texto completo del archivo <code>unua-libro.org</code> es el
siguiente:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #6272a4;">#+setupfile: ../../plantillas/kunularo.org</span>

<span style="color: #6272a4;">#+include: ./indice.org</span>

<span style="color: #6272a4;">#+attr_html: :class nav</span>
<span style="color: #bd93f9;">| </span><span style="color: #8be9fd; text-decoration: underline;"><a href="./provincaj-analoj.org">&#8592;</a></span><span style="color: #bd93f9;"> | </span><span style="color: #8be9fd; text-decoration: underline;"><a href="./mapo-provinco.org">&#8594;</a></span><span style="color: #bd93f9;"> |</span><span style="color: #bd93f9;">
</span>
<span style="color: #8be9fd; text-decoration: underline;"><a href="./compartido/imagenes/runoj.svg">./compartido/imagenes/runoj.svg</a></span>

<span style="color: #6272a4;">#+attr_html: :class sello</span>
<span style="color: #8be9fd; text-decoration: underline;"><a href="./compartido/imagenes/firma-negro.svg">./compartido/imagenes/firma-negro.svg</a></span>

<span style="color: #6272a4;">#+attr_html: :class pag-tit-libro</span>
La Unua Libro

<span style="color: #8be9fd; text-decoration: underline;"><a href="./compartido/imagenes/runoj_2.svg">./compartido/imagenes/runoj_2.svg</a></span>

<span style="color: #6272a4;">#+attr_html: :class nav</span>
<span style="color: #bd93f9;">| </span><span style="color: #8be9fd; text-decoration: underline;"><a href="./provincaj-analoj.org">&#8592;</a></span><span style="color: #bd93f9;"> | </span><span style="color: #8be9fd; text-decoration: underline;"><a href="./mapo-provinco.org">&#8594;</a></span><span style="color: #bd93f9;"> |</span>
</pre>
</div>

<p>
La visualización de dicho archivo es esta:
</p>


<figure id="org39b82a0">
<img src="./imagenes/Captura_pagina.png" alt="Captura_pagina.png">

</figure>

<p>
Si empezamos por el principio, lo primero que hace este archivo es
establecer como <code>setupfile</code> el <code>kunularo.org</code>, que es una plantilla
que configura todos los archivos que componen el primero de los libros
que estoy editando. Su contenido es bastante sencillo, pero lo
explico en <a href="#setupfile">el siguiente apartado de <code>setupfile</code></a>.
</p>

<p>
La segunda línea lo que hace es importar un archivo que contiene el
índice o <i>tabla de contenidos</i> del libro. No se ha puesto en la
plantilla, porque no todas las páginas lo importarán y, por tanto,
sólo debe hacerse en aquellas páginas que sí necesiten el índice a la
izquierda.
</p>

<p>
Lo siguiente que aparece es un bloque que facilita la navegación del
libro hacia adelante y hacia atrás añadiendo una tabla con los
caracteres <code>←</code> y <code>→</code> para mostrar el archivo precedente o posterior al
actual. La macro <code>#+attr_html: :class nav</code> lo que hace es añadir al
elemento una propiedad o atributo <code>html</code> que es <code>class="nav"</code> dentro
de la etiqueta <code>&lt;table&gt;</code>. Esa clase está definida en un archivo <code>css</code>
que importa el <code>setupfile</code>. ¡Pero vamos a ver qué hace este archivo!
</p>
</div>
</div>
<div id="outline-container-setupfile" class="outline-3">
<h3 id="setupfile"><code>setupfile</code></h3>
<div class="outline-text-3" id="text-setupfile">
<p>
 <code>kunularo.org</code>, es una plantilla que configura todos los archivos que
componen el primero de los libros que estoy editando. Su contenido es
bastante sencillo, pero aún así tendrás que soportar que lo explique:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #6272a4;">#+author:</span>   <span style="color: #0189cc;">J. R. R. Tolkien
</span><span style="color: #6272a4;">#+title:</span>    <span style="color: #ffb86c; font-size: 144%; font-weight: bold;">La kunularo de l' ringo
</span><span style="color: #6272a4;">#+date:</span>     <span style="color: #0189cc;">&lt;2023-06-08&gt;
</span><span style="color: #6272a4;">#+options:  ':t *:t -:t ::t &lt;:t H:3 \n:nil ^:t arch:headline author:t c:nil</span>
<span style="color: #6272a4;">#+options:  creator:comment d:(not LOGBOOK) date:t e:t email:nil f:t inline:t</span>
<span style="color: #6272a4;">#+options:  num:nil p:nil pri:nil stat:t tags:t tasks:t tex:t timestamp:t toc:nil</span>
<span style="color: #6272a4;">#+options:  html-style:nil html-postamble:auto html-postamble:t</span>
<span style="color: #6272a4;">#+macro:    letra @@html:&lt;span class="$1"&gt;$2&lt;/span&gt;@@</span>
<span style="color: #6272a4;">#+language: eo</span>

<span style="color: #6272a4;">#+exclude_tags: noexport</span>
<span style="color: #6272a4;">#+select_tags:  export</span>

<span style="color: #6272a4;">#+html_container: div</span>
<span style="color: #6272a4;">#+html_doctype: xhtml-strict</span>
<span style="color: #6272a4;">#+html_head: &lt;link rel="stylesheet" type="text/css" href="compartido/css/style.css" /&gt;</span>
<span style="color: #6272a4;">#+html_head: &lt;link rel="stylesheet" type="text/css" href="compartido/css/style-rust.css" /&gt;</span>
<span style="color: #6272a4;">#+html_head: &lt;link rel="stylesheet" type="text/css" href="compartido/css/estilos.css" /&gt;</span>
</pre>
</div>

<p>
De este archivo, las primeras líneas son evidentes, son el autor, el
título y la fechas, creo que se entienden perfectamente.  Más
complejas y, quizá, más difíciles de entender para quien llega nuevo a
<code>org-mode</code>, son las líneas de <code>#+options:</code>. Para explicarlas un poco
quizá venga bien repasar <a href="https://notxor.nueva-actitud.org/2021/03/03/publicar-con-org-mode.html#org8147348">algún artículo donde lo cuento más
detenidamente</a>. Como añadido está la opción <code>html-style:nil</code>, que lo
que hace es evitar que <code>org-mode</code> añada en la cabecera
(<code>&lt;head&gt;...&lt;/head&gt;</code>) una etiqueta <code>style</code>, porque al final del
archivo, vamos a importar los estilos que necesita en forma de
archivos <code>css</code>.
</p>

<p>
Quizá sea más curiosa o digna de explicar la línea de <code>#+macro:</code>. En
este <i>blog</i> también podéis encontrar de manera más detallada <a href="https://notxor.nueva-actitud.org/2022/11/25/macros-en-org-mode.html">cómo se
manejan las macros</a> en <code>org-mode</code>. Pero para que no andes saltando a
otros artículos, si no quieres, una <i>macro</i> lo que hace es generar
texto que se exportará directamente del <code>org</code> al <code>html</code>. En este
ejemplo, el texto:
</p>

<div class="org-src-container">
<pre class="src src-org">(...)
anta&#365;pordo de Bilbo la maljunulo komencis mal&#349;ar&#285;i: trovi&#285;is grandaj
faskoj da artfajra&#309;oj &#265;iuspecaj kaj &#265;iuformaj, unuope etikeditaj
per granda ru&#285;a <span style="color: #deb887;">{{{letra(tengwar,x)}}}</span> kaj la elf-runo <span style="color: #deb887;">{{{letra(runas,G)}}}</span>.
</pre>
</div>

<p>
Se convierte en el <code>html</code>:
</p>

<div class="org-src-container">
<pre class="src src-html">&lt;<span style="color: #50fa7b; font-weight: bold;">p</span>&gt;
(...)
anta&#365;pordo de Bilbo la maljunulo komencis mal&#349;ar&#285;i: trovi&#285;is grandaj
faskoj da artfajra&#309;oj &#265;iuspecaj kaj &#265;iuformaj, unuope etikeditaj
per granda ru&#285;a &lt;<span style="color: #50fa7b; font-weight: bold;">span</span> <span style="color: #f8f8f2; font-weight: bold;">class</span>=<span style="color: #f1fa8c;">"tengwar"</span>&gt;x&lt;/<span style="color: #50fa7b; font-weight: bold;">span</span>&gt;  kaj la elf-runo &lt;<span style="color: #50fa7b; font-weight: bold;">span</span> <span style="color: #f8f8f2; font-weight: bold;">class</span>=<span style="color: #f1fa8c;">"runas"</span>&gt;G&lt;/<span style="color: #50fa7b; font-weight: bold;">span</span>&gt; .
&lt;/<span style="color: #50fa7b; font-weight: bold;">p</span>&gt;
</pre>
</div>

<p>
En los <code>css</code> están incluidas las clases <code>tengwar</code> y <code>runas</code>, que
importan las fuentes necesarias y las formatean, para que se muestren
como letras incrustadas.
</p>


<figure id="org5792f04">
<img src="./imagenes/Captura_letras-incrustadas.png" alt="Captura_letras-incrustadas.png">

</figure>

<p>
Las siguientes líneas sobre las <code>tags</code> me permiten mantener texto,
como comentarios o simplemente partes que aún necesitan revisión, que
no quiero que se exporten a la página <code>html</code>.
</p>

<p>
Lo último son las líneas que añadirán a nuestras cabeceras los enlaces
a los archivos de estilos. Los archivos <code>style.css</code> y <code>style-rust.css</code>
los he obtenido del siguiente repositorio:
<a href="https://github.com/ppalazon/org-mode-html-styles/">https://github.com/ppalazon/org-mode-html-styles/</a> distribuidos con
licencia <i>Apache 2.0</i>. El último, llamado <code>estilos.css</code> es propio del
proyecto y en él voy añadiendo las entradas para generar los estilos
que necesito.
</p>
</div>
</div>
</div>
<div id="outline-container-org3931336" class="outline-2">
<h2 id="org3931336">Procesar los <code>pdf</code> de imágenes</h2>
<div class="outline-text-2" id="text-org3931336">
<p>
Convertir una imagen de una página a texto es algo, en teoría,
sencillo si tienes las herramientas:
</p>

<ul class="org-ul">
<li>Un programa que extraiga la imagen del <code>pdf</code>.</li>
<li>Un programa que convierta la imagen en texto mediante <code>OCR</code>.</li>
</ul>
</div>
<div id="outline-container-org8d6a3e1" class="outline-3">
<h3 id="org8d6a3e1">Extraer imágenes del archivo <code>pdf</code></h3>
<div class="outline-text-3" id="text-org8d6a3e1">
<p>
El primer paso consiste en convertir la página correspondiente del
<code>pdf</code> en un archivo de imagen. El programa que utilizo desde la línea
de comandos es <code>pdfimages</code>. Explico cómo funciona con un ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-shell">pdfimages -png -f 12 -l 27 fichero.pdf pagina
</pre>
</div>

<p>
Veamos las opciones de <code>pdfimages</code>:
</p>

<dl class="org-dl">
<dt><code>-png</code></dt><dd>Especifica que la salida será en formato <code>png</code>.</dd>
<dt><code>-f 12</code></dt><dd>la primera (<i>first</i>) página, será la <code>12</code>.</dd>
<dt><code>-l 27</code></dt><dd>la última (<i>last</i>) página, será la <code>27</code>.</dd>
<dt><code>fichero.pdf</code></dt><dd>será el archivo del que se extraigan las imágenes.</dd>
<dt><code>pagina</code></dt><dd>es la raíz para nombrar los archivos de imagen
obtenidos.</dd>
</dl>

<p>
Ese comando, por tanto extraerá las imágenes y las guardará en los
archivos nombrados de <code>pagina-000.png</code> hasta <code>pagina-015.png</code>. Si
los nombres de los archivos ya estaban siendo utilizados, <code>pdfimages</code>
los sobrescribirá, por lo que hay que ser cuidadoso para no
<i>machacar</i> otros trabajos anteriores. Recuerda que cada vez que hagas
un proceso de estos se reiniciará la numeración.
</p>
</div>
</div>
<div id="outline-container-orgbf70e9c" class="outline-3">
<h3 id="orgbf70e9c">Convertir la imagen en texto: <code>OCR</code></h3>
<div class="outline-text-3" id="text-orgbf70e9c">
<p>
<code>OCR</code> significa <i>reconocimiento óptico de caracteres</i> por sus
iniciales en inglés. Consiste en generar texto a partir de una
«fotografía» del mismo.
</p>

<p>
El programa que utilizo es <code>tesseract</code>. Explicaré su uso, como en el
caso anterior, como si lo llamara desde línea de comandos, que tendría
la forma:
</p>

<div class="org-src-container">
<pre class="src src-shell">tesseract -l epo imagen.png fichero
</pre>
</div>

<p>
Veamos las opciones:
</p>

<dl class="org-dl">
<dt><code>-l epo</code></dt><dd>selecciona el lenguaje, en este caso <code>epo</code> es el código
para Esperanto, pues utiliza el formato códigos de lenguaje de 3
caracteres (ISO 639-2). Para
español será <code>spa</code> o para inglés <code>eng</code>. Seleccionar el lenguaje es
importante porque automáticamente activa el conjunto de caracteres
que buscar y el diccionario de la lengua correspondiente. Si la
imagen contiene varios idiomas se pueden encadenar utilizando el
<code>+</code>, por ejemplo: <code>-l epo+spa+eng</code>.</dd>
<dt><code>imagen.png</code></dt><dd>El archivo de imagen que vamos a procesar.</dd>
<dt><code>fichero</code></dt><dd>es el nombre del archivo donde se guardará el texto. Si
no se especifica nada, creará el archivo <code>fichero.txt</code>. Si se
establece otro formato de salida, la extensión utilizada cambiará.
Pero para lo que estoy haciendo, nos basta con texto plano.</dd>
</dl>
</div>
</div>
<div id="outline-container-org04d012c" class="outline-3">
<h3 id="org04d012c">Automatización del proceso</h3>
<div class="outline-text-3" id="text-org04d012c">
<p>
Ir haciendo todo ese proceso página a página, para cualquier libro, es
un trabajo monótono y sujeto a errores. En un libro de más de mil
páginas es <i>la muerte a pellizcos</i>. Hay que automatizarlo para evitar
errores y para tener vida aparte de editar contenido. Además, ya
puestos, lo de automatizar el procesamiento <code>OCR</code> puede servirme para
otros proyectos.
</p>

<p>
Como usuario habitual de documentos <code>org-mode</code>, la manera que se me
ocurrió es hacer un pequeño módulo que automatice todo el trabajo,
extrayendo imágenes convirtiéndolas en texto plano e insertando éste
en un <i>buffer</i> de <i>Emacs</i>.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">org</span>)

(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">ocr-fichero</span> <span style="color: #f1fa8c;">""</span>)
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">ocr-inicio</span>  0)
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">ocr-fin</span>     0)
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">ocr-idioma</span>  <span style="color: #f1fa8c;">""</span>)
</pre>
</div>

<p>
Para ello, debemos partir de un <i>buffer</i> <code>org</code> y colocar el cursor en
el lugar donde queremos que se inserte el texto. Hay que tener en
cuenta que si vamos a insertar más de un texto, la posición del cursor
no cambia, lo que hace es <i>insertar a partir de él</i> todo texto que le
vaya suministrando el sistema. ¿De dónde podemos sacar la información
que rellene esas variables?  Sencillo: desde <code>org-mode</code> podemos
acceder a las propiedades de un encabezado mediante la función
<code>org-entry-get</code>. Esas propiedades se definen de la siguiente manera en
un <i>buffer</i> <code>org</code>:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #ff79c6; font-size: 130%; font-weight: bold;">*</span><span style="color: #ff79c6; font-size: 130%; font-weight: bold;"> Encabezado</span>
<span style="color: #87cefa;">:PROPERTIES:</span>
<span style="color: #f1fa8c;">:nombre_propiedad_1:</span> <span style="color: #f8f8f2; background-color: #282a36;">valor</span>
<span style="color: #f1fa8c;">:nombre_propiedad_2:</span> <span style="color: #f8f8f2; background-color: #282a36;">"otro valor"</span>
<span style="color: #f1fa8c;">:nombre_propiedad_3:</span> <span style="color: #f8f8f2; background-color: #282a36;">0</span>
<span style="color: #87cefa;">:END:</span>
</pre>
</div>

<p>
En nuestro caso, para cargar las propiedades que dijimos antes creé
una función <code>iniciar</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">iniciar</span> ()
  <span style="color: #6272a4;">"Iniciar las variables globales para el proceso."</span>
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> ocr-fichero (org-entry-get (point) <span style="color: #f1fa8c;">"fichero"</span>))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> ocr-inicio  (string-to-number (org-entry-get (point) <span style="color: #f1fa8c;">"desde"</span>)))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> ocr-fin     (string-to-number (org-entry-get (point) <span style="color: #f1fa8c;">"hasta"</span>)))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> ocr-idioma  (org-entry-get (point) <span style="color: #f1fa8c;">"idioma"</span>)))
</pre>
</div>

<p>
No hay mucho que explicar:
</p>

<ul class="org-ul">
<li><code>point</code> es el valor con la posición del cursor en un <i>buffer</i> de
<code>org-mode</code>.</li>
<li><code>string-to-number</code>, convierte una cadena de texto en un valor
numérico.</li>
</ul>

<p>
Para procesar una página, como expliqué antes, haciéndolo desde la
línea de comandos, debemos dar tres pasos: 1) extraer una página del
fichero convirtiéndola en archivo gráfico, 2) generar el texto
mediante el proceso de <code>OCR</code> y 3) insertarlo en el <i>buffer</i>. Los
mismos pasos los hacemos desde una función:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">procesar-pagina</span> (num)
  <span style="color: #6272a4;">"Inserta el texto obtenido al procesar la imagen de la p&#225;gina NUM en el /point/."</span>
  (message <span style="color: #f1fa8c;">"Procesando la p&#225;gina %s"</span> num)
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Obtener la imagen con el texto
</span>  (call-process-shell-command (format <span style="color: #f1fa8c;">"pdfimages -png -f %d -l %d %s pagina"</span> num num ocr-fichero))
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Obtener el texto de la imagen
</span>  (call-process-shell-command (format <span style="color: #f1fa8c;">"tesseract -l %s pagina-000.png temporal"</span> ocr-idioma))
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Meter el texto en el punto
</span>  (insert-file-contents <span style="color: #f1fa8c;">"temporal.txt"</span>)
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Borrar los ficheros temporales
</span>  (shell-command <span style="color: #f1fa8c;">"rm pagina-000.png temporal.txt"</span>))
</pre>
</div>

<p>
Para hacerlo, vemos que llama a las aplicaciones externas con la
función <code>call-process-shell-command</code>, o <code>shell-command</code>. Esta función
necesita como parámetro una cadena que se corresponda con el comando
deseado.  La cadena se genera con <code>format</code> utilizando una cadena
cargada con elementos como <code>%d</code> para aceptar decimales o <code>%s</code> para
aceptar cadenas luego sustituye esos elementos por los valores que se
pasan como argumentos en la misma llamada a <code>format</code>.
</p>

<p>
Los comandos anteriores generan un fichero gráfico de nombre
<code>pagina-000.png</code> y el archivo de texto. La función
<code>insert-file-contents</code> inserta en la posición del cursor el contenido
que se encuentre en <code>temporal.txt</code>. El último paso, una vez tenemos
los datos cargados en el <i>buffer</i> de <i>Emacs</i>, a continuación podemos
descartar esos archivos y los borro.
</p>

<p>
Hacer sólo una página no soluciona mucho, tendría que hacerse por
lotes. Para ello sólo hay que llamar a la función anterior una vez
por cada página de la que queremos extraer el texto:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">procesar-ocr</span> ()
  <span style="color: #6272a4;">"Procesa las p&#225;ginas especificadas del documento dado en el buffer actual."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (iniciar)       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Establece las variables globales
</span>  (mapc 'procesar-pagina (number-sequence ocr-fin ocr-inicio -1)))
</pre>
</div>

<p>
Esta función es la que llamaremos desde nuestro <i>buffer</i> <code>org</code> para
realizar el proceso completo. Por ello, la definimos para <i>Emacs</i> como
<code>interactive</code>, permitiéndonos llamarla como a cualquier otra función
del editor con <code>M-x procesar-ocr</code>. Lo primero que hace la función es
llamar a la función <code>iniciar</code> que vimos antes para establecer los
valores de trabajo.
</p>

<p>
La función <code>mapc</code> realiza una llamada a <code>procesar-página</code> por cada
valor devuelto por la función <code>number-sequence</code>. Hay que remarcar que
el recorrido lo hago de <code>ocr-fin</code> a <code>ocr-inicio</code> con un incremento de
<code>-1</code>. Es decir, como los textos se van a ir insertando a partir de la
posición del cursor y los últimos empujarán a los primeros, lo que
quiero es que inserte primero las últimas páginas porque las irá
<i>empujando</i> hacia el final según vaya procesando otras.
</p>

<p>
Para una visión más completa del módulo, pongo el código completo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">package --- Summary
</span>
<span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Commentary:
</span>
<span style="color: #6272a4;">;;</span><span style="color: #6272a4;">: `</span><span style="color: #bd93f9;">procesar-ocr</span><span style="color: #6272a4;">' realiza la conversi&#243;n de un pdf compuesto de
</span><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">im&#225;genes a texto plano, incrust&#225;ndolo despu&#233;s en un /buffer/ org.
</span>
<span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Code:
</span>
(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">org</span>)

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Variables globales para el proceso
</span>
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">ocr-fichero</span> <span style="color: #f1fa8c;">""</span>
  <span style="color: #6272a4;">"Variable que contiene el nombre de ocr-fichero a convertir.

En el archivo `</span><span style="color: #bd93f9;">org</span><span style="color: #6272a4;">' donde se guardar&#225; el resultado, debe estar en
una propiedad llamada `</span><span style="color: #bd93f9;">fichero</span><span style="color: #6272a4;">'."</span>)
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">ocr-inicio</span> 0
  <span style="color: #6272a4;">"N&#250;mero de p&#225;gina donde comenzar la conversi&#243;n."</span>)
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">ocr-fin</span> 0
  <span style="color: #6272a4;">"N&#250;mero de p&#225;gina donde finalizar la conversi&#243;n."</span>)
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">ocr-idioma</span> <span style="color: #f1fa8c;">""</span>
  <span style="color: #6272a4;">"Lenguaje de la lista de `tesseract --listlangs`."</span>)

<span style="color: #6272a4;">; </span><span style="color: #6272a4;">TODO - Habr&#237;a que comprobar que existen esas propiedades.
</span><span style="color: #6272a4;">; </span><span style="color: #6272a4;">la funci&#243;n  `</span><span style="color: #bd93f9;">org-entry-get</span><span style="color: #6272a4;">' devuelve una cadena vac&#237;a si la propiedad existe o
</span><span style="color: #6272a4;">; </span><span style="color: #6272a4;">pero est&#225; vac&#237;a o `</span><span style="color: #bd93f9;">nil</span><span style="color: #6272a4;">' si no existe. No s&#233; c&#243;mo se tomar&#225;n estas aplicaciones
</span><span style="color: #6272a4;">; </span><span style="color: #6272a4;">la falta de un par&#225;metro.
</span>(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">iniciar</span> ()
  <span style="color: #6272a4;">"Iniciar las variables globales para el proceso."</span>
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> ocr-fichero (org-entry-get (point) <span style="color: #f1fa8c;">"fichero"</span>))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> ocr-inicio  (string-to-number (org-entry-get (point) <span style="color: #f1fa8c;">"desde"</span>)))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> ocr-fin     (string-to-number (org-entry-get (point) <span style="color: #f1fa8c;">"hasta"</span>)))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> ocr-idioma  (org-entry-get (point) <span style="color: #f1fa8c;">"idioma"</span>)))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">procesar-pagina</span> (num)
  <span style="color: #6272a4;">"Inserta el texto obtenido al procesar la imagen de la p&#225;gina NUM en el /point/."</span>
  (message <span style="color: #f1fa8c;">"Procesando la p&#225;gina %s"</span> num)
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Obtener la imagen con el texto
</span>  (call-process-shell-command (format <span style="color: #f1fa8c;">"pdfimages -png -f %d -l %d %s pagina"</span> num num ocr-fichero))
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Obtener el texto de la imagen
</span>  (call-process-shell-command (format <span style="color: #f1fa8c;">"tesseract -l %s pagina-000.png temporal"</span> ocr-idioma))
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Meter el texto en el punto
</span>  (insert-file-contents <span style="color: #f1fa8c;">"temporal.txt"</span>)
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Borrar los ficheros temporales
</span>  (shell-command <span style="color: #f1fa8c;">"rm pagina-000.png temporal.txt"</span>))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">procesar-ocr</span> ()
  <span style="color: #6272a4;">"Procesa las p&#225;ginas especificadas del documento dado en el buffer actual."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (iniciar)       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Establece las variables globales
</span>  (mapc 'procesar-pagina (number-sequence ocr-fin ocr-inicio -1)))

(<span style="color: #ff79c6; font-weight: bold;">provide</span> '<span style="color: #bd93f9;">procesar-ocr</span>)
<span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">procesar-ocr.el ends here</span>
</pre>
</div>

<p>
La plantilla para crear un fichero nuevo a partir del proceso de <code>OCR</code>
está en el archivo <code>plantilla.org</code> del directorio raíz del proyecto,
junto <code>procesar-ocr.el</code>. El contenido es sencillo:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #6272a4;">#+setupfile: ../../plantillas/kunularo.org</span>

<span style="color: #6272a4;">#+include: ./indice.org</span>

<span style="color: #ff79c6; font-size: 130%; font-weight: bold;">*</span><span style="color: #ff79c6; font-size: 130%; font-weight: bold;"> Plantilla</span>
<span style="color: #87cefa;">:properties:</span>
<span style="color: #f1fa8c;">:desde:</span> <span style="color: #f8f8f2; background-color: #282a36;">0</span> 
<span style="color: #f1fa8c;">:hasta:</span> <span style="color: #f8f8f2; background-color: #282a36;">1</span>
<span style="color: #f1fa8c;">:fichero:</span> <span style="color: #f8f8f2; background-color: #282a36;">../../Tolkien-la-kunularo-de-la-ringoj.pdf</span>
<span style="color: #f1fa8c;">:idioma:</span> <span style="color: #f8f8f2; background-color: #282a36;">epo</span>
<span style="color: #87cefa;">:end:</span>
</pre>
</div>

<p>
Puesto que estoy haciendo el libro por capítulos, el procedimiento
aquí contado se resume en:
</p>

<ol class="org-ol">
<li>Copiar el archivo <code>plantilla.org</code> como <code>chapitroXX.org</code>.</li>
<li>Realizar los ajustes de las propiedades y el título del capítulo.</li>
<li>Llamar a <code>procesar-ocr</code>.</li>
<li>Corregir errores (los grandes que se ven a simple vista).</li>
<li>Pasar el diccionario para Esperanto con el <code>ispell</code> de <i>Emacs</i>.</li>
<li>Generar los archivos <code>html</code> llamando a <code>org-publish</code>.</li>
</ol>
</div>
</div>
</div>
<div id="outline-container-org1f3f0e9" class="outline-2">
<h2 id="org1f3f0e9">Fuentes para Esperanto</h2>
<div class="outline-text-2" id="text-org1f3f0e9">
<p>
Otra dificultad que me encuentro con este proyecto es la elección de
fuentes. No todas, especialmente las más vistosas, tienen las
<i>ĉapelitaj literoj</i> del Esperanto. Muchas, ni siquiera tienen las eñes
o las vocales acentuadas. Después de buscar un poco, encontré
<a href="https://www.dafontfree.io/palladio-serif-font/">Palladio</a>, que tiene un aspecto agradable y una buena colección de
glifos. Además se distribuye con licencia libre.
</p>

<p>
Más problemáticas fueron las fuentes especiales. Por un lado, una de
ellas también se distribuye de manera libre. En la fuente <a href="https://www.fontspace.com/ringbearer-font-f2246">Ringbearer</a>
se encuentran los glifos para las eñes y las tildes del español, pero
no las correspondientes al Esperanto... así pues, vamos poner sombrero
a algunas letras:
</p>


<figure id="orgab066b6">
<img src="./imagenes/Captura_modificar_tipos.png" alt="Captura_modificar_tipos.png">

</figure>

<p>
Para la otra fuente utilizada, sin embargo, no he encontrado con qué
licencia se distribuye. Es más, tampoco tiene, ni siquiera, los glifos
de eñes y tildes. Sólo pone que es <i>free</i> <a href="https://fontmeme.com/fonts/hobbiton-brush-hand-font/">donde la encontré</a>, pero sin
saber exactamente la licencia es complicado establecer si puedo
modificarla legalmente o no. En todo caso, y como es un proyecto
privado, que no se va a publicar no creo que me persigan.
</p>


<figure id="org179286f">
<img src="./imagenes/Captura_modificar-fuente.png" alt="Captura_modificar-fuente.png">

</figure>
</div>
</div>
<div id="outline-container-org090ed95" class="outline-2">
<h2 id="org090ed95">Conclusiones</h2>
<div class="outline-text-2" id="text-org090ed95">
<p>
El objetivo de este tipo de proyectos es aprender a hacer las cosas,
pero también quiero conseguir documentos electrónicos modificables y
editables. Tengo bastantes archivos de este estilo: archivos <code>pdf</code>
compuestos de las imágenes escaneadas de las páginas de un libro. He
elegido éste en concreto porque es un proyecto más complejo que otros:
</p>

<ul class="org-ul">
<li>Varios tipos de letra.</li>
<li>Lenguas distintas con otros alfabetos.</li>
<li>Imágenes.</li>
</ul>

<p>
Su destino será estar en un pequeño servidor doméstico y poder leer
tranquilamente con cualquier dispositivo. Sentarme en el sofá o en el
sillón, conectarme al <i>wifi</i> y abrir el navegador, ya sea con la
<i>tablet</i>, el móvil o el ordenador, sin necesitar instalar ninguna
aplicación especial.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>«El señor de los anillos»</i> en Esperanto. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>La compañía del anillo</i> en Esperanto. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>El primer libro</i> en Esperanto.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> <a href="/tags/ocr/index.html">ocr</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <category><![CDATA[ocr]]></category>
  <link>https://notxor.nueva-actitud.org/2023/07/12/edicion-y-exportacion-desde-org-mode-a-html.html</link>
  <pubDate>Wed, 12 Jul 2023 00:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Avanzando sin mirar demasiado atrás]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-06-13</div>
<p>
El lío con <i>Telegram</i> me pilló haciendo reformas en el <i>blog</i>. Tampoco
muy profundas, pero llevaba tiempo queriendo <i>darle algo de cariño</i> al
asunto de la visualización en dispositivos de pantalla pequeña. Poco a
poco el asunto se va arreglando y a estas alturas se debería ver igual
(¿de mal?) en todas las plataformas.
</p>

<p>
El asunto principal que quería tratar hoy es la sequía de ideas y el
tiempo que se necesita para publicar con regularidad en un <i>blog</i>.
Siendo, además, un <i>blog personal</i>, no monetizado y que lo único que
acarrea son gastos y problemas. Cuando empecé no pretendía nada en
particular, fui el primer sorprendido de que alguien, aparte de mí, lo
leyera. Es un <i>blog</i> plantado como <i>mis apuntes</i> de las <i>frikadas</i> que
me llaman la atención. Algunos de mis allegados que lo leen, o al
menos lo ojean por encima, se quejan de que no entienden de qué estoy
hablando la mayoría de veces. Es cierto que no hay una <i>línea
editorial</i> clara, escribo normalmente sobre lo que voy descubriendo, 
lo que voy utilizando, sobre cómo he hecho alguna cosa (para cuando
necesite volver a hacerla) o sobre cualquier tema, cualquier detalle,
que me parece, en ese momento, maravilloso.
</p>

<p>
Durante mucho tiempo he estado explorando <i>Emacs</i> y he ido desgranando
poco a poco todos los paquetes que utilizo y más. En realidad, escribí
sobre algunos de ellos que dejé de utilizar y están ocupando sitio en
el disco duro o sobre otros que al final los configuré de otra forma,
e incluso sobre algunos que desinstalé por diversas razones. Todo esto
salpicado por un montón de artículos rellenos de <i>vaporware</i> de
proyectos iniciados e inconclusos detenidos en el infinito
<i>pendientes</i> de mi agenda. Mis investigaciones sobre lenguajes, la
cantidad de ellos que he explicado por aquí, algunos con gusto y otros
con cierta distancia. También algunos proyectillos para aprender cómo
funcionan las cosas.
</p>

<p>
No voy a cerrar el <i>blog</i>, eso lo tengo claro, necesito los <i>apuntes</i>
que he ido tomando todos estos años. Lo único que quiero abandonar es
la presión de estar pensando en qué publicar para mantener la atención
del público. Un público al que no esperaba en los inicios y al que
agradezco sinceramente que pierda el tiempo con mis <i>tontás</i>. Pero
llevo un tiempo dándome cuenta que el <i>blog</i> imponía estrés, sólo por
el hecho de estar y que lo leyera gente. Así pues, decidí relajarme
hace unas semanas: lo abrí por diversión y escribiré sólo si me
divierte.
</p>

<p>
Como hice en el último aviso, quiero recordarte que ya no estoy en
<i>Telegram</i>. Si me quieres comentar algo sobre el <i>blog</i> o sobre
cualquier otro tema, me puedes encontrar en XMPP. He abierto una sala,
igual que abrí un grupo en <i>Telegram</i>. Puedes ver el enlace en el pie
de la página. Si usas <a href="https://f-droid.org/packages/eu.siacs.conversations/">Conversations</a> en el androide puedes escanear
este código:
</p>


<figure id="org4c5b1f2">
<img src="./imagenes/direccion-grupo-xmpp.png" alt="direccion-grupo-xmpp.png">

</figure>

<p>
También puedes buscar la sala: <code>Notxor-tiene-un-blog</code> en
<code>salas.suchat.org</code>. De momento es un grupo público, ya estamos tres
ocupantes sin haberle hecho publicidad. Además teniendo en cuenta que
el uso de XMPP es minoritario, no espero alcanzar la cifra de 5
usuarios totales.
</p>

<p>
Por último, pedir perdón a todos los que sigan el <i>blog</i> mediante
<i>RSS</i>, porque he vuelto a rehacer todas las páginas para incluir el
pie con el nuevo grupo y tendrán un montón de avisos falsos de
artículos nuevos en su lector de <i>feeds</i>.
</p>

<p>
<b>PdT</b>: Sí, bueno, no he querido releer esta entrada, no está
 ordenada ni corregida. Así (de bien o de mal) escribo todo de
 primeras, prefiero mantener aquí la espontaneidad más que la
 pulcritud. Un saludo a todos.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/blog/index.html">blog</a> ]]></description>
  <category><![CDATA[blog]]></category>
  <link>https://notxor.nueva-actitud.org/2023/06/13/avanzando-sin-mirar-demasiado-atrás.html</link>
  <pubDate>Tue, 13 Jun 2023 10:01:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Aviso a seguidores]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-06-10</div>
<p>
Esta entrada no es un artículo, es sólo un aviso a ese pequeño grupo
de lectores de este <i>blog</i> que se encontraban en el grupo de
<i>Telegram</i>, donde comentábamos un montón de historias. No sé si dicho
grupo seguirá existiendo. <i>Telegram</i> ha tenido a bien eliminarme la
cuenta, no tengo muy claro por qué. El caso es que no puedo, ni
siquiera reinstalar la aplicación: en cuanto pongo el número de
teléfono la instalación se bloquea.
</p>

<p>
Así pues, no pudiendo realizar ninguna acción con dicha aplicación de
mensajería, he eliminado el enlace al grupo que había en el pie de
página y he rehecho todas las páginas<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> para que <i>no</i> quede
constancia de dicho grupo. Me encontraréis por <i>Mastodon</i> si me
queréis comentar algo.
</p>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ya sabéis que es un sitio estático... mis más sinceras
disculpas si sigues el <i>blog</i> por el RSS, seguramente tienes un
aluvión de artículos de los últimos años marcados todos como nuevos. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/blog/index.html">blog</a> <a href="/tags/telegram/index.html">telegram</a> ]]></description>
  <category><![CDATA[blog]]></category>
  <category><![CDATA[telegram]]></category>
  <link>https://notxor.nueva-actitud.org/2023/06/10/aviso-a-seguidores.html</link>
  <pubDate>Sat, 10 Jun 2023 10:07:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Programando un tablero de ajedrez que cumpla las reglas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-04-17</div>
<p>
Llevo un tiempo sin contar nada en el <i>blog</i> y ya me estaba generando
estrés el pensamiento recurrente de <i>«debería escribir algo»</i>. Así, sin
tema concreto, sólo puedo utilizar lo que he estado haciendo todo este
tiempo. Que si bien no es sólo mérito mío<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, me ha tenido absorbido y
concentrado todo este tiempo sin procrastinar en otra cosa que no sea
ésta. Ya comenté <a href="https://notxor.nueva-actitud.org/2023/03/12/el-ajedrez-y-su-representacion.html">en el último artículo</a> lo de hacer un programa de
ajedrez<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>, pues bien: lo estamos haciendo, no sólo en una, sino en tres
formas de visualización o interfaces y el trabajo está siendo muy
instructivo. Cuando digo interfaces me refiero a representación del
tablero en pantalla y, efectivamente, estamos desarrollando
tres: 1. Modo texto desde el terminal. 2. Mediante la librería gráfica
<code>fltk</code> y 3. Mediante la librería gráfica <code>imgui</code>.
</p>

<p>
Primero veamos cómo pintan los distintos tableros:
</p>


<figure id="org06535d9">
<img src="./imagenes/Captura_no-gui.png" alt="Captura_no-gui.png">

<figcaption><span class="figure-number">Figura 1: </span>Partida desde línea de comandos</figcaption>
</figure>


<figure id="org6e02dfd">
<img src="./imagenes/Captura_fltk.png" alt="Captura_fltk.png">

<figcaption><span class="figure-number">Figura 2: </span>Partida en una ventana <code>fltk</code></figcaption>
</figure>


<figure id="org63451d6">
<img src="./imagenes/Captura_imgui.png" alt="Captura_imgui.png">

<figcaption><span class="figure-number">Figura 3: </span>Partida en una ventana <code>imgui</code></figcaption>
</figure>

<p>
Diferencias entre tableros:
</p>


<ul class="org-ul">
<li>El tablero en modo texto está conectado al <a href="https://stockfishchess.org/">motor de juego stockfish</a>,
es decir, permite jugar partidas contra la máquina. La forma de
comunicación, como se puede ver en la figura 1, consiste en escribir
las coordenadas de origen y destino. Con esas coordenadas se procesa
el movimiento y se genera el FEN que se le pasa al motor. Cuando el
motor contesta con sus coordenadas, se vuelve a realizar el
movimiento y a mostrarlo en pantalla.</li>
<li>El tablero en modo texto muestra la partida en el formato de
notación algebraico corto, mientras que los otros dos muestran el
estado actual de la partida en notación FEN<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>.</li>
<li>La librería <code>fltk</code> es más sencilla y requiere mucha menos computación
para dibujarse. <code>imgui</code> está diseñado para dibujarse como lo hacen los
videojuegos, en un bucle sin fin que se redibuja todo lo rápido que
puede para que sea percibido con suavidad. Esto está bien en juegos
3D exigentes para la tarjeta gráfica, pero el ajedrez no necesita
esa velocidad. De hecho, se puede ver en la figura 3 que está
limitado su redibujado a unos 10fps, más que suficiente para darle
fluidez a un programa de ajedrez.</li>
</ul>

<p>
Al conectar el motor de juego, con el protocolo UCI, nos dimos cuenta
que con ese protocolo, no comprueba nada ni tiene seguimiento de la
partida. Simplemente le pasas una determinada posición del tablero
mediante notación FEN y te devuelve la mejor jugada que pueda calcular
en base a ese estado. Así pues, el mantenerse dentro de las reglas del
ajedrez corre del lado del programa cliente. Es decir, El motor si
encuentra algo erróneo o absurdo se queda esperando una posición
«calculable» sin decir nada y por tanto el programa cliente no puede
saber si no contesta porque ha habido un error o porque está
calculando.
</p>


<figure id="org5fed572">
<img src="./imagenes/jugada.svg" alt="jugada.svg" class="org-svg">

<figcaption><span class="figure-number">Figura 4: </span>Comunicación entre elementos del programa</figcaption>
</figure>

<p>
En la figura anterior, el proceso <code>Partida</code> debe controlar el proceso de
juego asegurándose de que los distintos movimientos se ajustan a las
normas del ajedrez. Cuando es así, su estado cambia, luego veremos
cómo. El proceso <code>Interface</code> es el encargado de comunicar la <code>Partida</code> con
el <code>Motor</code> de juego, enviando jugadas, y con el usuario, mostrando el
tablero. El proceso <code>Motor</code> únicamente recibe una posición del estado de
la partida y emite la jugada que considera más oportuna. El motor
<i>stockfish</i> permite varios parámetros de configuración, incluyendo nivel
de profundidad de cálculo o el ajuste de ELO para controlar la
dificultad contra la que queremos enfrentarnos. Por ejemplo, también
se puede configurar si queremos que el motor se mantenga ocioso
mientras nosotros movemos o no. En mi caso lo tengo configurado a un
nivel de profundidad 10 (como limitación para acelerar un poco su
respuesta) y sin dejarlo pensar mientras muevo. Aún así me gana.
</p>
<div id="outline-container-org2d4f9de" class="outline-2">
<h2 id="org2d4f9de">Partida</h2>
<div class="outline-text-2" id="text-org2d4f9de">
<p>
Muestro aquí los objetos que intervienen en la partida para no hablar
en vacío, pero tampoco voy a hacer una disertación detallada de todos
los detalles:
</p>

<div class="org-src-container">
<pre class="src src-nim">type Tablero* = ref array[64, char]

type
  Movimiento* = object
    san*: string
    fen*: string

type
  Partida* = ref object
    tablero*: Tablero
    movimientos*: seq[Movimiento]
    turno*: string
    enroqueCortoBlancas*: bool
    enroqueLargoBlancas*: bool
    enroqueCortoNegras*: bool
    enroqueLargoNegras*: bool
    posAlPaso*: string
    contador*: int
    numJugada*: int
</pre>
</div>

<p>
El <code>Tablero</code> es un array de 64 caracteres, cada uno de los cuales
representa el contenido de una casilla. La <code>Partida</code> cuenta con un
<code>tablero</code> que es el que utilizan las interfaces para mostrarlo por
pantalla. Además, la <code>Partida</code> cuenta con una lista de <i>movimientos</i>. Cada
<code>Movimiento</code> consta de una cadena SAN<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup> y el FEN que muestra el estado de
la partida tras ese movimiento. El movimiento 0 es el estado inicial
del tablero al comenzar la partida. De momento, sólo es posible el
inicio estándar, pero esperamos poder iniciar las partidas de otros
modos, como el <i>ajedrez 960</i><sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>, o cuando ambos jugadores pactan una
ventaja, por ejemplo iniciando el juego uno de ellos con una figura
menos.
</p>

<p>
El <i>meollo</i> de la partida la controla <code>muevePieza</code>. Dicha función
controla que al realizar un movimiento se siguen las normas del
ajedrez llamando a la función <code>esMovimientoLegal</code>, y si, efectivamente
el movimiento es legal, realiza el movimiento, genera la cadena SAN y
la cadena FEN, las guarda y pone la <code>Partida</code> en el estado
correspondiente. Aunque aún faltan un par de detalles para dar por
finalizada la implementación de <code>Partida</code>. El código, de momento,
tiene esta forma:
</p>

<div class="org-src-container">
<pre class="src src-nim">##[
La función `muevePieza` cambia la posición de una pieza desde una
casilla de origen `co` a una casilla final `cf`, en el tablero `p`
dado.

Devuelve `true` si se efectúa el movimiento de pieza y `false` en
caso contrario. Cuando se realiza el movimiento de pieza también
cambia el turno en la partida.
]##
# TODO: Falta por implementar:
#       1. la promoción de los peones: de momento sólo promocionan a reina
#       2. detección del Mate
proc muevePieza*(p: Partida, co, cf: string): bool =
  var
    san: string
    [...]
  if p.esMovimientoLegal(t, co, cf):

    [...]

    # hace el movimiento
    t.ponValorCasilla(cf, figura)
    t.ponValorCasilla(co, VACIA)
    if san == "":  # Si ha habido enroque ya llega aquí relleno
      # si no, junta las partes de la notación del movimiento
      san = fig &amp; origen &amp; captura &amp; cf &amp; jaque &amp; ep
    # Cambia el jugador de turno
    p.cambiaTurno()
    # Guarda el registro del movimiento
    p.movimientos.add(Movimiento(san: san, fen: p.fen()))
    return true
  else:
    return false
</pre>
</div>

<p>
Algunas cosas merecen un poco más de atención, como los detalles sobre
movimientos de peones, reyes y torres. Estas tres piezas producen
cambios en el estado de <code>Partida</code> por reglas especiales que les afectan,
como la <i>captura al paso</i><sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup> de los peones, la regla de los cincuenta
movimientos<sup><a id="fnr.7" class="footref" href="#fn.7" role="doc-backlink">7</a></sup>, de los que Partida lleva un contador, o de las reglas de
enroque<sup><a id="fnr.8" class="footref" href="#fn.8" role="doc-backlink">8</a></sup>, que también debe vigilar Partida y que se ven afectadas por
movimientos de reyes y torres. Además, en el enroque se debe mover
también la torre y no sólo el rey y, por último, debe registrar los
datos para generar la cadena san que es la notación algebraica del
movimiento.
</p>

<p>
Sin embargo, el mayor peso de proceso y comprobaciones recae sobre la
función <code>esMovimientoLegal</code>:
</p>

<div class="org-src-container">
<pre class="src src-nim">##[
Para que un movimiento sea legal, en una partida `p` la pieza situada
en la casilla de origen `co` debe estar en su turno, no puede mover al
mismo sitio donde está y la casilla de destino `cf` debe ser
alcanzable según las normas del ajedrez.
]##
proc esMovimientoLegal(p: Partida, t: Tablero, co, cf: string): bool =
  var
    figura: char = t.contenidoCasilla(co)
    tablero: Tablero

  if figura != VACIA and estaEnTurno(p, figura) and co != cf and p.esDestinoLegal(t, co, cf):
    # Si el movimiento parece legal, realizamos el movimiento en un tablero aparte
    tablero = t.copiarTablero()
    tablero.ponValorCasilla(co, VACIA)
    tablero.ponValorCasilla(cf, figura)
    # Y comprobamos que no queda el rey propio en jaque
    if tablero.estaEnJaque(p, figura.colorPieza()):
      echo("Deja el rey propio en jaque.")
      return false
    return true
  else:
    return false
</pre>
</div>

<p>
Las comprobaciones que hace esta función son las siguientes:
</p>


<ol class="org-ol">
<li>Que para la casilla de origen no se ha seleccionado una casilla
vacía.</li>
<li>Que la figura de la casilla de origen está en su turno.</li>
<li>Que la casilla de origen y destino son distintas.</li>
<li>Que la figura de la casilla de origen puede mover a la casilla
final. La función <code>esDestinoLegal</code> comprueba las normas de
movimiento de cada pieza y determina si puede alcanzar la casilla
final.</li>
<li>Que al realizar el movimiento no quedaría el rey propio en
jaque. Para hacerlo, copia el tablero de la partida en otro,
poniéndolo en la situación de que el movimiento se ha realizado y
comprueba que el rey de su color no quede en jaque.</li>
</ol>

<p>
Falta por implementar un par de detalles que aún no tengo claro cómo
se pueden afrontar, aunque sí alguna idea:
</p>

<ul class="org-ul">
<li><b>Promoción del peón</b>: Cuando un peón alcanza la fila más alejada de
su posición de inicio puede promocionar a cualquier figura, excepto
a rey. Puede convertirse en reina, torre, alfil o caballo a elección
del jugador. Lo habitual es que todos elijamos la reina por ser la
pieza más potente, pero puede elegirse otra, por ejemplo, para
evitar ahogar al rey contrario y acabar en tablas o porque
estratégicamente le guste más al jugador. En la notación por
coordenadas se anota la pieza deseada después del movimiento, por
ejemplo: <code>e7e8N</code> coronaría el peón y lo convertiría en un caballo. En
modo gráfico podría ser mostrar un diálogo para que elija el jugador
y en modo texto, añadir la pieza deseada a las coordenadas al
introducir el movimiento para coronar el peón... pero aún hay que
hacerlo.</li>
<li><b>Detección del mate</b>: Actualmente <code>Partida</code> no sabe si ha acabado el
juego porque no se pueda evitar la captura de un rey. Mirando por
Internet he visto un algoritmo que tiene dos casos, a partir de un
jaque inicial:
<ol class="org-ol">
<li>El jaque inicial se da por dos piezas a la vez:
<ol class="org-ol">
<li>Comprobar si algún movimiento de rey evita el jaque.</li>
</ol></li>
<li>El jaque inicial lo da una sola pieza:
<ol class="org-ol">
<li>Comprobar si la pieza que da el jaque puede ser capturada.</li>
<li>Comprobar si se puede interponer una pieza propia entre el
rey y la pieza atacante.</li>
<li>Comprobar si algún movimiento del rey evita el jaque.</li>
</ol></li>
</ol></li>
</ul>

<p>
Poder analizar partidas implica navegarlas, poder avanzar y retroceder
tantas veces como sea necesario. Para colocar la partida en una
posición cualquiera, la aproximación por <i>fuerza bruta</i> de iniciarla e
ir haciendo todos los movimientos anteriores. Sin embargo, creo que
esta forma es un poco primitiva y que la mejor manera sería utilizar
la notación FEN. Por esto, tras cada movimiento se registra no sólo la
notación estándar, sino también el estado de la partida con FEN.
</p>
</div>
</div>
<div id="outline-container-org795ed6f" class="outline-2">
<h2 id="org795ed6f">Notación FEN</h2>
<div class="outline-text-2" id="text-org795ed6f">
<p>
La forma de comunicar al motor de juego la situación actual de la
partida es con la notación FEN. Ya lo expliqué en el artículo
anterior: consta de seis campos:
</p>

<ul class="org-ul">
<li>Cadena representando las 8 filas del tablero:
<ul class="org-ul">
<li>El tablero se lee de izquierda a derecha comenzando por la casilla
<code>a8</code> y de arriba hacia abajo hasta <code>h1</code>.</li>
<li>Cada fila se separa de la siguiente con el signo <code>/</code>.</li>
<li>Se utiliza la notación de piezas con la inicial inglesa, en
mayúscula para blancas y en minúscula para negras.</li>
<li>Las casillas vacías se muestran agrupándolas con un número.</li>
</ul></li>
<li>Indicador de color activo, o a quién le toca mover, <code>w</code> (<i>white</i>)
y <code>b</code> (<i>black</i>).</li>
<li>Indicador de posibilidad de enroques: <code>QKqk</code> (de <i>Queen</i> y <i>King</i>) que
actuarían como <i>flags</i> de que blancas (en mayúscula) y negras (en
minúscula) tienen capacidad de enrocar aún por alguno de los lados o
un <code>-</code> si ningún jugador tiene ya posibilidad de enroque.</li>
<li>Casilla de destino para la <i>captura al paso</i>. Si no hay casilla de
destino aparecerá un <code>-</code>. La casilla destino aparecerá después de un
doble avance de salida de un peón. Un peón contrario que se
encuentre en la fila 3 (para negras) o en la fila 6 (para blancas)
puede ejercer la acción de <i>captura al paso</i>, situándose en la casilla
donde hubiera terminado si el movimiento del peón que avanza hubiera
sido de una sola casilla.</li>
<li>Reloj de medios movimientos: Este número es el recuento de medios
movimientos desde el avance de peones o movimientos de captura y se
utiliza para la regla de conteo de 50 movimientos. Esta regla
establece <i>tablas</i> o <i>empate</i>, si se producen 50 movimientos seguidos
sin que se mueva un peón o se realice alguna captura.</li>
<li>Número de jugadas completas: Comienza puesto a 1 y se incrementa
tras cada movimiento de las negras.</li>
</ul>

<p>
Todos los campos llegan en una sola cadena separados por espacios.
</p>

<p>
En base a los campos anteriores se establece el estado de la <code>Partida</code>
con la función:
</p>

<div class="org-src-container">
<pre class="src src-nim">##[
Esta función `fen` recibe una cadena codificada con la notación FEN y
la utiliza para situar la partida `p` en el estado descrito por la
misma, decodificando los campos que esta notación proporciona.
]##

proc fen*(p: Partida, fen: string) =
  let campos = split(fen)
  p.limpiarTablero()
  p.ponPiezasFen(campos[0])
  p.turno = campos[1]
  p.ponEnroquesFen(campos[2])
  p.posAlPaso = campos[3]
  p.contador = parseInt(campos[4])
  p.numJugada = parseInt(campos[5])
</pre>
</div>

<p>
También hay una función que realiza el proceso inverso y devuelve una
cadena codificada como FEN a partir del estado de una partida:
</p>

<div class="org-src-container">
<pre class="src src-nim">proc fen*(p: Partida): string
</pre>
</div>
</div>
</div>
<div id="outline-container-org0e3ac3d" class="outline-2">
<h2 id="org0e3ac3d">Conclusiones</h2>
<div class="outline-text-2" id="text-org0e3ac3d">
<p>
No quiero <i>cansinar</i> mucho con el proyecto, aún está en pañales aunque
promete maneras. De momento tenemos un objeto que nos permite mantener
una partida de ajedrez dentro de las normas de juego, con alguna
carencia, que sin duda para cuando se publique este artículo ya estará
solucionada o en vías de solución. Además se puede conectar con un
motor de juego. De momento sólo se ha probado con <i>Stockfish</i> mediante
el protocolo UCI, aunque está pensado admitir otros motores como <i>GNU
chess</i> o <i>Crafty</i>. Quizá también soportar algún protocolo más, como
<i>XBoard</i>.
</p>

<p>
Lo que estoy ahora mirando es poder configurar el motor para jugar
desde la <i>interface</i>. También introducir otros parámetros del programa,
que me permitan o bien jugar o bien analizar una <i>partida</i> desde el
primer movimiento al último realizado.
</p>

<p>
El siguiente paso es poder cargar archivos <i>PGN</i>, con múltiples
partidas, que permita analizar su contenido, desarrollar las partidas
y hacer variaciones sobre ellas utilizando el motor de juego, etc.
</p>

<p>
También el asunto del reloj y el tiempo de juego está <i>en pendientes</i>,
pero no creo que sea el momento aún para afinar tanto. Primero hay que
terminar con la representación del tablero, asegurarnos de seguir las
normas del ajedrez y de que permite un análisis pausado de la partida.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Me está ayudando un amigo, pero no quiere que lo mencione, ni
le atribuya méritos en público, así que no diré su nombre, apodo, ni
dato alguno que pueda identificarlo... Pero no puedo dejar de
reconocer que anda detrás de mí con el látigo: me corrige el código,
lo simplifica, le encuentra errores, me echa la bronca por mi poca
seriedad con los comentarios de los commits o mi falta de acierto a la
hora de poner nombre a las funciones o escribir comentarios... en fin,
mi <i>Pepito Grillo</i> personal sin el cual este proyecto llevaría haciendo
aguas casi desde sus inicios.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Sí, ya sé que hay muchos, pero no todos hacen lo que queremos. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Notación de Forsyth-Edwars
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Standard Algebraic Notation</i> SAN, es la notación oficial de la
FIDE para representar las partidas en campeonatos y también es la base
de representación para los archivos PGN (<i>Portable Game Notation</i>).
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
El <i>ajedrez 960</i> lo propuso Bobby Fisher. En esta modalidad se
forma la primera línea de las figuras de manera
aleatoria. <a href="https://es.wikipedia.org/wiki/Ajedrez_aleatorio_de_Fischer">https://es.wikipedia.org/wiki/Ajedrez_aleatorio_de_Fischer</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://es.wikipedia.org/wiki/Captura_al_paso">https://es.wikipedia.org/wiki/Captura_al_paso</a> 
</p></div></div>

<div class="footdef"><sup><a id="fn.7" class="footnum" href="#fnr.7" role="doc-backlink">7</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://es.wikipedia.org/wiki/Regla_de_los_cincuenta_movimientos">https://es.wikipedia.org/wiki/Regla_de_los_cincuenta_movimientos</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.8" class="footnum" href="#fnr.8" role="doc-backlink">8</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://es.wikipedia.org/wiki/Enroque">https://es.wikipedia.org/wiki/Enroque</a> 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/ajedrez/index.html">ajedrez</a> <a href="/tags/nim/index.html">nim</a> ]]></description>
  <category><![CDATA[ajedrez]]></category>
  <category><![CDATA[nim]]></category>
  <link>https://notxor.nueva-actitud.org/2023/04/17/programando-un-tablero-de-ajedrez-que-cumpla-las-reglas.html</link>
  <pubDate>Mon, 17 Apr 2023 19:28:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[El ajedrez y su representación]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-03-12</div>
<p>
El ajedrez es un juego milenario que a estas alturas no necesita
presentación. Además, desde hace cientos de años se ha intentando
sistematizar la representación de las partidas con notaciones de
distinto tipo y alcance. Además, se pueden encontrar por internet
bases de datos cargadas con, literalmente, millones de partidas
anotadas y comentadas que pueden servir no sólo como entrenamiento a
las IA, sino también a las inteligencias naturales que pretenden
aprender este juego. Como necesitaba algún proyecto que me ayudara a
calibrar del todo <a href="https://notxor.nueva-actitud.org/2023/02/28/nim-un-lenguaje-compilado.html">si el lenguaje Nim del que ya hablé aquí</a>, me hace
sentir cómodo. Y en este artículo os cuento en que consistirá dicho
proyecto.
</p>
<div id="outline-container-org1d8f74d" class="outline-2">
<h2 id="org1d8f74d">Objetivos</h2>
<div class="outline-text-2" id="text-org1d8f74d">
<p>
Los objetivos no son muy ambiciosos, pero son ampliables. Contado así
deprisa, lo que pretendo es hacer un programa que sea capaz de mostrar
partidas para analizarlas y aprender de ellas. Para ello tiene que:
</p>

<ul class="org-ul">
<li>Mostrar un tablero por pantalla, con las reglas del ajedrez imbuidas en él.</li>
<li>Comprender los formatos más habituales de notación de partidas.</li>
<li>Posibilidad de hacer búsquedas de partidas.</li>
<li>Análisis de partidas.</li>
<li>Posibilidad de programar ejercicios de aprendizaje.</li>
</ul>

<p>
Como objetivo secundario y más a largo plazo hacer un pequeño motor de
juego para poder jugar contra la máquina o que sirva de asistente para
el análisis de las partidas de la base de datos. Sin embargo,
existiendo varios motores de juego ya plenamente probados, como
<a href="https://www.gnu.org/software/chess/">gnuchess</a> u otros.
</p>
</div>
</div>
<div id="outline-container-org592dd0d" class="outline-2">
<h2 id="org592dd0d">Notación</h2>
<div class="outline-text-2" id="text-org592dd0d">
<p>
Es complicado anotar las posiciones o movimientos del ajedrez y a lo
largo del tiempo se han ido proponiendo diferentes formas de hacerlo,
cada uno a su manera. Algunas de estas maneras conviven en la
actualidad y pueden presentarse en diferentes bases de datos. Además
contamos con las diferentes variantes idiomáticas para el nombre de
las piezas y su notación.
</p>

<table>
<caption class="t-above"><span class="table-number">Tabla 1</span> Los nombres de las piezas y su notación según el idioma</caption>

<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">idioma</th>
<th scope="col" class="org-left">peón</th>
<th scope="col" class="org-left">caballo</th>
<th scope="col" class="org-left">alfil</th>
<th scope="col" class="org-left">torre</th>
<th scope="col" class="org-left">dama</th>
<th scope="col" class="org-left">rey</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">Español</td>
<td class="org-left">P (Peón)</td>
<td class="org-left">C (Caballo)</td>
<td class="org-left">A (Alfil)</td>
<td class="org-left">T (Torre)</td>
<td class="org-left">D (Dama)</td>
<td class="org-left">R (Rey)</td>
</tr>

<tr>
<td class="org-left">Portugués</td>
<td class="org-left">P (Peão)</td>
<td class="org-left">C (Cavalo)</td>
<td class="org-left">B (Bispo)</td>
<td class="org-left">T (Torre)</td>
<td class="org-left">D (Dama)</td>
<td class="org-left">R (Rei)</td>
</tr>

<tr>
<td class="org-left">Esperanto</td>
<td class="org-left">P (Peono)</td>
<td class="org-left">Ĉ (Ĉevalo)</td>
<td class="org-left">K (Kuriero)</td>
<td class="org-left">T (Turo)</td>
<td class="org-left">D (Damo)</td>
<td class="org-left">R (Reĝo)</td>
</tr>

<tr>
<td class="org-left">Francés</td>
<td class="org-left">P (Pion)</td>
<td class="org-left">C (Cavalier)</td>
<td class="org-left">F (Fou)</td>
<td class="org-left">T (Tour)</td>
<td class="org-left">D (Dame)</td>
<td class="org-left">R (Roi)</td>
</tr>

<tr>
<td class="org-left">Italiano</td>
<td class="org-left">P (Pedone)</td>
<td class="org-left">C (Cavallo)</td>
<td class="org-left">A (Alfiere)</td>
<td class="org-left">T (Torre)</td>
<td class="org-left">D (Donna)</td>
<td class="org-left">R (Re)</td>
</tr>

<tr>
<td class="org-left">Alemán</td>
<td class="org-left">B (Bauer)</td>
<td class="org-left">S (Springer)</td>
<td class="org-left">L (Laüfer)</td>
<td class="org-left">T (Turm)</td>
<td class="org-left">D (Dame)</td>
<td class="org-left">K (Köning)</td>
</tr>

<tr>
<td class="org-left">Inglés</td>
<td class="org-left">P (Pawn)</td>
<td class="org-left">N (Knight)</td>
<td class="org-left">B (Bishop)</td>
<td class="org-left">R (Rook)</td>
<td class="org-left">Q (Queen)</td>
<td class="org-left">K (King)</td>
</tr>
</tbody>
</table>

<p>
En muchas bases de datos, especialmente las que utilizan el formato
<a href="http://www.saremba.de/chessgml/standards/pgn/pgn-complete.htm">PGN (Portable Game Notation)</a> utilizan los nombres en inglés. Las
notaciones pueden ser:
</p>

<ul class="org-ul">
<li><b>Notación algebraica</b>: Es la más extendida y está estandarizada por
la FIDE, especialmente con su notación inglesa, sin embargo, no es
unitaria y hay varios modos de hacer la anotación:
<ul class="org-ul">
<li>Notación algebraica estándar.</li>
<li>Notación algebraica larga.</li>
<li>Notación algebraica corta.</li>
<li>Notación algebraica mínima.</li>
<li>Notación algebraica de figuras.</li>
<li>Notación algebraica reversible.</li>
<li>Notación algebraica concisa de figuras.</li>
</ul></li>
<li><b>Notación descriptiva</b>: Más tradicional, está en desuso, pero se
sigue encontrando en libros antiguos y la siguen utilizando algunos
jugadores, especialmente los de más edad.</li>
<li><b>Notación numérica de la ICCF</b>: La necesidad de notación fue
especialmente importante para las partidas a través del correo y la
<a href="https://www.iccf.com/">Federación Internacional de Ajedrez por Corresponencia</a> elaboró y
estandarizó una notación numérica que es la oficial en sus
competiciones.</li>
<li><b>Notación de Smith</b>: es una notación sencilla diseñada para ser
reversible que anota la casilla de origen y destino de cada
movimiento y la pieza capturada si es necesario.</li>
<li><b>Notación de coordenadas</b>: Es similar a la notación algebraica pero
no utiliza código para la pieza movida y en lugar de utilizar letras
para las columnas utiliza también números.</li>
</ul>

<p>
Por todo esto, podemos encontrar que las mismas jugadas se pueden
expresar de muy diferentes maneras. Según un ejemplo sacado de la
wikipedia podríamos utilizar las siguientes maneras:
</p>

<table>


<colgroup>
<col  class="org-right">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-right">#.</th>
<th scope="col" class="org-left">Algebraica</th>
<th scope="col" class="org-left">Al. figuras</th>
<th scope="col" class="org-left">Al. larga</th>
<th scope="col" class="org-left">Al. reversible</th>
<th scope="col" class="org-left">Al. corta</th>
<th scope="col" class="org-left">Smith</th>
<th scope="col" class="org-left">Descriptiva</th>
<th scope="col" class="org-left">Coordenadas</th>
<th scope="col" class="org-left">ICCF</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-right">1.</td>
<td class="org-left">e4 e5</td>
<td class="org-left">e4 e5</td>
<td class="org-left">e2e4 e7e5</td>
<td class="org-left">e2-e4 e7-e5</td>
<td class="org-left">e24 e75</td>
<td class="org-left">e2e4 e7e5</td>
<td class="org-left">P4R P4R</td>
<td class="org-left">E2-E4 E7-E5</td>
<td class="org-left">5254 5755</td>
</tr>

<tr>
<td class="org-right">2.</td>
<td class="org-left">Cf3 Cc6</td>
<td class="org-left">♘f3 ♞c6</td>
<td class="org-left">Cg1f3 Cb8c6</td>
<td class="org-left">Cg1-f3 Cb8-c6</td>
<td class="org-left">Cg1f3 Cb8c6</td>
<td class="org-left">g1f3 b8c6</td>
<td class="org-left">C3AR C3Ad</td>
<td class="org-left">G1-F3 B8-C6</td>
<td class="org-left">7163 2836</td>
</tr>

<tr>
<td class="org-right">3.</td>
<td class="org-left">Ab5 a6</td>
<td class="org-left">♗b5 a6</td>
<td class="org-left">Af1b5 a7a6</td>
<td class="org-left">Af1-b5 a7-a6</td>
<td class="org-left">Af1b5 a76</td>
<td class="org-left">f1b5 a7a6</td>
<td class="org-left">A5C P3TD</td>
<td class="org-left">F1-B5 A7-A6</td>
<td class="org-left">6125 1716</td>
</tr>

<tr>
<td class="org-right">4.</td>
<td class="org-left">Axc6 dxc6</td>
<td class="org-left">♗xc6 dxc6</td>
<td class="org-left">Ab5xc6 d7xc6</td>
<td class="org-left">Ab5xNc6 d7xBc6</td>
<td class="org-left">Ab5:Cc6 d7:Ac6</td>
<td class="org-left">b5c6n d7c6b</td>
<td class="org-left">AxC PDxA</td>
<td class="org-left">B5-C6 D7-C6</td>
<td class="org-left">2536 4736</td>
</tr>

<tr>
<td class="org-right">5.</td>
<td class="org-left">d3 Ab4+</td>
<td class="org-left">d3 ♝b4+</td>
<td class="org-left">d2d3 Af8b4+</td>
<td class="org-left">d2-d3 Af8-b4+</td>
<td class="org-left">d23 Af8b4+</td>
<td class="org-left">d2d3 f8b4</td>
<td class="org-left">P3D A5C+</td>
<td class="org-left">D2-D3 F8-B4</td>
<td class="org-left">4243 6824</td>
</tr>

<tr>
<td class="org-right">6.</td>
<td class="org-left">Cc3 Cf6</td>
<td class="org-left">♘c3 ♞f6</td>
<td class="org-left">Cb1c3 Cg8f6</td>
<td class="org-left">Cb1-c3 Cg8-f6</td>
<td class="org-left">Cb1c3 Cg8f6</td>
<td class="org-left">b1c3 g8f6</td>
<td class="org-left">C3A C3A</td>
<td class="org-left">B1-C3 G8-F6</td>
<td class="org-left">2133 7866</td>
</tr>

<tr>
<td class="org-right">7.</td>
<td class="org-left">O-O Axc3</td>
<td class="org-left">O-O ♝xc3</td>
<td class="org-left">O-O Ab4xc3</td>
<td class="org-left">O-O Ab4xNc3</td>
<td class="org-left">O-O Ab4:Cc3</td>
<td class="org-left">e1g1c b4c3n</td>
<td class="org-left">O-O AxC</td>
<td class="org-left">E1-G1 B4-C3</td>
<td class="org-left">5171 2433</td>
</tr>
</tbody>
</table>

<p>
Como se puede observar, hay muchas maneras de indicar los movimientos,
siendo algunos más comprensibles que otros a ojos humanos. Los
símbolos que se suelen utilizar son varios:
</p>

<ul class="org-ul">
<li><b>+</b>: indica <i>jaque</i>.</li>
<li><b>++, #, ≠, ‡</b>: indica <i>jaque mate</i>.</li>
<li><b>O-O, O-O-O</b>: enroque corto y largo, respectivamente.</li>
<li><b>1-0</b>: ganan blancas.</li>
<li><b>0-1</b>: ganan negras.</li>
<li><b>½-½</b>: tablas.</li>
<li><b>!</b>: jugada excepcionalmente buena. Se pueden utilizar varios <b>!!</b> para dar aún más énfasis.</li>
<li><b>?</b>: jugada excepcionalmente mala. Se pueden utilizar varios <b>??</b> para dar aún más énfasis.</li>
</ul>

<p>
Dado que el tablero de ajedrez está dividido en casillas colocadas en
filas y en columnas, se han utilizado varios sistemas de coordenadas
para referirse a ellas. Por ejemplo, en la notación descriptiva las
columnas se denominan como:
</p>

<ul class="org-ul">
<li><b>TR</b>: columna de la <i>torre de rey</i>.</li>
<li><b>CR</b>: columna del <i>caballo de rey</i>.</li>
<li><b>AR</b>: columna del <i>alfil de rey</i>.</li>
<li><b>R</b>: columna del <i>rey</i>.</li>
<li><b>D</b>: columna de la <i>dama</i>.</li>
<li><b>AD</b>: columna del <i>alfil de dama</i>.</li>
<li><b>CD</b>: columna del <i>caballo de dama</i>.</li>
<li><b>TD</b>: columna de la <i>torre de dama</i>.</li>
</ul>

<p>
En este mismo sistema, las filas se numeran desde el punto de vista de
cada jugador, es decir, la fila <code>1</code> del jugador de blancas es la fila
<code>8</code> del jugador de negras y viceversa.
</p>


<figure id="org33de26a">
<img src="./imagenes/tablero.svg" alt="tablero.svg" class="org-svg">

</figure>

<p>
En la esquina superior derecha está el sistema de coordenadas más
utilizado por los distintos sistemas de notación. Abajo a la izquierda
está el sistema de coordenadas del <i>sistema descriptivo</i>. Como se
puede apreciar, este sistema tiene en cuenta la perspectiva del
jugador para la anotación haciendo que las casillas tengan dos
coordenadas distintas dependiendo del jugador. El tercer sistema,
abajo a la derecha, es el <i>sistema de coordenadas</i> utilizado por la
ICCF en partidas por correspondencia.
</p>

<p>
En las partidas por correspondencia además se anota el día de
recepción de la respuesta del contrincante y el día de respuesta.
</p>
</div>
<div id="outline-container-org74b0004" class="outline-3">
<h3 id="org74b0004">Notación de partidas y descripción del tablero</h3>
<div class="outline-text-3" id="text-org74b0004">
<p>
Hay dos tipos de notaciones, la notación de partidas y la descripción
de las posiciones en el tablero. Empecemos por la descripción de las
posiciones en el tablero:
</p>


<ul class="org-ul">
<li>FEN (Notación de Forsyth-Edwars): Consta de seis campos
<ul class="org-ul">
<li>Cadena representando las 8 filas del tablero:
<ul class="org-ul">
<li>El tablero se lee de izquierda a derecha comenzando por la
casilla <code>a8</code>.</li>
<li>Cada fila se separa de la siguiente con el signo <code>/</code>.</li>
<li>Se utiliza la notación de piezas en mayúscula para blancas y en
minúscula para negras.</li>
<li>Las casillas vacías se muestran agrupándolas con un número.</li>
</ul></li>
<li>Indicador de color activo, o a quién le toca mover, <code>b</code> y <code>n</code> si
la notación está en español o <code>w</code> y <code>b</code> si está en inglés (por
poner sólo dos ejemplos).</li>
<li>Indicador de posibilidad de enroques: aparecerá una combinación de
letras, en español serían <code>RDrd</code> o en inglés <code>QKqk</code> que actuarían como
flags de que blancas (en mayúscula) y negras (en minúscula) tienen
capacidad de enrocar aún por alguno de los lados o un <code>-</code> si no.</li>
<li>Casilla de destino al paso. Si no hay casilla de destino aparecerá
un <code>-</code>. La casilla destino aparecerá después de un doble avance de
salida de un peón. Un peón contrario que se encuentre en la fila 3
(para negros) o en la fila 6 (para blancos) puede ejercer la
acción de <i>comer al paso</i>.</li>
<li>Reloj medio de movimiento: Este número es el recuento de medios
movimientos desde el avance de peones o movimientos de captura y
se utiliza para la regla de conteo de 50 movimientos.</li>
<li>Número de jugadas completas: Comienza puesto a 1 y se incrementa
tras cada movimiento de las negras.</li>
</ul></li>
</ul>

<p>
Toda la información se codifica en una sola línea, pero un fichero
acabado en <code>.fen</code> puede contener varias de estas líneas para mostrar
diferentes posiciones de la partida.
</p>

<p>
La notación para la posición inicial de una partida sería:
</p>

<pre class="example" id="org5180aa0">
tcadract/pppppppp/8/8/8/8/PPPPPPPP/TCADRACT b RDrd - 0 1
</pre>

<p>
El formato EPD <i>(Extended Position Description)</i> Es muy similar a FEN,
pero añade una serie de campos de acciones que complementan la
información del tablero.
</p>

<p>
La notación de partidas como vimos antes se puede hacer de variadas
maneras imponiéndose la notación algebraica de un tiempo a esta
parte. La mayoría de las bases de datos que se pueden encontrar en un
formato que se denomina PGN (Portable Game Notation). Por ejemplo, una
partida podría tener la siguiente forma:
</p>

<pre class="example" id="orgd0166be">
[Event "Informal Game"]
[Site "London, England ENG"]
[Date "1851.07.??"]
[Round "-"]
[White "Anderssen, Adolf"]
[Black "Kieseritzky, Lionel"]
[Result "1-0"]

1.e4 e5 2.f4 exf4 3.Bc4 Qh4+ 4.Kf1 b5 5.Bxb5 Nf6 6.Nf3 Qh6 7.d3 Nh5 8.Nh4 Qg5
9.Nf5 c6 10.g4 Nf6 11.Rg1 cxb5 12.h4 Qg6 13.h5 Qg5 14.Qf3 Ng8 15.Bxf4 Qf6
16.Nc3 Bc5 17.Nd5 Qxb2 18.Bd6 Bxg1 19.e5 Qxa1+ 20.Ke2 Na6 21.Nxg7+ Kd8
22.Qf6+ Nxf6 23.Be7# 1-0
</pre>

<p>
Se puede observar dos partes perfectamente diferenciadas: una cabecera
con etiquetas encerradas en <code>[...]</code> con una estructura de <code>[etiqueta
"valor"]</code>, seguida de un bloque con las jugadas que componen la
partida. Cada jugada completa va precedida de su número de orden, con
un punto, y todo está separado por espacios o saltos de línea. Un
fichero <code>.pgn</code> es básicamente un fichero de texto plano con una o
varias partidas. Hay algunos que son un compendio de miles de ellas y
las búsquedas y manejo se hacen tediosos con un editor de texto.
</p>
</div>
</div>
</div>
<div id="outline-container-org3022f62" class="outline-2">
<h2 id="org3022f62">Implementación</h2>
<div class="outline-text-2" id="text-org3022f62">
<p>
¿Por dónde empezar? En principio, se podría pensar que no hace falta
que el tablero sepa las reglas del ajedrez para implementar uno que
sea capaz de cargar esas partidas y estudiarlas o incluso que sirva
para jugar alguna partida. Sería como jugar con un tablero físico con
sus fichas, la madera pintada no tiene consciencia de regla o norma
alguna más allá de quedarse donde la mano la suelte. Sin embargo, al
encontrarse algo como <code>"Ng8"</code> debe saber que es un caballo, pero
además debe saber cuál de los dos que puede tener el jugador puede
mover a la coordenada <code>g8</code>. Por tanto, se hace necesario que el
programa conozca toda la reglamentación del ajedrez.
</p>

<p>
De momento, el proyecto se llama <i>ŝako</i>, <i>ajedrez</i> en Esperanto,
aunque lo escribo <i>shako</i> por si alguna herramienta (no lo he
comprobado) tiene algún problema con caracteres <i>unicode</i> que estén
más allá del <code>ASCII</code>.
</p>

<p>
La forma más sencilla de implementar un tablero es utilizar un <i>array</i>
de 64 caracteres:
</p>

<div class="org-src-container">
<pre class="src src-nim">type
  Tablero* = ref object
    tablero: array[64, char]
</pre>
</div>

<p>
Podemos convertir de manera sencilla una cadena de dos caracteres
alfanuméricos en una posición en ese <i>array</i>. Se podría implementar un
diccionario que buscará la cadena y devolviera un entero con la
posición de la casilla buscada en el <i>array</i>. En mi caso me he
decantado por tener un <i>array</i> con las coordenadas:
</p>

<div class="org-src-container">
<pre class="src src-nim"> const
  coordenadas = [
    "a8", "b8", "c8", "d8", "e8", "f8", "g8", "h8",
    "a7", "b7", "c7", "d7", "e7", "f7", "g7", "h7",
    "a6", "b6", "c6", "d6", "e6", "f6", "g6", "h6",
    "a5", "b5", "c5", "d5", "e5", "f5", "g5", "h5",
    "a4", "b4", "c4", "d4", "e4", "f4", "g4", "h4",
    "a3", "b3", "c3", "d3", "e3", "f3", "g3", "h3",
    "a2", "b2", "c2", "d2", "e2", "f2", "g2", "h2",
    "a1", "b1", "c1", "d1", "e1", "f1", "g1", "h1"]

proc posicion*(t: Tablero, pos: string): char =
  var casilla: uint8 = coordenadas.find(pos).uint8()
  return t.tablero[casilla]
</pre>
</div>

<p>
Así, con poco esfuerzo podemos mostrar el tablero por pantalla
escribiendo el <i>array</i> hacia adelante:
</p>

<div class="org-src-container">
<pre class="src src-nim">const
  tableroInicial = [
    't', 'c', 'a', 'd', 'r', 'a', 'c', 't',
    'p', 'p', 'p', 'p', 'p', 'p', 'p', 'p',
    '.', '.', '.', '.', '.', '.', '.', '.',
    '.', '.', '.', '.', '.', '.', '.', '.',
    '.', '.', '.', '.', '.', '.', '.', '.',
    '.', '.', '.', '.', '.', '.', '.', '.',
    'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P',
    'T', 'C', 'A', 'D', 'R', 'A', 'C', 'T']

proc mostrarTablero*(t: Tablero): string =
  for i in 0 .. 63:
    if (i mod 8) == 0:
      result.add('\n')
    result.add(t.tablero[i])
    result.add(' ')
  return result
</pre>
</div>

<p>
El procedimiento <code>mostrarTablero</code> lo que hace es recorrer el <i>array</i> que
representa el tablero, carácter a carácter y lo va añadiendo a una
cadena dejando un espacio en blanco entre los caracteres y añadiendo
un salto de línea cuando la posición del <i>array</i> sea múltiplo de 8.
</p>

<p>
Para mostrar el tablero desde la posición del jugador de negras se
invierte el proceso:
</p>

<div class="org-src-container">
<pre class="src src-nim">proc mostrarTableroNegras*(t: Tablero): string =
  for i in countdown(63, 0):
    if (i mod 8) == 0:
      result.add(t.tablero[i])
      result.add('\n')
    else:
      result.add(t.tablero[i])
      result.add(' ')
  return result
</pre>
</div>

<p>
Hasta ahora no es mucho, lo que llevo hecho, apenas un par de tests y
cuatro funciones básicas para limpiar el tablero, iniciar uno con el
procedimiento <code>partidaNueva</code>, la posibilidad de obtener la ficha de una
determinada casilla, bien de manera numérica o por coordenada y
algunos tests para comprobar que todo va funcionando. De momento no
enseño mucho el código. Por ejemplo, me he hecho un <i>script</i> en <code>bash</code>
para manejar <code>nimble</code> de manera más sencilla:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #6272a4;">#</span><span style="color: #6272a4;">!/bin/</span><span style="color: #ff79c6; font-weight: bold;">bash</span><span style="color: #6272a4;">
</span>
<span style="color: #ff79c6; font-weight: bold;">function</span> <span style="color: #50fa7b; font-weight: bold;">crear_docs</span> () {
    nimble doc -o:doc/shako.html src/shako.nim
    nimble doc -o:doc/tablero.html src/tablero.nim
}

<span style="color: #ff79c6; font-weight: bold;">if</span> [ $<span style="color: #f8f8f2; font-weight: bold;">1</span> = <span style="color: #f1fa8c;">'run'</span> ] ; <span style="color: #ff79c6; font-weight: bold;">then</span>
    nimble c -r -o:bin/shako src/shako.nim
<span style="color: #ff79c6; font-weight: bold;">fi</span>
<span style="color: #ff79c6; font-weight: bold;">if</span> [ $<span style="color: #f8f8f2; font-weight: bold;">1</span> = <span style="color: #f1fa8c;">'doc'</span> ] ; <span style="color: #ff79c6; font-weight: bold;">then</span>
    crear_docs
<span style="color: #ff79c6; font-weight: bold;">fi</span>
<span style="color: #ff79c6; font-weight: bold;">if</span> [ $<span style="color: #f8f8f2; font-weight: bold;">1</span> = <span style="color: #f1fa8c;">'all'</span> ] ; <span style="color: #ff79c6; font-weight: bold;">then</span>
    nimble test
    nimble c -r -o:bin/shako src/shako.nim
    crear_docs
<span style="color: #ff79c6; font-weight: bold;">fi</span>
<span style="color: #ff79c6; font-weight: bold;">if</span> [ $<span style="color: #f8f8f2; font-weight: bold;">1</span> = <span style="color: #f1fa8c;">'tests'</span> ] ; <span style="color: #ff79c6; font-weight: bold;">then</span>
   nimble test
<span style="color: #ff79c6; font-weight: bold;">fi</span>
<span style="color: #ff79c6; font-weight: bold;">if</span> [ $<span style="color: #f8f8f2; font-weight: bold;">1</span> = <span style="color: #f1fa8c;">'clean'</span> ] ; <span style="color: #ff79c6; font-weight: bold;">then</span>
   rm -rf ./bin
   rm -rf ./doc
<span style="color: #ff79c6; font-weight: bold;">fi</span>
</pre>
</div>

<p>
La salida de todo el proceso, de momento queda así:
</p>

<pre class="example" id="orgdd49e40">
&gt; ./make.sh all
  Verifying dependencies for shako@0.0.1
  Compiling /home/notxor/proyectos/shako/tests/test_tablero (from package shako) using c backend

[Suite] Prueba del módulo «tablero»
  [OK] Un tablero vacío
  [OK] Iniciar tablero a partida nueva
  [OK] Posiciones por cadena de coordenada
   Success: Execution finished
   Success: All tests passed
  Verifying dependencies for shako@0.0.1
  Compiling src/shako (from package shako) using c backend
Tablero en memoria:

t c a d r a c t 
p p p p p p p p 
. . . . . . . . 
. . . . . . . . 
. . . . . . . . 
. . . . . . . . 
P P P P P P P P 
T C A D R A C T 
Tablero desde negras:
T C A R D A C T
P P P P P P P P
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
p p p p p p p p
t c a r d a c t

   Success: Execution finished
  Verifying dependencies for shako@0.0.1
 Generating documentation for src/shako (from package shako) using doc backend
   Success: Execution finished
  Verifying dependencies for shako@0.0.1
 Generating documentation for src/tablero (from package shako) using doc backend
   Success: Execution finished
</pre>
</div>
</div>
<div id="outline-container-org6db5347" class="outline-2">
<h2 id="org6db5347">Conclusiones</h2>
<div class="outline-text-2" id="text-org6db5347">
<p>
De momento, el programa está en mantillas. Si alguien espera poder
analizar partidas con él tendrá que esperar mucho tiempo, por lo que
es recomendable que espere sentado o en posiciones aún más cómodas y
que no olvide hidratarse y alimentarse para poder sobrellevar mucho
mejor la espera. Pero si no puedes esperar, te recomiendo <a href="https://scid.sourceforge.net/">SCID</a>. Que es
más o menos similar a lo que pretendo hacer.
</p>

<p>
Como me he puesto con este proyecto, amenazo con una serie de
artículos sobre su implementación. Avisados estáis. Lo siguiente será
la posibilidad de que entienda mínimamente la notación <i>FEN</i> para poder
iniciar el tablero de una manera más o menos directa. Sería el primer
modo de pasarle partidas e implementar algunas de las reglas básicas
como la de los <i>50 movimientos</i> que dice que la partida se acaba si se
alcanzan 50 movimientos sin que se mueva un peón o sin que una pieza
capture otra, o también las que gobiernan los enroques.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/ajedrez/index.html">Ajedrez</a> <a href="/tags/nim/index.html">nim</a> ]]></description>
  <category><![CDATA[Ajedrez]]></category>
  <category><![CDATA[nim]]></category>
  <link>https://notxor.nueva-actitud.org/2023/03/12/el-ajedrez-y-su-representacion.html</link>
  <pubDate>Sun, 12 Mar 2023 17:50:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Nim, un lenguaje compilado]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-02-28</div>
<p>
Hace un tiempo ya escribí en este <i>blog</i> mi tendencia y gusto por los
<a href="https://notxor.nueva-actitud.org/2022/09/09/lenguajes-repelentes.html">lenguajes interpretados</a>. Suele ser así, pero siempre hace falta tener
a mano algún lenguaje de esos compilados que te saquen de un apuro. Y
porque en la caja de herramientas no sólo debe haber llaves inglesas,
también son necesarias otras, con sus ventajas e inconvenientes,
porque lamentablemente, después de todos estos años, no se ha
inventado aún el <i>lenguaje definitivo</i>. Aunque sí veo a legiones de
<i>fans</i> de tal o cual lenguaje comportarse como si <i>el suyo</i> lo fuera.
Ahora hay que hacerlo todo en [......]<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. Me estoy yendo por las
ramas, en resumen, vamos a lo que importa: llevo unos días,
semanas,usando el <a href="https://nim-lang.org/">lenguaje Nim</a> y vengo a contártelo. Preparamos
<i>Emacs</i> para utilizarlo y comenzamos.
</p>

<p>
Antes de nada, <b>¿qué es <i>Nim</i>?</b>: Pues es un lenguaje de programación
con características muy apetecibles, según su <i>web</i>:
</p>

<ul class="org-ul">
<li><b>Eficiente</b>:
<ul class="org-ul">
<li>Genera ejecutables nativos para <i>Windows</i>, <i>GNU/Linux</i>, <i>macOS</i> y
<i>BSD</i>; sin dependencias externas de librerías o máquinas
virtuales.</li>
<li>Fuertemente <i>tipado</i>.</li>
<li>Gestión de memoria determinista inspirada en C++ y <i>Rust</i> y
adecuada para sistemas embebidos y tiempo real.</li>
<li>No sólo genera ejecutables, también podemos darle salida a otros
lenguajes como C, C++, <i>ObjectiveC</i>, <i>JavasCript</i>.</li>
</ul></li>
<li><b>Expresivo</b>:
<ul class="org-ul">
<li>Gran variedad de tipos que ya son habituales en todos los
lenguajes modernos: listas, tuplas, diccionarios, tipos (objetos),
secuencias, cadenas...</li>
<li>Tan orientado a objetos como funcional, aunque se define como
<i>lenguaje procedural</i>, puedes utilizar el estilo de programación
que más te guste.</li>
<li><i>Macros</i>, <i>templates</i> y <i>generics</i> te permiten definir nuevos
comandos y aspectos del lenguaje para ajustarlo al problema que
necesitas resolver.</li>
</ul></li>
</ul>

<p>
¿Es todo bueno? No..., bueno <i>no sé</i>. Me he encontrado raro, hay cosas
que no terminan de encajarme. Quizá soy muy cuadriculado o quizá
necesito más tiempo para acostumbrarme. Pero antes de entrar en
detalles, vamos con procurarnos el entorno de trabajo.
</p>
<div id="outline-container-orgeed5246" class="outline-2">
<h2 id="orgeed5246">Trabajar en <i>Emacs</i></h2>
<div class="outline-text-2" id="text-orgeed5246">
<p>
Sí, como era de esperar hay paquete para trabajar con <i>Nim</i> en
<i>Emacs</i>, se llama <code>nim-mode</code>... vamos por lo fácil: el código.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> nim-mode            <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Modo mayor para NIM
</span>  <span style="color: #8be9fd; font-style: italic;">:defer</span> t)
(<span style="color: #ff79c6; font-weight: bold;">use-package</span> flycheck-nim        <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Comprobaci&#243;n del c&#243;digo al vuelo
</span>  <span style="color: #8be9fd; font-style: italic;">:defer</span> t)
(<span style="color: #ff79c6; font-weight: bold;">use-package</span> flycheck-nimsuggest <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Comprobaci&#243;n de c&#243;digo utilizando nimsuggest
</span>  <span style="color: #8be9fd; font-style: italic;">:defer</span> t)
(<span style="color: #ff79c6; font-weight: bold;">use-package</span> ob-nim              <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Paquete para ~org-babel~
</span>  <span style="color: #8be9fd; font-style: italic;">:defer</span> t)
(add-hook 'nim-mode-hook 'nimsuggest-mode)
</pre>
</div>

<p>
Nada complicado de entender, simplemente tener los paquetes en el
sistema y añadir un <i>hook</i> para que active el modo <code>nimsuggest-mode</code>
cuando se entre en un archivo <code>nim</code>. <code>nimsuggest</code> es una aplicación
que viene con el propio <i>Nim</i> y que, como su nombre indica, hace
sugerencias al código, tanto para el autocompletado como para la
corrección de errores. Los paquetes de <i>Emacs</i> se sirven de él para
realizar su trabajo. Sin embargo, en la misma documentación dicen que
estos paquetes están en versión <i>alfa</i> y es posible que generen
errores al utilizarlos. Yo, de momento, no me he encontrado mayor
problema, pero es posible que con otra instalación sí los dé. Si
notáis que se enlentece la respuesta de <i>Emacs</i> o se comporta de
manera extraña al abrir archivos de <i>Nim</i>, pues tendréis ese <i>bug</i>.
De todas formas es buena idea ir guardando el trabajo cada poco, no
vayas a hacer tres módulos y 40 funciones, se te congele el editor y
pierdas el trabajo de todo el día.
</p>

<p>
Intenté también instalar <code>lsp</code> pero me da un error al compilar el
<code>nimlsp</code> y no he podido solucionarlo. Luego contaré cómo funciona el
gestor de paquetes de <i>Nim</i>, que es similar a los de otros lenguajes.
</p>

<p>
Las teclas que más he utilizado han sido:
</p>

<ul class="org-ul">
<li><code>M-.</code>: Para saltar a la definición de algún elemento (procedimiento,
variable, tipo...).</li>
<li><code>M-,</code>: Para regresar al punto desde el que saltaste con la tecla
anterior.</li>
<li><code>C-M-i</code>: Llamar a <code>company-nimsuggest</code> para el autocompletado.
Normalmente lo hace de manera automática.</li>
<li><code>C-c C-c</code>: compila y ejecuta un <i>buffer</i> de <i>Nim</i>.</li>
<li><code>C-c C-d</code>: llama a <code>nimsuggest-show-doc</code>, al hacerlo sobre un módulo
de la <i>librería general</i>, abre un <i>buffer</i> de nombre <code>*nim-doc*</code> con
la documentación de dicha librería.</li>
</ul>

<p>
Otro de los servicios que proporciona <code>nim-mode</code> es una pequeña ayuda
o documentación corta que muestra en el <i>minibuffer</i> cuando situamos
el cursor sobre algún símbolo o llamada.
</p>
</div>
</div>
<div id="outline-container-org1fc9eb0" class="outline-2">
<h2 id="org1fc9eb0">Pequeña introducción a <i>Nim</i></h2>
<div class="outline-text-2" id="text-org1fc9eb0">
<p>
Primero un clásico <i>hola mundo</i> algo más complejo que el habitual:
</p>

<div class="org-src-container">
<pre class="src src-nim">import system
const                # Más sobre variables y constantes más adelante
  a: int = 11
  b: int = 4
  c: float = 6.75
  d: float = 2.25

echo "a = ", a
echo "b = ", b
echo "--------------------"
echo "a + b = ", a + b
echo "a - b = ", a - b
echo "a * b = ", a * b
echo "a / b = ", a / b
echo "a div b = ", a div b
echo "a mod b = ", a mod b
echo "--------------------"
echo "c + d = ", c + d
echo "c - d = ", c - d
echo "c * d = ", c * d
echo "c / d = ", c / d
echo "--------------------"
echo "Hola Mundo!"
echo "--------------------"
echo "Eĥoŝanĝo ĉiuĵaŭde"
</pre>
</div>

<p>
Apreciaciones sobre el código anterior:
</p>

<ol class="org-ol">
<li>No hay una función <code>main</code> explícita. Ese código se está comportando
como si fuera un lenguaje de <i>script</i>, pero es compilado.</li>
<li>El indentado de los bloques de código, muy al estilo <i>Python</i>. Se
puede apreciar en el bloque de definición de constantes.</li>
<li><p>
Se declaran las variables con sus tipos. Se puede dejar al
compilador que suponga qué tipo es, pero algunas veces por el valor
no es suficiente. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-nim">let
  enteroPequeño: int8 = 4
  enteroGrande: int64 = 4
  sinSignoPeque: uint8 = 4
  sinSignoGrande: uint64 = 4
</pre>
</div>

<p>
Esas cuatro variables, aunque todas contengan \(4\), son de
diferentes tipos.
</p></li>
<li>Los comentarios comienzan con el símbolo <code>#</code>. Además se pueden
añadir también comentarios que la herramienta de construcción de
documentación extraerá del código con <code>##</code>. También se pueden
realizar comentarios de múltiples líneas encerrándolas entre dos
marcas <code>#[</code> y <code>]#</code>, o su equivalente para añadir documentación
<code>##[</code> y <code>]##</code>.</li>
<li>La importación de módulos se hace con <code>import</code> y el nombre del
módulo. En el ejemplo se podría haber obviado, pues importa un
módulo que ya está importado por defecto. Todo constructo público
que se encuentre en el módulo será importado directamente.</li>
</ol>

<p>
La compilación y ejecución es sencilla, en el <i>buffer</i> de edición
pulsa <code>C-c C-c</code><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. Si eres más de línea de comandos o esperas
algún error, lo mismo prefieres utilizar la consola de texto:
</p>

<pre class="example" id="org374f2e3">
$ nim c -r holamundo.nim
Hint: used config file '/etc/nim/nim.cfg' [Conf]
Hint: used config file '/etc/nim/config.nims' [Conf]
.........................................................
Hint:  [Link]
Hint: gc: refc; opt: none (DEBUG BUILD, `-d:release` generates faster code)
26666 lines; 0.221s; 31.68MiB peakmem; proj: /home/notxor/proyectos/nim-pruebas/holamundo.nim; out: /home/notxor/proyectos/nim-pruebas/holamundo [SuccessX]
Hint: /home/notxor/proyectos/nim-pruebas/holamundo  [Exec]
a = 11
b = 4
--------------------
a + b = 15
a - b = 7
a * b = 44
a / b = 2.75
a div b = 2
a mod b = 3
--------------------
c + d = 9.0
c - d = 4.5
c * d = 15.1875
c / d = 3.0
--------------------
Hola Mundo!
--------------------
Eĥoŝanĝo ĉiuĵaŭde
</pre>
</div>
<div id="outline-container-org7b7b908" class="outline-3">
<h3 id="org7b7b908">Declaración de variables y constantes</h3>
<div class="outline-text-3" id="text-org7b7b908">
<p>
La definición de variables y contantes cuenta con tres palabras clave:
</p>

<ul class="org-ul">
<li><code>const</code>: Establece valores que no pueden variar durante la ejecución
del programa. El valor debe ser conocido o se debe poder establecer
en <i>tiempo de compilación</i>.</li>
<li><code>let</code>: Establece valores que no pueden variar durante la ejecución
del programa. No es necesario conocer el valor al compilar y se
puede calcular en <i>tiempo de ejecución</i>, pero una vez establecido el
valor, este no puede variar.</li>
<li><code>var</code>: Define una variable que admite cambios durante la ejecución
de nuestro programa.</li>
</ul>

<p>
Por ver cómo funcionan estos tres tipos de definiciones veamos un
ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-nim">import std/unicode
import std/sequtils
import std/base64

const
  cadena: string = "Eĥoŝanĝo ĉiuĵaŭde"

proc codificar(): string
proc decodificar(): string

let
  encoded: string = codificar()
  decoded: string = decodificar()

var
  runas: seq[Rune]

proc codificar(): string =
  result = encode(cadena)

proc decodificar(): string =
  return decode(encoded)

proc convertirRunas(c: string): seq[Rune] =
  return toRunes(c)

runas = convertirRunas(cadena)

echo cadena
echo runas    # un seq[Rune] y se muestra exactamente como la string

echo("Codificado: ", encoded)
echo("Decodificado: ", decoded)
</pre>
</div>

<p>
Vemos que <code>cadena</code> está definida como constante. Luego, entre el
bloque <code>const</code> y el bloque <code>let</code>, se encuentran las <i>cabeceras</i> de dos
procedimientos que se definen más tarde. Deben estar adelantadas
porque las utilizamos en el bloque <code>let</code> antes de que el compilador
sepa de su existencia. ¿Podría haber evitado estas llamadas? Por
supuesto, pero así no aprendemos :-þ
</p>

<p>
En el bloque <code>var</code> se define un tipo un tanto raro <code>seq[Rune]</code>, que es
una secuencia de <code>Rune</code>. Un <code>Rune</code> es un tipo definido en el módulo
<code>unicode</code>, que en resumen es un <code>int16</code> que representa un carácter
<i>unicode</i>. Como se puede ver en el ejemplo se puede utilizar de manera
similar a una cadena.
</p>

<p>
Si observas la definición del procedimiento <code>codificar</code> verás que en
lugar de devolver el valor con <code>return</code> se utiliza una asignación a
<code>result</code>. Ésta es una variable <i>automágica</i> que está presente en todos
los procedimientos y que se puede utilizar dentro del cuerpo del mismo
para componer una respuesta válida. Es decir, podemos hacer que un
procedimiento devuelva un valor sin un <code>return</code> específico.
</p>
</div>
</div>
<div id="outline-container-org5985a87" class="outline-3">
<h3 id="org5985a87">Tipos complejos y referencias</h3>
<div class="outline-text-3" id="text-org5985a87">
<p>
También puedes utilizar punteros (o referencias) a las variables
utilizando la palabra clave <code>ref</code>. Vamos a poner un ejemplo con un
tipo compuesto.
</p>

<div class="org-src-container">
<pre class="src src-nim">type
  Persona = ref object
    nombre: string
    edad: int

var
  fulanito: Persona

# El orden de los campos se puede cambiar
fulanito = Persona(edad: 37, nombre: "Fulanito de tal")

echo "Nombre: ", fulanito.nombre
echo "Edad: ", $fulanito.edad

fulanito.edad += 3
doAssert fulanito.edad == 40

# Conversión a cadena y concatenación
echo "Edad cambiada: " &amp; $fulanito.edad

proc ponNombre(p: Persona, nombre: string) =
  p.nombre = nombre

fulanito.ponNombre("Pepe")
echo "Ahora se llama: ", fulanito.nombre

var
  menganito: Persona

new(menganito)
ponNombre(menganito, "Menganito")
doAssert menganito.nombre == "Menganito"
echo menganito[]
</pre>
</div>

<p>
Se puede observar que en el bloque <code>type</code> se define una referencia a
<i>objeto</i> <code>Persona</code>. Pongo <i>objeto</i> en cursiva porque no es en realidad
un objeto como se entiende para la programación orientada a
objetos. Está más cercano a lo que sería una <code>struct</code> en C/C++. Después
definimos un procedimiento que toma como argumentos un tipo <code>Persona</code>
y una cadena. Puesto que <code>Persona</code> es en realidad una referencia, el
argumento se puede modificar dentro del procedimiento. Algo que no
termina de gustarme, pero que es posible hacer para acercar un poco la
POO a través de <i>azúcar sintáctico</i>:
</p>

<div class="org-src-container">
<pre class="src src-nim">fulanito.ponNombre("Pepe")
</pre>
</div>

<p>
Pero el procedimiento está definido, aparentemente para:
</p>

<div class="org-src-container">
<pre class="src src-nim">ponNombre(fulanito, "Pepe")
</pre>
</div>

<p>
Y es cierto, la definición es la segunda, pero el lenguaje nos
proporciona un poco de <i>azúcar sintáctico</i> para poder escribirlo de la
primera forma. Hay que fijarse que es sólo <i>azúcar</i>, porque en
realidad, la función no está dentro del tipo. Para que lo estuviera
debería tener un campo de tipo <code>proc</code>. También se podría haber
solicitado espacio en memoria para la variable con <code>new</code> o manejando
las funciones internas <code>alloc</code>, <code>dealloc</code>, o <code>realloc</code>, que les
sonarán a los programadores de C y que están definidas en el módulo
<code>system</code>.
</p>

<p>
La última línea de código:
</p>

<div class="org-src-container">
<pre class="src src-nim">echo menganito[]
</pre>
</div>

<p>
Puede llamar la atención. Lo que hace la notación <code>[]</code> es
<i>desreferenciar</i> un objeto.
</p>

<p>
Aunque no sea 100% un lenguaje orientado a objetos, también nos
permite utilizar un poco de <i>herencia</i> entre los tipos:
</p>

<div class="org-src-container">
<pre class="src src-nim">type
  Persona = ref object of RootObj
    nombre*: string
    edad: int

  Estudiante = ref object of Persona # Student inherits from Person
    notas*: seq[float]

var
  jaimito: Estudiante
  persona: Persona

assert(jaimito of Estudiante)

jaimito = Estudiante(nombre: "Jaimito", edad: 7, notas: @[2.3, 0.1])
echo jaimito[]
</pre>
</div>
</div>
</div>
<div id="outline-container-org7ea0e2c" class="outline-3">
<h3 id="org7ea0e2c">Un vistazo general a otras características</h3>
<div class="outline-text-3" id="text-org7ea0e2c">
<p>
El siguiente bloque de código presenta por encima algunas otras
características del lenguaje, cómo hacer referencias, sobrecarga de
funciones, derreferenciar variables, construir operadores, comprobar
tipos, utilización de <code>pragma</code>... un bloque completito para lo corto
que es:
</p>

<div class="org-src-container">
<pre class="src src-nim">type
  Humano = object
    nombre: string
    edad: int

var
  juanito, zutanito: ref Humano

var
  ejemplo = Humano(nombre: "Pepito", edad: 30)

# Procedimiento para mostrar información. Sólo lo hará si la variabl
# `debug` declarada con anterioridad está a `true`. Utiliza el pragma
# `inline` para decirle al compilador que declare y compile la función
# de esa manera
var debug = false
proc log(mensaje: string) {.inline.} =
  if debug: stdout.writeLine(mensaje) # no sólo de echo vive el Hombre

# Crea una referencia a un objeto Humano a partir de datos
proc crearHumano(nombre: string, edad: int): ref Humano =
  result = new(Humano)
  result.nombre = nombre
  result.edad = edad

# Crea una referencia a un objeto Humano a partir de un objeto
proc crearHumano(quien: Humano): ref Humano =
  result = new(Humano)
  result.nombre = quien.nombre
  result.edad = quien.edad

log("Esto no debería mostrarse por pantalla.")

juanito = crearHumano("Juanito", 25)
zutanito = crearHumano(ejemplo)

proc `$`(quien: ref Humano): string =
  "Referencia a: (nombre: " &amp; quien.nombre &amp; ", edad: " &amp; $quien.edad &amp; ")"

when isMainModule:
  debug = true    # Activamos la información de salida con el procedimiento `log`

  echo ejemplo  # Humano de ejemplo para copiarlo en una referencia

  if zutanito is Humano:
    log("Zutanito tiene los valores: " &amp; $zutanito)

  if juanito is ref Humano:
    log("Juanito tiene los valores: " &amp; $juanito)

  # Derreferenciar los Humanos para mostrarlos o asignarlos
  echo juanito[]
  echo zutanito[]
  # Nombres de variables camelCase y snake_case intercambiables
  var otraVezJuanito: Humano = juanito[]
  echo otra_vez_juanito
</pre>
</div>

<p>
Para construir operadores se utiliza la sintaxis <code>`operador`</code>. En
<i>Nim</i> para convertir una variable en una cadena se utiliza el operador
<code>$</code> y en el código lo define para el tipo <code>ref Humano</code>. A partir de
ahí se puede utilizar con cualquier objeto de ese tipo para ver su
contenido. Se puede observar que la comprobación de tipos se realiza
con el operador <code>is</code>.
</p>

<p>
Los <code>pragma</code> proporcionan información adicional al compilador. Hay
muchos definidos y se pueden definir más. Tienen la estructura
<code>{.nombre.}</code>, en el código anterior se utiliza <code>{.inline.}</code> para
decirle al compilador que esa función debería compilarse como una
función <code>inline</code> de C.
</p>

<p>
Por último, una característica extraña es que los nombres de las
variables son intercambiables entre <i>camelCase</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> y <i>snake_case</i> de
manera que puedes escribirlas como mejor te parezca. Lo cual no deja
de ser sorprendente y extraño. Algo a lo que te tienes que acostumbrar
pero que si tienes un estilo definido y trabajas solo, puedes obviar.
</p>
</div>
</div>
</div>
<div id="outline-container-org732c26e" class="outline-2">
<h2 id="org732c26e">Metaprogramación</h2>
<div class="outline-text-2" id="text-org732c26e">
<p>
La amplitud que proporciona un artículo, de tamaño razonable, no
permite extendernos mucho sobre la <i>metaprogramación</i>, que se realiza
fundamentalmente de tres maneras: <code>generics</code>, <code>templates</code> y <code>macros</code>.
</p>

<p>
Las funciones genéricas son funciones que se escriben para ser
utilizadas con distintos tipos de datos. Se suele utilizar el tipo
genérico <code>T</code> para identificarlos. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-nim">proc loQueSea[T](i: T): string =
  "El valor de i es: " &amp; $i

echo loQueSea(42)
</pre>
</div>

<p>
Los <i>templates</i> lo que hacen es crear plantillas. Lo que hace el
ejemplo anterior sería una <i>template</i> pero utilizando también tipos
genéricos. Por poner un ejemplo sencillo sin utilizar tipos genéricos
podríamos definir un operador, tal que:
</p>

<div class="org-src-container">
<pre class="src src-nim">template `!=`(a, b: untyped): untyped =
  not (a == b)

assert(5 != 6) # reescribe el código a assert(not (5 == 6))
</pre>
</div>

<p>
Y por último los <i>macros</i> son capaces de generar código al estilo de
como funcionan los <i>macros</i> de <i>Lisp</i>. En el caso de <i>Lisp</i> el código
generado era una cadena que se pueda pasar al intérprete del lenguaje,
en el caso de <i>Nim</i> debe generarse un <i>árbol sintáctico</i>. Por ejemplo,
a efectos de ver cómo es un árbol sintáctico y cómo se puede
representar, copio aquí un ejemplo sencillo tomado del tutorial de la
página del lenguaje:
</p>

<div class="org-src-container">
<pre class="src src-nim">import std/macros

macro myAssert(arg: untyped): untyped =
  echo arg.treeREpr

let a = 1
let b = 2

myAssert(a != b)
</pre>
</div>

<p>
Los <i>macros</i> pueden recibir como argumentos bloques de código para
hacerlos aún más potentes. Pero toda potencia implica también un poco
de responsabilidad y si cualquier funcionalidad puede ser implementada
a través de <i>templates</i> o <i>generics</i>, es mejor utilizas éstas y evitar
el uso de <i>macros</i> en el código.
</p>

<p>
Por último, aunque los macros pueden iniciar procesos externos en la
<i>shell</i>, no pueden llamar a funciones de C, excepto a las que ya
contiene el compilador.
</p>
</div>
</div>
<div id="outline-container-orga003b36" class="outline-2">
<h2 id="orga003b36">Conclusiones</h2>
<div class="outline-text-2" id="text-orga003b36">
<p>
<i>Nim</i> me ha parecido un lenguaje lleno de posibilidades. Encuentro
extrañas algunas decisiones de diseño, como el asunto de la
equivalencia de nombres de variables y funciones, entre el <i>camel
case</i> y el <i>snake case</i> y que se pueda llamar <code>estaVariable</code> o
<code>esta_variable</code> indistintamente, dentro del código.
</p>

<p>
Es un lenguaje muy expresivo y aunque no puedo decir que lo domine,
todos los ejemplos que he probado a hacer, especialmente para ir
mostrando características mediante código para este artículo, han
funcionado muy bien.
</p>

<p>
He tenido que dejar en el tintero muchas cosas, como la compilación
cruzada entre sistemas, la capacidad de utilizar como objetivo
procesadores concretos, poder embeber código en <i>ensamblador</i>, etc.
</p>

<p>
Quizá necesite afianzarlo más con algún proyecto de esos sencillos que
me gusta afrontar para ponerme ante el reto de aprender un nuevo
lenguaje con más profundidad. Como hice <a href="https://notxor.nueva-actitud.org/tags/raytrace/index.html">el <i>raytracer</i></a> en <code>erlang</code> o
la implementación del <a href="https://notxor.nueva-actitud.org/tags/criptografia/index.html">algoritmo de cifrado RSA</a> en <i>Tcl</i>. En estos
días, un amigo me sugirió que hiciera algo sobre <i>ajedrez</i> otra de
esas cosas que me gustan... así que a lo mejor le hago caso y os
<i>cansino</i> un poco con ello.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ponga aquí el lenguaje que más le guste: Rust, Go, Python,
Ruby, Haskell... 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Si habéis instalado el paquete <code>ob-nim</code> podéis ejecutarlo
dentro de un bloque de código en <code>org-mode</code> y obtener el resultado
pulsando también <code>C-c C-c</code>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Observa que es <i>camelCase</i> y no <i>PascalCase</i>. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/nim/index.html">nim</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[nim]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2023/02/28/nim-un-lenguaje-compilado.html</link>
  <pubDate>Tue, 28 Feb 2023 17:01:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Lenguajes ligeros de marcas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-02-08</div>
<p>
El otro día estaba escribiendo algo y un conocido, bienintencionado,
me advirtió que el <i>markdown</i> que estaba utilizando no era el
estándar: «es <code>org-mode</code>...», repliqué. Después de una corta
conversación me quedó claro que no había mucha idea de lo que son los
<i>lenguajes ligeros de marcas</i>, que <i>markdown</i> tampoco fue el primero,
ni está estandarizado, y todos los esfuerzos por estandarizarlo han
quedado en propuestas que deben seguir todos los mortales por
sugerencia de su correspondiente autor. Y efectivamente, <code>org-mode</code> no
es más que otra <i>sugerencia</i>, para mí la mejor<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, y no la conoce
la gente a no ser que se mueva en el <i>minoritario</i> mundo de
<i>Emacs</i>. Pues en este artículo voy a hablar un poco sobre este tipo de
lenguajes y a compararlos mínimamente, explicando por qué prefiero
<code>org</code>.
</p>

<p>
Para empezar, estos lenguajes de marcas, los llamados <i>ligeros</i>,
suelen utilizar como objetivo otros lenguajes como el <code>html</code>, el
<code>xhtml</code> o el <code>xml</code>, también salidas a <i>LaTeX</i> (muchas veces como
lenguaje intermediario) o <code>pdf</code>. La lista de los lenguajes ligeros de
marcas es larga:
</p>

<ul class="org-ul">
<li>AciiDoc</li>
<li>BBCode</li>
<li>Creole</li>
<li>Gemtext</li>
<li>GitHub Flavored Markdown</li>
<li>Jira formatting Notation</li>
<li>Markdown</li>
<li>Markdown extra</li>
<li>Media Wiki</li>
<li>MultiMarkdown</li>
<li>Org-mode</li>
<li>PmWiki</li>
<li>POD</li>
<li>reStructuredtext</li>
<li>setext</li>
<li>Slack</li>
<li>TiddlyWiki</li>
<li>Textile</li>
<li>Texy</li>
<li>txt2tags</li>
</ul>

<p>
También existe el <i>anillo único para atarlos a todos en las
tinieblas</i>:
</p>
<p target="_blank">
<a href="https://pandoc.org" target="_blank">Pandoc</a>
</p>

<p>
Esta herramienta es capaz de interpretar documentos de <i>casi</i>
cualquier tipo de entrada y convertirlo a <i>casi</i> cualquier otro tipo
de salida. Convirtiendo entre los distintos formatos también.
</p>

<p>
Muchos proyectos utilizan <i>markdown</i>, pensando que es el <i>anillo
único</i>. El problema es que no es unitario, hay muchos distintos y cada
uno hace de su capa un sayo. Cada sistema puede diferir sobre cómo se
definen las cabeceras, o los bloques de texto, o las listas... por
otro lado tienes que ir metiendo código <code>html</code> directamente para las
tablas o las figuras o cualquier tipo de párrafo especial al que dar
formato. Y si terminas metiendo código <code>html</code> directamente, olvídate
de que tenga una salida a <i>LaTeX</i> decente, por ejemplo.
</p>

<p>
Por otro lado, también hay que recordar que esto de tener documentos
<i>fuente</i> para varias salidas es una facilidad para el <i>escritor</i>, pero
una (gran) pérdida para el posible lector. Lo habitual es que estas
herramientas generen unos acabados mediocres en todos sus documentos.
Digo todos, incluyendo <code>org-mode</code>, aunque éste te deja sortear el
problema del acabado a través de la publicación y las plantillas.
</p>
<div id="outline-container-org5a8ddf0" class="outline-3">
<h3 id="org5a8ddf0">Salidas</h3>
<div class="outline-text-3" id="text-org5a8ddf0">
<p>
Generar distintas salidas es un punto a favor cuando quieres ahorrar
trabajo cuando estás creando algún tipo de documentación. Sobre todo
para los programadores, cuya tendencia a escribir la documentación de
sus programas tiende a cero con límite -1. Puedes darte con un canto
en los dientes si escriben comentarios en el código. Para centrar un
poco las cosas, aquí va una pequeña lista de los lenguajes ligeros de
marcas: son los que he usado, pero hay decenas de ellos y tenía que
resumir de algún modo.
</p>

<table>
<caption class="t-above"><span class="table-number">Tabla 1</span> Formatos de salida para cada lenguaje de marcas ligero.</caption>

<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">lenguaje</th>
<th scope="col" class="org-left">HTML</th>
<th scope="col" class="org-left"><i>LaTeX</i></th>
<th scope="col" class="org-left">PDF</th>
<th scope="col" class="org-left">DocBook</th>
<th scope="col" class="org-left">ODF</th>
<th scope="col" class="org-left">EPUB</th>
<th scope="col" class="org-left">DOCX</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">Asciidoc</td>
<td class="org-left">Sí</td>
<td class="org-left">Sí</td>
<td class="org-left">Sí</td>
<td class="org-left">Sí</td>
<td class="org-left">Sí</td>
<td class="org-left">Sí</td>
<td class="org-left">no</td>
</tr>

<tr>
<td class="org-left">Markdown</td>
<td class="org-left">Sí</td>
<td class="org-left">A<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup></td>
<td class="org-left">A<sup><a id="fnr.2.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup></td>
<td class="org-left">A<sup><a id="fnr.2.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup></td>
<td class="org-left">A<sup><a id="fnr.2.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup></td>
<td class="org-left">A<sup><a id="fnr.2.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup></td>
<td class="org-left">A<sup><a id="fnr.2.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup></td>
</tr>

<tr>
<td class="org-left">org-mode</td>
<td class="org-left">Sí</td>
<td class="org-left">Sí</td>
<td class="org-left">Sí</td>
<td class="org-left">Sí</td>
<td class="org-left">Sí</td>
<td class="org-left">Sí</td>
<td class="org-left">Sí</td>
</tr>

<tr>
<td class="org-left">reST</td>
<td class="org-left">Sí</td>
<td class="org-left">Sí</td>
<td class="org-left">Sí</td>
<td class="org-left">Sí</td>
<td class="org-left">Sí</td>
<td class="org-left">Sí</td>
<td class="org-left">Sí</td>
</tr>

<tr>
<td class="org-left">Textile</td>
<td class="org-left">Sí</td>
<td class="org-left">no</td>
<td class="org-left">no</td>
<td class="org-left">no</td>
<td class="org-left">no</td>
<td class="org-left">no</td>
<td class="org-left">no</td>
</tr>

<tr>
<td class="org-left">Tiddlywiki</td>
<td class="org-left">Sí</td>
<td class="org-left">no</td>
<td class="org-left">no</td>
<td class="org-left">no</td>
<td class="org-left">no</td>
<td class="org-left">no</td>
<td class="org-left">no</td>
</tr>
</tbody>
</table>

<p>
Como ya dije esto es una ventaja para el que escribe, pero no para el
usuario de la documentación. Para que quede una documentación impresa
decente al final le tienes que dar algunos toques al <i>LaTeX</i> que pueda
generar la herramienta... para que quede un <i>epub</i> decente hay que
echarle también un rato a la edición del mismo, algo de <code>css</code> y otros
aspectos que hagan un archivo más redondo que el que pueden generar
estas herramientas <i>automágicamente</i>.
</p>

<p>
Por otro lado, algunos de estos lenguajes no cuentan con una única
implementación, sino varias. Esto es cierto, especialmente, para
<i>MarkDown</i> que tiene, prácticamente, una en cada lenguaje de
programación.  Esto hace que esté muy extendido entre programadores,
pero las salidas que genera también dependen de qué lenguaje o
implementación concreta estemos hablando. Por ejemplo, a <code>html</code>
exportan todas las implementaciones, pero luego, al resto de formatos
puedes encontrarte que no.  Además cada una hace de su capa un sayo y
algunos de los elementos se comportan de manera distinta y cambian la
sintaxis.
</p>

<p>
Después de pelearme con todas estas cosas, llegó un día que encontré
<code>org-mode</code>. Hace la mismas cosas que <code>markdown</code> o que
<code>reStructuredText</code> pero añade muchas más. No sólo generando
documentación, donde es capaz de exportar a casi cualquier formato
(por no decir a <i>todos</i>, que seguramente lo hace pero no lo he
probado) o de generar cualquier tipo de fichero: <code>txt</code>, <code>pdf</code>, <code>odt</code>,
<code>docx</code>, pero también <code>texi</code>, <code>man</code>, <code>groff</code>, <code>iCalendar</code>. Además de
todo eso, decía, es capaz de muchas cosas más: gestionar datos,
gestionar la agenda, capturar notas...
</p>

<p>
La forma más efectiva de trabajar con <code>org-mode</code> es su capacidad de
<i>publicación</i>, un pequeño listado de código en <code>elisp</code> que nos permite
generar la salida de un documento completo en casi cada uno de esos
formatos. Como he dicho antes, las salidas automáticas suelen carecer
de un buen diseño, pero en <code>org-mode</code> esto es salvable gracias a las
<i>plantillas</i> y a la herramienta de <i>publicación</i>. Pocas veces he
tenido que hacer cambios, desde que lo uso. Sobre ese sistema de
<i>publicación</i> está montado este <i>blog</i>. Con unos simples comandos se
genera todos los documentos <code>html</code> y <code>xml</code> (<i>rss</i>) que componen esta
página web.
</p>
</div>
</div>
<div id="outline-container-orgcec08e3" class="outline-3">
<h3 id="orgcec08e3">Funcionamiento</h3>
<div class="outline-text-3" id="text-orgcec08e3">
<p>
Los lenguajes ligeros de marcas no utilizan etiquetas, sino caracteres
para conseguir realizar su trabajo. Se parecen mucho unos a otros,
pero no son idénticos. Un resumen de los efectos tipográficos más
habituales sería esta tabla:
</p>

<table>
<caption class="t-above"><span class="table-number">Tabla 2</span> Marcas ligeras de tipos de letra habituales utilizados en los documentos</caption>

<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">lenguaje</th>
<th scope="col" class="org-left">negrita</th>
<th scope="col" class="org-left">cursiva</th>
<th scope="col" class="org-left">tachado</th>
<th scope="col" class="org-left">subrayado</th>
<th scope="col" class="org-left">fijo</th>
<th scope="col" class="org-left">código</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">Asciidoc</td>
<td class="org-left"><code>*...*</code></td>
<td class="org-left"><code>'...'</code></td>
<td class="org-left">etiqueta<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup></td>
<td class="org-left">etiqueta<sup><a id="fnr.3.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup></td>
<td class="org-left"><code>`...`</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Markdown</td>
<td class="org-left"><code>**...**</code></td>
<td class="org-left"><code>*...*</code></td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>`...`</code></td>
<td class="org-left"><code>```...```</code></td>
</tr>

<tr>
<td class="org-left">org-mode</td>
<td class="org-left"><code>*...*</code></td>
<td class="org-left"><code>/.../</code></td>
<td class="org-left"><code>+...+</code></td>
<td class="org-left"><code>_..._</code></td>
<td class="org-left"><code>~...~</code></td>
<td class="org-left"><code>=...=</code></td>
</tr>

<tr>
<td class="org-left">ReST</td>
<td class="org-left"><code>**...**</code></td>
<td class="org-left"><code>*...*</code></td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>``...``</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Textile</td>
<td class="org-left"><code>*...*</code></td>
<td class="org-left"><code>_..._</code></td>
<td class="org-left"><code>-...-</code></td>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>@...@</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Tiddlywiki</td>
<td class="org-left"><code>''...''</code></td>
<td class="org-left"><code>//...//</code></td>
<td class="org-left"><code>~~...~~</code></td>
<td class="org-left"><code>__...__</code></td>
<td class="org-left"><code>`...`</code></td>
<td class="org-left"><code>```...```</code></td>
</tr>
</tbody>
</table>

<p>
En esta tabla sólo he mostrado los lenguajes que he utilizado alguna
vez y las distintas notaciones que he tenido que aprender y memorizar.
Algunas muy similares y otras muy distintas. Algunas muy completas y
otras algo escasas y que deben, finalmente, utilizar etiquetas <i>no tan
ligeras</i>, para obtener los mismos resultados. <i>AsciiDoc</i>, por ejemplo,
define sus propias etiquetas, pero otros lenguajes como <i>Markdown</i> te
permiten utilizar las de <code>html</code>.
</p>
</div>
</div>
<div id="outline-container-org6a1a630" class="outline-2">
<h2 id="org6a1a630">Conclusión</h2>
<div class="outline-text-2" id="text-org6a1a630">
<p>
De momento, hasta que se invente algo mejor, me quedo con <code>org-mode</code>:
es completo, sencillo, expresivo, permite desde escribir simples anotaciones a
escribir libros, permite introducir notas al pie, cualquier tipo de
tipografía, enlaces internos a cabeceras, tablas, figuras o bloques de
código, exporta a una infinidad de salidas, permite llevar la agenda,
conectarse por <i>CalDav</i> a calendarios externos, controlar tiempos...
</p>

<p>
La ventaja de <code>org-mode</code> es su <i>sistema de publicación</i>. Con unas
pocas líneas de código <code>elisp</code> puedes controlar, plantillas, archivos
auxiliares sistema de exportación, etc. y lo convierte en una <i>navaja
suiza</i> de la edición. Si a esta <i>navaja suiza</i> (<code>org-mode</code>) le añades
el <i>poder del anillo único</i> (<i>Pandoc</i>) puedes generar cualquier tipo
de documento que puedas necesitar.
</p>

<p>
Seguramente esa flexibilidad la agradecerán todos aquellos que
necesitan escribir documentación y quieren proporcionarla en varios
formatos asequibles. <code>org-mode</code> nos permite cuidar las diferentes
salidas de dicha documentación.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Notas al pie de p&aacute;gina: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Para mí la más completa y flexible.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Depende de la implementación. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Utiliza etiquetas para generar <code>html class</code>. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/org-mode/index.html">org-mode</a> <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/markdown/index.html">markdown</a> <a href="/tags/asciidoc/index.html">asciidoc</a> ]]></description>
  <category><![CDATA[org-mode]]></category>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[markdown]]></category>
  <category><![CDATA[asciidoc]]></category>
  <link>https://notxor.nueva-actitud.org/2023/02/08/lenguajes-ligeros-de-marcas.html</link>
  <pubDate>Wed, 08 Feb 2023 10:58:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[armory3D y haxe]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-02-03</div>
<p>
Este artículo también podría llamarse <a href="https://armory3d.org/">Armory, un gamengine para
blender</a> pero resulta que fracasé en el intento de compilarlo en mi
máquina. Supongo que seré muy torpe, pero el <i>README</i> donde da las
instrucciones tampoco aclara mucho y haciendo lo que dice he sido
incapaz de conseguir compilar <code>armorlab</code>. A pesar de no haberlo
conseguido (aún), encontré un lenguaje de esos raros y <i>minoritarios</i>
de los que me gustan, o me suelen gustar, o me gusta chafardear. Así
que este artículo va sobre este lenguaje y cómo configurar nuestro
<i>Emacs</i> para darle soporte, con una introducción a mi fracaso inicial
con <i>Armory3D</i>.
</p>
<div id="outline-container-orgcdf5c61" class="outline-2">
<h2 id="orgcdf5c61">Compilando armorlab</h2>
<div class="outline-text-2" id="text-orgcdf5c61">
<p>
Nada más comenzar, primer error:
</p>

<div class="org-src-container">
<pre class="src src-bash">&gt; armorcore/Kinc/make --from armorcore -g opengl --compiler clang --compile
Unknown platform <span style="color: #f1fa8c;">'linux'</span>, please edit Tools/platform.sh
&gt; find . -name <span style="color: #f1fa8c;">"platform.sh"</span>
./armorcore/Kinc/Tools/platform.sh
&gt; emacs -nw ./armorcore/Kinc/Tools/platform.sh
</pre>
</div>

<p>
Después de abrir el fichero <code>platform.sh</code> me encontré el siguiente
contenido:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #ff79c6; font-weight: bold;">if</span> [[ <span style="color: #f1fa8c;">"$OSTYPE"</span> == <span style="color: #f1fa8c;">"linux-gnu"</span>* ]]; <span style="color: #ff79c6; font-weight: bold;">then</span>
    <span style="color: #f8f8f2; font-weight: bold;">MACHINE_TYPE</span>=<span style="color: #fa8072;">`uname -m`</span>
    <span style="color: #ff79c6; font-weight: bold;">if</span> [[ <span style="color: #f1fa8c;">"$MACHINE_TYPE"</span> == <span style="color: #f1fa8c;">"armv"</span>* ]]; <span style="color: #ff79c6; font-weight: bold;">then</span>
        <span style="color: #f8f8f2; font-weight: bold;">KINC_PLATFORM</span>=linux_arm
    <span style="color: #ff79c6; font-weight: bold;">elif</span> [[ <span style="color: #f1fa8c;">"$MACHINE_TYPE"</span> == <span style="color: #f1fa8c;">"aarch64"</span>* ]]; <span style="color: #ff79c6; font-weight: bold;">then</span>
        <span style="color: #f8f8f2; font-weight: bold;">KINC_PLATFORM</span>=linux_arm64
    <span style="color: #ff79c6; font-weight: bold;">elif</span> [[ <span style="color: #f1fa8c;">"$MACHINE_TYPE"</span> == <span style="color: #f1fa8c;">"x86_64"</span>* ]]; <span style="color: #ff79c6; font-weight: bold;">then</span>
        <span style="color: #f8f8f2; font-weight: bold;">KINC_PLATFORM</span>=linux_x64
    <span style="color: #ff79c6; font-weight: bold;">else</span>
        <span style="color: #8be9fd; font-style: italic;">echo</span> <span style="color: #f1fa8c;">"Unknown Linux machine '$MACHINE_TYPE', please edit Tools/platform.sh"</span>
        <span style="color: #ff79c6; font-weight: bold;">exit</span> 1
    <span style="color: #ff79c6; font-weight: bold;">fi</span>
<span style="color: #ff79c6; font-weight: bold;">elif</span> [[ <span style="color: #f1fa8c;">"$OSTYPE"</span> == <span style="color: #f1fa8c;">"darwin"</span>* ]]; <span style="color: #ff79c6; font-weight: bold;">then</span>
        <span style="color: #f8f8f2; font-weight: bold;">KINC_PLATFORM</span>=macos
<span style="color: #ff79c6; font-weight: bold;">elif</span> [[ <span style="color: #f1fa8c;">"$OSTYPE"</span> == <span style="color: #f1fa8c;">"FreeBSD"</span>* ]]; <span style="color: #ff79c6; font-weight: bold;">then</span>
        <span style="color: #f8f8f2; font-weight: bold;">KINC_PLATFORM</span>=freebsd_x64
<span style="color: #ff79c6; font-weight: bold;">elif</span> [[ <span style="color: #f1fa8c;">"$OSTYPE"</span> == <span style="color: #f1fa8c;">"msys"</span>* || <span style="color: #f1fa8c;">"$OSTYPE"</span> == <span style="color: #f1fa8c;">"cygwin"</span>* ]]; <span style="color: #ff79c6; font-weight: bold;">then</span>
        <span style="color: #f8f8f2; font-weight: bold;">KINC_PLATFORM</span>=windows_x64
        <span style="color: #f8f8f2; font-weight: bold;">KINC_EXE_SUFFIX</span>=.exe
<span style="color: #ff79c6; font-weight: bold;">else</span>
        <span style="color: #8be9fd; font-style: italic;">echo</span> <span style="color: #f1fa8c;">"Unknown platform '$OSTYPE', please edit Tools/platform.sh"</span>
        <span style="color: #ff79c6; font-weight: bold;">exit</span> 1
<span style="color: #ff79c6; font-weight: bold;">fi</span>
</pre>
</div>

<p>
Como veis en el error, el <code>$OSTYPE</code> que devuelve mi sistema es <code>linux</code>
y el que espera el chismático es <code>linux-gnu</code>. Lo que hice fue, puesto
que sabía que el que necesitaba era <code>linux_x64</code>, añadir otro <code>elif</code>
como el del siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #ff79c6; font-weight: bold;">elif</span> [[ <span style="color: #f1fa8c;">"$OSTYPE"</span> == <span style="color: #f1fa8c;">"linux"</span>* ]]; <span style="color: #ff79c6; font-weight: bold;">then</span>
  <span style="color: #f8f8f2; font-weight: bold;">KINC_PLATFORM</span>=linux_x64
</pre>
</div>

<p>
Después empecé a ver varios errores que pedían librerías que estaban
instaladas y no entendía muy bien qué estaba pasando. Luego me di
cuenta, cuando profundicé un poquito en <code>haxe</code>, que me faltaban
algunas librerías del lenguaje y no de <code>c++</code>, como pensé al
principio. Por tanto, con <code>haxelib</code> instalé las librerías del lenguaje
<code>hxcpp</code> y <code>zip</code>.
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; haxelib install hxcpp &amp; haxelib install zip
</pre>
</div>

<p>
Esto me hace superar esos primeros errores que aparecieron. Sin
embargo, llega un momento en que intenta compilar para <i>Wayland</i> y ahí
me quedé atascado, porque no lo tengo instalado y no lo instalaré hasta
que KDE no tenga un soporte decente de él.
</p>

<p>
Así pues, <i>Armory</i> descartado por el momento.
</p>
</div>
</div>
<div id="outline-container-orgbb4c5af" class="outline-2">
<h2 id="orgbb4c5af">Un poco de <i>mi</i> historia con <code>haxe</code></h2>
<div class="outline-text-2" id="text-orgbb4c5af">
<p>
Aunque lo conocí hace tiempo nunca le hice mucho caso. Me pareció una
buena idea pero nunca pasé de leer sobre el lenguaje, mirar por encima
algún tutorial y ya.
</p>

<p>
La primera vez que me lo encontré fue en aquella época en que las que
teníamos las <i>webs</i> infladas con el infausto <i>flash</i>. Una época en la
que la interactividad y los juegos <i>on line</i> venían enlatados en
binarios generados con dicha herramienta. No había alternativa libre
hasta que apareció <a href="https://www.openfl.org/">OpenFL</a> que era una implementación libre que sigue
evolucionando. Cuando lo miré en aquella época, tampoco era totalmente
funcional para suplantar <i>flash</i>, aunque ya se podían hacer cosas con
ello. El lenguaje era <code>haxe</code> y lo estuve <i>chafardeando</i>, pero mi
reticencia a meter cosas binarias en las páginas <i>web</i> hicieron que lo
dejara aparte, como una curiosidad nada más.
</p>

<p>
Un tiempo más tarde me encontré con un libro del amigo <i>Morci</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>
que hablaba de la creación de juegos con <i>OpenFL</i>. Si alguien está
interesado el <a href="https://openlibra.com/es/book/videojuegos-multiplataforma-con-openfl">libro está disponible</a> en <code>openlibra.com</code>.  Recuerdo que
me conseguí una copia del libro y lo estuve mirando. Lo ojeé por
encima y lo aparqué. No llegué a instalar ni <code>OpenFL</code> ni <code>haxe</code>, pero
volvía a tener referencia sobre ellos.
</p>

<p>
Hace poco, hablando con un allegado, programador, me estuvo contando
que la empresa donde trabaja, que hasta ahora lo estaba haciendo
principalmente con <i>Java</i>, se está moviendo hacia <code>haxe</code> y están
pasando partes de los sistemas que hacen hacia este lenguaje.
</p>

<p>
Por último, estos días encontré <i>Armony3D</i> y realmente echo de menos
hacer jueguecillos con <i>Blender3D</i> desde que eliminaron el
<i>gamengine</i>.  Cotilleando por la web del motor me decidí a probar y me
puse a instalar todo. No he conseguido hacerlo funcionar del todo,
como he contado antes, pero bueno, estos son las cosas que hice:
</p>

<ol class="org-ol">
<li>Instalé <i>Blender3D 3.3 LTS</i>, que es la versión que pide <i>Armory3D</i>.</li>
<li>Instalé <code>haxe</code>.</li>
<li>Descargué los fuentes de <code>armorlab</code> y hasta aquí llegué.</li>
</ol>

<p>
No he conseguido hacer funcionar el chismático para lo que quería,
pero ya que tengo instalado el lenguaje, vamos a probarlo.
</p>
</div>
</div>
<div id="outline-container-orgc2da91b" class="outline-2">
<h2 id="orgc2da91b">haxe</h2>
<div class="outline-text-2" id="text-orgc2da91b">
<p>
El lenguaje <code>haxe</code> se define a sí mismo como un lenguaje de propósito
general, multiparadigma que soporta tanto <i>POO</i> como programación
funcional. Aunque mirando la documentación lo primero que presentan y
lo que parece más evolucionado es el apartado <i>POO</i>. La sintaxis es
familiar para programadores de <code>c++</code>, <code>java</code>, <code>PHP</code>, <code>c#</code>, etc.
</p>

<p>
El <i>compilador</i> de <code>haxe</code> puede generar diversas salidas para diversos
sistemas y lenguajes.
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Plataforma</th>
<th scope="col" class="org-left">Salida</th>
<th scope="col" class="org-left">Tipos estáticos</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">JavaScript</td>
<td class="org-left">fuentes</td>
<td class="org-left">No</td>
</tr>

<tr>
<td class="org-left">HashLink<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup></td>
<td class="org-left"><i>byte code</i> + fuentes</td>
<td class="org-left">Sí</td>
</tr>

<tr>
<td class="org-left">Eval</td>
<td class="org-left">Intérprete</td>
<td class="org-left">No</td>
</tr>

<tr>
<td class="org-left">JVM</td>
<td class="org-left"><i>byte code</i></td>
<td class="org-left">Sí</td>
</tr>

<tr>
<td class="org-left">Java</td>
<td class="org-left">fuentes</td>
<td class="org-left">Sí</td>
</tr>

<tr>
<td class="org-left">PHP7</td>
<td class="org-left">fuentes</td>
<td class="org-left">No</td>
</tr>

<tr>
<td class="org-left">C++</td>
<td class="org-left">fuentes</td>
<td class="org-left">Sí</td>
</tr>

<tr>
<td class="org-left">Lua</td>
<td class="org-left">fuentes</td>
<td class="org-left">No</td>
</tr>

<tr>
<td class="org-left">C#</td>
<td class="org-left">fuentes</td>
<td class="org-left">Sí</td>
</tr>

<tr>
<td class="org-left">Python</td>
<td class="org-left">fuentes</td>
<td class="org-left">No</td>
</tr>

<tr>
<td class="org-left">Flash</td>
<td class="org-left"><i>byte code</i></td>
<td class="org-left">Sí</td>
</tr>

<tr>
<td class="org-left">Neko</td>
<td class="org-left"><i>byte code</i></td>
<td class="org-left">No</td>
</tr>

<tr>
<td class="org-left">ActionScript</td>
<td class="org-left">fuentes</td>
<td class="org-left">No</td>
</tr>

<tr>
<td class="org-left">PHP5</td>
<td class="org-left">fuentes</td>
<td class="org-left">No</td>
</tr>
</tbody>
</table>

<p>
Para ver cómo funcionaba me propuse hacer un ejemplo sencillo que
fuera fácil de entender pero un poco más complejo que el clásico <i>Hola
mundo</i>. Ahí va el código:
</p>

<div class="org-src-container">
<pre class="src src-haxe">// Clases de Puntos

class Punto {
    var x:Int;
    var y:Int;

    public function new(x, y) {
        this.x = x;
        this.y = y;
    }

    public function toString() {
        return "Punto(" + x + ", " + y + ")";
    }
}

class Punto3D extends Punto {
    var z:Int;

    public function new(x, y, z) {
        super(x, y);
        this.z = z;
    }

    public override function toString() {
        return "Punto3D(" + x + ", " + y + ", " + z + ")";
    }
}

class PruebaPunto {
    static public function main():Void {
        var p = new Punto(-1, 65);
        var p3 = new Punto3D(21, 32, -6);

        trace(p.toString());
        trace(p3.toString());
    }
}
</pre>
</div>
</div>
</div>
<div id="outline-container-orga022f98" class="outline-2">
<h2 id="orga022f98">Configuración de <i>Emacs</i></h2>
<div class="outline-text-2" id="text-orga022f98">
<p>
En toda la documentación, tanto para <i>Armony3D</i> como para <code>haxe</code> me
encontré los pasos para instalar los <i>plugins</i> necesarios para los más
variopintos editores. Pero en ningún lado hay referencia de cómo
hacerlo para <i>Emacs</i>. Ya que no lo hacen ellos, lo haré yo, porque
efectivamente hay paquetes que soportan este lenguaje y también para
<code>babel</code> de <code>org-mode</code> (por si alguien se plantea hacer programación
literaria con este lenguaje).
</p>

<p>
Añadí a mi <code>init.el</code> el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> haxe-mode
  <span style="color: #8be9fd; font-style: italic;">:mode</span> (<span style="color: #f1fa8c;">"\\.hx\\'"</span> . haxe-mode)
  <span style="color: #8be9fd; font-style: italic;">:no-require</span> t
  <span style="color: #8be9fd; font-style: italic;">:init</span>
  (<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">js</span>)
  (<span style="color: #ff79c6; font-weight: bold;">define-derived-mode</span> <span style="color: #50fa7b; font-weight: bold;">haxe-mode</span> js-mode <span style="color: #f1fa8c;">"Haxe"</span>
    <span style="color: #6272a4;">"Haxe syntax highlighting mode. This is simply using js-mode for now."</span>))

(<span style="color: #ff79c6; font-weight: bold;">use-package</span> battle-haxe
  <span style="color: #8be9fd; font-style: italic;">:hook</span> (haxe-mode . battle-haxe-mode)
  <span style="color: #8be9fd; font-style: italic;">:bind</span> ((<span style="color: #f1fa8c;">"S-&lt;f4&gt;"</span> . #'pop-global-mark) <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Para regresar despu&#233;s de visitar una definici&#243;n
</span>         <span style="color: #8be9fd; font-style: italic;">:map</span> battle-haxe-mode-map
         (<span style="color: #f1fa8c;">"&lt;f4&gt;"</span> . #'battle-haxe-goto-definition)
         (<span style="color: #f1fa8c;">"C-c &lt;f4&gt;"</span> . #'battle-haxe-helm-find-references))
  <span style="color: #8be9fd; font-style: italic;">:custom</span>
  (battle-haxe-yasnippet-completion-expansion t <span style="color: #f1fa8c;">"Mant&#233;n esto si quieres expansi&#243;n de completado yasnippet"</span>)
  (battle-haxe-immediate-completion nil <span style="color: #f1fa8c;">"Activar/desactivar el completado inmediato al pulsar &#171;.&#187; u otros prefijos significativos"</span>))
(<span style="color: #ff79c6; font-weight: bold;">use-package</span> ob-haxe
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t)
</pre>
</div>

<p>
Como veis instalo tres paquetes:
</p>

<ul class="org-ul">
<li><code>haxe-mode</code> proporciona coloreado de sintaxis y pocas cosas más.</li>
<li><code>battle-haxe</code> proporciona autocompletado a través de <code>company</code> y
control de sintaxis a través de <code>flycheck</code>.</li>
<li><code>ob-haxe</code>: paquete para <code>org-babel</code>.</li>
</ul>

<p>
Si se va a utilizar en bloques de código dentro de ficheros <code>org</code> hay
que darlo de alta también en la lista de lenguajes
<code>org-babel-load~languages</code>.
</p>

<p>
En principio todo funciona como se espera con algunas dificultades.
Los paquetes para <i>Emacs</i> soportan la versión <code>4.0.0</code> de <code>haxe</code>,
mientras que el lenguaje va ya por la versión <code>4.2.5</code> y hay algunas
cosas que no van finas. Algunas palabras clave (como <code>override</code>) no
las colorea como el resto de la sintaxis. El autocompletado lanza
errores y a veces no funciona.
</p>
</div>
</div>
<div id="outline-container-org5f87a02" class="outline-2">
<h2 id="org5f87a02">Diferentes compilados</h2>
<div class="outline-text-2" id="text-org5f87a02">
<p>
Del ejemplo mostrado en el apartado anterior hice algunas pruebas de
compilado a diferentes <i>targets</i>. El primero fue correr el <i>scritp</i> a
ver si funcionaba todo:
</p>

<div class="org-src-container">
<pre class="src src-shell">haxe --main PruebaPunto --interp
PruebaPunto.hx:35: Punto(-1, 65)
PruebaPunto.hx:36: Punto3D(21, 32, -6)
</pre>
</div>

<ul class="org-ul">
<li><p>
Salida a <i>Python</i>: Una vez comprobado que todo funcionaba hice la
prueba de compilar a <i>Python</i> y ejecutarlo a ver qué nos decía:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; haxe --main PruebaPunto --python PruebaPunto.py
&gt; python3 PruebaPunto.py
<span style="color: #50fa7b; font-weight: bold;">Punto</span>(-1, 65)
<span style="color: #50fa7b; font-weight: bold;">Punto3D</span>(21, 32, -6)
</pre>
</div>

<p>
El primer paso lo que hace es <i>compilar</i> el código <code>haxe</code> en código
<i>Python</i>. Al ejecutar el código generado, la salida es muy parecida
a la que produce el original. Por si alguien tiene curiosidad aquí
va el código generado:
</p>

<div class="org-src-container">
<pre class="src src-python"><span style="color: #ff79c6; font-weight: bold;">import</span> sys

<span style="color: #ff79c6; font-weight: bold;">class</span> <span style="color: #8be9fd; font-style: italic;">Punto</span>:
<span style="background-color: #373844;"> </span>   <span style="color: #f8f8f2; font-weight: bold;">__slots__</span> <span style="color: #ff79c6;">=</span> (<span style="color: #f1fa8c;">"x"</span>, <span style="color: #f1fa8c;">"y"</span>)
<span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">def</span> <span style="color: #50fa7b; font-weight: bold;">__init__</span>(<span style="color: #ff79c6; font-weight: bold;">self</span>,x,y):
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">self</span>.<span style="color: #f8f8f2; font-weight: bold;">x</span> <span style="color: #ff79c6;">=</span> x
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">self</span>.<span style="color: #f8f8f2; font-weight: bold;">y</span> <span style="color: #ff79c6;">=</span> y
<span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">def</span> <span style="color: #50fa7b; font-weight: bold;">toString</span>(<span style="color: #ff79c6; font-weight: bold;">self</span>):
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">return</span> ((((<span style="color: #f1fa8c;">"Punto("</span> <span style="color: #ff79c6;">+</span> <span style="color: #8be9fd; font-style: italic;">str</span>(<span style="color: #ff79c6; font-weight: bold;">self</span>.x)) <span style="color: #ff79c6;">+</span> <span style="color: #f1fa8c;">", "</span>) <span style="color: #ff79c6;">+</span> <span style="color: #8be9fd; font-style: italic;">str</span>(<span style="color: #ff79c6; font-weight: bold;">self</span>.y)) <span style="color: #ff79c6;">+</span> <span style="color: #f1fa8c;">")"</span>)

<span style="color: #ff79c6; font-weight: bold;">class</span> <span style="color: #8be9fd; font-style: italic;">Punto3D</span>(Punto):
<span style="background-color: #373844;"> </span>   <span style="color: #f8f8f2; font-weight: bold;">__slots__</span> <span style="color: #ff79c6;">=</span> (<span style="color: #f1fa8c;">"z"</span>,)
<span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">def</span> <span style="color: #50fa7b; font-weight: bold;">__init__</span>(<span style="color: #ff79c6; font-weight: bold;">self</span>,x,y,z):
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">self</span>.<span style="color: #f8f8f2; font-weight: bold;">z</span> <span style="color: #ff79c6;">=</span> <span style="color: #bd93f9;">None</span>
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #8be9fd; font-style: italic;">super</span>().__init__(x,y)
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">self</span>.<span style="color: #f8f8f2; font-weight: bold;">z</span> <span style="color: #ff79c6;">=</span> z
<span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">def</span> <span style="color: #50fa7b; font-weight: bold;">toString</span>(<span style="color: #ff79c6; font-weight: bold;">self</span>):
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">return</span> ((((((<span style="color: #f1fa8c;">"Punto3D("</span> <span style="color: #ff79c6;">+</span> <span style="color: #8be9fd; font-style: italic;">str</span>(<span style="color: #ff79c6; font-weight: bold;">self</span>.x)) <span style="color: #ff79c6;">+</span> <span style="color: #f1fa8c;">", "</span>) <span style="color: #ff79c6;">+</span> <span style="color: #8be9fd; font-style: italic;">str</span>(<span style="color: #ff79c6; font-weight: bold;">self</span>.y)) <span style="color: #ff79c6;">+</span> <span style="color: #f1fa8c;">", "</span>) <span style="color: #ff79c6;">+</span> <span style="color: #8be9fd; font-style: italic;">str</span>(<span style="color: #ff79c6; font-weight: bold;">self</span>.z)) <span style="color: #ff79c6;">+</span> <span style="color: #f1fa8c;">")"</span>)

<span style="color: #ff79c6; font-weight: bold;">class</span> <span style="color: #8be9fd; font-style: italic;">PruebaPunto</span>:
<span style="background-color: #373844;"> </span>   <span style="color: #f8f8f2; font-weight: bold;">__slots__</span> <span style="color: #ff79c6;">=</span> ()
<span style="background-color: #373844;"> </span>   @<span style="color: #8be9fd; font-style: italic;">staticmethod</span>
<span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">def</span> <span style="color: #50fa7b; font-weight: bold;">main</span>():
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #f8f8f2; font-weight: bold;">p</span> <span style="color: #ff79c6;">=</span> Punto(<span style="color: #ff79c6;">-</span>1,65)
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #f8f8f2; font-weight: bold;">p3</span> <span style="color: #ff79c6;">=</span> Punto3D(21,32,<span style="color: #ff79c6;">-</span>6)
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #8be9fd; font-style: italic;">print</span>(<span style="color: #8be9fd; font-style: italic;">str</span>(p.toString()))
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #8be9fd; font-style: italic;">print</span>(<span style="color: #8be9fd; font-style: italic;">str</span>(p3.toString()))

<span style="color: #ff79c6; font-weight: bold;">class</span> <span style="color: #8be9fd; font-style: italic;">haxe_iterators_ArrayIterator</span>:
<span style="background-color: #373844;"> </span>   <span style="color: #f8f8f2; font-weight: bold;">__slots__</span> <span style="color: #ff79c6;">=</span> (<span style="color: #f1fa8c;">"array"</span>, <span style="color: #f1fa8c;">"current"</span>)
<span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">def</span> <span style="color: #50fa7b; font-weight: bold;">__init__</span>(<span style="color: #ff79c6; font-weight: bold;">self</span>,array):
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">self</span>.<span style="color: #f8f8f2; font-weight: bold;">current</span> <span style="color: #ff79c6;">=</span> 0
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">self</span>.<span style="color: #f8f8f2; font-weight: bold;">array</span> <span style="color: #ff79c6;">=</span> array
<span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">def</span> <span style="color: #50fa7b; font-weight: bold;">hasNext</span>(<span style="color: #ff79c6; font-weight: bold;">self</span>):
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">return</span> (<span style="color: #ff79c6; font-weight: bold;">self</span>.current <span style="color: #ff79c6;">&lt;</span> <span style="color: #8be9fd; font-style: italic;">len</span>(<span style="color: #ff79c6; font-weight: bold;">self</span>.array))
<span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">def</span> <span style="color: #50fa7b; font-weight: bold;">next</span>(<span style="color: #ff79c6; font-weight: bold;">self</span>):
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">def</span> <span style="color: #50fa7b; font-weight: bold;">_hx_local_3</span>():
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">def</span> <span style="color: #50fa7b; font-weight: bold;">_hx_local_2</span>():
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #f8f8f2; font-weight: bold;">_hx_local_0</span> <span style="color: #ff79c6;">=</span> <span style="color: #ff79c6; font-weight: bold;">self</span>
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #f8f8f2; font-weight: bold;">_hx_local_1</span> <span style="color: #ff79c6;">=</span> _hx_local_0.current
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   _hx_local_0.<span style="color: #f8f8f2; font-weight: bold;">current</span> <span style="color: #ff79c6;">=</span> (_hx_local_1 <span style="color: #ff79c6;">+</span> 1)
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">return</span> _hx_local_1
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">return</span> python_internal_ArrayImpl._get(<span style="color: #ff79c6; font-weight: bold;">self</span>.array, _hx_local_2())
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">return</span> _hx_local_3()

<span style="color: #ff79c6; font-weight: bold;">class</span> <span style="color: #8be9fd; font-style: italic;">python_internal_ArrayImpl</span>:
<span style="background-color: #373844;"> </span>   <span style="color: #f8f8f2; font-weight: bold;">__slots__</span> <span style="color: #ff79c6;">=</span> ()
<span style="background-color: #373844;"> </span>   @<span style="color: #8be9fd; font-style: italic;">staticmethod</span>
<span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">def</span> <span style="color: #50fa7b; font-weight: bold;">_get</span>(x,idx):
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">if</span> ((idx <span style="color: #ff79c6;">&gt;</span> <span style="color: #ff79c6;">-</span>1) <span style="color: #ff79c6; font-weight: bold;">and</span> ((idx <span style="color: #ff79c6;">&lt;</span> <span style="color: #8be9fd; font-style: italic;">len</span>(x)))):
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">return</span> x[idx]
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">else</span>:
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">return</span> <span style="color: #bd93f9;">None</span>

<span style="color: #ff79c6; font-weight: bold;">class</span> <span style="color: #8be9fd; font-style: italic;">HxOverrides</span>:
<span style="background-color: #373844;"> </span>   <span style="color: #f8f8f2; font-weight: bold;">__slots__</span> <span style="color: #ff79c6;">=</span> ()
<span style="background-color: #373844;"> </span>   @<span style="color: #8be9fd; font-style: italic;">staticmethod</span>
<span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">def</span> <span style="color: #50fa7b; font-weight: bold;">stringOrNull</span>(s):
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">if</span> (s <span style="color: #ff79c6; font-weight: bold;">is</span> <span style="color: #bd93f9;">None</span>):
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">return</span> <span style="color: #f1fa8c;">"null"</span>
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">else</span>:
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">return</span> s

<span style="color: #ff79c6; font-weight: bold;">class</span> <span style="color: #8be9fd; font-style: italic;">python_internal_MethodClosure</span>:
<span style="background-color: #373844;"> </span>   <span style="color: #f8f8f2; font-weight: bold;">__slots__</span> <span style="color: #ff79c6;">=</span> (<span style="color: #f1fa8c;">"obj"</span>, <span style="color: #f1fa8c;">"func"</span>)
<span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">def</span> <span style="color: #50fa7b; font-weight: bold;">__init__</span>(<span style="color: #ff79c6; font-weight: bold;">self</span>,obj,func):
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">self</span>.<span style="color: #f8f8f2; font-weight: bold;">obj</span> <span style="color: #ff79c6;">=</span> obj
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">self</span>.<span style="color: #f8f8f2; font-weight: bold;">func</span> <span style="color: #ff79c6;">=</span> func
<span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">def</span> <span style="color: #50fa7b; font-weight: bold;">__call__</span>(<span style="color: #ff79c6; font-weight: bold;">self</span>,<span style="color: #ff79c6;">*</span>args):
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">return</span> <span style="color: #ff79c6; font-weight: bold;">self</span>.func(<span style="color: #ff79c6; font-weight: bold;">self</span>.obj,<span style="color: #ff79c6;">*</span>args)

PruebaPunto.main()
</pre>
</div>

<p>
El único cambio que he hecho en el código generado es eliminar
algunas líneas en blanco para que no fuera demasiado largo el
listado de código dentro del artículo. Todo lo demás es tal cual lo
exporta <code>haxe</code>. Vemos que el código ha crecido un poco en
complejidad y añade clases por parte de <code>haxe</code> que no hubiéramos
añadido nosotros en caso de haber querido hacer el código en
<i>Python</i> directamente.
</p></li>

<li><p>
También probé con <i>JavaScript</i>. El código generado fue el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-javascript">(<span style="color: #ff79c6; font-weight: bold;">function</span> (<span style="color: #f8f8f2; font-weight: bold;">$global</span>) { <span style="color: #f1fa8c;">"use strict"</span>;
<span style="color: #ff79c6; font-weight: bold;">function</span> <span style="color: #50fa7b; font-weight: bold;">$extend</span>(<span style="color: #f8f8f2; font-weight: bold;">from</span>, <span style="color: #f8f8f2; font-weight: bold;">fields</span>) {
        <span style="color: #ff79c6; font-weight: bold;">var</span> <span style="color: #f8f8f2; font-weight: bold;">proto</span> = Object.create(from);
        <span style="color: #ff79c6; font-weight: bold;">for</span> (<span style="color: #ff79c6; font-weight: bold;">var</span> <span style="color: #f8f8f2; font-weight: bold;">name</span> <span style="color: #ff79c6; font-weight: bold;">in</span> fields) proto[name] = fields[name];
        <span style="color: #ff79c6; font-weight: bold;">if</span>( fields.toString !== Object.<span style="color: #bd93f9;">prototype</span>.toString ) proto.toString = fields.toString;
        <span style="color: #ff79c6; font-weight: bold;">return</span> proto;
}
<span style="color: #ff79c6; font-weight: bold;">var</span> <span style="color: #f8f8f2; font-weight: bold;">Punto</span> = <span style="color: #ff79c6; font-weight: bold;">function</span>(<span style="color: #f8f8f2; font-weight: bold;">x</span>,<span style="color: #f8f8f2; font-weight: bold;">y</span>) {
        <span style="color: #bd93f9;">this</span>.x = x;
        <span style="color: #bd93f9;">this</span>.y = y;
};
Punto.<span style="color: #bd93f9;">prototype</span> = {
        <span style="color: #50fa7b; font-weight: bold;">toString</span>: <span style="color: #ff79c6; font-weight: bold;">function</span>() {
                <span style="color: #ff79c6; font-weight: bold;">return</span> <span style="color: #f1fa8c;">"Punto("</span> + <span style="color: #bd93f9;">this</span>.x + <span style="color: #f1fa8c;">", "</span> + <span style="color: #bd93f9;">this</span>.y + <span style="color: #f1fa8c;">")"</span>;
        }
};
<span style="color: #ff79c6; font-weight: bold;">var</span> <span style="color: #f8f8f2; font-weight: bold;">Punto3D</span> = <span style="color: #ff79c6; font-weight: bold;">function</span>(<span style="color: #f8f8f2; font-weight: bold;">x</span>,<span style="color: #f8f8f2; font-weight: bold;">y</span>,<span style="color: #f8f8f2; font-weight: bold;">z</span>) {
        Punto.call(<span style="color: #bd93f9;">this</span>,x,y);
        <span style="color: #bd93f9;">this</span>.z = z;
};
Punto3D.__super__ = Punto;
Punto3D.<span style="color: #bd93f9;">prototype</span> = $extend(Punto.<span style="color: #bd93f9;">prototype</span>,{
        <span style="color: #50fa7b; font-weight: bold;">toString</span>: <span style="color: #ff79c6; font-weight: bold;">function</span>() {
                <span style="color: #ff79c6; font-weight: bold;">return</span> <span style="color: #f1fa8c;">"Punto3D("</span> + <span style="color: #bd93f9;">this</span>.x + <span style="color: #f1fa8c;">", "</span> + <span style="color: #bd93f9;">this</span>.y + <span style="color: #f1fa8c;">", "</span> + <span style="color: #bd93f9;">this</span>.z + <span style="color: #f1fa8c;">")"</span>;
        }
});
<span style="color: #ff79c6; font-weight: bold;">var</span> <span style="color: #f8f8f2; font-weight: bold;">PruebaPunto</span> = <span style="color: #ff79c6; font-weight: bold;">function</span>() { };
PruebaPunto.main = <span style="color: #ff79c6; font-weight: bold;">function</span>() {
        <span style="color: #ff79c6; font-weight: bold;">var</span> <span style="color: #f8f8f2; font-weight: bold;">p</span> = <span style="color: #ff79c6; font-weight: bold;">new</span> <span style="color: #8be9fd; font-style: italic;">Punto</span>(-1,65);
        <span style="color: #ff79c6; font-weight: bold;">var</span> <span style="color: #f8f8f2; font-weight: bold;">p3</span> = <span style="color: #ff79c6; font-weight: bold;">new</span> <span style="color: #8be9fd; font-style: italic;">Punto3D</span>(21,32,-6);
        console.log(<span style="color: #f1fa8c;">"PruebaPunto.hx:35:"</span>,p.toString());
        console.log(<span style="color: #f1fa8c;">"PruebaPunto.hx:36:"</span>,p3.toString());
};
<span style="color: #ff79c6; font-weight: bold;">var</span> <span style="color: #f8f8f2; font-weight: bold;">haxe_iterators_ArrayIterator</span> = <span style="color: #ff79c6; font-weight: bold;">function</span>(<span style="color: #f8f8f2; font-weight: bold;">array</span>) {
        <span style="color: #bd93f9;">this</span>.current = 0;
        <span style="color: #bd93f9;">this</span>.array = array;
};
haxe_iterators_ArrayIterator.<span style="color: #bd93f9;">prototype</span> = {
        <span style="color: #50fa7b; font-weight: bold;">hasNext</span>: <span style="color: #ff79c6; font-weight: bold;">function</span>() {
                <span style="color: #ff79c6; font-weight: bold;">return</span> <span style="color: #bd93f9;">this</span>.current &lt; <span style="color: #bd93f9;">this</span>.array.length;
        }
        ,next: <span style="color: #ff79c6; font-weight: bold;">function</span>() {
                <span style="color: #ff79c6; font-weight: bold;">return</span> <span style="color: #bd93f9;">this</span>.array[<span style="color: #bd93f9;">this</span>.current++];
        }
};
PruebaPunto.main();
})({});
</pre>
</div>

<p>
La forma de conseguir ese código es bastante parecido al de
conseguir el de <i>Python</i>:
</p>

<div class="org-src-container">
<pre class="src src-shell">haxe --main PruebaPunto --js PruebaPunto.js
</pre>
</div>

<p>
Con los lenguajes interpretados no ha habido problema y aunque
<code>haxe</code> produce una capa de abstracción por encima, el código
generado es bastante asequible y se sigue entendiendo sin mucho
esfuerzo.
</p></li>

<li><p>
Para <i>compilar</i> a <i>Java</i> encontré dos modos, uno genera únicamente
un módulo <code>jar</code> ejecutable:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; haxe --main PruebaPunto --jvm PruebaPunto.jar
&gt; java -jar PruebaPunto.jar
PruebaPunto.hx:35: Punto(-1, 65)
PruebaPunto.hx:36: Punto3D(21, 32, -6)
</pre>
</div>

<p>
Ese comando, con la salida a <code>--jvm</code> sólo genera un archivo
comprimido con nombre <code>PruebaPunto.jar</code> que se puede ejecutar
directamente. Sin embargo, si queremos también el código fuente la
salida debemos hacerla a <code>--java~</code>:
</p>

<p>
Dado mi desconocimiento del sistema me sorprendí cuando al ejecutar
</p>

<div class="org-src-container">
<pre class="src src-shell">haxe --main PruebaPunto --java PruebaPunto.java
haxelib run hxjava hxjava_build.txt --haxe-version 4205 --feature-level 1 --out PruebaPunto.java/PruebaPunto
javac <span style="color: #f1fa8c;">"-sourcepath"</span> <span style="color: #f1fa8c;">"src"</span> <span style="color: #f1fa8c;">"-d"</span> <span style="color: #f1fa8c;">"obj"</span> <span style="color: #f1fa8c;">"-g:none"</span> <span style="color: #f1fa8c;">"@cmd"</span>
</pre>
</div>

<p>
Vi que hacía más cosas y cuando intenté abrir el <code>.java</code> resultó ser
un directorio con un gran número de archivos dentro, un directorio
<code>src</code> con el código fuente. También encontramos un directorio <code>obj</code>
donde están los archivos <code>.class</code> compilados. También está el <code>.jar</code>
generado (al ejecutarlo se obtiene la misma salida que antes).  Los
ficheros <code>.java</code> generados son bastante complejos. El fichero fuente
de la clase <code>Punto</code> tiene más de 300 líneas.
</p>

<p>
Para hacernos una idea, los archivos fuente que se generan son:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; tree src
src
&#9492;&#9472;&#9472; haxe
    &#9500;&#9472;&#9472; Exception.java
    &#9500;&#9472;&#9472; exceptions
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; NotImplementedException.java
    &#9474;&#160;&#160; &#9492;&#9472;&#9472; PosException.java
    &#9500;&#9472;&#9472; iterators
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; ArrayIterator.java
    &#9474;&#160;&#160; &#9492;&#9472;&#9472; ArrayKeyValueIterator.java
    &#9500;&#9472;&#9472; java
    &#9474;&#160;&#160; &#9492;&#9472;&#9472; Init.java
    &#9500;&#9472;&#9472; lang
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; Closure.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; DynamicObject.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; EmptyObject.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; Enum.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; FieldLookup.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; Function.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; HxObject.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; IEquatable.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; IHxObject.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; ParamEnum.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; Runtime.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; StringExt.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; StringRefl.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; VarArgsBase.java
    &#9474;&#160;&#160; &#9492;&#9472;&#9472; VarArgsFunction.java
    &#9500;&#9472;&#9472; Log_Anon_62__Fun.java
    &#9500;&#9472;&#9472; Log.java
    &#9500;&#9472;&#9472; root
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; Array.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; PruebaPunto.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; Punto3D.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; Punto.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; Reflect.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; Std.java
    &#9474;&#160;&#160; &#9500;&#9472;&#9472; StringBuf.java
    &#9474;&#160;&#160; &#9492;&#9472;&#9472; Type.java
    &#9492;&#9472;&#9472; ValueException.java
</pre>
</div></li>

<li><p>
Y, por último, también hice las consiguientes pruebas con <code>clang</code>.
También la salida del comando es más compleja que en el caso de los
lenguajes interpretados.
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; haxe --main PruebaPunto --cpp PruebaPunto.cc
...
Creating /home/notxor/proyectos/haxe-intro/PruebaPunto.cc/obj/linux64/__pch/haxe/hxcpp.h.gch...
...
Compiling group: runtime
g++ -D_CRT_SECURE_NO_DEPRECATE -DHX_UNDEFINE_H -c -fvisibility=hidden -O2 -fpic -fPIC -Wno-overflow -DHX_LINUX -DHXCPP_M64 -DHXCPP_VISIT_ALLOCS(haxe) -DHX_SMART_STRINGS(haxe) -DHXCPP_API_LEVEL=400(haxe) -m64 -DHXCPP_M64 -I/home/notxor/opt/haxe/lib/hxcpp/4,2,1/include ... <span style="color: #f8f8f2; font-weight: bold;">tags</span>=[haxe]
...
Link: PruebaPunto
&gt; PruebaPunto.cc/PruebaPunto 
PruebaPunto.hx:35: Punto(-1, 65)
PruebaPunto.hx:36: Punto3D(21, 32, -6)
</pre>
</div>

<p>
Efectivamente genera el ejecutable, pero cargado con toda una capa
de abstracción. Aunque no con tanta complejidad como en el caso de
<i>Java</i>. En este caso genera un par de directorios: <code>include</code> y <code>src</code>
donde se encuentran los ficheros de cabecera y los fuentes,
respectivamente, de nuestras clases.
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; tree include
include
&#9500;&#9472;&#9472; haxe
&#9474;&#160;&#160; &#9492;&#9472;&#9472; Log.h
&#9500;&#9472;&#9472; PruebaPunto.h
&#9500;&#9472;&#9472; Punto3D.h
&#9500;&#9472;&#9472; Punto.h
&#9492;&#9472;&#9472; Std.h

&gt; tree src
src
&#9500;&#9472;&#9472; __boot__.cpp
&#9500;&#9472;&#9472; __files__.cpp
&#9500;&#9472;&#9472; haxe
&#9474;&#160;&#160; &#9492;&#9472;&#9472; Log.cpp
&#9500;&#9472;&#9472; __lib__.cpp
&#9500;&#9472;&#9472; __main__.cpp
&#9500;&#9472;&#9472; PruebaPunto.cpp
&#9500;&#9472;&#9472; Punto3D.cpp
&#9500;&#9472;&#9472; Punto.cpp
&#9500;&#9472;&#9472; __resources__.cpp
&#9492;&#9472;&#9472; Std.cpp
</pre>
</div>

<p>
Aunque la estructura es simple, el contenido de esas clases se aleja
de la sencillez de nuestro código y, por ejemplo, la clase <code>Punto</code>
tiene una cabecera y un cuerpo de más de 100 líneas cada archivo.
</p></li>
</ul>
</div>
</div>
<div id="outline-container-org81a70d5" class="outline-2">
<h2 id="org81a70d5">Conclusiones</h2>
<div class="outline-text-2" id="text-org81a70d5">
<p>
<code>haxe</code> es una herramienta que parece madura para producir aplicaciones
multiplataforma. Parece que tiene una comunidad activa alrededor
principalmente de la programación de juegos. Sin embargo, la última
referencia que tenía sobre este lenguaje fue de una empresa que estaba
migrando bastante del sistema que tenía en <i>Java</i> a este lenguaje.
</p>

<p>
Por cuatro pruebas que he hecho, aún no le he visto las ventajas que
puede tener con hacer directamente el código deseado, más allá de lo
que pueden ser los juegos. Aunque supongo, que vistas la librerías de
soporte a <i>JavaScript</i>, a <i>PHP</i>... salidas a ejecutables compilados
para la máquina, o compilados para la <code>jvm</code>... En fin, capacidad para
gestionar la aplicación y su <i>interface</i> con el mismo lenguaje.
</p>

<p>
De momento, si no lo necesito, no creo que lo use mucho por la
complejidad de todo el sistema, pero lo mismo a alguno de los que
puedan leer este artículo les es útil.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Morci</i> era el <i>nick</i> que utilizaba cierto profesor de la
Universidad de Castilla la Mancha por los foros de <i>BlenderAdictos</i> y
con el que coincidí en alguna ocasión, compartiendo sala de
conferencias o alguna publicación. No creo que lea esto, pero si lo
hace le envío un saludo.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Máquina virtual propia de <code>haxe</code>. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/haxe/index.html">haxe</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[haxe]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2023/02/03/armony3D-y-haxe.html</link>
  <pubDate>Fri, 03 Feb 2023 16:51:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Programación Orientada a Objetos en Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-01-29</div>
<p>
A raíz del <a href="https://notxor.nueva-actitud.org/2023/01/19/lisp-y-familia.html">último artículo</a>, donde hablaba de algunos lenguajes de la
familia de <i>LISP</i>, me han preguntado por la <span id="nota">POO<span class="nota">Programación Orientada a Objetos</span></span> que se puede hacer dentro de <code>elisp</code> y su
compatibilidad con <span id="nota">CLOS<span class="nota">Common Lisp Object System</span></span>. En
<code>elisp</code> encontramos el paquete con el acrónimo <i>EIEIO</i>, que significa
<i>Enhanced Implementation of Emacs Interpreted Objects</i>. No hay que
instalar nada, es uno de los paquetes <i>built-in</i> y lo encuentras
instalado con tu instalación de <i>Emacs</i>. En este artículo voy a hacer
una breve introducción a <code>eieio</code> para todos aquellos que no pueden, o
sí, vivir sin objetos en su código y quieran usarlos programando para
<i>Emacs</i> en <code>elisp</code>.
</p>

<p>
Siempre es recomendable leer la documentación, como he hecho yo para
escribir este artículo. No empleo <i>POO</i> cuando trabajo en el <code>elisp</code>,
no porque le tenga manía a dicho <i>estilo</i> de programación, sino porque
mis neuronas a estas alturas se alienan en modo <i>funcional</i> cuando
pienso en hacer algo con <code>elisp</code> o, en general, con cualquiera de los
herederos de <i>LISP</i>. También es necesario advertir que <code>eieio</code> no es
una implementación completa de <i>CLOS</i> y hay diferencias entre ambos
sistemas. Esto es debido a que <code>elisp</code> tiene algunas restricciones en
su diseño y por tanto no puede soportar la especificación <i>CLOS</i> al
completo. Si estás decidido a utilizarlo y has utilizado antes <i>CLOS</i>,
sería conveniente que le echaras un vistazo antes a dichas
limitaciones.
</p>

<p>
Entre las características que proporciona <code>eieio</code> están:
</p>

<ol class="org-ol">
<li>Una manera estructurada de crear clases básicas con atributos y
métodos, con herencia múltiple y muy similar a <i>CLOS</i>.</li>
<li>Comprobación de tipos.</li>
<li>Navegadores de clases: simple y complejo, con comandos como
<code>eieio-browse</code>.</li>
<li>Soporte <code>edebug</code> para los métodos.</li>
<li>Soporte de compilación a <code>bytecode</code> de los métodos.</li>
<li>Ayuda para la extensión del sistema de clases y métodos.</li>
<li>Muchas clases básicas para tareas interesantes.</li>
<li>Sistema simple de <i>tests</i> para <i>TDD</i>.</li>
<li>Soporte para entradas públicas y privadas en las clases.</li>
</ol>
<div id="outline-container-orgda37083" class="outline-2">
<h2 id="orgda37083">Definiendo clases</h2>
<div class="outline-text-2" id="text-orgda37083">
<p>
Para definir una clase, se utiliza el macro <code>defclass</code> con la
siguiente estructura:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defclass</span> <span style="color: #8be9fd; font-style: italic;">nombre-clase</span> (lista-superclases) (lista-slots) <span style="color: #8be9fd; font-style: italic;">&amp;rest</span> opciones-y-doc)
</pre>
</div>

<p>
Al crear una clase, <i>automágicamente</i> <code>eieio</code> nos crea una función con
la que podemos saber si un objeto pertenece a dicha clase, la función
<code>nombre-clase-p</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(nombre-clase-p objeto)
</pre>
</div>

<p>
Devolverá <code>t</code> si es de esa clase y <code>nil</code> en caso contrario. También
encontraremos otras funciones creadas <i>automágicamente</i> como
<code>nombre-clase-child-p</code> para comprobar si es de una clase derivada y
algunos más. Como siempre, hay que remitirnos a la documentación. Sin
embargo, esto me recuerda que hay que hablar un poco de la <i>herencia</i>.
</p>
</div>
<div id="outline-container-org8b3b38c" class="outline-3">
<h3 id="org8b3b38c">Herencia</h3>
<div class="outline-text-3" id="text-org8b3b38c">
<p>
Hablar en abstracto es complicado. Creo que será mejor si pongo un
ejemplo sencillo para ilustrar cómo funciona. Tampoco voy a ser
exhaustivo, pero sí quiero ser los más amplio posible sin complicar
mucho las explicaciones.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defclass</span> <span style="color: #8be9fd; font-style: italic;">mi-clase-base</span> ()
  ((slot-a <span style="color: #8be9fd; font-style: italic;">:initarg</span> <span style="color: #8be9fd; font-style: italic;">:slot-a</span>)
   (slot-b <span style="color: #8be9fd; font-style: italic;">:initarg</span> <span style="color: #8be9fd; font-style: italic;">:slot-b</span>))
  <span style="color: #6272a4;">"Mi clase base para el ejemplo."</span>)
</pre>
</div>

<p>
Como vemos, en la macro, la lista de clases para la herencia está
vacía: <code>()</code>.  Vamos a derivar otra clase de esta:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defclass</span> <span style="color: #8be9fd; font-style: italic;">mi-clase-derivada</span> (mi-clase-base)
  ((su-propio-slot-a <span style="color: #8be9fd; font-style: italic;">:initarg</span> <span style="color: #8be9fd; font-style: italic;">:su-propio-slot-a</span>))
  <span style="color: #6272a4;">"Una subclase de mi-clase-base."</span>)
</pre>
</div>

<p>
En este caso, <code>mi-clase-derivada</code> tendrá <code>slot-a</code> y <code>slot-b</code> heredados
de la clase base y contará también con <code>su-propio-slot-a</code>.
</p>

<p>
Si en la definición de la clase se pide una lista de clases de las que
deriva es porque en <code>eieio</code> se puede utilizar la herencia múltiple.
Por seguir con el mismo ejemplo, podríamos haber definido también una
<i>interface</i>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defclass</span> <span style="color: #8be9fd; font-style: italic;">mi-interface</span> ()
  ((interface-slot <span style="color: #8be9fd; font-style: italic;">:initarg</span> <span style="color: #8be9fd; font-style: italic;">:interface-slot</span>))
  <span style="color: #6272a4;">"Una interfaz para tener comportamientos especiales"</span>
  <span style="color: #8be9fd; font-style: italic;">:abstract</span> t)
</pre>
</div>

<p>
Como se puede observar, una <i>interface</i> es una clase más, pero
declarada como <code>:abstract t</code>. Nuestra clase derivada, si añadimos la
<i>interface</i> se podría haber hecho así:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defclass</span> <span style="color: #8be9fd; font-style: italic;">mi-clase-derivada</span> (mi-clase-base mi-interface)
  ((su-propio-slot-a <span style="color: #8be9fd; font-style: italic;">:initarg</span> <span style="color: #8be9fd; font-style: italic;">:su-propio-slot-a</span>))
  <span style="color: #6272a4;">"Una subclase de mi-clase-base."</span>)
</pre>
</div>

<p>
Así, además de su <i>slot</i> propio y de los heredados de <code>mi-clase-base</code>,
tendría también el heredado de <code>mi-interface</code>.
</p>

<p>
Como se puede ver, cada definición de campo utiliza <code>:initarg</code> para
dar un valor inicial al mismo. Al definirlos podemos realizar muchos
tipos de operaciones sobre ellos:
</p>

<dl class="org-dl">
<dt><code>:initarg</code></dt><dd>Valor inicial del campo.</dd>
<dt><code>:initform</code></dt><dd>Una expresión cuyo resultado tras su evaluación
determinará el valor inicial del campo.</dd>
<dt><code>:print</code></dt><dd>una función que imprimirá el contenido del campo.</dd>
<dt><code>:writer</code></dt><dd>una función que escribirá el contenido del campo.</dd>
<dt><code>:reader</code></dt><dd>una función que leerá el contenido del campo.</dd>
<dt><code>:type</code></dt><dd>especificación del tipo.</dd>
<dt><code>:protection</code></dt><dd>especificación de la protección del campo. Puede
tomar los valores <code>:public</code>, <code>:private</code> y <code>:protected</code>.</dd>
</dl>

<p>
Como hemos visto al definir <code>mi-interface</code>, las clases también admiten
varias opciones. En el ejemplo he utilizado <code>:abstract t</code> que no permite
crear objetos directamente de esa clase, sino que obliga a que se
utilice, tan sólo, a efectos de herencia. Hay muchos más y es
recomendable que mires esas opciones en la documentación.
</p>
</div>
</div>
<div id="outline-container-orgab0ee47" class="outline-3">
<h3 id="orgab0ee47">Crear instancias</h3>
<div class="outline-text-3" id="text-orgab0ee47">
<p>
Para crear un objeto de una determinada clase se utiliza
<code>make-instance</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(make-instance 'nombre-clase <span style="color: #8be9fd; font-style: italic;">&amp;rest</span> argumentos-de-inicio)
</pre>
</div>

<p>
Para seguir nuestro ejemplo podríamos hacer algo como:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> objeto (make-instance 'mi-clase-derivada
                            <span style="color: #8be9fd; font-style: italic;">:slot-a</span> 3 <span style="color: #8be9fd; font-style: italic;">:slot-b</span> 7
                            <span style="color: #8be9fd; font-style: italic;">:interface-slot</span> 42
                            <span style="color: #8be9fd; font-style: italic;">:su-propio-slot-a</span> 13))
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">=&gt; #s(mi-clase-derivada 3 7 42 13)
</span>(mi-clase-deriva-p objeto)
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">=&gt; t</span>
</pre>
</div>

<p>
A partir de este momento, <code>objeto</code> será una instancia de
<code>mi-clase-base</code>, con los valores especificados en su creación.
</p>

<p>
Por otro lado, hay muchas formas de acceder a los <i>slots</i> o campos de
un objeto. Los más habituales (pero no lo únicos, mira en la
documentación) son:
</p>

<dl class="org-dl">
<dt><code>slot-value</code></dt><dd><p>
Esta función nos permite acceder al valor de un
<i>slot</i>. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(slot-value objeto <span style="color: #8be9fd; font-style: italic;">:slot-a</span>)
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">=&gt; 3</span>
</pre>
</div></dd>

<dt><code>set-slot-value</code></dt><dd><p>
Esta función permite establecer valores en un
<i>slot</i>. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(set-slot-value objeto <span style="color: #8be9fd; font-style: italic;">:slot-a</span> 25)
(slot-value objeto <span style="color: #8be9fd; font-style: italic;">:slot-a</span>)
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">=&gt; 25</span>
</pre>
</div></dd>
</dl>
</div>
</div>
<div id="outline-container-org2dffd37" class="outline-3">
<h3 id="org2dffd37">Definir métodos</h3>
<div class="outline-text-3" id="text-org2dffd37">
<p>
Para definir métodos se tira de un macro que pertenece a la librería
<i>CL</i> (<i>Common LISP</i>). Siguiendo con el sencillo ejemplo que vamos
llevando, podríamos definir un método que sumara un determinado
<i>valor</i> entero al <code>slot-a</code>. Mira el ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">cl-defmethod</span> <span style="color: #50fa7b; font-weight: bold;">suma-a</span> ((obj mi-clase-derivada)
                      (valor integer))
  <span style="color: #6272a4;">"Suma VALOR al :slot-a de un objeto de mi-clase-derivada."</span>
  (set-slot-value obj <span style="color: #8be9fd; font-style: italic;">:slot-a</span>
                  (+ valor (slot-value obj <span style="color: #8be9fd; font-style: italic;">:slot-a</span>))))
</pre>
</div>

<p>
Por explicarlo un poco más detalladamente, vemos que el método
<code>suma-a</code> toma dos argumentos. El primero, <code>obj</code> es de tipo
<code>mi-clase-derivada</code>. Lo he llamado <code>obj</code>, pero si utilizas otros
lenguajes orientados a objetos lo mismo te es más fácil llamarlo
<code>this</code> o <code>self</code>. También admite un <code>valor</code> de tipo <code>integer</code>.  Después
encontramos una cadena que será la documentación del método y en
último lugar se encuentra el cuerpo del método. El cuerpo puede ser
cualquier forma válida de <code>elisp</code>. En el ejemplo, utilizo el acceso a
los campos para establecer un nuevo valor de <code>:slot-a</code> con la suma de
dicho campo y el argumento pasado en la llamada. Evaluando el código:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(suma-a objeto 4)
(slot-value objeto <span style="color: #8be9fd; font-style: italic;">:slot-a</span>)
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">=&gt; 29</span>
</pre>
</div>

<p>
La definición de métodos además tiene muchas más opciones y detalles
que deben consultarse en la documentación, pero sirva el ejemplo como
una sencilla introducción.
</p>
</div>
</div>
</div>
<div id="outline-container-org5e36ebe" class="outline-2">
<h2 id="org5e36ebe">Conclusiones</h2>
<div class="outline-text-2" id="text-org5e36ebe">
<p>
No voy a profundizar mucho más. Si alguien está interesado en la
Programación Orientada a Objetos para <i>Emacs</i>, puede mirar la
documentación del paquete <code>eieio</code>. Seguramente encontrará también
otros documentos a través de <i>Internet</i> que le sirvan de orientación.
</p>

<p>
También podemos ver el árbol de clases o la lista de métodos con los
comandos <code>eieio-browse</code> o <code>eieio-display-method-list</code>.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/elisp/index.html">elisp</a> <a href="/tags/poo/index.html">poo</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[elisp]]></category>
  <category><![CDATA[poo]]></category>
  <link>https://notxor.nueva-actitud.org/2023/01/29/programacion-orientada-a-objetos-en-emacs.html</link>
  <pubDate>Sun, 29 Jan 2023 08:43:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[LISP y familia]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-01-19</div>
<p>
<i>LISP</i> es el segundo lenguaje de programación más antiguo en activo.
Como precursor de los lenguajes funcionales no ha pasado de moda. Me
han preguntado por él y su familia y yo he contestado <i>«muy bien.
¡Gracias!»</i>. Pero, hay muchos <i>LISP</i>, innumerables. En su día hubo
tantos y tan diversos que tuvieron que crear la especificación
<i>commond lisp</i>. Además es un lenguaje que ha inspirado otros muchos (a
todos, o la mayoría de, los funcionales) y tiene también
descendientes, de los que <i>Scheme</i> y <i>Clojure</i> son miembros
destacados. Si hoy traigo este artículo es porque me preguntaron sobre
<i>LISP</i>, sobre <i>Scheme</i>, sobre las similitudes, las diferencias y sobre
la utilidad de aprenderlo o no.
</p>

<p>
Si eres usuario de <i>Emacs</i> tienes <i>LISP</i> muy cerca. Seguro que ya has
tenido que meterte en el fichero de configuración a cambiar cosas.
Quizá te haya asustado la gran cantidad de paréntesis que se cierran
al final de algunas formas. Veamos un ejemplo<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">notxor-blog-get-tags</span> (post-filename)
<span style="color: #6272a4;">"Extract the `#+filetags:` from POST-FILENAME as list of strings."</span>
(<span style="color: #ff79c6; font-weight: bold;">let</span> ((case-fold-search t))
  (<span style="color: #ff79c6; font-weight: bold;">with-temp-buffer</span>
    (insert-file-contents post-filename)
    (goto-char (point-min))
    (<span style="color: #ff79c6; font-weight: bold;">if</span> (search-forward-regexp <span style="color: #f1fa8c;">"^\\#\\+filetags:[ ]*:</span><span style="color: #8be9fd;">\\</span><span style="color: #bd93f9;">(</span><span style="color: #f1fa8c;">.*</span><span style="color: #8be9fd;">\\</span><span style="color: #bd93f9;">)</span><span style="color: #f1fa8c;">:$"</span> nil t)
        (split-string (match-string 1) <span style="color: #f1fa8c;">":"</span>)
      (<span style="color: #ff79c6; font-weight: bold;">if</span> (search-forward-regexp <span style="color: #f1fa8c;">"^\\#\\+filetags:[ ]*</span><span style="color: #8be9fd;">\\</span><span style="color: #bd93f9;">(</span><span style="color: #f1fa8c;">.+</span><span style="color: #8be9fd;">\\</span><span style="color: #bd93f9;">)</span><span style="color: #f1fa8c;">$"</span> nil t)
          (split-string (match-string 1)))))))
</pre>
</div>

<p>
Si vemos el final se juntan 7 paréntesis de cierre y hay gente que
puede perderse con tantos. Si en lugar de ser paréntesis fueran
llaves, como ocurre muchas veces en otros lenguajes, la queja puede
ser menor. Normalmente, en esos lenguajes se los ordena de la
siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">notxor-blog-get-tags</span> (post-filename)
  <span style="color: #6272a4;">"Extract the `#+filetags:` from POST-FILENAME as list of strings."</span>
  (<span style="color: #ff79c6; font-weight: bold;">let</span> ((case-fold-search t))
    (<span style="color: #ff79c6; font-weight: bold;">with-temp-buffer</span>
      (insert-file-contents post-filename)
      (goto-char (point-min))
      (<span style="color: #ff79c6; font-weight: bold;">if</span> (search-forward-regexp <span style="color: #f1fa8c;">"^\\#\\+filetags:[ ]*:</span><span style="color: #8be9fd;">\\</span><span style="color: #bd93f9;">(</span><span style="color: #f1fa8c;">.*</span><span style="color: #8be9fd;">\\</span><span style="color: #bd93f9;">)</span><span style="color: #f1fa8c;">:$"</span> nil t)
          (split-string (match-string 1) <span style="color: #f1fa8c;">":"</span>)
          (<span style="color: #ff79c6; font-weight: bold;">if</span> (search-forward-regexp <span style="color: #f1fa8c;">"^\\#\\+filetags:[ ]*</span><span style="color: #8be9fd;">\\</span><span style="color: #bd93f9;">(</span><span style="color: #f1fa8c;">.+</span><span style="color: #8be9fd;">\\</span><span style="color: #bd93f9;">)</span><span style="color: #f1fa8c;">$"</span> nil t)
              (split-string (match-string 1)
          )
        )
      )
    )
  )
)
</pre>
</div>

<p>
Este formato también es correcto sintácticamente, sin embargo, añade
unas cuantas líneas prácticamente vacías al final de la definición
que, por lo menos a quienes usamos estos lenguajes habitualmente, nos
resultan antiestéticas. Si eres programador y te pagan por líneas de
código producido, o <i>al peso</i>, olvídate de la estética.
</p>

<p>
En la última parte del artículo muestro algunos ejemplos de código
equivalente, o que hace lo mismo, si lo quieres expresar así, con el
objetivo de mostrar algunos aspectos que me parecen remarcables para
hablar de las similitudes y diferencias de los lenguajes herederos de
<i>LISP</i>.
</p>

<p>
Si me preguntas por qué creo que <i>LISP</i> y los lenguajes que se han
derivado de él, son tan potentes, mi respuesta es por las <i>macros</i>. Ya
he hablado en este <i>blog</i> sobre macros de <i>LISP</i> y no voy a darle
muchas más vueltas. Una definición corta de macro podría ser que es
una expresión que se transforma en código <i>LISP</i>. Quizá se vea más
claro con un ejemplo simple, como hacer una instrucción que incremente
variables:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defmacro</span> <span style="color: #50fa7b; font-weight: bold;">inc</span> (var)
  (list 'setq var (list '+ 1 var)))

(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">prueba-variable</span> 2)

(inc prueba-variable)
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">=&gt; 3
</span>
(inc 2)
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">=&gt; ERROR</span>
</pre>
</div>

<p>
Esa expresión del macro se transformará en <i>tiempo de compilación</i> en
la siguiente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> prueba-variable (+ 1 prueba-variable))
</pre>
</div>

<p>
En el segundo caso dará error pues se transformará en:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> 2 (+ 1 2))
</pre>
</div>

<p>
Los <i>Scheme</i> suelen utilizar la expresión <code>define-sintax</code> en lugar de
la <code>defmacro</code>, pero el objetivo es similar y el nombre en <i>Scheme</i> es
toda una declaración de intenciones.
</p>

<p>
La potencia de esto es que los sistemas basados en <i>LISP</i>, como
<i>Emacs</i> o <i>AutoCAD</i>, terminan convirtiéndose en un <i>LISP</i> disfrazado
de otra cosa, como un editor de texto o un editor gráfico. Lo mismo
ocurre los sistemas que se basen en <i>Scheme</i>. Generando su propia
sintaxis a través de las macros se pueden crear lenguajes específicos
para un ámbito de problemas. Hace, por ejemplo, que se puedan tener
librerías como <i>CLOS</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> que transforma un lenguaje funcional
permitiendo el soporte para <i>POO</i>.
</p>
<div id="outline-container-orga72f4ed" class="outline-2">
<h2 id="orga72f4ed">Funcionamiento básico</h2>
<div class="outline-text-2" id="text-orga72f4ed">
<p>
El lenguaje <i>LISP</i> es uno de esos lenguajes cuya sintaxis la puedes
aprender en 10 minutos y tardar una vida en comprender todas sus
implicaciones. Básicamente todo se basa en las <i>listas</i>, una lista es
lo que haya dentro de unos paréntesis, desde una lista vacía <code>'()</code> a
cualquier otro largo. La maquinaria de <i>LISP</i>, por defecto, intenta
ejecutar el primer elemento tomando como argumentos el resto de
elementos. Ese simple hecho hace que, en estos lenguajes, los datos
sean código y el código sea datos.
</p>

<p>
Como también hay veces en que no quieres que se ejecute el primer
elemento, porque estás trabajando con una lista de datos pura, se
utiliza la función <code>quote</code> para <i>entrecomillar</i> la función:
</p>

<div class="org-src-container">
<pre class="src src-scheme">(quote (1 2 3 4))
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">es equivalente a
</span>'(1 2 3 4)
</pre>
</div>

<p>
Decidir cuándo utilizar el apóstrofe o no depende de si quieres que la
liste <i>se ejecute</i> o se interprete como datos puros. Si quieres que
algún elemento de una lista de datos, sea interpretado, se utiliza la
coma. Por ejemplo, en <i>Scheme</i>:
</p>

<div class="org-src-container">
<pre class="src src-scheme">'(1 2 ,(- 5 2) 4)
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">'(1 2 (unquote (- 5 2)) 4)</span>
</pre>
</div>

<p>
Generalmente, el <code>unquote</code> se utiliza dentro de la definición de
macros.
</p>

<p>
Otro aspecto importante, que lo diferencia de otros lenguajes es que
las operaciones matemáticas son también como cualquier otra
función. En este caso no existen los operadores, son funciones y como
tales se utilizan como cualquier función. La precedencia de operadores
no tiene sentido, pues como listas que son se determina el orden
operando desde la más interna a la más externa, como en cualquier
grupo de listas anidadas.
</p>

<p>
Hace un tiempo hice un minicurso de <code>emacs-lisp</code> <a href="https://notxor.nueva-actitud.org/tags/elisp/index.html">que puedes encontrar
en este mismo blog</a>. Allí, en los primeros artículos hablo de las cosas
básicas con más detenimiento. Aunque está enfocado al uso específico
en <i>Emacs</i>, es aplicable, en gran medida, a otros sabores de <i>LISP</i>.
</p>
</div>
</div>
<div id="outline-container-orgc78c0ca" class="outline-2">
<h2 id="orgc78c0ca">Similitudes y diferencias</h2>
<div class="outline-text-2" id="text-orgc78c0ca">
<p>
Obviadas las <i>macros</i> en el código, puesto que estaríamos en un nivel
más profundo de lo que serían estos lenguajes. El resto de
comparaciones están relacionadas con la <i>maquinaria</i> que hay debajo.
</p>

<p>
Una diferencia importante entre <i>LISP</i> y <i>Scheme</i> es que el primero
tiene dos espacios de nombres independientes para <i>variables</i> y
<i>funciones</i> y <i>Scheme</i> sólo dispone de uno para todo. Eso hace que
<i>LISP</i> utilice <code>defvar</code> para definir variables y <code>defun</code> para definir
funciones, mientras que <i>Scheme</i> haga ambas cosas con <code>define</code>.
</p>

<p>
También en este artículo se menciona <i>Clojure</i> como lenguaje heredero
de <i>LISP</i>. También cuenta con diferentes espacios de nombres para
variables y funciones. En su caso se utilizan las funciones <code>def</code> para
variables y <code>defn</code> para funciones. En su caso, está utilizando la
máquina virtual de <i>Java</i>, lo que le proporciona otra serie de
herramientas y matices que explota el lenguaje. Se podría hablar casi
de un híbrido, pues se trabaja con la <i>JVM</i> con una sintaxis similar a
la de <i>LISP</i>. Tiene otras funcionalidades, entre la que puede ser
utilizado para <i>exportar</i> a <i>Javascript</i> para la programación <i>web</i>.
Pero tampoco voy a meterme en más explicaciones sobre <i>Clojure</i>.
</p>

<p>
Además de estas diferencias, nos encontramos con algunas herramientas
que distinguen entre mayúsculas y minúsculas y otras que no. Veamos un
ejemplo en <code>emacs-lisp</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">Estado</span> 0)
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">estado</span> 2)
Estado
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">=&gt; 0
</span>estado
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">=&gt; 2</span>
</pre>
</div>

<p>
En algunos otros <i>LISP</i> se produciría un error porque ambas variables
se convertirían internamente en <code>ESTADO</code> y por tanto chocarían en el
espacio de nombres.
</p>
</div>
<div id="outline-container-orgd092283" class="outline-3">
<h3 id="orgd092283">Variables</h3>
<div class="outline-text-3" id="text-orgd092283">
<p>
Las variables tanto en <i>LISP</i> como en <i>Scheme</i> pueden modificarse
utilizando la función de asignación <code>set</code> en <i>LISP</i> y la función
<code>set!</code> en <i>Scheme</i>. Sin embargo, en <i>Clojure</i>, por defecto, las
variables no pueden modificarse, a no ser que se especifique en el
código con <code>^dynamic</code> y por convención se encierra el nombre mediante
asteriscos para que quien lea el código sepa directamente que esa
variable puede cambiar su valor a lo largo del tiempo de ejecución.
</p>
</div>
</div>
<div id="outline-container-orgbbe09a4" class="outline-3">
<h3 id="orgbbe09a4">Funciones</h3>
<div class="outline-text-3" id="text-orgbbe09a4">
<p>
Como dije antes las <i>funciones</i> son <i>listas</i>. La diferencia es que
entre los <i>Scheme</i> y los <i>LISP</i> se definen en un espacio de nombres
general o en uno específico. La consecuencia directa es que en <i>LISP</i>
puedes encontrar que bajo una misma denominación se encuentra una
función pero también puede haber una variable.
</p>

<p>
Recuerda, siempre se intenta <i>ejecutar</i> el primer elemento de la lista
utilizando el resto de elementos como parámetros. No hay más secreto.
Llamar a un función es colocar su nombre como primer elemento de una
lista.
</p>
</div>
</div>
<div id="outline-container-orga58e496" class="outline-3">
<h3 id="orga58e496">Compilación y <i>REPL</i></h3>
<div class="outline-text-3" id="text-orga58e496">
<p>
La mayoría de los <i>LISP</i> y derivados pueden compilarse, bien para
generar binarios del sistema, o bien para generar <i>bytecode</i>
intermedio, también pueden utilizarse desde <i>scripts</i> interpretados o,
por último, desde su propio <i>prompt REPL</i>. Sin embargo, algunos de
éstos están más pensados para ser compilados, otros para ser más
interactivos y otros para ser más de automatización por
<i>scripts</i>. Aunque más adelante muestro un pequeño estudio de
velocidades no debes quedarte con el dato puro. Todas las pruebas se
han realizado utilizando las herramientas para <i>script</i> de cada una de
ellas. Evidentemente, en esas pruebas tienen ventaja los lenguajes
diseñados para ello. Otros como <i>Clojure</i> tienen el problema añadido
de que deben cargar la máquina de <i>Java</i> cuando funciona para
<i>script</i>, en una aplicación en funcionamiento con la máquina de <i>Java</i>
ya cargada, será tan veloz como lo sería <i>Java</i> y por tanto, su
rendimiento es mucho mejor cuando se compila a <code>jar</code>. <i>Commond LISP</i>
está pensado para aplicaciones más pesadas y ser compilado. Los
<i>Scheme</i> son más de <i>script</i>, aunque en el caso de <i>Racket</i> también
tenga su compilador: <code>raco</code>. En fin, que tienes múltiples opciones de
generar tus aplicaciones y, según para qué las quieras, te puedes
decantar por una herramienta u otra.
</p>
</div>
</div>
<div id="outline-container-org3ad468e" class="outline-3">
<h3 id="org3ad468e">Funciones lambda</h3>
<div class="outline-text-3" id="text-org3ad468e">
<p>
En la mayoría de casos la forma de generar una función sin nombre es
utilizar la forma <code>(lambda ...)</code>, salvo en <i>Clojure</i> que se utiliza la
forma <code>(fn ...)</code>. En el caso de los <i>Scheme</i>, podemos observar que las
dos siguientes formas son equivalentes y la primera es un poco de
<i>azúcar sintáctico</i> para la segunda:
</p>

<div class="org-src-container">
<pre class="src src-scheme">(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">mul</span> x y)
  (* x y))
(mul 2 3)
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">=&gt; 6
</span>
(<span style="color: #ff79c6; font-weight: bold;">define</span> <span style="color: #50fa7b; font-weight: bold;">mul2</span>
  (<span style="color: #ff79c6; font-weight: bold;">lambda</span> (x y) (* x y)))
(mul 2 3)
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">=&gt; 6</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org97ea7b7" class="outline-3">
<h3 id="org97ea7b7">Resultados</h3>
<div class="outline-text-3" id="text-org97ea7b7">
<p>
Por otro lado, los resultados de los <i>scripts</i> son similares pero no
idénticos en todos los casos. Si corres el código de cada ejemplo,
verás que la mayoría de ellos da un resultado <i>preciso</i> de las
operaciones en el formato <code>numerador/denominador</code>, mientras que
<i>Emacs</i> da el resultado numérico decimal.
</p>

<p>
En las pruebas realizadas se calcularon 5 ensayos con cada herramienta
y en la siguiente tabla encontramos los resultados medios de cada uno
de los tiempos de ejecución.
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Lenguaje</th>
<th scope="col" class="org-right">real</th>
<th scope="col" class="org-right">user</th>
<th scope="col" class="org-right">sys</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">emacs lisp</td>
<td class="org-right">0.224</td>
<td class="org-right">0.180</td>
<td class="org-right">0.041</td>
</tr>

<tr>
<td class="org-left">commond lisp SBCL</td>
<td class="org-right">0.396</td>
<td class="org-right">0.378</td>
<td class="org-right">0.019</td>
</tr>

<tr>
<td class="org-left">scheme guile</td>
<td class="org-right">0.291</td>
<td class="org-right">0.667</td>
<td class="org-right">0.039</td>
</tr>

<tr>
<td class="org-left">scheme racket</td>
<td class="org-right">0.257</td>
<td class="org-right">0.222</td>
<td class="org-right">0.036</td>
</tr>

<tr>
<td class="org-left">clojure</td>
<td class="org-right">0.861</td>
<td class="org-right">0.873</td>
<td class="org-right">0.117</td>
</tr>
</tbody>
</table>

<p>
La ejecución de cada uno de los <i>scripts</i> se realizó con los
siguientes comandos:
</p>

<ol class="org-ol">
<li><p>
<i>Emacs LISP</i>:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; emacs --script emacs.el

4999950000
</pre>
</div></li>

<li><p>
<i>Commond LISP SBCL</i>:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; sbcl --script sbcl.lisp

5688945777431137355938334570000/1137800533491555986667 
</pre>
</div></li>

<li><p>
<i>Guile</i>:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; guile scheme.scm
5689059557484486511537001270000/1137800533491555986667
</pre>
</div></li>

<li><p>
<i>Racket</i>:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; racket racket.rkt
5689059557484486511537001270000/1137800533491555986667
</pre>
</div></li>

<li><p>
<i>Clojure</i>:
</p>

<div class="org-src-container">
<pre class="src src-shell">clojure -M clojure.clj
-5689002665857759799939/5689002667457779933335
</pre>
</div>

<p>
No tengo muy claro a qué se debe la discrepancia en el resultado en
este caso. Estoy convencido de que tiene que ver con la forma de
declarar variables y gestionarlas. El cambio en el código más
importante es que sólo es válido el valor de una variable dinámica
dentro del bloque <code>binding</code>, por eso el <code>print</code> se ha desplazado a
la función principal. Seguramente, además, el error será mío y
necesitará seguramente otro acumulador intermedio, pero en el
intento de mantener el código lo más parecido entre unos y otros
chismáticos, ha hecho que a <i>Clojure</i> se le atragante el código que se
hizo primero para <code>emacs-lisp</code>.
</p></li>
</ol>
</div>
</div>
</div>
<div id="outline-container-orgffe02ee" class="outline-2">
<h2 id="orgffe02ee">Conclusiones</h2>
<div class="outline-text-2" id="text-orgffe02ee">
<p>
En fin, espero que esto te sirva para apreciar las diferencias y
semejanzas de los lenguajes de la familia de <i>LISP</i>. Siendo una
comparativa rápida, ya puedes hacerte una idea de lo básico.
</p>

<p>
En cuanto a la utilidad no sabría decir. Desde luego que yo le
encuentro utilidad, tengo a estas alturas mucho código metido en mi
<i>Emacs</i> para hacer mis cosas y todas las semanas me encuentro metiendo
más código o reformando el que ya tengo. Pero bueno, ¿de qué te sirve
un destornillador si nunca pones o quitas tornillos?
</p>
</div>
</div>
<div id="outline-container-orga098f14" class="outline-2">
<h2 id="orga098f14">Código de pruebas</h2>
<div class="outline-text-2" id="text-orga098f14">
</div>
<div id="outline-container-org7758415" class="outline-3">
<h3 id="org7758415">emacs-lisp</h3>
<div class="outline-text-3" id="text-org7758415">
</div>
<div id="outline-container-org2e16c5f" class="outline-4">
<h4 id="org2e16c5f">Código</h4>
<div class="outline-text-4" id="text-org2e16c5f">
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">ochok</span> (k)
  <span style="color: #6272a4;">"Define una funci&#243;n que devuelve el valor de multiplicar por 8 K."</span>
  (* 8 k))

(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">calculo-total</span> 0
  <span style="color: #6272a4;">"Define una variable."</span>)

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">termino</span> (k)
  <span style="color: #6272a4;">"Realiza algunos c&#225;lculos con K."</span>
  (<span style="color: #ff79c6; font-weight: bold;">let</span> ((n (ochok k)))
    (- (/ 4 (+ n 1))
       (/ 2 (+ n 4))
       (/ 1 (+ n 5))
       (/ 1 (+ n 6)))))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">f-lambda</span> (cuenta)
  <span style="color: #6272a4;">"Muestra como se usa una funci&#243;n lambda y se la aplica CUENTA."</span>
    ((<span style="color: #ff79c6; font-weight: bold;">lambda</span> (x y) (* x y )) (termino cuenta) 12))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">calcular</span> (veces)
  <span style="color: #6272a4;">"Repite un n&#250;mero de VECES las mismas operaciones."</span>
  (<span style="color: #ff79c6; font-weight: bold;">dotimes</span> (n veces)
    (<span style="color: #ff79c6; font-weight: bold;">setq</span> calculo-total (+ n calculo-total (f-lambda veces)))))

(calcular 100000)
(print calculo-total)
</pre>
</div>
</div>
</div>
<div id="outline-container-orgda2851d" class="outline-4">
<h4 id="orgda2851d">Tiempos</h4>
<div class="outline-text-4" id="text-orgda2851d">
<table>


<colgroup>
<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-right">Ensayo</th>
<th scope="col" class="org-right">real</th>
<th scope="col" class="org-right">user</th>
<th scope="col" class="org-right">sys</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-right">1</td>
<td class="org-right">0.223</td>
<td class="org-right">0.183</td>
<td class="org-right">0.037</td>
</tr>

<tr>
<td class="org-right">2</td>
<td class="org-right">0.223</td>
<td class="org-right">0.171</td>
<td class="org-right">0.049</td>
</tr>

<tr>
<td class="org-right">3</td>
<td class="org-right">0.222</td>
<td class="org-right">0.167</td>
<td class="org-right">0.052</td>
</tr>

<tr>
<td class="org-right">4</td>
<td class="org-right">0.228</td>
<td class="org-right">0.201</td>
<td class="org-right">0.026</td>
</tr>

<tr>
<td class="org-right">5</td>
<td class="org-right">0.225</td>
<td class="org-right">0.180</td>
<td class="org-right">0.042</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-right"><b>Media</b></td>
<td class="org-right">0.224</td>
<td class="org-right">0.180</td>
<td class="org-right">0.041</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="outline-container-orgd3f4fe6" class="outline-3">
<h3 id="orgd3f4fe6">Commond Lisp - SBCL</h3>
<div class="outline-text-3" id="text-orgd3f4fe6">
</div>
<div id="outline-container-org6097a32" class="outline-4">
<h4 id="org6097a32">Código</h4>
<div class="outline-text-4" id="text-org6097a32">
<div class="org-src-container">
<pre class="src src-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">ochok</span> (k)
  <span style="color: #6272a4;">"Define una funci&#243;n que devuelve el valor de multiplicar por 8 K."</span>
  (* 8 k))

(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">calculo-total</span> 0
  <span style="color: #6272a4;">"Define una variable."</span>)

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">termino</span> (k)
  <span style="color: #6272a4;">"Realiza algunos c&#225;lculos con K."</span>
  (<span style="color: #ff79c6; font-weight: bold;">let</span> ((n (ochok k)))
    (- (/ 4 (+ n 1))
       (/ 2 (+ n 4))
       (/ 1 (+ n 5))
       (/ 1 (+ n 6)))))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">f-lambda</span> (cuenta)
  <span style="color: #6272a4;">"Muestra como se usa una funci&#243;n lambda y se la aplica CUENTA."</span>
    ((<span style="color: #ff79c6; font-weight: bold;">lambda</span> (x y) (* x y )) (termino cuenta) 12))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">calcular</span> (veces)
  <span style="color: #6272a4;">"Repite un n&#250;mero de VECES las mismas operaciones."</span>
    (<span style="color: #ff79c6; font-weight: bold;">dotimes</span> (n veces)
      (setq calculo-total (+ n calculo-total (f-lambda veces)))))

(calcular 100000)
(print calculo-total)
</pre>
</div>
</div>
</div>
<div id="outline-container-org31ad3cc" class="outline-4">
<h4 id="org31ad3cc">Tiempos</h4>
<div class="outline-text-4" id="text-org31ad3cc">
<table>


<colgroup>
<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-right">Ensayo</th>
<th scope="col" class="org-right">real</th>
<th scope="col" class="org-right">user</th>
<th scope="col" class="org-right">sys</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-right">1</td>
<td class="org-right">0.396</td>
<td class="org-right">0.372</td>
<td class="org-right">0.024</td>
</tr>

<tr>
<td class="org-right">2</td>
<td class="org-right">0.399</td>
<td class="org-right">0.382</td>
<td class="org-right">0.017</td>
</tr>

<tr>
<td class="org-right">3</td>
<td class="org-right">0.396</td>
<td class="org-right">0.379</td>
<td class="org-right">0.017</td>
</tr>

<tr>
<td class="org-right">4</td>
<td class="org-right">0.395</td>
<td class="org-right">0.371</td>
<td class="org-right">0.024</td>
</tr>

<tr>
<td class="org-right">5</td>
<td class="org-right">0.396</td>
<td class="org-right">0.384</td>
<td class="org-right">0.012</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-right"><b>Media</b></td>
<td class="org-right">0.396</td>
<td class="org-right">0.378</td>
<td class="org-right">0.019</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="outline-container-org728d1e2" class="outline-3">
<h3 id="org728d1e2">Scheme guile</h3>
<div class="outline-text-3" id="text-org728d1e2">
</div>
<div id="outline-container-org4ce10c3" class="outline-4">
<h4 id="org4ce10c3">Código</h4>
<div class="outline-text-4" id="text-org4ce10c3">
<div class="org-src-container">
<pre class="src src-scheme">(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">ochok</span> k)
  <span style="color: #6272a4;">"Define una funci&#243;n que devuelve el valor de multiplicar por 8 K."</span>
  (* 8 k))

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Define una variable global
</span>(<span style="color: #ff79c6; font-weight: bold;">define</span> <span style="color: #50fa7b; font-weight: bold;">calculo-total</span> 0
  <span style="color: #f1fa8c;">"Una variable global para acumular el resultado."</span>)

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">termino</span> k)
  <span style="color: #6272a4;">"Realiza algunos c&#225;lculos con K."</span>
  (<span style="color: #ff79c6; font-weight: bold;">let</span> ((n (ochok k)))
    (- (/ 4 (+ n 1))
       (/ 2 (+ n 4))
       (/ 1 (+ n 5))
       (/ 1 (+ n 6)))))

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">f-lambda</span> cuenta)
  <span style="color: #6272a4;">"Muestra como se usa una funci&#243;n lambda y se la aplica CUENTA."</span>
  ((<span style="color: #ff79c6; font-weight: bold;">lambda</span> (x y) (* x y )) (termino cuenta) 12))

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">calcular</span> veces)
  <span style="color: #6272a4;">"Repite un n&#250;mero de VECES las mismas operaciones."</span>
  (<span style="color: #ff79c6; font-weight: bold;">let</span> <span style="color: #50fa7b; font-weight: bold;">loop</span> ((n veces))
    (<span style="color: #ff79c6; font-weight: bold;">unless</span> (zero? n)
      (<span style="color: #ff79c6; font-weight: bold;">set!</span> calculo-total (+ n calculo-total (f-lambda veces)))
      (loop (- n 1)))))

(calcular 100000)
(display calculo-total)
</pre>
</div>
</div>
</div>
<div id="outline-container-orgd88777a" class="outline-4">
<h4 id="orgd88777a">Tiempos</h4>
<div class="outline-text-4" id="text-orgd88777a">
<table>


<colgroup>
<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-right">Ensayo</th>
<th scope="col" class="org-right">real</th>
<th scope="col" class="org-right">user</th>
<th scope="col" class="org-right">sys</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-right">1</td>
<td class="org-right">0.293</td>
<td class="org-right">0.720</td>
<td class="org-right">0.009</td>
</tr>

<tr>
<td class="org-right">2</td>
<td class="org-right">0.296</td>
<td class="org-right">0.663</td>
<td class="org-right">0.047</td>
</tr>

<tr>
<td class="org-right">3</td>
<td class="org-right">0.281</td>
<td class="org-right">0.632</td>
<td class="org-right">0.064</td>
</tr>

<tr>
<td class="org-right">4</td>
<td class="org-right">0.297</td>
<td class="org-right">0.648</td>
<td class="org-right">0.049</td>
</tr>

<tr>
<td class="org-right">5</td>
<td class="org-right">0.286</td>
<td class="org-right">0.673</td>
<td class="org-right">0.027</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-right"><b>Media</b></td>
<td class="org-right">0.291</td>
<td class="org-right">0.667</td>
<td class="org-right">0.039</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="outline-container-org9461c13" class="outline-3">
<h3 id="org9461c13">Scheme racket</h3>
<div class="outline-text-3" id="text-org9461c13">
</div>
<div id="outline-container-org5a055fc" class="outline-4">
<h4 id="org5a055fc">Código</h4>
<div class="outline-text-4" id="text-org5a055fc">
<div class="org-src-container">
<pre class="src src-scheme">#lang racket/base

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">ochok</span> k)
  <span style="color: #6272a4;">"Define una funci&#243;n que devuelve el valor de multiplicar por 8 K."</span>
  (* 8 k))

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Define una variable global
</span>(<span style="color: #ff79c6; font-weight: bold;">define</span> <span style="color: #50fa7b; font-weight: bold;">calculo-total</span> 0)

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">termino</span> k)
  <span style="color: #6272a4;">"Realiza algunos c&#225;lculos con K."</span>
  (<span style="color: #ff79c6; font-weight: bold;">let</span> ((n (ochok k)))
    (- (/ 4 (+ n 1))
       (/ 2 (+ n 4))
       (/ 1 (+ n 5))
       (/ 1 (+ n 6)))))

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">f-lambda</span> cuenta)
  <span style="color: #6272a4;">"Muestra como se usa una funci&#243;n lambda y se la aplica CUENTA."</span>
    ((<span style="color: #ff79c6; font-weight: bold;">lambda</span> (x y) (* x y )) (termino cuenta) 12))

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">calcular</span> veces)
  <span style="color: #6272a4;">"Repite un n&#250;mero de VECES las mismas operaciones."</span>
  (<span style="color: #ff79c6; font-weight: bold;">let</span> <span style="color: #50fa7b; font-weight: bold;">loop</span> ((n veces))
    (<span style="color: #ff79c6; font-weight: bold;">unless</span> (zero? n)
      (<span style="color: #ff79c6; font-weight: bold;">set!</span> calculo-total (+ n calculo-total (f-lambda veces)))
      (loop (- n 1)))))

(calcular 100000)
(display calculo-total)
</pre>
</div>
</div>
</div>
<div id="outline-container-orge6a872d" class="outline-4">
<h4 id="orge6a872d">Tiempos racket</h4>
<div class="outline-text-4" id="text-orge6a872d">
<table>


<colgroup>
<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-right">Ensayo</th>
<th scope="col" class="org-right">real</th>
<th scope="col" class="org-right">user</th>
<th scope="col" class="org-right">sys</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-right">1</td>
<td class="org-right">0.263</td>
<td class="org-right">0.243</td>
<td class="org-right">0.021</td>
</tr>

<tr>
<td class="org-right">2</td>
<td class="org-right">0.250</td>
<td class="org-right">0.202</td>
<td class="org-right">0.048</td>
</tr>

<tr>
<td class="org-right">3</td>
<td class="org-right">0.254</td>
<td class="org-right">0.214</td>
<td class="org-right">0.041</td>
</tr>

<tr>
<td class="org-right">4</td>
<td class="org-right">0.262</td>
<td class="org-right">0.226</td>
<td class="org-right">0.036</td>
</tr>

<tr>
<td class="org-right">5</td>
<td class="org-right">0.256</td>
<td class="org-right">0.223</td>
<td class="org-right">0.032</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-right"><b>Media</b></td>
<td class="org-right">0.257</td>
<td class="org-right">0.222</td>
<td class="org-right">0.036</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="outline-container-orgc7732d0" class="outline-3">
<h3 id="orgc7732d0">Clojure</h3>
<div class="outline-text-3" id="text-orgc7732d0">
</div>
<div id="outline-container-org5d43462" class="outline-4">
<h4 id="org5d43462">Código</h4>
<div class="outline-text-4" id="text-org5d43462">
<div class="org-src-container">
<pre class="src src-clojure">(defn ochok [k]
  "Define una función que devuelve el valor de multiplicar por 8 K."
  (* 8 k))

;; Define una variable global y dinámica
(def ^:dynamic *calculo-total* 0)

(defn termino [k]
  "Realiza algunos cálculos con K."
  (let [n (ochok k)]
    (- (/ 4 (+ n 1))
       (/ 2 (+ n 4))
       (/ 1 (+ n 5))
       (/ 1 (+ n 6)))))

(defn f-lambda [cuenta]
  "Muestra como se usa una función lambda y se la aplica CUENTA."
    ((fn [x y] (* x y )) (termino cuenta) 12))

(defn calcular [veces]
  "Repite un número de VECES las mismas operaciones."
  (binding [*calculo-total* 0]
    (loop [n veces]
    (if (&lt; n 0)
      (set! *calculo-total* (+ n *calculo-total* (f-lambda veces)))
      (recur (- n 1))))
  (print *calculo-total*)))

(calcular 100000)
</pre>
</div>
</div>
</div>
<div id="outline-container-orgc80a97b" class="outline-4">
<h4 id="orgc80a97b">Tiempos</h4>
<div class="outline-text-4" id="text-orgc80a97b">
<table>


<colgroup>
<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-right">Ensayo</th>
<th scope="col" class="org-right">real</th>
<th scope="col" class="org-right">user</th>
<th scope="col" class="org-right">sys</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-right">1</td>
<td class="org-right">0.881</td>
<td class="org-right">2.122</td>
<td class="org-right">0.096</td>
</tr>

<tr>
<td class="org-right">2</td>
<td class="org-right">0.851</td>
<td class="org-right">2.072</td>
<td class="org-right">0.136</td>
</tr>

<tr>
<td class="org-right">3</td>
<td class="org-right">0.870</td>
<td class="org-right">0.052</td>
<td class="org-right">0.111</td>
</tr>

<tr>
<td class="org-right">4</td>
<td class="org-right">0.848</td>
<td class="org-right">0.058</td>
<td class="org-right">0.131</td>
</tr>

<tr>
<td class="org-right">5</td>
<td class="org-right">0.853</td>
<td class="org-right">0.063</td>
<td class="org-right">0.113</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-right"><b>Media</b></td>
<td class="org-right">0.861</td>
<td class="org-right">0.873</td>
<td class="org-right">0.117</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
El ejemplo está sacado de una función del código que mantiene
este sitio estático. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Common Lisp Object System</i> es una librería estándar de <i>LISP</i>
que permite la <i>Programación Orientada a Objetos</i>.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/lisp/index.html">lisp</a> <a href="/tags/elisp/index.html">elisp</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[lisp]]></category>
  <category><![CDATA[elisp]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2023/01/19/lisp-y-familia.html</link>
  <pubDate>Thu, 19 Jan 2023 13:28:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[¿Mastodon necesita citar toots?]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2023-01-05</div>
<p>
Llevo unos días viendo por <i>Mastodon</i> que <i>Eugen</i> se está replanteando
proporcionar la herramienta de citar <i>toots</i> a <i>Mastodon</i>, cuando
hasta el momento se ha negado. Este artículo es una reflexión en voz
alta en la que intento decidir si es bueno o malo el permitir las
citas de <i>toots</i>. El argumento en contra, lo da el propio <i>Eugen</i>
cuando afirma que es una herramienta que se usa para lanzar las
huestes de seguidores contra alguien, como se demuestra en la red del
pájaro azul. Primeras reflexiones sobre el hecho.
</p>
<div id="outline-container-orgad8af00" class="outline-2">
<h2 id="orgad8af00">Citas y mala fe</h2>
<div class="outline-text-2" id="text-orgad8af00">
<p>
<i>Mastodon</i>, sobre todo desde que esta red se ha popularizado más
gracias a la ímproba labor de <i>Elon Musk</i> en favor de las tecnologías
descentralizadas, no es un lugar idílico. En la red, ningún lugar lo
es. Los sitios, las páginas, las herramientas, las redes sociales, los
foros, los... vamos, el ambiente de cualquier lugar donde los seres
humanos se relacionen dependen de cómo se relacionan las personas
presentes. La tecnología es aséptica y está fuera de toda
consideración moral, no es buena o mala, como no es bueno o malo un
cuchillo jamonero, sino que depende de las intenciones del que lo
empuña: puede cortar jamón o introducirse entre las costillas de
alguien y el cuchillo en sí mismo, está más allá de toda consideración
moral.
</p>

<p>
Por tanto, el incluir la opción de citar <i>toots</i> puede ser bueno,
cuando se emplea con fines documentales y malo cuando se emplea, como
dice <i>Eugen</i> para lanzar las hordas de seguidores contra alguien.
</p>

<p>
Mi pregunta es, ¿nos libra ésto de la <i>mala fe</i>? La respuesta es que
no. De hecho, de vez en cuando se ven capturas de <i>toots</i> en formato
de imagen que se añaden como adjunto al <i>toot</i>. No suelo leerlas, no
me gustan, por las siguientes razones:
</p>

<ol class="org-ol">
<li>Hasta ahora tenemos la opción de que nuestros <i>toots</i> se borren
automáticamente y pasen al olvido. En mi caso, mis cuentas están
configuradas para que eliminen <i>toots</i> a la semana de ser
publicados. Si hacen una captura de un <i>toot</i> mío y lo difunden por
ahí, pierdo el control de mi contenido.</li>
<li>Las capturas de pantalla pueden manipularse para decir cualquier
cosa. Si existe <i>mala fe</i>, cualquiera puede coger un <i>toot</i> tuyo y
modificarlo para que parezca que dices algo que en realidad no
dices. Y no, no hay evidencia gráfica de que la captura esté siendo
manipulada... creo que necesito explicarlo más y lo haré en el
siguiente apartado.</li>
<li>Normalmente he visto, tal y como dice <i>Eugen</i>, que se utiliza para
señalar a la persona citada, dando pie al acoso.</li>
</ol>

<p>
Al final, quien quiera terminará citando lo que le venga en gana y no
proveer de dicha herramienta solamente va a significar una pequeña
incomodidad para el que quiere hacerlo.
</p>
</div>
</div>
<div id="outline-container-org3282e27" class="outline-2">
<h2 id="org3282e27">Captura de toot</h2>
<div class="outline-text-2" id="text-org3282e27">
<p>
Como he dicho en el apartado anterior, se puede modificar un <i>toot</i>
sin siquiera necesitar grandes herramientas para hacerlo, lo voy a
hacer con un <i>toot</i> mío, que luego borraré. Veamos la siguiente
imagen:
</p>


<figure id="org3b06862">
<img src="./imagenes/Captura_toot-normal.png" alt="Captura_toot-normal.png">

</figure>

<p>
He publicado un <i>toot</i> con una de mis cuentas en <i>Mastodon</i>. En la
imagen podemos apreciar qué texto tiene y cómo se ve en la columna
normal de <i>toots</i>.<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>
</p>

<p>
Puesto que iban entrando más <i>toots</i> y era complicado hacer capturas
de pantalla mientras editaba, seleccioné el <i>toot</i> y lo llevé a la
columna de conversaciones. Como no es una conversación aparece solo y
me permite trabajar de manera más sencilla.
</p>

<p>
Lo siguiente es seleccionar el texto que quieres modificar:
</p>


<figure id="orgd691058">
<img src="./imagenes/Captura_seleccionar-toot-texto.png" alt="Captura_seleccionar-toot-texto.png">

</figure>

<p>
Una vez que tenemos seleccionado el texto, pulsamos el botón derecho
del ratón y tendremos un menú que diga algo como <i>Inspeccionar
elemento</i>. Nos llevará al código interno de la página y nos mostrará
el contenido:
</p>


<figure id="orgdc0edbf">
<img src="./imagenes/Captura_inspeccionar-texto.png" alt="Captura_inspeccionar-texto.png">

</figure>

<p>
Podemos modificar el contenido, porque lo tenemos ahí en pantalla y
generar una imagen capturando los cambios:
</p>


<figure id="org6cb308a">
<img src="./imagenes/Captura_toot-modificado.png" alt="Captura_toot-modificado.png">

</figure>

<p>
Este sistema es <i>muy burdo</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>, pero hay quien <i>van con él</i> y es
mucho más grave que la cita directa, porque permite no sólo sacar de
contexto lo que alguien dice, sino además mostrar que dice lo que
nunca dijo. Además no tienes que modificar ninguna imagen, buscar
fuentes equivalentes y hacer un apaño gráfico (que no está al alcance
de cualquiera). Directamente el navegador te proporciona todo:
colores, fuentes y renderizado, ajustándose perfectamente a tu
pantalla, como si lo hubiera escrito de verdad la persona citada.
</p>
</div>
</div>
<div id="outline-container-org01865af" class="outline-2">
<h2 id="org01865af">Ya se puede citar un toot</h2>
<div class="outline-text-2" id="text-org01865af">
<p>
De todas maneras, en la actualidad ya se puede citar un <i>toot</i> en
<i>Mastodon</i>. Cuando lo seleccionamos en el navegador nos proporciona
una URL única que podemos pegar en nuestro <i>toot</i> para realizar la
cita. La opción, supongo, que sería poner una manera fácil cuando
accedemos a <i>Mastodon</i> desde una aplicación, o que sea más sencillo
que copiar-pegar una URL desde el navegador y poco más.
</p>

<p>
Luego la herramienta está para quien quiera usarla.
</p>
</div>
</div>
<div id="outline-container-orgbf5576f" class="outline-2">
<h2 id="orgbf5576f">Conclusiones</h2>
<div class="outline-text-2" id="text-orgbf5576f">
<p>
Sigo sin tener claro si la herramienta de citar <i>toots</i> mejorará la
experiencia o terminará siendo un arma para el acoso, como se ha visto
en otras redes. Algunos periodistas o científicos, o investigadores,
por ejemplo, pueden utilizarla para citar fuentes. Para esos fines, el
poder señalar de dónde proviene la información o, simplemente, señalar
un hilo del que tirar para continuar con tu búsqueda, es una
herramienta interesante.
</p>

<p>
Si caemos en la cultura del odio y/o de la cancelación, desde luego es
un arma de destrucción de la paz, el diálogo y la confrontación de
ideas. Vivo mejor sin nadie que me diga qué debo pensar o contra quién
tengo que lanzar mis bilis. Prefiero no odiar y no juzgar a nadie y
que todos se puedan expresar con libertad. Sólo puedo ser
intransigente con los intransigentes, con los de <i>estás conmigo o
contra mí</i>, con los nazis, los fascistas, los racistas, los
machistas... en fin, sólo soy intransigente con aquellos que antes de
apreciar un ser humano y sus actos, se limitan a mirar una <i>etiqueta</i>
donde clasificarlo, generalmente excluyéndolo de un difuso concepto de
<i>nosotros</i> que está sustentado por los eslóganes que sus tres neuronas
pueden aguantar.
</p>

<p>
Pero esto, creo, que nada tiene que ver con la herramienta en sí, sino
con su uso.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
A estas alturas ya está borrado. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Se puede utilizar también para modificar capturas de titulares
de periódicos y cualquier otra página. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/mastodon/index.html">mastodon</a> ]]></description>
  <category><![CDATA[mastodon]]></category>
  <link>https://notxor.nueva-actitud.org/2023/01/05/mastodon-necesita-citar-toots.html</link>
  <pubDate>Thu, 05 Jan 2023 09:48:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Curso básico de Esperanto]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-12-30</div>
<p>
Este 2023 comenzaremos el año aprendiendo Esperanto. Será un curso
básico gratuito de este idioma, comenzando desde cero y avanzando poco
a poco hasta alcanzar un nivel básico en el que se podría mantener una
conversación informal sobre temas de la vida cotidiana. El
<span id="nota">Esperanto<span class="nota">Si piensas que <i>los idiomas se te dan mal</i>, prueba con esta lengua.</span></span>  es una lengua que nació con el objetivo de ser
una lengua auxiliar que sirviera como medio de comunicación entre
diferentes culturas y los hablantes de distintos idiomas. Se diseñó
para:
</p>

<ul class="org-ul">
<li>Servir de unión entre los pueblos del mundo permitiendo la
comunicación entre las personas.</li>
<li>Ser fácil de aprender:
<ul class="org-ul">
<li>Una gramática sin demasiadas reglas</li>
<li>Gramática sin excepciones</li>
<li>Una sola conjugación sin verbos irregulares</li>
</ul></li>
<li>Facilidad para crear nuevas palabras mediante un completo sistema de
afijos y palabras compuestas.</li>
<li>Gran expresividad y precisión semántica.</li>
</ul>

<div class="tabs">
  <div class="tab">
    <input type="radio" id="accion1" name="rd">
    <label class="tab-label" for="accion1">Instrucciones (español)</label>
    <div class="tab-content">

<ul class="org-ul">
<li><p>
El método que se utilizará será <i>la zagreba metodo</i> y se encontrará
disponible de forma completa en esta misma página en el enlace:
</p>

<p>
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo/">https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo/</a>
</p></li>

<li>Para inscribirse se puede enviar un correo electrónico a la
dirección <a href="mailto:kurso-esperanto@nueva-actitud.org">mailto:kurso-esperanto@nueva-actitud.org</a> antes del 8 de
enero de 2023</li>

<li>Cada semana se realizará un tema:

<ul class="org-ul">
<li>Cada tema consta de un texto y audio, un espacio de gramática, un
pequeño diccionario de términos nuevos y unos ejercicios.</li>
<li>El alumno escuchará el audio, estudiará la gramática y realizará
los ejercicios por su cuenta. Completado todo, se enviarán los
ejercicios al correo electrónico del curso.</li>
<li>El profesor corregirá los ejercicios y enviará las aclaraciones
personalizadas a cada alumno.</li>
</ul></li>

<li><p>
Cada 2-4 temas, dependiendo de la disponibilidad de alumnos y
profesor se realizarán sesiones de tutoría por videoconferencia. La
sala se podrá encontrar en el siguiente enlace:
</p>

<p>
<a href="https://jitsi.nobigtech.es/EsperantaKurso">https://jitsi.nobigtech.es/EsperantaKurso</a>
</p>

<ul class="org-ul">
<li>Durante las sesiones de tutoría se realizarán las siguientes
actividades:

<ul class="org-ul">
<li>Lectura en Esperanto de pequeños textos sencillos adecuados al
nivel alcanzado.</li>
<li>Traducción de los mismos textos al español.</li>
<li>Ejercicios de conversación en Esperanto. Visionado de vídeos.</li>
<li>Preguntas y solución de dudas de los alumnos.</li>
<li>El profesor hablará <i>siempre en Esperanto</i>, pero lo hará
despacio, vocalizando y remarcando las palabras para facilitar
la comprensión de los alumnos.</li>
</ul></li>
</ul></li>

<li><b>No</b> es un curso formal; no habrá calificaciones, ni diplomas, ni
ningún otro factor externo que muestre la competencia de los
alumnos. Sólo la satisfacción de los conocimientos adquiridos.</li>

<li>Dependiendo de la implicación de los alumnos se podría montar un
segundo curso de continuación para mejorar las competencias con el
lenguaje.</li>
</ul>

  </div>
</div>
<div class="tab">
  <input type="radio" id="accion2" name="rd">
  <label class="tab-label" for="accion2">Instrukcioj (Esperanto)</label>
  <div class="tab-content">

<ul class="org-ul">
<li><p>
La metodo uzota estos <i>la zagreba kurso</i>, kiu troviĝos plene
disponebla en ĉi tiu retpaĝo ĉe la ligilo:
</p>

<p>
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo/">https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo/</a>
</p></li>

<li>Por alligi al kurso, vi povas sendi retmesaĝon al retpoŝto
<a href="mailto:kurso-esperanto@nueva-actitud.org">mailto:kurso-esperanto@nueva-actitud.org</a> antaŭ la oka de januaro de
<ol class="org-ol">
<li></li>
</ol></li>

<li>Ĉiusemajne ni faros lecionon:

<ul class="org-ul">
<li>Ĉiu leciono havas tekston kaj aŭdaĵo, gramatikan spacon,
vortareton de novaj vortoj kaj edzercadojn.</li>
<li>La lernanto aŭdos kaj legos la tekston, studos la gramatikon kaj
la novajn vortojn, kaj kompletos la edzercadojn. Poste, oni sendos
la edzercadojn al retpoŝto de la kurso.</li>
<li>La instruisto korektos tiujn edzercadojn kaj sendos personajn
klarigojn por ĉiu lernanto.</li>
</ul></li>

<li><p>
Ĉiu 2-4 leciono, dependante de la dispono de lernantoj kaj
instruisto, oni faros gvidajn sesiojn per videokomuniko. La
retĉambro oni povos trovi en la sekvanta ligilo:
</p>

<p>
<a href="https://jitsi.nobigtech.es/EsperantaKurso">https://jitsi.nobigtech.es/EsperantaKurso</a>
</p>

<ul class="org-ul">
<li>Dum la gvidajn sesiojn oni faros la sekvantajn agadojn:

<ul class="org-ul">
<li>Esperanta legado de etaj simplaj tekstoj konvenaj al nivelo
atingota.</li>
<li>Tradukado de tiuj tekstoj al la hispana.</li>
<li>Konversaciaj edzercoj en Esperanto. Ankaŭ oni vidos videojn.</li>
<li>Demandoj kaj klarigoj de la duboj de la lernantoj.</li>
<li>La instruisto parolos <i>ĉiam esperante</i>, sed malrapide, klare
prononciante kaj remarkante la vortojn por faciligi la kompreno
de la lernantaro.</li>
</ul></li>
</ul></li>

<li><b>Ne</b> estas formala kurso; ne estos kvalivikoj, nek diplomoj, nek iu
ajn ekstera faktoro, kiu montros la kapablo de la lernantoj. Nur la
ĝojo de la konoj atingitaj.</li>

<li>Laŭ la impliko de la lernantaro oni faros duan daŭran kurson por
plibonigi la esperantajn kapablojn.</li>
</ul>

    </div>
  </div>
  <div class="tab">
    <input type="radio" id="accionfin" name="rd">
    <label class="tab-close" for="accionfin">Ocultar instrucciones</label>
  </div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <link>https://notxor.nueva-actitud.org/2022/12/30/curso-basico-de-esperanto.html</link>
  <pubDate>Fri, 30 Dec 2022 10:18:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Un ejemplo de macro de org-mode]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-12-05</div>
<p>
El otro día hablé de las macros de <code>org-mode</code>. No pensé que fuera un
tema importante, porque creí que lo conocía todo el mundo y que
incluso sería de uso generalizado. Alguien, me preguntó para qué y
cómo se pueden utilizar, que si podía poner <i>«un ejemplo práctico»</i>.
De eso va este artículo y voy a explicar un macro, con algunas
variaciones, sobre un efecto para web que sea práctico. Veamos: pasa
el cursor por encima <span id="nota">de estas palabras<span class="nota">Esto es un ejemplo de efecto visual generado desde una macro de <code>org-mode</code>. Y dentro se pueden utilizar todas las etiquetas del mismo: <b>negrita</b>, <i>cursiva</i>, <del>tachado</del>, etc.</span></span> y luego pulsa y mantén pulsado el botón ratón.
</p>

<p>
El ejemplo, como digo, es una adaptación de algo que estoy utilizando
en un <span id="nota">proyecto personal<span class="nota">Si sale adelante ya os cansinaré con él, no os preocupéis, o sí.</span></span>.  Si ya has pulsado sobre las
palabras marcadas en este párrafo y en el anterior, habrás visto que
aparece un <i>bocadillo</i> con texto en su interior.
</p>

<p>
Manos a la obra.
</p>
<div id="outline-container-org7488c20" class="outline-2">
<h2 id="org7488c20">Un poco de <code>html</code> y <code>css</code></h2>
<div class="outline-text-2" id="text-org7488c20">
<p>
El efecto se consigue con un poco de <code>html</code> aderezado con <code>css</code>. Voy a
comenzar por éste último. El código, sin nada de <code>javascript</code>, que
genera el efecto es el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-css">  <span style="color: #6272a4;">/* </span><span style="color: #6272a4;">Notas sobre marcos
   --------------------------------------------------</span><span style="color: #6272a4;"> */</span>
<span style="color: #50fa7b; font-weight: bold;">.nota</span> {
    <span style="color: #ff79c6; font-weight: bold;">display</span>:none;
    <span style="color: #ff79c6; font-weight: bold;">padding</span>:5px;
    <span style="color: #ff79c6; font-weight: bold;">border</span>:1px solid <span style="color: #000000; background-color: #cc9;">#cc9</span>;
    <span style="color: #ff79c6; font-weight: bold;">border-radius</span>:5px;
    <span style="color: #ff79c6; font-weight: bold;">background-color</span>:<span style="color: #000000; background-color: #fafaea;">#fafaea</span>;
    <span style="color: #ff79c6; font-weight: bold;">position</span>:relative;
    <span style="color: #ff79c6; font-weight: bold;">width</span>:250px;
    <span style="color: #ff79c6; font-weight: bold;">overflow</span>:auto;
    <span style="color: #ff79c6; font-weight: bold;">z-index</span>:1;
}
<span style="color: #6272a4;">/* </span><span style="color: #6272a4;">Al pasar el rat&#243;n por encima del id `nota`, lo mostramos con
   otro fondo y al pulsar se muestra la  clase `.nota` en un marco.
   Esta clase `nota`, tiene que estar dentro del id `nota`
   para que pueda funcionar.
</span><span style="color: #6272a4;">*/</span>
<span style="color: #50fa7b; font-weight: bold;">#nota</span> {
    <span style="color: #ff79c6; font-weight: bold;">text-decoration-line</span>: underline;
    <span style="color: #ff79c6; font-weight: bold;">text-decoration-style</span>: wave;
    <span style="color: #ff79c6; font-weight: bold;">text-decoration-color</span>: <span style="color: #000000; background-color: #faa;">#faa</span>;
}
<span style="color: #50fa7b; font-weight: bold;">#nota:hover</span> {
    <span style="color: #ff79c6; font-weight: bold;">background-color</span>: <span style="color: #000000; background-color: #cc3;">#cc3</span>;
}
<span style="color: #50fa7b; font-weight: bold;">#nota:active .nota</span> {
    <span style="color: #ff79c6; font-weight: bold;">display</span>:inline-block;
    <span style="color: #ff79c6; font-weight: bold;">font-size</span>: 0.9em;
    <span style="color: #ff79c6; font-weight: bold;">position</span>:absolute;
}
</pre>
</div>

<p>
En el código se puede observar que necesitamos una etiqueta con
<code>id="nota"</code>, que en el código ajustaremos mediante <code>#nota {...}</code> que
contenga una clase <code>nota</code>, que ajustaremos mediante <code>.nota {...}</code>.
</p>

<p>
La clase nota dibuja un marco de <code>250px</code> de ancho cuando pulsemos y
mantengamos pulsado el botón del ratón (<code>#nota:active</code>). Si no se va a
utilizar en pantallas táctiles se puede pasar ese código a
<code>#nota:hover</code> para que se muestre al pasar el cursor por encima. Sin
embargo, en las pantallas táctiles es más delicado porque no hay un
cursor que pasar por encima y, por tanto, es más sencillo hacerlo
mediante pulsación.
</p>

<p>
Como digo el código <code>html</code> debe ser una etiqueta con <code>id</code> que contenga
una <code>clase</code>, ambas <code>nota</code>. Por supuesto, puedes llamar a la etiqueta
de una manera y a la clase de otra, por ejemplo <i>nota</i> y <i>marco</i>, pero
tienes que recordar que la clase tiene que estar inscrita en la
etiqueta con el <code>id</code> adecuado. El código que necesitamos sería algo
así:
</p>

<div class="org-src-container">
<pre class="src src-html">&lt;<span style="color: #50fa7b; font-weight: bold;">p</span>&gt;Esto es &lt;<span style="color: #50fa7b; font-weight: bold;">span</span> <span style="color: #f8f8f2; font-weight: bold;">id</span>=<span style="color: #f1fa8c;">"nota"</span>&gt;un ejemplo&lt;<span style="color: #50fa7b; font-weight: bold;">span</span> <span style="color: #f8f8f2; font-weight: bold;">class</span>=<span style="color: #f1fa8c;">"nota"</span>&gt;Este es el mensaje que aparece.&lt;/<span style="color: #50fa7b; font-weight: bold;">span</span>&gt;&lt;/<span style="color: #50fa7b; font-weight: bold;">span</span>&gt;de c&#243;mo funciona.&lt;/<span style="color: #50fa7b; font-weight: bold;">p</span>&gt;
</pre>
</div>

<p>
También podrías anidar un párrafo <code>&lt;p&gt;</code> dentro de un <code>&lt;div&gt;</code> o
cualquier combinación de etiquetas <code>html</code> a tu gusto. En mi caso
prefiero utilizar la etiqueta <code>&lt;span&gt;</code> porque la puedes meter incluso
una dentro de otra y te sirve tanto <i>para lo mucho, como para lo
poco</i>.
</p>
</div>
</div>
<div id="outline-container-org5b30079" class="outline-2">
<h2 id="org5b30079">Generar la <code>macro</code></h2>
<div class="outline-text-2" id="text-org5b30079">
<p>
Si has leído el artículo del otro día, ya sabrás que se utiliza una
etiqueta <code>#+macro:</code> en la cabecera del archivo para definirla con el
formato:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #6272a4;">#+macro: nombre texto</span>
</pre>
</div>

<p>
Para no liarnos, el nombre elegido es <span id="nota">~nota~<span class="nota">Hoy estoy de un original subido, o no.</span></span>.
</p>

<p>
Para llamarlo utilizamos el siguiente formato. Por ejemplo, el párrafo
anterior está escrito como:
</p>

<div class="org-src-container">
<pre class="src src-org">Para no liarnos, el nombre elegido es <span style="color: #deb887;">{{{nota(</span><span style="color: #50fa7b;">nota</span><span style="color: #deb887;">,Hoy estoy de un
original subido\, o no.)}}}</span>.
</pre>
</div>

<p>
Obsérvese que se ha <i>«escapado»</i> la coma en el texto anterior para que
no sea tomado como un nuevo parámetro. Este código genera al exportar
el siguiente <code>html</code>:
</p>

<div class="org-src-container">
<pre class="src src-html">&lt;<span style="color: #50fa7b; font-weight: bold;">p</span>&gt;
Para no liarnos, el nombre elegido es &lt;<span style="color: #50fa7b; font-weight: bold;">span</span> <span style="color: #f8f8f2; font-weight: bold;">id</span>=<span style="color: #f1fa8c;">"nota"</span>&gt;~nota~&lt;<span style="color: #50fa7b; font-weight: bold;">span</span> <span style="color: #f8f8f2; font-weight: bold;">class</span>=<span style="color: #f1fa8c;">"nota"</span>&gt;Hoy estoy de un original subido, o no.&lt;/<span style="color: #50fa7b; font-weight: bold;">span</span>&gt;&lt;/<span style="color: #50fa7b; font-weight: bold;">span</span>&gt;.
&lt;/<span style="color: #50fa7b; font-weight: bold;">p</span>&gt;
</pre>
</div>

<p>
Antes de nada debemos tener claro que para exportar código <code>html</code> en
la misma línea, en <code>org-mode</code> se utiliza <code>@@html:&lt;etiqueta&gt;@@</code>, por lo
tanto el <i>texto</i> de la macro se debería escribir tal que:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #6272a4;">@@</span><span style="color: #ff79c6; background-color: #373844; font-weight: bold;">html:</span>&lt;span id="nota"&gt;<span style="color: #6272a4;">@@</span>$1<span style="color: #6272a4;">@@</span><span style="color: #ff79c6; background-color: #373844; font-weight: bold;">html:</span>&lt;span class="nota"&gt;<span style="color: #6272a4;">@@</span>$2<span style="color: #6272a4;">@@</span><span style="color: #ff79c6; background-color: #373844; font-weight: bold;">html:</span>&lt;/span&gt;&lt;/span&gt;<span style="color: #6272a4;">@@</span>  
</pre>
</div>

<p>
donde <code>$1</code> se sustituirá por la cadena que identificará la <i>nota</i> y
<code>$2</code> lo hará con el contenido del cuadro emergente. Por tanto, el
código completo será:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #6272a4;">#+macro: nota @@html:&lt;span id="nota"&gt;@@$1@@html:&lt;span class="nota"&gt;@@$2@@html:&lt;/span&gt;&lt;/span&gt;@@</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org4377e1f" class="outline-2">
<h2 id="org4377e1f">Conclusiones</h2>
<div class="outline-text-2" id="text-org4377e1f">
<p>
A lo largo del artículo se pueden apreciar el resultado, pero para
saber cómo llamarlo podemos observar el primer párrafo:
</p>

<div class="org-src-container">
<pre class="src src-org">El otro d&#237;a habl&#233; de las macros de <span style="color: #50fa7b;">org-mode</span>. No pens&#233; que fuera un
tema importante, porque cre&#237; que lo conoc&#237;a todo el mundo y que
incluso ser&#237;a de uso generalizado. Alguien, me pregunt&#243; para qu&#233; y
c&#243;mo se pueden utilizar, que si pod&#237;a poner <span style="font-style: italic;">&#171;un ejemplo pr&#225;ctico&#187;</span>.
De eso va este art&#237;culo y voy a explicar un macro, con algunas
variaciones, sobre un efecto para web que sea pr&#225;ctico. Veamos: pasa
el cursor por encima <span style="color: #deb887;">{{{nota(de estas palabras,Esto es un ejemplo de
efecto visual generado desde una macro de </span><span style="color: #50fa7b;">org-mode</span><span style="color: #deb887;">. Y dentro se
pueden utilizar todas las etiquetas del mismo: </span><span style="color: #deb887; font-weight: bold;">negrita</span><span style="color: #deb887;">\, </span><span style="color: #deb887; font-style: italic;">cursiva</span><span style="color: #deb887;">\,
</span><span style="color: #deb887; text-decoration: line-through;">tachado</span><span style="color: #deb887;">\, etc.)}}}</span> y luego pulsa y mant&#233;n pulsado el bot&#243;n rat&#243;n.
</pre>
</div>

<p>
Como se puede ver, en las últimas líneas está la llamada a la macro
que genera el efecto. Dentro de ésta se puede utilizar el marcado de
<code>org-mode</code>, recordando que hay que <i>escapar</i> las comas. La llamada a
la macro lo que hace es sustituir el texto, que en nuestro ejemplo
genera código <code>html</code> incrustado <i>inline</i>.
</p>

<p>
Espero que esta vez, con un ejemplo más práctico, se haya entendido
cómo funcionan las macros. En cierto modo, funcionan de forma muy
similar a las macros de <i>Lisp</i>. En el caso del artículo se genera
código <code>html</code>, pero lo puedes ajustar para conseguir cualquier otro
tipo de texto.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/org-mode/index.html">org-mode</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[org-mode]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2022/12/05/un-ejemplo-de-macro-de-org-mode.html</link>
  <pubDate>Mon, 05 Dec 2022 12:54:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Macros en org-mode]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-11-25</div>
<p>
Gracias a las preguntas que me hacen algunos usuarios me doy cuenta de
que no siempre me explico con toda claridad y que, muchas veces, doy
por sentado que las cosas simples las conoce todo el mundo.  No
obstante, puesto que mi información proviene de leerme el manual,
entiendo a quien prefiere remitir al preguntón a leérselo. Sin
embargo, mi inclinación siempre es responder con algo más sustancial
que un <i>«lee el manual»</i>. También porque me sirve de excusa para
escribir algo en el <i>blog</i> y tenerlo en barbecho el mínimo tiempo
posible. En este artículo responderé a unas preguntas básicas que un
nuevo usuario de <i>Emacs</i> me hace, sobre el uso de <code>org-mode</code>,
específicamente la capacidad de utilizar <i>macros</i> para introducir
texto repetitivo, también para explicar para qué pueden servir, o se
pueden utilizar, las propiedades de los apartados y demás cosas
relacionadas con las «macros».
</p>

<p>
Puesto que hablar en abstracto es complicado, me vais a permitir poner
un ejemplo de <i>buffer</i> <code>org-mode</code> con una serie de <i>macros</i>, para luego
explicarlos más detenidamente. El código del ejemplo sería el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #6272a4;">#+title:</span> <span style="color: #ffb86c; font-size: 144%; font-weight: bold;">Expansi&#243;n de macros
</span><span style="color: #6272a4;">#+author:</span> <span style="color: #0189cc;">Notxor
</span><span style="color: #6272a4;">#+etiquetas: emacs, org, macro</span>
<span style="color: #6272a4;">#+macro: autores yo, m&#237;, me y conmigo</span>
<span style="color: #6272a4;">#+macro: hoy (eval (format-time-string (or $1 "%Y-%m-%d")))</span>

<span style="color: #ff79c6; font-size: 130%; font-weight: bold;">*</span><span style="color: #ff79c6; font-size: 130%; font-weight: bold;"> Hoy es </span><span style="color: #deb887; font-size: 130%; font-weight: bold;">{{{hoy}}}</span>
<span style="color: #87cefa;">:PROPERTIES:</span>
<span style="color: #f1fa8c;">:numero:</span>   <span style="color: #f8f8f2; background-color: #282a36;">42</span>
<span style="color: #87cefa;">:END:</span>

Los <span style="font-style: italic;">macros de la p&#225;gina</span>:

<span style="color: #f8f8f2; background-color: #282a36;">1.</span> <span style="font-weight: bold;">T&#237;tulo</span>: <span style="color: #deb887;">{{{title}}}</span>
<span style="color: #f8f8f2; background-color: #282a36;">2.</span> <span style="font-weight: bold;">Autor</span>: <span style="color: #deb887;">{{{author}}}</span>
<span style="color: #f8f8f2; background-color: #282a36;">3.</span> <span style="font-weight: bold;">Etiquetas</span>: <span style="color: #deb887;">{{{keyword(etiquetas)}}}</span>
<span style="color: #f8f8f2; background-color: #282a36;">4.</span> <span style="font-weight: bold;">Lista de autores</span>: <span style="color: #deb887;">{{{autores}}}</span>
<span style="color: #f8f8f2; background-color: #282a36;">5.</span> <span style="font-weight: bold;">Propiedad /numero/</span>: <span style="color: #deb887;">{{{property(numero)}}}</span>
<span style="color: #f8f8f2; background-color: #282a36;">6.</span> <span style="font-weight: bold;">Fecha de hoy</span>: <span style="color: #deb887;">{{{hoy(%A\, %d de %B de %Y)}}}</span>
<span style="color: #f8f8f2; background-color: #282a36;">7.</span> Llamamos al <span style="font-style: italic;">contador</span> <span style="color: #deb887;">{{{n(contador)}}}</span> vez y <span style="color: #deb887;">{{{n(contador)}}}</span>
   veces.
<span style="color: #f8f8f2; background-color: #282a36;">8.</span> Y tener varios contadores con varios nombres: <span style="color: #deb887;">{{{n(otro)}}}</span> vez,
   <span style="color: #deb887;">{{{n(otro)}}}</span> veces, <span style="color: #deb887;">{{{n(otro)}}}</span> veces y el otro contador tambi&#233;n
   <span style="color: #deb887;">{{{n(contador)}}}</span> veces.

<span style="color: #ff79c6; font-size: 130%; font-weight: bold;">*</span><span style="color: #ff79c6; font-size: 130%; font-weight: bold;"> Otra cabecera</span>
<span style="color: #87cefa;">:PROPERTIES:</span>
<span style="color: #f1fa8c;">:numero:</span>   <span style="color: #f8f8f2; background-color: #282a36;">37</span>
<span style="color: #87cefa;">:END:</span>

Aqu&#237; el <span style="font-style: italic;">n&#250;mero</span> es <span style="color: #deb887;">{{{property(numero)}}}</span>.
</pre>
</div>

<p>
El resultado del código anterior al exportar a <code>html</code> será:
</p>


<figure id="org8f8f5e1">
<img src="./imagenes/captura-expansion-macros.png" alt="captura-expansion-macros.png">

</figure>

<p>
Viendo la imagen y el código que la genera, se puede explicar mejor
cómo funcionan las <i>macros</i>:
</p>

<p>
Para empezar, se deben meter entre llaves triples, tal que
<code>{{{macro}}}</code> se sustituye por el valor de <code>#+macro:</code> en algunos
casos, como para <code>title</code> o <code>author</code>. Sin embargo, en los que definimos
nosotros se debe emplear la sintaxis <code>{{{keyword(macro)}}}</code>. Se puede
expresar la explicación también al revés, en las primeras se utiliza
una forma abreviada que expresa <code>{{{keyword(title)}}}</code> o
<code>{{{keyword(author)}}}</code>.
</p>

<p>
También podemos definir nuestros propios <i>macros</i> utilizando la
sintaxis:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #6272a4;">#+macro: nombre cuerpo</span>
</pre>
</div>

<p>
En el <i>cuerpo</i> los valores expresados coo <code>$1, $2... $n</code> son
argumentos que puede recibir, finalmente se forma una cadena con la
que sustituir la macro. Por otro lado, también se puede utilizar
cualquier forma <code>elisp</code> cuya evaluación resulte en una cadena de
texto. En el ejemplo anterior vemos que se ha definido una macro de la
siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #6272a4;">#+macro: hoy (eval (format-time-string (or $1 "%Y-%m-%d")))  </span>
</pre>
</div>

<p>
Dicho macro nos devuelve la fecha de hoy dándonos la oportunidad de
especificar un formato, que se puede pasar en un parámetro o en su
defecto se utilizar el formato ISO «año-mes-día». En el ejemplo de
documento anterior se muestra que se utiliza con un simple <code>{{{hoy}}}</code>
devolviendo la fecha en formato ISO, pero en el punto 6 de la lista
inferior se utiliza un formato introduciendo el parámetro entre
paréntesis. A propósito se ha introducido en éste una coma que debe
estar escapada. Si no lo hacemos así nos lanzará un error al
interpretar que hay dos parámetros, puesto que en la llamada, entre
paréntesis se utiliza el caracter <code>,</code> como separador.
</p>

<p>
Es decir, tenemos que fijarnos en que la cadena no está encerrada
entre comillas ni se utiliza delimitador alguno, si necesitamos varios
parámetros debemos separarlos mediante comas. Es aconsejable juguetear
un poco con esto para acostumbrarnos al modo de funcionamiento,
similar a otros lenguajes, pero muy distinta a como funciona <code>elisp</code>.
</p>

<p>
También podemos apreciar que se pueden sustituir <i>macros</i> con los
valores de las propiedades. En el punto 5 se sustituye
<code>{{{property(numero)}}}</code> por el valor definido como propiedad en la
primera cabecera. Con posterioridad, en el siguiente apartado, se ha
modificado el valor de la propiedad del mismo nombre y por tanto
también la sustitución. Por tanto, podemos utilizar las <i>properties</i>
de los distintos encabezados para agrupar expresiones o datos de
manera que al cambiar el valor de una propiedad, cambiará en texto en
todas las apariciones de la macro al hacer la exportación.
</p>

<p>
Por último, mencionar que se pueden tener contadores, por ejemplo,
para realizar enumeraciones más allá de lo que son las listas
numeradas o las entradas de titulares. No es algo que haya utilizado
mucho y por tanto sólo puedo remitir al lector a la documentación si
necesita esta funcionalidad más que yo.
</p>
<div id="outline-container-org099fb21" class="outline-2">
<h2 id="org099fb21">Conclusiones</h2>
<div class="outline-text-2" id="text-org099fb21">
<p>
No hay mucho más que explicar y el funcionamiento es muy sencillo.  Si
no lo has usado nunca, seguramente es porque no lo conocías. Después
de conocerlo, seguro que se te ocurren varias formas de utilización
que te ahorrarán trabajo.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2022/11/25/macros-en-org-mode.html</link>
  <pubDate>Fri, 25 Nov 2022 09:51:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Tutorial para blogear como Notxor]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-11-17</div>
<p>
A raíz de haber publicado en Mastodon que había añadido alguna
característica más al código que soporta este <i>blog</i>. Me han
preguntado cómo funciona y si puedo explicar un poco el flujo de
trabajo. No hay nada más sencillo, lo único que hago es aprovecharme
de toda la funcionalidad que ya proporciona <code>org-mode</code> para generar
<code>html</code>. De esta manera, conseguir un sitio estático es sencillo. Pero
empezaré por el principio y explicaré un poco el código.
</p>

<p>
Por cierto, el código lo podéis encontrar en <a href="https://codeberg.org/Notxor/notxor-blog">Codeberg</a> y descargarlo
libremente.  En el <i>README</i> explico en qué está basado y algunas
modificaciones que le he ido haciendo según lo he ido necesitando.
Concretamente las adicciones que le hice al código de
<code>org-static-blog</code> durante el tiempo que estuvo sin mantenimiento.
Después ha seguido evolucionando y añadiendo características como el
hacer ficheros <code>RSS</code> por etiqueta, que es algo que yo hice también en
su día. Por lo tanto, seguramente, os sea más cómodo instalar dicho
paquete y configurarlo en vuestro <i>Emacs</i>. Así empecé yo este <i>blog</i>.
Luego el código se ha ido modificando poco a poco para ajustarlo más a
mis necesidades y ya no uso el paquete de <i>ELPA</i>.
</p>

<p>
Las características que añadí por mi cuenta a esa versión antigua de
<code>org-static-blog</code> son principalmente tres:
</p>

<ol class="org-ol">
<li>La posibilidad de navegar el <i>blog</i> completo, mediante la
utilización de enlaces relativos, en un servidor de pruebas, como
el que proporciona <i>Emacs</i> con el comando <code>httpd-start</code>. En
aquellos tiempos no se podía hacer, se tenía que publicar
directamente.</li>
<li>La generación de ficheros <code>rss.xml</code> por etiquetas.</li>
<li>Que tenga en cuenta y muestre el <i>autor</i> del artículo. Esto último
ha sido a petición, pero ya que está lo dejo, en mi <i>blog</i> no tiene
mucho sentido.</li>
</ol>

<p>
El resto es sólo generación de sitio estático puro y duro, pero en
lugar de utilizar <code>org-export</code> se utilizan las funciones de
publicación del código.
</p>

<p>
Además hay que recordar que mi código no es un paquete. Hay que
cargarlo con <code>(load-file ...)</code>, todo el código para generar los <code>html</code>
está contenido en el fichero <code>notxor-blog.el</code>. Pero es posible que
necesites más código que no está en mi repositorio. Ahí sólo
encontrarás el código <code>elisp</code> y el archivo <code>estilos.css</code> que es el que
da formato y color a las páginas. Pero además utilizo un par de
archivos <code>javascript</code>, para el coloreo de sintaxis y el formateo de
fórmulas matemáticas, que luego comentaré.
</p>

<p>
Como explicar en abstracto cómo funciona el código y cómo es la
estructura de directorios, voy a poner el ejemplo que tengo más a
mano: este <i>blog</i>. ¿Qué estructura tiene el sitio? ¿Dónde pongo los
archivos auxiliares? ¿Dónde pone los generados la herramienta?
</p>
<div id="outline-container-orgf32bb09" class="outline-2">
<h2 id="orgf32bb09">Trasteando con los archivos auxiliares</h2>
<div class="outline-text-2" id="text-orgf32bb09">
<p>
Primero, antes de entrar en materia, vamos a echar un vistazo a la
estructura de directorios:
</p>

<pre class="example" id="orge1a36a8">
.
├── 2017
│   ├── ...
│   └── index.html
├── 2018
│   ├── ...
│   └── index.html
├── 2019
│   ├── ...
│   └── index.html
├── 2020
│   ├── ...
│   └── index.html
├── 2021
│   ├── ...
├── 2022
│   ├── ...
│   └── index.html
├── about
│   └── index.html
├── archivo.html
├── etiquetas.html
├── favicon.png
├── index.html
├── medios
│   ├── css
│   │   └── estilos.css
│   ├── fonts
│   │   ├── Cantarell-Bold.otf
│   │   ├── EBGaramond12-Regular.ttf
│   │   ├── FiraCode-Retina.ttf
│   │   └── Sugar &amp; Vinegar.ttf
│   ├── img
│   │   ├── abatar.png
│   │   ├── ...
│   │   ├── mastodon-icono.png
│   │   └── search.png
│   ├── index.html
│   └── js
│       ├── es
│       │   ├── ...
│       ├── jquery-latest.min.js
│       ├── main.js
│       └── MathJax.js
├── rss.xml
└── tags
    ├── acoso
    │   ├── index.html
    │   └── rss.xml
    ├── ...
    └── zettelkasten
        ├── index.html
        └── rss.xml

1301 directories, 3521 files
</pre>

<p>
Puede parecer un poco complejo, pero no lo es tanto. Los directorios
<code>2017-2022</code> los crea la herramienta automáticamente cuando publicas un
artículo lo guardará en una estructura de directorios tal que
<code>/año/mes/día/título</code>.
</p>

<p>
Justo debajo de esos directorios, encontramos otro que se llama
<code>about</code>, pero no es obligatorio llamarlo así, simplemente se pretende
tener un espacio donde puedes presentar el <i>blog</i> o cualquier otra
tontería (como tengo yo). Luego en el preámbulo de la página, donde
está el menú se enlaza a ese sitio con un simple enlace <code>html</code>:
</p>

<div class="org-src-container">
<pre class="src src-html">&lt;<span style="color: #50fa7b; font-weight: bold;">li</span>&gt;&lt;<span style="color: #50fa7b; font-weight: bold;">a</span> href=\<span style="color: #f1fa8c;">"/about/\"</span>&gt;Acerca de...&lt;/<span style="color: #50fa7b; font-weight: bold;">a</span>&gt;&lt;/<span style="color: #50fa7b; font-weight: bold;">li</span>&gt;
</pre>
</div>

<p>
Lo podéis llamarlo como queráis, pero recordad que siendo un enlace a
un directorio, cargará automáticamente <code>index.html</code>.
</p>

<p>
Lo siguiente es el fichero <code>archivo.html</code>. Eso lo genera la
herramienta y es un listado de todos los artículos publicados. Su
nombre se puede modificar, modificando una variable:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defcustom</span> <span style="color: #f8f8f2; font-weight: bold;">notxor-blog-archive-file</span> <span style="color: #f1fa8c;">"archivo.html"</span>
  <span style="color: #6272a4;">"File name of the list of all blog posts.
The archive page lists all posts as headlines."</span>
  <span style="color: #8be9fd; font-style: italic;">:type</span> '(string)
  <span style="color: #8be9fd; font-style: italic;">:safe</span> t)
</pre>
</div>

<p>
He visto también <i>blogs</i> que prefieren cargar directamente el archivo
general. La lista son los títulos de los artículos y sus fechas, pero
cuando se alarga la lista es un poco lento de carga. Prefiero el
índice que muestra sólo unas pocas entradas. Esas se pueden configurar
en la variable:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defcustom</span> <span style="color: #f8f8f2; font-weight: bold;">notxor-blog-index-length</span> 10
  <span style="color: #6272a4;">"Number of articles to include on index page."</span>
  <span style="color: #8be9fd; font-style: italic;">:type</span> '(integer)
  <span style="color: #8be9fd; font-style: italic;">:safe</span> t)
</pre>
</div>

<p>
También está el fichero <code>etiquetas.html</code>. Este es un listado de las
etiquetas y los archivos que las portan. Lo genera automáticamente la
herramienta y también se pude configurar el nombre modificando una
variable:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defcustom</span> <span style="color: #f8f8f2; font-weight: bold;">notxor-blog-tags-file</span> <span style="color: #f1fa8c;">"etiquetas.html"</span>
  <span style="color: #6272a4;">"File name of the list of all blog posts by tag.
The tags page lists all posts as headlines."</span>
  <span style="color: #8be9fd; font-style: italic;">:type</span> '(string)
  <span style="color: #8be9fd; font-style: italic;">:safe</span> t)
</pre>
</div>

<p>
El fichero <code>index.html</code> es el índice de portada del blog. Lo genera la
herramienta y también se puede configurar el nombre con una variable:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defcustom</span> <span style="color: #f8f8f2; font-weight: bold;">notxor-blog-index-file</span> <span style="color: #f1fa8c;">"index.html"</span>
  <span style="color: #6272a4;">"File name of the blog landing page.
The index page contains the most recent
`notxor-blog-index-length` full-text posts."</span>
  <span style="color: #8be9fd; font-style: italic;">:type</span> '(string)
  <span style="color: #8be9fd; font-style: italic;">:Safe</span>' t)
</pre>
</div>

<p>
En este último caso está así hecho por si se quiere poner otra página
de portada al cargar la URL principal y que haya un enlace al inicio
del <i>blog</i>. He visto como otros usuarios, en <i>blogs</i> personales, más
curriculares, que utilizan una carátula a modo de presentación o
currículo y desde ahí, enlazan el blog. En mi caso, como no utilizo el
<i>blog</i> para esos menesteres, prefiero que se muestre el índice
directamente.
</p>

<p>
Después encuentras el directorio <code>medios</code> que dentro tiene más
subdirectorios interesantes:
</p>

<ul class="org-ul">
<li>Un directorio para la hoja de estilos <code>css</code>.</li>
<li>Un directorio donde guardar las fuentes que utiliza el sitio.</li>
<li>Un directorio para meter el poco <code>javascript</code> que usa la página.</li>
</ul>

<p>
Voy a empezar por éste último. El <code>javascript</code> que utilizo es muy
poco, fundamentalmente para dos cosas: el visionado de fórmulas
matemáticas con <code>MathJax.js</code> y el coloreado de sintaxis, y también
para los botones de <i>paypal</i> y <i>LiberaPay</i>. Por supuesto, cada uno es
libre de si utilizar o no, las librerías <code>js</code> que quiera y considere
oportuno. Para cargarlas, las llamo en otra variable:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defcustom</span> <span style="color: #f8f8f2; font-weight: bold;">notxor-blog-page-postamble</span>
  <span style="color: #f1fa8c;">"&lt;div&gt;
    &lt;script src=\"/medios/js/jquery-latest.min.js\"&gt;&lt;/script&gt;
    &lt;script src=\"https://polyfill.io/v3/polyfill.min.js?features=es6\"&gt;&lt;/script&gt;
    &lt;script id=\"MathJax-script\" async src=\"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js\"&gt;&lt;/script&gt;
    &lt;script src=\"/medios/js/main.js\"&gt;&lt;/script&gt;
    &lt;div class=\"footer\"&gt;
        &lt;div class=\"redes\"&gt;
            &lt;p&gt;
                &lt;a rel=\"me\" href=\"https://masto.rocks/web/@Notxor\" target=\"_blank\"&gt;&lt;img src=\"/medios/img/mastodon-icono.png\" width=\"24px\" float=\"left\" /&gt;&lt;/a&gt;
                &lt;a rel=\"me\" href=\"https://masto.nobigtech.es/@Notxor\" target=\"_blank\"&gt;&lt;img src=\"/medios/img/mastodon-icono.png\" width=\"24px\" float=\"left\" /&gt;&lt;/a&gt;
                &lt;a href=\"https://diasp.org/people/15172490a88f01339a3f782bcb452bd5\" target=\"_blank\"&gt;&lt;img src=\"/medios/img/diaspora-icono.png\" width=\"24px\" float=\"left\" /&gt;&lt;/a&gt;
            &lt;/p&gt;
        &lt;/div&gt;
        &lt;p&gt;Generado con &lt;code&gt;notxor-blog&lt;/code&gt; en &lt;i&gt;Emacs&lt;/i&gt;&lt;/p&gt;
        &lt;p&gt;
            &lt;img style=\"display: inline-block;\" src=\"/medios/img/cc-by-nc-sa.png\" align=\"middle\" /&gt;
               &lt;br /&gt;2012 - &lt;span id=\"footerYear\"&gt;&lt;/span&gt; &lt;a href=\"mailto:notxor@nueva-actitud.org\"&gt;Notxor&lt;/a&gt;
            &amp;nbsp;&amp;nbsp;-&amp;nbsp;&amp;nbsp;
            Powered by &lt;a href=\"https://codeberg.org/Notxor/org-static-blog\" target=\"_blank\"&gt;notxor-blog&lt;/a&gt;
            &lt;script type=\"text/javascript\"&gt;document.getElementById(\"footerYear\").innerHTML = (new Date()).getFullYear();&lt;/script&gt;
        &lt;/p&gt;
        &lt;table&gt;
            &lt;tr&gt;
                &lt;td&gt;
                    &lt;b&gt;Donar por Paypal&lt;/b&gt;
                &lt;/td&gt;
                &lt;td&gt;
                    &lt;b&gt;Donar por Liberapay&lt;/b&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;
                    &lt;!-- Inserci&#243;n de bot&#243;n pypal --&gt;
                    &lt;form action=\"https://www.paypal.com/cgi-bin/webscr\" method=\"post\" target=\"_top\"&gt;
                        &lt;input type=\"hidden\" name=\"cmd\" value=\"_s-xclick\" /&gt;
                        &lt;input type=\"hidden\" name=\"hosted_button_id\" value=\"29VXCW8SRNJ78\" /&gt;
                        &lt;input type=\"image\" src=\"https://www.paypalobjects.com/es_ES/ES/i/btn/btn_donateCC_LG.gif\" border=\"0\" name=\"submit\" title=\"PayPal - Donar online de forma segura.\" alt=\"Bot&#243;n Donar con PayPal\" /&gt;
                        &lt;img alt=\"\" border=\"0\" src=\"https://www.paypal.com/es_ES/i/scr/pixel.gif\" width=\"1\" height=\"1\" /&gt;
                    &lt;/form&gt;
                &lt;/td&gt;
                &lt;td&gt;
                    &lt;!-- Inserci&#243;n de bot&#243;n liberapay --&gt;
                    &lt;script src=\"https://liberapay.com/Notxor/widgets/button.js\"&gt;&lt;/script&gt;
                    &lt;noscript&gt;
                        &lt;a href=\"https://liberapay.com/Notxor/donate\"&gt;
                            &lt;img alt=\"Donate using Liberapay\" src=\"https://liberapay.com/assets/widgets/donate.svg\"&gt;&lt;/a&gt;
                    &lt;/noscript&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
        &lt;/table&gt;
    &lt;/div&gt;
&lt;/div&gt;"</span>
  <span style="color: #6272a4;">"HTML to put after the content of each page."</span>
  <span style="color: #8be9fd; font-style: italic;">:type</span> '(string)
  <span style="color: #8be9fd; font-style: italic;">:safe</span> t)
</pre>
</div>

<p>
He querido pone completo todo el final de la página. En las primeras
líneas se aprecia la llamada a las librerías establecidas. La única
que no está accesible en la red es <code>main.js</code> que hace unas pequeñas
conversiones:
</p>

<div class="org-src-container">
<pre class="src src-javascript">$(document).ready(<span style="color: #ff79c6; font-weight: bold;">function</span>() {
    <span style="color: #6272a4;">/*******************************************************************
     * 1. replace css class "src" and "example" with "prettyprint", for
     *    prettify.js to render
     * 2. replace detail language css class, e.g. "src-scheme" to
     *    "lang-scheme" per the description of prettify.js
     ******************************************************************/</span>
    <span style="color: #ff79c6; font-weight: bold;">var</span> <span style="color: #f8f8f2; font-weight: bold;">$blocks</span> = $(<span style="color: #f1fa8c;">'pre.src'</span>);
    $blocks.each(<span style="color: #ff79c6; font-weight: bold;">function</span>(<span style="color: #f8f8f2; font-weight: bold;">index</span>) {
        <span style="color: #ff79c6; font-weight: bold;">var</span> <span style="color: #f8f8f2; font-weight: bold;">self</span> = $(<span style="color: #bd93f9;">this</span>);
        <span style="color: #ff79c6; font-weight: bold;">var</span> <span style="color: #f8f8f2; font-weight: bold;">classes</span> = self.removeClass(<span style="color: #f1fa8c;">'src'</span>).attr(<span style="color: #f1fa8c;">'class'</span>).split(<span style="color: #f1fa8c;">/\s+/</span>);
        $.each(classes, <span style="color: #ff79c6; font-weight: bold;">function</span>(<span style="color: #f8f8f2; font-weight: bold;">idx</span>, <span style="color: #f8f8f2; font-weight: bold;">cls</span>) {
            <span style="color: #ff79c6; font-weight: bold;">if</span> (cls.substring(0, 4) === <span style="color: #f1fa8c;">'src-'</span>) {
                <span style="color: #ff79c6; font-weight: bold;">var</span> <span style="color: #f8f8f2; font-weight: bold;">lang</span> = cls.substring(4);
                self.removeClass(cls).addClass(<span style="color: #f1fa8c;">'lang-'</span> + lang);
            }
        });
        self.addClass(<span style="color: #f1fa8c;">'prettyprint'</span>);
    });
    $(<span style="color: #f1fa8c;">'pre.example'</span>).removeClass(<span style="color: #f1fa8c;">'example'</span>).addClass(<span style="color: #f1fa8c;">'prettyprint'</span>);

    <span style="color: #6272a4;">/*******************************************************************
     * 1. remove all org exported line number spans
     * 2. add css class "linenums" to code block per the description of
     *    prettify.js
     ******************************************************************/</span>
    <span style="color: #ff79c6; font-weight: bold;">var</span> <span style="color: #f8f8f2; font-weight: bold;">$lines</span> = $(<span style="color: #f1fa8c;">'span.linenr'</span>);
    <span style="color: #ff79c6; font-weight: bold;">var</span> <span style="color: #f8f8f2; font-weight: bold;">$linedBlocks</span> = $lines.parent();
    $lines.remove();
    $linedBlocks.each(<span style="color: #ff79c6; font-weight: bold;">function</span>(<span style="color: #f8f8f2; font-weight: bold;">index</span>) {
        $(<span style="color: #bd93f9;">this</span>).addClass(<span style="color: #f1fa8c;">'linenums'</span>);
    });

    <span style="color: #6272a4;">/*******************************************************************
     * pretty print all code blocks
     ******************************************************************/</span>
    prettyPrint();
});
</pre>
</div>

<p>
Hace un tiempo tenía activados los comentarios y se gestionaban con
una <a href="https://github.com/jacobwb/hashover">herramienta libre que se llama <i>hashover</i></a>. El lugar del código
desde donde se pueden incluir llamadas a esa u otras herramientas es
otra variable:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defcustom</span> <span style="color: #f8f8f2; font-weight: bold;">notxor-blog-post-comments</span>
  <span style="color: #f1fa8c;">"&lt;section&gt;
      &lt;h1&gt;Comentarios&lt;/h1&gt;
      &lt;blockquote&gt;
          &lt;p&gt;Debido a algunos ataques mailintencionados a trav&#233;s de la
              herramienta de comentarios, he decidido no proporcionar
              dicha opci&#243;n en el &lt;i&gt;Blog&lt;/i&gt;. Si alguien quiere comentar
              algo, me puede encontrar en &lt;a rel=\"me\" href=\"https://masto.rocks/web/@Notxor\" target=\"_blank\"&gt;&lt;i&gt;Mastodon&lt;/i&gt;&lt;/a&gt;
              y en &lt;a href=\"https://diasp.org/people/15172490a88f01339a3f782bcb452bd5\" target=\"_blank\"&gt;&lt;i&gt;Diaspora&lt;/i&gt;&lt;/a&gt;
              con el &lt;i&gt;nick&lt;/i&gt; de &lt;b&gt;Notxor&lt;/b&gt;.&lt;/p&gt;
          &lt;p&gt;Tambi&#233;n se ha abierto un grupo en Telegram (&lt;a href=\"https://t.me/+S4-CQG2Mewod_lvj\" target=\"_blank\"&gt;enlace de invitaci&#243;n al grupo&lt;/a&gt;), para usuarios de esa red.&lt;/p&gt;
          &lt;p&gt;Disculpen las molestias.&lt;/p&gt;
      &lt;/blockquote&gt;
  &lt;/section&gt;"</span>
  <span style="color: #6272a4;">"HTML code for comments to put after each blog post."</span>
  <span style="color: #8be9fd; font-style: italic;">:type</span> '(string)
  <span style="color: #8be9fd; font-style: italic;">:safe</span> t)
</pre>
</div>

<p>
En esa variable se pude establecer cualquier código <code>html</code> que
necesite la herramienta de comentarios para que se despliegue.
Recomiendo <i>HashOver</i> porque es una herramienta libre, la descargas y
la pones en tu sitio, no necesita que se creen una cuenta o se logueen
en sitios de terceros cuando visiten tu página. El contenido se guarda
en texto plano en el directorio <code>/hashover</code> del sitio y no necesitas
montar tampoco una base de datos para ello<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>

<p>
Siguiendo, vemos que también hay un fichero <code>rss.xml</code> donde se
actualiza el índice de las últimas entradas. Este se actualiza cada
vez que publicas en el <i>blog</i> y hace que <i>tus fieles seguidores</i>
tengan noticia de lo último que vas publicando.
</p>
</div>
</div>
<div id="outline-container-orgb246112" class="outline-2">
<h2 id="orgb246112">Flujo de trabajo</h2>
<div class="outline-text-2" id="text-orgb246112">
<p>
Una vez configurado tu sitio y funcionando todo.  Si te gusta
reflexionar antes de publicar y corregir y pulir lo que se
publicará<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> como a mí, sólo tienes que realizar los siguientes
pasos.
</p>

<ol class="org-ol">
<li>Tener una idea para un artículo.</li>
<li><p>
Crear un borrador con <code>M-x notxor-blog-create-draft</code>. Ese comando
pregunta por el título, genera toda la estructura en un archivo que
se guardará en el directorio de borradores. Ese directorio se
guarda en la variable:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defcustom</span> <span style="color: #f8f8f2; font-weight: bold;">notxor-blog-drafts-directory</span> <span style="color: #f1fa8c;">"~/blog/borradores/"</span>
  <span style="color: #6272a4;">"Directory where unpublished ORG files are stored.
When publishing, draft are rendered as HTML, but not included in
the index, archive, tags, or RSS feed."</span>
  <span style="color: #8be9fd; font-style: italic;">:type</span> '(directory))
</pre>
</div>

<p>
La estructura con la que comenzará dicho artículo está determinado
también en el código y lo puedes ajustar a tu gusto:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">notxor-blog-create-new-post</span> (<span style="color: #8be9fd; font-style: italic;">&amp;optional</span> draft)
  <span style="color: #6272a4;">"Create a new blog post.
Prompts for a title and proposes a file name.  The file name is
only a suggestion; You can choose any other file name if you so
choose.  if DRAFT, create a new blog draft."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (<span style="color: #ff79c6; font-weight: bold;">let</span> ((title (read-string (notxor-blog-gettext 'title))))
    (find-file (concat
                (<span style="color: #ff79c6; font-weight: bold;">if</span> draft
                    notxor-blog-drafts-directory
                    notxor-blog-posts-directory)
                (read-string (notxor-blog-gettext 'filename)
                             (concat (format-time-string <span style="color: #f1fa8c;">"%Y-%m-%d-"</span> (current-time))
                                     (replace-regexp-in-string <span style="color: #f1fa8c;">"\s"</span> <span style="color: #f1fa8c;">"-"</span> (downcase title))
                                     <span style="color: #f1fa8c;">".org"</span>))))
    (insert <span style="color: #f1fa8c;">"#+title:    "</span> title <span style="color: #f1fa8c;">"\n"</span>
            <span style="color: #f1fa8c;">"#+date:     "</span> (format-time-string <span style="color: #f1fa8c;">"&lt;%Y-%m-%d %H:%M&gt;"</span>) <span style="color: #f1fa8c;">"\n"</span>
            <span style="color: #f1fa8c;">"#+author:   "</span> <span style="color: #f1fa8c;">"\n"</span>
            <span style="color: #f1fa8c;">"#+filetags: "</span> <span style="color: #f1fa8c;">"\n"</span>
            <span style="color: #f1fa8c;">"#+options:  H:4 num:nil toc:nil \\n:nil ::t |:t ^:{} -:nil f:t *:t &lt;:t"</span>)))
</pre>
</div></li>

<li>Normalmente cuando estoy escribiendo en un artículo para el <i>blog</i>
suelo cambiar a <code>notxor-blog-mode</code>. Ese modo es simplemente un
derivado de <code>org-mode</code> pero me permite definir teclas directas para
las acciones más habituales.</li>
<li><p>
Se escribe el borrador, se repasa y se edita las veces que hagan
falta hasta que se considere publicable. En ese momento, el
artículo debe pasar al directorio correspondiente. En mi caso dicho
directorio se encuentra configurado como:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defcustom</span> <span style="color: #f8f8f2; font-weight: bold;">notxor-blog-posts-directory</span> <span style="color: #f1fa8c;">"~/blog/articulos/"</span>
  <span style="color: #6272a4;">"Directory where published ORG files are stored.
When publishing, posts are rendered as HTML, and included in the
index, archive, tags, and RSS feed."</span>
  <span style="color: #8be9fd; font-style: italic;">:type</span> '(directory))
</pre>
</div></li>

<li><p>
Cuando se ha pasado el borrador a artículo, se invoca a la función
<code>notxor-blog-publish</code>. Esta función genera el artículo, actualiza
el <code>index.html</code>, <code>archivo.html</code>, <code>rss.xml</code> y actualiza los ficheros
<code>html</code> de etiquetas, con el formato:
<code>/tags/etiqueta/index.html</code>. Esos archivos los escribe en el
directorio que esté configurado como salida:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defcustom</span> <span style="color: #f8f8f2; font-weight: bold;">notxor-blog-publish-directory</span> <span style="color: #f1fa8c;">"~/public_html/"</span>
  <span style="color: #6272a4;">"Directory where published HTML files are stored."</span>
  <span style="color: #8be9fd; font-style: italic;">:type</span> '(directory))
</pre>
</div>

<p>
En mi caso los mando a un directorio local de mi ordenador. En él
hago pruebas de visualización y compruebo que todo funciona:
enlaces, imágenes, etc. Suelo hacer un servidor de pruebas desde
línea de comandos con:
</p>

<div class="org-src-container">
<pre class="src src-bash">python3 -m http.server 8080
</pre>
</div></li>

<li>Si necesito un fichero <code>rss.xml</code> por etiquetas llamo a la función
<code>notxor-blog-assemble-rss-by-tag</code>. Igual que en el paso anterior se
generaban los índices de las etiquetas, ahora se generan los <i>feed</i>
en <code>/tags/etiqueta/rss.xml</code>. Por tanto, puedes pasar la <i>URL</i>
<code>https://tags/etiqueta/rss.xml</code> a quien esté interesado sólo en
alguno de los temas que toca el <i>blog</i>.</li>

<li>Después de comprobar que todo ha salido bien<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> lo subo al sitio
con <a href="https://filezilla-project.org/download.php">FileZilla</a>.</li>
</ol>

<p>
Posteriormente cuando la gente lo lee y encuentra los errores que se
me han colado, vuelvo al original<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>, arreglo el error y utilizo la
función <code>notxor-blog-publish-file</code>. Esto genera sólo el ejecutable y
lo pone en su sitio, así que sólo hay que subir un archivo corregido.
</p>
</div>
</div>
<div id="outline-container-org67a00e6" class="outline-2">
<h2 id="org67a00e6">Conclusiones</h2>
<div class="outline-text-2" id="text-org67a00e6">
<p>
Veo más acertado que utilices una herramienta más <i>general</i> que la
mía, que la tengo ya bastante acomodada a mí. En algunos casos se ha
quedado atrás con respecto a las características que le han metido a
las nuevas versiones de <code>org-static-blog</code>.
</p>

<p>
No sé si todo lo explicado hasta aquí ha quedado suficientemente
claro. Todo lo que he contado es cómo me apaño yo con esto para
mantener un <i>blog</i> pequeñito, con sólo <code>html</code>, <code>css</code> y un poquitín de
<code>javascript</code>. Como tampoco soy diseñador, pues queda como queda:
simple y sin grandes pretensiones.
</p>

<p>
Lo hago con <i>Emacs</i> porque es <b>la herramienta</b>, si pudiera engancharle
una sartén también me haría unos huevos fritos.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Sin embargo, eso no implica que haya un montón de imbéciles
intentando hacer saltar tu base de datos inyectando SQL, sin
conocimiento de lo que están haciendo. Hasta bloquear un servidor
modesto como el que sostiene este humilde <i>blog</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Aún así se te escaparán errores. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Por mucho cuidado que tengas siempre se te colará algún error.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En el directorio <code>articulos</code> no en el de <code>borradores</code>. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2022/11/17/tutorial-para-blogear-como-notxor.html</link>
  <pubDate>Thu, 17 Nov 2022 17:31:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Verificarse en Mastodon]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-11-14</div>
<p>
Estos días se está dando una gran migración de personas desde
<i>Twitter</i> a <i>Mastodon</i>. Muchos de los nuevos, y no tan nuevos, tienen
la inmediata reacción de ponerse el icono de verificación junto al
nombre. Quiero entender que es una <i>coña</i> viniendo de donde vienen.
Pero sí hay una forma de <i>verificar</i> la cuenta y de eso va este
artículo. Si estás llegando nuevo a <i>Mastodon</i> puede interesarte, pero
me estoy encontrando también con veteranos de esas redes que
desconocen esta funcionalidad. Primero os contaré una historia de por
qué me interesa este asunto, particularmente y después el cómo se
puede hacer.
</p>
<div id="outline-container-org01d6b7c" class="outline-2">
<h2 id="org01d6b7c">Un poco de historia</h2>
<div class="outline-text-2" id="text-org01d6b7c">
<p>
Hace un tiempo <i>Fanta</i> montó el servidor <code>mastodon.madrid</code> y me pidió
si me importaba echarle una mano con la moderación del mismo.
Entonces yo andaba por <code>mastodon.social</code> y me cambié de servidor.
Nunca tuve que intervenir mucho, eran tiempos donde los nodos pequeños
apenas recibían reportes y cuando recibíamos alguno y yo iba a
comprobarlo, me encontraba con que <i>Fanta</i> o <i>Aurora</i> ya lo habían
solucionado. Por tanto, mi intervención, salvo en un par de ocasiones
que hubo suficientes dudas como para tener que consultarlo entre los
tres antes de proceder a tomar ninguna acción, fue mínima.
</p>

<p>
Cuento esto, porque una de esas veces hubo alguna movida
extraordinaria. Eran los tiempos de la pandemia y había reportes sobre
un par de cuentas negacionistas y antivacunas, muy dispuestos a
defender su <i>libertad</i> individual, con absoluto desprecio del bien
común o de las vidas de los demás. El caso es que se tomó la
resolución de bloquear ambas cuentas, con el consiguiente rebote de
los usuarios. Fue doloroso, porque eran gente con la que yo
interaccionaba e incluso me caían bien, cuando no hablábamos de la
pandemia, claro. A uno de ellos me lo sigo encontrando por las redes,
pero no hablamos sobre esto. Al otro, que creo que es el responsable
de toda la movida posterior, no he vuelto a encontrarlo o, si lo he
hecho, no relaciono su nuevo <i>nick</i> con él.
</p>

<p>
El caso es que después del bloqueo, nos encontramos con que habían
creado varios <b>perfiles falsos</b> en distintos servidores, con el nombre
de <i>Notxor</i> en los que se empeñaban en vincularme<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> con el
nazismo. En la mayoría de los servidores eran bloqueadas esas cuentas
por apología del nazismo. Pero llegaron a abrir un nodo de <i>Mastodon</i>
para completar su pataleta y estuvieron un tiempo esas cuentas
activas. Algunos <i>admins</i> del <i>fediverso</i> incluso llegaron a bloquear
las cuentas auténticas en prevención.
</p>

<p>
Por todo esto, lo de poder <i>verificar</i> de algún modo quién eres tú y
quién un suplantador me parece una buena idea.
</p>
</div>
</div>
<div id="outline-container-org802b0e3" class="outline-2">
<h2 id="org802b0e3">Cómo verificarse</h2>
<div class="outline-text-2" id="text-org802b0e3">
<p>
Lo bueno del sistema es que cualquiera que tenga una página web o un
blog puede autentificarse a sí mismo. Lo malo es que, como en el caso
que os he contado, si pueden montar un nodo de <i>Mastodon</i> para eso,
pueden autentificarse a sí mismos. ¿Cómo puedes saber la diferencia?
Hay que comprobar si el enlace que se utiliza es el <i>blog</i> o la página
de la persona en cuestión. Si la <i>URL</i> no coincide con el original,
estás ante un suplantador.
</p>

<p>
La forma de visualizarlo en <i>Mastodon</i> es como aparece en mi perfil:
</p>


<figure id="org676120f">
<img src="./imagenes/Captura-verificacion-cuenta.png" alt="Captura-verificacion-cuenta.png">

</figure>

<p>
Por compararlo con una cuenta no verificada podéis mirar ésta:
</p>


<figure id="orgf0c74a4">
<img src="./imagenes/Captura-cuenta-no-verificada.png" alt="Captura-cuenta-no-verificada.png">

</figure>

<p>
Se puede observar que en la primera imagen, visualmente, se resalta en
verde la <i>URL</i> certificada.
</p>
</div>
<div id="outline-container-orgb1f7cff" class="outline-3">
<h3 id="orgb1f7cff">¿Qué necesitamos hacer?</h3>
<div class="outline-text-3" id="text-orgb1f7cff">
<p>
Lo primero que necesitamos es tener acceso al código fuente de una
página web que nos pertenezca y poner un enlace en nuestro perfil
cuando lo rellenamos. Mirad en la siguiente imagen:
</p>


<figure id="org422c837">
<img src="./imagenes/Captura-poner-url-en-perfil.png" alt="Captura-poner-url-en-perfil.png">

</figure>

<ol class="org-ol">
<li>Debemos poner la <i>URL</i> de nuestra página en uno de los espacios del
formulario que aparece al <i>editar el perfil</i>.</li>
<li><p>
Podemos copiar la etiqueta que debemos poner en nuestra página. En
mi ejemplo será:
</p>

<div class="org-src-container">
<pre class="src src-html">&lt;<span style="color: #50fa7b; font-weight: bold;">a</span> <span style="color: #f8f8f2; font-weight: bold;">rel</span>=<span style="color: #f1fa8c;">"me"</span> <span style="color: #f8f8f2; font-weight: bold;">href</span>=<span style="color: #f1fa8c;">"https://masto.rocks/@Notxor"</span>&gt;Mastodon&lt;/<span style="color: #50fa7b; font-weight: bold;">a</span>&gt;
</pre>
</div></li>
</ol>

<p>
Fijaos que la etiqueta está dentro de un enlace que referencia a la
cuenta de <i>Mastodon</i>. Si ya tienes algún enlace de este tipo en
tu web, basta con que añadas la etiqueta <code>rel="me"</code> en dicho enlace.
</p>

<p>
Como sabéis el código de este <i>blog</i> está mantenido en <i>elisp</i> desde
<i>Emacs</i> y yo me lo guiso y yo me lo como. En mi caso no he puesto el
texto «mastodon» en la etiqueta sino una imagen con el icono de la
red, añadiendo el siguiente código.
</p>


<figure id="org653ac83">
<img src="./imagenes/captura-insercion-codigo.png" alt="captura-insercion-codigo.png">

</figure>

<p>
Al estar el <code>html</code> embebido dentro de código <code>lisp</code> hay que escapar
las comillas, pero el resto es todo igual.
</p>
</div>
</div>
</div>
<div id="outline-container-org9c4a916" class="outline-2">
<h2 id="org9c4a916">Conclusiones</h2>
<div class="outline-text-2" id="text-org9c4a916">
<p>
La autoverificación es muy sencilla, aunque es totalmente invisible si
no entras en el perfil de la cuenta. Si tenéis dudas de que alguien es
quien dice ser, comprobad si tiene la cuenta verificada y pedidle que
la verifique en caso contrario.
</p>

<p>
El amigo <a href="https://nixnet.social/users/sl1200">sl1200</a> desde una instancia de <i>Pleroma</i> me comentó que
también existe el servicio <a href="https://keyoxide.org/">keyoxide</a> para autentificar cuentas. No lo
he probado y no sé cómo va, pero puede ser una alternativa para
aquellos que se encuentren que su servidor no proporciona la
autentificación. No sé si lo implementará <i>Pleroma</i>, en todo caso
también será una forma de validarse para los usuarios de una versión
antigua de <i>Mastodon</i> u otras redes del <i>fediverso</i>. Si hay interés,
me pondré a investigarlo y os cuento cómo.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Igual que a mí, les ocurría a <i>Fanta</i> y a <i>Aurora</i>. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/mastodon/index.html">mastodon</a> <a href="/tags/html/index.html">html</a> ]]></description>
  <category><![CDATA[mastodon]]></category>
  <category><![CDATA[html]]></category>
  <link>https://notxor.nueva-actitud.org/2022/11/14/verificarse-en-mastodon.html</link>
  <pubDate>Mon, 14 Nov 2022 09:52:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Lisp - proyectos sencillos para comprenderlo]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-11-10</div>
<p>
Llevo un tiempo sin escribir en el <i>blog</i>, las cosas se van
complicando y un día por otro, no termino de encontrar esos momentos
en los que dedicarme a mí mismo. Este <i>blog</i> es una excusa para
<i>cacharrear</i>, experimentar, aprender y satisfacer mi curiosidad. De
rebote, por lo que sé, algunas personas, aparte de mí, leen el blog, e
incluso algunos encuentran alguna información útil en el caos de los
temas que trato. Hoy voy traigo una de las cosas que me hacen
procrastinar mucho, mirar las tripas de las cosas. En concreto, las de
<i>lisp</i>. Encontré dos proyectos que implementan un <i>lisp</i> sencillo y me
puse a repasar el código y ver cómo funcionaban. Uno de los proyectos
está escrito en <i>Python</i> y el otro en C/C++.
</p>

<p>
El primero, el más sencillo, apenas está esbozado un intérprete, sólo
admite operaciones aritméticas pero ya nos puede servir para hacernos
una idea de qué se necesita para programarte un intérprete de <i>Lisp</i>.
El proyecto lo podéis encontrar en:
</p>

<p>
<a href="https://github.com/renatoalencar/lisper">https://github.com/renatoalencar/lisper</a>
</p>

<p>
Todo el meollo se encuentra condensado en menos de 500 líneas de
código Python.
</p>

<p>
Por algún sitio, que ahora mismo no encuentro, leí que el autor lo que
pretendía al inicio del proyecto era conseguir con <a href="https://python.org"><i>Python</i></a> la misma
interoperatividad que tiene <a href="https://clojure.org">Clojure</a> con <a href="https://www.oracle.com/java/"><i>Java</i></a>. Sin embargo, el
proyecto lleva abandonado dos años y no se ha avanzado en ese
aspecto. Sin embargo, me parece útil, pues se puede apreciar cómo está
implementado de un simple vistazo. Todo el código está dentro del
archivo <code>lisper.py</code>. Además cuenta con ejemplos, un par de archivos
<i>Lisp</i> que podrían servir también para hacernos una idea de lo que es
capaz de <i>interpretar</i> tan exiguo <i>intérprete</i>.
</p>
<div id="outline-container-org4b88ad5" class="outline-2">
<h2 id="org4b88ad5">LispE</h2>
<div class="outline-text-2" id="text-org4b88ad5">
<p>
<i>LispE</i> es una implementación en C++ de <i>Lisp</i> muy básica. La puedes
encontrar en:
</p>

<p>
<a href="https://github.com/naver/lispe">https://github.com/naver/lispe</a>
</p>

<p>
Ahí encontraréis en el <i>About</i> que se presenta el proyecto como:
</p>

<blockquote>
<p>
An implementation of a full fledged Lisp interpreter with Data
Structure, Pattern Programming and High level Functions with Lazy
Evaluation à la Haskell.
</p>
</blockquote>

<p>
Es decir, que es «una implementación completa de un intérprete Lisp
con estructuras de datos, patrones de programación y funciones de alto
nivel implementadas con <i>Lazy Evaluation</i> como en Haskell».
</p>

<p>
El proyecto se llama <i>Lisp Elémentaire</i> o <i>Lisp Elemental</i>. No tiene
mucho recorrido en cuanto a librerías, pero sí proporciona algunas
funciones bastante interesantes:
</p>

<ul class="org-ul">
<li>Procesamiento de cadenas</li>
<li>Funciones matemáticas (exponentes, logaritmos)</li>
<li>Funciones del sistemas (fecha, <code>ls</code>, etc.)</li>
<li>Acceso a red mediante <i>Sockets</i></li>
<li>Bases de datos <i>SQLite</i></li>
<li>Es multihilo</li>
<li>Tiene un puente con <i>Python</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup></li>
<li>Programación <i>GUI</i> con <a href="https://www.fltk.org/"><i>fltk</i></a></li>
<li>Tiene un editor de código interno que podemos invocar desde el
intérprete.</li>
</ul>

<p>
A pesar de su simpleza, permite mucho juego... de hecho llevo una
semana arruinando mi productividad jugueteando con esto.
</p>

<p>
También hay que destacar que el autor se ha esmerado con la
documentación y la podemos encontrar en el espacio <i>wiki</i> del
proyecto. Encontraremos bastante información sobre la herramienta,
sobre <i>Lisp</i> y sobre otros temas interesantes, como pruebas de
rendimiento, comparación con otros lenguajes, cómo ampliar librerías
en C/C++ para <i>LispE</i> o cómo embeber el intérprete en un programa.
</p>

<p>
Por supuesto, también cuenta con información sobre todas las funciones
implementadas. Incorpora algunas inspiradas y que les sonarán a los
programadores de <a href="https://www.haskell.org/"><i>Haskell</i></a> como <code>map</code>, <code>zip</code>, <code>filter</code>, <code>takewhile</code>...
</p>
</div>
</div>
<div id="outline-container-orgbc966d9" class="outline-2">
<h2 id="orgbc966d9">Conclusiones</h2>
<div class="outline-text-2" id="text-orgbc966d9">
<p>
Este último proyecto, es el más prometedor, espero que no se detenga y
aunque hay señales de estar vivo, veo que en los últimos tiempos los
aportes son reducidos.
</p>

<p>
Ahora mismo no tengo un proyecto en el que se pueda utilizar para
probar, pero no estaría mal intentar hacer algo con el intérprete
embebido en un ejecutable y hacer lo clásico de disfrazar un <i>Lisp</i> de
otra cosa como hacen en <i>Emacs</i> o en <i>AutoCAD</i>.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Proporciona una librería <i>Python</i> para ejecutar código <i>Lisp</i> y
el intérprete de <i>LispE</i> también acepta que le inyectemos código en
<i>Python</i>. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/lisp/index.html">lisp</a> <a href="/tags/programación/index.html">programación</a> ]]></description>
  <category><![CDATA[lisp]]></category>
  <category><![CDATA[programación]]></category>
  <link>https://notxor.nueva-actitud.org/2022/11/10/lisp-proyectos-sencillos-para-comprenderlo.html</link>
  <pubDate>Thu, 10 Nov 2022 17:09:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Control de versiones]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-10-23</div>
<p>
Ya he hablado sobre el <i>control de versiones</i> en varias ocasiones en
el <i>blog</i>. A los lectores habituales, que creo que los hay (aunque
sigo sin entender muy bien por qué) ya les sonará el haber leído algo
sobre esto. Sin embargo, hoy va a ser un artículo muy
introductorio. No sé exactamente cuándo publicaré este <i>post</i> y es
posible que cuando estés leyendo este escrito, ya haya comenzado un
curso de programación para alumnos de la E.S.O.<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. Este año es el
primero, aunque ya he hecho cursos sobre robótica en el mismo centro.
Tengo pensado también preparar contenido sobre el control de
versiones. Por lo tanto, es un artículo muy básico, con muchas
definiciones de conceptos y poca práctica para que sirva de lectura
introductoria a mis chicos. Te lo puedes saltar, si ya sabes de qué
va, pero si nunca has utilizado un <i>control de versiones</i> o estás
empezando a hacerlo, lo mismo te viene bien aprender unos pocos
conceptos básicos, porque luego, cada herramienta hace de su capa un
sayo y llama a las cosas como se le ocurre al <i>iluminado</i> que crea la
herramienta.
</p>
<div id="outline-container-org29fa8d0" class="outline-2">
<h2 id="org29fa8d0">¿Para qué sirve el control de versiones?</h2>
<div class="outline-text-2" id="text-org29fa8d0">
<p>
Antes de nada también hay que aclarar que el concepto de <i>control de
versiones</i> es un tanto ambiguo y lo podemos encontrar nombrado de
diversas maneras: SCM (<i>Source Control Management</i>), CVS (<i>Concurrent
Version System</i>), SCS (<i>Source Control System</i>), VC (<i>Version
Control</i>)...
</p>

<p>
A partir de esos nombres ya te puedes imaginar algunos aspectos
sencillos:
</p>

<ul class="org-ul">
<li>La cosa va de <b>control</b>, es decir, hay algo complejo que debemos
manejar y gestionar de alguna manera más sencilla que el tomar notas
a mano.</li>
<li>También hay <b>versiones</b>, es decir, un mismo <i>proyecto</i> puede tener
varias versiones de su contenido:
<ul class="org-ul">
<li>Las versiones se pueden referir al contenido generado por varias
personas, que se deben guardar de manera conjunta (<b>concurrente</b>)
en el mismo sitio, porque cada una aporta una parte del trabajo.</li>
<li>Las versiones se pueden referir también a los avances que se van
produciendo en el contenido de proyecto.</li>
</ul></li>
</ul>

<p>
Estoy siendo cuidadoso de no utilizar la palabra <b>código</b> porque,
aunque estos sistemas los desarrollaron programadores para gestionar
su trabajo en equipo, se pueden utilizar para cualquier otro fin. Como
por ejemplo, mantener un montón de cambios en lo artículos de un
<i>blog</i> como éste; para hacer un trabajo escolar en equipo; para
gestionar un trabajo individual complejo que puede estar sujeto a
modificaciones.
</p>

<p>
¿Qué hace que sea útil un sistema de estos? Ahí van algunas posibles
respuestas y no sólo una, sino todas ellas:
</p>

<ul class="org-ul">
<li>Que tienes la libertad de borrar, mover, cambiar... y arrepentirte
sin perder información en ningún momento. Si algo ha estado en el
repositorio en una versión anterior, sigue estando en él.</li>
<li>Que puedes realizar cambios en el proyecto o trabajo y los demás
participantes los tendrán de forma <i>inmediata</i>.</li>
<li>Que puedes tener algunas <b>ramas</b> del trabajo de <i>forma experimental</i>
aunque luego, al final, no se integren el resultado definitivo.</li>
<li>Que puedes volver <i>en el tiempo</i> a versiones anteriores y ver su
evolución, o evolucionarlas de forma paralela en otras <i>ramas</i>.</li>
<li>Que sabes quién, cómo y cuándo, apareció algún contenido en el
proyecto, manteniendo una cronología perfecta de la evolución del
mismo.</li>
<li>Que tienes una copia completa en un repositorio remoto. En caso de
pérdida, borrado o catástrofe, tienes una copia de seguridad
completa de toda la información.</li>
</ul>

<p>
También deberías saber que existen muchos sistemas de estos: algunos
son <i>centralizados</i> y otros <i>distribuidos</i>, pero no te preocupes de
eso ahora, primero vamos a dar un repaso a los conceptos básicos.
</p>
</div>
</div>
<div id="outline-container-org4ee0e7a" class="outline-2">
<h2 id="org4ee0e7a">Conceptos básicos</h2>
<div class="outline-text-2" id="text-org4ee0e7a">
<p>
La mayoría de las veces las palabras se corresponden con los
conceptos, pero en estos ámbitos no es raro encontrarse que una misma
palabra, o comando, en dos sistemas de <i>control de versiones</i>
diferentes, no corresponden al mismo concepto, o acción. O encuentras
matices que hacen que la coincidencia no sea perfecta. Pero en
general, podemos entender:
</p>

<dl class="org-dl">
<dt><b>Repositorio</b></dt><dd>Es el almacén donde se guarda el contenido, un
espacio donde están alojados los archivos y directorios que forman
parte del proyecto... en todas sus <i>versiones</i>. Cada participante en
el proyecto tiene su repositorio local y suele existir, al menos,
uno remoto donde se guardarán los cambios de todos.</dd>
<dt><b>Sistema de control de versiones</b></dt><dd>es un programa que ayuda a
mantener un repositorio donde pueden realizar cambios varias
personas de manera conjunta.</dd>
<dt><b>Commit</b></dt><dd>se corresponde con la acción de guardar los cambios que
hemos hecho en el repositorio. Habitualmente, esos cambios se
guardan en el repositorio local.</dd>
<dt><b>Trunk</b></dt><dd>esta es la línea principal o <i>tronco</i> del contenido del
repositorio.</dd>
<dt><b>Branch</b></dt><dd>es una escisión de la línea principal. Normalmente se
utilizan para añadir características nuevas al contenido del
repositorio y nos permiten experimentar sin afectar a la línea
principal.</dd>
<dt><b>Fork</b></dt><dd>bifurcación de la línea principal. En algunos sistemas se
le llama así a continuar el desarrollo del proyecto de manera
paralela al repositorio original. En otros sistemas se utiliza para
referirse a una bifurcación generada por la aplicación para resolver
problemas de concurrencia. En otros puede ser el simple hecho de
hacer una copia local del repositorio general.</dd>
<dt><b>Log</b></dt><dd>listado de los <i>commits</i> de cambios.</dd>
<dt><b>Merge</b></dt><dd>acción de juntar dos ramas del repositorio en una, por
ejemplo, para volcar los cambios de una rama en la línea principal.</dd>
<dt><b>Pull</b></dt><dd>acción de descargar al repositorio local los cambios
almacenados en un repositorio remoto.</dd>
<dt><b>Push</b></dt><dd>acción de enviar los cambios almacenados en el repositorio
local al repositorio remoto.</dd>
<dt><b>Sync</b></dt><dd>acción de sincronizar el repositorio local con el remoto.</dd>
</dl>

<p>
Existen otros conceptos y acciones que se pueden realizar en un
repositorio, como revertir cambios o situarlo en determinado estado
anterior. Pero los enumerados anteriormente son los más básicos y con
los que hay que lidiar más a menudo en el trabajo diario.
</p>
</div>
</div>
<div id="outline-container-org487d071" class="outline-2">
<h2 id="org487d071">Gestión de cambios</h2>
<div class="outline-text-2" id="text-org487d071">
<p>
La gestión de los cambios tiene aspectos diferentes según el tipo de
proyecto en el que estés trabajando. Si es un proyecto personal y no
es necesario un seguimiento exhaustivo de la evolución del proyecto,
el tener el contenido en un sistema de control de versiones, puede ser
una forma de mantener una copia de seguridad. Sin embargo, hay todo un
arte en subir los cambios al repositorio mediante <i>commits</i>.
</p>

<p>
Cada <i>commit</i> se convierte en una información valiosa para comprender
la evolución del proyecto y cuanto más detallados estén los <i>commits</i>,
mejor podrás comprenderlo. Cada uno de ellos lleva aparejado un
<i>mensaje</i> de texto, que sería el <i>título</i>, por decirlo así, pero
también se pueden añadir más <i>mensajes</i> para detallar el cambio
realizado. La mayoría de sistemas abren un editor de texto para
facilitarnos el escribir el mensaje del <i>commit</i>. La estructura del
<i>commit</i> suele ser:
</p>

<ul class="org-ul">
<li>Una línea de título del mensaje de <i>commit</i>, que suele ser
obligatoria.</li>
<li>Después de una línea en blanco, en el editor, se puede escribir toda
la explicación que se necesite para detallar lo que se ha
hecho. Esta parte es opcional, si el cambio es evidente no es
necesaria. Desde la línea de comandos se pueden proporcionar varias
cadenas de texto para formar el cuerpo.</li>
</ul>
</div>
<div id="outline-container-orgf1c504b" class="outline-3">
<h3 id="orgf1c504b">¿Cómo hacer un commit?</h3>
<div class="outline-text-3" id="text-orgf1c504b">
<p>
Ten en cuenta las siguientes premisas:
</p>

<ul class="org-ul">
<li><b>Un <i>commit</i>, un cambio</b>: recuerda realizar un <i>commit</i> para cada
cambio que hagas. Si modificas muchas cosas y agrupas todo el
trabajo que has hecho durante horas en un sólo mensaje, el
seguimiento de los cambios te será más difícil.</li>
<li><b>Revisa el lenguaje</b>: recuerda escribir claramente y con corrección
un menaje descriptivo que se ajuste al cambio que has hecho.</li>
<li><b>Sé escueto</b>: el mensaje de <i>título</i> no debería tener más de 50 ó 60
caracteres. Si necesitas explicar algo más detalladamente, utiliza
el cuerpo del <i>commit</i> para hacerlo.</li>
<li>Utiliza el verbo en <b>imperativo</b>, por ejemplo: añade..., borra...,
crea..., arregla..., etc.</li>
<li>No uses puntos suspensivos, ni un punto, al final del <i>commit</i>,
recuerda que es un título y no lo necesita.</li>
<li>Si el proyecto es de código, asegúrate que el estado del repositorio
permite compilar y ejecutar el programa o librería. No olvides
añadir todas las dependencias y código necesario para que sea así, o
puedes tener a otros compañeros volviéndose locos por un error tuyo.</li>
</ul>

<p>
La teoría es esa, o esas son las <i>buenas maneras</i> que deberíamos
utilizar, luego algunos somos descuidados y hacemos de nuestra capa un
sayo, para, al final, aprender a base de compartir <i>repositorios</i> con
otros programadores y que te saquen los colores cuando no cuidas estos
detalles.
</p>
</div>
</div>
<div id="outline-container-org58e8838" class="outline-3">
<h3 id="org58e8838">Texto plano</h3>
<div class="outline-text-3" id="text-org58e8838">
<p>
Los gestores de versiones suelen funcionar bien sobre archivos de
texto plano. Recuerda que todas estas herramientas se desarrollaron
para soportar <i>código</i>. A los que usamos texto plano para generar
nuestros documentos, bien sea con lenguajes de marcado ligero, como
<code>org-mode</code> o <i>markdown</i>, bien con lenguajes de marcado más pesado como
<i>TeX</i>, <i>LaTeX</i>, <i>Lout</i>, nos vienen muy bien estas herramientas de
gestión de cambios. Sin embargo, si utilizas muchas <i>imágenes raster</i>,
o documentos de ofimática cerrados, aunque los pueden gestionar, cada
cambio se almacena guardando el archivo completo, formando un
repositorio enorme y pesado. Por eso, el repositorio puede crecer en
tamaño hasta hacerse inmanejable. Si tu proyecto consiste en trabajar
sobre archivos binarios, estas herramientas no son recomendables.
</p>
</div>
</div>
</div>
<div id="outline-container-org0986b37" class="outline-2">
<h2 id="org0986b37">Repositorios remotos</h2>
<div class="outline-text-2" id="text-org0986b37">
<p>
Una de las pegas que puedes encontrar en el manejo de estas
herramientas es la dificultad de montar un repositorio remoto. Suele
aparejar el montaje de un servidor que proporcione el acceso al mismo
y no es fácil, muchas veces, encontrar un lugar donde situar el
<i>remoto</i> al alcance de todos los miembros del equipo.<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>
</p>

<p>
Voy a mencionar dos estrategias muy utilizadas, aparte de la
mencionada de montar un servidor, que no está al alcance de todos:
</p>

<ul class="org-ul">
<li>Aprovechar <i>la nube</i> para que nos haga de repositorio.</li>
<li>Utilizar un servicio de repositorios ya montado.</li>
</ul>
</div>
<div id="outline-container-org1ba6f09" class="outline-3">
<h3 id="org1ba6f09">La nube</h3>
<div class="outline-text-3" id="text-org1ba6f09">
<p>
Si tenemos algún lugar en lo que se denomina <i>la nube</i> que sea
compartido, se puede montar un repositorio remoto allí para
sincronizar cambios. Dependiendo del sistema de control de versiones
que estés utilizando puedes tener algunos problemas para sincronizar
dichos repositorios. Por ejemplo, <code>git</code>, uno de los sistemas más
extendidos para estas tareas utiliza archivos guardados en directorios
ocultos. Al colocarlos en <i>nubes</i> tipo <i>NextCloud</i> o <i>Dropbox</i>, debes
recordar de activar la sincronización de los archivos y directorios
ocultos o no se sincronizará correctamente.
</p>

<p>
A su vez, si está en un directorio compartido, tenemos que ser muy
cuidadosos al sincronizarnos. No podemos escribir a la vez y debemos
asegurarnos de que cuando lo hacemos el repositorio se encuentre
actualizado con respecto a la copia remota.
</p>

<p>
Por todo ello, esta estrategia nos es útil para almacenar
repositorios personales, pero es bastante difícil de mantener en el
caso de proyectos con varios participantes.
</p>
</div>
</div>
<div id="outline-container-org8542e24" class="outline-3">
<h3 id="org8542e24">Repositorios públicos</h3>
<div class="outline-text-3" id="text-org8542e24">
<p>
Desde hace tiempo existen servicios que nos proporcionan un espacio
donde colocar nuestros repositorios. Entre los pioneros de este tipo
de servicios está <a href="https://sourceforge.net/">SourceForge</a>. En la mayoría de los casos, para
proyectos de <i>software libre</i> el alojamiento es gratuito, pero alojar
proyectos personales o con licencias no libres, suele conllevar el
pago del servicio. Podemos encontrar varios de estos servicios para
alojar nuestros repositorios, aparte del ya mencionado:
</p>

<ul class="org-ul">
<li><a href="https://savannah.gnu.org/">GNU Savannah</a>: pertenece a la <i>Free Software Fundation</i> y está
enfocado al desarrollo de <i>software libre</i>. Hay que hacer una
solicitud de espacio cumpliendo los requisitos necesarios. Puede
albergar repositorios de diferentes herramientas de gestión: <code>cvs</code>,
<code>svn</code>, <code>git</code>, <code>hg</code>.</li>
<li><i>Repos privativos</i>: suelen pertenecer a corporaciones o
empresas. Normalmente son sitios donde sólo trabajan con <code>git</code>:
<a href="https://github.com/">GitHub</a>, <a href="https://gitlab.com/">GitLab</a>, <a href="https://bitbucket.org">BitBucket</a>...</li>
<li><i>Repos libres</i>: En algunos casos podemos encontrar servidores que
funcionan de una manera más abierta y libre. Entre los que trabajan
con <code>git</code> podemos mencionar <a href="https://gitea.io">Gitea</a> o <a href="https://codeberg.org/">Codeberg</a>. También merece una
mención el servicio de <a href="https://chiselapp.com/">Chisel</a> si quieres alojar un repositorio con
<code>fossil</code>.</li>
</ul>
</div>
</div>
<div id="outline-container-org22f1f3e" class="outline-3">
<h3 id="org22f1f3e">¿Qué proporcionan estos servicios?</h3>
<div class="outline-text-3" id="text-org22f1f3e">
<p>
Normalmente los servicios de alojamiento de repositorios suelen
aparejar una serie de herramientas muy útiles para el desarrollo de
proyectos: <i>wiki</i>, foros, gestión de errores, página web del proyecto,
etc.
</p>

<p>
Muchas herramientas de control de versiones se centran, como <code>git</code>, en
la gestión de los cambios del proyecto. Los servicios de repositorio,
también llamados <i>servicios de forja</i>, proporcionan esas herramientas
complementarias a la gestión del proyecto.
</p>

<p>
Otros sistemas, como <code>fossil</code>, proporcionan dichas herramientas en
todos sus repositorios, incluidos los locales, por diseño.
</p>
</div>
</div>
</div>
<div id="outline-container-orgb89617b" class="outline-2">
<h2 id="orgb89617b">Conclusiones</h2>
<div class="outline-text-2" id="text-orgb89617b">
<p>
El control de versiones es una herramienta auxiliar para programación,
que se puede utilizar para gestionar (casi) cualquier tipo de proyecto
conjunto.
</p>

<p>
Permite seguir los cambios realizados por los participantes del
equipo, especialmente en los contenidos de texto plano.
</p>

<p>
Es muy recomendable aprender cómo funciona alguno de estos sistemas.
Más recomendable aún aprender varios. En mi caso, trabajo
habitualmente con <code>git</code> pero en los últimos tiempos, si necesito
alguna de las herramientas de <i>forja</i>, utilizo <code>fossil</code> en
repositorios locales, en lugar de subirlo a uno público en la
red. Aunque cada vez más, necesito esas herramientas, porque utilizo
la <i>wiki</i> para anotar ideas, lo <i>tickets</i> para planificar tareas y
anotar errores que hay que corregir, etc.
</p>
</div>
</div>
<div id="outline-container-org5438cbd" class="outline-2">
<h2 id="org5438cbd">Notas al pie</h2>
<div class="outline-text-2" id="text-org5438cbd">
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Para los no españoles, aclarar que es el acrónimo de <i>Enseñanza
Secundaria Obligatoria</i> y los chavales que estarán en mi grupo,
tendrán, o pueden tener, entre 11 y 16 años.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Montar un servidor para el repositorio remoto implica unas
complejidades que se escapan de este artículo.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/cms/index.html">cms</a> <a href="/tags/fossil/index.html">fossil</a> <a href="/tags/git/index.html">git</a> ]]></description>
  <category><![CDATA[cms]]></category>
  <category><![CDATA[fossil]]></category>
  <category><![CDATA[git]]></category>
  <link>https://notxor.nueva-actitud.org/2022/10/23/control-de-versiones.html</link>
  <pubDate>Sun, 23 Oct 2022 18:42:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[eXeLearning]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-10-11</div>
<p>
Llevo tiempo buscando alguna manera de poder poner en línea cursos sin
todo el aparato que necesitan las herramientas de <i>e-learning</i> como
<a href="https://moodle.org/">moodle</a> y otras similares: bases de datos, <code>php</code>, <i>javascript</i>, mucho
espacio en disco... En fin, sólo quiero colgar un par de cursos
puntuales, más como información o como formación desasistida que no
necesite muchos recursos. Ya utilicé hace tiempo <a href="https://exelearning.net/"><i>eXelearning</i></a> hice
una chapuza, que está colgada en este <i>blog</i>, <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo/">como curso de
<i>Esperanto</i></a> y no volví a hacerle mucho caso. Sin embargo, ahora me veo
en la necesidad de recurrir a él de nuevo y llevo unas semanas, no
sólo trabajando con él, sino explorando sus posibilidades. Por ello,
no he podido resistir la tentación de presentároslo, si no lo
conocéis.
</p>

<p>
Primero vamos con un poco de los antecedentes, es decir, las
necesidades que debo cubrir y cómo las cubre esta herramienta <i>de
autor</i>. Antes de nada, si lo que necesitas es crearte un centro de
estudios virtual, gestionar evaluaciones y alumnos, esta aplicación no
es lo que necesitas, sin embargo, te puede ser muy útil para crear
contenido. En mi caso, lo quiero para crear un sólo curso, que no será
por completo <i>on line</i> y que me ayudará en la formación que damos a
los voluntarios de la <a href="https://asociacionpica.org">Asociación PICA</a> cuando quieren comenzar a
trabajar con niños que han sufrido abusos. Hasta ahora, formábamos
siempre de manera presencial. Sin embargo, <i>la pandemia</i>, nos mostró
que lo mismo era necesario descentralizar la enseñanza y algunos temas
podrían preparárselos por su cuenta. Otros, en los que la interacción
es necesaria, como las dinámicas de grupo o el <i>rolplaying</i>, se
seguirán haciendo de manera presencial.
</p>

<p>
Pero vamos ya con el <i>chismático</i>.
</p>
<div id="outline-container-org378d357" class="outline-2">
<h2 id="org378d357">La herramienta</h2>
<div class="outline-text-2" id="text-org378d357">
<p>
No hay paquete para <i>OpenSuse Tumbleweed</i>, que ya sabréis todos que es
<i>mi distro</i> preferida. Lo encuentras en la lista de paquetes
experimentales y me da cosa <i>enguarrinar</i> la lista de servidores de
actualización de una <i>rolling release</i> con experimentos, bastante en
el filo camina ya.
</p>

<p>
La alternativa es ir a la página <i>web</i> de la aplicación y descargar
<i>la versión portable para GNU/Linux</i>. Encuentras también paquetes para
Debian, Ubuntu, Fedora, Red Hat y sus versiones <i>SNAP</i>, si lo
utilizas.
</p>

<p>
La versión portable viene en un <code>.zip</code> y yo lo descargué y descomprimí
en un directorio local en <code>~/opt</code>, y al descomprimirlo quedó todo
metido en <code>~/opt/exelearning27</code>. Luego creé un <i>script</i> lanzador en
<code>~/opt/bin</code> y ya lo puedo llamar desde cualquier sitio.
</p>
</div>
<div id="outline-container-org462fd23" class="outline-3">
<h3 id="org462fd23">Primer arranque</h3>
<div class="outline-text-3" id="text-org462fd23">
<p>
La primera vez que lo lanzas aparecerá una imagen como esta:
</p>


<figure id="org8cd0f80">
<img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_primera-pantalla.png" alt="Captura_primera-pantalla.png">

</figure>

<p>
Como se puede apreciar en la <i>URL</i> de la ventana, lo que hace la
aplicación es montar un servidor local en <code>localhost</code>, abrir el
navegador por defecto y conectarse a él<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. La apariencia es muy
similar a una aplicación de escritorio, con su barra de menú y sus
paneles.
</p>

<p>
Por comenzar por algún sitio, veamos la barra de menús. En su modo de
funcionamiento básico se ven de la siguiente manera:
</p>


<figure id="orgaeaef69">
<img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_menu_archivo.png" alt="Captura_menu_archivo.png">

</figure>

<p>
En el menú archivo se pueden apreciar los habituales comandos de
abrir, guardar, importar, exportar, salir, etc. Nada que no se vea
habitualmente en cualquier aplicación de escritorio. Más adelante
hablaré de las posibilidades de exportación del documento.
</p>

<p>
Por otro lado, el menú <i>ayuda</i> nos mostrará la siguiente ventana:
</p>


<figure id="org456a6c8">
<img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_ventana_ayuda.png" alt="Captura_ventana_ayuda.png">

</figure>

<p>
En esta ventana nos enlaza recursos en línea para aprender a utilizar
la herramienta.
</p>

<p>
He dejado para el final las dos entradas del menú centrales, porque
tienen dos modos. Si nos fijamos en la parte derecha de la barra de
menú veremos dos botones:
</p>


<figure id="org06ebe79">
<img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_modo_y_visualizar.png" alt="Captura_modo_y_visualizar.png">

</figure>

<p>
Por defecto, yo tengo seleccionado el <i>modo avanzado</i>, que se
diferencia del <i>modo normal</i> en que permite crear nuestros propios
estilos de página y fabricarnos nuestros propios <i>iDevices</i>, que ahora
veremos. Los menús centrales quedan de la siguiente manera:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Normal</th>
<th scope="col" class="org-left">Avanzado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_menu_utilidades.png" alt="Captura_menu_utilidades.png"></td>
<td class="org-left"><img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_menu_utilidades_avanzado.png" alt="Captura_menu_utilidades_avanzado.png"></td>
</tr>
</tbody>
</table>


<p>
Esas imágenes corresponden al menú de <i>utilidades</i> y el menú de
estilos cambia de la siguiente manera: Los estilos que muestra de
manera básica son desplazados a un <i>submenú</i>.
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Normal</th>
<th scope="col" class="org-left">Avanzado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_menu_estilos.png" alt="Captura_menu_estilos.png"></td>
<td class="org-left"><img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_menu_estilos_avanzado.png" alt="Captura_menu_estilos_avanzado.png"></td>
</tr>
</tbody>
</table>

<p>
El <i>gestor de estilos</i> nos mostrará la lista de estilos que tengamos
instalada y nos dará la posibilidad de gestionar algunos:
</p>


<figure id="org2b56863">
<img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_ventana_gestor_estilos.png" alt="Captura_ventana_gestor_estilos.png">

</figure>

<p>
Como vemos, es una lista de estilos y una serie de botones que nos
permiten hacer algunas acciones con ellos, como buscar en la red otros
estilos y descargarlos a nuestro ordenador. Aquellos estilos de la
lista que muestran activado el botón con el icono del lápiz, nos
permiten modificarlo.  Luego hablaré más detenidamente sobre la
creación de estilos.
</p>

<p>
Por último, el botón de <i>visualización previa</i> nos mostrará la página
tal y como la verá el futuro usuario del contenido y podremos utilizar
todo el recurso tal y como le aparecerá al alumno.
</p>


<figure id="org7129346">
<img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_previsualizacion.png" alt="Captura_previsualizacion.png">

</figure>
</div>
</div>
<div id="outline-container-org1bbcbd8" class="outline-3">
<h3 id="org1bbcbd8">Los paneles</h3>
<div class="outline-text-3" id="text-org1bbcbd8">
<p>
Son tres los paneles que encontramos en la pantalla principal. A la
izquierda tenemos dos paneles, el de arriba nos muestra la estructura
del proyecto
</p>


<figure id="org53796bd">
<img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_panel_estructura.png" alt="Captura_panel_estructura.png">

</figure>

<p>
El inferior nos muestra un listado con los <i>iDevices</i> que podemos
meter en el contenido. Después hablaré de los <i>iDevices</i> más
detenidamente:
</p>


<figure id="org97616db">
<img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_panel_idevices.png" alt="Captura_panel_idevices.png">

</figure>

<p>
La edición del contenido se llevará a cabo en el panel grande de la
derecha:
</p>


<figure id="orgd132479">
<img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_panel_contenido.png" alt="Captura_panel_contenido.png">

</figure>
</div>
</div>
<div id="outline-container-org362997a" class="outline-3">
<h3 id="org362997a">iDevices</h3>
<div class="outline-text-3" id="text-org362997a">
<p>
Los <i>iDevices</i>, como los llama la aplicación, son los distintos
<i>chismáticos</i> que se pueden cargar en el contenido del curso. Cada uno
de esos <i>iDevices</i> se muestra como un recuadro en el contenido. Tiene
diferentes opciones y se rellena de diferentes maneras.
</p>

<p>
Por ejemplo, el más utilizado y el que se encuentra el primero en la
lista es el <i>iDevice</i> de <i>texto</i>. Cuando lo tenemos dispuesto en el
contenido nos aparecerá en modo visualización y nos permite entrar en
modo edición o borrarlo, con los siguientes iconos:
</p>


<figure id="orgdce0f0c">
<img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_iconos_edicion_borrado.png" alt="Captura_iconos_edicion_borrado.png">

</figure>

<p>
Al pasar al <i>modo edición</i> vemos cómo cambia la pantalla:
</p>


<figure id="org628870b">
<img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_idevice_texto_edicion.png" alt="Captura_idevice_texto_edicion.png">

</figure>

<p>
En la anterior imagen vemos un <i>iDevice</i> de texto en <i>modo edición</i>
y vamos a ver sus partes<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>:
</p>

<ul class="org-ul">
<li>Título: En el título no sólo podemos establecer un nombre en un
<i>widget</i> de entrada de texto. También hay un pequeño botón que nos
permite cambiar el icono que aparecerá junto a él.</li>
<li>Área de edición de texto: La parte central es un completo editor de
<code>html</code>, podemos escribir y formatear el contenido y enlazar
cualquier tipo de recurso: imágenes, audio, vídeo. También podemos
acceder directamente al código <code>html</code> y modificarlo, o añadir
algunos efectos que vienen añadidos gracias al <i>javascript</i> de
<i>eXeLearning</i> y que harán más vistosos nuestros temas.</li>
<li>Los iconos de gestión: nos permiten gestionar el <i>iDevice</i>, guardar
los cambios, revertir los cambios, borrarlo del contenido, ordenar
en qué posición lo queremos con las flechas, o cambiarlo de <i>nodo</i>
con el <i>widget desplegable</i> de la derecha.</li>
</ul>

<p>
Entre otras cosas, el editor nos permite también la inclusión de
fórmulas en <i>LaTeX</i>, efectos de <i>bocadillo</i> o <i>tooltips</i>, abrir
ventanas de diálogo con más información o efectos de acordeón,
paginación por pestañas o carrusel, etc. Incluso nos permite hacer
<i>mapas mentales</i> sencillos.
</p>

<p>
El editor más profundo es el editor de código fuente, donde tienes
acceso a todo el código:
</p>


<figure id="orgaadce76">
<img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_editor_codigo_fuente.png" alt="Captura_editor_codigo_fuente.png">

</figure>
</div>
</div>
<div id="outline-container-org1e6726b" class="outline-3">
<h3 id="org1e6726b">Modo avanzado</h3>
<div class="outline-text-3" id="text-org1e6726b">
<p>
Una de las primeras cosas que seguramente querrás hacer es crear tu
propio <i>estilo</i> para el curso que estás haciendo. Por ejemplo,
partiendo del estilo básico nos presenta un diálogo de creación que
nos permite de manera rápida y visual, hacerle todos los cambios que
consideremos oportunos sin escribir una sola línea de código <code>html</code>,
<code>css</code> o <code>javascript</code>. Sólo rellenando un formulario.
</p>


<figure id="org0f058e4">
<img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_editor_estilo.png" alt="Captura_editor_estilo.png">

</figure>

<p>
¿Podemos hacer grandes cosas con esto? Pues generalmente no, a no ser
que tus necesidades sean muy básicas. Si quieres algo más de chicha,
tienes que tirar de código. Puede servirte, eso sí, para iniciar el
diseño básico, establecer algunos parámetros generales como los
colores, fondos, tipos de letra básicos y tener de esa manera listos
un par de archivos <code>css</code>, iconos básicos para las funciones generales
de un curso y el código <code>javascript</code> de <i>eXeLearning</i> como punto de
partida.
</p>

<p>
Como vimos en la ventana del <i>gestor de estilos</i> algunos aparecían
como modificables y otros no. La diferencia entre ellos es que los
archivos <code>css</code> han sido generados con el <i>editor de estilo</i> y sólo con
él, o se han modificado algunas cosas desde el texto. Es posible, que
algún fichero modificado a mano pueda ser reconocido por el <i>editor</i>,
sin embargo, según dónde toquemos podemos perder la oportunidad de
hacerlo con esa herramienta.
</p>

<p>
En mi caso, los estilos los guarda en el directorio de instalación de
<i>eXeLearning</i>, que como dije al principio es <code>~/opt/exelearning27/</code>.
Ahí encontrarás un directorio llamado <code>style</code>, cada directorio dentro
de él corresponde con un estilo de los que tengas instalados en tu
ordenador. Accediendo a ellos puedes modificar el comportamiento de
cualquier estilo, sus iconos, su visualización.
</p>
</div>
</div>
</div>
<div id="outline-container-org1399616" class="outline-2">
<h2 id="org1399616">Exportación de resultados</h2>
<div class="outline-text-2" id="text-org1399616">
<p>
Una de las cosas que más me han interesado cuando comencé a trastear
con él fue su capacidad de exportar los documentos a múltiples
formatos. Nos permite generar objetos <i>SCROM</i> o <i>IMS</i> que pueden
cargar posteriormente en gestores de cursos como <i>moodle</i>. Podemos
generar lecciones o incluso exámenes con preguntas de tipo test, con
alternativas, para autocorrección.
</p>


<figure id="org85ad92d">
<img src="https://notxor.nueva-actitud.org/2022/10/11/imagenes/Captura_menu_exportacion.png" alt="Captura_menu_exportacion.png">

</figure>

<p>
Podemos también, más allá de los formatos para herramientas
educativas, podemos generar un archivo <code>epub3</code>, que soportan también
el uso de <i>javascript</i> para mostrar contenido interactivo, o
simplemente crear una página web con nuestro curso, empaquetándola (o
no) en un fichero <code>zip</code>.
</p>

<p>
Por las limitaciones que cuentan algunos sitios, si no necesitas un
control de estudiantes, calificaciones y demás, y tan sólo quieres
generar el contenido para que te sirva como una herramienta más para
la transmisión de conocimientos, que se pueda cargar en cualquier
dispositivo, o mostrar en cualquier pantalla (hay incluso un estilo
especialmente pensado para presentaciones), <i>eXeLearning</i> es una
alternativa muy válida para hacerlo. En mi caso, genero la página
dentro de un <code>zip</code><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> y lo subo al sitio. Este tipo de exportación
también tiene la ventaja de poderse cargar con aplicaciones como
<i>eXeReader</i> que es una aplicación para móvil.
</p>
</div>
</div>
<div id="outline-container-org1e204f5" class="outline-2">
<h2 id="org1e204f5">Conclusiones</h2>
<div class="outline-text-2" id="text-org1e204f5">
<p>
<i>eXeLearning</i> nació en Nueva Zelanda, sin embargo, desde 2010, el
INTEF<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup> español lleva el mantenimiento de la herramienta y cuenta
con una comunidad comprometida para su desarrollo. Siendo dependiente
del Ministerio de Educación español, la herramienta se encuentra
traducida a todas las lenguas cooficiales: castellano, catalán,
euskera, galego.
</p>

<p>
Si lo quieres ver en acción puedes aprovechar <a href="http://descargas.intef.es/cedec/exe_learning/Manuales/manual_exe27/">su manual</a> y además, ahí
encontrarás toda la información necesaria para su uso, mucho mejor
explicada de lo que puedo hacer yo en un simple artículo del <i>blog</i>.
</p>

<p>
También podéis echarle un vistazo a la <a href="https://descargas.intef.es/cedec/proyectoedia/guias/contenidos/guia_rea_exe/index.html">guía de creación de contenido REA</a><sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>
del Ministerio de Educación.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Es importante recordar que debes salir de la aplicación con su
correspondiente menú, pues si cierras la pestaña, el servidor se
quedará esperando conexiones en segundo plano.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Cada <i>iDevice</i> tiene las suyas, pero el más simple es el de
texto y por tanto, será el mejor ejemplo que encontremos. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Siempre es más cómodo subir un archivo <code>zip</code> al sitio y
descomprimirlo en remoto, que subir decenas de archivos pequeñitos.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Instituto Nacional de Tecnologías Educativas y Formación de
profesorado, dependiente del Ministerio de Educación español. 
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
REA Recurso Educativo Abierto.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/cursos/index.html">cursos</a> <a href="/tags/exelearning/index.html">exelearning</a> ]]></description>
  <category><![CDATA[cursos]]></category>
  <category><![CDATA[exelearning]]></category>
  <link>https://notxor.nueva-actitud.org/2022/10/11/exelearning.html</link>
  <pubDate>Tue, 11 Oct 2022 09:06:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Toda la ayuda de Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-09-29</div>
<p>
Quieres aprender a utilizar <i>Emacs</i> y en lugar de ponerte a ello,
pretendes que te haga yo el trabajo. Bien, así no funciona el
aprendizaje, hazme caso. Muchas cosas las podrás aprender leyendo este
<i>blog</i>, así que, de alguna manera ya tienes muchas cosas explicadas.
Además, una de las ventajas de <i>Emacs</i> es que todo es consultable, el
mismo código te explica cómo funciona o, al menos, para qué sirve,
sólo tienes que preguntar y leer. ¿Cómo preguntas? Pues para eso
tienes el sistema de ayuda, uno de los más completos que puedes
encontrar en este mundo. En este pequeño artículo te voy a explicar
cómo puedes usarla, que es la manera cómo yo me inicié y aprendí a
utilizarlo. Además hay un montón de <i>blogs</i>, artículos y canales de
vídeo que te proporcionarán información adicional. La ventaja de la
ayuda que viene con <i>Emacs</i> es que la puedes consultar dentro del
propio editor e incluso ejecutar el código de los ejemplos que
encuentras.
</p>
<div id="outline-container-org23ee805" class="outline-2">
<h2 id="org23ee805">F1</h2>
<div class="outline-text-2" id="text-org23ee805">
<p>
No me refiero a la fórmula uno. Me refiero a la tecla de función <code>F1</code>
que en el mundo mundial, de toda la <i>mundialidad</i>, suele asociarse con
la ayuda de las aplicaciones; en <i>Emacs</i> también. Aunque, los que
usamos este editor habitualmente, estamos más acostumbrados a la
combinación <code>C-h</code>. Pero recuerda, cualquiera de los dos métodos te
permitirá acceder a la ayuda.
</p>

<p>
Algo más sobre las teclas: como has visto <code>&lt;F1&gt;</code> y <code>C-h</code> son
equivalentes. Ocurre lo mismo con otras teclas. Por ejemplo, una muy
socorrida que se utiliza bastante es la combinación <code>M-x</code> para
introducir a continuación un comando. El mismo efecto lo consigues
pulsando <code>&lt;ESC&gt; x</code><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> y también la tienes en la tecla de <i>menú</i>
junto al <code>&lt;Control derecho&gt;</code>. Esto es para que veas, que algunas veces
las cosas se pueden hacer de varias maneras.
</p>
</div>
</div>
<div id="outline-container-orgc01ee89" class="outline-2">
<h2 id="orgc01ee89">¿Por dónde empezar?</h2>
<div class="outline-text-2" id="text-orgc01ee89">
<p>
Esta pregunta es la más fácil de contestar. Si no has utilizado
<i>Emacs</i> con antelación, te vendrá muy bien que comiences por aprender
cómo funciona, cómo moverte por un fichero, como cargar, modificar y
guardar los ficheros, etc. Por tanto, te vendrá muy bien hacer el
<i>tutorial</i> que viene con él. Además puedes elegir en qué idioma
hacerlo.
</p>

<p>
Como ya te he dicho antes, en <i>Emacs</i> las cosas se pueden hacer de
varias maneras. Una es aprenderte la combinación de teclas que hace lo
que quieres<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>, pero de éstas sólo te aprenderás las que usas
normalmente. Otra forma de utilizar funcionalidades es, como te he
dicho antes, llamándolas desde <code>M-x</code> o <code>&lt;ESC&gt; x</code> o la tecla de menú.
Por abreviar y centrarnos en la tarea de aprender a manejar <i>Emacs</i>,
son equivalentes:
</p>

<pre class="example" id="org7949a45">
M-x help-with-tutorial &lt;=&gt; C-h t
</pre>

<p>
Al activarlo te mostrará un <i>buffer</i> con explicaciones básicas de cómo
moverte por <i>Emacs</i> y ejercicios simples para acostumbrarte a su
manejo.
</p>
</div>
</div>
<div id="outline-container-orgdf03468" class="outline-2">
<h2 id="orgdf03468">Apropos y la ayuda para la ayuda</h2>
<div class="outline-text-2" id="text-orgdf03468">
<p>
¿Ya has hecho el tutorial? Bien, pues vamos a seguir con otras cosas
que te pueden ser de ayuda. Pulsa <code>M-x</code> (o cualquiera de sus
variantes, ya sabes) y escribe <code>apropos</code>, te pedirá un término que
buscar, teclea <code>help</code> y debería aparecerte algo como:
</p>


<figure id="org7799bdf">
<img src="./imagenes/Captura_apropos-buffer.png" alt="Captura_apropos-buffer.png">

</figure>

<p>
Quizá tu <i>Emacs</i> no se vea exactamente así, pero quédate con el
contenido del <i>buffer</i> de la derecha. Ahí tienes una lista de
variables y funciones que contienen el término <code>help</code>, puedes moverte
por él. Quiero que vayas a la entrada <code>help-for-help</code>, pero quería que
vieras que aún no sabiendo el nombre exacto puedes buscar la
referencia.
</p>


<figure id="org49f5c4a">
<img src="./imagenes/Captura_help-for-help.png" alt="Captura_help-for-help.png">

</figure>

<p>
Muestra información sobre el comando <code>help-for-help</code>, no demasiada,
pero te indica a qué teclas está ligado, junto con una breve
explicación de lo que hace, la versión desde la que se encuentra
incluido en <i>Emacs</i>, etc. Algunas funciones y variables están bien
documentadas y otras pueden dejarte algo que de desear. Básicamente,
este comando abre un <i>buffer</i> de ayuda para manejar la ayuda de
<i>Emacs</i>. Si lo llamas con cualquiera de las teclas a las que está
asignado, por ejemplo pulsando <code>&lt;f1&gt; &lt;f1&gt;</code>, te aparecerá un <i>buffer</i>
como el siguiente:
</p>


<figure id="orgff53844">
<img src="./imagenes/Captura_hfh-buffer.png" alt="Captura_hfh-buffer.png">

</figure>

<p>
Fíjate que es una lista de cosas que puedes consultar pulsando una
tecla de ayuda, la que completaría la combinación de teclas está
remarcada a la izquierda. Si no te cabe toda la información en la
pantalla, usa las teclas de página arriba y página abajo para moverte
por el <i>buffer</i>. En resumen, ¿de qué ayuda podemos hablar? Pues toda
la ayuda, ¿cómo? pues usando <code>C-h &lt;tecla&gt;</code>. Mira el listado:
</p>

<ul class="org-ul">
<li>Comandos, teclas y funciones:

<ul class="org-ul">
<li><code>m</code>: Muestra ayuda sobre los comandos y teclas propios de los
modos menores y mayor que tengas activados.</li>
<li><code>b</code>: Muestra todas las teclas configuradas y la función asignada
a cada una de ellas.</li>
<li><code>k</code>: Muestra ayuda para una determinada combinación de teclas.</li>
<li><code>c</code>: Muestra sólo la función a la que está asignada una
combinación de teclas.</li>
<li><code>w</code>: Muestra qué tecla lanza un comando específico.</li>
<li><code>a</code>: Busca comandos con ese nombre (similar a <code>apropos</code>)</li>
<li><code>d</code>: Busca documentación para funciones, variables y demás.</li>
<li><code>x</code>: Muestra la ayuda para un comando<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>.</li>
<li><code>f</code>: Muestra ayuda para una función.</li>
<li><code>v</code>: Muestra ayuda sobre una variable.</li>
<li><code>o</code>: Muestra ayuda para una función o una variable.</li>
</ul></li>

<li>Manuales

<ul class="org-ul">
<li><code>r</code>: Muestra el manual de <i>Emacs</i>.</li>
<li><code>F</code>: Muestra la sección del manual para un comando.</li>
<li><code>K</code>: Muestra la sección del manual para una combinación de teclas.</li>
<li><code>i</code>: Muestra todos los manuales instalados.</li>
<li><code>R</code>: Muestra un manual específico.</li>
<li><code>S</code>: Muestra la descripción de un símbolo en el manual correspondiente.</li>
</ul></li>

<li>Otros comandos de ayuda

<ul class="org-ul">
<li><code>C-e</code>: Ayuda de cómo extender <i>Emacs</i> con paquetes.</li>
<li><code>p</code>: Abre un <i>buffer</i> para buscar información sobre paquetes.</li>
<li><code>P</code>: Describe un paquete específico.</li>
<li><code>t</code>: Inicia el tutorial de <i>Emacs</i>.</li>
<li><code>e</code>: Muestra el <i>buffer</i> <code>*Messages*</code> con los mensajes recientes
del área de eco.</li>
<li><code>l</code>: Muestra las últimas pulsaciones que se han hecho.</li>
<li><code>.</code>: Muestra ayuda local en el punto donde estás.</li>
</ul></li>

<li>Varios

<ul class="org-ul">
<li><code>C-a</code>: Muestra la ventana de inicio por defecto de <i>Emacs</i>.</li>
<li><code>C-f</code>: Muestra las preguntas frecuentes de <i>Emacs</i>.</li>
<li><code>C-n</code>: Muestra novedades sobre los cambios recientes.</li>
<li><code>C-p</code>: Muestra información sobre problemas conocidos.</li>
<li><code>C-d</code>: Muestra ayuda sobre cómo depurar <i>Emacs</i>.</li>
<li><code>g</code>: Muestra información sobre el proyecto <i>GNU</i>.</li>
<li><code>C-c</code>: Muestra la licencia de uso de <i>Emacs</i>.</li>
</ul></li>

<li>Internacionalización y sistemas de códigos de letras y tipos

<ul class="org-ul">
<li><code>I</code>: Describe métodos de entrada para caracteres especiales.</li>
<li><code>C</code>: Describe el sistema de códigos.</li>
<li><code>L</code>: Describe el entorno para una determinada lengua.</li>
<li><code>s</code>: Muestra la tabla de símbolos.</li>
<li><code>h</code>: Muestra un archivo con varios sistemas de escritura. 	Display the HELLO file illustrating various scripts</li>
</ul></li>
</ul>

<p>
No quiero decir que te lo tengas que leer todo para aprender a
utilizar <i>Emacs</i>. De hecho, yo no me lo he leído todo, sin embargo, sí
aprendí cómo utilizar la ayuda. Cuando tengo dudas o no sé hacer algo,
lo primero que hago es abrir la ayuda o buscar toda la información que
pueda sobre lo que necesito.
</p>
</div>
</div>
<div id="outline-container-org58bda11" class="outline-2">
<h2 id="org58bda11">Manuales</h2>
<div class="outline-text-2" id="text-org58bda11">
<p>
Tienes mucha información en los manuales. Algunos son libros
completos. Si utilizas la combinación <code>C-h i</code> te muestra una lista de
todos los manuales que encuentre en el sistema. Algunos paquetes
tienen su manual y vienen con él, como <code>org-mode</code>. Los más importantes
son:
</p>

<ul class="org-ul">
<li><i>Emacs</i></li>
<li><code>org-mode</code></li>
<li><i>Emacs Lisp Intro</i></li>
<li><i>Elisp</i></li>
</ul>

<p>
Pero también son muy recomendables otros más específicos según el uso
que vayas a darle a <i>Emacs</i>. Así a bote pronto se me ocurren: el
manual de <code>eshell</code>, el manual de <code>magit</code>, el manual de <code>calc</code> y el
manual <i>Widget</i> y el de <i>Transient</i> si quieres meterte en temas de
programación de <i>interfaces</i> con <i>Emacs</i>.
</p>

<p>
Si vas a utilizar tu <i>Emacs</i> para temas de programación, también es
recomendable que le eches un vistazo al manual de <i>EDE</i> y al de
<code>gdb</code>.
</p>
</div>
</div>
<div id="outline-container-org7df0591" class="outline-2">
<h2 id="org7df0591">Conclusiones</h2>
<div class="outline-text-2" id="text-org7df0591">
<p>
Ya sé que leer cuesta un esfuerzo extra a que te lo den todo
resuelto. Quizá te has acostumbrado a que ese problema que tú tienes
ahora, lo tiene que haber tenido alguien antes y seguramente está
relatado en algún <i>blog</i>. En muchos casos es así y en este mismo sitio
te puedes encontrar con muchas respuestas a dudas que puedes tener.
Pero el mérito de esas respuestas no están más que en la documentación
que viene con <i>Emacs</i>, que es donde suelo mirar como primera opción.
</p>

<p>
Me parece una buena manera de aprender, porque así lo he hecho yo. Son
tres pasos muy sencillos:
</p>

<ol class="org-ol">
<li>Intento resolver mi problema recurriendo a la ayuda del programa.</li>
<li>Si no lo encuentro o no soy capaz de solucionarlo por mi cuenta,
pido ayuda.</li>
<li>Después documento todo lo que he hecho, fundamentalmente para
cuando lo vuelva a necesitar, pero además también, porque puede
ayudar a otras personas y lo publico en el <i>blog</i> o me lo apunto en
mis notas.</li>
</ol>

<p>
Así pues, no me seas vago y lee los manuales. Sé que no es una lectura
muy amena, pero sí muy provechosa.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Esa combinación significa que pulsas la tecla de <i>escape</i>, la
sueltas y pulsas luego la <code>x</code>.  Sí, la tecla escape, yo la tengo
mapeada también en el bloqueo de las mayúsculas y necesito mover menos
la mano.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Sí, esa es una de las queja-excusas de los que no lo usan. Que
hay una infinidad de teclas para todo. Es cierto, hay una infinidad de
teclas porque hay una infinidad de funcionalidades que llamar.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Lo que diferencia un <i>comando</i> de una función es que el comando
se puede llamar, bien desde <code>M-x</code> o bien con una combinación de
teclas.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2022/09/29/toda-la-ayuda-de-emacs.html</link>
  <pubDate>Thu, 29 Sep 2022 22:38:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Lenguajes repelentes]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-09-09</div>
<p>
Hoy traigo sólo un poco de reflexión e historia de los lenguajes de
programación al <i>blog</i>. Ya lo siento, hoy toca <i>chapa</i> de la fina...
Y es que no he podido resistirme al título, porque me ponga como me
ponga al final los lenguajes en los que programo son <i>repelentes</i>, o
al menos yo así los llamo. Para entrar en materia con un poco más de
conocimiento de causa: supongo que la mayoría sabéis qué es eso de
<i>REPL</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. Esos son los lenguajes que yo llamo <i>repelentes</i>; bueno,
también existen los lenguajes que <i>son</i> repelentes para mi gusto (el
<i>C++</i> y el <i>Java</i>, fundamentalmente, y que curiosamente no es ninguno
<i>REPL</i>). Si tienes paciencia suficiente para leer este artículo, te
contaré por qué me gustan algunos lenguajes y por qué no me gustan
esos mismos lenguajes. El criterio es el que me sale a mí, sin ninguno
más, ni más vueltas y sé que caigo en contradicciones, ya veréis que
algunos lenguajes me caen bien por lo mismo que no me gusta de
otros. En algunos de los lenguajes aquí desglosados, me he permitido
poner un poco de código para que se vea cómo luce visualmente. En fin:
no te garantizo nada, a tu discreción dejo la lectura.
</p>
<div id="outline-container-org86527c7" class="outline-2">
<h2 id="org86527c7">Motivos, ninguno</h2>
<div class="outline-text-2" id="text-org86527c7">
<p>
Aprendí a programar, no sé muy bien por qué. El caso es que aprendí y
lo utilizo para mis cosas. En mi ingenuidad inicial, pensé que la
tecnología era algo lógico, exacto, pero me encontré <i>amando y
odiando</i> como amo a las personas, sin un porqué concreto. Hay personas
que te parecen buenas, sanas, interesantes y las amas por más aristas,
pegas y defectos que la gente de tu alrededor las encuentre. Eso me
pasa a mí también con los lenguajes de programación y con muchas otras
cosas de la tecnología. Amar <i>algo</i> siempre me ha parecido raro, pero
amo programar, casi tanto como conducir una moto por una carretera de
montaña sin tráfico. Pensándolo ahora, quizá sea porque me concentro
en una actividad que requiere toda mi atención. Sobre la moto hay
quizá más adrenalina, porque también exige coordinación física y mi
integridad está en juego. Sobre la programación quizá más sublime, más
intelectual y, también, más reforzante intelectualmente.
</p>

<p>
Hace tiempo que no tengo un <i>lenguaje favorito</i>, no me merece la
pena. Cuando aprendía, iba saltando de un lenguaje a otro, el último
siempre era el candidato y pasé por muchos y muchas fases. Ahora los
voy acumulando poco a poco, cada año o cada dos años añado alguno más
a la cuenta y no veo que pueda aprender ni la mitad de los que me
llaman la atención antes de morirme. Hacer una cronología exacta de
cuáles aprendí primero y cuáles después se me hace complicado, porque
algunos aparecen y desaparecen para volver al cabo de un tiempo. No es
raro tampoco que esos lenguajes que durante el primer vistazo me
parecen <i>feos</i> o <i>raros</i>, más adelante se conviertan en uno de los que
amo, igual que me pasa con las personas. Así que voy a repasar estos
lenguajes <i>repelentes</i> que me gustan.
</p>
</div>
</div>
<div id="outline-container-org48d814b" class="outline-2">
<h2 id="org48d814b">Smalltalk</h2>
<div class="outline-text-2" id="text-org48d814b">
<p>
Supongo que alguno de vosotros esperaba que empezara por <i>Lisp</i>, por
antigüedad y porque en este <i>blog</i> creo que no hay ni una sola línea
de <i>Smalltalk</i> y sí cientos de <i>Lisp</i>. Pero en fin, os sorprenderá,
pero soy así y creo que ya no cambiaré mucho.
</p>

<p>
<i>Smalltalk</i> fue uno de esos descubrimientos intermitentes que me
apasionó durante un tiempo, pero ese enamoramiento se diluyó por la
cantidad de pegas que hay que superar con él. Mi primer contacto fue
con el <a href="https://squeak.org/">entorno Squeak</a>. Fue en un ámbito educativo y me gustó como
herramienta, especialmente con sus <i>Etoys</i> que permitían de forma muy
sencilla juguetear en el aula con gráficos y crear entornos de
simulación sencillos. El primer contacto se quedó en el <i>juguete</i>.
Más tarde, metido en la filosofía del lenguaje: <i>Todo es un objeto</i>,
comencé a programar en ciclos <i>REPL</i> utilizando sus herramientas
<i>Transcript</i> y <i>Workspace</i>.
</p>

<p>
Esto fue en una segunda mirada, en la que también descubrí las
bondades de la programación TDD<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> y me encontré escribiendo más
código en el depurador que en el <i>Browser</i>. Un lenguaje hermoso, claro
y con unos principios sencillos. <i>Todo</i> es un objeto, los
condicionales y los bucles son métodos de la clase <i>boolean</i>, los
bloques de código son objetos con los que trabaja el <i>evaluador</i>. Los
objetos los puedes modificar sobre la marcha mientras se están
ejecutando en el entorno sin que haya el más mínimo problema. Así que
puedes <i>ver</i> cómo tus clases y tus objetos van tomando forma y
ajustándolos a lo que quieres.
</p>

<p>
Sin embargo, la apariencia de <i>Squeak</i> es bastante infantil, se diseñó
para ser utilizada en ámbitos educativos para los chavales y aunque
hay de todo: <a href="https://www.croquet.io/">entornos de virtualidad 3D como <i>Croquet</i></a>, <i>webservers</i> y
muchos otros tipos de aplicaciones (emuladores, <i>game engines</i>, bases
de datos), resulta un poco frustrante programar para este entorno.
Crear una aplicación útil y cuando se la enseñas a alguien sólo se
fija en los <i>iconitos</i> de colorines infantiles.
</p>

<p>
Probé otros <i>Smalltalks</i>, algunos <i>profesionales</i>, pero el entorno
completo significaba muchos miles de euros y los libres son escasos.
<a href="https://pharo.org/">EL entorno Pharo</a> prometía, era un derivado de <i>Squeak</i> con un
aspecto más profesional y menos infantil. Curiosamente, eso que
parecía que era lo que quería era lo que me disgustaba de <i>Pharo</i>.
Las decisiones de diseño no iban hacia donde a mí me gustaba y no
cuajó. Hacer programas para mí es sencillo, me da un poco igual el
aspecto de la interfaz, normalmente suelo preferir las interfaces
interactivas, tipo <i>repelente</i>, pero la mayoría de la gente no: quiere
GUI's y botones.
</p>

<p>
Me sigue gustando <i>Smalltalk</i>, orientado a objetos puro, pero apenas
lo utilizo actualmente. Aunque me he plantado el recuperarlo para el
aula con chicos y enseñarles algo de programación con <i>Squeak</i>, en
lugar de con el <a href="https://scratch.mit.edu/">infumable <i>scratch</i></a>. No sé, lo mismo hasta aprenden a
programar de verdad en lugar de arrastrar bloques uno detrás de otro a
ver si encuentran el que hace lo que quieren.
</p>
</div>
</div>
<div id="outline-container-org751be68" class="outline-2">
<h2 id="org751be68">Lisp</h2>
<div class="outline-text-2" id="text-org751be68">
<p>
Dicen las <i>malas lenguas</i> que lo del <i>REPL</i> lo inventó <i>Lisp</i> y no soy
quién para negarlo, teniendo en cuenta que es uno de los primeros
lenguajes de programación. Este lenguaje (o alguno de sus derivados,
porque incluyo aquí también <i>Scheme</i>) lo utilizo casi a diario.
</p>

<p>
La filosofía es bastante sencilla: <i>todo es una lista</i>, las listas son
datos, las listas son código. Dicen, también <i>las malas lenguas</i>, que
<i>Lisp</i> no es un lenguaje ideal para ningún <i>nicho</i> de programación, o
ámbito de problemas. Sin embargo, con él se puede hacer cualquier
lenguaje para cualquier ámbito de programación concreto. De hecho, las
aplicaciones más exitosas que lo utilizan<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> pueden ser
consideradas como un <i>Lisp disfrazado</i> de otra cosa. Es decir,
podríamos decir que <i>Emacs</i> es un <i>Lisp disfrazado de editor</i>. A estas
alturas, creo que no hará falta decir que tengo miles de líneas
propias de código <i>Lisp</i> que corren en <i>Emacs</i> para <i>hacer mis cosas</i>,
desde este <i>blog</i>, a tomar notas, gestionar mi agenda, hacer informes.
</p>

<p>
Pero también le encuentro pegas. Especialmente a <i>Commond Lisp</i>, con
una gestión de dependencias imposible muchas veces, cualquier
aplicación que quieres pasar a alguien tiene que terminar en un
<i>contenedor</i> con todas las librerías y algo que apenas serían algunos
<i>Kb</i> de código termina ocupando decenas de <i>Mb</i>. Como en <i>Smalltalk</i>
el problema se produce cuando quiero compartir algún programa que he
hecho. A mí en mi entorno me funciona y el aspecto tampoco me preocupa
demasiado. Pero hacerlo funcionar en otro entorno y con un aspecto
«poco moderno» a la gente no le apetece probarlo... no puedes hacerte
millonario vendiendo módulos de <i>Emacs</i>.
</p>

<p>
Normalmente, suelo utilizar, o mejor dicho, me gusta más, hacer
programas interactivos, a los que enviarles comandos y acciones desde
un entorno <i>repelente</i> para trabajar. Sin embargo, me gusta ver los
resultados de modo más gráfico y eso es una de las ventajas de
<code>emacs-lisp</code>, que viene con el entorno completo. Por lo tanto, lo que
es <i>lisp</i> se me circunscribe casi exclusivamente a él. Hago mucho de
mi trabajo como psicólogo desde él: anotaciones, escritos, informes,
corrección de tests, seguimientos, estadísticas, agenda... en fin, que
para coordinarlo todo tengo que tener, además, unas 2.000 líneas de
código <code>elisp</code> propio, que me facilitan el trabajo rutinario. Sin
embargo, no puedo compartir esas herramientas de psicólogo para <i>el
psicólogo medio</i> con lo cual, me frustra a veces hablar de
herramientas con algunos compañeros y al comentarlos cómo lo hago yo,
que no me entiendan, mostrarles cómo y dado el aspecto de <i>texto
plano</i>, lo consideren arcaico. Por eso empecé a hacer una aplicación
que lo haga todo y sea capaz de hacer las cosas de manera interactiva,
pero tenga también botones y ventanas... pero no podrá ser en <i>lisp</i>.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">factorial</span> (n)
  (<span style="color: #ff79c6; font-weight: bold;">if</span> (= n 0)
      1
    (* n (factorial (- n 1)))))
</pre>
</div>
</div>
</div>
<div id="outline-container-org54edf7a" class="outline-2">
<h2 id="org54edf7a">Clojure</h2>
<div class="outline-text-2" id="text-org54edf7a">
<p>
La verdad es que comencé con <i>Clojure</i> este año. A principios de enero
<a href="https://notxor.nueva-actitud.org/2022/01/08/preparando-emacs-para-trabajar-con-clojure.html">configuré <i>Emacs</i> para trabajar con este lenguaje</a><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup> y comencé a
mirar un libro que se llama <a href="https://www.braveclojure.com/clojure-for-the-brave-and-true/"><i>Clojure for the Brave and True</i></a> y avancé
bastante rápido. No deja de ser un <i>lisp</i> aunque con algunas
idiosincrasias y corriendo sobre una máquina virtual de <i>Java</i>.
</p>

<p>
¿Me gusta <i>Clojure</i>? En general sí, pero leo a mucho exaltado hablando
de las glorias del desarrollo <i>repelente</i>, —bueno <i>REPL</i>, ya me
entendéis—, y parece que lo haya inventado <i>Clojure</i> hace dos semanas.
Y, en el fondo, está bien, pero tampoco le veo tantas ventajas sobre
el método tradicional de escribir código y probarlo (si tienes unos
<i>tests</i> a mano para hacerlo). Que por cierto, al final es lo que hacen
pero desde su propia <i>shell</i>.  Creo que dichos exaltados deben venir
del mundo «güindosero» y les daba urticaria abrir una consola de texto
hasta que encontraron <i>Clojure</i>; si no, no lo entiendo.
</p>

<p>
La ventaja que le veo a <i>Clojure</i> es que tienes al alcance toda la
inmensa librería de <i>Java</i> y puedes hacer literalmente cualquier cosa
que haga la <i>JvM</i> con un lenguaje mucho más agradable de trabajar que
el propio <i>Java</i>. Por tanto, su principal ventaja es que corre sobre
la <i>JVM</i>, puedes distribuir aplicaciones <code>jar</code>, llamar a librerías,
etc. También puede convertir el código en <code>javascript</code>, lo cual lo
hace apto también para <i>enmierdar webs</i> con un montón de código
innecesario para transmitir información.
</p>

<p>
La principal desventaja es... que corre sobre <i>JVM</i> y la carga es
lenta... me gusta que haya funciones especiales para evitar las
sobrecargas con las funciones <i>tail recursive</i>, mientras que en otros
<i>Lisp</i>, <i>Scheme</i> e incluso <i>erlang</i> te recomiendan utilizar
referencias circulares con una función auxiliar; en <i>Clojure</i> ya te
dicen que esa función auxiliar se llama <code>recur</code>. A mí me sigue
gustando más el llamar de nuevo a la función recursiva por su nombre,
puesto que utilizar otros nombres como <code>loop</code> y <code>recur</code>, me distrae un
poco de lo que hace la función, pero son gustos míos.
</p>

<p>
En resumen ¿me gusta <i>Clojure</i>? Sí. ¿Lo uso mucho? No. En general, si
necesito un <i>script</i> rápido lo más a mano que tengo es <code>bash</code>, o
incluso <i>Python</i> o, últimamente, <i>Tcl/Tk</i>, que además me permite hacer
<i>scripts</i> con ventanitas... En fin, lo mismo dentro de poco (o nunca)
se me ocurre algún proyecto donde utilizarlo.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defn factorial-reduce [n]
  (reduce * (range 1 (inc n))))
(defn factorial-loop [n]
  (loop [x n, acum 1]
    (if (&gt;= 1 x)
      acum
      (recur (dec x) (* x acum)))))
;; =&gt; user&gt; (time (factorial-loop 5))
;; =&gt; "Elapsed time: 0.134864 msecs"
;; =&gt; 120
;; =&gt; user&gt; (time (factorial-reduce 5))
;; =&gt; "Elapsed time: 0.206662 msecs"
;; =&gt; 120
</pre>
</div>

<p>
No está de más echar un vistazo a los resultados anteriores de las dos
versiones de la misma función (en cuanto a tiempos de ejecución me
refiero).
</p>
</div>
</div>
<div id="outline-container-orgcffd296" class="outline-2">
<h2 id="orgcffd296">Erlang</h2>
<div class="outline-text-2" id="text-orgcffd296">
<p>
Otro de los lenguajes <i>repelentes</i>. Además el mismo que es tachado
como <i>feo</i> por muchos y es cierto, al principio a mí también me lo
pareció. Pero luego he cambiado de opinión.  Lo que me enamoró de este
lenguaje es su capacidad para la <i>concurrencia</i>. Programar con él
consiste en levantar procesos que se comuniquen unos con otros incluso
en distintas máquinas... lo que lo hace ideal para aplicaciones en
red.
</p>

<p>
Tiene otras ventajas dada su <i>fea</i> sintaxis y la capacidad para
<i>deconstruir</i> los parámetros y variables en estructuras de datos
concretas, permite evitar muchas de las estructuras <i>condicionales</i> de
otros lenguajes de programación.
</p>

<p>
Puede hacer cosas tan vistosas como <a href="http://www.wings3d.com/">un modelador 3D</a>. O el <i>raytracer</i>
que me entretuve en hacer en los artículos, ¿quién iba a pensar que
se podía hacer un <i>raytracer</i> en /erlang?:
</p>

<ul class="org-ul">
<li><a href="https://notxor.nueva-actitud.org/2020/10/21/un-pequeno-raytracer.html">Un pequeño raytracer</a></li>
<li><a href="https://notxor.nueva-actitud.org/2020/10/24/trazando-rayos.html">La cámara de los rayos sin truenos</a></li>
<li><a href="https://notxor.nueva-actitud.org/2020/11/16/rayos-y-centellas.html">Rayos y centellas</a></li>
<li><a href="https://notxor.nueva-actitud.org/2020/11/20/material-difuso-y-correccion-gamma.html">Material difuso y corrección gamma</a></li>
<li><a href="https://notxor.nueva-actitud.org/2020/12/06/camara.html">Cámara</a></li>
</ul>

<p>
Viene también con todo un entorno de seguimiento y depuración, con sus
correspondientes <i>GUI</i>'s para que puedas apreciar mejor cómo
interactúan los procesos que has creado. Puede funcionar también en
modo interactivo o <i>repelente</i>, aunque el proceso de desarrollo
habitual que uso es el tradicional de escribir código, compilar y
pasar pruebas.
</p>

<p>
¿Me gusta <i>erlang</i>? Me encanta ¿Lo uso mucho? Pues no demasiado. Tengo
algunos <i>scripts</i> escritos en <i>erlang</i> pero no es el que más utilizo.
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">factorial</span>(0) -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span>1;
<span style="color: #50fa7b; font-weight: bold;">factorial</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>) <span style="color: #ff79c6; font-weight: bold;">when</span> <span style="color: #f8f8f2; font-weight: bold;">N</span> &gt; 0 -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span><span style="color: #f8f8f2; font-weight: bold;">N</span> * <span style="color: #8be9fd; font-style: italic;">factorial</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>-1).
</pre>
</div>
</div>
</div>
<div id="outline-container-org782eac4" class="outline-2">
<h2 id="org782eac4">Tcl/Tk</h2>
<div class="outline-text-2" id="text-org782eac4">
<p>
Creo que este lenguaje es el gran desconocido. Se inició en la
Universidad de Berkeley allá por 1988 y se desarrolló principalmente
en los laboratorios de <i>Sun</i> a la par de <i>Java</i>, pero parece que no le
hicieron la misma publicidad. Nació para ser embebido en otros
programas, principalmente escritos en <i>C</i>, pero terminó también
teniendo un desarrollo como entorno <i>REPL</i> y es famoso por su entorno
gráfico <i>Tk</i>, que en la actualidad se encuentra también portado a
otros lenguajes, además de en <i>Tcl</i>, está para <i>Python</i>, <i>Ruby</i> o
<i>Perl</i>. Es multiparadigma, tanto puedes emplear <i>POO</i>, como
programación funcional o procedural.
</p>

<p>
Por algún lado leí, que el desarrollo de <i>Tcl/Tk</i> parece una carrera
de imitación con el desarrollo de <i>Python</i>, compiándose unos a otros
de manera que lo que <i>inventa</i> uno, el otro lo <i>incorpora</i> al poco
tiempo. No sé cuánto de verdad habrá en ello, pero es cierto que me he
encontrado con una herramienta muy potente, con librerías para todo lo
que necesito. Sin embargo, su sintaxis no termina de gustarme y la
forma de gestionar los ámbitos de las variables, las variables
globales y otros detalles, me parece un poco <i>farragosa</i>.
</p>

<p>
¿Me gusta <i>Tcl/Tk</i>? Sí ¿Lo uso mucho? Pues últimamente lo estoy usando
donde antes utilizaba <i>Python</i>. Tiene cientos de librerías y se puede
hacer de todo con él... y lo noto menos pesado que <i>Python</i>.
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">factorial-recur</span> {val} {
    <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">val</span> == 0 } {
        <span style="color: #ff79c6; font-weight: bold;">return</span> 1
    } <span style="color: #ff79c6; font-weight: bold;">elseif</span> {$<span style="color: #f8f8f2; font-weight: bold;">val</span> &gt;= 1} {
        <span style="color: #ff79c6; font-weight: bold;">return</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">val</span> * [factorial-recur [<span style="color: #8be9fd; font-style: italic;">incr</span> val -1]]}]
    }
}
<span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">factorial-loop</span> {val} {
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">result</span> 1
    <span style="color: #ff79c6; font-weight: bold;">while</span> {$<span style="color: #f8f8f2; font-weight: bold;">val</span> != 1} {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">result</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">result</span> * $<span style="color: #f8f8f2; font-weight: bold;">val</span>}]
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">val</span> [<span style="color: #8be9fd; font-style: italic;">incr</span> val -1]
    }
    <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">result</span>
}
<span style="color: #6272a4;"># </span><span style="color: #6272a4;">=&gt; % time {factorial 5}
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">=&gt; 16 microseconds per iteration
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">=&gt; % time {factorial-loop 5}
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">=&gt; 13 microseconds per iteration</span>
</pre>
</div>

<p>
En el caso de <i>Tcl/Tk</i> se desempeña mejor el bucle que la recursión,
aunque no hay mucha diferencia.
</p>
</div>
</div>
<div id="outline-container-org2c7360f" class="outline-2">
<h2 id="org2c7360f">Python</h2>
<div class="outline-text-2" id="text-org2c7360f">
<p>
<i>Python</i> lo aprendí mucho antes que otros de los lenguajes cuando
estaba muy metido en la programación orientada a objetos, con
<i>Smalltalk</i> y fue agradable encontrar un lenguaje donde pudiera
emplearlo sin los problemas que habían empezado a molestarme en
<i>Squeak</i>. El caso es que se convirtió en el más usado de aquellos
tiempos y aún tengo algunas cosas hechas con él. Creo que era por la
versión 1.8.X cuando comencé a hacerle caso.
</p>

<p>
Con el tiempo comencé a cogerle un poco de ojeriza, no por el lenguaje
en sí, sino por mucho supuesto teórico que escribían cosas sobre sus
maravillas, que si la <i>introspección</i> esto, que si la <i>introspección</i>
aquello, que si la <i>flexibilidad</i>... en fin, que parecía que habían
inventado el mundo, cuando muchas de esas cosas estaban implícitas en
<i>Smalltalk</i> desde hacía décadas. Sin embargo, el lenguaje no tiene la
culpa de atraer a <i>singermornings</i> de cualquier especie.
</p>

<p>
Hubo una época donde estuve además jugueteando con él y con un editor
que <a href="https://leoeditor.com/">se llama <i>Leo</i></a>. Lo que ocurre es que, al poco de tomarme en serio
ese editor y <i>Python</i>, encontré tantas referencias a <code>org-mode</code> y
<i>Emacs</i> en las entradas de <i>blogs</i> que hablaban sobre dicho editor,
que me entró la curiosidad... y la curiosidad mató al gato, bueno al
león. Probé <i>Emacs</i> y <code>org-mode</code> y no hubo vuelta atrás. Muchas de las
cosas que utilizaba entonces en <i>Python</i> pasaron a estar implementadas
en <code>elisp</code>.
</p>

<p>
¿Me gusta <i>Python</i>? Por supuesto ¿Lo utilizo mucho? Pues cada vez
menos. En los <i>scripts</i> rápidos para línea de comandos está siendo
sustituido en mi caja de herramientas por <i>Tcl/Tk</i>. Si tengo que hacer
algo por red en plan <i>cliente-servidor</i> lo hago en <i>erlang</i>. Pero la
mayor parte de la carga de trabajo sigue descansando en <code>elisp</code> y
<i>Emacs</i>... porque algunas de las cosas que tenía implementadas en
<i>Python</i> me las encontré ya hechas en <code>org-mode</code> o en otros paquetes
del editor.
</p>
</div>
</div>
<div id="outline-container-orge95e9ab" class="outline-2">
<h2 id="orge95e9ab">El futuro</h2>
<div class="outline-text-2" id="text-orge95e9ab">
<p>
No creáis que he acabado mi periplo de lenguajes, ni mucho menos. Para
el futuro me estoy planteando el aprender <a href="https://julialang.org/"><i>julia</i></a>. También es un
lenguaje <i>repelente</i>, con su entorno para el <i>REPL</i>, quiero decir, ya
sabéis.  Promete además que es mucho más rápido que otros de estos
lenguajes <i>repelentes</i> que os he nombrado por aquí. Por lo que he
leído es incluso más rápido que <i>Python</i> con el <i>jit</i> activado o <i>C#</i>,
en algunos casos incluso más que <i>C++</i>, según las características de
algunas de las funciones del banco de pruebas, aunque en general,
siempre más lento que <i>C</i>. Me parece que promete mucho, quizá
demasiado. Cuando lo pruebe ya veremos.
</p>

<p>
Ese lenguaje me interesa, además, porque es otro de los lenguajes que
suenan para uso estadístico. En este artículo no he hablado sobre <i>R</i>,
aunque lo uso para algunas cosas, efectivamente para estadísticas. Es
un lenguaje que creo que se podría utilizar para otras cosas y no sólo
cálculos estadísticos, pero toda la literatura lo coloca en ese nicho
y no hay forma de sacarlo del hoyo. Parece que <i>julia</i> está siendo
utilizado también para cálculos estadísticos y en algunos ámbitos
parece haber desbancado a <i>R</i>. Cuando lo pruebe ya veremos.
</p>

<p>
Otra de las promesas de <i>julia</i> es la completa integración con tipos
de letra y códigos <i>UTF</i>. Otros lenguajes lo prometen también, pero al
final hay que estar haciendo conversiones más o menos explícitas entre
códigos... En fin: cuando lo pruebe ya veremos.
</p>

<p>
No he desistido tampoco de <i>Haskell</i>, llevo tiempo queriendo
aprenderlo y van cuatro intentos. Cada intento avancé más que el
anterior. Cuando creo que lo entiendo me aparece otra cosa y me pone
los conceptos patas arriba. En fin, algún día conseguiré
comprenderlo de verdad y ese día diré que soy programador de los de
verdad y no como cualquier psicólogo con ínfulas de programador.
</p>
</div>
</div>
<div id="outline-container-orga05b728" class="outline-2">
<h2 id="orga05b728">Conclusiones</h2>
<div class="outline-text-2" id="text-orga05b728">
<p>
Siento haberos dado la chapa con estas cosas, que seguramente sólo me
preocupan a mí. No encuentro <i>mi lenguaje favorito</i> y a estas alturas
tampoco creo que lo encontraré. Lo cual me hace estar más abierto a
qué debo usar para según qué cosas. Cuando tienes un martillo todo te
parecen clavos, pero en este caso en la caja de herramientas empieza a
haber un amplio muestrario de lenguajes, con varias opciones para
elegir entre los paradigmas: orientado a objetos, funcionales,
procedurales.
</p>

<p>
No quiero decir que me gusten menos los lenguajes compilados, pero me
gustan los lenguajes <i>repelentes</i>, con su <i>línea de comandos</i>
dispuesta a hacerme caso y funcionar, sin necesidad de editar ningún
fichero, ni escribir ningún programa, ni compilar nada. Pero son mis
gustos.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
El ciclo de <i>Read-Eval-Print-Loop</i> que han venido a abreviar en
<i>REPL</i> y que cuando lo leo deprisa me sale sin pensar <i>«repelente»</i>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Tests Driven Development</i> o desarrollo dirigido por pruebas,
que diríamos en cristiano.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Autocad y <i>Emacs</i>, por ejemplo.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
A estas alturas la configuración de <i>clojure</i> la he hecho sin
<i>lsp</i>. De hecho, ya no utilizo <i>lsp</i> con ningún lenguaje. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/programación/index.html">programación</a> <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/lisp/index.html">lisp</a> <a href="/tags/python/index.html">python</a> <a href="/tags/erlang/index.html">erlang</a> <a href="/tags/tcl/index.html">tcl</a> <a href="/tags/smalltalk/index.html">smalltalk</a> ]]></description>
  <category><![CDATA[programación]]></category>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[lisp]]></category>
  <category><![CDATA[python]]></category>
  <category><![CDATA[erlang]]></category>
  <category><![CDATA[tcl]]></category>
  <category><![CDATA[smalltalk]]></category>
  <link>https://notxor.nueva-actitud.org/2022/09/09/lenguajes-repelentes.html</link>
  <pubDate>Fri, 09 Sep 2022 10:30:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Programación literaria y la configuración de Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-08-31</div>
<p>
He visto infinidad de entradas en <i>blogs</i> referentes a <i>Emacs</i> que
tienen a bien, mostrar su propia configuración o <code>init.el</code>, no suelo
leerlos, me interesan más las configuraciones puntuales de
determinados paquetes, mucho más que la completa de todo el sistema.
Sin embargo, hay quien me ha pedido que haga lo mismo y publique mi
fichero de configuración de <i>Emacs</i>.  Supongo que pensarán que oculta
algo arcano, místico e inconfesable, para no iniciados, y hacer
<i>rular</i> el editor. Nada más lejos de la realidad. Sin embargo, si lo
único que quieres es <i>chafardear</i> el fichero de configuración, lo he
puesto en un repositorio de <i>Codeberg</i>. <a href="https://codeberg.org/Notxor/init-emacs">Sólo tienes que seguir el
enlace para verlo</a>.
</p>

<p>
Si alguien con curiosidad ha pinchado el enlace y queda desconcertado
porque ve que sólo hay un <code>README.org</code> con código dentro y se pregunta
que dónde está el <code>init.el</code>, la respuesta corta es <i>dentro</i> del
<code>README.org</code>, por supuesto. A la mayoría de los que lean este artículo
es posible que les resulte familiar el concepto de <i>programación
literaria</i>, pero puede ser algo nuevo para otros, así que me vais a
permitir que haga una breve explicación de lo que es.
</p>
<div id="outline-container-org4bc138a" class="outline-2">
<h2 id="org4bc138a">Programación literaria</h2>
<div class="outline-text-2" id="text-org4bc138a">
<p>
En español traducimos como <i>programación literaria</i> lo que denominó
<i>Donald E. Knuth</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> <i>literate programming</i>, que también se podría
traducir como <i>programación letrada o instruida</i>. Consiste en escribir
un documento que contiene las explicaciones del código conteniendo el
propio código. Ese documento servirá tanto como documentación del
programa como generador de la fuente entresacando el código en un
proceso que se llama <i>tangle</i>.
</p>

<p>
Es muy habitual el uso de la programación literaria en las
configuraciones de <i>Emacs</i>. Porque, al final, no es más que otra
herramienta para ordenar las ideas. Hay que tener en cuenta, que
aunque el <code>init.el</code> sea código <code>elisp</code>, en realidad no es un programa,
sino un montón de instrucciones para cargar paquetes, ajustar
variables, comportamientos, colores y zarandajas. Un programa, en
cambio, representa algo estructurado con una lógica interna. Una
configuración son ideas sin coherencia interna y, por tanto, la
programación literaria viene a dotar de alguna estructura a ese
amasijo de instrucciones.
</p>

<p>
Si se echa un vistazo a cómo se estructura el código podemos ver que
al final consiste en escribir un archivo <code>org</code> con bloques de código
del estilo:
</p>

<pre class="example" id="org064201f">
#+begin_src emacs-lisp :tangle ~/.emacs.d/init.el
 ...
#+end_src
</pre>

<p>
Para extraer luego esos bloques de código al(los) fichero(s)
correspondiente(s), basta hacer una llamada a la función
<code>org-babel~tangle</code>, bien directamente o mediante la combinación de
teclas <code>C-x C-v t</code>.
</p>

<p>
Si utilizas habitualmente este tipo de programación, un paquete que te
pude ayudar a acelerar tu flujo de trabajo es <code>auto-tangle</code>.
Básicamente hace ese trabajo por nosotros. Cada vez que guardamos el
archivo <code>org</code> con el que estamos trabajando llama por nosotros a la
función <code>org-babel-tangle</code>. Eso evita que se nos olvide... me pasa
que de vez en cuando hago alguna modificación en el código voy a ver
cómo cambia el comportamiento y no cambiaba nada... porque no había
hecho el <i>tangle</i>. Con el paquete <code>auto-tangle</code> evito esos
errores<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.
</p>
</div>
<div id="outline-container-org265105b" class="outline-3">
<h3 id="org265105b">Ventajas e inconvenientes</h3>
<div class="outline-text-3" id="text-org265105b">
<p>
La ventaja principal es que obtienes la documentación a la vez que el
código. A todos nos cuesta documentar lo que hemos hecho. Después de
haber escrito el código, nos parece una tarea pesada y aciaga, contar
lo que hace. Además, si acabamos de escribir el código, su
funcionamiento nos parece <i>autoexplicado</i> y por tanto redundante.  Nos
aburre y, por eso, solemos tener el código huérfano de documentación.
Cuando lo arrinconamos una temporada es posible que incluso no sepamos
cómo lo hicimos funcionar o por qué hicimos algo de aquella
determinada manera, que nos pareció tan clara que no contamos nada
sobre ella en la documentación.
</p>

<p>
Por otro lado, a veces arrancar un proyecto que tienes en la cabeza
cuesta un poco hasta que te centras y encuentras <i>que lo primero va
antes</i>.  Comenzar escribiendo qué queremos hacer nos puede facilitar
la tarea de iniciarlo.  Así, este estilo de programación, nos permite
poner en claro las ideas antes de escribir una sola línea de código.
</p>

<p>
Para mí, no todo son ventajas: no me acomodo a él.  Los inconvenientes
que he encontrado han sido varios, más achacables a mí que al
procedimiento en sí. Por ejemplo, programando con <i>Emacs</i>, estás
editando un archivo <code>org-mode</code>, si editas un bloque de código no
tienes activadas las herramientas de autocompletado, revisión de
sintaxis y otras ayudas para el desarrollo en el lenguaje concreto.
Vale, lo puedes editar en un <i>buffer</i> del modo apropiado para el
lenguaje pulsando <code>C-c '</code> para activar <code>org-edit-special</code>, sin embargo
nos encontraremos que sólo carga el bloque donde hayas pulsado dicha
combinación. No tienes todo el código y sus relaciones, si llamas a
otras funciones que luego estarán en el mismo archivo de código, el
análisis de sintaxis te estará lanzando errores y <i>warnings</i> que no se
corresponden con la realidad. Además, es difícil que el autocompletado
reconozca tus propias funciones, que indefectiblemente se encuentran
en otros bloques, dentro o fuera, del archivo que estás modificando.
</p>

<p>
Después de estar un tiempo utilizándolo para algunos proyectos, por
aquello de probarlo todo, he llegado a la conclusión de que no es un
estilo de trabajo al que yo me adapte bien. Y eso que a mí casi me
gusta más escribir y contar lo que estoy haciendo, que hacerlo.  Pero
no me resulta útil, me distrae y me cuesta seguir la lógica del
código.  Me obliga a tener abiertos varios <i>buffers</i> con la
información: el <code>org</code> y los fuentes generados por el <i>tangle</i>... y
claro, para aclararme también con los fuentes hay que meter
comentarios, por lo que algunas veces me encuentro escribiendo por
duplicado las mismas <i>tontás</i>.
</p>
</div>
</div>
</div>
<div id="outline-container-org5cc8ccd" class="outline-2">
<h2 id="org5cc8ccd">Inicio de <i>Emacs</i></h2>
<div class="outline-text-2" id="text-org5cc8ccd">
<p>
El archivo de inicio que genera el código enlazado al principio de
este artículo está incompleto. No sólo porque me falta repasar si me
he dejado alguno de los paquetes que tengo instalados para llamarlo de
manera específica. También porque al arrancar, pedirá confirmación de
seguridad para los <i>themes</i> utilizados. Es decir, durante el primer
inicio, solicitará confianza en el código del tema en cuestión. Una
vez otorgada, el propio <i>Emacs</i> modificará por su cuenta el <code>init.el</code>.
</p>

<p>
Al finalizar este artículo, el inicio va a cargar 116 paquetes, que en
mi máquina le lleva algo más de 4 segundos. Si tenéis una máquina más
lenta, es recomendable utilizar el modo <i>server</i> de <i>Emacs</i>. Tener el
editor corriendo en modo <i>demonio</i> se realiza con la instrucción:
</p>

<div class="org-src-container">
<pre class="src src-shell">emacs --daemon
</pre>
</div>

<p>
Para conectarse a él, en lugar de levantar desde cero todo ese
enjambre de paquetes, se llama al ejecutable <code>emacsclient</code>.  También
podemos automatizarlo un poco desde nuestra consola, para que utilice
las variables de entorno correctas. Podemos escribir en nuestro
<code>.bashrc</code>, por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #8be9fd; font-style: italic;">export</span> <span style="color: #f8f8f2; font-weight: bold;">ALTERNATE_EDITOR</span>=<span style="color: #f1fa8c;">"emacs"</span>
<span style="color: #8be9fd; font-style: italic;">export</span> <span style="color: #f8f8f2; font-weight: bold;">EDITOR</span>=<span style="color: #f1fa8c;">"emacsclient -t"</span>
<span style="color: #8be9fd; font-style: italic;">export</span> <span style="color: #f8f8f2; font-weight: bold;">VISUAL</span>=<span style="color: #f1fa8c;">"emacsclient -c -a emacs"</span>
</pre>
</div>

<p>
O si estás utilizando <code>fish</code>:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #8be9fd; font-style: italic;">set</span> ALTERNATE_EDITOR <span style="color: #f1fa8c;">"emacs"</span>
<span style="color: #8be9fd; font-style: italic;">set</span> EDITOR <span style="color: #f1fa8c;">"emacsclient -t"</span>
<span style="color: #8be9fd; font-style: italic;">set</span> VISUAL <span style="color: #f1fa8c;">"emacsclient -c -a emacs"</span>
</pre>
</div>

<p>
Muchas aplicaciones utilizan la variable de entorno <code>EDITOR</code>, para
abrir un editor, valga la <i>rebuznancia</i>, en consola en modo texto (por
eso la opción <code>-t</code>) y <code>VISUAL</code> para lanzar un editor en modo ventana,
esa es la opción <code>-c</code>. La coletilla <code>-a emacs</code> le dice que utilice, si
no puede llamar a <code>emacsclient</code> el comando habitual de <code>emacs</code> como
editor alternativo. Por ejemplo, si utilizas <code>fish</code> como <i>shell</i>, al
pulsar <code>M-e</code> (o <code>Alt-E</code>, si lo prefieres nombrar así), llamará a
<code>VISUAL</code>.  O utilizando <code>git</code> desde línea de comandos, cuando solicita
que escribas un mensaje para el <i>commit</i>, llama a <code>EDITOR</code>.
</p>
</div>
</div>
<div id="outline-container-orgf029dd8" class="outline-2">
<h2 id="orgf029dd8">Conclusión</h2>
<div class="outline-text-2" id="text-orgf029dd8">
<p>
Compartiendo el <code>init.el</code> no creo que aporte nada especial. El hacerlo
con <i>programación literaria</i>, siguiendo un poco las modas o costumbres
entre los usuarios de <i>Emacs</i> es sólo para tener algún motivo más para
escribir este artículo. Quizá el tema de la <i>programación literaria</i>
merezca más detenimiento o una explicación más larga. Ya me lo diréis.
</p>

<p>
Por último, algunos se quejan de que configuraciones complejas o con
cientos de paquetes, como es mi caso, tardan mucho es máquinas menos
potentes. Por eso añadí el apartado de <i>Inicio de Emacs</i>, con la
esperanza de que le sea útil a alguien.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Sí, el autor de <i>TeX</i>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Hasta que te olvidas de guardar los cambios a disco, que
estarás en las mismas. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/programación/index.html">programación</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[programación]]></category>
  <link>https://notxor.nueva-actitud.org/2022/08/31/programacion-literaria-y-la-configuracion-de-emacs.html</link>
  <pubDate>Wed, 31 Aug 2022 09:36:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[El mundo de las notas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-08-24</div>
<p>
Cuando digo <i>el mundo de las notas</i>...  No, no me refiero a las
calificaciones escolares. Me estoy refiriendo a lo complicado que es
tener un sistema coherente para tomar notas y apuntes con un ordenador
por medio. Llevo tanto tiempo intentando encontrar un sistema de notas
que satisfaga todas mis necesidades que ya he desesperado. Me he
planteado que voy a tener que hacerlo yo, pero antes os quiero
presentar el que estoy utilizando en estos momentos: <code>zetteldeft</code>.
</p>

<p>
Para ponernos en antecedentes, en el ejercicio de la psicología
clínica tengo que tomar muchas notas y, también, en algunos casos
generar documentos a partir de ellas. No hay un formato homogéneo,
algunas de las anotaciones tienen forma de texto, otras de tabla
(registros de conducta, índice de anotaciones, resultados de <i>tests</i>
psicológicos etc.), otras de gráfico (perfiles psicológicos,
familiogramas), aunque la mayoría de las anotaciones son de texto.
Pero el decir que son <i>de texto</i> es también resumir mucho, dentro de
estas también las hay de muchos tipos: objetivos, tareas, resumen de
sesión, etc. Además algunas de las anotaciones me gustaría que
estuvieran cifradas. Como digo, he probado varios sistemas, sobre los
mejores candidatos ya he hablado: <a href="https://notxor.nueva-actitud.org/2020/07/17/tomar-notas-con-org-roam.html">sobre <code>org-roam</code> una</a> y <a href="https://notxor.nueva-actitud.org/2020/10/29/org-roam-en-modo-servidor.html">dos veces</a> y
sobre <a href="https://notxor.nueva-actitud.org/2021/11/23/tiddlywiki.html">TiddlyWiki una</a> y <a href="https://notxor.nueva-actitud.org/2021/12/03/tiddlywiki-y-emacs.html">dos veces</a> también. En este artículo, vuelvo a
hablar de <i>Zettelkasten</i> y cómo funciona... aunque con otro paquete de
toma de notas sobre <i>Emacs</i>: <code>zetteldeft</code>.
</p>

<p>
Quizá primero deba explicar un poco más por qué no terminan de
convencerme las dos herramientas que he mencionado y anticipar que, la
que presento hoy por primera vez en el <i>blog</i>, tampoco termina de
ajustarse a lo que quiero, pero es más sencilla. Y... si no me sirve
(del todo) tampoco ¿por qué la comento?<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> Muy sencillo, la
herramienta no se ajusta a <i>todo</i> lo que <i>yo</i> necesito, pero a otro
usuario con otras necesidades le puede servir. Quizá, también debería
explicar un poco más qué hago yo con las notas y cuál es mi proceso:
</p>

<ol class="org-ol">
<li>Las notas de una sesión o de una conferencia o de lo que sea, las
tomo siempre <i>a mano</i> con un buen cuaderno y un buen bolígrafo.  Si
lo hago con el ordenador por medio, seguro que me pierdo algo
mientras pienso qué pulsación de teclas debo utilizar, qué programa
lanzar, etc. Para mí, es un <i>distractor</i> más que una herramienta.</li>
<li>La mayoría de las notas, en multitud de ocasiones, se pueden quedar
en el cuaderno, porque son cosas ya sabidas, o que no me aportan
nada, o fáciles de encontrar con una mínima búsqueda.</li>
<li>Las que pasan al sistema de notas suelen escribirse una vez. Es muy
raro que haya que editarlas. Por lo tanto, se leen muchas más veces
de lo que se escriben y por tanto tiene que ser fácil leerlas: para
eso hay que encontrarlas primero, así que el sistema de búsqueda
también es importante.</li>
<li>Alguna información de esas notas, porque atañen a datos personales
o estados de salud de personas reales, debe guardarse cifrada.
Hasta ahora puedo cifrar archivos completos, pero así pierdo la
capacidad de que unas notas se relacionen con otras notas con las
que debería mantener <i>enlace</i>. Necesitaría que se pudiera
fácilmente cifrar el contenido de la nota y mantener abiertos los
enlaces y etiquetas para que entre en las búsquedas.</li>
<li>Algunas anotaciones son una tabla y/o un gráfico. Hasta ahora me
estoy apañado bien con las tablas de <code>org-mode</code> y muchos gráficos
los puedo gestionar en <code>svg</code>.</li>
</ol>

<p>
Mis conclusiones hasta ahora, que ya he tardado, es que he comprendido
que el sistema <i>Zettelkasten</i> es un método magnífico para tomar notas
en un ámbito académico o de investigación, con el objeto de relacionar
ideas y generar así conocimiento. Yo lo uso para otro fin, y ya sé que
no es el objeto para el que fue creado, pero lo estoy usando para
<i>investigar</i>, si lo queréis llamar así, cómo piensa y cómo actúa una
persona, con el objetivo de comprenderla y poder ayudarla.
</p>

<p>
Las aplicaciones como <code>org-roam</code> y otras similares basan su <i>fuerza</i>
en una representación gráfica de las relaciones entre notas, que queda
muy <i>molona</i>, pero que a mí no me aporta nada y establece dependencias
a <i>bases de datos</i> y <code>javascript</code> que no necesito.
</p>

<p>
No tiene que ser tan complicado: el sistema básico funcionaba con
hojas de papel con un procedimiento de numeración que las enlazaba. Si
ves una nota marcada con el número <code>11b2</code> puedes estar seguro que hay
una tarjeta <code>11b</code>, con la que está enlazada y también una tarjeta
<code>11</code>, con la que estaría enlazada la <code>11b</code>. No es necesario mencionar
la numeración <i>backlink</i>, va implícita en el modo de numerar. Este
sistema de numeración es <i>lógica humana</i>, no computacional. En un
ordenador hay que forzar dicho enlace. Por otro lado, el sistema tiene
otras tarjetas cuyo único fin es contener un listado de referencias a
otras notas sobre algún determinado aspecto. Esto se puede suplir, y
se ha suplido, en los sistemas informáticos implementando los <i>tags</i>.
</p>

<p>
Pero me estoy enrollando mucho, vamos al lío.
</p>
<div id="outline-container-org9a17c80" class="outline-2">
<h2 id="org9a17c80">El sistema de notas <code>deft</code></h2>
<div class="outline-text-2" id="text-org9a17c80">
<p>
El paquete <code>deft</code> gestiona notas en un directorio. Puede utilizar tres
formatos de fichero <code>markdown</code>, <code>txt</code> y <code>org</code>. Al utilizarlo llamando
a <code>deft</code> muestra un <i>buffer</i> con una lista de las notas que tenemos en
el sistema, es decir, cualquier archivo con esas extensiones que se
encuentren en el directorio configurado<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.
</p>


<figure id="org81ce83c">
<img src="./imagenes/Captura_deft.png" alt="Captura_deft.png">

</figure>

<p>
Podemos filtrar las entradas escribiendo un filtro, valga la
<i>rebuznancia</i>:
</p>


<figure id="orga7c7a4d">
<img src="./imagenes/Captura_deft-filtro.png" alt="Captura_deft-filtro.png">

</figure>

<p>
Hay distintas funciones de búsqueda y configuraciones para ajustarlo a
tus necesidades, como seleccionar el formato del título o del fichero
cuando se crea una nota nueva, etc. Pero eso lo dejo a tu discreción,
en la <i>web</i> encontrarás mucha más información y siempre te puedes
ayudar con <code>apropos</code> y las opciones que se pueden configurar para
averiguar qué hace cada variable.
</p>

<p>
Para instalarlo y configurarlo, en mi <code>init.el</code> tengo el siguiente
código:
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> deft
<span style="color: #8be9fd; font-style: italic;">:ensure</span> t
<span style="color: #8be9fd; font-style: italic;">:bind</span> (<span style="color: #f1fa8c;">"&lt;f5&gt;"</span> . deft)
<span style="color: #8be9fd; font-style: italic;">:commands</span> (deft)
<span style="color: #8be9fd; font-style: italic;">:config</span> (<span style="color: #ff79c6; font-weight: bold;">setq</span> deft-directory <span style="color: #f1fa8c;">"~/Nextcloud/Notes"</span>
              deft-extensions '(<span style="color: #f1fa8c;">"org"</span> <span style="color: #f1fa8c;">"md"</span> <span style="color: #f1fa8c;">"txt"</span>)
              deft-default-extension <span style="color: #f1fa8c;">"org"</span>
              deft-use-filename-as-title t))
</pre>
</div>

<p>
Lo llamo pulsando <code>F5</code>. La configuración además utiliza el directorio
de notas con un directorio sincronizado por <code>Nextcloud</code>. Después se
establecen las extensiones de los ficheros de notas que debe leer de
dicho directorio. También se establece la extensión por defecto,
cuando se crea una nueva nota.  <code>deft</code> reconocerá como notas todos los
archivos con esas extensiones que se encuentre en el directorio
establecido<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>. La última opción es utilizar como título el nombre
del fichero. Otra opción es dejarlo a <code>nil</code> y obligar a <code>deft</code> a leer
la primera línea del archivo, que será tomada como el título para la
lista de notas.
</p>

<p>
Hay, como digo, muchas más opciones para la herramienta. Sin embargo,
en nuestro caso, no vamos a profundizar mucho más sobre él, es
sencillo de comprender y muy fácil de configurar usar. En su lugar voy
a comentar un problema, que me encontré, por mis propias manías, y
cómo lo solucioné, por si a alguien más le es útil.
</p>

<p>
El problema que se me plantaba es que soy de tener varios directorios
con notas. Tengo la tendencia, o costumbre, de poner en mis
<i>proyectos</i> un directorio de <i>notas</i> y claro, esta herramienta sólo
trabaja sobre un directorio, uno en toda su unicidad.  Lo que está
bien si sólo tienes un cajón de notas en lugar de decenas como tengo
yo.  Por ello, al final me hice la siguiente función que me facilita
cambiar de directorio de notas sobre la marcha. La pongo aquí, por si
os sirve de algo:
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">cambio-deft-dir</span> (dir)
  <span style="color: #6272a4;">"Cambiar de directorio Deft."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span> <span style="color: #f1fa8c;">"D"</span>)

  (message (format <span style="color: #f1fa8c;">"Se cambia def-directory a: %s"</span> dir))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> deft-directory (format <span style="color: #f1fa8c;">"%s"</span> dir))
  (deft-refresh))
</pre>
</div>

<p>
Es una función muy sencilla: pregunta por un directorio, se lo
facilitamos y establece la variable haciendo un refrescado después por
si hay algún <i>buffer</i> de <code>deft</code> abierto, para que se actualice y
cambie al compendio nuevo de notas. Ten en cuenta que el refresco, si
cambias a un directorio con muchas —pero que muchas— notas, puede
tardar un rato, apenas unos segundos, pero hay que tener paciencia.
</p>
</div>
</div>
<div id="outline-container-org6aaff88" class="outline-2">
<h2 id="org6aaff88">El paquete <code>zetteldeft</code></h2>
<div class="outline-text-2" id="text-org6aaff88">
<p>
El paquete <code>zetteldeft</code> lo que hace es añadir a <code>deft</code> las
características fundamentales del método <i>Zettelkasten</i><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>. Ya las
comenté más arriba, pero para centrarnos, concretamente los conceptos
clave que se han tenido en cuenta son:
</p>

<ol class="org-ol">
<li>Una idea en cada nota.</li>
<li>Conectar diferentes ideas en diferentes notas.</li>
<li>O mantener un conjunto de enlaces a otras notas.</li>
</ol>

<p>
Con ese resumen de tres puntos se monta todo el sistema sobre tarjetas
en papel, así que no hace falta meterle más rollos al <i>chismático</i>. Y
esos son los tres <i>puntos</i> que le añade el paquete <code>zetteldeft</code> a
<code>deft</code>. Este paquete es lo más sencillo y completo que he encontrado
hasta ahora.
</p>
</div>
<div id="outline-container-orgeca0d04" class="outline-3">
<h3 id="orgeca0d04">Instalación</h3>
<div class="outline-text-3" id="text-orgeca0d04">
<p>
Como siempre, lo primero va antes. La instalación es sencilla:
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> zetteldeft
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:after</span> deft
  <span style="color: #8be9fd; font-style: italic;">:config</span> (zetteldeft-set-classic-keybindings))
</pre>
</div>

<p>
Creo que el código es bastante claro y fácil de entender, así que no
le daré demasiadas vueltas. Sólo recordar que <code>deft</code> debe instalarse
antes y tiene que estar instalado cuando se instale el paquete.
</p>

<p>
Se puede dejar todo como viene por defecto, pero en mi caso, también
he añadido un sufijo a la cabecera cuando se crea una nota nueva, para
recordarme que también puedo utilizar <i>etiquetas</i> y he añadido la
siguiente línea en el <code>init.el</code>, justo después del código de
instalación.
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> zetteldeft-title-suffix <span style="color: #f1fa8c;">"\n# Tags #"</span>)
</pre>
</div>

<p>
Al utilizar la configuración clásica de teclas, se activan los
siguientes comandos. No pongo todos, pero sí los que más utilizo. La
combinación básica es <code>C-c d</code>.
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">tecla</th>
<th scope="col" class="org-left">comando</th>
<th scope="col" class="org-left">Acción</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>n</code></td>
<td class="org-left"><code>zetteldeft-new-file</code></td>
<td class="org-left">Crear una nota nueva</td>
</tr>

<tr>
<td class="org-left"><code>N</code></td>
<td class="org-left"><code>zetteldeft-new-file-and-link</code></td>
<td class="org-left">Crea una nota nueva e inserta enlace</td>
</tr>

<tr>
<td class="org-left"><code>B</code></td>
<td class="org-left"><code>zetteldeft-new-file-and-backlink</code></td>
<td class="org-left">Crea nota nueva e inserta enlace a la actual</td>
</tr>

<tr>
<td class="org-left"><code>b</code></td>
<td class="org-left"><code>zetteldeft-backlink-add</code></td>
<td class="org-left">Inserta un <i>backlink</i> en la nota</td>
</tr>

<tr>
<td class="org-left"><code>i</code></td>
<td class="org-left"><code>zetteldeft-find-file-id-insert</code></td>
<td class="org-left">Inserta enlace</td>
</tr>

<tr>
<td class="org-left"><code>I</code></td>
<td class="org-left"><code>zetteldeft-find-file-full-title-insert</code></td>
<td class="org-left">Inserta enlace con título completo</td>
</tr>

<tr>
<td class="org-left"><code>f</code></td>
<td class="org-left"><code>zetteldeft-follow-link</code></td>
<td class="org-left">Abre la nota enlazada</td>
</tr>

<tr>
<td class="org-left"><code>o</code></td>
<td class="org-left"><code>zetteldeft-find-file</code></td>
<td class="org-left">Abrir una nota<sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup></td>
</tr>

<tr>
<td class="org-left"><code>T</code></td>
<td class="org-left"><code>zetteldeft-tag-buffer</code></td>
<td class="org-left">Abre un <i>buffer</i> con una lista de etiquetas</td>
</tr>

<tr>
<td class="org-left"><code>t</code></td>
<td class="org-left"><code>zetteldeft-avy-tag-search</code></td>
<td class="org-left">Busca notas con una etiqueta</td>
</tr>

<tr>
<td class="org-left"><code>#</code></td>
<td class="org-left"><code>zetteldeft-tag-insert</code></td>
<td class="org-left">Inserta una etiqueta</td>
</tr>

<tr>
<td class="org-left"><code>r</code></td>
<td class="org-left"><code>zetteldeft-file-rename</code></td>
<td class="org-left">Renombra el fichero de una nota</td>
</tr>
</tbody>
</table>

<p>
Cuando queremos crear un archivo de nota nuevo, utilizando la
combinación <code>C-c d n</code> nos pregunta por un título de la nota. Al pulsar
<code>&lt;RET&gt;</code> generará un archivo con la fecha y hora en formato
<code>%Y-%m-%d-%H%M</code> y el título que le hayamos facilitado. Cuando
insertemos un enlace, por defecto, utilizará ese formato de fecha para
referirse a la nota y mostrará algo parecido a <code>§2020-04-17-161</code>,
siempre precedido, como se puede observar de un carácter <code>§</code>. Dicho
carácter es configurable y se puede cambiar por cualquier otro, pero
no me desagrada y lo he dejado tal cual. He leído por la <i>web</i> que
algunos usuario lo cambian por otro carácter que puedan escribir ellos
fácilmente. A mí no me parece difícil pulsar <code>AltGr-W</code><sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup>.
</p>

<p>
Como decía, el sistema desarrollado y utilizado por <i>Niklas Luhmann</i>
durante toda su carrera no tiene ningún método gráfico al uso, a no
ser que te pongas a dibujar en un papel, tarjeta a tarjeta uniéndolas
con líneas. Pero la informática nos permite hacerlo de manera
<i>automágica</i>, y sí, con este sistema también se puede obtener una
visualización gráfica del mismo, pero de forma indirecta. Si tienes
instalado <code>graphviz</code> puedes llamar al comando
<code>zetteldeft-org-graph-search</code>.  Dicho comando pide una nota desde la
que se comenzará el dibujo y creará un bloque de código tal que:
</p>

<pre class="example" id="org332f1a7">
#+begin_src dot :file ./graph.pdf :cmdline -Kfdp -Tpdf
  graph {
    ...
  }
#+end_src
</pre>

<p>
una vez que lo genera tienes la oportunidad de modificarlo y ponerlo
bonito. Cuando lo he usado he cambiado algunos parámetros, como la
salida, que prefiero que sea a <code>svg</code>. Pero eso es una cuestión de
gustos. No suelo hacer mucho caso de las gráficas de ese estilo, ni
siquiera a los <i>mapas mentales</i> que me hacía hace un tiempo... al
final no me aportan nada y tengo la tendencia a ver relaciones que no
hay cuando algo está dibujado cerca de otra cosa. Muchas veces hay
cosas juntas que se acomodan por razones gráficas, no conceptuales y
eso me distrae, prefiero tener el <i>mapa</i> en la cabeza y no en papel, a
no ser que lo que represente el papel esté a escala del espacio real,
pero del espacio real, no del espacio conceptual.
</p>
</div>
</div>
<div id="outline-container-orgb290f94" class="outline-3">
<h3 id="orgb290f94">Etiquetas</h3>
<div class="outline-text-3" id="text-orgb290f94">
<p>
Hasta ahora he hablado de los dos primeros pilares del método
<i>Zettelkasten</i>: las notas atómicas de sólo un tema por <i>tarjeta</i> y la
interrelación entre las tarjetas. Sólo nos falta conseguir nuestras
listas índices de tarjetas relacionadas por algún motivo. Para esto el
sistema provee las <i>etiquetas</i> o <i>tags</i>. Una etiqueta comienza por un
carácter <code>#</code>. Al escribir <i>tags</i> en nuestras notas podemos agruparlas,
pero no tengáis prisa por poner etiquetas. Poner una etiqueta es un
arma de doble filo. Las etiquetas sirven para agrupar cosas
semejantes, pero son el origen también de los prejuicios y dificultan
que pienses sin esos prejuicios sobre cualquier tema. En tu mente,
cualquier cosa se convierte en su etiqueta.
</p>

<p>
Sin más elucubraciones, si utilizamos la combinación <code>C-c d T</code> o el
comando <code>zetteldeft-tag-buffer</code>, nos abre el siguiente <i>buffer</i>:
</p>


<figure id="orga56a220">
<img src="./imagenes/Captura_lista-etiquetas.png" alt="Captura_lista-etiquetas.png">

</figure>

<p>
Hay que tener mucho cuidado con la combinación de teclas <code>C-c d</code>,
porque <code>C-c C-d</code> en <code>deft</code> se utiliza para borrar una nota, así que si
estás en el <i>buffer</i> <code>deft</code>, ten cuidado con lo que pulsas.
Afortunadamente, pregunta si realmente queremos borrarlo y podemos
reaccionar. El que avisa no es traidor, es <i>avisador</i>.
</p>

<p>
Para seleccionar una etiqueta podemos utilizar la combinación <code>C-c d
t</code> o el comando <code>zetteldeft-avy-tag-search</code>, que utiliza el modo <code>avy</code>
para saltar directamente mediante letras marcadas por etiquetas en
rojo:
</p>


<figure id="orgfd6c4a1">
<img src="./imagenes/Captura_lista-salto.png" alt="Captura_lista-salto.png">

</figure>

<p>
Si lo que estamos buscando es la etiqueta <code>#customize</code>, sólo tenemos
que pulsar la tecla <code>a</code> para abrir una lista de notas con dicha
etiqueta.
</p>


<figure id="orgf770122">
<img src="./imagenes/Captura_filtro-etiqueta.png" alt="Captura_filtro-etiqueta.png">

</figure>

<p>
Otra opción es abrir <code>deft</code> y teclear la palabra que estemos
buscando. Por ejemplo:
</p>


<figure id="orgcd4ef5d">
<img src="./imagenes/Captura_buscar-sin-etiqueta.png" alt="Captura_buscar-sin-etiqueta.png">

</figure>

<p>
para conseguir la vista anterior, he tecleado <code>custom</code> en el <i>buffer</i>
<code>deft</code>. Al ir sin el símbolo <code>#</code> encuentra no sólo aquellas notas que
tengan la etiqueta <code>customize</code>, sino también todas aquellas donde
dicha cadena esté presente. Como podéis suponer, el utilizar etiquetas
con otros caracteres especiales que no sea <code>#</code> pueden también buscarse
con este método y nos abre el abanico de tener diferentes tipos de
etiquetas.
</p>
</div>
</div>
</div>
<div id="outline-container-orgddd391a" class="outline-2">
<h2 id="orgddd391a">Conclusiones</h2>
<div class="outline-text-2" id="text-orgddd391a">
<p>
El sistema de tomar notas <i>Zettelkasten</i> es sencillo y simple. Pero
para funcionar necesita constancia. Su autor dedicaba varias horas de
su trabajo, diariamente, para mantenerlo: hacer anotaciones, enlazar
unas notas con otras, hacer listas de notas relacionadas,
almacenarlas, ordenarlas... Cuando escribía algún artículo o libro las
consultaba, seguía sus enlaces, sus referencias y le eran de utilidad.
Pero es un trabajo arduo. Claro, que su sistema estaba montado en
papel y los ordenadores nos sirven de ayuda... pero veo muchas pajas
mentales en sistemas que pretenden implementarlo, más preocupados de
la vistosidad que de la utilidad.
</p>

<p>
Para mí <code>zetteldeft</code> es la implementación completa y sencilla de un
método sencillo y completo para tomar notas, y que funciona
perfectamente y sin aspavientos. Me permite tener mis anotaciones y
además, como soy así de especial, mis anotaciones por proyecto,
gracias a la función que puse más arriba. Antes he utilizado otros
sistemas, como el propio <code>deft</code> u <code>org-roam</code>, en algunos casos he
convertido las notas para adaptarlas a <code>zetteldeft</code>, en otros me he
dejado llevar por la holgazanería y las he dejado como
estaban... sobre todo si no las necesito para el trabajo diario.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Seguro que alguno ya se lo estará preguntando.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Por defecto es <code>~/.deft</code>
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
También se le puede decir que recorra recursivamente
subdirectorios, si las tenemos separadas de tal manera. 
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ya he hablado sobre el método en cuestión y hay mucha
información mucho más completa y mejor explicado de lo que lo puedo
hacer yo.
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Funciona como el comando <code>find-file</code>, pero sólo busca en el
directorio de notas. 
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
¡Ojo! <code>AltGr-W</code> que es <code>§</code>, no <code>AltGr-w</code>, que es <code>ſ</code>. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/zettelkasten/index.html">zettelkasten</a> <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/deft/index.html">deft</a> <a href="/tags/zetteldeft/index.html">zetteldeft</a> ]]></description>
  <category><![CDATA[zettelkasten]]></category>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[deft]]></category>
  <category><![CDATA[zetteldeft]]></category>
  <link>https://notxor.nueva-actitud.org/2022/08/24/el-mundo-de-las-notas.html</link>
  <pubDate>Wed, 24 Aug 2022 00:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Codificación en base64]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-08-03</div>
<p>
Una de las cosas que siempre me han llamado la atención es la
capacidad de convertir datos binarios a cadenas de texto. Lo vemos
constantemente en el correo electrónico<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, o en cómo se guardan
las claves de encriptado. Ha habido varios sistemas para convertir
datos binarios en cadenas. La idea es poder trasmitir esa información
a través de la red sin las dificultades que plantearía el enviar datos
binarios que, seguramente, contendrán valores especiales para la
conexión, como el de fin de fichero o fin de transmisión. Eso
provocaría una interrupción y no se finalizaría el traspaso de los
datos de un sitio a otro.
</p>

<p>
El asunto es que algunas veces, incluso el texto plano puede contener
datos binarios. Recordemos que los sistemas se inventaron para
transmitir ASCII puro y el UTF se les puede indigestar. Por ejemplo,
si queremos transmitir el siguiente texto:
</p>

<blockquote>
<p>
Esto es un texto de prueba. No tiene ninguna importancia lo que
ponga, pero necesito escribir algunos caracteres especiales. Pueden
ser los caracteres acentuados y letras como la ñ (Ñ), o la ç (Ç). O
las áéíóú àèìòù äëïöü.
</p>
</blockquote>

<p>
Si quiero enviar esto directamente por una conexión es posible que
tenga algún signo indigesto para el <i>socket</i>. Para convertirlo en algo
más digerible tengo dos opciones. La primera, y más a mano, es
seleccionar el texto y llamar a la función de <i>Emacs</i>
<code>base64-encode-region</code> y me devolverá una cadena como la siguiente:
</p>

<pre class="example" id="org94fadda">
RXN0byBlcyB1biB0ZXh0byBkZSBwcnVlYmEuIE5vIHRpZW5lIG5pbmd1bmEgaW1wb3J0YW5jaWEg
bG8gcXVlCnBvbmdhLCBwZXJvIG5lY2VzaXRvIGVzY3JpYmlyIGFsZ3Vub3MgY2FyYWN0ZXJlcyBl
c3BlY2lhbGVzLiBQdWVkZW4Kc2VyIGxvcyBjYXJhY3RlcmVzIGFjZW50dWFkb3MgeSBsZXRyYXMg
Y29tbyBsYSDxICjRKSwgbyBsYSDnICjHKS4gTwpsYXMg4ent8/og4Ojs8vkg5Ovv9vwu
</pre>

<p>
Éste método tiene un inconveniente y es que los caracteres <i>multibyte</i>
que se manejan en <i>unicode</i> no los traga bien, se le indigestan. Si
intentamos utilizar ese tipo de caracteres, por ejemplo los del
Esperanto contenidos en <i>eĥoŝanĝo ĉiuĵaŭde</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>, no podría con
ellos.
</p>

<p>
La otra alternativa es guardar el texto en un fichero y llamar al
comando del sistema <code>base64</code>, ya que lo provee el propio sistema
operativo, tiene más cuidado con los caracteres <i>unicode</i>. Para la
demostración he añadido la expresión anterior al final del texto, por
lo que quedará como:
</p>

<blockquote>
<p>
Esto es un texto de prueba. No tiene ninguna importancia lo que
ponga, pero necesito escribir algunos caracteres especiales. Pueden
ser los caracteres acentuados y letras como la ñ (Ñ), o la ç (Ç). O
las áéíóú àèìòù äëïöü. «Eĥoŝanĝo ĉiuĵaŭde»
</p>
</blockquote>

<p>
La operación es sencilla:
</p>

<pre class="example" id="orgab46524">
$ base64 texto-plano.txt 
RXN0byBlcyB1biB0ZXh0byBkZSBwcnVlYmEuIE5vIHRpZW5lIG5pbmd1bmEgaW1wb3J0YW5jaWEg
bG8gcXVlCnBvbmdhLCBwZXJvIG5lY2VzaXRvIGVzY3JpYmlyIGFsZ3Vub3MgY2FyYWN0ZXJlcyBl
c3BlY2lhbGVzLiBQdWVkZW4Kc2VyIGxvcyBjYXJhY3RlcmVzIGFjZW50dWFkb3MgeSBsZXRyYXMg
Y29tbyBsYSDDsSAow5EpLCBvIGxhIMOnICjDhykuIE8KbGFzIMOhw6nDrcOzw7ogw6DDqMOsw7LD
uSDDpMOrw6/DtsO8LiDCq0XEpW/FnWFuxJ1vIMSJaXXEtWHFrWRlwrsK
</pre>

<p>
El comando es sencillo, le pasamos un nombre de fichero y devuelve una
cadena con el contenido convertido a <code>base64</code>. Si quieres guardarlo en
otro archivo tienes que aplicar un poco del <i>conocimiento fontanero</i>
propio de Unix/Linux.
</p>
<div id="outline-container-org5546479" class="outline-2">
<h2 id="org5546479">¿Cómo funciona base64?</h2>
<div class="outline-text-2" id="text-org5546479">
<p>
En el trasfondo de <code>base64</code> está la conversión de <i>bytes</i> de 8 <i>bits</i>
en grupos de 6 <i>bits</i> de tal manera que se pueden utilizar los
caracteres de <code>[A-Z][a-z][0-9][+/]</code>, es decir:
</p>

<pre class="example" id="org3db1aa8">
ABCDEFGHIJKLMNOPQRSTUWXYZabcdefghijklmnopqrstuwxyz0123456789+/
</pre>

<p>
Es decir, tomando un valor de 6 <i>bits</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> como índice de la cadena
anterior.
</p>

<p>
Hay que señalar que hay varios sistemas <code>base64</code>. La totalidad, o casi
la totalidad coinciden en la utilización del abecedario en mayúsculas,
en minúsculas y los números. Para completar el número de 64 se deben
emplear otros dos caracteres. La mayoría de los sistemas utilizan el +
y la barra /, pero puedes encontrar que utilicen otros.
</p>

<p>
También se utilizan otros caracteres especiales, como por ejemplo el
signo <code>=</code>, que se utiliza para rellenar espacios si la conversión no
es congruente al pasar de 8 a 6 bits y debemos añadir <i>bits</i>. Los
<i>bits</i> que se añaden al final son ceros, pero marcamos en la cadena
final cuántos ceros hemos añadido con uno o dos signos de igual:
</p>

<pre class="example" id="orgb9db99e">
- Hola mundo --&gt;  SG9sYSBtdW5kbw==
- Hola mund  --&gt;  SG9sYSBtdW5k
- Hola mun   --&gt;  SG9sYSBtdW4=
</pre>

<p>
Otro aspecto a tener en cuenta son los rellenos. En el código se hacen
añadiendo ceros al final<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>. Por ejemplo, la cadena <i>Hola</i> podemos
descomponerla en sus correspondientes <i>bits</i>:
</p>

<pre class="example" id="orgbfa3fb4">
Hola         --&gt; 01001000011011110110110001100001
base64(Hola) --&gt; SG9sYQ==
Hol          --&gt; 010010000110111101101100
base64(Hol)  --&gt; SG9s
Ho           --&gt; 0100100001101111
base64(Ho)   --&gt; SG8=
H            --&gt; 01001000
base64(H)    --&gt; SA==
</pre>

<p>
El proceso consiste en deshacer los octetos y convertirlos en
sextetos, tal que así:
</p>

<pre class="example" id="orgaf5084d">
   48 (H)   6f (o)   6c (l)   61 (a)
  01001000 01101111 01101100 01100001

  010010-000110-111101-101100-011000-01(00 00)
     S      G      9      s      Y    Q =  =
--------------------------------------------------
   48 (H)   6f (o)   6c (l)
  01001000 01101111 01101100

  010010-000110-111101-101100
     S      G      9      s
--------------------------------------------------
   48 (H)   6f (o)
  01001000 01101111

  010010-000110-1111(00)
     S      G     8  =
--------------------------------------------------
   48 (H)
  01001000

  010010-00(00 00)
     S   A  =  =
</pre>

<p>
En algunos sistemas es obligatorio marcar los ceros añadidos (2 ó 4)
con uno o dos caracteres <code>=</code> respectivamente al final de la cadena
generada. Sin embargo, es una pista importante a la hora de
decodificar la cadena para devolverlo a binario, saber cuántos ceros
debemos quitar del final.
</p>

<p>
La tabla de conversión sería la siguiente:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<tbody>
<tr>
<td class="org-left">A 000000</td>
<td class="org-left">B 000001</td>
<td class="org-left">C 000010</td>
<td class="org-left">D 000011</td>
<td class="org-left">E 000100</td>
<td class="org-left">F 000101</td>
<td class="org-left">G 000110</td>
<td class="org-left">H 000111</td>
</tr>

<tr>
<td class="org-left">I 001000</td>
<td class="org-left">J 001001</td>
<td class="org-left">K 001010</td>
<td class="org-left">L 001011</td>
<td class="org-left">M 001100</td>
<td class="org-left">N 001101</td>
<td class="org-left">O 001110</td>
<td class="org-left">P 001111</td>
</tr>

<tr>
<td class="org-left">Q 010000</td>
<td class="org-left">R 010001</td>
<td class="org-left">S 010010</td>
<td class="org-left">T 010011</td>
<td class="org-left">U 010100</td>
<td class="org-left">V 010101</td>
<td class="org-left">W 010110</td>
<td class="org-left">X 010111</td>
</tr>

<tr>
<td class="org-left">Y 011000</td>
<td class="org-left">Z 011001</td>
<td class="org-left">a 011010</td>
<td class="org-left">b 011011</td>
<td class="org-left">c 011100</td>
<td class="org-left">d 011101</td>
<td class="org-left">e 011110</td>
<td class="org-left">f 011111</td>
</tr>

<tr>
<td class="org-left">g 100000</td>
<td class="org-left">h 100001</td>
<td class="org-left">i 100010</td>
<td class="org-left">j 100011</td>
<td class="org-left">k 100100</td>
<td class="org-left">l 100101</td>
<td class="org-left">m 100110</td>
<td class="org-left">n 100111</td>
</tr>

<tr>
<td class="org-left">o 101000</td>
<td class="org-left">p 101001</td>
<td class="org-left">q 101010</td>
<td class="org-left">r 101011</td>
<td class="org-left">s 101100</td>
<td class="org-left">t 101101</td>
<td class="org-left">u 101110</td>
<td class="org-left">v 101111</td>
</tr>

<tr>
<td class="org-left">w 110000</td>
<td class="org-left">x 110001</td>
<td class="org-left">y 110010</td>
<td class="org-left">z 110011</td>
<td class="org-left">0 110100</td>
<td class="org-left">1 110101</td>
<td class="org-left">2 110110</td>
<td class="org-left">3 110111</td>
</tr>

<tr>
<td class="org-left">4 111000</td>
<td class="org-left">5 111001</td>
<td class="org-left">6 111010</td>
<td class="org-left">7 111011</td>
<td class="org-left">8 111100</td>
<td class="org-left">9 111101</td>
<td class="org-left">+ 111110</td>
<td class="org-left">/ 111111</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="outline-container-orgf44bdd8" class="outline-2">
<h2 id="orgf44bdd8">Otras consideraciones</h2>
<div class="outline-text-2" id="text-orgf44bdd8">
<p>
Podemos encontrarnos también con otros caracteres que no son los
especificados por la tabla anterior. Por ejemplo, en algunos sistemas
es obligatorio dividir la cadena en líneas insertando un par
<code>CL+CF</code>. El largo de las líneas puede variar según el sistema de
codificación, en algún de esos sistemas el largo es 64 en general,
pudiendo ser menor la última línea. Pero en la mayoría de sistemas
sólo se especifica que no debe ser más largo de 76 columnas y, por
último, en algunos otros no se especifica nada con respecto separar la
cadena en líneas.
</p>

<p>
Otro carácter que podemos encontrarnos es el <code>*</code>. Se utiliza para
separar el texto cifrado del que está en claro, aunque esté también
codificado en <code>base64</code>.
</p>

<p>
Aunque para nosotros las cadenas <i>«Hola mundo!»</i> y <i>«¡Hola mundo!»</i>
sean muy similares, por el pequeño cambio de utilizar la exclamación
del principio, los resultados pueden ser muy dispares:
</p>

<pre class="example" id="orgccd5de9">
 Hola mundo! --&gt; SG9sYSBtdW5kbyE=
¡Hola mundo! --&gt; oUhvbGEgbXVuZG8h
</pre>
</div>
</div>
<div id="outline-container-orga177271" class="outline-2">
<h2 id="orga177271">Conclusiones</h2>
<div class="outline-text-2" id="text-orga177271">
<p>
<code>base64</code> es un sistema de codificación muy interesante para transmitir
información binaria a través de la red. Estamos muy acostumbrados a
verlo, tanto, que quizá no reparamos en él. Lo tenemos asociado a
<i>claves de encriptado</i> porque es el formato en el que solemos ver la
información de esas claves. En realidad, no es un formato para ocultar
nada, sino para transmitirlo de forma segura.
</p>

<p>
Si os preguntáis si he hecho pruebas... pues sí, las he hecho. Si
alguno queréis trastear un poco os pongo aquí el código fuente en
<i>Tcl</i>:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #8be9fd; font-style: italic;">package</span> provide b64 1.0

<span style="color: #8be9fd; font-style: italic;">namespace</span> <span style="color: #50fa7b; font-weight: bold;">eval</span> ::b64 {
    <span style="color: #8be9fd; font-style: italic;">namespace</span> <span style="color: #50fa7b; font-weight: bold;">export</span> encode decode separar-lineas juntar-lineas
}

<span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Codifica la `cadena`
</span><span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">b64::encode</span> {cadena} {
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">cad</span> [<span style="color: #8be9fd; font-style: italic;">encoding</span> convertto utf-8 $<span style="color: #f8f8f2; font-weight: bold;">cadena</span>]
    <span style="color: #8be9fd; font-style: italic;">binary</span> <span style="color: #8be9fd; font-style: italic;">scan</span> $<span style="color: #f8f8f2; font-weight: bold;">cad</span> B* bits
    <span style="color: #ff79c6; font-weight: bold;">switch</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {[<span style="color: #8be9fd; font-style: italic;">string</span> length $<span style="color: #f8f8f2; font-weight: bold;">bits</span>] % 6}] {
        0 {<span style="color: #8be9fd; font-style: italic;">set</span> final {}}
        2 {<span style="color: #8be9fd; font-style: italic;">append</span> bits 0000; <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">final</span> ==}
        4 {<span style="color: #8be9fd; font-style: italic;">append</span> bits 00; <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">final</span> =}
    }
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">devolver</span> [<span style="color: #8be9fd; font-style: italic;">string</span> map {
        000000 A 000001 B 000010 C 000011 D 000100 E 000101 F 000110 G 000111 H
        001000 I 001001 J 001010 K 001011 L 001100 M 001101 N 001110 O 001111 P
        010000 Q 010001 R 010010 S 010011 T 010100 U 010101 V 010110 W 010111 X
        011000 Y 011001 Z 011010 a 011011 b 011100 c 011101 d 011110 e 011111 f
        100000 g 100001 h 100010 i 100011 j 100100 k 100101 l 100110 m 100111 n
        101000 o 101001 p 101010 q 101011 r 101100 s 101101 t 101110 u 101111 v
        110000 w 110001 x 110010 y 110011 z 110100 0 110101 1 110110 2 110111 3
        111000 4 111001 5 111010 6 111011 7 111100 8 111101 9 111110 + 111111 /
    } $<span style="color: #f8f8f2; font-weight: bold;">bits</span>]$<span style="color: #f8f8f2; font-weight: bold;">final</span>
    <span style="color: #ff79c6; font-weight: bold;">return</span> [separar-lineas $<span style="color: #f8f8f2; font-weight: bold;">devolver</span>]
}

<span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Decodifica la `cadena`
</span><span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">b64::decode</span> {cadena} {
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">cadena</span> [juntar-lineas $<span style="color: #f8f8f2; font-weight: bold;">cadena</span>]
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">num</span> [<span style="color: #8be9fd; font-style: italic;">string</span> trimright $<span style="color: #f8f8f2; font-weight: bold;">cadena</span> =]
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">str</span> [<span style="color: #8be9fd; font-style: italic;">string</span> map {
        A 000000 B 000001 C 000010 D 000011 E 000100 F 000101 G 000110 H 000111
        I 001000 J 001001 K 001010 L 001011 M 001100 N 001101 O 001110 P 001111
        Q 010000 R 010001 S 010010 T 010011 U 010100 V 010101 W 010110 X 010111
        Y 011000 Z 011001 a 011010 b 011011 c 011100 d 011101 e 011110 f 011111
        g 100000 h 100001 i 100010 j 100011 k 100100 l 100101 m 100110 n 100111
        o 101000 p 101001 q 101010 r 101011 s 101100 t 101101 u 101110 v 101111
        w 110000 x 110001 y 110010 z 110011 0 110100 1 110101 2 110110 3 110111
        4 111000 5 111001 6 111010 7 111011 8 111100 9 111101 + 111110 / 111111
    } $<span style="color: #f8f8f2; font-weight: bold;">num</span>]
    <span style="color: #ff79c6; font-weight: bold;">switch</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {[<span style="color: #8be9fd; font-style: italic;">string</span> length $<span style="color: #f8f8f2; font-weight: bold;">cadena</span>]-[<span style="color: #8be9fd; font-style: italic;">string</span> length $<span style="color: #f8f8f2; font-weight: bold;">num</span>]}] {
        0 {}
        1 {<span style="color: #8be9fd; font-style: italic;">set</span> str [<span style="color: #8be9fd; font-style: italic;">string</span> range $<span style="color: #f8f8f2; font-weight: bold;">str</span> 0 {end-2}]}
        2 {<span style="color: #8be9fd; font-style: italic;">set</span> str [<span style="color: #8be9fd; font-style: italic;">string</span> range $<span style="color: #f8f8f2; font-weight: bold;">str</span> 0 {end-4}]}
    }
    <span style="color: #ff79c6; font-weight: bold;">return</span> [<span style="color: #8be9fd; font-style: italic;">encoding</span> convertfrom utf-8 [<span style="color: #8be9fd; font-style: italic;">binary</span> <span style="color: #8be9fd; font-style: italic;">format</span> B* $<span style="color: #f8f8f2; font-weight: bold;">str</span>]]
}

<span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Separa la `cadena` en l&#237;neas de `ancho`
</span><span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">b64::separar-lineas</span> {cadena {ancho 76}} {
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">lista</span> {}
    <span style="color: #ff79c6; font-weight: bold;">while</span> {[<span style="color: #8be9fd; font-style: italic;">string</span> length $<span style="color: #f8f8f2; font-weight: bold;">cadena</span>] &gt; $<span style="color: #f8f8f2; font-weight: bold;">ancho</span>} {
        <span style="color: #8be9fd; font-style: italic;">lappend</span> lista [<span style="color: #8be9fd; font-style: italic;">string</span> range $<span style="color: #f8f8f2; font-weight: bold;">cadena</span> 0 [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">ancho</span> - 1}]]
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">cadena</span> [<span style="color: #8be9fd; font-style: italic;">string</span> range $<span style="color: #f8f8f2; font-weight: bold;">cadena</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">ancho</span>}] [<span style="color: #8be9fd; font-style: italic;">expr</span> {[<span style="color: #8be9fd; font-style: italic;">string</span> length $<span style="color: #f8f8f2; font-weight: bold;">cadena</span>] - 1}]]
    }
    <span style="color: #ff79c6; font-weight: bold;">if</span> {[<span style="color: #8be9fd; font-style: italic;">string</span> length $<span style="color: #f8f8f2; font-weight: bold;">cadena</span>] &gt; 0} {<span style="color: #8be9fd; font-style: italic;">lappend</span> lista $<span style="color: #f8f8f2; font-weight: bold;">cadena</span>}
    <span style="color: #ff79c6; font-weight: bold;">return</span> [<span style="color: #8be9fd; font-style: italic;">join</span> $<span style="color: #f8f8f2; font-weight: bold;">lista</span> <span style="color: #f1fa8c;">"\n"</span>]
}

<span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Elimina los saltos de l&#237;nea de `cadena`
</span><span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">b64::juntar-lineas</span> {cadena} {
    <span style="color: #ff79c6; font-weight: bold;">return</span> [<span style="color: #8be9fd; font-style: italic;">string</span> map {<span style="color: #f1fa8c;">"\n"</span> {}} $<span style="color: #f8f8f2; font-weight: bold;">cadena</span>]
}

<span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Algunas pruebas de conversi&#243;n
</span><span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">prueba</span> {} {
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">cadena</span> <span style="color: #f1fa8c;">"&#161;Hola mundo!"</span>
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">bcadena</span> [b64::encode $<span style="color: #f8f8f2; font-weight: bold;">cadena</span>]
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">ncadena</span> [b64::decode $<span style="color: #f8f8f2; font-weight: bold;">bcadena</span>]

    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">cadena1</span> <span style="color: #f1fa8c;">"e&#293;o&#349;an&#285;o &#265;iu&#309;a&#365;de"</span>
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">bcadena1</span> [b64::encode $<span style="color: #f8f8f2; font-weight: bold;">cadena1</span>]
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">ncadena1</span> [b64::decode $<span style="color: #f8f8f2; font-weight: bold;">bcadena1</span>]

    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">cadena2</span> <span style="color: #f1fa8c;">"Hola"</span>
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">bcadena2</span> [b64::encode $<span style="color: #f8f8f2; font-weight: bold;">cadena2</span>]
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">ncadena2</span> [b64::decode $<span style="color: #f8f8f2; font-weight: bold;">bcadena2</span>]

    <span style="color: #8be9fd; font-style: italic;">puts</span> <span style="color: #f1fa8c;">"$cadena: $ncadena | $bcadena"</span>
    <span style="color: #8be9fd; font-style: italic;">puts</span> <span style="color: #f1fa8c;">"$cadena1: $ncadena1 | $bcadena1"</span>
    <span style="color: #8be9fd; font-style: italic;">puts</span> <span style="color: #f1fa8c;">"$cadena2: $ncadena2 | $bcadena2"</span>

    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">c</span> [b64::juntar-lineas <span style="color: #f1fa8c;">"RXN0byBlcyB1biB0ZXh0byBkZSBwcnVlYmEuIE5vIHRpZW5lIG5pbmd1bmEgaW1wb3J0YW5jaWEg
bG8gcXVlCnBvbmdhLCBwZXJvIG5lY2VzaXRvIGVzY3JpYmlyIGFsZ3Vub3MgY2FyYWN0ZXJlcyBl
c3BlY2lhbGVzLiBQdWVkZW4Kc2VyIGxvcyBjYXJhY3RlcmVzIGFjZW50dWFkb3MgeSBsZXRyYXMg
Y29tbyBsYSDDsSAow5EpLCBvIGxhIMOnICjDhykuIE8KbGFzIMOhw6nDrcOzw7ogw6DDqMOsw7LD
uSDDpMOrw6/DtsO8LiDCq0XEpW/FnWFuxJ1vIMSJaXXEtWHFrWRlwrsK"</span>]
    <span style="color: #8be9fd; font-style: italic;">puts</span> $<span style="color: #f8f8f2; font-weight: bold;">c</span>

    <span style="color: #8be9fd; font-style: italic;">puts</span> [b64::decode $<span style="color: #f8f8f2; font-weight: bold;">c</span>]

    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">c</span> [b64::separar-lineas <span style="color: #f1fa8c;">"RXN0byBlcyB1biB0ZXh0byBkZSBwcnVlYmEuIE5vIHRpZW5lIG5pbmd1bmEgaW1wb3J0YW5jaWEgbG8gcXVlCnBvbmdhLCBwZXJvIG5lY2VzaXRvIGVzY3JpYmlyIGFsZ3Vub3MgY2FyYWN0ZXJlcyBlc3BlY2lhbGVzLiBQdWVkZW4Kc2VyIGxvcyBjYXJhY3RlcmVzIGFjZW50dWFkb3MgeSBsZXRyYXMgY29tbyBsYSDDsSAow5EpLCBvIGxhIMOnICjDhykuIE8KbGFzIMOhw6nDrcOzw7ogw6DDqMOsw7LDuSDDpMOrw6/DtsO8LiDCq0XEpW/FnWFuxJ1vIMSJaXXEtWHFrWRlwrsK"</span> 72]
    <span style="color: #8be9fd; font-style: italic;">puts</span> $<span style="color: #f8f8f2; font-weight: bold;">c</span>
    <span style="color: #8be9fd; font-style: italic;">puts</span> [b64::decode $<span style="color: #f8f8f2; font-weight: bold;">c</span>]
}

<span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Si se llama desde l&#237;nea de comandos con la opci&#243;n `-test` hace las pruebas
</span><span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">argc</span> &gt; 0 &amp; [<span style="color: #8be9fd; font-style: italic;">lindex</span> $<span style="color: #f8f8f2; font-weight: bold;">argv</span> 0] == <span style="color: #f1fa8c;">"-test"</span> } {prueba}
</pre>
</div>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Un medio con un protocolo que se inventó para enviar mensajes
de texto y al que se pueden añadir datos binarios como imágenes u
otros archivos. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Es una expresión sin sentido. Se podría traducir como <i>cambio
de eco todos los jueves</i>, pero tiene la particularidad de contener
todos los caracteres especiales del idioma condensados en una sencilla
expresión de dos palabras. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Los valores irán, por tanto, entre el valor b00000 y b11111
equivalentes al 0 y al 63 respectivamente.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En hexadecimal sería 0x00 ó  0x0000 respectivamente.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/criptografia/index.html">criptografia</a> ]]></description>
  <category><![CDATA[criptografia]]></category>
  <link>https://notxor.nueva-actitud.org/2022/08/03/codificacion-en-base64.html</link>
  <pubDate>Wed, 03 Aug 2022 08:34:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Codificar y descodificar cadenas con el algoritmo RSA]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-07-28</div>
<p>
Esta es la tercera y última entrega sobre el algoritmo RSA para
cifrado y descifrado de mensajes. Si te has perdido los anteriores, lo
mismo te vendría bien echarles un ojo, porque <a href="https://notxor.nueva-actitud.org/2022/07/21/algoritmo-de-cifrado-rsa.html">en el primero</a> explico
cómo funciona el algoritmo RSA, con un poco de matemáticas por medio,
y <a href="https://notxor.nueva-actitud.org/2022/07/23/generando-un-n%C3%BAmero-primo-grande.html">en el segundo</a> hablo sobre unos de los cálculos más complejos que hay
que realizar en el paso de generación de las claves. Si te has perdido
los anteriores porque no te interesaba el tema, no sé que haces
leyendo éste. En el presente artículo hablo sobre el resto de la
generación de las claves, creando un fichero para la llave pública y
otro para la llave privada y un par de funciones de cifrado y
descifrado que serán las que hagan la magia. El código completo lo
puedes encontrar al final del texto.
</p>

<p>
Podréis observar que en el código hay varias funciones de
exponenciación. Al trabajar con números tan grandes el operador
habitual <code>**</code> no funcionaba por desbordamiento. Sin embargo, parece
que los operadores habituales (<code>+ - / *</code>) siguen adelante en <i>TCL</i> con
los números grandes. Busqué algunos algoritmos que hicieran esa
operación de forma rápida y después de probar varias alternativas, me
di cuenta que en realidad no lo necesitaba, porque lo que realmente
era necesario ya estaba incluido en el código de las pruebas de
primalidad. Lo que necesitaba era el exponente modular. En fin, torpe
que soy.
</p>
<div id="outline-container-orgb84513d" class="outline-2">
<h2 id="orgb84513d">Generar la clave</h2>
<div class="outline-text-2" id="text-orgb84513d">
<p>
En el título del apartado hablo en singular, aunque en realidad el
proceso generará dos archivos, uno terminado en <code>-pub.key</code> y otro en
<code>-priv.key</code> que contendrán las claves que necesitamos, el primero la
<i>pública</i> y el segundo la <i>privada</i>.
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">generar-clave</span> {t} {
    <span style="color: #8be9fd; font-style: italic;">puts</span> <span style="color: #f1fa8c;">"Generando clave aleatoria de [expr {16 * $t}] bits"</span>

    <span style="color: #6272a4;"># 1. generar dos n&#250;meros primos
</span>    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">p</span> [generar-primo $<span style="color: #f8f8f2; font-weight: bold;">t</span>]
    <span style="color: #ff79c6; font-weight: bold;">while</span> { 1 } {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">q</span> [generar-primo $<span style="color: #f8f8f2; font-weight: bold;">t</span>]
        <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">p</span> != $<span style="color: #f8f8f2; font-weight: bold;">q</span>} <span style="color: #ff79c6; font-weight: bold;">break</span>
    }
    dict <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"p"</span> $<span style="color: #f8f8f2; font-weight: bold;">p</span>
    dict <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"q"</span> $<span style="color: #f8f8f2; font-weight: bold;">q</span>

    <span style="color: #6272a4;"># 2. Calcular el m&#243;dulo
</span>    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">n</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">p</span> * $<span style="color: #f8f8f2; font-weight: bold;">q</span>}]
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">t</span> [num-bits $<span style="color: #f8f8f2; font-weight: bold;">n</span>]
    dict <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"n"</span> $<span style="color: #f8f8f2; font-weight: bold;">n</span>
    dict <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"t"</span> $<span style="color: #f8f8f2; font-weight: bold;">t</span>

    <span style="color: #6272a4;"># 3. Calcular `phi(n)`
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">phiN</span> [mcm [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">p</span> - 1}] [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">q</span> - 1}]]
    dict <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"phi(n)"</span> $<span style="color: #f8f8f2; font-weight: bold;">phiN</span>

    <span style="color: #6272a4;"># 4. Calcular el exponente
</span>    <span style="color: #6272a4;">#    `e` &#191;65537?
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">e</span> [aleatorio [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">t</span> / 8}]]
    dict <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"e"</span> $<span style="color: #f8f8f2; font-weight: bold;">e</span>

    <span style="color: #6272a4;"># 5. Calcular el exponente `d`
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">d</span> [modinverso $<span style="color: #f8f8f2; font-weight: bold;">e</span>  $<span style="color: #f8f8f2; font-weight: bold;">phiN</span>]
    dict <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"d"</span> $<span style="color: #f8f8f2; font-weight: bold;">d</span>

    <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">key</span>
}
</pre>
</div>

<p>
La función que genera la clave sigue paso a paso el algoritmo. Se
puede mejorar el proceso, especialmente metiéndole comprobaciones de
que los pasos se completan satisfactoriamente dentro de las
especificaciones establecidas, como se ha hecho en el primer paso al
generar los números primos. El primer número se genera aleatoriamente
con el tamaño pedido<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. El segundo se pide en bucle y se comprueba
que no sea idéntico al primero. La probabilidad de esto ocurra es muy
pequeña, infinitesimal, dado el tamaño de los números. Sin embargo,
haciendo pruebas con números pequeños, ya me ha ocurrido que eran
idénticos<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.
</p>

<p>
Obtenidos dos números primos grandes, completamente aleatorios. El
siguiente paso es calcular el módulo. Este paso se podría juntar con
el primero y comprobar, además de que los dos números primos son de
tamaño ligeramente diferente, y que el <i>módulo</i>, sea igual o
superior al tamaño que le estamos pidiendo, es decir <code>16 * t</code>.
</p>

<p>
Para el tercer paso, calcular \(\lambda (n) = \phi (n)\) debemos
calcular el <i>mínimo común múltiplo</i> de \((p - 1) \cdot (q - 1)\). Y aquí
también me he tropezado con un montón de algoritmos, todos muy lentos
con números tan grandes, para calcular el <code>mcm</code>. El único que resultó
suficientemente rápido fue explotar la relación que existe entre el
<i>MCM</i> y el <i>mínimo común divisor</i> (MCD).
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">mcd</span> {a b} {
    <span style="color: #ff79c6; font-weight: bold;">while</span> {$<span style="color: #f8f8f2; font-weight: bold;">a</span> != $<span style="color: #f8f8f2; font-weight: bold;">b</span>} {
        <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">a</span> &gt; $<span style="color: #f8f8f2; font-weight: bold;">b</span>} {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">a</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">a</span> - $<span style="color: #f8f8f2; font-weight: bold;">b</span>}]
        } <span style="color: #ff79c6; font-weight: bold;">else</span> {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">b</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">b</span> - $<span style="color: #f8f8f2; font-weight: bold;">a</span>}]
        }
    }
    <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">a</span>
}

<span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">mcm</span> {a b} {
    <span style="color: #ff79c6; font-weight: bold;">return</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">a</span> * $<span style="color: #f8f8f2; font-weight: bold;">b</span> / [mcd $<span style="color: #f8f8f2; font-weight: bold;">a</span> $<span style="color: #f8f8f2; font-weight: bold;">b</span>]}]
}  
</pre>
</div>

<p>
Resultó que el algoritmo de cálculo del <i>MCD</i> es bastante más rápido
que el del <i>MCM</i>, y puesto que sabemos que:
</p>

<p>
\[mcm(a,b) = \frac{a \cdot b}{mcd(a,b)}\]
</p>

<p>
salía más a cuenta calcular <code>mcd</code> primero y en base a él el <code>mcm</code>, que
es lo que hace el código. Para calcular el primer exponente, no hay
mucho que hacer. El algoritmo sólo nos pide un número entre 1 y
\(\phi(n)\). Pero, puesto que elijo un número aleatorio de tamaño \(t/8\),
no necesito compararlo con \(\phi(n)\) pues siempre será,
matemáticamente menor. También me he encontrado mucha literatura que
parece tener cierta predilección y sugería el uso sistemático de 65537
(y múltiplos de él) como exponente <i>e</i> y calcular el <i>d</i> en base a
él. He estado curioseando algunas claves que tengo por el disco duro y
efectivamente algunas parecen confirmarlo, pero otras no. En todo
caso, no encuentro una explicación para ello y prefiero que la
aleatoriedad trabaje.
</p>

<p>
Por último, para calcular el segundo exponente necesitaremos la
función <code>modinverso</code>, que calcula el módulo inverso:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">modinverso</span> { e phi } {
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">m0</span> $<span style="color: #f8f8f2; font-weight: bold;">phi</span>
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">y</span> 0
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">x</span> 1

    try {
        <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">phi</span> == 1} {<span style="color: #ff79c6; font-weight: bold;">return</span> 0}
        <span style="color: #ff79c6; font-weight: bold;">while</span> {$<span style="color: #f8f8f2; font-weight: bold;">e</span> &gt; 1} {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">q</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">e</span> / $<span style="color: #f8f8f2; font-weight: bold;">phi</span>}]
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">t</span> $<span style="color: #f8f8f2; font-weight: bold;">phi</span>

            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">phi</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">e</span> % $<span style="color: #f8f8f2; font-weight: bold;">phi</span>}]
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">e</span> $<span style="color: #f8f8f2; font-weight: bold;">t</span>
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">t</span> $<span style="color: #f8f8f2; font-weight: bold;">y</span>

            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">y</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">x</span> - $<span style="color: #f8f8f2; font-weight: bold;">q</span> * $<span style="color: #f8f8f2; font-weight: bold;">y</span>}]
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">x</span> $<span style="color: #f8f8f2; font-weight: bold;">t</span>
        }
        <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">x</span> &lt; 0} {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">x</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">x</span> + $<span style="color: #f8f8f2; font-weight: bold;">m0</span>}]
        }
        <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">x</span>
    } on <span style="color: #ff79c6; font-weight: bold;">error</span> {} {
        <span style="color: #ff79c6; font-weight: bold;">return</span> -1
    }
}
</pre>
</div>

<p>
Como se puede observar, el código de cálculo está dentro de una
cláusula <code>try</code>. Esto es porque no siempre existe un <i>d</i>, dados un <i>e</i>
y un \(\phi\). Cuando esto ocurre termina produciéndose una división por
0 y se genera el consiguiente error. En esos casos, la función
devolverá <code>-1</code>. Cuando esto ocurre hay que volver a seleccionar otro
exponente <i>e</i> y repetir el cálculo.
</p>

<p>
Es decir, como no siempre dado un exponente podemos calcular su módulo
inverso, en algunas ocasiones nos encontraremos que debemos repetir
los cálculos, como veremos a continuación. De momento, nos basta con
saber que todos estos datos calculados son devueltos en un
<i>diccionario</i> de nombre <code>key</code>.
</p>
</div>
</div>
<div id="outline-container-org7710fa5" class="outline-2">
<h2 id="org7710fa5">Generar los ficheros de claves</h2>
<div class="outline-text-2" id="text-org7710fa5">
<p>
Hasta ahora hemos visto cómo realizar todos los cálculos para obtener
un diccionario con los datos necesarios para cifrar-descifrar
cadenas. Todo este proceso resultará más largo cuanto más grande sea
el tamaño de clave, pero, sólo necesitan hacerse una vez.  Los datos
que se han calculado pueden guardarse y utilizarse para el cifrado y
descifrado sin necesidad de repetirlo todo cada vez.
</p>

<p>
Finalmente, se utiliza una función que una vez realizados los cálculos
los guarda en archivos. Concretamente dos, uno contendrá la clave
pública y otra la clave privada. Necesita el tamaño en <i>bytes</i> del
tamaño de cada número primo y una cadena con el nombre que queremos
para la clave y que se usará como base para el nombre de los archivos
de clave. Esta función es:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">obtener-claves</span> {t nombre} {
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> [generar-clave $<span style="color: #f8f8f2; font-weight: bold;">t</span>]

    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">tam</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">t</span> + 1}]
    <span style="color: #ff79c6; font-weight: bold;">while</span> {[dict get $<span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"d"</span>] == -1 | [dict get $<span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"t"</span>] &lt; (16 * $<span style="color: #f8f8f2; font-weight: bold;">t</span>)} {
        <span style="color: #ff79c6; font-weight: bold;">if</span> {[dict get $<span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"d"</span>] == -1} {
            <span style="color: #8be9fd; font-style: italic;">puts</span> <span style="color: #f1fa8c;">"Clave indefinida."</span>
        } <span style="color: #ff79c6; font-weight: bold;">else</span> {
            <span style="color: #8be9fd; font-style: italic;">puts</span> <span style="color: #f1fa8c;">"Clave incompleta."</span>
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">tam</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">tam</span> + 1}]
        }
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> [generar-clave $<span style="color: #f8f8f2; font-weight: bold;">tam</span>]
    }

    <span style="color: #6272a4;"># Escribir clave p&#250;blica
</span>    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">fpub</span> <span style="color: #f1fa8c;">"$nombre-pub.key"</span>
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">f</span> [<span style="color: #8be9fd; font-style: italic;">open</span> $<span style="color: #f8f8f2; font-weight: bold;">fpub</span> w]
    <span style="color: #8be9fd; font-style: italic;">puts</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span> <span style="color: #f1fa8c;">"n:[dict get $key n]\ne:[dict get $key e]"</span>
    <span style="color: #8be9fd; font-style: italic;">close</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span>
    <span style="color: #6272a4;"># Escribir clave privada
</span>    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">fpriv</span> <span style="color: #f1fa8c;">"$nombre-priv.key"</span>
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">f</span> [<span style="color: #8be9fd; font-style: italic;">open</span> $<span style="color: #f8f8f2; font-weight: bold;">fpriv</span> w]
    <span style="color: #ff79c6; font-weight: bold;">foreach</span> {k v} $<span style="color: #f8f8f2; font-weight: bold;">key</span> {
        <span style="color: #8be9fd; font-style: italic;">puts</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span> <span style="color: #f1fa8c;">"$k:$v"</span>
    }
    <span style="color: #8be9fd; font-style: italic;">close</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span>
    <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">key</span>
}
</pre>
</div>

<p>
Vemos que lo primero que hace esa función es generar una clave. Con
esa clave puede ocurrir, sin haber puesto comprobaciones hasta ahora,
que aleatoriamente se hayan generado un par de números primos no tan
grandes como se desea o que no se haya podido calcular <i>d</i>, el segundo
exponente, por los motivos que comenté antes. Se podría acelerar los
cálculos repitiendo sólo aquellos necesarios con anterioridad y no
generando una nueva clave por completo. Pero dejo eso para una
posterior refactorización y mejora del código.
</p>

<p>
Realizados todos los cálculos e incluso generando un par de ficheros
con las claves... ¿funciona?
</p>
</div>
</div>
<div id="outline-container-orgd4acf85" class="outline-2">
<h2 id="orgd4acf85">Cifrar y descifrar cadenas</h2>
<div class="outline-text-2" id="text-orgd4acf85">
<p>
Para cifrar y descifrar cadenas, necesitamos las claves
correspondientes, obtenidas en los pasos anteriores.  Sin embargo,
como ya guardamos las claves en ficheros mediante la función
<code>obtener-claves</code>, lo que nos hace falta es leerlas desde donde las
guardamos:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">leer-fichero-clave</span> {nombre} {
    try {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">f</span> [<span style="color: #8be9fd; font-style: italic;">open</span> $<span style="color: #f8f8f2; font-weight: bold;">nombre</span> r]
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">datos</span> [<span style="color: #8be9fd; font-style: italic;">split</span> [<span style="color: #8be9fd; font-style: italic;">read</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span>] <span style="color: #f1fa8c;">"\n:"</span>]
        <span style="color: #8be9fd; font-style: italic;">close</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span>
    }

    <span style="color: #ff79c6; font-weight: bold;">foreach</span> {k v} [<span style="color: #8be9fd; font-style: italic;">lrange</span> $<span style="color: #f8f8f2; font-weight: bold;">datos</span> 0 [<span style="color: #8be9fd; font-style: italic;">expr</span> {[<span style="color: #8be9fd; font-style: italic;">llength</span> $<span style="color: #f8f8f2; font-weight: bold;">datos</span>] - 2}]] {
        dict <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> $<span style="color: #f8f8f2; font-weight: bold;">k</span> $<span style="color: #f8f8f2; font-weight: bold;">v</span>
    }
    <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">key</span>
}
</pre>
</div>

<p>
Es una función muy sencilla: se le proporciona un nombre de fichero y
lo lee. Espera encontrar una lista de parámetros con un formato muy
simple, en cada línea un par <code>nombre:valor</code>. Por ejemplo, una clave
privada tendrá los siguientes valores:
</p>

<pre class="example" id="org3e97ddd">
p:2496806461475996779639
q:747147072320567882239
n:1865481637842867751904719692788458184931721
t:141
phi(n):310913606307144625316912623209110270044974
e:73470389151338783283577819257589238878901
d:202567603045917330908610474508371510582647
</pre>

<p>
mientras que su par, la clave pública será:
</p>

<pre class="example" id="orgdc6c871">
n:1865481637842867751904719692788458184931721
e:73470389151338783283577819257589238878901
</pre>

<p>
Lo que hace es leer todo el contenido de golpe, dividiendo el
resultado en una lista de pares que luego se convierten en un
diccionario. Quizá la parte más oscura del código anterior es que se
elimina la línea en blanco que genera la escritura, convertida en una
cadena vacía, <code>{}</code>, generada en la lectura, mediante un <code>lrange</code>.
Sería recomendable algún tipo de código, como algún encabezado de
fichero, que nos permita asegurar que es un fichero de clave bien
formado.
</p>

<p>
El código para cifrar y descifrar consiste en dos pequeñas funciones
que hacen el cálculo \(c = m^e \; (mod \, n)\) para cifrar y
\(m \equiv c^d \; (mod \, n)\) para descifrar:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">rsa-encript</span> {cadena key} {
    <span style="color: #6272a4;"># Convertir la cadena de entrada en un n&#250;mero
</span>    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">num</span> [cad-a-num $<span style="color: #f8f8f2; font-weight: bold;">cadena</span>]
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">n</span> [dict get $<span style="color: #f8f8f2; font-weight: bold;">key</span> n]
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">e</span> [dict get $<span style="color: #f8f8f2; font-weight: bold;">key</span> e]
    <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">num</span> &lt; $<span style="color: #f8f8f2; font-weight: bold;">n</span>} {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">resultado</span> [expmod $<span style="color: #f8f8f2; font-weight: bold;">num</span> $<span style="color: #f8f8f2; font-weight: bold;">e</span> $<span style="color: #f8f8f2; font-weight: bold;">n</span>]
    } <span style="color: #ff79c6; font-weight: bold;">else</span> {
        <span style="color: #ff79c6; font-weight: bold;">error</span> <span style="color: #f1fa8c;">"&#171;$cadena&#187; es demasiado largo para la clave especificada."</span>
    }
    <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">resultado</span>
}

<span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">rsa-decript</span> { num key } {
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">n</span> [dict get $<span style="color: #f8f8f2; font-weight: bold;">key</span> n]
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">d</span> [dict get $<span style="color: #f8f8f2; font-weight: bold;">key</span> d]
    <span style="color: #ff79c6; font-weight: bold;">return</span> [num-a-cad [expmod $<span style="color: #f8f8f2; font-weight: bold;">num</span> $<span style="color: #f8f8f2; font-weight: bold;">d</span> $<span style="color: #f8f8f2; font-weight: bold;">n</span>]]
}
</pre>
</div>

<p>
A la primera le proporcionamos una <i>cadena</i> y una clave. Convierte la
cadena a un número que lo representa. Eso se hace mediante la función:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">cad-a-num</span> {cadena} {
    <span style="color: #ff79c6; font-weight: bold;">return</span> [<span style="color: #8be9fd; font-style: italic;">format</span> %lld 0x[<span style="color: #8be9fd; font-style: italic;">binary</span> encode hex $<span style="color: #f8f8f2; font-weight: bold;">cadena</span>]]
}
</pre>
</div>

<p>
Ésta, lo que hace es convertir la cadena en bytes hexadecimales con
<code>binary</code> y luego pasarlo a número decimal con el que poder operar con
<code>format</code>.
</p>

<p>
Antes de cifrar se comprueba que el módulo sea mayor que el número que
se debería cifrar, pues si no es así no se cumpliría la equivalencia
de exponentes para el descifrado. Por ello, si ocurriera eso, se
lanza un <code>error</code>. En caso contrario devuelve el valor cifrado.
</p>

<p>
El paso contrario es equivalente, pero a la inversa, se introduce un
número y una clave y devuelve una cadena formada con el resultado del
cálculo, mediante la función <code>num-a-cad</code>
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">num-a-cad</span> {num} {
    <span style="color: #ff79c6; font-weight: bold;">return</span> [<span style="color: #8be9fd; font-style: italic;">binary</span> decode hex [<span style="color: #8be9fd; font-style: italic;">format</span> %llx $<span style="color: #f8f8f2; font-weight: bold;">num</span>]]
}
</pre>
</div>

<p>
que realiza las operaciones inversas de <code>cad-a-num</code>, convierte el
número a formato hexadecimal mediante <code>format</code> y el resultado en una
cadena mediante <code>binary</code>. Si el número hexadecimal está bien formado y
corresponde a valores de caracteres, la cadena quedará bien formada.
</p>

<p>
Como ejemplo:
</p>

<pre class="example" id="org59754d8">
&gt; tclsh
% lappend auto_path ../src
/usr/lib64/tcl/tcl8.6 /usr/lib64/tcl /usr/lib /usr/share/tcl ../src
% package require rsa
1.0
% set key [rsa::obtener-claves 8 corto-inseguro]
Generando clave aleatoria de 128 bits
Clave indefinida.
Generando clave aleatoria de 144 bits
Clave indefinida.
Generando clave aleatoria de 144 bits
p 2496806461475996779639 q 747147072320567882239 n 1865481637842867751904719692788458184931721 t 141 phi(n) 310913606307144625316912623209110270044974 e 73470389151338783283577819257589238878901 d 202567603045917330908610474508371510582647
% set c [rsa::rsa-encript "hola" $key]
1084245477992884776922019206560106173451692
% rsa::rsa-decript $c $key
hola
% 
</pre>

<p>
Se puede ver que se ha generado la clave, se ha cifrado la cadena
<code>"hola"</code> y se ha vuelto a descifrar. Para observar el mismo proceso
desde la carga de ficheros podríamos hacer la simulación completa,
empezando por el cifrado:
</p>

<pre class="example" id="org503081e">
&gt; tclsh
% lappend auto_path ../src
/usr/lib64/tcl/tcl8.6 /usr/lib64/tcl /usr/lib /usr/share/tcl ../src
% package require rsa
1.0
% set key [rsa::leer-fichero-clave "corto-inseguro-pub.key"]
n 1865481637842867751904719692788458184931721 e 73470389151338783283577819257589238878901
% set c [rsa::rsa-encript "hola" $key]
1084245477992884776922019206560106173451692
% set conerror [rsa::rsa-encript "Hola mundo del cifrado!" $key]
«Hola mundo del cifrado!» es demasiado largo para la clave especificada.
% puts $conerror
can't read "conerror": no such variable
% 
...
% set key [rsa::leer-fichero-clave corto-inseguro-priv.key]
p 2496806461475996779639 q 747147072320567882239 n 1865481637842867751904719692788458184931721 t 141 phi(n) 310913606307144625316912623209110270044974 e 73470389151338783283577819257589238878901 d 202567603045917330908610474508371510582647
% rsa::rsa-decript $c $key
hola
%
</pre>

<p>
Se puede observar que la clave privada incluye también los datos de la
pública, por lo que se puede cifrar y descifrar sólo cargando la clave
privada. Sin embargo, con la clave pública sólo es posible el cifrado
y debemos cargar la privada para el descifrado.
</p>
</div>
</div>
<div id="outline-container-org6a35ede" class="outline-2">
<h2 id="org6a35ede">Conclusiones</h2>
<div class="outline-text-2" id="text-org6a35ede">
<p>
El algoritmo está funcionando, ¿qué faltaría? Pues faltan todas las
acciones correspondientes a la conformación correcta de claves, para
intercambio con otras aplicaciones. El módulo sólo es capaz de
utilizar las claves obtenidas con un formato muy básico, <i>crudo</i>.
Haría falta tener en cuenta el tema de los tamaños y cómo las
herramientas de cifrado serias, realizan operaciones de <i>relleno</i> para
no dar pistas de los tamaños empleados, para no facilitar el cálculo
inverso de claves. Pero en general, estoy satisfecho con el resultado
y ha sido más sencillo de implementar de lo que me esperaba.
</p>

<p>
Me estoy planteando, por seguir con la serie sobre criptografía con
hacer un par de cosas más: algún algoritmo de cifrado simétrico y
alguno de <i>hash</i>. Para firma digital también se utiliza RSA, así que
no tendría mucho más que explicar, salvo el protocolo de firmado.
Amenazo con volver.
</p>
</div>
</div>
<div id="outline-container-orge0f145f" class="outline-2">
<h2 id="orge0f145f">Código</h2>
<div class="outline-text-2" id="text-orge0f145f">
<p>
El código completo está a continuación. Necesita un refactorizado y
muchas pruebas para determinar su efectividad. Pero teóricamente todas
las premisas del algoritmo se cumplen. Una de las cosas que debería
hacerse es limitar la cantidad de funciones accesibles desde el
exterior, en el bloque <code>namespace export</code>. Hay también alguna función
que se hizo para incorporar algún otro algoritmo de cálculo y que se
ha quedado en el código como <i>código muerto</i>. Habría que hacer
limpieza.
</p>

<p>
He metido comentarios en todas las funciones para que se pueda hacer
uno la idea de lo que hace, los parámetros que necesita y lo que
devuelve.
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Paquete que proporciona el archivo
</span><span style="color: #8be9fd; font-style: italic;">package</span> provide rsa 1.0

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">Creamos un `namespace` para evitar choques de nombre
</span><span style="color: #8be9fd; font-style: italic;">namespace</span> <span style="color: #50fa7b; font-weight: bold;">eval</span> ::rsa {

    <span style="color: #6272a4;"># Rutinas que se exportan para trabajar con ellas
</span>    <span style="color: #8be9fd; font-style: italic;">namespace</span> <span style="color: #50fa7b; font-weight: bold;">export</span> num-bits es-primo generar-primo<span style="color: #f1fa8c;">\</span>
        exp-rapida obtener-claves mcm modinverso pow expmod<span style="color: #f1fa8c;">\</span>
        rsa-encript rsa-decript leer-fichero-clave

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: num-bits
</span>    <span style="color: #6272a4;">#   Devuelve el n&#250;mero de bits empleados para representar un n&#250;mero entero
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `valor` representa el n&#250;mero del que queremos saber el tama&#241;o
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   La cantidad de bits empleados en la representaci&#243;n del n&#250;mero
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">num-bits</span> valor {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">bits</span> -1
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">p</span> 0
        <span style="color: #ff79c6; font-weight: bold;">while</span> {$<span style="color: #f8f8f2; font-weight: bold;">valor</span> &gt;= $<span style="color: #f8f8f2; font-weight: bold;">p</span>} {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">p</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {(1 &lt;&lt; [<span style="color: #8be9fd; font-style: italic;">incr</span> bits])}]
        }
        <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">bits</span>
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: aleatorio
</span>    <span style="color: #6272a4;">#   Devuelve un n&#250;mero aleatorio (biginteger) utilizando el dispositivo
</span>    <span style="color: #6272a4;">#   `/dev/random` de Unix (Esto no funcionar&#225; en g&#252;ind&#243;n)
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `nbytes` determina el n&#250;mero de bytes que se leen del dispositivo
</span>    <span style="color: #6272a4;">#   y, por tanto, el tama&#241;o del n&#250;mero devuelto
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   Un n&#250;mero, entero, aleatorio dentro del rango establecido
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">aleatorio</span> {{nbytes 8}} {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">cadena</span> <span style="color: #f1fa8c;">""</span>
        <span style="color: #6272a4;"># Leo `nbytes` del dispositivo `/dev/random`
</span>        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">f</span> [<span style="color: #8be9fd; font-style: italic;">open</span> /dev/random rb]
        <span style="color: #ff79c6; font-weight: bold;">for</span> {<span style="color: #8be9fd; font-style: italic;">set</span> b 0} {$<span style="color: #f8f8f2; font-weight: bold;">b</span> &lt; $<span style="color: #f8f8f2; font-weight: bold;">nbytes</span>} {<span style="color: #8be9fd; font-style: italic;">incr</span> b} {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">byte</span> [<span style="color: #8be9fd; font-style: italic;">read</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span> 1]
            <span style="color: #6272a4;"># cada byte se convierte a una cadena hexadecimal y se
</span>            <span style="color: #6272a4;">#      concatena en `cadena`
</span>            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">cadena</span> $<span style="color: #f8f8f2; font-weight: bold;">cadena</span>[byte-a-hex $<span style="color: #f8f8f2; font-weight: bold;">byte</span>]
        }
        <span style="color: #8be9fd; font-style: italic;">close</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span>
        <span style="color: #6272a4;"># convierto la cadena hexadecimal en un n&#250;mero decimal (big %ll)
</span>        <span style="color: #ff79c6; font-weight: bold;">return</span> [<span style="color: #8be9fd; font-style: italic;">format</span> %lld 0x$<span style="color: #f8f8f2; font-weight: bold;">cadena</span>]
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: entero-entre
</span>    <span style="color: #6272a4;">#   Devuelve un entero aleatorio entre los valores m&#237;nimo y m&#225;ximo. El
</span>    <span style="color: #6272a4;">#   n&#250;mero aleatorio, devuelto por [aleatorio 8] al ser de 8 bytes,
</span>    <span style="color: #6272a4;">#   tendr&#225; un rango entre 0 y 18446744073709551615
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `min` El valor m&#237;nimo que debe devolver
</span>    <span style="color: #6272a4;">#   `max` El valor m&#225;ximo que debe devolver
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   Un entero `n` tal que 'min &lt;= n &lt;= max'
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">entero-entre</span> {min max} {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">dec</span> [aleatorio 8]
        <span style="color: #6272a4;"># el n&#250;mero m&#225;ximo que se puede obetener aleatoriamente por el
</span>        <span style="color: #6272a4;"># c&#243;digo anterior es 18446744073709551615
</span>        <span style="color: #ff79c6; font-weight: bold;">return</span> round([<span style="color: #8be9fd; font-style: italic;">expr</span> {(($<span style="color: #f8f8f2; font-weight: bold;">dec</span>/18446744073709551615.0) * ($<span style="color: #f8f8f2; font-weight: bold;">max</span> - $<span style="color: #f8f8f2; font-weight: bold;">min</span>)) + $<span style="color: #f8f8f2; font-weight: bold;">min</span>}])
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: byte-a-hex
</span>    <span style="color: #6272a4;">#   Convierte un `byte` a una cadena hexadecimal
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `byte` valor binario que convierte en cadena
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   Una cadena con la expresi&#243;n en hexadecimal del byte proporcionado
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">byte-a-hex</span> {byte} {
        <span style="color: #ff79c6; font-weight: bold;">return</span> [<span style="color: #8be9fd; font-style: italic;">binary</span> encode hex $<span style="color: #f8f8f2; font-weight: bold;">byte</span>]
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: cad-a-num
</span>    <span style="color: #6272a4;">#   Convierte una cadena a una expresi&#243;n num&#233;rica resultante de tratar
</span>    <span style="color: #6272a4;">#   sus caracteres mediante los n&#250;meros que los representan.
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `cadena` Es una cadena de texto.
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   El valor num&#233;rico que la representa.
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">cad-a-num</span> {cadena} {
        <span style="color: #ff79c6; font-weight: bold;">return</span> [<span style="color: #8be9fd; font-style: italic;">format</span> %lld 0x[<span style="color: #8be9fd; font-style: italic;">binary</span> encode hex $<span style="color: #f8f8f2; font-weight: bold;">cadena</span>]]
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: num-a-cad
</span>    <span style="color: #6272a4;">#   Toma un n&#250;mero para convertirlo en cadena.
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `num` Un n&#250;mero que expresa los caracteres de una cadena
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   Una cadena
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">num-a-cad</span> {num} {
        <span style="color: #ff79c6; font-weight: bold;">return</span> [<span style="color: #8be9fd; font-style: italic;">binary</span> decode hex [<span style="color: #8be9fd; font-style: italic;">format</span> %llx $<span style="color: #f8f8f2; font-weight: bold;">num</span>]]
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: expmod
</span>    <span style="color: #6272a4;">#   Exponenciaci&#243;n modular. Calcula el residuo cuando una base se eleva
</span>    <span style="color: #6272a4;">#   a un exponente y se divide por el m&#243;dulo. Se utiliza para acelerar
</span>    <span style="color: #6272a4;">#   el c&#225;lculo con grandes n&#250;meros.
</span>    <span style="color: #6272a4;">#   (Algoritmo sacado de la wikipedia)
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `base` el n&#250;mero base
</span>    <span style="color: #6272a4;">#   `exp`  el exponente
</span>    <span style="color: #6272a4;">#   `mod`  el m&#243;dulo
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   El resultado de la exponenciaci&#243;n
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">expmod</span> {base exp mod} {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">x</span> 1
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">y</span> $<span style="color: #f8f8f2; font-weight: bold;">base</span>
        <span style="color: #ff79c6; font-weight: bold;">while</span> {$<span style="color: #f8f8f2; font-weight: bold;">exp</span> &gt; 0} {
            <span style="color: #ff79c6; font-weight: bold;">if</span> {($<span style="color: #f8f8f2; font-weight: bold;">exp</span> % 2) == 1} {<span style="color: #8be9fd; font-style: italic;">set</span> x [<span style="color: #8be9fd; font-style: italic;">expr</span> {($<span style="color: #f8f8f2; font-weight: bold;">x</span> * $<span style="color: #f8f8f2; font-weight: bold;">y</span>) % $<span style="color: #f8f8f2; font-weight: bold;">mod</span>}]}
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">y</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {($<span style="color: #f8f8f2; font-weight: bold;">y</span> * $<span style="color: #f8f8f2; font-weight: bold;">y</span>) % $<span style="color: #f8f8f2; font-weight: bold;">mod</span>}]
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">exp</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">exp</span> &gt;&gt; 1}]
        }
        <span style="color: #ff79c6; font-weight: bold;">return</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">x</span> % $<span style="color: #f8f8f2; font-weight: bold;">mod</span>}]
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: mr-test
</span>    <span style="color: #6272a4;">#   Proc. auxiliar del test de &#171;Miller-Rabin&#187; sobre primalidad, sacando
</span>    <span style="color: #6272a4;">#   el bucle de dentro del bucle principal.
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `d` llega como el entero inmediatamente inferior del n&#250;mero testado
</span>    <span style="color: #6272a4;">#   `n` el n&#250;mero testado
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   0 significa que `n` es compuesto
</span>    <span style="color: #6272a4;">#   1 significa que `n` es primo
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">mr-test</span> {d n} {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">a</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> [entero-entre 1 [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">n</span> - 1}]] + 2]
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">x</span> [expmod $<span style="color: #f8f8f2; font-weight: bold;">a</span> $<span style="color: #f8f8f2; font-weight: bold;">d</span> $<span style="color: #f8f8f2; font-weight: bold;">n</span>]
        <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">x</span> == 1 || $<span style="color: #f8f8f2; font-weight: bold;">x</span> == ($<span style="color: #f8f8f2; font-weight: bold;">n</span> - 1) } {<span style="color: #ff79c6; font-weight: bold;">return</span> 1}
        <span style="color: #ff79c6; font-weight: bold;">while</span> {$<span style="color: #f8f8f2; font-weight: bold;">d</span> != ($<span style="color: #f8f8f2; font-weight: bold;">n</span> - 1)} {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">x</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {($<span style="color: #f8f8f2; font-weight: bold;">x</span> * $<span style="color: #f8f8f2; font-weight: bold;">x</span>) % $<span style="color: #f8f8f2; font-weight: bold;">n</span>}]
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">d</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">d</span> * 2}]
            <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">x</span> == 1} {
                <span style="color: #ff79c6; font-weight: bold;">return</span> 0
            } <span style="color: #ff79c6; font-weight: bold;">elseif</span> {$<span style="color: #f8f8f2; font-weight: bold;">x</span> == ($<span style="color: #f8f8f2; font-weight: bold;">n</span> - 1)} {
                <span style="color: #ff79c6; font-weight: bold;">return</span> 1
            }
        }
        <span style="color: #ff79c6; font-weight: bold;">return</span> 0
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: miller-rabin
</span>    <span style="color: #6272a4;">#   Algoritmo de primalidad probabil&#237;stico pero altamente utilizado en
</span>    <span style="color: #6272a4;">#   criptograf&#237;a. Est&#225; dise&#241;ado para evitar los falsos positivos.
</span>    <span style="color: #6272a4;">#   (Algoritmo sacado de la wikipedia, aunque adaptado)
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `n` El n&#250;mero cuya primalidad deseamos probar
</span>    <span style="color: #6272a4;">#   `k` El n&#250;mero de pruebas que queremos hacer
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   0 significa que el n&#250;mero `n` es compuesto
</span>    <span style="color: #6272a4;">#   1 significa que el n&#250;mero `n` es primo
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">miller-rabin</span> { n k } {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">d</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">n</span> - 1}]
        <span style="color: #ff79c6; font-weight: bold;">while</span> { ($<span style="color: #f8f8f2; font-weight: bold;">d</span> % 2) == 0 } {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">d</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">d</span> &gt;&gt; 1}]
        }
        <span style="color: #ff79c6; font-weight: bold;">for</span> {<span style="color: #8be9fd; font-style: italic;">set</span> i 0} {$<span style="color: #f8f8f2; font-weight: bold;">i</span> &lt; $<span style="color: #f8f8f2; font-weight: bold;">k</span>} {<span style="color: #8be9fd; font-style: italic;">incr</span> i} {
            <span style="color: #ff79c6; font-weight: bold;">if</span> {[mr-test $<span style="color: #f8f8f2; font-weight: bold;">d</span> $<span style="color: #f8f8f2; font-weight: bold;">n</span>] == 0} {
                <span style="color: #ff79c6; font-weight: bold;">return</span> 0
            }
        }
        <span style="color: #ff79c6; font-weight: bold;">return</span> 1
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: es-primo
</span>    <span style="color: #6272a4;">#   Determina si un n&#250;mero es primo.
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `num` El n&#250;mero cuya primalidad ser&#225; testeada
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   0 si el n&#250;mero `num` es compuesto
</span>    <span style="color: #6272a4;">#   1 si el n&#250;mero `num` es primo
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">es-primo</span> num {
        <span style="color: #6272a4;"># la variable `k` podr&#237;a ajustarse por par&#225;metro.
</span>        <span style="color: #6272a4;"># de momento la calculo en base a la cantidad de bits de `num`, de
</span>        <span style="color: #6272a4;"># esta manera habr&#225; un muestreo proporcional al tama&#241;o del n&#250;mero
</span>        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">k</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {2 * [num-bits $<span style="color: #f8f8f2; font-weight: bold;">num</span>]}]
        <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">k</span> &lt; 8} {<span style="color: #8be9fd; font-style: italic;">set</span> k 8}
        <span style="color: #6272a4;"># hacer la prueba `k` veces
</span>        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">primo</span> [miller-rabin $<span style="color: #f8f8f2; font-weight: bold;">num</span> $<span style="color: #f8f8f2; font-weight: bold;">k</span>]
        <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">primo</span>
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: generar-primo
</span>    <span style="color: #6272a4;">#   Devuelve un n&#250;mero primo del tama&#241;o en bytes especificado
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `s` es el tama&#241;o en bytes del n&#250;mero deseado
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   Un n&#250;mero primo
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">generar-primo</span> s {
        <span style="color: #ff79c6; font-weight: bold;">while</span> { 1 } {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">p</span> [aleatorio $<span style="color: #f8f8f2; font-weight: bold;">s</span>]
            <span style="color: #ff79c6; font-weight: bold;">if</span> {($<span style="color: #f8f8f2; font-weight: bold;">p</span> % 2) == 0} {
                <span style="color: #ff79c6; font-weight: bold;">continue</span>
            } <span style="color: #ff79c6; font-weight: bold;">else</span> {
                <span style="color: #ff79c6; font-weight: bold;">if</span> { [es-primo $<span style="color: #f8f8f2; font-weight: bold;">p</span>] } {
                    <span style="color: #ff79c6; font-weight: bold;">break</span>
                }
            }
        }
        <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">p</span>
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: pow
</span>    <span style="color: #6272a4;">#   Calcula la potencia de la base `b` calculando s&#243;lo las cifras &#171;1&#187;
</span>    <span style="color: #6272a4;">#   (o significativas) del exponente `e` expresado como binario.
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `b` Base del c&#225;lculo
</span>    <span style="color: #6272a4;">#   `e` Exponente del c&#225;lculo
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   Devuelve el c&#225;lculo b^e
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">pow</span> { b e } {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">r</span> 1
        <span style="color: #ff79c6; font-weight: bold;">while</span> {$<span style="color: #f8f8f2; font-weight: bold;">e</span> &gt; 0} {
            <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">e</span> &amp; 1} {
                <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">r</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">r</span> * $<span style="color: #f8f8f2; font-weight: bold;">b</span>}]
            }
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">b</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">b</span> * $<span style="color: #f8f8f2; font-weight: bold;">b</span>}]
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">e</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">e</span> &gt;&gt; 1}]
        }
        <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">r</span>
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: mcd (m&#225;ximo com&#250;n divisor)
</span>    <span style="color: #6272a4;">#   Calcula el m.c.d. de dos n&#250;meros
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `a` Uno de los n&#250;meros
</span>    <span style="color: #6272a4;">#   `b` El otro n&#250;mero
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   El m&#225;ximo com&#250;n divisor de los dos n&#250;meros
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">mcd</span> {a b} {
        <span style="color: #ff79c6; font-weight: bold;">while</span> {$<span style="color: #f8f8f2; font-weight: bold;">a</span> != $<span style="color: #f8f8f2; font-weight: bold;">b</span>} {
            <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">a</span> &gt; $<span style="color: #f8f8f2; font-weight: bold;">b</span>} {
                <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">a</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">a</span> - $<span style="color: #f8f8f2; font-weight: bold;">b</span>}]
            } <span style="color: #ff79c6; font-weight: bold;">else</span> {
                <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">b</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">b</span> - $<span style="color: #f8f8f2; font-weight: bold;">a</span>}]
            }
        }
        <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">a</span>
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: mcm (m&#237;nimo com&#250;n m&#250;ltiplo)
</span>    <span style="color: #6272a4;">#   Calcula el m.c.m. de dos n&#250;meros sabiendo la relaci&#243;n que hay con
</span>    <span style="color: #6272a4;">#   el m&#225;ximo com&#250;n divisor, que es bastante m&#225;s r&#225;pido de calcular:
</span>    <span style="color: #6272a4;">#                 a x b
</span>    <span style="color: #6272a4;">#   mcm(a, b) = ---------
</span>    <span style="color: #6272a4;">#               mcd(a, b)
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `a` Uno de los n&#250;meros a calcular
</span>    <span style="color: #6272a4;">#   `b` El otro n&#250;mero
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   El m&#237;nimo com&#250;n m&#250;ltiplo de dos n&#250;meros
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">mcm</span> {a b} {
        <span style="color: #ff79c6; font-weight: bold;">return</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">a</span> * $<span style="color: #f8f8f2; font-weight: bold;">b</span> / [mcd $<span style="color: #f8f8f2; font-weight: bold;">a</span> $<span style="color: #f8f8f2; font-weight: bold;">b</span>]}]
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: modinverso
</span>    <span style="color: #6272a4;">#   Calcula el inverso de un m&#243;dulo. Dado un exponente y un m&#243;dulo
</span>    <span style="color: #6272a4;">#   encuentra otro exponente congruente con ellos. Si no existe un
</span>    <span style="color: #6272a4;">#   n&#250;mero congruente termina lanzando un error `divide by cero`. En
</span>    <span style="color: #6272a4;">#   ese caso devuelve un `-1`.
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `e` Exponente calculado con anterioridad
</span>    <span style="color: #6272a4;">#   `phi` el phi(n) calculado
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   El segundo exponente para el c&#225;lculo del RSA
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">modinverso</span> { e phi } {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">m0</span> $<span style="color: #f8f8f2; font-weight: bold;">phi</span>
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">y</span> 0
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">x</span> 1

        try {
            <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">phi</span> == 1} {<span style="color: #ff79c6; font-weight: bold;">return</span> 0}
            <span style="color: #ff79c6; font-weight: bold;">while</span> {$<span style="color: #f8f8f2; font-weight: bold;">e</span> &gt; 1} {
                <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">q</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">e</span> / $<span style="color: #f8f8f2; font-weight: bold;">phi</span>}]
                <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">t</span> $<span style="color: #f8f8f2; font-weight: bold;">phi</span>

                <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">phi</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">e</span> % $<span style="color: #f8f8f2; font-weight: bold;">phi</span>}]
                <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">e</span> $<span style="color: #f8f8f2; font-weight: bold;">t</span>
                <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">t</span> $<span style="color: #f8f8f2; font-weight: bold;">y</span>

                <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">y</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">x</span> - $<span style="color: #f8f8f2; font-weight: bold;">q</span> * $<span style="color: #f8f8f2; font-weight: bold;">y</span>}]
                <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">x</span> $<span style="color: #f8f8f2; font-weight: bold;">t</span>
            }
            <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">x</span> &lt; 0} {
                <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">x</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">x</span> + $<span style="color: #f8f8f2; font-weight: bold;">m0</span>}]
            }
            <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">x</span>
        } on <span style="color: #ff79c6; font-weight: bold;">error</span> {} {
            <span style="color: #ff79c6; font-weight: bold;">return</span> -1
        }
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: generar-clave
</span>    <span style="color: #6272a4;">#   Genera una clave completa con un tama&#241;o `t` en bytes.
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `t` Tama&#241;o m&#237;nimo en bytes de la clave
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   Un diccionario con los datos de la clave generada
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">generar-clave</span> {t} {
        <span style="color: #8be9fd; font-style: italic;">puts</span> <span style="color: #f1fa8c;">"Generando clave aleatoria de [expr {16 * $t}] bits"</span>

        <span style="color: #6272a4;"># 1. generar dos n&#250;meros primos
</span>        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">p</span> [generar-primo $<span style="color: #f8f8f2; font-weight: bold;">t</span>]
        <span style="color: #ff79c6; font-weight: bold;">while</span> { 1 } {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">q</span> [generar-primo $<span style="color: #f8f8f2; font-weight: bold;">t</span>]
            <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">p</span> != $<span style="color: #f8f8f2; font-weight: bold;">q</span>} <span style="color: #ff79c6; font-weight: bold;">break</span>
        }
        dict <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"p"</span> $<span style="color: #f8f8f2; font-weight: bold;">p</span>
        dict <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"q"</span> $<span style="color: #f8f8f2; font-weight: bold;">q</span>

        <span style="color: #6272a4;"># 2. Calcular el m&#243;dulo
</span>        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">n</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">p</span> * $<span style="color: #f8f8f2; font-weight: bold;">q</span>}]
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">t</span> [num-bits $<span style="color: #f8f8f2; font-weight: bold;">n</span>]
        dict <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"n"</span> $<span style="color: #f8f8f2; font-weight: bold;">n</span>
        dict <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"t"</span> $<span style="color: #f8f8f2; font-weight: bold;">t</span>

        <span style="color: #6272a4;"># 3. Calcular `phi(n)`
</span>        <span style="color: #6272a4;">#
</span>        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">phiN</span> [mcm [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">p</span> - 1}] [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">q</span> - 1}]]
        dict <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"phi(n)"</span> $<span style="color: #f8f8f2; font-weight: bold;">phiN</span>

        <span style="color: #6272a4;"># 4. Calcular el exponente
</span>        <span style="color: #6272a4;">#    `e` &#191;65537?
</span>        <span style="color: #6272a4;">#
</span>        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">e</span> [aleatorio [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">t</span> / 8}]]
        dict <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"e"</span> $<span style="color: #f8f8f2; font-weight: bold;">e</span>

        <span style="color: #6272a4;"># 5. Calcular el exponente `d`
</span>        <span style="color: #6272a4;">#
</span>        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">d</span> [modinverso $<span style="color: #f8f8f2; font-weight: bold;">e</span>  $<span style="color: #f8f8f2; font-weight: bold;">phiN</span>]
        dict <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"d"</span> $<span style="color: #f8f8f2; font-weight: bold;">d</span>

        <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">key</span>
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: rsa-encript
</span>    <span style="color: #6272a4;">#   Cifra una cadena dada con los datos proporcionados por una clave.
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `cadena` es la cadena de texto que queremos cifrar.
</span>    <span style="color: #6272a4;">#   `key` es un diccionario que debe tener al menos dos elementos:
</span>    <span style="color: #6272a4;">#         `n` es el m&#243;dulo de cifrado-descifrado RSA.
</span>    <span style="color: #6272a4;">#         `e` es el exponente de cifrado RSA.
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   Un n&#250;mero que representa la cadena codificada.
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">rsa-encript</span> {cadena key} {
        <span style="color: #6272a4;"># Convertir la cadena de entrada en un n&#250;mero
</span>        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">num</span> [cad-a-num $<span style="color: #f8f8f2; font-weight: bold;">cadena</span>]
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">n</span> [dict get $<span style="color: #f8f8f2; font-weight: bold;">key</span> n]
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">e</span> [dict get $<span style="color: #f8f8f2; font-weight: bold;">key</span> e]
        <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">num</span> &lt; $<span style="color: #f8f8f2; font-weight: bold;">n</span>} {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">resultado</span> [expmod $<span style="color: #f8f8f2; font-weight: bold;">num</span> $<span style="color: #f8f8f2; font-weight: bold;">e</span> $<span style="color: #f8f8f2; font-weight: bold;">n</span>]
        } <span style="color: #ff79c6; font-weight: bold;">else</span> {
            <span style="color: #ff79c6; font-weight: bold;">error</span> <span style="color: #f1fa8c;">"&#171;$cadena&#187; es demasiado largo para la clave especificada."</span>
        }
        <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">resultado</span>
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: rsa-decript
</span>    <span style="color: #6272a4;">#   Descifra un n&#250;mero que contiene un mensaje cifrado mediante RSA.
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `num` el n&#250;mero que hay que descifrar
</span>    <span style="color: #6272a4;">#   `key` un diccionario que debe contener al menos dos elementos:
</span>    <span style="color: #6272a4;">#         `n` es el m&#243;dulo de cifrado-descifrado RSA.
</span>    <span style="color: #6272a4;">#         `d` es el exponente de descifrado RSA.
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   La cadena descifrada.
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">rsa-decript</span> { num key } {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">n</span> [dict get $<span style="color: #f8f8f2; font-weight: bold;">key</span> n]
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">d</span> [dict get $<span style="color: #f8f8f2; font-weight: bold;">key</span> d]
        <span style="color: #ff79c6; font-weight: bold;">return</span> [num-a-cad [expmod $<span style="color: #f8f8f2; font-weight: bold;">num</span> $<span style="color: #f8f8f2; font-weight: bold;">d</span> $<span style="color: #f8f8f2; font-weight: bold;">n</span>]]
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: obtener-claves
</span>    <span style="color: #6272a4;">#   Obtiene un par de ficheros con la clave p&#250;blica y la clave privada.
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `t` es el tama&#241;o de la clave.
</span>    <span style="color: #6272a4;">#   `nombre` una cadena de texto que ser&#225; el nombre utilizado para las
</span>    <span style="color: #6272a4;">#            claves generadas.
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   Nada
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">obtener-claves</span> {t nombre} {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> [generar-clave $<span style="color: #f8f8f2; font-weight: bold;">t</span>]

        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">tam</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">t</span> + 1}]
        <span style="color: #ff79c6; font-weight: bold;">while</span> {[dict get $<span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"d"</span>] == -1 | [dict get $<span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"t"</span>] &lt; (16 * $<span style="color: #f8f8f2; font-weight: bold;">t</span>)} {
            <span style="color: #ff79c6; font-weight: bold;">if</span> {[dict get $<span style="color: #f8f8f2; font-weight: bold;">key</span> <span style="color: #f1fa8c;">"d"</span>] == -1} {
                <span style="color: #8be9fd; font-style: italic;">puts</span> <span style="color: #f1fa8c;">"Clave indefinida."</span>
            } <span style="color: #ff79c6; font-weight: bold;">else</span> {
                <span style="color: #8be9fd; font-style: italic;">puts</span> <span style="color: #f1fa8c;">"Clave incompleta."</span>
                <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">tam</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">tam</span> + 1}]
            }
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> [generar-clave $<span style="color: #f8f8f2; font-weight: bold;">tam</span>]
        }

        <span style="color: #6272a4;"># Escribir clave p&#250;blica
</span>        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">fpub</span> <span style="color: #f1fa8c;">"$nombre-pub.key"</span>
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">f</span> [<span style="color: #8be9fd; font-style: italic;">open</span> $<span style="color: #f8f8f2; font-weight: bold;">fpub</span> w]
        <span style="color: #8be9fd; font-style: italic;">puts</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span> <span style="color: #f1fa8c;">"n:[dict get $key n]\ne:[dict get $key e]"</span>
        <span style="color: #8be9fd; font-style: italic;">close</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span>
        <span style="color: #6272a4;"># Escribir clave privada
</span>        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">fpriv</span> <span style="color: #f1fa8c;">"$nombre-priv.key"</span>
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">f</span> [<span style="color: #8be9fd; font-style: italic;">open</span> $<span style="color: #f8f8f2; font-weight: bold;">fpriv</span> w]
        <span style="color: #ff79c6; font-weight: bold;">foreach</span> {k v} $<span style="color: #f8f8f2; font-weight: bold;">key</span> {
            <span style="color: #8be9fd; font-style: italic;">puts</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span> <span style="color: #f1fa8c;">"$k:$v"</span>
        }
        <span style="color: #8be9fd; font-style: italic;">close</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span>
        <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">key</span>
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: leer-fichero-claves
</span>    <span style="color: #6272a4;">#   Lee el fichero de claves dado en el argumento `nombre`
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `nombre` debe ser un nombre de archivo.
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   un diccionario con los valores de la clave encontrados en el fichero.
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">leer-fichero-clave</span> {nombre} {
        try {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">f</span> [<span style="color: #8be9fd; font-style: italic;">open</span> $<span style="color: #f8f8f2; font-weight: bold;">nombre</span> r]
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">datos</span> [<span style="color: #8be9fd; font-style: italic;">split</span> [<span style="color: #8be9fd; font-style: italic;">read</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span>] <span style="color: #f1fa8c;">"\n:"</span>]
            <span style="color: #8be9fd; font-style: italic;">close</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span>
        }

        <span style="color: #ff79c6; font-weight: bold;">foreach</span> {k v} [<span style="color: #8be9fd; font-style: italic;">lrange</span> $<span style="color: #f8f8f2; font-weight: bold;">datos</span> 0 [<span style="color: #8be9fd; font-style: italic;">expr</span> {[<span style="color: #8be9fd; font-style: italic;">llength</span> $<span style="color: #f8f8f2; font-weight: bold;">datos</span>] - 2}]] {
            dict <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">key</span> $<span style="color: #f8f8f2; font-weight: bold;">k</span> $<span style="color: #f8f8f2; font-weight: bold;">v</span>
        }
        <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">key</span>
    }
}
</pre>
</div>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Hay que recordar aquí, que el tamaño de la clave será el
cuadrado del tamaño que entra en la función, pues \(n=p \cdot q\) y cada
número primo, tanto <i>p</i> como <i>q</i> tendrán el tamaño <i>t</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Aunque sólo sucedió en una ocasión y para tamaño de clave
pequeño. Pero no está de más asegurarnos que son distintos. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/criptografia/index.html">criptografia</a> ]]></description>
  <category><![CDATA[criptografia]]></category>
  <link>https://notxor.nueva-actitud.org/2022/07/28/codificar-y-descodificar-cadenas-con-el-algoritmo-rsa.html</link>
  <pubDate>Thu, 28 Jul 2022 18:56:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Generando un número primo grande]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-07-23</div>
<p>
El título de este artículo podría haber sido <i>algoritmo de cifrado RSA
palote palote</i>. <a href="https://notxor.nueva-actitud.org/2022/07/21/algoritmo-de-cifrado-rsa.html">En el artículo anterior</a> comencé a hablar sobre cifrado
mediante RSA y expliqué cómo funciona el algoritmo, en este abundo un
poco más y comienzo la implementación en código. Voy a llegar hasta el
momento de la generación de un número primo grande (muy grande), los
algoritmos que he empleado y algunas otras cosas «laterales» que he
considerado interesante explicar. Si te gustan los números primos
sigue leyendo... y si no, pues sigue leyendo, que siempre se aprende
algo.
</p>

<p>
Debo también explicar, que como últimamente le estaba dando al
<a href="https://tcl.tk">Tcl/Tk</a><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> pensé en realizarlo sin necesidad de forzar a mis
neuronas más de la cuenta cambiando de lenguaje. Si programas en otros
lenguajes no debería ser muy difícil seguir el código escrito. En cada
función he añadido comentarios con una breve explicación de lo que
hace, qué es cada parámetro y que devuelve. Como puesto así, <i>a
cachos</i>, es posible que no dé una idea general de cómo funciona, lo
pondré todo junto, en un sólo listado, al final del artículo, por si
alguien tiene la curiosidad de probarlo. El dividirlo, durante la
explicación, en pequeños fragmentos, es porque es más fácil de
encontrar el código al que hago referencia. Pero vamos al tajo.
</p>

<p>
Conseguir un generador de números primos de cualquier tamaño es el
objetivo. Mi forma de trabajar es el habitual: unos pocos <i>tests</i> y a
cumplirlos:
</p>

<div class="org-src-container">
<pre class="src src-tcl">test esPrimo3 { <span style="color: #f1fa8c;">"Tres es primo"</span> }     -body { es-primo 3 }    -result 1
test esPrimo5 { <span style="color: #f1fa8c;">"Cinco es primo"</span> }    -body { es-primo 5 }    -result 1
test esPrimo8 { <span style="color: #f1fa8c;">"Ocho no es primo"</span> }  -body { es-primo 8 }    -result 0
test esPrimo9 { <span style="color: #f1fa8c;">"Nueve no es primo"</span>}  -body { es-primo 9 }    -result 0
test esPrimo11 { <span style="color: #f1fa8c;">"Once es primo"</span> }    -body { es-primo 11 }   -result 1
test esPrimo977 { <span style="color: #f1fa8c;">"977 es primo"</span> }    -body { es-primo 977 }  -result 1
test esPrimo978 { <span style="color: #f1fa8c;">"978 no es primo"</span> } -body { es-primo 978 }  -result 0
test esPrimo1999 { <span style="color: #f1fa8c;">"1999 es primo"</span> }  -body { es-primo 1999 } -result 1
test esPrimo2915 { <span style="color: #f1fa8c;">"2915 no"</span> }        -body { es-primo 2915 } -result 0
test esPrimo3571 { <span style="color: #f1fa8c;">"3571 es primo"</span> }  -body { es-primo 3571 } -result 1
</pre>
</div>

<p>
La lista de <i>tests</i> de números primos, y compuestos, puede ser tan
larga como quieras. Pongo estos sólo como muestra.
</p>

<p>
Por supuesto, de momento fallarán todos los <i>tests</i> porque ni siquiera
existe la función <code>es-primo</code>, pero podemos ver que dicha función
necesitará un parámetro numérico y deberá devolver 1 si el parámetro
es un número primo y 0 si el parámetro en un número compuesto.
</p>

<p>
El primer procedimiento que creo será <code>es-primo</code>:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">es-primo</span> num {
    <span style="color: #ff79c6; font-weight: bold;">return</span> 0
}
</pre>
</div>

<p>
Evidentemente fallará en la mitad de los <i>tests</i> de los números que
sean primos, pero al menos me he quitado la ristra de errores que
dicen que no existe el procedimiento llamado.
</p>

<p>
Otro hecho, aunque este puramente subjetivo, es la desazón que me
produce el que algún <i>test</i> falle. Independientemente de que sepa el
motivo, o falte algo por implementar y esté seguro de que es lo
esperado... el desasosiego se apodera de mí. Hay que picar código
hasta conseguir pasarlos todos. Pero primero hay que saber qué
escribir y aquí me tropecé con <i>el problema de la primalidad</i>.
</p>
<div id="outline-container-org3c92d77" class="outline-2">
<h2 id="org3c92d77">El problema de primalidad</h2>
<div class="outline-text-2" id="text-org3c92d77">
<p>
Pensaba que a estas alturas las cosas estarían mejor resueltas, pero
encontré que el problema de la <i>primalidad</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>, aún tiene algunas
aristas que pulir. Me gustaría, por aquello de la seguridad, tener la
certeza de estar empleando un par de números primos para la
tarea. Saber la primalidad en números pequeños es bastante sencillo,
pero los que necesito son enormes y es más complicado asegurarnos.
Encontré dos formas de determinar la <i>primalidad</i> que podían
servirme. Podría hacer algo de historia, porque este problema viene ya
desde la Antigua Grecia y hay algoritmos de todo tipo para determinar
si un número es primo. Pero por no enrollarme demasiado hablaré de los
dos métodos más aceptados a estas alturas:
</p>

<ul class="org-ul">
<li>Algoritmos con certeza
<ul class="org-ul">
<li>Algoritmo de <i>Lucas-Lehmer</i></li>
<li>Algoritmo AKS</li>
</ul></li>
<li>Algoritmos probabilísticos
<ul class="org-ul">
<li>Algoritmo <i>Miller-Rabin</i></li>
</ul></li>
</ul>

<p>
Primero probé con algoritmos seguros, concretamente el de
<i>Lucas-Lehmer</i> me pareció bastante sencillo de implementar.
</p>
</div>
<div id="outline-container-org3aa0428" class="outline-3">
<h3 id="org3aa0428">Algoritmo de Lucas-Lehmer</h3>
<div class="outline-text-3" id="text-org3aa0428">
<p>
Lo podéis <a href="https://es.wikipedia.org/wiki/Test_de_primalidad#Tests_verdaderos_de_primalidad">encontrar en la wikipedia</a>, no voy a entrar en más
explicaciones ni darle más a las matemáticas. A continuación pongo la
implementación del algoritmo, tal y como la escribí:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">lucas-lehmer</span> num {
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">s</span> 4
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">m</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {(2 ** $<span style="color: #f8f8f2; font-weight: bold;">num</span>) - 1}]
    <span style="color: #ff79c6; font-weight: bold;">for</span> {<span style="color: #8be9fd; font-style: italic;">set</span> j 2} {$<span style="color: #f8f8f2; font-weight: bold;">j</span> &lt;= ($<span style="color: #f8f8f2; font-weight: bold;">num</span> - 1)} {<span style="color: #8be9fd; font-style: italic;">incr</span> j} {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">sj</span> $<span style="color: #f8f8f2; font-weight: bold;">s</span>
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">s</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {(($<span style="color: #f8f8f2; font-weight: bold;">sj</span> ** 2) - 2) % $<span style="color: #f8f8f2; font-weight: bold;">m</span>}]
        <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">sj</span> == 0} {<span style="color: #ff79c6; font-weight: bold;">return</span> 1}
    }
    <span style="color: #ff79c6; font-weight: bold;">return</span> 0
}
</pre>
</div>

<p>
Sencillo de entender y escribir, va probando si hay algún
\(2 \leq x \leq n-1\) que divida de forma exacta a \(n\), pero nos
encontramos con un problema de ejecución:
</p>

<pre class="example" id="orgfdf7e6e">
% rsa::generar-primo 8
exponent too large
</pre>

<p>
Vale, si el número es muy grande, que para lo que necesitamos 8 bytes
es pequeño, no funciona... la solución pasa por implementar una
exponenciación más resultona y que funcione con números grandes.
</p>

<p>
Para eso implementé una función de exponenciación rápida... también
podéis mirar el algoritmo y las explicaciones en la <i>wikipedia</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">exp-rapida</span> {base exp} {
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">res</span> 1
    <span style="color: #ff79c6; font-weight: bold;">for</span> {<span style="color: #8be9fd; font-style: italic;">set</span> i 1} {$<span style="color: #f8f8f2; font-weight: bold;">i</span> &lt;= $<span style="color: #f8f8f2; font-weight: bold;">exp</span>} {<span style="color: #8be9fd; font-style: italic;">incr</span> 1} {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">res</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">res</span> * $<span style="color: #f8f8f2; font-weight: bold;">exp</span>}]
    }
    <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">res</span>
}
</pre>
</div>

<p>
Es rápida porque no debe hacer todos los cálculos, pero aún así es
lenta. Al final el tiempo empleado entre unas cosas y otras hace que
este algoritmo sea impracticable. Para números primos de 8 bytes se
podía pasar, tranquilamente, una hora calculando. Utilizarlo para
números de \(2^8\) bits hubiera sido morir en el intento.
</p>

<p>
Estuve mirando también el algoritmo AKS, que menciono antes, pero es
mucho más lioso. Había seis pasos, cada uno de ellos lento, con muchos
bucles y, he de confesar que a ojo, me pareció aún lento aún que el
<i>Lucas-Lehmer</i>.
</p>
</div>
</div>
<div id="outline-container-org8aedfe1" class="outline-3">
<h3 id="org8aedfe1">Algoritmo de Miller-Rabin</h3>
<div class="outline-text-3" id="text-org8aedfe1">
<p>
La otra opción era implementar uno probabilístico... y escogí el
algoritmo de <i>Miller-Rabin</i> por dos motivos:
</p>

<ol class="org-ol">
<li>Sin tener mucha idea de por qué, aunque leí unas parrafadas enormes
con justificaciones matemáticas, es el más utilizado en
criptografía.</li>
<li>Siendo un algoritmo probabilístico, parece estar diseñado para
reducir al máximo la existencia de falsos positivos. Es decir, que
si falla en su respuesta, posiblemente esté descartando algún
número primo considerándolo <i>compuesto</i>, pero al final, las
operaciones del algoritmo <i>RSA</i> se realizarán con una seguridad
razonable asumiendo que los números utilizados son primos.</li>
</ol>

<p>
El inconveniente: algunos <i>tests</i> fallan algunas veces, especialmente
con números pequeños y no es raro que rechace el 5 y el 11
considerándolos como compuestos. La precisión del algoritmo depende
también del número de iteraciones que utilizas y yo lo hice
dependiente del tamaño del número que queremos probar.
</p>

<p>
El algoritmo funciona de la siguiente forma:
</p>

<ul class="org-ul">
<li>Dado un número \(n > 1\) y el número de veces \(k\) que queremos
probarlo</li>
<li>Se definen \(r\) y \(s\) tal que \(r\) es impar y \((n - 1)=r \cdot 2^s\)</li>
<li><b>Para</b> \(1 \leq j \leq k\) <b>hacer</b>:
<ol class="org-ol">
<li>\(a \leftarrow x\) siendo \(x\) un entero aleatorio entre \([n, n-2]\)</li>
<li>\(y \leftarrow a^r \; mod \, n\)</li>
<li><b>Si</b> \((y \neq 1) \land (y \neq n - 1)\) <b>entonces</b>:
<ol class="org-ol">
<li>\(j \leftarrow 1\)</li>
<li><b>Mientras</b> \(j \leq (s - 1) \land y \neq (n-1)\) <b>hacer</b>:
<ol class="org-ol">
<li>\(y \leftarrow y^2 \; mod \, n\)</li>
<li><b>Si</b> \(y = 1\) <b>entonces</b> devolver <i>compuesto</i></li>
<li>\(j \leftarrow j + 1\)</li>
</ol></li>
<li><b>Si</b> \(y \neq (n-1)\) <b>entonces</b> devolver <i>compuesto</i></li>
</ol></li>
</ol></li>
<li>devolver <i>posible primo</i></li>
</ul>

<p>
El algoritmo también presenta cierta sencillez, aunque no deja de ser
un bucle dentro de un bucle. Lo he implementado de la siguiente
manera:
</p>

<div class="org-src-container">
<pre class="src src-tcl">  <span style="color: #6272a4;"># ######################################################################
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Procedimiento: mr-test
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">Proc. auxiliar del test de &#171;Miller-Rabin&#187; sobre primalidad, sacando
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">el bucle de dentro del bucle principal.
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Par&#225;metros:
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">`d` llega como el entero inmediatamente inferior del n&#250;mero testado
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">`n` el n&#250;mero testado
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Devuelve:
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">0 significa que `n` es compuesto
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">1 significa que `n` es primo
</span><span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">mr-test</span> {d n} {
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">a</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> 2 + [entero-entre 1 [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">n</span> - 1}]]]
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">x</span> [expmod $<span style="color: #f8f8f2; font-weight: bold;">a</span> $<span style="color: #f8f8f2; font-weight: bold;">d</span> $<span style="color: #f8f8f2; font-weight: bold;">n</span>]
    <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">x</span> == 1 || $<span style="color: #f8f8f2; font-weight: bold;">x</span> == ($<span style="color: #f8f8f2; font-weight: bold;">n</span> - 1) } {<span style="color: #ff79c6; font-weight: bold;">return</span> 1}
    <span style="color: #ff79c6; font-weight: bold;">while</span> {$<span style="color: #f8f8f2; font-weight: bold;">d</span> != ($<span style="color: #f8f8f2; font-weight: bold;">n</span> - 1)} {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">x</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {($<span style="color: #f8f8f2; font-weight: bold;">x</span> * $<span style="color: #f8f8f2; font-weight: bold;">x</span>) % $<span style="color: #f8f8f2; font-weight: bold;">n</span>}]
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">d</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">d</span> * 2}]
        <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">x</span> == 1} {
            <span style="color: #ff79c6; font-weight: bold;">return</span> 0
        } <span style="color: #ff79c6; font-weight: bold;">elseif</span> {$<span style="color: #f8f8f2; font-weight: bold;">x</span> == ($<span style="color: #f8f8f2; font-weight: bold;">n</span> - 1)} {
            <span style="color: #ff79c6; font-weight: bold;">return</span> 1
        }
    }
    <span style="color: #ff79c6; font-weight: bold;">return</span> 0
}

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">######################################################################
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Procedimiento: miller-rabin
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">Algoritmo de primalidad probabil&#237;stico pero altamente utilizado en
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">criptograf&#237;a. Est&#225; dise&#241;ado para evitar los falsos positivos.
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">(Algoritmo sacado de la wikipedia, aunque adaptado)
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Par&#225;metros:
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">`n` El n&#250;mero cuya primalidad deseamos probar
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">`k` El n&#250;mero de pruebas que queremos hacer
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Devuelve:
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">0 significa que el n&#250;mero `n` es compuesto
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">1 significa que el n&#250;mero `n` es primo
</span><span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">miller-rabin</span> { n k } {
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">d</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">n</span> - 1}]
    <span style="color: #ff79c6; font-weight: bold;">while</span> { ($<span style="color: #f8f8f2; font-weight: bold;">d</span> % 2) == 0 } {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">d</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">d</span> &gt;&gt; 1}]
    }
    <span style="color: #ff79c6; font-weight: bold;">for</span> {<span style="color: #8be9fd; font-style: italic;">set</span> i 0} {$<span style="color: #f8f8f2; font-weight: bold;">i</span> &lt; $<span style="color: #f8f8f2; font-weight: bold;">k</span>} {<span style="color: #8be9fd; font-style: italic;">incr</span> i} {
        <span style="color: #ff79c6; font-weight: bold;">if</span> {[mr-test $<span style="color: #f8f8f2; font-weight: bold;">d</span> $<span style="color: #f8f8f2; font-weight: bold;">n</span>] == 0} {
            <span style="color: #ff79c6; font-weight: bold;">return</span> 0
        }
    }
    <span style="color: #ff79c6; font-weight: bold;">return</span> 1
}
</pre>
</div>

<p>
He sacado el bucle interno a otra función auxiliar pero básicamente es
lo mismo. Hay que recordar que con esta función, la probabilidad de
falso positivo es \((\frac{1}{4})^k\). A mayor \(k\) es más pequeña la
probabilidad de que sea un falso primo.
</p>

<p>
He hecho depender el número de pruebas del tamaño del número. Para
saber el número de bits de un número utilizo la siguiente función:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #6272a4;"># </span><span style="color: #6272a4;">######################################################################
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Procedimiento: num-bits
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">Devuelve el n&#250;mero de bits empleados para representar un n&#250;mero entero
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Par&#225;metros:
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">`valor` representa el n&#250;mero del que queremos saber el tama&#241;o
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Devuelve:
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">La cantidad de bits empleados en la representaci&#243;n del n&#250;mero
</span><span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">num-bits</span> valor {
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">bits</span> -1
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">p</span> 0
    <span style="color: #ff79c6; font-weight: bold;">while</span> {$<span style="color: #f8f8f2; font-weight: bold;">valor</span> &gt;= $<span style="color: #f8f8f2; font-weight: bold;">p</span>} {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">p</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {(1 &lt;&lt; [<span style="color: #8be9fd; font-style: italic;">incr</span> bits])}]
    }
    <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">bits</span>
}
</pre>
</div>

<p>
Antes se llamaba al test de primalidad directamente. Sin embargo, al
incluir la necesidad de añadir el número de veces que debe hacer la
prueba, se ha optado por poner una función <code>es-primo</code> intermedia entre
las funciones de <code>generar-primo</code> y la de test, <code>miller-rabin</code>.
</p>

<p>
Esta función se llama desde el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #6272a4;"># </span><span style="color: #6272a4;">######################################################################
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Procedimiento: es-primo
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">Determina si un n&#250;mero es primo.
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Par&#225;metros:
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">`num` El n&#250;mero cuya primalidad ser&#225; testeada
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Devuelve:
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">0 si el n&#250;mero `num` es compuesto
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">1 si el n&#250;mero `num` es primo
</span><span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">es-primo</span> num {
    <span style="color: #6272a4;"># la variable `k` podr&#237;a ajustarse por par&#225;metro.
</span>    <span style="color: #6272a4;"># de momento la calculo en base a la cantidad de bits de `num`, de
</span>    <span style="color: #6272a4;"># esta manera habr&#225; un muestreo proporcional al tama&#241;o del n&#250;mero
</span>    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">k</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {2 * [num-bits $<span style="color: #f8f8f2; font-weight: bold;">num</span>]}]
    <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">k</span> &lt; 8} {<span style="color: #8be9fd; font-style: italic;">set</span> k 8}
    <span style="color: #6272a4;"># hacer la prueba `k` veces
</span>    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">primo</span> [miller-rabin $<span style="color: #f8f8f2; font-weight: bold;">num</span> $<span style="color: #f8f8f2; font-weight: bold;">k</span>]
    <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">primo</span>
}

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">######################################################################
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Procedimiento: generar-primo
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">Devuelve un n&#250;mero primo del tama&#241;o en bytes especificado
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Par&#225;metros:
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">`s` es el tama&#241;o en bytes del n&#250;mero deseado
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Devuelve:
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">Un n&#250;mero primo
</span><span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">generar-primo</span> s {
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">veces</span> 0
    <span style="color: #ff79c6; font-weight: bold;">while</span> { 1 } {
        <span style="color: #8be9fd; font-style: italic;">incr</span> veces
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">p</span> [aleatorio $<span style="color: #f8f8f2; font-weight: bold;">s</span>]
        <span style="color: #ff79c6; font-weight: bold;">if</span> {($<span style="color: #f8f8f2; font-weight: bold;">p</span> % 2) == 0} {
            <span style="color: #ff79c6; font-weight: bold;">continue</span>
        } <span style="color: #ff79c6; font-weight: bold;">else</span> {
            <span style="color: #6272a4;"># if { [lucas-lehmer $p] } 
</span>            <span style="color: #ff79c6; font-weight: bold;">if</span> { [es-primo $<span style="color: #f8f8f2; font-weight: bold;">p</span>] } {
                <span style="color: #ff79c6; font-weight: bold;">break</span>
            }
        }
    }
    <span style="color: #ff79c6; font-weight: bold;">return</span> [<span style="color: #8be9fd; font-style: italic;">list</span> $<span style="color: #f8f8f2; font-weight: bold;">veces</span> $<span style="color: #f8f8f2; font-weight: bold;">p</span>]
}
</pre>
</div>

<p>
Como he explicado antes <code>generar-primo</code> primariamente llamaba al
algoritmo <i>Lucas-Lehmer</i>. Pero primero tenía que generar el número que
hay que contrastar. El parámetro que se le pasa a esta función
indicará el tamaño en <i>bytes</i> del número que queremos obtener con
<code>aleatorio</code>... y aquí me encontré también con la dificultad de generar
números aleatorios.
</p>
</div>
</div>
</div>
<div id="outline-container-org5d14066" class="outline-2">
<h2 id="org5d14066">Generación de números aleatorios</h2>
<div class="outline-text-2" id="text-org5d14066">
<p>
Primero pongo la función que escribí para obtener un número aleatorio
y luego me explico mejor:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #6272a4;"># </span><span style="color: #6272a4;">######################################################################
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Procedimiento: aleatorio
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">Devuelve un n&#250;mero aleatorio (biginteger) utilizando el dispositivo
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">`/dev/random` de Unix (Esto no funcionar&#225; en g&#252;ind&#243;n)
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Par&#225;metros:
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">`nbytes` determina el n&#250;mero de bytes que se leen del dispositivo
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">y, por tanto, el tama&#241;o del n&#250;mero devuelto
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Devuelve:
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">Un n&#250;mero, entero, aleatorio dentro del rango establecido
</span><span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">aleatorio</span> {{nbytes 8}} {
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">cadena</span> <span style="color: #f1fa8c;">""</span>
    <span style="color: #6272a4;"># Leo `nbytes` del dispositivo `/dev/random`
</span>    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">f</span> [<span style="color: #8be9fd; font-style: italic;">open</span> /dev/random rb]
    <span style="color: #ff79c6; font-weight: bold;">for</span> {<span style="color: #8be9fd; font-style: italic;">set</span> b 0} {$<span style="color: #f8f8f2; font-weight: bold;">b</span> &lt; $<span style="color: #f8f8f2; font-weight: bold;">nbytes</span>} {<span style="color: #8be9fd; font-style: italic;">incr</span> b} {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">byte</span> [<span style="color: #8be9fd; font-style: italic;">read</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span> 1]
        <span style="color: #6272a4;"># cada byte se convierte a una cadena hexadecimal y se
</span>        <span style="color: #6272a4;">#      concatena en `cadena`
</span>        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">cadena</span> $<span style="color: #f8f8f2; font-weight: bold;">cadena</span>[<span style="color: #8be9fd; font-style: italic;">binary</span> encode hex $<span style="color: #f8f8f2; font-weight: bold;">byte</span>]
    }
    <span style="color: #8be9fd; font-style: italic;">close</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span>
    <span style="color: #6272a4;"># convierto la cadena hexadecimal en un n&#250;mero decimal (big %ll)
</span>    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">n</span> [<span style="color: #8be9fd; font-style: italic;">format</span> %lld 0x$<span style="color: #f8f8f2; font-weight: bold;">cadena</span>]
    <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">n</span>
}
</pre>
</div>

<p>
Podría haber utilizado la función habitual del lenguaje, que según la
notación de <i>Tcl</i> es <code>::tcl::mathfunc::rand</code>. Sin embargo, quería algo
menos predecible que un número pseudoaleatorio. Una opción sería
utilizar la <i>API</i> que ofrecen algunos organismos como <a href="https://www.random.org/">www.random.org</a>
para la generación de números aleatorios. Sin embargo, he utilizado
otro método: leer del dispositivo <code>/dev/random</code><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>, básicamente
porque lo tengo a mano.
</p>

<p>
Siguiendo la filosofía de <i>Unix</i>, se utiliza como cualquier fichero:
se abre <i>el fichero</i>, <i>se lee</i> de él y se cierra. Aquí tropiezo con el
tipo de datos que devuelve y la idiosincrasia del lenguaje que estoy
utilizando. En <i>Tcl</i> todo es una cadena, no hay tipos. Por tanto,
tengo que convertir el contenido binario leído en una cadena.  Lo que
hago es leer uno a uno los bytes que me dice el parámetro, convierto
el binario obtenido en una cadena que lo expresa en hexadecimal y
cuando termino de leer bytes, cierro el archivos y convierto la cadena
hexadecimal formada en un número decimal utilizando la función
<code>format</code>. Por defecto, si se llama sin parámetro devolverá un número
aleatorio de 8 bytes.
</p>

<p>
Otra de las funciones aleatorias que necesita el código es
<code>entero-entre</code>. Esta función la llama la función auxiliar (el bucle
interno, si lo prefieres llamar así). En este caso, puesto que ya
tenía hecha la función de <code>aleatorio</code>, lo que hace es obtener un
número aleatorio de 8 bytes mediante dicha función y hacer un simple
cálculo.
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #6272a4;"># </span><span style="color: #6272a4;">######################################################################
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Procedimiento: entero-entre
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">Devuelve un entero aleatorio entre los valores m&#237;nimo y m&#225;ximo. El
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">n&#250;mero aleatorio, devuelto por [aleatorio 8] al ser de 8 bytes,
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">tendr&#225; un rango entre 0 y 18446744073709551615
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Par&#225;metros:
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">`min` El valor m&#237;nimo que debe devolver
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">`max` El valor m&#225;ximo que debe devolver
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Devuelve:
</span><span style="color: #6272a4;">#   </span><span style="color: #6272a4;">Un entero `n` tal que 'min &lt;= n &lt;= max'
</span><span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">entero-entre</span> {min max} {
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">dec</span> [aleatorio 8]
    <span style="color: #6272a4;"># el n&#250;mero m&#225;ximo que se puede obetener aleatoriamente por el
</span>    <span style="color: #6272a4;"># c&#243;digo anterior es 18446744073709551615
</span>    <span style="color: #ff79c6; font-weight: bold;">return</span> round([<span style="color: #8be9fd; font-style: italic;">expr</span> {(($<span style="color: #f8f8f2; font-weight: bold;">dec</span>/18446744073709551615.0) * ($<span style="color: #f8f8f2; font-weight: bold;">max</span> - $<span style="color: #f8f8f2; font-weight: bold;">min</span>)) + $<span style="color: #f8f8f2; font-weight: bold;">min</span>}])
}
</pre>
</div>

<p>
El cálculo consiste en obtener un número entre <code>0</code> y
<code>0xffffffffffffffff</code> y hacer una regla de tres.
</p>

<p>
De momento, con todo lo explicado hasta aquí, ya consigo hacer el
primer paso del algoritmo RSA, que es conseguir números primos muy
altos. El siguiente paso será, después de probar que efectivamente el
código es seguro, generar las dos claves que necesitamos.
</p>

<p>
De momento, me pondré con una <i>refactorización</i> para eliminar todo el
código inútil que hay. El código que muestro al final del artículo
está aún sin refactorizar. Por ejemplo, para hacer pruebas me puse a
contar también el número de <i>intentos</i> de encontrar un número primo al
azar. Y la función que debería devolver <i>un</i> número primo, devuelve
una lista con el número de intentos y el número primo juntos.
</p>
</div>
</div>
<div id="outline-container-orgf7e689f" class="outline-2">
<h2 id="orgf7e689f">Pruebas</h2>
<div class="outline-text-2" id="text-orgf7e689f">
<p>
Por ejemplo, buscando primos de 16 <i>bytes</i> me puse a contar la
cantidad de veces que hay que <i>tirar el dado</i> para que nos devuelva un
número primo. Me hice un <i>script</i> sencillito cuya salida era algo
parecido a:
</p>

<pre class="example" id="org989bfb3">
Intentos:  198 -- Primo: 42257895601817581841334192879244172861
Intentos:  149 -- Primo: 268013252449733683657437157911978100873
Intentos:  138 -- Primo: 118450050774604994062315721188627087679
Intentos:    1 -- Primo: 249880285931983262494435137763895968483
Intentos:   36 -- Primo: 8008379698234226130537034850572345927
Intentos:   51 -- Primo: 32904817994662091085344712101414460091
Intentos:    1 -- Primo: 298689198394747193867273799433969986389
Intentos:   44 -- Primo: 219365110495942244274573360479389771271
Intentos:   80 -- Primo: 285990911941440299303524155960171686387
Intentos:  291 -- Primo: 338447441262384199035015634515322563473
...
</pre>

<p>
Mostré esta salida a un amigo y le llamaron la atención los dos unos
que hay. ¿Es difícil acertar a la primera? ¿Cómo de difícil? ¿Estamos
obteniendo verdaderos números primos? Pues nada, ya tuvimos una tarde
entretenida haciendo pruebas y más pruebas.
</p>

<p>
Para resumir, y no irme por las ramas explicativas, para saber si era
difícil acertar a la primera, hice otro <i>script</i>, también sencillito,
que me calculara la media del tiempo empleado en cada intento y la
media de intentos necesarios para encontrar un número primo. El
cálculo se repetía 100 veces para cada <i>familia</i> de números primos.
No fue más amplia, porque los tiempos empleados para los primos de 32
y 64 bits se convertían en prohibitivos. Para calcular los 100
correspondientes a los 64 bits, sólo tenéis que hacer un simple
cálculo y sabréis que tardó más de hora y media en hacerlo.
</p>

<table>


<colgroup>
<col  class="org-right">

<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-right">bytes</th>
<th scope="col" class="org-right">seg.</th>
<th scope="col" class="org-right">intentos</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-right">8</td>
<td class="org-right">0.0611</td>
<td class="org-right">37.39</td>
</tr>

<tr>
<td class="org-right">16</td>
<td class="org-right">0.5663</td>
<td class="org-right">72.08</td>
</tr>

<tr>
<td class="org-right">32</td>
<td class="org-right">4.7169</td>
<td class="org-right">177.66</td>
</tr>

<tr>
<td class="org-right">64</td>
<td class="org-right">47.1604</td>
<td class="org-right">352.71</td>
</tr>
</tbody>
</table>

<ul class="org-ul">
<li><b>bytes</b>: Tamaño en <i>bytes</i> del número primo generado</li>
<li><b>seg.</b>: Tiempo medio de cálculo en segundos</li>
<li><b>intentos</b>: Número medio de intentos antes de encontrar al azar un
número primo.</li>
</ul>

<p>
Las conclusiones de estas pruebas son que algunas veces se han
encontrado número primos a la primera, cosas del azar, pero ha sido en
raras ocasiones. Podríamos considerar que la media de intentos, aunque
haga falta un muestreo más alto, sería una estimación la densidad de
números primos entre el conjunto de números de ese tamaño. Por último,
que la generación de claves seguras puede llevar algunos minutos de
proceso.
</p>
</div>
</div>
<div id="outline-container-org0d6d09d" class="outline-2">
<h2 id="org0d6d09d">Conclusión</h2>
<div class="outline-text-2" id="text-org0d6d09d">
<p>
De momento el proyecto sigue adelante y más fácilmente de lo esperado
(sí, esperaba más complicación). Aún utilizando un algoritmo
probabilístico para obtener los primos el proceso es lento, pero
seguro. Como dije antes la probabilidad matemática de obtener un falso
positivo es \((\frac{1}{4})^k\). Utilizo la fórmula \(2 \cdot num-bits\).
En números como los que se utilizarán en las claves ese error será de
\((\frac{1}{4})^{1024} = 3,09434604738 \cdot 10^{-617}\).
</p>

<p>
Después de la refactorización, continuaré con la implementación del
algoritmo RSA. <i>Sigan atentos a sus pantallas...</i>
</p>
</div>
</div>
<div id="outline-container-org3fc1490" class="outline-2">
<h2 id="org3fc1490">Código fuente completo</h2>
<div class="outline-text-2" id="text-org3fc1490">
<p>
A continuación se muestra todo el código del paquete tal y como se
encuentra en esta fase del desarrollo. Omito las pruebas unitarias que
he ido haciendo, porque harían muy largo este apartado y son
triviales. Al finalizar la serie de artículos publicaré todo el
código.
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Paquete que proporciona el archivo
</span><span style="color: #8be9fd; font-style: italic;">package</span> provide rsa 1.0

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">Creamos un `namespace` para evitar choques de nombre
</span><span style="color: #8be9fd; font-style: italic;">namespace</span> <span style="color: #50fa7b; font-weight: bold;">eval</span> ::rsa {

    <span style="color: #6272a4;"># Rutinas que se exportan para trabajar con ellas
</span>    <span style="color: #8be9fd; font-style: italic;">namespace</span> <span style="color: #50fa7b; font-weight: bold;">export</span> num-bits es-primo generar-primo exp-rapida

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: num-bits
</span>    <span style="color: #6272a4;">#   Devuelve el n&#250;mero de bits empleados para representar un n&#250;mero entero
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `valor` representa el n&#250;mero del que queremos saber el tama&#241;o
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   La cantidad de bits empleados en la representaci&#243;n del n&#250;mero
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">num-bits</span> valor {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">bits</span> -1
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">p</span> 0
        <span style="color: #ff79c6; font-weight: bold;">while</span> {$<span style="color: #f8f8f2; font-weight: bold;">valor</span> &gt;= $<span style="color: #f8f8f2; font-weight: bold;">p</span>} {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">p</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {(1 &lt;&lt; [<span style="color: #8be9fd; font-style: italic;">incr</span> bits])}]
        }
        <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">bits</span>
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: exp-rapida
</span>    <span style="color: #6272a4;">#   Calcula el resultado de una exponenciaci&#243;n.
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `base` la base del c&#225;lculo
</span>    <span style="color: #6272a4;">#   `exp` el exponente del c&#225;lculo
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   El resultado de la operaci&#243;n
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">exp-rapida</span> {base exp} {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">res</span> 1
        <span style="color: #ff79c6; font-weight: bold;">for</span> {<span style="color: #8be9fd; font-style: italic;">set</span> i 1} {$<span style="color: #f8f8f2; font-weight: bold;">i</span> &lt;= $<span style="color: #f8f8f2; font-weight: bold;">exp</span>} {<span style="color: #8be9fd; font-style: italic;">incr</span> 1} {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">res</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">res</span> * $<span style="color: #f8f8f2; font-weight: bold;">exp</span>}]
        }
        <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">res</span>
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: lucas-lehmer
</span>    <span style="color: #6272a4;">#   Realiza el tests de primalidad con el algoritmo Lucas-Lehmer
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `num` El n&#250;mero que debe ser probado
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   `0` significa que `num` es compuesto
</span>    <span style="color: #6272a4;">#   `1` significa que `num` es primo
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">lucas-lehmer</span> num {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">s</span> 4
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">m</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {[exp-rapida 2 $<span style="color: #f8f8f2; font-weight: bold;">num</span>] - 1}]
        <span style="color: #ff79c6; font-weight: bold;">for</span> {<span style="color: #8be9fd; font-style: italic;">set</span> j 2} {$<span style="color: #f8f8f2; font-weight: bold;">j</span> &lt;= ($<span style="color: #f8f8f2; font-weight: bold;">num</span> - 1)} {<span style="color: #8be9fd; font-style: italic;">incr</span> j} {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">sj</span> $<span style="color: #f8f8f2; font-weight: bold;">s</span>
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">s</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {(($<span style="color: #f8f8f2; font-weight: bold;">sj</span> ** 2) - 2) % $<span style="color: #f8f8f2; font-weight: bold;">m</span>}]
            <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">sj</span> == 0} {<span style="color: #ff79c6; font-weight: bold;">return</span> 1}
        }
        <span style="color: #ff79c6; font-weight: bold;">return</span> 0
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: aleatorio
</span>    <span style="color: #6272a4;">#   Devuelve un n&#250;mero aleatorio (biginteger) utilizando el dispositivo
</span>    <span style="color: #6272a4;">#   `/dev/random` de Unix (Esto no funcionar&#225; en g&#252;ind&#243;n)
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `nbytes` determina el n&#250;mero de bytes que se leen del dispositivo
</span>    <span style="color: #6272a4;">#   y, por tanto, el tama&#241;o del n&#250;mero devuelto
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   Un n&#250;mero, entero, aleatorio dentro del rango establecido
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">aleatorio</span> {{nbytes 8}} {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">cadena</span> <span style="color: #f1fa8c;">""</span>
        <span style="color: #6272a4;"># Leo `nbytes` del dispositivo `/dev/random`
</span>        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">f</span> [<span style="color: #8be9fd; font-style: italic;">open</span> /dev/random rb]
        <span style="color: #ff79c6; font-weight: bold;">for</span> {<span style="color: #8be9fd; font-style: italic;">set</span> b 0} {$<span style="color: #f8f8f2; font-weight: bold;">b</span> &lt; $<span style="color: #f8f8f2; font-weight: bold;">nbytes</span>} {<span style="color: #8be9fd; font-style: italic;">incr</span> b} {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">byte</span> [<span style="color: #8be9fd; font-style: italic;">read</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span> 1]
            <span style="color: #6272a4;"># cada byte se convierte a una cadena hexadecimal y se
</span>            <span style="color: #6272a4;">#      concatena en `cadena`
</span>            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">cadena</span> $<span style="color: #f8f8f2; font-weight: bold;">cadena</span>[<span style="color: #8be9fd; font-style: italic;">binary</span> encode hex $<span style="color: #f8f8f2; font-weight: bold;">byte</span>]
        }
        <span style="color: #8be9fd; font-style: italic;">close</span> $<span style="color: #f8f8f2; font-weight: bold;">f</span>
        <span style="color: #6272a4;"># convierto la cadena hexadecimal en un n&#250;mero decimal (big %ll)
</span>        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">n</span> [<span style="color: #8be9fd; font-style: italic;">format</span> %lld 0x$<span style="color: #f8f8f2; font-weight: bold;">cadena</span>]
        <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">n</span>
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: entero-entre
</span>    <span style="color: #6272a4;">#   Devuelve un entero aleatorio entre los valores m&#237;nimo y m&#225;ximo. El
</span>    <span style="color: #6272a4;">#   n&#250;mero aleatorio, devuelto por [aleatorio 8] al ser de 8 bytes,
</span>    <span style="color: #6272a4;">#   tendr&#225; un rango entre 0 y 18446744073709551615
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `min` El valor m&#237;nimo que debe devolver
</span>    <span style="color: #6272a4;">#   `max` El valor m&#225;ximo que debe devolver
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   Un entero `n` tal que 'min &lt;= n &lt;= max'
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">entero-entre</span> {min max} {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">dec</span> [aleatorio 8]
        <span style="color: #6272a4;"># el n&#250;mero m&#225;ximo que se puede obetener aleatoriamente por el
</span>        <span style="color: #6272a4;"># c&#243;digo anterior es 18446744073709551615
</span>        <span style="color: #ff79c6; font-weight: bold;">return</span> round([<span style="color: #8be9fd; font-style: italic;">expr</span> {(($<span style="color: #f8f8f2; font-weight: bold;">dec</span>/18446744073709551615.0) * ($<span style="color: #f8f8f2; font-weight: bold;">max</span> - $<span style="color: #f8f8f2; font-weight: bold;">min</span>)) + $<span style="color: #f8f8f2; font-weight: bold;">min</span>}])
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: expmod
</span>    <span style="color: #6272a4;">#   Exponenciaci&#243;n modular. Calcula el residuo cuando una base se eleva
</span>    <span style="color: #6272a4;">#   a un exponente y se divide por el m&#243;dulo. Se utiliza para acelerar
</span>    <span style="color: #6272a4;">#   el c&#225;lculo con grandes n&#250;meros.
</span>    <span style="color: #6272a4;">#   (Algoritmo sacado de la wikipedia)
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `base` el n&#250;mero base
</span>    <span style="color: #6272a4;">#   `exp`  el exponente
</span>    <span style="color: #6272a4;">#   `mod`  el m&#243;dulo
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   El resultado de la exponenciaci&#243;n
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">expmod</span> {base exp mod} {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">x</span> 1
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">y</span> $<span style="color: #f8f8f2; font-weight: bold;">base</span>
        <span style="color: #ff79c6; font-weight: bold;">while</span> {$<span style="color: #f8f8f2; font-weight: bold;">exp</span> &gt; 0} {
            <span style="color: #ff79c6; font-weight: bold;">if</span> {($<span style="color: #f8f8f2; font-weight: bold;">exp</span> % 2) == 1} {<span style="color: #8be9fd; font-style: italic;">set</span> x [<span style="color: #8be9fd; font-style: italic;">expr</span> {($<span style="color: #f8f8f2; font-weight: bold;">x</span> * $<span style="color: #f8f8f2; font-weight: bold;">y</span>) % $<span style="color: #f8f8f2; font-weight: bold;">mod</span>}]}
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">y</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {($<span style="color: #f8f8f2; font-weight: bold;">y</span> * $<span style="color: #f8f8f2; font-weight: bold;">y</span>) % $<span style="color: #f8f8f2; font-weight: bold;">mod</span>}]
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">exp</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">exp</span> &gt;&gt; 1}]
        }
        <span style="color: #ff79c6; font-weight: bold;">return</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">x</span> % $<span style="color: #f8f8f2; font-weight: bold;">mod</span>}]
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: mr-test
</span>    <span style="color: #6272a4;">#   Proc. auxiliar del test de &#171;Miller-Rabin&#187; sobre primalidad, sacando
</span>    <span style="color: #6272a4;">#   el bucle de dentro del bucle principal.
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `d` llega como el entero inmediatamente inferior del n&#250;mero testado
</span>    <span style="color: #6272a4;">#   `n` el n&#250;mero testado
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   0 significa que `n` es compuesto
</span>    <span style="color: #6272a4;">#   1 significa que `n` es primo
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">mr-test</span> {d n} {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">a</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> 2 + [entero-entre 1 [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">n</span> - 1}]]]
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">x</span> [expmod $<span style="color: #f8f8f2; font-weight: bold;">a</span> $<span style="color: #f8f8f2; font-weight: bold;">d</span> $<span style="color: #f8f8f2; font-weight: bold;">n</span>]
        <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">x</span> == 1 || $<span style="color: #f8f8f2; font-weight: bold;">x</span> == ($<span style="color: #f8f8f2; font-weight: bold;">n</span> - 1) } {<span style="color: #ff79c6; font-weight: bold;">return</span> 1}
        <span style="color: #ff79c6; font-weight: bold;">while</span> {$<span style="color: #f8f8f2; font-weight: bold;">d</span> != ($<span style="color: #f8f8f2; font-weight: bold;">n</span> - 1)} {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">x</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {($<span style="color: #f8f8f2; font-weight: bold;">x</span> * $<span style="color: #f8f8f2; font-weight: bold;">x</span>) % $<span style="color: #f8f8f2; font-weight: bold;">n</span>}]
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">d</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">d</span> * 2}]
            <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">x</span> == 1} {
                <span style="color: #ff79c6; font-weight: bold;">return</span> 0
            } <span style="color: #ff79c6; font-weight: bold;">elseif</span> {$<span style="color: #f8f8f2; font-weight: bold;">x</span> == ($<span style="color: #f8f8f2; font-weight: bold;">n</span> - 1)} {
                <span style="color: #ff79c6; font-weight: bold;">return</span> 1
            }
        }
        <span style="color: #ff79c6; font-weight: bold;">return</span> 0
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: miller-rabin
</span>    <span style="color: #6272a4;">#   Algoritmo de primalidad probabil&#237;stico pero altamente utilizado en
</span>    <span style="color: #6272a4;">#   criptograf&#237;a. Est&#225; dise&#241;ado para evitar los falsos positivos.
</span>    <span style="color: #6272a4;">#   (Algoritmo sacado de la wikipedia, aunque adaptado)
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `n` El n&#250;mero cuya primalidad deseamos probar
</span>    <span style="color: #6272a4;">#   `k` El n&#250;mero de pruebas que queremos hacer
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   0 significa que el n&#250;mero `n` es compuesto
</span>    <span style="color: #6272a4;">#   1 significa que el n&#250;mero `n` es primo
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">miller-rabin</span> { n k } {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">d</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">n</span> - 1}]
        <span style="color: #ff79c6; font-weight: bold;">while</span> { ($<span style="color: #f8f8f2; font-weight: bold;">d</span> % 2) == 0 } {
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">d</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {$<span style="color: #f8f8f2; font-weight: bold;">d</span> &gt;&gt; 1}]
        }
        <span style="color: #ff79c6; font-weight: bold;">for</span> {<span style="color: #8be9fd; font-style: italic;">set</span> i 0} {$<span style="color: #f8f8f2; font-weight: bold;">i</span> &lt; $<span style="color: #f8f8f2; font-weight: bold;">k</span>} {<span style="color: #8be9fd; font-style: italic;">incr</span> i} {
            <span style="color: #ff79c6; font-weight: bold;">if</span> {[mr-test $<span style="color: #f8f8f2; font-weight: bold;">d</span> $<span style="color: #f8f8f2; font-weight: bold;">n</span>] == 0} {
                <span style="color: #ff79c6; font-weight: bold;">return</span> 0
            }
        }
        <span style="color: #ff79c6; font-weight: bold;">return</span> 1
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: es-primo
</span>    <span style="color: #6272a4;">#   Determina si un n&#250;mero es primo.
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `num` El n&#250;mero cuya primalidad ser&#225; testeada
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   0 si el n&#250;mero `num` es compuesto
</span>    <span style="color: #6272a4;">#   1 si el n&#250;mero `num` es primo
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">es-primo</span> num {
        <span style="color: #6272a4;"># la variable `k` podr&#237;a ajustarse por par&#225;metro.
</span>        <span style="color: #6272a4;"># de momento la calculo en base a la cantidad de bits de `num`, de
</span>        <span style="color: #6272a4;"># esta manera habr&#225; un muestreo proporcional al tama&#241;o del n&#250;mero
</span>        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">k</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> {2 * [num-bits $<span style="color: #f8f8f2; font-weight: bold;">num</span>]}]
        <span style="color: #ff79c6; font-weight: bold;">if</span> {$<span style="color: #f8f8f2; font-weight: bold;">k</span> &lt; 8} {<span style="color: #8be9fd; font-style: italic;">set</span> k 8}
        <span style="color: #6272a4;"># hacer la prueba `k` veces
</span>        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">primo</span> [miller-rabin $<span style="color: #f8f8f2; font-weight: bold;">num</span> $<span style="color: #f8f8f2; font-weight: bold;">k</span>]
        <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">primo</span>
    }

    <span style="color: #6272a4;"># ######################################################################
</span>    <span style="color: #6272a4;"># Procedimiento: generar-primo
</span>    <span style="color: #6272a4;">#   Devuelve un n&#250;mero primo del tama&#241;o en bytes especificado
</span>    <span style="color: #6272a4;"># Par&#225;metros:
</span>    <span style="color: #6272a4;">#   `s` es el tama&#241;o en bytes del n&#250;mero deseado
</span>    <span style="color: #6272a4;"># Devuelve:
</span>    <span style="color: #6272a4;">#   Un n&#250;mero primo
</span>    <span style="color: #6272a4;">#
</span>    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">generar-primo</span> s {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">veces</span> 0
        <span style="color: #ff79c6; font-weight: bold;">while</span> { 1 } {
            <span style="color: #8be9fd; font-style: italic;">incr</span> veces
            <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">p</span> [aleatorio $<span style="color: #f8f8f2; font-weight: bold;">s</span>]
            <span style="color: #ff79c6; font-weight: bold;">if</span> {($<span style="color: #f8f8f2; font-weight: bold;">p</span> % 2) == 0} {
                <span style="color: #ff79c6; font-weight: bold;">continue</span>
            } <span style="color: #ff79c6; font-weight: bold;">else</span> {
                <span style="color: #6272a4;"># if { [lucas-lehmer $p] } 
</span>                <span style="color: #ff79c6; font-weight: bold;">if</span> { [es-primo $<span style="color: #f8f8f2; font-weight: bold;">p</span>] } {
                    <span style="color: #ff79c6; font-weight: bold;">break</span>
                }
            }
        }
        <span style="color: #ff79c6; font-weight: bold;">return</span> [<span style="color: #8be9fd; font-style: italic;">list</span> $<span style="color: #f8f8f2; font-weight: bold;">veces</span> $<span style="color: #f8f8f2; font-weight: bold;">p</span>]
    }
}
</pre>
</div>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Lo pronuncian <i>tíkel tikey</i> yo lo deletreaba antes, pero ahora
me hace gracia el nombre tal como lo pronuncian los <i>programadores</i>
anglosajones, como <i>D. Richard Hipp</i> el padre de <a href="https://sqlite.org">Sqlite</a> o <a href="https://fossil-scm.org">Fossil</a>.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Es decir, el determinar con certeza si un número es primo o no. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ya disculparéis que no ponga el enlace.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Si alguien quiere copiar el código en <i>Windows</i> no le
funcionará. Habría que buscar otra fuente de números aleatorios
razonablemente segura. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/criptografia/index.html">criptografia</a> ]]></description>
  <category><![CDATA[criptografia]]></category>
  <link>https://notxor.nueva-actitud.org/2022/07/23/generando-un-número-primo-grande.html</link>
  <pubDate>Sat, 23 Jul 2022 19:22:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Algoritmo de cifrado RSA]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-07-21</div>
<p>
Una de las cosas que, de siempre, me han llamado la atención es el
cifrado y la criptografía. Pienso que no soy el único y que a la
mayoría de la gente le resulta interesante, o al menos el tema les
puede parecer curioso. La necesidad que tenemos de ocultar nuestros
mensajes a la mirada indiscreta de los demás. No sólo los importantes
mensajes de estado, o los juegos de espías, también nuestros asuntos
individuales se pueden ver afectados por la necesidad de intimidad.
Algo de lo que soy especialmente consciente, cuando trabajo como
psicólogo y debo gestionar información <i>muy sensible</i> para las
personas que han depositado su confianza en mí. Además, como uno de
mis pasatiempos es no dejar que esas curiosidades que me surgen caigan
en el vacío, me dio por examinar algún algoritmo de cifrado.  Este
artículo son las notas que voy tomando sobre el algoritmo RSA.  Como
sé que este tipo de problemas me pican en la punta de los dedos, estoy
seguro de que al final intentaré escribir un programa que codifique y
descodifique una cadena, sólo para decir que soy capaz.
</p>
<div id="outline-container-org56052da" class="outline-2">
<h2 id="org56052da">RSA</h2>
<div class="outline-text-2" id="text-org56052da">
<p>
Como dije antes, el algoritmo elegido es el llamado <i>RSA</i>. Que también
parece un nombre, un tanto, <i>críptico</i>. En realidad son las iniciales
de los apellidos del trío de personas que lo publicaron: Ron Rivest,
Adi Shamir y Leonard Adleman, en 1977. Esto fue en el <i>MIT</i> y llegó a
ser patentado para esa institución, sin embargo, parece ser que el
primero en describirlo fue el matemático Clifford Cocks, en 1973, cuyo
trabajo no trascendió porque estaba en un documento interno de una
agencia de seguridad inglesa y sólo se conoció la existencia de ese
trabajo tras la desclasificación de dicho documento.
</p>

<p>
El algoritmo se basa en la idea de la dificultad que implica revertir
un cálculo. Por ejemplo: si nos dicen que <code>681.013</code> es el resultado de
multiplicar dos números primos y nos piden que digamos cuáles son, con
lápiz y papel... bueno tardaremos, si somos capaces de hacerlo, una
infinidad de tiempo más que cuando hacemos directamente la operación
\(773 \times 881\). Ir probando cada número primo hasta dar con uno que
divida de forma exacta el número dado, a mano, nos llevaría toda una
vida. Con el uso de ordenadores, que los hemos fabricado para que cada
vez calculen más rápido, la cosa se simplifica un bastante. Por eso,
el tamaño de la clave recomendada es de <code>1024</code> bits y no de <code>20</code>, como
es en nuestro ejemplo, lo que alarga el proceso de cálculo inverso
hasta situarlo en un punto en el que no merece la pena la espera.
Según se van <i>acelerando</i> los procesadores hay que elegir <i>claves</i> más
largas. Pero al final, la seguridad de una clave dependerá de los
recursos que <i>el atacante</i> esté dispuesto a gastar para obtener la
información y lo que para él suponga tenerla.
</p>

<p>
Expresado de otro modo. Es posible que alguien, cuidando de su
intimidad, envíe una lista de la compra cifrada a su pareja para que
se pase por el <i>super</i> al volver del trabajo. Es posible, que dicha
información fuera del agrado de alguna gran corporación de las que
viven del <i>BigData</i>, pero ¿les merece la pena pasar meses de cómputo
para obtenerla?... El <i>calentamiento global</i> agravado porque gúguel
quiere saber que compras garbanzos y bacalao porque vas a perpetrar un
potaje... en fin.
</p>

<p>
Entrando un poco más en materia, de forma matemática, el algoritmo se
basa en que es fácil encontrar tres números enteros positivos
(grandes), \(e\), \(d\) y \(n\), con \(m\) cumpliendo \(0 \leq m < n\)
</p>

<p>
\[(m^d)^e \equiv m \quad (mod \: n)\]
</p>

<p>
Esa equivalencia expresa que si dividimos \((m^d)^e\) por \(n\)
obtendremos el mismo resto que si calculamos el resto de \(m / n\). Es
decir, lo que se conoce cómo <i>congruencia de módulo</i>. Además, para
algunos cálculos es conveniente que ambos exponentes puedan
intercambiarse en el orden de cálculo, lo que implica que también debe
cumplirse:
</p>

<p>
\[(m^e)^d \equiv m \quad (mod \: n)\]
</p>

<p>
Todas estas congruencias se buscan para hacer fácil la codificación y
decodificación de los mensajes. De manera que en <i>la clave pública</i> se
compartirán el <i>módulo</i>, \(n\) y un <i>exponente</i>, \(e\). De este modo la
codificación será la operación:
</p>

<p>
\[c = m^e \; (mod \: n)\]
</p>

<p>
donde \(m\) es el mensaje que se quiere transmitir y \(c\) el mismo
mensaje codificado.
</p>

<p>
Para descodificarlo se empleará <i>la clave privada</i>, que contendrá, al
menos, el mismo módulo \(n\) y el otro exponente \(d\). El cálculo inverso
que se realiza es:
</p>

<p>
\[m = c^d \; (mod \: n)\]
</p>

<p>
Es decir, tengo que realizar un cálculo con unos datos y para
deshacerlo necesito otros datos. Por tanto, la historia consiste en
compartir los datos que realizan el cálculo de cifrado, guardando los
de descifrado. En este caso se generan dos claves una pública, la que
comparto y otra privada, la que guardo. Puesto que lo que comparto es
la parte que sirve para cifrar, podemos poner el símil cerrajero de
<i>un candado</i>: lo que envío es un candado y me guardo en el bolsillo
<i>la llave</i> que lo abre.
</p>

<p>
Teniendo más o menos claro cómo funciona, voy a repasar qué necesito
implementar para realizarlo:
</p>

<ol class="org-ol">
<li>Necesito calcular el módulo \(n\):
<ul class="org-ul">
<li>Para ello necesito encontrar dos números primos, \(p\) y \(q\),
grandes. Deberían seleccionarse al azar y diferir en unos pocos
<i>bits</i> para hacer más difícil su factorización.</li>
<li>No hace falta decir que hay que mantenerlos en secreto.</li>
</ul></li>
<li>Necesito determinar también dos exponentes, \(e\) y \(d\), uno de
ellos, \(e\), irá en la clave pública junto con el módulo
\(n=p \cdot q\)... Es decir:
<ul class="org-ul">
<li><b>Clave pública</b>: formada por \(e\) y \(n\)</li>
<li><b>Clave privada</b>: formada por \(d\) y \(n\) <sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup></li>
</ul></li>
</ol>

<p>
Hasta aquí, tengo la sensación de que entiendo todo (<i>pa' lo cortito
que soy yo</i>). Claro, que me he saltado toda la parte de las
demostraciones matemáticas y confío <i>a ciegas</i> en lo que dicen los
matemáticos expertos. ¿Quién soy yo para llevarles la contraria?
Además, seguro que yo sería incapaz de hacer ninguna de esas
demostraciones, así que, a lo práctico: voy con el algoritmo para
encontrar esos cuatro datos que necesito calcular. A ver si no se me
complican mucho las cosas (que seguro que sí, o no). En todo caso, los
pasos complejos o largos, si lo prefieres expresar así, son la
generación de claves. El cifrado y descifrado, teniendo las claves
calculadas, son relativamente menos exigentes.
</p>
</div>
</div>
<div id="outline-container-orgc74cb55" class="outline-2">
<h2 id="orgc74cb55">Algoritmo</h2>
<div class="outline-text-2" id="text-orgc74cb55">
<p>
Viendo las consideraciones anteriores podemos hacernos una idea
general de cuál será el algoritmo. Sólo hace falta detallar un poco
cómo vamos a calcular según qué parámetros y sobre qué otros
algoritmos nos apoyaremos para hacerlo. Otro punto de apoyo serán las
recomendaciones <a href="https://es.wikipedia.org/wiki/PKCS">PKCS</a> donde tratan de estandarizar las distintas
herramientas que utilicen este algoritmo.
</p>

<ol class="org-ol">
<li><p>
<b>Calcular los <i>dos</i> números primos</b>.
</p>

<p>
Esto también conlleva bastante complejidad. Determinar si un número
es primo o no, la prueba de <i>primalidad</i>, es otro de esos problemas
matemáticos que son interesantes. De hecho, existen algoritmos
probabilísticos como el de <a href="https://es.wikipedia.org/wiki/Test_de_primalidad_de_Miller-Rabin">Miller-Rabin</a>, que suele ser el más
utilizado en criptografía, o test de primalidad segura como el
<a href="https://es.wikipedia.org/wiki/Test_de_primalidad_AKS">algoritmo AKS</a>.
</p></li>

<li><b>Se calcula <i>n</i>, el módulo</b> a partir de los números primos
obtenidos en paso anterior. Este es un paso bastante fácil, ya que
\(n=p \cdot q\). Ese valor se utilizará tanto para la clave pública como
para la privada.</li>

<li><b>Calcular el mínimo común múltiplo</b> de \(p-1\) y \(q-1\), es decir,
calcular \(\lambda(n)=mcm(p-1,q-1)\), puesto que \(\phi(n)=\lambda(n)\) siendo \(p\) y
\(q\) primos<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.</li>

<li><b>Escoger \(e\), el primer exponente</b>, de manera que se cumplan las
siguientes condiciones:

<ul class="org-ul">
<li>\(1 < e < \lambda(n)\): es decir, un entero mayor que uno y menor que
\(\lambda(n)\)</li>
<li>\(mcd(e, \lambda(n)) = 1\): es decir, que ambos números, \(\lambda(n)\) y \(e\)
deben ser <i>coprimos</i> (no divisibles entre sí).</li>
<li>Tener en cuenta que valores pequeños de \(e\) tienen más riesgo de
ser descifrados.</li>
</ul></li>

<li><b>Calcular \(d\), el segundo exponente</b> dado que \(d \equiv e^{-1} \; (mod \,
   \lambda(n))\). Como ya se dijo antes \(d\) es parte de la clave privada y
debe mantenerse en secreto.</li>
</ol>

<p>
Con este algoritmo, y en cinco complejos pasos, se puede montar ya un
par de claves de <i>cifrado-descifrado</i> para <i>criptografía
asimétrica</i>. Las recomendaciones son que en las claves figure la
siguiente información:
</p>

<ul class="org-ul">
<li><b>Clave pública</b>:
<ul class="org-ul">
<li><b>Información obligatoria</b>
<ul class="org-ul">
<li><b>\(n\)</b>: El módulo compuesto por la multiplicación de dos números
primos.</li>
<li><b>\(e\)</b>:  Exponente de cifrado.</li>
</ul></li>
<li>No se recomienda <b>ninguna otra</b> información adicional.</li>
</ul></li>
<li><b>Clave privada</b>:
<ul class="org-ul">
<li><b>Información obligatoria</b>:
<ul class="org-ul">
<li><b>\(n\)</b>: El módulo. También presente en la clave pública.</li>
<li><b>\(d\)</b>: El exponente de descifrado.</li>
</ul></li>
<li><b>Información sugerida</b>: Para agilizar cálculos de descifrado se
recomienda almacenar también en la clave privada lo siguiente:
<ul class="org-ul">
<li><b>\(p\)</b>: El primer factor primo.</li>
<li><b>\(q\)</b>: El segundo factor primo.</li>
<li><b>\(dP\)</b>: Un entero positivo tal que \(e \cdot dP \equiv 1 \; (mod \, (p-1))\)</li>
<li><b>\(dQ\)</b>: Un entero positivo tal que \(e \cdot dQ \equiv 1 \; (mod \, (q-1))\)</li>
<li><b>\(qInv\)</b>: Un entero positivo tal que: \(qInv < p\) y, además,
\(q \cdot qInv \equiv 1 \; (mod \, p)\)</li>
</ul></li>
</ul></li>
</ul>

<p>
De momento no voy a mirar, siquiera, las especificaciones de cómo
almacenar esas claves para hacerlas accesibles a otros programas de
<i>software</i>. Aunque no descarto que en el futuro no me sea interesante
tener mi <i>programita</i> listo para poder intercambiar claves, poder cifrar
información mediante una clave generada con <code>gnupg</code> o enviar una clave
pública, generada por él y que la pueda utilizar otro <i>software</i>. En
la actualidad la prioridad es que funcione. De momento todo es humo
que flota en el ambiente.
</p>
</div>
</div>
<div id="outline-container-org7d5943e" class="outline-2">
<h2 id="org7d5943e">Conclusión</h2>
<div class="outline-text-2" id="text-org7d5943e">
<p>
Como bien podéis ver, no he concluido nada. Sólo he explicado por
encima cómo funciona el algoritmo <i>RSA</i> y poco más. Ahora bien,
habiendo comprendido en qué consiste, el reto consistirá en
implementarlo de aquí en uno o dos artículos. Supongo que, como en
todo, el demonio está en los detalles y ya superar el primer paso, el
de elegir los números primos es capaz por sí solo de tragarse otro, u
otro par artículos. En fin, estoy hablando sobre <i>expectativas</i>,
veremos cómo se desarrollan finalmente las cosas.
</p>

<p>
Así pues, creo que se acerca una de esas series en que me pongo a
programar <i>tontás</i> porque me gusta el reto. Ya siento aburriros<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>,
pero algo tendré que hacer este verano.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En la <i>clave privada</i> suelen encontrarse otra serie de datos
que facilitan los cálculos de descifrado. En la pública se omiten
porque darían demasiadas pistas para poder factorizar la privada. Pero
lo veremos más adelante.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Más información en wikipedia:
</p>
<ul class="org-ul">
<li><a href="https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Key_generation">https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Key_generation</a></li>
<li><a href="https://en.wikipedia.org/wiki/Carmichael_function">https://en.wikipedia.org/wiki/Carmichael_function</a></li>
</ul></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
¡Qué va! No tendré ningún remordimiento en ello ;-)
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/criptografia/index.html">criptografia</a> ]]></description>
  <category><![CDATA[criptografia]]></category>
  <link>https://notxor.nueva-actitud.org/2022/07/21/algoritmo-de-cifrado-rsa.html</link>
  <pubDate>Thu, 21 Jul 2022 09:01:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Pikchr]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-07-05</div>
<p>
Los generadores de gráficos a partir de texto que más utilizo son
<a href="https://graphviz.org"><i>Graphviz</i></a> y <a href="https://plantuml.com/es/"><i>PlantUML</i></a>. Supongo que a estas alturas todos los
conoceréis e incluso los utilizaréis con más arte de lo que lo pueda
hacer yo.  Estos días, continuando con la historia de <i>Fossil</i>,
encontré que tiene integrado un generador de gráficos, de los
generados por texto, que se llama <i>Pikchr</i>. Es un descendiente de
<i>PIC</i> un lenguaje pensado para trabajar embebido en <code>troff</code>, además
con versión <code>GNU</code> (<code>gpic</code>), de los años 80. Y si te estás preguntando
si nuestro querido <i>Emacs</i> puede trabajar con él, pues sí, existe
<code>pikchr-mode</code> para que podamos editar nuestros propios gráficos desde
nuestro editor favorito. Según su <i>web</i>, <i>Pikchr</i> genera diagramas
para documentación técnica escrita en <i>markdown</i> o lenguajes de marcas
similares, utilizando un lenguaje duradero que sea fácil de leer y
mantener para los humanos utilizando cualquier editor de texto. Para
no andarme por las ramas, veamos el primer <i>esquema</i> que nos
encontramos en su documentación<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>
</p>


<figure id="org2c6f1c2">
<img src="imagenes/esquema1.svg" alt="esquema1.svg" class="org-svg">

</figure>

<p>
Como vemos la salida especifica <code>HTML+SVG</code>, eso es así, cuando lo
invocamos desde línea de comandos. Genera un documento <code>html</code> con el
<code>svg</code> integrado. El gráfico anterior lo he generado pulsando <code>C-c C-c</code>
en el bloque de código mientras edito este artículo en <i>Emacs</i>, que se
ocupa él de llamar a ejecutable para generar el <code>svg</code>. Si lo hubiera
generado escribiendo el contenido en un fichero de texto y hubiera
llamado al ejecutable, lo habría hecho de la siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-shell">pikchr esquema.pikchr &gt; esquema.html
</pre>
</div>

<p>
El resultado en <code>html</code> lo podéis cargar del siguiente <i>link</i>:
</p>

<p>
<a href="./imagenes/esquema.html">Fichero <code>html</code> generado</a>
</p>

<p>
Si lo abres verás que al pinchar en el gráfico muestra el código y al
pinchar en el código muestra el gráfico, esto es bueno recordarlo,
porque en la documentación podemos ver el código de los ejemplos
pinchando en ellos. Si solo necesitas generar el gráfico, el formato
de salida es <code>SVG</code> y lo puedes hacer desde línea de comandos así:
</p>

<div class="org-src-container">
<pre class="src src-shell">pikchr --svg-only esquema.pikchr &gt; esquema.svg
</pre>
</div>

<p>
Después de ver las diferentes salidas, analicemos un poco el código
para entender un poco cómo funciona: elemento a elemento.
</p>

<ol class="org-ol">
<li>En la primera línea se define una flecha que apunta a la derecha,
<code>arrow right</code> el siguiente valor es el tamaño, <code>200%</code>, si no
especificamos un tamaño, por defecto utiliza 1,25cm. Al
especificarlo en porcentaje el ancho será 2,5cm. Luego hay dos
cadenas de texto. La primera la escribirá por encima de la línea y
la segunda debajo.</li>
<li>El siguiente elemento es una caja, <code>box</code>, con las esquinas
redondeadas, <code>rad 10px</code>. La lista de cadenas se mostrarán una
encima de la otra y el parámetro <code>fit</code> fuerza a que el texto esté
inscrito en la caja y esta crezca si es necesario.</li>
<li>La tercera línea es idéntica a la primera, cambia el texto. Por
ampliar un poco más la información, en lugar de expresar el ancho
en porcentaje, se puede hacer en puntos <code>px</code>, centímetros, pulgadas
y otras medidas habituales en este tipo de programas.</li>
<li>La siguiente línea dibuja una flecha de doble dirección que apunta
hacia abajo desde el conector <code>s</code> de <i>la última caja</i>. Los
elementos tienen «conectores» siguiendo los puntos cardinales tal y
como se ponen en los mapas cartográficos.</li>
<li>El último elemento es otra caja con las características de la
última caja gracias al parámetro <code>same</code>. Es decir, una caja de
esquinas redondeadas en <code>10px</code> y que ajustará su tamaño al texto
especificado.</li>
</ol>

<p>
También debemos observar que los elementos van distribuyéndose hacia
la derecha, hasta que una instrucción cambia la dirección hacia abajo,
<code>down</code>, a partir de ese momento todos los elementos se colocan uno
debajo del otro.
</p>
<div id="outline-container-orge2490e5" class="outline-2">
<h2 id="orge2490e5">Elementos gráficos</h2>
<div class="outline-text-2" id="text-orge2490e5">

<figure id="orge2f8e0a">
<img src="./imagenes/elementos.svg" alt="elementos.svg" class="org-svg">

</figure>

<p>
Es un grupo bastante limitado de elementos para realizar los
gráficos. Sin embargo, son unos pocos más que los disponibles en
<i>PIC</i>.
</p>

<p>
También podemos definir nuevos elementos con <i>macros</i> y llamarlos
desde nuestro código:
</p>


<figure id="org347980d">
<img src="imagenes/definir-propios.svg" alt="definir-propios.svg" class="org-svg">

</figure>

<p>
Se puede apreciar que hemos definido <code>rombo</code> componiéndolo con un par
de elementos básicos. El primero es un <code>box</code> de color <code>invis</code>
(invisible) y sobre él, se dibuja una línea utilizando los puntos
conectores, de oeste (<code>.w</code>) a norte (<code>.n</code>), a este (<code>.e</code>), después a
sur (<code>.s</code>) y lo cerramos con <code>close</code>. Como queremos los extremos
angulosos le decimos que el radio sea cero, <code>rad 0</code> y por último
pasamos un parámetro <code>$1</code>. Ese parámetro está donde estaría el texto
normalmente, centrado en el centro geométrico de la linea que hemos
dibujado, y por tanto, al llamar a <code>rombo</code> lo hacemos pasándole una
cadena, que será la que escriba en esa posición.
</p>

<p>
El <a href="https://pikchr.org/home/doc/trunk/doc/userman.md">manual de usuario</a> es bastante corto e incompleto, por ejemplo lo de
definir figuras compuestas lo he sacado mirando código de algunos
ejemplos y de los <i>tests</i> que se incluyen con el código fuente. Luego
investigando he encontrado referencia en los manuales de <i>PIC</i> y de
<i>GnuPIC</i>, que están enlazados en la documentación de <i>Pikchr</i>.
</p>
</div>
</div>
<div id="outline-container-org1ee2618" class="outline-2">
<h2 id="org1ee2618">Instalación</h2>
<div class="outline-text-2" id="text-org1ee2618">
<p>
Quizá debería haber empezado por este punto más arriba. Posiblemente.
Pero quería crear algo de expectación sobre la herramienta antes de
hablar de su instalación, porque no he encontrado ningún paquete ya
hecho para <i>OpenSuse Tumbleweed</i>, que es la <i>distro</i> de <i>GNU/Linux</i>
que uso habitualmente. Ignoro si habrá paquetes precompilados en otras
distribuciones de <i>GNU/Linux</i> o si estará compilado para otros
sistemas operativos. En mi caso lo he compilado y todo ha sido muy
sencillo. Es código en <code>c</code> que utiliza apenas las librerías más
básicas de <i>entrada-salida</i> para hacer su trabajo.
</p>

<p>
Descargué el fichero <code>tar.gz</code> de la página <i>web</i> del proyecto (que
como se puede apreciar es un repositorio <code>fossil</code>) y compilé.
Simplemente tecleé <code>make</code>, generó un par de ejecutables: <code>lemon</code><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>
y <code>pikchr</code>. Copié el segundo en mi directorio <code>~/opt/bin</code>, que es
donde instalo las aplicaciones que compilo, mis <i>scripts</i> y mis
programas, y a partir de ahí lo tengo disponible y completamente
funcional en mi línea de comandos; sin dependencias de librerías ni
nada más, sólo el ejecutable.
</p>
</div>
<div id="outline-container-org893814b" class="outline-3">
<h3 id="org893814b">Alternativas a la compilación</h3>
<div class="outline-text-3" id="text-org893814b">
<p>
Si te estás diciendo que para qué compilar, que te da pereza hacer
esas cosas a estas alturas del siglo XXI y tal y tal. También puedes
utilizarlo de otras maneras.
</p>

<p>
La primera, como dije es que viene integrado en <code>fossil</code>. De hecho, lo
descubrí mirando la ayuda de este gestor de versiones e investigando
para qué servía el comando <code>pikchr</code> desde la línea de comandos, porque
no me había tropezado con semejante instrucción en ninguno de los
sistemas de control de versiones que había manejado antes. Vi que
generaba <code>svg</code> y también encontré en la ayuda de la documentación del
<i>wiki</i> interno, que se podía utilizar para generar gráficos en dicha
documentación... Pero a lo que vamos, que me enrollo y no aclaro
nada. Si tienes instalado <code>fossil</code> puedes generar los gráficos
utilizando éste último con una sencilla llamada:
</p>

<div class="org-src-container">
<pre class="src src-shell">fossil pikchr [opciones] archivo.pikchr archivo.svg
</pre>
</div>

<p>
Las opciones las miráis en la <i>ayuda</i> de <code>fossil</code> que sería muy largo
explicarlas todas.
</p>

<p>
Si no tienes esa herramienta instalada siempre puedes utilizar la
<a href="https://pikchr.org/home/pikchrshow">Herramienta interactiva que hay en su página</a> <i>web</i> para generar tus
gráficos.
</p>


<figure id="org155391b">
<img src="./imagenes/Captura_herramienta-interactiva.png" alt="Captura_herramienta-interactiva.png">

</figure>

<p>
Como podemos ver, tiene dos paneles, escribimos nuestros comandos en
uno y podemos ir viendo lo que ocurre en el otro. Cuando terminamos la
forma de descargar el resultado es un poco peculiar. Debemos pinchar
en el <i>pichorro</i> donde dice <code>svg</code> y copiará el contenido al
portapapeles como texto. Debemos pegarlo con un editor dentro de un
fichero. Pero como alternativa, también nos sirve.
</p>
</div>
</div>
</div>
<div id="outline-container-orgd9dfef8" class="outline-2">
<h2 id="orgd9dfef8">Conclusiones</h2>
<div class="outline-text-2" id="text-orgd9dfef8">
<p>
Soy novato con esta herramienta y aún me quedan cosas por probar. La
documentación que he encontrado tampoco es muy amplia. Me ha llamado
la atención <i>PIC</i> (<code>gpic</code>), un programa antiguo que me hubiera gustado
conocer en aquellos días, cuando me pegaba con el <i>postscript</i> a pelo.
</p>

<p>
Seguiré utilizando <code>graphviz</code> y <code>plantuml</code> para embeber gráficos en
<code>org-mode</code>, puesto que los soporta <code>org-babel</code> y, sin embargo, no
existe el <code>ob-pikchr</code> necesario.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Disculpad si lo he traducido al castellano. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<code>lemon</code> es un ejecutable intermedio que ayuda en la generación
del ejecutable importante, que es <code>pikchr</code>. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/gráficos/index.html">gráficos</a> <a href="/tags/pikchr/index.html">pikchr</a> <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/fossil/index.html">fossil</a> ]]></description>
  <category><![CDATA[gráficos]]></category>
  <category><![CDATA[pikchr]]></category>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[fossil]]></category>
  <link>https://notxor.nueva-actitud.org/2022/07/05/pikchr.html</link>
  <pubDate>Tue, 05 Jul 2022 16:33:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Fossil-scm]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-06-26</div>
<p>
<a href="https://notxor.nueva-actitud.org/2020/11/30/probando-fossil.html">Ya comenté</a> que estaba probando <a href="https://fossil-scm.org/home/doc/trunk/www/index.wiki">Fossil-scm</a> para ver si merecía la pena
el cambio después de los esfuerzos que he hecho para comprender
<a href="https://git-scm.com/">git-scm</a>, el que nunca parece que llegaré a dominar me esfuerce lo que
me esfuerce. Algunos me habéis preguntado si <i>Fossil</i> no se aleja
demasiado de la filosofía <i>Unix</i> que tanto me gusta y es cierto, lo
hace, pero estoy dispuesto a concederle una excepción en mis
preferencias y otros, me habéis hecho otras preguntas. En este
artículo, quiero contar mis experiencias de uso de la herramienta,
tras más de un año utilizándolo y ya no en pruebas, además de
contestar algunas preguntas sobre <i>ramas</i> y <i>forks</i> que surgieron <a href="https://notxor.nueva-actitud.org/2022/05/08/control-de-versiones.html">a
raíz de otro artículo</a> anterior donde contaba cómo utilizarlo desde
<i>Emacs</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. Por tanto, dejadme que el formato sea el de preguntas y
respuestas.
</p>
<div id="outline-container-org702dd91" class="outline-2">
<h2 id="org702dd91">¿Por qué te gusta <i>Fossil</i> si se aleja tanto de la <i>filosofía Unix</i>?</h2>
<div class="outline-text-2" id="text-org702dd91">
<p>
Sí, es cierto. <i>Fossil</i> te proporciona muchas más herramientas que el
simple seguimiento del código de un proyecto; una <i>web</i> de repositorio
donde puedes encontrar multitud de herramientas:
</p>

<ul class="org-ul">
<li>Un <i>wiki</i> para la documentación</li>
<li>Foro para intercambiar opiniones</li>
<li>Gestión de <i>tickets</i> o tareas, que se pueden abrir, adjudicar,
priorizar, modificar y cerrar cuando estén cumplidas.</li>
<li>Herramientas de administración del repositorio.</li>
<li><i>Chat</i> para intercambiar opiniones en directo.</li>
<li>Documentación de ayuda de <i>Fossil</i>.</li>
</ul>

<p>
Proporciona, por defecto, todo lo que proporcionan páginas como <a href="https://github.com/">github</a>
o <a href="https://about.gitlab.com/">gitlab</a> (entre las privativas), o <a href="https://gitea.io">gitea</a>, o <a href="https://codeberg.org/">codeberg</a>. Lo tienes todo
dentro de un único fichero, que es una base de datos <code>sqlite3</code> y te lo
puedes llevar donde quieras. Puedes usarlo en un servidor o como
repositorio local, o ambas cosas. Utilizo, además, <i>Nextcloud</i> para
que me haga de <i>remoto</i> con los repositorios. Cuando utilizaba
repositorios <i>git</i>, la actualización de <i>Nextcloud</i> solía lanzarme
errores, tenía que asegurarme que los directorios ocultos se
actualizaban correctamente. Con <i>Fossil</i> no existe ese problema.
</p>
</div>
</div>
<div id="outline-container-orgac88f6a" class="outline-2">
<h2 id="orgac88f6a">¿Cómo creo un repositorio nuevo?</h2>
<div class="outline-text-2" id="text-orgac88f6a">
<p>
El proceso es sencillo. Voy a crear un proyecto nuevo para hacer
pruebas con él y no estropear ninguno de los míos. En mi caso, tengo
agrupados los repositorios en <code>~/Nextcloud/repos</code> y los locales donde
trabajo en <code>~/proyectos</code>. Los pasos son los siguientes:
</p>

<ol class="org-ol">
<li><p>
Crear el fichero que hará de repositorio.
</p>

<div class="org-src-container">
<pre class="src src-shell">fossil init ~/Nextcloud/repos/prueba-fossil.fossil
</pre>
</div>

<p>
Nos contestará algo parecido a:
</p>

<pre class="example" id="org70945b0">
≻ fossil init ~/Nextcloud/repos/prueba-fossil.fossil
project-id: 97a74719ac63a1231e43a2c5c15fbc39416fa807
server-id:  9f581b18342998e2d839e559c954357b97876cd4
admin-user: notxor (initial password is "FDrW4pztN6")
</pre>

<p>
Podemos observar que crea un usuario administrador con el nombre de
nuestro usuario y establece una contraseña para el mismo. La
contraseña no la pide cuando trabajes en local, pero si el <i>repo</i>
se accede a través de servidor será necesaria.
</p></li>

<li><p>
Crear el directorio de trabajo y entrar en él:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #8be9fd; font-style: italic;">cd</span> ~/proyectos
mkdir prueba-fossil
<span style="color: #8be9fd; font-style: italic;">cd</span> ~/proyectos/prueba-fossil
</pre>
</div></li>

<li><p>
Abrir el repositorio de trabajo se hace utilizando el comando
<code>open</code> en ese directorio. Nos contará algo como lo siguiente:
</p>

<pre class="example" id="orgd0dc235">
≻ fossil open ~/Nextcloud/repos/prueba-fossil.fossil 
project-name: &lt;unnamed&gt;
repository:   /home/notxor/Nextcloud/repos/prueba-fossil.fossil
local-root:   /home/notxor/proyectos/prueba-fossil/
config-db:    /home/notxor/.config/fossil.db
project-code: 97a74719ac63a1231e43a2c5c15fbc39416fa807
checkout:     7d1e11d43506a1c32815d181bd1e7a3a09f6eb15 2022-06-25 09:40:22 UTC
tags:         trunk
comment:      initial empty check-in (user: notxor)
check-ins:    1
</pre></li>
</ol>

<p>
A partir de aquí ya podemos trabajar en el contenido y sincronizar el
trabajo con nuestro repositorio remoto, que en mi caso, gracias a
<i>Nextcloud</i>, también es local pero guarda copia en otra máquina
remota.
</p>
</div>
</div>
<div id="outline-container-org2715a26" class="outline-2">
<h2 id="org2715a26">¿Cómo descargo un repositorio a mi disco duro?</h2>
<div class="outline-text-2" id="text-org2715a26">
<p>
Esta pregunta tiene dos acepciones en <i>Fossil</i>, una es descargarte el
archivo contenedor y otra es <i>abrir</i> un repositorio local donde hacer
cambios, compilar el código, etc. Hemos visto ya, que para abrir un
repositorio local de trabajo tenemos que hacer el paso del punto 3 de
la pregunta anterior. Así que me centraré en obtener un fichero
<code>.fossil</code> de un servidor remoto.
</p>

<p>
Para las pruebas voy a necesitar un servidor. Voy a montar uno con mis
<i>repos</i>, que los guardo, como ya he dicho, en <code>~/Nextcloud/repos</code>.
Levantar un servidor local es tan sencillo como utilizar el comando
<code>server</code> de <i>Fossil</i>:
</p>

<pre class="example" id="orgce8ca27">
  &gt; fossil server ~/Nextcloud/repos --port 8080
Listening for HTTP requests on TCP port 8080
</pre>

<p>
A partir de ahí están disponibles todos los repositorios que haya en
ese directorio, en ficheros con extensión <code>.fossil</code>, pero recuerda que
son bases de datos <i>SQLite3</i>. Para conectarnos al servidor del
repositorio, podemos utilizar cualquier navegador:
</p>


<figure id="org2c25342">
<img src="./imagenes/Captura_conexion-al-server.png" alt="Captura_conexion-al-server.png">

</figure>

<p>
Podemos apreciar que se apunta la <code>URL</code> a <code>localhost</code> y se añade el
nombre del repositorio sin la extensión <code>.fossil</code>. Para descargar el
repositorio completo <i>clonándolo</i> en un directorio local.
</p>

<div class="org-src-container">
<pre class="src src-shell">&#8827; fossil clone http://localhost:8080/prueba-fossil prueba-fossil.fossil
Round-trips: 2   Artifacts sent: 0  received: 4
Clone done, wire bytes sent: 544  received: 1327  ip: 127.0.0.1
Rebuilding repository meta-data...
  100.0% complete...
Extra delta compression... 
Vacuuming the database... 
project-id: 97a74719ac63a1231e43a2c5c15fbc39416fa807
server-id:  3a8847c1dea9b851e362ebbbe689c11257344c50
admin-user: notxor (password is <span style="color: #f1fa8c;">"qY7GseCMph"</span>)
</pre>
</div>

<p>
Vemos que nos genera un nuevo fichero <code>.fossil</code>, con el nombre de
nuestro usuario (en mi caso <code>notxor</code>) y nos proporciona una contraseña
para conectarnos con este repositorio, que es distinta a la contraseña
del repositorio remoto.
</p>

<p>
Suele ser más sencillo hacerlo en un único paso si hacemos desde el
servidor un <code>open</code> en lugar de un clone. Para hacerlo desde cero he
borrado el directorio de trabajo y lo he vuelto a crear vacío. Luego
he hecho el siguiente comando:
</p>

<pre class="example" id="org118bf72">
≻ fossil open http://localhost:8080/prueba-fossil
fossil clone http://localhost:8080/prueba-fossil /home/notxor/proyectos/prueba-fossil/prueba-fossil.fossil
Round-trips: 2   Artifacts sent: 0  received: 4
Clone done, wire bytes sent: 550  received: 1327  ip: 127.0.0.1
Rebuilding repository meta-data...
  100.0% complete...
Extra delta compression... 
Vacuuming the database... 
project-id: 97a74719ac63a1231e43a2c5c15fbc39416fa807
server-id:  f160e27ad3a030c343c86d842d8e2abf0400a389
admin-user: notxor (password is "UtWc3CDZgA")
Pull from http://localhost:8080/prueba-fossil
Round-trips: 1   Artifacts sent: 0  received: 0
Pull done, wire bytes sent: 321  received: 359  ip: 127.0.0.1
project-name: &lt;unnamed&gt;
repository:   /home/notxor/proyectos/prueba-fossil/prueba-fossil.fossil
local-root:   /home/notxor/proyectos/prueba-fossil/
config-db:    /home/notxor/.config/fossil.db
project-code: 97a74719ac63a1231e43a2c5c15fbc39416fa807
checkout:     7d1e11d43506a1c32815d181bd1e7a3a09f6eb15 2022-06-25 09:40:22 UTC
tags:         trunk
comment:      initial empty check-in (user: notxor)
check-ins:    1
</pre>

<p>
No me gusta tener el <code>.fossil</code> local en el mismo directorio que el
código y como digo, suelo utilizar repositorios que son alcanzables de
manera local. Sin embargo, cuando he clonado un repositorio a través
de red recomiendo los siguientes pasos:
</p>

<ol class="org-ol">
<li><p>
Crear el directorio del proyecto:
</p>

<pre class="example" id="org69a8955">
≻ cd proyectos
≻ mdkir proyecto-nuevo
≻ cd proyecto-nuevo
</pre></li>

<li><p>
Clonar el repositorio:
</p>

<pre class="example" id="orgc2d569c">
≻ fossil clone https://usuario:password@sitio-repo/nuevo-proyecto ../nuevo-proyecto.fossil
</pre>

<p>
Fíjate que paso el usuario y la contraseña. También se puede
emplear <code>ssh</code>, por ejemplo. En todo caso, el <code>.fossil</code> clonado
prefiero que esté en el directorio padre (en mi caso <code>~/proyectos</code>)
y no donde el código fuente.
</p></li>

<li><p>
Abrir el repositorio clonado:
</p>

<pre class="example" id="orge09b289">
≻ fossil open ../nuevo-proyecto.fossil
</pre></li>
</ol>

<p>
Si todo ha ido bien, cada cambio que hagamos en ese repositorio se
asignará al usuario que hayamos utilizado en la URL del paso 2.
También nos preguntará si queremos que recuerde la contraseña, si le
decimos que sí la recordará y la sincronización será más rápida. Si
tenemos activado <code>auto-sync</code> en el repositorio, cuando hagamos cambios
en el local, se subirán al remoto sin necesidad de hacer <code>push</code>
(particularmente, prefiero ser yo quien decida cuándo modifico el
<i>repo</i> remoto y lo tengo desactivado en todos mis <i>repos</i>).
</p>
</div>
</div>
<div id="outline-container-orgf8bea0d" class="outline-2">
<h2 id="orgf8bea0d">¿Por qué <code>fossil</code> no me muestra los archivos nuevos?</h2>
<div class="outline-text-2" id="text-orgf8bea0d">
<p>
Si estás acostumbrado a otros sistemas, es posible que al preguntar con
<code>fossil status</code> cuál es el estado del repositorio, te sorprenda que no
muestre archivos nuevos. Crearé uno en nuestro repositorio de pruebas
para que se vea correctamente el asunto:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #8be9fd; font-style: italic;">echo</span> <span style="color: #f1fa8c;">"Esto es un repositorio de pruebas para mostrar c&#243;mo funciona `fossil-scm`."</span> &gt; README.md
</pre>
</div>

<p>
En nuestro repositorio estarán los siguientes ficheros:
</p>

<pre class="example" id="org7d081c3">
≻ ls
prueba-fossil.fossil  README.md
</pre>

<p>
Vemos claramente el archivo <i>clonado</i> y nuestro nuevo <code>README.md</code>, sin
embargo, al mirar el estado del repositorio, nos aparece lo siguiente:
</p>

<pre class="example" id="org9953e83">
≻ fossil status
repository:   /home/notxor/proyectos/prueba-fossil/prueba-fossil.fossil
local-root:   /home/notxor/proyectos/prueba-fossil/
config-db:    /home/notxor/.config/fossil.db
checkout:     7d1e11d43506a1c32815d181bd1e7a3a09f6eb15 2022-06-25 09:40:22 UTC
tags:         trunk
comment:      initial empty check-in (user: notxor)
</pre>

<p>
No se ha enterado de nuestro nuevo archivo. Para que el repositorio lo
tenga en cuenta, debemos añadir la opción <code>--extra</code> al comando:
</p>

<pre class="example" id="org2638613">
≻ fossil status --extra
repository:   /home/notxor/proyectos/prueba-fossil/prueba-fossil.fossil
local-root:   /home/notxor/proyectos/prueba-fossil/
config-db:    /home/notxor/.config/fossil.db
checkout:     7d1e11d43506a1c32815d181bd1e7a3a09f6eb15 2022-06-25 09:40:22 UTC
tags:         trunk
comment:      initial empty check-in (user: notxor)
EXTRA      README.md
</pre>

<p>
Está marcado como <code>EXTRA</code>, es decir, <i>no pertenece al repositorio</i>. Si
queremos que <code>fossil</code> lo tenga en cuenta, debemos añadirlo al mismo.
</p>

<pre class="example" id="orgc0d9ce7">
≻ fossil add README.md 
ADDED  README.md
≻ fossil status
repository:   /home/notxor/proyectos/prueba-fossil/prueba-fossil.fossil
local-root:   /home/notxor/proyectos/prueba-fossil/
config-db:    /home/notxor/.config/fossil.db
checkout:     7d1e11d43506a1c32815d181bd1e7a3a09f6eb15 2022-06-25 09:40:22 UTC
tags:         trunk
comment:      initial empty check-in (user: notxor)
ADDED      README.md
</pre>

<p>
Para completar el proceso, vamos a hacer un <code>commit</code>:
</p>

<pre class="example" id="orgd3a9cf7">
≻ fossil commit -m "Añadido fichero README.md"
Pull from http://localhost:8080/prueba-fossil
Round-trips: 1   Artifacts sent: 0  received: 0
Pull done, wire bytes sent: 393  received: 360  ip: 127.0.0.1
New_Version: bf6f949de739c5965d80ba8e2ad9b67a412442d7d73766f66239fbee03be9c6b
Sync with http://localhost:8080/prueba-fossil
Round-trips: 1   Artifacts sent: 2  received: 0
Sync done, wire bytes sent: 670  received: 356  ip: 127.0.0.1
Warning: The check-in was successful and is saved locally but you
         are not authorized to push the changes back to the server
         at http://localhost:8080/prueba-fossil
</pre>

<p>
Lo primero que hace es un <code>pull</code> del repositorio remoto. Pero llama
más la atención el <code>warning</code> final. Para sincronizar el repositorio
local con el remoto necesitamos hacerlo con usuario y contraseña:
</p>

<pre class="example" id="orgd17c2ec">
≻ fossil sync http://localhost:8080/prueba-fossil -B notxor:Mi-Contraseña
Round-trips: 1   Artifacts sent: 0  received: 0
Sync done, wire bytes sent: 529  received: 397  ip: 127.0.0.1
</pre>
</div>
</div>
<div id="outline-container-org5892ae8" class="outline-2">
<h2 id="org5892ae8">No entiendo cómo se gestionan las ramas</h2>
<div class="outline-text-2" id="text-org5892ae8">
<p>
Vamos a imaginar que necesitamos dos ramas de desarrollo para nuestro
magnífico proyecto de pruebas y vamos a crear dos ramas:
</p>

<div class="org-src-container">
<pre class="src src-bash">&#8827; fossil branch new Primera trunk
&#8827; fossil branch new Segunda trunk
</pre>
</div>

<p>
Ahora, si hacemos un listado con las ramas del repositorio nos dirá lo
siguiente:
</p>

<pre class="example" id="org4fda2c2">
≻ fossil branch ls
   Primera
   Segunda
 * trunk
</pre>

<p>
El listado de ramas muestra tres ramas: <code>trunk</code>, marcada con un <code>*</code> es
la rama activa de nuestro <i>repo</i>. En la <i>timeline</i> gráfica se puede
apreciar lo siguiente:
</p>


<figure id="org4b9f80c">
<img src="./imagenes/Captura_timeline-ramas.png" alt="Captura_timeline-ramas.png">

</figure>

<p>
Otra curiosidad de <i>Fossil</i> es que, como se puede ver en la imagen, al
final de cada rama, el último <code>commit</code> es el <code>leaf</code> de la misma.
</p>

<p>
Vamos a hacer cambios en una rama, por ejemplo, en <code>Primera</code> y
seguimos el siguiente procedimiento:
</p>

<ol class="org-ol">
<li><p>
Cambiar a la rama <code>Primera</code>:
</p>

<pre class="example" id="orga8ea986">
≻ fossil branch ls
   Primera
   Segunda
 * trunk
≻ fossil update Primera
-------------------------------------------------------------------------------
checkout:     13f6106d312e9aa54ae326f0576761287d31a527 2022-06-25 12:02:22 UTC
tags:         Primera
comment:      Create new branch named "Primera" (user: notxor)
changes:      None. Already up-to-date
≻ fossil branch ls
 * Primera
   Segunda
   trunk
</pre></li>
</ol>

<p>
Tras hacer unos cambios en el único archivo que tenemos y subir esos
cambios, en cada una de esas ramas tenemos un gráfico similar a:
</p>


<figure id="orgba61269">
<img src="./imagenes/Captura_cambios-ramas.png" alt="Captura_cambios-ramas.png">

</figure>

<p>
Llevar los cambios a <code>trunk</code> no es complicado. Recordemos que en
<i>Fossil</i> no existe el <code>rebase</code>, sólo el <code>merge</code>.
</p>

<pre class="example" id="org96f84a3">
≻ fossil update trunk
UPDATE README.md
-------------------------------------------------------------------------------
updated-from: 3d3eede7e32fd6e3024e41cd8f61bccae3842597 2022-06-25 13:46:08 UTC
updated-to:   a359332a2a5961dec66f59142d762d3d137dd8a2 2022-06-25 12:01:45 UTC
tags:         trunk
comment:      Añadido fichero README.md (user: notxor)
changes:      1 file modified.
 "fossil undo" is available to undo changes to the working checkout.
≻ fossil merge Primera
UPDATE README.md
 "fossil undo" is available to undo changes to the working checkout.
≻ fossil commit -m "Commit para el merge con la rama Primera."
New_Version: d76eb3b89ad477536069e218cbdbc075c25c043d62ca28a53942ac05780ed05f
</pre>

<p>
Los pasos han sido:
</p>

<ol class="org-ol">
<li>Cambiar a la rama <code>trunk</code></li>
<li>Hacer <code>merge</code> con la rama <code>Primera</code></li>
<li>Hacer un <code>commit</code> con los cambios aportados por el <code>merge</code>.</li>
</ol>

<p>
El gráfico queda así:
</p>


<figure id="org63e6bcd">
<img src="./imagenes/Captura_arbol-merge.png" alt="Captura_arbol-merge.png">

</figure>

<pre class="example" id="org372a545">
≻ fossil merge Segunda
MERGE README.md
***** 1 merge conflict in README.md
WARNING: 1 merge conflicts
"fossil undo" is available to undo changes to the working checkout.
≻ emacs -nw README.md
</pre>

<p>
Al hacer el <code>merge</code> con la segunda rama, como era de esperar, hay
conflictos pues sólo hay un archivo y con poco contenido que separe
suficientemente los cambios para que no entren en conflicto. El
aspecto del fichero <code>README.md</code>, al editarlo, es el siguiente:
</p>


<figure id="org73b1dcc">
<img src="./imagenes/Captura_conflictos-merge.png" alt="Captura_conflictos-merge.png">

</figure>

<p>
Una vez hechos los cambios lo dejamos así:
</p>

<pre class="example" id="org5272bb6">
Esto es un repositorio de pruebas para mostrar cómo funciona
`fossil-scm`.

Esto es un listado con cambios:

+ Cambios en la rama `Primera`
+ Es un cambio hecho desde la `Segunda` rama.
</pre>

<p>
Una vez solucionados los conflicto, ya podemos hacer el <code>commit</code> y
nuestro árbol quedará así:
</p>


<figure id="orgb21affd">
<img src="./imagenes/Captura_arbol-fusion-dos-ramas.png" alt="Captura_arbol-fusion-dos-ramas.png">

</figure>

<p>
Hay que recordar que los cambios en las dos ramas se han pasado a
<code>trunk</code>, pero si volvemos a una de las ramas:
</p>

<pre class="example" id="org86cbc1c">
≻ fossil update Primera
UPDATE README.md
-------------------------------------------------------------------------------
updated-from: e09a941c5d43eb1faa333db47a0c87bcb8b001f7 2022-06-25 14:13:54 UTC
updated-to:   a4838e1179459d57804d159ef0155d0c54d47118 2022-06-25 12:07:43 UTC
tags:         Primera
comment:      Cambios para el ejemplo en la rama Primera. (user: notxor)
changes:      1 file modified.
 "fossil undo" is available to undo changes to the working checkout.
≻ fossil merge trunk
UPDATE README.md
 "fossil undo" is available to undo changes to the working checkout.
</pre>

<p>
Al cambiar a la rama <code>Primera</code> lo primer que nos advierte con <code>UPDATE
README.es</code> es que debemos actualizar porque ha habido cambios que no
están en esta rama. Hacemos un <code>merge</code> con <code>trunk</code> y debería estar ya
toda la información cargada en esta rama también, también podríamos
haber hecho un <code>update</code>. Te recuerdo que no hay <code>rebase</code> en <i>Fossil</i>
pero se pueden hacer los <code>merges</code> y <code>updates</code> que sean necesarios. Voy
también a hacerlo en la otra rama:
</p>

<pre class="example" id="org98357fd">
≻ fossil update Segunda
MERGE README.md
-------------------------------------------------------------------------------
updated-from: a4838e1179459d57804d159ef0155d0c54d47118 2022-06-25 12:07:43 UTC
updated-to:   3d3eede7e32fd6e3024e41cd8f61bccae3842597 2022-06-25 13:46:08 UTC
tags:         Segunda
comment:      Cambios para el ejemplo en la rama Segunda. (user: notxor)
changes:      1 file modified.
uncommitted merge against e09a941c5d.
WARNING: 1 uncommitted prior merges
 "fossil undo" is available to undo changes to the working checkout.
</pre>

<p>
En este caso, como vemos, <code>fossil</code> pide un <code>merge</code>. Cuando <code>fossil</code>
pide <code>update</code>, normalmente no habrá conflicto, pero si pide <code>merge</code>
sí. No quiero liar mucho la perdiz, sigamos sin más conflictos, por el
momento.
</p>

<p>
Volvemos a la primera rama, la que llamamos <code>Primera</code>. Después de
hacer el <code>merge</code> con <code>trunk</code> lo suyo sería hacer un <code>commit</code> para
sincronizar el repositorio y la copia de trabajo:
</p>

<pre class="example" id="orgef2e28a">
≻ fossil branch ls
 * Primera
   Segunda
   trunk
≻ fossil commit -m "Merge con la rama principal."
New_Version: 5519680712d91b66d2ce32121ded84c47e10a7869c80b5d2da40f3587e2c987a
</pre>

<p>
¿Cómo se ve gráficamente? Te puedes estar preguntando, así:
</p>


<figure id="orgd3d8191">
<img src="./imagenes/Captura_continuar-rama.png" alt="Captura_continuar-rama.png">

</figure>

<p>
Si nos fijamos en el gráfico, es posible liarse con tanta flechita,
sin embargo, ya me he acostumbrado a ello e interpreto las líneas más
finas como el camino que llevan los cambios de una rama a otra. Es
decir, ese gráfico lo interpreto como que los cambios han ido de las
ramas <code>Primera</code> y <code>Segunda</code> a la rama <code>trunk</code>. Luego, desde <code>trunk</code>,
los cambios (los de la rama <code>Segunda</code>) pasan a la rama <code>Primera</code>.
</p>
</div>
<div id="outline-container-orgcbfa87a" class="outline-3">
<h3 id="orgcbfa87a"><code>Forks</code></h3>
<div class="outline-text-3" id="text-orgcbfa87a">
<p>
No hay mucha diferencia entre lo que en <i>Fossil</i> se llama <code>fork</code> y lo
que es una rama (<code>branch</code>) ¿Cuál es la diferencia?, pues que una rama
es un <code>fork</code> hecho de manera voluntaria. Cualquier división o
ramificación en el repositorio es una rama o un <code>fork</code> según cómo lo
mires o lo quieras llamar. Por tanto, existen ramas creadas de manera
accidental... ¿cómo?
</p>

<p>
Imagina que dos usuarios del repositorio están modificando el mismo
fichero de manera independiente. El primero en terminar su trabajo, lo
subirá al repositorio. El segundo sigue trabajando y cuando termina
sube los cambios al repositorio. En ese momento, <i>Fossil</i> le avisará
de que hay un conflicto. Ha habido cambios desde que actualizó por
última vez el repositorio:
</p>

<ul class="org-ul">
<li>Si subiera sus cambios, machacaría el trabajo del primero.</li>
<li>Si hace un <code>pull</code> del repositorio para actualizarse, puede perder su
trabajo.</li>
</ul>

<p>
Si opta por subir sus cambios forzándolo con <code>--force</code>, lo que hace
<i>Fossil</i> es crear un <code>fork</code> que no machacará el trabajo de nadie.
Después se hará un <code>merge</code> o lo que sea necesario, para actualizar
todos los cambios. Si se opta por actualizar sin hacer un <code>fork</code> lo
habitual es hacer:
</p>

<pre class="example" id="orgfd94e02">
fossil upgrade -n -v
</pre>

<p>
La opción <code>-n</code> hace lo que llaman un <code>dry-run</code>. Básicamente hará un
<code>update</code> de los ficheros donde no haya conflictos y un <code>merge</code> de los
que entren en conflicto. Hecho eso se modifican los archivos
conflictivos para arreglarlos y luego se hará el <code>commit</code> sin
problemas.
</p>
</div>
</div>
</div>
<div id="outline-container-org1d3adba" class="outline-2">
<h2 id="org1d3adba">¿Cómo puedo convertir un repositorio de <code>git</code> a <code>fossil</code>?</h2>
<div class="outline-text-2" id="text-org1d3adba">
<p>
Tanto <code>git</code> como <code>fossil</code> tienen comandos para importar y exportar los
datos de un repositorio. Hay modos de pasar un repositorio de una
herramienta a otra. Recuerda que en el de <i>Fossil</i> también hay
entradas para marcar cuándo se ha modificado una página del <i>wiki</i> o
se ha creado un <i>ticket</i>, o se ha cambiado su prioridad, o se ha
completado, o... <i>Git</i> no tiene dichos <i>chismáticos</i> así que esas
partes no se pueden importar ni exportar. Para eso utilizaremos la
opción <code>--git</code> indicándole a <code>fossil</code> que se ciña a lo que entiende
dicha herramienta.
</p>

<p>
Para importar a <i>Fossil</i> un repositorio desde <i>Git</i>, se emplea el
siguiente método:
</p>

<pre class="example" id="org863123a">
cd git-repo
git fast-export --all | fossil import --git nuevo-repo.fossil
</pre>

<p>
con ese par de comandos, vale son tres, pero dos están enlazados
con un <code>pipe</code> para usar la salida de uno como la entrada del otro,
obtenemos el fichero <code>nuevo-repo.fossil</code>. Una vez obtenido lo podemos
ya clonar, abrir o lo que queramos hacer con él.
</p>

<p>
Para hacerlo al contrario. Es decir, pasar un repositorio de <i>Fossil</i>
a <i>Git</i>, los pasos son similares pero inversos:
</p>

<pre class="example" id="orgca0db80">
git init nuevo-repo
cd nuevo-repo
fossil export --git /camino/al/repo.fossil | git fast-import
</pre>

<p>
Como se puede apreciar, aquí la diferencia es que primero hay que
crear el directorio del nuevo repositorio para <code>git</code> y luego se le
pide a <code>fossil</code> la información estando en el directorio que queremos
utilizar como repositorio.
</p>
</div>
</div>
<div id="outline-container-orge8b68a7" class="outline-2">
<h2 id="orge8b68a7">¿Se puede tener un repositorio <code>fossil</code> y actualizar un <code>git</code>?</h2>
<div class="outline-text-2" id="text-orge8b68a7">
<p>
La respuesta corta es <i>no</i>. Pero puedes sincronizar un par de
repositorios, uno <i>Git</i> y otro <i>Fossil</i>. Se puede, según la
documentación de <i>Fossil</i>, pero yo nunca lo he conseguido hacer sin
obtener algún error bloqueante. Lo mismo tú tienes más suerte que yo
(o no eres tan <i>patazas</i>).
</p>

<p>
Imagina que tienes un <i>repo</i> remoto en <i>Fossil</i> que quieres
sincronizar con un <i>repo</i> en <i>Git</i>. La documentación afirma que habría
que hacer algo así (lo copio literalmente, para no cagarla):
</p>

<pre class="example" id="org15b1f65">
fossil clone /path/to/remote/repo.fossil repo.fossil
mkdir repo
cd repo
fossil open ../repo.fossil
mkdir ../repo.git
cd ../repo.git
git init .
fossil export --git --export-marks ../repo/fossil.marks  \
       ../repo.fossil | git fast-import                  \
       --export-marks=../repo/git.marks
</pre>

<p>
Una vez completada la descarga se necesitaría actualizar con <code>git
checkout trunk</code>. En todo caso, hecho esto, se supone que los cambios
en el repositorio <i>Fossil</i> se pueden importar al repositorio <i>Git</i> con
la siguiente secuencia:
</p>

<pre class="example" id="orgf9ecf7e">
cd ../repo
fossil pull
cd ../repo.git
fossil export --git --import-marks ../repo/fossil.marks  \
       --export-marks ../repo/fossil.marks               \
       ../repo.fossil | git fast-import                  \
       --import-marks=../repo/git.marks                  \
       --export-marks=../repo/git.marks
</pre>

<p>
Al contrario, los cambios en el repositorio de <i>Git</i> se pueden
actualizar en el de <i>Fossil</i> de la siguiente manera:
</p>

<pre class="example" id="org9d3abe3">
git fast-export --import-marks=../repo/git.marks                  \
    --export-marks=../repo/git.marks --all | fossil import --git  \
    --incremental --import-marks ../repo/fossil.marks             \
    --export-marks ../repo/fossil.marks ../repo.fossil
cd ../repo
fossil push
</pre>

<p>
Como digo, no conseguí que me funcionara. Sólo lo he intentado una vez
para un proyecto muy concreto, que se inició y lo tengo en un
repositorio de <a href="https://codeberg.org">Codeberg</a> y que quería hacer el seguimiento también con
<i>Fossil</i>. Tras una mañana de tirarme de los pelos decidí abandonar y
dejar que continuara sólo en repositorio de <i>Git</i>.
</p>
</div>
</div>
<div id="outline-container-org90acfa4" class="outline-2">
<h2 id="org90acfa4">Conclusiones</h2>
<div class="outline-text-2" id="text-org90acfa4">
<p>
Llevo un año utilizando <i>Fossil</i>, me proporciona un montón de
herramientas que utilizo en mis repositorios privados. No lo he
utilizado, al menos aún, en uno público o compartido con alguien. Por
tanto, mi experiencia es limitada a mis cosas. Y lo suelo utilizar
siempre o casi siempre a través de línea de comandos, incluso para los
<i>settings</i>. Aunque suelo consultar los <i>repos</i>, escribir en los
<i>wikis</i> o crear los <i>tickets</i> desde la interfaz gráfica del
navegador.
</p>

<p>
Aunque es un rival para <code>git</code>, sigo utilizando este, por tanto, no lo
veo una <i>alternativa</i>. A mí me va bien para mis cosas, pero si
participo en otro proyecto con más gente lo habitual es que utilicen
<code>git</code>, y no me molesta, no creo que sean excluyentes para mi modo de
trabajar. Sí es cierto que cuando inicio un proyecto nuevo lo hago con
<i>Fossil</i>. Además he estado siguiendo algunos vídeos de su creador
<i>Richard Hipp</i>, creador también de <i>SQLite</i>. En ellos critica <code>git</code>,
bien, bueno... ¿qué va a decir el padre de la otra criatura?... pues
eso, <i>mi niño es el mejor</i>.
</p>

<p>
Había preparado un ejercicio más largo con más respuestas a más
preguntas, pero creo que ya me ha quedado un <i>ladrillo</i> bastante
infumable, así que os dejo una de las capturas:
</p>


<figure id="orgefb73b0">
<img src="./imagenes/Captura_cambiar-mensaje-de-commit.png" alt="Captura_cambiar-mensaje-de-commit.png">

</figure>

<p>
Iba a ilustrar una de las preguntas que era si se pueden cambiar los
mensajes del <code>commit</code> una vez en el repositorio. La respuesta es sí,
se puede, en la imagen se puede ver que se ha hecho y que
automáticamente ha generado otro <i>evento</i> en la <i>timeline</i> que dice
que la hemos cambiado (el de encima de la pila).
</p>

<p>
Me dejo en el tintero el tema de gestión de usuarios en repositorios
remotos, pero como eso también lo tenéis en la documentación que viene
con <i>Fossil</i> y realmente es bastante sencillo, no le doy más vueltas
al tema. Además, la interfaz gráfica para dicha gestión está plagada
de ayuda para aclararte lo que haces, sólo tienes que leer.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Que por cierto, a los <i>talibanes</i> de la filosofía Unix que usan
<i>Emacs</i>... en fin.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/fossil/index.html">fossil</a> ]]></description>
  <category><![CDATA[fossil]]></category>
  <link>https://notxor.nueva-actitud.org/2022/06/26/fossil-scm.html</link>
  <pubDate>Sun, 26 Jun 2022 10:14:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Abreviaturas en Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-06-02</div>
<p>
Una de las formas de ahorrar algunas pulsaciones de teclas es utilizar
<i>abreviaturas</i>. Ya hablé por aquí de los <i>snippets</i>, que serían
plantillas más o menos extensas de estructuras de texto repetitivas.
Las abreviaturas son sus hermanas pequeñas y consisten en algo tan
sencillo como sustituir un texto corto, una abreviatura, por una
expresión más larga de una o más palabras.
</p>

<p>
Para hacerlo todo más práctico, voy a mostrar dos ejemplos sencillos y
de ese modo creo que será más comprensible el mecanismo de las
abreviaturas. He hecho una copia de seguridad de las abreviaturas que
tengo definidas para mí, y partiré de cero para no enfangar las mías
con las pruebas que pueda hacer en el presente artículo.
</p>

<p>
Hay que tener en cuenta que las abreviaturas pueden ser generales y
encontrarse disponibles para todos los modos, o pueden ser <i>locales</i>
del modo mayor que esté activo. Aunque generalmente, programando,
suelen ser más útiles los <i>snippets</i> y <code>completion</code>, también podemos
aprovechar la inmediatez de las abreviaturas. Los ejemplos que voy a
mostrar comprenden las dos opciones: definiré uno de manera global y
otro de manera local. Aunque, como veréis, el procedimiento es el
mismo y sólo cambia el comando invocado.
</p>

<p>
Por otro lado, también podemos decir que las abreviaturas son un modo
menor (<code>abbrev-mode</code>) que nos permite utilizarlas. Más adelante
veremos que podemos usarlas sin necesidad de tener el modo activo
invocando un comando; sin embargo, la mayor parte de su potencia se
deriva de la sustitución <i>automágica</i> de textos mientras escribimos.
</p>
<div id="outline-container-orgea0d94f" class="outline-2">
<h2 id="orgea0d94f">Definir abreviaturas</h2>
<div class="outline-text-2" id="text-orgea0d94f">
<p>
Imagina que tenemos un texto largo que se repite con cierta frecuencia
y queremos escribir menos, pero que el texto sea completo. No parto de
una lista completamente vacía, pues hay algunos modos como <code>pydev</code> que
proporcionan sus correspondientes abreviaturas. Pero si utilizas el
comando <code>list-abbrevs</code>, te aparecerá algo como lo siguiente:
</p>


<figure id="org9f91793">
<img src="./imagenes/Captura de pantalla_lista-vacia.png" alt="Captura de pantalla_lista-vacia.png">

</figure>

<p>
Por poner un ejemplo, voy a definir una abreviatura desde el siguiente
supuesto: cuando escribo artículos es muy habitual que tenga que
escribir muchas veces la palabra <code>Emacs</code>, porque es uno de mis temas
favoritos. Como me voy a dejar la yema de los dedos en el intento, voy
a escribir una abreviatura que cuando me encuentre en <code>org-mode</code>, que
es el modo en el que escribo los artículos, me permita escribirlo con
un par de pulsaciones de tecla, es decir, que cuando yo escriba
<code>em&lt;SPC&gt;</code> lo expanda a <code>Emacs</code>. El procedimiento es sencillo:
</p>

<ol class="org-ol">
<li>Escribo la palabra completa: <code>Emacs</code></li>
<li>Después pulso <code>C-x a l</code></li>
<li>Me pide una abreviatura: <code>em&lt;RET&gt;</code></li>
</ol>

<p>
Ya está, a partir de ahora, cuando esté activado <code>abbrev-mode</code> en el
modo mayor <code>org-mode</code> y yo escriba <code>em</code>, <i>Emacs</i> escribirá toda la
palabra por mí. Para comprobarlo, veamos nuestra lista de abreviaturas
modificada:
</p>


<figure id="orgb563c9d">
<img src="./imagenes/Captura_abreviatura-emacs.png" alt="Captura_abreviatura-emacs.png">

</figure>

<p>
Cuando sólo queremos expandir una palabra es sencillo. Algo más lioso
cuando queremos sustituir varias palabras, pero porque tenemos que
decirle a <i>Emacs</i> cuántas debe tomar con el prefijo <code>C-u num</code>. Vamos a
suponer que quiero definir la abreviatura del texto siguiente:
</p>

<p>
GNU's not Unix
</p>

<p>
y quiero establecerla a <code>gnu</code>. Es decir, cada vez que pulse las teclas
<code>g</code>, <code>n</code>, <code>u</code>, <code>&lt;SPC&gt;</code>, ─siendo éste último cualquier carácter
considerado como tal, no sólo la tecla de espacio, también la coma, el
punto, etc.─, lo sustituirá por el texto completo. Para definirlo,
hago el siguiente procedimiento:
</p>

<ol class="org-ol">
<li>Escribo el texto completo: «GNU's not Unix»</li>
<li>Nada más escribirlo pulso la siguiente combinación de teclas:
<code>C-u 3 C-x a g</code>. Fijaos que en esta ocasión estoy utilizando <code>C-x a
   g</code> y por tanto la definición será <i>global</i>.</li>
<li>En la línea de estado nos pide la abreviatura: <code>gnu&lt;RET&gt;</code></li>
</ol>

<p>
Como he dicho antes, he cambiado el comando para hacerlo global y he
utilizado el prefijo <code>C-u 3</code> para indicarle a <i>Emacs</i> que debe
utilizar las tres palabras anteriores a la posición del cursor.
Podemos comprobarlo también mirando la lista de abreviaturas.
</p>


<figure id="orgf7a8d7e">
<img src="./imagenes/Captura_abreviaturas.png" alt="Captura_abreviaturas.png">

</figure>

<p>
Aprovecho para llamar la atención sobre la lista de abreviaciones.
Nos abre un <i>buffer</i> de nombre <code>*Abbrevs*</code>, pero vemos que el modo es
<code>edit-abbrevs</code>, lo que nos da pie a modificarlas directamente en ese
espacio. Por ejemplo, puesto que suelo escribir la palabra <i>Emacs</i>,
generalmente en cursiva, he aprovechado y he puesto los delimitadores
de este tipo de letra en la expresión. Tras guardar con <code>C-x C-s</code>,
cada vez que escriba <code>em</code> el editor lo cambiará por <code>/Emacs/</code>.
</p>

<p>
Otra forma de modificar el contenido de las abreviaciones es, una vez
que lo tenemos salvado en un fichero, por defecto
<code>~/.emacs.d/abbrev_defs</code>, podemos modificar el código fuente, que en
nuestro caso aparecerá del siguiente modo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;</span><span style="color: #6272a4;">-*-coding: utf-8;-*-
</span>(define-abbrev-table 'global-abbrev-table
  '(
    (<span style="color: #f1fa8c;">"gnu"</span> <span style="color: #f1fa8c;">"GNU's not Unix"</span> nil <span style="color: #8be9fd; font-style: italic;">:count</span> 0)
   ))

(define-abbrev-table 'org-mode-abbrev-table
  '(
    (<span style="color: #f1fa8c;">"em"</span> <span style="color: #f1fa8c;">"/Emacs/"</span> nil <span style="color: #8be9fd; font-style: italic;">:count</span> 5)
   ))
</pre>
</div>
</div>
</div>
<div id="outline-container-org2a4129e" class="outline-2">
<h2 id="org2a4129e">Resumen de comandos</h2>
<div class="outline-text-2" id="text-org2a4129e">
<p>
Hay poco más que contar una vez que comprendes cómo funciona este
modo. Para resumir un poco las cosas que se pueden hacer con él, voy a
dar un repaso a los principales comandos, la combinación de teclas
asignada y para qué sirve cada uno. Por ejemplo, para definir
abreviaturas y gestionarlas se utilizan los siguientes comandos:
</p>

<dl class="org-dl">
<dt><code>C-x a g</code> (<code>add-global-abbrev</code>)</dt><dd>Define una abreviatura global que
estará disponible en todos los modos. Es el equivalente interactivo
al comando <code>M-x define-global-abbrev &lt;RET&gt; abrv &lt;RET&gt; expresión
  &lt;RET&gt;</code></dd>
<dt><code>C-x a l</code> (<code>add-mode-abbrev</code>)</dt><dd>Define una abreviatura para el modo
mayor activo en ese momento. Es el equivalente interactivo al
comando <code>M-x define-mode-abbrev &lt;RET&gt; abrv &lt;RET&gt; expresion &lt;RET&gt;</code>.</dd>
<dt><code>M-x kill-all-abbrevs</code></dt><dd>Elimina todas las abreviaturas definidas.</dd>
<dt><code>C-x a i g</code> (<code>inverse-add-global-abbrev</code>)</dt><dd>Define una palabra en el
texto del <i>buffer</i> como una abreviatura global y solicitará su
correspondiente <i>expansión</i> en el <i>minibuffer</i>.</dd>
<dt><code>C-x a i l</code> (<code>inverse-add-mode-abbrev</code>)</dt><dd>Define una palabra del
<i>buffer</i> como abreviatura del modo. Funciona de manera similar al
anterior comando.</dd>
<dt><code>M-x edit-abbrevs</code></dt><dd>Nos muestra la lista de abreviaturas definidas
en un <i>buffer</i> y nos permite modificarlas.</dd>
<dt><code>M-x write-abbrev-file &lt;RET&gt; nombre &lt;RET&gt;</code></dt><dd>Escribe en el archivo
<code>nombre</code> todas las definiciones de abreviaturas activas.</dd>
<dt><code>M-x read-abbrev-file &lt;RET&gt; nombre &lt;RET&gt;</code></dt><dd>Lee el archivo <code>nombre</code>
y carga las definiciones de abreviaturas que contiene. Hay otro
comando similar, <code>quietly-read-abbrev-file</code>, cuya única diferencia
es que no muestra ningún mensaje en el <i>minibuffer</i>.</dd>
</dl>

<p>
Estos dos últimos comandos son muy útiles cuando queremos mantener
nuestras abreviaturas agrupadas por temática. Me explico: hay veces en
que un área de nuestro trabajo necesita ciertas abreviaturas y pueden
chocar con otras que tengamos definida en otras áreas. Estos comandos
nos permiten tener varios archivos, que podemos activar según el tema
en el que estemos trabajando.
</p>

<p>
Hay algunos otros comandos que nos permiten controlar la <i>expansión</i>
del contenido de las abreviaturas.
</p>

<dl class="org-dl">
<dt><code>C-x a e</code> (<code>expand-abbrev</code>)</dt><dd>Expande la abreviatura. Es efectivo
incluso cuando <code>abbrev-mode</code> no está activo. Vamos, que normalmente,
si estuviera activo, no lo necesitarás. Pero es bueno saber que si
se te ha olvidado activarlo o, por algún motivo lo has desactivado,
puedes seguir utilizando tus abreviaturas definidas.</dd>
<dt><code>M-x unexpand-abbrev</code></dt><dd>Su función es dejar la abreviatura tal cual
sin expandirla, pero hablaré un poco más en el siguiente apartado.</dd>
<dt><code>M-x expand-region-abbrevs</code></dt><dd>Expande todas las abreviaturas que se
encuentren en la región seleccionada.</dd>
<dt><code>M-/</code> (<code>dabbrev-expand</code>)</dt><dd>Expande la palabra en el <i>buffer</i> como
una <i>abreviatura dinámica</i>. Es decir, busca en el <i>buffer</i> la última
palabra que comience igual y la expande. Por ejemplo, si comenzamos
a escribir <code>abr</code> y pulsamos <code>M-/</code> en este <i>buffer</i>, lo expandirá,
posiblemente, a la palabra <i>abreviatura</i>. Un comando similar es
<code>hippie-expand</code> que si lo usamos repetidamente nos muestra varias
posibles expansiones, en lugar de sólo la última, por lo que me
parece más útil y os recomiendo más su uso.</dd>
</dl>

<p>
También puede ocurrir que hayamos definido nosotros, o algún modo lo
haga, abreviaturas en el sistema y que por olvido o desconocimiento
estemos tecleando todo el texto. Se puede habilitar a <i>Emacs</i> que nos
avise de que un determinado texto tiene definida una abreviatura
activando en nuestro <code>init.el</code> la variable <code>abbrev-suggest</code>. De esta
manera nos advertirá de que contamos con la posibilidad de ahorrarnos
tecleos. Si nos hemos perdido algunos de esos avisos podemos utilizar
el comando <code>abbrev-suggest-show-report</code> que nos hará un informe de
todas las sugerencias que nos haya hecho el sistema durante la sesión
de trabajo.
</p>
</div>
</div>
<div id="outline-container-orgcc0f957" class="outline-2">
<h2 id="orgcc0f957">Recomendaciones</h2>
<div class="outline-text-2" id="text-orgcc0f957">
<p>
Es posible que haya ocasiones que no queramos que nos sustituya la
abreviatura por su expresión. Ya hemos visto que el comando es <code>M-x
unexpand-abbrev</code>. Otra opción, que es la que uso yo, en curarnos en
salud y utilizar abreviaturas con caracteres especiales que sea raro
que se necesiten tal cual en un texto. Por ejemplo, para mis cosas
suelo utilizar de prefijo el carácter <code>'</code> o el <code>¡</code>. Por hacerlo más
gráfico, mi modo usual para definir los ejemplos del principio del
artículo, hubiera sido utilizar <code>'g</code> en lugar de <code>gnu</code> y <code>'e</code> en lugar
de <code>em</code> para las abreviaturas. De esta forma es más raro encontrarse
el caso de tener que revertir una sustitución.
</p>

<p>
Por defecto, <code>unexpand-abbrev</code> no está mapeada a ninguna tecla. Si
utilizas habitualmente las abreviaturas y lo necesitas, considera el
mapear dicha función a una combinación de teclas.  En el manual
recomiendan utilizar <code>C-q</code>. En mi caso, dado que utilizo el sistema
anterior, no suelo necesitarlo, pero está bien recordar que tienes la
posibilidad de hacerlo.
</p>

<p>
Como vimos en el apartado anterior <code>hippie-expand</code> es un comando
también bastante más útil que el simple <code>dabbrev-expand</code> y, es
posible, que quieras mapear la combinación <code>M-/</code> a aquel comando en
lugar de al que viene mapeado por defecto.
</p>
</div>
</div>
<div id="outline-container-org4560519" class="outline-2">
<h2 id="org4560519">Conclusiones</h2>
<div class="outline-text-2" id="text-org4560519">
<p>
Mientras programo me resulta más cómodo el uso de <code>completion</code> y de
<code>snippets</code> que el de abreviaturas. Sin embargo, también reconozco
puede ser útil.  Aunque, se me ha dado el caso que acostumbrado a
algunas abreviaturas en <i>Emacs</i>, al tener que cambiar de editor, se me
ha hecho la adaptación un poco pesada. Tecleaba la abreviatura y al
ver que no se expandía recordaba que no estaba en <i>Emacs</i> y que tenía
que teclear el texto correctamente.
</p>

<p>
Las abreviaturas pueden representar un gran ahorro de pulsaciones de
teclas. Pero también significa que debes invertir tiempo en ajustar y
afinar todo tu sistema de abreviaturas para que te sean útiles a largo
plazo.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2022/06/02/abreviaturas-en-emacs.html</link>
  <pubDate>Thu, 02 Jun 2022 09:14:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Trókola]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-05-06</div>
<p>
Estaba aburrido, esto es lo único que puede decir en mi descargo. Hoy
traigo un nuevo <i>vaporware</i>, por supuesto maravilloso, que veremos
acabar en ningún sitio, en cuanto aparezca un nuevo proyecto más nuevo
y por tanto mucho más emocionante.  El caso es que en el artículo
anterior ya os hablé de mi redescubrimiento de mi olvidado
<code>Tcl/Tk</code>. ¿Sería conveniente hacer algo con él para afianzarlo? <i>Sí,
claro</i>... y ¿qué hago? Me vino una idea perversa a la que no pude
resistirme: <i>Hacer un sistema o una librería para programar aventuras
conversacionales con Tcl</i>. Muy bien, pero mejor no cuento nada, porque
al final seguro que se queda en nada como el 99% de los proyectos de
programación y... <i>¿qué dices? ¡Si tienes un blog casi en
barbecho</i>. Pues nada, aquí estoy para <i>cansinaros</i> un rato.
</p>
<div id="outline-container-orgf0ce3c1" class="outline-2">
<h2 id="orgf0ce3c1">El proyecto</h2>
<div class="outline-text-2" id="text-orgf0ce3c1">
<p>
Se llama «Trókola». Sí, ya sé, a algunos les sonará lo de la «junta de
la trócola» como excusa de mecánico caradura para inflar la factura.
No tengo una idea muy clara de por qué lo he llamado así, más allá de
porque no se me ocurría otro. Pero como es <i>mi</i> proyecto lo llamo como
me apetece.
</p>

<p>
Hay quien afirma que cada jugador de <i>conversacionales</i> tiene el sueño
de programar la suya ─la más maravillosa del mundo mundial─ y que todo
programador de <i>conversacionales</i> anhela hacer su herramienta de
creación, ─por supuesto, también la mejor del mundo mundial─. Ese no
es mi caso: no creo que <i>Trókola</i> aspire a ser el sistema definitivo,
ni tan siquiera creo que nadie lo vaya a utilizar nunca.  Incluso no
creo que esto lo lea nadie del mundillo de las aventuras
conversaciones.  Tampoco me he puesto objetivos que cumplir, ni sé
hasta dónde quiero llegar, de momento, me conformo con unas pocas
cosas, la primera y fundamental, como he dicho, lo de afianzar el
lenguaje para mis necesidades del futuro. Por otro lado, me he
encontrado que también lo podré utilizar en el móvil a través de
<code>Termux</code> (y he comprobado que funciona el poco código que hay).
</p>

<p>
Como digo, no me planteo que sea el mejor sistema del universo, pero
me gustaría trabajar varias características que me parecen importantes
y que otros sistemas obvian o lo hacen casi de perfil.
</p>

<dl class="org-dl">
<dt><b>Multilingüe</b></dt><dd>La mayoría de los sistemas están programados en
inglés para la lengua inglesa, con su gramática y sintaxis. Adaptar
posteriormente cualquier otro idioma se hace muy complicado. Sobre
todo cuando ese idioma tiene una gramática más compleja que el
inglés. Lo voy a diseñar por tanto en español con su sintaxis más
compleja, pero con el Esperanto en mente, con una sintaxis mucho más
simple, para trabajar los mecanismos de ajuste y simplificación.</dd>
<dt><b>Rolero</b></dt><dd>La mayoría de sistemas contemplan el escueto «la
violencia no es el camino» o cualquier otra similar para eludir el
hecho de la complejidad que se esconde cuando hay que simular
combates, puntos de vida, características de los personajes, etc. Y,
por supuesto, porque <i>matar orcos</i> puede ser también divertido.</dd>
<dt><b>Abierto</b></dt><dd>Quizás no es la palabra adecuada. Con <i>abierto</i> quiero
decir que los personajes no estén <i>enclaustrados</i> en lo que contiene
la clásica <i>room</i>. Es decir, que puedan oír o ver lo que hay en
localizaciones adyacentes o alcanzables mediante los sentidos, que
si hay una ventana en una habitación, pueda ver el personaje lo que
hay en el patio, por ejemplo. Y que el creador del juego no tenga
que <i>trampear</i> el sistema para que eso se pueda hacer.</dd>
</dl>

<p>
Estas son los objetivos de partida para lo que quiero hacer y si por
casualidad termina no siendo tan <i>vaporware</i> como creo, me gustaría
también tener en cuenta algunos otros aspectos, digamos secundarios,
que trabajar en el futuro:
</p>

<dl class="org-dl">
<dt><b>Distribución</b></dt><dd>¿Cómo se podría distribuir un juego con este
sistema? Hay intérprete de <code>Tcl</code> para casi cada sistema operativo
(en <i>GNU/Linux</i> seguramente está instalado en la mayoría de
máquinas). Pero quizá no está bien pedir a los posibles jugadores
que se lo instalen sólo para un juego y habría que hacer un
intérprete simple, para cada sistema, que corra el juego. Por tanto,
me quiero limitar a sólo utilizar lo básico de <code>Tcl</code>. Nada de
librerías de programación orientada a objetos, ni de ningún otro
tipo. Sólo utilizando las estructuras de datos que proporciona el
lenguaje de base: listas, arrays, diccionarios, etc. Quizá es una
limitación autoimpuesta superflua porque no creo que haya nunca un
juego terminado con él, pero no quiero añadir mierdas de las que
luego me puedo arrepentir. Cuanto más simple y menos dependencias
mejor.</dd>
<dt><b>Multijugador</b></dt><dd>Jugar siempre es más divertido cuando juegas con
alguien. Sería un lujo, poder jugar varias personas, bien llevando
el mismo personaje o, mucho mejor, llevando cada uno un personaje
distinto y que puedan jugar una conversacional al estilo de un MUD
pequeñito para tres, cuatro o cindo jugadores a lo sumo, cada uno
con su correspondiente personaje. Además, una de sus posibles
utilidades para mí, iría por hacerlo multijugador, aunque fuera de
pocos jugadores pero que cada uno llevara su personaje.</dd>
<dt><b>Un poco de multimedia no hace daño</b></dt><dd>Son aventuras de texto, puro
y duro, pero tampoco se hacen ascos a algún gráfico o sonido que
ilustren lo que dice el contenido. Que no den pistas extra o
despisten, pero que aporten un poco más de refinamiento.</dd>
</dl>
</div>
</div>
<div id="outline-container-orgb26175b" class="outline-2">
<h2 id="orgb26175b">Inicio del proyecto</h2>
<div class="outline-text-2" id="text-orgb26175b">
<p>
De momento hay poco que enseñar, más que las ganas de hacerlo. Pero he
empezado ya con ello. He creado un repositorio <code>fossil</code> e incluso he
escrito las primeras líneas de código, sincronizando el <i>remoto</i> en mi
nube personal de <i>Nextcloud</i>.
</p>
</div>
<div id="outline-container-org29d299e" class="outline-3">
<h3 id="org29d299e">Cómo y por qué <code>fossil</code></h3>
<div class="outline-text-3" id="text-org29d299e">
<p>
Ya dije que llevo tiempo utilizando <code>fossil</code> para mis proyectos
particulares, aún a riesgo de que me critiquen los más puristas de la
filosofía <i>Unix</i>. Por esto, empezaré por los porqués y luego hablaré
de cómo.
</p>

<p>
Algunos proyectos son privados, es decir, los hago sólo para mí y no
creo que le puedan interesar a nadie más o directamente no son de la
incumbencia de nadie más, como por ejemplo, mi contabilidad. He venido
utilizando algunos subterfugios como utilizar <code>Nextcloud</code> como
servidor remoto para poder llevarlos. Sin embargo, me encuentro
siempre con problemas con <code>git</code> y lo mal que se lleva <i>Nextcloud</i> con
los archivos y directorios ocultos. <code>git</code> guarda la información en un
sin fin de archivos de nombres incomprensibles y se da, de vez en
cuando, el caso de que <i>Nextcloud</i> da error en alguno de ellos. Por
contra, <code>fossil</code> utiliza <code>sqlite3</code>, lo guarda todo en una base de
datos y todavía no se me ha dado el caso de que falle una
sincronización. Además, allá donde copie ese fichero, tengo un
repositorio completo.
</p>

<p>
Utilizando <code>git</code> además necesito siempre un archivo donde anotar ideas
y todo lo relacionado con el proyecto que no forma parte del proyecto
propiamente. Otro(s) para la documentación, etc. En el caso de
<code>fossil</code>, el mismo repositorio cuenta con <i>wiki</i>, gestión de tareas
(<i>tickets</i>), foro, <i>chat</i>... bueno, vale, el <i>chat</i> no lo uso conmigo
mismo, pero todo lo demás sí: en el foro abro hilos sobre las
características que me gustaría que tuviera y me creo un <i>ticket</i> por
cada tarea que debo hacer, en el <i>wiki</i> voy escribiendo documentación
del proyecto, etc. La interfaz <i>UI</i> es una página <i>web</i>, que si bien
no tiene el más glorioso diseño, funciona bien y rápido. Y cualquier
anotación en él, bien sea en el foro, en la <i>wiki</i>, sea en el código o
en los <i>tickets</i>, se añade a la línea de tiempo y tengo referencia de
cuándo se hizo, puedo filtrar las modificaciones del repositorio que
quiero ver: todas, wiki, foro, tareas, o que oculte alguna. En fin,
toda esto me da una visión más completa de la historia del proyecto.
Por ejemplo, lo poco que hay hecho del proyecto se ve así:
</p>


<figure id="orge7a21ef">
<img src="./imagenes/Captura_timeline.png" alt="Captura_timeline.png">

</figure>

<p>
Por otro lado, como curiosidad, todo este mundillo de <a href="https://fossil-scm.org"><code>fossil</code></a> y
<a href="https://sqlite.org"><code>sqlite3</code></a>, <a href="https://tcl.tk/"><code>Tcl/Tk</code></a>, etc. parece formar un ecosistema un tanto
endémico. Si vas a la página <code>Tcl</code> tiene toda la pinta de ser un
repositorio <code>fossil</code>, igualmente con <code>sqlite3</code>. Además, <code>fossil</code> y
<code>sqlite3</code> son del mismo autor. El primer lenguaje con soporte para
<code>squlite</code> fue <code>Tcl</code>, hecho por el mismo autor, que embebe una versión
minimalista del <code>tclsh</code> como lenguaje de <i>script</i> para su herramienta
de gestión de repositorios <code>fossil</code>.
</p>

<p>
Utilizar un repositorio <code>fossil</code> no es muy distinto de hacerlo con
otras herramientas de control de versiones. La documentación viene
incluida y se puede consultar con <code>fossil help</code>. Por resumir, lo
primero que debemos hacer es iniciar el repositorio. En nuestro caso:
</p>

<div class="org-src-container">
<pre class="src src-shell">fossil init ~/Nextcloud/repos/trokola.fossil
</pre>
</div>

<p>
ese comando creará el fichero <code>sqlite3</code> que hace de repositorio. La
extensión <code>.fossil</code> es opcional, podemos utilizar cualquiera, sin
embargo, la uso, porque en el caso de utilizar <code>fossil</code> en modo
servidor simplemente lanzo:
</p>

<div class="org-src-container">
<pre class="src src-shell">fossil server ~/Nextcloud/repos --port 8081
</pre>
</div>

<p>
De este modo, todos los archivos con la extensión <code>.fossil</code> en ese
directorio, se sirven como repositorios remotos. Basta con añadir el
nombre del fichero a la dirección del servidor y entras directamente
en el repositorio:
</p>


<figure id="org83e8f97">
<img src="./imagenes/Captura_modo-servidor.png" alt="Captura_modo-servidor.png">

</figure>

<p>
Como se puede apreciar, al utilizarlo en <i>modo servidor</i> pide usuario
y contraseña para poder modificar cualquier cosa del mismo. En modo
<i>local</i> te <i>logea</i> con tu usuario.
</p>

<p>
Hasta aquí sólo hemos creado el repositorio en un sitio que vamos a
tratar como si fuera remoto, puesto que es el fichero que se va
mantener en la nube de <i>Nextcloud</i>. Ahora debemos crearnos la copia
local.
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #8be9fd; font-style: italic;">cd</span> proyectos
mkdir trokola
<span style="color: #8be9fd; font-style: italic;">cd</span> trokola
fossil open ~/Nextcloud/trokola.fossil
</pre>
</div>

<p>
Esta acción nos crea otro archivo, en este caso oculto <code>.fslckout</code> que
contiene el repositorio local. Una cosa es <i>abrir</i> nuestro repositorio y
otra sincronizarlo. Para hacer que sincronice con el repositorio
puesto en <i>Nextcloud</i> como remoto debemos añadirlo a la lista:
</p>

<div class="org-src-container">
<pre class="src src-shell">fossil remote add origin ~/Nextcloud/repos/trokola.fossil
</pre>
</div>

<p>
Ese comando añade nuestro repositorio con el nombre <code>origin</code>. A partir
de ahora basta con que hagamos <code>fossil push</code> para subir nuestros
<i>commits</i> al repositorio remoto. O si tenemos varios remotos y sólo
queremos actualizar uno de ellos <code>fossil push repositorio</code>, donde
<code>repositorio</code> sería el nombre que hemos utilizado para ese remoto.
</p>
</div>
</div>
</div>
<div id="outline-container-orgea91806" class="outline-2">
<h2 id="orgea91806">Primer código</h2>
<div class="outline-text-2" id="text-orgea91806">
<p>
El código hasta ahora es muy simple, pero ya comprende el primer
<i>comando</i> o <i>acción</i> del sistema: <i>salir</i>. No voy a extenderme mucho
en explicaciones que seguramente os resultarán <i>cansinas</i>.
</p>


<figure id="orgc51e85c">
<img src="./imagenes/Captura_codigo-fuente.png" alt="Captura_codigo-fuente.png">

</figure>

<p>
De momento todo está embutido en un solo fichero llamado <code>trokola.tcl</code>
que consiste, en el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-tcl">  <span style="color: #6272a4;">#!/usr/bin/tclsh
</span>
<span style="color: #6272a4;"># </span><span style="color: #6272a4;">#####################################################################
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Trokola - Herramienta de ficci&#243;n interactiva con Tcl/Tk
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Copyright (C) 2022 -- Notxor <a href="mailto:notxor%40nueva-actitud.org">&lt;notxor@nueva-actitud.org&gt;</a>
</span><span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">This program is free software: you can redistribute it and/or modify
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">it under the terms of the GNU General Public License as published by
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">the Free Software Foundation, either version 3 of the License, or
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">(at your option) any later version.
</span><span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">This program is distributed in the hope that it will be useful,
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">GNU General Public License for more details.
</span><span style="color: #6272a4;">#</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">You should have received a copy of the GNU General Public License
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">along with this program.  If not, see <a href="https://www.gnu.org/licenses/&gt;.
# ######################################################################

proc prompt {{t &quot;">&lt;https://www.gnu.org/licenses/&gt;.
</a></span><span style="color: #6272a4;"><a href="https://www.gnu.org/licenses/&gt;.
# ######################################################################

proc prompt {{t &quot;"># </a></span><span style="color: #6272a4;"><a href="https://www.gnu.org/licenses/&gt;.
# ######################################################################

proc prompt {{t &quot;">######################################################################
</a></span><a href="https://www.gnu.org/licenses/&gt;.
# ######################################################################

proc prompt {{t &quot;">
</a><span style="color: #ff79c6; font-weight: bold;"><a href="https://www.gnu.org/licenses/&gt;.
# ######################################################################

proc prompt {{t &quot;">proc</a></span><a href="https://www.gnu.org/licenses/&gt;.
# ######################################################################

proc prompt {{t &quot;"> </a><span style="color: #50fa7b; font-weight: bold;"><a href="https://www.gnu.org/licenses/&gt;.
# ######################################################################

proc prompt {{t &quot;">prompt</a></span><a href="https://www.gnu.org/licenses/&gt;.
# ######################################################################

proc prompt {{t &quot;"> {{t </a><span style="color: #f1fa8c;"><a href="https://www.gnu.org/licenses/&gt;.
# ######################################################################

proc prompt {{t &quot;">"&gt;</a> "</span>}} {
    <span style="color: #8be9fd; font-style: italic;">puts</span> -nonewline $<span style="color: #f8f8f2; font-weight: bold;">t</span>
    <span style="color: #8be9fd; font-style: italic;">flush</span> stdout
}

<span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">terminar</span> {{despedida <span style="color: #f1fa8c;">"Adi&#243;s."</span>}} {
    <span style="color: #8be9fd; font-style: italic;">puts</span> $<span style="color: #f8f8f2; font-weight: bold;">despedida</span>
    <span style="color: #ff79c6; font-weight: bold;">exit</span> 0
}

<span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">procesa</span> {linea} {
    <span style="color: #ff79c6; font-weight: bold;">switch</span> $<span style="color: #f8f8f2; font-weight: bold;">linea</span> {
        abandonar {terminar}
        <span style="color: #ff79c6; font-weight: bold;">default</span> {<span style="color: #8be9fd; font-style: italic;">puts</span> <span style="color: #f1fa8c;">"Has dicho: $linea"</span>}
    }
}

<span style="color: #6272a4;">###############################################################################</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">#                               </span><span style="color: #6272a4;">Bucle Principal                               #
</span><span style="color: #6272a4;">###############################################################################</span><span style="color: #6272a4;">
</span><span style="color: #ff79c6; font-weight: bold;">while</span> {true} {
    prompt
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">linea</span> [<span style="color: #8be9fd; font-style: italic;">gets</span> stdin]
    procesa $<span style="color: #f8f8f2; font-weight: bold;">linea</span>
}
</pre>
</div>

<p>
He eliminado, en este listado del código fuente, los comentarios de
las funciones donde se explican los parámetros que reciben y lo que
devuelven y hacen.
</p>

<p>
De momento al hacerlo funcionar lo que hace es entrar en el bucle
principal y repetir todo lo que le enviemos sin procesar, de momento,
nada más. En el procedimiento <code>procesa</code> si la línea es «abandonar»
llama a al procedimiento <code>terminar</code> que sale de nuevo al sistema
mostrando una despedida.
</p>

<p>
Supongo que estaréis pensando <i>¡Qué mierda de código!</i>, y os doy la
razón. Pero esto es sólo la semilla de la que nacerá el nuevo inútil
sistema.
</p>
</div>
</div>
<div id="outline-container-org2940084" class="outline-2">
<h2 id="org2940084">Conclusión</h2>
<div class="outline-text-2" id="text-org2940084">
<p>
Un amiguete me dice que no cuente nada, que cuando lo cuentas, los
proyectos se <i>gafan</i> de alguna manera y no salen. No tengo esas
supersticiones, los proyectos salen o <i>se ponen</i> según el empeño de
los que los llevan a cabo. Sé que programaré con mucho empeño,
compaginándolo con otros proyectos en marcha, en ratos libres, durante
dos o tres meses. Si he terminado algo decente en ese tiempo, se lo
enseñaré a alguien y si no, pues se quedará en el motón de
<i>pendientes</i>. Pero seguro que por el camino encontraré buen
aprendizaje.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/conversacionales/index.html">conversacionales</a> <a href="/tags/programación/index.html">programación</a> <a href="/tags/tcl/index.html">tcl</a> ]]></description>
  <category><![CDATA[conversacionales]]></category>
  <category><![CDATA[programación]]></category>
  <category><![CDATA[tcl]]></category>
  <link>https://notxor.nueva-actitud.org/2022/05/06/trokola.html</link>
  <pubDate>Fri, 06 May 2022 19:42:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Tcl/Tk]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-04-24</div>
<p>
Un lenguaje que aparece recursivamente en mi línea de trabajo y al que
normalmente no he hecho mucho caso es <code>Tcl</code> y su <i>toolkit</i> <code>Tk</code>. Es
posible que a la mayoría os suene el <code>Tk</code>, por la librería de <i>Python</i>
o cualquier otro lenguaje de <i>script</i> que lo utilice para añadir
<i>widgets</i> de una manera sencilla. Es posible que incluso lo tengas
instalado en tu ordenador sin saberlo, especialmente si utilizas
GNU/Linux como sistema operativo. Lo usa <code>sqlite</code>, lo usa <code>fossil</code>, lo
que no es de extrañar porque ambas herramientas vienen del mismo
programador, pero lo utilizan otras herramientas también.  La
explicación para hacerle un poco de <i>casito</i> de nuevo a este lenguaje
es que últimamente estoy dándole más a <code>fossil</code> como herramienta de
control de versiones y me he visto utilizando un subconjunto de <code>Tcl</code>
que trae embebido... y ¡oye, no está tan mal y lo dejaba siempre
olvidado!  Vaya una pequeña introducción al lenguaje y de sus
principales características, sin ánimo de ser exhaustivo.
</p>

<p>
Mi primer contacto con este lenguaje, curiosamente, fue en <i>windows</i>.
En un trabajo donde estuve, trabajábamos con varias «lectoras de
marcas» que se conectaban a través del <code>COM1</code>. El <i>software</i> que
manejaba (absolutamente propietario) buscaba un conector de seguridad
por <i>hardware</i> que se enchufaba en el puerto paralelo de la
impresora. El caso es que me fui de vacaciones y cuando volví, me
habían cambiado el ordenador, habíamos pasado de <i>Windows 98</i> a
<i>Windows XP</i> y me hicieron el cambio a traición. Me habían dejado
encima de la mesa un disco <i>Zip</i> con la copia de seguridad y todo
conectado; habían instalado todos los programas declarados, incluido
el de la lectora de marcas. Sin embargo, no comprobaron que
funcionara: en el ordenador viejo se habían llevado la garrapata de
seguridad, enchufada. Cuando volví ya se habían desecho de los
ordenadores viejos y fue imposible recuperar el <i>chismático de
seguridad anticopia</i>.  Recuerdo que se pidió uno a la casa, pero
mientras tanto, tuvimos que hacer una lectura de exámenes y tuvimos
que escribir y leer del <i>COM1</i> un poco «a pelo». Lo intenté hacer como
pude con <code>C/C++</code>, pero los puertos <code>COM</code> estaban cerrados y era un
cristo abrirlos. Tuvo que venir a ayudarme uno de los informáticos de
la casa. Él instaló una versión de <i>Tcl/Tk</i> y haciendo unas pruebas,
entre los dos conseguimos hacer un proceso simple de lectura/escritura
pudiendo corregir los exámenes que necesitábamos. Los <i>scripts</i> los
guardé y los utilicé más de una vez... el <i>software</i> oficial
<i>caducaba</i> y te sugería que compraras otra máquina (caras de la
muerte). Incluso con esos <i>scripts</i> pude hacer funcionar máquinas
viejas, de tipo manual, de las que tenías que ir metiendo las hojas de
una en una, que estaban guardadas en un armario pero que en alguna
ocasión nos salvó la situación.
</p>

<p>
No voy a ser exhaustivo, está <a href="https://tcl.tk">la web del lenguaje</a> si alguien quiere
profundizar más y también puede encontrar libros y tutoriales
dedicados a este <i>ignorado</i> lenguaje. Y me refiero a <i>ignorado</i> no
porque no lo conozcamos sino a que tiendo a pasar de largo sin
hacerle demasiado caso. Por tanto, como <i>abogado de las causas
perdidas</i>, para intentar que no se sienta tan excluido, voy con una
introducción al mismo.
</p>
<div id="outline-container-org0dcc8e4" class="outline-2">
<h2 id="org0dcc8e4">Introducción a Tcl/Tk</h2>
<div class="outline-text-2" id="text-org0dcc8e4">
<p>
El <code>Tcl/Tk</code>, de <i>Tool Command Language</i>, es uno de esos lenguajes
llamados de <i>script</i>. Pensado para automatizar procesos, no para
programar sistemas. No he comprobado si es rápido o lento, tampoco me
importa demasiado, he hecho algún <i>script</i> para <code>sqlite3</code> en una
(copia de) base de datos que tengo para mi trabajo y me ha parecido
bastante útil.  Principalmente, porque es un lenguaje con unas bases
muy simples y, por tanto, le he cogido enseguida el
gustillo/tranquillo. Por lo que he visto, hay complejidades a las que
no he llegado, porque (aún) no las he necesitado, pero tiene librerías
también para casi cualquier asunto. Puedes abrir <i>canales</i> que pueden
ser ficheros, <i>streams</i>, <i>sockets</i>, tratándolos todos de la misma
manera.
</p>

<p>
Pero voy a dejarme ya de introducción: vamos con las bases del
lenguaje.
</p>
</div>
<div id="outline-container-org5d894a3" class="outline-3">
<h3 id="org5d894a3">Todo son comandos</h3>
<div class="outline-text-3" id="text-org5d894a3">
<p>
Para <code>Tcl/Tk</code> los <i>scripts</i> son una ristra de comandos uno tras otro.
Cada comando comienza con una instrucción o comando, a la que le sigue
una lista de parámetros y termina con un salto de línea o con un punto
y coma. Lo que hay tras el <code>;</code> antes del salto de línea es ignorado
por el intérprete. Esto es invariable y, por ejemplo, no hay operador de
asignación, existe el comando <code>set</code>:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">etiqueta</span> <span style="color: #f1fa8c;">"Hola Mundo!"</span>
<span style="color: #8be9fd; font-style: italic;">puts</span> $<span style="color: #f8f8f2; font-weight: bold;">etiqueta</span>
</pre>
</div>

<p>
Esta característica hace que, viniendo de <code>lisp</code>, casi sienta la
tentación de meter cada comando entre paréntesis.
</p>
</div>
</div>
<div id="outline-container-org7d949d3" class="outline-3">
<h3 id="org7d949d3">No hay tipos, todo son cadenas</h3>
<div class="outline-text-3" id="text-org7d949d3">
<p>
No necesitas convertir unos tipos en otros para operar con ellos,
porque todos son cadenas. Además las cadenas internamente se guardan en
UTF-8 y por tanto no hay problemas con la conversión de códigos.
Alguno se estará preguntando, que si todo es una cadena, por qué en el
ejemplo anterior se escribió la cadena <code>Hola Mundo!</code> rodeada de
comillas... veamos el siguiente ejemplo en la <i>shell</i>:
</p>

<pre class="example" id="org85375c6">
% puts Hola
Hola
% puts Mundo!
Mundo!
% puts Hola Mundo!
can not find channel named "Hola"
% 
</pre>

<p>
Al haber espacios en blanco, <code>Tcl</code> piensa que hay una lista de
parámetros para <code>puts</code>. En ese caso, <code>puts</code> espera que el primer
parámetro sea lo que llama <i>channel</i>, que puede ser un fichero, un
<i>stream</i>, un <i>socket</i>, etc. Cuando sólo tiene un parámetro utiliza la
salida por defecto. Para agrupar esas cadenas se utilizan las
comillas y así se convierten en un solo argumento. También se pueden
utilizar las llaves, con una sutil diferencia. Veamos un ejemplo:
</p>

<pre class="example" id="org2c5f7e1">
% puts "\tHola Mundo!\n"        
      Hola Mundo!

% puts {\tHola Mundo!\n}
\tHola Mundo!\n
</pre>

<p>
Como se puede apreciar, cuando los caracteres <i>aglutinadores</i> son las
comillas, interpreta los caracteres especiales de la cadena, mientras
que cuando utilizamos las llaves no interpreta nada. Y cuando digo que
todo es una cadena, es que todo es una cadena:
</p>

<pre class="example" id="org0993b30">
% set a pu
pu
% set b ts
ts
% $a$b "Hola Mundo!"
Hola Mundo!
</pre>

<p>
Como se puede apreciar se ha formado el comando <code>puts</code> dividiendo la
cadena en dos y guardando cada mitad en una variable diferente. Al
poner ambas variables juntas (concatenadas) se interpretan
sustituyéndolas por su contenido y conformando la sentencia completa
<code>puts "Hola Mundo!"</code>.
</p>

<p>
A estas alturas, algunos estarán pensando: <i>y si todo son cadenas
¿cómo hago cálculos?</i>. La respuesta corta es con el comando <code>expr</code>.
</p>

<pre class="example" id="org8d12225">
% set a 5
5
% set b 10
10
% puts [expr $a+$b]
15
</pre>

<p>
<i>¡Eh! Un momento, habíamos quedado que se agrupaban las cadenas con
las comillas o con las llaves... ¿qué son esos corchetes?</i> Cuando
queremos sustituir un argumento con lo que devuelva otro comando
utilizamos los corchetes. En el caso anterior queremos que muestre el
resultado del comando <code>expr $a+$b</code>.
</p>

<pre class="example" id="orgeb06245">
% expr $a + $b
15
% [expr $a + $b]
invalid command name "15"
</pre>

<p>
Se puede apreciar, que cuando utilizamos los corchetes, el sistema al
recibir la cadena <code>"15"</code>, interpreta que debe ser un comando e intenta
ejecutarlo.
</p>

<p>
Atención a las operaciones, porque hay que distinguir la aritmética
entera de la flotante. Por ejemplo:
</p>

<pre class="example" id="org7c053b6">
% expr 1 / 10
0
% expr 1.0 / 10
0.1
% expr 1. / 10
0.1
</pre>
</div>
</div>
<div id="outline-container-orgb5246b0" class="outline-3">
<h3 id="orgb5246b0">Listas</h3>
<div class="outline-text-3" id="text-orgb5246b0">
<p>
Uno de los objetos... no, mejor otro nombre, no sea que nos
equivoquemos con la POO... Uno de los tipos... no, tampoco, habíamos
quedado que no hay <i>tipos</i> en este lenguaje... Uno de
los... <i>pichorros</i>, que más utilizo para agrupar la información en los
programas son las listas.
</p>

<pre class="example" id="orge9a32a6">
% set l [list a b foo "hello world"]
a b foo {hello world}
% puts [llength $l]
4
</pre>

<p>
Sencillo de entender: una lista se crea con el comando <code>list</code>. También
podemos apreciar cómo internamente la cadena <code>hello word</code> ha pasado de
representarse con comillas a su forma estática con llaves. Por
ejemplo, si hubiéramos escrito el siguiente código:
</p>

<pre class="example" id="orgcc6a405">
% set a maldito
maldito
% set l [list a b foo "hola $a mundo!"]
a b foo {hola maldito mundo!}
</pre>

<p>
Vemos cómo se almacena la forma estática después de interpretar el
contenido de la cadena.
</p>

<p>
<code>Tcl</code> además viene con una gran cantidad de procedimientos para
trabajar con listas, cortarlas, anexarlas, ver el largo, sustituir
elementos, etc. Pero eso ya lo consultáis en la documentación.
</p>
</div>
</div>
<div id="outline-container-org792d1ca" class="outline-3">
<h3 id="org792d1ca">Procedimientos</h3>
<div class="outline-text-3" id="text-org792d1ca">
<p>
Lo de <i>un comando detrás de otro</i> está bien, es muy sencillo de
entender pero <i>¿cómo hago mis propios comandos?</i> Para esto existe un
comando <code>proc</code> que recibe tres parámetros: 1) el nombre del
procedimiento, 2) la lista de parámetros que recibe, 3) el bloque de
código que debe ejecutar. Por ejemplo, imaginad que queremos tener un
procedimiento de suma equivalente al de <code>lisp</code>, sin necesidad de
escribir <code>expr</code> cada vez que quiera hacer una simple suma. El código
sería así:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">+</span> {a b} {
  <span style="color: #8be9fd; font-style: italic;">expr</span> $<span style="color: #f8f8f2; font-weight: bold;">a</span>+$<span style="color: #f8f8f2; font-weight: bold;">b</span>
}
</pre>
</div>

<p>
En este caso, <code>proc</code> recibe el nombre de procedimiento <code>+</code>, con la
lista de parámetros <code>{a b}</code> y un bloque de código que hace <code>expr
$a+$b</code>. Vamos a hacerlo funcionar:
</p>

<pre class="example" id="orge74faa6">
% proc + {a b} {
  expr $a+$b
}
% puts [+ 5 12]
17
</pre>

<p>
Voy a complicarlo un poco: quiero hacer un procedimiento para tener
todos los operadores aritméticos en forma de <i>prefijo</i> y, de paso,
vemos por encima un poco sobre bucles:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">operadores</span> [<span style="color: #8be9fd; font-style: italic;">list</span> + - * /]
<span style="color: #ff79c6; font-weight: bold;">foreach</span> o $<span style="color: #f8f8f2; font-weight: bold;">operadores</span> {
    <span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">$o</span> {a b} [<span style="color: #8be9fd; font-style: italic;">list</span> <span style="color: #8be9fd; font-style: italic;">expr</span> <span style="color: #f1fa8c;">"\$a $o \$b"</span>]
}
</pre>
</div>

<p>
Se puede apreciar, que en el caso de los parámetros, el carácter <code>$</code>
debe ir escapado para que sea evaluado al devolver la <i>lista</i> de
comandos y no al evaluar la expresión, mientras que el operador se
sustituye desde el inicio. Si no lo hacemos así, el intérprete buscará
y no encontrará las <i>variables</i> <code>a</code> y <code>b</code>, fuera de la función.
</p>

<p>
El funcionamiento lo podemos ver en el siguiente ejemplo:
</p>

<pre class="example" id="org3a531ae">
% set operadores [list + - * /]
+ - * /
% foreach o $operadores {
        proc $o {a b} [list expr "\$a $o \$b"]
  }
% puts [/ 10. 3]
3.3333333333333335
</pre>

<p>
Quizá hubiera sido mejor definir esos procedimientos para que
aceptaran una lista de números, en lugar de tan sólo dos parámetros,
como en <code>lisp</code> o <code>scheme</code>.  Lo haré en un momento, pero dejadme que
primero consideremos la lista de argumentos de un procedimiento. Si es
variable, es decir, si queremos que pueda haber llamadas con distinto
número de parámetros podemos hacer dos cosas: definir algunos valores
por defecto o analizar cada argumento para actuar en consecuencia.
</p>

<p>
En cuanto a los parámetros por defecto, veamos un sencillo ejemplo
fabricándonos nuestra función de incremento:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">inc</span> {valor {incremento 1}} {
  <span style="color: #8be9fd; font-style: italic;">expr</span> $<span style="color: #f8f8f2; font-weight: bold;">valor</span>+$<span style="color: #f8f8f2; font-weight: bold;">incremento</span>
}
</pre>
</div>

<p>
La lista de parámetros se ha convertido en una lista de listas y el
parámetro <code>incremento</code> devolverá <code>1</code> en el caso de que no esté
definido. Lo vemos en funcionamiento:
</p>

<pre class="example" id="orgf3d5f27">
% proc inc {valor {incremento 1}} {
    expr $valor+$incremento
}
% inc 13 2
15
% inc 13
14
% set a 5
5
% inc $a
6
% puts $a
5
</pre>

<p>
En el ejemplo podemos apreciar que en los procedimientos, la
instrucción <code>return</code> es opcional. Como en muchos otros lenguajes,
<code>Tcl</code> devuelve el valor de la última instrucción evaluada si no existe
un <code>return</code> específico. También podemos ver, que nuestro código nos
devuelve un valor, pero no modifica los parámetros recibidos como hace
la función original <code>incr</code>. Se pueden hacer llamadas por referencia
con <code>upvar</code> para poder modificarlos, pero creo que sería liar mucho la
perdiz para una introducción. Que sepáis que se puede y si alguien lo
necesita y/o tiene curiosidad que lo mire en la documentación, de
todas formas pondré un ejemplo más adelante.
</p>

<p>
La otra forma de tener argumentos opcionales es analizar la lista de
parámetros y hacer algo con ella. Por ejemplo, para crear un comando
<code>suma</code> que acepte una lista de números que sumar, podríamos hacerlo de
la siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">suma</span> args {
    <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">s</span> 0
    <span style="color: #ff79c6; font-weight: bold;">foreach</span> i $<span style="color: #f8f8f2; font-weight: bold;">args</span> {
        <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">s</span> [<span style="color: #8be9fd; font-style: italic;">expr</span> $<span style="color: #f8f8f2; font-weight: bold;">s</span> + $<span style="color: #f8f8f2; font-weight: bold;">i</span>]
    }
    <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">s</span>
}
</pre>
</div>

<p>
Veamos el código en acción:
</p>

<pre class="example" id="orgf8126d3">
% proc suma args {
      set s 0
      foreach i $args {
          set s [expr $s + $i]        
      }
      return $s
  }
% suma 1 2 3 4 5
15
% suma 1.1 2.2 3.3 4.4 5.5
16.5
% suma
0
% 
</pre>

<p>
Por último, con respecto a los procedimientos, nada nos impide hacer
nuestros propios bloques de control utilizando los ya existentes o
incluso nuestro propio sistema de <i>macros</i>. Aunque no lo analizaré en
profundidad, dejo el ejemplo para que lo desentrañéis:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">do</span> {variable primero ultimo cuerpo} {
    <span style="color: #8be9fd; font-style: italic;">upvar</span> $<span style="color: #f8f8f2; font-weight: bold;">variable</span> v
    <span style="color: #ff79c6; font-weight: bold;">for</span> {<span style="color: #8be9fd; font-style: italic;">set</span> v $<span style="color: #f8f8f2; font-weight: bold;">primero</span>} {$<span style="color: #f8f8f2; font-weight: bold;">v</span> &lt;= $<span style="color: #f8f8f2; font-weight: bold;">ultimo</span>} {<span style="color: #8be9fd; font-style: italic;">incr</span> v} {
        <span style="color: #ff79c6; font-weight: bold;">uplevel</span> $<span style="color: #f8f8f2; font-weight: bold;">cuerpo</span>
    }
}
</pre>
</div>

<p>
Quizá verlo en acción nos puede servir mejor para entender cómo
funciona.
</p>

<pre class="example" id="org042d131">
% proc do {variable primero ultimo cuerpo} {
      upvar $variable v
      for {set v $primero} {$v &lt;= $ultimo} {incr v} {
          uplevel $cuerpo
      }
  }
% set a {}
% do i 1 5 {
      lappend a [expr $i*$i]
  }
% puts $a
1 4 9 16 25
% puts "Contador: $i -- lista: $a"
Contador: 6 -- lista: 1 4 9 16 25
% 
</pre>

<p>
No hace falta explicar el comando <code>for</code>, es equivalente al de otros
lenguajes como <code>C/C++</code>; lo único es observar cómo es un procedimiento
que acepta cuatro parámetros. Después de definirlo podemos utilizar
nuestro nuevo procedimiento de control <code>do</code>, creamos una lista vacía
<code>a</code> y la llenamos con los cuadrados de los primeros cinco enteros.
Además vemos que los comandos <code>upvar</code> y <code>uplevel</code> sirven para trabajar
con variables y bloques de códigos <i>por referencia</i>, pero los detalles
los tendréis que buscar en la documentación.
</p>
</div>
</div>
<div id="outline-container-org56b25ee" class="outline-3">
<h3 id="org56b25ee">Evaluación del código</h3>
<div class="outline-text-3" id="text-org56b25ee">
<p>
Como todo es una cadena, al final todo es evaluar cadenas como
código. Por ejemplo:
</p>

<pre class="example" id="org1392c10">
% set cadena "puts hola"
puts hola
% eval $cadena
hola
</pre>

<p>
El comando <code>eval</code> hace ese trabajo, pero no es el único. También
existe, como hemos visto el comando <code>uplevel</code>, para trabajar <i>por
referencia</i> con el código embebido dentro de otra función. Por
ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #ff79c6; font-weight: bold;">proc</span> <span style="color: #50fa7b; font-weight: bold;">repetir</span> {n cuerpo} {
  <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">res</span> <span style="color: #f1fa8c;">""</span>
  <span style="color: #ff79c6; font-weight: bold;">while</span> {$<span style="color: #f8f8f2; font-weight: bold;">n</span>} {
      <span style="color: #8be9fd; font-style: italic;">incr</span> n -1
      <span style="color: #8be9fd; font-style: italic;">set</span> <span style="color: #f8f8f2; font-weight: bold;">res</span> [<span style="color: #ff79c6; font-weight: bold;">uplevel</span> $<span style="color: #f8f8f2; font-weight: bold;">cuerpo</span>]
      <span style="color: #8be9fd; font-style: italic;">puts</span> <span style="color: #f1fa8c;">"$n -- $res"</span>
  }
  <span style="color: #ff79c6; font-weight: bold;">return</span> $<span style="color: #f8f8f2; font-weight: bold;">res</span>
}
</pre>
</div>

<p>
El comando <code>incr</code> incrementa una variable de <i>tipo entero</i>. Lo hace en
una unidad si sólo recibe el parámetro de la variable, pero podemos
indicar también un segundo parámetro con el valor del incremento. En
el ejemplo, ese valor de incremento es <code>-1</code>.
</p>

<p>
En la condición del comando <code>while</code> vemos que, como ocurre en <code>C/C++</code>,
el valor de <code>0</code> es equivalente al valor lógico <code>false</code>.
</p>

<p>
El ejemplo en funcionamiento:
</p>

<pre class="example" id="orgbad8197">
% proc repetir {n cuerpo} {
    set res ""
    while {$n} {
        incr n -1
        set res [uplevel $cuerpo]
        puts "$n -- $res"
    }
    return $res
  }
% set x 5
5
% repetir 5 {
    incr x
}
4 -- 6
3 -- 7
2 -- 8
1 -- 9
0 -- 10
10
% repetir 5 {
    puts "Hola cinco veces"
}
Hola cinco veces
4 -- 
Hola cinco veces
3 -- 
Hola cinco veces
2 -- 
Hola cinco veces
1 -- 
Hola cinco veces
0 -- 
%
</pre>

<p>
En el ejemplo de incrementar la variable <code>x</code> vemos cómo se va
incrementando en cada paso, porque cuando hace el incremento también
devuelve el valor. Sin embargo, el comando <code>puts</code> no devuelve
nada, sólo imprime la cadena, por lo que <code>res</code> se mantiene vacío
durante toda la ejecución.
</p>
</div>
</div>
<div id="outline-container-org801efd4" class="outline-3">
<h3 id="org801efd4">Tk</h3>
<div class="outline-text-3" id="text-org801efd4">
<p>
El <i>toolkit</i> gráfico es sencillo y potente. Su diseño es quizá lo que
podríamos definir como <i>viejuno</i> o <i>vintage</i>, sin embargo, más allá de
la estética es sencillo de utilizar. Por no alargar innecesariamente
el artículo, vamos a hacer de manera interactiva un <i>«Hola mundo!»</i>
gráfico con él y si os interesa ya lo ampliaréis.
</p>

<p>
Lo primero será lanzar el intérprete gráfico es <code>wish</code>, igual que el
de <code>Tcl</code> es <code>tclsh</code>. Vemos que comparten el mismo <i>prompt</i>:
</p>

<pre class="example" id="org02bd747">
&gt; wish
%
</pre>

<p>
Al pulsar <i>enter</i> tras el <code>wish</code> nos aparecerá una ventana muy
sencilla:
</p>


<figure id="org428df1b">
<img src="./imagenes/Captura_wish.png" alt="Captura_wish.png">

</figure>

<p>
Añadimos la etiqueta de «Hola mundo!»
</p>

<pre class="example" id="org3bc6661">
% label .l -text "Hola, Mundo!"
.l
% pack .l
%
</pre>

<p>
El comando <code>label</code> tiene un nombre de <i>widget</i>: <code>.l</code> y un texto. El
comando <code>pack</code> lo dibuja en la ventana.
</p>


<figure id="orgb77774c">
<img src="./imagenes/Captura_etiqueta.png" alt="Captura_etiqueta.png">

</figure>

<p>
Y también le vamos a añadir un botón para cerrar la ventana:
</p>

<pre class="example" id="org4817b10">
% button .b -text "Salir" -command exit
.b
% pack .b
%
</pre>

<p>
Vemos que el comando <code>button</code> es muy similar a <code>label</code> pero se ha
añadido un parámetro <code>-command exit</code>. El resultado gráfico es:
</p>


<figure id="orga37f64a">
<img src="./imagenes/Captura_boton.png" alt="Captura_boton.png">

</figure>

<p>
Al pulsar el botón, la ventana se cerrará.
</p>

<p>
Todo lo podemos empaquetar en un archivo con el siguiente aspecto:
</p>

<div class="org-src-container">
<pre class="src src-tcl"><span style="color: #6272a4;">#</span><span style="color: #6272a4;">!/usr/bin/wish
</span>
label .l -text <span style="color: #f1fa8c;">"Hola, Mundo!"</span>
pack .l
button .b -text <span style="color: #f1fa8c;">"Salir"</span> -command <span style="color: #ff79c6; font-weight: bold;">exit</span>
pack .b
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-orgd822a0d" class="outline-2">
<h2 id="orgd822a0d">Conclusiones</h2>
<div class="outline-text-2" id="text-orgd822a0d">
<p>
A mí me parece que <code>Tcl</code>, junto con su extensión gráfica <code>Tk</code>, es un
lenguaje bastante expresivo y con un funcionamiento fácil de
comprender, a la par que potente, especialmente la capacidad de tener
<i>widgets</i>, evaluando cadenas de texto que son interpretadas como
código. Tan sencillo que afirman que programar un intérprete para él
desde cero no es una tarea demasiado ardua y que con poco código se
puede hacer perfectamente.
</p>

<p>
Además, se considera que es <i>multiparadigma</i>, puesto que dispone de
unas librerías que lo convierten en un lenguaje orientado objetos, o
en un lenguaje funcional.
</p>

<p>
Si lo tienes instalado en tu sistema, y no lo has utilizado nunca, es
el momento de hacerlo. Usa los ejemplos que hay en este artículo,
juega con ellos y (re)descubre este magnífico lenguaje.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/tcl/index.html">tcl</a> <a href="/tags/tk/index.html">tk</a> <a href="/tags/programación/index.html">programación</a> ]]></description>
  <category><![CDATA[tcl]]></category>
  <category><![CDATA[tk]]></category>
  <category><![CDATA[programación]]></category>
  <link>https://notxor.nueva-actitud.org/2022/04/24/tcl-tk.html</link>
  <pubDate>Sun, 24 Apr 2022 17:49:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Algunos ajustes para Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-04-06</div>
<p>
Algunas veces doy por sentado que todo el mundo conoce lo que yo sé,
porque lo que sé lo he adquirido leyendo y leer sabemos todos.  Eso
hace que muchas veces no hable, bueno, más bien no escriba, sobre
algún apartado que puede ser interesante para otras personas, que
quizá no conozcan las posibilidades que ofrece, o se están iniciando,
en <i>Emacs</i>. En algunos sitios, foros o grupos de internet en los que
participo se han comentado cosas, se han hecho peticiones de
información y se ha hablado de aspectos que, en mi ingenuidad, pensé
que todo el mundo conocía. Uno de los temas es el recurrente control
del tema, el aspecto, de <i>Emacs</i>, cosas como, por ejemplo, cambiar el
tema pulsando una tecla, o cómo configurar las fuentes de caracteres o
el tipo de fuente que utilizamos. Y por último, otro de los aspectos
que trataré en este artículo es el que más me sorprende, porque creí
que todo el mundo conocía: la capacidad de agrupar <i>buffers</i> en
<i>perspectivas</i> de manera que al cambiar de <i>perspectiva</i> cambiará la
distribución de nuestro marco en <i>Emacs</i>. Me sorprende porque todo el
mundo, especialmente los recién llegados, parecen conocer las pestañas
que nos brinda <i>Emacs</i> desde hace relativamente pocas versiones (y que
no alcanza lo que la gente espera), pero desconocen las
<i>perspectivas</i>, que son generalmente lo que necesitan.
</p>

<p>
Concretamente, hablaré de tres cosas, dos son paquetes que utilizo y
que me resultan muy útiles:
</p>

<ul class="org-ul">
<li><code>heaven-and-hell</code>: intercambia entre un <i>theme</i> claro y otro oscuro
pulsando una tecla.</li>
<li><code>perspective</code>: agrupa <i>bufferes</i> dentro del mismo marco.</li>
</ul>

<p>
El otro tema, el de los tipos de fuentes, tiene más que ver con los
gustos personales que con la funcionalidad propiamente dicha, pero
también hay alguna consideración técnica que hacer.
</p>
<div id="outline-container-org2258514" class="outline-2">
<h2 id="org2258514">Heaven and Hell y otros aspectos visuales</h2>
<div class="outline-text-2" id="text-org2258514">
<p>
Este paquete es bastante pequeño, apenas unas pocas líneas de código
que nos permiten cambiar el <i>theme</i> de <i>Emacs</i> al vuelo. Nos permite
cambiar entre un fondo claro y uno oscuro sin mucha dilación. Hay
veces que trabajo en sitios muy iluminados, o incluso la calle, donde
se ajustan mejor, o son más legibles, si lo queréis expresar así, los
temas claros. En cambio, en otras ocasiones, por ejemplo, por la
tarde-noche o con iluminación más pobre, los fondos claros molestan a
la vista y me cansan. Entrar en las opciones del tema y cambiarlo no
lleva mucho tiempo. Sin embargo, este paquete me permite cambiar entre
un fondo claro y otro oscuro pulsando <code>F6</code>. Eso es algo que a mí me
resulta muy útil.
</p>

<p>
Sólo configuro dos teclas:
</p>

<ul class="org-ul">
<li><code>C-c F6</code>: Desactiva el <i>theme</i> y vuelve a mostrar el tema por
defecto de <i>Emacs</i>, como si no hubiéramos instalado ninguno.</li>
<li><code>F6</code>: Cambia entre los temas claro y oscuro definidos en la lista de
temas en la variable del paquete <code>heaven-and-hell-themes</code>.</li>
</ul>

<p>
Se puede iniciar <i>Emacs</i> con el tema claro o con el oscuro,
dependiendo del valor de la variable <code>heaven-and-hell-theme-type</code> que
se configura también en el arranque.
</p>

<p>
El código de configuración está un poco retocado con respecto a la
página del paquete, ahora explicaré por qué:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Intercambiar tema claro y oscuro
</span>(<span style="color: #ff79c6; font-weight: bold;">use-package</span> heaven-and-hell
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:init</span>
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> heaven-and-hell-theme-type 'light) <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">'dark) ;; Omit to use light by default
</span>  (<span style="color: #ff79c6; font-weight: bold;">setq</span> heaven-and-hell-themes
        '((light . tsdh-light)
          (dark . dracula))) <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Themes can be the list: (dark . (tsdh-dark wombat))
</span>  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Optionall, load themes without asking for confirmation.
</span>  (<span style="color: #ff79c6; font-weight: bold;">setq</span> heaven-and-hell-load-theme-no-confirm t)
  <span style="color: #8be9fd; font-style: italic;">:hook</span> (after-init . heaven-and-hell-init-hook))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">ajuste-powerline-theme</span> ()
  <span style="color: #6272a4;">"Hace un reset de la powerline tras cambiar el tema."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (heaven-and-hell-toggle-theme)
  (powerline-reset))

(global-set-key (kbd <span style="color: #f1fa8c;">"C-c &lt;f6&gt;"</span>) 'heaven-and-hell-load-default-theme)
(global-set-key (kbd <span style="color: #f1fa8c;">"&lt;f6&gt;"</span>)     'ajuste-powerline-theme)
</pre>
</div>

<p>
El cambio fundamental es que he sacado la configuración de las teclas
fuera de la forma <code>use-package</code> porque necesitaba un ajuste especial.
En concreto, también utilizo el paquete <code>powerline</code>. Al intercambiar
entre el modo claro y el modo oscuro el carácter separador de los
campos de la línea de estado quedan dibujados con el mismo color del
tema anterior, porque no los actualiza el <i>theme</i> sino que debe
hacerlo <code>powerline</code>.
</p>


<figure id="orgf4b6c2b">
<img src="./imagenes/Captura_linea-powerline.png" alt="Captura_linea-powerline.png">

</figure>

<p>
Para que el tema ajuste bien, tras el cambio, hay que hacer un
<code>powerline-reset</code>. Por tanto, en lugar de ejecutar sólo el cambio de
color del <i>theme</i> hay que ejecutar también un redibujado de la línea
de estado:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">ajuste-powerline-theme</span> ()
  <span style="color: #6272a4;">"Hace un reset de la powerline tras cambiar el tema."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (heaven-and-hell-toggle-theme)
  (powerline-reset))
</pre>
</div>

<p>
Este paso no es necesario si no utilizamos el paquete <code>powerline</code> o
tendréis que ajustarlo si utilizáis algún otro <i>embellecedor</i> de la
línea de estado.
</p>

<p>
Por otro lado, por algún motivo que (aún) no comprendo, si ejecuto
<code>package-autoremove</code> siempre desinstala <code>heaven-and-hell</code>, por lo que
algunas veces se demora el arranque ya que <code>use-package</code> lo tiene que
volver a descargar e instalar. En fin, tampoco llega la sangre al río,
aunque a veces es algo molesto.
</p>
</div>
</div>
<div id="outline-container-org59bffa4" class="outline-2">
<h2 id="org59bffa4">Perspective</h2>
<div class="outline-text-2" id="text-org59bffa4">
<p>
Agrupa <i>buffers</i> en perspectivas de manera que al cambiar de una a
otra modifica la distribución de <i>buffers</i> en el marco. Una buena
idea, y es lo que yo hago, es utilizar una perspectiva para cada
proyecto que tengamos abierto. De esa manera podrás tener <i>buffers</i>
del mismo tiempo, por ejemplo <code>magit</code> y sabrás exactamente a qué
proyecto está asociado.
</p>

<p>
Si lo tienes activos, al arrancar <i>Emacs</i> siempre se crea la
perspectiva <i>main</i> (el nombre es configurable y podemos cambiarlo como
casi todas las cosas de <i>Emacs</i>). La perspectiva <i>main</i> la suelo
utilizar para visualizar la información no relacionada con ningún
proyecto ni actividad. Como por ejemplo, consultar la agenda, mostrar
el <code>dashboard</code>.
</p>

<p>
Podemos ver una serie de capturas de tres perspectivas abiertas. Cada
una con sus <i>buffers</i>.
</p>


<figure id="orgef6e868">
<img src="./imagenes/Captura_persp-main.png" alt="Captura_persp-main.png">

</figure>


<figure id="org8556518">
<img src="./imagenes/Captura_persp-prog.png" alt="Captura_persp-prog.png">

</figure>


<figure id="org47693b7">
<img src="./imagenes/Captura_persp-blog.png" alt="Captura_persp-blog.png">

</figure>

<p>
Como podéis apreciar, en la línea de estado aparece una lista de las
perspectivas. Por defecto, los caracteres que se utilizan son los
corchetes <code>[...]</code> con el separador <code>|</code>, pero se puede establecer
cualquiera otros. También se puede configurar el aspecto de la lista,
como el color de las perspectivas y también el de la perspectiva
activa.
</p>

<p>
El código de configuración es también muy simple.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> perspective
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:init</span>
  (persp-mode t))
</pre>
</div>

<p>
El aspecto de cómo se mostrará la perspectiva activa se configura en
el apartado <code>custom-set-faces</code>. Pongo toda la forma aquí, aunque
también engloba algunos aspectos que comentaré en el apartado
siguiente, sobre los tipos de letra:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(custom-set-faces
 <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">custom-set-faces was added by Custom.
</span> <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">If you edit it by hand, you could mess it up, so be careful.
</span> <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Your init file should contain only one such instance.
</span> <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">If there is more than one, they won't work right.
</span> '(default ((t (<span style="color: #8be9fd; font-style: italic;">:family</span> <span style="color: #f1fa8c;">"DejaVu Sans Mono"</span> <span style="color: #8be9fd; font-style: italic;">:foundry</span> <span style="color: #f1fa8c;">"PfEd"</span> <span style="color: #8be9fd; font-style: italic;">:slant</span> normal <span style="color: #8be9fd; font-style: italic;">:weight</span> normal <span style="color: #8be9fd; font-style: italic;">:height</span> 98 <span style="color: #8be9fd; font-style: italic;">:width</span> normal))))
 '(org-level-1 ((t (<span style="color: #8be9fd; font-style: italic;">:inherit</span> outline-1 <span style="color: #8be9fd; font-style: italic;">:height</span> 1.0))))
 '(org-level-2 ((t (<span style="color: #8be9fd; font-style: italic;">:inherit</span> outline-2 <span style="color: #8be9fd; font-style: italic;">:height</span> 1.0))))
 '(org-level-3 ((t (<span style="color: #8be9fd; font-style: italic;">:inherit</span> outline-3 <span style="color: #8be9fd; font-style: italic;">:height</span> 1.0))))
 '(org-level-4 ((t (<span style="color: #8be9fd; font-style: italic;">:inherit</span> outline-4 <span style="color: #8be9fd; font-style: italic;">:height</span> 1.0))))
 '(org-level-5 ((t (<span style="color: #8be9fd; font-style: italic;">:inherit</span> outline-5 <span style="color: #8be9fd; font-style: italic;">:height</span> 1.0))))
 '(org-level-6 ((t (<span style="color: #8be9fd; font-style: italic;">:inherit</span> outline-6 <span style="color: #8be9fd; font-style: italic;">:height</span> 1.0))))
 '(org-tree-slide-heading-level-1 ((t (<span style="color: #8be9fd; font-style: italic;">:inherit</span> outline-1 <span style="color: #8be9fd; font-style: italic;">:weight</span> bold <span style="color: #8be9fd; font-style: italic;">:height</span> 3.5))))
 '(org-tree-slide-heading-level-2 ((t (<span style="color: #8be9fd; font-style: italic;">:inherit</span> outline-2 <span style="color: #8be9fd; font-style: italic;">:weight</span> bold <span style="color: #8be9fd; font-style: italic;">:height</span> 2.5))))
 '(org-tree-slide-heading-level-3 ((t (<span style="color: #8be9fd; font-style: italic;">:inherit</span> outline-3 <span style="color: #8be9fd; font-style: italic;">:weight</span> bold <span style="color: #8be9fd; font-style: italic;">:height</span> 1.5))))
 '(persp-selected-face ((t (<span style="color: #8be9fd; font-style: italic;">:foreground</span> <span style="color: #f1fa8c;">"yellow"</span> <span style="color: #8be9fd; font-style: italic;">:weight</span> normal)))))
</pre>
</div>

<p>
Como dice el comentario del código, el código está añadido por el
comando <code>custom</code> y agrupa comportamientos de fuentes de varios
paquetes. La primera línea ejecutable del bloque identifica el tipo de
letra establecido por el menú <code>default-font</code>. Luego comentaré por qué
he seleccionado <code>DejaVu Sans Mono</code>.
</p>

<p>
Las siguientes 6 líneas establecen el tamaño del texto de las cabecera
de <code>org-mode</code>. Por defecto, algunos temas dibujan tamaños más grandes
de fuente para las cabeceras. Algo que, a mí concretamente, no me
gusta nada y por eso en todos los casos utilizo <code>:height 1.0</code>. No así
en el modo de presentación del paquete <code>org-tree-slide</code>. Por último,
modifico la visualización de la perspectiva seleccionada, con un color
de texto amarillo. Por defecto es de color azul y el peso de la fuente
es en negrita. Con fondo gris en la línea de estado se suele percibir
más como un borrón azul casi ilegible que como texto. Por eso,
prefiero un peso <i>normal</i> del tipo y un color claro, que no sea
blanco.
</p>

<p>
Por defecto, la combinación de teclas de <code>perspective</code> es <code>C-x x</code>, que
nos abre todo un abanico de acciones que podemos hacer con las
perspectivas. Las principales, o las que yo más utilizo, son:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">tecla</th>
<th scope="col" class="org-left">comando</th>
<th scope="col" class="org-left">acción</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>C-x x s</code></td>
<td class="org-left"><code>persp-switch</code></td>
<td class="org-left">Cambiar a otra perspectiva, la crea si no existe.</td>
</tr>

<tr>
<td class="org-left"><code>C-x x c</code></td>
<td class="org-left"><code>persp-kill</code></td>
<td class="org-left">Cierra la perspectiva y todos los <i>buffers</i> asociados.</td>
</tr>

<tr>
<td class="org-left"><code>C-x x n</code></td>
<td class="org-left"><code>persp-next</code></td>
<td class="org-left">Ir a la perspectiva siguiente.</td>
</tr>

<tr>
<td class="org-left"><code>C-x x p</code></td>
<td class="org-left"><code>persp-prev</code></td>
<td class="org-left">Ir a la perspectiva anterior.</td>
</tr>

<tr>
<td class="org-left"><code>C-x x r</code></td>
<td class="org-left"><code>persp-rename</code></td>
<td class="org-left">Renombrar la perspectiva.</td>
</tr>

<tr>
<td class="org-left"><code>C-x x b</code></td>
<td class="org-left"><code>persp-switch-to-buffer</code></td>
<td class="org-left">Cambiar al <i>buffer</i> de la perspectiva.</td>
</tr>

<tr>
<td class="org-left"><code>C-x x m</code></td>
<td class="org-left"><code>persp-merge</code></td>
<td class="org-left">Mezclar los <i>buffers</i> de la perspectiva actual con otra.</td>
</tr>
</tbody>
</table>

<p>
También podemos ir directamente de una perspectiva a otra utilizando
su número, asignándolo por orden tal y como aparecen ordenadas en la
línea de estado. Por defecto, se ordenan alfabéticamente y podemos
saltar utilizando <code>C-x x</code> y el dígito del orden de la perspectiva del
<code>1</code> al <code>0</code>. En este último caso corresponde a la perspectiva <code>10</code>. Se
pueden tener más perspectivas abiertas. En ese caso, se puede utilizar
la combinación <code>C-x x `</code>, pedirá un número y saltará a la
correspondiente... sé que existe esta opción, pero normalmente no
llego a tal cantidad de perspectivas en danza, suelo tener dos o tres,
o como mucho cinco perspectivas abiertas, así que no es algo que suela
usar.
</p>

<p>
Hay alguna función más, pero no las he usado nunca o casi
nunca... vamos, que no recuerdo haberlas necesitado. Mi costumbre
habitual es abrir una perspectiva que suele coincidir con el
<i>proyecto</i> o labor que esté realizando. Al cerrar una perspectiva con
<code>C-x x c</code> automáticamente se cerrarán todos los <i>buffers</i> relacionados
con dicha perspectiva y preguntará, en caso de que sea necesario, si
queremos guardar aquel que haya sido modificado. Cada perspectiva
conserva la distribución de <i>buffers</i> que le hayas puesto.
</p>

<p>
Por otro lado, cada una de las perspectivas tiene su <i>buffer</i>
<code>*scratch*</code>, que nos permite trabajar en varios proyectos con pruebas
de código diferenciadas.
</p>
</div>
</div>
<div id="outline-container-orgf1f22f3" class="outline-2">
<h2 id="orgf1f22f3">Tipos de letra</h2>
<div class="outline-text-2" id="text-orgf1f22f3">
<p>
Algunas veces miramos cómo podemos tener un tipo de letra vistoso y
hay algunos muy bonitos, pero que no siempre sirven para programar.
Sin embargo, algunas otras están diseñadas precisamente para esa tarea
¿cuál elegir? ¿Qué tipo de letra utilizo? Algunos también me lo han
preguntado, y alguna vez creo que ya hablé sobre el tema. En mi caso
los criterios son varios, más allá de que debe ser un tipo de fuente
<i>fija</i> o <i>mono</i>, concretamente a la fuente que utilizo le pido:
</p>

<ul class="org-ul">
<li>Distinguir claramente los caracteres <code>1, l, I</code> y <code>O, 0</code>.</li>
<li>Disponer de caracteres especiales. Recordad que también escribo en
<i>Esperanto</i> y se utilizan caracteres como ĉ, ĥ, ĵ, ŝ, ŭ...</li>
<li>En los ficheros de <code>org-mode</code>, debe soportar la utilización de
itálica, negrita, etc. Algunos tipos de letra no lo hacen y muestran
los modos especiales subrayados (algo que me <i>sobrerraya</i> a mí).</li>
</ul>

<p>
La primera de estas condiciones es imprescindible cuando vamos a
programar y supongo que ya la mayoría de vosotros lo tiene en cuenta
como yo. Fuentes que cumplen con esta condición hay infinidad y
podemos elegir entre muchas. Si es el único criterio que tenéis en
cuenta cualquier fuente que esté diseñada para programadores os
servirá.  Sin embargo, el siguiente criterio es más raro entre las
fuentes diseñadas para programar. Incluso pueden carecer de tildes,
porque algunos creadores de fuentes sólo contemplan el idioma inglés
para esa actividad. Por otro lado, la condición de tener un catálogo
de caracteres completo, lo cumplen también las fuentes que utilizo en
este <i>blog</i>, sin embargo, no podría programar cómodamente
utilizándolas para tal fin. Para mí es importante que las fuentes
tengan esos caracteres especiales y por tanto tengo que utilizar una
fuente fija (o <i>mono</i>) que los contenga, no me sirven todas. Por
último, la tercera condición, viene del hecho de que utilizo el modo
texto, y concretamente <code>org-mode</code> para mi trabajo diario y me gusta la
que la visualización sea correcta. Por ejemplo, <code>Fira Code</code> sería otra
fuente a tener en cuenta que cumple con las dos primeras condiciones,
y configurada en <i>Emacs</i> queda bastante vistosa, pero no cumple la
tercera condición.
</p>

<p>
Para no darle demasiadas vueltas al asunto, la fuente que utilizo yo
es <code>DejaVu Sans Mono</code>, como se pudo apreciar el bloque de código de mi
<code>init.el</code>. No es una fuente moderna de esas que les gustan a los
<i>Hipsters</i>, sin embargo cumple los requisitos anteriores y a mí me
resulta agradable de leer. No necesito hacer ningún esfuerzo para
diferenciar una palabra de otra ni una letra de otra.
</p>
</div>
</div>
<div id="outline-container-org72810de" class="outline-2">
<h2 id="org72810de">Conclusiones</h2>
<div class="outline-text-2" id="text-org72810de">
<p>
El flujo de trabajo se beneficia mucho de las perspectivas,
permitiendo abrir y cerrar funcionalidad sin necesidad de modificar
nuestro marco de trabajo.  Simplemente se abre una nueva perspectiva
se utilizan los <i>buffers</i> que sean necesarios y cuando se termina
dicha necesidad, al cerrar la perspectiva, todo queda como estaba.
Otro uso que le doy es, por ejemplo, utilizar las perspectivas para
separar tareas como leer el correo o los <i>feeds</i>, o chatear cuando
utilizo(aba) <code>erc</code>. O estás programando en una perspectiva y en otra
documentando lo que haces. Por poner una analogía, sería como la
funcionalidad que nos ofrecen los terminales (o escritorios en modo
gráfico) de <i>GNU/Linux</i>, en cada uno podemos tener abiertas nuestras
aplicaciones y podemos saltar de uno a otro con una combinación de
teclas.
</p>

<p>
Espero que estas pocas explicaciones os sean útiles.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">Emacs</a> <a href="/tags/perspective/index.html">perspective</a> <a href="/tags/themes-emacs/index.html">themes-emacs</a> ]]></description>
  <category><![CDATA[Emacs]]></category>
  <category><![CDATA[perspective]]></category>
  <category><![CDATA[themes-emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2022/04/06/algunos-ajustes-para-emacs.html</link>
  <pubDate>Wed, 06 Apr 2022 15:25:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[OpenStreetMap dentro de Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-03-27</div>
<p>
Una de las cosas que me gustan es la capacidad que tenemos los seres
humanos para representar cosas más o menos concretas en otras más o
menos abstractas. Los mapas son una expresión de esta capacidad y se
convierten en algo fascinante. Los miras y te imaginas cómo puede ser
el terreno que representan. Hoy traigo un tema que relaciona dos de
las cosas que me más me gustan: los mapas y <i>Emacs</i> en una sola
entrega.
</p>

<p>
Si documentas todo con <code>org-mode</code> y tienes necesidad también de
guardar información que localice los eventos en un mapa, la
combinación de <i>Emacs</i> y <i>OpenStreetMap</i> puede ser una solución
bastante efectiva. Por ejemplo, si quieres anotar dónde se encuentra
el monumento al Tío Jorge en Zaragoza puedes dar muchas explicaciones
o escribir en un fichero algo como:
</p>

<pre class="example" id="org15d50de">
[[osm:openstreetmap:41.66523,-0.87661,17][Monumento al Tío Jorge en el parque que lleva su nombre.]]
</pre>

<p>
Monumento al Tío Jorge en el parque que lleva su nombre. ← El enlace
funciona en el entorno de <i>Emacs</i>, pero como se puede comprobar, no
ocurre lo mismo con el <i>html</i> generado a partir de él. Es decir, al
pinchar en el enlace anterior, dentro de <i>Emacs</i>, la ventana se
convierte en algo así:
</p>


<figure id="org617f2c5">
<img src="./imagenes/Captura_osm-estatua-tio-jorge.png" alt="Captura_osm-estatua-tio-jorge.png">

</figure>

<p>
Como se puede apreciar a la izquierda se encuentra el mismo <i>buffer</i>
donde estoy escribiendo este artículo y a la derecha un mapa,
perfectamente centrado en el punto que hemos determinado en el
enlace. ¿Cómo se genera el enlace? Sencillo: la estructura del mismo
tiene un formato de campos separados por símbolos <code>:</code>:
</p>

<pre class="example" id="org8035656">
osm:tipo-mapa:localización
</pre>

<ul class="org-ul">
<li><code>osm</code>: éste es obligatorio para determinar el tipo de enlace que se
está utilizando. En este caso, <i>OpenStreetMap</i>.</li>
<li><p>
<code>tipo-mapa</code>: este campo hace que se utilice uno de los múltiples
tipos de mapas que se permiten en <i>OSM</i>. Si lo omitimos, utilizará
el mapa por defecto de <i>OSM</i>, el <i>Mapnik</i>, pero podemos utilizar
también otros valores:
</p>

<p>
<code>opentopomap</code>: mapa topográfico. <code>cyclosm</code>: mapa específico para
ciclistas. <code>openriverboatmap</code> <code>humanitarian</code> <code>stamen</code>: Los <i>Stamen</i>
son mapas más artísticos, destacando el <i>watercolor</i>, pero hay
varios más donde poder elegir.
</p></li>
<li><p>
<i>Posición en el mapa</i>: El tercer campo es un campo compuesto por
tres valores separados por comas:
</p>

<p>
Latitud, Longitud y Nivel: A nivel más alto, más detalles. Se pasa
desde el nivel 1 ó 2, que serían la representación del mapa mundial,
hasta el 19 que sería la representación más detallada.<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>
</p></li>
</ul>

<p>
También se puede establecer una dirección de una manera más sencilla,
como por ejemplo, remarcar algún punto importante, ya situado en el
mapa:
</p>

<ul class="org-ul">
<li>&lt;osm:Monumento a Velázquez, Paseo del Prado, Madrid&gt;</li>
</ul>

<p>
En este caso, el <i>link</i> utiliza los delimitadores <code>&lt;</code> y <code>&gt;</code> y también va
precedido por <code>osm</code>, sin embargo aquí se detalla el nombre del lugar
señalado, la calle y la ciudad. Utiliza el habitual mapa <i>Mapnik</i> de
<i>OSM</i> en el nivel más detallado (19). Si hay varios destinos que
coinciden en nombre, nos mostrará una lista donde podremos seleccionar
el que queramos. Por ejemplo:
</p>

<p>
&lt;osm:Museo del Prado, Paseo del Prado, Madrid&gt;
</p>

<p>
Como se puede apreciar, tampoco se traducen los enlaces a algo que
pueda abrir el navegador cuando se convierte a <i>html</i>. Además, puesto
que en el mapa se encuentran varias etiquetas como «Museo del Prado» y
varias direcciones etiquetadas como «museo» en el «Paseo del Prado»,
nos muestra una lista de museos, el Thyssen-Bornemisza, el Museo
Naval, el Museo del Prado, el Museo del Jamón<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>, nos muestra todas
las alternativas:
</p>


<figure id="org25616f5">
<img src="./imagenes/Captura_osm-por-direccion.png" alt="Captura_osm-por-direccion.png">

</figure>
<div id="outline-container-org544ad22" class="outline-2">
<h2 id="org544ad22">Bookmarks</h2>
<div class="outline-text-2" id="text-org544ad22">
<p>
Por si nos faltaba algo, también podemos almacenar nuestras
direcciones más habituales en un archivo que se llama <code>bookmarks</code> y
que se guardará en nuestro directorio <code>.emacs.d</code>.
</p>

<p>
El fichero tiene el siguiente aspecto:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;;; </span><span style="color: #6272a4;">Emacs Bookmark Format Version 1 ;;;; -*- coding: utf-8-emacs -*-
</span><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">This format is meant to be slightly human-readable;
</span><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">nevertheless, you probably don't want to edit it.
</span><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">-*- End Of Bookmark File Format Version Stamp -*-
</span>((<span style="color: #f1fa8c;">"osm: Monumento a Vel&#225;zquez, Paseo del Prado, Jer&#243;nimos, Retiro, Madrid, &#193;rea metropolitana de Madrid y Corredor del Henares, Comunidad de Madrid, 28014, Espa&#241;a, 40.41&#176; -3.69&#176; Z19 Mapnik"</span>
 (coordinates 40.413726999999994 -3.692691849999999 19)
 (server . default)
 (handler . osm-bookmark-jump))
(<span style="color: #f1fa8c;">"osm: Paseo Escopeteros del Rabal, Arrabal, Zaragoza, Arag&#243;n, 50015, Espa&#241;a, 41.67&#176; -0.88&#176; Z17 Mapnik"</span>
 (coordinates 41.66523 -0.87661 17)
 (server . default)
 (handler . osm-bookmark-jump))
)
</pre>
</div>

<p>
Los lugares marcados aparecerán en la visualización del mapa:
</p>


<figure id="org9bd2331">
<img src="./imagenes/Captura_osm-bookmarks.png" alt="Captura_osm-bookmarks.png">

</figure>

<p>
También podemos señalar puntos mediante código <code>elisp</code>. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(osm <span style="color: #f1fa8c;">"Palacio de la Aljafer&#237;a, Zaragoza"</span>)
(osm 42.325587 -0.612531 15 opentopomap <span style="color: #f1fa8c;">"Castillo de Loarre"</span>)
</pre>
</div>

<p>
En el primer caso se señala un punto destacado del mapa mediante una
cadena de dirección que se buscará en el mismo. En la segunda forma se
establecen unas coordenadas de latitud y longitud, un nivel de mapa y
también el servidor que queremos utilizar del mismo dándole un nombre.
</p>
</div>
</div>
<div id="outline-container-orgf7e6acb" class="outline-2">
<h2 id="orgf7e6acb">Instalar y configurar el paquete</h2>
<div class="outline-text-2" id="text-orgf7e6acb">
<p>
Si creéis que este paquete os puede ser útil, sólo tenéis que
instalarlo y probarlo. La instalación, como siempre es un simple
comando:
</p>

<pre class="example" id="org5e0f990">
M-x package-install RET osm
</pre>

<p>
Por no dar muchas vueltas y alargar innecesariamente esta entrada del
<i>blog</i>, la configuración que tengo en mi <code>init.el</code> es la siguiente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> osm
  <span style="color: #8be9fd; font-style: italic;">:bind</span> ((<span style="color: #f1fa8c;">"C-c m h"</span> . osm-home)
         (<span style="color: #f1fa8c;">"C-c m s"</span> . osm-search)
         (<span style="color: #f1fa8c;">"C-c m v"</span> . osm-server)
         (<span style="color: #f1fa8c;">"C-c m t"</span> . osm-goto)
         (<span style="color: #f1fa8c;">"C-c m x"</span> . osm-gpx-show)
         (<span style="color: #f1fa8c;">"C-c m j"</span> . osm-bookmark-jump))
  <span style="color: #8be9fd; font-style: italic;">:custom</span>
  (osm-server 'default)
  (osm-copyright t)
  <span style="color: #8be9fd; font-style: italic;">:init</span>
  (<span style="color: #ff79c6; font-weight: bold;">with-eval-after-load</span> 'org
    (<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">osm-ol</span>)))
</pre>
</div>

<p>
Esta configuración está copiada directamente de la <a href="https://github.com/minad/osm">página de hithub</a>
del paquete.
</p>

<p>
Una vez abierto un <i>buffer</i> <code>osm-mode</code>, dentro de él nos podemos mover
con el teclado y con el ratón:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">ratón</th>
<th scope="col" class="org-left">tecla</th>
<th scope="col" class="org-left">acción</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">rueda ↓</td>
<td class="org-left"><code>+</code></td>
<td class="org-left">Ampliar mapa</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">rueda ↑</td>
<td class="org-left"><code>-</code></td>
<td class="org-left">Reducir mapa</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">pinchar + desplazar</td>
<td class="org-left">flechas</td>
<td class="org-left">Mover el mapa</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>c</code></td>
<td class="org-left">Centrar mapa</td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>v</code></td>
<td class="org-left">Cambiar servidor</td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>s</code></td>
<td class="org-left">Buscar sitio</td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>t</code></td>
<td class="org-left">Ir coordenadas</td>
</tr>
</tbody>
</table>

<p>
En el <i>buffer</i> gráfico aparecen un menú de acciones y un <i>widget</i> que
permite cambiar el tipo de mapa empleado. Aunque todas las funciones
se pueden realizar con su correspondiente tecla asociada y/o se pueden
<i>mapear</i> a la combinación de teclas que sean más cómodas para el
usuario.
</p>
</div>
</div>
<div id="outline-container-org6e0fec2" class="outline-2">
<h2 id="org6e0fec2">Conclusiones</h2>
<div class="outline-text-2" id="text-org6e0fec2">
<p>
La parte de visualizar trazas GPX no la he probado, pero también se
puede. Después de probarlo unos días, creo que me será de utilidad,
teniendo en cuenta además, la capacidad de poder <i>localizar</i> los
lugares también desde código <code>elisp</code>. El que permita utilizar código
abre la posibilidad de interactuar más flexiblemente con el mapa. O el
poder meter en un archivo <code>org-mode</code> un enlace a los lugares a los que
se haga referencia.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En algunos tipos de mapas no están todas las representaciones y
es posible que falten las últimas. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Este es mejor visitarlo antes para coger fuerzas antes de
visitar los demás. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/mapas/index.html">mapas</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[mapas]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2022/03/27/openstreetmap-dentro-de-emacs.html</link>
  <pubDate>Sun, 27 Mar 2022 11:35:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[qemu, guix, haiku y otras yerbas I]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-03-06</div>
<p>
Aprovechando que tengo máquina de sobra para virtualización y que
también hay ganas de probar algunas cosas sin poner en riesgo la
instalación, pues me he puesto a experimentar un poco con máquinas
virtuales. ¿Qué quiero probar? Sencillo: <i>Guix</i>, <i>Haiku-os</i> y veré si
en el futuro, también <code>exwm</code>... ¿Con algún objetivo en mente o porque
sí? Bueno, <i>Guix</i> llevo con ganas de probar la <i>distro</i> desde el
momento que supe de ella y había probado en sus inicios, también
virtualmente, pero iba tan lenta que lo deseché. También he probado
antes <i>Haiku</i>, pero fue cuando estaba en versión <i>alfa</i> y no se podía
instalar en disco duro.  Por último, <code>exwm</code>, porque me gustan los
entornos de ventana <i>teselantes</i> y mi lado <i>friki</i> no puede evitar
pensar en tener el entorno de ventanas gestionado por <i>Emacs</i>. Quizás
sea mucho contenido para un solo artículo, así que lo partiré en
varios para no <i>cansinar</i> al pobre lector. En este veremos los
procesos de instalación de ambos sistemas operativos. En el siguiente
compararé el rendimiento de ambos y compararemos las características y
sensaciones.
</p>
<div id="outline-container-orge746e2c" class="outline-2">
<h2 id="orge746e2c">Instalación de Guix</h2>
<div class="outline-text-2" id="text-orge746e2c">
<ol class="org-ol">
<li><p>
Descargar la imagen y hace la comprobación
</p>

<div class="org-src-container">
<pre class="src src-shell">wget https://ftp.gnu.org/gnu/guix/guix-system-install-1.3.0.x86_64-linux.iso
wget https://ftp.gnu.org/gnu/guix/guix-system-install-1.3.0.x86_64-linux.iso.sig
gpg --verify guix-system-install-1.3.0.x86_64-linux.iso.sig
</pre>
</div></li>

<li><p>
Crear un dispositivo con <code>qemu</code>:
</p>

<div class="org-src-container">
<pre class="src src-shell">qemu-img create -f qcow2 guix-system.img 50G
</pre>
</div>

<pre class="example" id="org9ec844b">
~/qemu-vm $ ls -lah
total 612M
drwxr-xr-x   1 notxor         notxor    240 2022-03-02 10:25 .
drwx------   1 notxor         notxor   1.2k 2022-03-02 10:18 ..
-rw-r--r--   1 notxor         notxor   612M 2021-05-12  2021 guix-system-install-1.3.0.x86_64-linux.iso
-rw-r--r--   1 notxor         notxor    833 2021-05-12  2021 guix-system-install-1.3.0.x86_64-linux.iso.sig
~/qemu-vm $ qemu-img create -f qcow2 guix-system.img 50G
Formatting 'guix-system.img', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=53687091200 lazy_refcounts=off refcount_bits=16
~/qemu-vm $ ls -lah
total 612M
drwxr-xr-x   1 notxor         notxor    270 2022-03-02 10:27 .
drwx------   1 notxor         notxor   1.2k 2022-03-02 10:18 ..
-rw-r--r--   1 notxor         notxor   612M 2021-05-12  2021 guix-system-install-1.3.0.x86_64-linux.iso
-rw-r--r--   1 notxor         notxor    833 2021-05-12  2021 guix-system-install-1.3.0.x86_64-linux.iso.sig
-rw-r--r--   1 notxor         notxor   193k 2022-03-02 10:27 guix-system.img
~/qemu-vm $ 
</pre>

<p>
Ha creado el <code>guix-system.img</code>, aunque hemos dicho que el tamaño
fuera 50Gb, el archivo creado es de 193Kb, luego irá creciendo
según lo necesite hasta el máximo de 50Gb. Iniciamos la
instalación, siguiendo la documentación de <i>Guix</i>:
</p>

<div class="org-src-container">
<pre class="src src-shell">qemu-system-x86_64 -m 2048 -smp 1 -enable-kvm <span style="color: #f1fa8c;">\</span>
                   -nic user,<span style="color: #f8f8f2; font-weight: bold;">model</span>=virtio-net-pci -boot <span style="color: #f8f8f2; font-weight: bold;">menu</span>=on,<span style="color: #f8f8f2; font-weight: bold;">order</span>=d <span style="color: #f1fa8c;">\</span>
                   -drive <span style="color: #f8f8f2; font-weight: bold;">file</span>=guix-system.img <span style="color: #f1fa8c;">\</span>
                   -drive <span style="color: #f8f8f2; font-weight: bold;">media</span>=cdrom,<span style="color: #f8f8f2; font-weight: bold;">file</span>=guix-system-install-1.3.0.x86_64-linux.iso
</pre>
</div></li>
</ol>
</div>
<div id="outline-container-org66470ec" class="outline-3">
<h3 id="org66470ec">Proceso de instalación</h3>
<div class="outline-text-3" id="text-org66470ec">
<p>
Por lo que tengo entendido, todo el proceso de instalación de <i>Guix</i>
lo que hace es generar un /script/de <code>Guile scheme</code> que realizará
tanto la descarga como la configuración del sistema. Me llamó la
atención la simplicidad del mismo. Vamos a repasarlo, partiendo del
comando anterior:
</p>

<ul class="org-ul">
<li><code>-m 2048</code>: se reservan 2Gb de RAM para la máquina.</li>
<li><code>-enable-kvm</code>: acelera la máquina virtual.</li>
<li><code>-nic user,model=virtio-net-pci</code>: virtualizamos la red de la máquina
como si fuera una conexión cableada, dándole a la máquina virtual la
posibilidad de acceder a la Internet.</li>
<li><code>-boot menu=on,order=d</code>: establece que se arranque con el menú de
<code>grub</code> activado y que en el orden de preferencia de dispositivos para
el arranque se tome primero el <code>cdrom</code>.</li>
<li><code>-drive file=guix-system.img</code>: es el fichero de imagen que creamos
en el apartado anterior y el que queremos usar como disco duro
virtual.</li>
<li>~-drive</li>
</ul>
<p>
media=cdrom,file=guix-system-install-1.3.0.x86_64-linux.iso~: es la
imagen de instalación que montamos como si fuera un <code>cdrom</code> en <i>qemu</i>
para realizar la instalación desde ella.
</p>


<figure id="orgd440b0b">
<img src="./imagenes/Captura_instalacion-guix-0.png" alt="Captura_instalacion-guix-0.png">

</figure>

<p>
Tras el menú de arranque nos pregunta qué idioma queremos utilizar
durante el proceso de instalación.
</p>


<figure id="org2bec509">
<img src="./imagenes/Captura_Guix-lenguaje.png" alt="Captura_Guix-lenguaje.png">

</figure>

<p>
Una vez que hemos seleccionado el idioma vemos que ya el país nos lo
pregunta en español.
</p>


<figure id="org5124e6f">
<img src="./imagenes/Captura_Guix-pais.png" alt="Captura_Guix-pais.png">

</figure>

<p>
A continuación podemos seleccionar si queremos utilizar la instalación
interactiva <i>gráfica</i> (aunque sea <code>dialog</code> de terminal) o queremos la
instalación de <code>shell</code>. En mi caso seleccioné la <i>interfaz gráfica</i>.
</p>


<figure id="orgc875909">
<img src="./imagenes/Captura_Guix-tipo-instalacion.png" alt="Captura_Guix-tipo-instalacion.png">

</figure>

<p>
A continuación nos pide la zona horaria. En mi caso «Europa/Madrid».
</p>


<figure id="org86c6bf3">
<img src="./imagenes/Captura_Guix-zona-horaria.png" alt="Captura_Guix-zona-horaria.png">

</figure>

<p>
Después seleccionamos la distribución del teclado. En mi caso «Español
de España».
</p>


<figure id="org1fc444f">
<img src="./imagenes/Captura_Guix-teclado-1.png" alt="Captura_Guix-teclado-1.png">

</figure>


<figure id="orgba01623">
<img src="./imagenes/Captura_Guix-teclado-2.png" alt="Captura_Guix-teclado-2.png">

</figure>

<p>
A continuación nos pide un nombre para la máquina.
</p>


<figure id="orgbfe0302">
<img src="./imagenes/Captura_Guix-nombre-maquina.png" alt="Captura_Guix-nombre-maquina.png">

</figure>

<p>
A continuación nos hace una pregunta un poco enrevesada, además en
perfecto inglés. Por lo que he leído en la documentación, --puedo
estar equivocado--, nos pregunta si permitir que <i>Guix</i> añada otros
servidores que encuentre por la misma red para obtener paquetes de
instalación. Esto acelera la instalación de <i>Guix</i> en varias máquinas
de la misma red, pues la obtención de los paquetes se puede distribuir
entre ellas.
</p>


<figure id="org7a6a8f6">
<img src="./imagenes/Captura_Guix-subtitute-servers.png" alt="Captura_Guix-subtitute-servers.png">

</figure>

<p>
A continuación nos pide una contraseña para el usuario <code>root</code>. Por
supuesto, lo hará dos veces para evitar errores de tecleo.
</p>


<figure id="orgfbb6dfc">
<img src="./imagenes/Captura_Guix-password-root.png" alt="Captura_Guix-password-root.png">

</figure>

<p>
Nos propondrá que creemos usuarios. Al menos se debe crear uno.
</p>


<figure id="org2bb5198">
<img src="./imagenes/Captura_Guix-crear-usuario.png" alt="Captura_Guix-crear-usuario.png">

</figure>


<figure id="org74c07de">
<img src="./imagenes/Captura_Guix-formulario-usuario.png" alt="Captura_Guix-formulario-usuario.png">

</figure>

<p>
Una vez creado un usuario, nos pedirá la confirmación de su
contraseña, de nuevo para evitar errores de tecleo.
</p>


<figure id="org51cf119">
<img src="./imagenes/Captura_Guix-confirmar-password-usuario.png" alt="Captura_Guix-confirmar-password-usuario.png">

</figure>

<p>
A continuación nos permite seleccionar el escritorio que usará el
usuario, por defecto.
</p>


<figure id="orge8c058c">
<img src="./imagenes/Captura_Guix-seleccionar-escritorio.png" alt="Captura_Guix-seleccionar-escritorio.png">

</figure>

<p>
También podemos activar algunos servicios de red básicos. En mi caso
activé los tres propuestos.
</p>


<figure id="org048ce0c">
<img src="./imagenes/Captura_Guix-servicio-de-red.png" alt="Captura_Guix-servicio-de-red.png">

</figure>

<p>
Llega el momento de particionar el disco duro.
</p>


<figure id="org9d7fd08">
<img src="./imagenes/Captura_Guix-particionado-disco.png" alt="Captura_Guix-particionado-disco.png">

</figure>

<p>
Seleccioné la opción «guiada» y lo primero que pide es seleccionar el
disco duro donde instalarse. Hay que recordar que a <code>qemu</code> le dimos
dos unidades: el CD-ROM de instalación y un disco duro virtual de
50Gb, que es el primero que nos aparece en la lista.
</p>


<figure id="org6b6afd3">
<img src="./imagenes/Captura_Guix-seleccionar-disco.png" alt="Captura_Guix-seleccionar-disco.png">

</figure>

<p>
A continuación tenemos que elegir el tipo de particiones que vamos a
utilizar. En nuestro caso <code>gpt</code>.
</p>


<figure id="org203736e">
<img src="./imagenes/Captura_Guix-tabla-particiones.png" alt="Captura_Guix-tabla-particiones.png">

</figure>

<p>
Lo siguiente es decirle qué esquema de particiones queremos. Para no
complicarme mucho seleccioné el «Todo en una partición».
</p>


<figure id="orge7acb80">
<img src="./imagenes/Captura_Guix-esquema-particionado.png" alt="Captura_Guix-esquema-particionado.png">

</figure>

<p>
El sistema de instalación propone un particionado que acepté sin
modificar nada.
</p>


<figure id="org968db43">
<img src="./imagenes/Captura_Guix-particionado-guiado.png" alt="Captura_Guix-particionado-guiado.png">

</figure>

<p>
Una vez realizada esa parte, llega la delicada, que es dar formato al
disco. En este caso tampoco es muy delicada porque estoy utilizando un
disco duro virtual. Hasta ahora todo lo que se ha venido haciendo es
guardar opciones en un <code>script</code> que hará la instalación. Pero este
paso realiza una escritura en disco. Por lo que es posible que se
pierdan datos, si estamos utilizando un disco físico y lo advierte.
</p>


<figure id="org5cdec74">
<img src="./imagenes/Captura_Guix-dar-formato-disco.png" alt="Captura_Guix-dar-formato-disco.png">

</figure>

<p>
Como he dicho, lo que hace el instalador es generar un <code>script</code> que
realizará la instalación de manera automática con las opciones que le
hayamos dado. En el siguiente paso, nos muestra el código fuente del
mismo y nos da la oportunidad de modificarlo si queremos. Mi
recomendación es que no lo toquéis, pero cada uno es muy libre de
experimentar lo que quiera.
</p>


<figure id="org76a0110">
<img src="./imagenes/Captura_Guix-archivo-configuracion.png" alt="Captura_Guix-archivo-configuracion.png">

</figure>

<p>
A continuación el instalador se pone a descargar los paquetes que
necesita para configurar nuestro sistema operativo con los parámetros
que le hemos dado.
</p>


<figure id="orgb3bbb2a">
<img src="./imagenes/Captura_Guix-instalando.png" alt="Captura_Guix-instalando.png">

</figure>

<p>
Cuando termina de hacerlo nos muestra en el instalador la opción de
reiniciar el equipo con nuestro nuevo sistema operativo.
</p>


<figure id="org14b729e">
<img src="./imagenes/Captura_Guix-fin-instalacion.png" alt="Captura_Guix-fin-instalacion.png">

</figure>
</div>
</div>
<div id="outline-container-orgb5a9f9a" class="outline-3">
<h3 id="orgb5a9f9a">Iniciando Guix</h3>
<div class="outline-text-3" id="text-orgb5a9f9a">
<p>
Es el momento de <i>sacar</i> el CD-ROM de la unidad y reiniciar el
sistema. Si reiniciamos tal y como estamos, volverá a arrancar con la
unidad de instalación. Tenemos que cancelar el proceso y arrancar con
otra línea de comandos, eliminando la parte del CD-ROM.
</p>

<div class="org-src-container">
<pre class="src src-shell">qemu-system-x86_64 -m 1024 -smp 1 -enable-kvm <span style="color: #f1fa8c;">\</span>
                   -nic user,<span style="color: #f8f8f2; font-weight: bold;">model</span>=virtio-net-pci -boot <span style="color: #f8f8f2; font-weight: bold;">menu</span>=on <span style="color: #f1fa8c;">\</span>
                   -drive <span style="color: #f8f8f2; font-weight: bold;">file</span>=guix-system.img
</pre>
</div>

<p>
Cambia, por ser más detallado, que he eliminada <code>order=d</code> del arranque
y también ha desaparecido ese <code>drive</code> de la línea de comandos. Primero
nos arrancará el menú <code>grub</code>, porque se lo he pedido (también se puede
eliminar).
</p>


<figure id="org40d9d3a">
<img src="./imagenes/Captura_Guix-arranque-ya-instalado.png" alt="Captura_Guix-arranque-ya-instalado.png">

</figure>

<p>
La ventana de entrada al sistema pidiendo qué usuario utilizar:
</p>


<figure id="orgd0c3288">
<img src="./imagenes/Captura_Guix-pantalla-entrada.png" alt="Captura_Guix-pantalla-entrada.png">

</figure>

<p>
Nuestro XFCE4 funcionando a la perfección.
</p>


<figure id="orgdb2cbe7">
<img src="./imagenes/Captura_Guix-xfce.png" alt="Captura_Guix-xfce.png">

</figure>

<p>
Después de la instalación, podemos comprobar cómo ha crecido el
espacio del dispositivo.
</p>

<pre class="example" id="orgd51244d">
~/qemu-vm $ ls -lah
total 9.2G
drwxr-xr-x   1 notxor         notxor    206 2022-03-03 09:45 .
drwxr-xr-x   1 notxor         notxor    282 2022-03-03 09:43 ..
-rw-r--r--   1 notxor         notxor   612M 2022-03-03 09:43 guix-system-install-1.3.0.x86_64-linux.iso
-rw-r--r--   1 notxor         notxor    833 2022-03-03 09:44 guix-system-install-1.3.0.x86_64-linux.iso.sig
-rw-r--r--   1 notxor         notxor   8.6G 2022-03-03 09:45 guix-system.img
~/qemu-vm $
</pre>

<p>
Como podemos observar es un proceso sencillo y basta ir leyendo las
preguntas que nos va haciendo preguntas claras y tampoco demasiado
técnicas. Si lo estamos instalando en una máquina física, no
deberíamos tener mayor problema si nuestro <i>hardware</i> es completamente
compatible con GNU/Linux.
</p>
</div>
</div>
</div>
<div id="outline-container-org4da4237" class="outline-2">
<h2 id="org4da4237">Creando una máquina virtual de Haiku-os</h2>
<div class="outline-text-2" id="text-org4da4237">
<p>
Otra de las cosas que quería probar, puesto que estamos de
instalaciones virtuales, es <i>Haiku</i>. Ya lo probé hace años, también en
una máquina virtual. Entonces estaba en una versión <i>alfa</i> y no había
otra opción. La última versión, sin embargo, ya se puede instalar en
una partición física si se quiere.
</p>

<p>
Para el que no lo conozca, aunque creo que a estas alturas ya lo
conocerá todo el mundo, <i>Haiku</i>, además de un tipo de poesía de origen
japonés, es un sistema operativo que intenta resucitar <i>BeOS</i>.
<i>Resucitar</i> no sería la palabra, pues <i>BeOS</i> no murió a pesar del
fracaso comercial de <i>Be</i>, sigue teniendo un pequeño, aunque muy fiel,
grupo de seguidores.
</p>

<p>
El proceso de instalación es muy similar al que se ha hecho para
instalar <i>Guix</i>, pero lo voy a repetir para compararlo. En este caso,
cuando habla de instalación gráfica, se refiere a gráfica de verdad.
</p>

<p>
Antes de nada, lo primero será descargar la imagen del disco de
instalación.
</p>

<ol class="org-ol">
<li><p>
Vamos a la <a href="https://www.haiku-os.org/">web de haiku-os</a> y vemos un botón enorme de «descarga» en
el centro de la página.
</p>


<figure id="org0ad1422">
<img src="./imagenes/Captura_haiku-descarga.png" alt="Captura_haiku-descarga.png">

</figure></li>

<li><p>
Pinchamos en ese botón gordo de <i>downloads</i> y descargamos la <code>iso</code>
que nos vaya bien:
</p>


<figure id="org5782913">
<img src="./imagenes/Captura_haiku-download-iso.png" alt="Captura_haiku-download-iso.png">

</figure></li>

<li><p>
Copiamos la <code>iso</code> donde queramos crear la máquina virtual. En mi
caso la he puesto junto con la de <i>Guix</i> en el mismo directorio:
</p>

<pre class="example" id="orga70f767">
~/qemu-vm $ ls -lah
total 9.9G
drwxr-xr-x   1 notxor         notxor    270 2022-03-03 09:46 .
drwx------   1 notxor         notxor   1.3k 2022-03-03 10:02 ..
-rw-r--r--   1 notxor         notxor   612M 2021-05-12  2021 guix-system-install-1.3.0.x86_64-linux.iso
-rw-r--r--   1 notxor         notxor    833 2021-05-12  2021 guix-system-install-1.3.0.x86_64-linux.iso.sig
-rw-r--r--   1 notxor         notxor   8.6G 2022-03-03 09:51 guix-system.img
-rw-r--r--   1 notxor         notxor   719M 2022-03-01 22:13 haiku-r1beta3-x86_64-anyboot.iso
~/qemu-vm $
</pre></li>
</ol>

<p>
Si queréis probarlo antes de instalarlo, el disco de <i>Haiku</i> también
funciona, si la copiamos en un USB o la quemamos en un disco, como
sistema de prueba. Arrancando desde esa unidad nos deja probarlo sin
instalar nada.
</p>
</div>
<div id="outline-container-orgf1c1f10" class="outline-3">
<h3 id="orgf1c1f10">Proceso de instalación de Haiku-os</h3>
<div class="outline-text-3" id="text-orgf1c1f10">
<p>
En este caso, como lo voy a hacer en una máquina virtual, no me
preocupa tanto probarlo, lo haré desde <code>qemu</code>, lo podré trastear,
configurar a mi gusto y comprobar su estabilidad con una instalación
más permanente.
</p>

<p>
Pero vamos ya con la instalación. Lo primero es crear el disco virtual
para instalar <i>Haiku-OS</i> en él.
</p>

<div class="org-src-container">
<pre class="src src-shell">qemu-img create -f qcow2 haiku-os.img 50G
</pre>
</div>

<p>
El resultado es un archivo <code>haiku-os.img</code> de 193kb en el que haremos
la instalación.
</p>

<pre class="example" id="orgdecc315">
~/qemu-vm $ ls -lah
total 9.9G
drwxr-xr-x   1 notxor         notxor    294 2022-03-05 08:54 .
drwx------   1 notxor         notxor   1.3k 2022-03-05 08:49 ..
-rw-r--r--   1 notxor         notxor   612M 2021-05-12  2021 guix-system-install-1.3.0.x86_64-linux.iso
-rw-r--r--   1 notxor         notxor    833 2021-05-12  2021 guix-system-install-1.3.0.x86_64-linux.iso.sig
-rw-r--r--   1 notxor         notxor   8.6G 2022-03-03 09:51 guix-system.img
-rw-r--r--   1 notxor         notxor   193k 2022-03-05 08:54 haiku-os.img
-rw-r--r--   1 notxor         notxor   719M 2022-03-01 22:13 haiku-r1beta3-x86_64-anyboot.iso
~/qemu-vm $ 
</pre>

<p>
De manera similar a como se hizo la instalación de <i>Guix</i>, tenemos que
arrancar <code>qemu</code> con el dispositivo montando la <code>iso</code> al arrancar y el
<code>img</code> preparado como disco duro donde meteremos la instalación.  Por
tanto el comando es muy similar al utilizado anteriormente:
</p>

<div class="org-src-container">
<pre class="src src-shell">qemu-system-x86_64 -m 2048 -smp 1 -enable-kvm <span style="color: #f1fa8c;">\</span>
                   -nic user,<span style="color: #f8f8f2; font-weight: bold;">model</span>=virtio-net-pci -boot <span style="color: #f8f8f2; font-weight: bold;">menu</span>=on,<span style="color: #f8f8f2; font-weight: bold;">order</span>=d <span style="color: #f1fa8c;">\</span>
                   -drive <span style="color: #f8f8f2; font-weight: bold;">file</span>=haiku-os.img <span style="color: #f1fa8c;">\</span>
                   -drive <span style="color: #f8f8f2; font-weight: bold;">media</span>=cdrom,<span style="color: #f8f8f2; font-weight: bold;">file</span>=haiku-r1beta3-x86_64-anyboot.iso
</pre>
</div>

<p>
Como ya expliqué cada parte de este comando al instalar <i>Guix</i> no
volveré a repetiré el significado de cada uno, os remito a la
explicación más arriba.
</p>

<p>
Arrancamos el sistema desde línea de comandos:
</p>


<figure id="org12c766c">
<img src="./imagenes/Captura_inicio-instalacion.png" alt="Captura_inicio-instalacion.png">

</figure>

<p>
Tras arrancar nos pregunta el idioma en el que queremos trabajar y nos
permite seleccionar también la distribución del teclado. A
continuación, podemos seleccionar si queremos instalarlo o simplemente
probarlo, como dije antes.
</p>


<figure id="org2f62617">
<img src="./imagenes/Captura_haiku-idioma.png" alt="Captura_haiku-idioma.png">

</figure>

<p>
En mi caso, quiero instalar <i>Haiku</i>, por ello seleccioné el botón
correspondiente. Tras pulsarlo, nos aparece una ventana de información
importante, especialmente si quieres instalar <i>Haiku</i> en un
dispositivo físico en lugar de en uno virtual. Dándonos la oportunidad
de seguir adelante o salir de la instalación.
</p>


<figure id="orgddacdda">
<img src="./imagenes/Captura_haiku-info.png" alt="Captura_haiku-info.png">

</figure>

<p>
Como he decidido continuar, me pregunta en qué dispositivo quiero
instalarlo.
</p>


<figure id="org77b8816">
<img src="./imagenes/Captura_haiku-seleccion-dispositivo.png" alt="Captura_haiku-seleccion-dispositivo.png">

</figure>

<p>
Aunque tenemos preparada un dispositivo virtual para instalarlo,
<i>Haiku</i> no lo detecta. Tenemos que formatearlo con el sistema de
particiones de <i>BeOS</i>.
</p>


<figure id="org7955f0a">
<img src="./imagenes/Captura_haiku-ir-configurar-particiones.png" alt="Captura_haiku-ir-configurar-particiones.png">

</figure>

<p>
Para ello, particionamos el disco duro que nos aparece el primero en
la lista, de tamaño 50Gb que tenemos preparado.
</p>


<figure id="orgbb9121f">
<img src="./imagenes/Captura_haiku-particionador-disco.png" alt="Captura_haiku-particionador-disco.png">

</figure>

<p>
Debemos seleccionarlo en la lista y darle a la partición el formato
<i>Be File System</i>.
</p>


<figure id="org3412469">
<img src="./imagenes/Captura_haiku-dar-formato-disco.png" alt="Captura_haiku-dar-formato-disco.png">

</figure>

<p>
Después de haberlo hecho, ya nos aparece en la lista de dispositivos
destino nuestro disco duro.
</p>


<figure id="orgc5b1d71">
<img src="./imagenes/Captura_haiku-seleccionar-destino.png" alt="Captura_haiku-seleccionar-destino.png">

</figure>

<p>
El proceso de instalación es rapidísimo... tanto que no dio tiempo a
tomar un pantallazo durante el tiempo de espera. En unos segundos
pidió ya el reiniciar con el sistema operativo ya instalado.
</p>


<figure id="org3d95179">
<img src="./imagenes/Captura_haiku-instalacion-reinicio.png" alt="Captura_haiku-instalacion-reinicio.png">

</figure>

<p>
Igual que antes, para reiniciar, hay que extraer la unidad de
instalación. Cuando es física, simplemente la sacamos de su
localización y reiniciamos. Pero al ser virtual, lo tenemos que hacer
desde la línea de comandos, eliminando las partes no deseadas, como
antes.
</p>

<p>
Por último, el <i>software</i> que provee el disco de instalación puede
tener ya algo de tiempo  y es conveniente actualizarlo. Para ello,
entre las aplicaciones que vienen instaladas está el «actualizador de
software»
</p>


<figure id="org7e8a34d">
<img src="./imagenes/Captura_haiku-actualizar-software.png" alt="Captura_haiku-actualizar-software.png">

</figure>

<p>
También puedes instalar muchas más aplicaciones para <i>Haiku</i>, con la
aplicación <code>HaikuDepot</code>:
</p>


<figure id="org327be2d">
<img src="./imagenes/Captura_haiku-depot.png" alt="Captura_haiku-depot.png">

</figure>

<p>
Adivinad, cuál ha sido la primera que he instalado, no lo digo, os lo
enseño:
</p>


<figure id="orgea4d464">
<img src="./imagenes/Captura_haiku-emacs.png" alt="Captura_haiku-emacs.png">

</figure>
</div>
</div>
</div>
<div id="outline-container-org58a6028" class="outline-2">
<h2 id="org58a6028">Conclusiones</h2>
<div class="outline-text-2" id="text-org58a6028">
<p>
La virtualización me va a permitir probar cosas sin ensuciar el
sistema operativo instalado en mi máquina. Aún poniendo atención,
cuando probamos cosas, no siempre nos deshacemos de la «basura» que va
quedando, esas librerías y dependencias que instala el sistema y que
cuando lo desinstalamos, se quedan huérfanas en el disco.
</p>

<p>
De momento, y por comprobar, ambos sistemas operativos que quería
probar están funcionando correctamente. Incluso me han permitido
utilizar toda la pantalla del portátil y trabajar en modo pantalla
completa es posible.
</p>

<p>
Me ha sorprendido la ligereza y rapidez de <i>Haiku-os</i>, no lo recordaba
tan fluido, quizá también porque cuando lo probé, hace unos años había
bastante menos máquina.
</p>


<figure id="org115595a">
<img src="./imagenes/Captura_haiku-prueba-resolucion.png" alt="Captura_haiku-prueba-resolucion.png">

</figure>

<p>
La <i>demo</i> de la tetera me funciona a 1.102 fps, ocupa poco espacio con
lo básico instalado:
</p>

<pre class="example" id="org5987e2f">
~/qemu-vm $ ls -lh
total 9.4G
-rw-r--r--   1 notxor         notxor   8.6G 2022-03-03 09:51 guix-system.img
-rw-r--r--   1 notxor         notxor   822M 2022-03-05 10:17 haiku-os.img
~/qemu-vm $
</pre>

<p>
No llega al <i>giga</i> y trae todo el sistema gráfico integrado,
herramientas de programación, las habituales de todo sistema
operativo:
</p>

<ul class="org-ul">
<li>Gestor de ficheros</li>
<li>Lanzador de aplicaciones</li>
<li>Editor de textos básico (trae también un UI para programación con
<i>debugger</i> incluido)</li>
<li>Visor de procesos y recursos del sistema</li>
<li>Terminal</li>
<li>Navegador web gráfico</li>
<li>...</li>
</ul>

<p>
<i>Haiku</i> promete ser frugal con los recursos y puede ser una buena
alternativa para máquinas antiguas. Habría que comprobar cómo llevan
el tema de los <i>drivers</i>, las compatibilidades con el <i>hardware</i> y el
tema de la seguridad. De momento es un sistema operativo que aún no es
multiusuario, no hay usuario <code>root</code> o similar. Aunque ya mantiene
separados dos apartados <code>/system</code> y <code>/home</code>. Hay que recordar, que
<i>Haiku</i> como <i>BeOS</i>, no es <i>Unix</i>. Aunque sí cumple el estándar
<i>posix</i>. No hay que dejarse engañar porque en su terminal utilice
<code>bash</code> o porque su lista de aplicaciones sea muy similar a cualquier
lista de paquetes de una <i>distro</i> GNU/Linux... no. No es el objetivo
de <i>Haiku</i> convertirse en un núcleo para <i>GNU</i>, sino el hacer un
sistema operativo usable, agradable, rápido y multitarea. Mi primera
impresión es que lo están consiguiendo.
</p>

<p>
De <i>Guix</i> hablo menos, porque es una <i>distro GNU/Linux</i> y por tanto es
todo muy parecido lo que ya conocemos. Me ha llamado la atención la
sencillez del instalador.
</p>

<p>
Por último, para trabajar con los sistemas virtualizados, me he creado
dos comandos para lanzarlos que he situado en mi <code>~/opt/bin</code> para
llamarlos como un comando o aplicación más:
</p>

<ul class="org-ul">
<li><p>
Para <i>Guix</i> con nombre <code>guix-os</code>:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #6272a4;">#</span><span style="color: #6272a4;">! /usr/bin/</span><span style="color: #ff79c6; font-weight: bold;">bash</span><span style="color: #6272a4;">
</span>
<span style="color: #8be9fd; font-style: italic;">cd</span> ~/qemu-vm
qemu-system-x86_64 -m 2048 -smp 1 -enable-kvm <span style="color: #f1fa8c;">\</span>
                   -nic user,<span style="color: #f8f8f2; font-weight: bold;">model</span>=virtio-net-pci -boot <span style="color: #f8f8f2; font-weight: bold;">menu</span>=on <span style="color: #f1fa8c;">\</span>
                   -drive <span style="color: #f8f8f2; font-weight: bold;">file</span>=guix-system.img 
</pre>
</div></li>

<li><p>
Para <i>Haiku</i> con nombre <code>haiku-os</code>:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #6272a4;">#</span><span style="color: #6272a4;">! /usr/bin/</span><span style="color: #ff79c6; font-weight: bold;">bash</span><span style="color: #6272a4;">
</span>
<span style="color: #8be9fd; font-style: italic;">cd</span> ~/qemu-vm
qemu-system-x86_64 -m 2048 -smp 1 -enable-kvm <span style="color: #f1fa8c;">\</span>
                   -nic user,<span style="color: #f8f8f2; font-weight: bold;">model</span>=virtio-net-pci <span style="color: #f1fa8c;">\</span>
                   -drive <span style="color: #f8f8f2; font-weight: bold;">file</span>=haiku-os.img
</pre>
</div></li>
</ul>

<p>
En el siguiente capítulo, quiero comparar el gasto de recursos y
rendimiento entre ambos sistemas e improvisar un pequeño banco de
pruebas para ello. Aunque es complicado, pues la mayor diferencia es
la sensación que transmiten al usarse y lo perdido que vas con el <i>SO</i>
al que menos acostumbrado estás.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/qemu/index.html">qemu</a> <a href="/tags/guix/index.html">guix</a> <a href="/tags/virtualización/index.html">virtualización</a> <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/exwm/index.html">exwm</a> ]]></description>
  <category><![CDATA[qemu]]></category>
  <category><![CDATA[guix]]></category>
  <category><![CDATA[virtualización]]></category>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[exwm]]></category>
  <link>https://notxor.nueva-actitud.org/2022/03/06/qemu-guix-haiku-y-otras-yerbas-i.html</link>
  <pubDate>Sun, 06 Mar 2022 12:05:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Nueva máquina]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-02-24</div>
<p>
Llevo ya una docena de días, más o menos, como <del>niño con zapatos
nuevos</del> friki con ordenador nuevo. Me compré un <a href="https://slimbook.es">Slimbook</a> «essential»
de 15" con Ryzen 5 y RAM para abastecer al vecino. No sólo he
multiplicado velocidad de proceso al cambiar una máquina que tenía 12
años, también he multiplicado por cuatro la memoria. Pero os cuento
todo el proceso.
</p>


<figure id="org486f45a">
<img src="./imagenes/Captura_20220224_084039.png" alt="Captura_20220224_084039.png">

</figure>
<div id="outline-container-orgfeb1451" class="outline-2">
<h2 id="orgfeb1451">La compra</h2>
<div class="outline-text-2" id="text-orgfeb1451">
<p>
Con mucha pena me despido del <i>viejuno</i>, que ha dado lo mejor de sí
mismo. El problema fundamental del pobre, era la pantalla, algo que es
fundamental en un portátil, sobre todo si no encuentras pantallas para
él. Yo ya estaba acostumbrado a su lentitud y a ser rácano con los
recursos, sus 4Gb de RAM tenían que bastar para todo y se quedaban
escasos en algunas tareas (como la edición de vídeo o sonido, o
trabajar con Blender). El caso es que había que cambiarlo y estuve
estudiando varias alternativas. Al final me decidí por la que me
pareció era la mejor relación calidad-precio. Un portátil de 15" con
procesador AMD Ryzen 5 con 16Gb de RAM y 500Gb de disco duro, con
gastos de transporte incluidos ha salido por 765€. La misma
configuración en el modelo PRO X, &#x2013;además de estar agotado&#x2013;, se
ponía en más de 1.200€. La estética y la ligereza del <i>PRO</i> son algo
mejores, pero el <i>essential</i> tampoco es feo y sale por poco más de la
mitad de precio. En cuanto a la ligereza, 100 gramos arriba o abajo no
merecen ese pastizal y como lo transporto en mochila, tampoco es muy
significativo ese incremento.
</p>

<p>
La compra por la red siempre es delicada y hay cosas mejorables. La
interfaz de <i>Slimbook</i> es clara, pero el procedimiento algo confuso.
Sobre todo en el caso que falle algo, como me ocurrió a mí.
</p>

<p>
Para empezar, tienes que registrarte sí o sí, con datos personales
completos. Algo que podría ser opcional, pero al facturarte necesitan
un montón de datos: DNI, domicilio, teléfono, etc. Además esa
inscripción te da acceso a un foro de clientes.
</p>

<p>
La confusión vino cuando al realizar la configuración del equipo y
hacer la compra falló el método de pago elegido. El proceso de compra
se detuvo y volvió a <i>la casilla de salida</i>. No me di cuenta, pero
todo el proceso se grabó y aparecía en la lista de compras del
<i>usuario</i>. Pero como digo, al salirse y quedarse en la página inicial,
yo volví a hacerlo todo de nuevo&#x2026; volvió a fallar el método de pago,
no sé si por problemas con la web de mi banco o por algún fallo en la
página de <i>Slimbook</i>, el caso es que volví a la casilla de salida de
nuevo. En el tercer intento, decidí pagar haciendo transferencia, cogí
los datos y la hice (eso retrasa uno o dos días todo el proceso hasta
que la casa tiene constancia del ingreso). Cuando entré en <i>mi cuenta
de usuario</i> me di cuenta que todos los intentos estaban registrados.
No hay opción de borrarlos&#x2026; por tanto hay dos compras <i>pendientes de
pago</i> en mi cuenta.
</p>

<p>
El resto fue unos días de espera: un par de ellos para que apareciera
el pedido como pagado tras haber hecho la trasferencia, uno para que
confirmaran el pedido, 4 ó 5 mientras lo ensamblaban, otro par
mientras lo probaban y otros 4 ó 5 de transporte.
</p>
</div>
</div>
<div id="outline-container-org8b994e0" class="outline-2">
<h2 id="org8b994e0">Desempaquetado</h2>
<div class="outline-text-2" id="text-org8b994e0">
<p>
El paquete de envío está bastante bien pensado, el ordenador llega,
perfectamente protegido: Una caja, dentro de una caja.
</p>


<figure id="orgdc6c1b2">
<img src="./imagenes/IMG_20220214_171651.jpg" alt="IMG_20220214_171651.jpg">

</figure>

<p>
Y en la caja más interna, el ordenador:
</p>


<figure id="org7736038">
<img src="./imagenes/IMG_20220214_171710.jpg" alt="IMG_20220214_171710.jpg">

</figure>

<p>
El contenido de la misma es el esperado. Venía el ordenador y el cable
de toma de corriente. Además de la factura, un minimanual de
instrucciones con las características del ordenador. Un CD o DVD con los
<i>drivers</i> y algunas utilidades (el ordenado no lleva lector) y una
gamuza de las que no desprenden pelusa para limpieza.
</p>

<p>
Ya está, eso es todo, porque eso fue lo que pedí.
</p>


<figure id="orgf5dac3d">
<img src="./imagenes/IMG_20220214_171854.jpg" alt="IMG_20220214_171854.jpg">

</figure>

<p>
Antes de encenderlo, ya me pareció bonito:
</p>


<figure id="orgc502dfc">
<img src="./imagenes/IMG_20220214_172149.jpg" alt="IMG_20220214_172149.jpg">

</figure>
</div>
</div>
<div id="outline-container-org6a5c8a1" class="outline-2">
<h2 id="org6a5c8a1">Configuración</h2>
<div class="outline-text-2" id="text-org6a5c8a1">
<p>
Lo pedí sin sistema operativo. Mi intención era ponerle una <i>OpenSuse
Tumbleweed</i> cuando llegara. La sorpresa es que venía, a pesar de todo
con una Ubuntu instalada. El primer paso fue descargar una imagen de
<i>Tumbleweed</i> para instalación por red y fabricar un <i>USB</i> que
arrancara el ordenador e iniciara el proceso. Bien, encontronazo al
hacerle arrancar desde <i>USB</i> desde <code>grub</code>, algo que no había hecho
nunca y que os dejo por aquí, por si algún día lo necesitamos.
Pulsando <code>&lt;Supr&gt;</code> accedía a un menú <i>gráfico</i> de <code>grub</code> bastante
críptico y lioso. No conseguí hacerlo arrancar desde <i>USB</i>, ya sabéis
que soy muy torpe. Tuve que tirar al final, de la línea de comandos:
mucho más sencillo.
</p>

<p>
Obviaré el paso de encender el ordenador y pulsar <code>&lt;ESC&gt;</code> para entrar
en el <i>prompt</i> de <code>grub</code>. Entiendo que a estas alturas todo el mundo
sabe dónde encontrar ese sistema.
</p>

<ol class="org-ol">
<li><p>
<b>Encontrar las unidades</b> desde las que puedes arrancar:
</p>

<pre class="example" id="org81e2141">
grub&gt; ls

(proc) (hd0) (hd0,gpt2) (hd0,gpt1) (cd0) (cd0,msdos2) (cd0,msdos1)
</pre>

<p>
Con ese comando, como se ve en el ejemplo, aparece una lista de
unidades y yo buscaba una que tuviera una partición MS-DOS(FAT). En
la lista me apareció una que decía <code>(cd0,msdos1)</code>. Supongo que
dependerá de en qué conector lo hayas enchufado y que variará de un
equipo a otro, ya digo que es la primera vez que lo hacía y seguía
unas instrucciones en inglés que no coincidían exactamente con el
listado de mi <code>grub</code>.
</p></li>

<li><p>
<b>Establecer la raíz</b>. Una vez identificado el <code>USB</code> lo estableces
como raíz del sistema:
</p>

<pre class="example" id="org709e30b">
grub&gt; set root=(cd0,msdos1)
</pre></li>

<li><p>
<b>Localizar el arranque</b>. Entre todos los archivos que tenga el
<i>USB</i> hay que localizar el que arranca el ordenador. El
<i>bootloader</i> es un fichero <code>.efi</code> y suele estar por algún
directorio llamado <i>boot</i>. El de <i>Tumbleweed</i> lo encontré en
<code>/EFI/BOOT/grubx64.efi</code>:
</p>

<pre class="example" id="org26bb3a7">
grub&gt; chainloader /EFI/BOOT/grubx64.efi
</pre>

<p>
Es posible, que en vuestro <i>pendrive</i> sea distinto.
</p></li>

<li><p>
<b>Arrancar el sistema</b>. Si ya está todo, lo que necesitamos es
arrancar el sistema:
</p>

<pre class="example" id="org2ac0a41">
grub&gt; boot
</pre></li>
</ol>

<p>
El resto es seguir las instrucciones de instalación del sistema
operativo.
</p>
</div>
</div>
<div id="outline-container-orgd5e84a1" class="outline-2">
<h2 id="orgd5e84a1">Entorno de trabajo</h2>
<div class="outline-text-2" id="text-orgd5e84a1">
<p>
Llevo tantos años economizando recursos que ahora, teniendo máquina de
sobra, me he puesto un entorno Plasma completo, sólo por darme el
gusto. No he abandonado <code>awesomewm</code>, que también lo he instalado, ni
<code>i3</code>, ni <code>openbox</code>. Los he instalado y configurado también. Como
también he instalado y configurado <code>rofi</code>, mi menú de lanzamiento de
aplicaciones y programas, asignándole teclas para llamarlo desde
Plasma. ¿Me he pasado a Plasma, entonces? En realidad: no.
</p>

<p>
Siempre he tenido instalado Plasma(KDE), lo que ocurre es que tampoco
podía darme muchas alegrías con la máquina que tenía y estaba
obligado, por necesidad, a utilizar sistemas gráficos más comedidos
con los recursos. Ahora voy sobrado de máquina y me estoy dando un
atracón de pijadas gráficas. Conociéndome, me durará un mes o dos y
volveré a <code>awesome</code> o a <code>i3</code>, pero no será por falta de recursos.
Incluso durante ese periodo volveré a ellos cuando necesite hacer algo
con <i>Blender</i> o con <code>Kdenlive</code>.
</p>

<p>
Para moverme de un entorno a otro con facilidad tengo las teclas más
habituales configuradas igual en todos: para abrir <i>Emacs</i>, para abrir
una consola, para llamar a <code>rofi</code> y lanzar alguna aplicación, para
cambiar de escritorio, etc.
</p>


<figure id="org4b36037">
<img src="./imagenes/Captura_recursos-sistema.png" alt="Captura_recursos-sistema.png">

</figure>
</div>
</div>
<div id="outline-container-org7aa01e9" class="outline-2">
<h2 id="org7aa01e9">Conclusión</h2>
<div class="outline-text-2" id="text-org7aa01e9">
<p>
De momento, estoy satisfecho con la compra. He hecho algunas pruebas
como sobrecargar de polígonos alguna figura en <i>Blender</i> para ver
hasta dónde llegaba o meterle al <a href="https://notxor.nueva-actitud.org/2020/12/06/camara.html">raytracer hecho con erlang</a> procesos
hasta aburrir. Comprobando que, efectivamente, puedo seguir
consumiendo toda la memoria del sistema, pero que el techo alcanzado
está muy por encima de lo esperado y las cifras marean (a un cerebro
acostumbrado a pensar en términos mucho más escuetos). De hecho, con
el <i>raytracer</i> he llegado a lanzar un proceso por pixel y no he
llegado a saturar la memoria porque acababan los primeros mucho antes
de necesitar espacio para cargar los siguientes. Aún así, un <i>render</i>
que tardaba varios minutos, lo ha realizado en segundos sin
despeinarse.
</p>

<p>
¿Resumen? <b>Más feliz que una perdiz</b>. Veremos lo que dura, porque
sabemos que todo es transitorio, sin embargo, no podré negar que la
primera impresión ha sido muy buena. Espero que me dure otros 12 años
como su antecesor. Quizá haya que hacerle en el futuro alguna
ampliación, cambiarle el disco o algo similar. De momento me permite
llevarlo a todas partes sin hacerse pesado y tiene un rendimiento
muy bueno, sin ser una máquina de gama <i>top</i> o <i>ultra</i>.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/slimbook/index.html">slimbook</a> <a href="/tags/opensuse/index.html">opensuse</a> <a href="/tags/tumbleweed/index.html">tumbleweed</a> <a href="/tags/grub/index.html">grub</a> ]]></description>
  <category><![CDATA[slimbook]]></category>
  <category><![CDATA[opensuse]]></category>
  <category><![CDATA[tumbleweed]]></category>
  <category><![CDATA[grub]]></category>
  <link>https://notxor.nueva-actitud.org/2022/02/24/nueva-maquina.html</link>
  <pubDate>Thu, 24 Feb 2022 08:51:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Trasteando con yasnippets]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-02-13</div>
<p>
Hace poco, por Mastodon, el amigo Giorgio habló de <code>yasnippets</code> y de
cómo le habían servido para ser <i>más productivo</i> en su trabajo... he
de confesaros que las uso poco, o casi nada, para ser sinceros. Con
<code>Python</code> las utilicé, porque <code>elpy</code> las usa, pero para el resto de
modos, normalmente, ni las tengo instaladas. No porque no sean útiles,
sino porque yo no suelo utilizarlas. Sin embargo, entiendo que cada
uno tiene sus costumbres y su flujo de trabajo y que, <code>yasnippet</code>,
puede ser muy útil a otra gente. Por esto, en este artículo contaré
cómo instalar y configurar el paquete y cómo crear nuestros propios
<code>snippets</code> para adecuarlo a nuestras necesidades. Incluso, quizá
hablándome de ello a mí mismo, termine por cogerle el gusto.
</p>

<p>
Como digo, utilicé <code>snippets</code> programando en <code>Python</code> con <i>Emacs</i>.
Con <code>elpy</code> los <code>snippets</code> vienen de serie... a todo ésto creo que
todos sabemos lo que es un <code>snippet</code> (al menos los que programan un
poco), pero es posible que haya quien no, o está de más tirar de la
definición en la <i>Wikipedia</i>:
</p>

<blockquote>
<p>
<b>Snippet</b> es un término del idioma inglés utilizado en programación
para referirse a pequeñas partes reusables de código fuente, código
máquina o texto. Comúnmente son definidas como unidades o métodos
funcionales que se pueden integrar fácilmente en módulos mucho más
grandes, aportando funcionalidad.
</p>

<p>
Wikipedia
</p>
</blockquote>

<p>
Por expresarlo más rápidamente o de forma más directa: son pequeñas
plantillas de código que nos ahorran tecleos. En <i>Emacs</i> la gestión de
estos bloques de código la podemos realizar con <code>yasnippet</code> (que
significa, según su página, <i>«Yet Another Snippet» extension for
Emacs</i>).
</p>

<p>
No utilizando <code>elpy</code> lo tenía muy abandonado, porque no lo suelo usar,
el funcionamiento es muy útil, especialmente para programar, aunque no
sólo para esa actividad: hay <code>snippets</code> que sirven para muchas otras
cosas. Por poner un ejemplo, si tenemos activos los <code>snippets</code> en
<code>org-mode</code> y queremos introducir una línea con la fecha pulso la
combinación <code>C-c &amp; C-s</code> (luego veremos cómo configurar las teclas).
</p>

<ul class="org-ul">
<li><p>
<b>Paso 1</b>: tecleo <code>C-c &amp; C-s</code>
</p>


<figure id="org2c4b565">
<img src="./imagenes/Captura-pantalla-fecha-paso-1.png" alt="Captura-pantalla-fecha-paso-1.png">

</figure></li>

<li><p>
<b>Paso 2</b>: tecleo <code>date &lt;RET&gt;</code>
</p>


<figure id="orgb3fdc4b">
<img src="./imagenes/Captura-pantalla-fecha-paso-2.png" alt="Captura-pantalla-fecha-paso-2.png">

</figure></li>

<li><p>
<b>Paso 3</b>: tecleo <code>2022 &lt;TAB&gt;</code>
</p>


<figure id="orgd37d293">
<img src="./imagenes/Captura-pantalla-fecha-paso-3.png" alt="Captura-pantalla-fecha-paso-3.png">

</figure></li>

<li><p>
<b>Paso 4</b>: tecleo <code>02 &lt;TAB&gt;</code>
</p>


<figure id="orgd636b0c">
<img src="./imagenes/Captura-pantalla-fecha-paso-4.png" alt="Captura-pantalla-fecha-paso-4.png">

</figure></li>

<li><p>
<b>Resultado</b>: tecleo <code>09 &lt;TAB&gt;</code>
</p>


<figure id="org8a3d315">
<img src="./imagenes/Captura-pantalla-fecha-fin.png" alt="Captura-pantalla-fecha-fin.png">

</figure></li>
</ul>

<p>
Vemos que los <code>snippets</code> no sólo introducen texto por nosotros sino
que también nos proporcionan <i>paradas de tabulador</i> que nos permiten
introducir opciones simplemente avanzando con el tabulador (y
retrocediendo con <code>S-&lt;TAB&gt;</code>).
</p>

<p>
Muy bonito, ¿ahora cómo hacemos para que nuestro <i>Emacs</i> haga estas
cosas?
</p>
<div id="outline-container-orgc9decd8" class="outline-2">
<h2 id="orgc9decd8">Instalación de los paquetes necesarios</h2>
<div class="outline-text-2" id="text-orgc9decd8">
<p>
En un principio, instalando el paquete <code>yasnippet</code> sería suficiente.
Sin embargo, recomiendo instalar algunos paquetes auxiliares que nos
facilitarán el uso de <code>snippets</code>:
</p>

<ul class="org-ul">
<li><code>yasnippet</code>, proporciona la funcionalidad principal.</li>
<li><code>yasnippet-snippets</code>, proporciona una larga lista de <i>snippets</i> para
multitud de modos y lenguajes de programación.</li>
<li><code>ivy-yassnipet</code>, proporciona integración de <code>yasnippet</code> con <code>ivy</code>.
También existe un paquete <code>helm-yasnippet</code>, si utilizas <code>helm</code> para
proporcionarte menús interactivos.</li>
</ul>

<p>
La instalación de los paquetes es la habitual. Por ejemplo, para el
principal de <code>yasnippet</code>:
</p>

<pre class="example" id="org2800292">
M-x package-install &lt;RET&gt; yasnippet
</pre>

<p>
Con eso ya tendríamos toda la funcionalidad de los <code>snippets</code>, pero no
adelantamos nada si no tenemos <i>plantillas</i> que utilizar. Tenemos que
crearlas, lo que puede ser un trabajo arduo y aburrido haciéndolo
desde cero. Para ahorrarnos ese tedioso trabajo, el paquete
<code>yasnippet-snippets</code> nos proporciona decenas (si no, cientos), de
plantillas ya preparadas y revisadas para multitud de modos. Incluso,
para aquellos que no utilizas, por lo que el paquete ocupará más
espacio en disco del estrictamente necesario, aunque no tanto como
para que te debas preocupar por ello.
</p>

<p>
En cualquier momento, podemos consultar qué <code>snippets</code> tenemos
disponibles según el modo en el que estemos con el comando
</p>

<pre class="example" id="org4465f59">
M-x yas-describe-tables
</pre>


<figure id="org0904ef5">
<img src="./imagenes/Captura-pantalla-tabla-snippets.png" alt="Captura-pantalla-tabla-snippets.png">

</figure>

<p>
No es necesario que nos aprendamos toda la tabla, pero si trabajamos
habitualmente con este sistema podemos aprendernos el <code>key</code> del
<code>snippet</code> y luego utilizar el comando <code>yas-expand</code> (que yo lo tengo
mapeado a la combinación <code>s-y</code>, luego explicaré cómo). Con eso sólo,
es decir, tecleando el <code>key</code> y una combinación de teclas nos expandirá
toda la plantilla. Nos podremos mover por los puntos de tabulador
pulsando <code>&lt;TAB&gt;</code> para ir hacia adelante y <code>&lt;S-TAB&gt;</code> para ir
hacia atrás, como ya vimos antes.
</p>

<p>
Ahora que tenemos instalado el modo, vamos a configurarlo un poco.
</p>
</div>
<div id="outline-container-org55c35cb" class="outline-3">
<h3 id="org55c35cb">Configuración de los <code>snippets</code></h3>
<div class="outline-text-3" id="text-org55c35cb">
<p>
El primer paso que hay que hacer es decidir si lo vas a utilizar
siempre. Es decir, si quieres que automáticamente se cargue esta
funcionalidad en tu <i>Emacs</i> cada vez que inicia. Esto enlentecerá el
arranque del editor porque revisará todos los <code>snippets</code> para tenerlos
a mano. Recuerda que <i>Emacs</i> no es el editor más rápido de arrancar.
O simplemente no quieres ocupar memoria con algo que no vas a
utilizar. Por ejemplo, en mi caso, sólo los suelo usar programando,
por lo que por defecto no los tengo activados.
</p>

<p>
En el manual del modo <code>yasnippet</code> recomiendan (cómo no) tenerlo
permanentemente activado. Su configuración es sencilla:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">yasnippet</span>)

(yas-global-mode t)
</pre>
</div>

<p>
En mi caso, como no lo quiero cargado continuamente lo he retocado un
poco y he acomodado las combinaciones de teclas a mi gusto. El retoque
del código de configuración se debe principalmente a que utilizo
<code>use-package</code>.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> yasnippet
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c x"</span>)   'ivy-yasnippet)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c y"</span>)   'yas-minor-mode)
(global-set-key (kbd <span style="color: #f1fa8c;">"s-y"</span>)     'yas-expand)
</pre>
</div>

<p>
Con esas tres teclas y otras tres que define el modo <code>yasnippet</code> en su
código, tenemos configurada casi toda la funcionalidad que se necesita.
</p>

<table>
<caption class="t-above"><span class="table-number">Table 1:</span> Resumen de combinaciones de teclas</caption>

<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Combinación</th>
<th scope="col" class="org-left">Comando</th>
<th scope="col" class="org-left">Significado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>C-c &amp; C-s</code></td>
<td class="org-left"><code>yas-insert-snippet</code></td>
<td class="org-left">Insertar un <code>snippet</code> por nombre</td>
</tr>

<tr>
<td class="org-left"><code>C-c &amp; C-v</code></td>
<td class="org-left"><code>yas-visit-snippet-file</code></td>
<td class="org-left">Editar un <code>snippet</code></td>
</tr>

<tr>
<td class="org-left"><code>C-c &amp; C-n</code></td>
<td class="org-left"><code>yas-new-snippet</code></td>
<td class="org-left">Crear un nuevo <code>snippet</code></td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left"><code>C-c y</code></td>
<td class="org-left"><code>yas-minor-mode</code></td>
<td class="org-left">Activar el modo</td>
</tr>

<tr>
<td class="org-left"><code>C-c x</code></td>
<td class="org-left"><code>ivy-yasnippet</code></td>
<td class="org-left">Abrir lista de <i>snippets</i> en <code>ivy</code></td>
</tr>

<tr>
<td class="org-left"><code>s-y</code></td>
<td class="org-left"><code>yas-expand</code></td>
<td class="org-left">Expandir un <i>snippet</i> por su clave</td>
</tr>
</tbody>
</table>


<p>
Explico un poco más detalladamente las tres últimas combinaciones, que
son las configuraciones de tecla que he añadido yo y las otras, que
son las propias del modo, las veremos en el siguiente epígrafe:
</p>

<ul class="org-ul">
<li><p>
<code>yas-minor-mode</code>: es la función para activar el modo menor de
<code>yasnippet</code> que nos permite utilizarlo. Lo activo con configuración
de teclas incluida porque al no abrirse universalmente, activarlo
sólo afecta al <i>buffer</i> donde lo activas. Para trabajar con <i>Python</i>
no hace falta, porque <code>elpy</code> lo activa automáticamente al abrir un
fichero <code>.py</code>. Si quieres activarlo siempre para un modo concreto
siempre puedes poner un <i>hook</i>. Por ejemplo, si quisiéramos que se
activara siempre que editamos un archivo <code>org</code> añadiríamos:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-hook 'org-mode-hook 'yas-minor-mode)
</pre>
</div></li>

<li><code>ivy-yasnippet</code>: nos muestra en <code>ivy</code> la lista de <code>snippets</code>
disponibles para el modo mayor del <i>buffer</i> desde el que la
llamamos. Cuando comenzamos a teclear un nombre, la lista filtra
aquellos nombres que coincidan con lo que vamos escribiendo. Si no
estamos seguros de cuál es el <code>snippet</code> que necesitamos podemos
recorrer la lista que muestra y el contenido del <code>snippet</code> nos lo va
mostrando en el punto del cursor en el <i>buffer</i>.</li>

<li><code>yas-expand</code>: lo que hace es expandir un <code>snippet</code> a partir de su
clave <code>key</code>. Cuando llevas un tiempo utilizando esta herramienta,
terminas, a fuerza de verlas, aprendiéndote esas claves. Sobre todo,
si es un <code>snippet</code> que utilizas con asiduidad, lo más rápido es
aprenderse la <code>key</code> y expandirla sin buscar por la lista. Además, en
este caso, he utilizado una combinación de tecla poco habitual.
Normalmente en <i>Emacs</i> se utilizan &lt;control&gt; (<code>C</code>) y &lt;meta&gt; (<code>M</code>),
con o sin &lt;shift&gt; (<code>S</code>), sin embargo utilizo &lt;super&gt; (<code>s</code>), la que
algunos llaman <i>tecla windows</i> y otros la tapamos con una pegatina
de un pingüino.</li>
</ul>

<p>
Estas funcionalidades son <i>comodidades</i>, si lo queréis llamar así,
porque en realidad, lo mínimo que necesitas para trabajar con
<code>snippets</code> es crearlos, modificarlos y llamarlos. Esa funcionalidad
básica la detallo en el siguiente punto poniendo un pequeño ejemplo de
creación de <code>snippet</code>.
</p>
</div>
</div>
</div>
<div id="outline-container-org4f12d46" class="outline-2">
<h2 id="org4f12d46">Crear nuestros <code>snippets</code></h2>
<div class="outline-text-2" id="text-org4f12d46">
<p>
Al activar el modo <code>yasnippet</code> por defecto nos activa tres
combinaciones de teclas para lanzar sus comandos principales.  Figuran
en la tabla del apartado anterior. Esos tres comandos son:
</p>

<ul class="org-ul">
<li>Crear un <code>snippet</code> (<code>C-c &amp; C-n</code>)</li>
<li>Editar un <code>snippet</code> que ya existe (<code>C-c &amp; C-v</code>)</li>
<li>Insertar en el <i>buffer</i> de edición un <code>snippet</code> (<code>C-c &amp; C-s</code>)</li>
</ul>

<p>
Por supuesto, si utilizas estas funciones de manera habitual, sería
buena idea cambiar la combinación de teclas por algo más sencillo y
rápido de teclear. En mi caso las he dejado así porque normalmente
utilizo la funcionalidad de <code>ivy-yasnippet</code> o la expansión directa de
la clave (las pocas que me sé).
</p>

<p>
Vamos a ver cómo es un <code>snippet</code> por dentro par hacernos una idea. Por
ejemplo, si tecleamos:
</p>

<p>
<code>C-c &amp; C-v current-date</code>
</p>

<p>
nos abrirá un <i>buffer</i> con el siguiente contenido
</p>

<div class="org-src-container">
<pre class="src src-snippet"><span style="color: #6272a4;"># -*- mode: snippet -*-</span>
<span style="color: #6272a4;"># name: current-date</span>
<span style="color: #6272a4;"># key: dd</span>
<span style="color: #6272a4;"># contributor : Kristof Molnar-Tatai <a href="mailto:kristof.mlnr%40gmail.com">&lt;kristof.mlnr@gmail.com&gt;</a></span>
<span style="color: #6272a4;"># --</span>
`(format-time-string <span style="color: #f1fa8c;">"%Y-%m-%d"</span>)`       
</pre>
</div>

<p>
De ese código podemos extraer alguna información interesante:
</p>

<ul class="org-ul">
<li>Los ficheros que guardan los <code>snippets</code> se suelen guardar sin
extensión, por eso se añade la primera línea de <code>mode</code> seguida de la
cabecera del mismo que está dividida en etiquetas o campos.</li>
<li>La cabecera se separa del texto del <code>snippet</code> mediante la línea
<code># --</code></li>
<li>Se pueden introducir <i>formas lisp</i> que devuelvan una cadena.</li>
</ul>

<p>
Para ilustrarlo mejor, vamos a crear un nuevo <code>snippet</code>. Imagina que
tienes que hacer muchos informes psicológicos, como puede ser mi caso,
sobre los <i>tests</i> que van haciendo los clientes y el encabezado de
todos ellos es muy similar o repetitivo, por lo que decides crear una
plantilla de encabezado para incrustarla cuando escribes tus informes
con <i>Emacs</i>.
</p>

<p>
Al pulsar <code>C-c &amp; C-n</code> nos abrirá un <i>buffer</i> con el siguiente
contenido:
</p>

<div class="org-src-container">
<pre class="src src-snippet"><span style="color: #6272a4;"># -*- mode: snippet -*-</span>
<span style="color: #6272a4;"># name:</span>
<span style="color: #6272a4;"># key:</span>
<span style="color: #6272a4;"># --</span>
</pre>
</div>

<p>
El cursor aparece en la línea <code># name:</code>. Atentos, porque lo que hace
es crear un <i>buffer</i> y añadir un <code>snippet</code> con la estructura del
mismo. Lo único que tenemos que hacer es rellenar los datos y avanzar
pulsando <code>&lt;TAB&gt;</code>.
</p>

<p>
Para no liarme mucho más con las explicaciones muestro el contenido
final y luego lo explicamos:
</p>

<div class="org-src-container">
<pre class="src src-snippet"><span style="color: #6272a4;"># -*- mode: snippet -*-</span>
<span style="color: #6272a4;"># name: informe-cabecera</span>
<span style="color: #6272a4;"># key: inf-cab</span>
<span style="color: #6272a4;"># --</span>
INFORME que realiza /D. Fulanito de Tal/ con D.N.I. n&#186; 123456789Z
sobre los resultados obtenidos en la prueba <span style="color: #ff79c6; font-weight: bold;">${</span><span style="color: #ffb86c; background-color: #373844;">1</span><span style="color: #ff79c6; font-weight: bold;">:</span>test psicol&#243;gico<span style="color: #ff79c6; font-weight: bold;">}</span>
por D/&#241;a. <span style="color: #ff79c6; font-weight: bold;">${</span><span style="color: #ffb86c; background-color: #373844;">2</span><span style="color: #ff79c6; font-weight: bold;">:</span>Menganito de Cual<span style="color: #ff79c6; font-weight: bold;">}</span>, con D.N.I. n&#186; <span style="color: #ff79c6; font-weight: bold;">${</span><span style="color: #ffb86c; background-color: #373844;">3</span><span style="color: #ff79c6; font-weight: bold;">:</span>987654321A<span style="color: #ff79c6; font-weight: bold;">}</span>, a
petici&#243;n del interesado.
</pre>
</div>

<p>
El texto es lo de menos, puede ser cualquier otro, lo importante es
que nos fijemos dónde lo guarda <code>yasnippet</code>. Por defecto, al hacerlo
nos sugerirá un directorio llamado:
</p>

<pre class="example" id="org0792e05">
~/.emacs.d/snippets/[nombre-del-modo]
</pre>

<p>
En el caso anterior, lo queremos para hacer es tener un <code>snipper</code> para
insertar una cabecera. En la mayoría de los casos lo único que
cambiará será el <i>test</i> que se pasó y los datos, el nombre y el DNI,
del cliente:
</p>

<ul class="org-ul">
<li><code>${1:test psicológico}</code></li>
<li><code>${2:Menganito de Cual}</code></li>
<li><code>${3:987654321A}</code></li>
</ul>

<p>
Como se puede apreciar, las paradas de tabulador se denotan por
<code>${...}</code>. En este caso se han tenido en cuenta textos por defecto,
pero los campos podrían haber sido, por ejemplo <code>${1:}</code>. No hay
necesidad de incluir ese texto, con los números es suficiente para
establecer las paradas, pero puede venir muy bien cuando además hay
algún contenido frecuente, para ahorrar aún más tecleos.
</p>

<p>
Por último, si ya tenemos nuestro <code>snippet</code> creado y lo que queremos
es cambiar o corregir algún aspecto de él, utilizaremos la combinación
<code>C-c &amp; C-v</code> o utilizaremos el comando <code>M-x yas-visit-snippet-file</code>
para modificarlo.
</p>
</div>
</div>
<div id="outline-container-org4513299" class="outline-2">
<h2 id="org4513299">Conclusiones</h2>
<div class="outline-text-2" id="text-org4513299">
<p>
Esta es una entrada cortita, porque esta herramienta es muy sencilla
de utilizar, pero con una gran utilidad, especialmente para
programación. Nos ahorrará bastante trabajo de escritura repetitiva,
aparte de evitar errores tontos como meter «;» donde corresponde «:»
en una expresión y que el programa <i>tarde un poco más en compilar</i>,
dándonos de cabezazos hasta descubrir el sutil error de tecleo.
</p>

<p>
Para otros menesteres nos viene bien para introducir algunos tipos de
información repetitiva en textos. No lo suelo utilizar en <code>org-mode</code>,
pero sí me es muy útil en <code>html</code> para no olvidarme de cerrar ninguna
etiqueta. Cada uno decidirá cómo puede adecuar la herramienta a su
modo de trabajar, cuándo le es útil y cuando no.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/yasnippets/index.html">yasnippets</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[yasnippets]]></category>
  <link>https://notxor.nueva-actitud.org/2022/02/13/trasteando-con-yasnippets.html</link>
  <pubDate>Sun, 13 Feb 2022 15:45:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Programa #4]]></title>
  <description><![CDATA[
<div class="post-author">PICA</div>
<div class="post-date">2022-01-26</div>
<p>
Cuarto programa de «PICA, la actualidad» en el que hablamos sobre
suicidio, principalmente, pero también sobre otros temas.
</p>
<div id="outline-container-org134d6ae" class="outline-2">
<h2 id="org134d6ae">Contenido</h2>
<div class="outline-text-2" id="text-org134d6ae">
<p>
Se puede acceder a los contenidos escritos en: 
</p>
<a href="https://asociacionpica.org/radio/#GuionP04" target="_blank">Contenidos del cuarto programa</a>
</div>
</div>
<div id="outline-container-orgb1e4b37" class="outline-2">
<h2 id="orgb1e4b37">Audio</h2>
<div class="outline-text-2" id="text-orgb1e4b37">
<audio controls="controls" width="95%" id="orgfc14f3d">
<source src="https://ia801407.us.archive.org/0/items/pica-la-actualidad-4_202201/pica-la-actualidad-4.mp3">
<p>
Tu navegador no soporta la etiqueta de audio.
</p>
</audio>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/radio/index.html">radio</a> ]]></description>
  <category><![CDATA[radio]]></category>
  <link>https://notxor.nueva-actitud.org/2022/01/26/programa-4.html</link>
  <pubDate>Wed, 26 Jan 2022 20:36:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Programa #3]]></title>
  <description><![CDATA[
<div class="post-author">PICA</div>
<div class="post-date">2022-01-19</div>
<p>
Tercer programa de «PICA, la actualidad» donde se trata el tema de la
salud mental en la infancia durante la pandemia.
</p>
<div id="outline-container-orgd55da23" class="outline-2">
<h2 id="orgd55da23">Contenido</h2>
<div class="outline-text-2" id="text-orgd55da23">
<p>
Se puede acceder a los contenidos escritos en: 
</p>
<a href="https://asociacionpica.org/radio/#GuionP03" target="_blank">Contenidos del tercer programa</a>
</div>
</div>
<div id="outline-container-orga6f83dc" class="outline-2">
<h2 id="orga6f83dc">Audio</h2>
<div class="outline-text-2" id="text-orga6f83dc">
<audio controls="controls" width="95%" id="org79f83e1">
<source src="https://ia601404.us.archive.org/32/items/pica-la-actualidad-3/pica-la-actualidad-3.mp3">
<p>
Tu navegador no soporta la etiqueta de audio.
</p>
</audio>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/radio/index.html">radio</a> ]]></description>
  <category><![CDATA[radio]]></category>
  <link>https://notxor.nueva-actitud.org/2022/01/19/programa-3.html</link>
  <pubDate>Wed, 19 Jan 2022 20:36:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Programa #2]]></title>
  <description><![CDATA[
<div class="post-author">PICA</div>
<div class="post-date">2022-01-12</div>
<p>
Segundo programa de «PICA, la actualidad» donde hablamos sobre la
encuesta ETUDES del Plan Nacional de Drogas español, realizado a
escolares de edades comprendidas entre los 14 y los 18 años sobre los
hábitos de consumo de sustancias psicotrópicas.
</p>
<div id="outline-container-orgdb469c9" class="outline-2">
<h2 id="orgdb469c9">Contenido</h2>
<div class="outline-text-2" id="text-orgdb469c9">
<p>
Se puede acceder a los contenidos escritos en: 
</p>
<a href="https://asociacionpica.org/radio/#GuionP02" target="_blank">Contenidos del segundo programa</a>
</div>
</div>
<div id="outline-container-orge1ed19d" class="outline-2">
<h2 id="orge1ed19d">Audio</h2>
<div class="outline-text-2" id="text-orge1ed19d">
<audio controls="controls" width="95%" id="orgd77a05f">
<source src="https://ia801406.us.archive.org/17/items/pica-la-actualidad-02/%20pica-la-actualidad-02.mp3">
<p>
Tu navegador no soporta la etiqueta de audio.
</p>
</audio>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/radio/index.html">radio</a> ]]></description>
  <category><![CDATA[radio]]></category>
  <link>https://notxor.nueva-actitud.org/2022/01/12/programa-2.html</link>
  <pubDate>Wed, 12 Jan 2022 20:36:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Preparando Emacs para trabajar con Clojure]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2022-01-08</div>
<p>
Entre los propósitos del nuevo año está el aprender <i>Clojure</i>, incluso
tengo pensado un proyecto en el que emplearlo para aprender. Si las
cosas van bien, y no me falta tiempo, os lo iré poniendo por aquí para
enseñar <i>mis vergüenzas</i> como corresponde. Al empezar con el tema de
la programación con ese lenguaje, como con cualquier otro, lo primero
que he tenido que hacer es configurar mi editor favorito para ello. En
este artículo hablaré de los paquetes que he instalado y la
configuración que he hecho, todo muy sencillo. Hablaré un poco sobre:
<code>clojure-lsp</code>, <code>cider</code> y los primeros pasos con ellos.
</p>

<p>
<code>clojure-lsp</code> sólo es necesario si utilizas el modo <code>lsp</code> de <i>Emacs</i>,
si no quieres utilizarlo, con <code>cider</code> es suficiente para convertir tu
<i>Emacs</i> en un IDE para <i>Clojure</i>. Voy a hablar de las dos
posibilidades pero empezaré por la básica.
</p>
<div id="outline-container-org721130b" class="outline-2">
<h2 id="org721130b"><code>cider</code></h2>
<div class="outline-text-2" id="text-org721130b">
<p>
El primer paquete que encontré relacionado con <i>Clojure</i> fue <code>cider</code>.
La instalación no puede ser más sencilla:
</p>

<p>
<code>M-x package-install RET cider RET</code>
</p>

<p>
Este paquete proporciona un modo menor de <i>Emacs</i> que nos permite la
programación interactiva, como hacemos en <code>emacs-lisp</code>, o en <code>commond
lisp</code> con <code>SLIME</code>, o en <code>scheme</code> con <code>Geiser</code>, o en <i>Smalltalk</i>. Es
por tanto, un complemento a <code>clojure-mode</code> y le dota de interacción
con una consola <code>REPL</code> de <i>Clojure</i> donde poder probar nuestro código,
lanzar nuestra aplicación o depurarla. No se limita a establecer una
conexión a una consola y ya, sino que proporciona unas características
adicionales que nos dulcifica el trabajo con ella:
</p>

<ul class="org-ul">
<li>Autocompletado</li>
<li>Integración de tests</li>
<li>Mensajes de error más claros</li>
<li>Acceso a documentación</li>
<li>Depurador interactivo</li>
</ul>

<p>
Con este modo y el <code>clojure-mode</code> es suficiente para convertir <i>Emacs</i>
en un <code>IDE</code> para <i>Clojure</i>.
</p>


<figure id="org244c388">
<img src="./imagenes/Captura-emacs-cider.png" alt="Captura-emacs-cider.png">

</figure>

<p>
Se puede apreciar en la imagen anterior cómo funciona: abres un
<i>buffer</i> de cualquier archivo <i>Clojure</i> y pulsando <code>C-c C-x j j</code> se
lanza una consola interactiva. Se integra con <code>projectile</code> y si
detecta que el fichero editado pertenece a un proyecto lo carga en la
consola completo. Si pulsamos <code>,</code> nos aparecerá la lista de comandos
en <code>ivy</code>.
</p>


<figure id="org9df6b00">
<img src="./imagenes/Captura-emacs-cider-ivy.png" alt="Captura-emacs-cider-ivy.png">

</figure>

<p>
Además podemos evaluar cualquier código directamente. Por ejemplo, en
un fichero de código he añadido la forma:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(println "El número es" (+ 1 2 3))
</pre>
</div>

<p>
Tras pulsar la combinación de teclas <code>C-c C-e</code> estando el cursor al
final de esa línea el resultado aparecerá en el <i>buffer</i> <code>cider</code>, algo
parecido a cuando lo hacemos en un <i>buffer</i> <code>scratch</code> de <i>Emacs</i>, o
cuando lo hacemos en <code>SLIME</code> o en <code>Geiser</code>.
</p>


<figure id="orgbfc0f75">
<img src="./imagenes/Captura-cider-evaluacion-codigo.png" alt="Captura-cider-evaluacion-codigo.png">

</figure>

<p>
Si estás acostumbrado a trabajar con <code>lisp</code> o <code>scheme</code> en <i>Emacs</i>, la
integración es tan similar que no necesitas adaptarte, más allá de las
idiosincrasias sintácticas de <i>Clojure</i>, se entiende.
</p>

<p>
La cantidad de opciones y características que trae <code>cider</code> es tan
amplia que se sale del espacio de un artículo. En <a href="https://cider.mx/">su página web</a> podéis
encontrar toda la información necesaria. Me ha parecido muy
interesante el que traiga de fábrica un depurador. He mirado por
encima cómo funciona y la sorpresa ha sido que funciona exactamente
igual que el depurador que <code>emacs-lisp</code> trae de fábrica... otra
funcionalidad que <i>me suena</i> y no debo aprender de cero.
</p>

<p>
En resumen: podemos lanzar una consola cargada con el proyecto que
tengamos entre manos. Igual que la lanzamos la podemos parar. Podemos
evaluar código de forma interactiva, no sólo ejecutar nuestro proyecto
y ya. Además también nos permite depurar el código interactivamente.
Si no es suficiente, también nos permite acceder a la documentación
del lenguaje sobre la marcha. En fin, todo lo que se le puede pedir a
una herramienta de desarrollo específica, pero con la integración en
<i>Emacs</i> con todas las facilidades que da para la edición de código.
</p>

<p>
Si necesitas algo más, te lo proporcionará <code>lsp-mode</code>, pero con un
gasto extra de memoria y ciclos de proceso.
</p>
</div>
</div>
<div id="outline-container-orgda2e1fe" class="outline-2">
<h2 id="orgda2e1fe"><code>lsp-mode</code></h2>
<div class="outline-text-2" id="text-orgda2e1fe">
<p>
<a href="https://notxor.nueva-actitud.org/2021/03/11/emacs-y-lsp-mode.html">Ya hablé de <code>lsp-mode</code>,</a> así que sólo añadiré algún detalle a lo que ya
conté en la otra ocasión. Como sabéis, <code>lsp</code> necesita para funcionar
un servidor de lenguaje externo, que suele estar hecho en el mismo
lenguaje que quieres trabajar, pues cada lenguaje suele requerir el
suyo específico. Para <i>Clojure</i> no hay excepción y debemos instalar el
suyo. Para no enmarañar más con detalles, sólo vamos a trabajar dos
cosas:
</p>

<ul class="org-ul">
<li>Instalación de <code>clojure-lsp</code> (el servidor de lenguaje de <i>Clojure</i>)</li>
<li>Configuración de <i>Emacs</i> para activar <code>lsp-mode</code>. (Aunque lo haremos
de dos maneras diferentes para que no dependa de instalaciones)</li>
</ul>
</div>
<div id="outline-container-org06c167c" class="outline-3">
<h3 id="org06c167c">Servidor <code>clojure-lsp</code></h3>
<div class="outline-text-3" id="text-org06c167c">
<p>
Como he dicho antes, este servidor es necesario para que funcione el
modo <code>lsp</code> con <i>Clojure</i>. Es una herramienta externa y, en mi caso, he
descargado el <a href="https://github.com/clojure-lsp/clojure-lsp">código de su repositorio</a> para instalarlo. No estaría de
más consultar toda la información <a href="https://clojure-lsp.io/">en su página web</a>.
</p>

<p>
Descarga del código e instalación del servidor:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #8be9fd; font-style: italic;">cd</span> ~/proyectos
git clone https://github.com/clojure-lsp/clojure-lsp.git
<span style="color: #8be9fd; font-style: italic;">cd</span> clojure-lsp
./install --dir /home/notxor/opt/bin/
</pre>
</div>

<p>
Los cuatro pasos los he puesto juntos en una especie de <i>script</i>. En
realidad me llevó algo más de tiempo: buscarlo en <i>Internet</i>, mirar la
documentación y explicaciones de cómo instalarlo y decidir, una vez
descargado, dónde instalarlo, etc. Así que, te recomiendo, si estás
leyendo ésto, que en lugar de copiar el código anterior a ciegas,
teniéndolo como guía. deberías consultar también las opciones para
ajustarlo a tus necesidades. Pero como resumen, esas cuatro líneas,
esos cuatro pasos son suficientes.
</p>

<p>
Si todo ha ido bien, tras unos instantes de espera, mientras se
descarga el código, se compila y se instala ya tendremos nuestro
servidor funcional. Sólo hay que tener en cuenta, que lo he instalado
en un directorio <i>local</i> para mi usuario. Para que funcione, tengo que
decirle a <i>Emacs</i> dónde está y cómo lanzarlo para que lo arranque
cuando sea necesario.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> lsp-clojure-custom-server-command
      '(<span style="color: #f1fa8c;">"bash"</span> <span style="color: #f1fa8c;">"-c"</span> <span style="color: #f1fa8c;">"/home/notxor/opt/bin/clojure-lsp"</span>))
</pre>
</div>

<p>
Esto es importante, porque si no el modo <code>lsp</code> lanzará un error que
dice que no encuentra el servidor y no puede conectarse al mismo.
Para comprobar que está funcionando, podemos solicitar la lista de
procesos de <i>Emacs</i> con <code>M-x list-processes</code>.
</p>


<figure id="org3724065">
<img src="./imagenes/Captura-emacs-procesos.png" alt="Captura-emacs-procesos.png">

</figure>

<p>
En la imagen, entre los procesos con <code>PID</code> que son los externos
utilizados por <i>Emacs</i>, nos aparecerá <code>clojure-lsp</code> y también la
conexión del editor. Podemos comprobar que efectivamente, el comando
que lanza nuestro servidor es el que le proporcionamos en la variable
anterior.
</p>

<p>
Es un servidor un poco pesado para máquinas de pocos recursos. Está
hecho en <i>Clojure</i> y su ejecución necesita también cargar la máquina
virtual de <i>java</i>. Es recomendable eliminarlo si no lo estamos
usando. Recuerda cuando cierres <i>Emacs</i> que, según como cierres o si
estás utilizando <code>emacsclient</code>, que el servidor puede permanecer
funcionando esperando conexiones. Si no lo vas a usar más, es
recomendable matar el proceso.
</p>

<p>
Para configurarlo, pongo dos versiones. Desde <i>vanilla</i> se necesitarán
sólo algunos <i>hooks</i> para iniciar el proceso para los modos
necesarios. En este caso para los modos de <code>clojure</code>, <code>clojurescript</code>
y <code>clojurec</code>. Y también el comando que lanza el servidor que vimos
antes. Debería quedar algo así:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-hook 'clojure-mode-hook 'lsp)
(add-hook 'clojurescript-mode-hook 'lsp)
(add-hook 'clojurec-mode-hook 'lsp)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> lsp-clojure-custom-server-command
      '(<span style="color: #f1fa8c;">"bash"</span> <span style="color: #f1fa8c;">"-c"</span> <span style="color: #f1fa8c;">"/home/notxor/opt/bin/clojure-lsp"</span>))
</pre>
</div>

<p>
Si estamos utilizando, como en mi caso, <code>use-package</code>, la
configuración es distinta. En otras distribuciones
de <i>Emacs</i> como <code>doom-emacs</code>, por ejemplo, vienen por defecto
configuradas con <code>use-package</code>. Yo utilizo <i>GNU Emacs</i>, pero entiendo
que sería igual para esos otros entornos:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Configuraci&#243;n de lsp-mode
</span>(<span style="color: #ff79c6; font-weight: bold;">use-package</span> lsp-mode
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t
  <span style="color: #8be9fd; font-style: italic;">:init</span>
  (add-hook 'clojure-mode-hook #'lsp)
  (add-hook 'clojurescript-mode-hook #'lsp)
  (add-hook 'clojurec-mode-hook #'lsp)
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> lsp-clojure-custom-server-command
        '(<span style="color: #f1fa8c;">"bash"</span> <span style="color: #f1fa8c;">"-c"</span> <span style="color: #f1fa8c;">"/home/notxor/opt/bin/clojure-lsp"</span>))
  (add-hook 'python-mode-hook #'lsp)
  (add-hook 'c++-mode-hook #'lsp))  
</pre>
</div>

<p>
Ese bloque de código lo he copiado directamente de mi <code>init.el</code>. He
dejado al final los ganchos para otros lenguajes de programación con
los que utilizo <code>lsp-mode</code>, sólo para remarcar, que cada modo
necesitará su gancho, para conectarse a <code>lsp-mode</code>.
</p>
</div>
</div>
</div>
<div id="outline-container-orgd6c671a" class="outline-2">
<h2 id="orgd6c671a">Conclusión</h2>
<div class="outline-text-2" id="text-orgd6c671a">
<p>
Pues no hay mucho que concluir, de momento no he avanzado mucho más
allá. De momento no he pasado de crear un incipiente proyecto de
pruebas con la herramienta <code>lain</code>, para comprobar que toda la
maquinaria funciona. Entiendo que este tipo de herramientas tienen sus
ventajas, pero te obliga a aprender una herramienta <i>externa</i> al
lenguaje y distinta para cada uno de ellos. La estructura de proyecto
que genera puede ser aceptable, o incluso óptima para el mayor número
de casos, pero te acostumbra a un esquema de pensamiento uniforme y te
dificulta <i>salirte del redil</i> cuando sea necesario. No sé, habría que
investigarlo más y no es el tema del artículo, ya siento la
<i>disgresión</i> de pensamiento.
</p>

<p>
Si me tropiezo con algo interesante que contar sobre el tema ya lo iré
escribiendo. Con interesante me refiero, no sólo a cosas nuevas y
<i>frikis</i> de esas que me gustan, sino también a esas más «sórdidas» que
provocan las dificultades que se encuentran por el camino y cómo las
superamos.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/clojure/index.html">clojure</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[clojure]]></category>
  <link>https://notxor.nueva-actitud.org/2022/01/08/preparando-emacs-para-trabajar-con-clojure.html</link>
  <pubDate>Sat, 08 Jan 2022 23:14:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Programa #1]]></title>
  <description><![CDATA[
<div class="post-author">PICA</div>
<div class="post-date">2022-01-05</div>
<p>
Este es el primer programa de «PICA, la actualidad». Coincidiendo con
la tarde de Reyes, el 5 de enero.
</p>
<div id="outline-container-org4d38d51" class="outline-2">
<h2 id="org4d38d51">Contenido</h2>
<div class="outline-text-2" id="text-org4d38d51">
<p>
Se puede acceder a los contenidos escritos en: 
</p>
<a href="https://asociacionpica.org/radio/#GuionP01" target="_blank">https://asociacionpica.org/radio/#GuionP01</a>
</div>
</div>
<div id="outline-container-orgb6c9648" class="outline-2">
<h2 id="orgb6c9648">Audio</h2>
<div class="outline-text-2" id="text-orgb6c9648">
<audio controls="controls" width="95%" id="orgc236be5">
<source src="https://ia601406.us.archive.org/27/items/pica-actualidad-1/pica-actualidad-1.mp3">
<p>
Tu navegador no soporta la etiqueta de audio.
</p>
</audio>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/radio/index.html">radio</a> ]]></description>
  <category><![CDATA[radio]]></category>
  <link>https://notxor.nueva-actitud.org/2022/01/05/programa-1.html</link>
  <pubDate>Wed, 05 Jan 2022 20:36:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[EditorConfig y Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-12-30</div>
<p>
Una de las cosas que suele extrañar a los nuevos usuarios de <i>Emacs</i>
es su manera de realizar las indentaciones. Muchas veces puede ser
percibido como un problema y es que, en la mayoría de los casos,
dependen del <i>modo</i> de edición y no hay un comando estándar que
permita realizarlas. En la mayoría de los casos, eso se debe a que
quien programa el modo ajusta la indentación a las recomendaciones,
costumbres y convenios de estilo más aceptados para cada lenguaje.  No
es muy intuitivo para el usuario primerizo y para algunos puede ser un
problema. Aunque, en general no lo es, hay ocasiones en que uno,
participando en un grupo de trabajo se encuentra con <i>políticas</i>
específicas para el código y ajustar el comportamiento de <i>Emacs</i>
puede ser un dolor de cabeza para el usuario novel. En este artículo
hablaré de cómo hacerlo de manera muy sencilla.
</p>

<p>
La respuesta corta es: <i>Descarga <code>editorconfig-mode</code> y configúralo</i>.
La respuesta larga será el resto del artículo, donde contaré cómo
instalarlo, configurarlo y utilizarlo.
</p>
<div id="outline-container-org2054ab7" class="outline-2">
<h2 id="org2054ab7">¿Qué es <i>EditorConfig</i>?</h2>
<div class="outline-text-2" id="text-org2054ab7">
<p>
El <a href="https://editorconfig.org/">proyecto EditorConfig</a> es un proyecto que intenta crear un estándar
para ayuda a mantener de forma consistente el estilo de código, bien
sea entre distintos desarrolladores o bien sea entre distintos
editores de código.
</p>

<p>
La configuración se carga en un fichero de nombre <code>.editorconfig</code> que
puede dividirse en varios directorios o utilizar uno para cada
proyecto. El editor lo buscará en el directorio actual y realizará una
búsqueda en el <code>path</code> hasta llegar al archivo <code>.editorconfig</code> que esté
marcado con la propiedad <code>root = true</code>. Si es un estándar ¿Qué
editores lo soportan?
</p>

<ul class="org-ul">
<li>De manera <b>nativa</b>: BBEdit, CodeCrusader, CodeLite, elementaryCode,
Builder, Gitea, GitHub, GitLab, GitBucket, Gogs, IntelliJidea,
jdTextEdit, Kate, KTextEditor, Komodo, Kakoune, MonoDevelop, Nova,
PyCharm, ReSharper, Rider, RubyMine, Sourcehut, SourceLair,
TortoiseGit, VisualStudio (no la versión <i>Code</i>, que necesita
<i>plugin</i>), WorkingCopy</li>
<li>Con <b><i>plugin</i></b>:, AppCode, Atom, Brackets, C Lion, Coda,
Code::Blocks, Eclipse, Emacs, FarManager, Geany, Gedit, jEdit,
Lazarus, Micro, NetBeans, Notepad++, Pluma, PhpStorm, Sublime Text,
Textadept, textmate, Vim, VSCodium, VisualStudio Code</li>
</ul>

<p>
La lista puede ser más larga, pero aquí están los principales editores
de código. Si estás utilizando alguno que no se encuentre en ella,
debes buscar en la documentación de tu editor si soporta el estándar
<i>EditorConfig</i>, si lo hace de forma nativa o mediante <i>plugin</i> y cómo
puedes instalarlo y configurarlo. Yo me voy a centrar en configurarlo
en <i>Emacs</i>, que es mi editor principal.
</p>
</div>
<div id="outline-container-org5cefb9f" class="outline-3">
<h3 id="org5cefb9f">Configuración</h3>
<div class="outline-text-3" id="text-org5cefb9f">
<p>
Antes de nada, pondré el código del fichero que estoy utilizando yo
para que sirva de guía o de base para que cada uno se haga el suyo:
</p>

<div class="org-src-container">
<pre class="src src-conf"><span style="color: #6272a4;"># </span><span style="color: #6272a4;">El principal .editorconfig
</span><span style="color: #f8f8f2; font-weight: bold;">root</span> = true

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">Fin de linea estilo UNIX, acabar con un salto de l&#237;nea
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">y elimitar espacios al final de la l&#237;nea
</span>[<span style="color: #8be9fd; font-style: italic;">*</span>]
<span style="color: #f8f8f2; font-weight: bold;">end_of_line</span> = lf
<span style="color: #f8f8f2; font-weight: bold;">insert_final_newline</span> = true
<span style="color: #f8f8f2; font-weight: bold;">trim_trailing_whitespace</span> = true

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">Especificar el `charset` para javascript, python y erlang
</span>[<span style="color: #8be9fd; font-style: italic;">*.{js,py,erl}</span>]
<span style="color: #f8f8f2; font-weight: bold;">charset</span> = utf-8

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">Para python: indentaci&#243;n de cuatro espacios en blanco
</span>[<span style="color: #8be9fd; font-style: italic;">*.py</span>]
<span style="color: #f8f8f2; font-weight: bold;">indent_style</span> = space
<span style="color: #f8f8f2; font-weight: bold;">indent_size</span> = 4

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">Makefile necesita tabuladores para funcionar
</span>[<span style="color: #8be9fd; font-style: italic;">Makefile</span>]
<span style="color: #f8f8f2; font-weight: bold;">indent_style</span> = tab
<span style="color: #f8f8f2; font-weight: bold;">tab_width</span> = 8

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">Para javascript: indentaci&#243;n de dos espacios en blanco
</span>[<span style="color: #8be9fd; font-style: italic;">*.js</span>]
<span style="color: #f8f8f2; font-weight: bold;">indent_style</span> = space
<span style="color: #f8f8f2; font-weight: bold;">indent_size</span> = 2

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">Indentaci&#243;n para erlang: cuatro espacios en blanco
</span>[<span style="color: #8be9fd; font-style: italic;">*.{erl,hrl,app}</span>]
<span style="color: #f8f8f2; font-weight: bold;">indent_style</span> = space
<span style="color: #f8f8f2; font-weight: bold;">indent_size</span> = 4

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">Indentaci&#243;n para C/C++: cuatro espacios en blanco
</span>[<span style="color: #8be9fd; font-style: italic;">*.{c,cc,cpp,h,hpp}</span>]
<span style="color: #f8f8f2; font-weight: bold;">indent_style</span> = space
<span style="color: #f8f8f2; font-weight: bold;">indent_size</span> = 4

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">Indentaci&#243;n para R: dos espacios en blanco
</span>[<span style="color: #8be9fd; font-style: italic;">*.R</span>]
<span style="color: #f8f8f2; font-weight: bold;">indent_style</span> = space
<span style="color: #f8f8f2; font-weight: bold;">indent_size</span> = 2
</pre>
</div>

<p>
Utiliza un formato muy parecido a los ficheros de configuración
habituales y no creo que se necesite explicar mucho más. Cada bloque
consiste en una cabecera delimitada por caracteres <code>[...]</code> y tras ella
las propiedades que se aplicarán a los ficheros que coincidan con la
misma. Para dichas cabeceras se utilizan una serie de caracteres que
nos permiten establecer expresiones de manera muy similar a como lo
hacen las <i>expresiones regulares</i>, pero bastante más simplificado.
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Carácter</th>
<th scope="col" class="org-left">Descripción</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>*</code></td>
<td class="org-left">Cualquier cadena que no contenga <code>/</code></td>
</tr>

<tr>
<td class="org-left"><code>**</code></td>
<td class="org-left">Cualquier cadena</td>
</tr>

<tr>
<td class="org-left"><code>?</code></td>
<td class="org-left">Cualquier caracteres</td>
</tr>

<tr>
<td class="org-left"><code>[nombre]</code></td>
<td class="org-left">Coincidencia carácter a carácter</td>
</tr>

<tr>
<td class="org-left"><code>[!nombre]</code></td>
<td class="org-left">Que no coincida con <i>nombre</i></td>
</tr>

<tr>
<td class="org-left"><code>{c1,c2,c3}</code></td>
<td class="org-left">Coincidencia con cualquiera de las cadenas</td>
</tr>

<tr>
<td class="org-left"><code>{num1..num2}</code></td>
<td class="org-left">Con cualquier entero entre <code>num1</code> y <code>num2</code></td>
</tr>
</tbody>
</table>

<p>
Los caracteres especiales se pueden introducir <i>escapándolos</i> con
<i>backslash</i>, como por ejemplo <code>\[</code>.
</p>

<p>
La lista de propiedades no es muy larga:
</p>

<dl class="org-dl">
<dt><code>indent_style</code></dt><dd>Especifica si queremos que utilice <i>tabulador</i> con
<code>tab</code> o espacios en blanco con <code>space</code>.</dd>
<dt><code>indent_size</code></dt><dd>La cantidad de columnas de ancho que tendrá cada
nivel de indentación, cuando se utilizan espacios en blanco.</dd>
<dt><code>tab_width</code></dt><dd>Ancho del carácter tabulador. Normalmente no se
necesita, pues utiliza como valor por defecto el <code>indent_size</code>.</dd>
<dt><code>end_of_line</code></dt><dd>establece el tipo de final de línea y admite los
valores <code>lf</code> (tipo UNIX), <code>cr</code> (tipo Mac) o <code>crlf</code> (tipo Windows).</dd>
<dt><code>charset</code></dt><dd>establece el tipo de código que se utilizará. Los
valores admitidos son: <code>latin1</code>, <code>utf-8</code>, <code>utf-8-bom</code>, <code>utf-16be</code> o
<code>utf-16le</code>.</dd>
<dt><code>trim_trailing_whitespace</code></dt><dd>Si lo establecemos a <code>true</code> elimina
cualquier espacio en blanco al final de las líneas y puesto a
<code>false</code> para que no lo haga.</dd>
<dt><code>insert_final_newline</code></dt><dd>puesto a <code>true</code> se asegura de que el
fichero finalice con un carácter de salto de línea. Puesto a <code>false</code>
no lo comprobará.</dd>
<dt><code>root</code></dt><dd>debe especificarse en lo alto del fichero de
configuración, siendo la primera propiedad especificada. Cuando lo
configuramos a <code>true</code> estamos especificando que se deje de realizar
la búsqueda del fichero de configuración en éste.</dd>
</dl>
</div>
</div>
</div>
<div id="outline-container-org7e92caa" class="outline-2">
<h2 id="org7e92caa">Configurar <i>Emacs</i> para <i>EditConfig</i></h2>
<div class="outline-text-2" id="text-org7e92caa">
<p>
Como he dicho antes, <i>Emacs</i> está en la lista de editores que soportan
<i>EditConfig</i> mediante un <i>plugin</i>, lo que en <i>Emacs</i> se llama un
<i>paquete de modo</i>. En este caso, <code>editorconfig.el</code> proporciona un
<i>modo menor</i> para <i>Emacs</i>. La instalación es muy sencilla pues el
paquete está en <code>MELPA</code>.
</p>

<p>
<code>M-x package-install RET editorconfig RET</code>
</p>

<p>
Una vez instalado podemos configurarlo para que funcione adecuadamente
con nuestros proyectos. En su página, recomiendan:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">editorconfig</span>)
(editorconfig-mode 1)
</pre>
</div>

<p>
O, en caso de que utilices <code>use-package</code>, la configuración recomendada
es:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> editorconfig
  <span style="color: #8be9fd; font-style: italic;">:ensure</span> t
  <span style="color: #8be9fd; font-style: italic;">:config</span>
  (editorconfig-mode 1))
</pre>
</div>

<p>
Ambas configuraciones son válidas si quieres que <i>Emacs</i> utilice dicho
modo por defecto y siempre. Sin embargo, en mi caso no es así: sólo
necesito que lo haga en un proyecto donde el trabajo conjunto con
otros programadores con otros usos y costumbres y que me obliga a
usarlo para modificar el indentado por defecto del <i>modo</i> mayor sin
volverme loco.
</p>

<p>
En mi <code>init.el</code> he añadido lo siguiente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">use-package</span> editorconfig
  <span style="color: #8be9fd; font-style: italic;">:defer</span> t
  <span style="color: #8be9fd; font-style: italic;">:init</span>
  (add-hook 'ess-mode-hook 'editorconfig-mode-apply))
</pre>
</div>

<p>
No voy a explicar mucho, porque creo que las cuatro líneas están
<i>autoexplicadas</i>. Básicamente, la diferencia es que sólo quiero que se
active la configuración cuando se entra en el modo <code>ESS</code>, es decir,
cuando trabajo con <code>R</code>. Para ello he añadido un <code>:defer t</code> y también
he añadido un <code>add-hook</code> para que dispare el <code>editconfig</code> al entrar en
el modo <code>ess-mode</code>. Con una particularidad: al principio utilizaba
<code>editorconfig-mode</code> a secas, pero eso activaba el modo para todos los
<i>buffers</i> y lo mantenía activo una vez cerrados los ficheros de <code>R</code>
que es, únicamente, donde lo necesito.  Sin embargo, con
<code>editorconfig-mode-apply</code> establezco el modo únicamente para el
<i>buffer</i> concreto, cuando lo cierro, los demás <i>buffers</i> no se ven
afectados por el modo.
</p>
</div>
</div>
<div id="outline-container-org96b3279" class="outline-2">
<h2 id="org96b3279">Conclusiones</h2>
<div class="outline-text-2" id="text-org96b3279">
<p>
El resultado de utilizar <i>EditorConfig</i> es la homogeneización del
código entre distintos editores o desarrolladores. En mi caso lo
utilizo para un proyecto conjunto en <code>R</code> con otro compañero que ya lo
tenía iniciado y al que le molestan los anchos de 4 espacios que
introduce mi <i>Emacs</i> sin añadirle nada más. Puesto que tenía que
amoldarme al código ya escrito era muy incómodo escribir cualquier
función teclear directamente todos los espacios, o peor aún, pulsar
tabulador y luego borrar los espacios que me sobraban. Otra solución
es utilizar un editor distinto para ese trabajo específico. Las
opciones, que me planteé, eran utilizar o bien <i>RStudio</i> o bien
<i>Kate</i>. Ambos potentes editores, el primero dedicado casi
exclusivamente al trabajo sobre <code>R</code>, aunque también esté configurado
para asistir con lenguajes complementarios como <i>LaTeX</i>. <i>Kate</i> es un
editor muy potente perteneciente al proyecto <i>KDE/Plasma</i> y que
proporciona soporte para la mayoría de los lenguajes de programación
habidos y por haber. También soporta nativamente el estándar
<i>EditorConfig</i>. Sin embargo, no quería renunciar a mi editor favorito
y <code>editorconfig-mode</code> me proporciona la manera de salvar ese escollo.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/editorconfig/index.html">editorconfig</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[editorconfig]]></category>
  <link>https://notxor.nueva-actitud.org/2021/12/30/editorconfig-y-emacs.html</link>
  <pubDate>Thu, 30 Dec 2021 10:07:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Configurando Openbox]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-12-20</div>
<p>
Un amigo me preguntó por un escritorio ligero y funcional para
<i>GNU/Linux</i> y que no fuera muy técnico. Acostumbrado como estoy a los
escritorios de tipo <i>teselante</i> como <code>i3wm</code> y <code>awesomewm</code> estas fueron
mis primeras recomendaciones, pero justo son ese tipo de opciones lo
que él llama <i>más técnicas</i>. Ya las ha probado y no se acostumbra a
ellas y prefiere algo más <i>prosaico</i>. Mi escritorio (no tan) pesado es
<i>Plasma</i>, pero entiendo que las animaciones, la transparencia y esas
zarandajas se comen ciclos de CPU y otro poco de memoria... así pues,
nos fuimos a <code>openbox</code>. Durante las primeras pruebas de configuración
resultó un escritorio sencillo, ocupa muy poca memoria (menos que mi
<code>awesomewm</code> habitual) y parece que necesita menos CPU. En este
artículo veremos cómo lo he configurado a mi gusto (remarcando lo de
<i>mi gusto</i>).
</p>

<p>
Antes de nada su aspecto ha quedado así:
</p>


<figure id="org72569c0">
<img src="./imagenes/Captura-pantalla-openbox-aspecto-final.png" alt="Captura-pantalla-openbox-aspecto-final.png">

</figure>

<p>
¿Qué se puede ver en esa captura?
</p>

<ul class="org-ul">
<li>Una barra de tareas a la izquierda (<code>tint2</code>), que se esconde
automáticamente.</li>
<li><i>Consola</i> con información del sistema.</li>
<li>Un emplaste <code>conky</code> a la derecha con toda la información del
sistema.</li>
<li>Pasa desapercibido, por acostumbrados que estamos a ello, el fondo,
que está cargado con <code>Nitrogen</code>.</li>
</ul>

<p>
Veremos todas estas cosas y más. Pero comencemos por el principio:
¿Qué es <code>Openbox</code>? ¿Para qué sirve?
</p>
<div id="outline-container-orgcba8693" class="outline-2">
<h2 id="orgcba8693"><code>Openbox</code></h2>
<div class="outline-text-2" id="text-orgcba8693">
<p>
<code>Openbox</code> es un gestor de ventanas. Punto. Es decir, se ocupa de
dibujar ventanas, con su marco y su título, posicionarlas en la
pantalla y nada más. Bueno, también proporciona un menú para lanzar
aplicaciones y otro para saltar entre escritorios:
</p>


<figure id="orga57b312">
<img src="./imagenes/Captura-pantalla-menu-openbox.png" alt="Captura-pantalla-menu-openbox.png">

</figure>

<p>
Pulsando el botón derecho del ratón aparece el desplegable en
cualquier sitio de nuestra pantalla... pero ese es todo el cariño que
da. Además, si no lo has acompañado de otros programas que lo ayuden,
desde el punto de vista gráfico y funcional, es todo lo que tienes: un
fondo gris con un menú de texto, con la letra muy pequeña y ya está.
También tiene la opción de mostrar la lista de aplicaciones
funcionando y su correspondiente lista de escritorios pulsando el
botón central del ratón. Si no eres exigente ese es el mínimo con el
que te puedes conformar.
</p>

<p>
Instalarlo es sencillo: desde <code>Opensuse Tumbleweed</code> basta con
solicitarlo al instalador <code>zypper</code> (modifica el siguiente comando para
adecuarlo a tu distribución favorita):
</p>

<div class="org-src-container">
<pre class="src src-shell">sudo zypper install openbox
</pre>
</div>

<p>
Con eso ya nos aparece en el menú de <code>kdm</code> la posibilidad de arrancar
la sesión gráfica con <code>openbox</code>. También hay un par de paquetes
destinados a ayudarte a conseguir utilizar <code>openbox</code> como gestor de
ventanas para entornos de escritorio grandes:
</p>

<ul class="org-ul">
<li><code>openbox-kde</code></li>
<li><code>openbox-gnome</code></li>
</ul>

<p>
Si vemos el listado:
</p>

<pre class="example" id="org9308027">
$ sudo zypper search openbox
[sudo] password for root: 
Cargando datos del repositorio...
Leyendo los paquetes instalados...

S  | Name                     | Summary                                                  | Type
---+--------------------------+----------------------------------------------------------+--------
   | kvantum-openbox-themes   | Openbox themes for Kvantum engine                        | paquete
   | leechcraft-fenet-openbox | OpenBox Window Manager integration for LeechCraft        | paquete
i+ | openbox                  | ICCCM and EWMH Compliant Window Manager with Very Few -&gt; | paquete
   | openbox-adwaita-ob-theme | Adwaita theme for the Openbox Window Manager             | paquete
   | openbox-devel            | Includes and static libraries for openbox                | paquete
   | openbox-gnome            | Openbox GNOME integration                                | paquete
   | openbox-kde              | Openbox KDE integration                                  | paquete
   | openbox-theme-adapta     | Adapta openbox themes                                    | paquete
   | openbox-theme-matcha     | Matcha openbox themes                                    | paquete
   | openbox-theme-plata      | Plata openbox themes                                     | paquete
</pre>

<p>
La principal ventaja de <code>openbox</code> es ser más comedido a la hora de
usar recursos que los respectivos gestores de ventanas de los grandes
<i>escritorios</i>. Como puedes suponer, utilizarlo sólo equivale a no
tener una barra de tareas, un lanzador de aplicaciones, un paginador
de escritorios y cualquier otro tipo de <i>chismáticos</i> que complementan
el concepto de <i>escritorio</i>.
</p>

<p>
En el listado anterior podemos ver que también podemos instalar los
paquetes necesarios para utilizar <code>openbox</code> como gestor de ventanas de
<code>Gnome</code> y de <code>KDE/Plasma</code> y también algunos <i>temas</i> que nos ayudarán a
mejorar el aspecto de nuestro <code>openbox</code>.
</p>
</div>
<div id="outline-container-org79458d1" class="outline-3">
<h3 id="org79458d1">Configuración de <code>openbox</code></h3>
<div class="outline-text-3" id="text-org79458d1">
<p>
Toda la configuración del gestor de ventanas se lleva a cabo desde dos
ficheros situados en el <i>path</i> <code>~/.config/openbox/</code>, en realidad sólo
es necesario uno para determinar la funcionalidad de <code>openbox</code>, el
otro es un fichero que se ejecutará al iniciar el entorno y nos
ayudará lanzando algunos programas que nos permitirán darle un poco
más de funcionalidad al mismo. Los dos ficheros son:
</p>

<ul class="org-ul">
<li><code>rc.xml</code></li>
<li><code>autostart</code></li>
</ul>

<p>
No hace falta que te pegues directamente con el fichero <code>xml</code> si no te
ves con ánimo, a no ser que quieras modificar algunas combinaciones de
tecla o añadirle algo más de funcionalidad. Puedes configurar la mayor
parte de ellas con la aplicación <code>obconf</code>. Encontré que esta
aplicación tiene dos versiones que puedes elegir: la versión <code>gnome</code> y
la versión <code>qt</code> (ésta última es algo más ligera que la anterior).
</p>

<p>
La versión <code>gnome</code> tiene este aspecto:
</p>


<figure id="org5912809">
<img src="./imagenes/Captura-pantalla-obconf.png" alt="Captura-pantalla-obconf.png">

</figure>

<p>
Pero, como a mí me gustan los temas <i>Kvantum</i> para <i>KDE/Plasma</i>, me he
instalado la versión <code>qt</code> y el paquete de temas
<code>kvantum-openbox-themes</code> para obtener:
</p>


<figure id="org22d2250">
<img src="./imagenes/Captura-pantalla-obconf-qt.png" alt="Captura-pantalla-obconf-qt.png">

</figure>

<p>
Ambas versiones son excluyentes, si instalas una debes quitar la
otra.  El propio <code>zypper</code> avisa de la incompatibilidad y da la opción
de sustituir o no el comando <code>obconf</code>. La funcionalidad es idéntica en
ambas, con lo que es recomendable que instales una u otra dependiendo
de qué escritorio estés utilizando, si <code>GTK</code> la primera y si <code>QT</code> la
segunda.
</p>
</div>
</div>
<div id="outline-container-org6597f76" class="outline-3">
<h3 id="org6597f76">El fichero <code>autostart</code></h3>
<div class="outline-text-3" id="text-org6597f76">
<p>
Comenzamos con el listado de código tal y como lo he dejado y luego
voy comentando las cosas que lanzo desde ahí y las configuraciones
secundarias que he hecho.
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #6272a4;"># </span><span style="color: #6272a4;">Establecer el intercambio entre bloqueo de may&#250;sculas y escape
</span>setxkbmap -option caps:swapescape &amp;

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">Cambiar fondo de pantalla
</span>nitrogen --restore &amp;

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">Barra de herramientas
</span>tint2 &amp;

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">Lanzar `emacs` como servicio
</span>emacs --daemon &amp;

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">Visor del sistema
</span>conky &amp;

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">Bloqueo del salvapantallas
</span>xset -dpms &amp;

<span style="color: #6272a4;"># </span><span style="color: #6272a4;">Composici&#243;n de escritorio
</span><span style="color: #6272a4;"># </span><span style="color: #6272a4;">picom</span>
</pre>
</div>

<p>
El primer comando lo que hace es intercambiar las teclas de <i>bloqueo
de mayúsculas</i> y el <i>escape</i>, para tenerlo más a mano. El segundo,
<code>nitrogen</code> es una aplicación que nos permite ajustar el fondo de
pantalla, con la opción <code>--restore~</code> muestra el último fondo que se ha
utilizado, pero si lo utilizamos lanzando sólo la aplicación, nos
mostrará una ventana donde seleccionar de entre los fondos que
tengamos cargados:
</p>


<figure id="orgdd0e944">
<img src="./imagenes/Captura-pantalla-nitrogen.png" alt="Captura-pantalla-nitrogen.png">

</figure>

<p>
En mi caso, cada vez que veo un fondo que me gusta lo guardo en el
directorio <code>~/Imágenes/wallpapers</code>, que es el directorio que tengo
configurado en <code>nitrogen</code> para cargar los fondos.
</p>

<p>
El siguiente comando <code>tint2</code> es el comando de cargar la barra de
tareas. En la primera imagen del artículo podéis ver cómo ha quedado
con un poquito de configuración adicional. Sólo la he puesto vertical
y he metido algunos lanzadores. Pero hablaré más detenidamente de ello
en un apartado posterior, así que lo dejaré para más adelante.
</p>

<p>
Luego lanzo <i>Emacs</i> en modo <i>demonio</i> o <i>servidor</i>... eso hace que
esté siempre en funcionamiento (¿he comentado alguna vez que lo uso
muy a menudo?) y luego lo llamo con una combinación de teclas y lo uso
también como <i>editor del sistema</i>.
</p>

<p>
Lo siguiente es <code>conky</code>, para quien no lo conozca es toda esa
información que se ve en la pantalla a la derecha, con listando de
números y barras gráficas. También hablaré de su configuración más
tarde, por lo que no voy a extenderme aquí.
</p>

<p>
Con <code>xset -dpms</code> lo que hago es desactivar la opción de que la máquina
entre en hibernación cuando deja de recibir entradas durante un rato.
Me molesta mucho cuando estoy trabajando, consultando documentación en
papel o en otro dispositivo como la <i>tableta</i> o el <i>móvil</i> y
comparándola con el ordenador, que este se apague. Sin embargo, si me
alejo del teclado un momento, aunque sea corto, suelo bloquear la
pantalla con una combinación de teclas que veremos más adelante en el
apartado correspondiente.
</p>

<p>
Por último, había una llamada a <code>picom</code>. Este programa es un
<i>compositor</i>, es decir, sirve para añadirle al escritorio
transparencias y alguna que otra animación a la hora de mostrar menús,
ventanas y desplegables. A mí, particularmente, me suele cansar ese
tipo de cosas, aparte de que consumen sus ciclos de CPU. Sin embargo,
lo cargué al principio cuando estuve probando algunas barras de tareas
y <i>docks</i>, porque <i>pedían</i> composición.
</p>
</div>
</div>
</div>
<div id="outline-container-org725b438" class="outline-2">
<h2 id="org725b438">Barra de tareas</h2>
<div class="outline-text-2" id="text-org725b438">
<p>
He probado varias barras distintas, algunas mezclándolas entre ellas.
Fundamentalmente, mis pruebas han sido con:
</p>

<ul class="org-ul">
<li><code>polybar</code></li>
<li><code>cairo-dock</code></li>
<li><code>latte-dock</code></li>
<li><code>tint2</code></li>
</ul>

<p>
De las cuatro, la ganadora final ha sido <code>tint2</code>, por ser completa,
sencilla y ligera. El aspecto es altamente configurable, pero en eso
todas las anteriores tienen sus cosas. Para elegir me planteé qué es
lo que le pido (bueno, lo que pediría un usuario nuevo) a una barra de
tareas, o qué tipo de información se ha vuelto imprescindible para el
usuario de escritorio. Evidentemente, toda aquella que me proporciona
el emplasto <code>conky</code> ─que aparece en pantalla─ no es necesario que me
lo repita la barra y como el menú de aplicaciones ya lo proporciona
<code>openbox</code> tampoco necesito uno, prefiero uno que me permita manejar
los distintos escritorios y las aplicaciones que corren en cada uno.
En definitiva, la barra tenía que cumplir con estas tareas:
</p>

<ul class="org-ul">
<li>Lanzador rápido de aplicaciones: básicamente cuatro botones para el
navegador, el gestor de archivos, la consola y el gestor de correo.
(Estos son los básicos para mí, quizá otros usuarios, con otras
necesidades, añadirán o quitarán botones).</li>
<li>Paginador de escritorios: es decir, un intercambiador de escritorios
que a ser posible también informe de qué aplicaciones están
corriendo en cada uno.</li>
<li>Soporte para <i>systray icons</i>, para las aplicaciones que pueden
funcionar en segundo plano <i>iconificadas</i>.</li>
</ul>

<p>
Lo resumo en que <code>tint2</code> trae todo eso de casa y es el que menos
recursos consume. En los otros tienes que instalar y configurar los
correspondientes <i>plug-ins</i> para realizar esas tareas. Si estás
acostumbrado al entorno de <code>Gnome</code> te puede ir bien el <code>cairo-dock</code>,
altamente configurable, con animaciones vistosas y un montón de
<i>plug-ins</i> para todo tipo de tareas. El inconveniente es que da por
supuesto que tienes instalado algún programa de <i>composición</i> para
gestionar las transparencias y demás. En cambio, si estás más
acostumbrado a trabajar con entornos <i>KDE/Plasma</i> puedes utilizar
<code>latte-dock</code>. Permite tener barra de tareas idéntica a la de
<i>KDE/Plasma</i>, con los mismos <i>plugins</i>, capacidad para gestionar
varias barras a la vez (o barra y <i>dock</i>), etc. Igual que la anterior,
también pide que exista algún programa de composición para gestionar
correctamente la transparencia. Con esto puedes hacer un sencillo
<i>clon</i> de <i>Plasma</i> con <code>openbox</code>.
</p>

<p>
Para el final he dejado <code>polybar</code> que la utilizo con <code>i3wm</code> y me
parece una buena barra. Funciona perfectamente en ese entorno, sin
embargo, para <code>openbox</code> había que tocar la configuración. Lo intenté
con ahinco, pero aún así no he conseguí hacer que funcionara el
paginador de escritorios para <code>openbox</code>... y luego tuve que volver a
reconfigurarla para <code>i3wm</code> ─menos mal que me guardé una copia de la
configuración─.
</p>

<p>
Configurar <code>tint2</code> es sencillo, viene con el lanzador de su
configurador cargado. Al pinchar en él nos aparecerá una ventana tal
que:
</p>


<figure id="org3fd97a9">
<img src="./imagenes/Captura-pantalla-tint2-themes.png" alt="Captura-pantalla-tint2-themes.png">

</figure>

<p>
Esa pantalla es una lista de temas. Hay temas de barra horizontales y
verticales y para más especificidad tenemos también una serie de
<i>preferencias</i> para ajustarle todos los parámetros a cada tema:
</p>


<figure id="org5e0ac29">
<img src="./imagenes/Captura-pantalla-tint2-configurar-tema.png" alt="Captura-pantalla-tint2-configurar-tema.png">

</figure>

<p>
Es un poco farragoso por la cantidad de opciones que tiene, pero las
únicas que recuerdo haber utilizado, tras elegir el primer tema
<i>vertical</i> que encontré, es situarla en el centro del lado izquierdo y
hacer que se oculte automáticamente. Eso me deja sólo 2 píxeles a la
izquierda de la pantalla «sin utilizar» cuando maximizo cualquier
aplicación. Poniendo el cursor en ellas, se despliega toda la barra de
nuevo.
</p>

<p>
Esta barra, entre otras funcionalidades que pueden ser interesantes,
está la de poder mover una aplicación desde un escritorio a otro,
arrastrando los botones que las representan hacia el espacio del
escritorio deseado.
</p>
</div>
</div>
<div id="outline-container-org6fff214" class="outline-2">
<h2 id="org6fff214">Información del sistema</h2>
<div class="outline-text-2" id="text-org6fff214">
<p>
Muchos de los usuarios normalmente utilizan la barra de tareas para
mostrar información sobre el sistema. Yo también lo hago, pero muchas
veces es redundante con la información que tengo en pantalla gracias a
<code>conky</code>. Incluso la información que da <code>conky</code> suele ser más exacta y
precisa.
</p>


<figure id="orgdf1db48">
<img src="./imagenes/Captura-pantalla-conky.png" alt="Captura-pantalla-conky.png">

</figure>

<p>
Ya he <a href="https://notxor.nueva-actitud.org/2019/10/01/configuracion-de-awesomewm-y-conky.html">hablado sobre <code>conky</code> con anterioridad</a> en este <i>blog</i> y ya puse
el código que lo generaba. Sin embargo, le he hecho algún cambio para
que soporte <i>composición</i> con verdadera transparencia si se activa
dicha opción. El código para generar el <i>emplasto</i> que muestro arriba
es el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-lua"><span style="color: #6272a4;">-- </span><span style="color: #6272a4;">conky configuration
</span>
conky.config = {
   background = <span style="color: #bd93f9;">false</span>,
   use_xft = <span style="color: #bd93f9;">true</span>,
   <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">font = 'Terminus:size=8',
</span>   <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">font = 'DejaVu Sans Mono:size=8',
</span>   font = <span style="color: #f1fa8c;">'Fira Code:size=9'</span>,
   font1 = <span style="color: #f1fa8c;">'Fira Code:size=20'</span>,
   font2 = <span style="color: #f1fa8c;">'Fira Code:size=15'</span>,
   xftalpha = 0.8,
   update_interval = 2.0,
   total_run_times = 0,
   <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">cambios para entenderse con composici&#243;n
</span>   <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">own_window = false,
</span>   own_window = <span style="color: #bd93f9;">true</span>,
   own_window_type = <span style="color: #f1fa8c;">'desktop'</span>,
   own_window_transparent = <span style="color: #bd93f9;">true</span>,
   own_window_hints = <span style="color: #f1fa8c;">"below"</span>,
   own_window_colour = <span style="color: #f1fa8c;">'000000'</span>,
   own_window_class = <span style="color: #f1fa8c;">'Conky'</span>,
   <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">Hasta aqu&#237; es lo nuevo
</span>   double_buffer = <span style="color: #bd93f9;">true</span>,
   draw_shades = <span style="color: #bd93f9;">false</span>,
   draw_outline = <span style="color: #bd93f9;">false</span>,
   draw_borders = <span style="color: #bd93f9;">false</span>,
   stippled_borders = 0,
   border_margin = 4,
   border_width = 1,
   default_color = <span style="color: #f1fa8c;">'white'</span>,
   default_shade_color = <span style="color: #f1fa8c;">'brown'</span>,
   default_outline_color = <span style="color: #f1fa8c;">'white'</span>,
   <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">alignment = 'top_left',
</span>   alignment = <span style="color: #f1fa8c;">'top_right'</span>,
   top_cpu_separate = <span style="color: #bd93f9;">true</span>,
   gap_x = 10,
   gap_y = 10,
   no_buffers = <span style="color: #bd93f9;">true</span>,
   uppercase = <span style="color: #bd93f9;">false</span>,
   cpu_avg_samples = 2,
   net_avg_samples = 2,
   override_utf8_locale = <span style="color: #bd93f9;">true</span>,
   use_spacer = <span style="color: #f1fa8c;">'none'</span>,
}

conky.text = <span style="color: #f1fa8c;">[[
$hr
${alignc}${color #FF9922}${font1}${time %e}
${alignc}${color white}${font}${time %B} ${color #AA9922}${time %Y}
${alignc}${color yellow}${font}${time %A}
${color yellow}${time %Z: }${alignc}${color #AA9922}${font2}${time %H:%M}${font}
${color white}$hr
${color yellow}UpTime: ${color #AA9922}$uptime

${color yellow}CPU:${color #AA9922} $cpu% ${alignr} ${exec sensors | grep "Core 0" | cut -c15-22}
${cpugraph 20,400 FFFFFF AA9922}
${color yellow}Load: ${color #AA9922}$loadavg
${color yellow}Procesos: ${color #AA9922}$processes
${color yellow}Running: ${color #AA9922}$running_processes
${color white}Cores:
${color white}Core 1: ${color #AA9922}${cpubar cpu1 6,220}${color white} ${freq 1} MHz ${cpu cpu1}%
${color white}Core 2: ${color #AA9922}${cpubar cpu2 6,220}${color white} ${freq 2} MHz ${cpu cpu2}%
${color white}Core 3: ${color #AA9922}${cpubar cpu3 6,220}${color white} ${freq 3} MHz ${cpu cpu3}%
${color white}Core 4: ${color #AA9922}${cpubar cpu4 6,220}${color white} ${freq 4} MHz ${cpu cpu4}%

${color white}$hr
${color yellow}Uso CPU:
${color #AA9922}Nombre                           PID   CPU%   MEM%
${color white}${top name 1}               ${top pid 1} ${top cpu 1} ${top mem 1}
${color white}${top name 2}               ${top pid 2} ${top cpu 2} ${top mem 2}
${color white}${top name 3}               ${top pid 3} ${top cpu 3} ${top mem 3}
${color white}${top name 4}               ${top pid 4} ${top cpu 4} ${top mem 4}

${color yellow}Uso MEM:
${color #AA9922}Nombre                          MEM%
${color white}${top_mem name 1}              ${top_mem mem 1}
${color white}${top_mem name 2}              ${top_mem mem 2}
${color white}${top_mem name 3}              ${top_mem mem 3}
${color white}${top_mem name 4}              ${top_mem mem 4}

${color white}$hr
${color white}MEM: ${color #AA9922}$memperc% ${alignr}$mem/$memmax
${memgraph 20,400 FFFFFF AA9922}
${color white}SWAP: ${color #AA9922}$swapperc% ${alignr}$swap/$swapmax
${swapbar 6,400}
${color white}$hr
${color white}ROOT: ${color #AA9922}${fs_free_perc /}% ${alignr}${color #AA9922}${fs_free /}/${fs_size /}
${fs_bar 6,400 /}
${color white}HOME: ${color #AA9922}${fs_free_perc /home}% ${alignr}${color #AA9922}${fs_free /home}/${fs_size /home}
${fs_bar 6,400 /home}
${color white}$hr
${if_existing /sys/class/net/wlp8s0b1/operstate up}
${color yellow}WIFI: ${color white}${wireless_essid wlp8s0b1}${color #AA9922}${alignr}${addr wlp8s0b1}
${color white}Bajada: ${alignr}${color #AA9922}${downspeed wlp8s0b1}
${downspeedgraph wlp8s0b1 20,400 FFFFFF AA9922}
${color white}Subida: ${alignr}${color #AA9922}${upspeed wlp8s0b1}
${upspeedgraph wlp8s0b1 20,400 FFFFFF AA9922}
${endif}
${if_existing /sys/class/net/eth0/operstate up}
${color yellow}NET:${alignr}${color #AA9922}${addr eth0}
${color white}Bajada: ${alignr}${color #AA9922}${downspeed eth0}${color}
${downspeedgraph eth0 20,400 FFFFFF AA9922}
${color white}Subida: ${alignr}${color #AA9922}${upspeed eth0}
${upspeedgraph eth0 20,400 FFFFFF AA9922}
${endif}
${if_existing /sys/class/net/enp9s0u1/operstate up}
${color yellow}USB:${alignr}${color #AA9922}${addr enp9s0u1}
${color white}Bajada: ${alignr}${color #AA9922}${downspeed enp9s0u1}${color}
${downspeedgraph enp9s0u1 20,400 FFFFFF AA9922}
${color white}Subida: ${alignr}${color #AA9922}${upspeed enp9s0u1}
${upspeedgraph enp9s0u1 20,400 FFFFFF AA9922}
${endif}
]]</span>
</pre>
</div>

<p>
Si copias el código, fíjate que tendrás que cambiar algunas cosas,
como las fuentes de letra y los nombres de dispositivos, como los de
red, para que te funcione correctamente.
</p>
</div>
</div>
<div id="outline-container-org20ee12e" class="outline-2">
<h2 id="org20ee12e">Configuración de teclado</h2>
<div class="outline-text-2" id="text-org20ee12e">
<p>
<code>Openbox</code> viene ya con un gran repertorio de configuración de teclas
por defecto, pero se echan de menos algunas. Y todas ellas están en la
configuración existente en el <code>rc.xml</code>. Por hacer un resumen de las
principales las pongo en la siguiente tabla, pero antes está la
nomenclatura de teclas que utiliza:
</p>

<ul class="org-ul">
<li><code>A</code>: tecla <i>Alt</i>.</li>
<li><code>C</code>: tecla <i>Control</i>.</li>
<li><code>S</code>: tecla <i>Mayúsculas</i>.</li>
<li><code>W</code>: tecla de sistema o <i>windows</i> como viene a llamarse en muchos
teclados.</li>
</ul>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Keybind</th>
<th scope="col" class="org-left">Acción</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">C-A-Left</td>
<td class="org-left">Ir al escritorio de la izquierda</td>
</tr>

<tr>
<td class="org-left">C-A-Right</td>
<td class="org-left">Ir al escritorio de la derecha</td>
</tr>

<tr>
<td class="org-left">C-A-Up</td>
<td class="org-left">Ir al escritorio de arriba</td>
</tr>

<tr>
<td class="org-left">C-A-Down</td>
<td class="org-left">Ir al escritorio de abajo</td>
</tr>

<tr>
<td class="org-left">S-A-Left</td>
<td class="org-left">Enviar la ventana al escritorio de la izquierda</td>
</tr>

<tr>
<td class="org-left">S-A-Right</td>
<td class="org-left">Enviar la ventana al escritorio de la derecha</td>
</tr>

<tr>
<td class="org-left">S-A-Up</td>
<td class="org-left">Enviar la ventana al escritorio de arriba</td>
</tr>

<tr>
<td class="org-left">S-A-Down</td>
<td class="org-left">Enviar la ventana al escritorio de abajo</td>
</tr>

<tr>
<td class="org-left">W-F1</td>
<td class="org-left">Ir al escritorio 1</td>
</tr>

<tr>
<td class="org-left">W-F2</td>
<td class="org-left">Ir al escritorio 2</td>
</tr>

<tr>
<td class="org-left">W-F3</td>
<td class="org-left">Ir al escritorio 3</td>
</tr>

<tr>
<td class="org-left">W-F4</td>
<td class="org-left">Ir al escritorio 4</td>
</tr>

<tr>
<td class="org-left">W-d</td>
<td class="org-left">Mostrar escritorio</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">A-F4</td>
<td class="org-left">Cerrar ventana</td>
</tr>

<tr>
<td class="org-left">A-Escape</td>
<td class="org-left">La ventana actual pierde el foco</td>
</tr>

<tr>
<td class="org-left">A-space</td>
<td class="org-left">Muestra el menú de ventana</td>
</tr>

<tr>
<td class="org-left">A-Tab</td>
<td class="org-left">Ir a la siguiente ventana</td>
</tr>

<tr>
<td class="org-left">A-S-Tab</td>
<td class="org-left">Ir a la ventana anterior</td>
</tr>
</tbody>
</table>

<p>
También hay atajos donde está implicado el ratón, pero esos ya os los
miráis más despacio, porque son los habituales de cualquier entorno de
ventanas, aparte de que intento utilizar el ratón lo mínimo
imprescindible. Pero continuando con los atajos de teclado he metido
algunos más.  En algún caso he necesitado la documentación de
<code>openbox</code> para utilizar sus <code>Actions</code> para poder conseguir lo que
quería.  Por ejemplo, aunque normalmente con cuatro escritorios suele
ser suficiente para un uso normal del sistema, en ocasiones puede
ocurrir que necesitemos más temporalmente y luego queramos
eliminarlos:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Keybind</th>
<th scope="col" class="org-left">Acción</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">W-F12</td>
<td class="org-left">Añadir un escritorio</td>
</tr>

<tr>
<td class="org-left">W-F11</td>
<td class="org-left">Eliminar un escritorio</td>
</tr>
</tbody>
</table>

<p>
El código que he metido en el fichero de configuración, dentro del
apartado <code>keyboard</code> es el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-xml"><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">keybind</span> <span style="color: #f8f8f2; font-weight: bold;">key</span>=<span style="color: #f1fa8c;">"W-F12"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">action</span> <span style="color: #f8f8f2; font-weight: bold;">name</span>=<span style="color: #f1fa8c;">"AddDesktop"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
    <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">where</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span><span style="color: #f8f8f2; background-color: #282a36;">current</span><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">where</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">action</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">keybind</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">keybind</span> <span style="color: #f8f8f2; font-weight: bold;">key</span>=<span style="color: #f1fa8c;">"W-F11"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">action</span> <span style="color: #f8f8f2; font-weight: bold;">name</span>=<span style="color: #f1fa8c;">"RemoveDesktop"</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">keybind</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
</pre>
</div>

<p>
La opción <code>&lt;where&gt;current&lt;/where&gt;</code> hace que al crear el nuevo
escritorio el foco se mueva a él.
</p>

<p>
Los otros <i>keybindings</i> que me he puesto, para uso personal son los
siguientes:
</p>

<div class="org-src-container">
<pre class="src src-xml"><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">keybind</span> <span style="color: #f8f8f2; font-weight: bold;">key</span>=<span style="color: #f1fa8c;">"F12"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">action</span> <span style="color: #f8f8f2; font-weight: bold;">name</span>=<span style="color: #f1fa8c;">"Execute"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
    <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">command</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span><span style="color: #f8f8f2; background-color: #282a36;">kitty</span><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">command</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">action</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">keybind</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">keybind</span> <span style="color: #f8f8f2; font-weight: bold;">key</span>=<span style="color: #f1fa8c;">"A-F10"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">action</span> <span style="color: #f8f8f2; font-weight: bold;">name</span>=<span style="color: #f1fa8c;">"Execute"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
    <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">command</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span><span style="color: #f8f8f2; background-color: #282a36;">rofi -show drun -modi run,drun -show-icons -display-drun "Lanzar"</span><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">command</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">action</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">keybind</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">keybind</span> <span style="color: #f8f8f2; font-weight: bold;">key</span>=<span style="color: #f1fa8c;">"W-F10"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">action</span> <span style="color: #f8f8f2; font-weight: bold;">name</span>=<span style="color: #f1fa8c;">"Execute"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
    <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">command</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span><span style="color: #f8f8f2; background-color: #282a36;">rofi -show run -modi run -display-drun "Lanzar"</span><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">command</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">action</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">keybind</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">keybind</span> <span style="color: #f8f8f2; font-weight: bold;">key</span>=<span style="color: #f1fa8c;">"W-e"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">action</span> <span style="color: #f8f8f2; font-weight: bold;">name</span>=<span style="color: #f1fa8c;">"Execute"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
    <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">command</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span><span style="color: #f8f8f2; background-color: #282a36;">emacsclient -c -a emacs</span><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">command</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">action</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">keybind</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">keybind</span> <span style="color: #f8f8f2; font-weight: bold;">key</span>=<span style="color: #f1fa8c;">"print"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">action</span> <span style="color: #f8f8f2; font-weight: bold;">name</span>=<span style="color: #f1fa8c;">"Execute"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
    <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">command</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span><span style="color: #f8f8f2; background-color: #282a36;">spectacle</span><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">command</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">action</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">keybind</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
</pre>
</div>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Keybind</th>
<th scope="col" class="org-left">Acción</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">F12</td>
<td class="org-left">Abrir un terminal (<code>kitty</code>, en mi caso)</td>
</tr>

<tr>
<td class="org-left">A-F10</td>
<td class="org-left">Menú de aplicaciones <code>rofi</code></td>
</tr>

<tr>
<td class="org-left">W-F10</td>
<td class="org-left">Menú de ejecutables <code>rofi</code></td>
</tr>

<tr>
<td class="org-left">W-e</td>
<td class="org-left"><code>emacsclient</code></td>
</tr>

<tr>
<td class="org-left">print</td>
<td class="org-left">Captura de pantalla</td>
</tr>
</tbody>
</table>

<p>
La primera es porque necesito una consola en cualquier sitio en
cualquier momento, por eso le he puesto una tecla de función directa
<code>F12</code>. La consola que abre es <code>kitty</code> que es la que utilizo
últimamente para todo.
</p>

<p>
Después he configurado dos menús <code>rofi</code> el primero utiliza el comando:
</p>

<div class="org-src-container">
<pre class="src src-shell">rofi -show drun -modi run,drun -show-icons -display-drun <span style="color: #f1fa8c;">"Lanzar"</span>
</pre>
</div>

<p>
Ese comando proporciona una lista de las aplicaciones que se pueden
lanzar en el sistema y tiene el siguiente aspecto:
</p>


<figure id="org1aac768">
<img src="./imagenes/Captura-pantalla-rofi-aplicaciones.png" alt="Captura-pantalla-rofi-aplicaciones.png">

</figure>

<p>
Hace tiempo que vengo utilizando <code>rofi</code> para muchas cosas, pero
especialmente para mostrar un menú de aplicaciones. Lo utilizo en
<code>i3wm</code>, lo utilizo en <code>awesomewm</code> y por qué no utilizarlo también en
<code>openbox</code>. El caso es que puedo abrir un menú, ─bueno dos para ser
exactos─, desde el teclado sin mover la mano al ratón. El otro comando
es:
</p>

<div class="org-src-container">
<pre class="src src-shell">rofi -show run -modi run -display-drun <span style="color: #f1fa8c;">"Lanzar"</span>
</pre>
</div>

<p>
El aspecto del menú es:
</p>


<figure id="org9953e0b">
<img src="./imagenes/Captura-pantalla-rofi-ejecutables.png" alt="Captura-pantalla-rofi-ejecutables.png">

</figure>

<p>
Quizá es menos vistoso visualmente sin embargo, desde aquí tengo
acceso a todos los ejecutables y <i>scripts</i> que tengo en mi sistema. De
esa manera puedo lanzar casi cualquier cosa desde él.
</p>

<p>
Por supuesto, también hay una combinación de teclas para abrir,
mediante <code>emacsclient</code> el <i>Emacs</i> que está funcionando en modo
<i>demonio</i> o <i>servidor</i>, del que hable en el <code>autostart</code>.  Vale que
cinco segundos que tarda en arrancar desde cero no son tanto, pero con
<code>emacsclient</code> aparece de forma inmediata sin ningún retardo. Puede que
al día abra <i>Emacs</i> decenas de veces para todo tipo de tareas que hago
con él: consultar la agenda, llevar la contabilidad, escribir algún
documento para el trabajo, escribir algún artículo para el <i>blog</i>,
programar, etc. Es posible incluso que lo tenga cargado varias veces:
mientras consulto la agenda en un <i>frame</i>, en otro está cargado el
borrador de algún artículo o en otro puede estar cargado el código de
algún programa. No es extraño tener en mi máquina, repartidos por
varios <i>escritorios</i> varios <i>frames</i> de <i>Emacs</i>, cada uno con una
función diferente. Por ejemplo,
</p>


<figure id="orge71bf5c">
<img src="./imagenes/Captura-pantalla-emacsclient.png" alt="Captura-pantalla-emacsclient.png">

</figure>

<p>
Podemos observar en la imagen que tengo en dos escritorios <i>frames</i> de
<i>Emacs</i>. Sin embargo, al ver cuántos hilos de ejecución se están
utilizando en el sistema:
</p>

<div class="org-src-container">
<pre class="src src-shell">$ ps -e | grep emacs
 2207 ?        00:02:48 emacs-gtk
 3221 ?        00:00:00 emacsclient
11817 ?        00:00:00 emacsclient
</pre>
</div>

<p>
Es decir, sólo está cargado una vez el proceso pesado de <i>Emacs</i> y
luego hay dos <i>clientes</i> que son bastante más ligeros. Más ligeros que
tener dos (o más) <i>Emacs</i> completos cargados en memoria, quiero decir.
</p>
</div>
<div id="outline-container-org3ea9811" class="outline-3">
<h3 id="org3ea9811">Otras teclas para reposicionar ventanas</h3>
<div class="outline-text-3" id="text-org3ea9811">
<p>
Una de las opciones que proporciona <code>openbox</code> entre sus acciones es la
capacidad para mostrar las ventanas en el escritorio ajustándolas
haciéndolas crecer hacia los lados. No venían programadas por defecto,
pero sí las mencionaba la documentación y me parecieron interesantes.
Con esta característica también se pueden conseguir un reparto más
<i>teselado</i> de las aplicaciones. Las teclas las he configurado de la
siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-xml"><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">keybind</span> <span style="color: #f8f8f2; font-weight: bold;">key</span>=<span style="color: #f1fa8c;">"C-Left"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">action</span> <span style="color: #f8f8f2; font-weight: bold;">name</span>=<span style="color: #f1fa8c;">"GrowToEdge"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;&lt;</span><span style="color: #50fa7b; font-weight: bold;">direction</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span><span style="color: #f8f8f2; background-color: #282a36;">west</span><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">direction</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">action</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">keybind</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">keybind</span> <span style="color: #f8f8f2; font-weight: bold;">key</span>=<span style="color: #f1fa8c;">"C-Right"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">action</span> <span style="color: #f8f8f2; font-weight: bold;">name</span>=<span style="color: #f1fa8c;">"GrowToEdge"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;&lt;</span><span style="color: #50fa7b; font-weight: bold;">direction</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span><span style="color: #f8f8f2; background-color: #282a36;">east</span><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">direction</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">action</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">keybind</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">keybind</span> <span style="color: #f8f8f2; font-weight: bold;">key</span>=<span style="color: #f1fa8c;">"C-Up"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">action</span> <span style="color: #f8f8f2; font-weight: bold;">name</span>=<span style="color: #f1fa8c;">"GrowToEdge"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;&lt;</span><span style="color: #50fa7b; font-weight: bold;">direction</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span><span style="color: #f8f8f2; background-color: #282a36;">north</span><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">direction</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">action</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">keybind</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">keybind</span> <span style="color: #f8f8f2; font-weight: bold;">key</span>=<span style="color: #f1fa8c;">"C-Down"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
  <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">action</span> <span style="color: #f8f8f2; font-weight: bold;">name</span>=<span style="color: #f1fa8c;">"GrowToEdge"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;&lt;</span><span style="color: #50fa7b; font-weight: bold;">direction</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span><span style="color: #f8f8f2; background-color: #282a36;">south</span><span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">direction</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">action</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">keybind</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
</pre>
</div>

<p>
Las ventanas crecerán hacia un lado o hacia otro hasta que encuentren
un borde. Por lo que repartir la pantalla entre las distintas ventanas
sin que haya huecos vacíos entre ellas es relativamente sencillo.
</p>
</div>
</div>
</div>
<div id="outline-container-org85adbdd" class="outline-2">
<h2 id="org85adbdd">Conclusiones</h2>
<div class="outline-text-2" id="text-org85adbdd">
<p>
Esto es sólo una prueba de concepto que inicié para poder explicarle a
un amigo cómo configurar un sistema ligero pero plenamente funcional
con <i>GNU/Linux</i> sin necesidad de cargar los grandes escritorios.
Comenzó como tal, pero me está gustando el resultado y no descarto
utilizarlo con asiduidad también. Vale que en los entornos
<i>teselantes</i> se ocupan todos los espacios posibles repartiéndolos
entre las ventanas de las aplicaciones. Sin embargo, en mi trabajo
habitual termina estando cada aplicación maximizada en un escritorio.
Por tanto, en <code>openbox</code> puedo hacer lo mismo.  Tendré que
acostumbrarme a las nuevas combinaciones de teclas, pero no descargo
hacer un trabajo más detallado para conseguir uniformidad de teclado
entre los distintos sistemas de ventanas que utilizo y que cambio con
cierta regularidad.
</p>

<p>
Finalmente es un sistema de ventanas. Quizá sea menos intimidante para
el usuario nuevo, pero al final, puedes configurarlo todo para tocar
el ratón lo menos posible. El aprovechar la pantalla completa o no,
como hacen los sistemas <i>teselantes</i> también es una opción personal.
Al usuario nuevo le puede resultar raro que sea el sistema el que
decida dónde poner y qué tamaño dar a las ventanas que se abren,
porque no está acostumbrado a ello. Con un poco de entrenamiento,
apreciarán la sencillez y facilidad de sistemas de ventanas como
<code>i3wm</code> o como <code>awesomewm</code>. Para estos nuevos usuarios, la
recomendación es que utilicen los grandes entornos como <i>Gnome</i> o
<i>KDE/Plasma</i> en lugar de los otros, más ligeros pero más espartanos y
simples y que necesitan más trabajo para ajustarlos y ajustar,
también, los complementos que se necesitan para equiparar
funcionalidades.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/openbox/index.html">openbox</a> <a href="/tags/escritorio/index.html">escritorio</a> <a href="/tags/conky/index.html">conky</a> ]]></description>
  <category><![CDATA[openbox]]></category>
  <category><![CDATA[escritorio]]></category>
  <category><![CDATA[conky]]></category>
  <link>https://notxor.nueva-actitud.org/2021/12/20/configurando-openbox.html</link>
  <pubDate>Mon, 20 Dec 2021 10:23:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Estadística, ESS en Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-12-12</div>
<p>
Todos hemos oído alguna vez el aforismo aquel de que existen las
mentiras, las grandes mentiras y la estadística. En realidad, la
tercera parte de dicho aforismo no tiene que ver con la <i>estadística</i>
como tal, sino con el uso torticero o parcial de los resultados que se
puede hacer con cualquier estudio. Por el contrario, dicha ciencia
viene a ayudarnos a desenmarañar la estructura de una realidad más
compleja de lo que nuestras mentes pueden trabajar. Hacía tiempo que
tenía ganas de aprender un poco de <i>R</i> y he encontrado la excusa en el
clásico «por necesidades del trabajo». En el artículo de hoy quiero
contar lo sencillo que me ha sido montarme mi entorno en <i>Emacs</i> con
<i>ESS</i> para poder trabajar desde mi editor favorito.
</p>

<p>
Hace poco encontré, que cierto procedimiento estadístico, que uso con
cierta asiduidad, haciéndolo «a mano» con la ayuda de unos <i>scripts</i>,
tiene un módulo propio en <i>R</i>. Hace los cálculos completos, con
gráficos y todo, pues aunque dichos cálculos, no sean complicados de
hacer, sí son laboriosos y muchas veces <i>me conformo</i> con el cálculo
numérico más sencillo del <i>script</i>. El otro día, por accidente,
tropecé con dicho módulo y aprovechando que hace años que le tengo
ganas a <i>R</i> he decidido comenzar con dicho <i>lenguaje</i>...o
<i>sistema</i>... o <i>cosa</i>... para aprovechar la <i>excursión</i> y el espacio
que ocupará en el disco duro para algo más productivo que hacer unas
pequeñas estadísticas.
</p>
<div id="outline-container-orga37815f" class="outline-2">
<h2 id="orga37815f">¿Qué es R?</h2>
<div class="outline-text-2" id="text-orga37815f">
<p>
Esa pregunta es muy sencilla de hacer pero no tanto de responder.
Después de pasar un poco de tiempo intentando contestarla de manera
clara, sólo puedo asegurar que la respuesta no es unívoca. Incluso en
<a href="https://www.r-project.org">la propia página <i>web</i> de la herramienta</a> puedes encontrar referencias
donde se habla de <i>R</i> como un lenguaje de programación y donde se
habla de <i>R</i> como un entorno para el cálculo estadístico. Es un
proyecto <i>GNU</i> similar al <i>S</i> desarrollado por los laboratorios
<i>Bell</i>; tanto que la mayoría de los programas o <i>scripts</i> que tengas
en <i>S</i> correrán sin mayor problema en <i>R</i>. Para no alargarme, lo que
nos brinda se puede resumir en:
</p>

<ul class="org-ul">
<li>Gran capacidad para manejar y almacenar datos de manera efectiva.</li>
<li>Operadores para trabajar en cálculos con datos complejos como
<i>vectores</i>, <i>matrices</i> y otras agrupaciones de datos.</li>
<li>Una extensa colección de herramientas integradas para el análisis de
datos.</li>
<li>Capacidades gráficas para la representación de los datos
estadísticos.</li>
<li>Un lenguaje de programación completo, con sus correspondientes
bloques de código condicionales, bucles, funciones recursivas, etc.</li>
</ul>

<p>
Parece que todo el sistema está montado alrededor del <i>lenguaje R</i>
pero que muchos de sus usuarios prefieren pensar en él como un sistema
estadístico, con facilidad para ser extendido por paquetes. Puede
interactuar con código y librerías en otros lenguajes como <code>C</code>, <code>C++</code>
o <code>Fortran</code> y un usuario avanzado puede escribir directamente código
en <code>C</code> para manipular objetos <i>R</i>. (Después de esta primera lectura,
promete mucho el sistema).
</p>

<p>
Por lo que he visto, el lenguaje parece bastante <i>funcional</i>,
aplicando funciones a listas de datos, con recursividad, funciones
<i>lambda</i>, etc. No he profundizado mucho, pero es la sensación que me
da en estos primeros pasos de aprendizaje.
</p>

<p>
Instalando <i>R</i> encontré también <i>Rstudio</i> una aplicación que de
momento voy a dejar que ocupe algo de espacio en el disco duro.  Tan
solo la he abierto y parece un entorno bastante completo ─y por tanto
complejo─ que de momento no pretendo usar, pues me decanto más por
utilizar <i>Emacs</i> y <i>ESS</i>.
</p>
</div>
</div>
<div id="outline-container-org5b79cd0" class="outline-2">
<h2 id="org5b79cd0">ESS</h2>
<div class="outline-text-2" id="text-org5b79cd0">
<p>
<i>ESS</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> es un paquete también complejo para <i>Emacs</i>. Puede manejar
<i>R</i> pero hay otros lenguajes con los que puede trabajar. Su objetivo
es proporcionar una interfaz genérica para paquetes estadísticos.
Además, viene con una ayuda completa accesible desde el comando
habitual <code>C-h i</code>. Concretamente, lo que proporciona <i>ESS</i>, según la
propia ayuda:
</p>

<ul class="org-ul">
<li>Soporte para varios lenguajes: la familia <b>S</b> (R, S, S+); <b>SAS</b>;
<b>BUGS/JAGS</b>; <b>Stata</b>; <b>Julia</b>.</li>
<li>Edición de código de todos esos lenguajes.</li>
<li>Interacción con un proceso en ejecución:
<ul class="org-ul">
<li>Edición del <i>command-line</i></li>
<li>Historial del <i>command-line</i></li>
<li>Posibilidad de guardar el <i>log</i> del mismo</li>
<li>...</li>
</ul></li>
<li>Posibilidad de integrar páginas de ayuda y documentación de <i>R</i> (no
estoy seguro de si con otros lenguajes también funcionará ésta
funcionalidad, con <i>R</i> sí me ha funcionado, aunque a través de un
paquete del mismo <i>R</i>).</li>
</ul>

<p>
En fin, que proporciona <i>modos mayores</i> y <i>menores</i> que nos permitirán
trabajar con los mencionados sistemas estadísticos y lenguajes (que
por cierto a <i>Julia</i> también le tengo ganas).
</p>
</div>
<div id="outline-container-orgf8efbc8" class="outline-3">
<h3 id="orgf8efbc8">Instalación</h3>
<div class="outline-text-3" id="text-orgf8efbc8">
<p>
La instalación es sencilla con el sistema de paquetes de <i>Emacs</i>:
</p>

<pre class="example" id="orgdec8608">
M-x package-install RET ess RET
</pre>

<p>
Eso lo descarga y lo compila. Aunque si prefieres un método más
gráfico (y lento) puedes abrir la lista de paquetes con <code>M-x
list-packages</code> buscar el paquete <code>ess</code>, pinchar en el y luego en el
botón <i>install</i> lo instalará (que sé que hay gustos para todo).
</p>

<p>
La configuración que he metido en mi <code>init.el</code> es una sencilla línea:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">ess-r-mode</span>)
</pre>
</div>

<p>
Según la documentación, se especifica ese comando porque lo voy a
utilizar con <i>R</i>, pero también se puede utilizar el genérico:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">ess-site</span>)
</pre>
</div>

<p>
De momento, no he instalado nada más, aunque ojeando la lista de
paquetes he visto algunos dedicados a <i>ESS</i>, visualización de datos en
<i>Dired</i>, etc. que aún no sé si me serán útiles y que prefiero dejar
para cuando les encuentre su razón de ser. Tengo ya muchos paquetes
cargados en el pobre <code>init.el</code> y no me apetece cargar más que lo mismo
no utilizo.
</p>
</div>
</div>
<div id="outline-container-org63c3ad5" class="outline-3">
<h3 id="org63c3ad5">Interacción con ESS</h3>
<div class="outline-text-3" id="text-org63c3ad5">
<p>
He preparado un fichero muy sencillito donde defino una función de
incremento sólo para ver cómo funciona todo. Para hacer las pruebas he
creado un directorio <code>~/R</code> y he metido el siguiente código en un
fichero que he llamado <code>prueba-ess.R</code>:
</p>

<div class="org-src-container">
<pre class="src src-R">## Función de prueba para comprobar el funcionamiento de ESS.
## Devuelve el número incrementado en uno.

incremento &lt;- function (x) {
    return(x + 1)
}

incremento(3)
</pre>
</div>

<p>
Como podéis ver también he añadido una línea que llama a la función
para incrementar un 3, por lo que si lo corremos como <i>script</i>
devolverá <code>4</code>.
</p>

<p>
Al abrirlo con <code>C-x C-f ~/R/prueba-ess.R</code>, <i>Emacs</i> entra en el modo
<code>ESS</code>, especificando <code>ESS[R]</code> en la línea de estado. Lo que he
aprendido hasta ahora, es que nada más abrirlo, necesito abrir una
línea de comandos alternativa con la combinación de teclas <code>C-c C-z</code>,
para cargar el código. Al hacerlo, me pregunta por el directorio donde
quiero trabajar. Por defecto, me sugiere el mismo donde está el
fichero de código:
</p>

<p>
<code>R starting project directory? ~/R/</code>
</p>

<p>
Supongo, aunque no lo he probado, que esto se puede automatizar
asignando el <i>path</i> a alguna variable, aunque de momento no me parece
imprescindible hacerlo. Acepto ese directorio para el trabajo y me
aparece la consola en un <i>buffer</i> marcado como <code>*R*</code>:
</p>


<figure id="org6689ec1">
<img src="./imagenes/Captura-pantalla-ess-consola.png" alt="Captura-pantalla-ess-consola.png">

</figure>

<pre class="example" id="org95c4035">
&gt; setwd('/home/notxor/R/')
&gt; incremento(2)
Error in incremento(2) : no se pudo encontrar la función "incremento"
&gt; 
</pre>

<p>
Al intentar utilizar el código del fichero, como vemos, no funciona.
Sin embargo, al colocar el cursor en la definición de la función y
pulsar <code>C-c C-c</code> dicha función se carga en el <i>buffer</i> interactivo, y
el resultado ahora es el esperado:
</p>

<pre class="example" id="org543d661">
&gt; incremento(2)
[1] 3
&gt; 
</pre>

<p>
También puedes enviar una sola línea a la consola. Desde el <i>buffer</i>
de código. Situado el cursor en la línea <code>incremento(3)</code> se pulsa <code>C-c
RET</code> y en la consola aparece:
</p>

<pre class="example" id="org161be5d">
&gt; incremento(3)
[1] 4
</pre>

<p>
Para acceder a la ayuda con la combinación de teclas <code>C-c C-d</code> el
sistema me pidió instalar el paquete de <i>R</i> llamado <code>sos</code>. A partir de
ahí pude solicitar información de <i>R</i>. Por ejemplo, a través de la
<i>web</i> con <code>C-c C-d w</code>. 
</p>
</div>
</div>
</div>
<div id="outline-container-orgd4447a2" class="outline-2">
<h2 id="orgd4447a2">Conclusiones</h2>
<div class="outline-text-2" id="text-orgd4447a2">
<p>
De <i>R</i> sé lo básico, o como decía el dicho aquel: «necesito mejorar».
Sin embargo, todo lo que oigo sobre ese sistema es bueno.  Necesito un
sistema estadístico confiable y creo que el <i>tandem</i> de <i>R-Emacs</i>
puede ser mi herramienta. Además, no sólo me interesa el apartado
estadístico, ya sabéis que me encanta programar y el lenguaje de
programación <i>R</i>, sobre el que todo el mundo pasa de puntillas hasta
llegar a la estadística, tiene características interesantes que le
hacen candidato a ocupar su sitio entre los lenguajes <i>rarunos</i> que a
mí me gustan: <i>SmallTalk</i>, <i>LISP</i>, <i>erlang</i>... por el momento <i>R</i> se
está aproximando a ello aunque tiene un problema: en <i>SmallTalk</i> todo
es un objeto, en <i>LISP</i> todo es una lista, en <i>erlang</i> todo es un
proceso, en <i>R</i> no todo es algo, pero bueno, eso son minucias traídas
de los pelos. ;-)
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>(Emacs Speaks Statistics)</i> Literalmente <i>Emacs habla
estadística</i>.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/ess/index.html">ess</a> <a href="/tags/r/index.html">R</a> <a href="/tags/estadística/index.html">estadística</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[ess]]></category>
  <category><![CDATA[R]]></category>
  <category><![CDATA[estadística]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2021/12/12/estadistica-ess-en-emacs.html</link>
  <pubDate>Sun, 12 Dec 2021 09:41:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[TiddlyWiki y Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-12-03</div>
<p>
El otro día <a href="https://notxor.nueva-actitud.org/2021/11/23/tiddlywiki.html">ya hablé sobre TiddlyWiki</a> y hay quien me ha hablado como
si yo fuera alguna especie de traidor o hereje, por mirar otras
herramientas fuera del sagrado rito de <i>Emacs</i> y de la devoción al
santísimo <code>org-mode</code>. Pues ya me disculparéis, pero voy a seguir
haciéndolo y os voy a contar más cosas interesantes ─al menos para mí─
como puede ser la posibilidad de exportar un fichero <code>org</code> al formato
de sintaxis de los <code>tiddler</code> de <i>TiddlyWiki</i>.
</p>

<p>
Mi historia con <i>TiddlyWiki</i> es corta y comenzó con un error de
concepto. No sé si os habréis fijado, pero ha desaparecido del menú el
apartado de <i>Radio</i>. El <i>director</i> del programa decidió dejar de
hacerlo y no nos permitió continuar con él por tenerlo registrado a su
nombre. Por ello, he dejado de enlazar los audios. El tema es que el
resto de componentes del equipo decidimos continuar con nuestro propio
programa de radio. Se llamará «PICA La Actualidad» y hablaremos sobre
temas relacionados con la infancia y la adolescencia. Cuando
comencemos el programa, seguramente, el apartado de radio volverá a
aparecer en este <i>Blog</i>. Buscaba una herramienta que pudiéramos
manejar todos a la hora de preparar los programas, comentar temas e
informar en general, sobre los contenidos que vamos a trabajar.
Utilicé <i>TiddliWiki</i> porque me habían hablado muy bien de él y quería
probarlo y montar la <i>web</i> del programa (<a href="https://asociacionpica.org/radio">los curiosos que pinchen este
enlace</a>) con tres apartados diferentes:
</p>

<ol class="org-ol">
<li><i>Un lugar donde colgar los programas</i>. Bueno los programas estarán
enlazados en la <i>web</i> pero alojados en <a href="https://archive.org">archive.org</a>, porque no
tenemos mucho espacio.</li>
<li><i>Un lugar donde enlazar el contenido del programa</i>. Los temas de
los que hablaremos en el programa estarán disponibles para que
quien quiera pueda acceder a ellos. Citaremos y enlazaremos las
fuentes de los temas de los que hablaremos (ya hay algunos temas
enlazados y esperando a que hablemos, o no, de ellos).</li>
<li><i>Una</i> base de datos <i>donde enlazar otras asociaciones</i>. Dentro del
contenido del programa esperamos contar con otras asociaciones sin
ánimo de lucro que vengan y nos cuenten qué hacen. En la <i>web</i>
enlazaremos información a sus páginas, con sus teléfonos y correos
electrónicos para poder contactar con ellas.</li>
</ol>

<p>
He dicho antes que son <i>tres apartados</i>. En realidad, cada cosa está
en su propio <code>tiddler</code>, cada apartado es, simplemente, una etiqueta y
los <code>tiddlers</code> además de agruparse de esa manera, se pueden relacionar
también mediante enlaces. Pensamos que en el correspondiente a cada
programa se enlacen los temas de los que hablemos, las asociaciones
que se dediquen a ayudar a la sociedad con esos problemas, etc. Por si
no fuera suficiente relación, además los <code>tiddlers</code> tienen también
<i>campos</i> que pueden enlazar a otros <code>tiddlers</code> o a cualquier otros
datos (teléfonos, direcciones) o recursos que podamos necesitar
(documentación, <i>pdfs</i>, etc).
</p>

<p>
La <i>web</i> del programa ya está en marcha. Ha sido rápido, apenas he
tenido que hacer un par de <code>macros</code> para que haga los listados de las
diversas etiquetas y poco más. El usuario final, hecho todo esto, sólo
tiene que crear un <code>tiddler</code> con la etiqueta correspondiente o una
entrada del <i>diario</i> para el programa que quiera enlazar y todo el
sistema se organiza sólo, añade la nueva entrada en su correspondiente
lista (o listas) y no hay complicaciones con los enlaces ni con los
detalles, para la gente menos acostumbrada a trabajar con páginas
<i>web</i>. Además al estar todo embebido dentro de un fichero único, la
actualización es tan sencilla como sustituirlo con la nueva versión en
el sitio.
</p>

<p>
En mi caso, acostumbrado a trabajar con los comandos de teclado de
<i>Emacs</i> y redactar directamente <i>teniendo el C2</i> de <code>org-mode</code> me
resulta un poco lioso el editar el contenido en el mismo <i>TiddlyWiki</i>
y prefiero trabajar con mi editor favorito. He probado un <i>plugin</i> que
permite cambiar el editor y ponerle atajos de teclado al estilo de
<i>Emacs</i>, pero me he encontrado que algunos cambian ligeramente (en
lugar de pulsar <code>Ctrl</code> hay que pulsar <code>Alt</code>, que no es muy diferente),
pero me hago un lío. Buscando alternativas encontré dos paquetes que
pueden venir bien:
</p>

<ul class="org-ul">
<li><code>ox-tiddly</code>: permite exportar desde <code>org-mode</code> a formato de
<i>TiddlyWiki</i>, aunque con algunos problemas, porque el lenguaje de
los <i>tiddler</i> ha evolucionado desde que este paquete hizo su última
actualización en septiembre de 2020.</li>
<li><code>tid-mode</code>: En la documentación de <i>TiddlyWiki</i> mencionan este
que facilita la edición de archivos <code>.tid</code>. Especialmente
recomendable cuando se utiliza <code>tiddliwiki</code> en la versión <code>node.js</code>,
que en lugar de empaquetarse todo en un <code>.html</code>, se distribuye por
directorios y ficheros individuales (el modo más afín a otros
<i>wikis</i>). Pero también es de hace 8 años y por lo que he visto en el
código (no he llegado a instalarlo), sólo se preocupa de mantener
actualizado el campo de modificación del <code>tiddler</code></li>
</ul>
<div id="outline-container-orgd0cdaf5" class="outline-2">
<h2 id="orgd0cdaf5"><code>ox-tiddly</code></h2>
<div class="outline-text-2" id="text-orgd0cdaf5">
<p>
<code>ox-tiddly</code> es un paquete que permite exportar desde <code>org-mode</code> a
formato <code>tiddler</code>. La lástima es que es antiguo y las nuevas versiones
de <i>TiddlyWiki</i> han cambiado un poco las cosas, así pues, a pesar de la
exportación hay que dedicarle un poco de <i>cariño</i> al contenido
exportado. He preparado un ejemplo de contenido para convertirlo. Como
he dicho antes, este paquete hizo su última actualización hace más de
un año.
</p>

<p>
Para las pruebas he creado un nuevo <i>TiddlyWiki</i> con algunos <i>plugins</i>
instalados:
</p>

<ul class="org-ul">
<li>Idioma en español.</li>
<li><code>CodeMirror</code>: editor avanzado con completado de sintaxis y otras
características por si había que editar mucho (con los atajos de
teclado de <i>Emacs</i>).</li>
<li><code>Highlight</code>: coloreado de sintaxis de los bloques de código.</li>
</ul>

<p>
Todo lo demás de serie, cambiando sólo en el aspecto, la plantilla de
colores y añadir a las barras de edición algunos botones que por
defecto están ocultos (como el de importación, que es el icono de
<i>clip</i> para sujetar hojas que hay a la derecha, o el de información de
un <i>tiddler</i> que es la «i» con circulo de las tarjetas). La cosa quedó
así:
</p>


<figure id="orgbf05f62">
<img src="./imagenes/Captura-pantalla-tiddlywiki-ejemplo.png" alt="Captura-pantalla-tiddlywiki-ejemplo.png">

</figure>

<p>
La apariencia es lo de menos, el problema es que al exportar e
importar el <code>org</code> de prueba al formato <code>tid</code>, como decía es que
utiliza un formato antiguo y el resultado es:
</p>


<figure id="org02c9eec">
<img src="./imagenes/Captura-pantalla-exportacion-fallida.png" alt="Captura-pantalla-exportacion-fallida.png">

</figure>

<p>
Como se puede apreciar en la imagen se pueden detectar algunos
problemas, por ejemplo:
</p>

<ul class="org-ul">
<li>La fuente tachada no funciona. El exportador lo codifica como
<code>==tachado==</code>, cuando debería ser <code>~~tachado~~</code>.</li>
<li>Al llegar al texto de fuente fija, el exportador lo codifica como
<code>`fuente fija'</code>, cuando debería ser <code>`fuente fija`</code>. A partir de
ahí, como le falta el código de cierre para ese estilo de texto,
convierte todo el contenido en fuente fija.</li>
</ul>

<p>
Por lo menos, el exportador, lo que hace es generar un <i>buffer</i> y
abrirlo para edición. Voy a arreglar esos dos errores y veremos cómo
se comporta. También al principio del código añade un macro <code>&lt;&lt;ToC&gt;&gt;</code>
que ya no se utiliza y que voy a cambiar por algunas
etiquetas. Concretamente:
</p>

<pre class="example" id="orgc96b80a">
title: MiExportaciónUno
caption: Exportación hecha con un poco más de cariño
tags: Prueba [[porque sí]]

! {{!!caption}}
</pre>

<p>
Eso lo escribo al comienzo del <i>buffer</i> y dejo el resto igual. Al
hacer ahora la importación, vemos que esos valores se importan
correctamente al <i>tiddler</i>:
</p>


<figure id="org4245eda">
<img src="./imagenes/Captura-pantalla-mejorando-exportacion.png" alt="Captura-pantalla-mejorando-exportacion.png">

</figure>

<p>
Vemos que el bloque de código <code>html</code> (que en realidad contiene una
etiqueta <code>svg</code> reciclada de otro artículo) se exporta correctamente,
sin embargo, ni el bloque <code>quote</code> se exporta bien, ni el código del
gráfico ni el gráfico y tampoco el bloque de código <code>javascript</code>.
</p>

<p>
Pero quería ver cómo se desenvuelve con las tablas, también. Viendo el
éxito de la importación de etiquetas y que la <i>exportación</i> pura y
dura funciona, pues modifiqué el <code>org</code> para necesitar menos edición:
</p>


<figure id="orgbdbd7ee">
<img src="./imagenes/Captura-pantalla-importacion-completa.png" alt="Captura-pantalla-importacion-completa.png">

</figure>

<p>
Para llegar a ese resultado tuve que editar el <i>buffer</i> del <i>tiddler</i>
cambiando los bloques <code>{{{texto}}}</code> por bloques <code>```texto```</code>. El
bloque <code>quote</code> en <code>tid</code> tiene que ir entre dos etiquetas <code>&lt;&lt;&lt;</code> y ya
también aparece correctamente y, por último, la tabla, que yo había
creado así:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #bd93f9;">| Etiqueta | Valor         |</span><span style="color: #bd93f9;">
</span><span style="color: #bd93f9;">|----------+---------------|</span><span style="color: #bd93f9;">
</span><span style="color: #bd93f9;">| title    | {{!!title}}   |</span><span style="color: #bd93f9;">
</span><span style="color: #bd93f9;">| caption  | {{!!caption}} |</span><span style="color: #bd93f9;">
</span><span style="color: #bd93f9;">| tags     | {{!!tags}}    |</span><span style="color: #bd93f9;">
</span><span style="color: #bd93f9;">|          |               |</span>
</pre>
</div>

<p>
Al final la tuve que editar también, eliminando algún carácter «|» que
sobraba y añadiendo algún «!» para hacer las cabeceras. El enlace al
fichero gráfico no funcionaba así que lo modifiqué escribiéndolo como
se haría en <i>TiddlyWiki</i> directamente. Borré el bloque <code>#+RESULTS:</code> y
metí antes del bloque de código lo siguiente:
</p>

<pre class="example" id="orge7f26a8">
@@float:right;
[img[procesos-graphviz.svg]]
@@
</pre>

<p>
Para finalizar todo proceso encontré mucho más cómoda la edición del
<i>tiddler</i> directamente en <i>TiddlyWiki</i> y el resultado final, con la
información del <i>tiddler</i> importado quedó así:
</p>


<figure id="org047f8f8">
<img src="./imagenes/Captura-pantalla-tiddler-info-final.png" alt="Captura-pantalla-tiddler-info-final.png">

</figure>
</div>
</div>
<div id="outline-container-orgd31d21c" class="outline-2">
<h2 id="orgd31d21c">Conclusiones</h2>
<div class="outline-text-2" id="text-orgd31d21c">
<p>
El lenguaje de marcado que utiliza <i>TiddlyWiki</i> es muy sencillo y la
conversión desde <code>org-mode</code> no debería ser compleja:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Función</th>
<th scope="col" class="org-left">org-mode</th>
<th scope="col" class="org-left">tid</th>
<th scope="col" class="org-left">observaciones</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">negrita</td>
<td class="org-left"><code>* ... *</code></td>
<td class="org-left"><code>'' ... ''</code></td>
<td class="org-left">2 caracteres «'» en cada lado</td>
</tr>

<tr>
<td class="org-left">cursiva</td>
<td class="org-left"><code>/ ... /</code></td>
<td class="org-left"><code>// ... //</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">subrayado</td>
<td class="org-left"><code>_ ..._</code></td>
<td class="org-left"><code>__ ... __</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">tachado</td>
<td class="org-left"><code>+ ... +</code></td>
<td class="org-left"><code>~~ ... ~~</code></td>
<td class="org-left">&#xa0;</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">Encabezado 1</td>
<td class="org-left"><code>*</code></td>
<td class="org-left"><code>!</code></td>
<td class="org-left">Cambia «*» por «!»</td>
</tr>

<tr>
<td class="org-left">Encabezado 2</td>
<td class="org-left"><code>**</code></td>
<td class="org-left"><code>!!</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Encabezado 3</td>
<td class="org-left"><code>***</code></td>
<td class="org-left"><code>!!!</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">...</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Encabezado 6</td>
<td class="org-left"><code>******</code></td>
<td class="org-left"><code>!!!!!!</code></td>
<td class="org-left">&#xa0;</td>
</tr>
</tbody>
</table>

<p>
Los enlaces los dejo aparte, porque <i>TiddlyWiki</i> tiene, aparte de los
enlaces entre <i>tiddlers</i>, que utilizan el formato
<code>[[texto|NombreTiddler]]</code> o los enlaces externos <code>[[texto|URL]]</code>,
también puedes enlazar con formatos más específicos como
<code>[img[nombre-fichero]]</code> para la imagen... y también puede enlazar a
<i>macros</i> de la aplicación o definidos por el usuario mediante <code>&lt;&lt;
... &gt;&gt;</code> o enlazar a listas, por ejemplo de <i>etiquetas</i> mediante
<code>[tag[etiqueta]]</code> o hacer referencia a una etiqueta con
<code>{{NombreTidller!!etiqueta}}</code> (si la etiqueta pertenece al <i>tidler</i>
actual, basta con <code>{{!!etiqueta}}</code>).
</p>

<p>
Como se puede apreciar son sistemas muy parecidos, quitando la gran
posibilidad de enlazar distinto tipo de información que tiene
<i>TiddlyWiki</i>. Sin entrar en otras características como los <i>widgets</i>
que tienen también sus cosas.
</p>

<p>
Después de trabajar unos días con esta herramienta hay veces que echo
de menos la facilidad de edición que tengo con <i>Emacs</i> y la
simplicidad de hacer un poco de código que me automatice cosas.
</p>
</div>
<div id="outline-container-org0117ade" class="outline-3">
<h3 id="org0117ade">Ventajas e inconvenientes</h3>
<div class="outline-text-3" id="text-org0117ade">
<p>
A estas alturas no creo descubrir a nadie que no existe nada que sea
perfecto y cuando hablamos de <i>software</i> aún menos. Lo más parecido a
la perfección es <i>Emacs</i> y yo me manejo decentemente con él, sin
embargo necesita una curva de aprendizaje que para personal
acostumbrado sólo a pulsar botones y <i>pichorros</i> es directamente un
muro.
</p>

<p>
Si el objetivo es tener una página <i>web</i> basada en <i>wiki</i> que puedan
usar y manejar varios usuarios, <i>Emacs</i> y su poderoso <code>org-mode</code> no es
una opción factible para todo el equipo. Todas las opciones tienen sus
<i>pros</i> y sus <i>contras</i>.
</p>

<p>
Los principales <i>pros</i> de <i>Emacs</i> para hacerlo todo con él son:
Sistema muy potente que, menos café, hace de todo. Fácil de programar,
fácil de extender. Exporta a un sinfín de tipos de documentos: <code>pdf</code>,
<code>html</code>, <code>LibreOffice</code>.
</p>

<p>
Los principales <i>pros</i> de <i>TiddlyWiki</i> son la facilidad de edición de
contenido y la facilidad de modificar el sistema para ajustar su
apariencia. El que soporte varias formas de enlazar los contenidos.
Los detalles no son tan fáciles, pero editar el contenido lo puede
hacer cualquiera.
</p>

<p>
El único <i>contra</i> de <i>Emacs</i> es la complejidad de instalarse un
sistema desconocido y aprender todos los detalles que hay que saber
para encontrarse suelto con él. El sitio se generaría mediante un
fichero de código, con una estructura de directorios más o menos
compleja. Sin embargo, en <i>TiddlyWiki</i> todo funciona dentro de un
único fichero <code>html</code> y el <i>deploy</i> es tan sencillo como copiarlo en el
lugar apropiado.
</p>

<p>
Los ejemplos utilizados en este artículo los podéis bajar de los
siguientes enlaces:
</p>

<ul>
  <li><a href="./wiki-de-ejemplo.html" target="_blanck">El <em>TiddlyWiki</em> de ejemplo</a></li>
  <li><a href="./export-import-org-tid.org" target="_blanck">El fichero <em>org</em> de ejemplo</a></li>
</ul>
</div>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/tiddlywiki/index.html">tiddlywiki</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[tiddlywiki]]></category>
  <link>https://notxor.nueva-actitud.org/2021/12/03/tiddlywiki-y-emacs.html</link>
  <pubDate>Fri, 03 Dec 2021 20:04:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[TiddlyWiki]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-11-23</div>
<p>
Por algunas razones que no alcanzo a entender <code>org-roam</code> se ha vuelto
un monstruo y, para mi gusto, se ha desorbitado. O quizá es que me
sobrepasa a mí, particularmente y no termino de pillarle la gracia
como sí he hecho con otras funcionalidades y extensiones de <i>Emacs</i>.
El caso es que andaba en búsqueda de una herramienta para tomar mis
notas, algo que no fuera un sistema jerárquico artificial de
dividirlas, como en muchos sistemas de anotación que se utilizan, y
para lo que <i>Zettelkasten</i> es una solución mucho mejor. En este
artículo os contaré la peripecia y cómo he comenzado a utilizar
<i>TiddlyWiki</i>.
</p>

<p>
Para no perderme en la historia comenzaré por el principio: buscaba
algún sistema <i>Zettelkasten</i> funcional, de mi agrado, que me
permitiera mi dispersión de ideas sin encorsetarlas en una jerarquía
que tarde o temprano se mostrará demasiado rígida para contenerlo
todo. De ese modo llegué <a href="https://zettelkasten.sorenbjornstad.com">a una página que mostraba un ejemplo</a> completo
realizado por <a href="https://www.sorenbjornstad.com">Soren Bjornstad</a> y que utilizaba un sistema <i>Wiki</i>
llamado <b><i>TiddlyWiki</i></b>. «Bueno, es un <i>wiki</i>, las ideas, los
conceptos, las notas, se relacionan por enlaces... puede funcionar»,
pensé y me puse a investigar más sobre el asunto.
</p>
<div id="outline-container-org8f12046" class="outline-2">
<h2 id="org8f12046">El sistema</h2>
<div class="outline-text-2" id="text-org8f12046">
<p>
<a href="https://tiddlywiki.com/languages/es-ES/index.html">El sistema <i>TiddlyWiki</i> es un sistema <i>wiki</i> autocontenido</a>. No sé muy
bien si esa es la palabra que mejor lo define, pues también hay una
versión de <i>escritorio</i> que corre sobre <code>node.js</code>. A lo que me refiero
con autocontenido es a que te descargas un fichero <code>.html</code> y el código
y los datos van en él. Cuando haces modificaciones, guardas el fichero
con <code>C-s</code> y se copia completo, con el código y los datos que hayas
modificado. No funciona el menú <code>Archivo → Guardar como...</code> del
navegador, no guarda bien la información.
</p>

<p>
<i>Cacharrendo</i> llevo unos días con él y veo que es muy complejo. Me he
visto obligado a admitir la máxima que me impuse con <i>Emacs</i>: «No hay
soluciones simples para problemas complejos». Y los <i>plugins</i> no
hacen, sino multiplicar sus capacidades. Tengo anotado en pendientes
comprobar cómo va el <i>plugin</i> para importar bases de datos <code>bibtex</code> y
qué se puede hacer con ello.
</p>

<p>
Para empezar, la base de toda la información se encuentra en lo que
llaman <i>tiddlers</i>, que son el equivalente a las <i>tarjetas</i> del sistema
<i>Zettelkasten</i>. Cada pieza de información se guarda en un <i>tiddler</i>,
desde la más simple a la más compleja y está accesible mediante su
propio <i>link</i>. Por ejemplo, si creamos una etiqueta se guardará en un
<i>tiddler</i> pero se mostrará además dentro de otros <i>tiddlers</i> cuando la
utilicemos. Ese anidamiento es muy potente, podemos mostrar unos
<i>tiddlers</i> dentro de otros, se pueden crear contenedores, <i>widgets</i>,
enlaces internos y externos, seguramente algunas cosas más que aún
desconozco como los <i>macros</i> y que harán que me explote la cabeza.
</p>

<p>
Tiene <i>links</i> por todas partes. Por ejemplo, hay un panel de <i>info</i> en
todo <i>tiddler</i> que indica los <i>tiddlers</i> enlazados y también los
<i>tiddlers</i> que lo enlazan. Así nos facilita llegar a cualquier tipo de
información siguiendo el rastro de enlaces. Se pueden listar
<i>tiddlers</i> por etiquetas, los huérfanos, los que enlazan o son
enlazados por otros.
</p>

<p>
El contenido de un <i>tiddler</i> puede ser muy variopinto, como dije
antes, puede contener la definición de una etiqueta, pero también
puede estar generado por un <i>macro</i> para formar una lista, o
importarlo de otros <i>tiddler</i>, como por ejemplo hace el menú de
opciones o el <i>panel de control</i>, que es el resultado de contener en
un <i>tiddler</i> varios formularios incrustados en otros
<i>tiddlers</i>. Efectivamente, si modificamos cualquier valor en ese
formulario, se modificará el <i>tiddler</i> base y, por tanto, todos los
<i>tiddler</i> que lo lleven incrustado se verán modificados. En ese
sentido me recuerda a cómo funciona una hoja de cálculo cuando
aprendes a enlazar celdas mediante fórmulas, en lugar de trabajar con
valores directos, todo se recalcula en cuanto haces una modificación.
</p>
</div>
</div>
<div id="outline-container-org220cad1" class="outline-2">
<h2 id="org220cad1">Modo de uso</h2>
<div class="outline-text-2" id="text-org220cad1">
<p>
He visto, desde que empecé a curiosear, varias cosas hechas con esta
herramienta. Desde la propia página web de <i>TiddlyWiki</i> hasta blogs,
libros y un sin fin de información.
</p>

<p>
Lo más básico es descargarse el <i>sofware</i>, que como ya he dicho es una
página web que se verá así en el navegador:
</p>


<figure id="orgdaa81ee">
<img src="./imagenes/Captura-tiddlywiki-empty.png" alt="Captura-tiddlywiki-empty.png">

</figure>

<p>
En esa pantalla se pueden configurar los parámetros básicos del
proyecto. Como se puede observar por la <i>URL</i> se ha descargado un
fichero que se llama <code>empty.html</code> y que contiene todo el código que
necesitas para hacerlo funcionar. La ventana se divide en dos partes
claramente diferenciadas, la parte izquierda contiene los <i>tiddlers</i>,
o <i>tarjetas</i> si prefieres llamarlo así, y la parte derecha es una
barra de herramientas con <i>widgets</i> e información que nos permite
navegar y modificar nuestro <i>wiki</i>.
</p>

<p>
El <i>tiddler</i> que se muestra es el <i>GettingStarted</i>, que como su nombre
indica es donde comienza todo <i>wiki</i>: proporcionando un título, un
subtítulo y algún dato más. Vamos a hacerle algunos cambios:
</p>


<figure id="org5700b80">
<img src="./imagenes/Captura-pantalla-inicio-wiki.png" alt="Captura-pantalla-inicio-wiki.png">

</figure>

<p>
En la imagen anterior se puede apreciar que he modificado el título,
el subtítulo y he añadido un nuevo enlace a los <i>tiddlers</i> abiertos
por defecto. Se puede ver, que el sistema ha marcado en rojo el botón
de <i>guardar cambios</i>... al pulsarlo, aparece un mensaje de «saved
wiki» y vuelve a su color normal. Los iconos que hay al lado sirven
para crear nuevos <i>tiddler</i> con el más y para configuración con la
rueda dentada. Si pulsamos el <code>+</code> crearemos nuestro primer <i>tiddler</i> y
como vemos en la captura viene con un editor para facilitarnos la
vida:
</p>


<figure id="org32b3363">
<img src="./imagenes/Captura-pantalla-crear-tiddler.png" alt="Captura-pantalla-crear-tiddler.png">

</figure>

<p>
La primera línea del formulario está para que le pongamos un nombre.
En este caso lo he llamado «Mi primer tiddler». La siguiente línea nos
permite colocarle alguna etiqueta para facilitar búsquedas
posteriores. El siguiente bloque es el editor, que cuenta a su vez con
una zona de previsualización del texto. La sintaxis del texto es muy
parecida a <code>markdown</code> o a <code>org-mode</code>. También podemos seleccionar el
tipo de contenido, y hay bastante donde elegir, que va a tener el
<i>tiddler</i>. En este caso es <i>texto plano</i>, pero también podemos meter
otros tipos de contenido como <code>javascript</code>, por ejemplo, o <code>html</code>, o
gráficos <code>svg</code>. Y por último se pueden añadir <i>campos</i> con distinto
valor. Por ejemplo, he añadido un cambo <i>author</i> con nombre
<i>Notxor</i>. Estos campos son visibles en el <i>desplegable</i> de información
que tiene cada tarjeta y que se despliega con el menú de visualización
propio. Los iconos de arriba a la derecha nos permite guardar o
eliminar el <i>tiddler</i>, según le demos al icono <i>check</i> o al cubo de
basura.
</p>

<p>
Por poner otro ejemplo, vamos a ver cómo se configura para las
diversas lenguas, en concreto para la española, instalando el <i>plugin</i>
de idioma. Los pasos son muy sencillos:
</p>

<ol class="org-ol">
<li><p>
En la barra lateral, pulsamos el botón de la rueda dentada (o
cualquier enlace que veamos a <i>ControlPanel</i>)
</p>


<figure id="org6228279">
<img src="./imagenes/Captura-pantalla-control-panel.png" alt="Captura-pantalla-control-panel.png">

</figure></li>

<li><p>
Pinchamos en la pestaña <i>plugins</i> y dentro de ella en el botón <i>Get
more plugins</i> para que nos aparezca:
</p>


<figure id="org651ef95">
<img src="./imagenes/Captura-pantalla-get-more-plugins.png" alt="Captura-pantalla-get-more-plugins.png">

</figure>

<p>
Pinchamos en el botón <i>open plugin library</i> y nos abre una lista de
<i>plugins</i> por categorías, que se encuentra en la web de la
aplicación. Pinchamos en <code>languages</code>.
</p>


<figure id="org3207059">
<img src="./imagenes/Captura-pantalla-lenguajes.png" alt="Captura-pantalla-lenguajes.png">

</figure>

<p>
Aquí seleccionamos el lenguaje que deseamos utilizar pulsando en el
botón <i>install</i> correspondiente. Una vez hecho, podemos cerrar esta
ventana pulsando en <i>close</i>.
</p>


<figure id="org4083d0d">
<img src="./imagenes/Captura-pantalla-plugin-guardado.png" alt="Captura-pantalla-plugin-guardado.png">

</figure>

<p>
Ya tenemos el <i>plugin</i> guardado en nuestro <i>wiki</i> y lo podemos
utilizar.
</p></li>

<li><p>
Volvemos a la pestaña <i>info</i> del <i>ControlPanel</i> y bajamos a la
etiqueta <i>Hello! Current Lenguage</i>, en el desplegable seleccionamos
el idioma que queramos, en mi caso <i>Castellano - España</i> y nos
aparecerá todo en español.
</p>


<figure id="orgf1ba566">
<img src="./imagenes/Captura-pantalla-cambiado-lenguaje.png" alt="Captura-pantalla-cambiado-lenguaje.png">

</figure></li>
</ol>

<p>
Se puede apreciar que hay procedimientos muy sencillos, como éste, que
no haría falta ni mencionar aquí. Cualquier usuario acostumbrado a
trabajar con <i>GUI</i> llegará a la misma conclusión (una vez haya
encontrado los botones y menús correspondientes).
</p>

<p>
Pero lo primero que me llamó la atención del sistema este, es la
capacidad de organizar la información mediante esas pestañas y menús,
metiendo <i>tiddlers</i> dentro de <i>tiddlers</i>, enlazando contenido y
creando complejas estructuras que permiten hasta la propia gestión y
configuración del sistema.
</p>

<p>
También encontré un paquete <code>ox-tiddly</code>, que permite exportar
contenido desde <code>org-mode</code> a esta herramienta.
</p>
</div>
</div>
<div id="outline-container-org569547d" class="outline-2">
<h2 id="org569547d">Conclusiones</h2>
<div class="outline-text-2" id="text-org569547d">
<p>
Es aún prematuro decir si esta herramienta ha llegado para quedarse.
De momento es un descubrimiento que tenía relegado en algún rincón de
mi cerebro. Lo había visto mencionado en algún sitio, me había
encontrado alguna referencia, pero siempre había sido un <i>software</i>
sobre el que pasaba de puntillas sin hacerle mucho caso. Sin embargo,
me parece de esas cosas que me <i>pican</i>, como hizo <i>Emacs</i> en su día, y
no estoy diciendo que lo considere como <i>Emacs</i>, ni mucho menos. Pero
es de esas herramientas que la gente no usa porque aprenderlo implica
cierto esfuerzo por parte del nuevo usuario.
</p>

<p>
De momento, sigo en modo aprendizaje
<a href="https://groktiddlywiki.com/read/">leyendo un libro hecho con la misma herramienta</a>
que parece que trata más aspectos de los que podría haber supuesto en
una primera aproximación. Y mira que no soy muy amante de <code>javascript</code>
y que esta puede ser la única de las herramientas que me he encontrado
hasta ahora, hechas con ese lenguaje, que me ha llamado la atención lo
suficiente como para plantearme el adoptarla.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/wiki/index.html">wiki</a> <a href="/tags/zettelkasten/index.html">zettelkasten</a> <a href="/tags/tiddlywiki/index.html">tiddlywiki</a> ]]></description>
  <category><![CDATA[wiki]]></category>
  <category><![CDATA[zettelkasten]]></category>
  <category><![CDATA[tiddlywiki]]></category>
  <link>https://notxor.nueva-actitud.org/2021/11/23/tiddlywiki.html</link>
  <pubDate>Tue, 23 Nov 2021 09:18:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Interactuando con SVG]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-10-30</div>
<p>
Estos días de atrás comencé a dar unas clases
<i>extracurriculares</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> sobre <i>robótica</i> en un colegio de Zaragoza.
Es un colegio concertado laico que da buen servicio a una población
con un amplio asentamiento de población migrante y de otros colectivos
en peligro de exclusión. El proyecto me pareció interesante y, aparte
del dinero que pagan ─que es poco, porque son dos horas a la semana─,
me atrajo en cuanto me lo propusieron. Todo lo que hago me lo suelo
tomar en serio y estas clases no son una excepción.  Preparándolas me
he llegado a liar con <i>presentaciones</i> e interacciones con elementos
educativos que hasta ahora no había tocado. Por ejemplo, me hice una
imagen <code>svg</code> de la tarjeta <i>micro</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> que utilizaremos en el
aula. Sin embargo, quería que esa imagen fuera interactiva y en este
artículo os cuento un poco de mis investigaciones sobre añadir
interacción a los gráficos vectoriales desde <code>javascript</code>. Como veis,
otra vez hago de psicólogo metido a programador.
</p>
<div id="outline-container-org06d3a49" class="outline-2">
<h2 id="org06d3a49">El formato <code>SVG</code></h2>
<div class="outline-text-2" id="text-org06d3a49">
<p>
No creo descubrir a nadie cómo es el formato <code>SVG</code>, si digo que dicho
formato es, básicamente, una clase de <code>XML</code> concebida para guardar
<i>objetos gráficos</i> en su estructura.  Hay mucha información sobre él a
través de <i>Internet</i>. Podemos escribir el código <code>XML</code> directamente en
un <i>buffer</i> de <i>Emacs</i> o editarlo como un gráfico vectorial con
<i>Inkscape</i>. Por ejemplo, podemos escribir el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-xml"><span style="color: #f8f8f2; background-color: #282a36;">&lt;?</span><span style="color: #ff79c6; font-weight: bold;">xml</span> <span style="color: #6272a4;">version="1.0" encoding="UTF-8" standalone="no"</span><span style="color: #f8f8f2; background-color: #282a36;">?&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">svg</span> <span style="color: #f8f8f2; font-weight: bold;">viewbox</span>=<span style="color: #f1fa8c;">"0 0 250 100"</span> <span style="color: #f8f8f2; font-weight: bold;">width</span>=<span style="color: #f1fa8c;">"250"</span> <span style="color: #f8f8f2; font-weight: bold;">height</span>=<span style="color: #f1fa8c;">"100"</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
    <span style="color: #6272a4;">&lt;!-- </span><span style="color: #6272a4;">Creo un c&#237;rculo</span><span style="color: #6272a4;"> --&gt;</span>
    <span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #50fa7b; font-weight: bold;">circle</span> <span style="color: #f8f8f2; font-weight: bold;">cx</span>=<span style="color: #f1fa8c;">"50"</span> <span style="color: #f8f8f2; font-weight: bold;">cy</span>=<span style="color: #f1fa8c;">"50"</span> <span style="color: #f8f8f2; font-weight: bold;">r</span>=<span style="color: #f1fa8c;">"40"</span> <span style="color: #f8f8f2; font-weight: bold;">stroke</span>=<span style="color: #f1fa8c;">"#006600"</span> <span style="color: #f8f8f2; font-weight: bold;">stroke-width</span>=<span style="color: #f1fa8c;">"4"</span> <span style="color: #f8f8f2; font-weight: bold;">fill</span>=<span style="color: #f1fa8c;">"#00cc00"</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
<span style="color: #f8f8f2; background-color: #282a36;">&lt;</span><span style="color: #f8f8f2; background-color: #282a36;">/</span><span style="color: #50fa7b; font-weight: bold;">svg</span><span style="color: #f8f8f2; background-color: #282a36;">&gt;</span>
</pre>
</div>

<p>
El resultado se puede visualizar directamente en <i>Emacs</i>, como he
dicho, pero lo podemos abrir también en <i>Inkscape</i> para una edición
gráfica más cómoda:
</p>


<figure id="org44da939">
<img src="./imagenes/Captura-pantalla_inkscape-circulo.png" alt="Captura-pantalla_inkscape-circulo.png">

</figure>

<p>
Si lo abrimos en <i>Emacs</i> podemos alternar entre el gráfico
</p>


<figure id="orga7f6c5f">
<img src="./imagenes/Captura-pantalla-svg-vista.png" alt="Captura-pantalla-svg-vista.png">

</figure>

<p>
y el código que lo genera, sólo pulsando <code>C-c C-c</code>.
</p>


<figure id="org9f63ee4">
<img src="./imagenes/Captura-pantalla-svg-codigo.png" alt="Captura-pantalla-svg-codigo.png">

</figure>

<p>
¿Cuándo elegir un modo u otro de edición? Pues depende
fundamentalmente del usuario. Para mi gusto, cuando los gráficos son
sencillos, como el anterior, hacerlo con el texto de forma directa
tampoco es muy complicado. Sin embargo, cuando se avanza en
complejidad el manejo del gráfico en un <i>buffer</i> de texto y poder
imaginarse el resultado que acarreará el texto que estamos
escribiendo, se puede complicar mucho y para ello es recomendable
utilizar un editor como <i>Inkscape</i>.
</p>

<p>
Sin embargo, si vamos a incluir <code>javascript</code> en el archivo, al final
lo tendremos que editar en modo texto, pues <i>Inkscape</i> no permite, por
lo menos todavía, añadir código de forma directa.
</p>
</div>
</div>
<div id="outline-container-orgd399653" class="outline-2">
<h2 id="orgd399653">Incluir gráficos vectoriales en <code>html</code></h2>
<div class="outline-text-2" id="text-orgd399653">
</div>
<div id="outline-container-orgd43bbd3" class="outline-3">
<h3 id="orgd43bbd3">Dentro de una etiqueta <code>img</code></h3>
<div class="outline-text-3" id="text-orgd43bbd3">
<p>
La principal ventaja de incluir gráficos vectoriales en nuestra
página, es que se puede escalar sin problemas de <i>pixelado</i>. Además,
el formato <code>.svg</code> es un estándar soportado por la mayoría de los
navegadores. Quizá haya problemas con los más antiguos, pero incluso
<i>Internet Explorer</i> comenzó a soportarlo desde su versión 9.
</p>

<p>
El caso es que hay varias formas de incrustar contenido <code>svg</code> en un
fichero <code>html</code>. De primeras pensé que daría igual cualquiera de las
maneras que hay. Puesto que la forma más simple de editar un gráfico
vectorial es con alguna aplicación que facilite la tarea como <a href="https://inkscape.org/es/">Inkscape</a>,
lo utilicé para dibujar la tarjeta por sus dos lados:
</p>


<figure id="org13c4d16">
<img src="./imagenes/tarjeta.svg" alt="tarjeta.svg" class="org-svg">

</figure>

<p>
También tengo imágenes separadas para ilustrar los eventos que se
producen. Lo que quería conseguir eran algunos efectos simples, como
que se <i>iluminaran</i> los <i>leds</i> cuando pasara el ratón por encima o que
al «pulsar uno de los botones» se iluminaran todos.
</p>

<p>
El gráfico así generado es de buena calidad y se visualiza
correctamente independientemente del tamaño de la imagen generada.  El
problema es que cuando se importa como se haría con cualquier fichero
gráfico, no se puede acceder a los objetos internos. Probé a meterle
el <code>javascript</code> dentro de la imagen. El problema es que algunos
eventos los realizaba correctamente y otros no. Por ejemplo, no me
captura bien el <code>onclick</code>.
</p>

<p>
Necesitaba probar otros métodos para hacerlo interactivo, pero dada la
complejidad del <code>svg</code> que necesitaba, no me atreví a hacerlo mediante
código y preferí mantener los gráficos dibujados con <i>Inkscape</i> aunque
lo que hice fue copiar directamente luego el contenido del fichero
gráfico en una página <code>html</code> dentro de una etiqueta <code>svg</code>. Esta
etiqueta dentro de un fichero <code>html5</code> se comporta como cualquier otra
etiqueta y puede contener etiquetas tanto <code>svg</code> como <code>html</code>. En el
ejemplo de más adelante lo veremos mejor ilustrado.
</p>
</div>
</div>
<div id="outline-container-org627ed2e" class="outline-3">
<h3 id="org627ed2e">La etiqueta <code>svg</code> a pelo</h3>
<div class="outline-text-3" id="text-org627ed2e">
<p>
Esta opción es la más funcional para lo que quiero hacer.  ¿Qué
ventajas tiene?
</p>

<ul class="org-ul">
<li>Se carga rápidamente porque el código está en el interior del mismo
<code>html</code>.</li>
<li>Se puede dar formato a los objetos desde la hoja de estilos <code>css</code>.</li>
<li>Los objetos internos del <code>svg</code> son accesibles desde <code>DOM</code>.</li>
</ul>

<p>
Por contra, no es tan <i>impermeable</i> como cargar un fichero de gráficos
externos: hay que tener cuidado con que no nos cambie los tipos de
letra u otras opciones. Si el fichero gráfico es muy complejo y optas
por copiar el código <code>XML</code> interno, después de haberlo hecho o
modificado con <i>Inkscape</i>, tienes que quitar algunas etiquetas
exclusivas del editor, no aportan nada, el navegador las ignorará,
pero no dejan de ser <i>peso muerto</i> en el mismo gráfico.
</p>
</div>
</div>
<div id="outline-container-org0b933a6" class="outline-3">
<h3 id="org0b933a6">Interacción</h3>
<div class="outline-text-3" id="text-org0b933a6">
<p>
Para ilustrar el artículo, he hecho un pequeño documento <code>html</code> para
interactuar con objetos <code>svg</code> desde el contenido del documento. No he
querido complicarlo demasiado. Apenas son dos objetos rectangulares y
un objeto <code>input</code> que sirve para establecer el redondeo de las
esquinas de dichos rectángulos. Cuando dicho <i>redondeo</i> de esquinas es
igual al ancho del objeto, parece un círculo, mientras que cuando el
valor de redondeo es 0 la figura es un perfecto cuadrado. Además en
uno de ellos se invierten los valores, de modo que mientras uno es
redondo el otro es cuadrado. Cuando el valor del <code>input</code> sea 20 (el
valor medio) ambos cuadrados serán idénticos.
</p>

<div class="org-src-container">
<pre class="src src-html">&lt;<span style="color: #ff79c6; font-weight: bold;">!DOCTYPE</span> html&gt;
&lt;<span style="color: #50fa7b; font-weight: bold;">html</span>&gt;
    &lt;<span style="color: #50fa7b; font-weight: bold;">head</span>&gt;
        &lt;<span style="color: #50fa7b; font-weight: bold;">title</span>&gt;<span style="font-weight: bold; text-decoration: underline;">SVG la cuadratura del c&#237;rculo</span>&lt;/<span style="color: #50fa7b; font-weight: bold;">title</span>&gt;
        &lt;<span style="color: #50fa7b; font-weight: bold;">meta</span> <span style="color: #f8f8f2; font-weight: bold;">charset</span>=<span style="color: #f1fa8c;">"UTF-8"</span>&gt;
    &lt;/<span style="color: #50fa7b; font-weight: bold;">head</span>&gt;
    &lt;<span style="color: #50fa7b; font-weight: bold;">body</span>&gt;
        &lt;<span style="color: #50fa7b; font-weight: bold;">h1</span> <span style="color: #f8f8f2; font-weight: bold;">align</span>=<span style="color: #f1fa8c;">"center"</span>&gt;<span style="font-weight: bold; text-decoration: underline;">La cuadratura del c&#237;rculo</span>&lt;/<span style="color: #50fa7b; font-weight: bold;">h1</span>&gt;
        <span style="color: #6272a4;">&lt;!-- </span><span style="color: #6272a4;">Se pueden utilizar estilos para el objeto SVG</span><span style="color: #6272a4;"> --&gt;</span>
        &lt;<span style="color: #50fa7b; font-weight: bold;">style</span>&gt;
         .verde {
             stroke: #006600;
             fill  : #00cc00;
         }
         .rojo {
             stroke: #660000;
             fill  : #cc0000;
         }
        &lt;/<span style="color: #50fa7b; font-weight: bold;">style</span>&gt;
        <span style="color: #6272a4;">&lt;!-- </span><span style="color: #6272a4;">Se pueden agrupar elementos SVG en otros objetos HTML</span><span style="color: #6272a4;"> --&gt;</span>
        &lt;<span style="color: #50fa7b; font-weight: bold;">p</span> <span style="color: #f8f8f2; font-weight: bold;">align</span>=<span style="color: #f1fa8c;">"center"</span>&gt;
          &lt;<span style="color: #50fa7b; font-weight: bold;">svg</span> <span style="color: #f8f8f2; font-weight: bold;">viewBox</span>=<span style="color: #f1fa8c;">"0 0 250 100"</span> <span style="color: #f8f8f2; font-weight: bold;">width</span>=<span style="color: #f1fa8c;">"250"</span> <span style="color: #f8f8f2; font-weight: bold;">height</span>=<span style="color: #f1fa8c;">"100"</span>&gt; 
            &lt;<span style="color: #50fa7b; font-weight: bold;">a</span> <span style="color: #f8f8f2; font-weight: bold;">target</span>=<span style="color: #f1fa8c;">"_blank"</span>
               <span style="color: #8be9fd; font-style: italic;">xlink</span>:<span style="color: #f8f8f2; font-weight: bold;">href</span>=<span style="color: #f1fa8c;">"https://www.w3.org/Graphics/SVG/"</span>&gt;
              &lt;<span style="color: #50fa7b; font-weight: bold;">rect</span> <span style="color: #f8f8f2; font-weight: bold;">id</span>=<span style="color: #f1fa8c;">"circulo"</span> <span style="color: #f8f8f2; font-weight: bold;">x</span>=<span style="color: #f1fa8c;">"50"</span> <span style="color: #f8f8f2; font-weight: bold;">y</span>=<span style="color: #f1fa8c;">"10"</span> <span style="color: #f8f8f2; font-weight: bold;">rx</span>=<span style="color: #f1fa8c;">"40"</span> <span style="color: #f8f8f2; font-weight: bold;">ry</span>=<span style="color: #f1fa8c;">"40"</span> <span style="color: #f8f8f2; font-weight: bold;">height</span>=<span style="color: #f1fa8c;">"80"</span> <span style="color: #f8f8f2; font-weight: bold;">width</span>=<span style="color: #f1fa8c;">"80"</span> <span style="color: #f8f8f2; font-weight: bold;">stroke-width</span>=<span style="color: #f1fa8c;">"4"</span> <span style="color: #f8f8f2; font-weight: bold;">class</span>=<span style="color: #f1fa8c;">"verde"</span>/&gt;
            &lt;/<span style="color: #50fa7b; font-weight: bold;">a</span>&gt;
            &lt;<span style="color: #50fa7b; font-weight: bold;">rect</span> <span style="color: #f8f8f2; font-weight: bold;">id</span>=<span style="color: #f1fa8c;">"cuadrado"</span> <span style="color: #f8f8f2; font-weight: bold;">x</span>=<span style="color: #f1fa8c;">"150"</span> <span style="color: #f8f8f2; font-weight: bold;">y</span>=<span style="color: #f1fa8c;">"10"</span> <span style="color: #f8f8f2; font-weight: bold;">rx</span>=<span style="color: #f1fa8c;">"0"</span> <span style="color: #f8f8f2; font-weight: bold;">ry</span>=<span style="color: #f1fa8c;">"0"</span> <span style="color: #f8f8f2; font-weight: bold;">height</span>=<span style="color: #f1fa8c;">"80"</span> <span style="color: #f8f8f2; font-weight: bold;">width</span>=<span style="color: #f1fa8c;">"80"</span> <span style="color: #f8f8f2; font-weight: bold;">stroke-width</span>=<span style="color: #f1fa8c;">"4"</span> <span style="color: #f8f8f2; font-weight: bold;">class</span>=<span style="color: #f1fa8c;">"rojo"</span>/&gt;
          &lt;/<span style="color: #50fa7b; font-weight: bold;">svg</span>&gt;
        &lt;/<span style="color: #50fa7b; font-weight: bold;">p</span>&gt;
        &lt;<span style="color: #50fa7b; font-weight: bold;">div</span> <span style="color: #f8f8f2; font-weight: bold;">align</span>=<span style="color: #f1fa8c;">"center"</span>&gt;
            <span style="color: #6272a4;">&lt;!-- </span><span style="color: #6272a4;">Las interacciones pueden realizarse a trav&#233;s de formularios</span><span style="color: #6272a4;"> --&gt;</span>
            &lt;<span style="color: #50fa7b; font-weight: bold;">input</span> <span style="color: #f8f8f2; font-weight: bold;">type</span>=<span style="color: #f1fa8c;">"range"</span> <span style="color: #f8f8f2; font-weight: bold;">id</span>=<span style="color: #f1fa8c;">"rango"</span> <span style="color: #f8f8f2; font-weight: bold;">min</span>=<span style="color: #f1fa8c;">"0"</span> <span style="color: #f8f8f2; font-weight: bold;">max</span>=<span style="color: #f1fa8c;">"40"</span> <span style="color: #f8f8f2; font-weight: bold;">value</span>=<span style="color: #f1fa8c;">"40"</span> <span style="color: #f8f8f2; font-weight: bold;">oninput</span>=<span style="color: #f1fa8c;">"cuadratura(this.value)"</span> <span style="color: #f8f8f2; font-weight: bold;">width</span>=<span style="color: #f1fa8c;">"250"</span>&gt;
            &lt;<span style="color: #50fa7b; font-weight: bold;">p</span> <span style="color: #f8f8f2; font-weight: bold;">id</span>=<span style="color: #f1fa8c;">"etiqueta"</span>&gt;40&lt;/<span style="color: #50fa7b; font-weight: bold;">p</span>&gt;
        &lt;/<span style="color: #50fa7b; font-weight: bold;">div</span>&gt;
        &lt;<span style="color: #50fa7b; font-weight: bold;">script</span>&gt;
         function cuadratura(value) {
             // Establece el valor de redondeo de las esquinas de los dos
             // objetos del SVG. Obs&#233;rvese que se obtienen mediante `Id`
             var circulo = document.getElementById("circulo");
             var cuadrado = document.getElementById("cuadrado");
             var etiqueta = document.getElementById("etiqueta");
             circulo.setAttribute("rx", value);
             circulo.setAttribute("ry", value);
             cuadrado.setAttribute("rx", 40 - value);
             cuadrado.setAttribute("ry", 40 - value);
             etiqueta.innerHTML = value;
         }
        &lt;/<span style="color: #50fa7b; font-weight: bold;">script</span>&gt;
    &lt;/<span style="color: #50fa7b; font-weight: bold;">body</span>&gt;
&lt;/<span style="color: #50fa7b; font-weight: bold;">html</span>&gt;
</pre>
</div>

<p>
Dicho código genera la siguiente página:
</p>


<figure id="org05500b7">
<img src="./imagenes/Captura-pantalla-cuadratura-del-circulo.png" alt="Captura-pantalla-cuadratura-del-circulo.png">

</figure>

<p>
Se pueden apreciar tres partes fundamentales en el código:
</p>

<ul class="org-ul">
<li>Una parte de estilos (sólo para mostrar que, efectivamente, se
pueden afectar los estilos del <code>svg</code> desde los estilos de la
página).</li>
<li>Una parte <code>svg</code> donde se define el <code>viewbox</code> y un par de formas, que
serán las que cambien con los valores del formulario que hay justo a
continuación.</li>
<li>Un <code>script</code> que modifica los distintos objetos de la página: los dos
internos al <code>svg</code> y la <i>etiqueta</i> <code>html</code> que muestra el valor.</li>
</ul>

<p>
No he querido hacer un formulario completo para esto, sólo he puesto
un objeto <code>input</code> de tipo <code>range</code> para hacer las modificaciones.
Además en ese mismo elemento se llama al <code>javascript</code>, concretamente a
la función <code>cuadratura()</code> con el propio <code>value</code> del <code>input</code> como
parámetro. También se puede observar que en el código <code>svg</code> se pueden
añadir etiquetas <code>html</code>, como por ejemplo, la etiqueta <code>&lt;a&gt;</code> para
enlazar a otras direcciones <i>web</i>. Si pinchas en el objeto verde te
abrirá la página oficial de la organización <i>w3</i> sobre los gráficos
<code>svg</code>. Es sencillo, por tanto poder hacer cualquier gráfico
interactivo, aunque sea sólo a base de poner enlaces a otras páginas
dentro del contenido <code>svg</code>.
</p>

<p>
Si no quieres copiar el código anterior en un fichero <code>html</code> y
<i>trastearlo</i>, puedes interactuar con este código embebido en el mismo
artículo.
</p>

<style>
  .verde {
    stroke: #006600;
    fill  : #00cc00;
  }
  .rojo {
    stroke: #660000;
    fill  : #cc0000;
  }
</style>
<!-- Se pueden agrupar elementos SVG en otros objetos HTML -->
<p align="center">
  <svg viewBox="0 0 250 100" width="250" height="100">
    <a target="_blank"
       xlink:href="https://www.w3.org/Graphics/SVG/">
      <rect id="circulo" x="50" y="10" rx="40" ry="40" height="80" width="80" stroke-width="4" class="verde"/>
    </a>
    <rect id="cuadrado" x="150" y="10" rx="0" ry="0" height="80" width="80" stroke-width="4" class="rojo"/>
  </svg>
</p>
<div align="center">
  <!-- Las interacciones pueden realizarse a través de formularios -->
  <input type="range" name="rango" id="rango" min="0" max="40" value="40" oninput="cuadratura(this.value)" width="250">
  <p id="etiqueta">40</p>
</div>
<script>
  function cuadratura(value) {
    // Establece el valor de redondeo de las esquinas de los dos
    // objetos del SVG. Obsérvese que se obtienen mediante `Id`
    var circulo = document.getElementById("circulo");
    var cuadrado = document.getElementById("cuadrado");
    circulo.setAttribute("rx", value);
    circulo.setAttribute("ry", value);
    cuadrado.setAttribute("rx", 40 - value);
    cuadrado.setAttribute("ry", 40 - value);
    etiqueta.innerHTML = value;
  }
</script>
</div>
</div>
</div>
<div id="outline-container-org8f72679" class="outline-2">
<h2 id="org8f72679">Conclusiones</h2>
<div class="outline-text-2" id="text-org8f72679">
<p>
Estos días he aprendido mucho de las estructuras internas que se
manejan en un <code>svg</code>. Mucho del código que he trasteado lo he hecho con
<i>Emacs</i> viendo cómo los cambios en el texto se convertían en cambios
gráficos.
</p>

<p>
Nunca me había puesto a meterle código a un gráfico vectorial, pero no
es nada complicado hacerlo.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Las <i>extraescolares</i> de toda la vida, pero que las cambian el
nombre por aquello de que parezcan más modernas. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://microbit.org/">https://microbit.org/</a>
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/svg/index.html">svg</a> <a href="/tags/javascript/index.html">javascript</a> <a href="/tags/web/index.html">web</a> ]]></description>
  <category><![CDATA[svg]]></category>
  <category><![CDATA[javascript]]></category>
  <category><![CDATA[web]]></category>
  <link>https://notxor.nueva-actitud.org/2021/10/30/interactuando-con-svg.html</link>
  <pubDate>Sat, 30 Oct 2021 12:10:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[De regreso]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-10-10</div>
<p>
Mucho llevaba sin publicar nada original en el <i>blog</i>. Tanto que es
posible que la poca clientela que estaba atenta a esta página, se haya
difuminado y vuelva a escribir para mí solamente. El caso es que he
estado liado con cosas de trabajo y apenas he podido disponer de un
par de ratos en los que sentarme a escribir ésto, después de las
vacaciones de verano.
</p>
<div id="outline-container-orgb1451ff" class="outline-2">
<h2 id="orgb1451ff">Muchos cursos</h2>
<div class="outline-text-2" id="text-orgb1451ff">
<p>
Justo cuando me disponía a grabar el vídeo prometido sobre la captura
de la agenda, justo después del verano, se sucedieron las cosas muy
rápido y la vida se me complicó. Me contrataron de empresa que provee
formación <i>online</i> para el Servicio de Salud de Aragón y comencé a
tutorizar cursos para esa empresa. Y tutorizar implica prepararse el
contenido, corregir las respuestas de los alumnos, animar los foros
del curso, añadir información complementaria cuando sea necesario,
responder dudas, etc.
</p>

<p>
Además, con la misma empresa hemos hablado de la posibilidad de crear
un curso sobre una temática que yo controlo, ya disculparéis si no doy
más datos hasta que no esté todo cerrado.
</p>

<p>
Por otro lado, unos conocidos me pidieron aprender lo básico de
<i>Esperanto</i> y les tengo haciendo el curso que ya hicimos en este
sitio. No me ocupa demasiado tiempo, pero algo más es. Lo que más
tiempo me ocupa es mejorar mis <a href="https://moodle.org/?lang=es">conocimientos sobre <code>moodle</code></a> y ahora
<a href="https://exelearning.net/">también sobre <code>eXeLearning</code></a> para otros proyectos.
</p>

<p>
Eso sin contar el curso que estamos desarrollando un <i>grupo de
expertos</i> sobre <b>abuso sexual infantil</b> para el Colegio Oficial de
Profesionales de la Psicología de Aragón. Grupo del que soy
coordinador y donde debo dar ejemplo de diligencia, trabajo y
conocimientos.
</p>
</div>
</div>
<div id="outline-container-orgce1b921" class="outline-2">
<h2 id="orgce1b921">Moodle, la vorágine de pichorros</h2>
<div class="outline-text-2" id="text-orgce1b921">
<p>
Cada vez que abres un curso de <code>moodle</code> en modo de edición te asalta
una <i>interface</i> plagada de <i>pichorros</i> con un montón de <i>chismáticos</i>
que ajustar. Tan completa y enrevesada que intimida un poco,
especialmente a los usuarios nuevos, especialmente si no tienen
demasiados conocimientos de informática, lo que hace que no se atrevan
a tocar nada. Muy poderoso, muy funcional, pero no es sencillo de
utilizar. Puedes incluso bajar a escribir directamente el <code>html</code> del
contenido aunque también cuenta con una serie de herramientas más
visuales que facilitan el trabajo.
</p>

<p>
Tiene un montón de elementos didácticos que se pueden mostrar,
configurar y enlazar. Puedes generar <i>glosarios</i>, cuestionarios de
<i>autoevaluación</i>, sesiones de <i>lecciones online</i>, vídeo, actividades
lúdicas... Puedes ocultar algunos contenidos, hacer que se muestren en
determinadas circunstancias, etc. Cada uno de los <i>pichorros</i> cuenta
además con una profusa gama de opciones que modificar su
comportamiento y que pueden obligar al alumno a realizar determinadas
acciones para completarlos: desde simplemente leerlo o marcarlo como
completado a enviar una respuesta o varias.
</p>

<p>
Una herramienta muy completa ─y compleja, por tanto─ que tengo que
revisar y aprender cómo funcionan. Sobre todo porque también tiene sus
herramientas de <i>monitoreo</i> de los alumnos y sus avances, tanto
<i>cacharrímetros</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> como <i>cacharrógrafos</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> que resultan muy
útiles al profesor.
</p>
</div>
</div>
<div id="outline-container-org8006efd" class="outline-2">
<h2 id="org8006efd">eXeLearning, el aprendizaje independiente</h2>
<div class="outline-text-2" id="text-org8006efd">
<p>
Además, para temas personales estoy mirándome la herramienta
<code>eXeLearning</code> que promete, de momento, lo mismo que <code>moodle</code> pero sin
depender de un servidor. Es decir, se pueden crear cursos completos:
mostrar contenidos, cuestionarios de autoevaluación y un montón de
cosas más pero no dependes de un servidor. A cambio del seguimiento
de los alumnos que pierdes con el servidor, ganas un montón de
independencia. Puedes generar cursos <code>html</code> independientes que puedes
distribuir incluso dentro de un archivo <code>epub</code> que te genera la misma
aplicación. Por otro lado, también se puede exportar el contenido a un
fichero <code>SCORM</code> estándar que luego puedes colgar en un <code>moodle</code> o en
otros entornos de formación <i>online</i>.
</p>

<p>
Los <i>temas personales</i> que comenté antes consisten básicamente en
crear un curso de Esperanto moderno, para ponerlo al alcance de todo
el mundo. Las características que quiero para el curso son las
siguientes:
</p>

<ol class="org-ol">
<li>Completamente en <i>Esperanto</i> desde cero al <i>plena posedo</i>.</li>
<li>Modular: para que los alumnos lo puedan hacer desde cero o
comenzando en el nivel que ya tengan.</li>
<li>Que pueda ser <i>autoevaluado</i> como corregido por un profesor.</li>
<li>Textos y ejercición más modernos e interesantes.</li>
<li>Con contenidos actuales como canciones y vídeos.</li>
</ol>
</div>
</div>
<div id="outline-container-orgd4e7eb3" class="outline-2">
<h2 id="orgd4e7eb3">Otros</h2>
<div class="outline-text-2" id="text-orgd4e7eb3">
<p>
Además otros proyectos personales o de la Asociación PICA me ocupan
también. Concretamente estamos con un Plan de Prevención Contra el
Abuso entre Iguales.
</p>

<p>
Por otro lado, hace un tiempo comencé a traducir <i>Dune</i> del inglés al
<i>Esperanto</i> con la idea de practicar ambos idiomas a la vez. El caso
es que el estreno de la película me ha pillado con el 77,6% de la
novela traducida y me he propuesto terminarlo, aunque no con el ánimo
de publicarlo. Mi intención es crear un <code>epub</code> con él y leerlo en mi
libro electrónico, sentado tranquilamente en mi sofá con los pies
encima de la mesa. Me estoy forzando a traducir todos los días un
poco, aunque sólo sean un par de frases.
</p>
</div>
</div>
<div id="outline-container-org9e23b7b" class="outline-2">
<h2 id="org9e23b7b">Conclusiones</h2>
<div class="outline-text-2" id="text-org9e23b7b">
<p>
Me faltan horas en el día para hacer todas las cosas que quiero hacer
y unos <i>proyectos</i> empujan a los otros para hacerse un hueco.  Dentro
de poco, espero, se habrán acoplado unos con otros y podrán coger
ritmo de nuevo. Algunos desaparecerán y otros llegarán.  Espero que a
partir de ahora vuelva a poder publicar con regularidad en el <i>blog</i>
pero tampoco puedo prometer nada.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Cacharro</i>, bien <i>chismático</i> o bien <i>pichorro</i>, que nos da
información numérica de un parámetro. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Cacharro</i>, bien <i>chismático</i> o bien <i>pichorro</i>, que nos da una
información gráfica de un parámetro.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/blog/index.html">blog</a> ]]></description>
  <category><![CDATA[blog]]></category>
  <link>https://notxor.nueva-actitud.org/2021/10/10/de-regreso.html</link>
  <pubDate>Sun, 10 Oct 2021 15:12:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Configuración de org-mode para utilizarlo como agenda (I)]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-07-30</div>
<p>
El configurar correctamente <code>org-mode</code> para utilizarlo como agenda es
un procedimiento sencillo, pero que a algunos parece que se les
atranca. Por lo tanto, me he planteado escribir esta entrada en el
<i>blog</i>, además lo acompañará un vídeo que resume todo el proceso de
una manera sencilla. Utilizo <i>programación literaria</i> para explicar
todos los pasos según los voy haciendo.
</p>

<p>
El procedimiento del artículo es sencillo:
</p>

<ol class="org-ol">
<li>Iniciar <i>Emacs</i> sin cargar la configuración con el comando</li>
</ol>

<div class="org-src-container">
<pre class="src src-bash">emacs -q
</pre>
</div>

<ol class="org-ol">
<li>Generar una configuración mínima para hacer más agradable la
modificación de código.</li>
<li>Después de cargar la configuración mínima, modificarla únicamente
en los aspectos relacionados con la <i>agenda</i>.</li>
</ol>
<div id="outline-container-orga5ff1ed" class="outline-2">
<h2 id="orga5ff1ed">Inicio de paquetes y configuración mínima de variables</h2>
<div class="outline-text-2" id="text-orga5ff1ed">
<p>
Por defecto, al arrancar mediante <code>emacs -q</code>, no se carga ningún tipo
de configuración y los valores son los que cargarían por defecto en
una primera instalación.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(package-initialize)

(custom-set-variables
 '(Info-default-directory-list
   '(<span style="color: #f1fa8c;">"/usr/share/info/"</span> <span style="color: #f1fa8c;">"/usr/local/share/info/"</span> <span style="color: #f1fa8c;">"~/opt/share/info/"</span>))
 '(custom-enabled-themes '(dracula))
 '(custom-safe-themes
   '(<span style="color: #f1fa8c;">"549ccbd11c125a4e671a1e8d3609063a91228e918ffb269e57bd2cd2c0a6f1c6"</span> default))
 '(ivy-mode t)
 '(truncate-lines t)
 '(display-line-numbers-type 'visual)
 '(scroll-bar-mode nil)
 '(which-key-mode t))

(global-company-mode t)
</pre>
</div>

<p>
La primera línea anterior le dice a <i>Emacs</i> que cargue la lista de
paquetes que encuentre en el sistema. Es hacer un poco trampa porque
ya tengo en mi máquina los paquetes necesarios instalados y no hablo
sobre la instalación en ningún momento. Sin embargo, <code>org-mode</code> ya
viene por defecto en <i>Emacs</i>.
</p>

<p>
También le digo a este <i>Emacs pelado</i> dónde puede encontrar los
archivos <code>info</code> que utiliza para mostrar la documentación, por si más
tarde fuera necesario consultarla. Cambio el tema de <i>Emacs</i> a uno
oscuro y después cargo unas pocas herramientas que mejoran la
comodidad al usar el editor:
</p>

<ul class="org-ul">
<li><code>ivy</code>, un modo que hace la interacción con <i>Emacs</i> mucho más
agradable, proporcionando listas de comandos, de ficheros,
de... muchas cosas.</li>
<li><code>which-key</code>, un modo que nos proporciona información sobre las
cadenas de comandos de teclado disponibles.</li>
<li><code>company</code>, nos proporciona el completado de sintaxis cuando estamos
programando.</li>
</ul>
</div>
</div>
<div id="outline-container-org38d7185" class="outline-2">
<h2 id="org38d7185">Configuración para la agenda</h2>
<div class="outline-text-2" id="text-org38d7185">
<p>
Primero se configura el formato para las fechas en la variable
<code>calendar-date-style</code>, de entre tres estilos establecidos:
</p>

<ul class="org-ul">
<li><code>american</code> con el formato <code>mes/día/año</code>.</li>
<li><code>european</code> con el formato <code>día/mes/año</code>.</li>
<li><code>iso</code> con el formato <code>año/mes/día</code>.</li>
</ul>

<p>
Después especificar qué día comienza la semana en la variable
<code>calendar-week-start-day</code>. La función admite un número entre <code>0</code> y
<code>6</code>:
</p>

<ul class="org-ul">
<li>0 - domingo</li>
<li>1 - lunes</li>
<li>2 - martes</li>
<li>3 - miércoles</li>
<li>4 - jueves</li>
<li>5 - viernes</li>
<li>6 - sábado</li>
</ul>

<p>
Por defecto, el valor se establece a <code>0</code>, <i>domingo</i>, que es el día en
el que comienza la semana en muchos países. En otros, como aquí, la
semana comienza el lunes, por lo que ajusto el día de comienzo a <code>1</code>.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> calendar-date-style 'iso)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> calendar-week-start-day 1)
</pre>
</div>
</div>
<div id="outline-container-orga8d707f" class="outline-3">
<h3 id="orga8d707f">Nombres de días y meses</h3>
<div class="outline-text-3" id="text-orga8d707f">
<p>
Los nombres de los días y de los meses se establecen en dos variables
cada uno, una con el formato abreviado y otra con el nombre completo.
</p>

<ul class="org-ul">
<li><code>calendar-day-header-array</code> ... "Do", "Lu", etc.</li>
<li><code>calendar-day-name-array</code> ... "domingo", "lunes", etc.</li>
<li><code>calendar-month-abbrev-array</code> ... "Ene", "Feb", etc.</li>
<li><code>calendar-month-name-array</code> ... "enero", "febrero", etc.</li>
</ul>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> calendar-day-header-array [<span style="color: #f1fa8c;">"Do"</span> <span style="color: #f1fa8c;">"Lu"</span> <span style="color: #f1fa8c;">"Ma"</span> <span style="color: #f1fa8c;">"Mi"</span> <span style="color: #f1fa8c;">"Ju"</span> <span style="color: #f1fa8c;">"Vi"</span> <span style="color: #f1fa8c;">"S&#225;"</span>])
(<span style="color: #ff79c6; font-weight: bold;">setq</span> calendar-day-name-array [<span style="color: #f1fa8c;">"domingo"</span> <span style="color: #f1fa8c;">"lunes"</span> <span style="color: #f1fa8c;">"martes"</span> <span style="color: #f1fa8c;">"mi&#233;rcoles"</span> <span style="color: #f1fa8c;">"jueves"</span> <span style="color: #f1fa8c;">"viernes"</span> <span style="color: #f1fa8c;">"s&#225;bado"</span>])
(<span style="color: #ff79c6; font-weight: bold;">setq</span> calendar-month-abbrev-array [<span style="color: #f1fa8c;">"Ene"</span> <span style="color: #f1fa8c;">"Feb"</span> <span style="color: #f1fa8c;">"Mar"</span> <span style="color: #f1fa8c;">"Abr"</span> <span style="color: #f1fa8c;">"May"</span> <span style="color: #f1fa8c;">"Jun"</span> <span style="color: #f1fa8c;">"Jul"</span> <span style="color: #f1fa8c;">"Ago"</span> <span style="color: #f1fa8c;">"Sep"</span> <span style="color: #f1fa8c;">"Oct"</span> <span style="color: #f1fa8c;">"Nov"</span> <span style="color: #f1fa8c;">"Dic"</span>])
(<span style="color: #ff79c6; font-weight: bold;">setq</span> calendar-month-name-array [<span style="color: #f1fa8c;">"enero"</span> <span style="color: #f1fa8c;">"febrero"</span> <span style="color: #f1fa8c;">"marzo"</span> <span style="color: #f1fa8c;">"abril"</span> <span style="color: #f1fa8c;">"mayo"</span> <span style="color: #f1fa8c;">"junio"</span> <span style="color: #f1fa8c;">"julio"</span> <span style="color: #f1fa8c;">"agosto"</span> <span style="color: #f1fa8c;">"septiembre"</span> <span style="color: #f1fa8c;">"octubre"</span> <span style="color: #f1fa8c;">"noviembre"</span> <span style="color: #f1fa8c;">"diciembre"</span>])
</pre>
</div>

<p>
Sólo quiero recordar dos cosas. Una es que estas variables esperan
recibir un <i>array</i> y no una lista. Otra es que en castellano, los
nombres de los meses y de los días no se escriben con mayúsculas, por
eso, aunque sí las utilizo para las abreviaturas no las uso en los
nombres completos.
</p>
</div>
</div>
<div id="outline-container-org3302644" class="outline-3">
<h3 id="org3302644">Ficheros de datos</h3>
<div class="outline-text-3" id="text-org3302644">
<p>
Necesitamos mínimo un fichero. Dos, si utilizamos el <i>diario</i>: uno
será para la agenda y otro para el diario. El fichero de diario lo
trataré más adelante, aunque es opcional.
</p>

<p>
Se pueden tener varios ficheros <code>org</code> donde guardar la información de
los eventos. Podemos, por ejemplo, tener distintos ficheros para
agrupar conceptos como <i>trabajo</i>, <i>ocio</i>, <i>familia</i>, etc. En mi caso
utilizo dos, uno de los ficheros donde se guardan los eventos
capturados a través del calendario de mi servidor <i>Nextcloud</i> y que se
sincroniza con la agenda de <i>Emacs</i> a través del paquete <code>org-caldav</code>.
Pero en el ejemplo, sólo utilizaré uno.
</p>

<p>
Los distintos ficheros se configuran en la variable <code>org-agenda-files</code>
y espera una lista de ficheros con el <i>path</i> completo.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-agenda-files '(<span style="color: #f1fa8c;">"~/agenda/agenda.org"</span>))
</pre>
</div>

<p>
El fichero debe existir para que funcione la <i>agenda</i>. <code>org-mode</code> se
quejará si encuentra en la lista algún fichero que no existe y
propondrá eliminarlo de la lista, pues entiende que se ha borrado. No
suele ser mala idea el tener varios ficheros, uno dedicado a cada una
de nuestras actividades, por ejemplo. Uno para el trabajo, otro para
el ocio, etc. Al visualizarse juntos no hay problema con que se
solapen las actividades. O por ejemplo, si tenemos que gestionar la
agenda de un grupo de trabajo, podemos tener separadas las tareas de
cada miembro del grupo. Somos libres de adaptar la lógica de nuestros
ficheros a la lógica de trabajo.
</p>

<p>
Otra forma de configurar varios ficheros separados es juntarlos todos
en un directorio y configurar dicho directorio en la variable
<code>org-agenda-files</code>, de esta manera, cuando genere la vista de la
agenda consultará todos los archivos <code>org</code> que se encuentren en él.
</p>
</div>
</div>
<div id="outline-container-orgc4c94aa" class="outline-3">
<h3 id="orgc4c94aa">Configuración del diario y eventos periódicos</h3>
<div class="outline-text-3" id="text-orgc4c94aa">
<p>
El fichero del <i>diario</i> se configura en la variable <code>diary-file</code>. El
diario se puede utilizar para recordatorio de fechas señaladas,
cumpleaños, festivos, eventos periódicos. Hay que establecer esa
variable y también <code>org-agenda-diary-file</code>.
</p>

<p>
También hay que configurar si queremos que nos muestre las entradas
del diario en la vista de la agenda mediante la variable
<code>org-agenda-include-diary</code> puesto a <code>t</code>.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> diary-file <span style="color: #f1fa8c;">"~/agenda/diario.org"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-agenda-diary-file <span style="color: #f1fa8c;">"~/agenda/diario.org"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-agenda-include-diary t)
</pre>
</div>

<p>
Las entradas se pueden cargar mediante dos comandos principalmente:
</p>

<ul class="org-ul">
<li><p>
Uno con <code>org-anniversary</code> con el formato:
</p>

<pre class="example" id="orgfa998e4">
%%(org-anniversary año mes dia) Texto explicativo
</pre></li>

<li><p>
Otro para eventos periódicos flotantes:
</p>

<pre class="example" id="org4e5e020">
%%(diary-float mes dia orden) Texto explicativo
</pre></li>
</ul>

<p>
En ambas sintaxis los parámetros de <code>año</code>, <code>mes</code> o <code>día</code> deben ser
números. Es decir, nos encontraremos un error si completamos con <code>0</code>,
como me pasó a mí durante la realización del vídeo: Había preparado
una entrada de diario para que se visualizara al cargar la agenda y
resultó que no funcionó. Después de darle muchas vueltas, resultó, que
acostumbrado a escribir las fechas completando con ceros<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, al
hacerlo la agenda no lo reconocía como fecha válida. Eso me hizo
perder un poco de tiempo, porque repasaba la entrada y para mí estaba
correcta... hasta que al crear una entrada de diario desde la vista de
la agenda me encontré que la escribía en el fichero sin el cero.
</p>

<p>
Por otro lado, también se puede configurar la agenda para que ciertas
tareas las convierta en periódicas añadiendo en la fecha de <i>schedule</i>
o de <i>death</i> un sufijo con su periodicidad. Por ejemplo, si queremos
que nos avise semanalmente de alguna tarea rutinaria, podemos añadir a
la fecha, el sufijo <code>1w</code>; si lo queremos quincenal añadiremos <code>2w</code>; o
también, por ejemplo, si lo queremos trimestral: <code>3m</code>; o <code>1y</code> para
tareas anuales. Estas tareas, cuando se marcan como hechas lo que hace
<code>org-mode</code> es añadir un línea con la fecha y hora de la realización de
la tarea y modificar la fecha de <i>schedule</i> o <i>death</i> al próximo
evento, generando un histórico.
</p>
</div>
</div>
</div>
<div id="outline-container-org85f06af" class="outline-2">
<h2 id="org85f06af">Configuración de los elementos de entrada</h2>
<div class="outline-text-2" id="text-org85f06af">
<p>
Para la realización del vídeo se han configurado mínimamente los
dispositivos de entrada, ─ratón y teclado─, con lo mínimo para hacer
el trabajo más agradable. Por tanto, se carga el paquete <code>org-mouse</code>
para tener acceso en modo gráfico a las funciones del ratón y también
se estableces algunas combinaciones de teclas de uso común.
</p>
</div>
<div id="outline-container-orgfc04563" class="outline-3">
<h3 id="orgfc04563">Configuración del ratón</h3>
<div class="outline-text-3" id="text-orgfc04563">
<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Configurar rat&#243;n para el modo gr&#225;fico
</span>(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">org-mouse</span>)
</pre>
</div>
</div>
</div>
<div id="outline-container-org2bb111d" class="outline-3">
<h3 id="org2bb111d">Configuración de combinaciones de teclas</h3>
<div class="outline-text-3" id="text-org2bb111d">
<p>
Combinaciones de teclas que suelo utilizar con frecuencia.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Configuraci&#243;n de teclas
</span>(global-set-key (kbd <span style="color: #f1fa8c;">"C-;"</span>)   'iedit-mode)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c a"</span>) 'org-agenda)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c l"</span>) 'display-line-numbers-mode)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c s"</span>) 'dired-sidebar-toggle-sidebar)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c t"</span>) 'toggle-truncate-lines)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c w"</span>) 'whitespace-mode)
</pre>
</div>

<p>
Aunque últimamente utilizo la combinación <code>C-i</code> para el modo <code>iedit</code>,
he configurado <code>C-;</code> porque es la tecla que configura el paquete por
defecto. Las demás teclas no necesitan mucha más explicación, aunque
en el vídeo la podréis encontrar.
</p>
</div>
</div>
</div>
<div id="outline-container-org1908a7d" class="outline-2">
<h2 id="org1908a7d">Configuración de <code>dired</code></h2>
<div class="outline-text-2" id="text-org1908a7d">
<p>
El acceso directo de algunos modos al abrir los archivos
correspondientes. En concreto se cargan los modos para que muestre
iconos en el <i>buffer</i> de <code>dired</code>.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Hooks
</span>(add-hook 'dired-mode-hook 'all-the-icons-dired-mode) <span style="color: #6272a4;">; </span><span style="color: #6272a4;">muestra iconos en el &#225;rbol dired
</span>(add-hook 'dired-mode-hook 'dired-git-mode)           <span style="color: #6272a4;">; </span><span style="color: #6272a4;">identifica directorios git
</span>(add-hook 'dired-mode-hook 'auto-revert-mode)         <span style="color: #6272a4;">; </span><span style="color: #6272a4;">refresco de dired</span>
</pre>
</div>

<p>
Además, se establecen algunos parámetros en la configuración para que
se muestren a mi gusto directorios y ficheros.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Ajustes de dired-sidebar
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> dired-sidebar-theme 'nerd)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> dired-sidebar-use-term-integration t)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> dired-sidebar-use-custom-font t)
</pre>
</div>
</div>
</div>
<div id="outline-container-orgb68fac2" class="outline-2">
<h2 id="orgb68fac2">Configuración del paquete <code>ivy</code></h2>
<div class="outline-text-2" id="text-orgb68fac2">
<p>
El paquete <code>ivy</code> es uno de los fundamentales para hacer mucho más
amigable <i>Emacs</i> para el usuario.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Configurar ivy
</span><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">a&#241;adir &#8216;</span><span style="color: #bd93f9;">recentf-mode</span><span style="color: #6272a4;">&#8217; y bookmarks a &#8216;</span><span style="color: #bd93f9;">ivy-switch-buffer</span><span style="color: #6272a4;">&#8217;.
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> ivy-use-virtual-buffers t)
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">n&#250;mero de l&#237;neas de resultado mostradas
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> ivy-height 15)
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">no contar candidatos
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> ivy-count-format <span style="color: #f1fa8c;">""</span>)
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">no utilizar regexp por defecto
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> ivy-initial-inputs-alist nil)
</pre>
</div>
</div>
</div>
<div id="outline-container-org8cadc2f" class="outline-2">
<h2 id="org8cadc2f">Ajustes de fuentes de texto.</h2>
<div class="outline-text-2" id="text-org8cadc2f">
<p>
Algunos <i>themes</i> de <i>Emacs</i> modifican el tamaño de las fuentes de las
cabeceras de <code>org-mode</code>.  Buscan mejorar el aspecto de cómo se
mostrará el documento en pantalla, sin embargo cuando utilizo
<i>programación literaria</i>, como ahora, desajusta la visualización de la
lista de opciones que puede mostrar el paquete <code>company</code> y es mejor
desactivar esos tamaños.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(custom-set-faces
 '(org-level-1 ((t (<span style="color: #8be9fd; font-style: italic;">:inherit</span> outline-1 <span style="color: #8be9fd; font-style: italic;">:height</span> 1.0))))
 '(org-level-2 ((t (<span style="color: #8be9fd; font-style: italic;">:inherit</span> outline-2 <span style="color: #8be9fd; font-style: italic;">:height</span> 1.0))))
 '(org-level-3 ((t (<span style="color: #8be9fd; font-style: italic;">:inherit</span> outline-3 <span style="color: #8be9fd; font-style: italic;">:height</span> 1.0))))
 '(org-level-4 ((t (<span style="color: #8be9fd; font-style: italic;">:inherit</span> outline-4 <span style="color: #8be9fd; font-style: italic;">:height</span> 1.0))))
 '(org-level-5 ((t (<span style="color: #8be9fd; font-style: italic;">:inherit</span> outline-5 <span style="color: #8be9fd; font-style: italic;">:height</span> 1.0))))
 '(org-level-6 ((t (<span style="color: #8be9fd; font-style: italic;">:inherit</span> outline-6 <span style="color: #8be9fd; font-style: italic;">:height</span> 1.0)))))
</pre>
</div>
</div>
</div>
<div id="outline-container-orgf4748c4" class="outline-2">
<h2 id="orgf4748c4">El vídeo y los ficheros de trabajo</h2>
<div class="outline-text-2" id="text-orgf4748c4">
<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts allow-popups" title="Configuración de la Agenda en org-mode" src="https://video.nogafam.es/videos/embed/e2d8bd9c-8c20-48da-9d43-a9de7aac7f99" frameborder="0" allowfullscreen></iframe>

<p>
Si preferís el enlace al sitio:
</p>

<p>
<a href="https://video.nogafam.es/w/u1GkvDRiBe4Ks4s8kQAVCe">https://video.nogafam.es/w/u1GkvDRiBe4Ks4s8kQAVCe</a>
</p>

<p>
Desde ahí también podéis descargarlo y verlo cuando queráis sin estar
conectados.
</p>

<p>
Los ficheros utilizados son tres, está también el cuarto que es el
fichero <code>configuracion.el</code> generado a partir del código que se
encuentra en <code>configuracion-articulo.org</code>. Los podéis encontrar en:
</p>

<ul>
  <li>Fichero <a href="./ejemplo/configuracion-articulo.org" target="_blank">de configuración (programación literaria)</a></li>
  <li>Fichero <a href="./ejemplo/agenda.org" target="_blank">agenda.org</a></li>
  <li>Fichero <a href="./ejemplo/diario.org" target="_blank">diario.org</a></li>
</ul>

<p>
Es muy recomendable, si no has configurado nunca la agenda y quieres
aprender cómo funciona, que toquetees estos ficheros y que pruebes
cosas nuevas simplemente para aprender. Sin miedo a estropear tu
configuración, si tienes alguna, copiada de algún sitio y que
funciona, pero no entiendes muy bien cómo. Recuerda, arranca <i>Emacs</i>
con el parámetro <code>-q</code> y carga el fichero de configuración sin
preocuparte de romper nada.
</p>
</div>
</div>
<div id="outline-container-orgaaffce6" class="outline-2">
<h2 id="orgaaffce6">Conclusiones</h2>
<div class="outline-text-2" id="text-orgaaffce6">
<p>
En esta primera parte hablo principalmente de la configuración de
<i>agenda</i> y <i>diario</i>, entendiendo que añadimos las tareas y las
entradas al diario modificando directamente los ficheros que contienen
los datos.
</p>

<p>
En una próxima entrega hablaré sobre <i>la captura</i> de datos para la
agenda. En el vídeo se puede apreciar cómo se puede hacer dicha
captura desde la vista de agenda para el diario. Sin embargo, la
captura de datos para la agenda es bastante más compleja y merece un
capítulo aparte.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Con <i>completar con ceros</i> me refiero a que cuando escribo
fechas tengo la costumbre de escribir <code>2021/01/01</code> en lugar de
<code>2021/1/1</code>, para preservar dos posiciones alfanuméricas para el mes y
el día.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> <a href="/tags/agenda/index.html">agenda</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <category><![CDATA[agenda]]></category>
  <link>https://notxor.nueva-actitud.org/2021/07/30/configuracion-org-mode-agenda-i.html</link>
  <pubDate>Fri, 30 Jul 2021 00:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Introducción en vídeo a org-mode]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-07-19</div>
<p>
Vengo con otro experimento. Como la sensación del anterior vídeo no
fue demasiado buena, no me siento tan <i>productivo</i> editando vídeo como
me siento productivo escribiendo un artículo. Pienso que es por falta
de práctica. Después de haber editado uno, me planteé hacer otro, a
ver si las herramientas, ahora más familiares, me permitían funcionar
mucho más rápido. Además estoy valorando hacer un tercero, a ver si
mejoro algunas cosas. Por ejemplo, el sonido (que es penoso).
</p>

<p>
El vídeo actual quiere presentar, por encima, las capacidades de
<code>org-mode</code> y las cosas que se pueden hacer. No en profundidad, porque
era un vídeo planeado para 20 ó 30 minutos. Sin embargo, va montado en
dos partes. Cuando tenía casi terminado el montaje del vídeo y estaba
montando y ajustando el sonido, <code>kdenlive</code> me lanzó un error y algo
debió quedar mal en el fichero del proyecto, porque no conseguía
abrirlo y cuando lo hacía <i>petaba</i> la aplicación.
</p>

<p>
Al final pude arreglar un poco el fichero, gracias a que es XML y
parte del trabajo no se perdió. El problema es que lo tuve que dividir
en dos partes. Así pues, el vídeo no es un vídeo, que son dos. Además,
la limitación de tamaño en la plataforma de vídeo tampoco me hubiera
permitido hacerlo en un sólo vídeo, porque el archivo no puede superar
los 100Mb y todo junto, no sé si los hubiera sobrepasado.
</p>
<div id="outline-container-org6b1ff2e" class="outline-2">
<h2 id="org6b1ff2e">El contenido del vídeo</h2>
<div class="outline-text-2" id="text-org6b1ff2e">
<p>
Cualquiera que haya trabajado con <i>Emacs</i> encontrará el contenido
demasiado escueto. Apenas doy unas pinceladas de lo que puede hacer
<code>org-mode</code>. He tenido que dejar en el tintero muchas cosas para no
alargar demasiado el vídeo. Algo que me resulta más molesto que en los
artículos escritos, que pueden ser más largos o más cortos,
dependiendo del tema que se hable, pero es más difícil pensar en el
aburrimiento del que lo ve.
</p>

<p>
Hablo en general de cómo escribir un fichero <code>org</code> y cómo exportarlo a
otro formato, en concreto a <code>HTML</code>. Por desglosarlo más despacio, se
ven los aspectos básicos sobre:
</p>

<ul class="org-ul">
<li>Estilos de fuentes</li>
<li>Cabecera de archivo</li>
<li>Estructura del documento</li>
<li>Enlaces (tanto internos como externos)</li>
<li>Tablas</li>
<li>Gestión de tareas, fechas y listas (etiquetas)</li>
<li>Bloques de código</li>
<li>Exportación del documento a otros formatos (<code>HTML</code>)</li>
</ul>

<p>
El resultado se puede ver en el siguiente enlace:
</p>

<p target="_blank">
<a href="prueba-org-mode.html" target="_blank">prueba-org-mode.html</a>
</p>

<p>
y el fichero <code>org</code> que lo genera en
</p>

<a href="./prueba-org-mode.org" target="_blank">prueba-org-mode.org</a>

<p>
Si no has trabajado nunca con <code>org-mode</code> y es tu primer contacto,
puedes bajarte el archivo <code>org</code> y juguetear con él.
</p>

<p>
¿Vais a aprender algo con el vídeo? Pues si ya utilizas <i>Emacs</i> y
<code>org-mode</code>, puedes prescindir de perder el tiempo viéndolo, porque ya
digo que todo es muy básico y con seguridad es muy posible que
encuentres más interesante la música de fondo que he puesto que lo que
digo y muestro.
</p>
</div>
</div>
<div id="outline-container-org8830df0" class="outline-2">
<h2 id="org8830df0">Los vídeos</h2>
<div class="outline-text-2" id="text-org8830df0">
<p>
Como vengo diciendo, al final son dos vídeos de <i>introducción</i> a
<code>org-mode</code>. El sonido es penoso tirando a catastrófico, ya lo siento.
En la siguiente prueba, por sugerencia de <i>Deesix</i>, en lugar de
utilizar el portátil en el que trabajo, intentaré hacerlo con el
móvil. Posiblemente el sonido sea más claro, con menos ruido y pueda
no sonar tan opaco y mal. He hecho un par de pruebas de grabación y la
verdad es que funciona mejor. En la lista de aplicaciones para el
<i>Ubuntu Touch</i> que llevo en el móvil, encontré una aplicación de
grabación que lo hace directamente a <code>ogg</code>... y enchufándole los
auriculares con micrófono la captura es más aceptable que desde mi
viejo portátil.
</p>

<p>
Hasta ahora, para eliminar el ruido, tengo que pasarle al audio dos
veces el filtro de reducción de ruido de <code>Audacity</code>. Pero eso también
hace que la voz suene como si estuviera metido en una cueva y en algún
momento, juntándose por mi desgana al vocalizar, se pierda algún
contenido. Por ello, en estos vídeos he añadido la opción de ponerles
subtítulos, por si alguien no entiende muy bien lo que digo.
</p>
</div>
</div>
<div id="outline-container-org00c522f" class="outline-2">
<h2 id="org00c522f">Mi forma de pronunciar el inglés</h2>
<div class="outline-text-2" id="text-org00c522f">
<p>
A propósito del anterior vídeo hay quien se empeñó en corregirme la
forma de pronunciar algunos <i>palabros</i> de origen inglés. No tengo
ganas de discutir, pero no voy a cambiar de estilo. Me resulta
artificioso introducir vocablos ingleses en medio de una frase en
castellano. Las siglas las seguiré <i>deletreando</i> tal y como se hace en
castellano por lo mismo.
</p>

<p>
El otro día me eché unas risas al ver una entrevista a una periodista
cubana, de parte de un periodista español y le preguntaba que con las
restricciones de <i>Internet</i> en la isla, <i>cómo era posible estar
haciendo la entrevista</i>... La respuesta fue algo así como que <i>me
conecto a través de una aplicación «bipién»</i>. El periodista español le
preguntó qué aplicación era esa y repitió <i>por «bipién»</i>. Aún sabiendo
(por la cara del periodista) un poco más que él sobre redes, tardé un
rato en darme cuenta que se refería a <code>VPN</code>. ¿Por qué? Porque es
artificial, no esperas ─al menos yo no espero─ lenguas mezcladas.
</p>

<p>
Por otro lado, además, puestos a hacer esfuerzos creo que me pondré a
esforzarme en pronunciar correctamente las palabras inglesas
insertadas en una oración pensada en castellano, cuando vea que hay
reciprocidad y hacen el mismo esfuerzo por pronunciar correctamente
las palabras españolas en medio de una oración pensada en inglés. Así,
cuando oiga a un inglés o estadounidense pronunciar correctamente «Los
Ángeles», o «San Francisco», o «Toledo» o cualquier otro término, como
«siesta» o «tortilla», me plantearé si debo hacer dicho esfuerzo.
Recuerdo en un trabajo conjunto con un equipo norteamericano mi amigo
«Vázquez» era «Bascuas», que terminó desistiendo de que lo
pronunciaran correctamente. Sin embargo, sí debíamos pronunciar bien
los suyos, e incluso hacer el esfuerzo de pronunciar a la inglesa
apellidos como «Daias» (Díaz), porque se enfadaban de veras si
mezclábamos palabras pronunciadas en castellano en medio de una frase
en inglés, por no hacer ningún esfuerzo en comprenderla. Desde
entonces (entre enero y abril de 2010), aunque a veces se me escapa
alguna, procuro no pronunciar a la inglesa ninguna palabra que sepa
cómo se escribe, en reciprocidad al trato recibido.
</p>

<p>
Dichos esfuerzos se los merecen más otras lenguas, ─no puedo decir que
las domino, pero sí las <i>chapurreo/─, que sí intento pronunciar
correctamente cuando utilizo alguna de sus palabras: como el catalán,
el esperanto, o incluso el francés. Sin embargo, todas tienen sonidos
que no son nativos de mi lengua materna (el castellano) y la
pronunciación puede no ser exacta (sobre todo si hay una /ll</i> final en
catalán que nunca he conseguido pronunciarla bien). Por tanto, ya me
disculparán si no lo hago correctamente del todo.
</p>

<p>
Si, como digo, el objetivo es entendernos, es mejor no mezclar
idiomas.  Que por otro lado lo invaden todo. Incluso muy pocos parecen
saber ya que en castellano la <code>W</code> se lee como una <code>B</code> y les oyes
pronunciar <i>güenceslao</i> o <i>güamba</i>, en lugar de <i>Benceslao</i> o
<a href="https://es.wikipedia.org/wiki/Wamba_(Valladolid)"><i>Bamba</i></a>. O simplemente pronunciar cualquier nombre extranjero, ya sea
alemán, sueco, holandés o incluso italiano o portugués, a la
inglesa. Que recuerdo a un <i>membrillo</i> decir que íba a la «Feirou's
concentreison» cuando íbamos a la concentración motorista de Faro
(Portugal), si quería ser internacional podría haber dicho
«Concentraçao de Faro» y hubiera quedado mejor.
</p>

<p>
Así pues, si te molesta cómo lo pronuncio silencias el audio y miras
los subtítulos. Y hablando de idiomas, la música que he seleccionado
está en <i>Esperanto</i> es de Martin Wiese (es sueco, no pronuncies
«güeisa», recuerda: es sueco. Cuando se lo oí pronunciar a él mismo,
pronunció «Biss»).  Van tres canciones:
</p>

<ul class="org-ul">
<li><i>Pli ol nenio</i> (Más que nada)</li>
<li><i>Superbazaro</i> (Supermercado)</li>
<li><i>Anstataŭ letero</i> (En lugar de [a modo de, en vez de] una carta)</li>
</ul>
</div>
</div>
<div id="outline-container-org456b6fd" class="outline-2">
<h2 id="org456b6fd">Próximas entregas</h2>
<div class="outline-text-2" id="text-org456b6fd">
<p>
Tengo intención, por concretar mejor el experimento y ver si voy
cogiendo soltura con la edición de vídeo y la incomodidad que aún
siento editando vídeo va desapareciendo con la práctica, editar otro
vídeo. El tema sería la configuración de <code>org-mode</code> para utilizarlo
como agenda y lo que quiero incluir:
</p>

<ul class="org-ul">
<li>Personalización de días de la semana y nombres de meses en las
fechas.</li>
<li>Configuración de los diversos tipos de etiquetas.</li>
<li>Configuración de la captura de entradas para la agenda.</li>
<li>Tareas periódicas (diarias, semanales, mensuales, trimestrales,
anuales).</li>
<li>La agenda y los distintos listados de tareas y filtros.</li>
<li>El uso del <i>diario</i> para eventos periódicos, honomásticas,
cumpleaños y otras informaciones similares.</li>
</ul>

<p>
Si hay interés por el asunto, intentaré hacerlo más ameno (o fluido)
que hasta ahora y ver si puedo hacerlo además con mejor sonido,
grabando el sonido en directo mientras trabajo. Si bien no sería
«hacer un directo», sería un equivalente: capturar una sesión en la
que configuraría <code>org-mode</code> desde cero para gestionar una agenda. Aún
contando con un guión más o menos detallado, los imponderables que
sucedan, como errores en el código y demás, aportarían más frescura al
discurso hablado.
</p>
</div>
</div>
<div id="outline-container-orgbfd30e7" class="outline-2">
<h2 id="orgbfd30e7">El resultado</h2>
<div class="outline-text-2" id="text-orgbfd30e7">
<p>
La primera parte:
</p>

<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts allow-popups" title="Introducción a org-mode, parte 1" src="https://video.nogafam.es/videos/embed/bea86619-7f27-4e47-ae6a-a0e9ba666cb7" frameborder="0" allowfullscreen></iframe>

<p>
La segunda parte:
</p>

<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts allow-popups" title="Introducción a org-mode, parte 2" src="https://video.nogafam.es/videos/embed/7defd207-d331-4266-9016-387789a8457d" frameborder="0" allowfullscreen></iframe>

<p>
Los enlaces, por si queréis verlos fuera del <i>blog</i> son los
siguientes:
</p>

<ul class="org-ul">
<li><a href="https://video.nogafam.es/videos/watch/bea86619-7f27-4e47-ae6a-a0e9ba666cb7">Primera parte</a></li>
<li><a href="https://video.nogafam.es/videos/watch/7defd207-d331-4266-9016-387789a8457d">Segunda parte</a></li>
</ul>
</div>
</div>
<div id="outline-container-org62352b6" class="outline-2">
<h2 id="org62352b6">Conclusión</h2>
<div class="outline-text-2" id="text-org62352b6">
<p>
De momento, la tarea de editar vídeo sigue sin parecerme óptima. Un
vídeo lo miras de principio a fin pero es complicado ir haciendo lo
que hace la otra persona para que se te quede el procedimiento. Además
un texto lo puedes empezar a leer por donde quieras, ir directamente
al código, a un gráfico o a una explicación... en un vídeo es más
complicado encontrar justo lo que necesitas consultar. Por tango,
¿este <i>blog</i> se convertirá en <i>vlog</i>? ─como me ha preguntado alguno─,
pues no: me gusta escribir y contar cosas; cosas que sé o que creo
saber, cosas que siento o cosas que vivo. Un vídeo contándolas no me
resulta igual de atractivo. Así que no, no me voy a pasar al vídeo,
aunque puedo hacer alguno de vez en cuando.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> <a href="/tags/vídeo/index.html">vídeo</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <category><![CDATA[vídeo]]></category>
  <link>https://notxor.nueva-actitud.org/2021/07/19/introduccion-en-video-a-org-mode.html</link>
  <pubDate>Mon, 19 Jul 2021 21:31:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Videotutoriales]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-07-02</div>
<p>
A veces podemos tener la idea de que las cosas entran por los ojos y
un buen vídeo nos puede ahorrar muchas explicaciones. Esto puede ser
cierto y falso a la vez. No voy a entrar en muchos detalles, porque
creo que se verá de manera muy sencilla qué es lo que quiero expresar
con una serie de proyectos que estoy realizando. Se verá que cada cosa
tiene sus ventajas y sus inconvenientes y que es posible que lo que es
bueno para mostrar un proyecto no lo sea para mostrar otro. Se trata
de los siguientes temas.
</p>

<ol class="org-ol">
<li>Realizar un vídeo con mi forma de trabajar con <i>Emacs</i>.</li>
<li>Trabajar en un proyecto de programación, convirtiendo un proyecto
incipiente en <i>programación literaria</i>.</li>
<li>Ver si es posible realizar algunas de las entradas del <i>blog</i> en
forma de vídeo utilizando las herramientas a mi disposición:

<ul class="org-ul">
<li><code>ffmpeg</code></li>
<li><code>OBS</code></li>
<li><code>kdenlive</code></li>
<li><code>audacity</code></li>
<li><code>screenkey</code></li>
</ul></li>
</ol>

<p>
Entre los posibles inconvenientes está que mi <i>aterciopelada voz</i> no
se presta para ser grabada y mi incapacidad de aclararme conmigo mismo
sobre la marcha impiden que la captura del audio sea <i>fresca</i>. Para
eso siempre recurro a escribir lo que pienso, porque decir, digo
muchas tonterías. Aún teniendo el guión escrito, me encuentro con
algunos impedimentos técnicos derivados de lo justo que es mi
equipación para realizar estas tareas.
</p>
<div id="outline-container-org44af8cc" class="outline-2">
<h2 id="org44af8cc">Captura de pantalla con <code>ffmpeg</code></h2>
<div class="outline-text-2" id="text-org44af8cc">
<p>
De primeras pensé en hacerlo al estilo <i>yutuber pofesioná</i>
capturándolo todo con el <code>OBS Studio</code> mientras trabajaba. No hubo
manera de hacerlo correctamente. Aunque en el vídeo final hay algún
trozo capturado con <code>OBS</code> la mayoría del mismo está capturado con
<code>ffmpeg</code> utilizando el comando:
</p>

<div class="org-src-container">
<pre class="src src-shell">ffmpeg -f pulse -i default -f x11grab -framerate 10 -i :0.0 -q:v 5 fichero-video.mp4
</pre>
</div>

<p>
Viendo que mi tarjeta de sonido hace ruido como para ocultar el
despegue de un reactor, eliminé la captura del sonido:
</p>

<div class="org-src-container">
<pre class="src src-shell">ffmpeg -f x11grab -framerate 10 -i :0.0 -q:v 5 fichero-video.mp4
</pre>
</div>

<p>
Esta captura es directa y tendrá la resolución que tenga configurada
la pantalla. En mi caso, las <code>X</code> tienen una resolución de
<code>1920x1020</code> y a esa resolución quería el vídeo, para que el texto se
leyera con facilidad.
</p>

<p>
La captura se realiza además activando el programa <code>screenkey</code> para
mostrar qué teclas, y qué botón del ratón, voy pulsando mientras
trabajo. Esto facilitará mucho las explicaciones, porque podemos
obviar los listados interminables de las combinaciones de teclas.
</p>
</div>
</div>
<div id="outline-container-org354f062" class="outline-2">
<h2 id="org354f062">Ventajas e inconvenientes del videotutorial</h2>
<div class="outline-text-2" id="text-org354f062">
<p>
Todo lo que se me ocurre como ventaja es que es más visual, ese sería
su principal punto a favor. Se ve cómo se trabaja de forma directa,
qué teclas se pulsan y qué reacciones tiene <i>Emacs</i>. Para alguien que
se inicia en el uso de este editor es posible que vea que el trabajo
es tan fluido como con cualquier otro editor y se anime a probarlo más
a fondo.
</p>

<p>
Como digo, eso, quizá, sea su único punto a favor... el resto me he
encontrado con un montón de inconvenientes. Los enumero y explico
algunos:
</p>

<ul class="org-ul">
<li>Tenéis que soportar mi aterciopelada voz (podría ser considerado
como tortura en algunas culturas, lo sé).</li>
<li>El flujo de trabajo se me hace muy raro y farragoso (con lo fácil
que es escribir y ya).</li>
<li>Estoy limitado por el equipo con el cuento (soy pobre, os recuerdo
que podéis donar para comprar nuevo equipo si os <i>molan</i> los
vídeos).</li>
</ul>

<p>
Quizá el flujo de trabajo sea raro también, por una cuestión de
potencia del equipo con el que trabajo. Mi ordenador es un portátil
con un intel i5 y 4Gb de RAM de hace 11 años. El tema de gráficos y
proceso de sonido le vienen a estas alturas ya un poco justos, por no
decir cuesta arriba.
</p>

<p>
Como habéis visto antes la captura de vídeo la he hecho principalmente
con <code>ffmpeg</code> capturando a 10fps. Para ver cómo evoluciona el texto
sobre la pantalla es suficiente. Lo he hecho así por la imposibilidad,
o desconocimiento, de cómo conseguir la misma resolución con
<code>OBS</code>. Este programa se empeña en comprimir el vídeo y en algunos
momentos el texto se hacía ilegible. Sin embargo, lo he utilizado a la
hora de capturar las pruebas del código en el entorno gráfico. <code>OBS</code>
sincroniza bien el sonido con la imagen, sin embargo, al intentar
hacer la captura más precisa con <code>ffmep</code> el sonido se capturaba con
1,5 segundos de retardo, aproximadamente. Probé un montón de
parámetros para hacer la captura y después de perder mucho tiempo, me
decidí a capturar esa parte con <code>OBS</code>.
</p>

<p>
Capturar vídeo con <code>ffmpeg</code> y <code>OBS</code> y sonido con <i>Audacity</i> es lo de
menos: luego hay que montarlo todo y para eso utilicé <i>kdenlive</i>.
Juntar todas las pistas con un poco de coherencia supongo que será
cogerle el <i>tranquillo</i> al programa. El problema es que al generar el
vídeo tengo limitadas las posibilidades. Me he tenido que <i>pelear</i> con
los programas para conseguir la resolución que quería. Además de tener
que reducir la calidad, el tiempo que tarda en generar el vídeo,
bloqueándome cualquier otro trabajo, es enorme.
</p>

<p>
El principal problema con el sonido es la falta de aparatos
solventes. Toda la grabación de voz se realizó con unos auriculares
con micrófono. Sin embargo, el <i>hardware</i> produce tanto ruido que
posteriormente, con <i>audacity</i> debía pasarle a la pista varias veces
el filtro de reducción de ruido para conseguir algo decente. El
resultado es que la voz parece estar metida en una cueva. Aunque aún
presenta ruido que ha sido <i>enmascarado</i> por una bonita melodía de
fondo.
</p>
</div>
</div>
<div id="outline-container-orgeccd6a3" class="outline-2">
<h2 id="orgeccd6a3">Flujo de trabajo</h2>
<div class="outline-text-2" id="text-orgeccd6a3">
<p>
Mi expectativa era poder grabar el vídeo mientras iba haciendo el
trabajo. Como mucho al final sería cortar y pegar con <code>kdenlive</code> y
todo sería fácil, pero no ha sido así.
</p>

<p>
Primero, al capturar con <code>OBS</code> me encontraba que se empeñaba en
comprimir el vídeo y estropeaba la visualización del texto en
pantalla. También intenté capturar el vídeo con <code>ffmpeg</code>, reduciendo
los <code>fps</code>. El problema de la captura en directo es de mi <code>hardware</code> de
sonido, el problema de visualización del texto se puede solventar con
unas fuentes más grandes, pero el ruido parásito de la tarjeta de
sonido, no.
</p>

<p>
Por todos esos impedimentos, al final se desechó todo el sonido
grabado a la par que el vídeo y se grabó uno específicamente para
sustituirlo. La captura del sonido la he tenido que hacer, además, en
varias sesiones. Necesitaba la casa en silencio, así que aprovechaba
cuando la familia dormía, el perro del vecino no ladraba, las tórtolas
no se llamaban unas a otras, el camión de la basura no pasaba y, en
fin, cuando encontraba un poco de paz y sosiego para hacerlo. Si en el
vídeo, en algunas ocasiones, os parece que estoy susurrando, es que
efectivamente estaba susurrando porque cuando lo grabé todo el mundo
dormía. Ya lo siento.
</p>

<p>
Una vez registradas las imágenes y el sonido, hay que montarlo en el
vídeo. La herramienta elegida ha sido <code>kdenlive</code> como ya he dicho
antes y soy muy novato en estas lides. Se puede apreciar que ni
siquiera he sido capaz de alinear bien los títulos generados.  Tiene
tantos <i>pichorros</i> que me pierdo muchas veces y aunque sé lo que
quiero conseguir no sé muy bien cómo hacerlo.
</p>
</div>
</div>
<div id="outline-container-org1b6e0c4" class="outline-2">
<h2 id="org1b6e0c4">Resultados</h2>
<div class="outline-text-2" id="text-org1b6e0c4">
<p>
El resultado producido por el vídeo se puede ver en el repositorio
del <a href="https://codeberg.org/Notxor/espejitoproyecto">en <i>codeberg</i></a> y el vídeo es éste:
</p>

<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts allow-popups" title="Programación literaria con Emacs" src="https://video.nogafam.es/videos/embed/0c166161-8d59-4a48-9c87-feb55bb38c46" frameborder="0" allowfullscreen></iframe>

<p>
O directamente en <i>peertube</i>:
</p>

<p>
<a href="https://video.nogafam.es/videos/watch/0c166161-8d59-4a48-9c87-feb55bb38c46">https://video.nogafam.es/videos/watch/0c166161-8d59-4a48-9c87-feb55bb38c46</a>
</p>
</div>
</div>
<div id="outline-container-orge2b0f5d" class="outline-2">
<h2 id="orge2b0f5d">Conclusiones</h2>
<div class="outline-text-2" id="text-orge2b0f5d">
<p>
Con el vídeo soy menos productivo, no creo que pudiera mantener un
ritmo regular de publicar. Que no es que publique mucho, pero escribir
un <i>post</i> me lleva unas pocas horas, mientras que editar el vídeo me
lleva unos cuantos días. Además la falta de material adecuado: un
ordenador más potente, una tarjeta de sonido decente, un micrófono
adecuado, un espacio insonorizado que me permita grabar cuando quiera
y no cuando pueda, etc.
</p>

<p>
Ya me contaréis que os parece el experimento. Yo he visto el vídeo ya
unas cuantas veces mientras lo montaba, lo editaba y lo publicaba;
seguro que más fallos y pegas que le he encontrado yo ya no le vais a
encontrar. Pero ahí queda como referencia a superar en los próximos
vídeos (que viendo cómo ha quedado, es fácil hacerlo)
</p>

<p>
También aprovecho para agradecer a <a href="https://nogafam.es">https://nogafam.es</a> por
proporcionarme el espacio para alojar el vídeo de pruebas.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/tutorial/index.html">tutorial</a> <a href="/tags/video/index.html">video</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[tutorial]]></category>
  <category><![CDATA[video]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2021/07/02/videotutoriales.html</link>
  <pubDate>Fri, 02 Jul 2021 09:32:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Fuente con ligaduras Fira Code]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-06-24</div>
<p>
Venía preparado para escribir un largo artículo sobre algo, que
pensado más despacio parece una chorrada y hecho más deprisa lo es:
conseguir que nuestro querido <i>Emacs</i> muestre ligaduras en sus
fuentes.  A mí no me produce especial atracción, es algo muy
<i>hipster</i>, sin embargo, aprovechando que tengo dicha fuente instalada,
y la utilizo como fuente fija por defecto en la terminal, en
<i>hexchat</i>, en <i>firefox</i>, en... bueno, en casi todos los programas de
uso diario menos en <i>Emacs</i>.
</p>

<p>
En realidad, este artículo es el resultado de una conversación donde
un <i>friki</i> mostraba las bellas ligaduras en su editor de código y me
retaba a hacerlo en <i>mi feo Emacs</i>. El <i>pobrecico</i> aún no ha
interiorizado que cualquier cosa que haga su editor, seguramente, lo
hace <i>Emacs</i> desde hace mucho más tiempo. Así pues me puse a ello.
</p>

<p>
Me acordé de <code>fira-code-mode</code> y de que ya tenía las fuentes instaladas
en mi sistema. Lo bueno, es que si no las tienes tampoco pasa nada, el
mismo paquete te las instala. Pero vamos por pasos.
</p>

<ol class="org-ol">
<li><p>
<b>Instalar el paquete</b>
</p>

<p>
Como muchas veces hemos visto ya:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">M-x package-install RET fira-code-mode
</pre>
</div></li>

<li><p>
<b>Instalar las fuentes</b>
</p>

<p>
En mi caso ya las tenía instaladas. Pero hay que hacer un pequeño
apunte: el paquete las busca en <code>~/.local/share/fonts/</code>. Si no las
tienes ahí crea un enlace o copia las fuentes... o de forma aún más
sencilla:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">M-x fira-code-mode-install-fonts
</pre>
</div>

<p>
Ese simple comando instala las fuentes necesarias en el sitio donde
las busca, así no tendrás problemas.
</p></li>

<li><p>
<b>Establecer la fuente por defecto</b>
</p>

<p>
Una vez tenemos las fuentes instaladas y el modo preparado, hay que
decirle a <i>Emacs</i> que utilice esa fuente como predeterminada del
editor. Lo más rápido en este caso es recurrir al menú <code>Options -&gt;
   Set default font...</code>. La otra opción, para los que les gusta el
barro, es utilizar el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(custom-set-faces
 '(default ((t (<span style="color: #8be9fd; font-style: italic;">:family</span> <span style="color: #f1fa8c;">"Fira Code"</span> <span style="color: #8be9fd; font-style: italic;">:foundry</span> <span style="color: #f1fa8c;">"CTDB"</span> <span style="color: #8be9fd; font-style: italic;">:slant</span> normal <span style="color: #8be9fd; font-style: italic;">:weight</span> normal <span style="color: #8be9fd; font-style: italic;">:height</span> 98 <span style="color: #8be9fd; font-style: italic;">:width</span> normal)))))
</pre>
</div>

<p>
Ten cuidado, porque sólo debe haber un <code>custom-set-faces</code> en el
<code>init.el</code> y es posible que ya exista, por lo que sólo tienes que
modificarlo si ya existe.
</p></li>

<li><p>
<b>Activar el modo</b>
</p>

<p>
Debes decidir si quieres ligaduras para todo o sólo en algunos
casos, porque la configuración variará. Para la versión completa
sólo necesitas activar <code>global-fira-code-mode</code> y ya está. En mi
caso, como no quiero que lo utilice en todos los <i>buffers</i>, sólo en
los de programación o en <code>org-mode</code> he establecido los ganchos
adecuados:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-hook 'prog-mode-hook 'fira-code-mode)
(add-hook 'org-mode-hook 'fira-code-mode)
</pre>
</div>

<p>
Por supuesto, puedes activar o desactivar el modo en cada <i>buffer</i>
concreto de manera manual, llamando al comando <code>M-x fira-code-mode</code>
</p>

<p>
Por ejemplo, para conseguir verlo tal que:
</p>


<figure id="orgce8722f">
<img src="./imagenes/Captura-pantalla_comparacion-ligaduras.png" alt="Captura-pantalla_comparacion-ligaduras.png">

</figure>

<p>
Como se puede apreciar en la imagen anterior, la parte izquierda es
un <i>buffer</i> de una de las terminales de <i>Emacs</i> mostrando el texto
plano de un fichero hecho para probar las ligaduras. La parte
derecha es ese mismo fichero en un <i>buffer</i> de edición con las
ligaduras activadas. En este caso, como es un fichero <code>.txt</code> tuve
que activar el modo manualmente.
</p>

<p>
Por si a alguien le interesa para hacer pruebas, el contenido del
fichero es el siguiente:
</p>

<pre class="example" id="org7b83074">
     .= ..= .- := ::= =:= __
      == != === !== =/= =!=

 &lt;-&lt; &lt;&lt;- &lt;-- &lt;- &lt;-&gt; -&gt; --&gt; -&gt;&gt; &gt;-&gt;
 &lt;=&lt; &lt;&lt;= &lt;==    &lt;=&gt; =&gt; ==&gt; =&gt;&gt; &gt;=&gt;
    &gt;&gt;= &gt;&gt;- &gt;- &lt;~&gt; -&lt; -&lt;&lt; =&lt;&lt;
        &lt;~~ &lt;~ ~~ ~&gt; ~~&gt;

     &lt;&lt;&lt; &lt;&lt; &lt;= &lt;&gt;  &gt;= &gt;&gt; &gt;&gt;&gt;
   {. {| [| &lt;:  ✓  :&gt; |] |} .}
   &lt;||| &lt;|| &lt;| &lt;|&gt; |&gt; ||&gt; |||&gt;

            &lt;$ &lt;$&gt; $&gt;
            &lt;+ &lt;+&gt; +&gt;
            &lt;* &lt;*&gt; *&gt;

       \  \\  /* */  /// //
      &lt;/ &lt;!--  &lt;/&gt;  --&gt; /&gt;
      0xF 9:45 m-x *ptr www

       ;; :: ::: !! ?? %% &amp;&amp; 
      || .. ... ..&lt; .? ?. ?:
       -- --- ++ +++ ** ***

          ~= ~- -~ ~@
          ^= ?= /= /==
        -| _|_ |- |= ||=
        #! #= ## ### ####
      #{ #[ ]# #( #? #_ #_(
         
         
a*b a*A B*b A*B *a *A a* A*
a-b a-A B-b A-B -a -A a- A-
a+b a+A B+b A+B +a +A a+ A+
a:b a:A B:b A:B :a :A a: A:
</pre></li>
</ol>
<div id="outline-container-orga52f08e" class="outline-2">
<h2 id="orga52f08e">Conclusión</h2>
<div class="outline-text-2" id="text-orga52f08e">
<p>
¿Para qué sirven las ligaduras? La respuesta corta es para hacer el
texto más bonito, algunos dirán <i>más legible</i>. Hay quien prefiere cada
carácter en su sitio mientras programa.
</p>

<p>
Como va en gustos, tampoco le voy a dar muchas vueltas. Ya que me puse
con ello, se quedará en la configuración, pero no descarto que me
canse y finalmente desaparezcan las ligaduras de mi <i>Emacs</i>. Nunca se
sabe, porque hasta ahora he vivido perfectamente sin ellas y tampoco
creo que aporten nada imprescindible para mi trabajo.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/fuentes/index.html">fuentes</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[fuentes]]></category>
  <link>https://notxor.nueva-actitud.org/2021/06/24/fuente-con-ligaduras-fira-code.html</link>
  <pubDate>Thu, 24 Jun 2021 09:30:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[nyxt 2.0]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-06-10</div>
<p>
Creo que ya mencioné alguna vez <a href="https://nyxt.atlas.engineer/">nyxt</a> en este <i>blog</i> o quizá estoy
equivocado y sólo pensé hacerlo. En mi incansable búsqueda de un <i>web
browser</i> gráfico que llevarme a mis navegaciones por la <i>Internet</i>,
cada vez más, me van faltando alternativas. Parece que hay que quieren
obligarme a morir al palo de <i>chrome</i> y así llegué a encontrar éste
navegador, completamente escrito en <i>Lisp</i>. Hice varias pruebas con él
en su versión 1.1 y lo encontré muy prometedor pero algo inestable e
incompleto. Hace poco que me enteré que salió la versión 2.0<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> y vuelvo
al ataque, a ver si ha mejorado y efectivamente: lo ha hecho. ¿Es mi
navegador por defecto? Actualmente no, pero promete mucho y su modo
<i>Emacs</i> me facilita mucho las cosas.
</p>
<div id="outline-container-org6429f9d" class="outline-2">
<h2 id="org6429f9d">Inconveniente: no me compila</h2>
<div class="outline-text-2" id="text-org6429f9d">
<p>
A pesar de mis esfuerzos por compilarlo desde el código fuente no he
conseguido hacerlo. Mi hipótesis es que compila dependiendo de manera
bastante cerrada de cómo están situadas las librerías en la
distribución <i>GNU/Linux</i> y no encuentra dónde las sitúa <i>OpenSuse</i>.
Porque el error que me lanza es sobre una librería que tengo instalada
en una versión adecuada junto con el paquete <code>devel</code> con las
cabeceras.  El resto de dependencias, especialmente las de <i>Lisp</i> se
manejan automáticamente por el compilador <code>sbcl</code> ─el mismo que usa el
programador del sistema─ y no parece que haya problemas por ese lado.
</p>

<p>
No debo ser el único, porque una de las formas de distribución de
<i>nyxt</i> es con todo el paquete conteniendo las dependencias y librerías
metido todo en uno. Una solución que funciona, pero que ocupa un <i>güevo
y la yema del otro</i>.
</p>

<p>
Ese fue el motivo de descartarlo después de las pruebas iniciales que
hice la primera vez... pero acabándose las alternativas, a estas
alturas no me parece que sea tan descabellado instalarlo de ese modo.
No es el ideal y me gustaría haber podido compilarlo, pero al menos
funciona y puedo ir haciendo pruebas hasta que encuentre cómo arreglar
el problema de compilación.
</p>
</div>
</div>
<div id="outline-container-org1285cdd" class="outline-2">
<h2 id="org1285cdd">Cómo funciona</h2>
<div class="outline-text-2" id="text-org1285cdd">

<figure id="org6212364">
<img src="./imagenes/Captura-pantalla_nyxt-pagina-nyxt.png" alt="Captura-pantalla_nyxt-pagina-nyxt.png">

</figure>

<p>
La ventana del navegador tiene una apariencia pulcra y cuidada. ¿Te
recuerda a tu editor favorito? A mí sí. 
</p>

<p>
En la barra de estado podemos ver los habituales botones (de izquierda
a derecha) que nos permiten navegar a la página anterior, a la
posterior o recargar la página. El siguiente nos permite ejecutar uno
de los comandos del navegador y el último es la lista de <i>buffers</i>
abiertos. Al lado de la <i>botonera</i> está la dirección de la página que
tienes abierta. Más a la derecha una lista con los <i>buffers</i> que están
abiertos, y por último, el espacio más a la derecha, nos dice los
modos activados (por ejemplo, <code>emacs</code>, <code>noscript</code>, etc.).  Debajo de
la línea de estado, hay un <i>buffer</i> de texto que nos mostrará opciones
según los comandos, muy parecido a como funciona <i>Emacs</i> aunque más
ordenado y formateado en tablas.
</p>

<p>
Acabo de pasar por el asunto de los <i>comandos</i> muy rápido pero lleva
un completo intérprete de <i>Lisp</i> cargado en él.
</p>


<figure id="org8ee83b0">
<img src="./imagenes/Captura-pantalla_lisp-repl.png" alt="Captura-pantalla_lisp-repl.png">

</figure>

<p>
No lo he explorado aún a fondo, pero promete mucho, mucho. Para
rematar, no sé si os sonará, puedes meter cualquier parámetro de
inicio en el fichero <code>~/.config/nyxt/init.lisp</code>. Concretamente tengo
apenas dos ajustes para él:
</p>

<div class="org-src-container">
<pre class="src src-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Desactivar el javascript, por defencto al abrir un buffer
</span>(define-configuration buffer
  ((default-modes (append '(noscript-mode) %slot-default%))))

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Configurar las teclas de comando en modo Emacs
</span>(define-configuration buffer
  ((default-modes (append '(emacs-mode) %slot-default%))))
</pre>
</div>

<p>
Es posible también que no quieras modificar todas las teclas y sólo
quieras una o dos. Puedes, por ejemplo, modificar la combinación de
teclas para ejecutar un comando, sin cargar el <code>emacs-mode</code>, tal que:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(define-configuration buffer
  ((override-map (<span style="color: #ff79c6; font-weight: bold;">let</span> ((map (make-keymap <span style="color: #f1fa8c;">"override-map"</span>)))
                   (define-key map
                     <span style="color: #f1fa8c;">"M-x"</span> 'execute-command)))))
</pre>
</div>

<p>
Y esto me lleva al siguiente punto.
</p>
</div>
<div id="outline-container-org3129c4f" class="outline-3">
<h3 id="org3129c4f">Modos de teclas</h3>
<div class="outline-text-3" id="text-org3129c4f">
<p>
Otra de las cosas que me encanta del navegador es que cuenta con modos
de funcionamiento. Para resumirlo de manera rápida, <i>nyxt</i> puede
funcionar en tres modos, o conjuntos de definición de teclas, <code>CUA</code>
(por defecto), <code>emacs</code> y <code>vi</code> (este tiene dos modos, <code>vi-insert</code> y
<code>vi-normal</code><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>).
</p>

<p>
Por ejemplo, dos capturas para ver cómo cambian las cosas según el
modo empleado:
</p>


<figure id="orgcdc0d2e">
<img src="./imagenes/Captura-pantalla_follow-hint-CUA.png" alt="Captura-pantalla_follow-hint-CUA.png">

</figure>


<figure id="org7c1e347">
<img src="./imagenes/Captura-pantalla_follow-hint-emacs.png" alt="Captura-pantalla_follow-hint-emacs.png">

</figure>

<p>
En la primera captura se puede apreciar la configuración por defecto
de teclas. Sin embargo, en la siguiente, vemos la misma captura de
comando, pero con el <code>emacs-mode</code> activado.  Por ejemplo, la
combinación de teclas para activar <code>execute-command</code> en el modo por
defecto es <code>C-Espacio</code>, mientras que en <code>emacs-mode</code> es <code>M-x</code>.
</p>
</div>
</div>
<div id="outline-container-orgeb7e0bb" class="outline-3">
<h3 id="orgeb7e0bb">Edición</h3>
<div class="outline-text-3" id="text-orgeb7e0bb">
<p>
También cuenta con un editor de código interno:
</p>


<figure id="orgb10afc4">
<img src="./imagenes/Captura-pantalla_editor-buffer.png" alt="Captura-pantalla_editor-buffer.png">

</figure>

<p>
Aún le queda mucho recorrido para alcanzar otras herramientas de
desarrollo <code>html</code>, apenas es un <i>buffer</i> donde poder cargar un fichero
<code>html</code> o <code>css</code> o <code>js</code> y modificar un poco su código, sin coloreado de
sintaxis siquiera.
</p>
</div>
</div>
<div id="outline-container-org560f360" class="outline-3">
<h3 id="org560f360">Navegación sin ratón</h3>
<div class="outline-text-3" id="text-org560f360">
<p>
Navegar con ratón es como lo hacen el resto de los navegadores
<i>web</i>. El problema de otros navegadores es que sin ratón, navegar es
<i>la muerte a pellizcos</i>. Por el contrario, <code>nyxt</code> permite hacerlo sin
ese periférico sin morir en el intento.
</p>

<p>
Para navegar por las páginas <i>web</i> podemos encontrar dos maneras
distintas, que no falten alternativas. Una que tiene que ver con la
lógica de la página utilizando el comando <code>jump-to-heading</code>, que nos
mostrará una lista de las cabeceras definidas en la <i>web</i> cargada. Por
ejemplo:
</p>


<figure id="orgccf1a8c">
<img src="./imagenes/Captura-pantalla_navegacion-por-titulos.png" alt="Captura-pantalla_navegacion-por-titulos.png">

</figure>

<p>
Si las páginas <i>web</i> sólo nos permitieran saltar a esos titulares no
serían demasiado flexibles, quizá sería mejor leer un libro. La
potencia de la <i>web</i> es precisamente que podemos encontrar un montón
de enlaces en las páginas abiertas y formar la famosa <i>red</i>, abriendo
todo un inmenso mundo de posibilidades a la navegación. La mayoría de
los <i>browsers</i> gráficos permiten pinchar en cualquier enlace con el
ratón, pero, como he dicho antes, si por algún motivo no tienes ratón
o ganas de usarlo, navegar con cualquiera de ellos consiste en
descargar desesperadamente nuestra frustración sobre el tabulador
hasta alcanzar el elemento que deseamos para pulsar <i>enter</i>.
</p>

<p>
<code>nyxt</code> establece un comando que nos permite, mostrando una lista de
los enlaces encontrados en la página, seleccionar cuál queremos
utilizar y permitirnos saltar:
</p>


<figure id="org43783a9">
<img src="./imagenes/Captura-pantalla_navegacion-sin-raton.png" alt="Captura-pantalla_navegacion-sin-raton.png">

</figure>

<p>
El principio es sencillo, se añade una etiqueta, combinación de letras
a cada enlace y una lista que muestra el texto del enlace y la <code>URL</code>
asociada. Basta movernos por esa lista o teclear el <i>hint</i> y nos
moveremos como con el ratón.
</p>
</div>
</div>
</div>
<div id="outline-container-org03e4560" class="outline-2">
<h2 id="org03e4560">Conclusión</h2>
<div class="outline-text-2" id="text-org03e4560">
<p>
Es pronto para sacar conclusiones, me quedan aún muchas cosas para
investigar.  En su uso, encuentro que es un navegador ligero, responde
bien y rápido a los comandos, pero aún me encuentro torpe en su uso y
desconozco muchas de las posibilidades que puede ofrecer.
</p>

<p>
El que funcione mediante comandos, da la sensación, que permitirá el
poder generar <i>scripts</i> que no sólo configuren su funcionamiento, sino
que completen las cosas que puede hacer. Me da la sensación de que
puede convertirse en todo un nicho de desarrollo de aplicaciones, como
lo es <i>Emacs</i> y como otros navegadores intentas emular con un
lenguaje, <i>javascript</i>, menos agraciado que <i>Lisp</i>.
</p>

<p>
Ya volveré sobre el tema si consigo algo más interesante que contar.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
El día 20 del mes pasado. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Dos escrituras a elegir, vi, vi, vi, vi, viiiii</i>... ya me
disculparéis la coña. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/nyxt/index.html">nyxt</a> <a href="/tags/lisp/index.html">lisp</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[nyxt]]></category>
  <category><![CDATA[lisp]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2021/06/10/nyxt-2.0.html</link>
  <pubDate>Thu, 10 Jun 2021 08:58:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Charla sobre seguridad en redes]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-06-07</div>
<p>
Hace poco me propusieron hacer una charla sobre <i>Seguridad en Redes</i>
para una Asociación. Es una especie de intercambio o colaboración
entre asociaciones.  <a href="https://asociacionpica.org">PICA</a>, la asociación con la que yo colaboro,
ofreció organizar algunas charlas sobre diversos temas. Entre las
cuales se encuentra <a href="presentacion/index.html">ésta que yo voy a dar.</a> Por tanto, el artículo de
hoy va a ser muy cortito. Os ruego que veáis la presentación y me
sugiráis cosas que se pueden modificar, cambiar, meter o quitar para
dejar la charla redonda.
</p>

<p>
Los puntos fundamentales son:
</p>

<ul class="org-ul">
<li>Eliminar mitos sobre los <i>hackers</i>.</li>
<li>Dar unas nociones básicas sobre los <i>peligros</i> de conectarse a una
red.</li>
<li>Dar unas nociones básicas sobre autoprotección.</li>
</ul>

<p>
(que es lo que me han pedido), y:
</p>

<ul class="org-ul">
<li>Introducir el concepto de <i>soberanía digital</i>.</li>
<li>Presentarles las <i>Redes Sociales</i> distribuidas.</li>
</ul>

<p>
que no me lo han pedido pero me parece interesante meterlo también.
</p>

<p>
No he querido meter chistes o imágenes que siempre despistan un poco
del objetivo, pero intentaré hacerlo lo más ameno posible.
</p>

<p>
No quiero enrollarme mucho más, espero vuestros comentarios y ya os
contaré cómo sale. No sé si la grabarán o no... si la graban ya os lo
comentaré y pondré algún enlace (o no, depende de cómo me salga ;-)
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/hacking/index.html">hacking</a> <a href="/tags/seguridad/index.html">seguridad</a> <a href="/tags/redes/index.html">redes</a> ]]></description>
  <category><![CDATA[hacking]]></category>
  <category><![CDATA[seguridad]]></category>
  <category><![CDATA[redes]]></category>
  <link>https://notxor.nueva-actitud.org/2021/06/07/charla-sobre-seguridad-en-redes.html</link>
  <pubDate>Mon, 07 Jun 2021 09:19:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Programando un módulo para Minetest]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-05-28</div>
<p>
<a href="https://notxor.nueva-actitud.org/2021/05/07/minetest-y-otros-juegos-similares.html">Hace poco hablé de <i>Minetest</i> y comenté que lo estaba valorando</a> como
una posible herramienta educativa... todo consiste en programar lo que
necesitas para poder mostrarlo en un entorno <i>ya pensado</i> para poder
interactuar con él.  Me preguntaba entonces, en aquel artículo, si
sería muy difícil programar tus propios módulos para adaptar la
plataforma a tus necesidades. Bien, he comenzado la exploración y tras
algunos tropiezos voy encontrando la manera de hacerlo. En este
artículo vengo a contar <i>mis primeros pasitos</i>. ¿Qué hace el módulo de
prueba que quiero desarrollar? Un <i>espejo mágico</i>. Ya sabéis mi
debilidad con <i>las conversacionales</i> y yo quiero un objeto o un <i>algo</i>
con el que conversar: una <i>estupidez artificial</i> es lo más adecuado.
</p>
<div id="outline-container-orgfed0331" class="outline-2">
<h2 id="orgfed0331">Montar un mundo</h2>
<div class="outline-text-2" id="text-orgfed0331">
<p>
Lo primero que hice fue <i>un mundo</i> de pruebas, sólo para ver si era
complicado y trasteé un poco con los módulos, cuáles se cargan, cuáles
no... usé módulos hechos sólo por probar<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> y el mundo quedó
resultón.
</p>


<figure id="orgcfa0fe5">
<img src="./imagenes/Captura-pantalla_empezar-juego.png" alt="Captura-pantalla_empezar-juego.png">

</figure>

<p>
En la pantalla se puede ver que podemos crear un mundo simplemente
pulsando el botón donde dice <code>Nuevo</code>. Eso hará que nos aparezca la
pantalla de crear un nuevo mundo.
</p>

<p>
Otro aspecto importante es que si habilitamos las opción <code>Hospedar
servidor</code> desde cualquier ordenador conectado a la misma red, se puede
compartir el mundo y jugar juntos<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> desde los equipos conectados a
la misma.
</p>

<p>
Echado un primer vistazo al juego en general, ya vemos que podemos
utilizarlo en modo monousuario, como si fuera un lego virtual; poner
un servidor en una red local y jugar con los usuarios de dicha red,
algunas pruebas he hecho con mi hija conectados ambos en el mismo
mundo <i>local</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> y por último, también podemos conectarnos a un
servidor de los muchos que hay por <i>Internet</i> y jugar a un mundo que
ha hecho otro<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>.
</p>


<figure id="orgbb69372">
<img src="./imagenes/Captura-pantalla_crear-juego.png" alt="Captura-pantalla_crear-juego.png">

</figure>

<p>
El diálogo anterior nos permite generar un mundo con las opciones que
tenemos ahí. Ponerle un nombre, modificar la <i>semilla</i> aleatoria sobre
la que se generará el mapa, etc. Como lo que necesito es un mundo para
hacer pruebas tampoco hace falta mucha historia, pero ya puestos hice
un mundo con todo (cavernas, valles, y todas las opciones posibles).
Lo llamé <i>Kvintero</i> por otro proyecto con el que ando, pero tampoco es
importante a estas alturas el nombre. El caso es que funciona y lo
puedo recorrer, crear objetos y disponerlos en él como me parezca.
</p>

<p>
Es decir, ahora tenemos un terreno muy bonito, pero sigue siendo un
mundo por construir. Hay montañas, valles, cuevas, ríos... todo en
automático y sin esfuerzo. Como inicio, ya es bastante prometedor.
Puedes moverte e interactuar, pero si quieres tener cosas más
interesantes es aconsejable cargar algunos módulos, como he dicho.
</p>


<figure id="org6fd5fe4">
<img src="./imagenes/Captura-pantalla_cargar-modulos.png" alt="Captura-pantalla_cargar-modulos.png">

</figure>

<p>
En esa lista, al seleccionar el nombre de uno de los módulos nos
mostrará la información del módulo:
</p>


<figure id="org4f741fc">
<img src="./imagenes/Captura-pantalla_activar-modulo.png" alt="Captura-pantalla_activar-modulo.png">

</figure>

<p>
Como podemos observar, nos permite activarlo con el selector de
arriba, ver las dependencias (incluso las opcionales), etc.
Además, otra de las funciones recomendables de este diálogo lo
proporciona el botón que hay en la parte inferior derecha: <code>Encontrar
más mods</code>.
</p>


<figure id="orgbe769f1">
<img src="./imagenes/Captura-pantalla_repositorio-modulos.png" alt="Captura-pantalla_repositorio-modulos.png">

</figure>

<p>
Podemos obtener información más detallada de los módulos pulsando en
su botón de opción (el de más a la derecha) o incorporarlo al mundo
pulsando sobre el botón <code>+</code>. Si lo hacemos, el programa se conecta con
el <i>repositorio de módulos</i> y descarga el código en tu máquina y lo
guarda en el directorio <code>~/.minetest/mods/</code>
</p>

<p>
La estructura del directorio <code>.minetest</code> es buena tenerla en
cuenta... En ese lugar también guarda el sistema información que nos
viene muy bien, un fichero llamado <code>debug.txt</code> donde nos mostrará
avisos que nos pueden servir para depurar nuestro código.
</p>

<p>
También he descubierto, que lanzando <i>Minetest</i> desde la consola, nos
aparece información adicional que nos va declarando todas las acciones
que se llevan a cabo en el mundo. He utilizado el siguiente comando:
</p>

<div class="org-src-container">
<pre class="src src-shell">minetest &gt; servidor.log 2&gt; acciones.log
</pre>
</div>

<p>
Después podemos observar el contenido de dichos archivos. Por ejemplo,
<code>servidor.log</code> puede contener algo así:
</p>

<pre class="example" id="org986441f">
Loaded texture: /usr/share/minetest/games/minetest_game/menu/header.png
Loaded texture: /home/notxor/.minetest/games/Lord-of-the-Test-1.1.0/menu/icon.png
Loaded texture: /usr/share/minetest/games/devtest/menu/icon.png
Loaded texture: /usr/share/minetest/games/minetest_game/menu/icon.png
Loaded texture: /usr/share/minetest/textures/base/pack/plus.png
(T@mobs_animal)[MOD] Mobs Redo Animals loaded
</pre>

<p>
El fichero de acciones podría ser algo así:
</p>

<pre class="example" id="org1e6c04c">
2021-05-28 19:08:21: [Main]: Automatically selecting world at [/home/notxor/.minetest/worlds/Kvintero]
[ALSOFT] (EE) Failed to set real-time priority for thread: Operation not permitted (1)
[ALSOFT] (EE) Failed to set real-time priority for thread: Operation not permitted (1)
2021-05-28 19:08:29: ACTION[Main]: [MOD] Mobs Redo loaded
        .__               __                   __   
  _____ |__| ____   _____/  |_  ____   _______/  |_ 
 /     \|  |/    \_/ __ \   __\/ __ \ /  ___/\   __\
|  Y Y  \  |   |  \  ___/|  | \  ___/ \___ \  |  |  
|__|_|  /__|___|  /\___  &gt;__|  \___  &gt;____  &gt; |__|  
      \/        \/     \/          \/     \/        
2021-05-28 19:08:29: ACTION[Main]: World at [/home/notxor/.minetest/worlds/Kvintero]
2021-05-28 19:08:29: ACTION[Main]: Server for gameid="minetest" listening on 0.0.0.0:30000.
2021-05-28 19:08:32: ACTION[Server]: Notxor [127.0.0.1] joins game. List of players: Notxor
2021-05-28 19:08:32: WARNING[Main]: Irrlicht: Could not open file of texture: character.png
2021-05-28 19:08:34: ACTION[Server]: Notxor uses espejito:node, pointing at [node under=61,12,320 above=61,13,320]
2021-05-28 19:08:37: ACTION[Server]: Notxor pregunta al espejito: Hola
2021-05-28 19:08:41: ACTION[Server]: Notxor uses espejito:node, pointing at [node under=61,12,320 above=61,13,320]
2021-05-28 19:08:44: ACTION[Server]: Notxor pregunta al espejito: asdfasd 
2021-05-28 19:08:49: ACTION[Server]: Notxor uses espejito:node, pointing at [node under=61,12,320 above=61,13,320]
2021-05-28 19:08:58: ACTION[Server]: Notxor pregunta al espejito: Contenido de la pregunta
2021-05-28 19:09:01: WARNING[Main]: Irrlicht: Could not open file of texture: mobs_chicken_white.png
2021-05-28 19:09:06: ACTION[Server]: Notxor uses espejito:node, pointing at [node under=61,12,321 above=61,13,321]
2021-05-28 19:09:09: ACTION[Server]: Notxor pregunta al espejito: asdf asd
2021-05-28 19:09:14: ACTION[Server]: Notxor digs default:dirt_with_grass at (62,12,321)
2021-05-28 19:09:16: ACTION[Server]: Notxor digs default:dirt_with_grass at (62,12,322)
2021-05-28 19:09:17: ACTION[Server]: Notxor places node default:dirt_with_grass at (62,12,322)
2021-05-28 19:09:18: ACTION[Server]: Notxor places node default:dirt_with_grass at (62,12,321)
2021-05-28 19:09:19: ACTION[Server]: Notxor digs default:dirt at (63,12,320)
2021-05-28 19:09:19: ACTION[Server]: Notxor digs default:dirt_with_grass at (62,12,320)
2021-05-28 19:09:20: ACTION[Server]: Notxor places node default:dirt_with_grass at (62,12,320)
2021-05-28 19:09:21: ACTION[Server]: Notxor places node default:dirt_with_grass at (63,12,320)
2021-05-28 19:09:32: ACTION[Main]: Server: Shutting down
</pre>

<p>
Se puede observar, que he realizado algunas acciones sólo para ver
cómo se muestran en la salida. El redireccionar las salidas a ficheros
lo he hecho sólo a efectos de tener algo que cortar y pegar en el
artículo, pero no me parece una mala política si quieres tener un
seguimiento de lo que hacen los usuarios en tu servidor.
</p>
</div>
</div>
<div id="outline-container-org6cda4be" class="outline-2">
<h2 id="org6cda4be">Programar un módulo</h2>
<div class="outline-text-2" id="text-org6cda4be">
<p>
Esto es sólo una prueba, pero no me ha costado demasiado hacerlo, más
allá de algún pequeño atasco por falta de información, no porque haya
poca, sino porque me he tirado al ruedo sin leer el manual de
instrucciones y me ha pillado todo el asunto muy <i>poco leído</i> e
instruido.
</p>

<p>
El caso es que estuve pensando durante algún tiempo qué tipo de módulo
podía escribir, algo que fuera relativamente fácil de modelar, que
fuera, como mucho, un cubo para mostrarse en un <i>voxel</i>... pero sí
tenía claro que quería programar un diálogo de entrada de datos y
también una salida que fuera de texto a la consola. Todas esas
condiciones se cumplían en el intento de hacer un <i>espejo mágico</i> al
que hacer preguntas y que conteste.
</p>

<p>
Preparar el proyecto, fue muy sencillo: creé un directorio llamado
<code>espejito</code> dentro del directorio de módulos, es decir:
</p>

<p>
<code>~./.minetest/mods/espejito</code>
</p>

<p>
El único contenido que puse en el primer paso fue el fichero
<code>mod.conf</code> con el siguiente contenido:
</p>

<pre class="example" id="org3c57c9e">
name = espejito
description = Proporciona un espejo mágico con el que hablar
depends = default
author = Notxor
</pre>

<p>
Como se puede ver es una configuración muy sencilla: proporciona un
nombre, una descripción, las dependencias de otros módulos y el autor.
Es decir, la información mínima para funcionar, incluso algunos de los
campos no son necesarios para que <i>Minetest</i> lo procese como un módulo.
</p>

<p>
También creé un fichero llamado <code>init.lua</code>, al principio vacío.
</p>
</div>
<div id="outline-container-orgd013e60" class="outline-3">
<h3 id="orgd013e60">Crear el objeto</h3>
<div class="outline-text-3" id="text-orgd013e60">
<p>
Lo primero, y quizá lo más fácil, fue introducir un objeto nuevo en el
módulo. Sólo hay que registrar el nodo:
</p>

<div class="org-src-container">
<pre class="src src-lua">  minetest.register_node(
        <span style="color: #f1fa8c;">"espejito:node"</span>, {
           description = <span style="color: #f1fa8c;">"Espejito m&#225;gico"</span>,
           <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">drawtype = "glasslike",
</span>           drawtype = <span style="color: #f1fa8c;">"signlike"</span>,
           paramtype2 = <span style="color: #f1fa8c;">"wallmounted"</span>,
           selection_box = {
              <span style="color: #8be9fd; font-style: italic;">type</span> = <span style="color: #f1fa8c;">"wallmounted"</span>,
           },
           tiles = {<span style="color: #f1fa8c;">"espejito_textura.png"</span>},
           <span style="color: #50fa7b; font-weight: bold;">on_use</span> = <span style="color: #ff79c6; font-weight: bold;">function</span>(<span style="color: #f8f8f2; font-weight: bold;">itemstack</span>, <span style="color: #f8f8f2; font-weight: bold;">player</span>, <span style="color: #f8f8f2; font-weight: bold;">pointed_thing</span>)
              minetest.show_formspec(player:get_player_name(), <span style="color: #f1fa8c;">"pregunta_espejo"</span>, get_pregunta_formspec())
           <span style="color: #ff79c6; font-weight: bold;">end</span>,
           sounds = default.node_sound_glass_defaults(),
           groups = {cracky = 3},
})
</pre>
</div>

<p>
Este es el código tal y como está funcionando ahora, ha habido varias
evoluciones según miraba la documentación. De primeras, por ejemplo,
lo definí como un objeto <code>drawtype</code> de cristal, sin embargo, después
de mirar la documentación me pareció más adecuado que se dibujara como
un <i>cartel</i> o <i>señal</i>, además seleccioné el tipo de selección como
<i>montado en la pared</i> que es donde debería colgarse un espejo.
También, proporcioné una textura que se encuentra en el siguiente
<i>path</i>:
</p>

<p>
<code>~/.minetest/mods/espejito/textures/espejito_textura.png</code>
</p>

<p>
Es un <code>PNG</code> de \(16 \times 16\) creado para la ocasión y, como se puede
apreciar, no hace falta especificar el <i>path</i>, porque <i>Minetest</i>
entiende que debe estar en el lugar estándar.
</p>

<p>
Podemos ver también, que se especifican los sonidos de cristal. Es
decir, cuando lo rompemos, lo golpeamos o realizamos una acción con él
se utilizarán los sonidos que hay para <i>cristal</i> en el módulo
<code>default</code>.
</p>

<p>
También llamará la atención la aparición de <code>on_use</code> donde se
establece una función que se ejecutará cuando queramos usarlo, sin
embargo, lo explicaré más detenidamente más adelante, porque es donde
está el <i>meollo</i> del código. Pero antes de meternos en código quiero
comentar algunos aspectos interesantes de la declaración de los
objetos, por ejemplo el de cómo crear un <i>espejito mágico</i>:
</p>

<div class="org-src-container">
<pre class="src src-lua">minetest.register_craft(
   {
      <span style="color: #8be9fd; font-style: italic;">type</span> = <span style="color: #f1fa8c;">"shaped"</span>,
      output = <span style="color: #f1fa8c;">"espejito:node"</span>,
      recipe = { {<span style="color: #f1fa8c;">"default:glass"</span>, <span style="color: #f1fa8c;">"default:diamond"</span>, <span style="color: #f1fa8c;">"default:glass"</span>} },
})
</pre>
</div>

<p>
El formato de la creación de un <i>espejito</i> es sencillo de entender: es
un tipo <i>forma</i>, se genera una salida (<code>output = "espejito:node"</code>) con
una receta (<code>recipe</code>)<sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>.
</p>


<figure id="org726a814">
<img src="./imagenes/Captura-pantalla_espejo-en-pantalla.png" alt="Captura-pantalla_espejo-en-pantalla.png">

</figure>

<p>
Simplemente con esto ya aparece el objeto en el mundo. Aunque no se
puede hacer mucho con él: podemos crearlo, destruirlo, pero poco más.
</p>
</div>
</div>
<div id="outline-container-orgaa4179a" class="outline-3">
<h3 id="orgaa4179a">Dotar al objeto de acciones</h3>
<div class="outline-text-3" id="text-orgaa4179a">
<p>
Como dije antes, al declarar el objeto se ha metido una función que
responderá a la acción <code>on_use</code>. ¿Qué hace esa función? Mostrar un
formulario, veamos el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-lua"><span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #ff79c6; font-weight: bold;">function</span> <span style="color: #50fa7b; font-weight: bold;">get_pregunta_formspec</span>()
   <span style="color: #ff79c6; font-weight: bold;">return</span> <span style="color: #f1fa8c;">"size[5.75,3.5]"</span>..
      <span style="color: #f1fa8c;">"label[1,0.25;&#191;Qu&#233; desea vuestra excelencia?]"</span>..
      <span style="color: #f1fa8c;">"field[0.5,1.5;5.25,1;pregunta;Pregunta: ;]"</span>..
      <span style="color: #f1fa8c;">"button_exit[1.5,2.3;3,0.8;preguntar;Preguntar]"</span>
<span style="color: #ff79c6; font-weight: bold;">end</span>

<span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #ff79c6; font-weight: bold;">function</span> <span style="color: #50fa7b; font-weight: bold;">conversacion</span>()
   <span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">frases</span> = {
      <span style="color: #f1fa8c;">"Cu&#241;aaaaao..."</span>,
      <span style="color: #f1fa8c;">"No puedorrr, no puedorrr..."</span>,
      <span style="color: #f1fa8c;">"&#161;&#191;Que si quiere bolsa?!"</span>
   }
   <span style="color: #ff79c6; font-weight: bold;">return</span> frases[<span style="color: #8be9fd; font-style: italic;">math</span>.<span style="color: #8be9fd; font-style: italic;">random</span>(#frases)]
<span style="color: #ff79c6; font-weight: bold;">end</span>
</pre>
</div>

<p>
como vimos en <code>on_use</code> se llamaba a <code>show_formspec</code>, se obtiene el
nombre del jugador, se pone nombre al formulario (<code>pregunta_espejo</code>) y
se llama a la función <code>get_pregunta_fromspec()</code>.
</p>


<figure id="org4ff0dde">
<img src="./imagenes/Captura-pantalla_formulario.png" alt="Captura-pantalla_formulario.png">

</figure>

<p>
Para capturar el contenido del formulario:
</p>

<div class="org-src-container">
<pre class="src src-lua">minetest.register_on_player_receive_fields(<span style="color: #ff79c6; font-weight: bold;">function</span>(<span style="color: #f8f8f2; font-weight: bold;">player</span>, <span style="color: #f8f8f2; font-weight: bold;">formname</span>, <span style="color: #f8f8f2; font-weight: bold;">fields</span>)
      <span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">nombre_jugador</span> = player:get_player_name()
      <span style="color: #ff79c6; font-weight: bold;">if</span> fields.pregunta ~= <span style="color: #bd93f9;">nil</span> <span style="color: #ff79c6; font-weight: bold;">then</span>
         <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">informaci&#243;n de depuraci&#243;n a la consola
</span>         minetest.log(<span style="color: #f1fa8c;">"action"</span>, nombre_jugador .. <span style="color: #f1fa8c;">" pregunta al espejito: "</span> .. fields.pregunta)
         <span style="color: #ff79c6; font-weight: bold;">if</span> (formname == <span style="color: #f1fa8c;">"pregunta_espejo"</span> <span style="color: #ff79c6; font-weight: bold;">and</span> fields.pregunta ~= <span style="color: #f1fa8c;">""</span>) <span style="color: #ff79c6; font-weight: bold;">then</span>
            minetest.chat_send_player(nombre_jugador, conversacion())
         <span style="color: #ff79c6; font-weight: bold;">end</span>
      <span style="color: #ff79c6; font-weight: bold;">end</span>
<span style="color: #ff79c6; font-weight: bold;">end</span>)
</pre>
</div>


<figure id="org0dae758">
<img src="./imagenes/Captura-pantalla_respuestas.png" alt="Captura-pantalla_respuestas.png">

</figure>

<p>
Como se puede observar, independientemente de lo que le preguntemos al
espejo, lo que hace la función <code>conversacion</code> es enviar al azar una
frase de las que hay en su lista de frases. Vale, que no son muchas ni
muy inteligentes... pero es una <i>estupidez artificial</i>, que es como
una <i>inteligencia artificial</i> pero sin intentar engañar al usuario.
</p>
</div>
</div>
</div>
<div id="outline-container-orgd7df4df" class="outline-2">
<h2 id="orgd7df4df">Conclusiones</h2>
<div class="outline-text-2" id="text-orgd7df4df">
<p>
Es el primer módulo para <i>Minecraft</i> que hago y aún no está
terminado. Mi intención es hacer un <i>bot conversacional</i>.
</p>

<p>
Los siguientes pasos serán mejorar la funcionalidad de <code>conversacion</code>,
primero haciendo una especie de <i>Eliza</i> o algo similar.  El objetivo
no es crear algo usable para el juego como tal, aunque si es así,
tampoco pasaría nada. El objetivo último es aprender cómo funciona la
creación de módulos y profundizar hasta tener una idea más precisa de
lo que es factible a la hora de diseñar un juego para esta
plataforma.
</p>

<p>
Para más información podéis consultar un libro introductorio sobre la
programación de módulos para <i>Minetest</i> y la API de la plataforma en
los siguientes enlaces:
</p>

<ul class="org-ul">
<li><a href="https://rubenwardy.com/minetest_modding_book/en/index.html">https://rubenwardy.com/minetest_modding_book/en/index.html</a></li>
<li><a href="https://minetest.gitlab.io/minetest/">https://minetest.gitlab.io/minetest/</a></li>
</ul>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Y por tener código que mirar, copias y plagiar si fuera
necesario.  Algo que más que necesario es imprescindible cuando no
sabes muy bien qué estás haciendo, como es el caso.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Recuerda abrir en el cortafuegos el puerto 30000, o el que
utilices para el juego.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Es una experiencia bastante más agradable, no hay <i>lag</i> y todos
los jugadores son amigables (depende de con quién te juntes, claro) 
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Si hace poco que te has interesado por este mundillo,
seguramente el mundo que diseñe otro para jugar será mucho mejor del
que puedes crear tú en el primer momento... como me sucede a mí.
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
La estructura de la receta es conveniente mirarla en la
documentación. No es complicado de entender, pero necesita una
explicación larga, especialmente si no has jugado nunca a este juego.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/minetest/index.html">minetest</a> <a href="/tags/juegos/index.html">juegos</a> ]]></description>
  <category><![CDATA[minetest]]></category>
  <category><![CDATA[juegos]]></category>
  <link>https://notxor.nueva-actitud.org/2021/05/28/programando-un-módulo-para-minetest.html</link>
  <pubDate>Fri, 28 May 2021 11:25:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Utilizando tor con proxychains]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-05-21</div>
<p>
Hace un tiempo que el navegador <code>tor-browser</code> no me bloquea
<code>javascript</code>. He intentado varias cosas para no navegar por la red
utilizando el <code>js</code>. Intenté <i>torificar Firefox</i> para poder navegar con
él por <i>Internet</i>, porque el <i>plugin</i> sí funciona en el <i>Firefox</i>
normal, pero no funcionó. Oí hablar de <code>proxychains</code> hace unos meses,
pero fui procrastinando el utilizarlo, por pereza: otro <i>chismático</i>
que aprender... Sin embargo, el otro día, <a href="https://www.redeszone.net/tutoriales/seguridad/proxychains-tor-linux-ocultar-identidad-internet/">leí un artículo</a><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> y me
di cuenta de que era bastante sencillo de utilizar, no había excusa,
me decidí a probarlo. Este, corto, artículo va de los pasos que he
dado con mi <i>OpenSuse Tumbleweed</i> para configurarlo todo comprobando
que, efectivamente, funciona y cómo <code>proxychains</code> utiliza <code>tor</code> como
si fuera una <i>VPN</i>.
</p>

<p>
Lo primero es comprobar que tenía instalados ambos programas. De <code>tor</code>
estaba seguro, porque lo uso habitualmente. Sólo comprobé que está el
demonio ejecutándose.
</p>


<figure id="org35b292e">
<img src="./imagenes/Captura-pantalla_administrador-servicios.png" alt="Captura-pantalla_administrador-servicios.png">

</figure>

<p>
Efectivamente, podemos ver en el administrador de servicios que <code>tor</code>
está funcionando y está configurado para arrancar al iniciar la
máquina. Con <code>proxychains</code> fue otra historia, porque ni lo tenía
instalado.
</p>

<p>
Primero comprobé que existe un paquete para mi distribución:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; sudo zypper search proxychains
[sudo] password for root:
[...]
Cargando datos del repositorio...
Leyendo los paquetes instalados...

S  | Name                       | Summary                                      | Type
---+----------------------------+----------------------------------------------+------------
   | proxychains-ng             | Redirect connection through proxy servers    | paquete
   | proxychains-ng             | Redirect connection through proxy servers    | paquete src
   | proxychains-ng-debuginfo   | Debug information for package proxychains-ng | paquete
   | proxychains-ng-debugsource | Debug sources for package proxychains-ng     | paquete
</pre>
</div>

<p>
Bien, el paquete está, y por tanto lo instalé:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; sudo zypper install proxychains-ng
</pre>
</div>

<p>
Es una instalación sencilla, no me pidió ninguna dependencia y cero
<i>paquetes recomendados</i>.
</p>

<p>
Después de la instalación viene la configuración. En este caso seguí
los pasos dados por el artículo enlazado anteriormente. Comprobé
primero que el archivo de configuración está en el sitio indicado en
el texto. Muchas veces, al cambiar de distribución, sucede que las
cosas no se instalan en el mismo directorio. Para curarme en salud
hice la prueba:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; find / -name proxychains.conf 2&gt;/dev/null
/etc/proxychains.conf
</pre>
</div>

<p>
El artículo recomienda modificar la configuración de <code>proxychains</code> de
forma que debemos comentar la línea <code>strict_chain</code> y activar la línea
que aparece como <code>dynamic_chain</code>. 
</p>

<pre class="example" id="org43b07f7">
dynamic_chain
#
# (...)
#
#strict_chain
</pre>


<figure id="orgf4ef960">
<img src="./imagenes/Captura-pantalla_proxychains-conf.png" alt="Captura-pantalla_proxychains-conf.png">

</figure>

<p>
Además también recomienda modificar la última línea, que usa <code>socks4</code>,
para activar la conexión con <code>socks5</code> a través del puerto <i>proxy</i> que
abre <code>tor</code>, que es el <code>9050</code>. Así pues la línea quedará tal que:
</p>

<pre class="example" id="org021b9b7">
socks5 127.0.0.1 9050
</pre>

<p>
Después hay que probar cómo funciona. Para hacerlo me conecté con dos
navegadores diferentes a la página <a href="https://cualesmiip.com">https://cualesmiip.com</a> para poder
hacer la siguiente captura:
</p>


<figure id="org6a8b1cd">
<img src="./imagenes/Captura-pantalla_cual-es-mi-ip.png" alt="Captura-pantalla_cual-es-mi-ip.png">

</figure>

<p>
Se puede apreciar en la parte izquierda cómo <i>Falkon</i> muestra la <code>IP</code>
que corresponde a la máquina, pero al lanzar
</p>

<div class="org-src-container">
<pre class="src src-shell">proxychains4 firefox https://cualesmiip.com
</pre>
</div>

<p>
vemos a la derecha que <i>Firefox</i> obtiene un valor totalmente diferente
y lo localiza como uno de los servidores <code>tor</code>.
</p>

<p>
Se puede ver que en mi caso, en <i>OpenSuse Tumbleweed</i>, el ejecutable
es <code>proxychains4</code> y el formato del comando es sencillo:
</p>

<div class="org-src-container">
<pre class="src src-shell">proxychains4 [-f fichero.conf] aplicaci&#243;n [par&#225;metros de la aplicaci&#243;n]
</pre>
</div>

<p>
Podemos tener varias configuraciones para <code>proxychains</code> y cargar el
fichero de configuración que queramos. Por ejemplo, si tenemos algún
listado de <i>proxys</i> específicos para algunas tareas y queremos que
<i>enrute</i> las conexiones a través de ellos.
</p>
<div id="outline-container-orgc85c4be" class="outline-2">
<h2 id="orgc85c4be">Conclusiones</h2>
<div class="outline-text-2" id="text-orgc85c4be">
<p>
No hay mucho más que rascar, salvo profundizar más en el uso y las
opciones que proporciona <code>proxychains</code>. Recordando que cuantos más
saltos de nuestra información a través de <code>proxys</code>, más lenta será
nuestra navegación, aunque por otro lado, sea más difícil de seguir su
traza.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Siento no recordar quién lo enlazó por <i>mastodon</i> para
agradecérselo. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/tor/index.html">tor</a> <a href="/tags/seguridad/index.html">seguridad</a> ]]></description>
  <category><![CDATA[tor]]></category>
  <category><![CDATA[seguridad]]></category>
  <link>https://notxor.nueva-actitud.org/2021/05/21/utilizando-tor-con-proxychains.html</link>
  <pubDate>Fri, 21 May 2021 11:30:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Aprende Git como si fueras psicólogo]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-05-18</div>
<p>
Ya sé, no soy muy original en el título. El fondo del asunto es que
tras pelearnos con las bases de <i>LaTeX</i> la pregunta fue: «¿Y cómo
haces para saber cuándo se ha cambiado algo y quién lo ha hecho si el
trabajo es en equipo?» Mi respuesta es que no sólo cuando trabajo en
equipo, también cuando trabajo solo, hay ocasiones en que es
aconsejable llevar un control de los cambios que se hacen sobre un
proyecto. Este mismo problema lo tienen los programadores en su
trabajo y lo vienen resolviendo desde hace décadas con herramientas
que se llaman <i>control de versiones</i>. De éstas, la que uso últimamente
es <i>Git</i>, ─lo pronuncio como <i>guit</i>, con <i>g</i> suave─, que es uno de los
más potentes, aunque tenga fama de difícil.
<a href="https://notxor.nueva-actitud.org/2020/11/30/probando-fossil.html">También puedes utilizar <i>fossil</i></a>. Ambos dan para otro minicurso de los
míos, pero quiero ser breve y ya he hablado en alguna ocasión de cómo
uso <i>git</i> y lo puedes encontrar en el <i>blog</i>. Perdóname que no repita
contenido. Lee este artículo, si estás interesado en <code>git</code> y después
lee atentamente los que te recomiendo a continuación. El objetivo de
este artículo no es que aprendas a manejar un control de versiones
como un profesional, sino que sepas que existen este tipo de programas
y que también hay entornos gráficos para ellos.
</p>

<p>
Para comenzar, es recomendable encontrar la información previa en el
<i>blog</i>.  <a href="https://notxor.nueva-actitud.org/tags/git/index.html">Puedes encontrar otros artículos míos sobre <code>git</code> aquí</a> y te
recomiendo comenzar por éste primero:
</p>

<p>
<a href="https://notxor.nueva-actitud.org/2017/11/14/como-estoy-utilizando-git.html">https://notxor.nueva-actitud.org/2017/11/14/como-estoy-utilizando-git.html</a>
</p>

<p>
Como verás, es una herramienta muy potente pero algo compleja de
manejar, la curva de aprendizaje es empinada y puede jugar en nuestra
contra el miedo a cargarnos algo. Olvídate de ese miedo, los controles
de versiones se crearon precisamente para no perder nada de
información.  ¿Qué es lo que debemos aprender primero? ¿Por dónde
empezamos y de qué hilos hemos de ir tirando? Os voy a contar un
secreto: <i>La línea de comandos es tu amiga</i>. Pero entiendo que muchos
de vosotros no habéis abierto una consola en vuestra vida. En este
artículo trataré sobre herramientas gráficas para gestionar
<code>git</code>... pero no explicaré en profundidad qué es ni cómo funciona. Es
más, básicamente sólo te voy a hablar por encima de dos entornos
gráficos que ya vienen con <code>git</code>.
</p>

<p>
Lo primero que debemos aprender es que <code>git</code> organiza <i>repositorios</i>,
que a falta de mejor nombre, consisten en una serie de <i>instantáneas</i>
del estado de los ficheros de un directorio. Puedes imaginar que <code>git</code>
es una <i>cámara fotográfica</i> y que cada vez que le haces <i>una
foto</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> a tu directorio congelas su estado y podrás siempre volver
a verlo en ese estado, como cuando miras una foto de esas en las que
aún tenías pelo. Por otro lado, <code>git</code> también organiza ese álbum de
fotos y nos permite visualizar cada una de esas fotografías
organizándolas en distintos grupos<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> con sus separadores (<i>ramas</i>)
para que no se mezclen ni se líe todo. También puedes trastear con las
instantáneas y mezclarlas (<i>merge</i>), pegar parte de una en otra o
cambiar entre carpetas (<i>checkout</i>), cambiarles el fondo (<i>rebase</i>),
etc.
</p>

<p>
Viendo un repositorio podemos, por tanto ver claramente cómo ha ido
evolucionando nuestro proyecto, desde el principio hasta el estado
actual. Podemos situarnos en cualquiera de las <i>instantáneas</i> y ver
cómo estaba el proyecto cuando se hizo esa <i>foto</i>.
</p>

<p>
No quiero repetirme y te invito a que leas los artículos que ya
escribí sobre <code>git</code> en su día. Pero sé lo que estás pensando: ¿sólo
línea de comandos? Sí, bueno, la herramienta es de línea de comandos y
siempre es bueno conocerlos, sobre todo para tener más claro cómo
funcionan los mismos, pero hay herramientas gráficas para manejar los
repositorios. Si necesitas un entorno gráfico para manejar <code>git</code><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>
puedes encontrar muchos hechos para esa tarea, simplemente haciendo
una búsqueda por <i>Internet</i>. Además, algunos editores traen consigo
algún <i>plugin</i> o herramienta para hacerlo gráficamente también. Como
ya sabéis yo utilizo <i>Emacs</i> y éste tiene <code>magit</code>.
</p>

<p>
Pero seguramente, no necesitarás instalar ninguna herramienta extra,
pues <code>git</code> viene con su propia <i>interface</i> gráfica y no sólo una
... puede que incluso tengamos dos ya instaladas con la aplicación:
</p>

<ul class="org-ul">
<li><code>git gui</code></li>
<li><code>gitk</code></li>
</ul>

<p>
El primer comando lanza el <code>GUI</code> que sirve para controlar
repositorios, haciéndoles <i>fotos</i>, subiendo, bajando y sincronizando
la información que contienen los diversos repositorios, etc. El segundo es
un visualizador de <i>commits</i>, que nos los lista gráficamente y nos
permite ver fácilmente qué se cambió, cuándo y quién lo hizo.
</p>

<p>
Si abrimos el primero veremos una ventana similar a la siguiente:
</p>


<figure id="org5625245">
<img src="./imagenes/Captura-pantalla_git-gui.png" alt="Captura-pantalla_git-gui.png">

</figure>

<p>
Desde esa ventana podemos crear un repositorio nuevo, podemos abrir
uno ya creado, bien clonándolo desde algún sitio, o bien yendo a su
directorio donde abrirlo. Vale, esa no es la ventana de trabajo, sólo
una que nos muestra cuando lanzamos <code>git gui</code> estando en un directorio
donde no existe un repositorio, lo que suele ocurrir cuando lanzamos
el programa desde algún menú de aplicaciones. Si estamos utilizando
una consola en un directorio que ya es un repositorio y lo llamamos,
entiende que queremos abrir ese repositorio y nos muestra directamente
la ventana de trabajo:
</p>


<figure id="org525e786">
<img src="./imagenes/Captura-pantalla_git-ventana-trabajo.png" alt="Captura-pantalla_git-ventana-trabajo.png">

</figure>

<p>
Como no hay cambios en el repositorio, los espacios aparecen vacíos y
puede parecer una <i>interface</i> un poco sosa. Sin embargo, cuando
hayamos cambiado algo nos encontraremos enseguida que nos muestra en
el panel superior izquierdo los cambios marcados como <i>unstaged</i>. En
el panel superior derecho nos mostrará el contenido de hayamos
seleccionado a la izquierda. El panel inferior izquierdo nos muestra
las etiquetas de los cambios marcados como <i>staged</i> y el panel
inferior derecho es un espacio para escribir el mensaje o comentario
del <i>commit</i><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>.
</p>

<p>
Es decir, esta herramienta nos permite modificar el estado de un
repositorio en general. La ventana de trabajo está enfocada a los
<i>commit</i> que son los cambios más habituales del mismo, pero también
nos permitirá gestionar los distintos repositorios remotos que debe
sincronizar, las <i>ramas</i> del mismo y otra serie de acciones que
representan un cambio de estado para el proyecto.
</p>

<p>
Muy bonito lo de las <i>fotos</i> pero: ¿Cómo podemos recorrer nuestro
<i>álbum</i>?  Supongo que a estas alturas te preguntarás que aunque de
todas formas los proyectos avanzan siempre hacia adelante, te gustaría
poder ver qué se cambió, quién lo hizo y cuándo se compartió el cambio
y tener algún tipo de histórico del mismo.
</p>

<p>
Para eso podemos utilizar el otro programa que mencionamos antes:
<code>gitk</code>... de hecho lo podemos lanzar desde el mismo <code>git gui</code> en el
menú: <code>Repository</code> &gt; <code>Visualize master's History</code>.
</p>


<figure id="org114f329">
<img src="./imagenes/Captura-pantalla_gitk.png" alt="Captura-pantalla_gitk.png">

</figure>

<p>
También encontrarás, que es posible hacerlo al revés y lanzar <code>git
gui</code> desde la ventana de <code>gitk</code> con el menú <code>Archivo</code> &gt; <code>Start git
gui</code>. Para lanzar el programa desde una consola es siempre
recomendable hacerlo con el comando:
</p>

<div class="org-src-container">
<pre class="src src-shell">gitk --all
</pre>
</div>

<p>
Eso cargará todo el repositorio. Si no queremos cargarlo entero, con
sus ramas y todos los <i>commits</i> (las fotos) desde el principio de los
tiempos, podemos utilizar el comando <code>gitk</code> sin ninguna opción.
</p>

<p>
Pero bien, vamos a explicar un poco su <i>interface</i>. Como podemos
apreciar en la imagen anterior, he hecho una captura del repositorio
de este <i>blog</i>. Vemos que la parte superior de la ventana muestra una
lista de <i>fotos</i> del repositorio. Coinciden con los artículos que he
ido añadiendo y por tanto en los tres paneles todo es muy lineal: el
comentario asociado al <i>commit</i> en el panel de la izquierda, el
usuario que ha hecho los cambios (en este <i>blog</i> siempre yo) en el
panel del centro y a la derecha la fecha y la hora de cuándo se hizo
el cambio.
</p>

<p>
En la parte inferior nos muestra los datos asociados del <i>commit</i> que
seleccionemos arriba. En la parte inferior izquierda podremos ver los
cambios que se han hecho, a la derecha una lista de los ficheros que
se han modificado.
</p>

<p>
Entre la parte superior e inferior hay una barra de datos que nos
da información sobre el <i>commit</i>, como su etiqueta <code>SHA1</code> que es única
y también podemos buscar entre todos los <i>commits</i> con distintas
opciones.
</p>
<div id="outline-container-org545b2e2" class="outline-2">
<h2 id="org545b2e2">Conclusiones</h2>
<div class="outline-text-2" id="text-org545b2e2">
<p>
Ten en cuenta que la herramienta <code>git</code> es un poco complicada de
entender de primeras, si optas por <i>fossil</i>, encontrarás similares
problemas<sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>.  Mi recomendación es que leas atentamente los artículos
anteriores del <i>blog</i> donde cuento cómo lo utilizo yo y verás que las
herramientas gráficas lo que hacen es proporcionarte espacio gráficos
para las acciones que se harías en la línea de comandos.  Practica
esos comandos con ficheros de prueba en un directorio de prueba.
Posteriormente puedes buscar documentación completa, hay libros
gratuitos y todo tipo de ayuda que te permitirán alcanzar más
conocimientos sobre su uso que unos pocos artículos superficiales en
este <i>blog</i>.
</p>

<p>
Recuerda que las herramientas de control de versiones trabajan
especialmente bien con ficheros de texto. No almacenan las distintas
versiones de manera completa sino que ahorran espacio guardando sólo
los cambios. Sin embargo, si utilizas algún tipo de formato binario
las versiones se guardarán completas, con la consiguiente ineficiencia
de almacenado.
</p>

<p>
Particularmente, me encuentro más cómodo realizando el trabajo con
<code>git</code> desde la consola, sin embargo, entiendo que haya gente que
prefiere <i>verlo</i> en un formulario.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Lo que venimos llamando <i>commit</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Lo que llamamos <i>ramas</i>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Asegúrate que entiendes perfectamente su funcionamiento antes
de fiarlo todo a pulsar una serie de botones si conocer feacientemente
qué es lo que estás haciendo.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Retomando la metáfora de la <i>cámara de fotos</i>, podemos tomar
una instantánea cuando hemos añadido algo, cuando lo hemos borrado o
cuando lo hemos modificado. Y para guiarnos en lo que estamos
haciendo, es habitual comentar qué es lo que hacemos, qué tarea
completamos o problema arreglamos con las modificaciones de la
<i>foto</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Estas herramientas se hicieron pensando en la funcionalidad y
no en la facilidad de uso.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/git/index.html">git</a> ]]></description>
  <category><![CDATA[git]]></category>
  <link>https://notxor.nueva-actitud.org/2021/05/18/aprende-git-como-si-fueras-psicologo.html</link>
  <pubDate>Tue, 18 May 2021 10:12:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Minetest y otros juegos similares]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-05-07</div>
<p>
Hace tiempo ya <a href="https://notxor.nueva-actitud.org/2017/11/02/viaje-a-una-isla-imaginaria.html">hablé de mezclar juegos 3D y aventuras conversacionales</a>
y quedó en un intento bastante <i>vaporware</i>. Partíamos entonces de
modelarlo todo en <a href="https://blender.org">Blender3D</a> y manejar el movimiento en el <i>mundo</i> a
partir de comandos en la consola. Se llegó a hacer alguna acción de
movimiento, pero poco más. Llegamos a una limitación del <code>blender
gameengine</code> y decidimos pasarlo a <a href="https://godotengine.org/">Godot</a>... y en ese cambio, que
implicaba rehacer todo el código, llegó la parálisis. ¿Qué tiene que
ver esto con <a href="https://www.minetest.net/">minetest</a>? Pues bastante. Leí por ahí que es una
plataforma que permite generar diversos <i>juegos</i> o <i>mundos</i>
programables a través de una API en <code>Lua</code>. En definitiva, llevo unos
cuantos días explorando las posibilidades, mirando la documentación y
jugando.
</p>

<p>
Si alguno no sabéis qué es <i>Minetest</i> quizá os suene el comercial
<i>Minecraft</i>, el primero es un <i>clon</i> de este, pero libre. Las
preguntas que están guiando esta <i>investigación</i> son tres: <i>1.</i> ¿Puedo
realizar un juego en el que se introduzcan los comandos por consola?
<i>2.</i> ¿Se pueden hacer juegos independientes de un servidor para jugar
en local? y <i>3.</i>: en caso de que las respuestas a las dos preguntas
anteriores sean afirmativas, ¿será muy complicado hacerlo?
</p>

<p>
No sé aún, sólo busco hacer <i>juegos</i> como podrían ser aventuras
conversacionales, o gráficas, por divertimento. Mi último objetivo
sería poder hacer algún tipo de juego educativo a partir de esta
plataforma, aunque no termina de convencerme por ciertas razones que
comentaré más adelante. Todavía, hay que probar muchas cosas y
juguetear con toda la herramienta. La idea sería montar un servidor al
que un grupo de jugadores se pueda conectar y resolver algún tipo de
<i>puzle</i>, o similar, de forma colaborativa, o competitiva ─según el
objetivo planteado─.
</p>

<p>
La investigación ha empezado jugando. Ya había entrado e iniciado un
poco el juego cuando el amigo Fanta de <a href="https://mastodon.madrid">Mastodon Madrid</a> montó un
servidor de <i>Minetest</i>. Entonces me evadí de él, pues me consumía
horas que necesito emplear para otras cosas. Pero en esta ocasión,
para las investigaciones, me decidí a probar otro servidor <i>donde no
me conocieran</i>. Las casualidades quisieron que me conocieran
(virtualmente). Arranqué el juego conectándome a un servidor que se
llama «La Era del Dragón» y lo elegí porque fue el único servidor que
encontré con nombre en español.
</p>

<p>
Cuando inicié la aventura me puse mi <i>nick</i> habitual, <i>Notxor</i>,
aparecí en un castillo con un montón de espacios y estancias... yo no
sabía cómo salir y explorando caí en un agujero sin saber cómo
salir. De repente apareció otro usuario (posteriormente supe que era
uno de los administradores) que me hablaba (yo no recordaba cómo
contestar y tuve que mirar las teclas más habituales por <i>Internet</i>).
El caso es que lo primero que me preguntó fue: <i>¿Eres el mismo Notxor
del blog?</i> ... Vaya, debería haberme puesto otro nombre, pensé. Ya era
tarde, me habían descubierto, así que tuve que admitir que sí.
</p>

<p>
Intenté implicarme en el juego, pero fui tan bien recibido que creo
que la experiencia de jugador se me desvirtuó un poco al
principio... todavía tenía herramientas de madera y piedra y ya
saltaba por portales de un sitio a otro siguiendo al administrador del
nodo, minando con maquinaria pesada, visitando el espacio o el
infierno y teniendo herramientas, casi mágicas, que no sabía ni
utilizar. Para rematar la jugada de la procrastinación, hace unos días
mi hija me vio <i>jugando</i> y dijo «mi padre jugando al /minecraft/». La
corregí: «no, al /minetest/», y le conté lo que era y cómo funciona
más o menos. El caso es que se lo instaló en su ordenador y se conectó
al mismo servidor. Ahora compartimos también espacio virtual y algún
que otro sinsabor del juego<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. Y ya de últimas, ayer arrastró al
servidor a uno de sus amigos.
</p>


<figure id="orgcc9bdf6">
<img src="./imagenes/Captura-pantalla_dragones.png" alt="Captura-pantalla_dragones.png">

</figure>

<p>
El caso es que simplemente construirte tu casa, conseguir recursos y
administrarlos, moverte de arriba a abajo en un mundo aparentemente
<i>sin fin</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> es bastante entretenido y autorreforzante, por tanto
adictivo. Además permite interactuar con otros jugadores, por lo que
añade un plus de sociabilidad que hay que tener en cuenta, sobre todo
si se quiere intervenir con menores. Puede ser bastante interesante,
sobre todo en temas de trabajo en equipo o de socialización.
</p>


<figure id="org8dd6149">
<img src="./imagenes/Captura-pantalla_mi-casa.png" alt="Captura-pantalla_mi-casa.png">

</figure>

<p>
Los paisajes, a pesar de los <i>voxels</i> o <i>vóxeles</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>, que no tengo
muy claro cómo se pronuncia y escribe dicho <i>palabro</i>, son bastante
aparentes, hay ciclos de noche y día, árboles, plantas, terrenos
desérticos, selvas, jardines frutales, mares, ríos... Toda esa
variedad hace que se convierta en un mundo completo, si a eso le
añadimos los <i>mods</i> de animales, enemigos (como zombies, esqueletos,
dragones) y fauna en general. El poder domesticar animales o criarlos
en una granja; cultivar la tierra... Es decir, simplemente un mundo
puesto en un servidor y gente, jugadores, que interactúan, ya es
suficientemente interesante.
</p>

<p>
Pero lo que me gustaría hacer sería algo que significaré un pasito
más.  Ni siquiera necesitaría un mundo completo con todo. Mi intención
es hacer algo más parecido a lo que sería un <i>scape room</i>. El jugador
aparecería, por ejemplo, dentro de <i>una gruta</i> o de <i>un castillo</i> y el
objetivo sería salir de allí. O quizá... ¿Qué tal la <i>aventura
original</i> hecha en esta plataforma? ¿o un <i>remake</i> de <i>La Abadía del
Crimen</i>? ¿No estaría bien?
</p>
<div id="outline-container-org641d890" class="outline-2">
<h2 id="org641d890">Editor de mundos</h2>
<div class="outline-text-2" id="text-org641d890">

<figure id="org14284bc">
<img src="./imagenes/Captura-pantalla_minetest-malla.png" alt="Captura-pantalla_minetest-malla.png">

</figure>

<p>
Con el juego en sí, viene la opción de crear <i>servidores</i> con mundos
nuevos, poder modificarlos de la manera más creativa posible y
ponerlos en servicio.
</p>

<p>
No tengo muy claro aún cómo funciona todo. Hay muchas opciones y estoy
empezando a leer un poco de documentación. He encontrado incluso
sitios donde se crean juegos educativos en esta plataforma, con una
traducción incompleta, pero decente, al español, aunque está en
perfecto francés y tiene traducción al inglés.
</p>
</div>
<div id="outline-container-org2c73a0c" class="outline-3">
<h3 id="org2c73a0c">Juegos y <i>mods</i></h3>
<div class="outline-text-3" id="text-org2c73a0c">
<p>
Existen, y se encuentran fácilmente, paquetes que cargan opciones y
<i>mods</i> en <i>Minetest</i> que permiten jugar con objetos o personajes que
no están en el paquete básico del juego. Me ha llamado especialmente
un paquete que permite añadir elementos de <i>El Señor de los Anillos</i> a
tu servidor. No he podido usarlo propiamente, pues al cargarlo me da
un error en el código y no termina la carga. No sé todavía lo
suficiente como para intentar arreglar el problema, pero todo se
andará.
</p>


<figure id="org35d8089">
<img src="./imagenes/Captura-pantalla_lorg-of-the-test.png" alt="Captura-pantalla_lorg-of-the-test.png">

</figure>

<p>
Estoy aprendiendo. Hay un manual para crear <i>mods</i> y juegos en esta
dirección:
</p>

<p>
<a href="https://rubenwardy.com/minetest_modding_book/en/index.html">https://rubenwardy.com/minetest_modding_book/en/index.html</a>
</p>

<p>
El lenguaje de desarrollo de este tipo de juegos, y <i>mods</i>, es <code>Lua</code>.
No es un lenguaje que pueda decir que controlo especialmente, pero me
defiendo con él. Ya lo he utilizado en algunas ocasiones, por ejemplo
configurando mi gestor de ventanas <a href="https://awesomewm.org/">awesomewm</a>, o también, haciendo
algunas pruebas con el <i>game engine</i> <a href="https://love2d.org/">löve2D</a>.
</p>

<p>
Y hay mucha información sobre utilización de <i>Minetest</i> para la
enseñanza en <a href="https://www.minetest.net/education/">minetest.net/education</a>, que es la página francesa que he
mencionado antes.
</p>

<p>
Por lo que he podido observar hasta ahora, <i>Minetest</i> utiliza unas
bases de datos en <code>sqlite3</code>:
</p>

<ol class="org-ol">
<li><code>auth.sqlite3</code>: con tres tablas,
<ul class="org-ul">
<li><code>auth</code>:  <code>id</code> (<code>integer</code>), <code>name</code> (<code>varchar(32)</code>), <code>password</code>
(<code>varchar(512)</code>), <code>last_login</code> (<code>integer</code>)</li>
<li><code>sqlite_secuence</code>: <code>name</code>, <code>seq</code></li>
<li><code>user_privileges</code>: <code>id</code> (<code>integer</code>), <code>privilege</code> (<code>varchar(32)</code>)</li>
</ul></li>
<li><code>map.sqlite3</code>: una sola tabla,
<ul class="org-ul">
<li><code>blocks</code>: <code>pos</code> (<code>integer</code>), <code>data</code> (<code>blob</code>)</li>
</ul></li>
<li><code>players.sqlite3</code>: tiene cuatro tablas,
<ul class="org-ul">
<li><code>player</code>: <code>name</code> (<code>varchar(50)</code>), <code>pitch</code> (<code>numeric(11,4)</code>),
<code>yaw</code> (<code>numeric(11,4)</code>), <code>posX</code> (<code>numeric(11,4)</code>), <code>posY</code>
(<code>numeric(11,4)</code>), <code>posZ</code> (<code>numeric(11,4)</code>), <code>hp</code> (<code>integer</code>),
<code>breath</code> (<code>integer</code>), <code>creation_date</code> (<code>datetime</code>),
<code>modification_date</code> (<code>datetime</code>).</li>
<li><code>player_inventories</code>: <code>player</code> (<code>varchar(50)</code>), <code>inv_id</code>
(<code>integer</code>), <code>inv_width</code> (<code>integer</code>), <code>inv_name</code> (<code>text</code>),
<code>inv_size</code> (<code>integer</code>)</li>
<li><code>player_inventory_items</code>: <code>player</code> (<code>varchar(50)</code>), <code>inv_id</code>
(<code>integer</code>), <code>slot_id</code> (<code>integer</code>), <code>item</code> (<code>text</code>)</li>
<li><code>player_metadata</code>: <code>player</code> (<code>varchar(50)</code>), <code>metadata</code>
(<code>varchar(256)</code>), <code>value</code> (<code>text</code>)</li>
</ul></li>
</ol>

<p>
No sé si esta información será relevante para la programación, pero
parece interesante tenerla a mano.
</p>
</div>
</div>
</div>
<div id="outline-container-org5d91f1e" class="outline-2">
<h2 id="org5d91f1e">Conclusiones</h2>
<div class="outline-text-2" id="text-org5d91f1e">
<p>
El sistema de <i>Minetest</i> promete como soporte para distintos juegos.
Sin embargo, aún no tengo claro si esos juegos podrán ser viables,
para distribuir entre los posibles interesados, o si son fáciles de
hacer o si merece la pena hacerlos.
</p>

<p>
Parece un sistema orientado a realizar algunos tipos de actividades:
trabajar en la mina, crear tu granja, pelear con distintos <i>mods</i>, y
no tanto para proponer una determinada <i>aventura</i>, sea conversacional
o gráfica.
</p>

<p>
La principal pega que le encuentro es que no es <i>inclusivo</i>.
Proporciona mucha información relevante visualmente y de manera
auditiva. Antes de que los enemigos te ataquen, los oyes y para
defenderte tienes que «apuntar» tus armas con el ratón... Personas
ciegas o sordas estarán en franca desventaja si es que pueden jugar.
Esto no importa mucho para un juego normal, pero si quieres portarlo a
las aulas o generalizarlo, estarás dejando fuera, sin posibilidad de
recuperarlos de ningún modo, a algunos usuarios. Si por ejemplo, es un
juego educativo y lo quieres utilizar en un aula donde hay algún niño
ciego o sordo, no es de recibo dejarlos fuera. ¡Qué poco me gusta
<i>putear</i> a la gente por lo que es, en lugar de tener sólo en cuenta lo
que hace!
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Hace poco otro usuario le mató todos los animales de su granja:
los patos, los pollos, los perros... con el consiguiente disgusto. El
usuario fue expulsado por el administrador, pero es otra historia. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
estás situado en un mundo 3D de 62.000x62.000x62.000 ... puedes
cavar 31.000 posiciones hacia abajo o construir 31.000 posiciones
hacia arriba. No creo que nadie haya podido aún visitar los seis
extremos de un mundo virtual.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Vóxel</i> es una contracción de <i>volumetric pixel</i>, o pixel
volumétrico. Sería el equivalente 3D de un pixel 2D.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/juegos/index.html">juegos</a> <a href="/tags/minetest/index.html">minetest</a> ]]></description>
  <category><![CDATA[juegos]]></category>
  <category><![CDATA[minetest]]></category>
  <link>https://notxor.nueva-actitud.org/2021/05/07/minetest-y-otros-juegos-similares.html</link>
  <pubDate>Fri, 07 May 2021 18:02:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Lout, otro lenguaje de marcas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-04-21</div>
<p>
El otro día, acabando el minicurso de <i>LaTeX</i> y comentándolo en el
<a href="https://t.me/notxorblog">grupo de <i>Telegram</i> donde comentamos</a> los artículos, salió la
conversación sobre <i>Lout</i>. <a href="https://notxor.nueva-actitud.org/2019/01/24/lout-un-lenguaje-de-marcas-ligero.html">Ya hablé brevemente sobre este sistema</a> en
este <i>blog</i> hace un tiempo y conté una breve experiencia con él, pero
no abundé mucho en cómo se usa, para qué sirve o por qué debería
interesarte. En este artículo intentaré completar la información para
todo aquel curioso que quiera, introducirse un poco más en esta
herramienta. Como en el pasado artículo ya hablé un poco sobre la
historia y procedencia de <i>Lout</i>, en este me centraré en los aspectos
más prácticos.
</p>
<div id="outline-container-orgd22ddc0" class="outline-2">
<h2 id="orgd22ddc0">¿Qué es <i>Lout</i>?</h2>
<div class="outline-text-2" id="text-orgd22ddc0">
<p>
<i>Lout</i> es un sistema de marcado se genera documentos para impresión.
El formato que utiliza de salida es <i>PostScript</i>, si se necesita un
<code>pdf</code> se apoya en <code>ghoscript</code> para convertirlo. Puedes utilizar
<code>ps2pdf</code> o cualquier otra herramienta similar.
</p>

<p>
Se podría decir que es una especie de <i>LaTeX</i>, pues prácticamente
sirve para lo mismo. Sin embargo, está muy lejos de <i>TeX</i> en muchos
aspectos: unos positivos y otros negativos. Entre los puntos positivos
cuenta con la ligereza del sistema:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-right">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Contenido</th>
<th scope="col" class="org-right">Espacio</th>
<th scope="col" class="org-left">Unidad</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>lout.lib</code></td>
<td class="org-right">5.4</td>
<td class="org-left">Mb</td>
</tr>

<tr>
<td class="org-left"><code>lout</code></td>
<td class="org-right">692.0</td>
<td class="org-left">Kb</td>
</tr>

<tr>
<td class="org-left"><code>prg2lout</code></td>
<td class="org-right">915.2</td>
<td class="org-left">Kb</td>
</tr>

<tr>
<td class="org-left"><code>doc</code></td>
<td class="org-right">7.6</td>
<td class="org-left">Mb</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">Total</td>
<td class="org-right">14.6</td>
<td class="org-left">Mb</td>
</tr>
</tbody>
</table>

<p>
Es decir, todo el sistema está contenido en un poco más de catorce
megas y media. En <code>lout.lib</code> está todo lo necesario para generar los
documentos: las fuentes, las definiciones de documentos, etc. El
fichero <code>lout</code> es el ejecutable que <i>formatea</i> nuestro documento
pasándolo de texto plano con sus etiquetas a <i>PostScript</i>. Puede
utilizar el ejecutable auxiliar <code>prg2lout</code> que a partir de un fichero
de código genera una salida para que <i>Lout</i> pueda mostrar
adecuadamente listados de código con coloreado de sintaxis y otros
aditivos como número de línea, etc. Y por último, <code>doc</code> contiene toda
la documentación sobre <i>Lout</i>. El contenido de la documentación es el
siguiente:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Nombre</th>
<th scope="col" class="org-right">Páginas</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><i>design</i></td>
<td class="org-right">40</td>
</tr>

<tr>
<td class="org-left"><i>expert</i></td>
<td class="org-right">120</td>
</tr>

<tr>
<td class="org-left"><i>slides</i></td>
<td class="org-right">42</td>
</tr>

<tr>
<td class="org-left"><i>user</i></td>
<td class="org-right">327</td>
</tr>
</tbody>
</table>

<p>
En el documento <i>design</i> hay unas breves explicaciones de cómo
funciona el concepto de <i>caja</i> y cómo fluyen esas cajas en el diseño
general, cómo se alinean y cómo pueden incluirse unas dentro de
otras. En el documento <i>expert</i> se explican todos los comandos, se
amplía el concepto de cajas y se añade un poco de bajo nivel
(<i>PostScript</i>), diseño de páginas, definición de estructura de
documentos, ampliación o importación de nuevas fuentes, etc. Por
contra, <i>slides</i> presenta el sistema en formato de diapositivas
haciendo una introducción sencilla de entender. Por último, el fichero
<i>user</i> contiene toda la información relevante para el usuario final,
desde cómo iniciar un documento, los comandos para dar formato a las
páginas y a las fuentes, utilización de herramientas como <code>prg2lout</code>,
o los comandos para utilizar color, o diseños gráficos, importar
imágenes, hacer cuadros de texto y tablas; en resumen, <i>toda</i> la
documentación que necesitas para utilizarlo escribiendo un documento,
desde un simple resumen a todo un libro.
</p>
</div>
</div>
<div id="outline-container-org7401304" class="outline-2">
<h2 id="org7401304">Instalación</h2>
<div class="outline-text-2" id="text-org7401304">
<p>
La instalación es sencilla. Encontré que en <i>OpenSuse</i> puedes
instalarlo porque tiene el paquete en su repositorio. Sin embargo, con
mi habitual tendencia a complicarme la vida por cualquier tontería,
con el único propósito de aprender más, me decidí a bajarlo y
compilarlo. El código lo puedes encontrar en:
</p>

<p>
<a href="https://savannah.nongnu.org/projects/lout/">https://savannah.nongnu.org/projects/lout/</a>
</p>

<p>
También considero parte de la <i>instalación</i> el preparar <i>Emacs</i> para
poder utilizarlo. En este caso, no encontré ningún paquete en <code>MELPA</code>,
sin embargo, en <a href="http://emarsden.chez.com/lout/">http://emarsden.chez.com/lout/</a> encontré un paquete que
me proporciona un mínimo de utilidad para encontrarme cómodo editando
documentos <code>lout</code>. Su instalación es algo más compleja, porque no
consiste en llamar a <code>package-install</code> y ya.
</p>

<p>
Para instalarlo, descargué el paquete y descomprimí el contenido en el
directorio <code>~/.emacs.d/lout-mode</code>. En ese directorio se encuentra el
fichero <code>lout-mode.el</code> y otro <code>README</code>. En el <code>README</code> se puede
encontrar documentación sobre la instalación en nuestro sistema, pero
hay que recordar que es un paquete de 1999 y el modo que ahí explica
no funcionará en la actualidad, a poco actualizado que tengas
<i>Emacs</i>. En mi configuración he añadido las siguientes líneas, en
lugar del código recomendado en su documentación:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Configuraci&#243;n para Lout
</span>(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">lout-mode</span>)
(add-to-list 'auto-mode-alist '(<span style="color: #f1fa8c;">"\\.lout\\'"</span> . lout-mode))
(add-to-list 'auto-mode-alist '(<span style="color: #f1fa8c;">"\\.lt\\'"</span> . lout-mode))
</pre>
</div>

<p>
Como se puede ver, utilizo <code>require</code> para cargar el modo y añado dos
extensiones (<code>.lout</code> y <code>.lt</code>) para que se inicie automáticamente el
modo al abrir un fichero con esa extensión.
</p>
</div>
</div>
<div id="outline-container-orgf819037" class="outline-2">
<h2 id="orgf819037">Limitaciones y ventajas</h2>
<div class="outline-text-2" id="text-orgf819037">
<p>
Tan reducido sistema de descripción de documentos, si lo comparamos
con las <i>gigas</i> que puede ocupar <i>TeX</i> y sus derivados, no puede
alcanzar todas las opciones que nos proporciona éste último. Sin
embargo, se pueden hacer la mayoría de las cosas que se necesitan para
editar un documento completo, con la ventaja de poder llevarlo todo en
un espacio muy reducido. ¿Cuáles son las pegas, entonces? Por poner
las que se me ocurren así a bote pronto:
</p>

<ul class="org-ul">
<li>No tiene editores dedicados, aunque como he explicado más arriba sí
podemos encontrar un modo de <i>Emacs</i> que nos facilite el trabajo.</li>
<li><i>Encondings</i>: El sistema espera que los ficheros estén escritos con
el <i>encoding</i> <code>latin-1</code>. Si estás utilizando <i>GNU/Linux</i> o <i>MacOS</i>
el <i>encoding</i> por defecto es <code>UTF</code>. Se hace necesario, si estás
utilizando <i>Emacs</i> cambiar el <i>encoding</i> con
<code>set-codding-buffer-system</code>, (<code>C-x C-m f</code>) y seleccionar <code>latin-1</code>.
Sin embargo, a pesar de todo algunas fuentes, como la <code>Dingbats</code> no
se verá correctamente, dependiendo de qué visor de documentos tengas.</li>
<li>Tipos de letra: Los tipos de letra son bastante más reducidos, pues
de base sólo proporciona los definidos en <i>PostScript</i>.</li>
<li>Tipos de documento: Los tipos de documento que se pueden generar es
más reducido, aunque con el genérico <code>Doc</code> se pueden realizar otros
muchos y permite que derivemos de él los pripios.</li>
<li>Gráficos <i>PostScript</i>: <i>Lout</i> utiliza como lenguaje de programación
para la descripción de las páginas el lenguaje <i>PostScript</i>. Un
estándar que se ha ido dejando de lado en favor del <code>PDF</code>. Eso hace
que las imágenes y todo lo que queramos que dibuje en nuestra página
deba estar convertido a <i>PostScript</i> (<code>.ps</code>) o <i>PostScript
encapsulado</i> (<code>.eps</code>).</li>
</ul>

<p>
Entre las ventajas, podemos enumerar también algunas que le hacen
compañía a lo escueto de su instalación:
</p>

<ul class="org-ul">
<li>Sistema de diagramas, ─cajas, flechas, círculos─.</li>
<li>Sistema de gráficos, ─histogramas, gráficos de tarta─, perfectamente
integrados desde la base del documento sin paquetes adicionales.</li>
<li>Sistema de tablas más flexible que en <i>LaTeX</i>.</li>
</ul>
</div>
<div id="outline-container-org196e299" class="outline-3">
<h3 id="org196e299">Tipos de letra</h3>
<div class="outline-text-3" id="text-org196e299">
<p>
Los tipos de letra que se pueden encontrar en <i>Lout</i> son los
siguientes, especificando la familia y las formas que se pueden
utilizar:
</p>

<dl class="org-dl">
<dt><b>AvantGarde</b></dt><dd>Base Slope Bold BoldSlope BoldObl Book BookOblique
CondBold CondBook CondDemi CondMedium Demi DemiOblique ExtraLight
ExtraLightObl Medium MediumObl</dd>
<dt><b>Bookman</b></dt><dd>Base Slope Bold BoldSlope BoldItalic Demi DemiItalic
Light LightItalic Medium MediumItalic</dd>
<dt><b>Chancery</b></dt><dd>Base Slope Bold BoldSlope Roman Bold Italic Light Demi
LightItalic MediumItalic</dd>
<dt><b>Courier</b></dt><dd>Base Slope Bold BoldSlope BoldOblique Oblique</dd>
<dt><b>Helvetica</b></dt><dd>Base Slope Bold BoldSlope Black BlackOblique
BoldOblique Compressed Cond CondBlack CondBlackObl CondBold
CondBoldObl CondLight CondLightObl CondOblique ExtraCompressed Light
LightOblique Narrow NarrowBold NarrowBoldObl NarrowObl Oblique
UltraCompressed</dd>
<dt><b>Schoolbook</b></dt><dd>Base Slope Bold BoldSlope BoldItalic Italic Roman</dd>
<dt><b>Palatino</b></dt><dd>Base Slope Bold BoldSlope BoldItalic BoldItalicOsF
BoldOsF Italic ItalicOsF Roman SC</dd>
<dt><b>Symbol</b></dt><dd>Base Slope Bold BoldSlope</dd>
<dt><b>Times</b></dt><dd>Base Slope Bold BoldSlope BoldItalic BoldItalicOsF BoldSC
ExtraBold Italic ItalicOsF Roman RomanSC Semibold SemiboldItalic</dd>
<dt><b>Dingbats</b></dt><dd>Base Slope Bold BoldSlope</dd>
</dl>

<p>
Como se puede apreciar, algunas familias cuentan con un gran número de
formas externas y otras menos. Son los tipos de fuente que se definen
y se cargan por defecto en los documentos <i>PostScript</i>. Todas proceden
de <i>Adobe</i> y es posible que no se visualicen correctamente si no las
tienes instaladas en tu ordenador. Por ejemplo, utilizando diferentes
visualizadores de documentos podemos obtener resultados distintos:
</p>


<figure id="orgd6f5f4c">
<img src="./imagenes/Captura-pantalla_comparativa-visores.png" alt="Captura-pantalla_comparativa-visores.png">

</figure>

<p>
En la imagen vemos dos visores abriendo el mismo fichero, ─el manual
de usuario─, por la misma página, donde se muestra una tabla de
símbolos. A la izquierda, <code>xpdf</code> no tiene problemas para interpretar
correctamente todos los caracteres especiales, sin embargo, a la
derecha, <code>Okular</code> no muestra aquellos que provienen de la fuente
<code>Symbol</code> de <i>Adobe</i>.
</p>

<p>
Por lo que he podido ver, al exportar a <code>pdf</code>, el comando <code>ps2pdf</code>
incrusta las fuentes pero hay algunas, como <code>Symbol</code>, que no lo hace,
así que depende del visor encontrar una fuente adecuada para
sustituirla al visualizar el documento. Los documentos generados con
<i>Lout</i> se visualizan mejor con <code>gv</code> si es <i>PostScript</i> o con <code>xpdf</code> si
es <code>pdf</code>.
</p>
</div>
</div>
<div id="outline-container-org36803d8" class="outline-3">
<h3 id="org36803d8">Tipos de documento</h3>
<div class="outline-text-3" id="text-org36803d8">
<p>
Los tipos de documentos que vienen por defecto son:
</p>

<ul class="org-ul">
<li><code>doc</code>.  Cualquier tipo de documento, puede ser una nota, un artículo
o cualquier otro tipo.</li>
<li><code>report</code>. Un tipo de documento que se utiliza para informes
sencillos. No tiene tantos tipos de sección definida como para un
libro.</li>
<li><code>book</code>. Este paquete contiene todas las secciones definidas para
generar un libro.</li>
<li><code>slides</code>. Este paquete contiene las definiciones necesarias para
definir presentaciones.</li>
<li><code>picture</code>. Este tipo de documento está pensado para utilizar el
código para generar un gráfico o un diagrama con las herramientas
que proporciona <i>Lout</i>. Lo habitual es convertir la salida a
<i>encapsulated PostScript</i> para poder usarlo en otros documentos.</li>
</ul>

<p>
No son muchos tipos de documento, pero se pueden personalizar muy
fácilmente definiendo parámetros en la cabecera. Además, basándonos en
ellos, podemos armar nuestro propio tipo de documento fácilmente.
</p>
</div>
</div>
<div id="outline-container-orgb3743d6" class="outline-3">
<h3 id="orgb3743d6">Tratamiento de los idiomas</h3>
<div class="outline-text-3" id="text-orgb3743d6">
<p>
El sistema provee diversos lenguajes con los que trabajar en los
documentos. Así nos traduce las cabeceras del documento como
<i>capítulo</i> o <i>sección</i>, o nos proporciona en esa lengua fechas. Los
idiomas son los siguientes:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<tbody>
<tr>
<td class="org-left">Croatian Hrvatski</td>
<td class="org-left">Italian Italiano it</td>
</tr>

<tr>
<td class="org-left">Czech Cesky Cestina cs</td>
<td class="org-left">Norwegian Norsk no</td>
</tr>

<tr>
<td class="org-left">Danish Dansk da</td>
<td class="org-left">Polish Polski pl</td>
</tr>

<tr>
<td class="org-left">Dutch Nederlands nl</td>
<td class="org-left">Portuguese Português pt</td>
</tr>

<tr>
<td class="org-left">English en</td>
<td class="org-left">Programming</td>
</tr>

<tr>
<td class="org-left">EnglishUK en-GB</td>
<td class="org-left">Russian ru</td>
</tr>

<tr>
<td class="org-left">Esperanto eo</td>
<td class="org-left">Slovak Slovensky Slovencina</td>
</tr>

<tr>
<td class="org-left">Finnish Suomi ﬁ</td>
<td class="org-left">Slovenian Slovenia Slovenija sl</td>
</tr>

<tr>
<td class="org-left">French Francais Français fr</td>
<td class="org-left">Spanish Español es</td>
</tr>

<tr>
<td class="org-left">German Deutsch de</td>
<td class="org-left">Swedish Svenska sv</td>
</tr>

<tr>
<td class="org-left">Hungarian Magyar hu</td>
<td class="org-left">UpperSorbian hornjoserbsce serbsce</td>
</tr>
</tbody>
</table>

<p>
Cada uno de ellos se pueden llamar por cualquiera de esos nombres. Es
decir, para seleccionar el idioma español podemos utilizar cualquiera
de los siguientes nombres: <code>Spanish</code>, <code>Español</code> o <code>es</code>. Sin embargo,
cuando alguno de esos nombres contiene algún carácter especial como la
<code>ñ</code> si creas el documento desde <code>utf</code> es posible que no comprenda el
comando.
</p>

<p>
Posteriormente, en el texto se pueden intercalar otros lenguajes
llamando al comando <code>@Language</code> con el texto. Pero hay que recordar
que para visualizar los textos en cirílico hay que importar el paquete
<code>latin2</code>.
</p>
</div>
</div>
</div>
<div id="outline-container-org90acb8a" class="outline-2">
<h2 id="org90acb8a">¿Cómo funciona?</h2>
<div class="outline-text-2" id="text-org90acb8a">
<p>
Si vienes de <i>LaTeX</i> verás que el funcionamiento general sigue ciertas
pautas parecidas: hay una serie de <i>macros</i> o <i>comandos</i> que describen
un documento final. Además, esos <i>macros</i> o <i>comandos</i> pueden recibir
opciones para funcionar. ¿Cuáles son las diferencias? Pues
básicamente, hay que contar con que el carácter que determina un
<i>macro</i> o <i>comando</i> es <code>@</code>, en lugar del carácter <code>\</code> que se utiliza
en <i>TeX</i>. En realidad, el carácter <code>@</code> es un adorno pues podemos
definir comandos que no lo lleven y funcionarán correctamente sin él.
</p>

<p>
La manera más sencilla de utilizar este sistema es elegir un tipo de
documento en la cabecera y comenzar a escribir texto.
</p>

<p>
<i>Lout</i> lo que hace es ir reservando espacio formando <i>marcos</i> que van
incluyéndose unos dentro de otros, de izquierda a derecha y de arriba
hacia abajo. Cada contenido se va añadiendo al anterior y va
rellenando la página, cuando esta se completa, continúa en la página
siguiente. Por supuesto, podemos delimitar cada bloque que se verá
afectado por ese flujo o por un comando, utilizando los caracteres
<code>{}</code>.
</p>

<p>
Si me permitís, voy a poner un ejemplo amplio, aunque no exhaustivo de
las capacidades de <i>Lout</i>. Después, lo comentaré y será más fácil de
entender que hablando de forma abstracta.
</p>

<div class="org-src-container">
<pre class="src src-nil"># -*- lout -*-
# El enconding Latin-1 es necesario para que todo funcione como corresponde.
@SysInclude { tbl }
@SysInclude { diag }
@SysInclude { math }
@SysInclude { doc }

def @Comillas right x { @Char guillemotleft{x}@Char guillemotright }
def @Cuadro left y right x {
  @Box
    margin { 1f }
    paint { y }
  {x}
}

@Document
  @InitialFont { Palatino Base 12p }
  @InitialLanguage { Spanish }
//

@Text @Begin
@PP
En este párrafo se puede utilizar por ejemplo el tipo en @B negrita o
en @I itálica. También se podía cambiar el tipo de texto con de la
siguiente manera: { Helvetica Base } @Font { este texto se mostrará en
Helvetica }.

@PP
Podemos cambiar sobre la marcha la fuente, el color, el tamaño o
incluso hacer diagramas de cajas y flechas. Podemos escribir por
ejemplo @F "{ 20p } @Font Grande" para conseguir el efecto 20p @Font
Grande en nuestro texto. También podemos alinear ese baselinemark
@Font { texto más 20p @Font grande con el resto del texto }.

@PP @CentredDisplay
@Math { int from { 0 } to { 1 } dx over sqrt {1 - x sup 2} = pi over 2 }

@BeginSections
@Section @Title {Primera sección}
  @Tag { sec:primera }
@Begin
@LP @Comillas { Hola Mundo! }

@LP { lightgray } @Cuadro { Hola Mundo! }
@LP { lightblue } @Cuadro { Hola Mundo! }

@PP
Podemos escribir un documento en un lenguaje @I Base pero podemos
intercalar frases o textos en otro idioma utilizando el comando @F
"@Language", como por ejemplo escribir la fecha en Esperanto
@Comillas { Esperanto @Language @Date } utilizando el comando @F
{"Esperanto @Language @Date"} y luego seguir escribiendo en
el idioma base.

@End @Section

@Section @Title { Segunda sección }
  @Tag { sec:segunda }
@Begin

@PP
Un parrafo que es el contenido de la sección, aunque también lo podríamos
dividir en subsecciones. Los párrafos se marcan con @F "@"PP

@PP Tipos de legra:
@LP
{ AvantGarde Base } @Font AvantGarde, @LP
{ Bookman Base }    @Font Bookman,    @LP
{ Chancery Base }   @Font Chancery,   @LP
{ Courier Base }    @Font Courier,    @LP
{ Helvetica Base }  @Font Helvetica,  @LP
{ Schoolbook Base } @Font Schoolbook, @LP
{ Palatino Base }   @Font Palatino,   @LP
{ Symbol Base }     @Font Symbol,     @LP
{ Times Base }      @Font Times,      @LP
{ Dingbats Base }   @Font Dingbats.

@End @Section

@EndSections

@End @Text
</pre>
</div>

<p>
Para generar el documento <i>PostScript</i> he utilizado el siguiente
comando:
</p>

<div class="org-src-container">
<pre class="src src-shell">lout -S prueba &gt; prueba.ps
</pre>
</div>

<p>
El parámetro <code>-S</code> es un seguro de ejecución (<i>safety</i>). Evita que
<i>Lout</i> ejecute ningún comando del sistema. Eso nos permite mirar en la
salida del programa qué comandos necesita ejecutar y determinar si es
seguro hacerlo. Todo esto porque <i>Lout</i> puede ejecutar código <code>awk</code>, o
incluso <code>groff</code>, para generar la salida y eso podría hacer que se
ejecute en el sistema cualquier programa de manera maliciosa. En este
caso, como es un documento sencillo, no tiene llamadas a ningún
programa externo, como <code>prg2lout</code>, se consigue la salida de manera
directa y se genera en modo <i>seguro</i>.
</p>

<p>
El código de ejemplo que se muestra arriba produce el siguiente
documento.
</p>


<figure id="orgffb1ba3">
<img src="./imagenes/Captura-pantalla_documento-postcript.png" alt="Captura-pantalla_documento-postcript.png">

</figure>

<p>
La captura de la imagen anterior se ha hecho sobre el <i>viejuno</i> visor
de <i>PostScript</i> <code>gv</code>, que supongo que a estas alturas prácticamente
nadie tendrá instalado en su ordenador. El código que mostré
anteriormente está situado en un fichero que he llamado <code>prueba</code>, sin
ninguna extensión. Por esto, en el código le indico en la primera
linea a <i>Emacs</i> que es un fichero <i>Lout</i> para que active el modo
correspondiente cuando lo abro con el editor.
</p>

<div class="org-src-container">
<pre class="src src-nil"># -*- lout -*-
</pre>
</div>

<p>
Como se puede apreciar, en <i>Lout</i> los comentarios se introducen con el
carácter <code>#</code>.
</p>

<p>
Después, en el documento se realiza una serie de importaciones de
código. En este sentido es similar a <i>LaTeX</i>: cuenta con una cabecera
separada del cuerpo del documento, donde se hace la importación de
paquetes y se <i>programan</i> los macros que se necesitarán luego.
</p>

<div class="org-src-container">
<pre class="src src-nil">@SysInclude { tbl }
@SysInclude { diag }
@SysInclude { math }
@SysInclude { doc }

def @Comillas right x { @Char guillemotleft{x}@Char guillemotright }
def @Cuadro left y right x {
  @Box
    margin { 1f }
    paint { y }
  {x}
}
</pre>
</div>

<p>
Las importaciones son:
</p>

<ul class="org-ul">
<li><code>tbl</code>: Importa los comandos necesarios para dibujar tablas. Luego no
lo he usado en el cuerpo de texto. Iba a ser más exhaustivo
presentando el sistema pero casi da para hacer otro <i>minicurso</i> en
lugar de un artículo introductorio como me he planteado este.</li>
<li><code>diag</code>: Importa todos los comandos para dibujar diagramas, cajas,
flechas, etc.</li>
<li><code>math</code>: Importa todos los comandos necesarios para escribir fórmulas
matemáticas.</li>
<li><code>doc</code>: Importa todo lo necesario para escribir un documento, como
los tipos de letra, los estilos de texto, los encabezados, etc.</li>
</ul>

<p>
Si fuera un grupo de ficheros, para hacer la importación del
contenido, se utilizará <code>@Include</code>, dejando el comando <code>@SysInclude</code>
para importar ficheros del sistema.
</p>

<p>
Después de las importaciones, vemos un par de macros definidos con
<code>def</code>. El primero lo he definido igual que se hizo en <i>LaTeX</i>. Para
explicarlo mejor podemos comparar las siguientes líneas:
</p>

<p>
<i>En LaTeX</i>:
<i>En Lout</i>:
</p>
<div class="org-src-container">
<pre class="src src-nil">def @Comillas right x { @Char guillemotleft{x}@Char guillemotright }
</pre>
</div>

<p>
Podemos ver que hemos definido un comando <code>@Comillas</code> que recibe un
parámetro <code>x</code>; <code>right x</code> significa que el comando se aplicará al
elemento que aparezca directamente a la derecha del comando. En este
caso, como en el de <i>LaTeX</i> se introduce el parámetro entre los
caracteres de comillas angulares o <i>guillemot</i>: <code>«»</code>. Podemos apreciar
que cuando lo llamamos en el texto del documento con <code>@Comillas { Hola
Mundo! }</code> produce de salida «Hola Mundo!».
</p>

<p>
Por ilustrar cómo hacer una <i>macro</i> un poco más compleja, he definido
un comando <code>@Cuadro</code>, que toma una opción de color y dibuja un marco
de ese color al rededor del texto que se pasa como parámetro. La
opción se define a la izquierda como <code>left y</code><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> y el contenido
viene definido como <code>right x</code>. Se pueden definir parámetros con nombre
también, pero sólo merecen la pena si te planteas utilizar este
sistema hasta hacerte un usuario (muy) avanzado. El código de esta
segunda definición es sencillo de entender:
</p>

<div class="org-src-container">
<pre class="src src-nil">def @Cuadro left y right x {
  @Box
    margin { 1f }
    paint { y }
  {x}
}
</pre>
</div>

<p>
Como vemos, el macro <code>@Box</code> recibe dos parámetros: uno con nombre
<code>margin</code> que se establece a <code>1f</code><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> y otro <code>paint</code> que pintará el
fondo de la caja con el color que se especifique en el parámetro <code>y</code>.
Y dicha caja la rellenará con el contenido el parámetro <code>x</code>. En la
imagen, podemos apreciar que hemos dibujado dos cajas con el mismo
contenido pero con distinto color de fondo de la siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-nil">@LP { lightgray } @Cuadro { Hola Mundo! }
@LP { lightblue } @Cuadro { Hola Mundo! }
</pre>
</div>

<p>
La secuencia de comando establece un nuevo párrafo sin sangría
(<code>@LP</code>), y después se proporciona un comando con la estructura
simplificada de <code>color @Cuadro texto</code>. Los colores utilizados están
definidos en el fichero <code>xrgb</code> del sistema <i>Lout</i>.
</p>

<p>
Después de la cabecera viene el cuerpo del documento. Tiene la
siguiente forma:
</p>

<div class="org-src-container">
<pre class="src src-nil">@Document
  @InitialFont { Palatino Base 12p }
  @InitialLanguage { Spanish }
//

@Text @Begin

...

@End @Text
</pre>
</div>

<p>
Como se puede apreciar, el comando <code>@Document</code> recibe algunos
parámetros con nombre, concretamente, he definido el tipo de fuente
base y el lenguaje inicial del texto. Igualmente se podrían definir
muchos otros parámetros. Debo recordar que las opciones aquí definidas
se establecen de manera general, pero pueden ser modificadas
puntualmente. El documento de ejemplo muestra más adelante cómo
podemos cambiar el idioma puntualmente o el tipo de letra o su tamaño.
También hay que recordar que el contenido del documento se encontrará
entre las etiquetas <code>@Text @Begin</code> de inicio y <code>@End @Text</code> para
finalizar.
</p>

<p>
Al llamar a <code>Esperanto @Language @Date</code> nos devuelve la fecha del día
con el formato definido para <i>Esperanto</i>: <code>21a de aprilo de 2021</code>,
aunque el idioma del documento se estableció a <code>Spanish</code>. Los idiomas
se pueden establecer con varias palabras clave, como por ejemplo:
<code>Spanish</code>, <code>Español</code>, <code>es</code>. Sin embargo, me he encontrado con algunas
dificultades por el empleo de caracteres especiales como la <code>ñ</code> que al
no coincidir el código <code>UTF</code> con el <code>Latin1</code> es posible que dé
errores.
</p>

<p>
También podemos establecer algunos cambios en las fuentes, como el
estilo:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Macro</th>
<th scope="col" class="org-left">Estilo</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">@B</td>
<td class="org-left">Negrita (<i>Bold</i>)</td>
</tr>

<tr>
<td class="org-left">@I</td>
<td class="org-left">Itálica (<i>Italic</i>)</td>
</tr>

<tr>
<td class="org-left">@R</td>
<td class="org-left">Regular o Roman</td>
</tr>

<tr>
<td class="org-left">@S</td>
<td class="org-left">Mayúsculas (<i>Small Caps</i>)</td>
</tr>

<tr>
<td class="org-left">@F</td>
<td class="org-left">Fija (<i>Fixed</i>)</td>
</tr>

<tr>
<td class="org-left">@BI</td>
<td class="org-left">Negrita e Itálica</td>
</tr>

<tr>
<td class="org-left">@II</td>
<td class="org-left">Énfasis</td>
</tr>
</tbody>
</table>

<p>
En el último caso, <code>@II</code> produce un estilo de itálica cuando se
encuentra rodeado de texto en <i>roman</i>, pero produce un estilo <i>roman</i>
si se encuentra rodeado de texto en itálica. Sería el equivalente al
comando <code>emph</code> de otros sistemas. Los demás estilos son los
habituales.
</p>

<p>
Si miramos en el ejemplo también se puede apreciar cómo se ha cambiado
puntualmente a texto de paso más grande con el comando simplificado de
<code>tamaño @Font texto</code> o incluso cómo se ha cambiado la familia de la
fuente con <code>familia @Font texto</code>.
</p>
</div>
</div>
<div id="outline-container-orgbffd348" class="outline-2">
<h2 id="orgbffd348">Conclusión</h2>
<div class="outline-text-2" id="text-orgbffd348">
<p>
Como se puede apreciar en esta introducción el sistema de creación de
documentos de <i>Lout</i> es bastante sencillo, aunque completo. Es
sencillo crear nuevas macros y tiene la potencia suficiente como para
generar cualquier tipo de salida.
</p>

<p>
Me he dejado en el tintero varios aspectos avanzados para la
generación de documentos, como su propio sistema de gráficos:
histogramas, líneas, gráficos de tarta. Un sistema completo de dibujo
de diagramas: diagramas de análisis de sintaxis, cajas, flechas,
círculos. También un sistema completo para generar tablas complejas,
con diferentes estilos de líneas, columnas y celdas. Además de contar
con un completo sistema para representar fórmulas matemáticas.
</p>

<p>
Tampoco he hablado de sus capacidades para generar bibliografía y
contar con un índice temático alfabético. Ni sobre la posibilidad de
hacer referencias internas.
</p>

<p>
Puedes descargar los ficheros del ejemplo:
</p>

<ul class="org-ul">
<li>Fuente: <a href="./imagenes/prueba">./imagenes/prueba</a></li>
<li><i>PostScript</i>: <a href="./imagenes/prueba.ps">./imagenes/prueba.ps</a></li>
<li><code>PDF</code>: <a href="./imagenes/prueba.pdf">./imagenes/prueba.pdf</a></li>
</ul>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Se podría haber definido con cualquier nombre, por ejemplo
<code>left color</code>, pero no quería inducir a pensar que pudiera ser alguna
palabra clave.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<code>f</code> es la unidad de medida que representa el tamaño de letra
actual definido en el documento. También podría haberse definido en
base a <code>c</code> (centrímetros), <code>i</code> (pulgadas), <code>p</code> (puntos)... 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/lout/index.html">lout</a> <a href="/tags/documentos/index.html">documentos</a> ]]></description>
  <category><![CDATA[lout]]></category>
  <category><![CDATA[documentos]]></category>
  <link>https://notxor.nueva-actitud.org/2021/04/21/lout-otro-lenguaje-de-marcas.html</link>
  <pubDate>Wed, 21 Apr 2021 09:50:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Minicurso de LaTeX para psicólogos vi]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-04-15</div>
<p>
En el artículo de hoy pienso poner punto y final a este <i>minicurso</i> de
<i>LaTeX</i>. Hablaré de cómo crear nuestro propio <i>estilo</i> en un fichero
<code>.sty</code> para luego poder utilizarlo como con cualquier otro paquete,
con el comando <code>\usepackage</code>. Aunque sin meternos en demasiadas
profundidades de programación. Por último, veremos también cómo
proveer a nuestro documento de una bibliografía, que hará las veces de
<i>guinda del pastel</i>.
</p>
<div id="outline-container-orgf34bc63" class="outline-2">
<h2 id="orgf34bc63">Crear nuestro propio estilo</h2>
<div class="outline-text-2" id="text-orgf34bc63">
<p>
Llegados a este punto, igual que podemos simplificar nuestro
<i>documento maestro</i> con importaciones de contenido, podemos hacer algo
parecido con las cabeceras. Además, es muy aconsejable hacerlo con las
cabeceras porque es donde definiremos, ─o redefiniremos─, los comandos
y entornos que necesitamos a nuestro gusto. Eso puede hacer que
nuestra cabecera se vuelva compleja e ininteligible. Sacar toda la
complejidad de nuestro documento nos facilitará la lectura y nos
permitirá <i>cambiar el chip</i> entre pensar en el contenido y pensar en
el diseño. Para ello, podemos hacer el trabajo de dos maneras: una es
definir una <i>clase de documento</i> completa, que se guardará en un
fichero <code>.cls</code> y se importará en la instrucción <code>\documentclass</code>. Esta
manera es más compleja que simplemente especificar unos cuantos
estilos agrupando unos cuantos comandos en un fichero <code>.sty</code>, que
sería la segunda manera.
</p>

<p>
Además, tradicionalmente, también se hace diferencias en el tipo de
cosas que va en cada uno de ellos. En los archivos <code>cls</code> (<i>class</i>)
suele definirse el tamaño de papel, el tamaño de letra, comandos de
estructura del documento ─cabeceras, índices, datos─. Es aconsejable
además tener en cuenta parámetros que pueden establecerse como
opciones cuando se llama a <code>\documentclass</code>. Por otro lado, los
ficheros <code>sty</code> suelen utilizarse para simplemente dar formato nuestros
documentos definiendo el aspecto final del mismo: diseño de página,
tamaño de letra, familia de la fuente, etc.
</p>

<p>
Ambas formas, <i>estilo</i> y <i>clase</i> son muy similares: ¿Cuándo utilizar
un <i>paquete de estilo</i> o cuándo una <i>clase</i>? La regla básica es si
vamos a definir comandos que se pueden emplear en cualquier clase de
documento ─libro, artículo, carta, informe, etc─, mejor utilizamos un
paquete de estilo (<code>sty</code>). Si los comandos que vamos a definir, sólo
se podrán utilizar en una clase definida, mejor utilizamos un <code>cls</code>.
</p>

<p>
En nuestro caso, queremos que nuestros comandos sean utilizables por
cualquier tipo de documento que generemos; es más, lo que hacemos es
utilizar llamadas a determinadas opciones de diseño. Por tanto,
elegimos hacer nuestro propio <i>estilo</i> creando un fichero que se llame
<code>miestilo.sty</code> y que contendrá lo mismo que nuestra cabecera.
Exactamente lo mismo no, como digo lo normal es que queramos
reutilizar ese fichero y todo nuestro esfuerzo, para no tener que
repetirlo con cada documento. Por eso, lo más lógico es que metamos en
él aquellas cosas generales que tienen que ver con cómo se ve el
documento desentendiéndose del contenido. Así, por ejemplo, al
importar el paquete <code>hyperref</code> hacíamos una definición de parámetros
que pueden considerarse <i>contenido</i> en el comando <code>\hypersetup</code>, como
el autor o el título del <code>pdf</code>. Pero vamos con ejemplos para
ilustrarlo.
</p>

<p>
La primera cosa que necesitamos especificar para crear nuestro propio
estilo es el formato de código que vamos a emplear y la segunda,
ponerle un nombre al paquete. Para ello, comenzamos nuestro fichero de
estilo con las siguientes instrucciones:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6;">\NeedsTeXFormat</span>{LaTeX2e}
<span style="color: #ff79c6; font-weight: bold;">\ProvidesPackage</span>{<span style="color: #50fa7b; font-weight: bold;">miestilo</span>}[<span style="color: #f8f8f2; font-weight: bold;">2021/04/12 v1.0 Mi propio estilo</span>]
</pre>
</div>

<p>
La primera línea, como dije antes, especifica el formato de <i>TeX</i> que
queremos utilizar. En nuestro caso <i>LaTeX2e</i>. Hay que ser cuidadoso
con el uso de las mayúsculas y minúsculas en estos comandos.
</p>

<p>
El segundo comando, <code>\ProvidesPackage</code> define el nombre del paquete,
en nuestro caso <code>miestilo</code> y una serie de opciones o datos del estilo:
La fecha de realización, la versión (<code>v1.0</code>) y un nombre largo del
estilo.
</p>

<p>
El siguiente paso es sencillo: copiamos toda la cabecera de nuestro
documento, exceptuando los comandos <code>\title{}</code> y <code>\author{}</code> al
fichero <code>miestilo.sty</code>. Éste debería quedar como sigue:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6;">\NeedsTeXFormat</span>{LaTeX2e}
<span style="color: #ff79c6; font-weight: bold;">\ProvidesPackage</span>{<span style="color: #50fa7b; font-weight: bold;">miestilo</span>}[<span style="color: #f8f8f2; font-weight: bold;">2021/04/12 v1.0 Mi propio estilo</span>]

<span style="color: #ff79c6; font-weight: bold;">\usepackage</span>[<span style="color: #f8f8f2; font-weight: bold;">a4paper,margin=3cm</span>]{<span style="color: #50fa7b; font-weight: bold;">geometry</span>}
<span style="color: #6272a4;">% </span><span style="color: #6272a4;">Paquetes b&#225;sicos
</span><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>[<span style="color: #f8f8f2; font-weight: bold;">T1</span>]{<span style="color: #50fa7b; font-weight: bold;">fontenc</span>}    <span style="color: #6272a4;">% fuentes adecuadas para salida
</span><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>[<span style="color: #f8f8f2; font-weight: bold;">utf8</span>]{<span style="color: #50fa7b; font-weight: bold;">inputenc</span>} <span style="color: #6272a4;">% acentos y caracteres especiales, desde el teclado
</span><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>[<span style="color: #f8f8f2; font-weight: bold;">spanish</span>]{<span style="color: #50fa7b; font-weight: bold;">babel</span>} <span style="color: #6272a4;">% Traducci&#243;n al espa&#241;ol de los ep&#237;grafes
</span>                            <span style="color: #6272a4;">% de LaTeX: &#8216;Cap&#237;tulo&#8217;, &#8216;&#205;ndice&#8217;
</span>                            <span style="color: #6272a4;">% &#8216;Figura&#8217;...
</span><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>{<span style="color: #50fa7b; font-weight: bold;">palatino</span>}       <span style="color: #6272a4;">% Importamos la fuente Palatino
</span>
<span style="color: #ff79c6; font-weight: bold;">\usepackage</span>{<span style="color: #50fa7b; font-weight: bold;">pifont</span>}
<span style="color: #ff79c6; font-weight: bold;">\usepackage</span>{<span style="color: #50fa7b; font-weight: bold;">multirow</span>}       <span style="color: #6272a4;">% Tablas con celdas en varias l&#237;neas
</span><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>{<span style="color: #50fa7b; font-weight: bold;">graphicx</span>}       <span style="color: #6272a4;">% Paquete extendido de gr&#225;ficos
</span><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>{<span style="color: #50fa7b; font-weight: bold;">subcaption</span>}     <span style="color: #6272a4;">% M&#250;ltiple gr&#225;ficos en una figura
</span><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>{<span style="color: #50fa7b; font-weight: bold;">xcolor</span>}         <span style="color: #6272a4;">% Paquete para colores
</span><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>{<span style="color: #50fa7b; font-weight: bold;">hyperref</span>}       <span style="color: #6272a4;">% Habilitaci&#243;n de enlaces
</span><span style="color: #ff79c6;">\hypersetup</span>{                <span style="color: #6272a4;">% Configuraci&#243;n de los enlaces y el pdf
</span>   breaklinks=true,
   colorlinks=true,
   linkcolor=blue,
   citecolor=green,
   filecolor=cyan,
   pdflang={Spanish},
   pdfpagemode={UseOutLines},
   pdfpagelayout={OneColumn}}

<span style="color: #ff79c6;">\definecolor</span>{migris}{gray}{0.75}

<span style="color: #ff79c6; font-weight: bold;">\newcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\comillas</span>}[<span style="color: #f8f8f2; font-weight: bold;">1</span>]{<span style="color: #50fa7b; font-weight: bold;">\guillemotleft</span><span style="color: #50fa7b; font-weight: bold;">{#1}</span><span style="color: #50fa7b; font-weight: bold;">\guillemotright</span>}
<span style="color: #ff79c6; font-weight: bold;">\newenvironment</span>{<span style="color: #50fa7b; font-weight: bold;">cita</span>}{<span style="color: #6272a4; font-weight: bold;">%
</span><span style="color: #50fa7b; font-weight: bold;">  </span><span style="color: #50fa7b; font-weight: bold; font-style: italic;">\small</span><span style="color: #50fa7b; font-weight: bold; font-style: italic;">\it</span><span style="color: #50fa7b; font-weight: bold;">\begin</span><span style="color: #50fa7b; font-weight: bold;">{quotation}
    </span>}{<span style="color: #6272a4; font-weight: bold;">%
</span><span style="color: #50fa7b; font-weight: bold;">    </span><span style="color: #50fa7b; font-weight: bold;">\end</span><span style="color: #50fa7b; font-weight: bold;">{quotation}
  </span>}
</pre>
</div>

<p>
También tenemos que modificar nuestro documento que quedará como:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\documentclass</span>[<span style="color: #f8f8f2; font-weight: bold;">a4,11pt,doubleside</span>]{<span style="color: #50fa7b; font-weight: bold;">article</span>}
  <span style="color: #ff79c6; font-weight: bold;">\usepackage</span>{<span style="color: #50fa7b; font-weight: bold;">miestilo</span>}
  <span style="color: #ff79c6; font-weight: bold;">\title</span>{<span style="color: #8be9fd; font-style: italic;">Documento b&#225;sico de ejemplo</span>} <span style="color: #6272a4;">% El t&#237;tulo del documento
</span>  <span style="color: #ff79c6; font-weight: bold;">\author</span>{<span style="color: #8be9fd; font-style: italic;">Notxor</span>}                     <span style="color: #6272a4;">% El autor
</span>
<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">document</span>}                      <span style="color: #6272a4;">% Entorno que contiene el documento
</span>
<span style="color: #6272a4;">% </span><span style="color: #6272a4;">[...]
</span>
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">document</span>}
</pre>
</div>

<p>
El resto del código es el idéntico. pero como podemos ver, nuestra
cabecera de documento ha quedado reducida a la mínima expresión.
</p>

<p>
Pero de todas las cosas que nos son más útiles en un fichero de estilo
es la modificación de los encabezados o los términos utilizados en el
documento. Por ejemplo, si estuviéramos escribiendo un libro de texto,
podríamos añadir el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6;">\addto\captionsspanish</span>{<span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\partname</span>}{<span style="color: #50fa7b; font-weight: bold;">Unidad did&#225;ctica</span>}}
<span style="color: #ff79c6;">\addto\captionsspanish</span>{<span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\chaptername</span>}{<span style="color: #50fa7b; font-weight: bold;">Lecci&#243;n</span>}}
<span style="color: #ff79c6;">\addto\captionsspanish</span>{<span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\tablename</span>}{<span style="color: #50fa7b; font-weight: bold;">Tabla</span>}}  <span style="color: #6272a4;">% En lugar de &#171;cuadro&#187; por defecto
</span><span style="color: #ff79c6;">\addto\captionsspanish</span>{<span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\listtablename</span>}{<span style="color: #50fa7b; font-weight: bold;">&#205;ndice de tablas</span>}}
</pre>
</div>

<p>
Si nos fijamos bien en el código, estamos añadiendo (<code>addto</code>) a la
lista de títulos en español (<code>captionspanish</code>) los cambios realizados
en los comandos (<code>renewcommand</code>)...
</p>

<p>
De este modo, podríamos también redefinir la estructura de las
cabeceras desde cero. O también, por resaltarlas mediante las
facilidades de otro de los paquetes de <i>LaTeX</i> que conviene mirar:
<code>titlesec</code>. Por ejemplo, si añadimos a nuestro fichero de estilo el
siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #6272a4;">% </span><span style="color: #6272a4;">Modificar cabeceras
</span><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>{<span style="color: #50fa7b; font-weight: bold;">titlesec</span>}
<span style="color: #ff79c6;">\titleformat</span>{<span style="color: #ff5555; font-weight: bold;">\</span><span style="color: #ff79c6; font-weight: bold;">section</span>}[frame]
{<span style="color: #ff79c6; font-weight: bold;">\normalfont</span>}{<span style="color: #ff79c6;">\filcenter</span><span style="color: #8be9fd; font-style: italic;">\small</span>\ Secci&#243;n <span style="color: #ff79c6;">\thesection</span>}{7pt}{<span style="color: #ff79c6; font-weight: bold;">\Large</span><span style="color: #8be9fd; font-style: italic;">\sffamily</span><span style="color: #bd93f9; font-style: italic;">\bfseries</span><span style="color: #8be9fd; font-style: italic;">\filcenter</span>}

<span style="color: #ff79c6;">\titleformat</span>{<span style="color: #ff5555; font-weight: bold;">\</span><span style="color: #ff79c6; font-weight: bold;">subsection</span>}[block]
{<span style="color: #ff79c6; font-weight: bold;">\normalfont</span>}{ <span style="color: #ff79c6;">\colorbox</span>{migris}{<span style="color: #ff79c6; font-weight: bold;">\large</span><span style="color: #8be9fd; font-style: italic;">\sffamily</span><span style="color: #bd93f9; font-style: italic;">\bfseries</span><span style="color: #8be9fd; font-style: italic;"> </span><span style="color: #8be9fd; font-style: italic;">\thesubsection</span>}}{.5em}{<span style="color: #ff79c6; font-weight: bold;">\large</span><span style="color: #8be9fd; font-style: italic;">\sffamily</span><span style="color: #bd93f9; font-style: italic;">\bfseries</span>}
</pre>
</div>

<p>
El formato utilizado es el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6;">\titleformat</span>{<span style="color: #ff79c6;">\cabecera</span>}[Tipo]{Formato}{Etiqueta}{Separaci&#243;n}{C&#243;digo anterior}[C&#243;digo posterior]
</pre>
</div>

<p>
No quiero alargar demasiado este último artículo, pero creo que viendo
el formato, cómo lo uso y el resultado obtenido, es fácil saber cómo
funciona. En todo caso la información que aporta la documentación del
paquete <code>titlesec</code> es suficientemente clara. Como puedes ver, consiste
en dotar de formato tanto a la etiqueta numérica en el apartado
<code>Etiqueta</code> y al texto de la cabecera en el <code>Código anterior</code>. Contamos
además con diferentes <i>tipos</i> de cabecera. En el ejemplo he usado
<code>frame</code> (<i>marco</i>), y <code>block</code> (<i>bloque</i>), pero hay más. El resultado
es:
</p>


<figure id="org909bc80">
<img src="./imagenes/Captura-pantalla_cambio-cabeceras.png" alt="Captura-pantalla_cambio-cabeceras.png">

</figure>

<p>
Otro paquete digno de tener en cuenta en cuestión de estilos es el que
nos facilita el <i>diseño de las páginas</i>; entendiendo por tal, la
estructura de las cabeceras y los pies de las páginas. Como siempre,
pongo un ejemplo y luego lo explico más despacio.
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #6272a4;">% </span><span style="color: #6272a4;">Dise&#241;o de cabeceras y pies de p&#225;gina
</span><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>{<span style="color: #50fa7b; font-weight: bold;">fancyhdr</span>}                <span style="color: #6272a4;">% Importamos el paquete
</span>
<span style="color: #ff79c6; font-weight: bold;">\pagestyle</span>{<span style="color: #50fa7b; font-weight: bold;">fancy</span>}                    <span style="color: #6272a4;">% P&#225;gina por defecto
</span>
<span style="color: #ff79c6;">\fancyhf</span>{}                           <span style="color: #6272a4;">% Definici&#243;n del estilo de p&#225;gina por defecto
</span><span style="color: #ff79c6;">\fancyhead</span>[LE,RO]{<span style="color: #ff79c6;">\thepage</span>}
<span style="color: #ff79c6;">\fancyhead</span>[RE]{<span style="color: #ff79c6; font-weight: bold;">\textit</span>{<span style="color: #ff79c6; font-style: italic;">\nouppercase</span><span style="color: #ff79c6; font-style: italic;">{</span><span style="color: #ff79c6; font-style: italic;">\leftmark</span><span style="color: #ff79c6; font-style: italic;">}</span>}}
<span style="color: #ff79c6;">\fancyhead</span>[LO]{<span style="color: #ff79c6; font-weight: bold;">\textit</span>{<span style="color: #ff79c6; font-style: italic;">\nouppercase</span><span style="color: #ff79c6; font-style: italic;">{</span><span style="color: #ff79c6; font-style: italic;">\rightmark</span><span style="color: #ff79c6; font-style: italic;">}</span>}}
<span style="color: #ff79c6;">\fancyfoot</span>[R]{<span style="color: #ff79c6; font-weight: bold;">\small</span><span style="color: #ff79c6; font-weight: bold; font-style: italic;">\textit</span><span style="color: #8be9fd; font-style: italic;">{</span><span style="color: #ff79c6; font-style: italic;">\href</span><span style="color: #ff79c6; font-style: italic;">{https://notxor.nueva-actitud.org}{Notxor tiene un blog}</span><span style="color: #8be9fd; font-style: italic;">}</span>}
<span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\headrulewidth</span>}{<span style="color: #50fa7b; font-weight: bold;">0.4mm</span>}
<span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\footrulewidth</span>}{<span style="color: #50fa7b; font-weight: bold;">0.2mm</span>}
</pre>
</div>

<p>
El resultado es:
</p>


<figure id="orgcb581da">
<img src="./imagenes/Captura-pantalla_cabeceras-pies.png" alt="Captura-pantalla_cabeceras-pies.png">

</figure>

<p>
Lo que hace el código es sencillo de entender:
</p>

<ul class="org-ul">
<li>Importamos el paquete <code>fancyhdr</code>, que se trabaja sobre el aspecto de
las páginas.</li>
<li>Definimos el estilo por defecto, si no se especifica otra cosa, de
todas las páginas: <code>fancy</code>.</li>
<li>Borramos todas las definiciones que haya en el espacio dedicado a
cabeceras y pies con <code>\fancyhf{}</code>, para definir los nuevos desde
cero.</li>
<li>Definimos los contenidos con los comandos <code>\fancyhead</code> y
<code>\fancyfoot</code>. Ahora veremos la estructura de estos comandos.</li>
<li>Redefinimos las líneas de separación de las cabeceras y pies.</li>
</ul>

<p>
Los comandos para definir el contenido de cabeceras y pies tienen el
siguiente formato:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6;">\fancyhead</span>[posici&#243;n]{contenido}
<span style="color: #ff79c6;">\fancyfoot</span>[posici&#243;n]{contenido}
</pre>
</div>

<p>
El parámetro <code>posición</code> tiene los siguientes significados:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Inicial</th>
<th scope="col" class="org-left">Significado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>E</code></td>
<td class="org-left">Página par (<i>even</i>)</td>
</tr>

<tr>
<td class="org-left"><code>O</code></td>
<td class="org-left">Página impar (<i>odd</i>)</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left"><code>L</code></td>
<td class="org-left">Izquierda (<i>left</i>)</td>
</tr>

<tr>
<td class="org-left"><code>C</code></td>
<td class="org-left">Centro (<i>center</i>)</td>
</tr>

<tr>
<td class="org-left"><code>R</code></td>
<td class="org-left">Derecha (<i>right</i>)</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left"><code>H</code></td>
<td class="org-left">Cabecera (<i>head</i>)</td>
</tr>

<tr>
<td class="org-left"><code>F</code></td>
<td class="org-left">Pie (<i>foot</i>)</td>
</tr>
</tbody>
</table>

<p>
Por ejemplo, en el código anterior la definición
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6;">\fancyhead</span>[LE,RO]{<span style="color: #ff79c6;">\thepage</span>}
</pre>
</div>

<p>
Lo que hace es poner el número de página<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> a la izquierda (<code>L</code>) en
las páginas pares (<code>E</code>) codificando como <code>LE</code>, y a la derecha (<code>R</code>) en
las páginas impares (<code>O</code>), codificando como <code>RO</code>.
</p>

<p>
También podemos definir estilos de página especiales. Por ejemplo, en
el caso de necesitar una página totalmente en blanco, sin cabeceras ni
pies, ni líneas de separación, podríamos definir el siguiente estilo:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6;">\fancypagestyle</span>{plain}{              <span style="color: #6272a4;">% Definici&#243;n del estilo de p&#225;gina &#171;plain&#187;
</span><span style="color: #ff79c6;">\fancyhf</span>{}                           <span style="color: #6272a4;">% borra todo lo que hay en las cabeceras y pies
</span><span style="color: #ff79c6;">\fancyfoot</span>[C]{<span style="color: #ff79c6;">\thepage</span>}              <span style="color: #6272a4;">% Centramos el n&#250;mero de p&#225;gina en el pie
</span><span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\headrulewidth</span>}{<span style="color: #50fa7b; font-weight: bold;">0pt</span>}   <span style="color: #6272a4;">% quita las lineas de separaci&#243;n
</span><span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\footrulewidth</span>}{<span style="color: #50fa7b; font-weight: bold;">0pt</span>}}
</pre>
</div>

<p>
Luego, en nuestro texto podemos llamar a esa definición de página. He
añadido el siguiente contenido a nuestro fichero de ejemplos para
ilustrarlo:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff5555;">\pagebreak</span>
<span style="color: #ff79c6; font-weight: bold;">\thispagestyle</span>{<span style="color: #50fa7b; font-weight: bold;">plain</span>}
En esta p&#225;gina no hay cabeceras ni pies, est&#225; totalmente en blanco,
salvo el n&#250;mero de p&#225;gina centrado en el pie.
</pre>
</div>

<p>
Como se puede apreciar, se utiliza el comando <code>\thispagestyle</code> pasando
como parámetro el nombre del estilo de página que hemos definido.
Podemos, por tanto ajustar el diseño de la página también al contenido
o a nuestras necesidades.
</p>

<p>
Como siempre es muy aconsejable el mirar la documentación del paquete
para conocer todos los parámetros.
</p>
</div>
</div>
<div id="outline-container-org1df79f3" class="outline-2">
<h2 id="org1df79f3">Bibliografía</h2>
<div class="outline-text-2" id="text-org1df79f3">
<p>
La bibliografía es uno de los apartados más importantes en cualquier
tipo de documentación científica o de enseñanza. Documentarse
correctamente y proporcionar los datos suficientes para que cualquier
persona pueda seguir los razonamientos con una bibliografía completa
es la mejor manera de conseguir sentar una buena base argumentativa.
<i>TeX</i> en general, y <i>LaTeX</i> en particular, cuentan con una de las
herramientas más potentes para crear y mantener bases de datos
bibliográficas y poder citarlas desde nuestro texto.
</p>

<p>
En muchos entornos, como el universitario, el formato <code>bib</code> para las
bases de datos bibliográficas, se ha convertido en un estándar. Un
fichero <code>.bib</code> contiene, en texto plano, una serie de entradas con la
forma:
</p>

<div class="org-src-container">
<pre class="src src-latex">@tipo{etiqueta,
  propiedad1="valor1",
  propiedad2="valor2",
  ...
}
</pre>
</div>

<p>
Vamos, que así no parece que te sea de mucha utilidad la explicación,
pero vamos a crear un fichero de bibliografía para comprobar cómo
funciona. El contenido será el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #6272a4;">% </span><span style="color: #6272a4;">Encoding: UTF-8
</span>@book{Goossens,
  author="Michel Goossens and Frank Mittelbach and Alexander Samarin",
  title="The <span style="color: #ff79c6; font-weight: bold;">\LaTeX</span> Companion",
  editor="Addison-Wesley",
  year="1993"
}
@book{Lamport,
  author="Leslie Lamport",
  title="<span style="color: #ff79c6; font-weight: bold;">\LaTeX</span>",
  editor="Addison-Wesley",
  year="1996"
}
@Misc{minicurso,
  author = {Notxor},
  note   = {El minicurso consta de seis art&#237;culos consecutivos en el {<span style="color: #ff79c6; font-weight: bold;">\it</span><span style="color: #ff79c6; font-style: italic;"> blog</span>}.},
  title  = {Minicurso de utilizaci&#243;n de <span style="color: #ff79c6; font-weight: bold;">\LaTeX</span>},
  year   = {2021},
  url    = {https://notxor.nueva-actitud.org/2021/03/20/minicurso-de-latex-para-psic<span style="color: #6272a4;">%C3%B3logos.html},
</span>}

</pre>
</div>

<p>
El tipo del documento, en los dos primeros casos es <code>book</code>, luego
utilizo un <code>Misc</code> para poner una cita a una <i>web</i>, pero hay muchos
otro tipos de documentos <code>article</code>, <code>manual</code>, <code>conference</code>... El dato
de la <i>etiqueta</i> le proporciona una forma de referirnos a esa entrada
por un nombre corto. En este caso, sólo hay dos entradas y el autor es
distinto, por lo que podemos utilizar el apellido del autor como única
etiqueta. Cuando la base de datos crece y hay autores que se repiten
─algo muy habitual─, podemos establecer un sistema de etiquetas tal
que <code>autorAÑO</code> para que no haya conflictos entre entradas... O
cualquier otro sistema que proporcione un nombre único a la obra.
</p>

<p>
Hay herramientas que nos ayudan a crear y a mantener nuestras bases de
datos bibliográficas de una manera más visual y sencilla. En mi caso,
utilizo <a href="https://www.jabref.org/">una herramienta llamada <i>JabRef</i></a> que resulta sencilla de
utilizar: échale un ojo. Hay muchas más, busca por <i>Internet</i> cuál se
ajusta a tu forma de trabajar... también puedes mantener la base de
datos editando el fichero <code>bib</code> a mano, sin embargo, cualquier error
arruina toda la base de datos: una llave que se olvida, una coma que
falta, unas comillas que sobran. Depurar esos errores cuando lo
hacemos a mano puede ser complicado.
</p>


<figure id="org3ebf932">
<img src="./imagenes/Captura-pantalla_JabRef.png" alt="Captura-pantalla_JabRef.png">

</figure>

<p>
Como podemos ver en la captura de pantalla, tenemos nuestra lista de
ficheros de base de datos divididos por pestañas. Cada pestaña
contiene una lista de entradas, y cada entrada una lista de campos que
se pueden rellenar.
</p>

<p>
Una vez realizada nuestra base de datos, vamos a ver cómo la podemos
utilizar desde nuestro documento.
</p>

<p>
Para activar que se utilice una bibliografía necesitamos, como para
casi todo, importar un paquete, establecer sus opciones y especificar
la base de datos:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>[<span style="color: #f8f8f2; font-weight: bold;">backend=biber,style=apa</span>]{<span style="color: #50fa7b; font-weight: bold;">biblatex</span>}
<span style="color: #ff79c6; font-weight: bold;">\bibliography</span>{<span style="color: #bd93f9;">biblio.bib</span>}
</pre>
</div>

<p>
El paquete <code>biblatex</code> funciona dependiendo también de otras
herramientas externas. Tradicionalmente, se utiliza como <code>backend</code> la
aplicación <code>bibtex</code> o <code>biblatex</code>. Sin embargo, hay más herramientas y
últimamente vengo utilizando <code>biber</code>, porque me da la sensación de ser
algo más rápido a la hora de generar la bibliografía y las citas, pero
hay que recordar que dependerá de qué herramienta tengas instalada en
tu ordenador. El estilo de la bibliografía que utilizo es el <code>apa</code>
(<i>American Psychological Associaton</i>), que también depende de que
tengas instalado el correspondiente paquete en tu máquina.
</p>

<p>
Después de importar el paquete, necesitamos que se tenga en cuenta la
base de datos que estemos trabajando. En nuestro caso, como vimos
antes, creé un fichero de bibliografía con el nombre <code>biblio.tex</code> y es
el que pasamos como parámetro al comando <code>\bibliography</code>. Si
tuviéramos otras bases de datos, podemos referenciarlas también
añadiendo sus nombres separados por comas.
</p>

<p>
Para ilustrar cómo funciona el invento, además de añadir esos dos
comandos en la cabecera del documento, hay que citar las obras en
nuestro texto. Concretamente he añadido al final del documento lo
siguiente:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\section</span>{<span style="color: #50fa7b; font-size: 110%; font-weight: bold;">Uso de bibliograf&#237;a</span>}<span style="color: #ff79c6; font-weight: bold;">\label</span>{<span style="color: #bd93f9;">sec:uso-biblio</span>}

Podemos citar, por ejemplo a un autor simplemente (<span style="color: #ff79c6; font-weight: bold;">\cite</span>{<span style="color: #bd93f9;">Lamport</span>}) o
especificar tambi&#233;n la p&#225;gina (<span style="color: #ff79c6; font-weight: bold;">\cite</span>[<span style="color: #f8f8f2; font-weight: bold;">p&#225;g. 23</span>]{<span style="color: #bd93f9;">Goossens</span>}) y despu&#233;s
generar la bibliograf&#237;a. Incluso referenciar este minicurso
<span style="color: #ff79c6; font-weight: bold;">\cite</span>{<span style="color: #bd93f9;">minicurso</span>}.

<span style="color: #ff79c6; font-weight: bold;">\printbibliography</span>
</pre>
</div>

<p>
Como se puede apreciar, la cita se realiza utilizando el comando
<code>\cite{etiqueta}</code>, donde <code>etiqueta</code> hace referencia al <i>nombre único</i>
que vimos que había que proporcionar al documento citado. Además
podemos utilizar un parámetro indicando, por ejemplo la página, que se
mostrará en el resultado.
</p>

<p>
Una vez que terminado el contenido, con todas las citas necesarias,
utilizaremos el comando <code>\printbibliograpy</code> en el lugar donde queremos
que nos muestre la bibliografía.
</p>

<p>
El resultado obtenido quedaría así:
</p>


<figure id="org3937a0d">
<img src="./imagenes/Captura-pantalla_bibliografia.png" alt="Captura-pantalla_bibliografia.png">

</figure>

<p>
Como podemos ver, el comando <code>\printbibliography</code> nos genera una nueva
sección sin numerar con la lista de los documentos que hayamos citado.
Al añadir la bibliografís sin numerar, no aparecerá en nuestro índice,
pero a mí me gusta que la bibliografía aparezca allí. Muchas veces
buscando información, no te interesa releer el contenido, que lo
puedes haber leído decenas de veces, y lo que necesitas es encontrar
rápidamente una determinada fuente bibliográfica. Por eso tengo la
costumbre de añadir a la <i>tabla de contenidos</i> una línea con la
bibliografía de la siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\addcontentsline</span>{<span style="color: #50fa7b; font-weight: bold;">toc</span>}{<span style="color: #50fa7b; font-weight: bold;">section</span>}{<span style="color: #50fa7b; font-weight: bold;">Bibliograf&#237;a</span>}
<span style="color: #ff79c6; font-weight: bold;">\printbibliography</span>
</pre>
</div>

<p>
Como se puede ver, <code>\addcontentsline</code> añade una línea al bloque
<code>toc</code><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> de categoría <code>section</code> con el título <code>Bibliografía</code>.
</p>
</div>
</div>
<div id="outline-container-org98b4358" class="outline-2">
<h2 id="org98b4358">Conclusiones</h2>
<div class="outline-text-2" id="text-org98b4358">
<p>
¿Qué me he dejado en el tintero? Pues un montón de cosas. Hay cientos
de paquetes muy interesantes y tratarlos todos necesitaría, no seis
artículos sino un <i>blog</i> completo para verlo todo, aunque fuera por
encima. Aunque este artículo es el final del <i>minicurso</i>, desde luego
no es el final de <i>LaTeX</i>.
</p>

<p>
Podría haber hablado de las clases de documentos: artículo, libro,
informe, carta, presentación, examen... Pero no todos necesitamos los
mismos y es muy sencillo mirar la documentación y entender qué
comandos son específicos de esa clase y cómo utilizarlos, una vez
tenemos los conocimientos básicos.
</p>

<p>
Quizá podría haber hablado de otros aspectos y haber sacado del
contenido otras. Sin embargo, creo que el <i>minicurso</i> es básico, pero
suficientemente completo como para que te sientas cómodo utilizando
<i>LaTeX</i> por tu cuenta, sin recurrir al clásico <i>corta-pega</i> de código
de otros documentos sin llegar a comprender cómo funciona.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Recuerda el contador de página <code>\thepage</code>.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Table Of Contents</i>, el índice de materias que se mostrará al
principio del documento. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/latex/index.html">latex</a> ]]></description>
  <category><![CDATA[latex]]></category>
  <link>https://notxor.nueva-actitud.org/2021/04/15/minicurso-de-latex-para-psicologos-vi.html</link>
  <pubDate>Thu, 15 Apr 2021 17:25:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Minicurso de LaTeX para psicólogos v]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-04-10</div>
<p>
El problema en todo proyecto, incluyendo el crear documentación con
<i>LaTeX</i> es organizarse. La organización de la tarea es fundamental
para llevarlo a cabo, sobre todo si es un proyecto o documento
complejo. Por tanto, en el artículo de hoy vamos a ver cómo organizar
nuestro documento para poder dividirlo en partes más asequibles en
lugar de ir poniendo todo en un sólo fichero monolítico. Además,
puesto que veremos la forma de incluir el contenido de un fichero
<code>TeX</code> en otro, veremos también cómo definir algunos <i>comandos</i> propios
y, en la próxima entrega del minicurso los meteremos en un fichero de
estilo para importarlo como cualquier otro paquete. Lo que hará que
podamos utilizar de forma sencilla nuestros estilos entre los
diferentes documentos que generamos, creándonos plantillas que le
darán a nuestra producción estabilidad y presencia.
</p>
<div id="outline-container-orgf57063b" class="outline-2">
<h2 id="orgf57063b">El concepto de documento maestro</h2>
<div class="outline-text-2" id="text-orgf57063b">
<p>
Una forma de dividir el trabajo es utilizar un <i>documento maestro</i>,
entendiendo por tal, el fichero que contiene la cabecera y una serie
de instrucciones para importar el resto del contenido desde otros
ficheros. Lo habitual es que se utilicen dos tipos de ficheros <i>LaTeX</i>
para contener el código que generará nuestro documento:
</p>

<ul class="org-ul">
<li><code>.tex</code>: contienen contenido <i>LaTeX</i> que escribimos para generar el
documento.</li>
<li><code>.sty</code>: contienen todas las definiciones o <i>comandos</i> que le
proporcionan <i>estilo</i> a nuestro documento.</li>
</ul>

<p>
Lo más normal en proyectos grandes, como libros, tesis doctorales,
trabajos de fin de grado, etc. La forma más habitual de hacer una
importación de contenido <i>LaTeX</i> es utilizar el comando <code>\input{}</code>.
Dicho comando recibe como parámetro el nombre, sin la extensión, de un
fichero <i>LaTeX</i>. Las llamadas a <code>input</code> pueden incluir contenido que a
su vez llame a <code>input</code> para añadir otro contenido. Para verlo de una
forma más visual he creado tres ficheros <code>.tex</code> con el siguiente
contenido:
</p>

<ul class="org-ul">
<li><p>
El fichero <code>aa.tex</code>:
</p>
<div class="org-src-container">
<pre class="src src-latex"><span style="color: #6272a4;">% </span><span style="color: #6272a4;">Fichero aa.tex
</span><span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">itemize</span>}
  <span style="color: #ff79c6; font-weight: bold;">\item</span> Empieza el fichero <span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">aa.tex</span>}
  <span style="color: #ff79c6; font-weight: bold;">\item</span> Incluye: <span style="color: #ff79c6; font-weight: bold;">\par</span> <span style="color: #ff79c6; font-weight: bold;">\input</span>{<span style="color: #bd93f9;">bb</span>}
  <span style="color: #ff79c6; font-weight: bold;">\item</span> El final del fichero <span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">aa.tex</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">itemize</span>}
</pre>
</div></li>

<li><p>
El fichero <code>bb.tex</code>:
</p>
<div class="org-src-container">
<pre class="src src-latex"><span style="color: #6272a4;">% </span><span style="color: #6272a4;">Fichero bb.tex
</span><span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">itemize</span>}
  <span style="color: #ff79c6; font-weight: bold;">\item</span> El principio del fichero <span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">bb.tex</span>}
  <span style="color: #ff79c6; font-weight: bold;">\item</span> Incluye: <span style="color: #ff79c6; font-weight: bold;">\par</span> <span style="color: #ff79c6; font-weight: bold;">\input</span>{<span style="color: #bd93f9;">cc</span>}
  <span style="color: #ff79c6; font-weight: bold;">\item</span> El final del fichero <span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">bb.tex</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">itemize</span>}
</pre>
</div></li>

<li><p>
El fichero <code>cc.tex</code>:
</p>
<div class="org-src-container">
<pre class="src src-latex"><span style="color: #6272a4;">% </span><span style="color: #6272a4;">El fichero cc.tex
</span><span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">itemize</span>}
  <span style="color: #ff79c6; font-weight: bold;">\item</span> El contenido del fichero <span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">cc.tex</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">itemize</span>}
</pre>
</div></li>
</ul>

<p>
Como vemos, el fichero <code>aa.tex</code> incluye a <code>bb.tex</code> y este último
incluye el siguiente <code>cc.tex</code>. Después, basta con importar el primero
en nuestro fichero de ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\input</span>{<span style="color: #bd93f9;">aa</span>}
</pre>
</div>

<p>
El resultado es el siguiente:
</p>


<figure id="org25a8502">
<img src="./imagenes/Captura-pantalla_input.png" alt="Captura-pantalla_input.png">

</figure>

<p>
En lugar de trabajar con unas simples listas, podríamos haber
utilizado el comando <code>\input</code> para importar <i>apartados</i> completos del
documento general: capítulos, secciones, etc. Mover nuestro contenido
de un lugar a otro será tan fácil como mover la instrucción de
importación a posiciones anteriores o posteriores.
</p>

<p>
Básicamente, en eso consiste el concepto de <i>documento maestro</i>. Es
tan solo un documento donde se especifican las opciones y estilos,
manteniendo el contenido independiente del resultado final. De esta
forma, cualquier cambio en el estilo de algún tipo de párrafo se
<i>propaga</i> automáticamente a lo largo del texto dándole coherencia al
resultado final.
</p>

<p>
Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\documentclass</span>[<span style="color: #f8f8f2; font-weight: bold;">11pt,a4</span>]{<span style="color: #50fa7b; font-weight: bold;">book</span>}

<span style="color: #6272a4;">% </span><span style="color: #6272a4;">Carga de paquetes necesarios
</span>(...)
<span style="color: #6272a4;">% </span><span style="color: #6272a4;">Definici&#243;n de ajustes finos
</span>(...)
<span style="color: #6272a4;">% </span><span style="color: #6272a4;">Definici&#243;n de nuevos comandos
</span>
<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">document</span>}
<span style="color: #ff79c6; font-weight: bold;">\maketitle</span>

<span style="color: #ff79c6; font-weight: bold;">\tableofcontents</span>
<span style="color: #ff79c6; font-weight: bold;">\part</span>{<span style="color: #ff79c6; font-size: 130%; font-weight: bold;">Conceptos b&#225;sicos</span>}
<span style="color: #ff79c6; font-weight: bold;">\chapter</span>{<span style="color: #bd93f9; font-size: 130%; font-weight: bold;">Tema 1</span>}          <span style="color: #6272a4;">% Podemos manejar aqu&#237; las cabeceras
</span><span style="color: #ff79c6; font-weight: bold;">\input</span>{<span style="color: #bd93f9;">contenido-tema-1</span>}  <span style="color: #6272a4;">% para importar s&#243;lo el contenido
</span>
<span style="color: #ff79c6; font-weight: bold;">\input</span>{<span style="color: #bd93f9;">tema-2</span>}            <span style="color: #6272a4;">% o podemos importarlo todo desde aqu&#237;
</span><span style="color: #ff79c6; font-weight: bold;">\input</span>{<span style="color: #bd93f9;">otro-tema</span>}

<span style="color: #ff79c6; font-weight: bold;">\part</span>{<span style="color: #ff79c6; font-size: 130%; font-weight: bold;">Conceptos no tan b&#225;sicos</span>}
<span style="color: #ff79c6; font-weight: bold;">\input</span>{<span style="color: #bd93f9;">un-tema-avanzado</span>}
(...)
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">document</span>}
</pre>
</div>

<p>
En el código anterior podemos observar la estructura de un <i>documento
maestro</i>. Básicamente es una cabecera que define estilos que se
complementa con una lista de <i>importaciones</i> de contenido.
</p>
</div>
</div>
<div id="outline-container-orgde64351" class="outline-2">
<h2 id="orgde64351">Crear nuevos comandos y entornos</h2>
<div class="outline-text-2" id="text-orgde64351">
<p>
En ocasiones los comandos que nos proporciona <i>LaTeX</i> se nos quedan
cortos o no funcionan exactamente como queremos, para esto viene bien
tener la capacidad de crear un comando nuevo o modificar uno ya
existente. Las situaciones en que esto sea necesario pueden ser muy
variopintas, pero voy a poner dos ejemplos, aunque sean un poco
forzados, para ilustrar que no es nada complicado el hacer nuevos
comandos o redefinirlos, si fuera el caso. El formato del comando que
crea comandos es el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\newcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\nombre</span>}[<span style="color: #f8f8f2; font-weight: bold;">args</span>][<span style="color: #f8f8f2; font-weight: bold;">opciones</span>]{<span style="color: #50fa7b; font-weight: bold;">definici&#243;n</span>}
</pre>
</div>

<p>
Donde:
</p>

<dl class="org-dl">
<dt><code>\nombre</code></dt><dd>es el nombre del comando.</dd>
<dt><code>args</code></dt><dd>es un número menor de 9 que indica el número de argumentos
del comando.</dd>
<dt><code>opciones</code></dt><dd>define las opciones del comando... como implica el uso
de condicionales en el código, lo pongo para que sepáis que existe,
pero no es contenido para un uso básico de <i>LaTeX</i>.</dd>
<dt><code>definición</code></dt><dd>es texto <i>LaTeX</i> sin más, los argumentos dentro de
la definición tendrán el formato <code>#n</code>, donde <code>n</code> indica el número de
orden recibido.</dd>
</dl>

<p>
¿Complicado? Parece que dicho así en abstracto lo es, pero es bastante
más sencillo en la práctica. Vamos a ver un ejemplo sencillo: imagina
que no tienes en el teclado los caracteres <code>«»</code> necesarios para
utilizar las comillas españolas. Sin embargo, quieres utilizar las
comillas <i>a la española</i> y no <i>a la inglesa</i>. ¿Qué hacemos? Pues
definir un comando que al llamarlo las escriba por nosotros. Para ello
definimos el siguiente comando:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\newcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\comillas</span>}[<span style="color: #f8f8f2; font-weight: bold;">1</span>]{<span style="color: #50fa7b; font-weight: bold;">\guillemotleft</span><span style="color: #50fa7b; font-weight: bold;">{#1}</span><span style="color: #50fa7b; font-weight: bold;">\guillemotright</span>}
</pre>
</div>

<p>
Es decir, hemos definido el comando <code>\comillas</code>, que recibe <code>1</code>
parámetro y que escribe <code>\guillemotleft</code> (<code>«</code>) delante del parámetro
<code>#1</code> y después añade un <code>\guillemotright</code> (<code>»</code>).
</p>

<p>
Si añadimos en la cabecera dicho comando, podremos escribir en
cualquier sitio de nuestro documentos, ─también de los documentos que
importemos─, texto que haga referencia o llame a nuestro comando:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\section</span>{<span style="color: #50fa7b; font-size: 110%; font-weight: bold;">Definici&#243;n de nuevos comandos</span>}

He creado un nuevo comando que me permitan poner <span style="color: #ff79c6;">\comillas</span>{comillas
espa&#241;olas} con m&#225;s facilidad.
</pre>
</div>

<p>
Repasando el funcionamiento del comando, podemos ver en este ejemplo,
que el comando <code>\comillas</code> recibe un parámetro <code>#1</code> con valor
<code>comillas españolas</code> y, por tanto en la salida, lo rodea de un
carácter <code>\guillemotleft</code> delante y un carácter <code>\guillemotright</code>
detrás. Por otro lado, el mismo efecto se podría conseguir utilizando
<code>&lt;&lt;</code> delante y <code>&gt;&gt;</code> detrás, sin necesidad de crear un comando
específico. El resultado en nuestro documento será:
</p>


<figure id="org3a73fe0">
<img src="./imagenes/Captura-pantalla_comando.png" alt="Captura-pantalla_comando.png">

</figure>

<p>
Igual que podemos definir comandos, también podemos definir entornos
de texto. El comando para hacerlo es muy similar:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\newenvironment</span>{<span style="color: #50fa7b; font-weight: bold;">nombre</span>}[<span style="color: #f8f8f2; font-weight: bold;">args</span>][<span style="color: #f8f8f2; font-weight: bold;">opciones</span>]{<span style="color: #50fa7b; font-weight: bold;">comienzo</span>}{<span style="color: #50fa7b; font-weight: bold;">final</span>}
</pre>
</div>

<p>
La diferencia con la definición de comandos es que necesita dos
bloques de <i>código</i>. La primera, <code>comienzo</code>, determina todos los
comandos que afectarán al bloque de texto contenido en el entorno. La
segunda, <code>final</code>, se compondrá de los comandos que restauren la
presentación o características de los párrafos del documento que se
han modificado en el primero bloque. Para verlo más claro, va un
ejemplo. Pretendemos hacer que nuestras citas se remarquen visualmente
mejor, nos gusta que el tamaño de la letra sea un poco más pequeño y
que utilice letra cursiva para remarcar visualmente que ese texto no
lo hemos escrito nosotros. El código podría ser el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\newenvironment</span>{<span style="color: #50fa7b; font-weight: bold;">cita</span>}{<span style="color: #6272a4; font-weight: bold;">%
</span><span style="color: #50fa7b; font-weight: bold;">  </span><span style="color: #50fa7b; font-weight: bold; font-style: italic;">\small</span><span style="color: #50fa7b; font-weight: bold; font-style: italic;">\it</span><span style="color: #50fa7b; font-weight: bold;">\begin</span><span style="color: #50fa7b; font-weight: bold;">{quotation}
    </span>}{<span style="color: #6272a4; font-weight: bold;">%
</span><span style="color: #50fa7b; font-weight: bold;">    </span><span style="color: #50fa7b; font-weight: bold;">\end</span><span style="color: #50fa7b; font-weight: bold;">{quotation}
  </span>}
</pre>
</div>

<p>
En el código anterior definimos un entorno llamado <code>cita</code>. Podríamos
haber creado todo el entorno desde cero, definido márgenes, tipos de
letra, familia de la fuente, etc. Todas esas definiciones irían en el
primer bloque del comando. Posteriormente, deberíamos reestablecer los
márgenes, fuentes y familia de la fuente, en el segundo bloque. Sin
embargo, en <i>LaTeX</i> ya existe un entorno <code>quotation</code> que nos modifica
los márgenes izquierdo y derecho del contenido para remarcar que es
una cita textual de otro documento, libro u obra. Por lo tanto, vamos
a aprovecharlo y puesto que sólo necesitamos que la letra sea un poco
más pequeña (<code>\small</code>) y que se muestre en cursiva (<code>\it</code>), le
forzamos a que inicie un bloque <code>\quotation</code> con estas opciones y
cuando acabe, que restaure el estilo de texto cerrando dicho entorno.
</p>

<p>
Para hacer una prueba de funcionamiento he añadido el siguiente
texto, tras añadir el comando anterior a nuestra cabecera:
</p>

<div class="org-src-container">
<pre class="src src-latex">Esto es una cita realizada con un entorno definido mediante la
redefici&#243;n de un p&#225;rrafo con el comando <span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">newenvironment</span>}
propio.

<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">cita</span>}
  Esto es una cita realizada con el comando de entorno definido y
  personalizado. Hay que observar que <span style="color: #ff79c6; font-weight: bold;">\emph</span>{<span style="color: #ff79c6; font-style: italic;">se aprovecha</span>} la
  existencia de un formato de p&#225;rrafo <span style="color: #ff79c6;">\comillas</span>{ya existente} para
  modificar m&#237;nimamente el contenido.

  Y podemos ver que se pueden emplear sin problemas otros comandos que
  hemos definido nosotros.
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">cita</span>}
</pre>
</div>

<p>
El resultado obtenido es el siguiente:
</p>


<figure id="org608a8ac">
<img src="./imagenes/Captura-pantalla_entorno.png" alt="Captura-pantalla_entorno.png">

</figure>

<p>
Como vemos es muy sencillo el crear nuestros propios comandos y
entornos, basándonos en los ya existentes. Crear comandos o entornos
desde cero es algo más complejo y se sale de las pretensiones de este
minicurso. Por otro lado, es posible que nuestras necesidades pasen
por modificar el comportamiento de un comando o de un entorno ya
existentes y que se pueda aplicar con el mismo nombre de comando o
entorno. Si es así, si lo que hacemos en redefinir comandos previos,
<i>LaTeX</i> nos lanzará un error. Para evitar eso debemos utilizar los
comandos:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\nombre</span>}[<span style="color: #f8f8f2; font-weight: bold;">args</span>][<span style="color: #f8f8f2; font-weight: bold;">opciones</span>]{<span style="color: #50fa7b; font-weight: bold;">definici&#243;n</span>}
<span style="color: #ff79c6; font-weight: bold;">\renewenvironment</span>{<span style="color: #50fa7b; font-weight: bold;">nombre</span>}[<span style="color: #f8f8f2; font-weight: bold;">args</span>][<span style="color: #f8f8f2; font-weight: bold;">opciones</span>]{<span style="color: #50fa7b; font-weight: bold;">comienzo</span>}{<span style="color: #50fa7b; font-weight: bold;">final</span>}
</pre>
</div>

<p>
Las opciones de las definiciones son las mismas para los <i>renew</i> que
para los <i>new</i>, la única diferencia es que si utilizamos <i>new</i>, a
secas, <i>LaTeX</i> interpreta que estamos creando un comando totalmente
nuevo. Por tanto, si ya existía, nos lanzará un error para avisarnos
de que estamos intentando crear un comando con un nombre ya utilizado.
Si utilizamos <i>renew</i> interpretará que lo que queremos es <i>redefinir</i>
un comando si existe y, si no existe lo creará.
</p>
</div>
</div>
<div id="outline-container-org6216e64" class="outline-2">
<h2 id="org6216e64">Contadores</h2>
<div class="outline-text-2" id="text-org6216e64">
<p>
<i>LaTeX</i> utiliza una serie de contadores y/o variables para realizar
algunas tareas de numeración a lo largo de los documentos. Por
ejemplo, el número de página, el número de capítulo, el de la sección,
el orden del ítem en una lista de tipo <code>enumerate</code>, etc. También
podremos crear los nuestros, pero la necesidad de crear un contador o
variable también sobrepasa el uso básico de <i>LaTeX</i> para meterse en
profundidades de programación. De momento, en este minicurso, nos
vamos a quedar con la posibilidad de modificar un contador ya
existente, que ya es suficiente para un uso básico.
</p>

<p>
Por defecto, la lista de contadores con que cuenta <i>LaTeX</i> en un
documento de clase <i>book</i> es la siguiente:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Tipo de uso</th>
<th scope="col" class="org-left">contador</th>
<th scope="col" class="org-left">significado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">Estructura de documento</td>
<td class="org-left"><code>page</code></td>
<td class="org-left">Página</td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>part</code></td>
<td class="org-left">Parte</td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>chapter</code></td>
<td class="org-left">Capítulo</td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>section</code></td>
<td class="org-left">Sección</td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>subsection</code></td>
<td class="org-left">Apartado</td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>subsubsection</code></td>
<td class="org-left">Subapartado</td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>paragraph</code></td>
<td class="org-left">Párrafo</td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>subparagraph</code></td>
<td class="org-left">Subpárrafo</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">Para entornos flotantes</td>
<td class="org-left"><code>equation</code></td>
<td class="org-left">Ecuaciones</td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>figure</code></td>
<td class="org-left">Figuras</td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>table</code></td>
<td class="org-left">Tablas</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">Para anotaciones</td>
<td class="org-left"><code>footnote</code></td>
<td class="org-left">Nota al pie</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">Para enumeraciones</td>
<td class="org-left"><code>enumi</code></td>
<td class="org-left">1<sup>er</sup> nivel de la lista</td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>enumii</code></td>
<td class="org-left">2º nivel de la lista</td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>enumiii</code></td>
<td class="org-left">3<sup>er</sup> nivel de la lista</td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left"><code>enumiv</code></td>
<td class="org-left">4º nivel de la lista</td>
</tr>
</tbody>
</table>

<p>
Para obtener una cadena formateada con su valor, se suele utilizar el
nombre de contador con <i>the</i>, ─el artículo en inglés─, delante. Esto
es así, porque muchos de ellos pueden mostrarse encadenados. Por
ejemplo, el índice de una sección suele estar formado por el número de
capítulo y el número de sección. Hablar de los contadores y sus
idiosincrasias así en abstracto es complejo, mejor es ver cómo
funcionan y cómo podemos utilizarlos según nuestras necesidades.
</p>

<p>
Vamos a poner un par de ejemplos para ilustrar cómo se trabaja con los
contadores de una manera más avanzada. Para empezar, con un primer
ejemplo que podemos necesitar: comenzamos una enumeración, y resulta
que debemos detenerla para dar una explicación algo más
larga. Cerramos el entorno <code>enumerate</code>, escribimos nuestra explicación
y cuando queremos retomarla abriendo de nuevo el entorno <code>enumerate</code>
resulta que la numeración vuelve a comenzar por el <code>1</code>.
</p>

<p>
Observa el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">minipage</span>}[c]{0.40<span style="color: #ff79c6;">\linewidth</span>}
  Por alg&#250;n motivo necesitamos realizar una enumeraci&#243;n:

  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
  <span style="color: #ff79c6; font-weight: bold;">\item</span> &#205;tem 1
  <span style="color: #ff79c6; font-weight: bold;">\item</span> &#205;tem 2
  <span style="color: #ff79c6; font-weight: bold;">\item</span> &#205;tem 3
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}

  Aqu&#237; se interrumpe la enumeraci&#243;n para dar alguna explicaci&#243;n,
  cuando lo retomamos ocurre lo siguiente, si no modificamos el valor
  del contador:

  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
  <span style="color: #ff79c6; font-weight: bold;">\item</span> &#205;tem 4
  <span style="color: #ff79c6; font-weight: bold;">\item</span> &#205;tem 5
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">minipage</span>}
<span style="color: #ff79c6;">\hfill</span>
<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">minipage</span>}[c]{0.45<span style="color: #ff79c6;">\linewidth</span>}
  Los motivos para hacer la enumeraci&#243;n puede ser los mismos que en el
  caso de aqu&#237; al lado:

  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
  <span style="color: #ff79c6; font-weight: bold;">\item</span> &#205;tem 1 
  <span style="color: #ff79c6; font-weight: bold;">\item</span> &#205;tem 2
  <span style="color: #ff79c6; font-weight: bold;">\item</span> &#205;tem 3
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}

  Y tambi&#233;n tenemos que interrumpir la enumeraci&#243;n, dando
  explicaciones, por el motivo que sea. Ahora bien, en este caso
  modificamos el valor del contador:

  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
    <span style="color: #ff79c6; font-weight: bold;">\setcounter</span>{<span style="color: #f8f8f2; font-weight: bold;">enumi</span>}{<span style="color: #f8f8f2; font-weight: bold;">3</span>}
  <span style="color: #ff79c6; font-weight: bold;">\item</span> &#205;tem 4
  <span style="color: #ff79c6; font-weight: bold;">\item</span> &#205;tem 5
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">minipage</span>}
</pre>
</div>

<p>
El resultado será el siguiente:
</p>


<figure id="org30e2a42">
<img src="./imagenes/Captura-pantalla_cambiar-contador.png" alt="Captura-pantalla_cambiar-contador.png">

</figure>

<p>
No te pierdas en el código, sólo he definido dos <code>minipáginas</code> para
poder mostrar el efecto de no modificar el contador (a la izquierda) y
de modificarlo (a la derecha). Como podemos ver en la imagen, la
enumeración de la derecha se retoma con el ítem 4, mientras que la de
la izquierda comienza a numerar de nuevo. Para hacerlo, si miramos el
segundo entorno <code>enumerate</code> de la segunda <code>minipage</code>, he utilizado el
comando <code>\setcounter</code>
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\setcounter</span>{<span style="color: #f8f8f2; font-weight: bold;">contador</span>}{<span style="color: #f8f8f2; font-weight: bold;">valor</span>}
</pre>
</div>

<p>
Donde,
</p>

<dl class="org-dl">
<dt><code>contador</code></dt><dd>Es el nombre del contador que queremos modificar.</dd>
<dt><code>valor</code></dt><dd>Es el <i>valor</i> que se quiere establecer.</dd>
</dl>

<p>
Hay que tener en cuenta, que cuando el entorno <code>enumerate</code> inicia su
contador lo hace puesto a <code>0</code> porque luego cada comando <code>\item</code> lo
actualiza. De esta manera es recomendable pensar, para no liarnos, que
debemos establecer el valor del contador a aquél que tenía cuando lo
interrumpimos.
</p>

<p>
Ahora bien, una cosa son los contadores y otra es cómo se visualizan
en el código. Pongo un ejemplo completo y después lo explicaré:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\subsection</span>{<span style="color: #f1fa8c; font-weight: bold;">Visualizaci&#243;n de contadores</span>}

Cambiar los valores por defecto de los contadores de enumeraci&#243;n:

<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
<span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">enumi</span>}
  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
  <span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">enumii</span>}
    <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
    <span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">enumiii</span>}
      <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
      <span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">enumiv</span>}
      <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
    <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}

<span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\theenumi</span>}{<span style="color: #ff79c6; font-weight: bold;">\Alph</span><span style="color: #50fa7b; font-weight: bold;">{</span><span style="color: #f8f8f2; font-weight: bold;">enumi</span><span style="color: #50fa7b; font-weight: bold;">}</span>}
<span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\labelenumi</span>}{<span style="color: #50fa7b; font-weight: bold;">({</span><span style="color: #50fa7b; font-weight: bold;">\theenumi</span><span style="color: #50fa7b; font-weight: bold;">})</span>}
<span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\theenumii</span>}{<span style="color: #ff79c6; font-weight: bold;">\alph</span><span style="color: #50fa7b; font-weight: bold;">{</span><span style="color: #f8f8f2; font-weight: bold;">enumii</span><span style="color: #50fa7b; font-weight: bold;">}</span>}
<span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\labelenumii</span>}{<span style="color: #50fa7b; font-weight: bold;">--{</span><span style="color: #50fa7b; font-weight: bold;">\theenumii</span><span style="color: #50fa7b; font-weight: bold;">}--</span>}
<span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\theenumiii</span>}{<span style="color: #ff79c6; font-weight: bold;">\Roman</span><span style="color: #50fa7b; font-weight: bold;">{</span><span style="color: #f8f8f2; font-weight: bold;">enumiii</span><span style="color: #50fa7b; font-weight: bold;">}</span>}
<span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\labelenumiii</span>}{<span style="color: #50fa7b; font-weight: bold;">{</span><span style="color: #50fa7b; font-weight: bold;">\theenumiii</span><span style="color: #50fa7b; font-weight: bold;">}:</span>}
<span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\theenumiv</span>}{<span style="color: #ff79c6; font-weight: bold;">\alph</span><span style="color: #50fa7b; font-weight: bold;">{</span><span style="color: #f8f8f2; font-weight: bold;">enumi</span><span style="color: #50fa7b; font-weight: bold;">}.</span><span style="color: #ff79c6; font-weight: bold;">\arabic</span><span style="color: #50fa7b; font-weight: bold;">{</span><span style="color: #f8f8f2; font-weight: bold;">enumii</span><span style="color: #50fa7b; font-weight: bold;">} -- </span><span style="color: #ff79c6; font-weight: bold;">\Alph</span><span style="color: #50fa7b; font-weight: bold;">{</span><span style="color: #f8f8f2; font-weight: bold;">enumiii</span><span style="color: #50fa7b; font-weight: bold;">}).</span><span style="color: #ff79c6; font-weight: bold;">\Roman</span><span style="color: #50fa7b; font-weight: bold;">{</span><span style="color: #f8f8f2; font-weight: bold;">enumiv</span><span style="color: #50fa7b; font-weight: bold;">}</span>}
<span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\labelenumiv</span>}{<span style="color: #50fa7b; font-weight: bold;">{</span><span style="color: #50fa7b; font-weight: bold;">\theenumiv</span><span style="color: #50fa7b; font-weight: bold;">}~</span><span style="color: #ffb86c; font-weight: bold;">$</span><span style="color: #ffb86c; font-weight: bold;">\bullet</span><span style="color: #ffb86c; font-weight: bold;">$</span>}

<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
<span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">enumi</span>}
  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
  <span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">enumii</span>}
    <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
    <span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">enumiii</span>}
      <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
      <span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">enumiv</span>}
        <span style="color: #ff79c6; font-weight: bold;">\renewcommand</span>{<span style="color: #50fa7b; font-weight: bold;">\theenumiv</span>}{<span style="color: #ff79c6; font-weight: bold;">\arabic</span><span style="color: #50fa7b; font-weight: bold;">{</span><span style="color: #f8f8f2; font-weight: bold;">enumi</span><span style="color: #50fa7b; font-weight: bold;">}.</span><span style="color: #ff79c6; font-weight: bold;">\arabic</span><span style="color: #50fa7b; font-weight: bold;">{</span><span style="color: #f8f8f2; font-weight: bold;">enumii</span><span style="color: #50fa7b; font-weight: bold;">}.</span><span style="color: #ff79c6; font-weight: bold;">\arabic</span><span style="color: #50fa7b; font-weight: bold;">{</span><span style="color: #f8f8f2; font-weight: bold;">enumiii</span><span style="color: #50fa7b; font-weight: bold;">}.</span><span style="color: #ff79c6; font-weight: bold;">\arabic</span><span style="color: #50fa7b; font-weight: bold;">{</span><span style="color: #f8f8f2; font-weight: bold;">enumiv</span><span style="color: #50fa7b; font-weight: bold;">}.</span>}
      <span style="color: #ff79c6; font-weight: bold;">\item</span> etiqueta cambiada sobre la marcha.
      <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
    <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
</pre>
</div>

<p>
Sí, podemos escribir comandos en cualquier sitio de nuestro
documento. Cuando lo hacemos en la cabecera, afectará a todo el
documento, mientras que si lo hacemos en otros lugares, afectará sólo
al contenido del documento que se encuentra tras él. Por tanto, en
cualquier sitio podemos utilizar un <code>\renewcommand</code>, como ilustra el
ejemplo anterior.
</p>

<p>
El resultado del código de ejemplo anterior en nuestro documento es el
siguiente:
</p>


<figure id="orgd137726">
<img src="./imagenes/Captura-pantalla_visualizar-contadores.png" alt="Captura-pantalla_visualizar-contadores.png">

</figure>

<p>
Como se puede apreciar utilizo el comando <code>\renewcommand</code>, porque
estoy modificando <i>instrucciones</i> que ya estaban definidas.  Además,
también hay que llamar la atención, que una cosa es el contador
(<code>enumi</code>), otra su representación (<code>theenumi</code>) y otra la etiqueta que
utilizamos en la enumeración (<code>labelenumi</code>). Y para rematar, también
contamos con varias formas de enumeración:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Comando</th>
<th scope="col" class="org-left">Tipo</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>\arabic</code></td>
<td class="org-left">Número normal</td>
</tr>

<tr>
<td class="org-left"><code>\Roman</code></td>
<td class="org-left">Número romano en mayúscula</td>
</tr>

<tr>
<td class="org-left"><code>\roman</code></td>
<td class="org-left">Número romano en minúscula</td>
</tr>

<tr>
<td class="org-left"><code>\Alph</code></td>
<td class="org-left">Letra mayúscula</td>
</tr>

<tr>
<td class="org-left"><code>\alph</code></td>
<td class="org-left">Letra minúscula</td>
</tr>
</tbody>
</table>

<p>
Para ilustrar cómo funcionan los distintos tipos de numeración de los
contadores he introducido una tabla en nuestro fichero de ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">table</span>}[ht]
  <span style="color: #ff79c6; font-weight: bold;">\centering</span>
  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">tabular</span>}{lr}
    {<span style="color: #ff79c6; font-weight: bold;">\bf</span><span style="color: #bd93f9;"> Formato</span>} <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6; font-weight: bold;">\bf</span><span style="color: #bd93f9;"> Resultado</span>}<span style="color: #ff5555;">\\</span>
    <span style="color: #ff79c6; font-weight: bold;">\hline</span>
    <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\arabic</span><span style="color: #ffb86c;">{section}|</span> <span style="color: #ff5555;">&amp;</span> <span style="color: #ff79c6; font-weight: bold;">\arabic</span>{<span style="color: #f8f8f2; font-weight: bold;">section</span>} <span style="color: #ff5555;">\\</span>
    <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\Roman</span><span style="color: #ffb86c;">{section}|</span>  <span style="color: #ff5555;">&amp;</span> <span style="color: #ff79c6; font-weight: bold;">\Roman</span>{<span style="color: #f8f8f2; font-weight: bold;">section</span>} <span style="color: #ff5555;">\\</span>
    <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\roman</span><span style="color: #ffb86c;">{section}|</span>  <span style="color: #ff5555;">&amp;</span> <span style="color: #ff79c6; font-weight: bold;">\roman</span>{<span style="color: #f8f8f2; font-weight: bold;">section</span>} <span style="color: #ff5555;">\\</span>
    <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\Alph</span><span style="color: #ffb86c;">{section}|</span>   <span style="color: #ff5555;">&amp;</span> <span style="color: #ff79c6; font-weight: bold;">\Alph</span>{<span style="color: #f8f8f2; font-weight: bold;">section</span>} <span style="color: #ff5555;">\\</span>
    <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\alph</span><span style="color: #ffb86c;">{section}|</span>   <span style="color: #ff5555;">&amp;</span> <span style="color: #ff79c6; font-weight: bold;">\alph</span>{<span style="color: #f8f8f2; font-weight: bold;">section</span>} <span style="color: #ff5555;">\\</span>
    <span style="color: #ff79c6; font-weight: bold;">\hline</span>
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">tabular</span>}
  <span style="color: #ff79c6; font-weight: bold;">\caption</span>{<span style="color: #8be9fd; font-style: italic;">Tipos de numeraci&#243;n</span>}
  <span style="color: #ff79c6; font-weight: bold;">\label</span>{<span style="color: #bd93f9;">tab:tipos-numeracion</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">table</span>}
</pre>
</div>

<p>
El resultado es el siguiente:
</p>


<figure id="orgec0bb4f">
<img src="./imagenes/Captura-pantalla_tabla-numeracion.png" alt="Captura-pantalla_tabla-numeracion.png">

</figure>
</div>
</div>
<div id="outline-container-org0c8ce24" class="outline-2">
<h2 id="org0c8ce24">Conclusión</h2>
<div class="outline-text-2" id="text-org0c8ce24">
<p>
Para acabar el minicurso nos queda hablar de crear nuestro primer
archivo de estilos <i>LaTeX</i>. Una vez que hemos visto cómo podemos
definir y redefinir comandos y entornos, la tarea será fácil. El
fichero <code>.sty</code> que crearemos será sencillo, importará algunos estilos
externos y los modificará con los comandos que ya hemos visto.
Introduciré algún comando nuevo y presentaré algún paquete útil para
afinar en el aspecto de nuestros documentos. Con todo esto, creo que
nuestro <i>minicurso</i> llegará a su fin. No te pierdas la última
entrega.
</p>

<p>
Recuerda que nuestro fichero de ejemplo ha ido creciendo poco a poco y
que podéis descargarlo con las últimas modificaciones
<a href="imagenes/texto-prueba.tex">de este enlace</a>. A su vez, también puedes <a href="imagenes/texto-prueba.pdf">descargar el <code>pdf</code> generado</a>.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/latex/index.html">latex</a> ]]></description>
  <category><![CDATA[latex]]></category>
  <link>https://notxor.nueva-actitud.org/2021/04/10/minicurso-de-latex-para-psicologos-v.html</link>
  <pubDate>Sat, 10 Apr 2021 11:10:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Minicurso de LaTeX para psicólogos IV]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-04-02</div>
<p>
En este artículo, del <i>minicurso</i> de <i>LaTeX</i> voy a hablar de dos
cosas: <i>espaciado</i> y <i>entornos flotantes</i>. Sobre cómo separar
elementos y rellenar el espacio entre ellos, como me habéis preguntado
algunos y era momento de explicarlo un poco más. Y por supuesto, otra
de las funcionalidades imprescindibles para realizar un buen
documento: la inclusión de imágenes y tablas, que es la parte sobre
<i>entornos flotantes</i>. Hay que recordar que una de las primeras cosas
que llaman la atención a quien se acerca a <i>LaTeX</i> por primera vez es
que el sistema coloca, tanto tablas como figuras <i>donde quiere</i>. No es
exactamente así, pero puede dar esa impresión. Utilizaré algunos
paquetes que nos permiten tener más precisión a la hora de manejarse
con las figuras y tablas.
</p>
<div id="outline-container-orgbe6ec88" class="outline-2">
<h2 id="orgbe6ec88">Relleno, espacio y desplazamiento</h2>
<div class="outline-text-2" id="text-orgbe6ec88">
<p>
Por empezar por lo más fácil, vamos con las <i>unidades de medida</i>.  Las
principales son las siguientes, aunque hay más:
</p>

<ul class="org-ul">
<li><code>cm</code> Centímetros.</li>
<li><code>mm</code> Milímetros.</li>
<li><code>in</code> Pulgadas: <i>inch</i> en inglés.</li>
<li><code>pt</code> Puntos: cada punto es \(1 \over 72\) de pulgada.</li>
<li><code>em</code> Es una medida relativa al tamaño de una <i>M</i> mayúscula en la
fuente utilizada, con su tamaño definido, por lo que depende de qué
letra estemos usando.</li>
<li><code>ex</code> Como la anterior, es una medida relativa pero referida al
tamaño de una <i>x</i> minúscula.</li>
</ul>

<p>
Cualquiera de esas unidades es aceptado en cualquier instrucción que
necesite medidas. Yo tengo la costumbre de utilizar los centímetros
siempre que puedo, pero no pasa nada por utilizar otro sistema o
incluso mezclarlos. Por higiene mental suelo mantener la unidad de
medida en todos los lugares del documento, porque así me permite ver
de golpe las dimensiones a las que me refiero sin estar convirtiendo
entre ellas. Pero también hay que recordar que en algunas ocasiones
será más productivo el utilizar medidas relativas, así al cambiar la
fuente o el tamaño de la misma, los objetos se visualizarán
correctamente y mantendrán las proporciones.
</p>

<p>
Para hablar del resto de los aspectos, prefiero poner un ejemplo y
luego explico los detalles del <i>espaciado</i>.
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\section</span>{<span style="color: #50fa7b; font-size: 110%; font-weight: bold;">Unidades de medida, relleno y desplazamiento</span>}

Ejemplo de rellenos:

<span style="color: #ff79c6; font-weight: bold;">\noindent</span> A <span style="color: #ff79c6;">\hfill</span> B <span style="color: #ff79c6;">\hfill</span> C

<span style="color: #ff79c6; font-weight: bold;">\vspace</span>{<span style="color: #50fa7b; font-weight: bold;">1.5cm</span>}
<span style="color: #ff79c6; font-weight: bold;">\noindent</span> A <span style="color: #ff79c6;">\dotfill</span> B <span style="color: #ff79c6;">\dotfill</span> C

<span style="color: #ff79c6; font-weight: bold;">\noindent</span> A \, <span style="color: #ff79c6;">\dotfill</span> \, B \, <span style="color: #ff79c6;">\dotfill</span> \, C

<span style="color: #ff79c6; font-weight: bold;">\noindent</span> A <span style="color: #ff79c6; font-weight: bold;">\quad</span><span style="color: #ff79c6;">\dotfill</span><span style="color: #ff79c6; font-weight: bold;">\quad</span> B <span style="color: #ff79c6; font-weight: bold;">\quad</span><span style="color: #ff79c6;">\dotfill</span><span style="color: #ff79c6; font-weight: bold;">\quad</span> C

<span style="color: #ff79c6; font-weight: bold;">\vspace</span>{<span style="color: #50fa7b; font-weight: bold;">1.5cm</span>}
<span style="color: #ff79c6; font-weight: bold;">\noindent</span> A <span style="color: #ff79c6;">\hrulefill</span> B <span style="color: #ff79c6;">\hrulefill</span> C <span style="color: #ff79c6; font-weight: bold;">\par</span>
<span style="color: #ff79c6; font-weight: bold;">\noindent</span> A~<span style="color: #ff79c6;">\hrulefill</span>~B~<span style="color: #ff79c6;">\hrulefill</span>~C <span style="color: #ff79c6; font-weight: bold;">\par</span>
<span style="color: #ff79c6; font-weight: bold;">\noindent</span> A <span style="color: #ff79c6; font-weight: bold;">\qquad</span><span style="color: #ff79c6;">\hrulefill</span><span style="color: #ff79c6; font-weight: bold;">\qquad</span> B <span style="color: #ff79c6; font-weight: bold;">\qquad</span><span style="color: #ff79c6;">\hrulefill</span><span style="color: #ff79c6; font-weight: bold;">\qquad</span> C

<span style="color: #ff79c6; font-weight: bold;">\vspace</span>{<span style="color: #50fa7b; font-weight: bold;">1cm</span>}
<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">center</span>}
  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">minipage</span>}[t]{0.5<span style="color: #ff79c6;">\linewidth</span>}
    <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">verse</span>}
      Con diez ca&#241;ones por banda,<span style="color: #ff5555;">\\</span>
      <span style="color: #ff79c6; font-weight: bold;">\hspace</span>{<span style="color: #50fa7b; font-weight: bold;">1em</span>}viento en popa, a toda vela<span style="color: #ff5555;">\\</span>
      no corta el mar, sino vuela<span style="color: #ff5555;">\\</span>
      <span style="color: #ff79c6; font-weight: bold;">\hspace</span>{<span style="color: #50fa7b; font-weight: bold;">1em</span>}un velero bergant&#237;n<span style="color: #ff5555;">\\</span>[1em]
      Bajel pirata que llaman<span style="color: #ff5555;">\\</span>
      <span style="color: #ff79c6; font-weight: bold;">\hspace</span>{<span style="color: #50fa7b; font-weight: bold;">1em</span>}por su bravura el temido<span style="color: #ff5555;">\\</span>
      en todo mar conocido<span style="color: #ff5555;">\\</span>
      <span style="color: #ff79c6; font-weight: bold;">\hspace</span>{<span style="color: #50fa7b; font-weight: bold;">1em</span>}del uno al otro conf&#237;n<span style="color: #ff5555;">\\</span>[1em]
      (...)
    <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">verse</span>}
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">minipage</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">center</span>}

Con esto cubrimos el tema de los espacios en general.
</pre>
</div>

<p>
El resultado de lo anterior se visualiza así:
</p>


<figure id="org9215923">
<img src="./imagenes/Captura-pantalla_espacios-rellenos.png" alt="Captura-pantalla_espacios-rellenos.png">

</figure>

<p>
Hasta ahora no lo he dicho, porque me parecía obvio que para
distinguir entre párrafos había que dejar una línea en blanco entre
ellos. Pero por las preguntas que he recibido, no era tan obvio como
yo pensaba.  Es bastante sencillo ese comando de espaciado, aunque
también lo podemos formar con el comando <code>\par</code>. Además se puede
observar que al escribir un párrafo <i>LaTeX</i> produce una <i>sangría</i> en
la primera línea y lo ajusta al espacio disponible.
</p>

<p>
Veamos los diversos comandos empleados en el pequeño ejemplo anterior:
</p>

<dl class="org-dl">
<dt><code>\noindent</code></dt><dd>Elimina la sangría de la primera línea del párrafo y
utiliza, por tanto, todo el <code>\textwidth</code> disponible.</dd>
<dt><code>\hfill</code></dt><dd>Rellena con espacio en blanco en horizontal. En la
primera línea vemos que los elementos <code>A</code>, <code>B</code> y <code>C</code> se distribuyen
en todo el ancho dejando en blanco el hueco entre ellos. También
tiene un equivalente <code>\vfill</code> para rellenar con espacio vertical.</dd>
<dt><code>\vspace</code> y <code>\hspace</code></dt><dd>Proporcionan espacio <i>vertical</i> y
<i>horizontal</i> respectivamente. Necesita un parámetro que indique
cuánto espacio hay que dejar.</dd>
<dt><code>\dotfill</code> y <code>\hrulefill</code></dt><dd>Equivalentes a <code>\hfill</code> pero rellenan el
espacio con una línea de puntos o con una línea sólida,
respectivamente.</dd>
<dt><code>\,</code></dt><dd>Proporciona un espacio horizontal que equivale a <code>0.25em</code>.
Se suele emplear cuando dos elementos quedan demasiado juntos y
queremos un ligera separación visual. En modo matemático también
existe otro comando <code>\;</code> que proporciona una separación equivalente
a <code>0.5em</code>, pero no funciona fuera de fórmulas matemáticas.</dd>
<dt><code>\quad</code> y <code>\qquad</code></dt><dd>Proporcionan espacio horizontal que equivale a
<code>1em</code> y <code>2em</code> respectivamente.</dd>
<dt><code>\par</code></dt><dd>Produce un salto de párrafo. Se utiliza en aquellas
ocasiones en que en el texto no podemos introducir una línea en
blanco pero queremos que se muestre un cambio de párrafo. Por
ejemplo, lo utilizaremos para escribir párrafos dentro de la celda
de una tabla.</dd>
<dt><code>~</code></dt><dd>No proporciona espacio extra, es simplemente un <i>espacio</i>. La
peculiaridad es que es un <i>espacio inseparable</i>. Se utiliza,
normalmente, cuando quieres utilizar algunas de las expresiones que
suelen visualizarse mejor cuando van juntas, par que no se separen
por un salto de línea. Por ejemplo, es habitual escribirlo para
mantener juntos elementos como <code>Sr.~D.</code> o <code>D.N.I.~nº</code>.</dd>
<dt><code>\\</code></dt><dd>Es un salto de línea. Además puede llevar aparejado un
parámetro de distancia. Como se puede apreciar en <i>la poesía</i> del
ejemplo, la separación visual entre estrofas se logra añadiendo un
pequeño salto de <code>1em</code> en la última línea de cada una.</dd>
</dl>

<p>
Por último, he añadido la poesía utilizando una <i>minipágina</i>. Como se
puede apreciar podemos alinear la <i>minipágina</i>, ─no su contenido─, de
manera independiente. Es decir, he centrado la <i>minipágina</i> en el
ancho de página necesario, pero su contenido continúa con sus propias
reglas alineándose de manera independiente, para ilustrar que se
pueden crear <i>cuadros</i> que podemos colocar en nuestra hoja de manera
independiente al flujo general del texto. Esto lo podemos aprovechar
aún más con los <i>elementos flotantes</i> que vamos a ver ahora.
</p>

<p>
A estas alturas ya te habrás dado cuenta de que da igual cuántos
espacios en blanco, o cuántos retornos de carro separen los objetos.
La separación entre palabras o entre párrafos será la misma con uno o
con 30 espacios, o con una o con 30 líneas. Por lo tanto, podemos
utilizar esos espacios para facilitarnos la visualización del
documento, porque al final, <i>LaTeX</i> los ajustaría como si no
existieran.
</p>
</div>
</div>
<div id="outline-container-orgd0f9aac" class="outline-2">
<h2 id="orgd0f9aac">Elementos flotantes</h2>
<div class="outline-text-2" id="text-orgd0f9aac">
<p>
Las imágenes y las tablas son elementos imprescindibles para escribir
documentación psicológica o de cualquier tipo. Especialmente si son
<i>papers</i> de investigación, donde se deben mostrar ordenadamente
estadísticas y gráficos. Comenzaré por la más compleja, que es hacer
tablas. Tampoco voy a entrar en demasiadas florituras, como modificar
los colores de las celdas y las líneas, para eso hay paquetes y
documentación por <i>Internet</i> suficiente como para que lo investigues
por tu cuenta. Pero sí interesa que entiendas los conceptos básicos
desde el principio y lo demás es aplicar comandos.
</p>
</div>
<div id="outline-container-org1078086" class="outline-3">
<h3 id="org1078086">Tablas</h3>
<div class="outline-text-3" id="text-org1078086">
<p>
Antes de nada no hay que confundir el entorno <code>table</code> con el entorno
<code>tabular</code>. El primero, <code>table</code> es el <i>marco flotante</i>, con su título y
demás características, del entorno <code>tabular</code> que contiene. Por tanto,
el entorno <code>tabular</code> define las filas y columnas que se situarán en
nuestra página donde <code>table</code> decida, que no tiene por qué ser justo
donde nosotros la hemos puesto en nuestro texto.
</p>
</div>
<div id="outline-container-org9b84f60" class="outline-4">
<h4 id="org9b84f60">El entorno <code>table</code></h4>
<div class="outline-text-4" id="text-org9b84f60">
<p>
Cuando definimos una <i>tabla</i> o <i>cuadro</i>, <i>LaTeX</i> reserva espacio para
ella e intenta situarla de manera que quede acoplada junta sin
interponer saltos de páginas y que no interfiera con el resto del
texto. Por esto, es muy habitual que la tabla no se dibuje justo donde
nosotros la introdujimos y aparezca en otro lugar. El entorno se
definirá tal que así:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">table</span>}[posici&#243;n]
  <span style="color: #ff79c6; font-weight: bold;">\caption</span>{<span style="color: #8be9fd; font-style: italic;">El t&#237;tulo o /caption/ de la tabla</span>}<span style="color: #ff79c6; font-weight: bold;">\label</span>{<span style="color: #bd93f9;">tab:mi-tabla</span>}
  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">tabular</span>}
    (...)
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">tabular</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">table</span>}
</pre>
</div>

<p>
Como parámetro a <code>table</code> tenemos que expresar en qué posición la
queremos mediante un parámetro. Ese parámetro está compuesto de
algunas letras con cierto significado y en ocasiones un signo <code>!</code>.  Lo
bueno, es que el significado de dichas iniciales, son consistentes a
lo largo de todos los entornos y paquetes que utilicemos. Veamos el
significado de esas letras:
</p>

<dl class="org-dl">
<dt><code>h</code></dt><dd>Indica que ponga la tabla <i>aquí</i> (<i>here</i>), justo en la
posición del texto donde nosotros la hemos puesto.</dd>
<dt><code>t</code></dt><dd>Indica que se ponga la tabla al principio (<i>top</i>) de una
página.  Normalmente esa página será la siguiente, a no ser que ya
esté ocupada con otro flotante.</dd>
<dt><code>b</code></dt><dd>Indica que reserve espacio al final (<i>bottom</i>) de la página.
Será normalmente la página que está produciéndose, a no ser que ya
esté ocupado el espacio por otro flotante o no quepa la tabla en el
espacio restante de la página, por lo que se pasará a la siguiente.</dd>
<dt><code>p</code></dt><dd>Indica a <i>LaTeX</i> que reserve una página completa para la
tabla. Normalmente se reservará la siguiente página.</dd>
<dt><code>!</code></dt><dd>Enfatiza que se debe hacer todo lo posible por obedecer el
parámetro de posición.</dd>
</dl>

<p>
Podemos observar que <i>LaTeX</i> trabaja creando espacios donde colocar
los elementos que le vamos proporcionando. Normalmente sus decisiones
de diseño son mejores que las nuestras. Podemos <i>forzarlo</i> un poquito
indicándole que nos ponga la tabla <i>aquí y que es importante</i> con el
parámetro <code>[h!]</code>. Aunque una vez te acostumbras a su modo de colocar
los elementos <i>flotantes</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> lo habitual es que utilicemos un valor
tal que <code>[htp]</code>. Es decir: coloca el flotante aquí, si no cabe hazle
hueco en el principio de la siguiente página y si tampoco cabe,
reserva una página entera.
</p>
</div>
</div>
<div id="outline-container-orgbb83ede" class="outline-4">
<h4 id="orgbb83ede">El entorno <code>tabular</code></h4>
<div class="outline-text-4" id="text-orgbb83ede">
<p>
El entorno habitual se utiliza para definir una tabla propiamente
dicha. Igual que con <code>table</code> podemos definir su posición. Porque si no
necesitamos numerar la tabla con su correspondiente título o
explicación al pie podemos obviar el entorno <code>table</code> que lo envuelve.
Si no necesitamos esos adornos, como digo, podemos crear una tabla en
cualquier lugar utilizando sólo el entorno <code>tabular</code>. Por poner un
ejemplo sencillo, dibujo una tabla con cuatro columnas:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\section</span>{<span style="color: #50fa7b; font-size: 110%; font-weight: bold;">Entornos flotantes</span>}
<span style="color: #ff79c6; font-weight: bold;">\subsection</span>{<span style="color: #f1fa8c; font-weight: bold;">Tablas</span>}

La forma m&#225;s sencilla de tabla es definir tantas filas y columnas como
se necesiten. Por ejemplo podemos verlo en la tabla <span style="color: #ff79c6; font-weight: bold;">\ref</span>{<span style="color: #bd93f9;">tab:sencilla</span>}.

<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">table</span>}[h!t]
  <span style="color: #ff79c6; font-weight: bold;">\centering</span>
  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">tabular</span>}{lcrp{3cm}}
    {<span style="color: #ff79c6; font-weight: bold;">\bf</span><span style="color: #bd93f9;"> Nombre</span>} <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6; font-weight: bold;">\bf</span><span style="color: #bd93f9;"> Apellidos</span>} <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6; font-weight: bold;">\bf</span><span style="color: #bd93f9;"> Edad</span>} <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6; font-weight: bold;">\bf</span><span style="color: #bd93f9;"> Observaciones</span>} <span style="color: #ff5555;">\\</span>
    <span style="color: #ff79c6; font-weight: bold;">\hline</span>
    Fulanito     <span style="color: #ff5555;">&amp;</span> de Tal y Tal    <span style="color: #ff5555;">&amp;</span> 27         <span style="color: #ff5555;">&amp;</span> Esto es un p&#225;rrafo largo que
                                                  puede ocupar varias lineas.<span style="color: #ff79c6; font-weight: bold;">\par</span>
                                                  O incluso varios p&#225;rrafos de alto.<span style="color: #ff5555;">\\</span>
    <span style="color: #ff79c6; font-weight: bold;">\hline</span>
    Menganito    <span style="color: #ff5555;">&amp;</span> de Tal y Pascual <span style="color: #ff5555;">&amp;</span> 15        <span style="color: #ff5555;">&amp;</span>  <span style="color: #ff5555;">\\</span>
    <span style="color: #ff79c6; font-weight: bold;">\hline</span>
    Paco         <span style="color: #ff5555;">&amp;</span> P&#233;rez P&#233;rez      <span style="color: #ff5555;">&amp;</span> 21        <span style="color: #ff5555;">&amp;</span> S&#243;lo es un texto de prueba largo
                                                  para ver c&#243;mo lo alinea <span style="color: #ff79c6; font-weight: bold;">\LaTeX</span>.<span style="color: #ff79c6; font-weight: bold;">\par</span>
                                                  No est&#225;s obligado a rellenar todos
                                                  los huecos. <span style="color: #ff5555;">\\</span>
    <span style="color: #ff79c6; font-weight: bold;">\hline</span>
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">tabular</span>}
  <span style="color: #ff79c6; font-weight: bold;">\caption</span>{<span style="color: #8be9fd; font-style: italic;">Tabla sencilla</span>}<span style="color: #ff79c6; font-weight: bold;">\label</span>{<span style="color: #bd93f9;">tab:sencilla</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">table</span>}
</pre>
</div>

<p>
Al añadir el código anterior veremos que se ha alcanzado casi el final
de la página y la tabla no cabe en ella. En nuestro lector veremos que
se muestra así:
</p>


<figure id="org6e0b8a6">
<img src="./imagenes/Captura-pantalla_tabla-sencilla.png" alt="Captura-pantalla_tabla-sencilla.png">

</figure>

<p>
Como vemos, la tabla se mostrará en la siguiente página, y como no hay
ningún contenido posterior a ella, la mostrará centrada en ella. Pero
vamos a analizar los detalles del entorno <code>tabular</code>.
</p>

<ul class="org-ul">
<li><code>\centering</code>: Indica a <i>LaTeX</i> que centre la tabla en el espacio
horizontal disponible.</li>
<li><code>{lcrp{3cm}}</code>: Especifica la alineación de las columnas. Podemos
observar que hay cuatro:
<dl class="org-dl">
<dt><code>l</code></dt><dd>La primera columna estará alineada a la izquierda (<i>left</i>).</dd>
<dt><code>c</code></dt><dd>La segunda columna estará centrada.</dd>
<dt><code>r</code></dt><dd>La tercera columna estará alineada a la derecha (<i>right</i>).</dd>
<dt><code>p{3cm}</code></dt><dd>La cuarta columna es de tipo <i>párrafo</i> y solicitamos
que nos proporciones un ancho de <code>3cm</code>.</dd>
</dl></li>
<li>Separadores de celdas: el carácter <code>&amp;</code> separa las columnas dentro de
una fila y las filas se separan con <code>\\</code>.</li>
</ul>

<p>
Después del código anterior he añadido a nuestro documento de pruebas
el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-latex">La tabla <span style="color: #ff79c6; font-weight: bold;">\ref</span>{<span style="color: #bd93f9;">tab:sencilla</span>} ser&#237;a a&#250;n m&#225;s sencilla de ver si
eliminamos la columna de observaciones tontas. Y generamos la tabla,
a&#250;n m&#225;s sencilla <span style="color: #ff79c6; font-weight: bold;">\ref</span>{<span style="color: #bd93f9;">tab:aun-mas-sencilla</span>}.

<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">table</span>}[h!t]
  <span style="color: #ff79c6; font-weight: bold;">\centering</span>
  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">tabular</span>}{llr}
    {<span style="color: #ff79c6; font-weight: bold;">\bf</span><span style="color: #bd93f9;"> Nombre</span>} <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6; font-weight: bold;">\bf</span><span style="color: #bd93f9;"> Apellidos</span>}  <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6; font-weight: bold;">\bf</span><span style="color: #bd93f9;"> Edad</span>} <span style="color: #ff5555;">\\</span>
    <span style="color: #ff79c6; font-weight: bold;">\hline</span>
    Fulanito     <span style="color: #ff5555;">&amp;</span> de Tal y Tal     <span style="color: #ff5555;">&amp;</span> 27         <span style="color: #ff5555;">\\</span>
    Menganito    <span style="color: #ff5555;">&amp;</span> de Tal y Pascual <span style="color: #ff5555;">&amp;</span> 15         <span style="color: #ff5555;">\\</span>
    Paco         <span style="color: #ff5555;">&amp;</span> P&#233;rez P&#233;rez      <span style="color: #ff5555;">&amp;</span> 21         <span style="color: #ff5555;">\\</span>
    <span style="color: #ff79c6; font-weight: bold;">\hline</span>
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">tabular</span>}
  <span style="color: #ff79c6; font-weight: bold;">\caption</span>{<span style="color: #8be9fd; font-style: italic;">Tabla a&#250;n m&#225;s sencilla</span>}
  <span style="color: #ff79c6; font-weight: bold;">\label</span>{<span style="color: #bd93f9;">tab:aun-mas-sencilla</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">table</span>}
</pre>
</div>

<p>
El resultado es:
</p>


<figure id="org39e53f9">
<img src="./imagenes/Captura-pantalla_tabla-aun-mas-sencilla.png" alt="Captura-pantalla_tabla-aun-mas-sencilla.png">

</figure>

<p>
Podemos observar, que aunque tampoco cabe esta tabla más sencilla en
el espacio del final de la página, se añade a la página siguiente como
antes. Pero como, efectivamente, sí cabe el texto previo, y éste se
añadirá al final de la página hasta completar el espacio.
</p>

<p>
También se pueden hacer tablas más complejas que tengan celdas que
ocupan más de una fila o una columna. Para que ocupen varias columnas
no hace falta añadir nada, sólo utilizar el comando <code>\multicolumn</code> con
el siguiente formato:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\multicolumn</span>{<span style="color: #50fa7b; font-weight: bold;">n&#186; columnas</span>}{<span style="color: #50fa7b; font-weight: bold;">alineaci&#243;n</span>}{<span style="color: #50fa7b; font-weight: bold;">texto</span>}
</pre>
</div>

<p>
Sin embargo, para hacer que las celdas se expandan por varias filas,
necesitaremos incluir el paquete <code>multirow</code> con el habitual:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>{<span style="color: #50fa7b; font-weight: bold;">multirow</span>}
</pre>
</div>

<p>
Posteriormente lo llamaremos con la siguiente sintaxis:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6;">\multirow</span>[pos-v]{filas}{ancho}[ajuste]{texto}
</pre>
</div>

<p>
Donde:
</p>

<ul class="org-ul">
<li><code>pos-v</code>: indica la alineación de la celda. <code>[t]</code> para arriba (<i>top</i>),
<code>[c]</code> para centrar y <code>[b]</code> para abajo (<i>bottom</i>).</li>
<li><code>filas</code>: indica el número de filas en el que se expandirá. Si tiene
un número negativo indica que se expandirá hacia arriba \(1-filas\)
líneas de la tabla.</li>
<li><code>ancho</code>: indica el ancho de la columna. Hay dos valores genéricos
muy utilizados que son <code>*</code> para que el ancho de la columna se ajuste
al ancho más natural, y <code>=</code> que indica que se utilice el ancho
especificado para la columna.</li>
<li><code>ajuste</code>: es un ajuste fino para situar mejor el texto, añadiendo un
poco de espacio mínimo cuando hay bastantes filas. Si el valor es
negativo se cuenta el espacio debajo.</li>
<li><code>texto</code>: es el contenido de la celda.</li>
</ul>

<p>
Para ver como funciona de una manera más práctica, he añadido a
nuestro documento de pruebas una tabla más compleja con el siguiente
texto:
</p>

<div class="org-src-container">
<pre class="src src-latex">Sin embargo, la vida no siempre permite hacer las cosas tan sencillas
y hay tablas que se nos complican. Como por ejemplo la tabla <span style="color: #ff79c6; font-weight: bold;">\ref</span>{<span style="color: #bd93f9;">tab:compleja</span>}.

<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">table</span>}[h!t]
  <span style="color: #ff79c6; font-weight: bold;">\centering</span>
  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">tabular</span>}{|l|l|r|r|r|r|}
    <span style="color: #ff79c6; font-weight: bold;">\hline</span>
    <span style="color: #ff79c6;">\multirow</span>[c]{2}{*}[-3mm]{Localidad} <span style="color: #ff5555;">&amp;</span> <span style="color: #ff79c6;">\multirow</span>[c]{2}{*}[-3mm]{Centro educativo} <span style="color: #ff5555;">&amp;</span> <span style="color: #ff79c6; font-weight: bold;">\multicolumn</span>{<span style="color: #50fa7b; font-weight: bold;">4</span>}{<span style="color: #50fa7b; font-weight: bold;">c</span>}{<span style="color: #50fa7b; font-weight: bold;">M&#233;todo</span>} <span style="color: #ff79c6;">\vline</span> <span style="color: #ff5555;">\\</span> <span style="color: #ff79c6; font-weight: bold;">\cline</span>{<span style="color: #50fa7b; font-weight: bold;">3-6</span>}
                                 <span style="color: #ff5555;">&amp;</span> <span style="color: #ff5555;">&amp;</span> <span style="color: #ff79c6; font-weight: bold;">\multicolumn</span>{<span style="color: #50fa7b; font-weight: bold;">2</span>}{<span style="color: #50fa7b; font-weight: bold;">c</span>}{<span style="color: #50fa7b; font-weight: bold;">I</span>} <span style="color: #ff79c6;">\vline</span> <span style="color: #ff5555;">&amp;</span> <span style="color: #ff79c6; font-weight: bold;">\multicolumn</span>{<span style="color: #50fa7b; font-weight: bold;">2</span>}{<span style="color: #50fa7b; font-weight: bold;">c</span>}{<span style="color: #50fa7b; font-weight: bold;">II</span>} <span style="color: #ff79c6;">\vline</span> <span style="color: #ff5555;">\\</span> <span style="color: #ff79c6; font-weight: bold;">\cline</span>{<span style="color: #50fa7b; font-weight: bold;">3-6</span>}
                                 <span style="color: #ff5555;">&amp;</span>                   <span style="color: #ff5555;">&amp;</span> V    <span style="color: #ff5555;">&amp;</span> M    <span style="color: #ff5555;">&amp;</span> V    <span style="color: #ff5555;">&amp;</span> M    <span style="color: #ff5555;">\\</span> <span style="color: #ff79c6; font-weight: bold;">\hline</span>
    <span style="color: #ff79c6; font-weight: bold;">\hline</span>
    <span style="color: #ff79c6;">\multirow</span>[c]{2}{*}{Zaragoza} <span style="color: #ff5555;">&amp;</span> IES Arrabal       <span style="color: #ff5555;">&amp;</span> 2,56 <span style="color: #ff5555;">&amp;</span> 2,85 <span style="color: #ff5555;">&amp;</span> 3,31 <span style="color: #ff5555;">&amp;</span> 3,01 <span style="color: #ff5555;">\\</span> <span style="color: #ff79c6; font-weight: bold;">\cline</span>{<span style="color: #50fa7b; font-weight: bold;">2-6</span>}
                                 <span style="color: #ff5555;">&amp;</span> IES Ram&#243;n y Cajal <span style="color: #ff5555;">&amp;</span> 2,35 <span style="color: #ff5555;">&amp;</span> 2,40 <span style="color: #ff5555;">&amp;</span> 3,01 <span style="color: #ff5555;">&amp;</span> 2,89 <span style="color: #ff5555;">\\</span>
    <span style="color: #ff79c6; font-weight: bold;">\hline</span>
    <span style="color: #ff79c6;">\multirow</span>[c]{2}{*}{Huesca}   <span style="color: #ff5555;">&amp;</span> IES Coso alto     <span style="color: #ff5555;">&amp;</span> 3,33 <span style="color: #ff5555;">&amp;</span> 3,52 <span style="color: #ff5555;">&amp;</span> 4,00 <span style="color: #ff5555;">&amp;</span> 3,72 <span style="color: #ff5555;">\\</span> <span style="color: #ff79c6; font-weight: bold;">\cline</span>{<span style="color: #50fa7b; font-weight: bold;">2-6</span>}
                                 <span style="color: #ff5555;">&amp;</span> IES Front&#243;n       <span style="color: #ff5555;">&amp;</span> 3,20 <span style="color: #ff5555;">&amp;</span> 3,32 <span style="color: #ff5555;">&amp;</span> 3,95 <span style="color: #ff5555;">&amp;</span> 3,70 <span style="color: #ff5555;">\\</span>
    <span style="color: #ff79c6; font-weight: bold;">\hline</span>
    <span style="color: #ff79c6;">\multirow</span>[c]{2}{*}{Teruel}   <span style="color: #ff5555;">&amp;</span> IES Amantes       <span style="color: #ff5555;">&amp;</span> 3,22 <span style="color: #ff5555;">&amp;</span> 3,51 <span style="color: #ff5555;">&amp;</span> 3,97 <span style="color: #ff5555;">&amp;</span> 3,61 <span style="color: #ff5555;">\\</span> <span style="color: #ff79c6; font-weight: bold;">\cline</span>{<span style="color: #50fa7b; font-weight: bold;">2-6</span>}
                                 <span style="color: #ff5555;">&amp;</span> IES Viaducto      <span style="color: #ff5555;">&amp;</span> 3,10 <span style="color: #ff5555;">&amp;</span> 3,35 <span style="color: #ff5555;">&amp;</span> 3,55 <span style="color: #ff5555;">&amp;</span> 3,35 <span style="color: #ff5555;">\\</span>
    <span style="color: #ff79c6; font-weight: bold;">\hline</span>
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">tabular</span>}
  <span style="color: #ff79c6; font-weight: bold;">\caption</span>{<span style="color: #8be9fd; font-style: italic;">Ejemplo de una tabla con l&#237;neas y columnas m&#250;ltiples.</span>}<span style="color: #ff79c6; font-weight: bold;">\label</span>{<span style="color: #bd93f9;">tab:compleja</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">table</span>}
</pre>
</div>

<p>
Además de lo que son las celdas múltiples vemos otras características
que quiero destacar. Por ejemplo, la forma de poner las líneas entre
las columnas, utilizando el carácter <code>|</code> en la definición de las
mismas:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">tabular</span>}{|l|l|r|r|r|r|r|}
  (...)
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">tabular</span>}
</pre>
</div>

<p>
Sin embargo, cuando se utiliza el comando <code>\multicolumn</code> se pierden
las posiciones de esa columna y podemos perder la línea vertical, por
eso, en algunos sitios, tras el comando <code>\multicolumn</code> aparece un
comando <code>\vline</code>, que dibuja dicha línea vertical del mismo modo que
<code>\hline</code> dibuja la horizontal. También, al utilizar <code>\multirow</code>, no
necesitamos toda la línea dibujada con <code>hline</code> y lo que se utiliza es
un comando <code>\cline</code> que especifica a qué columnas hay que dibujarle la
separación.
</p>

<p>
El resultado es el siguiente:
</p>


<figure id="org9418540">
<img src="./imagenes/Captura-pantalla_tabla-compleja.png" alt="Captura-pantalla_tabla-compleja.png">

</figure>

<p>
Como hemos visto, se separan las columnas con el carácter <code>|</code>, sin
embargo, podemos utilizar cualquier carácter. Por ejemplo, un uso
bastante habitual es utilizar, para números decimales. Para definir el
separador, empleo la sintaxis <code>@{'}</code>. Vamos al ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-latex">En la tabla <span style="color: #ff79c6; font-weight: bold;">\ref</span>{<span style="color: #bd93f9;">tab:coma</span>} podemos observar un ejemplo del uso de los
separadores entre columnas para alinear n&#250;mero por la coma. Algo que
puede llamar la atenci&#243;n a la los nuevos usuarios de <span style="color: #ff79c6; font-weight: bold;">\LaTeX</span>.

<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">table</span>}[h!t]
  <span style="color: #ff79c6; font-weight: bold;">\centering</span>
  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">tabular</span>}{lr@{'}l}
    {<span style="color: #ff79c6; font-weight: bold;">\bf</span><span style="color: #bd93f9;"> Elemento</span>} <span style="color: #ff5555;">&amp;</span> <span style="color: #ff79c6; font-weight: bold;">\multicolumn</span>{<span style="color: #50fa7b; font-weight: bold;">2</span>}{<span style="color: #50fa7b; font-weight: bold;">c</span>}{<span style="color: #50fa7b; font-weight: bold;">\bf</span><span style="color: #50fa7b; font-weight: bold;"> Valor</span>} <span style="color: #ff5555;">\\</span>
    <span style="color: #ff79c6; font-weight: bold;">\hline</span>
    Elemento 1     <span style="color: #ff5555;">&amp;</span>     1<span style="color: #ff5555;">&amp;</span>23   <span style="color: #ff5555;">\\</span>
    Elemento 2     <span style="color: #ff5555;">&amp;</span>    14<span style="color: #ff5555;">&amp;</span>3402 <span style="color: #ff5555;">\\</span>
    Elemento 3     <span style="color: #ff5555;">&amp;</span>     0<span style="color: #ff5555;">&amp;</span>27   <span style="color: #ff5555;">\\</span>
    Elemento 4     <span style="color: #ff5555;">&amp;</span> 12345<span style="color: #ff5555;">&amp;</span>123  <span style="color: #ff5555;">\\</span>
    Elemento 5     <span style="color: #ff5555;">&amp;</span>   234<span style="color: #ff5555;">&amp;</span>2    <span style="color: #ff5555;">\\</span>
    <span style="color: #ff79c6; font-weight: bold;">\hline</span>
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">tabular</span>}
  <span style="color: #ff79c6; font-weight: bold;">\caption</span>{<span style="color: #8be9fd; font-style: italic;">Alineaci&#243;n y separaci&#243;n a la coma.</span>}<span style="color: #ff79c6; font-weight: bold;">\label</span>{<span style="color: #bd93f9;">tab:coma</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">table</span>}
</pre>
</div>

<p>
Si analizamos la estructura de las columnas vemos que hay tres,
definidas como <code>{lrl}</code>. La diferencia es que entre la segunda y la
tercera columna hemos definido un carácter <code>'</code> como separador. Después
en la tabla, en lugar de escribir <code>1'23</code> sustituimos la coma por el
carácter <code>&amp;</code><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.
</p>

<p>
El resultado del código anterior nos muestra el siguiente resultado:
</p>


<figure id="org95904f3">
<img src="./imagenes/Captura-pantalla_alinear-coma.png" alt="Captura-pantalla_alinear-coma.png">

</figure>

<p>
Las tablas además nos pueden dar aún más juego, pero como introducción
valga esta pequeña introducción.
</p>
</div>
</div>
</div>
<div id="outline-container-org15ce779" class="outline-3">
<h3 id="org15ce779">Figuras y el paquete <code>graphicx</code></h3>
<div class="outline-text-3" id="text-org15ce779">
<p>
Si queremos que nuestro documento tenga imágenes, como ocurre con todo
lo que hemos visto hasta ahora, necesitamos importar un paquete.
Existen dos paquetes para esto:
</p>

<ul class="org-ul">
<li><code>graphics</code>: paquete de gráficos <i>estándar</i>.</li>
<li><code>graphicx</code>: paquete <i>extendido</i> de gráficos.</li>
</ul>

<p>
Por lo general, es más habitual emplear el segundo, pues proporciona
más comandos que los del <i>estándar</i> y tenemos así funcionalidad extra.
Un complemento bastante interesante para los gráficos es un paquete de
colores. Que como ocurre con los gráficos podemos encontrar en dos
formatos: un paquete <i>estándar</i> y uno <i>extendido</i>.
</p>

<p>
En la cabecera, para mostrar todos estos puntos he añadido, por tanto,
dos líneas para incluir los paquetes necesarios:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>{<span style="color: #50fa7b; font-weight: bold;">graphicx</span>}       <span style="color: #6272a4;">% Paquete extendido de gr&#225;ficos
</span><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>{<span style="color: #50fa7b; font-weight: bold;">xcolor</span>}         <span style="color: #6272a4;">% Paquete para colores</span>
</pre>
</div>

<p>
Además para una primera prueba, en la cabecera he utilizado uno de los
comandos que proporciona el paquetes <code>xcolor</code>, para ilustrarlo:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6;">\definecolor</span>{migris}{gray}{0.75}
</pre>
</div>

<p>
Este comando tiene la sintaxis siguiente:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6;">\definecolor</span>{nombre}{modelo}{valor}
</pre>
</div>

<p>
Veamos el significado de los parámetros de ese comando:
</p>

<ul class="org-ul">
<li><code>nombre</code>: es el nombre del color que estamos definiendo.</li>
<li><p>
<code>modelo</code>: Define el <i>modelo</i> de color que estamos utilizando. Hay
varios modelos.
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-right">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Modelo</th>
<th scope="col" class="org-right">Rango</th>
<th scope="col" class="org-left">Significado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">rgb</td>
<td class="org-right">0..1</td>
<td class="org-left">Cantidad de rojo (R), verde (G) y azul (B)</td>
</tr>

<tr>
<td class="org-left">RGB</td>
<td class="org-right">0..255</td>
<td class="org-left">Cantidad de rojo (R), verde (G) y azul (B)</td>
</tr>

<tr>
<td class="org-left">gray</td>
<td class="org-right">0..1</td>
<td class="org-left">Cantidad de gris</td>
</tr>

<tr>
<td class="org-left">Gray</td>
<td class="org-right">0..15</td>
<td class="org-left">Sólo 15 niveles de gris.</td>
</tr>

<tr>
<td class="org-left">HTML</td>
<td class="org-right">00..FF</td>
<td class="org-left">Utiliza el mismo formato que en <code>html</code></td>
</tr>

<tr>
<td class="org-left">cmy</td>
<td class="org-right">0..1</td>
<td class="org-left">Cián, Magenta y amarillo (Y)</td>
</tr>

<tr>
<td class="org-left">cmyk</td>
<td class="org-right">0..1</td>
<td class="org-left">Cián, Magenta, amarillo (Y) y negro (K)</td>
</tr>
</tbody>
</table>

<p>
Existen más modelos, pero estos son los más habituales.
</p></li>
<li><code>valor</code>: El valor numérico o conjunto de valores que definen el
color.</li>
</ul>

<p>
En el ejemplo anterior he creado un <i>color</i> de nombre <code>migris</code>
utilizando el modelo <code>gray</code> que sirve para definir grises. En este
caso el valor es <code>0.75</code>.
</p>

<p>
Vamos con un ejemplo con colores:
</p>

<div class="org-src-container">
<pre class="src src-latex">Esto es una <span style="color: #ff79c6;">\colorbox</span>{migris}{prueba} de
<span style="color: #ff79c6;">\colorbox</span>[rgb]{0.9,0.9,0.0}{cajas de texto} con colores.
</pre>
</div>

<p>
El resultado es el siguiente:
</p>


<figure id="org9da0481">
<img src="./imagenes/Captura-pantalla_cajas-color.png" alt="Captura-pantalla_cajas-color.png">

</figure>

<p>
Podemos observar que el comando <code>\colorbox</code> recibe varios parámetros y
para entenderlos todos es aconsejable leer la documentación del
paquete <code>graphicx</code>. Las dos formas que he utilizado son las más
habituales, la primera utiliza el nombre del color que hemos definido
con <code>\definecolor</code>. En el segundo caso, definimos el color sobre la
marcha especificando el modelo (<code>rgb</code> en el ejemplo), el valor del
color (<code>0.9,0.9,0.0</code> para definir un amarillo intenso) y el contenido
de la caja.
</p>

<p>
Podemos refinarlo un poco más cambiando el color del fondo de la
página, rotando cajas, desplazándolas, etc. En el documento de prueba
he añadido el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff5555;">\newpage</span> <span style="color: #ff79c6;">\pagecolor</span>{migris}
Esto es una <span style="color: #ff79c6;">\colorbox</span>{white}{prueba} de
<span style="color: #ff79c6;">\colorbox</span>[rgb]{0.9,0.9,0.0}{cajas de texto} con colores. Y tambi&#233;n
podemos darle un poco de rotaci&#243;n
<span style="color: #ff79c6; font-weight: bold;">\hspace</span>{<span style="color: #50fa7b; font-weight: bold;">-4.5cm</span>}<span style="color: #ff79c6;">\rotatebox</span>[origin=c]{90}{<span style="color: #ff79c6;">\colorbox</span>{white}{Texto Rotado}}

Es decir, nos permite m&#225;s juego que s&#243;lo escribir texto de forma lineal.

<span style="color: #ff5555;">\newpage</span> <span style="color: #ff79c6;">\nopagecolor</span>
Esto es otra p&#225;gina y desactivamos el color de la misma.
</pre>
</div>

<p>
He añadido dos páginas. La primera define un color de fondo <code>migris</code>,
que ya lo definimos un poco más arriba, con el comando <code>\pagecolor</code>.
Después he modificado un poco las cajas, para que se aprecien al
cambiar el fondo y he puesto una línea:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\hspace</span>{<span style="color: #50fa7b; font-weight: bold;">-4.5cm</span>}<span style="color: #ff79c6;">\rotatebox</span>[origin=c]{90}{<span style="color: #ff79c6;">\colorbox</span>{white}{Texto Rotado}}
</pre>
</div>

<p>
De esa línea ya conocemos el comando <code>\hspace</code>. Al usarlo con un valor
negativo mueve el punto de inserción de texto cuatro centímetros y
medio a la izquierda. Lo siguiente es un comando <code>\rotatebox</code> con sus
parámetros:
</p>

<ul class="org-ul">
<li><code>[origin=c]</code>: En este caso el <i>origen</i> del giro está centrado,
<code>c</code>. Pero puede ser cualquier combinación con las letras habituales:
<code>t</code> arriba (<i>top</i>), <code>b</code> abajo (<i>bottom</i>), <code>l</code> izquierda (<i>left</i>),
<code>r</code> derecha (<i>right</i>). También se pueden definir con una pareja de
esas letras <code>lt</code> para <i>izquierda-arriba</i>, <code>rb</code> para <i>derecha-abajo</i>,
etc.</li>
<li><code>{90}</code>: Grados de giro en dirección contraria a las agujas de un
reloj. Si queremos el giro en la misma dirección que las agujas del
reloj podemos utilizar grados negativos.</li>
</ul>

<p>
Pero lo que más me interesa es que se pueda apreciar cómo se va
<i>dibujando</i> diferentes estructuras simplemente utilizando un comando
detrás de otro. Se utiliza <code>\colorbox</code> como parámetro para
<code>\rotatebox</code> que a su vez se ve afectado por <code>hspace</code>.
</p>

<p>
Los efectos se pueden apreciar en la siguiente imagen:
</p>


<figure id="orgb8fa9cd">
<img src="./imagenes/Captura-pantalla_color-de-pagina.png" alt="Captura-pantalla_color-de-pagina.png">

</figure>
</div>
<div id="outline-container-org735f02b" class="outline-4">
<h4 id="org735f02b">Figuras flotantes.</h4>
<div class="outline-text-4" id="text-org735f02b">
<p>
El entorno <code>figure</code> funciona exactamente igual que el entorno <code>table</code>:
es un recubrimiento de la figura para dotarla de un pié, permitirnos
alinearla en el espacio, dotarla de una etiqueta, etc.
</p>

<p>
Por poner un ejemplo, veamos el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-latex">Vamos a insertar una figura, la <span style="color: #ff79c6; font-weight: bold;">\ref</span>{<span style="color: #bd93f9;">fig:claustro</span>}, con una fotograf&#237;a
del claustro del Monasterio de Veruela.

<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">figure</span>}[h!t]
  <span style="color: #ff79c6; font-weight: bold;">\centering</span>
  <span style="color: #ff79c6;">\includegraphics</span>[width=0.9<span style="color: #ff79c6;">\linewidth</span>]{claustro.png}
  <span style="color: #ff79c6; font-weight: bold;">\caption</span>[<span style="color: #f8f8f2; font-weight: bold;">Cl&#225;ustro del Monasterio de Veruela</span>]{<span style="color: #8be9fd; font-style: italic;">Fotograf&#237;a hecha con el m&#243;vil del claustro
    del Monasterio de Veruela</span>} <span style="color: #ff79c6; font-weight: bold;">\label</span>{<span style="color: #bd93f9;">fig:claustro</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">figure</span>}
</pre>
</div>

<p>
Como se puede apreciar en el código, el entorno <code>figure</code> es muy
similar al entorno <code>table</code>. Lo interesante del contenido viene dado
por el comando <code>\includegraphics</code> que podemos ver en el ejemplo, que
necesita unos parámetros, como el tamaño del ancho que ocupará, por
ejemplo, y un nombre de un fichero gráfico. También, si vuestro
objetivo es generar vuestros propios diseños podéis generarlos con
paquetes gráficos. La estrella de éstos es el paquete <code>Tikz</code>, pero lo
habitual es que los dibujos, gráficos o imágenes las tengamos ya
hechas en ficheros <i>raster</i> (<code>png</code>, <code>jpg</code>, etc) o vectoriales (<code>svg</code>,
<code>eps</code>, <code>ps</code>, <code>pdf</code>). Puesto que lo habitual es que quieras generar
<code>pdf</code> es aconsejable que utilices dicho formato también para los
gráficos vectoriales y evitar de ese modo conversiones entre formatos
a la hora de generar el documento.
</p>


<figure id="orgf966fb2">
<img src="./imagenes/Captura-pantalla_imagen.png" alt="Captura-pantalla_imagen.png">

</figure>

<p>
Otro problema bastante habitual es que algunas veces necesitamos
mostrar varias imágenes en una sola figura. Normalmente para poder
visualizar gráficos mostrando, por ejemplo, las distribuciones de
diversas variables de un vistazo. Para poder hacerlo, se utiliza el
paquete <code>subcaption</code>.
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>{<span style="color: #50fa7b; font-weight: bold;">subcaption</span>}     <span style="color: #6272a4;">% M&#250;ltiple gr&#225;ficos en una figura</span>
</pre>
</div>

<p>
Ese paquete tiene múltiples opciones y como siempre es recomendable
mirar la documentación del paquete para poder exprimirlo
completamente. Si necesitamos utilizar varias imágenes en una figura.
Veamos un ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">figure</span>}
  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">subfigure</span>}[b]{.45<span style="color: #ff79c6;">\linewidth</span>}
    <span style="color: #ff79c6;">\includegraphics</span>[width=0.9<span style="color: #ff79c6;">\linewidth</span>]{claustro}
    <span style="color: #ff79c6;">\subcaption</span>{Una subfigura}<span style="color: #ff79c6; font-weight: bold;">\label</span>{<span style="color: #bd93f9;">fig:3a</span>}
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">subfigure</span>}
  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">subfigure</span>}[b]{.45<span style="color: #ff79c6;">\linewidth</span>}
    <span style="color: #ff79c6;">\includegraphics</span>[width=0.9<span style="color: #ff79c6;">\linewidth</span>]{claustro}
    <span style="color: #ff79c6;">\subcaption</span>{Una segunda subfigura}<span style="color: #ff79c6; font-weight: bold;">\label</span>{<span style="color: #bd93f9;">fig:3b</span>}
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">subfigure</span>}
  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">subfigure</span>}[b]{.95<span style="color: #ff79c6;">\linewidth</span>}
    <span style="color: #ff79c6; font-weight: bold;">\centering</span>
      <span style="color: #ff79c6;">\colorbox</span>[rgb]{0.8,0.8,1.0}{<span style="color: #ff79c6; font-weight: bold;">\Huge</span><span style="color: #ff79c6; font-weight: bold; font-style: italic;">\LaTeX</span>}
    <span style="color: #ff79c6;">\subcaption</span>{La &#250;ltima subfigura}<span style="color: #ff79c6; font-weight: bold;">\label</span>{<span style="color: #bd93f9;">fig:3d</span>}
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">subfigure</span>}
  <span style="color: #ff79c6; font-weight: bold;">\caption</span>{<span style="color: #8be9fd; font-style: italic;">Un par de im&#225;genes en una misma figura</span>}<span style="color: #ff79c6; font-weight: bold;">\label</span>{<span style="color: #bd93f9;">fig:multi</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">figure</span>}
</pre>
</div>

<p>
Como se puede ver el paquete <code>subcaption</code> proporciona el entorno
<code>subfigure</code>. También hubiéramos podido utilizar dentro del entorno
<code>figure</code> entornos <code>minipage</code>, sin embargo, no hubiéramos podido
referenciar con títulos dichas imágenes. En el caso de utiliza
<code>minipage</code>, el paquete <code>subcaption</code> también provee el comando
<code>subcaption</code>, valga la <i>rebuznancia</i>.
</p>

<p>
El resultado del código anterior se puede visualizar en la siguiente
imagen.
</p>


<figure id="org10ab583">
<img src="./imagenes/Captura-pantalla_subcaption.png" alt="Captura-pantalla_subcaption.png">

</figure>
</div>
</div>
</div>
</div>
<div id="outline-container-org80857d6" class="outline-2">
<h2 id="org80857d6">Conclusiones</h2>
<div class="outline-text-2" id="text-org80857d6">
<p>
Los entornos flotantes nos proporcionan aclaraciones necesarias para
nuestro documento que matizan o aclaran las explicaciones textuales.
El uso de tablas e imágenes es de lo más habitual en el trabajo del
día a día. Es recomendable, si vais a utilizar tablas que necesiten
distribuirse por varias páginas, que le echéis un ojo al paquete
<code>longtable</code>.
</p>

<p>
Pero hay tantas opciones y tantos paquetes que nos permiten presentar
información de este tipo que se salen de lo que se considera un uso
básico de <i>LaTeX</i> y del espacio de este <i>minicurso</i>, pero hay mucha
información en <i>Internet</i>.
</p>

<p>
Para la próxima entrega veremos cómo estructurar un documento grande y
pode dividir el trabajo en ficheros independientes que sean más
manejables que uno grande monolítico y del <i>modo matemático</i>. De
momento nuestro <a href="imagenes/texto-prueba.tex">fichero de ejemplo</a> va creciendo para generar
<a href="imagenes/texto-prueba.pdf">un fichero <code>pdf</code> un poco caótico</a>.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Que por algo se llaman <i>flotantes</i>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Recordemos que el símbolo <code>&amp;</code> es la separación entre
columnas.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/latex/index.html">latex</a> ]]></description>
  <category><![CDATA[latex]]></category>
  <link>https://notxor.nueva-actitud.org/2021/04/02/minicurso-de-latex-para-psicologos-iv.html</link>
  <pubDate>Fri, 02 Apr 2021 08:49:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Minicurso de LaTeX para psicólogos III]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-03-26</div>
<p>
Hasta ahora hemos trabajado un poco con <i>LaTeX</i>, he hablado de sus
ventajas e inconvenientes, hemos trasteado con las fuentes y, espero,
que hayamos visto que el león no es tan fiero como lo pintan.  Por
otro lado, aún nos quedan un montón de cosas que ver y un largo camino
que recorrer. En esta entrega del <i>minicurso</i> hablaré de los enlaces e
<i>hipervínculos</i> tanto internos como externos. También veremos algo
sobre entornos y la <i>colocación</i> o <i>desplazamiento</i> de objetos sobre
la página.
</p>

<p>
Los avances que vayamos haciendo en nuestro fichero de prueba los
podéis ir comprobando si le echáis un ojo a:
</p>

<ul class="org-ul">
<li><a href="./imagenes/texto-prueba.tex">Fichero <i>LaTeX</i> de prueba</a></li>
<li><a href="./imagenes/texto-prueba.pdf"><code>pdf</code> generado</a></li>
</ul>
<div id="outline-container-orgfb46c70" class="outline-2">
<h2 id="orgfb46c70">Enlaces</h2>
<div class="outline-text-2" id="text-orgfb46c70">
<p>
En la pasada entrega ya vimos cómo manejaba <i>LaTeX</i> la posibilidad de
realizar referencias a objetos de la estructura interna del documento.
Podemos <i>citar</i> el apartado o figura o tabla que queremos explicar por
su numeración de forma sencilla. Esto es facilitarnos la vida, pero ya
que estamos generando un archivo <code>pdf</code> que posiblemente se lea por
pantalla, es posible que quieras hacerlo <i>navegable</i>, es decir: poder
habilitar enlaces donde poder <i>pinchar</i> y que nos lleve a esa
localización de forma cómoda.
</p>

<p>
Como puedes suponer, y como vengo diciendo en las anteriores entregas,
para conseguir estos enlaces <i>pinchables</i> hay que instalar un paquete.
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>{<span style="color: #50fa7b; font-weight: bold;">hyperref</span>}
</pre>
</div>

<p>
Poniendo la instrucción anterior en el preámbulo de nuestro documento
esos enlaces se generan solos cuando utilizamos el comando <code>\ref</code> o
<code>\pageref</code>. Cuando pasemos el cursor en pantalla sobre esas
referencias, cambiará de forma indicando que se puede pinchar ahí.
</p>


<figure id="org1ccc3bb">
<img src="./imagenes/Captura-pantalla_enlaces-coloraos.png" alt="Captura-pantalla_enlaces-coloraos.png">

</figure>

<p>
<i>¡Eh! Han aparecido unos rectángulos horribles en el índice</i>. Sí, y no
sólo en el índice, sino también en todas las referencias internas que
haya en el documento. No debes alarmarte, al imprimir en papel no se
muestran, es sólo un efecto que delimita las áreas donde se puede
pinchar y no afecta a la calidad de impresión. Si queremos utilizar el
documento sólo para difundirlo de manera electrónica, es recomendable
quitar ese horror visual. Para ello hay una opción <code>hidelinks</code> que
podemos utilizar así:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>[<span style="color: #f8f8f2; font-weight: bold;">hidelinks</span>]{<span style="color: #50fa7b; font-weight: bold;">hyperref</span>}
</pre>
</div>

<p>
Esa opción lo que hace es que se muestren los enlaces como texto
normal, sin el horrible rectángulo rojo. Sin embargo, al pasar por
encima el cursor, éste seguirá cambiando de forma e indicando que se
puede pinchar sobre él<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. Otra forma de eliminar ese horrible
recuadro rojo es utilizar la opción <code>[colorlinks=true]</code>, que suele ser
lo mejor si pensamos que el documento se distribuirá en su formato
electrónico y no impreso.
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>[<span style="color: #f8f8f2; font-weight: bold;">colorlinks=true</span>]{<span style="color: #50fa7b; font-weight: bold;">hyperref</span>}
</pre>
</div>

<p>
Con esa opción lo que hace <code>hyperref</code> es colorear el texto:
</p>


<figure id="org76ce189">
<img src="./imagenes/Captura-pantalla_color-texto-enlaces.png" alt="Captura-pantalla_color-texto-enlaces.png">

</figure>

<p>
Ahora, en lugar de un recuadro rojo, tenemos todo el texto de ese
color. ¿Se puede cambiar? Por supuesto. De momento lo podemos hacer a
un color estándar como <code>blue</code>, pero aprovecharé para mostrar más
opciones de configuración de <code>hyperref</code>. Y como esas opciones se
harían la importación del paquete un pequeño suplicio, éste provee un
comando de configuración que podemos utilizar. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>{<span style="color: #50fa7b; font-weight: bold;">hyperref</span>}       <span style="color: #6272a4;">% Habilitaci&#243;n de enlaces
</span><span style="color: #ff79c6;">\hypersetup</span>{                <span style="color: #6272a4;">% Configuraci&#243;n de los enlaces y el pdf
</span>   breaklinks=true,
   colorlinks=true,
   linkcolor=blue,
   citecolor=green,
   filecolor=cyan,
   pdfauthor={Notxor},
   pdftitle={Documento b&#225;sico de ejemplo},
   pdfkeywords={latex, tutorial},
   pdflang={Spanish},
   pdfpagemode={UseOutLines},
   pdfpagelayout={OneColumn}}
</pre>
</div>

<p>
Todas esas opciones que figuran en el comando <code>\hypersetup</code>, podrían
ponerse como opciones a la hora de cargar el paquete <code>\hyperref</code> pero
harían que la lectura de esas opciones nos confundiera. Al separar la
carga de la configuración ganamos en claridad para el ojo humano. He
puesto muchas opciones que además las podemos dividir en dos grupos.
El primero grupo se refiere al aspecto de los enlaces:
</p>

<ul class="org-ul">
<li><code>beaklinks=true</code> habilita la posibilidad de que los enlaces puedan
dividirse entre dos líneas. Por defecto no es así y si un enlace cae
al final de una línea se mostrará en una línea escribiendo en el
margen o incluso perdiéndose fuera de la página.</li>
<li><code>colorlinks=true</code> habilita el uso de colores para los enlaces, como
ya habíamos visto antes.</li>
<li><code>linkcolor</code> define el color con el que se mostrarán los colores de
los enlaces normales.</li>
<li><code>citecolor</code> define el color de los enlaces de las citas
bibliográficas.</li>
<li><code>filecolor</code> define el color de los enlaces a ficheros externos.</li>
</ul>

<p>
El siguiente grupo de opciones se refiere a las opciones para definir
en el fichero <code>pdf</code> generado. Algunas son opciones para los
<i>metadatos</i> del mismo, pero otras nos permiten controlar cómo queremos
que una herramienta de visualización lo abra:
</p>

<ul class="org-ul">
<li><code>pdfauthor</code> nos permite establecer quién es el autor del documento,
se puede proporcionar una lista separada por comas.</li>
<li><code>pdftitle</code> nos permite establecer el título en los metadatos del
fichero.</li>
<li><code>pdfkeywords</code> estable etiquetas en los metadatos que pueden
facilitar su búsqueda por herramientas externas.</li>
<li><code>pdflang</code> permite establecer el idioma del fichero.</li>
<li><code>pdfpagemode</code> permite establecer que cuando se abra el fichero con
el visor correspondiente nos permita navegar por el índice, o
muestre una lista de miniaturas, etc.</li>
<li><code>pdfpagelayout</code> indica al visor de documento si debe mostrar el
documento en dos columnas, o en una, o como una colección de
miniaturas, etc.</li>
</ul>

<p>
Todas esas opciones, y más, están perfectamente explicadas en la
documentación del paquete <code>hyperref</code> y no está de más leerla.
</p>
</div>
<div id="outline-container-org7412835" class="outline-3">
<h3 id="org7412835">Otros enlaces</h3>
<div class="outline-text-3" id="text-org7412835">
<p>
El paquete nos proporciona más funcionalidades que vamos a repasar en
este apartado. Por ejemplo, nos permite crear un enlace a cualquier
<code>label</code> que tengamos definida en el documento. La sintaxis es muy
sencilla:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6;">\hyperref</span>[etiqueta]{texto del enlace}
</pre>
</div>

<p>
Por ejemplo, podemos llamar a las etiquetas que tenemos definidas en
nuestro documento de pruebas de la siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\section</span>{<span style="color: #50fa7b; font-size: 110%; font-weight: bold;">Enlaces</span>}

Desde cualquier sitio podemos enlazar otras secciones utilizando el
comando <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\hyperref</span><span style="color: #ffb86c;">|</span>. Por ejemplo, podemos
<span style="color: #ff79c6;">\hyperref</span>[sec:fuentes]{referenciar una secci&#243;n} y tambi&#233;n
<span style="color: #ff79c6;">\hyperref</span>[tab:fuentes]{referenciar una tabla}.
</pre>
</div>

<p>
El resultado en nuestro documento será algo así:
</p>


<figure id="orgd0bcbca">
<img src="./imagenes/Captura-pantalla_enlaces-random.png" alt="Captura-pantalla_enlaces-random.png">

</figure>

<p>
Como se puede apreciar, nos marca en azul<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> los enlaces.
</p>

<p>
Como hemos visto, al importar el paquete <code>hyperref</code> todas las
referencias se nos convierten automáticamente en enlace. Es posible
que no queramos que sea así, es decir: queremos que se muestren
correctamente las referencias a la página o al elemento, pero no
queremos generar el consiguiente enlace. Para ello, el paquete
<code>hyperref</code> nos proporciona los comandos <code>\ref*</code> y <code>\pageref*</code> que
funcionan de manera idéntica a sus homólogos generales. Para verlo en
nuestro ejemplo vamos a añadir el siguiente texto en nuestro documento
de pruebas:
</p>

<div class="org-src-container">
<pre class="src src-latex">En este caso podemos referenciar la secci&#243;n <span style="color: #ff5555; font-weight: bold;">\</span><span style="color: #ff79c6; font-weight: bold;">ref</span>*{sec:fuentes} en la
p&#225;gina <span style="color: #ff5555; font-weight: bold;">\</span><span style="color: #ff79c6; font-weight: bold;">pageref</span>*{sec:fuentes} pero se generan los enlaces
correspondientes.
</pre>
</div>

<p>
Al visualizar el resultado vemos que aunque las referencias están
correctamente escritas, no hay enlace, ni coloreado ni oculto.
</p>


<figure id="org15eb352">
<img src="./imagenes/Captura-pantalla_referencias-sin-enlace.png" alt="Captura-pantalla_referencias-sin-enlace.png">

</figure>

<p>
Normalmente necesitamos enlazar a <i>secciones</i>, <i>tablas</i> o <i>figuras</i> de
nuestro documento, pero también es posible que nos interese crear un
enlace a cualquier sitio del documento que no sea una <i>cabecera</i>.
<code>hyperref</code> nos proporciona un mecanismo para hacerlo de forma
sencilla. Podemos utilizar dos comandos que al funcionar de manera
conjunta nos proporcionan esa funcionalidad:
</p>

<dl class="org-dl">
<dt><code>\hypertarget{etiqueta}{texto}</code></dt><dd>proporciona un lugar al que
queremos llegar desde cualquier otro lugar del fichero.</dd>
<dt><code>\hyperlink{etiqueta}{texto}</code></dt><dd>produce el enlace a la <code>etiqueta</code>
que esté definida por <code>\hypertarget</code>.</dd>
</dl>

<p>
Pues vamos a ello: <i>¡Más madera para nuestro fichero de ejemplo!</i>:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #6272a4;">% </span><span style="color: #6272a4;">[...]
</span><span style="color: #6272a4;">% </span><span style="color: #6272a4;">Al final del apartado de &#171;Estructura y enlaces internos he a&#241;adido
</span>Me interesa enlazar este punto de aqu&#237; <span style="color: #ff79c6;">\hypertarget</span>{un-enlace}{para
enlazarlo desde cualquier parte del archivo}. Por ejemplo, he creado
una <span style="color: #ff79c6; font-weight: bold;">\emph</span>{<span style="color: #ff79c6; font-style: italic;">etiqueta</span>} para poder enlazar a esta zona del fichero.
<span style="color: #6272a4;">% </span><span style="color: #6272a4;">[...]
</span>
<span style="color: #ff79c6; font-weight: bold;">\section</span>{<span style="color: #50fa7b; font-size: 110%; font-weight: bold;">Enlaces</span>}

Desde cualquier sitio podemos enlazar otras secciones utilizando el
comando <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\hyperref</span><span style="color: #ffb86c;">|</span>. Por ejemplo, podemos
<span style="color: #ff79c6;">\hyperref</span>[sec:fuentes]{referenciar una secci&#243;n} y tambi&#233;n
<span style="color: #ff79c6;">\hyperref</span>[tab:fuentes]{referenciar una tabla}.

En este caso podemos referenciar la secci&#243;n <span style="color: #ff5555; font-weight: bold;">\</span><span style="color: #ff79c6; font-weight: bold;">ref</span>*{sec:fuentes} en la
p&#225;gina <span style="color: #ff5555; font-weight: bold;">\</span><span style="color: #ff79c6; font-weight: bold;">pageref</span>*{sec:fuentes} pero se generan los enlaces
correspondientes.

Tambi&#233;n puedo enlazar cualquier parte del fichero utilizando los
comandos <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\hypertarget</span><span style="color: #ffb86c;">|</span> e <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\hyperlink</span><span style="color: #ffb86c;">|</span> y por eso puedo
enlazar <span style="color: #ff79c6;">\hyperlink</span>{un-enlace}{cualquier lugar}.
</pre>
</div>

<p>
El resultado es:
</p>


<figure id="org8f0fd6c">
<img src="./imagenes/Captura-pantalla_hyperlinks.png" alt="Captura-pantalla_hyperlinks.png">

</figure>

<p>
También se pueden enlazar contenidos en la <i>web</i> con el comando de
sintaxis:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6;">\href</span>[opciones]{URL}{texto}
</pre>
</div>

<p>
He añadido para probarlo el siguiente texto al final del apartado de
<i>enlaces</i>:
</p>

<div class="org-src-container">
<pre class="src src-latex">Llamar a ficheros externos es realmente f&#225;cil utilizando el comando
<span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\href</span><span style="color: #ffb86c;">|</span> como por ejemplo
<span style="color: #ff79c6;">\href</span>{https://notxor.nueva-actitud.org}{este blog}. Pod&#233;is encontrar
m&#225;s informaci&#243;n
<span style="color: #ff79c6;">\href</span>{https://ctan.javinator9889.com/macros/latex/contrib/hyperref/doc/hyperref-doc.pdf}{en este enlace}.
Tambi&#233;n podemos abrir ficheros:

<span style="color: #ff79c6;">\href</span>{./texto-prueba.tex}{Este mismo fichero en el editor por defecto}.
</pre>
</div>

<p>
Se puede apreciar que no sólo se pueden llamar <i>URLs</i> que estén en la
<i>web</i>, también podemos enlazar archivos externos que estén en el
<i>path</i> de nuestro <code>pdf</code>. Tened en cuenta que si eso es así, es posible
que nuestro enlace no funcione si no se encuentra el archivo enlazado.
</p>


<figure id="orgd52f8f6">
<img src="./imagenes/Captura-pantalla_enlaces-externos.png" alt="Captura-pantalla_enlaces-externos.png">

</figure>

<p>
Estos enlaces aparecen coloreados en magenta. Se puede configurar
también el color en las opciones del paquete <code>hyperref</code>. Para más
detalles, como siempre, os remito a la documentación del paquete.
</p>
</div>
</div>
</div>
<div id="outline-container-org1c3395a" class="outline-2">
<h2 id="org1c3395a">Notas al pie</h2>
<div class="outline-text-2" id="text-org1c3395a">
<p>
Una de las funcionalidades más habituales de las referencias y es una
de las cosas que <i>LaTeX</i> sabe manejar muy bien. En realidad, las
<i>notas al pie</i> no necesitan que sepas nada sobre enlaces, las hace
<i>LaTeX</i> de manera <i>automágica</i>. Simplemente tienes que escribir lo que
quieras como parámetro de un comando <code>\footnote{...}</code> y aparecerá en
nuestro pie de página lo que escribamos, que pueden ser párrafos
enteros, tablas, imágenes, cualquier elemento <i>LaTeX</i>. Si no cabe en
el pie de página se expandirá por los pies de las páginas siguientes.
Aunque es raro que se necesite hacer aclaraciones tan largas, es
posible.
</p>

<div class="org-src-container">
<pre class="src src-latex">Para acabar con los enlaces<span style="color: #ff79c6; font-weight: bold;">\footnote</span>{<span style="color: #bd93f9;">En este caso no se acaba con los
enlaces, nos falta hablar de los &#237;ndices de </span><span style="color: #bd93f9; font-weight: bold;">\emph</span><span style="color: #bd93f9;">{</span><span style="color: #bd93f9; font-style: italic;">palabras clave</span><span style="color: #bd93f9;">} que lo
dejo para otra entrega:

No se puede tener todo...</span>} hablo de los pies de p&#225;gina.
</pre>
</div>

<p>
Podemos ver el resultado del código anterior en la siguiente imagen:
</p>


<figure id="orgd2780bc">
<img src="./imagenes/Captura-pantalla_nota-al-pie.png" alt="Captura-pantalla_nota-al-pie.png">

</figure>

<p>
También se pueden hacer anotaciones en el margen, pero dejo esta
peculiaridad para que lo investiguéis... no estaréis esperando que lo
cuente todo en esta introducción a <i>LaTeX</i>.
</p>
</div>
</div>
<div id="outline-container-org75c68bd" class="outline-2">
<h2 id="org75c68bd">Entornos</h2>
<div class="outline-text-2" id="text-org75c68bd">
<p>
Un entorno es todo lo que coloquemos entre una etiqueta <code>\begin{...}</code>
y una etiqueta <code>\end{...}</code>. Por supuesto, las dos etiquetas deben ser
del mismo tipo. Hay múltiples y numerosos entornos que tienen varios
efectos sobre cómo se muestra el contenido. Por supuesto, estos
entornos se pueden anidar unos dentro de otros. Por ejemplo, todo
nuestro documento se encuentra contenido entre etiquetas
<code>\begin{document}</code> y <code>\end{document}</code> y dentro de éstas se pueden
abrir todos los entornos que se quiera. Sólo hay que recordar que se
deben cerrar los entornos internos antes que los externos, de manera
que un entorno debe estar contenido completamente por su entorno
<i>maestro</i> o <i>padre</i>.
</p>
</div>
<div id="outline-container-org40522ff" class="outline-3">
<h3 id="org40522ff">De alineación</h3>
<div class="outline-text-3" id="text-org40522ff">
<p>
Hay entornos que nos permiten desplazar nuestro texto y alinearlo de
las tres maneras habituales: izquierda, centro y derecha. Para ello
utilizaremos entornos que responden a las opciones <code>flushleft</code>,
<code>center</code> y <code>flushright</code>, respectivamente. Para ilustrar cómo funcionan
estos entornos he escrito el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\section</span>{<span style="color: #50fa7b; font-size: 110%; font-weight: bold;">Entornos</span>}

<span style="color: #ff79c6; font-weight: bold;">\subsection</span>{<span style="color: #f1fa8c; font-weight: bold;">Entornos de alineaci&#243;n</span>}

<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">flushleft</span>}
  Este p&#225;rrafo estar&#225; alineado <span style="color: #ff79c6; font-weight: bold;">\fbox</span>{<span style="color: #50fa7b; font-weight: bold;">a la izquierda</span>}<span style="color: #ff5555;">\\</span>
  las l&#237;neas se ajustar&#225;n, como deben, al margen<span style="color: #ff5555;">\\</span>
  de ese lado.
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">flushleft</span>}
<span style="color: #ff79c6;">\hrule</span>
<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">center</span>}
  Este p&#225;rrafo mostrar&#225; sus <span style="color: #ff79c6; font-weight: bold;">\fbox</span>{<span style="color: #50fa7b; font-weight: bold;">l&#237;neas centradas</span>} en el<span style="color: #ff5555;">\\</span>
  espacio destinado al texto.<span style="color: #ff5555;">\\</span>
  cada una de las l&#237;neas centradas, independientemente<span style="color: #ff5555;">\\</span>
  de su longitud.
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">center</span>}
<span style="color: #ff79c6;">\hrule</span>
<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">flushright</span>}
  Por &#250;ltimo, podemos alinear todo nuestro texto<span style="color: #ff5555;">\\</span>
  <span style="color: #ff79c6; font-weight: bold;">\fbox</span>{<span style="color: #50fa7b; font-weight: bold;">a la derecha</span>} como est&#225; este p&#225;rrafo.

  Incluso si hay varios p&#225;rrafos<span style="color: #ff5555;">\\</span>
  mantendr&#225; la alineaci&#243;n.
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">flushright</span>}
</pre>
</div>

<p>
En el código anterior he introducido el comando <code>\hrule</code> para separar
visualmente los entornos mediante una línea horizontal. Dicho código
hace lo siguiente:
</p>


<figure id="org8ebd176">
<img src="./imagenes/Captura-pantalla_entornos-alineacion.png" alt="Captura-pantalla_entornos-alineacion.png">

</figure>

<p>
En este apartado incluiré también el entorno <code>minipage</code>. Este entorno
nos permite dividir el ancho de la página en distintas <i>páginas</i> o
recuadro, espacio horizontal o como lo quieras llamar. Como puede ser
un poco confuso explicar así en vacío a qué nos referimos con esto,
mejor lo explico sobre un ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-latex">Hay veces que conviene poder dividir el ancho del texto en
<span style="color: #ff79c6; font-weight: bold;">\emph</span>{<span style="color: #ff79c6; font-style: italic;">trozos</span>} m&#225;s peque&#241;os que nos permitan jugar un poco con el
dise&#241;o de la p&#225;gina

<span style="color: #ff79c6; font-weight: bold;">\vspace</span>{<span style="color: #50fa7b; font-weight: bold;">0.3cm</span>}
<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">minipage</span>}[c]{0.4<span style="color: #ff79c6;">\linewidth</span>}
  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">center</span>}
    <span style="color: #ff79c6; font-weight: bold;">\fbox</span>{<span style="color: #50fa7b; font-weight: bold;">\Huge</span><span style="color: #50fa7b; font-weight: bold; font-style: italic;">{</span><span style="color: #50fa7b; font-weight: bold; font-style: italic;">\LaTeXe</span><span style="color: #50fa7b; font-weight: bold; font-style: italic;">}</span>}    
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">center</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">minipage</span>}
<span style="color: #ff79c6;">\hfill</span>
<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">minipage</span>}[c]{0.5<span style="color: #ff79c6;">\linewidth</span>}
  El texto de la izquierda est&#225; hecho con la instrucci&#243;n
  <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\fbox</span><span style="color: #ffb86c;">{</span><span style="color: #ffb86c;">\Huge</span><span style="color: #ffb86c;">{</span><span style="color: #ffb86c;">\LaTeXe</span><span style="color: #ffb86c;">}}|</span> para ilustrar el funcionamiento del
  entorno <span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">minipage</span>}.
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">minipage</span>}
<span style="color: #ff79c6; font-weight: bold;">\vspace</span>{<span style="color: #50fa7b; font-weight: bold;">0.3cm</span>}

Los entornos <span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">minipage</span>} son excelentes amigos para ello. Pero
s&#243;lo sirve para zonas peque&#241;as. Si deseamos que el dise&#241;o de varias
columnas se mantenga entre p&#225;ginas, es mejor utilizar el paquete
<span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">multicolumn</span>}.
</pre>
</div>

<p>
He enmarcado las <code>migipage</code> con párrafos normales para poder comparar
entre las dos formas. El entorno <code>minipage</code> reserva tanto espacio
vertical como necesite la <i>minipágina</i> más alta. La alineación
vertical se controla con el parámetro a la hora de definir las
<i>minipáginas</i>. En este caso, ambas están alineadas verticalmente en el
centro con el parámetro <code>c</code>. También se pueden alinear arriba con <code>t</code>
(<i>top</i>) o en la parte baja con <code>b</code> (<i>bottom</i>). El último dato es el
ancho, que lo podemos definir directamente con <code>Ncm</code> como en muchos
otros sitios. En este caso he preferido dividirlo en función del ancho
de la línea: la primera página es el <code>40%</code> del ancho del texto,
mientras que la segunda es el <code>50%</code>.
</p>

<p>
Además, he preferido separar ambas <i>minipáginas</i> con un espacio de
tres milímetros del párrafo anterior y del posterior, utilizando el
comando <code>\vspace{0.3cm}</code>. También, como el ancho total de las dos
<i>minipáginas</i> es el <code>90%</code> de la línea, entre ambas he añadido una
instrucción <code>\hfill</code> para rellenar con blanco el espacio entre las
<i>minipáginas</i>.
</p>

<p>
El resultado del código anterior lo podemos visualizar aquí:
</p>


<figure id="org45ce531">
<img src="./imagenes/Captura-pantalla_minipaginas.png" alt="Captura-pantalla_minipaginas.png">

</figure>
</div>
</div>
<div id="outline-container-orgf5826b6" class="outline-3">
<h3 id="orgf5826b6">Entornos de lista</h3>
<div class="outline-text-3" id="text-orgf5826b6">
<p>
Otros entornos importantes en nuestros documentos son las <i>listas</i>,
que podemos definir de tres tipos: <i>enumeraciones</i>, <i>lista de ítem</i> y
<i>descripciones</i>. Por supuesto hay más tipos, pero con esos tres
vamos a ver lo básico:
</p>

<ol class="org-ol">
<li>Las listas numeradas las conseguimos con el entorno <code>enumerate</code>.</li>
<li>Las listas de ítems las hacemos con el entorno <code>itemize</code>.</li>
<li>Con el entorno <code>description</code> la definición <code>\item</code> recibe un
parámetro que es el término que <i>describimos</i> en el cuerpo.</li>
<li>En cualquier otro entorno poner un parámetro al ítem modifica su
entorno y muestra como símbolo el contenido de ese parámetro.</li>
<li>Se pueden anidar varias listas, pero sólo hasta una profundidad de
cuatro. Si se intentan anidar más, <i>LaTeX</i> dará un error.</li>
</ol>

<p>
El siguiente código muestra todos estos aspectos:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\subsection</span>{<span style="color: #f1fa8c; font-weight: bold;">Entornos de lista</span>}

<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
<span style="color: #ff79c6; font-weight: bold;">\item</span> Listas numeradas:

  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
    <span style="color: #ff79c6; font-weight: bold;">\item</span> Uno
    <span style="color: #ff79c6; font-weight: bold;">\item</span> Dos Otra lista m&#225;s interna
      <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
      <span style="color: #ff79c6; font-weight: bold;">\item</span> Uno
      <span style="color: #ff79c6; font-weight: bold;">\item</span> Dos
      <span style="color: #ff79c6; font-weight: bold;">\item</span> Tres
        <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
        <span style="color: #ff79c6; font-weight: bold;">\item</span> Uno
        <span style="color: #ff79c6; font-weight: bold;">\item</span> Dos
        <span style="color: #ff79c6; font-weight: bold;">\item</span> Tres
        <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
      <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
    <span style="color: #ff79c6; font-weight: bold;">\item</span> Tres
    <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}

<span style="color: #ff79c6; font-weight: bold;">\item</span> Listas sin numerar:
  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">itemize</span>}
    <span style="color: #ff79c6; font-weight: bold;">\item</span> Uno
    <span style="color: #ff79c6; font-weight: bold;">\item</span>[<span style="color: #ffb86c; font-weight: bold;">$</span><span style="color: #ffb86c; font-weight: bold;">\bullet</span><span style="color: #ffb86c; font-weight: bold;">$</span>] Dos
    <span style="color: #ff79c6; font-weight: bold;">\item</span>[<span style="color: #ffb86c; font-weight: bold;">$</span><span style="color: #ffb86c; font-weight: bold;">\spadesuit</span><span style="color: #ffb86c; font-weight: bold;">$</span>] Tres
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">itemize</span>}

<span style="color: #ff79c6; font-weight: bold;">\item</span> Lista de descripciones:
  <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">description</span>}
  <span style="color: #ff79c6; font-weight: bold;">\item</span>[<span style="color: #f8f8f2; font-weight: bold;">Uno</span>] Este es el uno.
  <span style="color: #ff79c6; font-weight: bold;">\item</span>[<span style="color: #f8f8f2; font-weight: bold;">Dos</span>] Este es el dos.
  <span style="color: #ff79c6; font-weight: bold;">\item</span>[<span style="color: #f8f8f2; font-weight: bold;">Tres</span>] Este es el tres.
  <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">description</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">enumerate</span>}
</pre>
</div>

<p>
El resultado es el siguiente:
</p>


<figure id="org1ad1228">
<img src="./imagenes/Captura-pantalla_listas.png" alt="Captura-pantalla_listas.png">

</figure>

<p>
Por supuesto, hay más cosas que referentes a las listas. Se puede
modificar, por ejemplo, el aspecto de la numeración, utilizar números
romanos o letras o definir las etiquetas a nuestro gusto. Pero esas
acciones implican, o bien, la inclusión de otros paquetes o la
definición de macros. Un aspecto sobre el que aún no he hablado y que
reservo para más adelante, cuando ya estemos más habituados a su
funcionamiento.
</p>
</div>
</div>
<div id="outline-container-org26b152c" class="outline-3">
<h3 id="org26b152c">Entornos de estilo</h3>
<div class="outline-text-3" id="text-org26b152c">
<p>
Llamo <i>entorno de estilo</i> a aquel que modifique el aspecto del texto
que contiene. Por ejemplo, el entorno <code>quote</code> nos permite citar
brevemente a otros autores de forma sencilla y <i>LaTeX</i> modificará el
aspecto del texto para que quede remarcado que pertenece a otro autor.
</p>

<p>
Aparte del entorno <code>quote</code> existe otro muy similar llamado
<code>quotation</code>. La diferencia fundamental entre ambos es que <code>quotation</code>
soporta citas largas que se pueden desplegar en varias páginas
incluso. Otro detalle entre ambos, es que el primero no utiliza
sangrías en la primera línea, lo que puede hacer confuso encontrar un
párrafo atendiendo sólo a su margen izquierdo.
</p>

<p>
Otros entornos que podríamos describir en este apartado serían
<code>verbatim</code> y <code>verse</code>. Ya había hablado del comando <code>\verb</code>, el entorno
<code>verbatim</code> proporciona una manera sencilla de visualizar <i>comandos</i> de
<i>LaTeX</i> o también nos puede servir para incluir algo de código de
programación en nuestro documento. No abundaré mucho sobre ésto,
porque es un <i>minicurso</i> para psicólogos y, de todas formas, existen
mejores maneras de introducir el código en el documento. Pero haré
también una pequeña referencia al entorno <code>verse</code>. Este entorno nos
proporciona una buena manera de escribir, como su nombre indica,
versos.
</p>
</div>
</div>
</div>
<div id="outline-container-org8814e95" class="outline-2">
<h2 id="org8814e95">A modo de resumen y lo que está por venir</h2>
<div class="outline-text-2" id="text-org8814e95">
<p>
En resumen, sigo necesitando más espacio para lo que quiero hablar.
Como se puede apreciar lo que se puede hablar sólo con lo básico de
<i>LaTeX</i> es muy amplio. Si a eso añadimos la complejidad que pueden
aportar el manejo de paquetes, podría estar escribiendo cientos de
artículos y no se agotaría el tema.
</p>

<p>
En la próxima entrega quiero hablar sobre entornos flotantes, como las
figuras y las tablas. Sin que sirva de precedente incluiré un paquete
que se llama <code>longtables</code> que como su nombre indica nos sirve para
definir tablas que pueden ocupar más de una página. Lo incluyo, porque
es habitual encontrar en textos de psicología con grandes tablas donde
se ordenan de alguna manera diversos conceptos y para hacer eso, se
necesita ese paquete.
</p>

<p>
Os recuerdo que en la introducción de este artículo hay enlace a los
ficheros <code>TeX</code> y <code>PDF</code> con los ejemplos.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
El cambio de cursor depende de la aplicación que utilicemos
para leer el <code>pdf</code> y es posible que las aplicaciones más sencillas no
lo muestren, o incluso no puedan utilizar el enlace por no tener
habilitada esa característica.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Recuerda que cambiamos el color de los enlaces en el punto
anterior, si no lo hiciste puede que te aparezca en rojo.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/latex/index.html">latex</a> ]]></description>
  <category><![CDATA[latex]]></category>
  <link>https://notxor.nueva-actitud.org/2021/03/26/minicurso-de-latex-para-psicologos-iii.html</link>
  <pubDate>Fri, 26 Mar 2021 08:49:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Minicurso de LaTeX para psicólogos II]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-03-22</div>
<p>
En la anterior entrega hablé por encima de las ventajas que tiene un
sistema de generación de documentos escritos como <i>LaTeX</i> sobre los
más extendidos <i>editores de documentos</i>. Como principal inconveniente
conté que <i>LaTeX</i> no te deja hacer lo que quieres directamente. Y
también expliqué por encima que, efectivamente, los cambios que
haremos sobre nuestro documento tienen que ser meditados y
conscientes. Para ello, se utiliza el concepto de <i>paquete</i>, cualquier
cosa, cualquier necesidad que tengas, a la hora de producir un
documento impreso, seguramente ya lo habrá tenido alguien y habrá
creado un <i>paquete</i> que facilite la edición. Por tanto, en esta
ocasión hablaré sobre <i>paquetes</i>, sobre la estructura de los
documentos y sobre las fuentes y sus características.
</p>
<div id="outline-container-org5039571" class="outline-2">
<h2 id="org5039571">Los paquetes y las fuentes</h2>
<div class="outline-text-2" id="text-org5039571">
<p>
Ya vimos en la anterior entrega que utilizábamos varios paquetes para
poder trabajar: uno cambiaba el idioma de inglés, ─el idioma por
defecto─, a español, <code>babel</code>; otro cambiaba el formato del texto,
─ASCII por defecto─, a <code>utf8</code> (o <code>latin1</code>) que utilizan los
ordenadores modernos, <code>inputenc</code>; por último, otro modificaba las
fuentes de salida, de forma similar a como las cambia para la entrada
el paquete anterior, <code>fontenc</code>.
</p>

<p>
Con la prueba que hicimos vimos un documento impreso que aunque,
correcto formalmente, tenía un aspecto un poco desfasado. La fuente
que utiliza es <i>antigua</i>, no se me ocurre otra palabra para
definirla. ¿La podemos cambiar? ¿Podemos cambiar el tamaño?
</p>

<p>
Vamos a cambiar la fuente básica del documento a una de las fuentes
que más utilizo. Para ello sólo tengo que añadir un línea en la
cabecera de nuestro documento que <i>importe</i> la fuente que queremos a
nuestro trabajo:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>{<span style="color: #50fa7b; font-weight: bold;">palatino</span>}
</pre>
</div>

<p>
Al final del documento pondré un enlace al fichero <i>TeX</i> tal y como
quede después de todos los cambios que vaya haciendo. De momento vamos
a concentrarnos en el cambio de fuente. Por ver comparados los dos
resultados, los pongo juntos:
</p>


<figure id="org05c0843">
<img src="./imagenes/comparacion-fuentes.png" alt="comparacion-fuentes.png">

</figure>

<p>
Como se puede ver, <i>palatino</i> (a la izquierda) es un tipo de fuente
más legible y bonita que la configurada por defecto. La letra se ha
cambiado en todo el documento, ya veremos otras florituras como
cambiar el tipo en las cabeceras. ¿A alguien le ha pasado alguna vez
que han querido cambiar la fuente de su documento y ésta cambia unas
veces sí y otras no? En <i>LaTeX</i> no pasa, cambia todo porque todo el
texto es del mismo <i>estilo</i> y los cambios que tiene que hacer los
marcas sólo en las partes donde es necesario. Sin embargo, en un
editor de documentos es posible que un párrafo esté marcado como
<code>cuerpo de texto</code> mientras el siguiente sea <code>párrafo normal</code>... cuando
ambos coinciden no hay problema, pero si modificas el formato de
<code>párrafo normal</code> y hay párrafos marcados como <code>cuerpo de texto</code> que no
has visto, resulta que tienes que ir párrafo a párrafo haciendo el
cambio.
</p>

<p>
¿Queda mejor el cambio de letra? <i>Sí, pero he probado yo a hacerlo y
me ha dado un error...</i> Es posible, comprueba que tienes instalado el
paquete de la fuente <code>Palatino</code>. Recuerda que <i>LaTeX</i> no usa las
fuentes del sistema sino las propias y aunque tengas la fuente
instalada en el sistema se producirá un error si no está instalado el
paquete de <i>LaTeX</i>. Tienes que comprobarlo en el gestor de paquetes de
<i>LaTeX</i>.
</p>

<p>
Otra de las cosas que pueden resultar chocantes es la forma de definir
los márgenes y la geometría de la página. Supongo que os resultó
extraño estar definiéndolas haciendo sumas y restas como en nuestro
encabezamiento y teniendo en cuenta el tamaño de la zona impresa.
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6;">\textheight</span> = 21cm          <span style="color: #6272a4;">% largo del texto impreso (por defecto 19cm)
</span><span style="color: #ff79c6;">\textwidth</span> = 18cm           <span style="color: #6272a4;">% ancho texto impreso (por defecto 14cm)
</span><span style="color: #ff79c6;">\topmargin</span> = -1cm           <span style="color: #6272a4;">% margen superior (por defecto 3cm): 3-1=2cm
</span><span style="color: #ff79c6;">\oddsidemargin</span> = -1.5cm     <span style="color: #6272a4;">% margen izquierdo (por defecto 4.5cm): 4.5-1.5=3cm</span>
</pre>
</div>

<p>
Hay un paquete que nos facilita las cosas a la hora de lidiar con
estos aspectos: <code>geometry</code>. Con este paquete podemos sustituir todo lo
anterior por una sola línea:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\usepackage</span>[<span style="color: #f8f8f2; font-weight: bold;">a4paper,margin=3cm</span>]{<span style="color: #50fa7b; font-weight: bold;">geometry</span>}
</pre>
</div>

<p>
Por supuesto, <code>geometry</code> es más complejo que sólo lo que he puesto
ahí, no tienes más que mirar su documentación. Podemos definir cada
margen de forma separada con las opciones <code>top</code>, <code>bottom</code>, <code>left</code> y
<code>right</code>, el espacio para cabeceras y pies, guardar diversas geometrías
de página y llamarlas según lo necesitemos, etc. Todas esas opciones
pasan de lo que es el uso básico. Pero es bueno tener presente que
podemos utilizar el comando <code>\newgeometry</code> para definir las opciones
de la geometría para aquellas páginas que se necesite cambiar.  Toda
la geometría depende también de las opciones del documento. Lo que
hace <code>a4paper</code> en las opciones del paquete es definir el <code>A4</code> como el
tamaño de papel de la geometría en adelante. Lo normal, es que lo
hayamos definido al declarar el documento.
</p>

<p>
Por ejemplo, el tamaño de texto que utiliza <i>LaTeX</i> por defecto es
<code>10pt</code>, como dije en el artículo anterior. Lo podemos ajustar en las
opciones de documento:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\documentclass</span>[<span style="color: #f8f8f2; font-weight: bold;">a4,11pt,doubleside</span>]{<span style="color: #50fa7b; font-weight: bold;">article</span>}
</pre>
</div>

<p>
Las opciones del documento se definen como en cualquier paquete. A mí
me gusta pensar que, al fin y al cabo, <i>LaTeX</i> es un <i>paquete</i> que
funciona sobre <i>TeX</i>.
</p>

<p>
Ahí, por ejemplo, se define que utilizamos papel <code>A4</code>, con una fuente
de <code>11pt</code> y que el documento se imprimirá a doble cara, es decir, que
la <i>geometría</i> de las páginas pares e impares será distinta.
</p>

<p>
Los tamaños de las fuentes pueden ser <code>10pt</code>, <code>11pt</code> y <code>12pt</code>. Si
necesitamos jugar con otros tamaños, podemos utilizar el tipo de
documento <i>memoria</i>: <code>\documentclass{memoir}</code>, donde se pueden definir
los siguientes tamaños: <code>9pt</code>, <code>10pt</code>, <code>11pt</code>, <code>12pt</code>, <code>14pt</code>, <code>17pt</code>,
<code>20pt</code>, <code>25pt</code>, <code>30pt</code>, <code>36pt</code>, <code>48pt</code> y <code>60pt</code>. Esos son los tamaños
básicos, que se pueden modificar con los comandos relativos que vimos
ya en el artículo anterior y que podemos ver en el ejemplo anterior.
</p>

<p>
Además, podemos modificar con qué fuentes vamos a trabajar. Para
ilustrarlo he añadido a nuestro fichero de prueba la siguiente
sección<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\section</span>{<span style="color: #50fa7b; font-size: 110%; font-weight: bold;">Fuentes</span>}

Podemos, de todas formas, hacer un cambio de fuente temporal, si es lo
que queremos.

<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">table</span>}[!h]
 <span style="color: #ff79c6; font-weight: bold;">\centering</span>
 <span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">tabular</span>}{l l}
<span style="color: #ff79c6; font-weight: bold;">\hline</span>
  <span style="color: #ff79c6; font-weight: bold;">\textbf</span>{<span style="color: #bd93f9;">Comando</span>} <span style="color: #ff5555;">&amp;</span> <span style="color: #ff79c6; font-weight: bold;">\textbf</span>{<span style="color: #bd93f9;">Resultado</span>} <span style="color: #ff5555;">\\</span>
<span style="color: #ff79c6; font-weight: bold;">\hline</span>
 <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|{</span><span style="color: #ffb86c;">\fontfamily</span><span style="color: #ffb86c;">{pag}</span><span style="color: #ffb86c;">\selectfont</span><span style="color: #ffb86c;"> Avant Garde}|</span>              <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6;">\fontfamily</span>{pag}<span style="color: #ff79c6;">\selectfont</span> Avant Garde} <span style="color: #ff5555;">\\</span>
 <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|{</span><span style="color: #ffb86c;">\fontfamily</span><span style="color: #ffb86c;">{fvs}</span><span style="color: #ffb86c;">\selectfont</span><span style="color: #ffb86c;"> Bitstream Vera Sans}|</span>      <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6;">\fontfamily</span>{fvs}<span style="color: #ff79c6;">\selectfont</span> Bitstream Vera Sans} <span style="color: #ff5555;">\\</span>
 <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|{</span><span style="color: #ffb86c;">\fontfamily</span><span style="color: #ffb86c;">{pbk}</span><span style="color: #ffb86c;">\selectfont</span><span style="color: #ffb86c;"> Bookman}|</span>                  <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6;">\fontfamily</span>{pbk}<span style="color: #ff79c6;">\selectfont</span> Bookman} <span style="color: #ff5555;">\\</span>
 <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|{</span><span style="color: #ffb86c;">\fontfamily</span><span style="color: #ffb86c;">{bch}</span><span style="color: #ffb86c;">\selectfont</span><span style="color: #ffb86c;"> Charter}|</span>                  <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6;">\fontfamily</span>{bch}<span style="color: #ff79c6;">\selectfont</span> Charter} <span style="color: #ff5555;">\\</span>
 <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|{</span><span style="color: #ffb86c;">\fontfamily</span><span style="color: #ffb86c;">{cmr}</span><span style="color: #ffb86c;">\selectfont</span><span style="color: #ffb86c;"> Computer Modern}|</span>          <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6;">\fontfamily</span>{cmr}<span style="color: #ff79c6;">\selectfont</span> Computer Modern} <span style="color: #ff5555;">\\</span>
 <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|{</span><span style="color: #ffb86c;">\fontfamily</span><span style="color: #ffb86c;">{pcr}</span><span style="color: #ffb86c;">\selectfont</span><span style="color: #ffb86c;"> Courier}|</span>                  <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6;">\fontfamily</span>{pcr}<span style="color: #ff79c6;">\selectfont</span> Courier} <span style="color: #ff5555;">\\</span>
 <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|{</span><span style="color: #ffb86c;">\fontfamily</span><span style="color: #ffb86c;">{phv}</span><span style="color: #ffb86c;">\selectfont</span><span style="color: #ffb86c;"> Helvetica}|</span>                <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6;">\fontfamily</span>{phv}<span style="color: #ff79c6;">\selectfont</span> Helvetica} <span style="color: #ff5555;">\\</span>
 <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|{</span><span style="color: #ffb86c;">\fontfamily</span><span style="color: #ffb86c;">{fi4}</span><span style="color: #ffb86c;">\selectfont</span><span style="color: #ffb86c;"> Inconsolata}|</span>              <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6;">\fontfamily</span>{fi4}<span style="color: #ff79c6;">\selectfont</span> Inconsolata} <span style="color: #ff5555;">\\</span>
 <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|{</span><span style="color: #ffb86c;">\fontfamily</span><span style="color: #ffb86c;">{lmr}</span><span style="color: #ffb86c;">\selectfont</span><span style="color: #ffb86c;"> Latin Modern}|</span>             <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6;">\fontfamily</span>{lmr}<span style="color: #ff79c6;">\selectfont</span> Latin Modern} <span style="color: #ff5555;">\\</span>
 <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|{</span><span style="color: #ffb86c;">\fontfamily</span><span style="color: #ffb86c;">{lmss}</span><span style="color: #ffb86c;">\selectfont</span><span style="color: #ffb86c;"> Latin Modern Sans}|</span>       <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6;">\fontfamily</span>{lmss}<span style="color: #ff79c6;">\selectfont</span> Latin Modern Sans} <span style="color: #ff5555;">\\</span>
 <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|{</span><span style="color: #ffb86c;">\fontfamily</span><span style="color: #ffb86c;">{lmtt}</span><span style="color: #ffb86c;">\selectfont</span><span style="color: #ffb86c;"> Latin Modern Typewriter}|</span> <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6;">\fontfamily</span>{lmtt}<span style="color: #ff79c6;">\selectfont</span> Latin Modern Typewriter} <span style="color: #ff5555;">\\</span>
 <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|{</span><span style="color: #ffb86c;">\fontfamily</span><span style="color: #ffb86c;">{pnc}</span><span style="color: #ffb86c;">\selectfont</span><span style="color: #ffb86c;"> New Century Schoolbook}|</span>   <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6;">\fontfamily</span>{pnc}<span style="color: #ff79c6;">\selectfont</span>  New Century Schoolbook} <span style="color: #ff5555;">\\</span>
 <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|{</span><span style="color: #ffb86c;">\fontfamily</span><span style="color: #ffb86c;">{ppl}</span><span style="color: #ffb86c;">\selectfont</span><span style="color: #ffb86c;"> Palatino}|</span>                 <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6;">\fontfamily</span>{ppl}<span style="color: #ff79c6;">\selectfont</span>  Palatino} <span style="color: #ff5555;">\\</span>
 <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|{</span><span style="color: #ffb86c;">\fontfamily</span><span style="color: #ffb86c;">{ptm}</span><span style="color: #ffb86c;">\selectfont</span><span style="color: #ffb86c;"> Times}|</span>                    <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6;">\fontfamily</span>{ptm}<span style="color: #ff79c6;">\selectfont</span>  Times} <span style="color: #ff5555;">\\</span>
 <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|{</span><span style="color: #ffb86c;">\fontfamily</span><span style="color: #ffb86c;">{put}</span><span style="color: #ffb86c;">\selectfont</span><span style="color: #ffb86c;"> Utopia}|</span>                   <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6;">\fontfamily</span>{put}<span style="color: #ff79c6;">\selectfont</span>  Utopia} <span style="color: #ff5555;">\\</span>
 <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|{</span><span style="color: #ffb86c;">\fontfamily</span><span style="color: #ffb86c;">{pzc}</span><span style="color: #ffb86c;">\selectfont</span><span style="color: #ffb86c;"> Zapf Chancery}|</span>            <span style="color: #ff5555;">&amp;</span> {<span style="color: #ff79c6;">\fontfamily</span>{pzc}<span style="color: #ff79c6;">\selectfont</span>  Zapf Chancery} <span style="color: #ff5555;">\\</span>
<span style="color: #ff79c6; font-weight: bold;">\hline</span>
 <span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">tabular</span>}
 <span style="color: #ff79c6; font-weight: bold;">\caption</span>{<span style="color: #8be9fd; font-style: italic;">Colecci&#243;n de fuentes</span>}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">table</span>}
</pre>
</div>

<p>
Aunque todavía no hemos visto cómo hacer tablas, he utilizado una para
mostrar el comando y su resultado. Si intentas copiar y pegar el
código anterior, comprueba que tienes instaladas las fuentes que se
usan aquí. El resultado es el siguiente:
</p>


<figure id="org512c445">
<img src="./imagenes/Captura-pantalla_tipos-fuente.png" alt="Captura-pantalla_tipos-fuente.png">

</figure>

<p>
Si estás acostumbrado a utilizar las fuentes del sistema y prefieres
utilizarlas, también se puede, pero no con <i>TeX</i> o <i>LaTeX</i>
directamente, sino con los derivados <i>XeTeX</i> o <i>XeLaTeX</i>. Como esos
aspectos se salen fuera de la intención del minicurso de <i>LaTeX</i>, lo
dejo para que lo investiguéis.
</p>

<p>
De momento, con los comandos que nos proporciona <i>LaTeX</i> para manejar
las fuentes estamos servidos. Por ejemplo, para definir la fuente
general, como hemos visto, utilizamos el paquete que queramos. Los más
habituales son:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<tbody>
<tr>
<td class="org-left">\usepackage{pslatex}</td>
<td class="org-left">\usepackage{bookman}</td>
</tr>

<tr>
<td class="org-left">\usepackage{helvet}</td>
<td class="org-left">\usepackage{palatino}</td>
</tr>

<tr>
<td class="org-left">\usepackage{newcent}</td>
<td class="org-left">\usepackage{pxfonts}</td>
</tr>

<tr>
<td class="org-left">\usepackage{txfonts}</td>
<td class="org-left">\usepackage{concrete}</td>
</tr>

<tr>
<td class="org-left">\usepackage{cmbright}</td>
<td class="org-left">\usepackage{fourier}</td>
</tr>

<tr>
<td class="org-left">\usepackage{mathptmx}</td>
<td class="org-left">\usepackage{mathpazo}</td>
</tr>
</tbody>
</table>

<p>
Por supuesto, <a href="https://tug.org/FontCatalogue/">hay un extenso catálogo de fuentes</a> que podemos
utilizar. No es necesario tenerlas todas instaladas, pero cuando las
necesitemos lo que tenemos que instalar su paquete correspondiente.
Estos paquetes suelen proporcionar comandos específicos y opciones
para seleccionar entre las variantes de la fuente cuál se
utilizará. Es muy recomendable echarle un vistazo si queremos hacer
algún tipo de <i>floritura</i> como veremos ahora. Sin embargo, la mayoría
de las veces será suficiente con incluir el paquete y no preocuparnos
demasiado del aspecto que tendrá el documento, porque normalmente las
opciones por defecto suelen arrojar buenos resultados.
</p>
</div>
<div id="outline-container-org16dbe81" class="outline-3">
<h3 id="org16dbe81">Atributos de las fuentes</h3>
<div class="outline-text-3" id="text-org16dbe81">
<p>
Podía ser titulado este apartado, <i>cómo cometer todos los errores que
cometemos en los editores de documentos respecto a las fuentes</i>. Pero
quedaba un título muy largo para una sección. Como digo, no se suelen
utilizar los atributos de las fuentes directamente, salvo cuando ya
estamos en condiciones de crear, o si lo prefieres <i>programar</i>,
nuestros propios estilos para el documento. Lo pongo aquí para que se
vea que se puede hacer lo mismo, pero con algo más de esfuerzo.
</p>

<p>
Todas las fuentes en <i>LaTeX</i> tienen cinco atributos:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Atributo</th>
<th scope="col" class="org-left">Significado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><i>encoding</i></td>
<td class="org-left">Valore numéricos de los caracteres</td>
</tr>

<tr>
<td class="org-left"><i>family</i></td>
<td class="org-left"><i>Familia</i> de la fuente</td>
</tr>

<tr>
<td class="org-left"><i>serie</i></td>
<td class="org-left">Representa el <i>peso</i> de la fuente</td>
</tr>

<tr>
<td class="org-left"><i>shape</i></td>
<td class="org-left">Es la forma de la fuente</td>
</tr>

<tr>
<td class="org-left"><i>size</i></td>
<td class="org-left">Tamaño de la fuente</td>
</tr>
</tbody>
</table>

<p>
El <i>encoding</i> lo podemos seleccionar con el comando <code>\char</code>, por
ejemplo, <code>\char126</code> nos devolverá un carácter <code>~</code>. En <i>TeX</i> y en
<i>LaTeX</i> el número no puede sobrepasar el valor <code>255</code>, pero en <i>XeTeX</i>
o <i>XeLaTeX</i> se puede utilizar el código <code>utf</code> en hexadecimal.
</p>

<p>
En la lista que pusimos antes de las fuentes ya utilizamos el comando
<code>\fontfamily</code> y podemos ver cómo funciona. No voy a darle más vueltas,
sólo hay que mirar los ejemplos anteriores.
</p>

<p>
La <i>serie</i> de la fuente se determina con:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Valor</th>
<th scope="col" class="org-left">Significado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>\fontseries{}</code></td>
<td class="org-left"><i>Peso</i> de la fuente</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">m</td>
<td class="org-left">Medium</td>
</tr>

<tr>
<td class="org-left">b</td>
<td class="org-left">Bold</td>
</tr>

<tr>
<td class="org-left">bx</td>
<td class="org-left">Bold extended</td>
</tr>

<tr>
<td class="org-left">sb</td>
<td class="org-left">Semi-bold</td>
</tr>

<tr>
<td class="org-left">c</td>
<td class="org-left">Condensed</td>
</tr>
</tbody>
</table>

<p>
La <i>forma</i> puede ser:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Valor</th>
<th scope="col" class="org-left">Significado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>\fontshape{}</code></td>
<td class="org-left"><i>Forma</i> de la fuente</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">n</td>
<td class="org-left">Normal</td>
</tr>

<tr>
<td class="org-left">it</td>
<td class="org-left">Itálica</td>
</tr>

<tr>
<td class="org-left">sl</td>
<td class="org-left"><i>Slanted</i>, oblicua</td>
</tr>

<tr>
<td class="org-left">sc</td>
<td class="org-left"><i>Small Caps</i></td>
</tr>
</tbody>
</table>

<p>
El <i>tamaño</i> necesita un parámetro adicional al tamaño de la fuente,
que es <i>el interlineado</i>. Es decir, el tamaño de la separación entre
líneas del texto. Un valor de <code>1</code> especifica una separación idéntica
al tamaño de letra que definimos. Por tanto, la forma en que lo
haremos será <code>\fontsize{pt}{1}</code>, dónde <i>pt</i> indica el tamaño en puntos
que queremos para nuestra fuente. Por poner un ejemplo, si escribimos
en nuestro documento:
</p>

<div class="org-src-container">
<pre class="src src-latex">{<span style="color: #ff79c6;">\fontfamily</span>{bch}<span style="color: #ff79c6;">\fontsize</span>{30}{1}<span style="color: #ff79c6;">\fontshape</span>{sc}<span style="color: #ff79c6;">\selectfont</span>{Qu&#233; pasada!}}<span style="color: #ff79c6; font-weight: bold;">\normalfont</span>
Tengo todo el poder en la punta de mis dedos.
</pre>
</div>

<p>
Por explicar un poco más el comando que está escrito encerrado entre
<code>{}</code>:
</p>

<dl class="org-dl">
<dt><code>\fontfamily{bch}</code></dt><dd>Define la familia utilizada a <i>Charter</i>.</dd>
<dt><code>\fontsize{30}{1}</code></dt><dd>Establece un tamaño de <code>30pt</code> con un
interlineado de <code>1</code>.</dd>
<dt><code>\fontshape{sc}</code></dt><dd>El texto se escribirá en <i>small caps</i> (pequeñas
mayúsculas).</dd>
<dt><code>\selectfont</code></dt><dd>recoge los parámetros anteriores y se los aplica al
elemento <code>{Qué pasada}</code>.</dd>
</dl>

<p>
Obsérvese la vuelta al tipo de fuente general del documento con el
comando <code>\normalfont</code>. Con estas pocas líneas obtendremos un resultado
tal que:
</p>


<figure id="org1afca5a">
<img src="./imagenes/Captura-pantalla_cambio-fuente.png" alt="Captura-pantalla_cambio-fuente.png">

</figure>

<p>
Si a todo ésto le añadimos que podemos producir un salto de línea
donde queramos con el comando <code>\\</code> o un salto de página con
<code>\pagebreak</code>, ya podemos cometer todos los errores que hacemos cuando
utilizamos un <i>editor de documentos</i> sin ningún tipo de problemas.
</p>

<p>
Este tipo de cosas no cuentan como aspectos básicos de <i>LaTeX</i>, no te
preocupes si hay algo que se te escapa. Lo cuento porque es importante
que seas consciente de dos cosas:
</p>

<ol class="org-ol">
<li>Puedes hacer muchas más cosas de las que <i>a priori</i> dan a entender
los artículos introductorios que leo por ahí. Pero hacerlas implica
un gasto de energía, que impedirá que lo hagas si no es
estrictamente necesario.</li>
<li>Cualquier cosa que necesites seguramente ya estará implementada en
un paquete, mira en la documentación, averigua por <i>Internet</i>.
Seguro que alguien más avanzado necesitó algo parecido e implementó
un paquete o preparó una plantilla, que te facilitarán la vida.</li>
</ol>
</div>
</div>
</div>
<div id="outline-container-org30352b0" class="outline-2">
<h2 id="org30352b0">Estructura de los documentos y referencias internas</h2>
<div class="outline-text-2" id="text-org30352b0">
<p>
La estructura de los documentos viene definida por su tipo, como
dijimos en el artículo anterior. La forma más habitual de tener una
referencia del contenido de nuestro documento es hacer una <i>tabla de
contenidos</i> que nos muestre dicha estructura. Simplemente tenemos que
ir definiendo las cabeceras con el comando apropiado. Dichas cabeceras
se definen con los siguientes comandos:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Comandos</th>
<th scope="col" class="org-left">Significado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>\part</code></td>
<td class="org-left">Agrupación superior de contenidos</td>
</tr>

<tr>
<td class="org-left"><code>\chapter</code></td>
<td class="org-left">Capítulo</td>
</tr>

<tr>
<td class="org-left"><code>\section</code></td>
<td class="org-left">Sección</td>
</tr>

<tr>
<td class="org-left"><code>\subsection</code></td>
<td class="org-left">Apartado</td>
</tr>

<tr>
<td class="org-left"><code>\subsubsection</code></td>
<td class="org-left">Subapartado</td>
</tr>

<tr>
<td class="org-left"><code>\paragraph</code></td>
<td class="org-left">Punto</td>
</tr>

<tr>
<td class="org-left"><code>\subparagraph</code></td>
<td class="org-left">Subpunto</td>
</tr>
</tbody>
</table>

<p>
Estos comandos tienen su equivalente con <code>*</code>, la diferencia es que
cuando definimos un capítulo con <code>\chapter*{Nombre}</code>, el capítulo y
sus apartados internos no se mostrarán en la tabla de contenidos del
documento.
</p>

<p>
Los editores de documentos nos han acostumbrado a citar nuestros
apartados, figuras, tablas con referencias vagas. Si citamos la
sección <i>2.3</i> y resulta que luego decidimos añadir otro apartado
delante de esa sección, la numeración cambia y tenemos que repasar el
texto para modificar todas esas referencias que hayamos puesto a
mano. Eso es un hecho que nos coarta a la hora de redactar de forma
directa nuestras referencias con los <i>editores de documentos</i>.
</p>

<p>
<i>LaTeX</i> nos proporciona el comando <code>\label{}</code> para señalar el objeto
referenciado. Por ejemplo, en nuestro documento de pruebas, he añadido
un par de etiquetas. La primera en la sección y la segunda en la tabla:
</p>

<div class="org-src-container">
<pre class="src src-latex">...
<span style="color: #ff79c6; font-weight: bold;">\section</span>{<span style="color: #50fa7b; font-size: 110%; font-weight: bold;">Fuentes</span>}<span style="color: #ff79c6; font-weight: bold;">\label</span>{<span style="color: #bd93f9;">sec:fuentes</span>}
...
   <span style="color: #ff79c6; font-weight: bold;">\caption</span>{<span style="color: #8be9fd; font-style: italic;">Colecci&#243;n de fuentes</span>}<span style="color: #ff79c6; font-weight: bold;">\label</span>{<span style="color: #bd93f9;">tab:fuentes</span>}
...
</pre>
</div>

<p>
Puedes utilizar cualquier nombre que se te ocurra para las etiquetas,
como <code>a32EEfun4</code>, siempre que luego te acuerdes del mismo. Lo más
racional es llamar a las cosas por un nombre significativo. En el
ejemplo, quiero referenciar un apartado que habla sobre <i>fuentes</i> y
una tabla que las muestra. Si las dos etiquetas fueran <code>fuentes</code> no se
podría distinguir a cual de las dos te refieres. Por eso es muy
interesante utilizar el truco de anteponer en la etiqueta un preámbulo
<code>sec:</code>, o <code>fig:</code>, o <code>tab:</code> según el tipo de objeto al que queremos
referenciar. Como digo es voluntario, pero es una forma de que sepamos
a primera vista, si estamos referenciando una sección de texto, una
figura o una tabla, respectivamente.
</p>

<p>
Los comandos de referencia son dos: <code>\ref</code> y <code>\pageref</code>. El primero
nos devolverá el <i>número</i> del objeto, por eso <code>\label</code> debe estar
anexado al título del apartado o al <i>caption</i> de la tabla o figura,
que son los que <i>conocen</i> dicho número.  Para ver correctamente el
resultado de las referencias necesitaremos repetir la <i>compilación</i>
del documento. La primera pasada lo que hace <i>LaTeX</i> es crear un
fichero auxiliar donde guarda los números de todas las etiquetas y la
segunda pasada los coloca en su lugar. Si nos quedamos con el
documento que genera corriendo sólo una vez veremos algo así:
</p>


<figure id="org11c016a">
<img src="./imagenes/Captura-pantalla_ref-incompletas.png" alt="Captura-pantalla_ref-incompletas.png">

</figure>

<p>
Podemos apreciar que utiliza el conjunto <code>??</code> para indicar que le
falta un hervor todavía. Después de dárselo ya veremos algo como:
</p>


<figure id="org943d7ea">
<img src="./imagenes/Captura-pantalla_ref-completas.png" alt="Captura-pantalla_ref-completas.png">

</figure>

<p>
Resulta un poco laborioso si lo hacemos desde la línea de comandos.
La situación más compleja que se nos puede presentar es generar un
documento que tenga hacer una <i>tabla de contenidos</i>, o índices de
tablas y/o figuras y cuente además con bibliografía y múltiples
enlaces internos. En este caso tendremos que utilizar cuatro pasos:
</p>

<ol class="org-ol">
<li>Generación, con <code>pdflatex</code>, del primer <code>pdf</code> y de los archivos
auxiliares de índices, referencias y otros enlaces. Se analizan
todas las referencias menos las citas bibliográficas.</li>
<li>Generación del segundo <code>pdf</code> con la sustitución de todos los
enlaces e índices y referencias incrustadas, salvo la
bibliografía.</li>
<li>Generar el índice de citas bibliográficas con la herramienta
adecuada. La tradicional es <code>bibtex</code>, pero en la actualidad hay
otras herramientas como <code>biber</code>, <code>biblatex</code> o <code>natbib</code>. Ya hablaré
sobre <i>bibliografía</i> en otra entrega de este <i>minicurso</i>.</li>
<li>Generar el <code>pdf</code> definitivo con las citas bibliográficas y la
bibliografía perfectamente ensambladas.</li>
</ol>

<p>
Si estás utilizando algún editor dedicado, seguramente hará todos los
pasos por ti, o por lo menos, como hace <i>Emacs</i> avisará de que hay una
tarea más que realizar y cuál es.
</p>
</div>
<div id="outline-container-orgc7fa740" class="outline-3">
<h3 id="orgc7fa740">Cabeceras de sección demasiado largas</h3>
<div class="outline-text-3" id="text-orgc7fa740">
<p>
Hay ocasiones que necesitamos ponerle a una sección un título
perfectamente descriptivo de lo que es. Lo más habitual es que un
título siendo descriptivo será también demasiado largo y nos estropee
los índices o los encabezados de página<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. Por ejemplo, si
definimos una cabecera de una sección tal que:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\section</span>{<span style="color: #50fa7b; font-size: 110%; font-weight: bold;">Esto es un t&#237;tulo muy largo y muy necesario para demostrar
  que mi capacidad de s&#237;ntesis es mediocre tirando a nula</span>}
</pre>
</div>

<p>
obtenemos, como es natural, un índice y un título con este aspecto:
</p>


<figure id="org7d76626">
<img src="./imagenes/Captura-pantalla_indice-largo.png" alt="Captura-pantalla_indice-largo.png">

</figure>

<p>
En el texto nos puede servir, al fin y al cabo no suele haber
elementos alrededor que se descuadren por tener un vecino indeseable
como ese. Sin embargo, en el índice puede resultar molesto tener un
elemento que ocupa más de una línea. Si en lugar de definir la cabecera
como hemos visto antes, lo definimos así:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\section</span>[<span style="color: #f8f8f2; font-weight: bold;">Un t&#237;tulo largo</span>]{<span style="color: #50fa7b; font-size: 110%; font-weight: bold;">Esto es un t&#237;tulo muy largo y muy necesario para demostrar
  que mi capacidad de s&#237;ntesis es mediocre tirando a nula</span>}
</pre>
</div>

<p>
Lo único que hemos cambiado es que hemos añadido una <i>opción</i> de
título. El resultado se verá como sigue:
</p>


<figure id="orgcd390f3">
<img src="./imagenes/Captura-pantalla_indice-acortado.png" alt="Captura-pantalla_indice-acortado.png">

</figure>

<p>
Como podemos apreciar, el título en la página sigue mostrándose, de
manera idéntica, en toda su extensión. Sin embargo, en el índice se ha
empleado el título alternativo que le hemos proporcionado en la
opción.
</p>
</div>
</div>
</div>
<div id="outline-container-org1f04d68" class="outline-2">
<h2 id="org1f04d68">Resumen</h2>
<div class="outline-text-2" id="text-org1f04d68">
<p>
Creo que este curso introductorio se me está yendo de las manos,
cuento tres <i>tontás</i> y el resto se va a la siguiente entrega. Apenas
he hablado un poco sobre las fuentes y sobre las cosas que no hay que
hacer... o sí, que nunca se sabe, porque poder se pueden hacer.
</p>

<p>
Pero también hemos visto cómo se utilizan los comandos más
habituales. Las pruebas las voy colocando en un archivo que podéis
descargar también en el siguiente enlace:
</p>

<ul class="org-ul">
<li><a href="./imagenes/texto-prueba.tex">Código en <i>LaTeX</i></a></li>
<li><a href="./imagenes/texto-prueba.pdf">Resultado en PDF</a></li>
</ul>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Recuerda siempre que debe estar delante del cierre de documento
<code>\end{document}</code>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Que ya veremos que se puede hacer que las cabeceras y los pies
de página se pueden configurar con diversa información y diseño. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/latex/index.html">latex</a> ]]></description>
  <category><![CDATA[latex]]></category>
  <link>https://notxor.nueva-actitud.org/2021/03/22/minicurso-de-latex-para-psicologos-ii.html</link>
  <pubDate>Mon, 22 Mar 2021 10:10:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Minicurso de LaTeX para psicólogos]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-03-20</div>
<p>
No sé cuánto me ocupará, es muy probable que tenga que dividirlo en
varias entregas para no hacerlas demasiado grandes. Mi intención con
este artículo es servir de introducción al empleo de <i>LaTeX</i> para la
generación de documentos. Está enfocado a psicólogos porque soy
psicólogo y porque quiero que sirva un poco de ayuda a mis compañeros
del <i>grupo de trabajo del Colegio Oficial de Profesionales de la
Psicología</i> de Aragón, puesto que estoy generando la documentación de
trabajo que generamos con este sistema. Por tanto, está dedicado,
especialmente a mis compañeros psicólogos. Disculpadme el resto de
posibles lectores si les presto más atención a ellos que al público en
general...  y quizá me ponga algo más pesado con el <a href="https://apastyle.apa.org/">estilo de la
APA</a><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, algo que es <i>de facto</i> el formato estándar para publicar
<i>papers</i> sobre psicología, especialmente en el <i>APA Journal</i>. Con
<i>LaTeX</i> conseguiremos ceñirnos a ese estándar de forma <i>automágica</i>.
</p>
<div id="outline-container-org34a2b55" class="outline-2">
<h2 id="org34a2b55">¿Por qué usar <i>LaTeX</i> para generar documentos?</h2>
<div class="outline-text-2" id="text-org34a2b55">
<p>
En el trabajo del día a día de un psicólogo se generan bastantes
documentos (cartas, informes, artículos...) y para la mayoría de
profesionales la aplicación estrella es un <i>editor de documentos</i> del
tipo <i>wysiwyg</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. Puede parecer que es buena idea darle todo el
poder de edición al usuario y ponérselo todo a la vista para que haga
lo que quiera, pero al final eso es un problema más grande que no
hacerlo. Todos hemos sufrido trabajar documentos que nos llegan (o que
producimos) cuyo formato interno es inexistente. Los títulos no se
distinguen lógicamente del contenido salvo porque el autor modifica el
tamaño de la letra (o cambia el tipo) o lo pone en negrita y/o
cursiva...  y como de una vez para otra no se acuerda de qué formato
estaba poniendo unos títulos de sección son en negrita y cursiva, con
la fuente a 15pt, otros en negrita sólo o en cursiva sólo, en 16pt, o
cambia sólo el tamaño a 14pt.  Además, para rematar la jugada, cuando
quiere que haya un salto de página comienza a introducir saltos de
línea con el <i>enter</i>. Para cuando acaba de darle formato a su
documento y está perfectamente orgulloso de su trabajo, hacer una
tabla de contenidos es una tarea titánica.
</p>

<p>
Todas esas prácticas, en última instancia, son un dolor de cabeza
cuando cambiamos nuestro documento a una versión distinta del mismo
<i>editor</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>. Podemos encontrarnos incluso que <i>no puede abrirlo</i>, o
nos pide que lo guardemos en otro formato o mil cosas más. El caso es
que ese documento no se verá bien. Incluso puede ser así con la misma
versión del programa, pero en otra máquina distinta: de repente <i>todo
se descaraja</i>. Los saltos de página no están donde los pusimos, los
saltos de línea (sí, hay gente que salta de línea aún dándole al
<code>&lt;RET&gt;</code>), las tablas se nos salen por los márgenes o el texto
sobreescribe alguna ilustración. ¿Quién no ha lidiado con fichero así?
</p>

<p>
Esos son los problemas de tener toda la capacidad para <i>editar</i> un
documento, pero no saber nada de <i>edición de documentos</i>.  Aún
suponiendo que sabemos utilizar correctamente esta herramienta, vemos
que el resultado impreso de nuestros documentos es sobrepasado con
creces por su equivalente <i>LaTeX</i>, ¿por qué?
</p>

<p>
<i>LaTeX</i> utiliza fuentes de calidad pensadas para ser impresas en
papel, mientras que los otros sistemas utilizan las fuentes que tengas
instaladas en la máquina, que normalmente están pensadas para
visualizarse en pantalla. Además, a no ser que seas diseñador o
<i>editor</i>, el diseño de página será siempre mejor el que produzca
<i>LaTeX</i>. Moverá figuras y tablas donde queden mejor en la impresión,
no donde nosotros las pongamos. Ajustará márgenes y tipos de letra
para conseguir una perfecta armonía del documento. Esto crea un poco
de desconcierto al principio de utilizar <i>LaTeX</i>, pero cuando te
acostumbras a <i>citar</i> la figura con etiquetas, en lugar de escribir
<i>«en la figura anterior»</i> como única indicación, hace que los enlaces
dentro del documento se potencien, mejore la visualización del
documento, la congruencia de los tipos hará que sea más legible y
agradable y, por último, la fuente empleada, junto con su ajuste, le
darán un acabado profesional que no tienes en un <i>editor de
documentos</i>, a no ser que seas diseñador o editor profesional (y en
ese caso tampoco utilizarás un <i>editor de documentos</i> para hacer el
trabajo).
</p>

<p>
Por tanto, <i>LaTeX</i> ayuda a mantener la coherencia del documento sin
esfuerzo, nos proporciona una buena salida impresa permitiéndonos
concentrarnos en el contenido y no en el aspecto (que como sabemos va
a ser muy superior a lo que conseguiríamos nosotros a mano). Pero,
¿tan maravillosa herramienta tiene inconvenientes? Pues sí: ocupa
bastante en nuestro disco duro y tiene una curva de aprendizaje un
poco empinada al principio (aunque muy agradecida al final), por lo
que puede hacer que la gente no quiera gastar su tiempo en
aprenderlo. Algo, que no será tu problema si estás leyendo ésto.
</p>
</div>
</div>
<div id="outline-container-org8a5c0ea" class="outline-2">
<h2 id="org8a5c0ea">Conceptos básicos</h2>
<div class="outline-text-2" id="text-org8a5c0ea">
<p>
Me voy a ahorrar toda la introducción a la historia de <i>TeX</i><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup> y
de su derivada <i>LaTeX</i><sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>. El objetivo que me propongo es
proporcionar una introducción a <i>LaTeX</i> allanando la <i>curva de
aprendizaje</i> lo más posible. Sin embargo, en Internet se pueden
encontrar mucha documentación sobre <i>TeX ─ LaTeX</i>.
</p>
</div>
<div id="outline-container-org2281bc8" class="outline-3">
<h3 id="org2281bc8">Instalación</h3>
<div class="outline-text-3" id="text-org2281bc8">
<p>
En cada sistema operativo hay diversas <i>distribuciones</i> de <i>LaTeX</i> y
contar con pelos y señales todas las opciones de instalación que hay
se sale de lo que es un contenido. Por ejemplo, en <i>windows</i> podemos
encontrar <a href="https://miktex.org/">MikTeX</a>, aunque también estaría bien echarle un ojo a
<a href="http://www.cervantex.es/">CervanTeX</a>. Para <i>Mac</i> podemos encontrar <a href="https://tug.org/mactex/">MacTeX</a> o para <i>GNU/Linux</i>
también podemos encontrar <a href="https://miktex.org/">MikTeX</a>. Todas ellas son distribuciones de
<i>TeX</i> que nos proporcionan el sistema de generación de documentos.
¿Qué paquetes instalar? Pues mi recomendación es hacer una instalación
básica o la <i>recomendada</i> de la herramienta que estemos instalando.
Con posterioridad podemos modificar la lista de paquetes, instalar
algunos que necesitemos o eliminar los que nos estorben. Para estos
primeros pasos con <i>LaTeX</i>, con una instalación mínima será suficiente
y seguramente no necesites instalar nada más.
</p>

<p>
En el futuro, es posible que <i>necesites</i> instalar algún paquete más
por alguna funcionalidad concreta: como generar algún tipo de
documento en especial, tener algún tipo de <i>entorno</i><sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup> especial para
nuestro trabajo, etc.
</p>

<p>
Para generar nuestros documentos necesitamos un <i>editor de texto</i>...
A un editor de texto plano me refiero, no de <i>documentos</i>.
Escribiremos nuestro contenido en <i>texto plano</i> y mediante la
herramienta ejecutable se generará el documento resultante. El formato
de salida dependerá de lo que queramos, pero voy a suponer que lo que
queremos es generar un <code>pdf</code> (aunque hay otros formatos de salida como
<code>dvi</code> o <code>postscript</code>... nos quedaremos, a efectos prácticos, con el
más frecuente en el día a día).
</p>

<p>
Si no estáis acostumbrados a la línea de comandos es posible que os
asustéis al principio con el paso de generar el documento: abrir una
consola y teclear un comando debería ser algo natural. Pero los
usuarios se han acostumbrado a hacerlo todo gráficamente. Por esto, os
recomiendo algún tipo de editor, especialmente si está pensado para la
edición de <i>LaTeX</i> que os facilite la vida. Yo utilizo <i>Emacs</i>, pero
es otro mundo aún más complejo que el propio <i>LaTeX</i> así que sólo os
lo recomiendo en el caso de que queráis profundizar en otras
herramientas y lo vayáis a usar para otras cosas además.
</p>

<p>
Los editores más recomendables para comenzar, si estás empezando con
<i>LaTeX</i>, son <a href="https://www.xm1math.net/texmaker/">TeXMaker</a>, <a href="https://www.texstudio.org/">TeXStudio</a> (ambos son multiplataforma y cuentan
con versiones para <i>windows</i>, <i>Mac</i> y <i>GNU/Linux</i>) o <a href="https://kile.sourceforge.io/index.php">Kile</a>, que cuenta
con versiones para <i>windows</i> y para <i>GNU/Linux</i>. Quizá los más
completos sean los dos primeros y permiten no sólo editar nuestro
documento, sino que nos permiten visualizarlo mientras lo editamos.
Todos tienen <i>autocompletado de sintaxis</i> y bonitos menús y paneles
donde buscar ese comando que nos hace falta. Nos permiten generar
nuestro documento seleccionando algún botón o llamando a algún menú.
</p>

<p>
Si estás pensando que utilizar <i>LaTeX</i> es como programar te dejo que
lo sigas pensando. Es similar, entra un fichero con el código que
entiende el <i>programador</i> pasa por un ejecutable que genera una salida
y consigues el resultado. Programar, realmente es algo más complejo
que escribir documentos con <i>TeX</i>, pero usarlo te puede hacer sentir
como el <i>hacker</i> de la oficina, así que adelante.
</p>
</div>
</div>
<div id="outline-container-orgd78d7a3" class="outline-3">
<h3 id="orgd78d7a3">Estructura del documento</h3>
<div class="outline-text-3" id="text-orgd78d7a3">
<p>
Al principio, nos puede resultar chocante, que tengamos que elegir qué
tipo de documento queremos escribir, sobre todo si estamos
acostumbrados a las herramientas <i>wysiwig</i>, donde nos presentan un
remedo gráfico que representa una página en blanco para que empecemos
a llenarla sin saber de antemano con qué. Por tanto, nos puede
resultar curioso tener que decir antes: ¿Quiero escribir un artículo
(<i>article</i>), un libro (<i>book</i>), una carta (<i>letter</i>)? ¿En qué tamaño
de papel? ¿Con qué márgenes o diseño de página? Las respuestas a estas
preguntas le proporcionan a <i>LaTeX</i> los datos para que haga su
trabajo.
</p>

<p>
La elección puede ser bastante amplia, pues podemos generar documentos
que van desde un cartel hasta un libro, pasando por una tesis
doctoral, una carta, un currículo, o también una <i>presentación</i>.  El
amplio espectro de documentos necesita también diferentes <i>comandos</i>
de edición y si no sabéis por dónde empezar, os recomiendo partir de
una <a href="https://www.latextemplates.com/">plantilla ya hecha</a>, pero antes debéis saber cómo funciona todo.
</p>

<p>
¿Cómo se ve un documento básico?:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\documentclass</span>{<span style="color: #50fa7b; font-weight: bold;">article</span>}
  <span style="color: #ff79c6;">\textheight</span> = 21cm          <span style="color: #6272a4;">% largo del texto impreso (por defecto 19cm)
</span>  <span style="color: #ff79c6;">\textwidth</span> = 18cm           <span style="color: #6272a4;">% ancho texto impreso (por defecto 14cm)
</span>  <span style="color: #ff79c6;">\topmargin</span> = -1cm           <span style="color: #6272a4;">% margen superior (por defecto 3cm): 3-1=2cm
</span>  <span style="color: #ff79c6;">\oddsidemargin</span> = -1.5cm     <span style="color: #6272a4;">% margen izquierdo (por defecto 4.5cm): 4.5-1.5=3cm
</span>  <span style="color: #ff79c6;">\parindent</span> = 0mm            <span style="color: #6272a4;">% Eliminar la sangr&#237;a del p&#225;rrafo
</span>  <span style="color: #6272a4;">% Paquetes b&#225;sicos
</span>  <span style="color: #ff79c6; font-weight: bold;">\usepackage</span>[<span style="color: #f8f8f2; font-weight: bold;">T1</span>]{<span style="color: #50fa7b; font-weight: bold;">fontenc</span>}    <span style="color: #6272a4;">% fuentes adecuadas para salida
</span>  <span style="color: #ff79c6; font-weight: bold;">\usepackage</span>[<span style="color: #f8f8f2; font-weight: bold;">utf8</span>]{<span style="color: #50fa7b; font-weight: bold;">inputenc</span>} <span style="color: #6272a4;">% acentos y caracteres especiales, desde el teclado
</span>  <span style="color: #ff79c6; font-weight: bold;">\usepackage</span>[<span style="color: #f8f8f2; font-weight: bold;">spanish</span>]{<span style="color: #50fa7b; font-weight: bold;">babel</span>} <span style="color: #6272a4;">% Traducci&#243;n al espa&#241;ol de los ep&#237;grafes
</span>                              <span style="color: #6272a4;">% de LaTeX: &#8216;Cap&#237;tulo&#8217;, &#8216;&#205;ndice&#8217; &#8216;Figura&#8217;...
</span><span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">document</span>}
<span style="color: #6272a4;">% </span><span style="color: #6272a4;">Cuerpo del documento
</span>Aqu&#237; est&#225; escrito el contenido de nuestro art&#237;culo.
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">document</span>}
</pre>
</div>

<p>
Obtendremos un documento tal que:
</p>


<figure id="org5fcdebf">
<img src="./imagenes/documento-uno.png" alt="documento-uno.png">

</figure>

<p>
Tanto escribir para generar tan poco contenido. ¿Cómo se explica ésto?
Pues muy sencillo: las primeras líneas son de configuración. Volvamos
a lo que hemos escrito para entenderlo.
</p>

<p>
Vemos dos partes diferenciadas en el código anterior: La primera parte
es el preámbulo donde cargaremos todos los paquetes que tendrán un
efecto visual, o de configuración, sobre el documento. Es decir,
estamos armando las condiciones que queremos que use <i>LaTeX</i> para
generar nuestro documento. La segunda parte se encontrará contenida
entre los comandos <code>\begin{document}</code> y <code>\end{document}</code><sup><a id="fnr.7" class="footref" href="#fn.7" role="doc-backlink">7</a></sup> y como se
pude suponer ahí es donde escribiremos nuestro contenido.
</p>

<p>
Los comandos, podemos observar que comienzan siempre por un carácter
<code>\</code> seguido del nombre del comando propiamente dicho y luego podemos
encontrar algún valor entre <i>corchetes</i> (<code>[...]</code>) que representan
valores opcionales o <i>son los parámetros</i> de la función principal que
aparecerá entre <i>llaves</i> (<code>{...}</code>). Como todo lo que hay ahí es muy
básico, lo que he escrito sólo carga los paquetes mínimos para
trabajar en otro idioma que no sea inglés. En nuestro caso <i>spanish</i>
para español, pero podría haber sido <code>catalan</code>, si fuera esa la lengua
en la que escribiéramos el documento. En todo caso esos tres paquetes
sirven para:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Paquete</th>
<th scope="col" class="org-left">Opción</th>
<th scope="col" class="org-left">Resultado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>fontenc</code></td>
<td class="org-left"><code>T1</code></td>
<td class="org-left">Fuentes del documento de salida.</td>
</tr>

<tr>
<td class="org-left"><code>inputenc</code></td>
<td class="org-left"><code>utf8</code></td>
<td class="org-left">Fuentes del archivo de entrada.<sup><a id="fnr.8" class="footref" href="#fn.8" role="doc-backlink">8</a></sup></td>
</tr>

<tr>
<td class="org-left"><code>babel</code></td>
<td class="org-left"><code>spanish</code></td>
<td class="org-left">Utilizar el <i>español</i> como idioma del documento.</td>
</tr>
</tbody>
</table>

<p>
El contenido se encontrará entre las marcas de comienzo y final del
documento. Pero en la cabecera definimos cómo se debe representar. El
primer comando debe ser siempre <code>\documentclass{}</code> que definirá el
tipo de documento que queremos escribir. Los tipos más habituales,
aunque hay muchos diferentes, son:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Tipo</th>
<th scope="col" class="org-left">Documento</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>article</code></td>
<td class="org-left">Un artículo</td>
</tr>

<tr>
<td class="org-left"><code>book</code></td>
<td class="org-left">Un libro</td>
</tr>

<tr>
<td class="org-left"><code>report</code></td>
<td class="org-left">Un informe</td>
</tr>

<tr>
<td class="org-left"><code>letter</code></td>
<td class="org-left">Una carta</td>
</tr>
</tbody>
</table>

<p>
Del tipo de documento, se deduce su estructura. Por ejemplo, un
artículo no tendrá <i>capítulos</i> pero sí <i>secciones</i>, mientras que un
libro tendrá de ambos y añadirá el concepto de <i>parte</i> como
organización superior al capítulo. Mientras que un informe puede tener
capítulos pero no partes... o una carta no tener nada de eso, pero sí un
<i>saludo</i>, una <i>despedida</i> y una <i>firma</i>. Como se puede ver, el tipo de
documento es un dato fundamental para que <i>LaTeX</i> haga su trabajo
correctamente.
</p>
</div>
</div>
<div id="outline-container-orga3bd41a" class="outline-3">
<h3 id="orga3bd41a">Idiomas y su tratamiento</h3>
<div class="outline-text-3" id="text-orga3bd41a">
<p>
Por defecto, como he <i>sugerido</i> antes, el idioma utilizado es el
inglés, así que hay que configurarlo para trabajar con otros
idiomas. No voy a complicar mucho el tema, me quedaré en los paquetes
básicos y que podemos cambiar el idioma con el paquete <code>babel</code>.  Hay
otros sistemas <i>TeX</i> que tratan las diferentes lenguas de otra manera
a <i>LaTeX</i> y es posible cambiar el idioma sobre la marcha. Son muy
recomendables si el documento que vas a generar es multilingüe. Pero
se sale del objetivo de este artículo<sup><a id="fnr.9" class="footref" href="#fn.9" role="doc-backlink">9</a></sup>.
</p>

<p>
Resumiendo, en la configuración mínima he puesto los paquetes para
trabajar en español. Los caracteres de entrada son importantes porque
dependen de qué códigos de fuente utiliza tu sistema operativo.  Si
estás utilizando <code>GNU/Linux</code> o <code>MacOS</code> las fuentes serán <code>utf8</code>, si
estás utilizando <code>windows</code> las fuentes serán <code>latin1</code>. Por tanto, el
formato del fichero de entrada es útil para escribir directamente con
nuestro teclado y que el sistema lo interprete correctamente. Si no
incluimos los paquetes anteriores necesitaremos especificar los
caracteres especiales como acentos, <code>ñ</code> o la apertura de interrogación
o exclamación con una secuencia de comandos como las siguientes:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">caracter</th>
<th scope="col" class="org-left">secuencia</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>á</code></td>
<td class="org-left"><code>\'a</code></td>
</tr>

<tr>
<td class="org-left"><code>é</code></td>
<td class="org-left"><code>\'e</code></td>
</tr>

<tr>
<td class="org-left"><code>í</code></td>
<td class="org-left"><code>\'{i}</code></td>
</tr>

<tr>
<td class="org-left"><code>ó</code></td>
<td class="org-left"><code>\'o</code></td>
</tr>

<tr>
<td class="org-left"><code>ú</code></td>
<td class="org-left"><code>\'u</code></td>
</tr>

<tr>
<td class="org-left"><code>ñ</code></td>
<td class="org-left"><code>\~n</code></td>
</tr>

<tr>
<td class="org-left"><code>¿</code></td>
<td class="org-left"><code>?`</code></td>
</tr>

<tr>
<td class="org-left"><code>¡</code></td>
<td class="org-left"><code>!`</code></td>
</tr>
</tbody>
</table>

<p>
Hay más, como sus correspondientes utilizando las mayúsculas, pero
también para conseguir otros caracteres especiales de puntuación como
guiones largos <code>─</code> mediante dos <code>--</code> o tres <code>---</code> guiones.
</p>

<p>
Por otro lado, si no incluimos el paquete <code>babel</code> para el español
encontraremos que nos marcará algunas cosas en inglés, por ejemplo
pondrá <i>content</i> en lugar de <i>contenido</i> o <i>índice</i> o utilizará el
término <i>chapter</i> en lugar del español <i>capítulo</i>. Podemos
redefinirlos mediante el comando <code>\renewcommand</code>, y es sencillo, pero
puede ser un listado muy largo que podemos evitar con sólo una línea.
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">nombre</th>
<th scope="col" class="org-left">comando</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">Capítulo</td>
<td class="org-left"><code>\renewcommand{\chaptername}{Capítulo}</code></td>
</tr>

<tr>
<td class="org-left">Figura</td>
<td class="org-left"><code>\renewcommand{\figurename}{Figura}</code></td>
</tr>

<tr>
<td class="org-left">Bibliografía</td>
<td class="org-left"><code>\renewcommand{\bibname}{Bibliografía}</code></td>
</tr>
</tbody>
</table>

<p>
Por poner sólo tres ejemplos. Además, como estos aspectos superan lo
que podríamos considerar un conocimiento básico para neófitos, vamos
con cosas más prosaicas y sencillas para empezar.
</p>
</div>
</div>
<div id="outline-container-org906062e" class="outline-3">
<h3 id="org906062e">Caracteres especiales</h3>
<div class="outline-text-3" id="text-org906062e">
<p>
Puesto que <i>LaTeX</i> utiliza algunos caracteres especiales para
configurar sus comandos, el uso de los mismos puede llevar al error a
la hora de generar el documento. Así por ejemplo, puesto que el
carácter para introducir comentarios en nuestro documento es el <code>%</code> es
posible que al introducir un texto tal que <code>45%</code> perdamos la parte del
texto que aparezca después en esa línea. Entonces, ¿no podemos
escribir porcentajes? Sí, sí podemos: aunque los caracteres especiales
los debemos <i>escapar</i> con el carácter <code>\</code>. En la siguiente tabla
podemos ver todos los caracteres especiales, cómo se <i>escapan</i> y para
qué sirven:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">carácter</th>
<th scope="col" class="org-left">escape</th>
<th scope="col" class="org-left">utilidad</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">\</td>
<td class="org-left"><code>\\</code></td>
<td class="org-left">Inicio de comando o escape</td>
</tr>

<tr>
<td class="org-left">{, }</td>
<td class="org-left">\{, \}</td>
<td class="org-left">Abre-cierra un bloque de código</td>
</tr>

<tr>
<td class="org-left">$</td>
<td class="org-left">\$</td>
<td class="org-left">Abre-cierra el modo matemático</td>
</tr>

<tr>
<td class="org-left">&amp;</td>
<td class="org-left">\&amp;</td>
<td class="org-left">Tabulador en tablas y matrices</td>
</tr>

<tr>
<td class="org-left">#</td>
<td class="org-left">\#</td>
<td class="org-left">Señala parámetros en las macros</td>
</tr>

<tr>
<td class="org-left">_, ^</td>
<td class="org-left">\_, \^</td>
<td class="org-left">Subíndice y superíndice</td>
</tr>

<tr>
<td class="org-left">~</td>
<td class="org-left">\~</td>
<td class="org-left">Evitar el corte de renglón</td>
</tr>

<tr>
<td class="org-left">%</td>
<td class="org-left">\%</td>
<td class="org-left">Inicio de comentarios</td>
</tr>
</tbody>
</table>

<p>
Cuando necesitemos escribir alguno de esos caracteres y que sea
legible en el texto, debemos utilizar la secuencia de escape. Si los
utilizamos sin escape, <i>LaTeX</i> lo interpretará como un comando de
edición y actuará en consecuencia. Si vemos algo raro en nuestro texto
suele deberse a que hemos olvidado <i>escapar</i> alguno de estos
caracteres.
</p>
</div>
</div>
<div id="outline-container-org9843a49" class="outline-3">
<h3 id="org9843a49">Tipo de texto</h3>
<div class="outline-text-3" id="text-org9843a49">
<p>
Lo primero que llama la atención a quien llegue a <i>LaTeX</i> desde un
editor de documentos es la dificultad de modificar las fuentes del
documento. Por supuesto, se pueden cambiar, pero no tienes la misma
libertad que en un editor de documento, donde en cada párrafo o, si me
apuras, en cada carácter, podemos seleccionar el tipo de fuente que
queremos, el tamaño o el tipo.
</p>

<p>
Pero una cosa es que se pueda y otra que se deba. Si no utilizamos esa
posibilidad con cuidado, nuestros documentos se verán mermados en
cuanto a aspecto y legibilidad. Por ésto, <i>LaTeX</i>, aunque nos deja
modificar todo el aspecto del texto, lo hace de forma que el usuario
sea consciente de lo que hace y cómo afecta al resultado impreso.
</p>

<p>
Sobre el aspecto de la fuente:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">comando</th>
<th scope="col" class="org-left">significado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>\textnormal{...}</code></td>
<td class="org-left">Texto normal</td>
</tr>

<tr>
<td class="org-left"><code>\textbf{...}</code></td>
<td class="org-left">Texto en <b>negrita</b></td>
</tr>

<tr>
<td class="org-left"><code>\emph{...}</code></td>
<td class="org-left"><i>Énfasis</i></td>
</tr>

<tr>
<td class="org-left"><code>\textsl{...}</code></td>
<td class="org-left"><i>Slant</i>, texto inclinado</td>
</tr>

<tr>
<td class="org-left"><code>\textit{...}</code></td>
<td class="org-left"><i>Itálica</i></td>
</tr>

<tr>
<td class="org-left"><code>\textrm{...}</code></td>
<td class="org-left">Roman, texto en <i>roman</i></td>
</tr>

<tr>
<td class="org-left"><code>\textsf{...}</code></td>
<td class="org-left">Texto en San Serif.</td>
</tr>

<tr>
<td class="org-left"><code>\texttt{...}</code></td>
<td class="org-left"><code>Tipewriter</code>. Tipo fijo</td>
</tr>

<tr>
<td class="org-left"><code>\verb</code></td>
<td class="org-left"><code>Verbatim</code>.</td>
</tr>
</tbody>
</table>



<p>
Hay algunas que nos pueden parecer inútiles o redundantes pero no lo
son. Por ejemplo, el texto con énfasis utilizando el comando <code>\emph{}</code>
cuando se encuentra dentro de un entorno en itálica <code>\textit{}</code>
mostrará el texto en <i>roman</i> para que se distinga (enfatice) del resto
en itálica.
</p>

<p>
Algo que puede llamar la atención al principio es el comando <code>\verb</code>.
Todos los demás utilizan <code>{}</code> para enmarcar el texto al que afectan.
Sin embargo, <code>verb</code> no lo hace. Cualquier cosa que se ponga en un
texto <code>verb</code> no se interpretará y puesto que es muy frecuente
utilizarlo para mostrar textos que contienen caracteres especiales, el
utilizar las llaves puede ser un engorro, porque podemos encontrarnos
dentro alguna llave y <i>LaTeX</i> no sabrá si es parte del texto o del
comando. Por tanto, lo que se hace en este comando es proporcionar un
carácter de comienzo y de final. Por lo general utilizo <code>|</code> pero puede
ser cualquiera. Suelo utilizar ese carácter, que es bastante visual,
pero si el texto que escribimos lo contiene, hay que utilizar algún
otro símbolo que no esté en él: <code>@</code>, <code>¡</code>, <code>!</code>... recordando siempre
que se utiliza el mismo carácter para abrir y para cerrar el texto
<i>verbatim</i>.
</p>
</div>
</div>
<div id="outline-container-org0bbdf2b" class="outline-3">
<h3 id="org0bbdf2b">Tamaños de texto</h3>
<div class="outline-text-3" id="text-org0bbdf2b">
<p>
Así mismo los tamaños están limitados y no puedes utilizar el tamaño
de la fuente que quieras, especificando tamaño por puntos a ojo... ya
que pocos saben que un <i>punto</i> tipográfico está definido como \(1/72\)
de pulgada o \(352,7777\) micrómetros. En <i>LaTeX</i> los tamaños que
definas pueden estar en puntos (<code>pt</code>) y también en centímetros (<code>cm</code>),
pero los tipos serán siempre relativos: se define el tamaño del texto
normal y a partir de ese se definen el resto de los tamaños. Por
ejemplo, para un tamaño de letra de <code>10pt</code>, los tamaños serán:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">comando</th>
<th scope="col" class="org-right">tamaño en pt</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>\tiny</code></td>
<td class="org-right">5</td>
</tr>

<tr>
<td class="org-left"><code>\scriptsize</code></td>
<td class="org-right">7</td>
</tr>

<tr>
<td class="org-left"><code>\footnotesize</code></td>
<td class="org-right">8</td>
</tr>

<tr>
<td class="org-left"><code>\small</code></td>
<td class="org-right">9</td>
</tr>

<tr>
<td class="org-left"><code>\normalsize</code></td>
<td class="org-right">10</td>
</tr>

<tr>
<td class="org-left"><code>\large</code></td>
<td class="org-right">12</td>
</tr>

<tr>
<td class="org-left"><code>\Large</code></td>
<td class="org-right">14.4</td>
</tr>

<tr>
<td class="org-left"><code>\LARGE</code></td>
<td class="org-right">17.28</td>
</tr>

<tr>
<td class="org-left"><code>\huge</code></td>
<td class="org-right">20.74</td>
</tr>

<tr>
<td class="org-left"><code>\Huge</code></td>
<td class="org-right">24.88</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="outline-container-orgcc16195" class="outline-3">
<h3 id="orgcc16195">Ejemplo visual</h3>
<div class="outline-text-3" id="text-orgcc16195">
<p>
Como hablar de todas estas cosas así en teoría es complicado de
visualizar, voy a poner aquí el contenido de un archivo, generaré el
fichero <code>pdf</code> y pondré una captura de cómo se ve el documento.
</p>

<p>
Voy a utilizar el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\documentclass</span>{<span style="color: #50fa7b; font-weight: bold;">article</span>}
    <span style="color: #ff79c6;">\textheight</span> = 21cm          <span style="color: #6272a4;">% largo del texto impreso (por defecto 19cm)
</span>    <span style="color: #ff79c6;">\textwidth</span> = 18cm           <span style="color: #6272a4;">% ancho texto impreso (por defecto 14cm)
</span>    <span style="color: #ff79c6;">\topmargin</span> = -1cm           <span style="color: #6272a4;">% margen superior (por defecto 3cm): 3-1=2cm
</span>    <span style="color: #ff79c6;">\oddsidemargin</span> = -1.5cm     <span style="color: #6272a4;">% margen izquierdo (por defecto 4.5cm): 4.5-1.5=3cm
</span>    <span style="color: #ff79c6;">\parindent</span> = 0mm            <span style="color: #6272a4;">% Eliminar la sangr&#237;a del p&#225;rrafo
</span>    <span style="color: #6272a4;">% Paquetes b&#225;sicos
</span>    <span style="color: #ff79c6; font-weight: bold;">\usepackage</span>[<span style="color: #f8f8f2; font-weight: bold;">T1</span>]{<span style="color: #50fa7b; font-weight: bold;">fontenc</span>}    <span style="color: #6272a4;">% fuentes adecuadas para salida
</span>    <span style="color: #ff79c6; font-weight: bold;">\usepackage</span>[<span style="color: #f8f8f2; font-weight: bold;">utf8</span>]{<span style="color: #50fa7b; font-weight: bold;">inputenc</span>} <span style="color: #6272a4;">% acentos y caracteres especiales, desde el teclado
</span>    <span style="color: #ff79c6; font-weight: bold;">\usepackage</span>[<span style="color: #f8f8f2; font-weight: bold;">spanish</span>]{<span style="color: #50fa7b; font-weight: bold;">babel</span>} <span style="color: #6272a4;">% Traducci&#243;n al espa&#241;ol de los ep&#237;grafes
</span>                                <span style="color: #6272a4;">% de LaTeX: &#8216;Cap&#237;tulo&#8217;, &#8216;&#205;ndice&#8217;
</span>                                <span style="color: #6272a4;">% &#8216;Figura&#8217;...
</span><span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">document</span>}                <span style="color: #6272a4;">% Entorno que contiene el documento
</span><span style="color: #ff79c6; font-weight: bold;">\title</span>{<span style="color: #8be9fd; font-style: italic;">Documento b&#225;sico de ejemplo</span>} <span style="color: #6272a4;">% El t&#237;tulo del documento
</span><span style="color: #ff79c6; font-weight: bold;">\author</span>{<span style="color: #8be9fd; font-style: italic;">Notxor</span>}                     <span style="color: #6272a4;">% El autor
</span>
<span style="color: #ff79c6; font-weight: bold;">\maketitle</span>                          <span style="color: #6272a4;">% Genera el t&#237;tulo, junto con autor y fecha
</span>
<span style="color: #ff79c6;">\abstract</span>                           <span style="color: #6272a4;">% Resumen del documento
</span>Este es un documento de prueba para ver las posibilidades de cada tipo
de letra y tama&#241;o. Vamos a ello.

<span style="color: #ff79c6; font-weight: bold;">\section</span>{<span style="color: #50fa7b; font-size: 110%; font-weight: bold;">Tipos de letra</span>}            <span style="color: #6272a4;">% Secci&#243;n sobre los tipos de letra
</span>Esto es un texto con diferentes tipos de letra: este es el normal,
este est&#225; en <span style="color: #ff79c6; font-weight: bold;">\textbf</span>{<span style="color: #bd93f9;">negrita</span>}, este est&#225; <span style="color: #ff79c6; font-weight: bold;">\emph</span>{<span style="color: #ff79c6; font-style: italic;">enfatizado</span>}, este es
<span style="color: #ff79c6; font-weight: bold;">\textsl</span>{<span style="color: #ff79c6; font-style: italic;">inclinado</span>} aunque no se diferencia mucho de la
<span style="color: #ff79c6; font-weight: bold;">\textit</span>{<span style="color: #ff79c6; font-style: italic;">it&#225;lica</span>}, aunque s&#237; podemos diferenciar el tipo
<span style="color: #ff79c6; font-weight: bold;">\textrm</span>{<span style="color: #8be9fd; font-style: italic;">roman</span>}, del tipo <span style="color: #ff79c6; font-weight: bold;">\textsf</span>{<span style="color: #8be9fd; font-style: italic;">san serif</span>} o del tipo
<span style="color: #ff79c6; font-weight: bold;">\texttt</span>{<span style="color: #8be9fd; font-style: italic;">Tipewrite</span>}.

Adem&#225;s podemos escribir el mismo texto con otro formato de comando,
v&#233;ase la gracia: Esto es un texto con diferentes tipos de letra: este
es el normal, este est&#225; en {<span style="color: #ff79c6; font-weight: bold;">\bf</span><span style="color: #bd93f9;"> negrita</span>}, este est&#225; {<span style="color: #ff79c6; font-weight: bold;">\em</span><span style="color: #ff79c6; font-style: italic;"> enfatizado</span>},
este es {<span style="color: #ff79c6; font-weight: bold;">\sl</span><span style="color: #ff79c6; font-style: italic;"> inclinado</span>} aunque no se diferencia mucho de la {<span style="color: #ff79c6; font-weight: bold;">\it</span><span style="color: #ff79c6; font-style: italic;">
  it&#225;lica</span>}, aunque s&#237; podemos diferenciar el tipo {<span style="color: #ff79c6; font-weight: bold;">\rm</span><span style="color: #8be9fd; font-style: italic;"> roman</span>}, del
tipo {<span style="color: #ff79c6; font-weight: bold;">\sf</span><span style="color: #8be9fd; font-style: italic;"> san serif</span>} o del tipo {<span style="color: #ff79c6; font-weight: bold;">\tt</span><span style="color: #8be9fd; font-style: italic;"> Tipewrite</span>}. Pero tienes que mirar
el c&#243;digo para verlo.

El resultado, como puedes ver, es el mismo.

<span style="color: #ff79c6; font-weight: bold;">\section</span>{<span style="color: #50fa7b; font-size: 110%; font-weight: bold;">Tama&#241;os del texto</span>}         <span style="color: #6272a4;">% Secci&#243;n sobre el tama&#241;o de las fuentes
</span>
<span style="color: #ff79c6; font-weight: bold;">\begin</span>{<span style="color: #50fa7b; font-weight: bold;">itemize</span>}                     <span style="color: #6272a4;">% Entorno que contiene una lista sin numerar
</span><span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\tiny</span><span style="color: #ffb86c;">{}|</span> <span style="color: #8be9fd; font-style: italic;">\tiny</span>{muy muy muy peque&#241;o}
<span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\scriptsize</span><span style="color: #ffb86c;">{}|</span> <span style="color: #8be9fd; font-style: italic;">\scriptsize</span>{muy muy peque&#241;o}
<span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\footnotesize</span><span style="color: #ffb86c;">{}|</span> <span style="color: #8be9fd; font-style: italic;">\footnotesize</span>{muy peque&#241;o}
<span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\small</span><span style="color: #ffb86c;">{}|</span> <span style="color: #8be9fd; font-style: italic;">\small</span>{peque&#241;o}
<span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\normalsize</span><span style="color: #ffb86c;">{}|</span> <span style="color: #8be9fd; font-style: italic;">\normalsize</span>{normal}
<span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\large</span><span style="color: #ffb86c;">{}|</span> <span style="color: #8be9fd; font-style: italic;">\large</span>{grande}
<span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\Large</span><span style="color: #ffb86c;">{}|</span> <span style="color: #8be9fd; font-style: italic;">\Large</span>{muy grande}
<span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\LARGE</span><span style="color: #ffb86c;">{}|</span> <span style="color: #8be9fd; font-style: italic;">\LARGE</span>{muy muy grande}
<span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\huge</span><span style="color: #ffb86c;">{}|</span> <span style="color: #8be9fd; font-style: italic;">\huge</span>{enorme}
<span style="color: #ff79c6; font-weight: bold;">\item</span> <span style="color: #ff79c6; font-weight: bold;">\verb</span><span style="color: #ffb86c;">|</span><span style="color: #ffb86c;">\Huge</span><span style="color: #ffb86c;">{}|</span> <span style="color: #8be9fd; font-style: italic;">\Huge</span>{m&#225;s que enorme}
<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">itemize</span>}

<span style="color: #ff79c6; font-weight: bold;">\end</span>{<span style="color: #50fa7b; font-weight: bold;">document</span>}                       <span style="color: #6272a4;">% Final del documento</span>
</pre>
</div>

<p>
Ahora mismo es posible que no entiendas todos los comandos, pero a
poco que los mires, verás que son muy fáciles de entender, además,
porque he puesto comentarios para indicar qué hacen.
</p>

<p>
El siguiente paso es generar el documento. Para ello abro una consola
y tecleo el siguiente comando, suponiendo que el fichero lo haya
llamado <code>texto.tex</code>:
</p>

<div class="org-src-container">
<pre class="src src-shell">$ pdflatex texto
</pre>
</div>

<p>
Debemos estar situados en el directorio donde guardamos el documento.
Además, es de señalar que se llama al comando sin la extensión <code>.tex</code>
del fichero. Si todo ha ido bien, generará el documento y una serie de
ficheros auxiliares. El documento <code>pdf</code> que se verá de la siguiente
manera:
</p>


<figure id="org257aea3">
<img src="./imagenes/Captura-pantalla_documento-fuentes.png" alt="Captura-pantalla_documento-fuentes.png">

</figure>

<p>
Es posible que para generar la salida completa, sobre todo cuando
existen enlaces internos que saltan de una página a otra, o a una
figura, o a una tabla; o cuando se quiere o se necesita un índice de
materias, o índices de tablas y gráficos, o bibliografía... Como digo,
<i>es posible</i> que se necesite invocar el comando varias veces.
¿Cuántas? No te preocupes, normalmente los editores que trabajan sobre
<i>LaTeX</i> hacen esas llamadas por ti, de manera automática detectan si
es necesario y lo hacen por nosotros, nos podemos despreocupar un
poco, pero si vemos que aparecen algún <code>?</code> en un lugar donde esperamos
encontrar un enlace a una página, o a una figura, o una cita de la
bibliografía, es que necesitamos llamar a <code>pdflatex</code> de nuevo.
</p>
</div>
</div>
</div>
<div id="outline-container-org9944802" class="outline-2">
<h2 id="org9944802">Conclusión</h2>
<div class="outline-text-2" id="text-org9944802">
<p>
La conclusión en realidad es un continuará. Me está quedando algo
demasiado largo y apenas he podido rascar un poco la superficie de lo
que es y cómo se utiliza <i>LaTeX</i>. Es posible que estés pensando que no
te supone mucha ventaja el tener que aprenderte los comandos y todas
esas cosas, pero desde luego ni siquiera hemos rascado toda la
potencialidad de la herramienta. No hemos hablado de los enlaces
internos, la generación de índices, la bibliografía, los tipos de
documentos, incluidas las presentaciones en <code>pdf</code>... en fin, que
apenas hemos visto nada.
</p>

<p>
La principal ventaja de esta herramienta es que ni en tus mejores
sueños consigues un acabado de los documentos como el que puede
proporcionar <i>LaTeX</i>.  Otra ventaja es que el original lo puedes abrir
con cualquier editor de texto en cualquier ordenador y que, teniendo
<i>LaTeX</i> instalado, la salida será idéntica, sin importar la máquina.
Además, podrás escribir un documento <i>LaTeX</i> sin tener siquiera
instalado el programa, aunque no lo podrás visualizar, podrás trabajar
en él sin ningún problema.
</p>

<p>
La principal desventaja es que tienes que aprender una tecnología
nueva a la que no estás acostumbrado.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Asociación Americana de Psicología, en su acrónimo en inglés.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Acrónimo de <i>What You See Is What You Get</i>: lo que ves es lo
que obtienes.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Entendiendo en esta frase <i>editor</i> como un editor de
documentos, no un editor de texto. 
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Se lee <i>tej</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Hay más variantes como <i>XeTeX</i> o <i>luaTeX</i>, pero se escapan de
este minicurso. 
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ya veremos lo que son los <i>entornos</i>, pero básicamente se pude
decir que es todo lo que va entre unas etiquetas <code>begin</code> y <code>end</code> que
marcan que ese texto se debe tratar de una determinada manera. 
</p></div></div>

<div class="footdef"><sup><a id="fn.7" class="footnum" href="#fnr.7" role="doc-backlink">7</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Es un <i>entorno</i> que contiene a todo el documento.
</p></div></div>

<div class="footdef"><sup><a id="fn.8" class="footnum" href="#fnr.8" role="doc-backlink">8</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Si estás utilizando <i>windows</i>, el valor de la opción debería
ser <code>latin1</code>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.9" class="footnum" href="#fnr.9" role="doc-backlink">9</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Si hay interés lo contaré en otro artículo.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/latex/index.html">latex</a> ]]></description>
  <category><![CDATA[latex]]></category>
  <link>https://notxor.nueva-actitud.org/2021/03/20/minicurso-de-latex-para-psicólogos.html</link>
  <pubDate>Sat, 20 Mar 2021 09:12:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Emacs y lsp-mode]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-03-11</div>
<p>
Hoy vengo con un modo que hace poco que empecé a utilizar: <code>lsp-mode</code>.
La verdad es que no lo utilizo demasiado, la mayor parte de mi trabajo
la hago en <code>org-mode</code> y lo que menos hago es programar, que es para lo
que es más útil <code>lsp</code>, aunque también podría usarlo para
<i>LaTeX</i>. <i>Language Server Protocol</i> se está convirtiendo en un
estándar para todos los editores de código e incluso los <i>editores
viejunos</i> como <i>Emacs</i> y <i>vim</i> lo soportan. Este artículo hablará de
cómo configurarlo mínimamente en <i>Emacs</i> y sobre un par de pruebas que
he hecho para ver su funcionamiento.
</p>

<p>
Como decía, mi trabajo habitual, como corresponde a un psicólogo, no
es programar sino escribir mucha documentación, informes, registros de
visitas, planes de prevención, cursos de formación, <i>blog</i>... en fin,
la mayor parte de lo que hago es escribir con <code>org-mode</code> o con <i>LaTeX</i>
y para ello no necesito utilizar <code>lsp-mode</code>. En realidad, tampoco lo
necesito utilizar cuando programo, algo que últimamente hago en
<code>elixir</code> y para el que utilizo el paquete <code>alchemist</code> de <i>Emacs</i>, que
cubre todas mis necesidades de sobra.
</p>

<p>
Descubrí <code>lsp-mode</code> cuando hice la aproximación o intento de aprender
<code>Rust</code>. Lenguaje, que como ya dije en este <i>blog</i>, abandoné por
desconfianza en los miembros de la <i>fundación</i> que se ha hecho cargo
de su desarrollo. Cuando empecé a trastear con ese lenguaje, el modo
de <i>Emacs</i> pedía insistentemente el <code>lsp-mode</code> y al final cedí y lo
instalé. La experiencia fue breve pero pensé que debía probar un poco
más ese paquete. La verdad es que <code>lsp</code> convierte cualquier editor en
un <i>IDE</i> completo y proporciona funcionalidad de completado de
sintaxis, ayuda contextual, navegación por el código, etc. Todo lo que
puedas esperar de un buen editor.  Para muchas de esas cosas <i>Emacs</i>
tiene suficientes herramientas para trabajar y no necesita, en
principio, <i>servidores externos</i>. Recuerdo que alguien me preguntó una
vez qué editor <i>actual</i> usaría, que no sean mis dos preferidos <i>Emacs</i>
y <i>vim</i>. Quizá la respuesta esperada estaría entre los famosos
<i>sublime</i>, <i>atom</i> y similare... sin embargo, creo que mi respuesta
ahora, conociendo <code>lsp</code> sería <i>Kate</i>: tiene todo lo que tienen los
mencionados (y más), y <code>kate</code> <i>traga</i> menos recursos además de tener
el soporte de <code>lsp</code>, que lo convierte en una magnífica alternativa.
</p>

<p>
Para entender cómo funciona <code>lsp</code> hay que comenzar diciendo que es el
acrónimo de <i>Protocolo de Servidor de Lenguaje</i>. Es decir, hay un
servidor con el que se comunica el editor para dotarle de todas esas
características. Cada lenguaje tiene su <i>servidor</i> independiente, lo
que obliga a que tendremos que tener un servidor de esos por
lenguaje. No voy a entrar más allá en cómo funciona pero hay que dejar
claro que la funcionalidad la proporciona un elemento externo al
editor.
</p>
<div id="outline-container-org9c1cfce" class="outline-2">
<h2 id="org9c1cfce">Instalación de <code>lsp-mode</code></h2>
<div class="outline-text-2" id="text-org9c1cfce">
<p>
Tenemos la habitual instrucción de <code>package-install</code>. Como tampoco voy
a ser muy exhaustivo, si estáis pensando en utilizarlo, es <a href="https://emacs-lsp.github.io/lsp-mode/">que os
leáis su web</a>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">M-x package-install &lt;RET&gt; lsp-mode &lt;RET&gt;
</pre>
</div>

<p>
El paquete ya estará instalado en nuestro editor aunque de una manera
muy básica. Lo que hace <code>lsp-mode</code> es intentar integrar el
funcionamiento de <code>lsp</code> con los habituales paquetes de <i>Emacs</i>
<code>company</code>, <code>flycheck</code> o <code>flymake</code>, <code>projectile</code> son los básicos, pero
también utiliza otros como <code>dired</code>, <code>treemacs</code>, <code>iedit</code>...  Por tanto
hay que tener en cuenta que debemos tener instalados todos esos
paquetes en nuestro <i>Emacs</i> para tener toda la funcionalidad. Al menos
para lo básico:
</p>

<ul class="org-ul">
<li><code>company</code>: es un paquete para el autocompletado de código. Hay
paquetes para multitud de lenguajes específicos.</li>
<li><code>flymake</code>: viene instalado con <i>Emacs</i> en sus últimas versiones y
sirve para evaluar errores y <i>warnings</i> del código sobre la marcha.</li>
<li><code>projectile</code>: es un paquete para la gestión de proyectos.</li>
</ul>

<p>
También es muy recomendable instalar junto con <code>lsp-mode</code> el paquete
<code>lsp-ui</code> porque éste nos facilita también la navegación visual por el
código, desplegables de documentación, selector de acciones de código,
etc. Otro paquete que puede ser interesante es <code>dap-mode</code> para
integrar el <i>debugger</i>.  Aunque según qué lenguaje, sobre todo si
podemos utilizar <code>gdb</code>, también podemos utilizar el modo de depuración
propio de <i>Emacs</i>. Y por último, también es recomendable que si usas
<code>ivy</code> o <code>helm</code> es recomendable que instales el paquete <code>lsp-ivy</code> o
<code>lsp-helm</code>.
</p>
</div>
<div id="outline-container-orgc2296e5" class="outline-3">
<h3 id="orgc2296e5">Configuración</h3>
<div class="outline-text-3" id="text-orgc2296e5">
<p>
La configuración que tengo activada para las pruebas incluye tan solo
dos lenguajes. Uno es <code>C++</code>, para el que no he tenido que hacer nada
especial durante su configuración. Parece que <code>lsp-mode</code> ya lo trae
preparado todo. Fue abrir un fichero con en ese lenguaje y todo
funcionó sin problemas. El segundo lenguaje es <code>Python</code>, que necesité
instalar el servidor del lenguaje. Lo que me viene bien para mostrar
las dos alternativas.
</p>

<p>
No voy a entrar en la configuración de todos los otros paquetes
auxiliares, porque sería extenderme innecesariamente. La configuración
que tengo en mi <code>init.el</code> es muy sencilla:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Establecer prefijo para lsp-mode
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> lsp-keymap-prefix <span style="color: #f1fa8c;">"C-l"</span>)

<span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Configuraci&#243;n de lsp-mode
</span>(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">lsp-mode</span>)
(add-hook 'python-mode-hook #'lsp)
(add-hook 'c++-mode-hook #'lsp)
</pre>
</div>

<p>
La primera línea no necesita mucha explicación: establece como prefijo
para los comandos de <code>lsp</code> la combinación <code>C-l</code>. Las dos últimas
líneas indican que cuando se entre en los modos para programar en
<code>Python</code> o <code>c++</code> se lance el modo <code>lsp</code>. Como sabéis <code>#'</code> es un atajo
para <i>función</i> en <code>elisp</code>. Lo que hace esa función es levantar el
servidor y entrar en <code>lsp-mode</code>. Arrancar el servidor, puede llevar
unos segundos. Además hay que añadir que al entrar en <code>lsp-mode</code> este
configura de forma automática tanto <code>lsp-ui</code> como <code>company-mode</code>. Si
se quiere retrasar el lanzamiento del servidor hasta que sea visible
el contenido del <i>buffer</i>, se puede utilizar <code>lsp-deferred</code> en lugar
de <code>lsp</code>.
</p>

<p>
Utilizando <code>flymake</code>, en su día, también definí un par de
combinaciones para navegar por los errores y que vienen bien mientras
programas con <code>flymake</code> activado:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(global-set-key (kbd <span style="color: #f1fa8c;">"C-c f n"</span>) 'flymake-goto-next-error)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c f p"</span>) 'flymake-goto-prev-error)
</pre>
</div>

<p>
Como digo, en mi caso ya tenía algunas de estas herramientas
configuradas y preparadas para trabajar. Pero para profundizar un poco
haciendo pruebas y poder escribir este artículo he utilizado el
<code>lsp-mode</code> con los dos lenguajes que dije antes. Aunque programo más
en otros lenguajes y no uso para ellos esta herramienta.
</p>

<p>
Para más precisión en la configuración, es recomendable, que antes te
<a href="https://emacs-lsp.github.io/lsp-mode/page/settings/">leas detenidamente todas las opciones</a> que hay en su <i>web</i> para ajustar
todos los aspectos y comportamientos.
</p>


<figure id="orga13d2be">
<img src="./imagenes/Captura-pantalla_lsp-cplusplus.png" alt="Captura-pantalla_lsp-cplusplus.png">

</figure>

<p>
En ambos lenguajes parece funcionar correctamente:
</p>


<figure id="orgc988a94">
<img src="./imagenes/Captura-pantalla_lsp-python.png" alt="Captura-pantalla_lsp-python.png">

</figure>

<p>
Al menos todo lo bien en las pruebas que he hecho, que aunque no han
sido exhaustivas ni durante demasiado tiempo, puedo asegurar que en
ambos casos me ha funcionado el modo con soltura. Sin embargo, para
usar <code>lsp-mode</code> con <code>Python</code> he tenido que instalar el paquete del
servidor de lenguaje.
</p>
</div>
</div>
</div>
<div id="outline-container-org101d6f9" class="outline-2">
<h2 id="org101d6f9">Instalando servidores de lenguaje</h2>
<div class="outline-text-2" id="text-org101d6f9">
<p>
Como dije antes, para trabajar con <code>C++</code> no necesité ningún paso
intermedio, simplemente, instalé el modo y lo configuré como hemos
visto antes. Automáticamente funcionó con ese lenguaje. No fue así con
<code>Python</code>: abría un fichero <code>.py</code>, intentaba activar el modo <code>lsp-mode</code>
y lanzaba un error. El problema lo pude resumir en que no encontraba
el <i>Language Server</i> y tuve que instalarlo.
</p>

<p>
La instalación fue tan sencilla como abrir una consola y teclear:
</p>

<div class="org-src-container">
<pre class="src src-shell">pip install pyls
</pre>
</div>

<p>
A partir de ese momento comenzó a funcionar <code>lsp-mode</code>. Estuve
barajando también el instalar <code>jedi-language-server</code>, en lugar de
<code>pyls</code>, pero implicaba que también había que instalar <code>lsp~jedi</code> en
<i>Emacs</i> para funcionar y me pareció que ya eran demasiados paquetes
sólo para hacer pruebas. La alternativa parece también válida e
interesante, pero no quería liarlo más.
</p>

<p>
En todo esto de instalar o no servidores <code>ls</code> supongo que influye
también el haber utilizado con ese lenguaje algún editor que ya
soportaba de antes <code>lsp</code> y de tener instalado precisamente el que
necesitas. De todas formas, también podemos encontrar que el mismo
modo <code>lsp</code> puede instalar una serie de servidores con el comando
<code>lsp-install-server</code>.
</p>

<p>
Es también conveniente <a href="https://emacs-lsp.github.io/lsp-mode/page/languages/">echar un vistazo a todos los servidores</a>
soportados por <code>lsp-mode</code> y seguir las instrucciones para instalar el
que nos convenga.
</p>
</div>
</div>
<div id="outline-container-orge81fc30" class="outline-2">
<h2 id="orge81fc30">Funciones principales de <code>lsp-mode</code></h2>
<div class="outline-text-2" id="text-orge81fc30">
<p>
Las funciones principales, o que más se utilizan, vienen definidas a
partir del atajo de teclado que hayamos establecido en la
configuración. En mi caso utilizo como combinación base para
<code>lsp-mode</code> el atajo <code>C-l</code>:
</p>

<dl class="org-dl">
<dt><code>lsp-format-buffer</code></dt><dd><code>C-l = =</code>, unifica el formato del <i>buffer</i>
para unificar el aspecto y hacer el código más legible.</dd>

<dt><code>lsp-format-region</code></dt><dd><code>C-l = r</code>. Da formato a la región
seleccionada.</dd>

<dt><code>lsp-find-declaration</code></dt><dd><code>C-l g d</code>, nos lleva a la declaración de
una función, constante o variable.</dd>

<dt><code>lsp-find-definition</code></dt><dd><code>C-l g g</code>, nos lleva donde esté definida la
función, constante o variable.</dd>

<dt><code>lsp-find-references</code></dt><dd><code>C-l g r</code>, nos muestra una lista de todas
las apariciones y referencias de una función, constante o variable
dentro del proyecto permitiéndonos saltar a ellas.</dd>

<dt><code>lsp-rename</code></dt><dd><code>C-l r r</code>, renombra un identificador en todas sus
apariciones.</dd>

<dt><code>lsp-workspace-shutdown</code></dt><dd><code>C-l s q</code>, sale del espacio de trabajo
cerrando el servidor y saliendo del modo.</dd>

<dt><code>lsp-workspace-restart</code></dt><dd><code>C-l s r</code>, reinicia el espacio de
trabajo.</dd>

<dt><code>lsp</code></dt><dd><code>C-l s s</code>, lanza el espacio de trabajo levantando el
servidor y entrando en el modo.</dd>
</dl>

<p>
Hay más funciones que explorar pero esta es la lista de las que más he
usado y que más útiles puede resultar.
</p>
</div>
</div>
<div id="outline-container-orgfe61feb" class="outline-2">
<h2 id="orgfe61feb">Conclusión</h2>
<div class="outline-text-2" id="text-orgfe61feb">
<p>
El modo <code>lsp-mode</code> es bastante completo, pero al final se integra con
otros modos y paquetes que ya puedes utilizar directamente en <i>Emacs</i>
sin necesitarlo: como <code>dired</code> (para la gestión de directorios) o
<code>iedit</code> (para escribir a la vez en varias zonas de un <i>buffer</i>), etc.
</p>

<p>
¿Qué aporta entonces <code>lsp-mode</code> a <i>Emacs</i>? Pues básicamente
uniformidad entre lenguajes... Poco más que reseñar. Por ejemplo, toda
la funcionalidad que proporciona <code>lsp</code> lo proporciona, por ejemplo,
<code>alchemist</code>, el modo de programación para <code>elixir</code>, pero con sus
atajos de teclas y sus idiosincrasias. Quizá también aporte que
algunos programadores decidan pasarse a editores <i>viejunos</i>, pero
potentes, que les proporcionen las mismas funcionalidades que los
modernos pero sin tantos quebraderos de cabeza como las
configuraciones: configuras mínimamente el editor, configuras <code>lsp</code> y
todo funciona como esperas de un <i>IDE</i>.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/lsp-mode/index.html">lsp-mode</a> <a href="/tags/programación/index.html">programación</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[lsp-mode]]></category>
  <category><![CDATA[programación]]></category>
  <link>https://notxor.nueva-actitud.org/2021/03/11/emacs-y-lsp-mode.html</link>
  <pubDate>Thu, 11 Mar 2021 09:20:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Publicar con org-mode II]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-03-03</div>
<p>
Este es un artículo de esos incoherentes en los que me dedico a
contestar preguntas y peticiones de aclaración.  Ya en este <i>blog</i>
hablé de cómo <a href="https://notxor.nueva-actitud.org/2021/01/13/publicar-html-con-org-mode.html">publicar en <code>html</code> con <code>org-mode</code>,</a> fue un artículo casi
a vuela pluma y rápido sin detenerme en detalles y eso ha propiciado
varias dudas.  Además, algunos me habéis preguntado por más detalles
sobre la <i>publicación</i> y los distintos formatos en los que podemos
publicar.  Además de detalles que hay que tener en cuenta.  El
principal foco de atención han sido las plantillas, y particularmente
qué <i>opciones</i> de exportación son más aconsejables.  También cómo
montar un servidor local para visualizar los cambios y hacer pruebas,
en el caso de que sea un proyecto para <code>html</code>: bien sea un <i>blog</i> o
simplemente documentación. Y también cómo gestionar si se desea que la
salida se produzca en varios formatos, por ejemplo, <code>html</code> y <code>pdf</code>. Y
también si es mejor utilizar etiquetas <code>include</code> o enlazar los
archivos.  Algunas de estas preguntas tienen respuestas sencillas de
procedimiento, pero a otras sólo puedo contestar: <i>depende</i>. Ahora
bien, ese <i>depende</i> es lo que explico en adelante.
</p>

<p>
El <i>depende</i> principal es el de la salida que queremos obtener y en
función de esa salida debemos trabajar. Cuando el proyecto sólo se
publicará en un formato, no hay ningún problema: configuramos ese
formato y no hará falta más. Cuando hacemos cambios generamos la
salida y todo funcionará perfectamente. El problema viene cuando
queremos generar documentos de diverso tipo con sus diferentes
idiosincrasias. No hace falta rebuscar mucho, por ejemplo, si nos
fijamos en la manera en que <code>html</code> y <code>TeX</code> numeran sus cabeceras,
veremos que son significativamente distintas y que, por tanto,
necesito tener configuradas opciones distintas según el formato de
salida. ¿Eso complica las cosas? Pues un poco: necesitamos cabeceras
de exportación con opciones distintas, e incluso quizá diferentes
opciones de publicación. Ten en cuenta que <i>exportación</i> y
<i>publicación</i>, aunque lo pueda parecer de primeras, no son sinónimos
para mí.
</p>

<p>
Efectivamente, podemos separar lo que significa convertir nuestro
documento <code>org</code> en otro formato, ─eso es exportación─, de lo que
significa facilitar el acceso al contenido, ─que es la publicación─.
Si te has perdido un poco, espero que lo entiendas con el ejemplo.
</p>

<p>
Vamos a imaginar que queremos generar una documentación de algún
proyecto es una especie de <i>wiki</i> donde las distintas <i>páginas</i>
estarán enlazadas mediante enlaces, valga la <i>rebuznancia</i>, entre
ficheros <code>org</code>.  Exportar esta <i>wiki</i> a formato <code>html</code> es sencillo:
sólo hay que seguir los pasos del artículo donde explicaba como
publicar <code>html</code> desde <code>org-mode</code>. Como todo ya está explicado en ese
artículo no voy a dar muchos detalles: se ponen enlaces entre los
archivos <code>org</code> y recordamos activar <code>:recursive t</code> en las opciones de
publicación del proyecto, ya está todo listo... Pero, <i>opciones de
publicación</i>... <i>opciones de exportación</i>... <i>¡uff!</i> ¿de qué va todo
esto?
</p>
<div id="outline-container-org1668720" class="outline-2">
<h2 id="org1668720">Opciones de exportación</h2>
<div class="outline-text-2" id="text-org1668720">
<p>
Algunos me dicen que copian las cabeceras de sus documentos <code>org</code><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> y no
entienden por qué unas veces les muestra bien los subíndices, como en
H<sub>2</sub>O ─por poner un ejemplo─, y otras veces muestra algo como H_2O o
incluso H<sub>2O</sub>, sin ninguna explicación aparente. La respuesta a ese
gran enigma es que estás copiando las <i>opciones</i> sin saber qué
significan y qué comportamientos controlan.  Revisa la documentación
de <code>org-mode</code>, ahí está todo explicado.  Pero si te da pereza sigue
leyendo un poco.
</p>

<p>
La manera más rápida de generar una plantilla de exportación es copiar
una ya hecha.  Sin embargo, algunas veces nos encontramos con líneas
como la siguiente:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #6272a4;">#+options:  H:3 num:nil toc:nil \n:nil ::nil |:t ^:{} -:nil f:t *:t &lt;:t</span>
</pre>
</div>

<p>
Nos puede parecer algo esotérico y casi mágico, que casi da miedo
tocar para no <i>cagarla</i>, pero tenemos que ser conscientes que cada
elemento de esa lista tiene efectos sobre el documento
generado. Además esos elementos se circunscriben al fichero en
cuestión y sólo afectan a la exportación del mismo. Utilizar otras
opciones, para otros contenidos es lo que hace que la utilidad de las
plantillas sea increíble. Por ejemplo, en la exportación a <code>html</code>
podemos no necesitar tener el índice de los apartados, ─especialmente
si lo vamos a tratar como páginas <i>web</i> enlazadas─, pero al generar la
salida para <code>pdf</code> con los mismos archivos, nos puede parecer
imprescindible. Lo más rápido será tener plantillas para generar
<code>html</code> y para generar <code>pdf</code>... además, al generar así los <code>html</code>
querremos que se creen un montón de ficheros con una determinada
estructura, mientras que para el <code>pdf</code> lo querremos todo en un archivo
<i>monolítico</i>. Bien, vale, pero me estoy enrollando. Vamos con las
opciones, no voy a ser exhaustivo, porque están bien explicadas en la
documentación de <code>org-mode</code>. Voy a explicar, brevemente las que he
puesto en el ejemplo anterior y alguna más porque la considero
importante conocer.
</p>

<dl class="org-dl">
<dt><code>H</code></dt><dd>Establece el número de niveles de cabecera que se exportarán
como tal. A partir del número expresado, el resto de cabeceras <code>org</code>
se exportarán como elementos de una lista.</dd>
<dt><code>num</code></dt><dd>Establece si queremos que las cabeceras se numeren al
exportar. Un valor de <code>nil</code> hará que se omita el número. También
podemos tenerlo activado mediante <code>t</code> y si, en el documento,
queremos que algún apartado no sea numerado se le puede añadir una
propiedad (<code>C-c C-x p</code>) <code>UNNUMBERED</code> puesta a <code>t</code>. Si ponemos esa
propiedad a <code>notoc</code>, el apartado y todos sus subapartados no
aparecerán tampoco en el índice de contenido.</dd>
<dt><code>toc</code></dt><dd>Establece si al exportar se generará un índice de contenido
para el fichero. Si en lugar de <code>nil</code> o <code>t</code> aparece un número, lo
que hace es limitar el nivel de encabezado que aparecerá en el
índice de contenido.</dd>
<dt><code>\n</code></dt><dd>Establece si debe preservar los saltos de línea cuando
realiza la exportación.</dd>
<dt><code>:</code></dt><dd>Establece si las regiones de ancho fijo (que comienzan cada
línea con un carácter <code>:</code> y un espacio o retorno de carro) se
exportan al fichero generado o se ocultan. Si establecemos el valor
a <code>nil</code>, podemos utilizar estas secciones como si fueran comentarios
dentro de nuestro fichero <code>org</code> que luego no aparecerán en la
salida. Podemos hacer algo similar con los <i>drawers</i> y la opción
<code>d</code>.</dd>
<dt><code>|</code></dt><dd>Establece si exportará las tablas.</dd>
<dt><code>^</code></dt><dd>Establece cómo se tratarán los subíndices y superíndices.
Los valores pueden ser <code>nil</code>, <code>t</code> ó <code>{}</code>. Los dos primeros
desactivan y activan, respectivamente, la notación que emplea los
caracteres <code>_</code> para subíndices y <code>^</code> para superíndices. La opción
marcada con las llaves indica que sólo tendrá efecto, convertir a
subíndice o superíndice, en aquellas cadenas que se encuentren entre
llaves a continuación de uno de esos caracteres.</dd>
<dt><code>-</code></dt><dd>Activar o desactivar la conversión de cadenas especiales. Es
decir, si activamos esta opción la salida interpretará las cadenas
especiales <code>\-</code>, <code>--</code> y <code>---</code>.</dd>
<dt><code>f</code></dt><dd>Activa o desactiva la exportación de las notas a pie de
página.</dd>
<dt><code>*</code></dt><dd>Activa o desactiva la exportación de texto enfatizado,
negrita, cursiva, etc.</dd>
<dt><code>&lt;</code></dt><dd>Activa o desactiva la inclusión de marcas de tiempo y fecha
en la exportación.</dd>
</dl>

<p>
Hay más y todas interesantes y están muy bien explicadas en la
documentación de <code>org-mode</code>. Además, otra opción que me parece muy
importante es poder exportar el contenido con otro nombre. Como es
normal, por defecto, el contenido se exportará a un fichero con nombre
idéntico al fichero <code>org</code> pero con la extensión adecuada: <code>html</code>,
<code>pdf</code>, etc.
</p>

<p>
Si como hemos visto antes, tenemos un fichero que realizará la
exportación a <code>html</code> y otro a <code>pdf</code>, no podemos llamar a los dos con
el mismo nombre, porque ya hemos visto que podemos necesitar
diferentes opciones de exportación. Por ejemplo, si tenemos un fichero
<code>exportar-html.org</code> y otro <code>exportar-pdf.org</code>, por defecto se
generarán los archivos de salida <code>exportar-html.html</code> y
<code>exportar-pdf.pdf</code> ... feo ¿no? Nos gustaría obtener como resultado
<code>exportar.html</code> y <code>exportar.pdf</code>. ¿Cómo lo podemos hacer? Añadiendo en
cada fichero el nombre del fichero donde queremos exportar, por
ejemplo, en nuestro fichero <code>exportar-html.org</code>:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #6272a4;">#+setupfile: mi-plantilla-html.org</span>
<span style="color: #6272a4;">#+export_file_name: exportar.html</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-orgaf54f2e" class="outline-2">
<h2 id="orgaf54f2e">Opciones de publicación</h2>
<div class="outline-text-2" id="text-orgaf54f2e">
<p>
Mucho de lo que voy a hablar ahora, ya lo conté en el artículo sobre
publicar <code>html</code> que dije antes. Voy a repetir algunas cosas, pero
añadiendo la opción de que queremos exportar tanto a <code>html</code> en
ficheros distintos, como en <code>pdf</code> en un fichero monolítico.
</p>

<p>
Mi costumbre, como ya conté, es tener en el proyecto un fichero
<code>elisp</code> para configurar los proyectos de exportación y cargarlo según
lo necesite. Pongo aquí uno que podría servirnos de ejemplo, o
plantilla para nuestro proyecto de <i>doble exportación</i>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">ox-publish</span>)

(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-publish-project-alist
      '(
        (<span style="color: #f1fa8c;">"org-to-html"</span>
         <span style="color: #8be9fd; font-style: italic;">:base-directory</span> <span style="color: #f1fa8c;">"~/proyectos/programa/documentacion/"</span>
         <span style="color: #8be9fd; font-style: italic;">:base-extension</span> <span style="color: #f1fa8c;">"org"</span>
         <span style="color: #8be9fd; font-style: italic;">:publishing-directory</span> <span style="color: #f1fa8c;">"~/proyectos/programa/docs/"</span>
         <span style="color: #8be9fd; font-style: italic;">:language</span> es
         <span style="color: #8be9fd; font-style: italic;">:publishing-function</span> org-html-publish-to-html
         <span style="color: #8be9fd; font-style: italic;">:exclude</span> <span style="color: #f1fa8c;">"documentacion-pdf.org"</span>
         <span style="color: #8be9fd; font-style: italic;">:recursive</span> t
         <span style="color: #8be9fd; font-style: italic;">:section-numbers</span> nil
         <span style="color: #8be9fd; font-style: italic;">:headline-levels</span> 6
         <span style="color: #8be9fd; font-style: italic;">:html-preamble</span> t)
        (<span style="color: #f1fa8c;">"org-to-pdf"</span>
         <span style="color: #8be9fd; font-style: italic;">:base-directory</span> <span style="color: #f1fa8c;">"~/proyectos/programa/documentacion"</span>
         <span style="color: #8be9fd; font-style: italic;">:base-extension</span> <span style="color: #f1fa8c;">"org"</span>
         <span style="color: #8be9fd; font-style: italic;">:language</span> es
         <span style="color: #8be9fd; font-style: italic;">:publishing-directory</span> <span style="color: #f1fa8c;">"~/proyectos/programas/docs"</span>
         <span style="color: #8be9fd; font-style: italic;">:exclude</span> <span style="color: #f1fa8c;">"documentacion-html.org"</span>
         <span style="color: #8be9fd; font-style: italic;">:recursive</span> nil
         <span style="color: #8be9fd; font-style: italic;">:section-numbers</span> t
         <span style="color: #8be9fd; font-style: italic;">:publishing-function</span> org-latex-publish-to-pdf
         <span style="color: #8be9fd; font-style: italic;">:headline-levels</span> 5)
        (<span style="color: #f1fa8c;">"org-auxiliares"</span>
         <span style="color: #8be9fd; font-style: italic;">:base-directory</span> <span style="color: #f1fa8c;">"~/proyectos/programa/documentacion/"</span>
         <span style="color: #8be9fd; font-style: italic;">:base-extension</span> <span style="color: #f1fa8c;">"css</span><span style="color: #8be9fd;">\\</span><span style="color: #bd93f9;">|</span><span style="color: #f1fa8c;">js</span><span style="color: #8be9fd;">\\</span><span style="color: #bd93f9;">|</span><span style="color: #f1fa8c;">png</span><span style="color: #8be9fd;">\\</span><span style="color: #bd93f9;">|</span><span style="color: #f1fa8c;">ttf</span><span style="color: #8be9fd;">\\</span><span style="color: #bd93f9;">|</span><span style="color: #f1fa8c;">pdf"</span>
         <span style="color: #8be9fd; font-style: italic;">:publishing-directory</span> <span style="color: #f1fa8c;">"~/proyectos/programa/docs/"</span>
         <span style="color: #8be9fd; font-style: italic;">:recursive</span> t
         <span style="color: #8be9fd; font-style: italic;">:publishing-function</span> org-publish-attachment)
        (<span style="color: #f1fa8c;">"documentacion"</span> <span style="color: #8be9fd; font-style: italic;">:components</span> (<span style="color: #f1fa8c;">"org-to-html"</span> <span style="color: #f1fa8c;">"org-to-pdf"</span> <span style="color: #f1fa8c;">"org-auxiliares"</span>))))
</pre>
</div>

<p>
Ese código está planteado para una estructura tal que:
</p>

<pre class="example" id="orgcf300db">
.
├── docs
│   └── ... (directorio donde se publicará)
├── documentacion
│   ├── documentacion-html.org
│   └── documentacion-pdf.org
├── publicacion-docs.el
├── org
│   ├── css
│   │   └── ... (hojas de estilo)
│   ├── img
│   │   └── ... (ficheros de imagen)
│   ├── js
│   │   └── ... (ficheros javascript)
│   └── ... (ficheros org)
├── plantillas
│   ├── plantilla-html.org
│   └── plantilla-pdf.org
└── README.org
</pre>

<p>
Como se puede ver, tenemos dos tipos de plantillas: para <code>html</code> y para
<code>pdf</code>. Dos tipos de ficheros fuente: para <code>html</code> y para <code>pdf</code>. ¿Cómo
evitamos que al exportar el sistema nos cree más salida de la que
necesitamos. Es decir, sólo necesitamos que se genere <code>html</code> desde el
fichero <code>documentación-html.org</code> y sólo necesitamos que se genere
<code>pdf</code> desde el fichero <code>documentación-pdf.org</code>. Para esto tenemos dos
proyectos de exportación: <code>org-to-html</code> y <code>org-to-pdf</code>. Pero vemos
que, aunque los contenidos al final serán los mismos las opciones
cambian. Especialmente hay que señalar que el <i>otro</i> generador es
excluido del proyecto. Cuando generamos <code>html</code> queremos que utilice el
<code>org</code> correspondiente e ignore el otro.
</p>
</div>
</div>
<div id="outline-container-orgd8dec4f" class="outline-2">
<h2 id="orgd8dec4f">Montar un servidor local</h2>
<div class="outline-text-2" id="text-orgd8dec4f">
<p>
Cuando trabajamos en un proyecto que se visualizará como una página
<i>web</i> es útil, muchas veces, contar con una manera de montar un
servidor local que actúe como si fuera un sitio de <i>Internet</i> general,
pero sólo accesible desde <code>localhost (127.0.0.1)</code>. No tienes por qué
hacerlo desde <i>Emacs</i> si no quieres, pero ya que estás editando con
él, para qué lo vas a hacer desde fuera.  Desde fuera hay muchas
maneras: hay lenguajes que proporcionan sus propios servidores
locales y que podemos utilizar.
</p>

<p>
Por ejemplo, en <code>Python 3.x</code>:
</p>

<div class="org-src-container">
<pre class="src src-shell">python -m http.server 8080
</pre>
</div>

<p>
En <code>PHP</code>:
</p>

<div class="org-src-container">
<pre class="src src-shell">php -S localhost:8080
</pre>
</div>

<p>
En <code>Ruby</code>:
</p>

<div class="org-src-container">
<pre class="src src-shell">ruby -run -e httpd . -p 8080
</pre>
</div>

<p>
El listado puede ser muy largo, porque parece que cada lenguaje que se
utiliza de uno u otro modo para programar para la <i>web</i> tiene un
sistema de hacerlo. En todos los casos anteriores se cuenta que el
lanzamiento se hace situándose en el directorio donde se encuentran
los ficheros de salida y utilizan, algunos sin mencionarlo, el
directorio actual (<code>.</code>) para levantar un <i>demonio</i> <code>httpd</code>. Además, en
todos los ejemplos anteriores se ha utilizado el puerto <code>8080</code>, pero
se podría utilizar cualquier otro al uso, recordando que los puertos
recomendados para los servicios, ─por ejemplo, <code>80</code> es el puerto
<code>http</code> por defecto─, necesitan permisos de <i>root</i> para habilitarlos.
</p>

<p>
Es bastante cómodo tener el servidor levantado, al hacer cambios y
generar la salida en su correspondiente directorio, podemos ir viendo
el efecto de esos cambios con cualquier navegador.
</p>

<p>
En los ejemplos anteriores hemos podido ve que las herramientas para
montar servidores locales, necesitan todas un par de datos: el
directorio donde está la página y el puerto por el que servir el
contenido.  Normalmente, en los ejemplos anteriores el directorio se
omite, porque se entiende que el comando se lanza desde una consola
estando situados en él.  De la misma manera, en <i>Emacs</i>, necesitamos
especificar qué directorio y qué puerto queremos utilizar. Esto lo
hacemos con un poco de código <code>elisp</code>. Por ejemplo, una de las
estrategias para configurar nuestro servidor local puede ser ajustar
los valores necesarios en el mismo fichero que cargábamos antes con
los proyectos de publicación, añadiendo las siguientes líneas:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> httpd-port 8080)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> httpd-root <span style="color: #f1fa8c;">"~/mi-directorio"</span>)
(httpd-start)
</pre>
</div>

<p>
Si sólo tienes un proyecto de publicación <code>html</code>, lo puedes establecer
mediante <code>M-x customize-group &lt;RET&gt; simple-httpd</code>. En todo caso, esas
tres líneas de código bastan para lanzar nuestro servidor. Las podemos
evaluar con el código del proyecto de publicación o tenerlas a mano en
algún <i>buffer</i> donde las podamos evaluar... o establecerlas una a una
con <code>M-x</code>.
</p>
</div>
</div>
<div id="outline-container-org1dad14c" class="outline-2">
<h2 id="org1dad14c">Flujo de trabajo</h2>
<div class="outline-text-2" id="text-org1dad14c">
<p>
Más que por <code>simple-httpd.es</code>, que es el fuente donde descansa nuestro
servidor, las preguntas estaban enfocadas al flujo de trabajo con
<code>html</code>.  Bien, hasta aquí hemos hablado de los primeros pasos:
</p>

<ol class="org-ol">
<li>Crear el contenido con <code>org-mode</code>.</li>
<li>Publicar el contenido con las herramientas de <i>Emacs</i>.</li>
<li>Servir los <code>html</code> desde un servidor local para visualizarlos.</li>
</ol>

<p>
¿Cómo seguimos? Cuando tenemos alguna modificación que comprobar la
publicamos y para eso, sólo hay que ir repitiendo los pasos del <code>1</code> al
<code>3</code> y viéndolos en el navegador que más nos guste. Por otro lado, a
algunos no os gusta partir de un <code>css</code> ya hecho, para ir modificando
los distintos aspectos del mismo. La justificación que me habéis dado
es válida: terminas con un <code>css</code> con un montón de elementos que tiene
que cargar el navegador, pero que no son útiles. Por otro lado, además
de la declaración del <code>css</code> que se incluye en la cabecera en la misma
aparece un apartado de <code>style</code>, no sólo es que queda feo, es que ocupa
también. Se puede aligerar la cabecera desactivando la exportación de
esos valores mediante:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #6272a4;">#+options: html-style: nil</span>
</pre>
</div>

<p>
Si queremos crear nuestro <code>css</code> desde lo más básico a lo más general,
podemos observar dicha inclusión y tomarla como código básico para
exportación.  Al menos, la exportación desde <code>org-mode</code> establece las
siguientes clases específicas:
</p>

<dl class="org-dl">
<dt><code>p.author</code></dt><dd>Información del autor incluyendo el <i>email</i>.</dd>
<dt><code>p.date</code></dt><dd>Fecha de publicación</dd>
<dt><code>p.creator</code></dt><dd>Información sobre la versión de <code>org-mode</code> y <i>Emacs</i>.</dd>
<dt><code>.title</code></dt><dd>Título del documento.</dd>
<dt><code>.subtitle</code></dt><dd>Subtítulo del documento.</dd>
<dt><code>.todo</code></dt><dd>palabras clave <code>TODO</code>.</dd>
<dt><code>.done</code></dt><dd>palabras clave <code>DONE</code>.</dd>
<dt><code>.WAITING</code></dt><dd>clase para encabezados a la espera.</dd>
<dt><code>.timestamp</code></dt><dd>etiqueta de tiempo.</dd>
<dt><code>.timestamp-kwd</code></dt><dd>palabra clave asociada a una etiqueta de tiempo,
como <code>scheduled</code>.</dd>
<dt><code>.timestamp-wrapper</code></dt><dd>espacio alrededor de la etiqueta de tiempo y
su palabra clave.</dd>
<dt><code>.tag</code></dt><dd>Etiqueta en una cabecera. Típicamente las que aparecen a
la derecha de la cabecera.</dd>
<dt><code>._HOME</code></dt><dd>Cada etiqueta utilizándose como una clase, reemplazando
<code>@</code> por <code>_</code></dd>
<dt><code>.target</code></dt><dd>objetivo para <i>links</i>.</dd>
<dt><code>.linenr</code></dt><dd>número de línea en bloques de código</dd>
<dt><code>.code-highlighted</code></dt><dd>líneas de código destacadas</dd>
<dt><code>div.outline-N</code></dt><dd>Nivel de cabecera, donde <code>N</code> es un número (<code>1</code>,
<code>2</code>, ... <code>6</code>)</dd>
<dt><code>div.outline-text-N</code></dt><dd><code>div</code> extra para el texto de la cabecera.</dd>
<dt><code>.section-number-N</code></dt><dd>Número de sección de la cabecera.</dd>
<dt><code>.figure-number</code></dt><dd>Etiqueta para las figuras tal que «Figure 1:»</dd>
<dt><code>.table-number</code></dt><dd>Etiqueta para las tablas, tal que «Table 1:»</dd>
<dt><code>.listing-number</code></dt><dd>Etiqueta para bloques de código «Listing 1:»</dd>
<dt><code>div.figure</code></dt><dd>Clase para imágenes en líneas de texto.</dd>
<dt><code>pre.src</code></dt><dd>Código fuente formateado.</dd>
<dt><code>pre.example</code></dt><dd>bloques <code>example</code></dd>
<dt><code>p.verse</code></dt><dd>Párrafos <i>verse</i></dd>
<dt><code>div.footnotes</code></dt><dd>Cabecera para la sección de <i>notas al pie</i>.</dd>
<dt><code>p.footnote</code></dt><dd>Párrafo que contiene una nota al pie.</dd>
<dt><code>.footref</code></dt><dd>Número de referencia de una nota al pie (siempre como
<code>&lt;sup&gt;</code>).</dd>
<dt><code>.footnum</code></dt><dd>Número de una nota al pie (siempre como <code>&lt;sup&gt;</code>).</dd>
<dt><code>.org-svg</code></dt><dd>Clase por defecto para una imagen <code>.svg</code> enlazada.</dd>
</dl>

<p>
¿Qué ocurre si quiero definir mis propias clases? Pues es algo
sencillo. Vamos a imaginar que quiero crear una clase para el <code>css</code>
que me <i>formatee</i> con un determinado estilo, por ejemplo, un <i>aviso</i>,
que haga que el texto se escriba en rojo para destacarlo. El código
<code>css</code> es muy sencillo:
</p>

<div class="org-src-container">
<pre class="src src-css"><span style="color: #50fa7b; font-weight: bold;">.aviso</span> {
  <span style="color: #ff79c6; font-weight: bold;">color</span>: <span style="color: #ffffff; background-color: #FF0000;">#FF0000</span>;
}
</pre>
</div>

<p>
Hacer que un párrafo de nuestro documento se muestre con el formato
para la clase <code>aviso</code> es tan sencillo como escribir en nuestro fichero
<code>org</code>:
</p>

<div class="org-src-container">
<pre class="src src-org">...

<span style="color: #6272a4;">#+attr_html: :class aviso</span>
Este es un p&#225;rrafo de aviso que mostrar&#225; el texto en rojo.

...
</pre>
</div>

<p>
Si no quiero definir una clase y utilizar directamente las propiedades
de <code>html</code> podría haber escrito el código así:
</p>

<div class="org-src-container">
<pre class="src src-org">...

<span style="color: #6272a4;">#+attr_html: :class aviso :style color:red;</span>
Este es un p&#225;rrafo de aviso que mostrar&#225; el texto en rojo.

...
</pre>
</div>

<p>
Además de las clases mencionadas arriba, un <code>css</code> básico debe contar
con definiciones para las etiquetas de texto habituales en un fichero
<code>html</code>: <code>&lt;html&gt;</code>, <code>&lt;body&gt;</code>, <code>&lt;h1&gt;</code> ... <code>&lt;h6&gt;</code>, <code>&lt;p&gt;</code>, <code>&lt;em&gt;</code>, <code>&lt;i&gt;</code>,
<code>&lt;b&gt;</code>, <code>&lt;table&gt;</code>, <code>&lt;dt&gt;</code>, <code>&lt;dh&gt;</code>, <code>&lt;dd&gt;</code>, <code>&lt;li&gt;</code>, <code>&lt;ol&gt;</code>, <code>&lt;ul&gt;</code>,
<code>&lt;img&gt;</code>... y también puede definir estilos especiales para dos tipos
de elementos marcados con <code>id=</code>: <code>#preamble</code>, <code>#content</code> y
<code>#postamble</code>.
</p>

<p>
De estos tres últimos elementos, nuestro fichero <code>org</code> genera sólo,
por decirlo así, el <code>content</code>. El pie y la cabecera están controladas
por variables:
</p>

<dl class="org-dl">
<dt><code>org-html-preamble</code></dt><dd>si no es <code>nil</code> genera un preámbulo con el
contenido de la variable <code>org-html-preamble-format</code>.</dd>
<dt><code>org-html-preamble-format</code></dt><dd>cadena <code>html</code> que se mostrará en la
exportación. Por defecto está vacía.</dd>
<dt><code>org-html-postamble</code></dt><dd>si no es <code>nil</code> genera un pie de página con
el contenido de la variable <code>org-html-postamble-format</code>.</dd>
<dt><code>org-html-postamble-format</code></dt><dd><p>
cadena <code>html</code> que se mostrará.  Por
defecto, su valor se establece:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-html-postamble-format
      '((<span style="color: #f1fa8c;">"en"</span> <span style="color: #f1fa8c;">"&lt;p class=\"author\"&gt;Author: %a (%e)&lt;/p&gt;
&lt;p class=\"date\"&gt;Date: %d&lt;/p&gt;
&lt;p class=\"creator\"&gt;%c&lt;/p&gt;
&lt;p class=\"validation\"&gt;%v page&lt;/p&gt;"</span>)))
</pre>
</div></dd>
</dl>

<p>
Algunos sistemas de publicación, se basan en todas estas estructuras,
variables y métodos para generar sitios <i>web</i> estáticos. Por ejemplo,
<code>org-static-blog</code>, con el que está hecho este <i>blog</i>, se basa en estos
procedimientos añadiéndoles un poco de funcionalidad mediante código
<code>elisp</code>.
</p>
</div>
</div>
<div id="outline-container-org2c9526f" class="outline-2">
<h2 id="org2c9526f">Conclusiones</h2>
<div class="outline-text-2" id="text-org2c9526f">
<p>
Este no es un artículo muy coherente. He escrito sobre distintos
aspectos de lo mismo y hecho muchas referencias a un artículo anterior
que no tienes por qué haber leído. Sin embargo, espero que hayas
podido ver, o al menos intuir, toda la flexibilidad que tiene
<code>org-mode</code> a la hora de exportar y publicar contenido.
</p>

<p>
Todo lo que he escrito lo he sacado de la documentación, por lo que la
contestación rápida a las preguntas hubiera sido: <i>lee el puto
manual</i>.  Pero no me sale ser tan <i>borde</i> y prefiero contestar, porque
muchas veces me obliga a buscar el porqué de las cosas y entender
mejor lo que creía que ya sabía.
</p>

<p>
A veces, la necesidad de concisión hace que dé por sabido algo que
parece no serlo. Eso es fuente de muchas de las preguntas que me
hacéis y para las que, de vez en cuando, tampoco tengo una respuesta
clara, porque yo también las puedo estar haciendo por inercia y sin
<i>leer el puto manual</i>... así que: ¡gracias por las preguntas! Porque
me obligan a buscar las respuestas.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Hay quien me ha dicho: <i>de sitios solventes como tu
blog</i>... ¿solvente mi <i>blog</i>? Revisa el concepto, por favor. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2021/03/03/publicar-con-org-mode.html</link>
  <pubDate>Wed, 03 Mar 2021 09:19:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Nova projekto por videoj]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-02-25</div>
<p>
Hodiaŭ mi alportas ĉi tie rapidan noton pri nova ilo por verki, fari
kaj konservi esperantajn videojn, libere kaj senpage. Mi prezentas
<a href="https://fediverse.tv">fediverse.tv</a> por tiuj, kiuj volus krei novajn videojn, <i>video-blogoj</i>,
liberigi iliajn videojn de iloj kiel <i>Youtube</i> aŭ <i>vimeo</i>, ktp.
</p>

<p>
Kelkaj tagoj antaŭe, mi vidis ekkomencintan projekton mastrumitan de
amikaro kiu mi kontaktas nur rete. La celo de la grupo estas doni
liberan spacon al tiuj, kiuj bezonas lokon por videoj kaj ne volas uzi
la ilojn kaj la regulojn de <i>Google</i> kaj <i>vimeo</i>. Mi legis la
manifeston (per la hispana) ĉe:
</p>

<p>
<a href="https://blog.fediverse.tv/Manifiesto/">https://blog.fediverse.tv/Manifiesto/</a>
</p>

<p>
Post legi tion mi, ŝerce, diris al tiuj amikoj: «Do, ne interesas al
mi, ne estas <i>Esperanto</i> inter la lingvoj permesataj». La respondo
estis tuja: «se vi volas esperanton, vi iĝos moderiganto por tiu
lingvo» ... Do, mi akceptis la taskon.
</p>

<p>
La <i>idearo</i> estas tiel:
</p>

<ul class="org-ul">
<li>Malakcepti ajna faŝisma ideo aŭ ekstremisma.</li>
<li>Respekti la geografian kaj etnan devenon de la homoj.</li>
<li>Respekti ĉiun identeco pri sekso kaj genro.</li>
<li>La <i>scio</i> devas esti libere atingebla por tiuj, kiuj volos akiri
ĝin.</li>
<li>Traktu la aliajn ulojn tiel, kiel vi volas estu traktota.</li>
<li>Malakcepti iun ajn filmon rilata al neplenaĝuloj.</li>
<li>Krei, verki fari originalan kaj liberajn aĵojn (per libera licenco).</li>
<li>Rajto por mencii verkado kun aŭtoraj rajtoj (oni devas mencii la
verkon kaj la originalajn aŭtorojn).</li>
</ul>

<p>
Unue la administrantoj ne volas <i>morti per sukceso</i> kaj ili limigis la
registrado: nur 200 kontoj por sekurigi la bonan funkciadon de ĉiuj el
ili. Kiam kreskos la retan spacon ankaŭ malfermos la ebleco por krei
novajn kontojn. Nun restas kelkajn kontojn. Mi esperas ke iu ajn
esperantisto volos fari konton por siaj esperantaj videoj, aŭ
transdoni tiujn, kiujn li havas ĉe <i>youtube</i>. 
</p>

<p>
Do, se vi volas spacon por konservi viajn videojn, kiu ne spionas
viajn datumojn, estas libera kaj respektema, memoru pri <a href="https://fediverse.tv/">fediverse.tv</a>
</p>

<p>
Se vi ne konas la <i>federa universo</i> devas scii, ke ĝi estas lokaj
serviloj, interkonektitaj por diversaj servoj: sociaj retoj kiel
<i>mastodon</i>, <i>pleroma</i>, <i>gnusocial</i>; lokoj por kunigi fotojn kaj
bildojn, kiel <i>pixelfed</i>; lokoj por kunigi filmojn kiel
<i>peertube</i>... ĉiuj el ili povas vidigi verkon en alia reto. La
serviloj estis <i>federaj</i>.
</p>

<p>
La ilo <i>fediverse.tv</i> estas <i>peertube</i> loko kaj ĝi konektas kun la
tuta federa reto kiu respektas la idearon. Mi esperas vidi vin tie.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/redes-sociales/index.html">redes-sociales</a> <a href="/tags/fediverso/index.html">fediverso</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[redes-sociales]]></category>
  <category><![CDATA[fediverso]]></category>
  <link>https://notxor.nueva-actitud.org/2021/02/25/nova-projekto-por-videoj.html</link>
  <pubDate>Thu, 25 Feb 2021 10:01:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Aprender elixir]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-02-15</div>
<p>
Estos días de atrás abandoné el aprendizaje de <code>Rust</code> por motivos
ajenos al propio lenguaje o a mi dura mollera. Mi tiempo de estudio se
ha quedado vacío y hay unas horas al día que podría aprovechar en
procrastinar como todo el mundo o buscarme algo distinto que aprender.
Después de pensarlo un poco aparecieron un par de puntos que me
gustaría poder aprender a mi ritmo:
</p>

<ol class="org-ol">
<li><code>elixir</code></li>
<li><code>phoenix</code></li>
</ol>

<p>
Parece que <a href="https://git.pleroma.social/pleroma/pleroma/">la red social pleroma</a> está realizada con <code>elixir</code> y montada
sobre un <i>framework</i> muy parecido a <code>ruby on rails</code>, porque se diseñó
con él en mente, <a href="https://www.phoenixframework.org/">que se llama <code>phoenix</code>.</a>  Si a eso le añadimos que
<code>elixir</code> puede ejecutar e integrarse con librerías hechas en <code>erlang</code>,
y que <code>erlang</code> es un lenguaje que me encanta, no he podido resistir la
curiosidad. Además creo que tengo un proyecto por finalizar donde
ambas herramientas pueden ser de gran ayuda.
</p>
<div id="outline-container-org931d208" class="outline-2">
<h2 id="org931d208">Primeras impresiones</h2>
<div class="outline-text-2" id="text-org931d208">
<p>
De momento sólo he echado un ojo por encima de manera rápida a
<code>elixir</code> y sus satélites. Llamo satélites a esos programas que vienen
con los lenguajes para formar una especie de ecosistema simbiótico
entre distintas aplicaciones. Con <code>erlang</code> se trabajaba con <code>rebar3</code>
─aunque yo era más partidario de utilizar <code>make</code>, como el <i>viejuno</i>
que soy~, en <code>Rust</code> se utilizaba <code>cargo</code> y parece que en <code>elixir</code> se
utiliza <code>mix</code>. Ahora parece que todos los lenguajes tienen su sistema
de paquetes y herramienta para instalar librerías y dependencias.
</p>

<p>
Por resumir muy rápido mis primeras impresiones sobre el lenguaje,
<code>elixir</code>, me está pareciendo un <code>erlang</code> con una sintaxis muy parecida
a <code>Ruby</code>. No he profundizado mucho pero, a primera vista, mantiene
todas esas cosas que me gustan de <code>erlang</code>, también permite utilizar
<i>OTP</i> pero con sintaxis <code>elixir</code> y algunas características más
especiales que tengo que asimilar todavía.
</p>
</div>
</div>
<div id="outline-container-orgf3a50b2" class="outline-2">
<h2 id="orgf3a50b2">Preparando las herramientas</h2>
<div class="outline-text-2" id="text-orgf3a50b2">
</div>
<div id="outline-container-org2f6ef20" class="outline-3">
<h3 id="org2f6ef20">Compilando <code>elixir</code></h3>
<div class="outline-text-3" id="text-org2f6ef20">
<p>
El lenguaje depende de tener instalado también <code>erlang</code>, y esa
dependencia la tengo cumplida, aunque un poco a mi manera: <a href="https://notxor.nueva-actitud.org/2020/12/12/compilando-erlang-en-opensuse.html">como ya
conté en este blog</a>, yo utilizo una versión compilada, instalada en mi
directorio personal de programas opcionales.  Básicamente, cualquier
cosa que necesito para hacer algunas pruebas, o que no está en un
paquete oficial para <i>OpenSuse</i> lo compilo en un directorio <i>local</i>
para mi usuario en el directorio <code>~/opt</code> y si es ejecutable, va a
<code>~/opt/bin</code>, y en él también hay librerías cargadas en <code>~/opt/lib/</code>,
etc.
</p>

<p>
El camino alternativo y fácil sería instalar los paquetes que vienen
para <i>OpenSuse</i>, sin embargo, mi enfermiza tendencia a complicarme la
vida hacen que me haya compilado estas herramientas.
</p>

<p>
Si has compilado <code>erlang</code>, como yo, no te costará nada compilar
también <code>elixir</code>.  Sin embargo, al descargar el código fuente del
lenguaje de su repositorio <code>git</code>, me encuentro que no hay un
<code>configure</code> que echarse a la cara.  La alternativa es modificar los
<code>path</code> en el <code>Makefile</code>. Esperaba tener que modificar toda aparición
de <code>/usr/local/</code> por mi directorio de <i>opcionales</i>, sin embargo, me
encontré que el fichero, ya en la primera línea del mismo comienza
por:
</p>

<div class="org-src-container">
<pre class="src src-makefile"><span style="color: #f8f8f2; font-weight: bold;">PREFIX</span> ?= /usr/local
</pre>
</div>

<p>
Y yo la cambié por:
</p>

<div class="org-src-container">
<pre class="src src-makefile"><span style="color: #f8f8f2; font-weight: bold;">PREFIX</span> ?= /home/notxor/opt
</pre>
</div>

<p>
Si os fijáis he puesto el <code>path</code> absoluto, porque el relativo <code>~</code> no
me funcionó correctamente. Una vez modificado el <code>Makefile</code> el proceso
es el habitual:
</p>

<div class="org-src-container">
<pre class="src src-shell">make
make install
</pre>
</div>

<p>
Eso compila e instala el lenguaje. Pero si intentamos generar también
la documentación nos saltará un error que nos dice que falta una
herramienta, <code>ex_doc</code>, para compilarlo. Si queremos tener también la
documentación tenemos que instalar alguna cosa más.  Suponiendo que
estamos aún en el directorio de los fuentes de <code>elixir</code> podemos
ejecutar lo siguiente:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #8be9fd; font-style: italic;">cd</span> ..
git clone git://github.com/elixir-lang/ex_doc.git
<span style="color: #8be9fd; font-style: italic;">cd</span> ex_doc
../elixir/bin/mix<span style="color: #ff79c6; font-weight: bold;"> do</span> deps.get, compile
</pre>
</div>

<p>
Al terminar la compilación de esa herramienta, podemos volver al
directorio de los fuentes de <code>elixir</code> y terminar con la compilación de
la documentación:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #8be9fd; font-style: italic;">cd</span> ../elixir
make docs                    <span style="color: #6272a4;"># </span><span style="color: #6272a4;">generar las p&#225;ginas HTML
</span>make docs <span style="color: #f8f8f2; font-weight: bold;">DOCS_FORMAT</span>=epub   <span style="color: #6272a4;"># </span><span style="color: #6272a4;">generar los documentos EPUB</span>
</pre>
</div>

<p>
Como digo, la instalación de la documentación y la herramienta que
necesita para generarse es totalmente opcional y podemos prescindir de
ella para trabajar. Al fin y al cabo, la documentación está accesible
desde la <i>Internet</i> sin necesidad de ocupar espacio en nuestro disco
duro.
</p>
</div>
</div>
<div id="outline-container-org183ed92" class="outline-3">
<h3 id="org183ed92">Instalando <code>PostgreSQL</code></h3>
<div class="outline-text-3" id="text-org183ed92">
<p>
¿Por qué <code>PostgreSQL</code>? La respuesta es sencilla: la base de datos por
defecto que utiliza <code>phoenix</code> es esa. La respuesta más larga implica,
o tiene que ver, que siempre me ha gustado esa base de datos más que
la más popular <code>MySQL</code> (ahora <code>mariadb</code>). Me vais a permitir que deje
las explicaciones para otro momento y no alargar el artículo en
demasía. Si al contrario, os gusta más <code>MySQL</code> también se puede
utilizar esa abase de datos.
</p>

<p>
Algunas consideraciones iniciales: No necesito un servidor de bases de
datos corriendo continuamente, tan sólo quiero hacer algunas pruebas
locales y temporales, por lo tanto, decidí no instalar el paquete de
que viene con <i>OpenSuse</i> y hacerlo todo más manual... ¿qué tal si lo
compilamos?
</p>

<p>
Me he bajado el código fuente de la <i>web</i> de <code>PostgreSQL</code> metido en un
archivo comprimido... ni siquiera he querido hacerlo con un
respositorio <code>git</code> para mantenerlo actualizado, porque no sé si durará
más allá de las pruebas que voy a hacer. Al desempaquetar el código
fuente vemos que se genera con las habituales herramientas de
<code>GNU/Linux</code>:
</p>

<div class="org-src-container">
<pre class="src src-shell">./configure --prefix=~/opt
make
make install
mkdir ~/opt/data
</pre>
</div>

<p>
Lo hecho hasta este momento es decirle a <code>configure</code> que utilice como
directorio destino <i>mi</i> directorio personal de herramientas totalmente
opcionales <code>~/opt</code> y que ahí se instalará todo. Por ejemplo, los
binarios irán al directorio <code>~/opt/bin</code>. Para arrancar el servidor y
pararlo me he hecho un pequeño <i>script</i> que me facilitará la vida:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #6272a4;">#</span><span style="color: #6272a4;">! /usr/bin/</span><span style="color: #ff79c6; font-weight: bold;">bash</span><span style="color: #6272a4;">
</span>
pg_ctl -D /home/notxor/opt/data -l /home/notxor/opt/data/logfile $<span style="color: #f8f8f2; font-weight: bold;">1</span>
</pre>
</div>

<p>
Ese contenido lo he guardado en <code>~/opt/bin/base-de-datos</code> y como el
directorio está en el <code>path</code> tan sólo tengo que llamar a:
</p>

<div class="org-src-container">
<pre class="src src-shell">base-de-datos start
</pre>
</div>

<p>
cuando quiero levantar la base de datos y a
</p>

<div class="org-src-container">
<pre class="src src-shell">base-de-datos stop
</pre>
</div>

<p>
cuando quiero parar el servidor. Para observar las conexiones y
acciones sobre la base de datos, se activa el fichero
<code>~/opt/data/logfile</code> para facilitarme la información necesaria para la
administración de la base de datos. Obsérvese que lo de <code>start</code> o
<code>stop</code> está en la sustitución del parámetro <code>$1</code> del <i>script</i>.
</p>

<p>
Para probar si todo funciona como se espera, voy a activar el servidor
de base de datos, crear una base de datos y conectarme a ella:
</p>

<div class="org-src-container">
<pre class="src src-shell">base-de-datos start
createdb test
psql test
</pre>
</div>

<p>
Si todo ha ido bien debería aparecernos un <code>prompt</code> que nos indica que
estamos conectados a la base de datos <code>test</code> y podemos hacer algunas
pruebas más, tanto con comandos de <code>PostgreSQL</code> como de instrucciones
<code>SQL</code>:
</p>

<pre class="example" id="org7141fea">
test=# \dS+
test=# select * from pg_user;
 usename | usesysid | usecreatedb | usesuper | userepl | usebypassrls |  passwd  | valuntil | useconfig 
---------+----------+-------------+----------+---------+--------------+----------+----------+-----------
 notxor  |       10 | t           | t        | t       | t            | ******** |          | 
(1 row)

test=# select * from pg_database;
  oid  |  datname  | datdba | encoding | datcollate  |  datctype   | datistemplate | datallowconn | datconnlimit | datlastsysoid | datfrozenxid | datminmxid | dattablespace |            datacl             
-------+-----------+--------+----------+-------------+-------------+---------------+--------------+--------------+---------------+--------------+------------+---------------+-------------------------------
 13299 | postgres  |     10 |        6 | es_ES.UTF-8 | es_ES.UTF-8 | f             | t            |           -1 |         13298 |          478 |          1 |          1663 | 
 16384 | test      |     10 |        6 | es_ES.UTF-8 | es_ES.UTF-8 | f             | t            |           -1 |         13298 |          478 |          1 |          1663 | 
     1 | template1 |     10 |        6 | es_ES.UTF-8 | es_ES.UTF-8 | t             | t            |           -1 |         13298 |          478 |          1 |          1663 | {=c/notxor,notxor=CTc/notxor}
 13298 | template0 |     10 |        6 | es_ES.UTF-8 | es_ES.UTF-8 | t             | f            |           -1 |         13298 |          478 |          1 |          1663 | {=c/notxor,notxor=CTc/notxor}
(4 rows)

test=# \q
</pre>

<p>
Bien, parece que todo ha funcionado correctamente. Es el momento de
pararlo a la espera de necesitarlo más adelante: <code>base-de-datos
stop</code>. Pero ya lo tengo listo para cuando haga falta.
</p>

<p>
¿Por qué no lo hago por el método tradicional de activar un demonio?
Sería el método más normal, si quisiera tener un servidor de datos
permanente, sin embargo, sólo necesitaré acceder a <code>PostgreSQL</code> cuando
esté haciendo las pruebas.
</p>
</div>
</div>
<div id="outline-container-orgc2b90c3" class="outline-3">
<h3 id="orgc2b90c3">Preparando <code>phoenix</code></h3>
<div class="outline-text-3" id="text-orgc2b90c3">
<p>
Como he dicho antes <code>phoenix</code> es un <i>framework</i> destinado a realizar
aplicaciones <i>web</i> muy influido por <i>ruby on rails</i>, pero desarrollado
en <code>elixir</code>. Puesto que el proyecto que tengo pensado pasa por
desarrollar, precisamente, una página <i>web</i> con servicios de un
<i>servidor</i> para múltiples <i>clientes</i>, creo que dicho <i>framework</i> es
una buena herramienta para probar.
</p>

<p>
Las dependencias principales ya las tengo satisfechas: <code>elixir</code> y
<code>PostgreSQL</code>. También depende de <code>erlang</code>, porque <code>elixir</code> necesita
una máquina virtual donde correr y para ello utiliza <code>BEAM</code>, pero
bueno, no la he nombrado porque se puede dar por obvia al instalarme
el lenguaje.
</p>

<p>
Para instalar el <i>framework</i> hay que tirar del gestor de paquetes de
<code>elixir</code>. No llego a entender la tendencia de todos los lenguajes a
tener su propio gestor de paquetes. Bueno, sí la entiendo pero me
sigue pareciendo una forma de ensuciar una instalación del sistema
operativo y una manera de generar conflictos y duplicar librerías.
Pero es cierto que al final, <code>pip</code> para <code>Python</code>, <code>gem</code> para <code>Ruby</code>,
<code>npm</code> para <code>node.js</code>, <code>cargo</code> para <code>Rust</code>, <code>rebar3</code> para <code>erlang</code> o
<code>mix</code> para <code>elixir</code>, por poner unos ejemplos, son herramientas que han
llegado para quedarse. De nada sirve quejarse, los <i>fans</i> de cada
lenguaje te hablan maravillas de la suya en cuestión. Aunque en
esencia son todas <i>el mismo perro</i>. Pero vamos con la instalación:
</p>

<div class="org-src-container">
<pre class="src src-shell">mix archive.install hex phx_new
</pre>
</div>

<p>
Aparecen una serie de mensajes, pide confirmación y, en caso
afirmativo, lo instala en el directorio local de paquetes:
</p>

<pre class="example" id="org1707740">
Resolving Hex dependencies...
Dependency resolution completed:
New:
  phx_new 1.5.7
* Getting phx_new (Hex package)
All dependencies are up to date
Compiling 10 files (.ex)
Generated phx_new app
Generated archive "phx_new-1.5.7.ez" with MIX_ENV=prod
Are you sure you want to install "phx_new-1.5.7.ez"? [Yn] y
* creating /home/notxor/.mix/archives/phx_new-1.5.7
</pre>

<p>
Ya está instalado, voy a hacer una pequeña prueba a ver si todo
funciona como debe, sin meterme mucho en profundidades, ─que aún no
tengo yo tampoco muy claro cómo funciona el chismático─.
</p>

<p>
Inicio o creación de un nuevo proyecto:
</p>

<div class="org-src-container">
<pre class="src src-bash">mix phx.new hola_phoenix
</pre>
</div>

<p>
Ese comando genera todo el <i>esqueleto</i> de la aplicación. Pero aún no
la base de datos, que tenemos que crear nosotros a mano.
</p>

<pre class="example" id="org734160b">
* creating hola_phoenix/config/config.exs
* creating hola_phoenix/config/dev.exs
* creating hola_phoenix/config/prod.exs
* creating hola_phoenix/config/prod.secret.exs
* creating hola_phoenix/config/test.exs
* creating hola_phoenix/lib/hola_phoenix/application.ex
* creating hola_phoenix/lib/hola_phoenix.ex
* creating hola_phoenix/lib/hola_phoenix_web/channels/user_socket.ex
* creating hola_phoenix/lib/hola_phoenix_web/views/error_helpers.ex
* creating hola_phoenix/lib/hola_phoenix_web/views/error_view.ex
* creating hola_phoenix/lib/hola_phoenix_web/endpoint.ex
* creating hola_phoenix/lib/hola_phoenix_web/router.ex
* creating hola_phoenix/lib/hola_phoenix_web/telemetry.ex
* creating hola_phoenix/lib/hola_phoenix_web.ex
* creating hola_phoenix/mix.exs
* creating hola_phoenix/README.md
* creating hola_phoenix/.formatter.exs
* creating hola_phoenix/.gitignore
* creating hola_phoenix/test/support/channel_case.ex
* creating hola_phoenix/test/support/conn_case.ex
* creating hola_phoenix/test/test_helper.exs
* creating hola_phoenix/test/hola_phoenix_web/views/error_view_test.exs
* creating hola_phoenix/lib/hola_phoenix/repo.ex
* creating hola_phoenix/priv/repo/migrations/.formatter.exs
* creating hola_phoenix/priv/repo/seeds.exs
* creating hola_phoenix/test/support/data_case.ex
* creating hola_phoenix/lib/hola_phoenix_web/controllers/page_controller.ex
* creating hola_phoenix/lib/hola_phoenix_web/templates/layout/app.html.eex
* creating hola_phoenix/lib/hola_phoenix_web/templates/page/index.html.eex
* creating hola_phoenix/lib/hola_phoenix_web/views/layout_view.ex
* creating hola_phoenix/lib/hola_phoenix_web/views/page_view.ex
* creating hola_phoenix/test/hola_phoenix_web/controllers/page_controller_test.exs
* creating hola_phoenix/test/hola_phoenix_web/views/layout_view_test.exs
* creating hola_phoenix/test/hola_phoenix_web/views/page_view_test.exs
* creating hola_phoenix/lib/hola_phoenix_web/gettext.ex
* creating hola_phoenix/priv/gettext/en/LC_MESSAGES/errors.po
* creating hola_phoenix/priv/gettext/errors.pot
* creating hola_phoenix/assets/webpack.config.js
* creating hola_phoenix/assets/.babelrc
* creating hola_phoenix/assets/js/app.js
* creating hola_phoenix/assets/css/app.scss
* creating hola_phoenix/assets/js/socket.js
* creating hola_phoenix/assets/package.json
* creating hola_phoenix/assets/static/favicon.ico
* creating hola_phoenix/assets/css/phoenix.css
* creating hola_phoenix/assets/static/images/phoenix.png
* creating hola_phoenix/assets/static/robots.txt

Fetch and install dependencies? [Yn] 
* running mix deps.get
* running mix deps.compile
* running cd assets &amp;&amp; npm install &amp;&amp; node node_modules/webpack/bin/webpack.js --mode development

We are almost there! The following steps are missing:

    $ cd hola_phoenix

Then configure your database in config/dev.exs and run:

    $ mix ecto.create

Start your Phoenix app with:

    $ mix phx.server

You can also run your app inside IEx (Interactive Elixir) as:

    $ iex -S mix phx.server
</pre>

<p>
Al terminar el proceso vemos que nos sugiere ya las cosas que debemos
hacer a continuación. Lo primero ir al directorio base del proyecto.
En nuestro caso <code>hola_phoenix</code>. A continuación tenemos que modificar
el archivo <code>config/dev.exs</code>. Por eso la base de datos tenemos que
generarla a mano, porque seguramente la conexión al servidor fallará
con los datos por defecto. Al abrir el fichero vemos algo como:
</p>

<div class="org-src-container">
<pre class="src src-elixir"># Configure your database
config :hola_phoenix, HolaPhoenix.Repo,
  username: "postgresql",
  password: "postgresql",
  database: "hola_phoenix_dev",
  hostname: "localhost",
  show_sensitive_data_on_connection_error: true,
  pool_size: 10
</pre>
</div>

<p>
Tenemos que cambiar el valor de <code>username</code> y <code>password</code> para ajustarla
a lo que solicite nuestro servidor. Además en ese mismo archivo
podemos configurar los datos del servidor, como el puerto, por
ejemplo, e incluso nos avisa de que si queremos utilizar <code>HTTPS</code> con
las pruebas, podemos generar un certificado autofirmado con el
comando:
</p>

<div class="org-src-container">
<pre class="src src-shell">mix phx.gen.cert
</pre>
</div>

<p>
Una vez configurados los datos de acceso a la base de datos, tenemos
que crearla:
</p>

<div class="org-src-container">
<pre class="src src-src">   ≻ mix ecto.create
Compiling 14 files (.ex)
Generated hola_phoenix app
The database for HolaPhoenix.Repo has already been created
</pre>
</div>

<p>
La herramienta <code>ecto</code> se encarga de todo lo referente al mantenimiento
y comunicación con la base de datos.
</p>

<p>
Lo siguiente es probar cómo funciona levantando el servidor con el
comando <code>mix phx.server</code>. El resultado lo veremos si dirigimos nuestro
navegador favorito a <code>http://localhost:4000</code>:
</p>


<figure id="orgbb5db9a">
<img src="imagenes/Captura-pantalla_phoenix-funcionando.png" alt="Captura-pantalla_phoenix-funcionando.png">

</figure>

<p>
La otra opción es ejecutar nuestro servidor dentro de la aplicación
interactiva de <code>elixir</code>, que se llama <code>iex</code>. El comando, como nos
sugiere el aviso tras crear el proyecto es:
</p>

<div class="org-src-container">
<pre class="src src-shell">iex -S mix phx.server
</pre>
</div>

<p>
¿Para qué podemos querer ejecutar la aplicación dentro de un <i>prompt</i>
interactivo? Pues por ejemplo, para tener acceso a la herramienta
<code>observer</code> que cargará con la máquina virtual de <code>erlang</code>. Con ella
podemos observar la estructura de nuestra aplicación:
</p>


<figure id="orgaf497e0">
<img src="imagenes/Captura-pantalla_observer.png" alt="Captura-pantalla_observer.png">

</figure>

<p>
o mirar los recursos que está utilizando nuestro sistema:
</p>


<figure id="orgf52a021">
<img src="imagenes/Captura-pantalla_observer-grafico.png" alt="Captura-pantalla_observer-grafico.png">

</figure>

<p>
Para acceder a esa herramienta, basta con teclear en el <i>prompt</i>
interactivo la instrucción:
</p>

<pre class="example" id="orgc946aa3">
iex(1)&gt; :observer.start()
</pre>

<p>
o también, con la instrucción <code>:debugger.start()</code>, acceder al
<code>debugger</code>:
</p>


<figure id="orgfb41b12">
<img src="imagenes/Captura-pantalla_debugger.png" alt="Captura-pantalla_debugger.png">

</figure>
</div>
</div>
</div>
<div id="outline-container-org820540a" class="outline-2">
<h2 id="org820540a">Conclusiones</h2>
<div class="outline-text-2" id="text-org820540a">
<p>
De momento, tampoco controlo mucho de cómo funciona todo esto: estoy
en fase de aprendizaje. Pero hay cosas que me suenan a <code>erlang</code>.  Por
ejemplo, en <code>erlang</code> también se podía acceder a las herramientas con
<code>observer:start().</code> o <code>debugger:start().</code>
</p>

<p>
Ya iré poniendo por aquí algunos avances según vaya aprendiendo más
cosas. Si alguien tiene alguna sugerencia, se agradecerá el
comentario.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/elixir/index.html">elixir</a> <a href="/tags/erlang/index.html">erlang</a> ]]></description>
  <category><![CDATA[elixir]]></category>
  <category><![CDATA[erlang]]></category>
  <link>https://notxor.nueva-actitud.org/2021/02/15/aprender-elixir.html</link>
  <pubDate>Mon, 15 Feb 2021 10:10:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Dejo Rust sin terminar de aprenderlo del todo]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-02-13</div>
<p>
Como sabéis llevo una temporada trasteando con <code>Rust</code> y me estaba
gustando. El caso es que el otro día me llegó una información que me
llenó de incertidumbre. Ya hace unos días de ello, pero al final he
decidido abandonar <code>Rust</code> no por sus idiosincrasias sino por sus
mantenedores. Mozilla deja el mantenimiento del lenguaje y se lo pasa
a <a href="https://foundation.rust-lang.org/members/">una <i>Fundación</i> de la que no me fío</a>.
</p>

<p>
Hay que tener en cuenta, que todas las operaciones de instalación y
mantenimiento de las herramientas del lenguaje se hacen <i>confiando</i> en
la ejecución de <i>scripts</i> remotos. Ya la misma Mozilla en algunos
casos me ha parecido un gran <i>olifante</i> insensible, pero es que la
<i>Rust Fundation</i> está en manos de:
</p>

<ul class="org-ul">
<li>Google</li>
<li>Amazon</li>
<li>Microsoft</li>
<li>Huawei</li>
<li>Mozilla</li>
</ul>

<p>
No hay ninguna de esas empresas que merezca mi confianza en lo más
mínimo.
</p>

<p>
Es una lástima que un lenguaje como <code>Rust</code>, además cuando estaba
empezando a apreciarlo de verdad, se convierta en algo sospechoso por
el lugar del que viene y el modo en que se gestiona la instalación y
mantenimiento de sus paquetes. Pero es que no puedo estar tranquilo a
partir de ahora ejecutando <code>cargo</code> en mi máquina.
</p>

<p>
Quizá esté siendo un poco paranoico, pero tiraré de <code>C/C++</code> como hasta
ahora cuando necesite compilar algo. No cierro la puerta a retomar más
adelante el lenguaje, cuando no haya más remedio o cuando pueda estar
convencido de su seguridad.
</p>

<p>
Ahora toca desinstalarlo, y desinstalar algunas herramientas que
estaba utilizando como <code>starship shell</code>.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/rust,/index.html">rust,</a> <a href="/tags/gafam/index.html">gafam</a> ]]></description>
  <category><![CDATA[rust,]]></category>
  <category><![CDATA[gafam]]></category>
  <link>https://notxor.nueva-actitud.org/2021/02/13/dejo-rust-sin-terminar-de-aprenderlo-del-todo.html</link>
  <pubDate>Sat, 13 Feb 2021 18:45:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[En qué ando estos días]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-02-09</div>
<p>
Tengo la sensación, quizá subjetiva de que escribo poco en el <i>blog</i>
últimamente. Aunque algún que otro artículo he sacado, me parece que
podría quizá ser más generoso en mis escritos. Lo cierto es que estoy
liado con mis cosas y tengo que contarlo. Así pues, en este artículo,
os vais a encontrar un poco de todo: hablaré sobre el <i>blog</i> y su
cambio de aspecto, hablaré sobre <code>rust</code> y sobre cómo estoy utilizando
<i>Emacs</i> para aprender con algún que otro problemilla que he ido
solventando sobre la marcha.
</p>
<div id="outline-container-org5131d54" class="outline-2">
<h2 id="org5131d54">Cambio de aspecto del <i>blog</i> con <code>css</code></h2>
<div class="outline-text-2" id="text-org5131d54">
<p>
Los cambios recientes en el <i>blog</i> están incompletos, aún me faltan
algunas cosas que quiero <i>matizar</i> un poco. Lo fundamental es que he
abandonado el diseño de una columna por el de dos y la cabecera
aparece ahora a la izquierda con su menú. Lo que me ha costado más ha
sido hacerme con un fondo para el <i>blog</i>. No quería simplemente
utilizar alguna fotografía de las miles que se pueden encontrar por
<i>Internet</i> para fondos <i>web</i>; prefiero algo más personal. Alguno de
los antiguos lectores recordarán que hice una animación<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> para un
tema en <i>Esperanto</i> y he tomado de ahí algunos de los modelos para
fabricar el fondo. No es un fondo espectacular, ni profesional, pero
al menos es mío.
</p>
</div>
<div id="outline-container-orgcb103e5" class="outline-3">
<h3 id="orgcb103e5">Trabajar en <i>Emacs</i> para la <code>web</code></h3>
<div class="outline-text-3" id="text-orgcb103e5">
<p>
Aprovechando la tesitura de los cambios, ─y puesto que algunos me
habéis preguntado cómo me las apaño para levantar un servidor <code>web</code>
con el editor─, os cuento cómo lo hago con las pruebas.
</p>

<p>
En este caso, para toquetear el <code>css</code> y ver cómo van reaccionando los
distintos parámetros en la página, sin estropear nada de la actual, lo
que hago es copiar algunos ficheros en otro directorio. Me explico:
</p>

<ol class="org-ol">
<li>Tengo copia local del <i>blog</i> para hacer pruebas en el directorio
<code>~/public_html</code> y cuando publico algo, <code>org-static-mode</code> lo guarda
ahí. Hago pruebas de visualización en local, corrijo errores y
cuando creo que está todo correcto lo subo a su sitio en <i>Internet</i>
con <code>FileZilla</code>.</li>
<li>Para no estropear ese directorio y terminar arrastrando demasiada
basura al sitio correspondiente lo que hago es copiar algunos
directorios y ficheros para las pruebas. Para este caso:
<ul class="org-ul">
<li><code>~/public_html/medios</code>, donde se encuentran agrupados <code>css</code>,
<code>fuentes</code>, <code>img</code> y <code>js</code> que son las cosas necesarias para el
<i>diseño</i> de la página.</li>
<li>Algunos ficheros <code>html</code>, como el <code>index.html</code> y los últimos
artículos con su estructura de directorios para interactuar un
poco en las pruebas.</li>
</ul></li>
<li>Todo eso va copiado a un directorio que se puede llamar, por
ejemplo, <code>~/proyectos/cambios-web</code> que será donde tengamos que
levantar el servidor de pruebas:
<ul class="org-ul">
<li><code>M-x httpd-serve-directory</code> tras pulsar <code>&lt;RET&gt;</code> le decimos
nuestro directorio de trabajo, en el ejemplo
<code>~/proyectos/cambios-web</code>.</li>
<li>Y por último, levantamos el servidor con <code>M-x httpd-start</code></li>
</ul></li>
<li><p>
Abrimos el navegador con la dirección <code>http://localhost:8080</code>.  Por
defecto el puerto donde se sirve el contenido es <code>8080</code>. Si quieres
cambiarlo, digamos por el <code>6969</code>, tienes que evaluar la expresión:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> httpd-port 6969)
</pre>
</div></li>
</ol>

<p>
Posteriormente el trabajo consiste en ir haciendo las modificaciones
que consideramos oportunas e ir actualizando la visualización pulsando
<code>&lt;F5&gt;</code> en el navegador. Algunas veces, incluso se pueden ir
modificando los <i>pichorros</i> en las <i>herramientas de desarrollador</i>,
<code>C-s-i</code>, en el navegador para probar directamente y posteriormente
pasar esos parámetros al código.
</p>

<p>
El servidor lo podemos parar con el comando <code>M-x httpd-stop</code>. Tampoco
quiero enrollarme mucho sobre el tema. Si te parece interesante y te
gustaría saber un poco más sobre cómo trabajar en <i>Emacs</i> para la
<i>web</i> me lo dices por los canales habituales y dedico un artículo
completo con todo lujo de detalle al tema.
</p>
</div>
</div>
</div>
<div id="outline-container-org0b93e7d" class="outline-2">
<h2 id="org0b93e7d">Aprendiendo <code>rust</code></h2>
<div class="outline-text-2" id="text-org0b93e7d">
<p>
Llevo un tiempo ya aprendiéndolo, como un mes leyendo documentación y
haciendo pruebas simples. Algunos me han preguntado si he abandonado
<code>erlang</code> y no es el caso. Ese lenguaje llegó para quedarse y ya me
encuentro bastante cómodo con él. Como lenguaje concurrente es
increíble y lo uso con bastante asiduidad ahora para <i>prototipado
rápido</i>, cuando antes tiraba de <code>Python</code>. Pero mi idea era también
avanzar en algún lenguaje compilado, que no es para hacer prototipos
rápidos pero sí veloces de ejecución. <i>C/C++</i> ya lo conozco y tengo
algunas habilidades<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. El caso es que me propuse aprender <code>Rust</code>,
que parece que todo el mundo dice que es muy rápido y muy seguro.
</p>

<p>
Después de <a href="https://doc.rust-lang.org/stable/book/title-page.html">leerme <i>el libro</i> del lenguaje</a> y, como ocurre en estas
ocasiones, enterarme de más bien poco, ─porque no aprendo hasta que no
tropiezo─, decidí iniciar un proyecto para tropezar. Si has leído más
cosas en el <i>blog</i> te sonará una serie de programar un <i>raytracer</i> con
<code>erlang</code>, pues bien: voy a hacer lo mismo con <code>Rust</code> aunque sin
contarlo por aquí, porque eso me convertiría en el <i>pesao</i> de los
<i>raytracer</i>.
</p>

<p>
De momento, no soy nada productivo con el lenguaje. Su sintanxis e
idiosincrasias lo hacen un lenguaje un tanto farragoso al principio.
Además, su intención de ser <i>seguro</i> lo llevan casi a la paranoia y se
queja por todo. Bien es cierto que en esas mismas quejas advierte
claramente qué problemas encuentra y sugiere cómo se pueden atajar.
Pero creo que es un buen lenguaje y me está gustando.
</p>

<p>
Aún no siendo productivo aún con <code>Rust</code>, sí creo que le estoy cogiendo
el tranquillo y, aunque el proyecto avanza muy lentamente, voy
consiguiendo pequeños logros, sin copiar el código de ningún sitio. Mi
primera pelea fue con las interfaces hasta que las encontré, la
segunda para separar el código en módulos, luego con los operadores y
cómo definirlos para nuevos tipos de datos, luego con los <i>tests</i>,
luego escribir la salida en un fichero... y así a trompicones avanzo
poco a poco.
</p>
</div>
<div id="outline-container-org7ec7e9f" class="outline-3">
<h3 id="org7ec7e9f">Configurando <i>Emacs</i> para usarlo con <code>Rust</code></h3>
<div class="outline-text-3" id="text-org7ec7e9f">
<p>
Hay un paquete para trabajar con <code>Rust</code> en <i>Emacs</i> que se llama
<code>rustic</code>. Ya os advierto que más rústico y rural que yo no lo hay. La
instalación es como siempre sencilla:
</p>

<pre class="example" id="orgf4afb22">
M-x package-install &lt;RET&gt; rustic &lt;RET&gt;
</pre>

<p>
En la configuración sólo añadí un escueto:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">rustic</span>)
</pre>
</div>

<p>
Sin embargo, cada vez que abría un fichero <code>.rs</code> el modo <code>rustic</code>
preguntaba por <code>lsp</code><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>. Como sabéis, <code>lsp</code> es un modo que permite
a <i>Emacs</i> convertirse en un IDE moderno integrándose con otros
paquetes como <code>company</code>, <code>projectile</code> o <code>flycheck</code>. Hasta ahora no
había probado <code>lsp</code> porque la otra vez que lo intenté, resultó en un
enlentecimiento casi desesperante del editor y no le vi la utilidad.
</p>

<p>
Supongo que aquel problema sería con respecto al modo de edición, que
en aquella ocasión era <code>Python</code>, esta vez, siguiendo los pasos de
configuración, que no han sido muchos, la cosa va un poco mejor. Tarda
en arrancar el <i>Emacs</i>, ha duplicado el tiempo de carga y se sitúa en
tres segundos y medio, más o menos. Cuando abro algún proyecto de
<code>Rust</code> también tarda en cargar el fichero de código mientras levanta
el servidor y se conecta, pero luego funciona con soltura.
</p>

<p>
El problema creo que viene del montón de dependencias que tiene
<code>lsp-mode</code> cuando lo instalas. Tienes que instalar también otros
paquetes, como <code>lsp-ivy</code> (o <code>lsp-helm</code>), <code>company-lsp</code>, <code>lsp-ui</code>,
<code>dap-mode</code> y también parece que es recomendable instalar <code>eglot</code>.
Después de intentar configurarlo todo he ido renunciando a algunas
cosas, aunque mantengo los paquetes instalados por compatibilidad, lo
demás que uso viene en el código:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">lsp-mode</span>)
(add-hook 'rust-mode-hook #'lsp)
(add-hook 'rust-mode-hook '(lsp-install-server 'rust-analyzer))
(add-hook 'rustic-mode-hook 'englot-ensure)
</pre>
</div>

<p>
El paquete <code>dap-mode</code><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup> he sido incapaz de hacerlo funcionar, pero
puesto que es un paquete de depuración tiro del clásico <code>gdb</code> de toda
la vida para hacer lo mismo.
</p>
</div>
</div>
<div id="outline-container-orged7964b" class="outline-3">
<h3 id="orged7964b">Depuración con <code>gdb</code></h3>
<div class="outline-text-3" id="text-orged7964b">
<p>
Y si no funciona el chismático de depuración moderno, pues habrá que
tirar del clásico. Es un poco menos vistoso pero funciona con
solvencia. El problema es que al no estar integrado en el IDE tienes
que hacer un par de cosas más tú a mano.
</p>

<p>
Si ya has utilizado antes <i>Emacs</i> como un entorno gráfico de
depuración con <code>gdb</code> te puedes saltar éste punto. Si no lo has hecho,
voy a dar unas breves pinceladas de cómo lo hago yo. Si crees que es
interesante el tema, ya me lo dices y prometo que escribiré un
artículo completo sobre el tema.
</p>

<p>
Arrancar <code>gdb</code> en <i>Emacs</i> es sencillo: <code>M-x gdb</code>, nos pregunta por el
comando que utilizará, que por defecto es <code>gdb -i=mi</code> y obtendremos una
ventana parecida a:
</p>


<figure id="orgf6c8cf9">
<img src="imagenes/Captura-pantalla_gud.png" alt="Captura-pantalla_gud.png">

</figure>

<p>
Es un <i>buffer</i> que se llama <code>gud</code> y que muestra el <i>prompt</i> del
depurador <code>gdb</code>. Si estamos acostumbrados a utilizar <code>gdb</code> desde la
línea de comandos lo podemos hacer aquí directamente. Si os sale una
ventana divida en varios <i>buffers</i>, es porque tenéis configurada la
variable <code>gdb-many-windows</code> a <code>t</code>.
</p>


<figure id="orgcefec41">
<img src="imagenes/Captura-pantalla_gdb-many-windows.png" alt="Captura-pantalla_gdb-many-windows.png">

</figure>

<p>
En todo caso, si no tenéis esa variable activada y queréis activar los
<i>buffers</i> de visualización, sólo tenéis que teclear <code>M-x
gdb-many-windows</code> y os aparecerán.
</p>

<p>
De momento, hemos cargado el depurador pero en vacío y no hay un
programa que depurar. Para hacerlo, nos vamos al <i>buffer</i> <code>gud</code>, si no
estamos en él, y tecleamos <code>file nombre-del-ejecutable</code>. En este caso
yo he tecleado:
</p>

<pre class="example" id="orgd71c599">
file ~/proyectos/rust/rustracer/target/debug/rustracer
</pre>

<p>
Debería abrirnos el fichero principal de código también, pero si no es
así, lo abrimos nosotros... La pantalla quedaría así:
</p>


<figure id="org265b883">
<img src="imagenes/Captura-pantalla_gud-cargado.png" alt="Captura-pantalla_gud-cargado.png">

</figure>

<p>
Ahora sólo necesitamos hacer que nuestro programa se pare en algún
sitio durante la ejecución para poder inspeccionar cómo evoluciona.
Establecer un punto de parada o <code>breakpoint</code> podemos hacerlo de varias
formas. Yo utilizo dos, principalmente. Una es teclear en el <i>buffer</i>
<code>gud</code> el comando <code>break NN</code> donde <code>NN</code> es el número de línea donde
quiero establecer el punto de parada. La otra es ir al <i>buffer</i> donde
se muestra el código fuente, ir a la línea donde quiero hacer la
parada y llamar al comando <code>gud-break</code>.
</p>


<figure id="org9cdf64d">
<img src="imagenes/Captura-pantalla_break-points.png" alt="Captura-pantalla_break-points.png">

</figure>

<p>
Sea cual sea el método empleado, podemos observar que nos señala
gráficamente el punto de parada con un círculo rojo la línea donde lo
hemos establecido y además aparece en la lista del <i>buffer</i> de
<i>breakpoints</i>, abajo a la derecha.
</p>

<p>
El resto de acciones las podemos llevar a cabo manualmente desde <code>gud</code>
o utilizar la barra de botones, que es muy similar a cualquier otra
herramienta de depuración.
</p>
</div>
</div>
</div>
<div id="outline-container-orgb624eb6" class="outline-2">
<h2 id="orgb624eb6">Conclusiones</h2>
<div class="outline-text-2" id="text-orgb624eb6">
<p>
Ando liado porque soy así de liable, siempre con un montón de
proyectos, siempre con ganas de aprender cosas nuevas y agotando todo
mi tiempo libre para no permitirme descansar a mí mismo.  Y ahora,
después de haberos cansinado con varias cosas deslabazadas, sin un
hilo conductor coherente os estaréis preguntado <i>Y ¿a mí qué?</i> a lo
que yo os respondo: <i>A mí tampoco, ¡gracias!</i>. Bueno, de acuerdo, era
sólo por escribir un poco y que no penséis que tengo el <i>blog</i>
abandonado... es que no doy para más: hago lo que puedo.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Si no lo recuerdas, lo puedes ver en
<a href="https://www.youtube.com/watch?v=CxhFjPa_wd0">https://www.youtube.com/watch?v=CxhFjPa_wd0</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Por ejemplo, compilando <code>erlang</code> la última vez me lanzó un par
de errores de <i>C++</i> en mi máquina y pude resolverlas fácilmente.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Language Server Protocol</i> 
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Un paquete adaptador para <i>Debug Adapter Protocols</i>, que sería
la herramienta de depuración del entorno.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/blog/index.html">blog</a> <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/rust/index.html">rust</a> ]]></description>
  <category><![CDATA[blog]]></category>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[rust]]></category>
  <link>https://notxor.nueva-actitud.org/2021/02/09/en-que-ando-estos-dias.html</link>
  <pubDate>Tue, 09 Feb 2021 15:52:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Sobre la ética y el software]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-01-30</div>
<p>
Hoy tocan unas pocas reflexiones sobre el uso de la tecnología en
estos tiempos. Lo que hay a continuación son reflexiones personales y
subjetivas, no esperes aprender nada especial, pero me gustaría que
pensaras conmigo. Mi idea con este artículo es sólo reflexionar un
poco más sobre una vieja cuestión en el uso de las herramientas como
armas y aplicar esos mismos criterios básicos a los instrumentos
actuales: <i>software</i>, informática, <i>inteligencia artificial</i>...
¿Debemos dar un paso más hacia otros postulados éticos respecto a la
tecnología? ¿Las <i>libertades personales</i> pueden estar en contra de los
<i>derechos fundamentales</i>? Y ¿Por qué debería importarme?  Estos días
de atrás la amiga <a href="https://barcelona.social/users/titi">Fedizen4 o Titi</a> enlazó en esas redes <i>fediversales</i>
por las que me muevo, un artículo a otras licencias éticas que quieren
ir más allá de lo que representa el <i>software libre</i>. Después hice
preguntas similares sobre las licencias en el IRC del CAAD (canal
<code>#caad</code> del <code>irc-hispano</code>), obteniendo algunas respuestas derrotistas
que después comentaré.  Eso me abrió a pensar en escribir este
artículo cuyo objeto es clarificar también mi línea de pensamiento al
forzarme a repensarla para poner todo por escrito.  Si no te gustan
los ladrillos filosófico-ético-morales no leas ésto.
</p>
<div id="outline-container-orgc02ee04" class="outline-2">
<h2 id="orgc02ee04">Antecedentes</h2>
<div class="outline-text-2" id="text-orgc02ee04">
<p>
El <i>ser humano</i> es un ser vivo que nace desarmado. En la naturaleza,
sólos sin herramientas, no podríamos enfrentarnos al entorno, seríamos
la presa más fácil de cazar por los depredadores: no somos rápidos
para huir ni fuertes para pelear. Tampoco lo somos para perseguir
piezas de caza o matarlas con nuestras propias manos. Para todo eso
hemos necesitado siempre herramientas y la colaboración de una
comunidad.  Desde la prehistoria hemos necesitado herramientas para
cumplir con estas tareas y desde la prehistoria dichas herramientas se
han convertido en armas al dirigirse contra los humanos. Hay teorías
que sostienen que al contrario que en los animales, cuyas armas
evolucionan junto a los mecanismos que pueden inhibir su uso con
congéneres, las armas humanas, y su poder destructor, evolucionan
mucho más rápidamente de lo que somos capaces de asumir.
</p>

<p>
Quizá te estás preguntando a qué viene hablar sobre armas y
herramientas cuando tu interés está centrado en el <i>software</i>, pero te
pido que tengas un poco de paciencia, intentaré ir al grano de una
forma más o menos directa, aunque necesito establecer algunas premisas
para cimentar mi disperso discurso de pensamiento y poder ponerlo en
palabras. Todo esto viene al caso de intentar centrar un discurso
sobre el <i>bien</i> y el <i>mal</i>, en algo más concreto como el uso de
instrumentos y no en algo abstracto difícil de definir.
</p>

<p>
El punto al que quiero llegar sin enrollarme mucho, es a que la
<i>bondad</i> o <i>maldad</i> no está en la herramienta sino que es una
característica del uso y de la percepción del mismo. Un cuchillo en
manos de un cocinero es un útil magnífico para elaborar riquísimos
platos de comida; empleado para herir o matar a otras personas, el
mismo cuchillo, no es ni mejor ni peor de lo que lo era en manos del
cocinero, sin embargo, los fines pueden ser percibidos de manera
completamente distinta e implica juicios de valor completamente
distintos. Siguiendo este hilo de pensamiento podemos perdernos en
eternas discusiones sobre la legitimidad en el uso de la violencia o
el concepto de <i>guerra justa</i> (si hay alguna que lo sea) o de la
autodefensa... Si estuviera escribiendo algún ensayo al uso, estos
conceptos merecerían uno o dos capítulos, pero siendo esto un artículo
corto para un <i>blog</i> pequeño, unipersonal, tendré que dejarlos así en
el aire.  Resumiendo, toda herramienta puede ser considerada un arma
según cómo se emplee y con qué fines... si no estás de acuerdo con
esta explicación ya me lo comentas, si quieres.
</p>

<p>
Hace unos años<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, cuando más utilizaba <code>Smalltalk</code>, recuerdo que
alguien me criticó por utilizar la herramienta <a href="https://www.exept.de/en/products/smalltalk-x-en.html">Smalltalk/X</a> para
realizar algunos programas de uso personal. La crítica se basaba en
que <i>no es software libre</i>, entendido así en general, pues contiene
una limitación en su licencia que prohibe su uso en ámbito militar o
en la fabricación de armas. Tendría que repasar la licencia para
decirlo con claridad, porque no me acuerdo bien de la restricción. El
caso es que efectivamente me sirve para ilustrar como la ética y la
libertad, en los temas del <i>software</i> no van juntas como no lo van
tampoco en los temas del <i>mercado</i>.
</p>

<p>
<i>En cuestiones de tecnología la ética lo es todo y debe prevalecer en
todo</i>, lo <a href="https://retina.elpais.com/retina/2020/12/22/tendencias/1608655621_852613.html">afirma Gabriela Ramos en una entrevista para el periódico</a>
«el País». Puedes estar, o no, de acuerdo con ella, en todo caso toda
actividad humana está, lo quieras o no, sujeta a la valoración ética
de la misma. Puede que afirmar «lo es todo» sea excesivo, aunque no me
parece que lo sea el que la <i>ética debe prevalecer</i>. No me parece que
el fin justifique los medios en ningún caso.
</p>
</div>
</div>
<div id="outline-container-org1b0e307" class="outline-2">
<h2 id="org1b0e307">Movimiento del <i>software libre</i></h2>
<div class="outline-text-2" id="text-org1b0e307">
<p>
El <i>software libre</i> fue en su día un paso muy importante en el camino
hacia el reconocimiento de los derechos que tiene el usuario de
<i>software</i> sobre los programas y sistemas que ejecuta en su máquina.
</p>

<p>
El problema de las <i>licencias</i> de los programas no es sencillo de
abordar, pues puede considerarse un programa como un <i>bien</i>, como un
<i>servicio</i>, como una <i>obra creativa</i> o como una mezcla de todas esas
cosas a la vez. Hay que remarcar que el <i>producto</i> por el que se paga
no es lo suficientemente tangible como para decir que compras <i>algo
físico</i>, estás comprando sólo el derecho de uso. Pagar por el sistema
operativo de un ordenador significa que has pagado por el derecho a
que la máquina arranque cuando le das al botón, poniéndose en estado
susceptible de aceptar entradas y generar salidas. Pero todos esos
programas e información viene guardado en un soporte digital que se
leerá en máquinas que para hacer su trabajo deben poder hacer copias
de soportes digitales.
</p>

<p>
Siendo el <i>software</i> un <i>bien intangible</i> la primera reacción de las
empresas que querían ganar dinero con el <i>software</i> fue ocultarlo y
limitar su uso con sistemas anticopia. Tanto lo limitaron que se llegó
al punto de casi prohibir al usuario usarlo: sólo lo puedes instalar
en una máquina, si ya lo has instalado en una máquina y tienes que
cambiar de máquina pues que tengas buena suerte con la instalación en
la nueva... Al fin y al cabo, parece que lo que vendían era el
<i>soporte físico</i> de los programas, metidos en bonitas cajas. Pero no
era así. De hecho, la llegada de una Internet rápida ha hecho que el
<i>software</i> se mueva a servicios <i>online</i> y ya no haya un soporte
físico que comprar. Pero en aquellos tiempos se podía llegar al
extremo del absurdo, en muchas ocasiones, limitando el <i>derecho de
uso</i> a quien pagaba, mientras las copias no autorizadas fluían (o
fluyen) sin poder evitarlo. Tuvo que aparecer alguien como <i>Richard
M. Stallman</i>, con la intención de defender los derechos de los
usuarios de varias maneras agrupadas en <i>las cuatro libertades
fundamentales del software libre</i>:
</p>

<ul class="org-ul">
<li><b>Libertad de uso</b>: El usuario tiene derecho a utilizar el <i>software</i>
sin restricciones para lo que quiera.</li>
<li><b>Libertad de estudio</b>: El usuario tiene derecho a ver cómo está
hecho el programa que ejecuta en su máquina y estudiar cómo
funciona.</li>
<li><b>Libertad de modificación</b>: El usuario tiene derecho a hacer cambios
en el <i>software</i> para ajustarlo a sus necesidades.</li>
<li><b>Libertad de distribución</b>: El usuario tiene derecho a distribuir el
<i>software</i> que produce o empaqueta.</li>
</ul>

<p>
En ninguna de esas <i>libertades</i> se especifica que sea <i>gratis</i>, sin
embargo, el término <i>free</i> en inglés ha dado mucho lugar a confusión
en el mundo del <i>software libre</i>, pues significa tanto <i>libre</i> como
<i>gratis</i> en inglés.
</p>

<p>
En el momento en que una licencia, como pasaba con <i>Smalltalk/X</i>
limitara una de esas libertades, ─en este caso la libertad de uso─, no
puede considerarse <i>software libre</i>. En todo caso, para vigilar la
protección de los derechos del usuario, nació la <i>FSF</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> y
estableció como marco de libertades las licencias GPL<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>. A estas
alturas, el que más y el que menos, estamos acostumbrados a sus listas
de <i>software libre</i>, de <i>licencias libres</i>, de <i>hardware libre</i>.
Muchas de esas <i>licencias éticas</i> no entran en el conjunto de las
<i>licencias libres</i>.
</p>

<p>
Hace falta poco esfuerzo para darse cuenta que al estudiar estas
licencias, a las <i>GPL</i> me refiero, se ha realizado una limitación en
la <i>libertad de distribución</i>: no se pueden distribuir copias de
nuestras modificaciones con otra licencia que no sea la <i>GPL</i>. Sin
embargo, esta restricción a la <i>libertad</i> es percibida como <i>buena</i> y
adecuada en el mundo del <i>software libre</i>, que por tanto también
restringe las libertades del usuario sin ningún tipo de
arrepentimiento. Esa limitación está prevista para que no pueda
retirarse el acceso al <i>software</i>, y que sea la <i>comunidad</i> de
usuarios la depositaria del derecho por encima del uso individual. Que
está muy bien, pero es un freno a la libertad absoluta.
</p>

<p>
Quiero poner énfasis en ésto, porque la misma FSF, con sus licencias
libres, pone límites a la libertad absoluta. Lo repito con el fin de
remarcarlo: el hecho es así sin entrar en las consideraciones de valor
que lo califiquen como <i>bueno</i> o como <i>malo</i>.
</p>
</div>
</div>
<div id="outline-container-org56f15c8" class="outline-2">
<h2 id="org56f15c8">El <i>open source</i></h2>
<div class="outline-text-2" id="text-org56f15c8">
<p>
Para contrarrestar esa restricción liberticida cierta empresa de
<i>sotware</i> enarboló la bandera <i>libertaria</i> contra la opresión de las
<i>GPL</i>. Los inicios del <i>open source</i> estuvieron auspiciados por
<i>Micro$oft</i> en un intento de ponerle aún más límites a las libertades
del <i>sotware libre</i>. En aquella época se criticaron las licencias
<i>GPL</i>, especialmente lo hizo <i>Steve Ballmer</i>, que llegó a calificarlas
de <i>cáncer</i> para la tecnología informática. Sin embargo, ese mismo
directivo de esa empresa elogiaba las licencias <i>BSD</i>. Teniendo en
cuanta que <i>Micro$oft</i> había plagiado toda la funcionalidad de redes
de <i>OpenBSD</i>, no era de extrañar.
</p>

<p>
El caso es que lo viví como un intento de meter confusión entre los
programadores y desarrolladores de <i>software</i>. Se reconocía que el
código que se enseñaba normalmente tiene más calidad que el que se
esconde, aunque sea sólo por el hecho de que lo ve más gente y los
programadores le ponen más cuidado o quizá porque hay más ojos que
pueden detectar errores y corregirlo. El caso es que sus virtudes se
pretendieron separar de todo concepto ético o de libertad que promovía
la FSF con sus licencias GPL.
</p>

<p>
El objetivo lo han cumplido, sólo hay que ver que incluso los mismos
desarrolladores de código, no tienen claras las diferencias entre los
conceptos de <i>software libre</i> y <i>open source</i>. Y la confusión es mayor
cuanto más jóvenes son esos desarrolladores. Sin embargo, esa
estrategia no dio para más y ahora <i>Micro$oft</i> se encuentra en plena
táctica de <i>constrictor</i>, ─abraza y ahoga─, con GNU/Linux.
</p>

<p>
El caso es que, desde mi punto de vista práctico, el <i>open source</i>
siempre me ha parecido escaso. Cuando he intentado compilar alguno de
los sistemas <i>open source</i> siempre he fracasado.  Creo que no por
falta de conocimientos, aunque yo sea psicólogo y no informático. Soy
bien capaz de compilar cualquier sistema de <i>software libre</i> que
necesite. Normalmente en el código publicado como <i>open source</i> se
omiten los ficheros de configuración, <i>makefiles</i>, dependencias y
demás cosas necesarias para generar un ejecutable funcional. Al final
tienes que fiarte de que el código fuente que se enseña es ─y sólo es
ese─ el mismo que genera el binario que ejecutas en tu ordenador. Así
pues, la única <i>libertad</i> que parece mantener el <i>open source</i> con
respecto al <i>software libre</i>, que es la de poder comprobar cómo
funciona el programa, nace viciada <i>de facto</i>.
</p>

<p>
Por tanto, para mí, no es contemplable como alternativa ética, de
ningún modo.
</p>
</div>
</div>
<div id="outline-container-orge630ae8" class="outline-2">
<h2 id="orge630ae8">Movimiento del <i>software ético</i></h2>
<div class="outline-text-2" id="text-orge630ae8">
<p>
<a href="https://ethicalsource.dev/">El software ético</a> se anuncia como un paso más en la ética... ¿está en
el camino correcto? Me pregunto, y aún no tengo una respuesta muy
clara o muy formada.
</p>

<p>
Cuando me llegó el enlace y me puse a investigar, efectivamente,
encontré documentación y también comentarios paralelos. En este caso,
las críticas venían tanto de los partidarios del <i>software privativo</i>
como de los partidarios del <i>software libre</i>. Algunos de esos
comentarios eran directamente descalificaciones para la impulsora del
movimiento, <i>Christine Peterson</i>, y de su <a href="https://ethicalsource.dev/community-code-of-conduct/">código de conducta</a>.
</p>

<p>
Quizá es cierto, no lo sé porque no he interactuado con esa
<i>comunidad</i>, que las normas y el código de conducta es demasiado
estricto y muchas veces un desafortunado comentario <i>jocoso</i>
desencadena un <i>baneo</i>. Parece que, como en muchas otras comunidades
de <i>software</i> hay una benevolente líder que guía el proyecto con mano
de hierro. Veo cierto paralelismo con las críticas recibidas por
<i>Richard Stallman</i> cuando estaba al frente de la FSF. Es algo que
parece esperable en todo este tipo de movidas.
</p>

<p>
Este tipo de movimientos está formados por seres humanos y aún no
conozco ningún ser humano perfecto. Todos somos criticables y todos
somos <i>risibles</i>, si te pones a analizarnos con nuestras brillantes
ideas y nuestras sombras, todo junto amalgamado en una perfecta
contradicción con patas.
</p>

<p>
Sin embargo, juzgando <i>a priori</i> <a href="https://ethicalsource.dev/licenses/">las licencias que promueve</a> este
movimiento de <i>software ético</i>, las ideas me parecen de lo más
loable:
</p>

<ul class="org-ul">
<li>La <a href="https://firstdonoharm.dev/">Hipocratic License</a> prohibe el uso del <i>software</i> licenciado en
cualquier actividad que atente contra los <a href="https://www.un.org/es/universal-declaration-human-rights/"><i>Derechos Humanos</i></a>. Esta
licencia es la que promueve la <i>benevolente matriarca</i> del
movimiento.</li>
<li>La <a href="https://github.com/996icu/996.ICU">996.ICU</a> está pensada para los defensores de los derechos de los
trabajadores.</li>
<li>La <a href="https://github.com/raisely/NoHarm">Do No Harm License</a> está pensada para aquellos desarrolladores que
quieren dejar un mundo mejor. Abarca aspectos como las limitaciones
para las actividades delictivas, tráfico de personas, actos
violentos, etc. En realidad es una BSD con cláusulas de limitación.</li>
<li>La <a href="https://framagit.org/inno3/tm-contract-for-oss-maintainers">inno3</a> está pensada más como una orientación contractual para
desarrolladores que se dedican a mantener servicios de <i>software
libre</i> u <i>open source</i> para que se puedan obtener unas correctas
condiciones laborales y de remuneración.</li>
<li>La <a href="https://www.open-austin.org/atmosphere-license/about/index.html">Atmosphere License</a> está destinada a preservar el medio ambiente.
En realidad es un conjunto de licencias que tocan algunas premisas
sobre el uso del petróleo, las energías renovables y otros conceptos
afines.</li>
<li>La <a href="https://thufie.lain.haus/NPL.html">(Cooperative) Non-violent Public License</a> tiene dos formas, la
<i>NPL</i> y la <i>CNPL</i>. Está pensada no sólo para la distribución de
<i>software</i> sino también para <i>obras creativas</i> en general. Después
de leerla parece una licencia GPL que garantiza los cuatro derechos
o libertades del <i>software libre</i> pero introduce algunas
restricciones sobre el uso del <i>software</i> o la <i>obra</i> en actividades
violentas o contra los derechos humanos. La versión <i>cooperative</i>
añade la limitación de uso en empresas tradicionales, aunque
salvaguarda los derechos de uso para cooperativas, por ejemplo.</li>
</ul>
</div>
</div>
<div id="outline-container-orge961b3a" class="outline-2">
<h2 id="orge961b3a">Las herramientas y la limitación de la libertad</h2>
<div class="outline-text-2" id="text-orge961b3a">
<p>
Las herramientas humanas, como ya he dicho antes, siempre se pueden
utilizar como arma. Los utensilios son indiferentes al uso que hacen
los seres humanos de ellos y, en general, el que sea un <i>buen</i> uso o
un uso <i>malvado</i> depende de la apreciación subjetiva de la persona.
</p>

<p>
Quizá los <i>liberales</i> se retuerzan en sus asientos cuando comento que
la Libertad pura no es sostenible e incluso es contraproducente.
Tampoco estoy descubiéndoles nada que no hayan percibido en sus
propias <i>liberales carnes</i> estos días de atrás con la movida de
<i>GameStop</i> y el foro de pequeños inversores de <i>Reddit</i>. He leído
comentarios que califican esos hechos como <i>troleada</i> o <i>gamberrada</i>
de unos <i>niños bien</i>.  No terminan de asimilar que una acción
conjunta, comunitaria, barra con las mismas normas a todopoderosas
firmas individualistas. Firmas, que por otro lado, piden la
desregulación del mercado, puesto que en Europa están prohibidas esas
prácticas de <i>apostar en corto a la baja</i>, y que ahora,
paradógiamente, se encuentran clamando al regulador de <i>Wall Street</i>
para que les deje incumplir el contrato y que ponga freno tales
desmanes. Demostrado queda, por tanto, que el <i>mercado libre se regula
solo</i>, es una falacia que sólo quieren que así sea mientras ganen
dinero los de siempre.
</p>

<p>
Como comentábamos en el IRC las grandes corporaciones, pongas la
licencia que pongas en tu <i>software</i>, se limpiarán el culo con
ellas. Tienen medios para copiar, ya sea descaradamente o no,
cualquier software que puedas hacer tú en tu casa. Hasta ahora lo han
venido haciendo muchas veces, saben que no tienen rival y que los
pequeños desarrolladores no pueden obligarles a asumir las licencias
del software, porque lo tienen que hacer judicialmente. Hasta ahora,
la FSF ha podido denunciar algunos pocos casos flagrantes de
incumplimiento, pero eso implica una dedicación y unos gastos que no
se pueden mantener en el tiempo por falta de fondos.
</p>

<p>
Sin embargo, estamos hablando de nuestras herramientas de trabajo. En
la actualidad todos necesitamos de algún modo la informática para
hacer nuestro trabajo. Aunque muchos podemos trabajar con papel y
lápiz no es habitual que hagamos nuestras cartas o informes a mano.
También es habitual que tengamos, a estas alturas, documentos
guardados en <i>la nube</i>, accesibles desde diversos dispositivos. En
todo caso, estamos hablando de que la informática, Internet, y todo lo
que tiene que ver con ellas, se han convertido en nuestras herramientas
de trabajo. Las podemos utilizar como herramienta o como arma, bien o
mal, de manera constructiva o malvada. Aún concediendo que las grandes
corporaciones se van a saltar la licencia, pongas la que pongas a tu
<i>software</i>, yo dormiría más tranquilo si mi elección está más de
acuerdo con mis valores éticos que si no lo está, o ni siquiera lo he
pensado.
</p>

<p>
Esa elección pasa por limitar las libertades puras y no dar permiso de
uso a aquellos que utilicen mi código para emplearlo en actividades
contra mis principios.
</p>
</div>
</div>
<div id="outline-container-org0f8af36" class="outline-2">
<h2 id="org0f8af36">Conclusiones</h2>
<div class="outline-text-2" id="text-org0f8af36">
<p>
No es que no me parezca importante la contribución del <i>software
libre</i> al avance de las modernas herramientas informáticas. Al
contrario.
</p>

<p>
Sin embargo, he llegado a cierto desasosiego. Podría emplear la
táctica del fabricante de cuchillos que es: <i>no preocuparme por el uso
que se le dé</i>. Sea este bueno o malo desde una concepción <i>ética</i> de
los términos «bueno» y «malo». Nada tienen que ver las consideraciones
éticas con la generación de código y entiendo que muchos
<i>informáticos</i> ni se la planteen, al menos de momento. Sin embargo,
estoy acostumbrado a trabajar con seres humanos, con sus luces y sus
sombras, y sé que el ser humano es capaz de las gestas más gloriosas y
de las más pérfidas miserias, el mismo ser humano, la misma persona.
</p>

<p>
Necesito, por tanto, cubrir ese quemazón que me producen las
<i>licencias del software</i> y me parece que a partir de ahora seré más
cuidadoso con la que emplee. Y debo decir que mi tendencia, ahora,
será elegir no sólo la que sea más libre y garantice los derechos del
usuario, sino aquella que garantice que esos derechos no se utilizan
de una forma <i>torticera</i> o <i>no ética</i> o que priorice los beneficios de
unos pocos en contra del beneficio de la comunidad.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Estoy hablando de los primeros años 2000, no recuerdo el año
exacto pero sería entre el año 2003 y el 2005. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Free Software Fundation</i> o Fundación del Software Libre. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Genaral Public License</i> o Licencia pública General. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/ética/index.html">ética</a> <a href="/tags/software-libre/index.html">software-libre</a> <a href="/tags/open-source/index.html">open-source</a> ]]></description>
  <category><![CDATA[ética]]></category>
  <category><![CDATA[software-libre]]></category>
  <category><![CDATA[open-source]]></category>
  <link>https://notxor.nueva-actitud.org/2021/01/30/sobre-la-etica-y-el-software.html</link>
  <pubDate>Sat, 30 Jan 2021 09:12:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Tablas para cálculos en org-mode]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-01-22</div>
<p>
No es la primera vez que en este <i>blog</i> hablo sobre las tablas y todas
las cosas que nos proporcionan a los usuarios de <code>org-mode</code>.  Algunos,
al haberme referido a ellas como <i>hojas de cálculo</i>, esperaban tener
la suerte de que se utilizaran de la misma manera y se han topado con
un pequeño muro de dificultades. Me han preguntado por cómo funcionan
y cómo las pueden utilizar y por qué las he llamado en alguna ocasión
<i>hojas de cálculo</i> en texto plano si no lo son. Este artículo trata
esos temas e intentará dar ejemplos suficientes para aquellos que
habiendo manejado hojas de cálculo, quieran probar la potencia de las
tablas de <code>org-mode</code>.
</p>
<div id="outline-container-orga54ac9d" class="outline-2">
<h2 id="orga54ac9d">Direcciones de celda</h2>
<div class="outline-text-2" id="text-orga54ac9d">
<p>
Si tienes experiencia con las hojas de cálculo, desde que <i>Lotus
1-2-3</i> impuso la nomenclatura de utilizar letras para las columnas y
números para las filas, la cosa ha cambiado poco. El primer concepto a
tener en cuenta, en <code>org-mode</code>, es que en las tablas no sólo hay
direcciones absolutas, sino también relativas: por ejemplo, podemos
utilizar la versión absoluta de una celda con el formato
<code>@FILA$COLUMNA</code>, además, las columnas, por ejemplo, ─pero las filas
igual─, se pueden referenciar como <code>$+1</code> o <code>$-2</code>... o también <code>$&lt;</code> y
<code>$&gt;</code> son referencias a la primera y la última de las columnas. De
manera similar ocurre con las filas: se pueden utilizar las
referencias <code>@-2</code> ó <code>@+3</code>, de forma relativa o <code>@&lt;</code> y <code>@&gt;</code> para la
primera y la última fila respectivamente. Teniendo en cuenta que las
líneas de separación no se cuentan ni en vertical <code>|</code> ni en horizontal
<code>-</code>, sólo cuentan las filas y columnas con datos. <code>@0</code> implica la fila
actual y <code>$0</code> la columna actual, aunque generalmente se omiten. De
esta manera si el cálculo de la celda <code>@2$3</code> implica el contenido de
otra celda de la fila, pongamos la de la columna <code>5</code>, podríamos
escribir la referencia como <code>@2$5</code>, o <code>@0$5</code>, o <code>$5</code>. Si utilizamos la
primera, la dirección es absoluta. Si luego queremos aplicar la
fórmula en otras celdas de otras filas, el cálculo se hará siempre con
el contenido de esa celda particular. Las otras dos formas son
equivalentes y referencian el contenido de la misma fila en su quinta
columna.
</p>

<p>
La forma de los rangos de celdas es similar a las <i>hojas de cálculo</i> a
las que estamos acostumbrados, se utiliza la notación de dos
caracteres <code>.</code>: <code>$1..$4</code> indica las columnas de la uno a la cuatro de
la fila actual.
</p>

<p>
También se pueden referenciar valores que se encuentran en otras
tablas. Para no liarnos mucho, vamos con un ejemplo sencillo, aunque
más práctico.
</p>
</div>
</div>
<div id="outline-container-org5e56f4d" class="outline-2">
<h2 id="org5e56f4d">Ejemplo práctico</h2>
<div class="outline-text-2" id="text-org5e56f4d">
<p>
Vamos a suponer que queremos montar nuestro propio sistema de
calificaciones, de una asignatura. Tenemos cinco alumnos y hemos
planificado tres exámenes distintos, de tipo <i>test</i>. En realidad lo
podemos hacer con una tabla un poco más compleja, como veremos al
final, pero para que sirva de ejemplo, haremos una tabla por cada
examen parcial.
</p>

<p>
Vamos con la práctica, copia la siguiente tabla o escribe una similar,
primero vamos con la definición de los exámenes:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">#+name: Pruebas
| Examen | Preguntas | Alternativas |
|--------+-----------+--------------|
|        |           |              |
|        |           |              |
|        |           |              |
</pre>
</div>

<p>
En esta tabla no vamos a hacer cálculos, sino definir las
características de nuestros exámenes. El ponerle un nombre con el
parámetro <code>#+name:</code> no aporta nada visualmente, pero nos permitirá
referenciar el contenido de la misma con la forma <code>remote(name,ref)</code>.
Vamos a rellenar los campos con los siguientes datos.
</p>

<table id="orgd4e8e21">


<colgroup>
<col  class="org-left">

<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Examen</th>
<th scope="col" class="org-right">Preguntas</th>
<th scope="col" class="org-right">Alternativas</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">P1</td>
<td class="org-right">40</td>
<td class="org-right">4</td>
</tr>

<tr>
<td class="org-left">P2</td>
<td class="org-right">35</td>
<td class="org-right">5</td>
</tr>

<tr>
<td class="org-left">P3</td>
<td class="org-right">100</td>
<td class="org-right">2</td>
</tr>
</tbody>
</table>

<p>
Y ahora vamos a preparar nuestra primera tabla, para el primer examen.
</p>

<div class="org-src-container">
<pre class="src src-org-mode">#+name: NotasP1
| N | Nombre          | Aciertos | Errores | Nota | Dec |
|---+-----------------+----------+---------+------+-----|
| 1 | Pepe López      |          |         |      |     |
| 2 | Amanda Torres   |          |         |      |     |
| 3 | Juan Pérez      |          |         |      |     |
| 4 | Elisa Ronchón   |          |         |      |     |
| 5 | Adalberto Épila |          |         |      |     |
</pre>
</div>

<p>
Una vez creada la plantilla sitúo el cursor en la celda de la primera
línea de datos, que corresponde al ficticio alumno <i>Pepe López</i> justo
en la bajo la columna de <i>Nota</i>.
</p>


<figure id="org70642d7">
<img src="imagenes/Captura-pantalla_nueva-formula.png" alt="Captura-pantalla_nueva-formula.png">

</figure>

<p>
Vamos a meter ahora la fórmula de calificación de un examen de
alternativas. Como sabéis, el cálculo se no sólo a los aciertos
obtenidos, sino que se elimina el factor de puntuación obtenida por
respuestas aleatorias que pueden dar los alumnos, restando a esos
aciertos el número de errores dividido por el número de alternativas
menos uno. Es decir, siendo los aciertos \(A\), los errores \(E\) y las
alternativas \(a\) la fórmula sería:
</p>

<p>
\[ Nota = A - \frac{E}{a - 1} \]
</p>

<p>
Para introducir dicha fórmula, situados en la celda que he mencionado
antes, tecleamos a continuación la fórmula:
</p>

<p>
<code>:=$3-($4/(remote(Pruebas,@2$3)-1))</code>
</p>

<p>
Como se ve, primero se teclea la entrada <code>:=</code> y a continuación las
referencias de las celdas que necesitamos. <code>$3</code> será el número de
aciertos en la prueba de nuestro ficticio alumno <i>Pepe López</i>, <code>$4$ es
la celda en la columna de /Errores/ para la misma fila y luego,
necesitamos las alternativas, que está en la tabla que hemos llamado
~Pruebas</code> y lo llamamos con <code>remote(Pruebas,@2$3)</code>. Al pulsar <code>&lt;RET&gt;</code>,
o <code>&lt;TAB&gt;</code> obtenemos algo así
</p>


<figure id="org4cd3ae3">
<img src="imagenes/Captura-pantalla_primera-formula.png" alt="Captura-pantalla_primera-formula.png">

</figure>

<p>
Hay que fijarse especialmente en la última línea que ha aparecido
<i>automágicamente</i>: es nuestra fórmula.
</p>

<div class="org-src-container">
<pre class="src src-org-mode">#+TBLFM: @2$5=$3-($4/(remote(Pruebas,@2$3)-1))
</pre>
</div>

<p>
Vamos a <i>deconstruirla</i> para entenderla. Tiene una etiqueta especial
con la forma <code>#+tblfm:</code>, que viene a significar algo así como
<i>fórmulas de la tabla</i>. A continuación establece que la celda (<code>@2$5</code>)
se calcula con nuestra fórmula asignando a la referencia su valor con
un signo <code>=</code>.
</p>

<p>
Puesto que queremos que se pueda calcular con la misma fórmula todas
las celdas de la columna, podemos borrar de esa referencia el <code>@2</code>.
Así pues, sitúa el cursor en la línea de la fórmula y borra el primer
<code>@2</code> de la izquierda, la línea debe quedar así:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">#+TBLFM: $5=$3-($4/(remote(Pruebas,@2$3)-1))
</pre>
</div>

<p>
Sin mover el cursor de esa línea pulsa <code>C-c C-c</code> y la tabla se
recalcula así:
</p>


<figure id="orga93d848">
<img src="imagenes/Captura-pantalla_recalcular-formula.png" alt="Captura-pantalla_recalcular-formula.png">

</figure>

<p>
Muy bonito, pero aún no calcula nada, porque no hay datos. Vamos a
repetir el proceso de cálculo para que lo veamos más claro. Introduce
los siguientes datos en ella:
</p>

<ol class="org-ol">
<li>Pepe López: <b>Aciertos</b> = 35, <b>Errores</b> = 5</li>
<li>Amanda Torres: <b>Aciertos</b> = 35, <b>Errores</b> = 6</li>
<li>Juan Pérez: <b>Acierto*s = 32, *Errores</b> 3</li>
<li>Elisa Ronchón: <b>Aciertos</b> = 40, <b>Errores</b> = 0</li>
<li>Adalberto Épila: <b>Aciertos</b> = 36, <b>Errores</b> = 4</li>
</ol>

<p>
Regresa a la línea de la fórmula tras haber introducido esos datos y
pulsa <code>C-c C-c</code>.
</p>


<figure id="org35a9e0b">
<img src="imagenes/Captura-pantalla_calculo-con-datos.png" alt="Captura-pantalla_calculo-con-datos.png">

</figure>

<p>
Está calculado... pero queda algo fea la tabla con los números
desalineados, unos con 5 decimales y otros sin ningunos. Para
solucionarlo, situados en la línea de la fórmula, la completamos
añadiendo a la misma <code>;%.3f</code>. Dicho de otro modo: separamos la fórmula
del formato con el caracter <code>;</code> y le decimos que el formato será el
valor de la celda <code>%</code> con un número de coma flotante de tres
decimales: <code>.3f</code>... el resultado queda así:
</p>


<figure id="orge2c0ed5">
<img src="imagenes/Captura-pantalla_formato-celdas.png" alt="Captura-pantalla_formato-celdas.png">

</figure>

<p>
Vamos con nuestra última columna. Colocándonos en cualquier celda de
la misma tecleamos la siguiente secuencia:
</p>

<p>
<code>:=10*($5/remote(Pruebas,@2$2));%.3f</code>
</p>

<p>
Como vemos, es sólo una fórmula sencilla que convierte la nota directa
en nota <i>decimalizada</i> y también le da un formato de tres decimales.
</p>

<p>
Las fórmulas de las dos columnas se encuentran en la misma cláusula
<code>#+tblfm</code>, sin embargo también podríamos tener las fórmulas separadas
de la siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">#+name: NotasP1
| N | Nombre          | Aciertos | Errores |   Nota |    Dec |
|---+-----------------+----------+---------+--------+--------|
| 1 | Pepe López      |       35 |       5 | 33.333 |  8.333 |
| 2 | Amanda Torres   |       35 |       6 | 33.000 |  8.250 |
| 3 | Juan Pérez      |       32 |       3 | 31.000 |  7.750 |
| 4 | Elisa Ronchón   |       40 |       0 | 40.000 | 10.000 |
| 5 | Adalberto Épila |       36 |       4 | 34.667 |  8.667 |
#+tblfm: $5=$3-($4/(remote(Pruebas,@2$3)-1));%.3f
#+tblfm: $6=10*($5/remote(Pruebas,@2$2));%.3f
</pre>
</div>

<p>
Dividirlo así puede facilitar la lectura y la edición de las diversas
fórmulas de una tabla. Podemos, además, calcular las fórmulas que
hayamos modificado exclusivamente o quizá recalcular toda la tabla.
Para hacer que se recalculen todas las fórmulas se utiliza la
combinación de teclas <code>C-c *</code>. Si tuviéramos que calcular algunas
fórmulas que dependan unas de otras, pueden necesitar que se calculen
de forma recursiva, si fuera necesario ésto se hace con <code>C-u C-u C-c
*</code>.
</p>

<p>
De todas formas, encuentro que es más interesante tener las fórmulas
en una sola línea y editarlas con la combinación <code>C-c '</code>. Este comando
abrirá un <i>buffer</i> de edición donde se listan las fórmulas de la
tabla, una por línea, para trabajar más cómodamente.
</p>

<p>
Las fórmulas pueden utilizar cualquier función que comprenda el
paquete <code>calc</code>. Pero además, también podemos utilizar la notación de
<code>elisp</code>, Por ejemplo, podemos escribir <code>'(apply '+ '($1..$4));N'</code>
</p>


<figure id="org03a68d1">
<img src="imagenes/Captura-pantalla_notas-3-parciales.png" alt="Captura-pantalla_notas-3-parciales.png">

</figure>
</div>
</div>
<div id="outline-container-orgfb6bd00" class="outline-2">
<h2 id="orgfb6bd00">Tablas complejas</h2>
<div class="outline-text-2" id="text-orgfb6bd00">
<p>
Hasta ahora en el artículo se ha seguido una política de tablas
simples: cálculos directos de filas y columnas sin marear mucho la
perdiz, aunque se han utilizado celdas de otras tablas. Sin embargo,
también se pueden utilizar algunas características de tablas más
complejas, como poner nombre a columnas o parámetros.
</p>

<p>
Para poner un ejemplo, vamos a hacer todos los cálculos que
realizábamos antes con cuatro tablas, ahora en una sola tabla como
ésta:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">|   | Nombre          |  D_1 |  E_1 |  D_2 |  E_2 |  D_3 |  E_3 | 1^er Par. | 2^o Par. | 3^er Par. | Final |
|---+-----------------+------+------+------+------+------+------+-----------+----------+-----------+-------|
| / |                 |    &lt; |      |      |      |      |      |         &lt; |          |         &gt; |       |
| ! |                 |   D1 |   E1 |   D2 |   E2 |   D3 |   E3 |        N1 |       N2 |        N3 |       |
|---+-----------------+------+------+------+------+------+------+-----------+----------+-----------+-------|
| # | Pepe López      |   35 |    5 |   25 |    2 |   60 |    2 |      8.33 |     7.00 |      5.80 |  7.04 |
| # | Amanda Torres   |   35 |    6 |   18 |    3 |   55 |    3 |      8.25 |     4.93 |      5.20 |  6.13 |
| # | Juan Pérez      |   32 |    3 |   32 |    2 |   80 |   10 |      7.75 |     9.00 |      7.00 |  7.92 |
| # | Elisa Ronchón   |   40 |    0 |   25 |    0 |   55 |   10 |     10.00 |     7.14 |      4.50 |  7.21 |
| # | Adalberto Épila |   36 |    4 |   30 |    4 |   80 |    4 |      8.67 |     8.29 |      7.60 |  8.19 |
|---+-----------------+------+------+------+------+------+------+-----------+----------+-----------+-------|
| # | Medias          |      |      |      |      |      |      |      8.60 |     7.27 |      6.02 |  7.30 |
|   | Preg./Altern.   |   40 |    4 |   35 |    5 |  100 |    2 |           |          |           |       |
| ^ |                 | max1 | alt1 | max2 | alt2 | max3 | alt3 |           |          |           |       |
#+tblfm: $9=10*($D1-($E1/($alt1-1)))/$max1;%.2f::$10=10*($D2-($E2/($alt2-1)))/$max2;%.2f::$11=10*($D3-($E3/($alt3-1)))/$max3;%.2f::$12=vsum($N1..$N3)/3;%.2f::@8$9=vsum(@3..@7)/5;%.2f::@8$10=vsum(@3..@7)/5;%.2f::@8$11=vsum(@3..@7)/5;%.2f::@8$12=vsum(@3..@7)/5;%.2f
</pre>
</div>

<p>
Hay que remarcar la primera columna rellena con caracteres que marcan
<i>líneas especiales</i>.  Al exportar, las líneas especiales no se
imprimirán, como se puede ver a continuación:
</p>

<table>


<colgroup>
<col  class="org-left">
</colgroup>

<colgroup>
<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">
</colgroup>

<colgroup>
<col  class="org-right">

<col  class="org-right">

<col  class="org-right">
</colgroup>

<colgroup>
<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Nombre</th>
<th scope="col" class="org-right">D_1</th>
<th scope="col" class="org-right">E_1</th>
<th scope="col" class="org-right">D_2</th>
<th scope="col" class="org-right">E_2</th>
<th scope="col" class="org-right">D_3</th>
<th scope="col" class="org-right">E_3</th>
<th scope="col" class="org-right">1^er Par.</th>
<th scope="col" class="org-right">2^o Par.</th>
<th scope="col" class="org-right">3^er Par.</th>
<th scope="col" class="org-right">Final</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">Pepe López</td>
<td class="org-right">35</td>
<td class="org-right">5</td>
<td class="org-right">25</td>
<td class="org-right">2</td>
<td class="org-right">60</td>
<td class="org-right">2</td>
<td class="org-right">8.33</td>
<td class="org-right">7.00</td>
<td class="org-right">5.80</td>
<td class="org-right">7.04</td>
</tr>

<tr>
<td class="org-left">Amanda Torres</td>
<td class="org-right">35</td>
<td class="org-right">6</td>
<td class="org-right">18</td>
<td class="org-right">3</td>
<td class="org-right">55</td>
<td class="org-right">3</td>
<td class="org-right">8.25</td>
<td class="org-right">4.93</td>
<td class="org-right">5.20</td>
<td class="org-right">6.13</td>
</tr>

<tr>
<td class="org-left">Juan Pérez</td>
<td class="org-right">32</td>
<td class="org-right">3</td>
<td class="org-right">32</td>
<td class="org-right">2</td>
<td class="org-right">80</td>
<td class="org-right">10</td>
<td class="org-right">7.75</td>
<td class="org-right">9.00</td>
<td class="org-right">7.00</td>
<td class="org-right">7.92</td>
</tr>

<tr>
<td class="org-left">Elisa Ronchón</td>
<td class="org-right">40</td>
<td class="org-right">0</td>
<td class="org-right">25</td>
<td class="org-right">0</td>
<td class="org-right">55</td>
<td class="org-right">10</td>
<td class="org-right">10.00</td>
<td class="org-right">7.14</td>
<td class="org-right">4.50</td>
<td class="org-right">7.21</td>
</tr>

<tr>
<td class="org-left">Adalberto Épila</td>
<td class="org-right">36</td>
<td class="org-right">4</td>
<td class="org-right">30</td>
<td class="org-right">4</td>
<td class="org-right">80</td>
<td class="org-right">4</td>
<td class="org-right">8.67</td>
<td class="org-right">8.29</td>
<td class="org-right">7.60</td>
<td class="org-right">7.59</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">Medias</td>
<td class="org-right">&#xa0;</td>
<td class="org-right">&#xa0;</td>
<td class="org-right">&#xa0;</td>
<td class="org-right">&#xa0;</td>
<td class="org-right">&#xa0;</td>
<td class="org-right">&#xa0;</td>
<td class="org-right">8.60</td>
<td class="org-right">7.27</td>
<td class="org-right">6.02</td>
<td class="org-right">7.18</td>
</tr>

<tr>
<td class="org-left">Preg./Altern.</td>
<td class="org-right">40</td>
<td class="org-right">4</td>
<td class="org-right">35</td>
<td class="org-right">5</td>
<td class="org-right">100</td>
<td class="org-right">2</td>
<td class="org-right">&#xa0;</td>
<td class="org-right">&#xa0;</td>
<td class="org-right">&#xa0;</td>
<td class="org-right">&#xa0;</td>
</tr>
</tbody>
</table>

<p>
A veces, en tablas complejas es difícil, a la hora de meter fórmulas
saber las coordenadas de una determinada celda perdida en medio de la
tabla. Para ayudarnos a esto podemos activar
<code>org-table-toggle-coordinate-overlays</code> pulsando la combinación de
teclas <code>C-c }</code>, no confundir con <code>C-c {</code> que activa ─o desactiva─ la
depuración del cálculo de las fórmulas.
</p>


<figure id="orgf5f9552">
<img src="imagenes/Captura-pantalla_edicion-formulas.png" alt="Captura-pantalla_edicion-formulas.png">

</figure>

<p>
Como se puede ver en la imagen nos muestra información sobre el número
de filas y columnas, de manera que podemos editar las fórmulas más
cómodamente. Para desactivarlo, volvemos a utiliza la combinación de
teclas y es suficiente.
</p>

<p>
Otra cosa importante es entender las filas especiales, que no aparecen
en la impresión pero que proporcionan funcionalidad interesante:
</p>

<dl class="org-dl">
<dt><code>/</code></dt><dd>La fila que comienza con carácter <code>/</code> se refiere a la
visualización de las celdas. En concreto, en este ejemplo, los
caracteres <code>&lt;</code> y <code>&gt;</code> indican o <i>señalan</i> qué líneas verticales debe
dibujar. Hay más opciones y es recomendable leer la documentación
sobre tablas del manual de <code>org-mode</code>.</dd>
<dt><code>!</code></dt><dd>Una línea que comience con el carácter <code>!</code> establecerá el
nombre de la columna. Por eso en el ejemplo, en las fórmulas se
emplean los nombres <code>$D1</code>, <code>$E1</code>, <code>$D2</code>, etc. en lugar del nombre
genérico de <code>$3</code>, <code>$4</code>, etc. Eso nos permite poner nombre a las
columnas que sea más fácil de interpretar para nosotros que un
simple número.</dd>
<dt><code>#</code></dt><dd>Las filas que comienzan por un carácter <code>#</code> se recalcularán
automáticamente cuando dentro de la tabla se puls <code>&lt;TAB&gt;</code> o <code>&lt;RET&gt;</code>
o se utilice el comando <code>C-u C-c *</code> para recalcular la tabla. Las
filas que no estén así marcadas no se ven afectadas por dicho
comando.</dd>

<dt><code>^</code></dt><dd>Las filas que están marcadas con un carácter <code>^</code> identifican
el valor de la fila superior con un nombre. En nuestras fórmulas de
la tabla, se utilizan los valores <code>$max1</code> o <code>alt1</code>, por ejemplo, en
lugar de sus posiciones <code>@10$3</code> o <code>@10$4</code>. Si en lugar de utilizar
<code>^</code> encontramos <code>-</code> el efecto es similar, pero en ese caso, los
nombres se refieren a los valores de la línea inferior.</dd>

<dt><code>*</code></dt><dd>Aunque en nuestro ejemplo no se ha utilizado ninguna fila
marcada con un <code>*</code> es bueno tener en cuenta que al utilizarla
hacemos que una línea sea ignorada cuando se produce un recálculo
general de la tabla con el comando <code>C-u C-c *</code>. Esto se hace cuando
los cálculos demoran mucho el redibujado de la tabla.</dd>

<dt><code>$</code></dt><dd>Tampoco he utilizado esta marca en la tabla. Se utiliza para
establecer en una determinada fila algún valor con nombre del estilo
<code>maximo=200</code>, para luego utilizar en las fórmulas el nombre de
<code>$maximo</code> en lugar de una celda de la tabla.</dd>
</dl>
</div>
</div>
<div id="outline-container-orgffd0efc" class="outline-2">
<h2 id="orgffd0efc">Conclusiones</h2>
<div class="outline-text-2" id="text-orgffd0efc">
<p>
Como se puede apreciar, la forma de manejar tablas de <code>org-mode</code> nos
pueden facilitar los cálculos para nuestra documentación. Hay muchos
detalles que no he llegado a mostrar en este pequeño artículo y como
siempre aconsejo: leeros la documentación que viene con <code>org-mode</code>, es
bastante clarificadora.
</p>

<p>
En un principio pensé en incluir también la generación de gráficos con
<code>gnuplot</code> desde nuestras tablas, pero al final lo dejo para un
posterior artículo, puesto que éste ha quedado ya suficientemente
pelma.
</p>

<p>
Es recomendable que practiques un poco cómo he van editando las tablas
y calculando las fórmulas, para poder apreciar así, todas las
facilidades que nos provee <code>org-mode</code> para hacerlo con más facilidad.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/org-mode/index.html">org-mode</a> <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/tablas/index.html">tablas</a> ]]></description>
  <category><![CDATA[org-mode]]></category>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[tablas]]></category>
  <link>https://notxor.nueva-actitud.org/2021/01/22/tablas-para-calculos-en-org-mode.html</link>
  <pubDate>Fri, 22 Jan 2021 08:49:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Publicar html con org-mode]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-01-13</div>
<p>
En el artículo de hoy hablo de cómo exportar de <code>org-mode</code> a <code>html</code>
para utilizarlo en un proyecto con varios ficheros <code>org</code>
interconectados entre sí.  Al exportar, las referencias <code>org</code> se
convierten en sus correspondientes enlaces <code>html</code> guardando la misma
estructura de directorios que tengan los ficheros <code>org</code>.  Es la forma
en la que <code>org-mode</code> <i>publica</i>.  Si quieres ahorrarte el suplicio de
leer el artículo y como lo cuento, busca el apartado <i>publishing</i> en
la documentación de <code>org-mode</code>... pero si prefieres leer un resumen en
español y saber cómo lo hago yo: sigue leyendo.
</p>

<p>
¿De qué va todo esto de <i>publicar</i> <code>html</code> desde <code>org-mode</code>? ¿Para qué
lo puedo utilizar? Pues pondré un ejemplo, con un proyecto que estoy
empezando. Hace un tiempo puse por aquí una prueba para <a href="https://notxor.nueva-actitud.org/2018/11/04/prueba-generando-librojuego-desde-org-mode.html">crear un
<i>librojuego</i></a> con <code>org-mode</code>. 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.
</p>

<p>
El <i>caso de uso</i> 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 PICA<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>
con la que, los que leéis el <i>blog</i> habitualmente, sabéis que
colaboro.  El caso es que la <i>parte servidor</i> 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
<i>guiones</i> más interactivos, en formato <i>librojuego</i>. He probado varios
sistemas que automatizan la creación de ese tipo de <i>juegos</i>: he
probado <a href="https://github.com/idmillington/undum">Undum</a>, he probado <a href="http://twinery.org/">Twine</a>, he probado <a href="https://github.com/textadventures/squiffy">Squiffy</a>... y ninguno de
los tres ha funcionado como esperaba. El primero, que había que
escribir el código en puro <code>html</code> y <code>javascript</code>, 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 <code>node</code> y
un montón de paquetes, no terminaron de funcionar correctamente.  La
otra idea que se me ocurrió era montar un <code>wiki</code> enlazando páginas
directamente. Sin embargo, para que funcione tienes que tener un
servidor y para trabajar en modo <i>monousuario</i> es muy lioso.
</p>

<p>
Cuando le comenté los problemas que tenía para encontrar una
herramienta adecuada a un amigo del <i>CAAD</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>, me dijo: <i>pensaba
que lo harías con algún pichorro de Emacs</i>. Y tenía razón, al final no
me tendré que pegar con cosas como <i>electron</i> y <i>node</i> o desperdiciar
espacio en disco y en memoria con esas cosas, teniendo suficiente con
el texto gestionado por los <i>chismáticos</i> de <i>Emacs</i> y <code>org-mode</code>.
</p>
<div id="outline-container-org431856c" class="outline-2">
<h2 id="org431856c">Estructura de ficheros</h2>
<div class="outline-text-2" id="text-org431856c">
<p>
Para iniciar el proyecto es recomendable tener clara la estructura que
le daremos a nuestro contenido. El proyecto lo he llamado, de forma
provisional, <i>Kvintero</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> y tiene la siguiente estructura de
ficheros:
</p>

<pre class="example" id="orgbfc790c">
.
├── 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
</pre>

<p>
se pueden apreciar algunas cosas así a bote pronto: los directorios
<code>org</code> y <code>html</code> serán idénticos, pero mientras el primero está
compuesto de los fuentes de <code>org-mode</code> el segundo es el resultado de
convertir los fuentes en <code>html</code>. En esos directorios hay otros
subdirectorios para la(s) hoja(s) de estilos, las imágenes y los
archivos <code>javascript</code>. También hay un directorio que se llama
<code>plantillas</code>, 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 <code>kvintero.el</code> que contiene un par de formas que
definen algunas variables del proyecto para poder exportar cómodamente
en tres <i>teclazos</i>.
</p>

<p>
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 <code>org</code> y dentro de él: el <code>css</code>, el <code>img</code> y el
<code>js</code>, cada uno con sus cosas, para que no se mezclen.
</p>

<p>
Para que dicha estructura sea efectiva es recomendable que luego, en
los enlaces se utilicen siempre <i>paths relativos</i>. Para que el sitio
<i>desplegado</i> o <i>publicado</i>, ─como prefieras llamarlo─, funcione
incluso sin un servidor, es siempre recomendable el uso de dichos
<i>paths relativos</i>. Además, se pueden utilizar anclas a etiquetas
concretas dentro de otros ficheros <code>org</code><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>, como veremos después.
</p>
</div>
</div>
<div id="outline-container-orge4b5eaa" class="outline-2">
<h2 id="orge4b5eaa">El código</h2>
<div class="outline-text-2" id="text-orge4b5eaa">
<p>
Como he dicho antes, el código es muy sencillo, lo pongo aquí y luego
lo comentaré un poco:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">ox-publish</span>)

(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-publish-project-alist
      '(
        (<span style="color: #f1fa8c;">"fuentes-org"</span>
         <span style="color: #8be9fd; font-style: italic;">:base-directory</span> <span style="color: #f1fa8c;">"~/proyectos/kvintero/org/"</span>
         <span style="color: #8be9fd; font-style: italic;">:base-extension</span> <span style="color: #f1fa8c;">"org"</span>
         <span style="color: #8be9fd; font-style: italic;">:publishing-directory</span> <span style="color: #f1fa8c;">"~/proyectos/kvintero/html/"</span>
         <span style="color: #8be9fd; font-style: italic;">:recursive</span> t
         <span style="color: #8be9fd; font-style: italic;">:publishing-function</span> org-html-publish-to-html
         <span style="color: #8be9fd; font-style: italic;">:headline-levels</span> 4
         <span style="color: #8be9fd; font-style: italic;">:html-preamble</span> t)
        (<span style="color: #f1fa8c;">"org-auxiliares"</span>
         <span style="color: #8be9fd; font-style: italic;">:base-directory</span> <span style="color: #f1fa8c;">"~/proyectos/kvintero/org/"</span>
         <span style="color: #8be9fd; font-style: italic;">:base-extension</span> <span style="color: #f1fa8c;">"css</span><span style="color: #8be9fd;">\\</span><span style="color: #bd93f9;">|</span><span style="color: #f1fa8c;">js</span><span style="color: #8be9fd;">\\</span><span style="color: #bd93f9;">|</span><span style="color: #f1fa8c;">png</span><span style="color: #8be9fd;">\\</span><span style="color: #bd93f9;">|</span><span style="color: #f1fa8c;">ttf"</span>
         <span style="color: #8be9fd; font-style: italic;">:publishing-directory</span> <span style="color: #f1fa8c;">"~/proyectos/kvintero/html/"</span>
         <span style="color: #8be9fd; font-style: italic;">:recursive</span> t
         <span style="color: #8be9fd; font-style: italic;">:publishing-function</span> org-publish-attachment)
        (<span style="color: #f1fa8c;">"kvintero"</span> <span style="color: #8be9fd; font-style: italic;">:components</span> (<span style="color: #f1fa8c;">"fuentes-org"</span> <span style="color: #f1fa8c;">"org-auxiliares"</span>))))
</pre>
</div>

<p>
La primera línea no necesita mucho que explicar: nos aseguramos que
está en el sistema el paquete que proporciona <code>ox-publish</code>. 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:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #f1fa8c;">"nombre-proyecto"</span> ...)
</pre>
</div>

<p>
Vamos a analizarlo un poco más despacio.
</p>
</div>
<div id="outline-container-orgc6a2f3f" class="outline-3">
<h3 id="orgc6a2f3f">Proyectos de publicación</h3>
<div class="outline-text-3" id="text-orgc6a2f3f">
<p>
El primer elemento de la lista trata con los fuentes. Establece cuál
es su directorio base en <code>:base-directory</code>. 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 <code>fuentes-org</code> debe tratar o trabajar.
En <code>:base-extension</code> se especifica de qué tipo son los ficheros tiene
que procesar. Si nos fijamos en la primera forma la extensión es
única: <code>org</code>, pero en la segunda se establece una lista de extensiones
separadas por <code>\\|</code>. Lo siguiente que se necesita es el lugar donde se
depositará el resultado del proceso y se pone en
<code>:publishing-directory</code>. En este caso es un directorio local, pero
también se puede configurar un <code>path</code> con el formato que entienda
<code>tramp</code>, por ejemplo: <code>/ssh:usuario@host:path/al/sitio</code>.  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 <code>org-mode</code>.
</p>

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

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

<p>
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 <code>org-mode</code>.
</p>

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

<p>
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:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">[[file:cualquier.org::*Título de apartado][Texto mostrado]]
[[file:cualquier.org::#id-definido][Texto mostrado]]
[[file:cualquier.org::mi objetivo][Texto mostrado]]
</pre>
</div>

<p>
El formato con <code>*Título de apartado</code> busca entre los títulos de
sección que contenga el fichero el que coincida con <i>Título de
apartado</i>. Con <code>#id-definido</code> se busca un elemento que en sus
propiedades contenga <code>#+name: id-definido</code>. 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
<code>&lt;&lt;mi objetivo&gt;&gt;</code>, en el texto y se enlaza de la tercera forma.
</p>

<p>
Como digo, supongo que todos esos detalles ya los conocéis, al menos
quienes utilizáis habitualmente <code>org-mode</code>, pero, ─como digo─, no está
de más repasarlo.
</p>
</div>
</div>
</div>
<div id="outline-container-org5d335fe" class="outline-2">
<h2 id="org5d335fe">Plantillas y documentos</h2>
<div class="outline-text-2" id="text-org5d335fe">
<p>
Una forma de estandarizar y ahorrar tiempo en la publicación de los
ficheros <code>org</code>, tanto en <code>html</code> como en <code>pdf</code> es proporcionar al
sistema una plantilla que haga las veces de <i>configuración</i> 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:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">#+author:  Notxor
#+email:   notxor@nueva-actitud.org
#+options: ':t *:t -:t ::t &lt;: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: &lt;link rel="stylesheet" type="text/css" href="css/tus-estilos-favoritos.css" /&gt;
</pre>
</div>

<p>
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 <i>paths</i>, 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 <i>base</i> y utilizamos la misma
cabecera para publicar el sitio, no encontrará el fichero <code>.css</code>,
necesitamos cambiar la última línea a:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">#+html_head: &lt;link rel="stylesheet" type="text/css" href="../css/style.css" /&gt;
</pre>
</div>

<p>
Modificando el <i>path</i> en el que debe buscar la hoja de estilos.
</p>

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

<div class="org-src-container">
<pre class="src src-org-mode">#+setupfile: ../plantilla/plantilla-base.org
#+title: Este es el Título
#+subtitle: y este el Subtítulo
</pre>
</div>

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

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

<div class="org-src-container">
<pre class="src src-org-mode">* Notas    :noexport:

Esta información no se exportará al fichero ~html~
</pre>
</div>
</div>
<div id="outline-container-orga9bab23" class="outline-3">
<h3 id="orga9bab23">Hoja de estilos</h3>
<div class="outline-text-3" id="text-orga9bab23">
<p>
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
<i>Internet</i> ha muchos ficheros <code>css</code> para la exportación de <code>org-mode</code>
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:
</p>

<p>
<a href="http://thomasf.github.io/solarized-css">http://thomasf.github.io/solarized-css</a>
</p>

<p>
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 <i>Internet</i>.
Pero, es una hoja destinada a mostrar sólo una estructura <code>org</code>, 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 <i>tutorial</i>.
</p>

<p>
Puedes elegir entre dos temas de color:
</p>

<p>
<b>solarized-dark</b>
</p>


<figure id="org98345d4">
<img src="imagenes/Captura-pantalla_solarized-dark.png" alt="Captura-pantalla_solarized-dark.png">

</figure>

<p>
<b>solarized-light</b>
</p>


<figure id="org97083d4">
<img src="imagenes/Captura-pantalla_solarized-light.png" alt="Captura-pantalla_solarized-light.png">

</figure>

<p>
Particularmente me gusta más el <code>solarized-light</code> 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.
</p>
</div>
</div>
</div>
<div id="outline-container-orge4a5cfa" class="outline-2">
<h2 id="orge4a5cfa">Publicación</h2>
<div class="outline-text-2" id="text-orge4a5cfa">
<p>
Yo comenzaré con un pequeño fichero de texto en formato <code>org</code> para
empezar el proyecto, cualquier texto vale, yo he preparado estos
pequeños párrafos para comenzar:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">#+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...]]
</pre>
</div>

<p>
Comenzamos con los cambios:
</p>

<p>
El autor del <code>css</code> utiliza la carga de fuentes desde la habitual <i>URL</i>
de <i>gúguel</i>, una política que no es de mi agrado. Yo, en cambio, he
bajado de <i>Internet</i> <a href="https://www.dafont.com/es/">algunas fuentes de <i>daFont</i>,</a> 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 <a href="https://www.dafont.com/es/feathergraphy.font?text=E%26%23292%3BO%26%23348%3BAN%26%23284%3BO+%26%23264%3BIU%26%23308%3BA%26%23364%3BDE+e%26%23293%3Bo%26%23349%3Ban%26%23285%3Bo+%26%23265%3Biu%26%23309%3Ba%26%23365%3Bde">Feathergraphy</a>, que es gratuita para uso
personal<sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>, en los títulos y para el texto utilizaré la habitual
<i>Linux Libertine</i> que uso también como fuente principal en este
<i>blog</i>, y que tiene una licencia libre y se puede utilizar para
cualquier fin.
</p>

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

<div class="org-src-container">
<pre class="src src-css"><span style="color: #8be9fd; font-style: italic;">@font-face</span> {
    <span style="color: #ff79c6; font-weight: bold;">font-family</span>: <span style="color: #f1fa8c;">"Libertine Regular"</span>;
    <span style="color: #ff79c6; font-weight: bold;">src</span>: url(<span style="color: #f1fa8c;">'../fuentes/LinLibertine_R.ttf'</span>) format(<span style="color: #f1fa8c;">'truetype'</span>);
    <span style="color: #ff79c6; font-weight: bold;">font-weight</span>: normal;
    <span style="color: #ff79c6; font-weight: bold;">font-style</span>: normal;
}
<span style="color: #8be9fd; font-style: italic;">@font-face</span> {
    <span style="color: #ff79c6; font-weight: bold;">font-family</span>: <span style="color: #f1fa8c;">"Feathergraphy"</span>;
    <span style="color: #ff79c6; font-weight: bold;">src</span>: url(<span style="color: #f1fa8c;">'../fuentes/Feathergraphy2.ttf'</span>) format(<span style="color: #f1fa8c;">'truetype'</span>);
    <span style="color: #ff79c6; font-weight: bold;">font-weight</span>: normal;
    <span style="color: #ff79c6; font-weight: bold;">font-style</span>: normal;
}
</pre>
</div>

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

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

<p>
Si no estamos en un fichero <code>org</code>, podemos utilizar el comando <code>M-x
   org-publish-project RET kvintero RET</code>.
</p></li>
<li>Abrir el fichero en un navegador web. Obtendremos algo parecido a:</li>
</ol>


<figure id="org2e431cc">
<img src="imagenes/Captura-pantalla_Cambio-fuentes.png" alt="Captura-pantalla_Cambio-fuentes.png">

</figure>

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

<div class="org-src-container">
<pre class="src src-org-mode">#+setupfile: ../plantillas/plantilla-base.org
#+title: Kvintero

* Introducción
</pre>
</div>

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


<figure id="orgabf606f">
<img src="imagenes/Captura-pantalla_cabecera-numero.png" alt="Captura-pantalla_cabecera-numero.png">

</figure>

<p>
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 <i>plantilla</i>.  En concreto
en la línea:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">#+options: num:t p:nil pri:nil stat:t tags:t tasks:t tex:t timestamp:t toc:t
</pre>
</div>

<p>
Hay que cambiarla por:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">#+options: num:nil p:nil pri:nil stat:t tags:t tasks:t tex:t timestamp:t toc:nil
</pre>
</div>

<p>
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 <code>dired</code>, si tienes activado normalmente,
como yo el <code>dired-sidebar</code> lo tienes a mano. Pasas a ese <i>buffer</i>,
seleccionas los ficheros, ─si son muchos, puedes seleccionar el
directorio entero─, pulsando <code>m</code> para <i>marcar</i> y luego pulsas <code>T</code>
(obsérvese la mayúscula). Es lo mismo que hacer un <code>touch</code> en una
consola, que es el otro método rápido. Si ahora repites el comando de
publicar el proyecto, el resultado será:
</p>


<figure id="org8bdd84c">
<img src="imagenes/Captura-pantalla_cabecera-sin-numero.png" alt="Captura-pantalla_cabecera-sin-numero.png">

</figure>
</div>
</div>
<div id="outline-container-org8218a6f" class="outline-2">
<h2 id="org8218a6f">Poniendo una imagen</h2>
<div class="outline-text-2" id="text-org8218a6f">
<p>
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.
</p>

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

<div class="org-src-container">
<pre class="src src-org-mode">#+setupfile: ../plantillas/plantilla-base.org
#+title: Kvintero

* Introducción

[[file:img/menhir.png]]
</pre>
</div>

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


<figure id="orgf3a29d9">
<img src="imagenes/Captura-pantalla_imagen-centrada.png" alt="Captura-pantalla_imagen-centrada.png">

</figure>

<p>
Está bien, pero es un poco <i>soso</i>. 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 <code>css</code>.
</p>

<div class="org-src-container">
<pre class="src src-css"><span style="color: #50fa7b; font-weight: bold;">.float-left</span> {
    <span style="color: #ff79c6; font-weight: bold;">float</span>: left;
    <span style="color: #ff79c6; font-weight: bold;">margin-right</span>: 1em;
}
<span style="color: #50fa7b; font-weight: bold;">.float-right</span> {
    <span style="color: #ff79c6; font-weight: bold;">float</span>: right;
    <span style="color: #ff79c6; font-weight: bold;">margin-left</span>: 1em;
}
</pre>
</div>

<p>
En principio me bastaba con <code>float-left</code>, pero ya puestos, he creado
también <code>float-right</code> 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.
</p>

<p>
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>

<div class="org-src-container">
<pre class="src src-css"><span style="color: #50fa7b; font-weight: bold;">.p-inicio::first-line</span> {
    <span style="color: #ff79c6; font-weight: bold;">font-weight</span>: bold;
    <span style="color: #ff79c6; font-weight: bold;">color</span>: <span style="color: #ffffff; background-color: #000000;">rgba(0,0,0,0.85)</span>;
}
<span style="color: #50fa7b; font-weight: bold;">.p-inicio::first-letter</span> {
    <span style="color: #ff79c6; font-weight: bold;">position</span>: relative;
    <span style="color: #ff79c6; font-weight: bold;">padding-top</span>: 0.1em;
    <span style="color: #ff79c6; font-weight: bold;">display</span>: block;
    <span style="color: #ff79c6; font-weight: bold;">float</span>: left;
    <span style="color: #ff79c6; font-weight: bold;">font-family</span>: <span style="color: #f1fa8c;">'Feathergraphy'</span>;
    <span style="color: #ff79c6; font-weight: bold;">font-weight</span>: normal;
    <span style="color: #ff79c6; font-weight: bold;">font-size</span>: 3.2em;
    <span style="color: #ff79c6; font-weight: bold;">line-height</span>: 0.8em;
    <span style="color: #ff79c6; font-weight: bold;">color</span>: <span style="color: #ffffff; background-color: #d33682;">#d33682</span>;
    <span style="color: #ff79c6; font-weight: bold;">margin-right</span>: 0.1em;
}
</pre>
</div>

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

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

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


<figure id="orgd421b56">
<img src="imagenes/Captura-pantalla_imagen-fluye.png" alt="Captura-pantalla_imagen-fluye.png">

</figure>

<p>
¿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:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">#+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.
</pre>
</div>

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

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


<figure id="org2d0809a">
<img src="imagenes/Captura-pantalla_poniendo-clases.png" alt="Captura-pantalla_poniendo-clases.png">

</figure>

<p>
Primero hago los ajustes ahí, probando colores, márgenes, fuentes,
etc. y luego lo paso al código definitivo de la hoja de estilos.
</p>
</div>
</div>
<div id="outline-container-org57038fc" class="outline-2">
<h2 id="org57038fc">Conclusiones</h2>
<div class="outline-text-2" id="text-org57038fc">
<p>
Publicar proyectos es una forma sencilla, pero potente de crear
contenido <i>web</i> que se puede emplear para muchas cosas desde
<code>org-mode</code>. Una de los usos para desarrolladores es, generar la
documentación para colocarla en <i>Internet</i> o distribuirla con el
programa. Generar un <code>epub</code> fácilmente. Tener un sitio de <i>Internet</i>
estático de una manera sencilla. También, en lugar de enfocar la
publicación a <code>html</code> se puede enfocar a <code>pdf</code> con <i>LaTeX</i>, o incluso
tener proyectos que generen la documentación en varios formatos:
<code>info</code>, <code>html</code>, <code>pdf</code>, etc.
</p>

<p>
Hay un montón de aspectos que no he utilizado aquí, pero están
explicados en la documentación de <code>org</code>.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Protención a la Infancia Contra el Abuso <a href="https://asociacionpica.org">https://asociacionpica.org</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Club de Aventuras AD</i> en <a href="http://www.caad.es/">http://www.caad.es/</a>... sí, aún
existe el foro.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Su significado sería <i>Quinta Tierra</i>: en Esperanto <i>Kvin</i>
significa 5 y <i>Tero</i>, Tierra. 
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Hay una explicación completa de dichas anclas en el apartado
<i>4.8 Search Options in File Links</i> del manual de <code>org-mode</code>.
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Si la vas a emplear para algún proyecto profesional, que no se
te olvide pagar los pocos euros que cuesta. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> <a href="/tags/juegos/index.html">juegos</a> <a href="/tags/librojuegos/index.html">librojuegos</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <category><![CDATA[juegos]]></category>
  <category><![CDATA[librojuegos]]></category>
  <link>https://notxor.nueva-actitud.org/2021/01/13/publicar-html-con-org-mode.html</link>
  <pubDate>Wed, 13 Jan 2021 12:07:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Rust por encima, comparando con erlang]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-01-06</div>
<p>
Durante el 2020 he dedicado tiempo a aprender <code>erlang</code>. 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 <code>erlang</code> con las de
<code>Rust</code>, 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?
</p>

<p>
Después de trabajar un poco y hacer algún que otro proyecto con
<code>erlang</code>, 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 <code>erlang</code> llegué a <a href="https://www.infoq.com/articles/rust-erlang-comparison/">un artículo que lo
comparaba con Rust</a>. La tentación de probar el lenguaje fue grande,
porque algunas características de las que me encantan de <code>erlang</code>
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.
</p>
<div id="outline-container-org7c8b76e" class="outline-2">
<h2 id="org7c8b76e">Características</h2>
<div class="outline-text-2" id="text-org7c8b76e">
<p>
Quizá sea más fácil si enumero las características de <code>erlang</code> que me
gustan y vamos a ver cuáles proporciona <code>Rust</code>. Mirando en la
documentación encontré una <a href="https://doc.rust-lang.org/reference/influences.html">lista de lenguajes que han influido</a> a éste.
El caso es que aparecen en ella algunos lenguajes que me resultan
gratos:
</p>

<ul class="org-ul">
<li><code>erlang</code>: de éste toman el <i>paso de mensajes</i> y ha influido en otras
características.</li>
<li><code>scheme</code>: de él toma los <i>macros</i>.</li>
<li><code>ruby</code>: de aquí viene la sintaxis de <i>closures</i>.</li>
</ul>

<p>
Hay varios lenguajes más que tienen características interesantes:
<code>Haskell</code>, <code>OCaml</code>, <code>C++</code>, etc. Pero vamos a ver las cosas que me
gustaría encontrar y que <code>erlang</code> me proporciona.
</p>
</div>
<div id="outline-container-orgc595697" class="outline-3">
<h3 id="orgc595697">Inmutabilidad</h3>
<div class="outline-text-3" id="text-orgc595697">
<p>
En <code>erlang</code> la asignación de las variables no puede cambiar. De
primeras puede parecer complicado de entender que las variables <i>no
varíen</i>, 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 <i>no esperado</i>.
</p>

<p>
El caso es que <code>Rust</code> tiene variables que pueden <i>mutar</i>, 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.
</p>
</div>
</div>
<div id="outline-container-org8624c21" class="outline-3">
<h3 id="org8624c21">Concordancia de patrones</h3>
<div class="outline-text-3" id="text-org8624c21">
<p>
Esta es una de las características que más me han gustado de <code>erlang</code>.
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 <i>polimórfico</i>. 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.
</p>

<p>
Por lo que he visto <code>Rust</code> 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 <code>case</code> de <code>erlang</code>. 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.
</p>
</div>
</div>
<div id="outline-container-orgdd47ab3" class="outline-3">
<h3 id="orgdd47ab3">Tuples y listas</h3>
<div class="outline-text-3" id="text-orgdd47ab3">
<p>
La manera en la que <code>erlang</code> utiliza las estructuras de datos, no sólo
los <i>tuples</i>, pero pincipalmente éstos, es una forma muy inteligente
de organizar la información con la que trabaja el programa.  Una vez
que defines un <i>tuple</i> o una lista, se mantienen inmutables.  Pero
puedes organizar los datos de cualquier manera que te resulte cómodo y
luego descomponerlo con <i>patrones de concordancia</i> de manera rápida,
con una <i>asignación</i>.
</p>

<p>
Por lo que he visto en <code>Rust</code> también hay <i>tuples</i> y equivalentes a
las listas tiene <i>vectores</i> y <i>arrays</i>. Uno de esos tipos es inmutable
(<i>arrays</i>), más recomendable cuando se conoce el tamaño en tiempo de
compilación. Mientras que los <i>vectores</i> son conjuntos de datos que
pueden ajustarse en tiempo de ejecución. Veremos cómo se comportan
estos tipos de datos.
</p>
</div>
</div>
<div id="outline-container-orgbbca8d1" class="outline-3">
<h3 id="orgbbca8d1">Registros y ETS<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup></h3>
<div class="outline-text-3" id="text-orgbbca8d1">
<p>
Los registros son estructuras que pueden almacenar cualquier tipo de
dato válido de <code>erlang</code>. Son estructuras fijas que se definen junto al
programa y no pueden cambiarse durante la ejecución. No se pueden
añadir o quitar <i>campos</i> en medio de la ejecución. Además esos
registros se pueden organizar en <i>tablas ETS</i>, 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 <i>propietario</i> que
sea el único encargado de acceder a ella, como <i>lectura/escritura</i> o
como <i>escritura</i>, de esta forma se puede garantizar la integridad de
los datos. Todo esto, sin mencionar <code>Mnesia</code> que es una base de datos
que puedo organizar esas tablas <i>ETS</i> y almacenar datos relacionados
en ellas. No es <code>SQL</code> pero se pueden organizar consultas
equivalentes.
</p>

<p>
Parece ser que <code>Rust</code> proporciona <i>structs</i>. Sin embargo, no parece
que haya algo similar a <i>ETS</i>. Aunque supongo que un <i>vector de
structs</i> 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.
</p>
</div>
</div>
<div id="outline-container-orgf715264" class="outline-3">
<h3 id="orgf715264">Iteración</h3>
<div class="outline-text-3" id="text-orgf715264">
<p>
Como muchos otros lenguajes <i>funcionales</i>, <code>erlang</code> proporciona el
mecanismo de iteración como su principal modo para realizar <i>bucles</i>.
Además, en la librería <code>lists</code> proporciona algunas funciones
<i>iterativas</i> como <code>map</code>, <code>foreach</code>, <code>filter</code>, etc. Además, la potencia
de la iteración sobre la estructura <i>cabeza-cola</i>, <code>[H|T]</code>, como en
otros lenguajes funcionales es algo que se emplea con profusión. Eso
sin contar los maravillosos bloques de código, que incluso <i>Python</i>
copió para realizar operaciones rápidas, tipo:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Devuelve una lista con el doble de los t&#233;rminos impares
</span>[<span style="color: #f8f8f2; font-weight: bold;">X</span> * 2 <span style="color: #ff79c6; font-weight: bold;">||</span> <span style="color: #f8f8f2; font-weight: bold;">X</span> <span style="color: #ff79c6; font-weight: bold;">&lt;-</span> <span style="color: #f8f8f2; font-weight: bold;">List</span>, (<span style="color: #f8f8f2; font-weight: bold;">X</span> <span style="color: #8be9fd; font-style: italic;">rem</span> 2) /= 0].
</pre>
</div>

<p>
Parece ser que <code>Rust</code> cuenta con las instrucciones de bucle habituales
de otros lenguajes como <code>while</code>, <code>for</code>, 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.
</p>
</div>
</div>
<div id="outline-container-orge5ad6a6" class="outline-3">
<h3 id="orge5ad6a6">Comunicación entre procesos</h3>
<div class="outline-text-3" id="text-orge5ad6a6">
<p>
Al principio, la forma de comunicarse que tienen los procesos de
<code>erlang</code> 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 <i>buzón</i> para él e intercambiar mensajes con los
demás procesos.
</p>

<p>
La concurrencia es una de esas cosas que le dan <i>caché</i> a <code>erlang</code> 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 <code>erlang</code>.
</p>

<p>
Por lo que he leído hasta ahora sobre <code>Rust</code>, también está enfocado a
la concurrencia. Aún no sé qué mecanismos involucra.
</p>
</div>
</div>
<div id="outline-container-org5888c75" class="outline-3">
<h3 id="org5888c75">Documentación</h3>
<div class="outline-text-3" id="text-org5888c75">
<p>
La documentación con la que viene <code>erlang</code> 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 <i>Emacs</i> para realizar
esas consultas.
</p>

<p>
Por lo que he visto, <code>Rust</code> 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 <a href="https://www.rust-lang.org/learn">enlaces donde poder aprender</a> y consultar
los distintos aspectos del lenguaje. Además, después de mirar un poco
por encima, la ayuda viene en ficheros <code>html</code> y para leerla
cómodamente se lanza el navegador.
</p>
</div>
</div>
</div>
<div id="outline-container-orgba6b2e8" class="outline-2">
<h2 id="orgba6b2e8">Rust</h2>
<div class="outline-text-2" id="text-orgba6b2e8">
<p>
El caso es que me he puesto a investigar algo más sobre <code>Rust</code> y a
parte de todo lo que se puede encontrar en la <i>wikipedia</i>, donde te
explica que es un lenguaje desarrollado por la Fundación Mozilla para
el desarrollo de <i>bajo nivel</i>, o de <i>sistemas</i>, superando las
dificultades que presenta <i>C</i>, he visto en su página algo más de
información.
</p>

<p>
La curiosidad, antes de meterme en faena, sin tener muy claro por qué
merece la pena aprenderlo, me llevó a investigar si <i>a priori</i> 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 <i>Benchmark Game</i>.  Concretamente:
</p>

<ul class="org-ul">
<li><a href="https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/rust.html">Con <i>C</i></a></li>
<li><a href="https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/rust-clang.html">Con <i>C Lang</i></a></li>
<li><a href="https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/rust-gpp.html">Con <i>C++</i></a></li>
<li><a href="https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/rust-go.html">Con <i>Go</i></a></li>
</ul>

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

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

<p>
Quise probar algunos pequeños programillas, sólo por curiosidad e
instalé primero, los paquetes de <code>Rust</code> que hay en <i>OpenSuse</i>, aunque
en la documentación prefieren descargar (luego veremos ese método) los
programas de su <i>sitio web</i>. 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.
</p>

<p>
Después de esas pruebas, que ya habían aumentado mi curiosidad,
también <a href="https://www.tiobe.com/tiobe-index/">investigué la popularidad de <code>Rust</code></a>. 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 <i>curriculares</i> 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 <code>smalltalk</code>, <code>lisp</code>, <code>scheme</code>,
<code>erlang</code>... Todos lenguajes muy interesantes, pero poco populares o
usados en proyectos.
</p>
</div>
</div>
<div id="outline-container-org215c227" class="outline-2">
<h2 id="org215c227">Configurar el entorno de trabajo</h2>
<div class="outline-text-2" id="text-org215c227">
<p>
El entorno de trabajo, como se puede imaginar cualquiera que haya
leído un poco este <i>blog</i>, es <i>Emacs</i>. Pero vamos por partes.
</p>
</div>
<div id="outline-container-org03fa2ca" class="outline-3">
<h3 id="org03fa2ca">Instalación de <code>Rust</code></h3>
<div class="outline-text-3" id="text-org03fa2ca">
<p>
Como he dicho antes, en el <a href="https://doc.rust-lang.org/book/ch01-01-installation.html">manual de <code>Rust</code></a> realiza la instalación
desde su sitio con un simple comando:
</p>

<div class="org-src-container">
<pre class="src src-shell">$  curl --proto <span style="color: #f1fa8c;">'=https'</span> --tlsv1.2 https://sh.rustup.rs -sSf | sh
</pre>
</div>

<p>
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 <i>script</i> bajado de la
Internet así como así. Primero lo descargué y después de estudiar el
<i>script</i> lo ejecuté:
</p>

<div class="org-src-container">
<pre class="src src-shell">$ curl --proto <span style="color: #f1fa8c;">'=https'</span> --tlsv1.2 https://sh.rustup.rs -sSf &gt; sh.rustup.rs
$ bash sh.rustup.rs
</pre>
</div>

<p>
El estudio del <i>script</i>, tampoco ha sido exhaustivo, al final lo que
hace es descargar herramientas del sitio de <code>Rust</code>. 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
<i>TLS</i> 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 <i>software libre</i>.
</p>

<p>
Cuando ejecutas el <i>script</i>, aparece un menú preguntando el tipo de
instalación con tres alternativas: instalación por defecto, avanzada o
cancelar. Elegí la opción <code>1</code>, 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 instala<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. Hay que añadir ese
directorio al <code>$PATH</code>. Una vez hecho basta comprobar si la instalación
es correcta y funciona:
</p>

<div class="org-src-container">
<pre class="src src-shell">$ rustc --version
rustc 1.49.0 (e1884a8e3 2020-12-29)
$ cargo --version
cargo 1.49.0 (d00d64df9 2020-12-05)
</pre>
</div>

<p>
Una vez instalado se puede actualizar la instalación con:
</p>

<div class="org-src-container">
<pre class="src src-shell">$ rustup update
</pre>
</div>

<p>
o desinstalarlo con:
</p>

<div class="org-src-container">
<pre class="src src-shell">$ rustup uninstall
</pre>
</div>

<p>
o llamar a la documentación con:
</p>

<div class="org-src-container">
<pre class="src src-shell">$ rustup doc
</pre>
</div>

<p>
Como se puede apreciar un entorno completo.
</p>
</div>
</div>
<div id="outline-container-orgf7a5101" class="outline-3">
<h3 id="orgf7a5101">Preparar el editor</h3>
<div class="outline-text-3" id="text-orgf7a5101">
<p>
Aquí llega el momento de instalar paquetes en <i>Emacs</i> y convertirlo en
un auténtico <i>IDE</i> para <code>Rust</code>. No lo he probado mucho aún, pero lo
que he visto me ha gustado. Los paquetes que he instalado son los
siguientes:
</p>

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

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

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">rustic</span>)
</pre>
</div>

<p>
También, si usas <code>lsp-mode</code> hay que activar el <i>hook</i> para el
lenguaje:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-hook 'rustic-mode-hook #'lsp)
</pre>
</div>
</div>
</div>
<div id="outline-container-org5711dfe" class="outline-3">
<h3 id="org5711dfe">Probando todo</h3>
<div class="outline-text-3" id="text-org5711dfe">
<p>
Bueno pues vamos a por el <i>Hola mundo</i> correspondiente.
</p>

<div class="org-src-container">
<pre class="src src-shell">~ $ cd proyectos
~/proyectos $ mkdir hola-mundo
~/proyectos $ cd hola-mundo/
~/proyectos/hola-mundo $ emacs main.rs
</pre>
</div>

<p>
en ese fichero el contenido será:
</p>

<div class="org-src-container">
<pre class="src src-rust">fn main() {
    println!("Hola, mundo!");
}
</pre>
</div>

<p>
y compilamos
</p>

<div class="org-src-container">
<pre class="src src-shell">~/proyectos/hola-mundo $ rustc main.rs
~/proyectos/hola-mundo $ ./main
Hola, mundo!
</pre>
</div>

<p>
y todo funciona perfectamente. Ahora a probar... ya iré contando cómo
van las cosas.
</p>
</div>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Erlang Term Storage</i> 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Por defecto se instala en <code>~/.cargo/bin</code> 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/rust/index.html">rust</a> <a href="/tags/erlang/index.html">erlang</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[rust]]></category>
  <category><![CDATA[erlang]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2021/01/06/rust-por-encima.html</link>
  <pubDate>Wed, 06 Jan 2021 10:32:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Propósitos y despropósitos]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2021-01-02</div>
<p>
Ya <a href="https://notxor.nueva-actitud.org/2020/12/27/declaracion-de-intenciones.html">hice una <i>declaración de intenciones</i> para el año nuevo</a>, y no
utilizo el término <i>propósitos</i> 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.
</p>

<p>
Hay quien lee este <i>blog</i> no porque le interesen los temas de los que
hablo, sino porque es un amigo, o incluso un familiar. Ha elegido un
bando: el <i>mío</i>.  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 <a href="https://notxor.nueva-actitud.org/2020/12/27/declaracion-de-intenciones.html">en el grupo de Telegram</a> y casi me asusta.  Hay quien
ha elegido <i>mi</i> bando. <i>Asustar</i> no es esa la palabra que estoy
buscando, pero <i>sorprender</i> se queda corta con lo que quiero
expresar. Al fin y al cabo, este <i>blog</i> 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 <i>individualidad</i>
que con un sentimiento <i>colectivo</i> o de conexión. Sin embargo, siempre
es bienvenido saber que mis <i>tontás</i> 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 <i>hasta la última
gota de nuestra sangre</i>.
</p>
<div id="outline-container-org3e9a4e8" class="outline-2">
<h2 id="org3e9a4e8">Sobre el <i>software libre</i></h2>
<div class="outline-text-2" id="text-org3e9a4e8">
<p>
¿Cómo expresar lo que es para mí el <i>SL</i> sin hablar de ética?  Porque
no puedo hacerlo. Si me he decantado por él ha sido precisamente por
algunos aspectos <i>no técnicos</i>, que también los tiene, sino por los
aspectos éticos que el <i>software privativo</i> no tiene. Y también,
porque como digo en la introducción, genera <i>comunidad</i>. No hay un
proyecto interesante de <i>software libre</i> 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
<i>servicio técnico</i> del mismo. Quiero llamar la atención sobre el hecho
de que la mayoría de estos proyectos comienzan como algo <i>personal</i>,
una necesidad individual de solucionar un problema que se pone a
disposición de la comunidad.
</p>

<p>
Para mí es importante tener en cuenta esos matices porque el <i>alma
humana</i>, 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 <i>comunitario</i> 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
<i>comunismo</i> y el <i>liberalismo</i>, de la comunidad extrema al
individualismo extremo... ambos sistemas fracasados por menospreciar
uno de esos componentes del ser humano<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>

<p>
Como digo, el <i>software libre</i> consigue otorgarme libertades
individuales<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> 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.
</p>
</div>
</div>
<div id="outline-container-org62c2c22" class="outline-2">
<h2 id="org62c2c22">Sobre el número de usuarios y la calidad</h2>
<div class="outline-text-2" id="text-org62c2c22">
<p>
El que utilice unas herramientas minoritarias para hacer mi trabajo,
no debería necesitar mayor explicación. A estas alturas, no creo que
la <i>popularidad</i> de un <i>software</i> sea un índice de calidad. Ese
razonamiento nos puede llevar a conclusiones tan erradas como que el
<i>Seat Panda</i> o el <i>Opel Corsa</i> son mejores coches que el <i>Mercedes 500
SEL</i>, se han vendido más de los primeros.
</p>

<p>
Hay quien me ha preguntado por qué, si <i>Emacs</i> es tan bueno, no tiene
más usuarios con ánimo de echar <i>avispillas</i>, 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 <i>software</i> u otro.
</p>

<p>
Mucha gente no se calienta la cabeza con cosas como la <i>ética</i>, la
<i>comunidad</i>, la <i>calidad</i> o cualquier otra disquisición paralela.  Una
herramienta es sólo una herramienta: si encienden el ordenador y
arranca <i>Windows</i> no se preguntan más<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>. Cuentan con la ventaja de
que todo en la industria informática está hecho para que así sea; lo
utiliza <i>todo el mundo</i> 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.
</p>

<p>
Oigo también algunas expresiones como <i>no tiene nada que envidiar
a...</i> cuando hablamos de algún <i>software libre</i> comparándolo con
alguno <i>privativo</i>. Lo cual siempre es un error de concepto y parece,
que puesto que no hay grandes multinacionales detrás del <i>software</i>
que usamos, hay un problema con su calidad. Si fuera así, <i>GNU/Linux</i>
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.
</p>

<p>
Y puestos a comparar, me gustaría poder comparar la calidad de los
documentos generados por un usuario medio de <i>LaTeX</i> con los generados
por un usuario medio de <i>Word</i>. Sin entrar en más consideraciones esto
nos lleva al siguiente apartado: el esfuerzo.
</p>
</div>
</div>
<div id="outline-container-orgc744b2b" class="outline-2">
<h2 id="orgc744b2b">Sobre lo que sabemos y lo que creemos saber</h2>
<div class="outline-text-2" id="text-orgc744b2b">
<p>
En el <i>software libre</i> es condición necesaria, pero no suficiente,
saber <i>qué estás haciendo</i>. Si no sabes el <i>qué</i>, no encontrarás el
<i>cómo</i>. 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 <i>software libre</i> y el <i>privativo</i>. El primero parte de
la idea de que el usuario es <i>capaz</i> y sabe lo que está haciendo; el
otro utiliza la premisa de que el usuario es <i>tonto</i>, o no sabe nada
de informática, y hay que darle las cosas mascadas.
</p>

<p>
Por otro lado, también conozco muchas personas, excelentes
profesionales en otros campos, que creen que <i>saben informática</i>
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.
</p>

<p>
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 <i>la
informática</i> 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 <i>amateur</i> y
autodidacta seguramente terminarán siendo usadas en el trabajo
diario.
</p>

<p>
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 <i>software
libre</i>, tienen la idea de que es complejo, difícil y <i>elitista</i>... y
este pensamiento me lleva al siguiente punto del que quería hablar.
</p>
</div>
</div>
<div id="outline-container-orgac8df7a" class="outline-2">
<h2 id="orgac8df7a">Sobre predicar y el elitismo</h2>
<div class="outline-text-2" id="text-orgac8df7a">
<p>
He tropezado con algunos usuarios que se creen mejores que otros
porque utilizan ésta <i>distro</i> o la otra.  Algunos, incluso con la
pretendida <i>superioridad</i> 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
<i>superioridad moral</i>, creyendo que utilizar sólo <i>software libre</i> les
otorga algún tipo de <i>bula</i> o de una consideración ética superior.
</p>

<p>
También hay quien al poco tiempo de descubrir el maravilloso mundo del
<i>software libre</i> se convierte en <i>el pesao del linux</i>. Sí, yo también
he sido <i>un pesao del linux</i>. Es una fase por la que creo que pasamos
todos los usuarios <i>convencidos</i> de las bondades, de la calidad, de la
ética y la filosofía que hay detrás del <i>software libre</i>. 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 <i>Micro$oft</i>. 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.
</p>

<p>
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 <i>drivers</i> libres. Si te
pones límites en el <i>software</i> te encontrarás límites en el
<i>hardware</i>, eso lo sabemos: nos lo encontramos casi a diario, y
coincide con la filosofía de <i>software-hardware</i> de <i>ápel</i>. No es un
demérito utilizar una <i>distro</i> que te facilite la vida reconociendo
<i>drivers</i> 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 <i>kernel
monolítico</i> 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.
</p>
</div>
</div>
<div id="outline-container-org218c954" class="outline-2">
<h2 id="org218c954">Sobre lo que uso</h2>
<div class="outline-text-2" id="text-org218c954">
<p>
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.
</p>

<p>
Quizá decir que <i>mi</i> herramienta es <i>Emacs</i> no sea suficiente para
expresar todo lo que extraigo de él. No es un <i>editor</i>, es un sistema
<i>lisp</i> que sirve para editar archivos de texto. Es el ejemplo de cómo
ha ido cambiando mi percepción del <i>software libre</i> con el tiempo. Yo
también fui defensor de <i>vim</i> 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.
</p>

<p>
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
<i>software de oficina</i>, libre como <i>LibreOffice</i> o <i>privativo</i> como la
<i>suite</i> de <i>micro$oft</i>. La mayoría de los psicólogos, y otros
profesionales, no necesitan más.
</p>

<p>
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. <i>LaTeX</i> ya era una de las herramientas que
utilizaba antes de descubrir <i>Emacs</i> en toda su plenitud. Bueno,
<i>descubrir</i> 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: <i>vim</i>, que estaba instalado en la máquina. No tenía que
instalar nada. ¿Cuál fue la inflexión?  Descubrir <code>org-mode</code>.
</p>

<p>
Había oído muchas veces hablar de las bondades de <code>org-mode</code> pero
siempre daba un poco de pereza utilizarlo: instalar <i>Emacs</i>, 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 <i>textualizar</i>. 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 <code>lisp</code> y lo tenía muy olvidado.
</p>

<p>
¿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 <i>lisp</i> para adecuar el <i>chismático</i>
o para hacerme una funcionalidad nueva. Eso no es un uso para un
<i>usuario medio</i>... 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.
</p>
</div>
</div>
<div id="outline-container-orgf9d0281" class="outline-2">
<h2 id="orgf9d0281">Sobre las guerras de <i>software</i></h2>
<div class="outline-text-2" id="text-orgf9d0281">
<p>
Es muy cansino asistir a guerras de usuarios de las distintas
herramientas, <i>distros</i>, editores siempre con la misma cantinela.  No
es la primera vez que escribo por aquí que <i>cada uno tiene el sistema
operativo que se merece</i>, 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
<i>de expertos</i> 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.
</p>

<p>
Las estériles discusiones de si es mejor tal o cual <i>distro</i>, o si
<i>vim</i> o <i>Emacs</i>, o que si es mejor usar un <i>cacharrímetro</i> o un
<i>cacharrógrafo</i> 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 <i>memes</i> que
generan. No necesito convencer a nadie de que use lo mismo que yo,
porque no es un <i>esto es así y ya está</i>. Cada uno tenemos nuestras
<i>cadaunadas</i>.
</p>
</div>
</div>
<div id="outline-container-orgee565f2" class="outline-2">
<h2 id="orgee565f2">Sobre la privacidad, la estadística y la automatización</h2>
<div class="outline-text-2" id="text-orgee565f2">
<p>
El problema de la privacidad es otra de las <i>religiones</i> para
tecnólogos, o más bien <i>tecnópatas</i>. 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.
</p>

<p>
A este respecto, como ocurre con el <i>software libre</i> 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 <i>paranoico</i>.
</p>

<p>
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 <i>inteligencia artificial</i> y
el que no tiene nada que ocultar. Está claro que el <i>progreso</i> no lo
podemos detener, pero permitid que haga algunas consideraciones. Por
ejemplo, en el futuro la mayor parte del trabajo lo realizarán
robots.
</p>

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

<ol class="org-ol">
<li>Las <i>inteligencias artificiales</i> sólo reconocen los patrones que
tienen como entrada. Si los datos que le pasamos están sesgados,
sus resultados serán sesgados.</li>
<li>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 <i>no tiene que ver</i> con que vivas en un
determinado barrio o seas de determinada condición social, raza,
sexo u otras variables sociales; no te lo da <i>porque lo dice el
sistema de inteligencia artificial</i>; y ahora dime ¿con qué
variables han realizado el entrenamiento de dicha inteligencia?</li>
<li>Los mecanismos de entrenamiento que se utilizan en la <i>inteligencia
artificial</i> sólo tienen en cuenta el valor del acierto y se suelen
desprecian los <i>falsos positivos</i>.</li>
</ol>

<p>
Para entender lo que implican los <i>falsos positivos</i> contra los
<i>falsos negativos</i> voy a poner un ejemplo deportivo. Si estuviéramos
entrenando una <i>inteligencia artificial</i> para seleccionar jugadores de
fútbol para el <i>Barça</i><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>, 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 <i>pesos</i> o <i>valores</i> 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 <i>niveles</i> 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 <i>IA</i> que tiene en cuenta tanto los <i>falsos positivos</i> como
los <i>falsos negativos</i>. Este sería el funcionamiento ideal de toda
<i>IA</i>.
</p>

<p>
Sin embargo, en un banco, si no te dan el crédito porque la <i>IA</i> 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 <i>falsos negativos</i>, se producirá una
mejora en recuperación de fondos suficiente para que los responsables
no se preocupen de los <i>falsos negativos</i>, por qué iban a hacerlo si
han mejorado los beneficios. Además si esos <i>falsos negativos</i> recaen
en colectivos desfavorecidos, o sobre determinados grupos étnicos o
raciales, no se podrá achacar al banco racismo o clasismo: lo dice la
<i>IA</i>, 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.
</p>

<p>
No quiero que nada <i>mío</i>, mis datos, mis acciones, mis fotos o lo que
sea que esté relacionado conmigo se utilice para entrenar
<i>inteligencias artificiales</i> 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.
</p>
</div>
</div>
<div id="outline-container-org7aa339f" class="outline-2">
<h2 id="org7aa339f">Conclusiones</h2>
<div class="outline-text-2" id="text-org7aa339f">
<p>
Quien ha intentado mandarme <i>avispillas</i>, ya sabe que uso <i>Emacs</i>
habiendo sido y siendo usuario de <i>vim</i>, sé cuáles son las ventajas y
los inconvenientes de ambos y utilizo los dos. Uso más <i>Emacs</i> que
<i>vim</i>, pero uso los dos. Depende de para qué.
</p>

<p>
Algunos recién llegados al <i>software libre</i> vienen cometiendo los
mismos <i>errores</i> que cometí yo cuando empecé con <i>GNU/Linux</i> allá por
1998-1999. A éstos les digo que la arrogancia no es ninguna
característica deseable que venga con el <i>software</i>, es una condición
humana, ni mejora ni populariza la herramienta. Recuerda siempre que
el ego es directamente proporcional a la hostia que te mereces<sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Los <i>liberales</i> aún no se han dado cuenta, pero el
<i>neoliberalismo</i> ha fracasado.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Las cuatro: libertad para usarlo, libertad para estudiarlo,
libertad para modificarlo y también para distribuirlo.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Y no tienen por qué hacerlo. 
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Por poner un ejemplo. 
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
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.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/blog/index.html">blog</a> <a href="/tags/software-libre/index.html">software-libre</a> <a href="/tags/ética/index.html">ética</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[blog]]></category>
  <category><![CDATA[software-libre]]></category>
  <category><![CDATA[ética]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2021/01/02/propositos-y-despropositos.html</link>
  <pubDate>Sat, 02 Jan 2021 09:29:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[La venonta jaro]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-12-28</div>
<p>
Kelkaj tagoj antaŭe mi publikigis miajn intencojn por la venonta jaro
per la hispana. Tiu ĉi artikolo estas la rezulto de la sama afero, sed
esperante. Ĉi tiu lasta jaro 2020 estis stranga kaj mi bezonas rigardi
la venontan iluzie, espere kaj entuziasme. Do, mi skribas per ĉi tiu
artikolo, kaj ĝia frato per la hispana, kiuj projektoj mi havas por la
jaro, kiu baldaŭ komencos.
</p>
<div id="outline-container-org34db5ed" class="outline-2">
<h2 id="org34db5ed">Esperanto</h2>
<div class="outline-text-2" id="text-org34db5ed">
<p>
Tempo antaŭe mi promesis skribi pli per <i>Esperanto</i> en ĉi tiu <i>blogo</i>.
Kaj mi estas faranta tion: la klopodo por pensi esperante plibonigas
mian uzadon de la lingvo. Ankaŭ mi volas pli legi esperante.  <a href="https://notxor.nueva-actitud.org/2020/12/13/krei-epub-arhxivon.html">Mi jam
rakontis, kiel mi kreis <code>epub</code> arĥivojn pro tio</a>. Poste mi pensis se
estos taŭga krei <i>bit-bliotekon</i> por ke aliaj esperantistoj povos
elŝuti miajn librojn. Nu bone, la libroj ne estas miaj, mi nur faris
la <code>epub</code> version. Mi pensis ne nur meti miajn librojn (tiujn, kiujn
mi faris por elektronika versio), ankaŭ mi havas kelkaj el ili
eldonita de aliaj, kaj eble mi povas retrovi la ligilon, kie mi
elŝutis ilin.
</p>

<p>
Mi pensas ankaŭ pro la aŭtoraj rajtoj de la verkistoj, la tradukistoj
kaj la eldonistoj.  Fari elektronikan eldonon por mia propra uzado
estas unu afero, kaj alia disdoni ĝin.  Sed la leĝoj en diversaj
landoj estas ankaŭ diversaj.  En mia lando, mi pensas tion, ke la
eldono sen <i>profita intenco</i> estas permesata, kaj mi ne intencas vendi
la librojn, sed meti ilin por direkta elŝutado sen page.  Ankaŭ mi
serĉos, kaj ligos, kien oni povas aĉeti la libron papere aŭ alian
eldonon de la sama enhavo, mencianta ĉiam kiuj havas la rajtojn pri
kopio.
</p>

<p>
Mi ne havas multajn librojn, ankaŭ mi povas fari statikan paĝon, per
listo de titoloj kaj kovriloj, de ligiloj al dosierojn por elŝuti.  Se
poste, la kvanto kreskos eble mi faros serĉilon por trovi libron en
ĝi.  Se kelkaj el la legantoj pensas, ke tio estas kontraŭleĝa diru al
mi kaj mi rifuzos la projekton.
</p>
</div>
</div>
<div id="outline-container-org1127cfa" class="outline-2">
<h2 id="org1127cfa">Preventa plano</h2>
<div class="outline-text-2" id="text-org1127cfa">
<p>
Kiel kelkaj el vi scias, mi kunlaboras kun Asocio PICA<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. Tiu
pasanta jaro 2020 mi komencis fari <i>preventa plano</i> por batali la
ĉikanadon en la lernejoj kaj rete. Mi komencis sola la laboron kaj mi
intencas daŭrigi tiun laboron.
</p>

<p>
Tiu plano konsistas, kiel multaj el aliaj planoj, kutime prezentas
historion al infanoj, fiksante kelkaj valoroj aŭ taŭgaj pensmanieroj
kaj poste labori ilin ĉe klaso kun la instruisto. Kutime, tiuj
historioj estas prezentataj kiel rakontoj, videoj, <i>komiksoj</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.
Mia plano pensas pli interagi kun la infanoj proponanta historio sed
per <i>MUD</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>.
</p>

<p>
Kiam mi prezentis ĉi tiun projekton <a href="https://notxor.nueva-actitud.org/2020/12/27/declaracion-de-intenciones.html">en sama artikolon per la hispana</a>
kelkaj el la legantoj, precipe programistoj, oferis sin por kunlabori
en la projekto precipe, kiel programistoj.
</p>

<dl class="org-dl">
<dt><b>Kion mi jam havas?</b></dt><dd>Mi jam faris <i>malneton</i> de la plano, kun
formularoj por akiri informojn kaj la tuta projekto. Ankaŭ mi havas
<a href="https://codeberg.org/Notxor/erlmud">funkciantan prototipon de la <i>MUD</i></a>, sed ankaŭ sen historio nek lokoj
nek roluloj.</dd>

<dt><b>Kio mankas al mi?</b></dt><dd>Multaj aferoj. Mi devas verki la historiojn
de serĉado por kiam la infanoj eniros la <i>MUD</i>.  Interfaca retpaĝo
por la diversaj iloj, kiuj interagos en la plano. Ankaŭ mankas la
iloj por ke la instruistoj taksos la socian atmosferon de lia klaso.
Ankaŭ la statistikaj iloj bezonataj por taksi la efikon de la
planon, ktp.</dd>

<dt><b>Kion mi bezonas?</b></dt><dd>Ne nur programistoj. Ankaŭ mi bezonas, ke la
ilojn estos agrablaj por la uzantoj, simplaj kaj belaj. Tiel
agrablaj kiel mi povos. Mi pensas ke tiun ĉi venontan jaron ne
sufiĉos por finigi la planon kaj unue mi devas konkeri kelkajn
aliajn faciligoj: datumbazo, servilo... (<i>mono</i> por pagi tion). Sed
mi devas kompletigi paŝon post paŝo.</dd>

<dt><b>Kion minimune?</b></dt><dd>Kiel mi antaŭ diris, mi ne pensas, ke mi estos
kapabla por finigi la tutan planon dum ĉi tiu venonta jaro. Do, mi
pensas, la celo atingonta estas kompletigi la <i>MUD</i> kun sia retpaĝa
interfaco kaj, almenaŭ, kvar historiaj serĉadoj (<i>quest</i>) por la
infanoj. Se ne enmetitaj en la <i>MUD</i>, almenaŭ, finigitaj la
scenaroj.</dd>

<dt><b>Kion mi devas lerni?</b></dt><dd>fari tiujn laborojn bezonas intensa
lernado por mi. Mi bezonas pli lerni <code>erlang</code>, precipe <a href="https://github.com/ninenines/cowboy">la uzado de
<i>cowboy</i></a>. Ankaŭ por la verkado de la scenaroj mi bezonas pli lerni
ilojn taŭgajn. Verki tiajn interagajn historiojn estas pli malfacila
tasko ol verki linian rakonton; do, mi bezonas verki per interagaj
iloj. Eble kiel <i>libroludo</i> eble kiel <i>interaga aventuro</i>. Por
<i>libroludo</i> mi povas uzi ilojn tiel, kiel <a href="https://github.com/idmillington/undum">undum</a>, <a href="http://twinery.org/">twine</a>, ktp. (kiujn
mi ne konas). Por <i>interaga aventuro</i> mi pensas pri iloj tiel, kiel
<a href="https://www.tads.org/"><i>TADS</i></a>, <a href="https://github.com/komoku/aetheria"><i>AGE</i></a> aŭ aliaj (kiujn mi jam konas, sed mi devas
rememorigi). Ambaŭ manieroj havas avantaĝojn kaj malavantaĝojn:

<ul class="org-ul">
<li><i>Libroludo</i>: estas malpli interaga, sed pli <i>literatura</i>. Oni
povas rakonti historion pli detala por priskribi plenan mondon
imagan, pero plena informo.</li>
<li><i>interaga aventuro</i>: estas pli interaga kaj dinamika sed laciganta
se havas troajn detalojn en la priskriboj. Do la informa
alportanta al ludanto estas malpli detala. Ankaŭ la interparolado
kun artifikaj roloj estas ne naturaj kaj ili povas fari rezigni la
ludantojn.</li>
</ul></dd>
</dl>
</div>
</div>
<div id="outline-container-orge36c475" class="outline-2">
<h2 id="orge36c475">Konkludo</h2>
<div class="outline-text-2" id="text-orge36c475">
<p>
Bone mi konscias ke miaj projektoj ne estas tro interesaj por la
plimultoj, kiuj povas legi tion. Ĉar ili estas personaj kaj, eble, mi
havas jarojn de laboro por finigi ilin. Miaj projektoj kutime serĉas
la flankon kreivan, socian kaj kulturan.
</p>

<p>
Tiel la <i>bit-blioteko</i> kiel la <i>preventa plano</i>, estas miaj precipaj
planoj. Inter ili mi bezonos lerni multajn aferojn, krei ilojn, verki
historiojn (mi promesas traduki la historiojn ankaŭ al Esperanto). Do,
mi jam malhavos liberan tempon por la venonta jaro, kaj ankaŭ mi
promesas rakonti tiujn laborojn en ĉi tiu <i>blogo</i>, kiu estas alia
tasko.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Protección de la Infancia Contra el Abuso</i> aŭ <i>Protekto de
Infaneco Kontraŭ Perforto</i>... sed <i>abuso</i> ne estas nur <i>perforto</i> en
la hispana, ankaŭ <i>misuzo</i>, <i>trouzo</i>, <i>ĉikanado</i>, ktp.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Bild-rakontoj. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Multi-User Dungeon</i> sed ankaŭ mi vidis ĝin tiel, kiel
<i>Multi-User Dimension</i> aŭ <i>Multi-User Domain</i>.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/blog/index.html">blog</a> <a href="/tags/esperanto/index.html">esperanto</a> ]]></description>
  <category><![CDATA[blog]]></category>
  <category><![CDATA[esperanto]]></category>
  <link>https://notxor.nueva-actitud.org/2020/12/28/la-venonta-jaro.html</link>
  <pubDate>Mon, 28 Dec 2020 09:28:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Declaración de intenciones]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-12-27</div>
<p>
Acaba un año un tanto raro. Es curioso que sobrándole calificativos yo
no sepa muy bien cuál usar para definir en una palabra lo que ha sido
el 2020. El caso es que ya lo tenemos casi acabado y sólo nos queda
mirar hacia el futuro y ver qué podemos ir haciendo para mejorar lo
que hemos hecho éste último año. En esas me encuentro ahora mismo y
con ese propósito vengo a hacer mi lista de proyectos para
el 2021. Este es el momento de plantearme a qué quiero dedicar mi
tiempo este año que viene y esto es lo que he pensado.
</p>
<div id="outline-container-orgff7c1f6" class="outline-2">
<h2 id="orgff7c1f6">Proyectos</h2>
<div class="outline-text-2" id="text-orgff7c1f6">
</div>
<div id="outline-container-org28a50cf" class="outline-3">
<h3 id="org28a50cf">Plan de prevención</h3>
<div class="outline-text-3" id="text-org28a50cf">
<p>
Como sabéis muchos, colaboro en la Asociación PICA<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. Este año
pasado comencé un proyecto que está en el aire actualmente. La idea es
hacer un <i>Programa de Prevención del <b>acoso escolar</b> de PICA</i>.  Las
distintas partes en que lo divido en realidad se pueden considerar
<i>proyectos completos</i>.  Muchos programas de prevención proponen
actividades <i>lúdico-culturales</i> como leer un cómic o un cuento, ver un
vídeo o una película y luego trabajar sobre los valores y los
distintos aspectos que la historia ha presentado. Yo propongo algo más
interactivo: un <i>MUD</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. Básicamente es lo mismo, pero yo creo que
mejor, pues en un <i>MUD</i> se pueden dar interacciones entre los chavales
y monitorizar sus acciones y reacciones para luego trabajarlas en el
aula. Y realizarlo todo en un espacio de juego <i>seguro</i> para los
niños, que les fomente la imaginación y, por otro lado, fomente la
lectura.  Pero voy por partes:
</p>

<dl class="org-dl">
<dt><b>¿Qué tengo hecho hasta ahora?</b></dt><dd>Tengo elaborados un borrador del
plan, con algunos formularios de recogida de datos y el
planteamiento del programa completo. También tengo funcionando lo
que sería un prototipo del <i>MUD</i> en <code>erlang</code>.</dd>

<dt><b>¿Qué me falta?</b></dt><dd>Muchas cosas. Elaborar las historias o búsquedas
que se van a proponer a los alumnos cuando entren al <i>MUD</i>. Una
interface <i>web</i> funcional desde cualquier sistema operativo a través
de un navegador, para que no tengan que instalar nada.  Útiles para
que los profesores puedan evaluar el clima social y el posible abuso
en su aula. El aparato estadístico que compruebe si ha habido
mejoras en el grupo después de poner en práctica el plan.</dd>

<dt><b>¿Qué necesito?</b></dt><dd>Básicamente hacer todo el aparato <i>web</i> habitual
trabajando con <i>websockets</i> para las distintas herramientas, bases
de datos y demás complementos que se desarrollen. Y, aunque no creo
que me dé tiempo a terminar todo este año, si fuera así, necesitaré
también un servidor donde hacer pruebas (y por tanto: <i>pasta</i>).</dd>

<dt><b>¿Cuáles son los mínimos?</b></dt><dd>Todo eso es mucho trabajo y seguramente
una sola persona, especialmente tan torpe como yo, no pueda concluir
todo lo que hay que hacer en un año. Así que me he fijado unos
mínimos con los que me conformaría si no puedo alcanzar los máximos:
una capa <i>web</i> para el prototipo de <i>MUD</i> y, que al menos, cuente
con cuatro guiones de <i>quest</i> que se puedan proponer a los alumnos.</dd>

<dt><b>¿Qué tengo que aprender?</b></dt><dd>Básicamente este año tengo que seguir
aprendiendo <code>erlang</code>, especialmente <a href="https://github.com/ninenines/cowboy">cómo funciona <i>cowboy</i></a> y también
tengo que aprender ─o profundizar─ otras herramientas para los
guiones. Puesto que no me sirve una historia lineal, para hacer un
guión de un <i>quest</i>, he pensado escribir los guiones con
herramientas interactivas, tipo <i>librojuego</i>, como <a href="https://github.com/idmillington/undum">undum</a>, <a href="http://twinery.org/">twine</a> o
similares; o tipo <i>aventura conversacional</i>, como <a href="https://www.tads.org/"><i>TADS</i></a>, <a href="https://github.com/komoku/aetheria"><i>AGE</i></a> o
similares (que ya conozco y he utilizado, pero que tendría que
retomar de nuevo). Supongo que al final utilizaré lo que más cómodo
me resulte para realizar el guión. Pero aún tengo que analizar
algunos <i>pros</i> y <i>contras</i>:

<ul class="org-ul">
<li><i>Librojuego</i>: permite menos interacción pero es más <i>literario</i>,
puedes contar una historia más llena de detalles para <i>imaginar</i>
un mundo completo con mucha más información.</li>
<li><i>Conversacional</i>: más interactiva y dinámica, pero dificulta las
descripciones detalladas del mundo. Al ser menos <i>literaria</i>
también está el escollo de las conversaciones con personajes
virtuales, que es donde más información se puede dar al jugador y
que suelen resultar muy poco naturales.</li>
</ul></dd>
</dl>
</div>
</div>
<div id="outline-container-orgd6b437e" class="outline-3">
<h3 id="orgd6b437e">Esperanto</h3>
<div class="outline-text-3" id="text-orgd6b437e">
<p>
Como sabéis también le dedico tiempo al mundo del <i>Esperanto</i>, incluso
hace unos meses me propuse escribir más en esta lengua con el ánimo de
mantener el nivel alcanzado y mejorarlo mediante la lectura. Este año
pasado no se han podido hacer los habituales encuentros de los martes
por la tarde de La Frateco de Zaragoza y me he dado cuenta que mi
fluidez ha perdido bastante. Incluso cuando leo tengo que consultar
palabras en el diccionario que sé que conozco pero que la falta de uso
ha comenzado a borrar de mi memoria.
</p>

<p>
Me gusta leer y me gusta hacerlo en mi rincón del sofá preferido, con
mi <i>ebook</i> o mi <i>tablet</i>. Los fichero <code>pdf</code> que encuentro por ahí
suelen ser bastante incómodos de trabajar: tienen su ancho fijo y no
los puedes sacar de ahí. Tienen todos los inconvenientes del papel y
ninguna de sus ventajas. Por eso prefiero la flexibilidad de los
<code>epub</code> y cómo se adaptan al dispositivo donde los lees. Y por eso,
también, dedico parte de mi tiempo a convertir los libros que
encuentro en <code>pdf</code> a <code>epub</code> y tengo ya una lista de títulos
convertidos.
</p>

<p>
En este sentido, mi intención es poner todos los libros que tengo en
<code>epub</code>, tanto los que he editado yo, como los que he ido encontrando
por ahí en una especie de <i>bit-blioteca</i> donde la gente interesada los
pueda descargar de forma gratuita, sin <i>DRM</i> y sin ánimo de lucro.
</p>

<p>
Puesto que son pocos libros, la primera versión será una página
estática con portadas y títulos donde pinchar y descargar. Pero si
creciera más allá de lo esperado, es una <i>bit-blioteca</i> personal y no
debería ser necesario, le haré un <i>buscador</i> de títulos y autores.
</p>
</div>
</div>
</div>
<div id="outline-container-orga72aa4f" class="outline-2">
<h2 id="orga72aa4f">Conclusiones</h2>
<div class="outline-text-2" id="text-orga72aa4f">
<p>
Con esos proyectos, creo que tengo faena para entretenerme años. Como
veis, mis ideas no paran de bullir y crecer. Ya me gustaría que fueran
ideas más productivas económicamente para, entre otras cosas, poder
pagar la hipoteca haciendo trabajos que me gusta hacer y con los que
aprendo, en los que el componente creativo, el cultural o el social
tienen un peso específico.  Pero no soy nada pragmático, ya lo sabéis:
si hay que aprender un lenguaje de programación, me llaman la atención
lenguajes alejados de los que pide el mercado. Si hay que hacer algún
juego, lo hago <i>conversacional</i> que no tampoco tiene mercado. Todo mi
poco talento siempre empleado donde no se gana dinero.
</p>

<p>
Aunque no está especificado en los proyectos anteriores, no hace falta
decir que mi idea es continuar contándoos mis cosas en este <i>blog</i>
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Proteccdión a la Infancia contra el Abuso</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Multi-User Dungeon</i> aunque también lo he visto referido como
<i>Multi-User Dimension</i> o <i>Multi-User Domain</i>.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/blog/index.html">blog</a> <a href="/tags/proyectos/index.html">proyectos</a> ]]></description>
  <category><![CDATA[blog]]></category>
  <category><![CDATA[proyectos]]></category>
  <link>https://notxor.nueva-actitud.org/2020/12/27/declaracion-de-intenciones.html</link>
  <pubDate>Sun, 27 Dec 2020 08:11:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[lisp, slime y emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-12-23</div>
<p>
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 <i>lisp</i>. Dicho así
en genérico sin especificar ninguno de sus <i>sabores</i>. Por las dudas
que me planteado, tampoco tiene muy claro si tirar por <i>lisp</i> o seguir
por <i>scheme</i>, y para eso yo no tengo respuesta, porque depende de los
gustos de cada quien.  Él ya ha estado mirando algo de <i>scheme</i>,
aunque se declara <i>novato</i>, pero le interesa también saber algo más
sobre <i>lisp</i> para comparar y decidir. Intentaré contestar lo mejor que
pueda.
</p>
<div id="outline-container-orgaeb4b1f" class="outline-2">
<h2 id="orgaeb4b1f">Lisp</h2>
<div class="outline-text-2" id="text-orgaeb4b1f">
<p>
<i>Lisp</i> no es un único lenguaje o compilador. Ya hay toda una familia
de lenguajes como son <i>scheme</i>, <i>clojure</i>, <i>lisp</i>... Además de estos
grandes grupos con distintas características, cada uno tiene distintos
compiladores o sistemas. Entre los <code>scheme</code> podemos encontrar <code>guile</code>
o <code>chicken</code>, por ejemplo, entre los <code>lisp</code> tienes para elegir varios
<code>common-lisp</code>, <code>emacs-lisp</code> y otros. Además, entre los <code>common-lisp</code>
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 <code>SBCL</code><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>

<p>
Las diferencias fundamentales entre <code>scheme</code> y <code>lisp</code> son que <code>scheme</code>
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 <i>case sensitive</i>
mientras que <code>lisp</code> no diferencia entre mayúsculas y minúsculas. En
cambio, tiene dos tablas de asignación y por tanto, tienes que emplear
las instrucciones <code>defvar</code> y <code>defun</code>, 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.
</p>

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

<div class="org-src-container">
<pre class="src src-shell">sudo zypper install sbcl
</pre>
</div>

<p>
En el caso de las derivadas de <i>Debian</i> supongo que la instrucción
será alto estilo <code>apt-get install sbcl</code>. Comprueba el nombre del
paquete en cuestión.
</p>
</div>
<div id="outline-container-org9d20be9" class="outline-3">
<h3 id="org9d20be9">Libros</h3>
<div class="outline-text-3" id="text-org9d20be9">
<p>
Para la documentación que pides te recomiendo dos libros que puedes
encontrar por Internet:
</p>

<ul class="org-ul">
<li><a href="http://www.gigamonkeys.com/book/">Practical Common Lisp</a> de <i>Peter Seibel</i></li>
<li><a href="http://www.paulgraham.com/onlisp.html">On Lisp</a> de <i>Paul Graham</i></li>
</ul>

<p>
Además, si instalas <code>sbcl</code>, al menos en <code>OpenSuse</code>, viene con un
manual <code>info</code> que se integra perfectamente con el sistema de ayuda de
<i>Emacs</i>, así que allí puedes encontrar también más información sobre
cómo funciona <code>sbcl</code> de la que puedo dar yo en un pequeño artículo.
</p>
</div>
</div>
<div id="outline-container-org688ce4f" class="outline-3">
<h3 id="org688ce4f">Librerías de <code>quicklisp</code></h3>
<div class="outline-text-3" id="text-org688ce4f">
<p>
Si ya estás trabajando con <i>Emacs</i>, ya conocerás su sistema de
paquetes y lo tendrás configurado. Para <code>lisp</code> existe algo similar que
se llama <code>quicklisp</code>. Si ya tienes instalado <code>sbcl</code> en el sistema, lo
único que tienes que hacer es lo siguiente:
</p>

<div class="org-src-container">
<pre class="src src-shell">curl -O https://beta.quicklisp.org/quicklisp.lisp
sbcl --load quicklisp.lisp --eval <span style="color: #f1fa8c;">'(quicklisp-quickstart:install)'</span> --quit
sbcl --load ~/quicklisp/setup.lisp --eval <span style="color: #f1fa8c;">'(ql:add-to-init-file)'</span> --quit
</pre>
</div>

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

<p>
Esto es totalmente optativo, pero si vas a desarrollar con <code>lisp</code> 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.
</p>
</div>
</div>
</div>
<div id="outline-container-org5ffad3a" class="outline-2">
<h2 id="org5ffad3a">Slime y otros paquetes de <i>Emacs</i></h2>
<div class="outline-text-2" id="text-org5ffad3a">
<p>
<code>SLIME</code><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> es una herramienta de <i>Emacs</i> que facilita la vida a los
programadores de <code>lisp</code>. Instalarlo es tan fácil como cualquier otro
paquete de nuestro editor favorito:
</p>

<pre class="example" id="orgb52b59c">
package-install RET slime
</pre>

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

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> inferior-lisp-program <span style="color: #f1fa8c;">"/usr/bin/sbcl"</span>)
</pre>
</div>

<p>
Comprueba que en tu caso el <i>path</i> coincide antes de hacer el
<i>corta-pega</i>.
</p>

<p>
Si lo hemos instalado y configurado, podremos utilizarlo directamente
si cargamos de nuevo el fichero de configuración con <code>load-file</code> o
bien tras reiniciar <i>Emacs</i>. El paquete proporciona un entorno
interactivo de <code>lisp</code> y funciones que cargan a dicho entrono con el
código que vayamos escribiendo. Nos permite <i>trazar</i> y depurar código,
etc.
</p>
</div>
<div id="outline-container-org3441ff6" class="outline-3">
<h3 id="org3441ff6">El paquete <code>paredit</code></h3>
<div class="outline-text-3" id="text-org3441ff6">
<p>
Dices que, en <code>scheme</code>, te atascas con tanto paréntesis y pierdes la
cuenta de los que abres y los que debes cerrar. Lo siento, pero en
<code>lisp</code> 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
<code>show-paren-mode</code>, bien en el apartado <code>custom</code> de tu <code>init.el</code> o que
en cualquier sitio de ese fichero de configuración tengas algo como:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> show-paren-mode t)
</pre>
</div>

<p>
Esa opción lo que hace es mostrar el paréntesis <i>pareja</i> del
paréntesis sobre el que está situado el cursor. Bueno, no <i>sobre</i> 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 <code>hook</code> para los modos
que quieras, o llamando a <code>show-paren-mode</code> cuando lo quieras
activar.
</p>

<p>
Por otro lado, hay otros paquetes que te pueden echar una mano. Por
ejemplo, también uso el paquete <code>paredit</code>. 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 <code>lisp</code>, <code>scheme</code> o
lenguajes similares, aunque nada te impide usarlo siempre.  Lo puedes
activar mediante <code>hooks</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-hook 'emacs-lisp-mode-hook 'enable-paredit-mode)
(add-hook 'lisp-mode-hook 'enable-paredit-mode)
</pre>
</div>

<p>
Recuerda poner el <code>hook</code> para cada uno de los modos, porque la de
<code>lisp-mode-hook</code> no incluye a <code>emacs-lisp-mode-hook</code>. 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 <code>prog-mode-hook</code> y así se
cargaría en todos los modos de programación, que es otra opción
aceptable.
</p>

<p>
Echa un ojo a la lista de paquetes que hay disponibles porque hay
muchos que sirven para destacar los <i>pares</i> 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.
</p>
</div>
</div>
<div id="outline-container-org6a40953" class="outline-3">
<h3 id="org6a40953">Usando <code>slime</code></h3>
<div class="outline-text-3" id="text-org6a40953">
<p>
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:
</p>

<ol class="org-ol">
<li><p>
Abre <i>Emacs</i> y crea un <i>buffer</i> para los ejemplos:
</p>

<pre class="example" id="org10786f7">
C-x C-f ejemplos.lisp
</pre></li>

<li><p>
Escribe el código del primer ejemplo<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">hola-mundo</span> ()
  <span style="color: #6272a4;">"Escribe un mensaje de &#171;&#161;Hola Mundo!&#187;"</span>
  (format t <span style="color: #f1fa8c;">"&#161;Hola mundo!"</span>))
</pre>
</div></li>

<li><p>
Lanza <code>slime</code> con el comando:
</p>

<pre class="example" id="org5263369">
M-x slime
</pre>

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

<li>Evaluamos el código: <code>slime</code> tiene varias funciones de evaluación
de código, en nuestro caso vamos utilizar <code>M-x slime-eval-buffer</code>,
pero también se puede hacer para una función o para una región de
texto seleccionado.</li>

<li><p>
Vuelve al <i>buffer</i> de <code>slime</code> y prueba a ejecutar <code>(hola-mundo)</code>
</p>

<pre class="example" id="orgac8b9ff">
CL-USER&gt; (hola-mundo)
¡Hola mundo!
NIL
CL-USER&gt; _
</pre></li>
</ol>

<p>
Bien ya tienes el sistema funcionando... Ahora a escribir código.
</p>

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

<div class="org-src-container">
<pre class="src src-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">factorial</span> (n)
  <span style="color: #6272a4;">"Calcula el factorial del n&#250;mero n."</span>
  (<span style="color: #ff79c6; font-weight: bold;">if</span> (= n 0)
      1
      (* n (factorial (- n 1)))))
</pre>
</div>

<p>
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 <i>buffer</i> completo con
<code>slime-eval-buffer</code>, como hicimos antes, es posible (seguro) que te
diga que ya existía una función <code>hola-mundo</code> y te lance un <i>warning</i>.
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 <i>warning</i> sitúa
el cursor en cualquier línea de la definición de la función y utiliza
el comando <code>M-x slime-eval-defun</code>. Como ves, era sólo por mostrar otra
función que carga código.  A partir de ese momento, ya estará la
función <code>factorial</code> también disponible en <code>slime</code>:
</p>

<pre class="example" id="org196b31a">
CL-USER&gt; (factorial 6)
720
CL-USER&gt; _
</pre>

<p>
Por darle otra vuelta, prueba a hacer un trazado de la función
<code>factorial</code>, por ejemplo:
</p>

<pre class="example" id="orga2f896f">
CL-USER&gt; (trace factorial)
(FACTORIAL)
CL-USER&gt; (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&gt;
</pre>

<p>
Queda bonito ver cómo se desarrolla ─y desenrrolla─ la llamada a una
función recursiva y lo que va devolviendo.
</p>
</div>
</div>
<div id="outline-container-org84a9e4b" class="outline-3">
<h3 id="org84a9e4b">Paquetes externos</h3>
<div class="outline-text-3" id="text-org84a9e4b">
<p>
Si antes de llegar hasta aquí hiciste la instalación de <code>quicklisp</code> 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, <code>hunchentoot</code> es un servidor <i>web</i> hecho enteramente con
<code>lisp</code> y queremos ponerlo en marcha en nuestro sistema. Vamos por
pasos:
</p>

<ol class="org-ol">
<li>Crea un <i>buffer</i> nuevo con <code>C-x C-f servidor.lisp</code></li>

<li><p>
En ese <i>buffer</i> teclea el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(ql:quickload <span style="color: #f1fa8c;">"hunchentoot"</span>)
(hunchentoot:start (make-instance 'hunchentoot:easy-acceptor <span style="color: #8be9fd; font-style: italic;">:port</span> 6969))
</pre>
</div></li>

<li><p>
Evalúa el código anterior con <code>slime</code>. Después de unos segundos
bajando y preparando paquetes aparecerá el mensaje de que el
servidor está funcionando:
</p>

<pre class="example" id="org233ba94">
To load "hunchentoot":
  Load 1 ASDF system:
    hunchentoot
; Loading "hunchentoot"
.....
</pre></li>
</ol>

<p>
Si apuntamos cualquier navegador a la dirección <code>localhost:6969</code>
obtendremos una ventana como la siguiente:
</p>


<figure id="orgebe2374">
<img src="./imagenes/Captura-pantalla_servidor-lisp.png" alt="Captura-pantalla_servidor-lisp.png">

</figure>

<p>
Y ya vemos cómo de fácil es obtener todo un servidor
</p>
</div>
</div>
</div>
<div id="outline-container-orgc4d6a78" class="outline-2">
<h2 id="orgc4d6a78">Conclusiones</h2>
<div class="outline-text-2" id="text-orgc4d6a78">
<p>
Estas herramientas están hechas para funcionar conjuntamente, puedes
ponerle más cosas: configurarle el modo <code>lsp</code>, o lo que más rabia te
dé, pero esto es lo básico, básico, y un poco más que aporta
<code>quicklisp</code>.
</p>

<p>
Si has utilizado <i>Emacs</i> para trastear con <code>scheme</code> verás que <code>slime</code>
es a <code>lisp</code> lo que <code>geiser</code> es a <code>scheme</code>. No se trabaja de forma
idéntica en ambos, pero sí muy similar. 
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Steel Bank Common Lisp</i> <a href="http://www.sbcl.org">http://www.sbcl.org</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Superior Lisp Interaction Mode for Emacs</i> 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
No esperabas tanta originalidad, seguro. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/lisp/index.html">lisp</a> <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/slime/index.html">slime</a> ]]></description>
  <category><![CDATA[lisp]]></category>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[slime]]></category>
  <link>https://notxor.nueva-actitud.org/2020/12/23/slime-lisp-y-emacs.html</link>
  <pubDate>Wed, 23 Dec 2020 00:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Krei epub arĥivon]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-12-13</div>
<p>
Mi hodiaŭ parolos pri la transformadon de dosiero <code>pdf</code> al dosiero
<code>epub</code> 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 <i>Emacs</i> kaj <i>elisp</i> por kontroli tiun <code>OCR</code>
procezon, kiun ni bezonas por tiuj dosieroj, kiuj enhavas bildajn
skanadojn de teksto. La celo estas konverti nian <code>pdf</code> dosieron farita
de skanitaj bildoj al <code>epub</code> dosieron por pli bone legi en nia
<i>inklibro</i> aŭ tabuleto. Mi laboras per <i>Linukso</i> sed la rezulto estas
sendependa de la operaciumo kiun ni uzas. Mi iomete parolos pri kiuj
programoj mi uzas por tiuj laboroj.
</p>

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

<p>
Ni havas:
</p>


<figure id="org2c45b36">
<img src="./imagenes/Captura-pantalla_pdf.png" alt="Captura-pantalla_pdf.png">

</figure>

<p>
sed ni volas:
</p>


<figure id="org4452c52">
<img src="./imagenes/Captura-pantalla_epub.png" alt="Captura-pantalla_epub.png">

</figure>

<p>
por povi legi tiel:
</p>


<figure id="org62679fe">
<img src="./imagenes/Foto_lector.jpg" alt="Foto_lector.jpg">

</figure>

<p>
Do, ni bezonas kelkajn ilojn por fari nian laboron:
</p>

<ol class="org-ol">
<li>Konvertilo por bildformato: ni uzos la ilon <code>pdfimages</code> kiu prenas
la paĝojn de la <code>pdf</code> kaj skribas en sendependaj bildoj.</li>
<li>OCR ilo: ni uzos <code>tesseract-ocr</code>, kiu permesas traduki per multaj
lingvoj, inter ili <i>Esperanto</i>.</li>
<li><i>Emacs</i> por uzi ĝian skriptan lingvaĵon.</li>
</ol>

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

<p>
Aliflanke ni devas ankaŭ preni la enajn bildojn por la lasta paŝo de
nia procezo.
</p>
<div id="outline-container-orgd8a0f15" class="outline-2">
<h2 id="orgd8a0f15">Konverti dosieron</h2>
<div class="outline-text-2" id="text-orgd8a0f15">
<p>
Mi klarigos kiel mi faras por konverti pezan <code>pdf</code>, farita de skanitaj
bildoj, ĝis atingi sufiĉan bonan <code>epub</code> por legi per mia <i>bitlibro</i>.
Tiu legado estas pli agrabla ol legi la originan <code>pdf</code> per tiu ilo.
La teksto aranĝas al ekrano kaj faciligas bonan sperton de legado.
</p>

<p>
Ni povas fari la laboron mane:
</p>

<ol class="org-ol">
<li><p>
Preni la bildon de la <code>pdf</code> dosiero:
</p>

<div class="org-src-container">
<pre class="src src-shell">pdfimages -png -f 1 -l 10 dosiero.pdf pa&#285;o
</pre>
</div>

<p>
Tiu kreas bildoj de la <code>paĝo-001.png</code> al <code>paĝo-010.png</code>.
</p></li>

<li><p>
Konverti la bildoj en teksto:
</p>

<div class="org-src-container">
<pre class="src src-shell">tesseract -l epo pa&#285;o-001.png pa&#285;o-001
</pre>
</div>

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

<li>Aranĝi ĉiu la dosieroj <code>txt</code> en unu sola dosiero. Pro tiu ni povas
uzi <i>teksredaktilon</i>.</li>
</ol>

<p>
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 <i>Emacs</i>.
</p>
</div>
<div id="outline-container-org052c829" class="outline-3">
<h3 id="org052c829">Kodo</h3>
<div class="outline-text-3" id="text-org052c829">
<p>
Mi skribis la sekvantan kodon por aŭtomatigi la proceson en komandara
dosiero nomita <code>konverti-ocr.el</code>:
</p>


<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">konverti-ocr.el
</span>
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">La variabloj de la procezo.
</span>
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">dosiero</span> <span style="color: #f1fa8c;">""</span>
  <span style="color: #6272a4;">"Variablo kiu enhavas la nomon de la dosiero por konverti."</span>)
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">komenco</span> 0
  <span style="color: #6272a4;">"Pa&#285;a numero kie komencas la procezon."</span>)
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">fino</span> 0
  <span style="color: #6272a4;">"Pa&#285;a numero kie finas la procezon."</span>)
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">lingvo</span> <span style="color: #f1fa8c;">""</span>
  <span style="color: #6272a4;">"Lingvo de la listo `tesseract --listlangs`"</span>)

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">komencu</span> ()
  <span style="color: #6272a4;">"Sar&#285;u la variabloj por la procezo."</span>
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> dosiero (org-entry-get (point) <span style="color: #f1fa8c;">"dosiero"</span>))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> komenco (string-to-number (org-entry-get (point) <span style="color: #f1fa8c;">"de"</span>)))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> fino    (string-to-number (org-entry-get (point) <span style="color: #f1fa8c;">"gxis"</span>)))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> lingvo  (org-entry-get (point) <span style="color: #f1fa8c;">"lingvo"</span>)))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">pritrakti-pa&#285;o</span> (num)
  <span style="color: #6272a4;">"Enmeti la tekston kreata en la /punkto/."</span>
  (message <span style="color: #f1fa8c;">"Konverti pa&#285;on %s"</span> num)
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Habigi la bildon
</span>  (call-process-shell-command (format <span style="color: #f1fa8c;">"pdfimages -png -f %d -l %d %s pa&#285;o"</span> num num dosiero))
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Habigi la tekston
</span>  (call-process-shell-command (format <span style="color: #f1fa8c;">"tesseract -l %s pa&#285;o-000.png temporal"</span> lingvo))
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Enmeti la tekston en la /punkto/
</span>  (insert-file-contents <span style="color: #f1fa8c;">"temporal.txt"</span>)
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Forigi la temapajn dosierojn
</span>  (shell-command <span style="color: #f1fa8c;">"rm pa&#285;o-000.png temporal.txt"</span>))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">pritrakti-ocr</span> ()
  <span style="color: #6272a4;">"Lan&#265;as la taskon por konverti bildan pdf al teksto."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (komencu)       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Establece las variables globales
</span>  (mapc 'pritrakti-pa&#285;o (number-sequence fino komenco -1)))
</pre>
</div>

<p>
Mi preparas la dosieron kie ni enmetos la tekston de la konvertado:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #ff79c6; font-size: 130%; font-weight: bold;">*</span><span style="color: #ff79c6; font-size: 130%; font-weight: bold;"> Prologo</span>
  <span style="color: #87cefa;">:PROPERTIES:</span>
  <span style="color: #f1fa8c;">:de:</span>       <span style="color: #f8f8f2; background-color: #282a36;">20</span>
  <span style="color: #f1fa8c;">:gxis:</span>     <span style="color: #f8f8f2; background-color: #282a36;">34</span>
  <span style="color: #f1fa8c;">:dosiero:</span>  <span style="color: #f8f8f2; background-color: #282a36;">./la-mastro-de-la-ringoj.pdf</span>
  <span style="color: #f1fa8c;">:lingvo:</span>   <span style="color: #f8f8f2; background-color: #282a36;">epo</span>
  <span style="color: #87cefa;">:END:</span>
</pre>
</div>

<p>
Ni devas rimarki ke en la <code>PROPERTIES</code> difinoj ne povas uzi ĉapelitajn
literiojn.
</p>

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

<p>
La rezulton estas:
</p>


<figure id="orgb5c0c97">
<img src="./imagenes/Captura-pantalla_konvertado.png" alt="Captura-pantalla_konvertado.png">

</figure>

<p>
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
<i>Emacs</i> helpas min ĉar oni povas uzi aŭtokorektadon de teksto por
<i>Esperanto</i>. Sed la laboro de purigo neniam finiĝas, kiel ni vidos je
la fino.
</p>

<p>
Kiam la teksto estas sufiĉe purigita (aŭ mi pensas tion) mi konvertas
la dosieron, en nia ekzemplo nomita <code>probo-dosieron.org</code> al <code>html</code>
aranĝo. <i>Emacs</i> faciligas tiun taskon: mi nur devas uzi la komandon
<code>C-c C-e h h</code> kaj ĝi kreos la dosieron <code>probo-dosieon.html</code>. Poste,
tiuj <code>html</code> dosieroj poste estos aranĝitaj en la <code>epub</code> dosiero.
</p>
</div>
</div>
</div>
<div id="outline-container-org01ae57d" class="outline-2">
<h2 id="org01ae57d">Preti fontojn</h2>
<div class="outline-text-2" id="text-org01ae57d">

<figure id="org0ae6688">
<img src="./imagenes/Captura-pantalla_font-forge.png" alt="Captura-pantalla_font-forge.png">

</figure>

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

<p>
La tutaj ekzemploj de ĉi tiu artikolo estas prenataj de mia laboro por
aranĝi <i>la mastro de la ringoj</i> kiel <code>epub</code> dosiero por plezure legi
per mia bitlibro. Por tiu projekto mi serĉis literojn ĉe
<a href="https://www.dafont.com">https://www.dafont.com</a> 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.
</p>

<p>
Do, mi elektis miajn plej ŝatatajn literojn kaj uzis <code>fontforge</code> 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.
</p>


<figure id="org6a5fe57">
<img src="./imagenes/Captura-pantalla_titulo-parte.png" alt="Captura-pantalla_titulo-parte.png">

</figure>

<p>
aŭ
</p>


<figure id="org8c0b6bb">
<img src="./imagenes/Captura-pantalla_titulo-libro.png" alt="Captura-pantalla_titulo-libro.png">

</figure>

<p>
aŭ
</p>


<figure id="org1bef1bc">
<img src="./imagenes/Captura-pantalla_literoj.png" alt="Captura-pantalla_literoj.png">

</figure>

<p>
Por tiuj paĝoj estas pli grava nia laboro per <code>css</code> kaj <code>html</code> ol per
la fontoj. Pro tio ni atingas la lastan laboron por krei nian
bitlibron.
</p>
</div>
</div>
<div id="outline-container-org47da62d" class="outline-2">
<h2 id="org47da62d">Aranĝi dosieron</h2>
<div class="outline-text-2" id="text-org47da62d">

<figure id="org73767a6">
<img src="./imagenes/Captura-pantalla_sigil.png" alt="Captura-pantalla_sigil.png">

</figure>

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

<p>
Antaŭ, kiam ni konvertis la bildojn al tekstoj, ni kreis la diversajn
dosierojn <code>html</code>. Nun ni devas porti ene ĉi tiujn dosierojn al
<code>epub</code>.  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.
</p>

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

<p>
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.
</p>
</div>
</div>
<div id="outline-container-orgd7e8648" class="outline-2">
<h2 id="orgd7e8648">Konkludo</h2>
<div class="outline-text-2" id="text-orgd7e8648">
<p>
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.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/sigil/index.html">sigil</a> <a href="/tags/epub/index.html">epub</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[sigil]]></category>
  <category><![CDATA[epub]]></category>
  <link>https://notxor.nueva-actitud.org/2020/12/13/krei-epub-arhxivon.html</link>
  <pubDate>Sun, 13 Dec 2020 10:34:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Compilando erlang en OpenSuse]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-12-12</div>
<p>
A veces las cosas en las <i>rolling releases</i> se rompen un poco.  Me ha
pasado con el paquete de <code>erlang</code> desde que lo estoy usando. Con el
agravante de ser un paquete poco utilizado por el público y, parece
ser, algo falto de mantenimiento.
</p>

<p>
El caso es que hace un tiempo ya me pasó al ir a lanzar el <code>debugger</code>
que me apareció un misterioso mensaje de error en el que decía, algo
así como que no se podían encontrar los <i>drivers wx</i>... <i>hmmm, si está
todos instalado, como antes</i>, pensé. Después de eso, estuve un tiempo
soportando dicho error cuando intentaba lanzar cualquiera de las
aplicaciones gráficas que vienen con <code>erlang</code>.  Tras una actualización
de <i>OpenSuse Tumbleweed</i>, las cosas se arreglaron y achaqué los fallos
a algún problema con los paquetes y no le presté más atención. Seguí
trabando con <code>erlang</code> con normalidad hasta que volvió a romperse por
el mismo sitio. <i>Vaya, ¡tengo que depurar el error del raytracer!</i>
</p>

<p>
Comencé a investigar qué pasaba, miré en los <i>issues</i> de <i>OpenSuse</i>,
no encontré ninguno que se refiriera a lo que me estaba pasando a mí.
Pero sí encontré un problema parecido en otras distribuciones. <i>Un
hilo del que tirar</i>, pensé. Después de haberlo mirado bien, parece ser
que la conclusión era que la librería <code>wx_erlang</code> estaba compilada con
un compilador<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> diferente al que estaba destinada. <i>¿Y si tengo
instalados paquetes de dos versiones distintas?</i> Lo comprobé y no: mis
paquetes eran todos para la misma versión y del mismo proveedor...
<i>¿Cómo puedo probarlo?</i> Pues compilando mi librería <code>wx_erlang</code>...  <i>a
ver, que la busco</i>. Vaya, está junto a todo el código de <code>erlang</code>.
Tenía tres opciones: separarlo, bajar todo el código o me esperarme a
que se arregle con la siguiente actualización.
<i>Nah, me bajo todo, compilo <code>erlang</code>; que ya le tengo ganas y además
me da para un artículo del blog</i>. Y aquí me tenéis escribiendo un
artículo que demuestra lo <i>friki</i> que puedo llegar a ser.
</p>

<p>
Pues eso: <i>¡manos a la obra!</i>.
</p>
<div id="outline-container-org9a3f9b8" class="outline-2">
<h2 id="org9a3f9b8">Compilando</h2>
<div class="outline-text-2" id="text-org9a3f9b8">
<p>
Para compilar código fuente, necesitamos el código fuente<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. En la
página <i>web</i> de <code>erlang</code> nos sugieren descargar o bien un fichero
<code>.zip</code> (o <code>.tar.gz</code>, según nuestro sistema operativo), o bien
descargarlo de su repositorio en <code>github</code>. Yo opté por esta última.
Supongo que bajar el código en un paquete <code>zip</code> o <code>tar.gz</code> debe ser
similar a la hora de compilar. En todo caso, no está de más que le
echéis un ojo a los clásicos <code>README</code> e <code>INSTALL</code> por si acaso.
</p>

<div class="org-src-container">
<pre class="src src-shell">git clone https://github.com/erlang/otp.git
</pre>
</div>

<p>
Supongo que si te estás leyendo esto es porque piensas ahorrarte la
árida lectura de la documentación que viene junto con el código, pero
ya te digo que sólo podrás hacerlo si todo va bien. Es decir, si
sigues estos pasos, que son el resumen de los que yo he hecho, después
de limpiar y depurar algunos errores que me encontré. Por ejemplo,
cosas tan básicas como las herramientas que necesitas para compilar:
</p>

<p>
Las <b>dependencias</b> para la compilación son:
</p>

<ul class="org-ul">
<li>GNU <code>make</code>.</li>
<li><code>autoconf</code> para generar el <code>Makefile</code>.</li>
<li>Un compilador de <code>C</code>: bien el <i>GNU C Compiler</i> <code>gcc</code> o el compilador
para <i>LLVM</i>, <code>clang</code>.</li>
<li><code>Perl 5</code></li>
<li>GNU <code>m4</code>: Si se activa el soporte para código nativo <code>HiPE</code>. Se
puede desactivar <code>HiPE</code> utilizando el <i>flag</i> <code>--disable-hipe</code> al
configurar la compilación.</li>
<li><code>ncurses</code>, <code>termcap</code>, o <code>termlib</code>: Se necesitan las cabeceras y
las librerías que se conocen generalmente como <code>ncurses-devel</code>. Se
puede eliminar esta dependencia utilizando el <i>flag</i>
<code>--without-termcap</code> al configurar la compilación, pero eso
desactivará las facilidades de edición de línea en el <code>shell</code> de
<code>erlang</code>.</li>
<li><code>sed</code>: El <i>Stream Editor</i> para que los <i>scripts</i> puedan modificar
texto básico.</li>
<li><code>wxWidgets</code>:  también el paquete <code>dev</code>, las cabeceras de desarrollo
que proporcionan la herramienta <code>wx-config</code>. Esto es necesario para
compilar las herramientas gráficas, como el <code>observer</code> o el
<code>debugger</code>.</li>
</ul>

<p>
Si lo tienes instalado ya para los siguientes pasos, mejor.  Yo tuve
que realizar varias veces el <code>configure</code> porque también soy un
<i>cagaprisas</i> y no me leí bien las dependencias<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>.  Una vez
satisfechas las necesidades previas vamos al tajo.
</p>

<p>
Otro escollo que saltar: Establecer el directorio base.  Resulta que
los <i>scripts</i> intentan encontrar dónde está el código fuente a través
de la variable <code>ERL_TOP</code>. También viene en la documentación, pero me
di cuenta después de haber recibido algún que otro error incompresible
intentando compilar. Así que recapitulamos: Hemos bajado el código con
<code>git</code> y vamos a compilar.
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #8be9fd; font-style: italic;">cd</span> opt
<span style="color: #8be9fd; font-style: italic;">export</span> <span style="color: #f8f8f2; font-weight: bold;">ERL_TOP</span>=<span style="color: #fa8072;">`pwd`</span>
</pre>
</div>

<p>
Primero entramos en el directorio donde se ha descargado el código y
establecemos una variable de entorno para no tener sobresaltos cuando
el proceso necesita buscar el código en algún sitio.
</p>

<p>
Hasta aquí no hay mucho más que contar, todavía no deberías haber
encontrado ningún problema. Ahora al iniciar la compilación es cuando
nuestro sistema puede presentar algún problema para completar el
proceso. El primero es que... <i>¡No hay <code>makefile</code>!</i>. A ver,
tranquilidad, había que hacer lo del <code>configure</code>... a no, que no hay
ningún fichero <code>configure</code> tampoco, hay que generarlo:
</p>

<div class="org-src-container">
<pre class="src src-shell">./otp_build autoconf
./cofigure --help
</pre>
</div>

<p>
La segunda línea de ese bloque de código es absolutamente
discrecional, yo la aconsejo para que veáis todas las opciones con que
se puede compilar <code>erlang</code>, con todas sus librerías y herramientas o
sólo la máquina virtual o <code>HiPE</code> o etc. La primera línea es la
importante y la que nos genera el fichero <code>configure</code> para continuar
el proceso.
</p>

<div class="org-src-container">
<pre class="src src-shell">./configure --prefix=~/opt
</pre>
</div>

<p>
En mi caso, puesto que es una compilación para mí sólo me tengo creado
un directorio local, dentro de mi <code>home</code> donde voy metiendo esos
paquetes que me voy compilando para mí. Dentro de ese directorio
<code>~/opt</code> están sus correspondientes directorios <code>bin</code>, <code>share</code>, <code>lib</code>,
etc. Además, en mi <code>.bashrc</code> ya tengo añadido el <code>path</code> a <code>~/opt/bin/</code>
y por tanto no tengo que hacer nada más. Es posible que tú lo quieras
meter en <code>/local</code> o en <code>/usr/local</code>, que cada uno tenemos nuestras
<i>cadaunadas</i>.
</p>

<p>
En todo caso, si todas las dependencias están bien y ese paso no
arroja ningún error irresoluble nos queda compilar:
</p>

<div class="org-src-container">
<pre class="src src-shell">make
make install
</pre>
</div>

<p>
Si sólo quieres generar los ejecutables, ya has terminado. Si, como es
mi caso, estás montándote tu sistema de desarrollo para <code>erlang</code>,
seguro que querrás también tener la documentación. Hacerlo es tan
sencillo como:
</p>

<div class="org-src-container">
<pre class="src src-shell">make docs
make install-docs
</pre>
</div>

<p>
Mira en la documentación, porque así tal cual los genera todos por
cuatriplicado: <code>html</code>, <code>man</code>, <code>pdf</code> y <code>xml</code>. Lo mismo los quieres para
consultar con <code>erlang man [lib]</code>, que nos mostrará la documentación de
manual. O sólo te interesa tener la documentación para consultar en
<code>html</code> mientras programas, o imprimirte los <code>pdf</code> para tener la
documentación en papel<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>.
</p>

<p>
Y si todo ha ido bien, ya tienes tu sistema perfectamente preparado
para trabajar con <code>erlang</code>.
</p>
</div>
</div>
<div id="outline-container-org76c1817" class="outline-2">
<h2 id="org76c1817">Configurar <i>Emacs</i></h2>
<div class="outline-text-2" id="text-org76c1817">
<p>
Entiendo que a estas alturas ya tienes instalado el paquete
<code>erlang.el</code>. Ya escribí un artículo en el <i>blog</i> de cómo
configurarlo. Sólo quiero recordaros que deberíais cambiar el
directorio donde está instalado <code>erlang</code> en la configuración en
vuestro <code>init.el</code>
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Configurar el sitio de erlang
</span>(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">erlang-start</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> erlang-root-dir <span style="color: #f1fa8c;">"~/opt/lib64/erlang"</span>)
(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">erlang-flymake</span>)
</pre>
</div>
</div>
</div>
<div id="outline-container-org57c5113" class="outline-2">
<h2 id="org57c5113">Conclusiones</h2>
<div class="outline-text-2" id="text-org57c5113">
<p>
Un sistema <code>erlang</code> funcionando plenamente, compilado específicamente
para la máquina donde corre... ¿He notado diferencias? Pues sí y no.
Por ejemplo haciendo pruebas en el <i>raytracer</i>, los tiempos de
<i>render</i> se han mantenido muy parejos. Tanto que no puedo decir que
haya ningún tipo de mejora significativa.
</p>

<p>
Sin embargo, el tiempo de respuesta del sistema es mucho más rápido, o
al menos, esa sensación tengo cuando lanzo el <i>shell</i> o cuando dentro
de él levanto la aplicación <code>observer</code>, cuya respuesta subjetiva
ahora es <i>inmediata</i>.
</p>

<p>
Comparando uso de memoria y procesador de ambos sistemas, tampoco
percibo una diferencia significativa. Con lo cual, la única diferencia
que he podido observar es la rapidez con la que se ejecuta la máquina
virtual. Quizá en un sistema de producción sí se podría encontrar
algunas diferencias más.
</p>

<p>
De todas formas, y después de haberme molestado en compilarlo, lo
seguiré utilizando.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Entiendo que se referían a <code>erlc</code>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
¿Véis lo inteligente que puedo llegar a ser? He llegado yo solo a esa
conclusión y todo. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Vale, lo confieso, no me las leí... me hubiera ahorrado
bastante tiempo. 
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Compra una carretilla de papel, si es el caso. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/erlang/index.html">erlang</a> <a href="/tags/opensuse/index.html">opensuse</a> ]]></description>
  <category><![CDATA[erlang]]></category>
  <category><![CDATA[opensuse]]></category>
  <link>https://notxor.nueva-actitud.org/2020/12/12/compilando-erlang-en-opensuse.html</link>
  <pubDate>Sat, 12 Dec 2020 09:18:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Cámara]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-12-06</div>

<figure id="org83fa0cd">
<img src="./imagenes/imagen-final.png" alt="imagen-final.png">

</figure>
<div id="outline-container-org0bc6d8d" class="outline-2">
<h2 id="org0bc6d8d">Reorganización del código</h2>
<div class="outline-text-2" id="text-org0bc6d8d">
<p>
Desde la última entrega de la serie he modificado algunas cosas del
pequeño <i>raytracer</i>. Hasta ahora venía lanzando procesos
independientes para <code>imagen</code> y <code>camara</code>, haciéndolo por
separado desde el lanzador que había metido con calzador en la
librería general del <i>raytracer</i>.
</p>

<p>
Lo que he hecho es utilizar sólamente el proceso <code>camara</code> desde la
definición de la escena y que sea éste proceso el que levante los
otros procesos auxiliares como <code>imagen</code> o <code>renderer</code>. Así pues, en el
fichero de <code>escena</code>, a partir de ahora, sólo encontraremos los
parámetros de configuración de la imagen, la cámara y los
<i>objetos</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> del mundo.
</p>
</div>
<div id="outline-container-org6f965f4" class="outline-3">
<h3 id="org6f965f4">El formato <code>ppm</code></h3>
<div class="outline-text-3" id="text-org6f965f4">
<p>
Además, en los últimos días he cambiado el formato de salida. Hasta
ahora venía guardándose el fichero <code>ppm</code> como <code>P3</code> (ASCII) al formato
binario <code>P6</code>. Es básicamente lo mismo, pero ocupa bastante menos y se
escribe bastante más rápido.
</p>

<p>
Explico un poco más cómo funciona ésto del formato <code>ppm</code> porque hay
quien ha mostrado curiosidad por él y por qué lo utiliza el libro. No
estoy seguro de saber por qué lo usa el autor, sin embargo parece ser
el formato mejor pensado, quizá, para ser entendido por humanos.  Por
otro lado, debería referirme a dicho formato como <code>PNM</code> o <i>Portable
Anymap Format</i>, que engloba a varios tipos de fichero cada uno con su
extensión:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Tipo</th>
<th scope="col" class="org-left">ASCII</th>
<th scope="col" class="org-left"><i>raw</i></th>
<th scope="col" class="org-left">Ext.</th>
<th scope="col" class="org-left">Colores</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">Portable Bitmap</td>
<td class="org-left">P1</td>
<td class="org-left">P4</td>
<td class="org-left">.pbm</td>
<td class="org-left">0-1 (Blanco y Negro)</td>
</tr>

<tr>
<td class="org-left">Portable Graymap</td>
<td class="org-left">P2</td>
<td class="org-left">P5</td>
<td class="org-left">.pgm</td>
<td class="org-left">0-255 y 0-65535 (Escala de Grises)</td>
</tr>

<tr>
<td class="org-left">Portable Pixmap</td>
<td class="org-left">P3</td>
<td class="org-left">P6</td>
<td class="org-left">.ppm</td>
<td class="org-left">0-255 por cada canal: R,G,B.<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup></td>
</tr>
</tbody>
</table>

<p>
Estos ficheros cuentan con una cabecera en ASCII con el tipo de
fichero seguido con hasta tres valores numéricos y separado de los
datos por un salto de línea:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Cabecera</th>
<th scope="col" class="org-left">Significado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">P1..P6</td>
<td class="org-left">Tipo de fichero</td>
</tr>

<tr>
<td class="org-left">"#"</td>
<td class="org-left">Comentario encabezado por #</td>
</tr>

<tr>
<td class="org-left">1</td>
<td class="org-left">Ancho de la imagen</td>
</tr>

<tr>
<td class="org-left">2</td>
<td class="org-left">Alto de la imagen</td>
</tr>

<tr>
<td class="org-left">3</td>
<td class="org-left">Valor máximo del pixel</td>
</tr>

<tr>
<td class="org-left">"\n"</td>
<td class="org-left">Separación de cabecera y datos</td>
</tr>
</tbody>
</table>

<p>
Estos valores no tienen por qué estar escritos uno en cada línea. El
único valor que debe estar en una línea es el comentario, en el caso
de que lo haya.
</p>

<p>
Por poner un ejemplo de cómo se ve un fichero ASCII:
</p>

<pre class="example" id="org07d6c97">
P2
# Shows the word "FEEP" (example from Netpbm man page on PGM)
24 7
15
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  3  3  3  3  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15 15 15 15  0
0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0 15  0
0  3  3  3  0  0  0  7  7  7  0  0  0 11 11 11  0  0  0 15 15 15 15  0
0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0  0  0
0  3  0  0  0  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
</pre>


<figure id="org6b92620">
<img src="./imagenes/feep.png" alt="feep.png" width="350">

<figcaption><span class="figure-number">Figure 1: </span>Imagen magnificada</figcaption>
</figure>

<p>
Estos son los formatos básicos. Hay otro que se marca con <code>P7</code> que
permite la utilización del canal transparente. Dicho de otro modo, su
modelo de color es <code>RGBA</code>. Nos referimos a este tipo, para englobarlo
con los anteriores como <code>PAM</code> (<i>Portable Arbitrary Map</i>).
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Cabecera</th>
<th scope="col" class="org-left">Valor</th>
<th scope="col" class="org-left">Significado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">P7</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">número mágico</td>
</tr>

<tr>
<td class="org-left">WIDTH</td>
<td class="org-left">Número</td>
<td class="org-left">ancho de la imagen</td>
</tr>

<tr>
<td class="org-left">HEIGHT</td>
<td class="org-left">Número</td>
<td class="org-left">alto de la imagen</td>
</tr>

<tr>
<td class="org-left">DEPHT</td>
<td class="org-left">Número</td>
<td class="org-left">profundidad de color</td>
</tr>

<tr>
<td class="org-left">MAXVAL</td>
<td class="org-left">Número</td>
<td class="org-left">valor máximo</td>
</tr>

<tr>
<td class="org-left">TUPLTYPE</td>
<td class="org-left">Cadena</td>
<td class="org-left">tipo de imagen</td>
</tr>

<tr>
<td class="org-left">ENDHDR</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">Final de la cabecera</td>
</tr>
</tbody>
</table>

<p>
La mayoría de estos valores no necesitan explicación, sin embargo,
<code>TUPLTYPE</code> implica algunas consideraciones más. Este formato no tiene
versión <code>ASCII</code> legible por humanos y puede englobar a todos los
formatos anteriores según el valor de ese parámetro:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-right">

<col  class="org-right">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">TUPLTYPE</th>
<th scope="col" class="org-right">MAXVAL</th>
<th scope="col" class="org-right">DEPTH</th>
<th scope="col" class="org-left">Comentario</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">BLACKANDWHITE</td>
<td class="org-right">1</td>
<td class="org-right">1</td>
<td class="org-left">Equivalente a un <code>pbm</code> tipo <code>P4</code></td>
</tr>

<tr>
<td class="org-left">GRAYSCALE</td>
<td class="org-right">2..65535</td>
<td class="org-right">1</td>
<td class="org-left">Equivalente a un <code>pgm</code> tipo <code>P5</code></td>
</tr>

<tr>
<td class="org-left">RGB</td>
<td class="org-right">1..65535</td>
<td class="org-right">3</td>
<td class="org-left">Equivalente a un <code>ppm</code> tipo <code>P6</code></td>
</tr>

<tr>
<td class="org-left">BLACKANDWHITE_ALPHA</td>
<td class="org-right">1</td>
<td class="org-right">2</td>
<td class="org-left">2 bytes por pixel</td>
</tr>

<tr>
<td class="org-left">GRAYSCALE_ALPHA</td>
<td class="org-right">2..65535</td>
<td class="org-right">2</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">RGB_ALPHA</td>
<td class="org-right">1..65535</td>
<td class="org-right">4</td>
<td class="org-left">&#xa0;</td>
</tr>
</tbody>
</table>

<p>
En todos los casos, cuando <code>MAXVAL &gt; 255</code> se utilizan 2 bytes por
canal.
</p>

<p>
En el <i>raytracer</i> utilizo el formato de fichero <code>P6</code>. La cabecera de
la imagen final que he puesto es: <code>P6 600 400 255</code>, un salto de línea
y luego los datos en binario. La misma cabecera para un fichero en
esta última versión sería:
</p>

<pre class="example" id="org0d65e9a">
P7
WIDTH 600
HEIGHT 400
DEPTH 3
MAXVAL 255
TUPLTYPE RGB
ENDHDR
</pre>

<p>
A continuación se encontrarían los datos de los pixeles, de la misma
manera que en nuestra imagen <code>P6</code>. La única diferencia entre ambos
fichero serían las respectivas cabeceras.
</p>

<p>
Como dije antes, venía utilizando el modo <code>P3</code> como formato de
fichero, pero el que sea legible por humanos no aporta mucho al
fichero más allá de necesitar bastante más espacio para almacenarse.
El tema es que, puesto que no vamos a hacer modificaciones manuales a
la imagen, podemos utilizar su formato <i>raw</i> o binario. Para ello he
modificado el código de escritura del archivo gráfico de la siguiente
manera:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">escribir_imagen</span>(#<span style="color: #8be9fd; font-style: italic;">state</span>{ancho=<span style="color: #f8f8f2; font-weight: bold;">Ancho</span>,alto=<span style="color: #f8f8f2; font-weight: bold;">Alto</span>,lienzo=<span style="color: #f8f8f2; font-weight: bold;">Lienzo</span>,fichero=<span style="color: #f8f8f2; font-weight: bold;">Fichero</span>}) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Cabecera</span> = <span style="color: #8be9fd; font-style: italic;">io_lib</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"P6 ~p ~p 255~n"</span>, [<span style="color: #f8f8f2; font-weight: bold;">Ancho</span>,<span style="color: #f8f8f2; font-weight: bold;">Alto</span>]),
    <span style="color: #f8f8f2; font-weight: bold;">Imagen</span> =
        <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(
          <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">J</span>) -&gt;
                  <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(
                    <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">I</span>) -&gt;
                            <span style="color: #f8f8f2; font-weight: bold;">Color</span> = <span style="color: #8be9fd; font-style: italic;">maps</span>:<span style="color: #8be9fd; font-style: italic;">get</span>({<span style="color: #f8f8f2; font-weight: bold;">I</span>,<span style="color: #f8f8f2; font-weight: bold;">J</span>},<span style="color: #f8f8f2; font-weight: bold;">Lienzo</span>,{1,0,1}),
                            <span style="color: #8be9fd; font-style: italic;">escribe_color</span>(<span style="color: #f8f8f2; font-weight: bold;">Color</span>)
                    <span style="color: #ff79c6; font-weight: bold;">end</span>,
                    <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(0, <span style="color: #f8f8f2; font-weight: bold;">Ancho</span>-1))
          <span style="color: #ff79c6; font-weight: bold;">end</span>,
          <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(<span style="color: #f8f8f2; font-weight: bold;">Alto</span>-1, 0, -1)),
    {ok, <span style="color: #f8f8f2; font-weight: bold;">F</span>} = <span style="color: #8be9fd; font-style: italic;">file</span>:<span style="color: #8be9fd; font-style: italic;">open</span>(<span style="color: #f8f8f2; font-weight: bold;">Fichero</span>, [write]),
    <span style="color: #8be9fd; font-style: italic;">file</span>:<span style="color: #8be9fd; font-style: italic;">write</span>(<span style="color: #f8f8f2; font-weight: bold;">F</span>, <span style="color: #f8f8f2; font-weight: bold;">Cabecera</span> ++ <span style="color: #f8f8f2; font-weight: bold;">Imagen</span>),
    <span style="color: #8be9fd; font-style: italic;">file</span>:<span style="color: #8be9fd; font-style: italic;">close</span>(<span style="color: #f8f8f2; font-weight: bold;">F</span>).

<span style="color: #50fa7b; font-weight: bold;">escribe_color</span>({<span style="color: #f8f8f2; font-weight: bold;">R</span>,<span style="color: #f8f8f2; font-weight: bold;">G</span>,<span style="color: #f8f8f2; font-weight: bold;">B</span>}) -&gt;
    [<span style="color: #8be9fd; font-style: italic;">round</span>(255 * <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">clamp</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>, 0.0, 0.9999)),
     <span style="color: #8be9fd; font-style: italic;">round</span>(255 * <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">clamp</span>(<span style="color: #f8f8f2; font-weight: bold;">G</span>, 0.0, 0.9999)),
     <span style="color: #8be9fd; font-style: italic;">round</span>(255 * <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">clamp</span>(<span style="color: #f8f8f2; font-weight: bold;">B</span>, 0.0, 0.9999))].
</pre>
</div>

<p>
Como se puede apreciar, lo que ha cambiado es que ya no se convierte
el color a una cadena ASCII, lo demás continúa igual. Salvo que la
función <code>escribe_color/1</code> ha pasado de la librería <code>rerl</code> a ser parte
del módulo <code>imagen</code> pues sólo se la llama desde allí.
</p>

<p>
No descarto, en un futuro, modificar la salida al modo <code>P7</code> y que se
pueda seleccionar el tipo de salida del <i>raytracer</i> desde el blanco y
negro hasta el color completo con, o sin, canal <i>alfa</i>.
</p>

<p>
Puesto que ya tenemos nuestra cámara generándonos las imágenes en un
formato <i>raw</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> ahora nos faltan algunos otros detalles para
fabricarnos nuestra cámara virtual.
</p>
</div>
</div>
</div>
<div id="outline-container-org8c48c5f" class="outline-2">
<h2 id="org8c48c5f">Cámara</h2>
<div class="outline-text-2" id="text-org8c48c5f">
<p>
El esquema más sencillo de nuestra cámara está representado por un
punto en el espacio y un lienzo en el que dibujar:
</p>


<figure id="orged3c238">
<img src="./imagenes/camara.png" alt="camara.png">

<figcaption><span class="figure-number">Figure 2: </span>Representación esquemática de nuestra cámara</figcaption>
</figure>

<p>
En nuestra cámara podemos observar que el ángulo de visión \(\theta\) es
equivalente a \(2h\) y por tanto, para calcular \(h\) podemos hacer
\(h=tan(\frac{\theta}{2})\) que más adelante nos hará falta.
</p>

<p>
De momento, lo que más falta nos hace para representar una cámara
independiente es que la podemos mover y apuntar mirando en una
dirección determinada, que la podamos inclinar en cualquier dirección
del espacio 3D. La alternativa sería dejar la cámara fija y mover el
<i>mundo</i> para situarlo frente a ella, que es lo que veníamos haciendo.
</p>

<p>
Hasta ahora, para resumir un poco lo que era nuestra cámara,
situábamos su origen en el punto <code>{0,0,0}</code>; apuntaba, o <i>miraba</i>, en
la dirección <code>{0,0,-1}</code> y su inclinación era el vector <code>{0,1,0}</code>. Sin
embargo, queremos hacer que nuestra cámara se pueda colocar en
cualquier punto del espacio, mirando a cualquier otro punto del mismo
y poder inclinarla en cualquier dirección. Por tanto, hay que cambiar
el sistema de referencia a algo como:
</p>


<figure id="org6e55297">
<img src="./imagenes/camara-lookat.png" alt="camara-lookat.png">

</figure>

<p>
Hay que remarcar que aunque no se aprecie de manera exacta en la
figura tanto <code>Vup</code> como <code>v</code> y <code>w</code> coinciden en el mismo plano. Si el
valor <code>Vup</code> es <code>{0,1,0}</code> el plano al que me refiero será vertical y
nuestra cámara hará unas imágenes horizontales perfectas, pero si lo
inclinamos 45º a la izquierda estableciéndolo a <code>{-1,1,0}</code> obtendremos
una imagen tal que:
</p>


<figure id="org62ee85e">
<img src="./imagenes/imagen-inclinada.png" alt="imagen-inclinada.png">

</figure>
</div>
<div id="outline-container-org35024b3" class="outline-3">
<h3 id="org35024b3">Código de la cámara</h3>
<div class="outline-text-3" id="text-org35024b3">
<p>
Muy bonito todo pero ¿cómo ha quedado el código? Ya me perdonaréis si
me enrollo y no pongo una sola fórmula ni una sola línea de código.
Así que allá va un poco de código. Primero comento que he creado un
<i>registro</i> cámara para los valores básicos:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-record</span>(<span style="color: #8be9fd; font-style: italic;">camara</span>, { origen = {0,0,0}             <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Posici&#243;n de la c&#225;mara
</span>                , mira   = {0,0,-1}            <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Punto al que mira
</span>                , sup    = {0,1,0}             <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Orientaci&#243;n
</span>                , angulo = 80}).               <span style="color: #6272a4;">% </span><span style="color: #6272a4;">&#193;ngulo del campo de visi&#243;n</span>
</pre>
</div>

<p>
Comentar sólamente que el valor del ángulo por defecto es de 80º para
el campo de visión vertical. Como la elección de ese valor por defecto
no es aleatoria y necesita un poco más de explicación quiero sólo
remarcar el hecho y pedir paciencia, porque el porqué vendrá explicado
más adelante.
</p>

<p>
Para lanzar los rayos que generan la imagen, primero necesitamos el
punto desde el que debemos hacerlo (<code>origen</code>). También necesitamos
saber en qué dirección se encuentra el <i>lienzo</i> (<code>mira</code>), hacia dónde
está mirando la cámara. Por último, también necesitamos saber la
verticalidad de la cámara (<code>arriba</code>).
</p>

<p>
El registro nos sirve también para poder tener valores por defecto que
funcionan en la mayor parte de los casos. De esta manera en el fichero
de la <i>escena</i> seguramente nos sobre con pasar a la función <code>start</code> de
la cámara, los parámetros que cambien: generalmente, los puntos
<code>origen</code> y <code>mira</code>.
</p>

<p>
Dicha función queda de la siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">start</span>(#<span style="color: #8be9fd; font-style: italic;">camara</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">Origen</span>,mira=<span style="color: #f8f8f2; font-weight: bold;">MiraA</span>,sup=<span style="color: #f8f8f2; font-weight: bold;">VArriba</span>,angulo=<span style="color: #f8f8f2; font-weight: bold;">CV</span>},
      #<span style="color: #8be9fd; font-style: italic;">config</span>{ratio=<span style="color: #f8f8f2; font-weight: bold;">Ratio</span>,ancho=<span style="color: #f8f8f2; font-weight: bold;">Ix</span>,muestras=<span style="color: #f8f8f2; font-weight: bold;">Muestras</span>,profun=<span style="color: #f8f8f2; font-weight: bold;">Profun</span>,tesela=<span style="color: #f8f8f2; font-weight: bold;">Tesela</span>,procesos=<span style="color: #f8f8f2; font-weight: bold;">Procesos</span>}=<span style="color: #f8f8f2; font-weight: bold;">Config</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Estableciendo datos de la imagen...~n"</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Pid</span> = <span style="color: #8be9fd; font-style: italic;">rerl_imagen</span>:<span style="color: #8be9fd; font-style: italic;">start</span>(<span style="color: #f8f8f2; font-weight: bold;">Config</span>),
    <span style="color: #8be9fd; font-style: italic;">register</span>(imagen, <span style="color: #f8f8f2; font-weight: bold;">Pid</span>),

    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Estableciendo datos de la c&#225;mara...~n"</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Theta</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">grados_a_radianes</span>(<span style="color: #f8f8f2; font-weight: bold;">CV</span>),        <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Calcular el &#225;ngulo en radianes del campo de visi&#243;n
</span>    <span style="color: #f8f8f2; font-weight: bold;">H</span> = <span style="color: #8be9fd; font-style: italic;">math</span>:<span style="color: #8be9fd; font-style: italic;">tan</span>(<span style="color: #f8f8f2; font-weight: bold;">Theta</span> / 2),
    <span style="color: #f8f8f2; font-weight: bold;">Viewport_Alto</span> = 2.0 * <span style="color: #f8f8f2; font-weight: bold;">H</span>,                            <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Calcular el factor de altura de la imagen
</span>    <span style="color: #f8f8f2; font-weight: bold;">Viewport_Ancho</span> = <span style="color: #f8f8f2; font-weight: bold;">Viewport_Alto</span> * <span style="color: #f8f8f2; font-weight: bold;">Ratio</span>,

    <span style="color: #f8f8f2; font-weight: bold;">W</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">vector_unidad</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(<span style="color: #f8f8f2; font-weight: bold;">Origen</span>, <span style="color: #f8f8f2; font-weight: bold;">MiraA</span>)),
    <span style="color: #f8f8f2; font-weight: bold;">U</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">vector_unidad</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">cruz</span>(<span style="color: #f8f8f2; font-weight: bold;">VArriba</span>, <span style="color: #f8f8f2; font-weight: bold;">W</span>)),
    <span style="color: #f8f8f2; font-weight: bold;">V</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">cruz</span>(<span style="color: #f8f8f2; font-weight: bold;">W</span>, <span style="color: #f8f8f2; font-weight: bold;">U</span>),

    <span style="color: #f8f8f2; font-weight: bold;">Iy</span> = <span style="color: #8be9fd; font-style: italic;">round</span>(<span style="color: #f8f8f2; font-weight: bold;">Ix</span> / <span style="color: #f8f8f2; font-weight: bold;">Ratio</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Horizontal</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">U</span>, <span style="color: #f8f8f2; font-weight: bold;">Viewport_Ancho</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Vertical</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">V</span>, <span style="color: #f8f8f2; font-weight: bold;">Viewport_Alto</span>),
    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Eii = Origen - Viewport_Ancho/2 - Viewport_Alto/2 - {0,0,Focal}
</span>    <span style="color: #f8f8f2; font-weight: bold;">Medio_H</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">dividir</span>(<span style="color: #f8f8f2; font-weight: bold;">Horizontal</span>, 2),
    <span style="color: #f8f8f2; font-weight: bold;">Medio_V</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">dividir</span>(<span style="color: #f8f8f2; font-weight: bold;">Vertical</span>, 2),
    <span style="color: #f8f8f2; font-weight: bold;">Eii</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(
            <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(
              <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(<span style="color: #f8f8f2; font-weight: bold;">Origen</span>, <span style="color: #f8f8f2; font-weight: bold;">Medio_H</span>), <span style="color: #f8f8f2; font-weight: bold;">Medio_V</span>),
            <span style="color: #f8f8f2; font-weight: bold;">W</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Estado</span> = #<span style="color: #8be9fd; font-style: italic;">state</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">Origen</span>
                  , alto=<span style="color: #f8f8f2; font-weight: bold;">Viewport_Alto</span>
                  , ancho=<span style="color: #f8f8f2; font-weight: bold;">Viewport_Ancho</span>
                  , ix=<span style="color: #f8f8f2; font-weight: bold;">Ix</span>
                  , iy=<span style="color: #f8f8f2; font-weight: bold;">Iy</span>
                  , ratio=<span style="color: #f8f8f2; font-weight: bold;">Ratio</span>
                  , horizontal=<span style="color: #f8f8f2; font-weight: bold;">Horizontal</span>
                  , vertical=<span style="color: #f8f8f2; font-weight: bold;">Vertical</span>
                  , eii=<span style="color: #f8f8f2; font-weight: bold;">Eii</span>
                  , muestras=<span style="color: #f8f8f2; font-weight: bold;">Muestras</span>
                  , profundidad=<span style="color: #f8f8f2; font-weight: bold;">Profun</span>
                  , tesela=<span style="color: #f8f8f2; font-weight: bold;">Tesela</span>
                  , procesos=<span style="color: #f8f8f2; font-weight: bold;">Procesos</span>},
    <span style="color: #8be9fd; font-style: italic;">spawn</span>(rerl_camara, init, [<span style="color: #f8f8f2; font-weight: bold;">Estado</span>]).
</pre>
</div>

<p>
El cambio no es muy pronunciado: como se puede apreciar es que se
calcula <code>U</code> y <code>V</code> en base al ángulo del campo de visión vertical.
</p>

<p>
La imagen conseguida con un fichero escena tal que:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">escena</span>() -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Config</span> =
        #<span style="color: #8be9fd; font-style: italic;">config</span>{
           nombre = <span style="color: #f1fa8c;">"imagen.ppm"</span>,          <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Nombre del fichero de imagen generado
</span>           ratio = 16 / 9,                 <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Ratio ancho/alto de la imagen
</span>           ancho = 400,                    <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Ancho en puntos de la imagen
</span>           muestras = 100,                 <span style="color: #6272a4;">% </span><span style="color: #6272a4;">N&#186; de muestras por pixel
</span>           profun = 50,                    <span style="color: #6272a4;">% </span><span style="color: #6272a4;">N&#250;mero de &#171;rebotes&#187; por rayo.
</span>           tesela = 25,                    <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Tama&#241;o del lado de la tesela en puntos
</span>           procesos = 10},                 <span style="color: #6272a4;">% </span><span style="color: #6272a4;">N&#250;mero de procesos de c&#225;lculo
</span>
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Iniciando la c&#225;mara...~n"</span>),
    <span style="color: #f8f8f2; font-weight: bold;">O</span> = {-2,2,1},                          <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Origen de la c&#225;mara
</span>    <span style="color: #f8f8f2; font-weight: bold;">MiraA</span> = {0,0,-1},
    <span style="color: #f8f8f2; font-weight: bold;">CV</span> = 90,                               <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Campo de visi&#243;n vertical (&#225;ngulo en grados)
</span>    <span style="color: #f8f8f2; font-weight: bold;">Camara</span> = #<span style="color: #8be9fd; font-style: italic;">camara</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">O</span>,mira=<span style="color: #f8f8f2; font-weight: bold;">MiraA</span>,angulo=<span style="color: #f8f8f2; font-weight: bold;">CV</span>},
    <span style="color: #f8f8f2; font-weight: bold;">Pid_camara</span> = <span style="color: #8be9fd; font-style: italic;">rerl_camara</span>:<span style="color: #8be9fd; font-style: italic;">start</span>(<span style="color: #f8f8f2; font-weight: bold;">Camara</span>, <span style="color: #f8f8f2; font-weight: bold;">Config</span>),
    <span style="color: #8be9fd; font-style: italic;">register</span>(camara, <span style="color: #f8f8f2; font-weight: bold;">Pid_camara</span>),

    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Materiales de la escena
</span>    <span style="color: #f8f8f2; font-weight: bold;">Material_Suelo</span> = #<span style="color: #8be9fd; font-style: italic;">material</span>{tipo=difuso,albedo={0.2,0.2,0.0}},
    <span style="color: #f8f8f2; font-weight: bold;">Difuso</span> = #<span style="color: #8be9fd; font-style: italic;">material</span>{tipo=difuso,albedo={1.0,0.0,0.0}},
    <span style="color: #f8f8f2; font-weight: bold;">Cristal</span> = #<span style="color: #8be9fd; font-style: italic;">material</span>{tipo=transparente,albedo={1.0,1.0,1.0},ir=1.5},
    <span style="color: #f8f8f2; font-weight: bold;">Metal</span> = #<span style="color: #8be9fd; font-style: italic;">material</span>{tipo=reflexion,albedo={0.8,0.6,0.2},rugoso=0.3},

    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Esferas: geometr&#237;as de la escena
</span>    <span style="color: #f8f8f2; font-weight: bold;">Esfera_Suelo</span> = #<span style="color: #8be9fd; font-style: italic;">esfera</span>{centro={0,-100.5,-1},radio=100},
    <span style="color: #f8f8f2; font-weight: bold;">Esfera_Central</span> = #<span style="color: #8be9fd; font-style: italic;">esfera</span>{centro={0,0,-1},radio=0.5},
    <span style="color: #f8f8f2; font-weight: bold;">Esfera_Izda</span> = #<span style="color: #8be9fd; font-style: italic;">esfera</span>{centro={-1.0,0.0,-1.0},radio=0.5},
    <span style="color: #f8f8f2; font-weight: bold;">Esfera_Dcha</span> = #<span style="color: #8be9fd; font-style: italic;">esfera</span>{centro={1.0,0.0,-1.0},radio=0.5},

    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Montar los objetos para el render, cada geometr&#237;a con su material
</span>    <span style="color: #f8f8f2; font-weight: bold;">Objs</span> = [#<span style="color: #8be9fd; font-style: italic;">objeto</span>{geom=<span style="color: #f8f8f2; font-weight: bold;">Esfera_Central</span>,material=<span style="color: #f8f8f2; font-weight: bold;">Difuso</span>}
          , #<span style="color: #8be9fd; font-style: italic;">objeto</span>{geom=<span style="color: #f8f8f2; font-weight: bold;">Esfera_Suelo</span>,material=<span style="color: #f8f8f2; font-weight: bold;">Material_Suelo</span>}
          , #<span style="color: #8be9fd; font-style: italic;">objeto</span>{geom=<span style="color: #f8f8f2; font-weight: bold;">Esfera_Izda</span>,material=<span style="color: #f8f8f2; font-weight: bold;">Cristal</span>}
          , #<span style="color: #8be9fd; font-style: italic;">objeto</span>{geom=<span style="color: #f8f8f2; font-weight: bold;">Esfera_Dcha</span>,material=<span style="color: #f8f8f2; font-weight: bold;">Metal</span>}],

    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Tirar el render
</span>    camara ! {render,<span style="color: #f8f8f2; font-weight: bold;">Objs</span>}.
</pre>
</div>

<p>
Genera la siguiente imagen:
</p>


<figure id="org78f987a">
<img src="./imagenes/imagen-camara-movida.png" alt="imagen-camara-movida.png">

</figure>

<p>
Sin embargo, si modificamos el ángulo a <code>20</code>:
</p>


<figure id="org95dc131">
<img src="./imagenes/imagen-zoom.png" alt="imagen-zoom.png">

</figure>

<p>
Como se puede apreciar a ángulos de visión más estrechos, la imagen se
acerca como en un teleobjetivo. Para ángulos grandes la imagen se
alejará como en un gran angular. Por ejemplo, con un valor de 160º,
que sería casi un angular <i>ojo de pez</i>, la imagen se vería así:
</p>


<figure id="org63e7b62">
<img src="./imagenes/imagen-ojo-pez.png" alt="imagen-ojo-pez.png">

</figure>

<p>
Como observaréis, los grandes angulares distorsionan y curvan los
objetos. La esfera inferior aparece con lados casi rectilíneos no como
se esperan ver en una esfera.
</p>

<p>
¿Por qué cambia tanto la imagen cambiando sólo el ángulo del campo de
visión? Dejadme un momento que explico un poco mejor cómo funciona una
cámara fotográfica.
</p>
</div>
</div>
</div>
<div id="outline-container-org3cf2ec9" class="outline-2">
<h2 id="org3cf2ec9">Cámara fotográfica</h2>
<div class="outline-text-2" id="text-org3cf2ec9">
<p>
Al ojo humano podemos calcularle un ángulo de visión, o campo visual,
de 130º en horizontal y 80º en vertical<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>.
</p>

<p>
Para los cálculos vamos a fijarnos en el siguiente esquema:
</p>


<figure id="orge27cac2">
<img src="./imagenes/esquema-lente.png" alt="esquema-lente.png">

<figcaption><span class="figure-number">Figure 3: </span>Esquema de una lente simple.</figcaption>
</figure>

<p>
En una lente simple, no hay sensores como en las cámaras para tener
como referencia su tamaño, puesto que las distancias focales y
cualquier otro parámetro estará calculado en función a él. Resulta un
poco difícil explicar, por qué los angulares en la fotografía se miden
en mm o por qué decimos que un objetivo de 50mm es el angular
normal. Para ello tengo que cansinaros un poco más con las
matemáticas.
</p>

<p>
Vamos a darle un poco al cálculo del ángulo de visión en función de la
distancia focal y el tamaño del sensor (el normal es 35mm):
</p>

<p>
\[ \theta = 2 arctan \frac{S}{2f(m+1)}\]
</p>

<p>
donde \(\theta\) es el ángulo de visión, \(S\) el tamaño del sensor, \(F\)
la distancia focal y \(m\) el factor de magnificación que los
aficionados a la fotografía conocerán como <i>macro</i>. Para distancias de
enfoque grandes (\(m \thickapprox 0\)) sería:
</p>

<p>
\[ \theta = 2 arctan \frac{S}{2f}\]
</p>

<p>
El factor de magnificación, o <i>macro</i>, es despreciable en distancias
de enfoque lejanas (al <i>infinito</i>), pero tiene que tomarse en cuenta
en distancias de enfoque cercanas. Se calcula mediante la fórmula:
</p>

<p>
\[m = \frac{f}{D - f}\]
</p>

<p>
Donde \(f\) es la distancia focal en mm y \(D\) es la distancia de
enfoque. Por ejemplo, con un objetivo de 50mm enfocado a una distancia
de 55cm el cálculo sería:
</p>

<p>
\[m = \frac{f}{D - f} = \frac{50}{550 - 50} = 0,1\]
</p>

<p>
Por eso, entre las recomendaciones habituales que se les da a los
fotógrafos noveles cuando te están enseñando fotografía, encuadres y
demás, es que te alejes del sujeto al menos un metro para no
distorsionar la imagen... pero seguimos.
</p>

<p>
Por hacer una comparación si calculamos con un objetivo de 50mm su
ángulo de visión para estar enfocado al infinito, puesto que el factor
<code>m</code> es igual a cero (\(m=0\)), dicho ángulo será:
</p>

<p>
\[\theta = 2 arctan \frac{S}{2f(m+1)} = 2 arctan \frac{36}{2 \cdot 50} = 40º\]
</p>

<p>
Sin embargo, si lo enfocamos a 55cm como dijimos antes:
</p>

<p>
\[\theta = 2 arctan \frac{S}{2f(m+1)} = 2 arctan \frac{36}{2 \cdot 50 (0,1 + 1)} = 36º\]
</p>

<p>
Es decir, el ángulo es cuatro grados menor, no podrás enfocar bien a
distancias menores, a no ser que el objetivo sea <i>macro</i> y permita
mover las lentes para reducir ese ángulo. Si no es macro, tendrás que
cambiar el objetivo y calzarle a la cámara un <i>gran angular</i>.
</p>
</div>
<div id="outline-container-org89c3d08" class="outline-3">
<h3 id="org89c3d08">Enfoque</h3>
<div class="outline-text-3" id="text-org89c3d08">
<p>
En una fotografía estamos acostumbrados a ver que hay objetos que
vemos borrosos. Aquellos que están demasiado lejos o demasiado cerca
del punto enfocado.
</p>


<figure id="org69ac126">
<img src="./imagenes/lente-fina.png" alt="lente-fina.png">

</figure>

<p>
A simple vista podemos observar que cuanto más grande sea la lente más
grande será el ángulo en el que se enfocan los objetos. No podemos
cambiar el tamaño de la lente, sin embargo, podemos modificar el
ángulo en el que incide la luz en ella <i>obturador</i>, que no sólo
modifica la cantidad de luz que entra en la cámara, sino que también
afecta al enfoque. A quienes les gusta la fotografía saben que cuando
juegan con la apertura del diafragma del objetivo, consiguen un rango
de objetos enfocados más amplio cuando utilizan aperturas más
pequeñas. Sin embargo, a aperturas grandes enseguida los objetos
situados un poco antes o después, quedan desenfocados.
</p>
</div>
</div>
<div id="outline-container-orgdf2a173" class="outline-3">
<h3 id="orgdf2a173">Enfocar la cámara</h3>
<div class="outline-text-3" id="text-orgdf2a173">
<p>
Como hemos visto antes, el cálculo del enfoque necesita también la
distancia focal <i>f</i> y la apertura de la lente. El registro de la
cámara se modifica añadiendo ambos valores:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-record</span>(<span style="color: #8be9fd; font-style: italic;">camara</span>, { origen   = {0,0,0}           <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Posici&#243;n de la c&#225;mara
</span>                , mira     = {0,0,-1}          <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Punto al que mira
</span>                , sup      = {0,1,0}           <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Orientaci&#243;n del lado superior de la c&#225;mara
</span>                , angulo   = 80                <span style="color: #6272a4;">% </span><span style="color: #6272a4;">&#193;ngulo del campo de visi&#243;n
</span>                , apertura = 2.0               <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Di&#225;metro de la lente
</span>                , f        = 1.0}).            <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Distancia focal</span>
</pre>
</div>

<p>
El código de la cámara queda de la siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">start</span>(#<span style="color: #8be9fd; font-style: italic;">camara</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">Origen</span>,mira=<span style="color: #f8f8f2; font-weight: bold;">MiraA</span>,sup=<span style="color: #f8f8f2; font-weight: bold;">VArriba</span>,angulo=<span style="color: #f8f8f2; font-weight: bold;">CV</span>,apertura=<span style="color: #f8f8f2; font-weight: bold;">Apertura</span>,f=<span style="color: #f8f8f2; font-weight: bold;">Dist_Focal</span>},
      #<span style="color: #8be9fd; font-style: italic;">config</span>{ratio=<span style="color: #f8f8f2; font-weight: bold;">Ratio</span>,ancho=<span style="color: #f8f8f2; font-weight: bold;">Ix</span>,muestras=<span style="color: #f8f8f2; font-weight: bold;">Muestras</span>,profun=<span style="color: #f8f8f2; font-weight: bold;">Profun</span>,tesela=<span style="color: #f8f8f2; font-weight: bold;">Tesela</span>,procesos=<span style="color: #f8f8f2; font-weight: bold;">Procesos</span>}=<span style="color: #f8f8f2; font-weight: bold;">Config</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Estableciendo datos de la imagen...~n"</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Pid</span> = <span style="color: #8be9fd; font-style: italic;">rerl_imagen</span>:<span style="color: #8be9fd; font-style: italic;">start</span>(<span style="color: #f8f8f2; font-weight: bold;">Config</span>),
    <span style="color: #8be9fd; font-style: italic;">register</span>(imagen, <span style="color: #f8f8f2; font-weight: bold;">Pid</span>),

    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Estableciendo datos de la c&#225;mara...~n"</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Theta</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">grados_a_radianes</span>(<span style="color: #f8f8f2; font-weight: bold;">CV</span>),        <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Calcular el &#225;ngulo en radianes del campo de visi&#243;n
</span>    <span style="color: #f8f8f2; font-weight: bold;">H</span> = <span style="color: #8be9fd; font-style: italic;">math</span>:<span style="color: #8be9fd; font-style: italic;">tan</span>(<span style="color: #f8f8f2; font-weight: bold;">Theta</span> / 2),
    <span style="color: #f8f8f2; font-weight: bold;">Viewport_Alto</span> = 2.0 * <span style="color: #f8f8f2; font-weight: bold;">H</span>,                   <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Calcular el factor de altura de la imagen
</span>    <span style="color: #f8f8f2; font-weight: bold;">Viewport_Ancho</span> = <span style="color: #f8f8f2; font-weight: bold;">Viewport_Alto</span> * <span style="color: #f8f8f2; font-weight: bold;">Ratio</span>,

    <span style="color: #f8f8f2; font-weight: bold;">W</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">vector_unidad</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(<span style="color: #f8f8f2; font-weight: bold;">Origen</span>, <span style="color: #f8f8f2; font-weight: bold;">MiraA</span>)),
    <span style="color: #f8f8f2; font-weight: bold;">U</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">vector_unidad</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">cruz</span>(<span style="color: #f8f8f2; font-weight: bold;">VArriba</span>, <span style="color: #f8f8f2; font-weight: bold;">W</span>)),
    <span style="color: #f8f8f2; font-weight: bold;">V</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">cruz</span>(<span style="color: #f8f8f2; font-weight: bold;">W</span>, <span style="color: #f8f8f2; font-weight: bold;">U</span>),

    <span style="color: #f8f8f2; font-weight: bold;">Iy</span> = <span style="color: #8be9fd; font-style: italic;">round</span>(<span style="color: #f8f8f2; font-weight: bold;">Ix</span> / <span style="color: #f8f8f2; font-weight: bold;">Ratio</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Horizontal</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">U</span>, <span style="color: #f8f8f2; font-weight: bold;">Viewport_Ancho</span>), <span style="color: #f8f8f2; font-weight: bold;">Dist_Focal</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Vertical</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">V</span>, <span style="color: #f8f8f2; font-weight: bold;">Viewport_Alto</span>), <span style="color: #f8f8f2; font-weight: bold;">Dist_Focal</span>),
    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Eii = Origen - Viewport_Ancho/2 - Viewport_Alto/2 - {0,0,Focal}
</span>    <span style="color: #f8f8f2; font-weight: bold;">Medio_H</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">dividir</span>(<span style="color: #f8f8f2; font-weight: bold;">Horizontal</span>, 2),
    <span style="color: #f8f8f2; font-weight: bold;">Medio_V</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">dividir</span>(<span style="color: #f8f8f2; font-weight: bold;">Vertical</span>, 2),
    <span style="color: #f8f8f2; font-weight: bold;">Eii</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(
            <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(
              <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(<span style="color: #f8f8f2; font-weight: bold;">Origen</span>, <span style="color: #f8f8f2; font-weight: bold;">Medio_H</span>), <span style="color: #f8f8f2; font-weight: bold;">Medio_V</span>),
            <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">W</span>, <span style="color: #f8f8f2; font-weight: bold;">Dist_Focal</span>)),
    <span style="color: #f8f8f2; font-weight: bold;">Estado</span> = #<span style="color: #8be9fd; font-style: italic;">state</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">Origen</span>
                  , alto=<span style="color: #f8f8f2; font-weight: bold;">Viewport_Alto</span>
                  , ancho=<span style="color: #f8f8f2; font-weight: bold;">Viewport_Ancho</span>
                  , ix=<span style="color: #f8f8f2; font-weight: bold;">Ix</span>
                  , iy=<span style="color: #f8f8f2; font-weight: bold;">Iy</span>
                  , ratio=<span style="color: #f8f8f2; font-weight: bold;">Ratio</span>
                  , u=<span style="color: #f8f8f2; font-weight: bold;">U</span>
                  , v=<span style="color: #f8f8f2; font-weight: bold;">V</span>
                  , horizontal=<span style="color: #f8f8f2; font-weight: bold;">Horizontal</span>
                  , vertical=<span style="color: #f8f8f2; font-weight: bold;">Vertical</span>
                  , eii=<span style="color: #f8f8f2; font-weight: bold;">Eii</span>
                  , radio_lente = <span style="color: #f8f8f2; font-weight: bold;">Apertura</span> / 2
                  , muestras=<span style="color: #f8f8f2; font-weight: bold;">Muestras</span>
                  , profundidad=<span style="color: #f8f8f2; font-weight: bold;">Profun</span>
                  , tesela=<span style="color: #f8f8f2; font-weight: bold;">Tesela</span>
                  , procesos=<span style="color: #f8f8f2; font-weight: bold;">Procesos</span>},
    <span style="color: #8be9fd; font-style: italic;">spawn</span>(rerl_camara, init, [<span style="color: #f8f8f2; font-weight: bold;">Estado</span>]).
</pre>
</div>

<p>
El cambio fundamental para conseguir el desenfoque o <i>blur</i> de las
imágenes se da a la hora de lanzar los rayos:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Calcula la direcci&#243;n de un nuevo rayo. El origen siempre es el
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">origen de la c&#225;mara.
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #50fa7b; font-weight: bold;">lanza_rayo</span>(#<span style="color: #8be9fd; font-style: italic;">state</span>{profundidad=<span style="color: #f8f8f2; font-weight: bold;">Prf</span>}=<span style="color: #f8f8f2; font-weight: bold;">Estado</span>, <span style="color: #f8f8f2; font-weight: bold;">Cam</span>, <span style="color: #f8f8f2; font-weight: bold;">S</span>, <span style="color: #f8f8f2; font-weight: bold;">T</span>) -&gt;
    {<span style="color: #f8f8f2; font-weight: bold;">Origen</span>,<span style="color: #f8f8f2; font-weight: bold;">Eii</span>,<span style="color: #f8f8f2; font-weight: bold;">U</span>,<span style="color: #f8f8f2; font-weight: bold;">V</span>,<span style="color: #f8f8f2; font-weight: bold;">R_Lente</span>,<span style="color: #f8f8f2; font-weight: bold;">Horizontal</span>,<span style="color: #f8f8f2; font-weight: bold;">Vertical</span>} = <span style="color: #f8f8f2; font-weight: bold;">Cam</span>,
    {<span style="color: #f8f8f2; font-weight: bold;">X</span>,<span style="color: #f8f8f2; font-weight: bold;">Y</span>,<span style="color: #f8f8f2; font-weight: bold;">_</span>} = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">random_en_disco_unidad</span>(),<span style="color: #f8f8f2; font-weight: bold;">R_Lente</span>),
    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Offset = U*X + V*Y,
</span>    <span style="color: #f8f8f2; font-weight: bold;">Offset</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">U</span>, <span style="color: #f8f8f2; font-weight: bold;">X</span>), <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">V</span>, <span style="color: #f8f8f2; font-weight: bold;">Y</span>)),
    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Eii + Hor*U + Ver*V - Origen
</span>    <span style="color: #f8f8f2; font-weight: bold;">Dir</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(
            <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(
              <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(
                <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(
                  <span style="color: #f8f8f2; font-weight: bold;">Eii</span>,
                  <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">Horizontal</span>, <span style="color: #f8f8f2; font-weight: bold;">S</span>)),
                <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">Vertical</span>, <span style="color: #f8f8f2; font-weight: bold;">T</span>)),
              <span style="color: #f8f8f2; font-weight: bold;">Origen</span>),
            <span style="color: #f8f8f2; font-weight: bold;">Offset</span>),
    <span style="color: #f8f8f2; font-weight: bold;">O</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #f8f8f2; font-weight: bold;">Origen</span>, <span style="color: #f8f8f2; font-weight: bold;">Offset</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Rayo</span> = #<span style="color: #8be9fd; font-style: italic;">rayo</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">O</span>,dir=<span style="color: #f8f8f2; font-weight: bold;">Dir</span>},
    <span style="color: #8be9fd; font-style: italic;">color_rayo</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>, <span style="color: #f8f8f2; font-weight: bold;">Rayo</span>, <span style="color: #f8f8f2; font-weight: bold;">Prf</span>).
</pre>
</div>

<p>
El truco está en que en lugar de enviarlos desde el punto exacto del
origen de la cámara, se utiliza un punto ligeramente distante de él
según la distancia y la apertura. Para ello, hacemos que en lugar de
un punto, sea un círculo.
</p>

<p>
Para ello necesitamos también una función que nos dé un punto
aleatorio dentro de un disco de tamaño 1:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">random_en_disco_unidad</span>() -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">P</span> = {<span style="color: #8be9fd; font-style: italic;">random</span>(-1.0,1.0),<span style="color: #8be9fd; font-style: italic;">random</span>(-1.0,1.0),0},
    <span style="color: #f8f8f2; font-weight: bold;">M</span> = <span style="color: #8be9fd; font-style: italic;">modulo_cuadrado</span>(<span style="color: #f8f8f2; font-weight: bold;">P</span>),
    <span style="color: #ff79c6; font-weight: bold;">if</span> <span style="color: #f8f8f2; font-weight: bold;">M</span> &gt;= 1 -&gt;
            <span style="color: #8be9fd; font-style: italic;">random_en_disco_unidad</span>();
       true -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">P</span>
    <span style="color: #ff79c6; font-weight: bold;">end</span>.
</pre>
</div>

<p>
Y tenemos nuestra imagen con desenfoque. Con una distancia focal de
<code>1:1</code> obtenemos:
</p>


<figure id="orgdb3ef82">
<img src="./imagenes/imagen-f-1.png" alt="imagen-f-1.png">

</figure>

<p>
Cambiando la apertura a <code>1:25</code> obtenemos.
</p>


<figure id="org2ccc510">
<img src="./imagenes/imagen-f-25.png" alt="imagen-f-25.png">

</figure>

<p>
Supongo que está claro, no sólo por las explicaciones anteriores, sino
también atendiendo a las imágenes obtenidas, que una apertura más
pequeña (\(1/25\)) genera imágenes más enfocadas que una apertura más
grande (\(1/1\)).
</p>
</div>
</div>
</div>
<div id="outline-container-orgc6fb437" class="outline-2">
<h2 id="orgc6fb437">Conclusiones</h2>
<div class="outline-text-2" id="text-orgc6fb437">
<p>
Con esto hemos llegado al final del primer <i>libro-tutorial</i> de cómo
programar un <i>raytracer</i>. Tenemos una cámara plenamente funcional y
los materiales básicos: reflexión, refracción y color sólido.
Únicamente conoce una geometría: la esfera. Pero en definitiva es todo
lo que se espera de un <i>raytracer</i>. No lo he hecho en un fin de semana
porque era un plazo irreal y porque he perdido mucho tiempo en tareas
paralelas, como contarlo en el <i>blog</i> o traducir el código y el método
a <code>erlang</code>.
</p>

<p>
Por otro lado, el <i>raytracer</i> funciona de forma paralela, se pueden
ajustar el número de procesos que lanzará y repartiendo la imagen en
pequeñas partes, ─o grandes, porque también se puede configurar el
tamaño─, al hacerlo.
</p>

<p>
A partir de aquí, me tengo que pensar si sigo con la serie de
artículos, aunque quiero terminar la serie de los tres libros lo mismo
es muy aburrido el monotema en el que casi se está convirtiendo el
<i>blog</i>.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Recordad que el <code>objeto</code> lo habíamos definido como un <code>record</code>
compuesto de <i>geometría</i> y <i>material</i>. Así pues, encontraremos las
definiciones de las geometrías y materiales en el fichero de la
escena.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Algunos programas dan soporte a 0-65535 colores por canal RBG,
pero no todos.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Los aficionados a la fotografía (digital) estarán encantados
con el artículo de hoy, ─espero─: <i>formato raw</i>, <i>distancia focal</i>,
<i>apertura de obturardos</i>... hoy traigo de todo eso.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Por eso se ha elegido el ángulo de 80º como el valor por
defecto para el campo de visión vertical al definir la cámara.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/raytrace/index.html">raytrace</a> <a href="/tags/erlang/index.html">erlang</a> ]]></description>
  <category><![CDATA[raytrace]]></category>
  <category><![CDATA[erlang]]></category>
  <link>https://notxor.nueva-actitud.org/2020/12/06/camara.html</link>
  <pubDate>Sun, 06 Dec 2020 00:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Materiales]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-12-01</div>

<figure id="org677a71f">
<img src="./imagenes/imagen-portada.png" alt="imagen-portada.png">

</figure>

<p>
Como dice el título, el tema de hoy va de cálculo de materiales y
otras zarandajas. Conseguir una imagen realista tiene que ver con
conseguir que nuestras figuras geométricas tengan una apariencia
creíble. Habrá, como en todas las entregas del <i>raytracer</i>, espacio
para las matemáticas, para el código en <code>erlang</code> y para las
explicaciones con gráficos y figuras. Al final del artículo, como
siempre, expondré los cambios y decisiones diseño del <i>raytracer</i> que
voy tomando según avanzo.
</p>
<div id="outline-container-orged86099" class="outline-2">
<h2 id="orged86099">Proceso de desarrollo de los materiales</h2>
<div class="outline-text-2" id="text-orged86099">
<p>
Hasta ahora todos los materiales tenían apenas un color y un índice de
dispersión, porque todos eran del mismo tipo. Pero ahora,
necesitaremos obtener qué <i>tipo</i> de material tiene el objeto.  Es
decir, ahora, los materiales son siempre <i>difusos</i> y el cálculo del
material siempre es el mismo.
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-record</span>(<span style="color: #8be9fd; font-style: italic;">material</span>, { tipo       = nil           <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Tipo de material
</span>                  , albedo     = {0,0,0}       <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Factor de atenuaci&#243;n de color
</span>                  , dispersion = #<span style="color: #8be9fd; font-style: italic;">rayo</span>{}}).    <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Factor de dispersi&#243;n de la luz</span>
</pre>
</div>

<p>
Hasta este momento, el cálculo de la <i>dispersión</i> del material en un
punto se venía efectuando dentro del mismo proceso de cálculo del
pixel. Sin embargo, debido a la complejidad que encontraremos más
adelante impone la necesidad de tener más código en un nuevo módulo
que llamaremos <code>rerl_material</code>. Este fichero lo iniciamos con los
cálculos de dispersión para el material <i>difuso</i> que es el único que
veníamos utilizando hasta ahora.
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-module</span>(rerl_material).

<span style="color: #ffb86c;">-include</span>(<span style="color: #f1fa8c;">"registros.hrl"</span>).

<span style="color: #ffb86c;">-export</span>([<span style="color: #8be9fd; font-style: italic;">dispersion_luz/1</span>]).

<span style="color: #6272a4;">%%%</span><span style="color: #6272a4;">-------------------------------------------------------------------------
</span><span style="color: #6272a4;">%%% </span><span style="color: #6272a4;">c&#225;lculos del color para un impacto
</span><span style="color: #6272a4;">%%%</span><span style="color: #6272a4;">-------------------------------------------------------------------------
</span>
<span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Calcula la dispersi&#243;n de la luz en basea M (material) e I (el impacto)
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #50fa7b; font-weight: bold;">dispersion_luz</span>(#<span style="color: #8be9fd; font-style: italic;">impacto</span>{material=<span style="color: #f8f8f2; font-weight: bold;">M</span>}=<span style="color: #f8f8f2; font-weight: bold;">I</span>) -&gt;
    <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">M</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
        #<span style="color: #8be9fd; font-style: italic;">material</span>{tipo=difuso} -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">Direccion_Dispersion</span> =
                <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.normal, <span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.p), <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">random_vector_unidad</span>()),
            <span style="color: #f8f8f2; font-weight: bold;">Dispersion</span> = #<span style="color: #8be9fd; font-style: italic;">rayo</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.p,dir=<span style="color: #f8f8f2; font-weight: bold;">Direccion_Dispersion</span>},
            <span style="color: #f8f8f2; font-weight: bold;">M</span>#<span style="color: #8be9fd; font-style: italic;">material</span>{dispersion=<span style="color: #f8f8f2; font-weight: bold;">Dispersion</span>};
        <span style="color: #f8f8f2; font-weight: bold;">_</span> -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">M</span>#<span style="color: #8be9fd; font-style: italic;">material</span>{albedo={1.0,0.0,1.0}}
    <span style="color: #ff79c6; font-weight: bold;">end</span>.
</pre>
</div>

<p>
De esta manera, debemos modificar también el registro de material en
el fichero <code>mundo.rerl</code>. Observese, que la dispersión se establece a
<code>nil</code> y el material a <code>difuso</code>:
</p>

<div class="org-src-container">
<pre class="src src-erlang">{objeto,{esfera,{0,0,-1},0.5},{material,difuso,{1.0,0.5,0.3},nil}}.
{objeto,{esfera,{0,-100.5,-1},100},{material,difuso,{0.5,0.3,1.0},nil}}.
</pre>
</div>

<p>
El resultado es el siguiente:
</p>


<figure id="orga5ff1d9">
<img src="./imagenes/imagen-material-difuso.png" alt="imagen-material-difuso.png">

</figure>

<p>
Como podemos observar hemos conseguido nuestras dos esferas con un
poco de color. Nada espectacular pero ya empieza a parecer un
<i>raytracer</i> de verdad.
</p>
</div>
</div>
<div id="outline-container-org6c1a06f" class="outline-2">
<h2 id="org6c1a06f">Material metálico</h2>
<div class="outline-text-2" id="text-org6c1a06f">
<p>
En el libro-tutorial que estoy siguiendo para programar este
<i>raytracer</i> con <code>erlang</code> llaman a los materiales reflexivos
<i>metálicos</i>. Por esto, yo he preferido llamarlo <code>reflexion</code>, no sólo
los metales reflejan la luz, otros materiales también lo
hacen. Reflejar el entorno lo hace cualquier superficie pulida, sea
plástico, vidrio, líquido, etc.
</p>

<p>
En el libro, cómo calcular la reflexión comienza con una aproximación
tal como se explica en la siguiente figura:
</p>


<figure id="org9b0739a">
<img src="./imagenes/reflexion.png" alt="reflexion.png">

</figure>

<p>
Como se ve, lo que se hace es continuar el rayo a partir del punto de
impacto y luego calcular otro que vaya del punto de impacto a dos
veces la distancia a la base del origen de la normal en el punto de
impacto. Es decir, nuestros cálculos tienen que encontrar un vector
con el mismo módulo que \(V\). Según la figura podemos decir que el rayo
verde, el que estamos buscando es \(V + 2b\). Para calcular el largo de
\(b\) podemos obtenerlo mediante \(V \cdot N\), puesto que, aunque nuestra
normal \(N\) tiene una longitud de \(1\), puede ser que \(V\) no. Además,
como los puntos que se encuentren <i>dentro</i> tienen valor negativo, la
fórmula de la reflexión quedaría como:
</p>

<p>
\[R = V - 2 \times (V \cdot N) \times N\]
</p>

<p>
Traducida a nuestro código en el fichero <code>rerl.erl</code> aparece la
siguiente función:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">C&#225;lculo del vector (V) reflejado al incidir en una superficie con
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">normal (N).
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #50fa7b; font-weight: bold;">reflexion</span>(<span style="color: #f8f8f2; font-weight: bold;">V</span>, <span style="color: #f8f8f2; font-weight: bold;">N</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">resta</span>(<span style="color: #f8f8f2; font-weight: bold;">V</span>, <span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>, 2 * <span style="color: #8be9fd; font-style: italic;">punto</span>(<span style="color: #f8f8f2; font-weight: bold;">V</span>, <span style="color: #f8f8f2; font-weight: bold;">N</span>))).
</pre>
</div>

<p>
Luego, en la resolución del material llamaremos a esta función con el
valor de la dirección del <i>rayo</i> que incide y la <i>normal</i> en ese punto.
</p>

<p>
La alternativa a estos cálculos hubiera sido calcular el ángulo de
incidencia y reflejar el rayo con el ángulo equivalente, que son más
costosos de calcular... y que ya los veremos en los cálculos de otros
materiales que también reflejan.
</p>

<p>
Al añadir un nuevo material, nuestro fichero de materiales añaden
también el cálculo de la dispersión para el tipo <code>reflexion</code>:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Calcula la dispersi&#243;n de la luz en basea M (material), I (el impacto) y
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">R (el rayo que incide).
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #50fa7b; font-weight: bold;">dispersion_luz</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>, #<span style="color: #8be9fd; font-style: italic;">impacto</span>{material=<span style="color: #f8f8f2; font-weight: bold;">M</span>}=<span style="color: #f8f8f2; font-weight: bold;">I</span>) -&gt;
    <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">M</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
        #<span style="color: #8be9fd; font-style: italic;">material</span>{tipo=difuso} -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">Direccion_Dispersion</span> =
                <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.normal, <span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.p), <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">random_vector_unidad</span>()),
            <span style="color: #f8f8f2; font-weight: bold;">Dispersion</span> = #<span style="color: #8be9fd; font-style: italic;">rayo</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.p,dir=<span style="color: #f8f8f2; font-weight: bold;">Direccion_Dispersion</span>},
            <span style="color: #f8f8f2; font-weight: bold;">M</span>#<span style="color: #8be9fd; font-style: italic;">material</span>{dispersion=<span style="color: #f8f8f2; font-weight: bold;">Dispersion</span>};
        #<span style="color: #8be9fd; font-style: italic;">material</span>{tipo=reflexion} -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">Reflexion</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">reflexion</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">vector_unidad</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir), <span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.normal),
            <span style="color: #f8f8f2; font-weight: bold;">Dispersion</span> = #<span style="color: #8be9fd; font-style: italic;">rayo</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.p,dir=<span style="color: #f8f8f2; font-weight: bold;">Reflexion</span>},
            <span style="color: #f8f8f2; font-weight: bold;">M</span>#<span style="color: #8be9fd; font-style: italic;">material</span>{dispersion=<span style="color: #f8f8f2; font-weight: bold;">Dispersion</span>};
        <span style="color: #f8f8f2; font-weight: bold;">_</span> -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">M</span>#<span style="color: #8be9fd; font-style: italic;">material</span>{albedo={1.0,0.0,1.0}}
    <span style="color: #ff79c6; font-weight: bold;">end</span>.
</pre>
</div>

<p>
Para probarlo, he modificado también el archivo <code>mundo.rerl</code> dejándolo
así:
</p>

<div class="org-src-container">
<pre class="src src-erlang">{objeto,{esfera,{0,0,-1},0.5},{material,difuso,{0.7,0.3,0.3},nil}}.
{objeto,{esfera,{0,-100.5,-1},100},{material,difuso,{0.8,0.8,0.0},nil}}.

{objeto,{esfera,{-1.0,0.0,-1.0},0.5},{material,reflexion,{0.8,0.8,0.8},nil}}.
{objeto,{esfera,{1.0,0.0,-1.0},0.5},{material,reflexion,{0.8,0.6,0.2},nil}}.
</pre>
</div>

<p>
el resultado, al generar la imagen es:
</p>


<figure id="org95f8faf">
<img src="./imagenes/imagen-metales.png" alt="imagen-metales.png">

</figure>

<p>
Como se puede apreciar, la reflexión de la luz produce objetos de
aspecto pulido y metálico. Pero no todos los metales están pulidos,
así que vamos a por el siguiente paso.
</p>
</div>
<div id="outline-container-orgd0c0594" class="outline-3">
<h3 id="orgd0c0594">Material reflexivo rugoso</h3>
<div class="outline-text-3" id="text-orgd0c0594">
<p>
Calcular la reflexión en un material rugoso es sencillo de imitar si
ya somos capaces, como somos, de hacer una reflexión perfecta. Basta
con modificar ligeramente la dirección del rayo reflejado, es decir
podemos simularlo desviando el rayo a un punto aleatorio dentro de una
esfera determinada, como se ve en la siguiente figura:
</p>


<figure id="orga7df7df">
<img src="./imagenes/reflexion-rugosa.png" alt="reflexion-rugosa.png">

</figure>

<p>
El valor de <i>rugosidad</i> podemos establecerlo como el radio de dicha
esfera. Así, una rugosidad de valor <code>0</code>, equivale a la reflexión
perfecta y un valor de rugosidad superior a <code>1</code> equivale a un material
prácticamente <i>difuso</i>.
</p>

<p>
Necesitamos añadir al registro de material el radio de dicha esfera
que he llamado <code>rugoso</code>. El registro del material queda, por tanto así:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-record</span>(<span style="color: #8be9fd; font-style: italic;">material</span>, { tipo       = nil           <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Tipo de material
</span>                  , albedo     = {0,0,0}       <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Factor de atenuaci&#243;n de color
</span>                  , rugoso     = 0             <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Nivel de rugosidad
</span>                  , dispersion = #<span style="color: #8be9fd; font-style: italic;">rayo</span>{}}).    <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Factor de dispersi&#243;n de la luz</span>
</pre>
</div>

<p>
Al añadir un valor más al registro hay que modificar también los
valores de los objetos en el fichero <code>mundo.rerl</code>:
</p>

<div class="org-src-container">
<pre class="src src-erlang">{objeto,{esfera,{0,0,-1},0.5},{material,difuso,{0.7,0.3,0.3},nil,nil}}.
{objeto,{esfera,{0,-100.5,-1},100},{material,difuso,{0.2,0.2,0.0},nil,nil}}.

{objeto,{esfera,{-1.0,0.0,-1.0},0.5},{material,reflexion,{0.8,0.8,0.8},0.3,nil}}.
{objeto,{esfera,{1.0,0.0,-1.0},0.5},{material,reflexion,{0.8,0.6,0.2},0.8,nil}}.
</pre>
</div>

<p>
Además, he añadido diferenciado el cálculo cuando la rugosidad es <code>0</code>
y cuando llega con otra rugosidad. En el caso de <code>0</code>, nos ahorramos
los cálculos de la rugosidad, que son más costosos de realizar.
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">dispersion_luz</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>, #<span style="color: #8be9fd; font-style: italic;">impacto</span>{material=<span style="color: #f8f8f2; font-weight: bold;">M</span>}=<span style="color: #f8f8f2; font-weight: bold;">I</span>) -&gt;
    <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">M</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
        #<span style="color: #8be9fd; font-style: italic;">material</span>{tipo=difuso} -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">Direccion_Dispersion</span> =
                <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.normal, <span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.p), <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">random_vector_unidad</span>()),
            <span style="color: #f8f8f2; font-weight: bold;">Dispersion</span> = #<span style="color: #8be9fd; font-style: italic;">rayo</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.p,dir=<span style="color: #f8f8f2; font-weight: bold;">Direccion_Dispersion</span>},
            <span style="color: #f8f8f2; font-weight: bold;">M</span>#<span style="color: #8be9fd; font-style: italic;">material</span>{dispersion=<span style="color: #f8f8f2; font-weight: bold;">Dispersion</span>};
        #<span style="color: #8be9fd; font-style: italic;">material</span>{tipo=reflexion,rugoso=0} -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">Reflexion</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">reflexion</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">vector_unidad</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir), <span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.normal),
            <span style="color: #f8f8f2; font-weight: bold;">Dispersion</span> = #<span style="color: #8be9fd; font-style: italic;">rayo</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.p,dir=<span style="color: #f8f8f2; font-weight: bold;">Reflexion</span>},
            <span style="color: #f8f8f2; font-weight: bold;">M</span>#<span style="color: #8be9fd; font-style: italic;">material</span>{dispersion=<span style="color: #f8f8f2; font-weight: bold;">Dispersion</span>};
        #<span style="color: #8be9fd; font-style: italic;">material</span>{tipo=reflexion,rugoso=<span style="color: #f8f8f2; font-weight: bold;">Rugosidad</span>} -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">Reflexion</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">reflexion</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">vector_unidad</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir), <span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.normal),
            <span style="color: #f8f8f2; font-weight: bold;">Dispersion</span> = #<span style="color: #8be9fd; font-style: italic;">rayo</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.p,dir=<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #f8f8f2; font-weight: bold;">Reflexion</span>, <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">random_en_esfera_unidad</span>(), <span style="color: #f8f8f2; font-weight: bold;">Rugosidad</span>))},
            <span style="color: #f8f8f2; font-weight: bold;">M</span>#<span style="color: #8be9fd; font-style: italic;">material</span>{dispersion=<span style="color: #f8f8f2; font-weight: bold;">Dispersion</span>};
        <span style="color: #f8f8f2; font-weight: bold;">_</span> -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">M</span>#<span style="color: #8be9fd; font-style: italic;">material</span>{albedo={1.0,0.0,1.0}}
    <span style="color: #ff79c6; font-weight: bold;">end</span>.
</pre>
</div>

<p>
Después de todos estos cambios, el resultado es la siguiente imagen:
</p>


<figure id="orgfd2d2a8">
<img src="./imagenes/imagen-metal-rugoso.png" alt="imagen-metal-rugoso.png">

</figure>

<p>
Podemos apreciar la diferencia entre las dos esferas reflexivas. A la
izquierda, la esfera plateada, con un valor <code>rugoso</code> de \(0.3\) refleja
mejor su entorno que la esfera de la derecha, con un valor de \(0.8\).
Además se puede apreciar el efecto del cambio de color.
</p>
</div>
</div>
</div>
<div id="outline-container-org93a46a9" class="outline-2">
<h2 id="org93a46a9">Materiales transparentes</h2>
<div class="outline-text-2" id="text-org93a46a9">
<p>
En el libro los llaman <i>materiales dieléctricos</i>. No sé si será un
<i>falso amigo</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, pero en castellano el término dieléctrico se
emplea para denominar a los materiales aislantes o que no conducen
bien la electricidad. Sin embargo, en el libro lo utilizan para
referirse a materiales transparentes... y no me parece que el agua sea
mala conductora de la electricidad, precisamente.
</p>

<p>
La refracción se basa en la <i>Ley de Snell o Descartes</i>.
</p>


<figure id="org2837080">
<img src="./imagenes/Refraccion.png" alt="Refraccion.png">

<figcaption><span class="figure-number">Figure 1: </span>Refracción (imagen tomada de la wikipedia).</figcaption>
</figure>

<p>
Básicamente, dicha ley establece que:
</p>

<p>
\[n_1 \cdot sen \theta_1 = n_2 \cdot sen \theta_2\]
</p>

<p>
donde \(n_1\) y \(n_2\) son los índices de refracción de dos medios en
contacto. Cuando un rayo incide en una superficie con un ángulo
\(\theta_1\) se transmite al siguiente medio con un ángulo \(\theta_2\).
</p>

<p>
Para calcular el ángulo con el que se refracta el rayo en el segundo
medio, podemos despejar en la ecuación anterior:
</p>

<p>
\[sen \theta_2 = \frac{n_1}{n_2} \cdot sen \theta_1\]
</p>

<p>
En el lado de la refracción el <i>rayo refractado</i> \(R\), forma un ángulo
\(\theta_2\) con la normal en ese lado. Pero podemos descomponer dicho
rayo \(R\) en dos componentes: uno perpendicular a dicha normal y otro
paralelo a la normal:
</p>

<p>
\[R = R_{perpend.} + R_{paralelo}\]
</p>

<p>
Si resolvemos estos componentes por separado tenemos:
</p>

<p>
\[R_{perpend.} = \frac{n_1}{n_2} (R_1 + cos \theta_1)\]
</p>

<p>
\[R_{paralelo} = - \sqrt{1 - |R_{perpend.}|^2} \cdot n_1\]
</p>

<p>
También tendremos que resolver \(cos \theta_1\), pero sabemos que el
producto escalar de dos vectores lo podemos expresar como el producto
de sus módulos con el <i>coseno</i> del ángulo que forman, es decir:
</p>

<p>
\[a \cdot b = |a| |b| cos \theta\]
</p>

<p>
Si lo restringimos el módulo de esos vectores a \(1\):
</p>

<p>
\[a \cdot b = cos \theta\]
</p>

<p>
Y por tanto, en las ecuaciones anteriores podemos escribir
\(R_{perpend.}\) como
</p>

<p>
\[R_{perpend.} = \frac{n_1}{n_2} (R_1 + (-R_1 \cdot n_1)n_1)\]
</p>

<p>
Después de esta introducción matemática, el código para calcular la
refracción en el fichero <code>rerl.erl</code> la dejamos de la siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">C&#225;lculo del vector refractado al inicidir un rayo con direcci&#243;n UV
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">en una superficie con normal N y un factor de refracci&#243;n
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">determinado por N_div_N
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #50fa7b; font-weight: bold;">refraccion</span>(<span style="color: #f8f8f2; font-weight: bold;">UV</span>, <span style="color: #f8f8f2; font-weight: bold;">N</span>, <span style="color: #f8f8f2; font-weight: bold;">N_div_N</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Coseno</span> = <span style="color: #8be9fd; font-style: italic;">punto</span>(<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">UV</span>, -1), <span style="color: #f8f8f2; font-weight: bold;">N</span>),
    <span style="color: #f8f8f2; font-weight: bold;">R_perp</span> = <span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #f8f8f2; font-weight: bold;">UV</span>, <span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>, <span style="color: #f8f8f2; font-weight: bold;">Coseno</span>)), <span style="color: #f8f8f2; font-weight: bold;">N_div_N</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Raiz</span> = <span style="color: #8be9fd; font-style: italic;">math</span>:<span style="color: #8be9fd; font-style: italic;">sqrt</span>(<span style="color: #8be9fd; font-style: italic;">abs</span>(1 - <span style="color: #8be9fd; font-style: italic;">modulo_cuadrado</span>(<span style="color: #f8f8f2; font-weight: bold;">R_perp</span>))),
    <span style="color: #f8f8f2; font-weight: bold;">R_parl</span> = <span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>, -<span style="color: #f8f8f2; font-weight: bold;">Raiz</span>),
    <span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #f8f8f2; font-weight: bold;">R_perp</span>, <span style="color: #f8f8f2; font-weight: bold;">R_parl</span>).
</pre>
</div>

<p>
En los cálculos de la refracción, he preferido hacer algunos cálculos
por partes para no perderme yo mismo. Sin embargo, se puede comprobar
fácilmente que el código se corresponde con la fórmulas explicadas
anteriormente.
</p>

<p>
Luego, en la parte de tratamiento de los materiales se ha añadido un
apartado para los materiales transparentes:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">dispersion_luz</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>, #<span style="color: #8be9fd; font-style: italic;">impacto</span>{material=<span style="color: #f8f8f2; font-weight: bold;">M</span>,cara_frontal=<span style="color: #f8f8f2; font-weight: bold;">Frontal</span>}=<span style="color: #f8f8f2; font-weight: bold;">I</span>) -&gt;
  <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">M</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
      <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">....
</span>      #<span style="color: #8be9fd; font-style: italic;">material</span>{tipo=transparente,ir=<span style="color: #f8f8f2; font-weight: bold;">Ir</span>} -&gt;
          <span style="color: #f8f8f2; font-weight: bold;">Ratio_Refraccion</span> =
              <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">Frontal</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
                  true -&gt;
                      1.0 / <span style="color: #f8f8f2; font-weight: bold;">Ir</span>;
                  false -&gt;
                      <span style="color: #f8f8f2; font-weight: bold;">Ir</span>
              <span style="color: #ff79c6; font-weight: bold;">end</span>,
          <span style="color: #f8f8f2; font-weight: bold;">Direccion_Unidad</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">vector_unidad</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir),      <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Convertir la direcci&#243;n en un vector m&#243;dulo 1
</span>          <span style="color: #f8f8f2; font-weight: bold;">Refractado</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">refraccion</span>(<span style="color: #f8f8f2; font-weight: bold;">Direccion_Unidad</span>, <span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.normal, <span style="color: #f8f8f2; font-weight: bold;">Ratio_Refraccion</span>),
          <span style="color: #f8f8f2; font-weight: bold;">Dispersion</span> = #<span style="color: #8be9fd; font-style: italic;">rayo</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.p,dir=<span style="color: #f8f8f2; font-weight: bold;">Refractado</span>},
          <span style="color: #f8f8f2; font-weight: bold;">M</span>#<span style="color: #8be9fd; font-style: italic;">material</span>{dispersion=<span style="color: #f8f8f2; font-weight: bold;">Dispersion</span>};
    <span style="color: #f8f8f2; font-weight: bold;">_</span> -&gt;
          ok
  <span style="color: #ff79c6; font-weight: bold;">end</span>.
</pre>
</div>

<p>
En la primera parte del código para este material comprobamos si el
<i>impacto</i> es en la superficie exterior o la interior. Si el caso es
que el choque es en la parte interna de la superficie tenemos que
devolver el rayo a la trayectoria que traía en el aire. Después,
simplemente se llama a la función explicada anteriormente para
calcular la <i>dispersión</i>.
</p>

<p>
Convertí una de las esferas en transparente para ver cómo se veía y el
código del mundo quedó así:
</p>

<div class="org-src-container">
<pre class="src src-erlang">{objeto,{esfera,{0,0,-1},0.5},{material,difuso,{0.7,0.3,0.3},nil,nil,nil}}.
{objeto,{esfera,{0,-100.5,-1},100},{material,difuso,{0.2,0.2,0.0},nil,nil,nil}}.

{objeto,{esfera,{-1.0,0.0,-1.0},0.5},{material,transparente,{1.0,1.0,1.0},nil,1.5,nil}}.
{objeto,{esfera,{1.0,0.0,-1.0},0.5},{material,reflexion,{0.8,0.6,0.2},0.8,nil,nil}}.
</pre>
</div>

<p>
El resultado obtenido es el siguiente:
</p>


<figure id="orgb8866b7">
<img src="./imagenes/imagen-transparente.png" alt="imagen-transparente.png">

</figure>

<p>
Viendo ese resultado resulta que bueno, sí, es transparente y refracta
la luz, pero ¿no es demasiado? ¿no resulta irreal? Sí, ¿no?
</p>

<p>
Eso es por una razón muy sencilla: no todos los rayos que impactan con
una superficie transparente se refractan.
</p>


<figure id="org2ad795e">
<img src="./imagenes/refraccion_y_reflexion.png" alt="refraccion_y_reflexion.png">

<figcaption><span class="figure-number">Figure 2: </span>Ángulo crítico (Imagen tomada de la wikipedia).</figcaption>
</figure>

<p>
Cuando los rayos inciden en la superficie con un determinado ángulo se
refracta, pero si ese ángulo es el <i>ángulo crítico</i> puede no conseguir
refractarse y si sobrepasa dicho ángulo se refleja reflejarse.
</p>
</div>
</div>
<div id="outline-container-org3bc4763" class="outline-2">
<h2 id="org3bc4763">Hacia una refracción más realista</h2>
<div class="outline-text-2" id="text-org3bc4763">
<p>
Bueno, pues tenemos que volver a la Ley de Snell:
</p>

<p>
\[n_1 \cdot sen \theta_1 = n_2 \cdot sen \theta_2\]
</p>

<p>
Pero si consideramos que la esfera es de vidrio (índice de refracción \(n_1 = 1.5\)) y el
entorno es aire (índice de refracción \(n_2 = 1.0\)), entonces:
</p>

<p>
\[sen \theta_2 = \frac{n_1}{n_2} \cdot sen \theta_1\]
</p>

<p>
Puesto que \(sen \theta_2\) no puede ser superior a \(1\)<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> si resulta
que
</p>

<p>
\[sen \theta_2 = frac{n_1}{n_2} > 1.0\]
</p>

<p>
el rayo estará incidiendo en un ángulo en el que no puede refractarse
y por tanto debería reflejarse. Algo que tenemos fácilmente podemos
comprobar mirando el agua y viendo cómo se reflejan los objetos de la
otra orilla del río y sin embargo vemos el fondo en la orilla a
nuestros pies. A eso se le llama <i>reflectancia</i> o <i>refelctividad</i>.
</p>

<p>
Bien, vale, pero ¿cómo calculamos el \(sen \theta\)? Pues vamos a partir
de la ecuación básica de la trigonometría:
</p>

<p>
\[1 = sen^2 \theta + cos^2 \theta\]
</p>

<p>
y si despejamos
</p>

<p>
\[sen \theta = \sqrt{1 - cos^2 \theta}\]
</p>

<p>
y como vimos antes
</p>

<p>
\[cos \theta = R \cdot n\]
</p>

<p>
donde \(R\) es la dirección del rayo que incide y \(n\) la normal del
punto, si su módulo es igual a <code>1</code>, como hicimos antes. Puedo
enrollarme con más explicaciones, pero creo que está suficientemente
claro el proceso de razonamiento.
</p>

<p>
El código que resume todas estas disquisiciones queda así:
</p>

<div class="org-src-container">
<pre class="src src-erlang">#<span style="color: #8be9fd; font-style: italic;">material</span>{tipo=transparente,ir=<span style="color: #f8f8f2; font-weight: bold;">Ir</span>} -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Ratio_Refraccion</span> =
        <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">Frontal</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
            true -&gt;
                1.0 / <span style="color: #f8f8f2; font-weight: bold;">Ir</span>;
            false -&gt;
                <span style="color: #f8f8f2; font-weight: bold;">Ir</span>
        <span style="color: #ff79c6; font-weight: bold;">end</span>,
    <span style="color: #f8f8f2; font-weight: bold;">Direccion_Unidad</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">vector_unidad</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir),
    <span style="color: #f8f8f2; font-weight: bold;">Coseno</span> = <span style="color: #8be9fd; font-style: italic;">min</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">punto</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">Direccion_Unidad</span>, -1), <span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.normal), 1.0),
    <span style="color: #f8f8f2; font-weight: bold;">Seno</span> = <span style="color: #8be9fd; font-style: italic;">math</span>:<span style="color: #8be9fd; font-style: italic;">sqrt</span>(1 - <span style="color: #f8f8f2; font-weight: bold;">Coseno</span> * <span style="color: #f8f8f2; font-weight: bold;">Coseno</span>),
    <span style="color: #f8f8f2; font-weight: bold;">No_Refracta</span> = <span style="color: #f8f8f2; font-weight: bold;">Seno</span> * <span style="color: #f8f8f2; font-weight: bold;">Ratio_Refraccion</span> &gt; 1,
    <span style="color: #f8f8f2; font-weight: bold;">Refractado</span> =
        <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">No_Refracta</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
            true -&gt;
                <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Si no refracta, refleja
</span>                <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">reflexion</span>(<span style="color: #f8f8f2; font-weight: bold;">Direccion_Unidad</span>, <span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.normal);
            false -&gt;
                <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">refraccion</span>(<span style="color: #f8f8f2; font-weight: bold;">Direccion_Unidad</span>, <span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.normal, <span style="color: #f8f8f2; font-weight: bold;">Ratio_Refraccion</span>)
        <span style="color: #ff79c6; font-weight: bold;">end</span>,
    <span style="color: #f8f8f2; font-weight: bold;">Dispersion</span> = #<span style="color: #8be9fd; font-style: italic;">rayo</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.p,dir=<span style="color: #f8f8f2; font-weight: bold;">Refractado</span>},
    <span style="color: #f8f8f2; font-weight: bold;">M</span>#<span style="color: #8be9fd; font-style: italic;">material</span>{dispersion=<span style="color: #f8f8f2; font-weight: bold;">Dispersion</span>};
</pre>
</div>

<p>
Es decir, se comprueba si el rayo refleja o refracta y se utiliza una
fórmula u otra según el caso.
</p>

<p>
Para el mismo <i>mundo</i> el resultado es:
</p>


<figure id="org985f4c2">
<img src="./imagenes/imagen-refraccion-reflexion.png" alt="imagen-refraccion-reflexion.png">

</figure>

<p>
Puede parecer que a simple vista no hay mucha diferencia con el método
anterior pero no es así. Lo que ocurre es que parece que sólo se
aplica la reflexión a los rayos que han conseguido entrar en el
objeto... faltan los rayos reflejados en el exterior. También se puede
apreciar en el tiempo de <i>render</i>, puesto que las reflexiones cuesta
menos calcularlas que las refracciones.
</p>

<p>
Aún nos queda calcular la <i>reflectancia</i> o <i>refelctividad</i> exterior
para tener un material más ajustado a la realidad. Pero ésta tiene una
fórmula compleja. En el libro-tutorial que estoy siguiendo utiliza la
aproximación polinomial de <i>Christopher Schlick</i> afirmando que es
suficientemente precisa. La fórmula sería:
</p>

<p>
\[Reflectancia = r_0 + (1 - r_0) \times (1 - cos \theta)^5\]
</p>

<p>
donde \(r_0 = (\frac{1-i_r}{1+i_r})^2\) siendo \(i_r\) el índice de
refracción.
</p>

<p>
Traduciéndolo a código en el fichero <code>rerl.erl</code> nos queda dicha
aproximación así:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Calcula la reflectancia de una superficie en base al coseno (Cos)
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">del &#225;ngulo con que se mira y el &#237;ndice de refracci&#243;n Ir.
</span><span style="color: #50fa7b; font-weight: bold;">reflectancia</span>(<span style="color: #f8f8f2; font-weight: bold;">Cos</span>, <span style="color: #f8f8f2; font-weight: bold;">Ir</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">R</span> = (1 - <span style="color: #f8f8f2; font-weight: bold;">Ir</span>) / (1 + <span style="color: #f8f8f2; font-weight: bold;">Ir</span>),
    <span style="color: #f8f8f2; font-weight: bold;">R0</span> = <span style="color: #f8f8f2; font-weight: bold;">R</span> * <span style="color: #f8f8f2; font-weight: bold;">R</span>,
    <span style="color: #f8f8f2; font-weight: bold;">R0</span> + (1 - <span style="color: #f8f8f2; font-weight: bold;">R0</span>) * <span style="color: #8be9fd; font-style: italic;">math</span>:<span style="color: #8be9fd; font-style: italic;">pow</span>((1 - <span style="color: #f8f8f2; font-weight: bold;">Cos</span>), 5).
</pre>
</div>

<p>
Además, para tenerla en cuenta en nuestro material, el código es el
siguiente:
</p>

<div class="org-src-container">
<pre class="src src-erlang">#<span style="color: #8be9fd; font-style: italic;">material</span>{tipo=transparente,ir=<span style="color: #f8f8f2; font-weight: bold;">Ir</span>} -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Ratio_Refraccion</span> =
        <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">Frontal</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
            true -&gt;
                1.0 / <span style="color: #f8f8f2; font-weight: bold;">Ir</span>;
            false -&gt;
                <span style="color: #f8f8f2; font-weight: bold;">Ir</span>
        <span style="color: #ff79c6; font-weight: bold;">end</span>,
    <span style="color: #f8f8f2; font-weight: bold;">Direccion_Unidad</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">vector_unidad</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir),
    <span style="color: #f8f8f2; font-weight: bold;">Coseno</span> = <span style="color: #8be9fd; font-style: italic;">min</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">punto</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">Direccion_Unidad</span>, -1), <span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.normal), 1.0),
    <span style="color: #f8f8f2; font-weight: bold;">Seno</span> = <span style="color: #8be9fd; font-style: italic;">math</span>:<span style="color: #8be9fd; font-style: italic;">sqrt</span>(1 - <span style="color: #f8f8f2; font-weight: bold;">Coseno</span> * <span style="color: #f8f8f2; font-weight: bold;">Coseno</span>),
    <span style="color: #f8f8f2; font-weight: bold;">No_Refracta</span> = (<span style="color: #f8f8f2; font-weight: bold;">Seno</span> * <span style="color: #f8f8f2; font-weight: bold;">Ratio_Refraccion</span> &gt; 1) <span style="color: #8be9fd; font-style: italic;">orelse</span> (<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">reflectancia</span>(<span style="color: #f8f8f2; font-weight: bold;">Coseno</span>, <span style="color: #f8f8f2; font-weight: bold;">Ratio_Refraccion</span>) &gt; <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">random</span>()),
    <span style="color: #f8f8f2; font-weight: bold;">Refractado</span> =
        <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">No_Refracta</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
            true -&gt;
                <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Si no refracta, refleja
</span>                <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">reflexion</span>(<span style="color: #f8f8f2; font-weight: bold;">Direccion_Unidad</span>, <span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.normal);
            false -&gt;
                <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">refraccion</span>(<span style="color: #f8f8f2; font-weight: bold;">Direccion_Unidad</span>, <span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.normal, <span style="color: #f8f8f2; font-weight: bold;">Ratio_Refraccion</span>)
        <span style="color: #ff79c6; font-weight: bold;">end</span>,
    <span style="color: #f8f8f2; font-weight: bold;">Dispersion</span> = #<span style="color: #8be9fd; font-style: italic;">rayo</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">I</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.p,dir=<span style="color: #f8f8f2; font-weight: bold;">Refractado</span>},
    <span style="color: #f8f8f2; font-weight: bold;">M</span>#<span style="color: #8be9fd; font-style: italic;">material</span>{dispersion=<span style="color: #f8f8f2; font-weight: bold;">Dispersion</span>};
</pre>
</div>

<p>
Como se puede apreciar, se añadido otra condición para no refractar y
reflejarse, el resto del código se mantiene exactamente igual.
</p>

<p>
Para mostrar mejor el efecto de la reflectancia he cambiado algunos
parámetros de la imagen: la he hecho de 800 de ancho y he subido las
muestras a 500 en lugar de las 100 habituales. El resultado conseguido
es éste:
</p>


<figure id="org89a4f33">
<img src="./imagenes/imagen-suavizada.png" alt="imagen-suavizada.png">

</figure>

<p>
Se puede apreciar el reflejo de la bola central en nuestra bola
transparente (aunque se aprecia mejor en las zonas oscuras). También
podemos ver el reflejo del fondo sobre la parte superior de la bola
transparente. En esa imagen tenemos ejemplos de los tres materiales
básicos. Nuestro <i>raytracer</i> va tomando forma.
</p>
</div>
</div>
<div id="outline-container-org174a823" class="outline-2">
<h2 id="org174a823">Reorganización del proceso de <i>render</i></h2>
<div class="outline-text-2" id="text-org174a823">
<p>
Por último, en la versión actual se ha remodelado el proceso de
<i>render</i>. Hasta ahora venía haciéndose desde el fichero <code>rerl.erl</code>,
cuya función principal es contener las funciones de cálculo comunes a
todos los demás procesos.
</p>

<p>
Se ha creado un fichero <code>escena.erl</code> cuya única función es generar el
proceso de imagen, crear los objetos que intervienen en la escena,
crear la cámara, ajustarla y ponerla en marcha. El código ha quedado
así:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-module</span>(escena).

<span style="color: #ffb86c;">-include</span>(<span style="color: #f1fa8c;">"registros.hrl"</span>).

<span style="color: #ffb86c;">-export</span>([<span style="color: #8be9fd; font-style: italic;">escena/0</span>]).

<span style="color: #50fa7b; font-weight: bold;">escena</span>() -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Nombre</span> = <span style="color: #f1fa8c;">"imagen.ppm"</span>,                  <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Nombre del fichero de imagen generado
</span>    <span style="color: #f8f8f2; font-weight: bold;">O</span> = {0,0,0},                            <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Origen de la c&#225;mara
</span>    <span style="color: #f8f8f2; font-weight: bold;">Ratio</span> = 16 / 9,                         <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Ratio ancho/alto de la imagen
</span>    <span style="color: #f8f8f2; font-weight: bold;">Ancho</span> = 400,                            <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Ancho en puntos de la imagen
</span>    <span style="color: #f8f8f2; font-weight: bold;">Muestras</span> = 100,                         <span style="color: #6272a4;">% </span><span style="color: #6272a4;">N&#186; de muestras por pixel
</span>    <span style="color: #f8f8f2; font-weight: bold;">Profun</span> = 50,                            <span style="color: #6272a4;">% </span><span style="color: #6272a4;">N&#250;mero de &#171;rebotes&#187; por rayo.
</span>    <span style="color: #f8f8f2; font-weight: bold;">Tesela</span> = 25,                            <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Tama&#241;o del lado de la tesela en puntos
</span>    <span style="color: #f8f8f2; font-weight: bold;">Procesos</span> = 10,                          <span style="color: #6272a4;">% </span><span style="color: #6272a4;">N&#250;mero de procesos de c&#225;lculo
</span>
    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Preparar la imagen para el render
</span>    <span style="color: #f8f8f2; font-weight: bold;">Pid</span> = <span style="color: #8be9fd; font-style: italic;">rerl_imagen</span>:<span style="color: #8be9fd; font-style: italic;">start</span>({<span style="color: #f8f8f2; font-weight: bold;">Ancho</span>,<span style="color: #f8f8f2; font-weight: bold;">Ratio</span>,<span style="color: #f8f8f2; font-weight: bold;">Nombre</span>}),
    <span style="color: #8be9fd; font-style: italic;">register</span>(imagen, <span style="color: #f8f8f2; font-weight: bold;">Pid</span>),

    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Materiales
</span>    <span style="color: #f8f8f2; font-weight: bold;">Material_Suelo</span> = #<span style="color: #8be9fd; font-style: italic;">material</span>{tipo=difuso,albedo={0.2,0.2,0.0}},
    <span style="color: #f8f8f2; font-weight: bold;">Difuso</span> = #<span style="color: #8be9fd; font-style: italic;">material</span>{tipo=difuso,albedo={0.7,0.3,0.3}},
    <span style="color: #f8f8f2; font-weight: bold;">Cristal</span> = #<span style="color: #8be9fd; font-style: italic;">material</span>{tipo=transparente,albedo={1.0,1.0,1.0},ir=1.5},
    <span style="color: #f8f8f2; font-weight: bold;">Metal</span> = #<span style="color: #8be9fd; font-style: italic;">material</span>{tipo=reflexion,albedo={0.8,0.6,0.2},rugoso=0.3},

    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Esferas
</span>    <span style="color: #f8f8f2; font-weight: bold;">Esfera_Suelo</span> = #<span style="color: #8be9fd; font-style: italic;">esfera</span>{centro={0,-100.5,-1},radio=100},
    <span style="color: #f8f8f2; font-weight: bold;">Esfera_Central</span> = #<span style="color: #8be9fd; font-style: italic;">esfera</span>{centro={0,0,-1},radio=0.5},
    <span style="color: #f8f8f2; font-weight: bold;">Esfera_Izda</span> = #<span style="color: #8be9fd; font-style: italic;">esfera</span>{centro={-1.0,0.0,-1.0},radio=0.5},
    <span style="color: #f8f8f2; font-weight: bold;">Esfera_Dcha</span> = #<span style="color: #8be9fd; font-style: italic;">esfera</span>{centro={1.0,0.0,-1.0},radio=0.5},

    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Montar los objetos
</span>    <span style="color: #f8f8f2; font-weight: bold;">Objs</span> = [#<span style="color: #8be9fd; font-style: italic;">objeto</span>{geom=<span style="color: #f8f8f2; font-weight: bold;">Esfera_Central</span>,material=<span style="color: #f8f8f2; font-weight: bold;">Difuso</span>}
          , #<span style="color: #8be9fd; font-style: italic;">objeto</span>{geom=<span style="color: #f8f8f2; font-weight: bold;">Esfera_Suelo</span>,material=<span style="color: #f8f8f2; font-weight: bold;">Material_Suelo</span>}
          , #<span style="color: #8be9fd; font-style: italic;">objeto</span>{geom=<span style="color: #f8f8f2; font-weight: bold;">Esfera_Izda</span>,material=<span style="color: #f8f8f2; font-weight: bold;">Cristal</span>}
          , #<span style="color: #8be9fd; font-style: italic;">objeto</span>{geom=<span style="color: #f8f8f2; font-weight: bold;">Esfera_Dcha</span>,material=<span style="color: #f8f8f2; font-weight: bold;">Metal</span>}],

    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Iniciando la c&#225;mara...~n"</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Pid_camara</span> = <span style="color: #8be9fd; font-style: italic;">rerl_camara</span>:<span style="color: #8be9fd; font-style: italic;">start</span>({<span style="color: #f8f8f2; font-weight: bold;">O</span>,<span style="color: #f8f8f2; font-weight: bold;">Ratio</span>,<span style="color: #f8f8f2; font-weight: bold;">Ancho</span>,<span style="color: #f8f8f2; font-weight: bold;">Muestras</span>,<span style="color: #f8f8f2; font-weight: bold;">Profun</span>}),
    <span style="color: #8be9fd; font-style: italic;">register</span>(camara, <span style="color: #f8f8f2; font-weight: bold;">Pid_camara</span>),

    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Preparar procesos y lanzar el render
</span>    camara ! {mosaico,<span style="color: #f8f8f2; font-weight: bold;">Tesela</span>,<span style="color: #f8f8f2; font-weight: bold;">Procesos</span>},
    camara ! {render,<span style="color: #f8f8f2; font-weight: bold;">Objs</span>}.
</pre>
</div>

<p>
El proceso es casi el mismo. Sin embargo, hay que remarcar que después
de establecer los datos del <i>render</i> y la <i>imagen</i> se crean los
materiales y objetos que van a formar parte del <i>mundo</i> que hay
generar. Por tanto, prescindimos del archivo <code>mundo.rerl</code> que veníamos
utilizando hasta ahora, ─como hemos visto en los apartados
anteriores─. A partir de ahora, las modificaciones en la escena se
harán en este fichero.
</p>

<p>
Además, las funciones de reflexión y refracción de la luz se han
movido al módulo <code>rerl_material</code>, puesto que únicamente se llaman
desde él.
</p>
</div>
</div>
<div id="outline-container-org317c4da" class="outline-2">
<h2 id="org317c4da">Iluminación</h2>
<div class="outline-text-2" id="text-org317c4da">
<p>
Alguien<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> me preguntó por el tipo de iluminación que se emplea en el
libro. La respuesta corta es <i>Ambient Occlusion</i>. Es un sistema de
iluminación quizá más complejo de explicar que otros que necesitan
fuentes de luz. La base de este tipo de iluminación consiste en
calcular la <i>luz ambiente</i>, la que rebota de objetos a objetos.
</p>

<p>
Suele calcularse como:
</p>

<p>
\[A_{(\omega,n)} = \frac{1}{\pi} \int_{\omega \in \Omega} V_{(x,\omega)} |\omega \cdot n| d\omega\]
</p>

<p>
Al no haber fuentes de luz, la iluminación se parece a un día nublado,
sin sombras contrastadas. En nuestro caso, la intensidad de la luz
dependerá también del color del fondo. Cuanto más claro es el fondo
más iluminación hay.
</p>

<p>
Por ejemplo, si elegimos colores más oscuros para nuestro fondo:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>({0.2,0.0,0.2}, (1-<span style="color: #f8f8f2; font-weight: bold;">T</span>)),
          <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>({0.1,0.3,0.5},  <span style="color: #f8f8f2; font-weight: bold;">T</span>))
</pre>
</div>

<p>
obtenemos:
</p>


<figure id="org6bf1aea">
<img src="./imagenes/imagen-oc-oscuro.png" alt="imagen-oc-oscuro.png">

</figure>


<figure id="org86bd5d0">
<img src="./imagenes/imagen-oc-claro.png" alt="imagen-oc-claro.png">

</figure>

<p>
Esta segunda imagen está generada con un fondo absolutamente blanco,
para que se pueda comparar la diferencia en la iluminación de ambas
imágenes.
</p>

<p>
No podría decir por qué el autor del tutorial ha elegido esa
iluminación para la parte más básica del <i>raytracer</i>. Supongo, y es
una impresión totalmente subjetiva mía, que aunque es más difícil de
explicar, ─de hecho no lo explica en ningún sitio del libro y además
su computación es más exigente que para otros modelos de iluminación,
como la tipo <i>phong</i> que necesita fuentes de luz─, le ha permitido
generar imágenes desde el <i>minuto cero</i> del tutorial e ir añadiendo
características sin crear ningún tipo de objeto luminoso. Pero ya
digo, que es una especulación mía.
</p>
</div>
</div>
<div id="outline-container-orgb5f840d" class="outline-2">
<h2 id="orgb5f840d">Conclusiones</h2>
<div class="outline-text-2" id="text-orgb5f840d">
<p>
Nuestro <i>raytracer</i> va tomando forma poco a poco, aunque aún está en
mantillas ya que sólo admite como geometría de los objetos la esfera,
los materiales hacen su función de una manera solvente. Además, cuenta
con un procesamiento en paralelo de la imagen.
</p>

<p>
En las siguientes entregas nos meteremos más a fondo con la cámara
haciendo que pueda variar su posición, su orientación, dotarla de zoom
y profundidad de campo... en fin, hacerla parecer más una cámara
completa.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Falso amigo</i> se denominan los términos que parecen significar
algo en una lengua pero significan otra. Uno de esos <i>falsos amigos</i>
que más gustan a los angloparlantes en <i>Esperanto</i> es: «Homo penis
longe», cuya traducción al castellano es: <i>persona que se ha esforzado
durante mucho tiempo</i>, aunque los <i>anglos</i> suelen entender otras cosas
raras.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Supongo que a estas alturas todo el mundo sabe que \(0 < sen \mbox{ } \alpha < 1\)
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ya me disculparás, pero no recuerdo quién me hizo la pregunta. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/raytracer/index.html">raytracer</a> <a href="/tags/erlang/index.html">erlang</a> ]]></description>
  <category><![CDATA[raytracer]]></category>
  <category><![CDATA[erlang]]></category>
  <link>https://notxor.nueva-actitud.org/2020/12/01/materiales.html</link>
  <pubDate>Tue, 01 Dec 2020 00:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Probando fossil]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-11-30</div>
<p>
En algún sitio leí que <code>fossil</code> <i>is a github in a box</i>, y realmente lo
parece. Desde que el otro día leyera <a href="https://victorhckinthefreeworld.com/2020/11/25/fossil-la-alternativa-a-git/">el artítulo sobre <code>fossil</code> del
amigo Victor</a> me entró la curiosidad y ando probándolo. Mi objetivo es
hacer un resumen de mis impresiones, si queréis o necesitáis más
información la podéis encontrar en <a href="https://fossil-scm.org">el sitio web</a>. Y para avanzar un
poco, lo que veréis en esa página, precisamente, es el repositorio
<code>fossil</code> de <code>fossil</code>... para no marear más la perdiz, vamos al lío.
</p>
<div id="outline-container-org756e830" class="outline-2">
<h2 id="org756e830">¿Qué es <code>fossil</code>?</h2>
<div class="outline-text-2" id="text-org756e830">
<p>
Dicho de forma rápida es un gestor de versiones, como lo son <code>git</code>,
<code>Mercurial</code>, <code>bazaar</code>, o <code>cvs</code> o <code>svn</code>, por poner algunos ejemplos. De
hecho, el mismo Víctor lo presenta en el título de su artículo como un
<i>sustituto de git</i>. Y la verdad es que se puede decir eso... a grandes
rasgos lo puede ser, pero no es sólo eso. Si entramos en detalles no
son herramientas equivalentes.  <code>fossil</code> excede el mero hecho de lo
que se puede llamar <i>control de versiones</i> y para explicarlo habría
que compararlo con un sistema estilo <code>github</code> o <code>gitea</code>, metido en un
ejecutable.
</p>

<p>
En la página <i>web</i> de <code>fossil</code>, que por cierto es un <i>repositorio</i>
<code>fossil</code>, como ya he dicho antes, explican las principales
características con las que cuenta. No voy a repetirlas aquí, pero voy
a hacer algunas anotaciones.  Las características que me parecen más
remarcables, además del propio control de versiones son:
</p>

<ol class="org-ol">
<li><b>Herramientas de trabajo en equipo</b>: viene con control de errores,
foro, <i>wiki</i> y lo que llaman <i>anotaciones técnicas</i> (<i>technotes</i>)
que son páginas <i>wiki</i> que tienen asociado un momento temporal y
que aparecerán en el <i>timeline</i> del repositorio ─si queremos que
aparezcan─ para explicar algo sobre el código o el programa, como
puede ser un <i>cambio de versión</i> o cualquier otro tema relacionado
con el <i>software</i>.</li>

<li><b>Interface <i>web</i> del repositorio</b>: el comando <code>fossil ui</code> nos abre
un navegador<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. Por defecto nos arrancará en el <i>timeline</i>.</li>
</ol>


<figure id="orgb4c0b16">
<img src="./imagenes/Screenshot_2020-11-29_rerl_Timeline.png" alt="Screenshot_2020-11-29_rerl_Timeline.png">

</figure>

<p>
En el <i>timeline</i> no sólo constan los <i>commits</i> de código que
hagamos, sino también puede mostrarnos los cambios que hagamos en
el <i>wiki</i>, las etiquetas, o en cualquier otro contenido del
repositorio. Pero como digo, se puede filtrar qué información
mostrar en la misma <i>UI</i>.
</p>

<ol class="org-ol">
<li><b>Documentación completa de la herramienta</b>: integrado en la misma
<i>interface web</i> provee un sistema de ayuda que proporciona
información para todas las opciones de la línea de comandos y
muchas más cosas. Es decir, viene con su propio sistema de ayuda
cargado y preparado para que no necesitemos consultar ningún manual
fuera de la propia herramienta.</li>
</ol>


<figure id="org9f0b6ed">
<img src="./imagenes/Screenshot_2020-11-29_rerl_Help.png" alt="Screenshot_2020-11-29_rerl_Help.png">

</figure>

<ol class="org-ol">
<li><b>Sencillo, autocontenido</b>: todo está contenido en un sólo
ejecutable. No hay complejas dependencias ni de <i>plugins</i>. Y los
repositorios se guardan en ficheros de bases de datos <code>sqlite3</code>
haciendo que toda la información esté junta sin dispersar ficheros
por directorios.</li>

<li><b>Completa información</b>: Proporciona una completa información sobre
el código y sobre los <i>commits</i>. Por ejemplo, se puede visualizar
las anotaciones en un fichero.</li>
</ol>


<figure id="org2be7c0c">
<img src="./imagenes/Captura-vista-fichero.png" alt="Captura-vista-fichero.png">

</figure>

<p>
También se puede visualizar la información completa de un
determinado <i>commit</i>, incluyendo <i>diff</i>. Además de que permite
modificar los datos de los mismos, como puede ser el comentario con
el que se realizó la modificación u otros datos.
</p>


<figure id="org1bef236">
<img src="./imagenes/Screenshot_2020-11-29_rerl_Check-in_[df60969127].png" alt="Screenshot_2020-11-29_rerl_Check-in_[df60969127].png">

</figure>

<ol class="org-ol">
<li><b>Software libre</b>: Licencia BSD.</li>
</ol>

<p>
Si habéis pinchado en el enlace a la página de <code>fossil</code> que he puesto
arriba, ya habéis visto un repositorio <code>fossil</code> en acción. ¿Queréis
ver otro?  Pues id a la página de <a href="https://www.sqlite.org">sqlite</a>. Esa página es otro
repositorio, de hecho, <code>fossil</code> y <code>sqlite</code> son del mismo programador.
No tengo claro si creó <code>fossil</code> para el control de versiones de
<code>sqlite</code> o si creó <code>sqlite</code> para <code>fossil</code>, porque los ficheros del
respositorio y todos sus datos se guardan en bases de datos <code>sqlite</code>,
como ya he dicho antes.
</p>

<p>
Al crear un repositorio es aconsejable invertir un poco de tiempo en
ajustar algunas cosas en el fichero <code>.fossil</code> generado. Por ejemplo,
poner un nombre al proyecto en el apartado de configuración del mismo.
Si queremos tenerlo en un servidor y que se pueda acceder desde fuera
también debemos crear una pagina <i>wiki</i> con el nombre del proyecto,
que será la que se muestre en el apartado <code>home</code> del menú. O también
ajustar algunos parámetros, como explicaré después, para acondicionar
el respositorio a nuestras necesidades, aunque sea un repositorio
<i>privado</i> o local.
</p>
</div>
</div>
<div id="outline-container-org2e66566" class="outline-2">
<h2 id="org2e66566">Montar o no montar servidor</h2>
<div class="outline-text-2" id="text-org2e66566">
<p>
Con el servidor me encuentro un pequeño escollo a pesar de las
facilidades que da <code>fossil</code> para montar un pequeño, ─o gran─,
servidor.  La cosa consiste en tener el ejecutable y acceso a la
máquina: el ejecutable puede colocarse como <code>CGI</code> en un servidor web,
o directamente como un servidor a través de <code>http</code> o <code>ssh</code>, etc. El
único requisito es que el ejecutable esté accesible en la máquina que
hará de servidor del repositorio.
</p>

<p>
Montar un servidor es tan sencillo como teclear el comando
</p>

<div class="org-src-container">
<pre class="src src-shell">fossil server [opciones] [servidor]
</pre>
</div>

<p>
Entre las opciones podemos encontrar parámetros como el <code>puerto</code>,
forzar el acceso a <code>https</code>, limitar el acceso para hacerlo local con
<code>--locahost</code>, proporcionar una página de error, etc. El servidor puede
ser simplemente un directorio del disco con una colección de ficheros
con extensión <code>.fossil</code>. Si quieres montar un servidor sólo tienes que
abrir los puertos del <i>firewall</i> donde quieres que escuche, lanzar el
servidor y ya tienes un repositorio en tu red local. Por supuesto, si
quieres más detalles te recomiendo leer la ayuda. Por ejemplo, el
comando:
</p>

<div class="org-src-container">
<pre class="src src-shell">fossil ui
</pre>
</div>

<p>
lo que hace es montar un servidor local con dirección
<code>localhost:8080</code>, básicamente es un comando <code>fossil server
--localhost</code> que además lanza el <i>navegador web</i>. Si no tenemos
configurado uno para el repositorio en concreto, nos lanzará el que
tengamos configurado por defecto, pero también podemos decirle cuál
queremos utilizar para ese repositorio. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-shell">fossil set web-browser falkon
</pre>
</div>

<p>
hará que cuando llamemos al entorno gráfico, nos lo abra con el
navegador <code>falkon</code>. También podemos utilizar el mismo entorno gráfico
para hacer estas modificaciones en la configuración que necesitemos,
no solo en el repositorio, sino también en el entorno con el que
trabajamos en él.
</p>
</div>
<div id="outline-container-org59334e0" class="outline-3">
<h3 id="org59334e0">Uso básico de <code>fossil</code></h3>
<div class="outline-text-3" id="text-org59334e0">
<p>
Por lo que he podido ver hasta ahora, los <i>respositorios</i>, tanto
locales como remotos, se mantienen con ficheros <code>sqlite3</code>.
</p>

<p>
Para hacer las pruebas volqué el repositorio <code>git</code> del proyecto de
<i>raytracer</i> en un repositorio <code>fossil</code>:
</p>

<div class="org-src-container">
<pre class="src src-shell">git fast-export --all | fossil import --git ~/prueba.fossil
Rebuilding repository meta-data...
  100.0% complete...
Vacuuming... ok
project-id: 2c2c41b870550e99cefe4cd941aca798144b8db0
server-id:  a69aeb2f5f57f16fd1c772f59eb985708bee2533
admin-user: notxor (password is <span style="color: #f1fa8c;">"V7vgBd8YqN"</span>)
</pre>
</div>

<p>
En ese procedimiento se genera un fichero <code>fossil</code> que nos sirve de
repositorio. Además, nos proporciona una clave de acceso para el
usuario <code>admin</code>. Ese fichero lo podríamos haber colocado en cualquier
sitio accesible<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>, como por ejemplo en un <code>path</code> tal que
<code>~/repositorios</code>.
</p>

<div class="org-src-container">
<pre class="src src-shell">$ mkdir prueba-proyecto
$ cd prueba-proyecto
$ fossil open ~/repositorios/prueba.fossil 
LICENSE.txt
Makefile
README.org
mundo.rerl
src/registros.hrl
src/rerl.erl
src/rerl_camara.erl
src/rerl_imagen.erl
src/rerl_material.erl
src/rerl_objeto.erl
src/rerl_renderer.erl
src/rerl_tesela.erl
project-name: &lt;unnamed&gt;
repository:   /home/notxor/repositorios/prueba.fossil
local-root:   /home/notxor/prueba-proyecto/
config-db:    /home/notxor/.config/fossil.db
project-code: 2c2c41b870550e99cefe4cd941aca798144b8db0
checkout:     c957955db5afdf98344d16a4d829fcfd79775df8 2020-11-29 09:02:51 UTC
parent:       78da994df05b8eb275603b88161e1898c6588db9 2020-11-29 08:41:07 UTC
tags:         master, trunk
comment:      Primera aproximaci&#243;n a materiales transparentes. (user: notxor@nueva-actitud.org)
check-ins:    65
$ ls -lah
total 92K
drwxr-xr-x   3 notxor users  105 nov 27 12:37 .
drwxr-xr-x 113 notxor users 8,0K nov 27 12:37 ..
-rw-r--r--   1 notxor users  32K nov 27 12:37 .fslckout
-rw-r--r--   1 notxor users  34K nov 27 12:37 LICENSE.txt
-rw-r--r--   1 notxor users  775 nov 27 12:37 Makefile
-rw-r--r--   1 notxor users  332 nov 27 12:37 mundo.rerl
-rw-r--r--   1 notxor users 2,7K nov 27 12:37 README.org
drwxr-xr-x   2 notxor users  185 nov 27 12:37 src
</pre>
</div>

<p>
Ese comando, como se puede ver en el último listado, aparte de crear
todos los archivos del proyecto, genera un fichero con nombre
<code>.fslckout</code> que es otra base de datos <code>sqlite3</code>. Ese fichero guarda la
información en <i>local</i> como hace el directorio <code>.git</code>.
</p>

<p>
Ahora hay que decirle a nuestro repositorio local que se coordine con
otro remoto. Si hemos montado un servidor o si lo vamos a utilizar
desde un fichero en nuestro <code>path</code>, necesitamos que se mantenga
actualizado con un fichero <code>.fossil</code>, porque, aunque hemos creado el
local haciendo un <code>open</code>, por defecto no crea el enlace. Así pues,
tenemos que hacer:
</p>

<div class="org-src-container">
<pre class="src src-shell">$ fossil remote add remoto ~/repositorios/prueba.fossil
$ fossil remote list
remoto             file:///home/notxor/repositorios/prueba.fossil
</pre>
</div>

<p>
siguiendo el esquema:
</p>

<pre class="example" id="org74c041b">
fossil remote add [nombre] [URL]
</pre>

<p>
Podemos establecer tantos remotos como queramos. El siguiente paso es
un consejo, más que una necesidad porque depende de si hemos creado un
servidor para los repositorios remotos o no. Concretamente En mi caso
no lo creé y utilizo repositorios remotos <i>locales</i>, es decir, un
fichero <code>.fossil</code> accesible en el <code>path</code>. El problema es que cuando
añades un repositorio remoto, automáticamente lo activa como
<code>autosync</code>, es decir: automáticamente intenta sincronizar el remoto
cuando hacemos un <i>commit</i> en el local. Si no queremos ese
comportamiento o falla, como ocurre cuando el remoto no está en un
servidor propiamente dicho, sino que es local, os aconsejo desactivar
la autosincronización de repositorios.
</p>

<div class="org-src-container">
<pre class="src src-shell">$ fossil unset autosync
</pre>
</div>

<p>
De esta manera actualizar la información se debe hacer en dos pasos:
primero con <code>commit</code> y luego con <code>push</code>.
</p>

<p>
También os recomiendo establecer un <code>editor</code> para los <code>commits</code>, que
como podéis suponer, en mi caso he configurado <code>emacsclient</code> para la
línea de comandos con:
</p>

<div class="org-src-container">
<pre class="src src-shell">$ fossil set editor <span style="color: #f1fa8c;">"emacsclient -t"</span>
</pre>
</div>

<p>
Eso hace que el comando <code>commit</code> inicie el editor de nuestro gusto.
Sin embargo, si no tiene uno configurado hará el <code>commit</code> sin texto y
aunque luego lo podemos modificar en cualquier momento, siempre es
conveniente que vaya con las cosas puestas en su sitio y no tener que
hacerlo en varios pasos. El resto del proceso ya nos suena de otras
herramientas de este tipo:
</p>

<div class="org-src-container">
<pre class="src src-shell">$ fossil commit
emacsclient -t <span style="color: #f1fa8c;">'./ci-comment-1B1192236B5F.txt'</span>
New_Version: 0c8f9ac2c71ab213545a0748d480be86301fac4e7aebb24282f279ea29c59884
$ fossil push remoto
Push to file:///home/notxor/repositorios/prueba.fossil
server says: 400 Bad Request
Push done, sent: 649  received: 1000  ip: 
</pre>
</div>

<p>
Bien, hasta aquí hemos visto un repositorio convertido desde otra
herramienta, pero ¿cómo inicio un repositorio si quiero utilizar
<code>fossil</code> como el control de versiones de mi proyecto? Pues crear un
proyecto nuevo es sencillo:
</p>

<pre class="example" id="org00542d1">
$ mkdir proyecto-nuevo
$ cd proyecto-nuevo/
$ fossil init ../repositorios/proyecto-nuevo.fossil
project-id: 668d16b369e69e92a6fb955710b2bf5f6936a31f
server-id:  2d3f2b9eb6805b67900cbf761088ae089a636407
admin-user: notxor (initial password is "ztdSAUjxWP")
$ ls -lah ../repositorios/
total 236K
drwxr-xr-x   2 notxor users   35 nov 29 13:37 .
drwxr-xr-x 113 notxor users 8,0K nov 29 13:36 ..
-rw-r--r--   1 notxor users 224K nov 29 13:37 proyecto-nuevo.fossil
</pre>

<p>
En esos pasos creamos el directorio del proyecto e iniciamos un
repositorio remoto (aunque local).
</p>

<pre class="example" id="orgace289d">
$ fossil open ../repositorios/proyecto-nuevo.fossil 
project-name: &lt;unnamed&gt;
repository:   /home/notxor/repositorios/proyecto-nuevo.fossil
local-root:   /home/notxor/proyecto-nuevo/
config-db:    /home/notxor/.config/fossil.db
project-code: 668d16b369e69e92a6fb955710b2bf5f6936a31f
checkout:     00aeb8f8ba9b427317105151db1020840246dc47 2020-11-29 12:37:22 UTC
tags:         trunk
comment:      initial empty check-in (user: notxor)
check-ins:    1
$ ls -lah
total 44K
drwxr-xr-x   2 notxor users   23 nov 29 13:37 .
drwxr-xr-x 113 notxor users 8,0K nov 29 13:36 ..
-rw-r--r--   1 notxor users  32K nov 29 13:37 .fslckout
</pre>

<p>
En este paso, abrimos el repositorio remoto en el directorio que hemos
creado para el proyecto. No hay ningún fichero aún ni nada que
actualizar, pero se crea el repositorio local. El resto es ir
encadenando instrucciones <code>add</code>, <code>commit</code> y <code>push</code> como hemos visto
antes.
</p>

<p>
Alguno pensaréis que teniendo el repositorio <i>remoto</i> en el directorio
de <i>al lado</i> en realidad no es remoto y pierde las fuerza de «copia de
seguridad» de tu trabajo. Y es cierto, sin embargo, para compensar, el
fichero <code>.fossil</code> lo puedes sincronizar en un directorio a tu nube
<code>nextcloud</code>, por ejemplo, o añadirlo a tus copias de seguridad
periódicas, o usar <code>synthing</code> o cualquier otra herramienta de
sincronización externa. Es un fichero monolítico sin dependencias
externas; ni siquiera <code>fossil</code>, porque toda la información está
contenida en una base de datos <code>sqlite3</code>; puedes abrirlo como tal,
─pero si lo haces ten cuidado de no tocar nada que no debes─.
</p>
</div>
</div>
</div>
<div id="outline-container-org4a8589e" class="outline-2">
<h2 id="org4a8589e">Conclusiones</h2>
<div class="outline-text-2" id="text-org4a8589e">
<p>
Estoy contento con <code>fossil</code> por las pocas pruebas que he hecho con él,
parece un sistema amigable y tiene características que lo hacen
interesante como son: <i>foro</i>, <i>wiki</i>, <i>bug track</i>, etc. Todo
autocontenido y sin necesitar otras herramientas externas. El <i>slogan</i>
que dice que «/fossil/ es <i>github</i> metido en una caja», tiene
razón. Por lo menos a simple vista y por lo poco que lo he usado y
<i>trasteado</i>.
</p>

<p>
Me falta ver cómo se comporta en un proyecto compartido con un
servidor montado como corresponde. Pero de momento no descarto
continuar usando esta herramienta para proyectos personales sin
necesitar servidores externos y teniendo la posibilidad de mantener a
mano un montón de herramientas para documentación y gestión de
proyectos de código.
</p>

<p>
Lo voy a ir utilizando en pequeños proyectos personales a ver si
descubro alguna característica nueva o echo en falta algo. A ver si
termina de convencerme o desilusionarme. Es un sistema prometedor pero
¿tanto como para abandonar <code>git</code>? No lo creo, o al menos, no de
momento, en mi caso.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Se puede configurar cuál, no tiene por qué ser el navegador que
tengas configurado por defecto. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Puede ser cualquier sitio al que tengamos acceso directo. Si
está en la red hay que montar un servidor para acceder por <code>http</code>,
<code>https</code>, <code>ssh</code> o cualquier otro método de los permitidos. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/fossil/index.html">fossil</a> <a href="/tags/linux/index.html">linux</a> ]]></description>
  <category><![CDATA[fossil]]></category>
  <category><![CDATA[linux]]></category>
  <link>https://notxor.nueva-actitud.org/2020/11/30/probando-fossil.html</link>
  <pubDate>Mon, 30 Nov 2020 00:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Organización del espacio de trabajo en Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-11-25</div>
<p>
Hoy vengo a hablar de cómo organizar un poco el espacio de trabajo de
<i>Emacs</i>. Escribiré sobre las famosas <i>tabs</i> que se han incorporado en
las últimas versiones y sobre otras herramientas más <i>viejunas</i> pero
también válidas, que teníamos antes y que sigo utilizando, como
<code>perspective</code>. Así pues, si no te organizas tus ventanas de aquí en
adelante, será porque no quieres.
</p>

<p>
Como sabéis, llevo un tiempo trabajando con <i>Emacs</i> y vengo de nuevo a
<i>cansinar</i> con él. Concretamente con cómo me apaño para tener
controlados los <i>sienes y sienes</i> de <i>buffers</i> que puedo llegar a
tener abiertos en un momento dado. Mi respuesta a ésto, es sencilla:
<i>no los tengo controlados... del todo</i>... hay quien diría que <i>en
absoluto</i>. Cuando empecé a utilizar <i>Emacs</i> venía de otros editores
capaces de abrir <i>pestañas</i> mostrándolas visualmente y teniéndolas a
un <i>click</i> de ratón. La principio las eché de menos: porque el sistema
de <i>buffers</i>, hasta que lo entendí, me parecía marciano.  Cambiar de
un <i>buffer</i> a otro, abrir <i>buffer</i>, cerrar <i>buffer</i>, mostrar varios
<i>buffers</i> en el mismo <i>marco</i>.
</p>
<div id="outline-container-org9451a4f" class="outline-2">
<h2 id="org9451a4f">Método de sesiones</h2>
<div class="outline-text-2" id="text-org9451a4f">
<p>
Al principio puede parecer buena idea tener varias sesiones abiertas,
cada una con el aspecto con el que vayamos a trabajar. Puede ser un
método cuando estás trabajando en una máquina sobrada de recursos.
Este es el método más sencillo de entender: abres <i>Emacs</i> tantas veces
como necesites. Además, por lo que tengo comprobado, es la única forma
de que se mantengan las cosas en su sitio y no se trasvasen de un
lugar a otro <i>automágicamente</i>. Que resulta que abres un <i>buffer</i>
donde no toca, todo se lía y te pierdes en toda una marabunta de
cosas.
</p>

<p>
La evolución natural de este sistema es abrir una sola sesión pero
varios con <i>frames</i> lanzados con <code>C-x 5</code>. Esto es bastante más
agradecido para el gasto de RAM y otros recursos de la máquina, pero
tiene el inconveniente, ─o la ventaja─, de que se comparten los
<i>buffers</i> abiertos y puedes abrir cualquiera en cualquiera de los
<i>frames</i>. Además, si no tienes varias pantallas, la mejor forma de
mantenerlos a raya es repartirlos por los distintos escritorios.
</p>

<p>
A falta de pestañas, me puse a investigar cómo podía reducir mi
ansiedad de tener lo que fuera lo que estuviera editando a un golpe de
<i>click</i>... y como siempre ocurre en <i>Emacs</i> encontré varias
alternativas, de las cuales voy a mencionar sólo dos: <code>perspective</code> y
la moderna <code>tab-bar-mode</code>.
</p>
</div>
</div>
<div id="outline-container-org02217eb" class="outline-2">
<h2 id="org02217eb">Perspectivas</h2>
<div class="outline-text-2" id="text-org02217eb">
<p>
El paquete <code>perspective</code> es uno de esos paquetes que marcan la
diferencia a la hora de organizarte el trabajo.  Me ocurrió lo mismo
cuando descubrí los terminales múltiples de <i>GNU/Linux</i> y sus primos
pequeños los <i>escritorios múltiples</i> después. En cada uno puedes tener
lo que necesites abierto y distribuido por tu pantalla de trabajo para
poder saltar de un sitio a otro con apenas una combinación de teclas
(y <i>click</i> de ratón si quieres).
</p>

<p>
La instalación es muy fácil, está en <i>MELPA</i>:
</p>

<p>
<code>M-x package-install RET perspective RET</code>
</p>

<p>
En mi caso no tengo ninguna configuración adicional en mi <code>init.el</code>
porque no suelo tenerlo activado desde el inicio y sólo lo activo
cuando veo que necesitaré trabajar en varios asuntos de manera
simultánea, es decir: cuando lo necesito.
</p>

<p>
Algo que suele ser casi diario, últimamente que me paso días en los
que además del trabajo habitual, estoy con el proyecto del <i>raytracer</i>
y escribiendo artículos para el <i>blog</i>. Mientras voy programando, voy
leyendo el <code>pdf</code>, voy tomando apuntes, que se convierten
posteriormente en artículos para el <i>blog</i>, y realizando otras tareas
como la contabilidad, consulta de documentación, etc. Además de
<code>perspective</code>, otro paquete recomendable es <code>persp-projectile</code> si
utilizas <code>projectile</code>. En el que la <i>perspectiva</i> se alía con el
<i>proyecto</i> y permite abrir una perspectiva eligiendo entre toda la
lista de proyectos. Su instalación es muy sencilla:
</p>

<p>
<code>M-x package-install RET persp-projectile RET</code>
</p>

<p>
Como en el anterior caso, no tengo tampoco ningún otro código de
activación en el <code>init.el</code>. Simplemente cuando quiero abrir una
perspectiva para trabajar con un proyecto específico tecleo el comando
<code>M-x projectile-persp-switch-project</code>, selecciono el proyecto con el
que quiero trabajar, y respondo a la pregunta de qué fichero quiero
abrir y ya está todo: abierta una nueva <i>perspectiva</i>.
</p>

<p>
Para activar las perspectivas utilizo el comando <code>persp-mode</code> que
abrirá la perspectiva por defecto <i>main</i>. Se puede configurar el
nombre, como otras muchas opciones.
</p>


<figure id="org1ff7226">
<img src="./imagenes/Captura-pantalla_perspectiva-main.png" alt="Captura-pantalla_perspectiva-main.png">

</figure>

<p>
En la imagen podemos observar que en la linea de estado aparecen unas
etiquetas con las diferentes perspectivas abiertas, marcando la activa
con otro color. Esas etiquetas se pueden modificar, cambiar colores,
separadores, etc. Además, esas etiquetas se ordenan, ─también por
defecto─, alfabéticamente.
</p>

<p>
La primera cuando abres <code>perspective</code> es <code>main</code>. En esta perspectiva
suelo abrir tareas que yo llamo <i>de pantalla completa</i> como el lector
de RSS <code>elfeed</code> o la agenda, o esas cosas.
</p>

<p>
En otras perspectivas tengo abiertos varios <i>buffers</i> de trabajo:
</p>


<figure id="orgfe171f6">
<img src="./imagenes/Captura-pantalla_perspectiva-blog.png" alt="Captura-pantalla_perspectiva-blog.png">

</figure>

<p>
Si nos fijamos en la imagen anterior, en el <i>buffer</i> <code>*:Buffers:*</code>
vemos que <code>perspective</code> abre un <code>*scratch*</code> independiente para cada
perspectiva.
</p>
</div>
<div id="outline-container-org1fcae1f" class="outline-3">
<h3 id="org1fcae1f">Combinaciones de teclas y comandos</h3>
<div class="outline-text-3" id="text-org1fcae1f">
<p>
Como muchas otras cosas que se pueden configurar, la combinación de
teclas para trabajar con <i>perspectivas</i>, también puedes cambiarla en
tu configuración. Por defecto es <code>C-x x</code>.
</p>

<dl class="org-dl">
<dt><code>C-x x a</code></dt><dd>añadir <i>buffer</i> a la perspectiva.</dd>
<dt><code>C-x x k</code></dt><dd>eliminar el <i>buffer</i> de la perspectiva.</dd>
<dt><code>C-x x s</code></dt><dd>cambiar (<i>switch</i>) a una perspectiva. Si el nombre que
tecleamos no existe, crea una perspectiva nueva.</dd>
<dt><code>C-x x c</code></dt><dd>eliminar la perspectiva.</dd>
<dt><code>C-x x n</code> o <code>C-x x -&gt;</code></dt><dd>ir a la siguiente perspectiva... con <code>n</code> o
con la flecha a la derecha.</dd>
<dt><code>C-x x p</code> o <code>C-x x &lt;-</code></dt><dd>ir a la perspectiva anterior... con <code>p</code> o
con la flecha a la izquierda.</dd>
<dt><code>C-x x r</code></dt><dd>renombrar la perspectiva.</dd>
</dl>

<p>
Otro comando muy interesante y que descubrí hace poco, es la
posibilidad de guardar las perspectivas que tenemos abiertas en
nuestra sesión en un fichero con <code>C-x x C-s</code> y luego cargarlas desde
el mismo con <code>C-x x C-l</code>. De esa forma, podemos cargar el estado
completo de nuestra sesión, con sus perspectivas y <i>buffers</i>
abiertos.
</p>
</div>
</div>
</div>
<div id="outline-container-orgecc0b2f" class="outline-2">
<h2 id="orgecc0b2f">Pestañas con <code>tab-bar</code></h2>
<div class="outline-text-2" id="text-orgecc0b2f">
<p>
Otra forma de organizar nuestro <i>escritorio</i> en <i>Emacs</i> es utilizar el
modo <code>tab-bar</code> que nos permitirá tener diferentes <i>pestañas</i> con
diferentes diseños en la misma sesión.
</p>

<p>
Las últimas versiones de <i>Emacs</i> proporcionan un modo de pestañas que
se activa (y desactiva) con <code>M-x tab-bar-mode</code>.
</p>

<p>
Sin embargo, este método de distribuir el espacio de trabajo no ha
calado mucho en mi día a día. Especialmente porque ya estoy
acostumbrado al método descrito anteriormente y ese suele ser el que
utilizo. Aunque visualmente es algo más agradable de ver:
</p>


<figure id="orgaa82065">
<img src="./imagenes/Captura-pantalla_tab-bar.png" alt="Captura-pantalla_tab-bar.png">

</figure>

<p>
Aparecen, una serie de <i>botones</i> en la parte superior del espacio de
edición que representan las correspondientes pestañas. Esa barra está
orientada, o pensada, para ser manipulada gráficamente. Presenta
botones de cerrado (<code>x</code>) en cada pestaña<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> y de creación de una nueva
pestaña (<code>+</code>) en la barra, pero que no son útiles desde el <i>Emacs</i> en
consola.
</p>

<p>
Las combinaciones de teclas comienzan, ─por defecto─, con el prefijo
<code>C-x t</code> y las más habituales son:
</p>

<dl class="org-dl">
<dt><code>C-x t 2</code></dt><dd>crear una pestaña nueva.</dd>
<dt><code>C-x t 0</code></dt><dd>cerrar la pestaña actual.</dd>
<dt><code>C-x t f</code> o <code>C-x t C-f</code></dt><dd>abrir un fichero en una pestaña nueva.</dd>
<dt><code>C-x t r</code></dt><dd>renombrar la pestaña.</dd>
<dt><code>C-x t o</code></dt><dd>ir a la siguiente pestaña.</dd>
</dl>

<p>
El sistema es como es y no termino de entender por qué utilizan <code>o</code> en
lugar de <code>n</code> para ir a la siguiente pestaña<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. Supongo que debes
configurar esas teclas en tu <code>init.el</code>, porque los comandos sí que
existen como <code>tab-bar-switch-next-tab</code> o <code>tab-bar-switch-prev-tab</code>, o
incluso <code>tab-bar-switch-to-tab</code> para cambiar a una pestaña
determinada, o incluso un comando <code>tab-bar-switch-to-recent-tab</code> para
saltar a la pestaña de edición de la que vienes. Algo muy útil si
estás saltando entre dos pestañas yendo y viniendo.
</p>

<p>
Por tanto, si vas a utilizar esta característica con asiduidad, será
recomendable que configures todas esas acciones con sus
correspondientes teclas, especialmente si lo vas a usar en consola y
no en modo gráfico, que es donde este <i>modo</i> parece tener su fuerte.
</p>
</div>
</div>
<div id="outline-container-orgfd2f17e" class="outline-2">
<h2 id="orgfd2f17e">Conclusiones</h2>
<div class="outline-text-2" id="text-orgfd2f17e">
<p>
Elegir un paquete u otro no va más allá que de los gustos. Ambos,
tanto <code>perspective</code> como <code>tab-bar</code>, proporcionan formas de trabajo muy
similares. Cada uno tiene sus <i>pros</i> y sus <i>contras</i>.
</p>

<p>
El principal <i>pro</i> de <code>tab-bar</code> es que viene ya integrada en las
últimas versiones de <i>Emacs</i>. Por contra, <code>perspective</code> hay que
instalarlo desde fuera. El principal <i>contra</i> de <code>tab-bar</code> es que
viene inicialmente orientado a <i>pichorros</i> gráficos como para
utilizarlo sin más en sesiones en consola. Por contra, <code>perspective</code>
se utiliza de la misma manera en los dos casos y aunque sea un poco
menos agraciado estéticamente, no ocupa sitio visual, o <i>espacio de
pantalla</i> más que en la barra de estado.
</p>

<p>
Por tanto, elegir uno u otro, como muchas veces ocurre con nuestro
editor favorito, es una cuestión de gustos. Que cada uno elija el que
más se ajuste a su manera de trabajar y lo ajuste a sus gustos.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
También se puede configurar, como muchas cosas en <i>Emacs</i>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Que sería la opción habitual lógica a través de todos los
paquetes de <i>Emacs</i>: <code>n</code> para siguiente y <code>p</code> para anterior. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2020/11/25/organizacion-del-espacio-de-trabajo-en-emacs.html</link>
  <pubDate>Wed, 25 Nov 2020 00:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Material difuso y corrección gamma]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-11-20</div>
<p>
Pues aquí estoy de nuevo con otra entrega del <i>raytracer</i> y todo lo
que voy haciendo. Hoy voy a comenzar explicando cómo tengo configurado
<i>Emacs</i> para trabajar con <code>erlang</code>, porque me lo habéis pedido y luego
continuaré con las propuestas del libro... el de escribir un
<i>raytracer</i> en un fin de semana. Concretamente hablaré sobre el primer
material (el difuso) que propone y la <i>corrección gamma</i> del color.
</p>

<p>
Algunos me habéis preguntado cosas y otros me habéis mostrado un
profundo aburrimiento con mi <i>frikada</i>. No puedo adelantar si esta
serie durará mucho, ya siento aburriros, pero sois tan libres de no
leerlo como yo de escribirlo. Por otro lado, hay quien quiere saber
más, se queja de que voy lento y me pide que <i>le dé más caña</i>.  Pero
también hay quien ya se cansó en el primer artículo. Como he dicho
antes, traigo otros pequeños avances: nuestras esferas representadas
por primera vez con un material, ─en este caso, difuso─, y algunas
cosillas más, como la corrección <i>gamma</i> del color y otros apuntes
sobre las herramientas que estoy utilizando.
</p>

<p>
Voy a empezar por esta última, porque se debe a un pregunta que me han
hecho: <i>¿Qué usas para hacerlo?</i> La respuesta corta hubiera sido
<i>Emacs</i>, pero conociendo al que me la ha hecho, estoy seguro de que se
refiere a cosas más concretas.
</p>
<div id="outline-container-orgb9a36fd" class="outline-2">
<h2 id="orgb9a36fd">Configuración de <i>Emacs</i> para programar en <code>erlang</code></h2>
<div class="outline-text-2" id="text-orgb9a36fd">
<p>
El hecho de programar con <code>erlang</code>, siendo un lenguaje minoritario, no
cuenta con la profusión de herramientas que otros lenguajes tienen
para la edición, depuración y mantenimiento del código. De hecho, la
mayoría de las aplicaciones que sirven para ello, vienen con el propio
<code>erlang</code>: <code>observer</code>, <code>debugger</code>, etc. que se pueden lanzar desde la
consola, o <i>shell</i>, de <code>erlang</code> con llamando a <code>observer:start()</code> o
<code>debugger:start()</code>.
</p>

<p>
Si ya tienes instalado algún IDE como <code>eclipse</code> o <code>IntelliJ</code>, puedes
instalarte el <i>plugin</i> de <code>erlang</code>. No los he probado, pero
seguramente, conociendo ambos IDE's, serán unos paquetes que
funcionarán perfectamente y proporcionarán herramientas más allá del
coloreado de sintaxis.
</p>

<p>
A mí, esos IDE's me resultan demasiado pesados, complejos y prolijos,
llenos de botones situados por todas partes y, como sabéis, me decanto
más por un editor como <i>Emacs</i>. ¿Tengo que renunciar a muchas cosas
eligiendo un editor en lugar de un <i>IDE</i>? Pues no, prácticamente a
ninguna. Como digo, <code>erlang</code> trae sus propias aplicaciones de <i>debug</i>
y de visualizador de procesos<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>... y para lo demás está <i>Emacs</i>.
</p>
</div>
<div id="outline-container-orgf7451a0" class="outline-3">
<h3 id="orgf7451a0">Paquetes para trabajar con <code>erlang</code></h3>
<div class="outline-text-3" id="text-orgf7451a0">
<p>
Para trabajar con este lenguaje tengo tres paquetes instalados en
<i>Emacs</i> que para mí son los básicos. En la lista de paquetes podréis
encontrarlos, hay más<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. Pero los que yo uso son éstos y me son
suficientes:
</p>

<ul class="org-ul">
<li><code>erlang</code>: el paquete general, con coloreado de sintaxis, indentación
y algunas herramientas adicionales.</li>
<li><code>company-erlang</code>: para el autocompletado del código con <code>company</code>.</li>
<li><code>ivy-erlang-company</code>: autocompletado <i>company</i> con <code>ivy-mode</code><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>.</li>
</ul>

<p>
El segundo y el tercero no merecen demasiada atención, si ya tienes
configurado <code>ivy</code> y <code>company</code> para otros lenguajes, por ello de ese
trío me voy a concentrar en el primero. El paquete <code>erlang</code> es muy
fácil de configurar y no necesitas más que añadir a tu <code>init.el</code> una o
dos líneas, o tres según las herramientas que uses. En mi caso:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">erlang-start</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> erlang-root-dir <span style="color: #f1fa8c;">"/usr/lib64/erlang"</span>)
(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">erlang-flymake</span>)
</pre>
</div>

<p>
La primera línea inicia el paquete <code>erlang</code> en nuestro <i>Emacs</i>. La
segunda establece dónde está instalado. En <i>OpenSuSe Tumbleweed</i> se
instala en el <code>path</code> que veis arriba. Por defecto, el directorio
esperado es <code>/usr/local/erlang</code>. Si efectivamente lo tienes instalado
en ese directorio o creas un enlace para dicha dirección, no necesitas
ajustar la variable <code>erlang-root-dir</code>. En ese directorio, <i>Emacs</i>
buscará no sólo los ejecutables y librerías, sino también  la
documentación. Y creedme, que es un lujo pulsar <code>C-c C-d</code> y que
<i>Emacs</i> te abra la documentación de la librería o de la función sobre
la que se encuentre el cursor para consultarla.
</p>

<p>
La tercera línea de la configuración activa <code>flymake</code> para <code>erlang</code>.
Si no utilizáis <code>flymake</code> tampoco la necesitas. Lo veremos enseguida,
pero primero vamos a ver qué combinaciones de teclas utilizo más
frecuentemente:
</p>

<ul class="org-ul">
<li><code>C-c C-c</code>, <code>comment-region</code>: Comenta las lineas de código
seleccionadas.</li>
<li><code>C-c C-u</code>, <code>uncomment-region</code>: Habilita el código comentado por el
método anterior.</li>
<li><code>C-c C-d</code>, <code>erlang-man-function-no-prompt</code>: Muestra la página de
manual de <code>erlang</code> de la función en la que se encuentra el cursor.</li>
<li><code>C-c C-k</code>, <code>erlang-compile</code>: compila el módulo que estamos
editando.</li>
<li><code>C-c C-q</code>, <code>erlang-indent-function</code>: reorganiza el indentado de la
función al estilo de <code>erlang</code>.</li>
<li><code>C-c C-z</code>, <code>erlang-shell-display</code>: abre un <i>buffer</i> con un <i>shell</i>
de <code>erlang</code>.</li>
</ul>

<p>
Quizá lo más remarcable del paquete <code>erlang</code> son los <code>skeletons</code>. Los
<code>skeletons</code> son <i>plantillas</i> de código <code>erlang</code>. Hay desde módulos
completos para <code>application</code>, <code>gen_server</code>, <i>supervisores</i>, funciones
y estructuras de código más habituales como <code>receive</code>, cabeceras,
módulos, etc. Se pueden cargar desde el menú de <i>Emacs</i> o desde
comando con <code>M-x tempo-template-erlang-*</code> ... donde el <code>*</code> se
sustituye con el nombre del código que queramos, como <code>small-header</code> o
<code>small-server</code>, <code>application</code>, etc.
</p>
</div>
</div>
<div id="outline-container-org3ced9f0" class="outline-3">
<h3 id="org3ced9f0"><code>flymake</code></h3>
<div class="outline-text-3" id="text-org3ced9f0">
<p>
<code>flymake</code> es una herramienta que va compilando el código que estamos
escribiendo y notificando sus errores y avisos (<i>warnings</i>). No es
específica para <code>erlang</code>, de hecho encontraréis en la lista de
paquetes de <i>ELPA</i> todo un listado de ellas, porque cada lenguaje
tiene su correspondiente paquete. Sin embargo, no busquéis en esa
lista el paquete de <code>erlang</code>, no está.
</p>

<p>
En el caso de <code>erlang</code> el archivo <code>erlang-flymake</code> lo proporciona el
mismo paquete <code>erlang</code>. Por eso lo activamos en la configuración junto
a él.
</p>

<p>
El paquete <code>flymake</code> nos proporciona información muy valiosa para
encontrar errores de sintaxis avisándonos de varias maneras. En
formato texto podemos ver los siguientes avisos:
</p>


<figure id="orgd84ccc0">
<img src="./imagenes/Captura-pantalla_flymake-texto.png" alt="Captura-pantalla_flymake-texto.png">

</figure>

<p>
Como podemos ver en la imagen, en <code>1</code>, vemos que en la línea de estado
de <i>Emacs</i> aparece <code>[Flymake[3 1]</code>, es decir: <i>hay 3 errores y 1
aviso</i>. En \(2\) se encuentra una función donde están los errores. En la
imagen los errores se marcan en <i>rosa</i> y el aviso en <i>naranja</i>. Visto
así, no hay mucha información más que existen esos <i>errores</i> y
<i>warnings</i>. Si necesitamos más información, podemos apelar a <code>M-x
flymake-show-diagnostics</code> o <code>M-x flymake-show-diagnostics-buffer</code>.
Esta segunda hace que se muestre un <i>buffer</i> con esos errores tal y
como los da el compilador:
</p>


<figure id="org4a76dd2">
<img src="./imagenes/Captura-pantalla_flymake-texto-lista.png" alt="Captura-pantalla_flymake-texto-lista.png">

</figure>

<p>
Como podemos ver, en el <i>buffer</i> un desglose con las líneas donde se
han encontrado los errores y el tipo de error.
</p>

<p>
En modo gráfico la información es la misma pero presentada de manera
más gráfica:
</p>


<figure id="orga140413">
<img src="./imagenes/Captura-pantalla_gtk-lista.png" alt="Captura-pantalla_gtk-lista.png">

</figure>

<p>
Como se puede ver, en el margen aparecen los símbolos <code>!</code> para los
<i>warnings</i> y <code>!!</code> para los errores. Además subrayan los errores en
rojo y los <i>warnings</i> en azul. También se puede pinchar en la barra de
estado justo sobre <code>Flymake</code> y nos aparecerá un menú que nos permite
una serie de acciones, como por ejemplo, abrir el <i>buffer</i> de
diagnóstico... para aquellos que gustan de despegar su mano del
teclado para ir al ratón.
</p>
</div>
</div>
<div id="outline-container-org1ddf537" class="outline-3">
<h3 id="org1ddf537"><code>projectile</code> y <code>magit</code></h3>
<div class="outline-text-3" id="text-org1ddf537">
<p>
Además lo que casi convierte <i>Emacs</i> en un IDE son las herramientas de
<code>projectile</code> y <code>magit</code>. En realidad, ambas, no tienen nada de
específico para trabajar con código <code>erlang</code>, pero sí son potentes
herramientas para trabajar con código en general.
</p>

<p>
La primera, <code>projectile</code>, proporciona herramientas y comandos para
trabajar sobre conjuntos de ficheros fuente agrupados en <i>proyectos</i>.
Tiene muchas funciones útiles para gestionarlos, pero lo que más estoy
utilizando es la opción de compilar el proyecto con <code>C-c p c</code>, o
buscar algo dentro del proyecto con <code>C-c p s</code><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>.
</p>

<p>
La segunda, <code>magit</code>, es una de esas aplicaciones de <i>Emacs</i> que
aparece en todas partes como ejemplo de calidad. Sirve para gestionar
un proyecto con <code>git</code> y permite hacer de todo, aparte de lo habitual
de subir cambios, actualizar el repositorio o hacer <i>commits</i>: crear
ramas locales y remotas, <i>rebase</i>, <i>merge</i> o cualquier otro comando
que admita <code>git</code>, con especial mención a <i>log</i> o <i>diff</i>.
</p>

<p>
Si no has probado estas herramientas ya estás tardando en probarlas. Y
como ya he hablado sobre ellas en otras ocasiones en el <i>blog</i> pues
permitidme que lo deje aquí y dedique el artículo a los avances que he
ido haciendo en el <i>raytracer</i>.
</p>
</div>
</div>
</div>
<div id="outline-container-orgac61728" class="outline-2">
<h2 id="orgac61728">Primer material <i>diffuse</i></h2>
<div class="outline-text-2" id="text-orgac61728">
<p>
El material <i>difuso</i> es un tipo de material que produce sólidos con
aspecto mate.  Si no entiendes exactamente a qué tipo de objetos me
refiero, piensa en una goma de borrar o, en general, en cualquier tipo
de goma.  Este tipo de material presenta un aspecto rugoso o
granulado, de forma que la luz al incidir sobre este tipo de
superficies puede salir rebotada en cualquier dirección al azar y no
reflejando el entorno:
</p>


<figure id="org4b2375a">
<img src="./imagenes/material-difuso.png" alt="material-difuso.png">

</figure>

<p>
Siendo la superficie rugosa, los rayos de luz pueden rebotar en
cualquier dirección. El algoritmo más utilizado para este tipo de
materiales es el conocido como <i>Lambert</i>. Sin embargo, el libro
comienza con una aproximación que se supone algo menos exigente con
los cálculos. Esta aproximación propone crear dos <i>esferas</i> de puntos
tal que, dado el punto \(P\) donde incide el rayo se considera el centro
de una de ellas en \(P + \overrightarrow{n}\) y el centro de la otra en
\(P - \overrightarrow{n}\). De estas dos, la primera se considera que
está <i>fuera</i> de la superficie donde incide el rayo tangente a esa
superficie en ese mismo punto, mientras que la segunda estaría
<i>dentro</i> del objeto.
</p>

<p>
Básicamente, lo que hace es lanzar otro rayo cuando el rayo \(r\) incide
en el punto \(P\). Entonces, al azar, se obtiene el punto \(S\) dentro de
lo que sería la esfera de radio 1, para formar el vector \((S - P)\):
</p>


<figure id="orgace0166">
<img src="./imagenes/aproximacion-lambert.png" alt="aproximacion-lambert.png">

</figure>

<p>
Esta aproximación se traduce en el código en la creación de unas
funciones muy sencillas, algunas como <code>vec3_random/2</code> genera un punto
aleatorio que luego pediremos que esté entre <code>-1</code> y <code>1</code>.
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Devuelve un punto aleatorio cuyas coordenadas est&#225;n entre 0 y 1
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #50fa7b; font-weight: bold;">vec3_ramdom</span>() -&gt;
    {<span style="color: #8be9fd; font-style: italic;">random</span>(),<span style="color: #8be9fd; font-style: italic;">random</span>(),<span style="color: #8be9fd; font-style: italic;">random</span>()}.

<span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Devuelve un punto aleatorio cuyas coordenadas var&#237;an entre Min y
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Max.
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #50fa7b; font-weight: bold;">vec3_ramdom</span>(<span style="color: #f8f8f2; font-weight: bold;">Min</span>, <span style="color: #f8f8f2; font-weight: bold;">Max</span>) -&gt;
    {<span style="color: #8be9fd; font-style: italic;">random</span>(<span style="color: #f8f8f2; font-weight: bold;">Min</span>, <span style="color: #f8f8f2; font-weight: bold;">Max</span>), <span style="color: #8be9fd; font-style: italic;">random</span>(<span style="color: #f8f8f2; font-weight: bold;">Min</span>, <span style="color: #f8f8f2; font-weight: bold;">Max</span>), <span style="color: #8be9fd; font-style: italic;">random</span>(<span style="color: #f8f8f2; font-weight: bold;">Min</span>, <span style="color: #f8f8f2; font-weight: bold;">Max</span>)}.

<span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Devuelve un punto aleatorio que se encuentre dentro de una esfera
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">con centro 0 y radio 1.
</span><span style="color: #50fa7b; font-weight: bold;">random_en_esfera_unidad</span>() -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">P</span> = <span style="color: #8be9fd; font-style: italic;">vec3_ramdom</span>(-1, 1),
    <span style="color: #f8f8f2; font-weight: bold;">M</span> = <span style="color: #8be9fd; font-style: italic;">modulo_cuadrado</span>(<span style="color: #f8f8f2; font-weight: bold;">P</span>),
    <span style="color: #ff79c6; font-weight: bold;">if</span> <span style="color: #f8f8f2; font-weight: bold;">M</span> &gt;= 1 -&gt;
            <span style="color: #8be9fd; font-style: italic;">random_en_esfera_unidad</span>();
       true -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">P</span>
    <span style="color: #ff79c6; font-weight: bold;">end</span>.
</pre>
</div>

<p>
Hasta ahora la función <code>color_rayo</code> generaba el color basándose en la
normal del punto donde incidía el rayo y, por tanto, le bastaba con
conocer el rayo. Sin embargo, se ha modificado la función a <code>color_rayo/3</code>:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Calcula el color obtenido por un rayo particular
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #50fa7b; font-weight: bold;">color_rayo</span>(<span style="color: #f8f8f2; font-weight: bold;">_Estado</span>, <span style="color: #f8f8f2; font-weight: bold;">_Rayo</span>, 0) -&gt;
    {0.0,0.0,0.0};
<span style="color: #50fa7b; font-weight: bold;">color_rayo</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>, <span style="color: #f8f8f2; font-weight: bold;">Rayo</span>, <span style="color: #f8f8f2; font-weight: bold;">Contador</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Impactos</span> = <span style="color: #8be9fd; font-style: italic;">impactos</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>, <span style="color: #f8f8f2; font-weight: bold;">Rayo</span>, 0.001, ?<span style="color: #bd93f9;">INFINITO</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Orden_impactos</span> =
        <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">sort</span>(
          <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">I</span>,<span style="color: #f8f8f2; font-weight: bold;">J</span>) -&gt;
                  {<span style="color: #f8f8f2; font-weight: bold;">_</span>,#<span style="color: #8be9fd; font-style: italic;">impacto</span>{t=<span style="color: #f8f8f2; font-weight: bold;">T1</span>}} = <span style="color: #f8f8f2; font-weight: bold;">I</span>,
                  {<span style="color: #f8f8f2; font-weight: bold;">_</span>,#<span style="color: #8be9fd; font-style: italic;">impacto</span>{t=<span style="color: #f8f8f2; font-weight: bold;">T2</span>}} = <span style="color: #f8f8f2; font-weight: bold;">J</span>,
                  <span style="color: #f8f8f2; font-weight: bold;">T1</span> &lt; <span style="color: #f8f8f2; font-weight: bold;">T2</span>
          <span style="color: #ff79c6; font-weight: bold;">end</span>,
          <span style="color: #f8f8f2; font-weight: bold;">Impactos</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Impacto_Cercano</span> = <span style="color: #8be9fd; font-style: italic;">hd</span>(<span style="color: #f8f8f2; font-weight: bold;">Orden_impactos</span>),
    <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">Impacto_Cercano</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
        {true,<span style="color: #f8f8f2; font-weight: bold;">Im</span>} -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">Objetivo</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #f8f8f2; font-weight: bold;">Im</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.normal,<span style="color: #f8f8f2; font-weight: bold;">Im</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.p), <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">random_en_esfera_unidad</span>()),
            <span style="color: #f8f8f2; font-weight: bold;">R</span> = #<span style="color: #8be9fd; font-style: italic;">rayo</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">Im</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.p,dir=<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(<span style="color: #f8f8f2; font-weight: bold;">Objetivo</span>, <span style="color: #f8f8f2; font-weight: bold;">Im</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.p)},
            <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #8be9fd; font-style: italic;">color_rayo</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>, <span style="color: #f8f8f2; font-weight: bold;">R</span>, <span style="color: #f8f8f2; font-weight: bold;">Contador</span> - 1), 0.5);   <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Ojo recursi&#243;n
</span>        {false,<span style="color: #f8f8f2; font-weight: bold;">_</span>} -&gt;
            #<span style="color: #8be9fd; font-style: italic;">rayo</span>{dir=<span style="color: #f8f8f2; font-weight: bold;">Dir</span>} = <span style="color: #f8f8f2; font-weight: bold;">Rayo</span>,
            {<span style="color: #f8f8f2; font-weight: bold;">_</span>,<span style="color: #f8f8f2; font-weight: bold;">Y</span>,<span style="color: #f8f8f2; font-weight: bold;">_</span>} = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">vector_unidad</span>(<span style="color: #f8f8f2; font-weight: bold;">Dir</span>),
            <span style="color: #f8f8f2; font-weight: bold;">T</span> = 0.5 * (<span style="color: #f8f8f2; font-weight: bold;">Y</span> + 1),
            <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>({1.0,1.0,1.0}, (1-<span style="color: #f8f8f2; font-weight: bold;">T</span>)),      <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Del color blanco {1,1,1}
</span>                      <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>({0.5,0.7,1.0},  <span style="color: #f8f8f2; font-weight: bold;">T</span>))         <span style="color: #6272a4;">% </span><span style="color: #6272a4;">al color azul {0.5,07,1.0}
</span>    <span style="color: #ff79c6; font-weight: bold;">end</span>.
</pre>
</div>

<p>
Se puede observar que se ha convertido en una función recursiva,
porque sigue el rayo donde impacta y puede seguirlo las veces que sea
necesario.  Como podría darse el caso de que el rayo estuviera
rebotando infinitas veces, se pone una limitación con contador, que lo
hará sólo las veces que se determine por parámetro. Hacer notar
también que en la llamada a <code>impactos/4</code> se ha establecido una
distancia <code>Tmin</code> de <code>0.001</code>, hasta ahora se venía utilizando el valor
<code>0</code>, pero en los cálculos se consideraban valores como <code>0.0000001</code>
como significativos y a estas alturas podemos considerar que es
suficiente con una milésima para la aproximación a <code>0</code>.
</p>

<p>
Con todo esto el resultado obtenido es:
</p>


<figure id="org613e3fe">
<img src="./imagenes/imagen-cruda.png" alt="imagen-cruda.png">

</figure>

<p>
La imagen obtenida es suficientemente <i>prometedora</i>, aunque algo
oscura. Nos podemos preguntar si hemos hecho algo mal para que
nuestras esferas tengan un color gris tan oscuro. Sin embargo, la
explicación viene de una característica de nuestro sistema visual: su
adaptación a las diferentes intensidades de luz. Necesitamos ajustar
los colores de la imagen a cómo lo verían nuestros ojos en una
situación lumínica similar. Para ello se utiliza la <i>corrección gamma</i>
del color.
</p>

<p>
El cálculo de la superficie utilizando el procedimiento de <i>Lambert</i>
tampoco es muy compleja ni necesita mucho más tiempo. En mi máquina ha
sido al revés, se ha calculado más rápido que la aproximación.
</p>


<figure id="orga6ec540">
<img src="./imagenes/lambert.png" alt="lambert.png">

</figure>

<p>
La distribución del color en la fórmula de <i>Lambert</i> se distribuye
según el ángulo que forme la <i>normal</i> con el vector calculado,
pudiendo llegar a \(cos^3 \phi\).
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Devuelve un punto seg&#250;n la distribuci&#243;n de Lambert.
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #50fa7b; font-weight: bold;">random_vector_unidad</span>() -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">A</span> = <span style="color: #8be9fd; font-style: italic;">random</span>(0.0, 2 * ?<span style="color: #bd93f9;">PI</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Z</span> = <span style="color: #8be9fd; font-style: italic;">random</span>(-1.0, 1.0),
    <span style="color: #f8f8f2; font-weight: bold;">R</span> = <span style="color: #8be9fd; font-style: italic;">math</span>:<span style="color: #8be9fd; font-style: italic;">sqrt</span>(1 - <span style="color: #f8f8f2; font-weight: bold;">Z</span> * <span style="color: #f8f8f2; font-weight: bold;">Z</span>),
    {<span style="color: #f8f8f2; font-weight: bold;">R</span> * <span style="color: #8be9fd; font-style: italic;">math</span>:<span style="color: #8be9fd; font-style: italic;">cos</span>(<span style="color: #f8f8f2; font-weight: bold;">A</span>), <span style="color: #f8f8f2; font-weight: bold;">R</span> * <span style="color: #8be9fd; font-style: italic;">math</span>:<span style="color: #8be9fd; font-style: italic;">sin</span>(<span style="color: #f8f8f2; font-weight: bold;">A</span>), <span style="color: #f8f8f2; font-weight: bold;">Z</span>}.
</pre>
</div>

<p>
Sustituyendo la anterior llamada a <code>random_en_esfera_unidad/0</code> por
<code>random_vector_unidad/0</code> en el código del cálculo de color del pixel
se obtiene:
</p>


<figure id="org5dee48e">
<img src="./imagenes/imagen-lambert-cruda.png" alt="imagen-lambert-cruda.png">

</figure>

<p>
Si comparamos ambas imágenes calculadas, utilizando una aproximación
la primera y utilizando la distribución de <i>Lambert</i> la segunda, son
muy similares. Ésta última tiene unas sombras más suaves y quizá
parezcan algo más luminosas ambas esferas.
</p>
</div>
<div id="outline-container-orgfeff1ab" class="outline-3">
<h3 id="orgfeff1ab">Refactorización del código</h3>
<div class="outline-text-3" id="text-orgfeff1ab">
<p>
Tras una pequeña refactorización del código, he metido todos los
cálculos necesarios para realizar la imagen en los procesos <i>tesela</i>.
Los objetos dejan de intervenir en los cálculos y se ha reducido el
tiempo de <i>render</i> de la imagen anterior a unos 40 segundos. Una
tercera parte, aproximadamente de lo que se empleaba antes. Más
remarcable, si cabe porque no sólo calcula los mismos <i>samples</i> sino
que además tiene que calcular los diferentes rayos para el material.
</p>
</div>
</div>
</div>
<div id="outline-container-orgf1b6997" class="outline-2">
<h2 id="orgf1b6997">Corrección gamma</h2>
<div class="outline-text-2" id="text-orgf1b6997">
<p>
En el libro que estoy siguiendo para hacer este <i>raytracer</i> se limita
a meter una corrección <i>gamma</i> calculando la raíz cuadrada del color
que viene calculado. Sin embargo, he preferido cambiar la fórmula a
una más general y acorde con las matemáticas:
</p>

<p>
\[V_f = A \cdot V_0^\gamma \]
</p>

<p>
que traducida a código se convierte en:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">correccion_gamma</span>({<span style="color: #f8f8f2; font-weight: bold;">R</span>,<span style="color: #f8f8f2; font-weight: bold;">G</span>,<span style="color: #f8f8f2; font-weight: bold;">B</span>}, <span style="color: #f8f8f2; font-weight: bold;">Gamma</span>) -&gt;
    {<span style="color: #8be9fd; font-style: italic;">math</span>:<span style="color: #8be9fd; font-style: italic;">pow</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>, <span style="color: #f8f8f2; font-weight: bold;">Gamma</span>),
     <span style="color: #8be9fd; font-style: italic;">math</span>:<span style="color: #8be9fd; font-style: italic;">pow</span>(<span style="color: #f8f8f2; font-weight: bold;">G</span>, <span style="color: #f8f8f2; font-weight: bold;">Gamma</span>),
     <span style="color: #8be9fd; font-style: italic;">math</span>:<span style="color: #8be9fd; font-style: italic;">pow</span>(<span style="color: #f8f8f2; font-weight: bold;">B</span>, <span style="color: #f8f8f2; font-weight: bold;">Gamma</span>)}.
</pre>
</div>

<p>
Como se puede observar la corrección \(\gamma\) es una potencia donde el
<i>valor final</i>, \(V_f\), es el resultado de multiplicar el valor inicial,
\(V_0\), por una constante \(A\) después elevarlo a \(\gamma\). Por tanto,
si en el libro hacen una raíz cuadrada simplemente, están haciendo
\(A=1\) y \(\gamma=1/2\).
</p>

<p>
La función de corrección la he puesto en el código que escribe el
color del pixel en memoria:
</p>

<div class="org-src-container">
<pre class="src src-erlang">{pixel_color,<span style="color: #f8f8f2; font-weight: bold;">Pixel</span>,<span style="color: #f8f8f2; font-weight: bold;">Color</span>} -&gt;
    #<span style="color: #8be9fd; font-style: italic;">state</span>{lienzo=<span style="color: #f8f8f2; font-weight: bold;">Lienzo</span>,pixeles=<span style="color: #f8f8f2; font-weight: bold;">Px</span>} = <span style="color: #f8f8f2; font-weight: bold;">Estado</span>,
    <span style="color: #f8f8f2; font-weight: bold;">Nuevo_lienzo</span> = <span style="color: #8be9fd; font-style: italic;">maps</span>:<span style="color: #8be9fd; font-style: italic;">put</span>(<span style="color: #f8f8f2; font-weight: bold;">Pixel</span>, <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">correccion_gamma</span>(<span style="color: #f8f8f2; font-weight: bold;">Color</span>, 1/2), <span style="color: #f8f8f2; font-weight: bold;">Lienzo</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Faltan</span> = <span style="color: #f8f8f2; font-weight: bold;">Px</span> - 1,
    <span style="color: #f8f8f2; font-weight: bold;">Nuevo_Estado</span> = <span style="color: #f8f8f2; font-weight: bold;">Estado</span>#<span style="color: #8be9fd; font-style: italic;">state</span>{lienzo=<span style="color: #f8f8f2; font-weight: bold;">Nuevo_lienzo</span>,pixeles=<span style="color: #f8f8f2; font-weight: bold;">Faltan</span>},
    <span style="color: #ff79c6; font-weight: bold;">if</span> <span style="color: #f8f8f2; font-weight: bold;">Faltan</span> &lt; 1 -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">Tiempo</span> = <span style="color: #8be9fd; font-style: italic;">erlang</span>:<span style="color: #8be9fd; font-style: italic;">monotonic_time</span>(millisecond) - <span style="color: #f8f8f2; font-weight: bold;">Estado</span>#<span style="color: #8be9fd; font-style: italic;">state</span>.tiempo,
            <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"~nTiempo empleado en segundos: ~p~n"</span>, [<span style="color: #f8f8f2; font-weight: bold;">Tiempo</span> / 1000]),
            <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Escribiendo imagen...~n"</span>),
            <span style="color: #8be9fd; font-style: italic;">escribir_imagen</span>(<span style="color: #f8f8f2; font-weight: bold;">Nuevo_Estado</span>);
       true -&gt;
            ok
    <span style="color: #ff79c6; font-weight: bold;">end</span>,
    <span style="color: #8be9fd; font-style: italic;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">Nuevo_Estado</span>);
</pre>
</div>

<p>
Explicar con detalle cómo funciona la <i>corrección gamma</i> sería muy
largo, pero si vemos la serie de imágenes
</p>

<p>
<img src="./imagenes/imagen-gamma-2.png" alt="imagen-gamma-2.png"><img src="./imagenes/imagen-gamma-1.png" alt="imagen-gamma-1.png"><img src="./imagenes/imagen-gamma-1-2.png" alt="imagen-gamma-1-2.png"><img src="./imagenes/imagen-gamma-1-4.png" alt="imagen-gamma-1-4.png">
</p>

<p>
podemos percatarnos que valores superiores a \(1\) harán las imágenes
más <i>oscuras</i> mientras que valores inferiores a \(1\) harán las imágenes
más luminosas.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
De procesos, de aplicaciones, de tablas de las bases de datos,
de consumo de memoria y procesador... en fin, todo lo que esté
moviendo el nodo <code>erlang</code> que se quiera analizar. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<code>edts</code> es otro paquete, no lo he probado, pero parece basarse
en otros paquetes, como los anteriores para hacer su trabajo. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Éste se instaló como dependencia, así que no me preocupo por él. 
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Da la opción de buscar con distintas herramientas como <code>grep</code> o
<code>ag</code>, que deben estar instaladas en el sistema, junto con su
correspondiente paquete de <i>Emacs</i>. <code>grep</code> suele estar instalado por
defecto, pero no así <code>ag</code>. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/erlang/index.html">erlang</a> <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/raytrace/index.html">raytrace</a> ]]></description>
  <category><![CDATA[erlang]]></category>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[raytrace]]></category>
  <link>https://notxor.nueva-actitud.org/2020/11/20/material-difuso-y-correccion-gamma.html</link>
  <pubDate>Fri, 20 Nov 2020 10:03:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Rayos y centellas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-11-16</div>
<p>
Ya tenía claro que no se puede satisfacer, ni caer bien, a todo el
mundo. Y con esta serie de artículos sobre el <i>raytracer</i> hecho con
<code>erlang</code> los hechos vuelven a confirmármelo. Me encuentro con gente
que me pide, o me sugiere, dónde poner el énfasis en esta serie de
artículos. Unos afirman, que el tema de las matemáticas no es
interesante y que me centre en el código. Otros, al contrario, ponen
su atención en el funcionamiento teórico del <i>raytracer</i> y me piden
más explicaciones sobre el asunto. Por otro lado, hay quienes me dicen
que las explicaciones matemáticas no pueden faltar y que el código es
secundario y se puede obviar, sobre todo teniendo un repositorio donde
los interesados pueden ir a mirarlo y, por último, hay quien quiere
todas las explicaciones sobre el código y menos explicaciones
teóricas.
</p>

<p>
Como no puedo conciliar todas esas peticiones en un mismo artículo, lo
único que voy a hacer es llevar los temas más a mi manera y las partes
que no le gusten al lector que se las salte... como el que lee una
novela saltándose los párrafos gordos y leyendo sólo los diálogos,
luego dirán que no se han enterado de nada. O dicho de otra manera: lo
voy a escribir a mi manera, así que estás en tu derecho de leerlo a la
tuya. Eso sí, voy a poner un poco más de atención y separar los temas
de explicaciones teóricas y matemáticas del apartado de código y
<code>erlang</code>. El que no esté interesado en la programación en ese
lenguaje, se lo podrá saltar más fácilmente.
</p>
<div id="outline-container-org67546a2" class="outline-2">
<h2 id="org67546a2">¿Cómo funciona un <i>raytracer</i>?</h2>
<div class="outline-text-2" id="text-org67546a2">
<p>
Ya lo expliqué, aunque en un solo párrafo y de forma rápida, más bien
atropellada, porque pensé que a estas alturas el que más y el que
menos ya lo sabría. Pero me habéis hecho preguntas que me hacen
sospechar que no tenéis claro cómo funciona un <i>raytracer</i>. Por eso me
he planteado explicarlo más despacio.
</p>


<figure id="org94aaed9">
<img src="./imagenes/rayo-rebotado.png" alt="rayo-rebotado.png">

</figure>

<p>
Cuando hablaba, en el artículo anterior, de <i>imitar la luz al revés</i>
me refería a que en la vida real, la luz que nos llega al ojo es una
parte infinitesimal de la que parte de las fuentes de luz. Los fotones
rebotan azarosamente sobre los objetos y algunos de ellos, muy pocos,
llegan a nuestros ojos. El color lo marca la longitud de onda que
llega a nuestros receptores, es decir: la que los objetos no hayan
absorbido durante el camino de esa luz.
</p>

<p>
Programar un sistema que utilice el mismo procedimiento es
prácticamente imposible: habría que simular miles de millones de rayos
para seleccionar el color sólo de los que llegan al receptor. Quizá la
computación cuántica llegue a tal nivel de proceso, pero de momento es
inalcanzable.
</p>

<p>
Así pues lo que se hace es simular el «camino de vuelta» de los rayos
que nos interesan: los que llegan al receptor. Sin duda, es un
planteamiento más sencillo de acometer aunque no tan sencillo como
parece explicado de primeras. La pregunta es: ¿de qué color tengo que
pintar un pixel determinado? Parece una pregunta fácil, pero la
respuesta es compleja.
</p>


<figure id="org766d76e">
<img src="./imagenes/tipos-de-rayo.png" alt="tipos-de-rayo.png">

</figure>

<p>
El color de un pixel dependerá no sólo del material del objeto,
acordaos de nuestra primera esfera dibujada:
</p>


<figure id="orgbfdd096">
<img src="./imagenes/imagen-esfera-plana.png" alt="imagen-esfera-plana.png">

</figure>

<p>
Como veis, la esfera es absolutamente plana, lo que nos permitiría
percibir su forma sería la diferente orientación de su superficie con
respecto a la fuente de luz; también dependería el color de la luz
reflejada y refractada que hay en el «mundo» y de las sombras que
puedan proyectar otros objetos. Repito: cuando enviamos desde la
cámara unos <i>rayos de color</i> cuya finalidad es averiguar qué color
tendrá el pixel determinado sabemos que ese color dependerá también
del color de la luz reflejada por otros objetos a su alrededor y si ha
alcanzado algún objeto transparente, también dependerá de la
refracción que tenga ese rayo y del color del objeto visto a través y
así un largo etcétera.
</p>

<p>
En la otra figura anterior he dibujado algunos de los rayos que un
<i>raytracer</i> utiliza en sus cálculos:
</p>

<ul class="org-ul">
<li><b>Rayo de color</b> es aquel que se lanza desde el punto de vista para
obtener qué color tendrá el <i>pixel</i> de la imagen final. Depende del
material del objeto con el que choque y de su orientación hacia la
luz.</li>
<li><b>Rayo de reflexión</b> modifica el color del punto alcanzado por el
rayo de color. Sabemos que hay materiales que reflejan más su
entorno que otros: sin llegar al extremo del espejo, compara un
metal pulido con una goma de borrar.</li>
<li><b>Rayo de sombra</b> se traza para averiguar la cantidad de luz que
llega al punto alcanzado por el rayo. Si hay objetos que se
interpongan a esa luz y si la superficie está o no orientada hacia
la fuente.</li>
<li><b>Rayo de refracción</b> es aquel que se traza cuando se alcanza un
objeto transparente. Todos hemos observado cómo la luz se desvía al
atravesar un vaso de agua y por tanto, el <i>raytracer</i> debe hacer lo
mismo si quiere ser realista.</li>
</ul>

<p>
Pero todo esto son complicaciones que nos iremos encontrando cuando el
sistema avance más de estos primeros balbuceos en los que nos
encontramos.
</p>
</div>
<div id="outline-container-org247c201" class="outline-3">
<h3 id="org247c201">Procesando los rayos</h3>
<div class="outline-text-3" id="text-org247c201">
<p>
En la vida real, el <i>fotón</i> que llega a estimular la cámara o el ojo
ha seguido un tortuoso camino, a pesar de que sabemos que la luz se
transmite en línea recta ─en el espacio en el que nos movemos─. El
asunto, llevado a las matemáticas, es que no hay una fórmula exacta o
sencilla que trace todo ese camino entre ojo y fuente de luz y/o
viceversa, todo lo que tenemos es la fórmula de una recta con <i>origen</i>
y <i>dirección</i>. La solución es que podemos hacer el proceso por partes,
siendo cada parte un rayo independiente. El punto en el espacio en el
que el rayo encuentra un objeto, deberá lanzar al menos uno <i>de
sombra</i> para calcular la cantidad de luz que recibe y si el material
del objeto con el que ha chocado refleja mucho, o poco, su entorno
otro, enviará otro <i>de reflexión</i>, y/o si es transparente tendrá que
enviar otro <i>de refracción</i>, etc.
</p>

<p>
Al final, todo consiste en procesar rayos, muchos rayos, infinidad de
rayos. Ahora imaginad un rayo que encuentra una superficie de un
espejo enfrentado a otro espejo y empieza a <i>rebotar</i>. Ya se
verá<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> que hará falta limitar esos rebotes para no entrar en un
cálculo infinito, pero aún no hemos llegado a ese extremo.
</p>
</div>
</div>
</div>
<div id="outline-container-orgedad7b7" class="outline-2">
<h2 id="orgedad7b7">Refactorización de código</h2>
<div class="outline-text-2" id="text-orgedad7b7">
<p>
En estos días, desde el último artículo, no he avanzado en el
contenido del libro y me he centrado más en aspectos de cómo traducir
todo el sistema a <code>erlang</code>. El código ha sufrido una profunda
refactorización.  En realidad debería decir <i>refactorizaciones</i> porque
en estos días he hecho dos. La primera no me gustó, porque no me
aportaba nada de aprendizaje sobre <code>erlang</code>. Era montar una aplicación
tocha, con supervisores y procesos apoyándome en <code>OTP</code><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. Llegué
incluso a rehacer todo el código para dibujar nuestra esfera sin
ningún problema y fue tan sencillo que me dije: <i>no he aprendido
nada</i>.
</p>

<p>
Como soy tendente a complicarme yo sólo la vida, pensé: <i>¿qué pasa si
lo hago a mi manera, a las bravas?</i> ... por supuesto, en ello estoy,
complicándome la vida. Entre otras cosas porque me tropecé con un
error que se me hizo muy difícil de encontrar y me costó <i>trazar</i>
nuestra esfera. Finalmente, con la ayuda del amigo <i>deesix</i> lo
encontramos. Problemas por mi falta de fluidez con <code>erlang</code>. El
resumen de la búsqueda del <i>bug</i> era que repasé centenares de veces la
fórmulas y los cálculos que hacían las fórmulas. En algunos casos
llegué a hacer los cálculos con papel y lápiz, ─y mucha goma de
borrar─, para comprobar si un determinado valor estaba siendo
calculado correctamente. Y sabía que estaba rondando la <i>cámara</i>
virtual, pero tardé en encontrarlo. Al final, la ayuda del amigo
<i>Deesix</i> fue determinante para encontrarlo y era un problema de
asignación de valores a una variable.
</p>

<p>
Los libros que voy siguiendo<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> a estas alturas comienzan a derivar
clases y utilizar otras características de <code>C++</code> que desde <code>erlang</code> no
tiene sentido seguir, así pues, para estos problemas no son una
referencia. Quería aprender, y de momento estoy aprendiendo un montón
sobre cómo funciona <code>erlang</code> y lo potente que es. Sin embargo, estoy
aprendiendo por la vía dura de darme cabezazos casi constantemente,
más contra mi falta de habilidad que contra la complejidad del mismo
sistema. El objetivo buscado era conseguir lanzar todos los rayos para
la imagen básica... la repito aquí para saber a qué nos referimos:
</p>


<figure id="orgdfded7d">
<img src="./imagenes/imagen.png" alt="imagen.png">

</figure>

<p>
Bueno, pues básicamente me planteé hacer tres procesos:
</p>

<ul class="org-ul">
<li><i>Imagen</i>: que inicia el <i>render</i>, almacena la imagen en sus pasos
intermedios y la escribe a disco al finalizar.</li>
<li><i>Cámara</i>: lanza los rayos desde su punto de origen hacia el <i>mundo</i>
que determina el color del rayo. Hay un proceso por rayo... en la
imagen que estamos generando son \(400 \times 225 = 90.000\) procesos
independientes.</li>
<li><i>Mundo</i>: almacena una lista de los objetos que lo forman y se la
envía a los procesos de los rayos para que comprueben si chocan con
ellos.</li>
</ul>

<p>
Lo interesante de estas cosas de los procesos de <code>erlang</code> es que te
dan automáticamente el procesado en paralelo, y eso también tuvo
algunas consecuencias que mi lógica lineal no consiguió atrapar a la
primera.
</p>

<p>
Por ejemplo, hasta ahora no hacía falta almacenar la información de
cada <i>pixel</i> pues se procesaban uno tras otro y se escribían
directamente en su correspondiente fichero. Tuve que hacer algunos
cambios y ahora la <i>imagen</i> se guarda en memoria en un diccionario
indexado por el valor del <i>pixel</i>.  El código de la función principal
que veníamos trabajando quedó así:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">dibujar</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Iniciando dibujo...~n"</span>),

    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Datos de la Imagen
</span>    #<span style="color: #8be9fd; font-style: italic;">state</span>{ancho=<span style="color: #f8f8f2; font-weight: bold;">Ancho</span>,alto=<span style="color: #f8f8f2; font-weight: bold;">Alto</span>} = <span style="color: #f8f8f2; font-weight: bold;">Estado</span>,
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Establecidos datos de la imagen...~n"</span>),

    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Render
</span>    <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(
      <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">J</span>) -&gt;
              <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"."</span>),
              <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(
                <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">I</span>) -&gt;
                        <span style="color: #f8f8f2; font-weight: bold;">U</span> = <span style="color: #f8f8f2; font-weight: bold;">I</span> / (<span style="color: #f8f8f2; font-weight: bold;">Ancho</span> - 1),
                        <span style="color: #f8f8f2; font-weight: bold;">V</span> = <span style="color: #f8f8f2; font-weight: bold;">J</span> / (<span style="color: #f8f8f2; font-weight: bold;">Alto</span> - 1),
                        <span style="color: #f8f8f2; font-weight: bold;">UV</span> = {<span style="color: #f8f8f2; font-weight: bold;">U</span>,<span style="color: #f8f8f2; font-weight: bold;">V</span>},
                        <span style="color: #f8f8f2; font-weight: bold;">Pixel</span> = {<span style="color: #f8f8f2; font-weight: bold;">I</span>,<span style="color: #f8f8f2; font-weight: bold;">J</span>},
                        camara ! {trazar_rayo,<span style="color: #f8f8f2; font-weight: bold;">Pixel</span>,<span style="color: #f8f8f2; font-weight: bold;">UV</span>}
                <span style="color: #ff79c6; font-weight: bold;">end</span>,
                <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(0, <span style="color: #f8f8f2; font-weight: bold;">Ancho</span> - 1))
      <span style="color: #ff79c6; font-weight: bold;">end</span>,
      <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(<span style="color: #f8f8f2; font-weight: bold;">Alto</span> - 1, 0, -1)),
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"\nFinalizado\n"</span>).
</pre>
</div>

<p>
Como veis el bucle lo único que calcula es el <i>pixel</i> y el <i>UV</i> para
mandárselo a la cámara y se olvida de todo lo demás. Para volcar la
imagen hice otra función que se llama aparte:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">escribir_imagen</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>) -&gt;
    #<span style="color: #8be9fd; font-style: italic;">state</span>{ancho=<span style="color: #f8f8f2; font-weight: bold;">Ancho</span>,alto=<span style="color: #f8f8f2; font-weight: bold;">Alto</span>,lienzo=<span style="color: #f8f8f2; font-weight: bold;">Lienzo</span>} = <span style="color: #f8f8f2; font-weight: bold;">Estado</span>,
    <span style="color: #f8f8f2; font-weight: bold;">Cabecera</span> = <span style="color: #8be9fd; font-style: italic;">io_lib</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"P3~n~p ~p~n255~n"</span>, [<span style="color: #f8f8f2; font-weight: bold;">Ancho</span>,<span style="color: #f8f8f2; font-weight: bold;">Alto</span>]),
    <span style="color: #f8f8f2; font-weight: bold;">Imagen</span> =
        <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(
          <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">J</span>) -&gt;
                  <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"."</span>),
                  <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(
                    <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">I</span>) -&gt;
                            <span style="color: #f8f8f2; font-weight: bold;">Color</span> = <span style="color: #8be9fd; font-style: italic;">maps</span>:<span style="color: #8be9fd; font-style: italic;">get</span>({<span style="color: #f8f8f2; font-weight: bold;">I</span>,<span style="color: #f8f8f2; font-weight: bold;">J</span>}, <span style="color: #f8f8f2; font-weight: bold;">Lienzo</span>, {1,0,1}),
                            <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">escribe_color</span>(<span style="color: #f8f8f2; font-weight: bold;">Color</span>)
                    <span style="color: #ff79c6; font-weight: bold;">end</span>,
                    <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(0, <span style="color: #f8f8f2; font-weight: bold;">Ancho</span> - 1))
          <span style="color: #ff79c6; font-weight: bold;">end</span>,
          <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(<span style="color: #f8f8f2; font-weight: bold;">Alto</span> - 1, 0, -1)),
    {ok, <span style="color: #f8f8f2; font-weight: bold;">F</span>} = <span style="color: #8be9fd; font-style: italic;">file</span>:<span style="color: #8be9fd; font-style: italic;">open</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>#<span style="color: #8be9fd; font-style: italic;">state</span>.fichero, [write]),
    <span style="color: #8be9fd; font-style: italic;">file</span>:<span style="color: #8be9fd; font-style: italic;">write</span>(<span style="color: #f8f8f2; font-weight: bold;">F</span>, <span style="color: #f8f8f2; font-weight: bold;">Cabecera</span> ++ <span style="color: #f8f8f2; font-weight: bold;">Imagen</span>),
    <span style="color: #8be9fd; font-style: italic;">file</span>:<span style="color: #8be9fd; font-style: italic;">close</span>(<span style="color: #f8f8f2; font-weight: bold;">F</span>),
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"\nFinalizado\n"</span>).
</pre>
</div>

<p>
De esta función, cabe llamar la atención al color por defecto que se
empleará en el caso de que algún determinado <i>pixel</i> no se encuentre
en el diccionario que guarda la imagen: <code>{1,0,1}</code>. Elegí poner un
valor por defecto por dos razones:
</p>

<ol class="org-ol">
<li>Pensé que se me perdían algunos rayos y me adelanté a que en
imágenes más complejas no pudiera distinguir el negro de <i>falta un
pixel</i> del negro generado por el cálculo. El ojo humano no es
perfecto y darse cuenta de errores de pérdida de rayos por el color
va a ser complicado... sobre todo si utilizas un color tan habitual
como el negro.</li>
<li>No hubiera puesto ningún valor <i>por defecto</i> si hubiera estado
seguro de que se dibujaban todos los rayos.</li>
</ol>

<p>
Esto fue porque me llevé el primer susto cuando tenía ya todo
preparado para que empezara a funcionar de manera paralela. Lancé el
procedimiento y ese lanzamiento fue <i>paralelo</i><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>. Obtuve una
imagen tal que:
</p>


<figure id="org0fe1f94">
<img src="./imagenes/imagen-defecto.png" alt="imagen-defecto.png">

</figure>

<p>
<i>¿Cómo? ¿No ha dibujado nada?</i>, pensé. Y empecé a repasar el código
una y otra vez... <i>si ésto debería funcionar</i>. No encontrando el fallo
le puse algunos mensajes de aviso que me informaban si el proceso
pasaba por algunas determinadas funciones o no. Me di cuenta de que
además esos mensajes llegaban en un orden casi aleatorio, para obtener
una imagen tal que:
</p>


<figure id="org01fca1a">
<img src="./imagenes/imagen-trozo.png" alt="imagen-trozo.png">

</figure>

<p>
La conclusión fue sencilla después de que el <i>lelo</i> se diera cuenta
del <i>para</i> y de que el pobre proceso <i>mundo</i> estaba trabajando como
podía cuando los demás ya habían dado por concluida la jornada
laboral. Los procesos <i>cámara</i> e <i>imagen</i> estaban en total reposo
mientras el pobre <i>mundo</i> iba sacando el higadillo para poder terminar
antes de que yo cortara el proceso creyéndolo acabado. La solución de
momento es ponerle un contador a la cámara y que controle cuantos
rayos se han lanzado. Cuando el proceso <i>mundo</i> le manda el color de
un pixel a <i>imagen</i>, ésta informa a la cámara de que actualice el
contador de <i>rayos sueltos</i>. De esta manera se obtuvo la imagen
esperada:
</p>


<figure id="org61b3991">
<img src="./imagenes/imagen.png" alt="imagen.png">

</figure>

<p>
En el futuro quizá haya que automatizar el proceso de generar la
imagen de otra manera, teniendo claras las circunstancias en las que
se puede dar por concluido el procesamiento, pero de momento, como el
contador funciona y es simple de entender hasta para una mente tan
obtusa como la mía, pues lo mantengo.
</p>

<p>
Viendo el chasco con este primer intento por paralelizar los cálculos,
me decidí a convertirlo todo en procesos al más puro estilo <code>erlang</code>,
hasta los <i>rayos</i>. En realidad, si miramos el código, el proceso del
<i>rayo</i> está preparado para perpetuarse en un bucle, pero se mantiene
sólo hasta haber escrito el <i>pixel</i>. Sin embargo, no estoy seguro,
pero creo que será útil que se perpetúe durante un tiempo si ha de
lanzar otros <i>rayos</i> desde él: <i>rayos de sobra</i>, o <i>de reflexión</i>, o
<i>de refracción</i> o <i>antialiasing</i> y esperar a tener una respuesta con
un <i>color</i> más preciso.
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">start</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>, <span style="color: #f8f8f2; font-weight: bold;">Pixel</span>, <span style="color: #f8f8f2; font-weight: bold;">UV</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">spawn</span>(?<span style="color: #bd93f9;">MODULE</span>, init, [#<span style="color: #8be9fd; font-style: italic;">state</span>{rayo=<span style="color: #f8f8f2; font-weight: bold;">R</span>,pixel=<span style="color: #f8f8f2; font-weight: bold;">Pixel</span>,uv=<span style="color: #f8f8f2; font-weight: bold;">UV</span>}]).

<span style="color: #50fa7b; font-weight: bold;">init</span>(<span style="color: #f8f8f2; font-weight: bold;">State</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">self</span>() ! impacto,
    <span style="color: #8be9fd; font-style: italic;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">State</span>).

<span style="color: #50fa7b; font-weight: bold;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">State</span>) -&gt;
    <span style="color: #ff79c6; font-weight: bold;">receive</span>
        impacto -&gt;
            <span style="color: #8be9fd; font-style: italic;">impacto</span>(<span style="color: #f8f8f2; font-weight: bold;">State</span>, 0, ?<span style="color: #bd93f9;">INFINITO</span>);
        <span style="color: #f8f8f2; font-weight: bold;">_</span> -&gt;
            <span style="color: #8be9fd; font-style: italic;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">State</span>)
    <span style="color: #ff79c6; font-weight: bold;">end</span>.

<span style="color: #6272a4;">%%</span><span style="color: #6272a4;">-------------------------------------------------------------------------
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Funciones privadas
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">-------------------------------------------------------------------------
</span>
<span style="color: #50fa7b; font-weight: bold;">color</span>(<span style="color: #f8f8f2; font-weight: bold;">Objeto</span>, <span style="color: #f8f8f2; font-weight: bold;">R</span>, <span style="color: #f8f8f2; font-weight: bold;">Tmin</span>, <span style="color: #f8f8f2; font-weight: bold;">Tmax</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Hay_impacto</span> = <span style="color: #8be9fd; font-style: italic;">rerl_objeto</span>:<span style="color: #8be9fd; font-style: italic;">impacta</span>(<span style="color: #f8f8f2; font-weight: bold;">Objeto</span>, {<span style="color: #f8f8f2; font-weight: bold;">R</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmin</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmax</span>}),
    <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">Hay_impacto</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
        {true,<span style="color: #f8f8f2; font-weight: bold;">Np</span>} -&gt;
            {<span style="color: #f8f8f2; font-weight: bold;">X</span>,<span style="color: #f8f8f2; font-weight: bold;">Y</span>,<span style="color: #f8f8f2; font-weight: bold;">Z</span>} = <span style="color: #f8f8f2; font-weight: bold;">Np</span>,                                  <span style="color: #6272a4;">% </span><span style="color: #6272a4;">normal en el punto
</span>            <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>({<span style="color: #f8f8f2; font-weight: bold;">X</span>+1,<span style="color: #f8f8f2; font-weight: bold;">Y</span>+1,<span style="color: #f8f8f2; font-weight: bold;">Z</span>+1}, 0.5);                  <span style="color: #6272a4;">% </span><span style="color: #6272a4;">usar coordenadas como {R,G,B}
</span>        false -&gt;
            {<span style="color: #f8f8f2; font-weight: bold;">_</span>,<span style="color: #f8f8f2; font-weight: bold;">Y</span>,<span style="color: #f8f8f2; font-weight: bold;">_</span>} = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">vector_unidad</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir),
            <span style="color: #f8f8f2; font-weight: bold;">T</span> = 0.5 * (<span style="color: #f8f8f2; font-weight: bold;">Y</span> + 1),
            <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>({1.0,1.0,1.0}, (1-<span style="color: #f8f8f2; font-weight: bold;">T</span>)),      <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Del color blanco {1,1,1}
</span>                      <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>({0.5,0.7,1.0},  <span style="color: #f8f8f2; font-weight: bold;">T</span>));        <span style="color: #6272a4;">% </span><span style="color: #6272a4;">al color azul {0.5,07,1.0}
</span>        <span style="color: #f8f8f2; font-weight: bold;">_</span> -&gt;
            {1,0,0}
    <span style="color: #ff79c6; font-weight: bold;">end</span>.

<span style="color: #50fa7b; font-weight: bold;">impacto</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>, <span style="color: #f8f8f2; font-weight: bold;">Tmin</span>, <span style="color: #f8f8f2; font-weight: bold;">Tmax</span>) -&gt;
    mundo ! {<span style="color: #8be9fd; font-style: italic;">self</span>(), {get_objetos}},
    <span style="color: #f8f8f2; font-weight: bold;">Objetos</span> =
        <span style="color: #ff79c6; font-weight: bold;">receive</span>
            {<span style="color: #f8f8f2; font-weight: bold;">_</span>, <span style="color: #f8f8f2; font-weight: bold;">Respuesta</span>} -&gt;
                <span style="color: #f8f8f2; font-weight: bold;">Respuesta</span>
        <span style="color: #ff79c6; font-weight: bold;">end</span>,
    #<span style="color: #8be9fd; font-style: italic;">state</span>{rayo=<span style="color: #f8f8f2; font-weight: bold;">R</span>,pixel=<span style="color: #f8f8f2; font-weight: bold;">Pixel</span>} = <span style="color: #f8f8f2; font-weight: bold;">Estado</span>,
    <span style="color: #f8f8f2; font-weight: bold;">Impactos</span> =
        <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(
          <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">Obj</span>) -&gt;
                  <span style="color: #8be9fd; font-style: italic;">color</span>(<span style="color: #f8f8f2; font-weight: bold;">Obj</span>, <span style="color: #f8f8f2; font-weight: bold;">R</span>, <span style="color: #f8f8f2; font-weight: bold;">Tmin</span>, <span style="color: #f8f8f2; font-weight: bold;">Tmax</span>)
          <span style="color: #ff79c6; font-weight: bold;">end</span>,
          <span style="color: #f8f8f2; font-weight: bold;">Objetos</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Color</span> = <span style="color: #8be9fd; font-style: italic;">hd</span>(<span style="color: #f8f8f2; font-weight: bold;">Impactos</span>),
    imagen ! {pixel_color,<span style="color: #f8f8f2; font-weight: bold;">Pixel</span>,<span style="color: #f8f8f2; font-weight: bold;">Color</span>}.
</pre>
</div>
</div>
<div id="outline-container-org452c959" class="outline-3">
<h3 id="org452c959">Cargar el <i>mundo</i> desde un archivo</h3>
<div class="outline-text-3" id="text-org452c959">
<p>
Esta parte no viene en libro, pero ya puestos a tirar de
características de <code>erlang</code> como el autor tira de las de <code>C++</code> pues me
dio por hacerle un pequeño cargador de <i>mundos</i> al sistema. Entre los
mensajes que puede recibir el proceso <code>rerl_mundo</code> está el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-erlang">{cargar_mundo, <span style="color: #f8f8f2; font-weight: bold;">Nombre_Fichero</span>} -&gt;
    {ok,<span style="color: #f8f8f2; font-weight: bold;">Geoms</span>} = <span style="color: #8be9fd; font-style: italic;">file</span>:<span style="color: #8be9fd; font-style: italic;">consult</span>(<span style="color: #f8f8f2; font-weight: bold;">Nombre_Fichero</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Pids</span> = [<span style="color: #8be9fd; font-style: italic;">nuevo_objeto</span>(<span style="color: #f8f8f2; font-weight: bold;">X</span>) <span style="color: #ff79c6; font-weight: bold;">||</span> <span style="color: #f8f8f2; font-weight: bold;">X</span> <span style="color: #ff79c6; font-weight: bold;">&lt;-</span> <span style="color: #f8f8f2; font-weight: bold;">Geoms</span>],
    <span style="color: #8be9fd; font-style: italic;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">Pids</span>);
</pre>
</div>

<p>
El fichero que tengo preparado para la carga lo he llamado
<code>mundo.rerl</code> y tiene el siguiente contenido:
</p>

<div class="org-src-container">
<pre class="src src-erlang">{esfera,{0,0,-1},0.5}.
{esfera,{0,-100.5,-1},100}.
</pre>
</div>

<p>
No está automatizado aún para que lo cargue desde línea de comandos,
pero haciendo pruebas desde el lanzador funciona perfectamente y
genera dos objetos <i>esfera</i> con las geometrías dadas. Pero ya lo
veremos más adelante.
</p>

<p>
Además, también son independientes los procesos para los distintos
objetos del <i>mundo</i> aunque el código aún sólo reconoce la <i>esfera</i>
como geometría válida.
</p>

<p>
Pongo el código aquí de tres funciones para llamar la atención sobre
algún punto interesante de cómo funciona <code>erlang</code><sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">-------------------------------------------------------------------------
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Llamadas externas al proceso
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">-------------------------------------------------------------------------
</span>
<span style="color: #50fa7b; font-weight: bold;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>) -&gt;
    <span style="color: #ff79c6; font-weight: bold;">receive</span>
        {set_geometria,<span style="color: #f8f8f2; font-weight: bold;">Geometria</span>} -&gt;
            <span style="color: #8be9fd; font-style: italic;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>#<span style="color: #8be9fd; font-style: italic;">estado</span>{geometria=<span style="color: #f8f8f2; font-weight: bold;">Geometria</span>});
        {<span style="color: #f8f8f2; font-weight: bold;">From</span>, {impacta,<span style="color: #f8f8f2; font-weight: bold;">R</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmin</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmax</span>}} -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">Respuesta</span> = <span style="color: #8be9fd; font-style: italic;">hay_impacto</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>, <span style="color: #f8f8f2; font-weight: bold;">R</span>, <span style="color: #f8f8f2; font-weight: bold;">Tmin</span>, <span style="color: #f8f8f2; font-weight: bold;">Tmax</span>),
            <span style="color: #f8f8f2; font-weight: bold;">From</span> ! {<span style="color: #8be9fd; font-style: italic;">self</span>(),<span style="color: #f8f8f2; font-weight: bold;">Respuesta</span>},
            <span style="color: #8be9fd; font-style: italic;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>);
        terminar -&gt;
            ok;
        <span style="color: #f8f8f2; font-weight: bold;">_</span> -&gt;
            <span style="color: #8be9fd; font-style: italic;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>)
    <span style="color: #ff79c6; font-weight: bold;">end</span>.

<span style="color: #50fa7b; font-weight: bold;">impacta</span>(<span style="color: #f8f8f2; font-weight: bold;">From</span>, {<span style="color: #f8f8f2; font-weight: bold;">R</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmin</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmax</span>}) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">From</span> ! {<span style="color: #8be9fd; font-style: italic;">self</span>(),{impacta,<span style="color: #f8f8f2; font-weight: bold;">R</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmin</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmax</span>}},
    <span style="color: #ff79c6; font-weight: bold;">receive</span>
        {<span style="color: #f8f8f2; font-weight: bold;">From</span>,<span style="color: #f8f8f2; font-weight: bold;">Respuesta</span>} -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">Respuesta</span>
    <span style="color: #ff79c6; font-weight: bold;">end</span>.

<span style="color: #6272a4;">%%</span><span style="color: #6272a4;">-------------------------------------------------------------------------
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Interno: c&#225;lculos de impacto con el objeto en su Geometr&#237;a.
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">-------------------------------------------------------------------------
</span>
<span style="color: #50fa7b; font-weight: bold;">hay_impacto</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>, <span style="color: #f8f8f2; font-weight: bold;">R</span>, <span style="color: #f8f8f2; font-weight: bold;">_Tmin</span>, <span style="color: #f8f8f2; font-weight: bold;">_Tmax</span>)
  <span style="color: #ff79c6; font-weight: bold;">when</span> <span style="color: #8be9fd; font-style: italic;">is_record</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>#<span style="color: #8be9fd; font-style: italic;">estado</span>.geometria, esfera) -&gt;
    #<span style="color: #8be9fd; font-style: italic;">esfera</span>{centro=<span style="color: #f8f8f2; font-weight: bold;">Centro</span>,radio=<span style="color: #f8f8f2; font-weight: bold;">Radio</span>} = <span style="color: #f8f8f2; font-weight: bold;">Estado</span>#<span style="color: #8be9fd; font-style: italic;">estado</span>.geometria,
    <span style="color: #f8f8f2; font-weight: bold;">OC</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.origen, <span style="color: #f8f8f2; font-weight: bold;">Centro</span>),
    <span style="color: #f8f8f2; font-weight: bold;">A</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">modulo_cuadrado</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir),
    <span style="color: #f8f8f2; font-weight: bold;">Medio_B</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">punto</span>(<span style="color: #f8f8f2; font-weight: bold;">OC</span>, <span style="color: #f8f8f2; font-weight: bold;">R</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir),
    <span style="color: #f8f8f2; font-weight: bold;">C</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">modulo_cuadrado</span>(<span style="color: #f8f8f2; font-weight: bold;">OC</span>) - (<span style="color: #f8f8f2; font-weight: bold;">Radio</span> * <span style="color: #f8f8f2; font-weight: bold;">Radio</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Discriminante</span> = (<span style="color: #f8f8f2; font-weight: bold;">Medio_B</span> * <span style="color: #f8f8f2; font-weight: bold;">Medio_B</span>) - (<span style="color: #f8f8f2; font-weight: bold;">A</span> * <span style="color: #f8f8f2; font-weight: bold;">C</span>),
    <span style="color: #f8f8f2; font-weight: bold;">T</span> =
        <span style="color: #ff79c6; font-weight: bold;">if</span> <span style="color: #f8f8f2; font-weight: bold;">Discriminante</span> &lt; 0 -&gt;
                -1;
           true -&gt;
                <span style="color: #f8f8f2; font-weight: bold;">Raiz</span> = <span style="color: #8be9fd; font-style: italic;">math</span>:<span style="color: #8be9fd; font-style: italic;">sqrt</span>(<span style="color: #f8f8f2; font-weight: bold;">Discriminante</span>),
                ((-1*<span style="color: #f8f8f2; font-weight: bold;">Medio_B</span>) - <span style="color: #f8f8f2; font-weight: bold;">Raiz</span>) / <span style="color: #f8f8f2; font-weight: bold;">A</span>
        <span style="color: #ff79c6; font-weight: bold;">end</span>,
    <span style="color: #ff79c6; font-weight: bold;">if</span> <span style="color: #f8f8f2; font-weight: bold;">T</span> &gt; 0 -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">Punto</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">vector_unidad</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">hacia</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>, <span style="color: #f8f8f2; font-weight: bold;">T</span>), {0,0,-1})),
            {true,<span style="color: #f8f8f2; font-weight: bold;">Punto</span>};
       true -&gt;
            false
    <span style="color: #ff79c6; font-weight: bold;">end</span>;
<span style="color: #50fa7b; font-weight: bold;">hay_impacto</span>(<span style="color: #f8f8f2; font-weight: bold;">_</span>,<span style="color: #f8f8f2; font-weight: bold;">_</span>,<span style="color: #f8f8f2; font-weight: bold;">_</span>,<span style="color: #f8f8f2; font-weight: bold;">_</span>) -&gt;
    geometria_desconocida.
</pre>
</div>

<p>
Primero quiero llamar la atención del tándem:
</p>

<div class="org-src-container">
<pre class="src src-erlang">{<span style="color: #f8f8f2; font-weight: bold;">From</span>,{impacta,<span style="color: #f8f8f2; font-weight: bold;">R</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmin</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmax</span>}} -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Respuesta</span> = <span style="color: #8be9fd; font-style: italic;">hay_impacto</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>, <span style="color: #f8f8f2; font-weight: bold;">R</span>, <span style="color: #f8f8f2; font-weight: bold;">Tmin</span>, <span style="color: #f8f8f2; font-weight: bold;">Tmax</span>),
    <span style="color: #f8f8f2; font-weight: bold;">From</span> ! {<span style="color: #8be9fd; font-style: italic;">self</span>(), <span style="color: #f8f8f2; font-weight: bold;">Respuesta</span>},
    <span style="color: #8be9fd; font-style: italic;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>);
</pre>
</div>

<p>
y
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">impacta</span>(<span style="color: #f8f8f2; font-weight: bold;">From</span>, {<span style="color: #f8f8f2; font-weight: bold;">R</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmin</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmax</span>}) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">From</span> ! {<span style="color: #8be9fd; font-style: italic;">self</span>(),{impacta,<span style="color: #f8f8f2; font-weight: bold;">R</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmin</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmax</span>}},
    <span style="color: #ff79c6; font-weight: bold;">receive</span>
        {<span style="color: #f8f8f2; font-weight: bold;">From</span>,<span style="color: #f8f8f2; font-weight: bold;">Respuesta</span>} -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">Respuesta</span>
    <span style="color: #ff79c6; font-weight: bold;">end</span>.
</pre>
</div>

<p>
La segunda es una llamada <i>interna</i> a la segunda de manera que desde
fuera se puede emplear tanto la sintaxis:
</p>

<div class="org-src-container">
<pre class="src src-erlang">Pid_objeto ! {<span style="color: #8be9fd; font-style: italic;">self</span>(),{impacta,<span style="color: #f8f8f2; font-weight: bold;">R</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmin</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmax</span>}}.
</pre>
</div>

<p>
como
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #8be9fd; font-style: italic;">rerl_objeto</span>:<span style="color: #8be9fd; font-style: italic;">impacta</span>(<span style="color: #f8f8f2; font-weight: bold;">Pid_objeto</span>, {<span style="color: #f8f8f2; font-weight: bold;">R</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmin</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmax</span>}}.
</pre>
</div>

<p>
Ambas dos son accesibles para el código, pero la primera necesita ser
capturada y analizada por el proceso que envía la petición mientras
que la segunda devuelve esa información de forma directa, porque ya le
ha hecho el proceso que debería hacer el llamante. Eso evita tener que
capturar esa comunicación poniendo buzones <code>receive</code> cada dos por
tres... con un uso inteligente de <i>atoms</i> puedes utilizar la misma
función para varias operaciones como hace <code>OTP</code> con las llamadas a
<code>handle_call</code><sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup>, <code>handle_cast</code><sup><a id="fnr.6.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup> y <code>handle_info</code><sup><a id="fnr.6.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup>.
</p>

<p>
Por último, en la función <code>hay_impacto</code> se lleva a cabo el equivalente
al <i>polimorfismo</i> de la programación orientada a objetos. Como se
puede ver la cabecera incluye una cláusula <code>when</code> que comprueba que la
geometría que le llega es la de un registro <code>esfera</code>.
</p>

<p>
Otro aspecto que he reducido o cambiado en esta última refactorización
es eliminar el registro <code>vec3</code> para los puntos y vectores. Lo dejé
como una simple tupla de tres elementos y así puedo utilizarlas como
<code>{X,Y,Z}</code> o como <code>{R,G,B}</code>, si hace falta más adelante esa distinción
ya se hará.
</p>

<p>
A todo ésto, iba haciendo avances en la programación, pero el error en
los cálculos seguía y éste era el resultado:
</p>


<figure id="orge2a231c">
<img src="./imagenes/imagen-descuadrada.png" alt="imagen-descuadrada.png">

</figure>

<p>
Eso sí, lo hacía mucho más deprisa.
</p>
</div>
</div>
</div>
<div id="outline-container-orgd4ec2aa" class="outline-2">
<h2 id="orgd4ec2aa">Admitir varios objetos en el <i>render</i></h2>
<div class="outline-text-2" id="text-orgd4ec2aa">
<p>
El problema se arregló como dije, con ayuda. Me repasé las fórmulas
<i>sienes y sienes</i> de veces sin encontrar el error, las <i>deconstruí</i>
realizando los cálculos paso a paso y aún así la <i>cámara</i> seguía sin
enfocarse. Cuando se encontró el error fue el momento para perseguir
el objetivo inmediato que sigue el libro: diferenciar la cara interna
de la externa de los objetos.
</p>

<p>
Además, también, contaros cómo se ha conseguido representar varios
objetos en la escena, siguiendo el espíritu del libro, pero con un
código que se parece al original aún menos de lo que venía
pareciéndose hasta ahora.
</p>

<p>
El tema comienza con el registro <code>impacto</code>:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-record</span>(<span style="color: #8be9fd; font-style: italic;">impacto</span>, { p            = {0,0,0}    <span style="color: #6272a4;">% </span><span style="color: #6272a4;">vec3:     Punto del impacto
</span>                 , normal       = {0,1,0}    <span style="color: #6272a4;">% </span><span style="color: #6272a4;">vec3:     Normal en el punto del impacto
</span>                 , t            = 0          <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Num:      Factor de distancia del impacto
</span>                 , cara_frontal = false}).   <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Booleano: define si es impacto externo</span>
</pre>
</div>

<p>
Ese registro está preparado para devolver toda la información que
necesita el sistema para calcular el color. Echo de menos el mismo
registro de color en él, pero supongo que al no tener todavía ningún
tipo de soporte para texturas no lo necesita.
</p>

<p>
Básicamente consiste en determinar si el <i>rayo</i> coincide con la
superficie desde el interior o desde el exterior y cuál es la <i>normal</i>
en ese punto:
</p>


<figure id="org10f4218">
<img src="./imagenes/punto-impacto.png" alt="punto-impacto.png">

</figure>

<p>
Para ver si está impactando en una cara desde el exterior se utiliza
la función:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">cara_frontal</span>(<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>, <span style="color: #f8f8f2; font-weight: bold;">Impacto</span>, <span style="color: #f8f8f2; font-weight: bold;">Normal</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Cara_Frontal</span> = <span style="color: #8be9fd; font-style: italic;">punto</span>(<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir, <span style="color: #f8f8f2; font-weight: bold;">Normal</span>) &lt; 0,
    <span style="color: #f8f8f2; font-weight: bold;">N</span> =
        <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">Cara_Frontal</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
            true -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span><span style="color: #f8f8f2; font-weight: bold;">Normal</span>;
            false -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span><span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">Normal</span>, -1)
        <span style="color: #ff79c6; font-weight: bold;">end</span>,
    <span style="color: #f8f8f2; font-weight: bold;">Impacto</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>{cara_frontal=<span style="color: #f8f8f2; font-weight: bold;">Cara_Frontal</span>,normal=<span style="color: #f8f8f2; font-weight: bold;">N</span>}.
</pre>
</div>

<p>
Básicamente, como se puede ver es que comprueba el ángulo que forman
el rayo y la normal en el punto. Si están <i>enfrentados</i> es una cara
externa y en caso contrario interna (y le damos la vuelta a la
normal).
</p>

<p>
También es importante saber en qué punto(s) se produce ese <i>impacto</i>.
Hay que recordar que en nuestro modelo una esfera es sólo una fórmula
matemática y por tanto esos puntos no tienen grosor. Además de que lo
más probable es que si hay impacto con un objeto 3D no sea único sino
que atraviese el objeto al menos en dos puntos<sup><a id="fnr.7" class="footref" href="#fn.7" role="doc-backlink">7</a></sup>.
</p>

<p>
Ese registro se genera en el <code>objeto</code>, concretamente en la función
<code>hay_impacto/4</code>:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">hay_impacto</span>(#<span style="color: #8be9fd; font-style: italic;">esfera</span>{centro=<span style="color: #f8f8f2; font-weight: bold;">Centro</span>,radio=<span style="color: #f8f8f2; font-weight: bold;">Radio</span>}, #<span style="color: #8be9fd; font-style: italic;">rayo</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">Origen</span>,dir=<span style="color: #f8f8f2; font-weight: bold;">Dir</span>}=<span style="color: #f8f8f2; font-weight: bold;">R</span>, <span style="color: #f8f8f2; font-weight: bold;">Tmin</span>, <span style="color: #f8f8f2; font-weight: bold;">Tmax</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">OC</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(<span style="color: #f8f8f2; font-weight: bold;">Origen</span>, <span style="color: #f8f8f2; font-weight: bold;">Centro</span>),
    <span style="color: #f8f8f2; font-weight: bold;">A</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">modulo_cuadrado</span>(<span style="color: #f8f8f2; font-weight: bold;">Dir</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Medio_B</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">punto</span>(<span style="color: #f8f8f2; font-weight: bold;">OC</span>, <span style="color: #f8f8f2; font-weight: bold;">Dir</span>),
    <span style="color: #f8f8f2; font-weight: bold;">C</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">modulo_cuadrado</span>(<span style="color: #f8f8f2; font-weight: bold;">OC</span>) - (<span style="color: #f8f8f2; font-weight: bold;">Radio</span> * <span style="color: #f8f8f2; font-weight: bold;">Radio</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Discriminante</span> = (<span style="color: #f8f8f2; font-weight: bold;">Medio_B</span> * <span style="color: #f8f8f2; font-weight: bold;">Medio_B</span>) - (<span style="color: #f8f8f2; font-weight: bold;">A</span> * <span style="color: #f8f8f2; font-weight: bold;">C</span>),
    <span style="color: #ff79c6; font-weight: bold;">if</span>
        <span style="color: #f8f8f2; font-weight: bold;">Discriminante</span> &gt; 0 -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">Raiz</span> = <span style="color: #8be9fd; font-style: italic;">math</span>:<span style="color: #8be9fd; font-style: italic;">sqrt</span>(<span style="color: #f8f8f2; font-weight: bold;">Discriminante</span>),
            <span style="color: #f8f8f2; font-weight: bold;">T1</span> = (-<span style="color: #f8f8f2; font-weight: bold;">Medio_B</span> - <span style="color: #f8f8f2; font-weight: bold;">Raiz</span>) / <span style="color: #f8f8f2; font-weight: bold;">A</span>,
            <span style="color: #ff79c6; font-weight: bold;">if</span>
                <span style="color: #f8f8f2; font-weight: bold;">T1</span> &lt; <span style="color: #f8f8f2; font-weight: bold;">Tmax</span> <span style="color: #8be9fd; font-style: italic;">andalso</span> <span style="color: #f8f8f2; font-weight: bold;">T1</span> &gt; <span style="color: #f8f8f2; font-weight: bold;">Tmin</span> -&gt;
                    <span style="color: #f8f8f2; font-weight: bold;">T</span> = <span style="color: #f8f8f2; font-weight: bold;">T1</span>,
                    <span style="color: #f8f8f2; font-weight: bold;">P</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">hacia</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>, <span style="color: #f8f8f2; font-weight: bold;">T</span>),
                    <span style="color: #f8f8f2; font-weight: bold;">Normal</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">dividir</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(<span style="color: #f8f8f2; font-weight: bold;">P</span>, <span style="color: #f8f8f2; font-weight: bold;">Centro</span>), <span style="color: #f8f8f2; font-weight: bold;">Radio</span>),
                    <span style="color: #f8f8f2; font-weight: bold;">Impacto</span> = #<span style="color: #8be9fd; font-style: italic;">impacto</span>{p=<span style="color: #f8f8f2; font-weight: bold;">P</span>,t=<span style="color: #f8f8f2; font-weight: bold;">T</span>,normal=<span style="color: #f8f8f2; font-weight: bold;">Normal</span>},
                    <span style="color: #f8f8f2; font-weight: bold;">Exterior</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">cara_frontal</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>, <span style="color: #f8f8f2; font-weight: bold;">Impacto</span>, <span style="color: #f8f8f2; font-weight: bold;">Normal</span>),
                    {true, <span style="color: #f8f8f2; font-weight: bold;">Impacto</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>{cara_frontal=<span style="color: #f8f8f2; font-weight: bold;">Exterior</span>}};
                true -&gt;
                    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Este choque deber&#237;a ser tenido en cuenta como impacto de salida
</span>                    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">entiendo que en el libro lo obvia porque a&#250;n no hay materiales
</span>                    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">trasparentes y s&#243;lo lo tiene en cuenta si falla el anterior.
</span>                    <span style="color: #f8f8f2; font-weight: bold;">T2</span> = (-<span style="color: #f8f8f2; font-weight: bold;">Medio_B</span> + <span style="color: #f8f8f2; font-weight: bold;">Raiz</span>) / <span style="color: #f8f8f2; font-weight: bold;">A</span>,
                    <span style="color: #ff79c6; font-weight: bold;">if</span>
                        <span style="color: #f8f8f2; font-weight: bold;">T2</span> &lt; <span style="color: #f8f8f2; font-weight: bold;">Tmax</span> <span style="color: #8be9fd; font-style: italic;">andalso</span> <span style="color: #f8f8f2; font-weight: bold;">T2</span> &gt; <span style="color: #f8f8f2; font-weight: bold;">Tmin</span> -&gt;
                            <span style="color: #f8f8f2; font-weight: bold;">T</span> = <span style="color: #f8f8f2; font-weight: bold;">T2</span>,
                            <span style="color: #f8f8f2; font-weight: bold;">P</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">hacia</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>, <span style="color: #f8f8f2; font-weight: bold;">T</span>),
                            <span style="color: #f8f8f2; font-weight: bold;">Normal</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">dividir</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(<span style="color: #f8f8f2; font-weight: bold;">P</span>, <span style="color: #f8f8f2; font-weight: bold;">Centro</span>), <span style="color: #f8f8f2; font-weight: bold;">Radio</span>),
                            <span style="color: #f8f8f2; font-weight: bold;">Impacto</span> = #<span style="color: #8be9fd; font-style: italic;">impacto</span>{p=<span style="color: #f8f8f2; font-weight: bold;">P</span>,t=<span style="color: #f8f8f2; font-weight: bold;">T</span>,normal=<span style="color: #f8f8f2; font-weight: bold;">Normal</span>},
                            <span style="color: #f8f8f2; font-weight: bold;">Exterior</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">cara_frontal</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>, <span style="color: #f8f8f2; font-weight: bold;">Impacto</span>, <span style="color: #f8f8f2; font-weight: bold;">Normal</span>),
                            {true, <span style="color: #f8f8f2; font-weight: bold;">Impacto</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>{cara_frontal=<span style="color: #f8f8f2; font-weight: bold;">Exterior</span>}};
                        true -&gt;
                            {false, #<span style="color: #8be9fd; font-style: italic;">impacto</span>{t=?<span style="color: #bd93f9;">INFINITO</span>}}
                    <span style="color: #ff79c6; font-weight: bold;">end</span>
            <span style="color: #ff79c6; font-weight: bold;">end</span>;
        true -&gt;
            {false, #<span style="color: #8be9fd; font-style: italic;">impacto</span>{t=?<span style="color: #bd93f9;">INFINITO</span>}}
    <span style="color: #ff79c6; font-weight: bold;">end</span>;
<span style="color: #50fa7b; font-weight: bold;">hay_impacto</span>(<span style="color: #f8f8f2; font-weight: bold;">_</span>,<span style="color: #f8f8f2; font-weight: bold;">_</span>,<span style="color: #f8f8f2; font-weight: bold;">_</span>,<span style="color: #f8f8f2; font-weight: bold;">_</span>) -&gt;
    geometria_desconocida.
</pre>
</div>

<p>
Como se puede apreciar se generan impactos, bueno, en realidad se
genera sólo uno, ─o ninguno─. En el caso de que no haya impacto se
devuelve una <i>tupla</i> <code>{false,#impacto{t=?INFINITO}}</code>. Esto sirve, para
que el rayo pueda ordenar por distancia los impactos que haya:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">impacto</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>, <span style="color: #f8f8f2; font-weight: bold;">Tmin</span>, <span style="color: #f8f8f2; font-weight: bold;">Tmax</span>) -&gt;
    mundo ! {<span style="color: #8be9fd; font-style: italic;">self</span>(), {get_objetos}},
    <span style="color: #f8f8f2; font-weight: bold;">Objetos</span> =
        <span style="color: #ff79c6; font-weight: bold;">receive</span>
            {<span style="color: #f8f8f2; font-weight: bold;">_</span>, <span style="color: #f8f8f2; font-weight: bold;">Respuesta</span>} -&gt;
                <span style="color: #f8f8f2; font-weight: bold;">Respuesta</span>
        <span style="color: #ff79c6; font-weight: bold;">end</span>,
    #<span style="color: #8be9fd; font-style: italic;">state</span>{rayo=<span style="color: #f8f8f2; font-weight: bold;">R</span>,pixel=<span style="color: #f8f8f2; font-weight: bold;">Pixel</span>} = <span style="color: #f8f8f2; font-weight: bold;">Estado</span>,
    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Obtener todos los impactos del rayo con objetos
</span>    <span style="color: #f8f8f2; font-weight: bold;">Impactos</span> =
        <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(
          <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">Obj</span>) -&gt;
                  <span style="color: #8be9fd; font-style: italic;">rerl_objeto</span>:<span style="color: #8be9fd; font-style: italic;">impacta</span>(<span style="color: #f8f8f2; font-weight: bold;">Obj</span>, {<span style="color: #f8f8f2; font-weight: bold;">R</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmin</span>,<span style="color: #f8f8f2; font-weight: bold;">Tmax</span>})
          <span style="color: #ff79c6; font-weight: bold;">end</span>,
          <span style="color: #f8f8f2; font-weight: bold;">Objetos</span>),
    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Ordenarlos de m&#225;s cercano a m&#225;s lejano
</span>    <span style="color: #f8f8f2; font-weight: bold;">Iorden</span> =
        <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">sort</span>(
          <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">I</span>,<span style="color: #f8f8f2; font-weight: bold;">J</span>) -&gt;
                  {<span style="color: #f8f8f2; font-weight: bold;">_</span>,#<span style="color: #8be9fd; font-style: italic;">impacto</span>{t=<span style="color: #f8f8f2; font-weight: bold;">T1</span>}} = <span style="color: #f8f8f2; font-weight: bold;">I</span>,
                  {<span style="color: #f8f8f2; font-weight: bold;">_</span>,#<span style="color: #8be9fd; font-style: italic;">impacto</span>{t=<span style="color: #f8f8f2; font-weight: bold;">T2</span>}} = <span style="color: #f8f8f2; font-weight: bold;">J</span>,
                  <span style="color: #f8f8f2; font-weight: bold;">T1</span> &lt; <span style="color: #f8f8f2; font-weight: bold;">T2</span>
          <span style="color: #ff79c6; font-weight: bold;">end</span>,
          <span style="color: #f8f8f2; font-weight: bold;">Impactos</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Color</span> = <span style="color: #8be9fd; font-style: italic;">color</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>,<span style="color: #8be9fd; font-style: italic;">hd</span>(<span style="color: #f8f8f2; font-weight: bold;">Iorden</span>)),
    imagen ! {pixel_color,<span style="color: #f8f8f2; font-weight: bold;">Pixel</span>,<span style="color: #f8f8f2; font-weight: bold;">Color</span>}.
</pre>
</div>

<p>
Esta función obtiene una lista de <i>objetos</i> en el <i>mundo</i> y establece
si se cruza con ellos. Esos <code>Impactos</code> luego se ordenan en <code>Iorden</code> y
se obtiene el <code>Color</code> más cercano.
</p>

<p>
De momento, también, ese color lo decide el <code>rayo</code> sin embargo, me
parecería más lógico que lo decidiera el <i>objeto</i> o la <i>textura</i>.
</p>

<p>
La imagen obtenida es:
</p>


<figure id="orgbf91c6a">
<img src="./imagenes/imagen-dos-esferas.png" alt="imagen-dos-esferas.png">

</figure>

<p>
Os recuerdo los datos con los que se generan ambas esferas:
</p>

<div class="org-src-container">
<pre class="src src-erlang">{esfera,{0,0,-1},0.5}.
{esfera,{0,-100.5,-1},100}.
</pre>
</div>

<p>
Nuestra esfera de siempre es la que tiene centro en <code>{0,0,-1}</code> y un
radio <code>0.5</code>. La otra se puede observar que tiene un radio <code>100</code> y se
sitúa su centro en <code>{0,-100.5,-1}</code>. Es decir, esta segunda se sitúa
justo debajo de nuestra esfera de siempre a <code>-100.5</code> en la coordenada
<i>y</i>. <code>100</code> de su propio radio y <code>0.5</code> de la otra. Por tanto, sabemos
que ambas están situadas una encima de la otra y apenas se tocan en un
solo punto.
</p>

<p>
Si vemos la esfera inferior de color verde mientras la pequeña la
vemos azul es por el tema de las normales. Como sabéis se está
utilizando como <i>color</i> el valor de la <i>normal</i> en el punto. Mientras
a la pequeña la vemos desde un lateral orientado en el eje <i>z</i>, a la
grande la vemos desde la parte superior, orientada con el eje
<i>y</i>. Puesto que pasamos los valores de <code>{x,y,z}</code> directamente a
valores <code>{r,g,b}</code> los orientados en <i>y</i> se mapean a <i>g</i> y los
orientados a <i>z</i> se mapean a <i>b</i>. También podemos ver que la parte
derecha de la esfera pequeña es más <i>rojiza</i> que la izquierda, puesto
que en horizontal el componente que se alinea es <i>x</i> que se mapea a
<i>r</i>.
</p>
</div>
<div id="outline-container-org843e15e" class="outline-3">
<h3 id="org843e15e">La última refactorización</h3>
<div class="outline-text-3" id="text-org843e15e">
<p>
Después de todo lo anterior y como no terminaba de encontrar el punto
a la paralelización de los procesos de <i>render</i> me decidí a dividir la
imagen en teselas y hacer el dibujo por partes. Básicamente, he
añadido dos archivos más al desarrollo <code>rerl_renderer.erl</code> y
<code>rerl_tesela.erl</code>. La función del primero es controlar qué <i>teselas</i>
hay que dibujar. Levanta tantos procesos <i>tesela</i> como se especifique
por parámetro y éstos le van pidiendo las teselas que haya que
dibujar, cuando un proceso finaliza una tesela pide la siguiente hasta
que ya se han dibujado todas. Momento en que los procesos de dibujo
van muriendo y cuando han muerto todos se escribe la imagen.
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-module</span>(rerl_renderer).

<span style="color: #ffb86c;">-include</span>(<span style="color: #f1fa8c;">"registros.hrl"</span>).

<span style="color: #ffb86c;">-record</span>(<span style="color: #8be9fd; font-style: italic;">state</span>, {teselas  = []       <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Lista de teselas que procesar
</span>              , procesos = 10       <span style="color: #6272a4;">% </span><span style="color: #6272a4;">N&#250;mero de procesos por defecto
</span>              , camara   = {}       <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Datos de la c&#225;mara necesarios para calcular el pixel
</span>              , finados  = 0}).     <span style="color: #6272a4;">% </span><span style="color: #6272a4;">N&#250;mero de procesos finalizados
</span>
<span style="color: #ffb86c;">-export</span>([<span style="color: #8be9fd; font-style: italic;">start/3</span>, <span style="color: #8be9fd; font-style: italic;">init/1</span>]).

<span style="color: #50fa7b; font-weight: bold;">start</span>(<span style="color: #f8f8f2; font-weight: bold;">Teselas</span>,<span style="color: #f8f8f2; font-weight: bold;">Procesos</span>,<span style="color: #f8f8f2; font-weight: bold;">Camara</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Estado</span> = #<span style="color: #8be9fd; font-style: italic;">state</span>{teselas=<span style="color: #f8f8f2; font-weight: bold;">Teselas</span>,procesos=<span style="color: #f8f8f2; font-weight: bold;">Procesos</span>,camara=<span style="color: #f8f8f2; font-weight: bold;">Camara</span>},
    <span style="color: #8be9fd; font-style: italic;">spawn</span>(rerl_renderer, init, [<span style="color: #f8f8f2; font-weight: bold;">Estado</span>]).

<span style="color: #50fa7b; font-weight: bold;">init</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>).

<span style="color: #50fa7b; font-weight: bold;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>) -&gt;
    <span style="color: #ff79c6; font-weight: bold;">receive</span>
        {iniciar_render,<span style="color: #f8f8f2; font-weight: bold;">Lado</span>,<span style="color: #f8f8f2; font-weight: bold;">Ix</span>,<span style="color: #f8f8f2; font-weight: bold;">Iy</span>,<span style="color: #f8f8f2; font-weight: bold;">Muestras</span>} -&gt;
            <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Iniciando dibujo...~n"</span>),
            #<span style="color: #8be9fd; font-style: italic;">state</span>{procesos=<span style="color: #f8f8f2; font-weight: bold;">Procesos</span>,camara=<span style="color: #f8f8f2; font-weight: bold;">Cam</span>} = <span style="color: #f8f8f2; font-weight: bold;">Estado</span>,
            <span style="color: #8be9fd; font-style: italic;">iniciar_procesos</span>(<span style="color: #f8f8f2; font-weight: bold;">Lado</span>, {<span style="color: #f8f8f2; font-weight: bold;">Ix</span>,<span style="color: #f8f8f2; font-weight: bold;">Iy</span>}, <span style="color: #f8f8f2; font-weight: bold;">Muestras</span>, <span style="color: #f8f8f2; font-weight: bold;">Procesos</span>, <span style="color: #f8f8f2; font-weight: bold;">Cam</span>),
            <span style="color: #8be9fd; font-style: italic;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>);
        {<span style="color: #f8f8f2; font-weight: bold;">From</span>, nueva_tesela} -&gt;
            {<span style="color: #f8f8f2; font-weight: bold;">Respuesta</span>,<span style="color: #f8f8f2; font-weight: bold;">Mosaico</span>} = <span style="color: #8be9fd; font-style: italic;">devolver_nueva_tesela</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>),
            <span style="color: #f8f8f2; font-weight: bold;">From</span> ! <span style="color: #f8f8f2; font-weight: bold;">Respuesta</span>,
            <span style="color: #f8f8f2; font-weight: bold;">Nuevo_Estado</span> = <span style="color: #f8f8f2; font-weight: bold;">Estado</span>#<span style="color: #8be9fd; font-style: italic;">state</span>{teselas=<span style="color: #f8f8f2; font-weight: bold;">Mosaico</span>},
            <span style="color: #8be9fd; font-style: italic;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">Nuevo_Estado</span>);
        proceso_finado -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">Finados</span> = <span style="color: #f8f8f2; font-weight: bold;">Estado</span>#<span style="color: #8be9fd; font-style: italic;">state</span>.finados + 1,
            <span style="color: #ff79c6; font-weight: bold;">if</span> <span style="color: #f8f8f2; font-weight: bold;">Finados</span> =:= <span style="color: #f8f8f2; font-weight: bold;">Estado</span>#<span style="color: #8be9fd; font-style: italic;">state</span>.procesos -&gt;
                    imagen ! escribir_imagen;
               true -&gt;
                    <span style="color: #8be9fd; font-style: italic;">loop</span>(#<span style="color: #8be9fd; font-style: italic;">state</span>{finados=<span style="color: #f8f8f2; font-weight: bold;">Finados</span>})
            <span style="color: #ff79c6; font-weight: bold;">end</span>;
        <span style="color: #f8f8f2; font-weight: bold;">_</span> -&gt;
            <span style="color: #8be9fd; font-style: italic;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>)
    <span style="color: #ff79c6; font-weight: bold;">end</span>.

<span style="color: #6272a4;">%%%</span><span style="color: #6272a4;">-------------------------------------------------------------------------
</span><span style="color: #6272a4;">%%% </span><span style="color: #6272a4;">Funciones internas
</span><span style="color: #6272a4;">%%%</span><span style="color: #6272a4;">-------------------------------------------------------------------------
</span>
<span style="color: #50fa7b; font-weight: bold;">iniciar_procesos</span>(<span style="color: #f8f8f2; font-weight: bold;">Lado</span>, {<span style="color: #f8f8f2; font-weight: bold;">Ix</span>,<span style="color: #f8f8f2; font-weight: bold;">Iy</span>}, <span style="color: #f8f8f2; font-weight: bold;">Muestras</span>, <span style="color: #f8f8f2; font-weight: bold;">Procesos</span>, <span style="color: #f8f8f2; font-weight: bold;">Cam</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">foreach</span>(
      <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">_</span>) -&gt;
              <span style="color: #f8f8f2; font-weight: bold;">P</span> = <span style="color: #8be9fd; font-style: italic;">rerl_tesela</span>:<span style="color: #8be9fd; font-style: italic;">start</span>(<span style="color: #f8f8f2; font-weight: bold;">Lado</span>, {<span style="color: #f8f8f2; font-weight: bold;">Ix</span>,<span style="color: #f8f8f2; font-weight: bold;">Iy</span>}, <span style="color: #f8f8f2; font-weight: bold;">Muestras</span>, <span style="color: #f8f8f2; font-weight: bold;">Cam</span>, <span style="color: #8be9fd; font-style: italic;">self</span>()),
              <span style="color: #f8f8f2; font-weight: bold;">P</span> ! render_tesela
      <span style="color: #ff79c6; font-weight: bold;">end</span>,
      <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(1,<span style="color: #f8f8f2; font-weight: bold;">Procesos</span>)).

<span style="color: #50fa7b; font-weight: bold;">devolver_nueva_tesela</span>(#<span style="color: #8be9fd; font-style: italic;">state</span>{teselas=<span style="color: #f8f8f2; font-weight: bold;">Mosaico</span>}) -&gt;
    <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">Mosaico</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
        [] -&gt;
            {no_hay,[]};
        [<span style="color: #f8f8f2; font-weight: bold;">H</span>|<span style="color: #f8f8f2; font-weight: bold;">T</span>] -&gt;
            {{ok,<span style="color: #f8f8f2; font-weight: bold;">H</span>}, <span style="color: #f8f8f2; font-weight: bold;">T</span>}
    <span style="color: #ff79c6; font-weight: bold;">end</span>.
</pre>
</div>

<p>
Como se puede apreciar por el código anterior es todo muy simple.
</p>

<p>
Por otro lado, todo el código para dibujar cada pixel ha pasado a
trabajar en <code>rerl_tesela</code>.
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-module</span>(rerl_tesela).

<span style="color: #ffb86c;">-include</span>(<span style="color: #f1fa8c;">"registros.hrl"</span>).

<span style="color: #ffb86c;">-record</span>(<span style="color: #8be9fd; font-style: italic;">state</span>, {lado     = 25         <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Tama&#241;o de la tesela cuadrada
</span>              , imagen   = {400,225}  <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Tama&#241;o de la imagen en pixeles
</span>              , muestras = 10         <span style="color: #6272a4;">% </span><span style="color: #6272a4;">N&#250;mero de muestras por pixel
</span>              , camara   = {}         <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Datos de la c&#225;mara necesarios para calcular el pixel
</span>              , renderer = nil}).     <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Pid del proceso controlador del render
</span>
<span style="color: #ffb86c;">-export</span>([<span style="color: #8be9fd; font-style: italic;">start/5</span>, <span style="color: #8be9fd; font-style: italic;">init/1</span>]).

<span style="color: #50fa7b; font-weight: bold;">start</span>(<span style="color: #f8f8f2; font-weight: bold;">Lado</span>, <span style="color: #f8f8f2; font-weight: bold;">Imagen</span>, <span style="color: #f8f8f2; font-weight: bold;">Muestras</span>, <span style="color: #f8f8f2; font-weight: bold;">Cam</span>, <span style="color: #f8f8f2; font-weight: bold;">PidR</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Estado</span> = #<span style="color: #8be9fd; font-style: italic;">state</span>{lado=<span style="color: #f8f8f2; font-weight: bold;">Lado</span>,imagen=<span style="color: #f8f8f2; font-weight: bold;">Imagen</span>,muestras=<span style="color: #f8f8f2; font-weight: bold;">Muestras</span>,camara=<span style="color: #f8f8f2; font-weight: bold;">Cam</span>,renderer=<span style="color: #f8f8f2; font-weight: bold;">PidR</span>},
    <span style="color: #8be9fd; font-style: italic;">spawn</span>(rerl_tesela, init, [<span style="color: #f8f8f2; font-weight: bold;">Estado</span>]).

<span style="color: #50fa7b; font-weight: bold;">init</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>).

<span style="color: #50fa7b; font-weight: bold;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>) -&gt;
    <span style="color: #ff79c6; font-weight: bold;">receive</span>
        render_tesela -&gt;
            <span style="color: #8be9fd; font-style: italic;">siguiente_tesela</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>),
            <span style="color: #8be9fd; font-style: italic;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>);
        terminar -&gt;
            ok;
        <span style="color: #f8f8f2; font-weight: bold;">_</span> -&gt;
            <span style="color: #8be9fd; font-style: italic;">loop</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>)
    <span style="color: #ff79c6; font-weight: bold;">end</span>.

<span style="color: #6272a4;">%%%</span><span style="color: #6272a4;">===================================================================
</span><span style="color: #6272a4;">%%% </span><span style="color: #6272a4;">Funciones internas
</span><span style="color: #6272a4;">%%%</span><span style="color: #6272a4;">===================================================================
</span>
<span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Pide una tesela que procesar y si no hay informa al controlador de
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">render de que para su proceso.
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #50fa7b; font-weight: bold;">siguiente_tesela</span>(#<span style="color: #8be9fd; font-style: italic;">state</span>{renderer=<span style="color: #f8f8f2; font-weight: bold;">Rendr</span>}=<span style="color: #f8f8f2; font-weight: bold;">Estado</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Rendr</span> ! {<span style="color: #8be9fd; font-style: italic;">self</span>(), nueva_tesela},
    <span style="color: #f8f8f2; font-weight: bold;">Tesela</span> =
        <span style="color: #ff79c6; font-weight: bold;">receive</span>
            <span style="color: #f8f8f2; font-weight: bold;">Respuesta</span> -&gt;
                <span style="color: #f8f8f2; font-weight: bold;">Respuesta</span>
        <span style="color: #ff79c6; font-weight: bold;">end</span>,
    <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">Tesela</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
        no_hay -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">Rendr</span> ! proceso_finado,
            <span style="color: #8be9fd; font-style: italic;">self</span>() ! terminar;
        {ok, <span style="color: #f8f8f2; font-weight: bold;">Vt</span>} -&gt;
            <span style="color: #8be9fd; font-style: italic;">render_tesela</span>(<span style="color: #f8f8f2; font-weight: bold;">Estado</span>, <span style="color: #f8f8f2; font-weight: bold;">Vt</span>)
    <span style="color: #ff79c6; font-weight: bold;">end</span>.

<span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Recorre los pixeles dentro de la tesela para hacer el render
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #50fa7b; font-weight: bold;">render_tesela</span>(#<span style="color: #8be9fd; font-style: italic;">state</span>{lado=<span style="color: #f8f8f2; font-weight: bold;">Lado</span>,imagen={<span style="color: #f8f8f2; font-weight: bold;">Ix</span>,<span style="color: #f8f8f2; font-weight: bold;">Iy</span>}}=<span style="color: #f8f8f2; font-weight: bold;">Estado</span>, {<span style="color: #f8f8f2; font-weight: bold;">Tx</span>,<span style="color: #f8f8f2; font-weight: bold;">Ty</span>}) -&gt;
    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">convertir la posici&#243;n de la tesela en pixeles de la imagen.
</span>    <span style="color: #f8f8f2; font-weight: bold;">Escala</span> = (<span style="color: #f8f8f2; font-weight: bold;">Lado</span> - 1),
    <span style="color: #f8f8f2; font-weight: bold;">Xmin</span> = <span style="color: #f8f8f2; font-weight: bold;">Tx</span> * <span style="color: #f8f8f2; font-weight: bold;">Lado</span>,
    <span style="color: #f8f8f2; font-weight: bold;">Xmax</span> = <span style="color: #8be9fd; font-style: italic;">min</span>(<span style="color: #f8f8f2; font-weight: bold;">Xmin</span> + <span style="color: #f8f8f2; font-weight: bold;">Escala</span>, <span style="color: #f8f8f2; font-weight: bold;">Ix</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Ymin</span> = <span style="color: #f8f8f2; font-weight: bold;">Ty</span> * <span style="color: #f8f8f2; font-weight: bold;">Lado</span>,
    <span style="color: #f8f8f2; font-weight: bold;">Ymax</span> = <span style="color: #8be9fd; font-style: italic;">min</span>(<span style="color: #f8f8f2; font-weight: bold;">Ymin</span> + <span style="color: #f8f8f2; font-weight: bold;">Escala</span>, <span style="color: #f8f8f2; font-weight: bold;">Iy</span>),
    <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(
      <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">Y</span>) -&gt;
              <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(
                <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">X</span>) -&gt;
                        <span style="color: #8be9fd; font-style: italic;">procesa_pixel</span>({<span style="color: #f8f8f2; font-weight: bold;">X</span>,<span style="color: #f8f8f2; font-weight: bold;">Y</span>}, <span style="color: #f8f8f2; font-weight: bold;">Estado</span>)
                <span style="color: #ff79c6; font-weight: bold;">end</span>,
                <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(<span style="color: #f8f8f2; font-weight: bold;">Xmin</span>, <span style="color: #f8f8f2; font-weight: bold;">Xmax</span>))
      <span style="color: #ff79c6; font-weight: bold;">end</span>,
      <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(<span style="color: #f8f8f2; font-weight: bold;">Ymin</span>,<span style="color: #f8f8f2; font-weight: bold;">Ymax</span>)),
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"."</span>),
    <span style="color: #8be9fd; font-style: italic;">self</span>() ! render_tesela.

<span style="color: #6272a4;">%%%</span><span style="color: #6272a4;">-------------------------------------------------------------------------
</span><span style="color: #6272a4;">%%% </span><span style="color: #6272a4;">Funciones de render
</span><span style="color: #6272a4;">%%%</span><span style="color: #6272a4;">-------------------------------------------------------------------------
</span>
<span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Calcula el color obtenido por un rayo particular
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #50fa7b; font-weight: bold;">color_rayo</span>(<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Impactos</span> = <span style="color: #8be9fd; font-style: italic;">rerl_mundo</span>:<span style="color: #8be9fd; font-style: italic;">llamada</span>(mundo, {impacto,<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>,0,?<span style="color: #bd93f9;">INFINITO</span>}),
    <span style="color: #f8f8f2; font-weight: bold;">Orden_impactos</span> =
        <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">sort</span>(
          <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">I</span>,<span style="color: #f8f8f2; font-weight: bold;">J</span>) -&gt;
                  {<span style="color: #f8f8f2; font-weight: bold;">_</span>,#<span style="color: #8be9fd; font-style: italic;">impacto</span>{t=<span style="color: #f8f8f2; font-weight: bold;">T1</span>}} = <span style="color: #f8f8f2; font-weight: bold;">I</span>,
                  {<span style="color: #f8f8f2; font-weight: bold;">_</span>,#<span style="color: #8be9fd; font-style: italic;">impacto</span>{t=<span style="color: #f8f8f2; font-weight: bold;">T2</span>}} = <span style="color: #f8f8f2; font-weight: bold;">J</span>,
                  <span style="color: #f8f8f2; font-weight: bold;">T1</span> &lt; <span style="color: #f8f8f2; font-weight: bold;">T2</span>
          <span style="color: #ff79c6; font-weight: bold;">end</span>,
          <span style="color: #f8f8f2; font-weight: bold;">Impactos</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Impacto_Cercano</span> = <span style="color: #8be9fd; font-style: italic;">hd</span>(<span style="color: #f8f8f2; font-weight: bold;">Orden_impactos</span>),
    <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">Impacto_Cercano</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
        {true,<span style="color: #f8f8f2; font-weight: bold;">Np</span>} -&gt;
            {<span style="color: #f8f8f2; font-weight: bold;">X</span>,<span style="color: #f8f8f2; font-weight: bold;">Y</span>,<span style="color: #f8f8f2; font-weight: bold;">Z</span>} = <span style="color: #f8f8f2; font-weight: bold;">Np</span>#<span style="color: #8be9fd; font-style: italic;">impacto</span>.normal,                   <span style="color: #6272a4;">% </span><span style="color: #6272a4;">normal en el punto
</span>            <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>({<span style="color: #f8f8f2; font-weight: bold;">X</span>+1,<span style="color: #f8f8f2; font-weight: bold;">Y</span>+1,<span style="color: #f8f8f2; font-weight: bold;">Z</span>+1}, 0.5);                  <span style="color: #6272a4;">% </span><span style="color: #6272a4;">usar coordenadas como {R,G,B}
</span>        {false,<span style="color: #f8f8f2; font-weight: bold;">_</span>} -&gt;
            #<span style="color: #8be9fd; font-style: italic;">rayo</span>{dir=<span style="color: #f8f8f2; font-weight: bold;">Dir</span>} = <span style="color: #f8f8f2; font-weight: bold;">Rayo</span>,
            {<span style="color: #f8f8f2; font-weight: bold;">_</span>,<span style="color: #f8f8f2; font-weight: bold;">Y</span>,<span style="color: #f8f8f2; font-weight: bold;">_</span>} = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">vector_unidad</span>(<span style="color: #f8f8f2; font-weight: bold;">Dir</span>),
            <span style="color: #f8f8f2; font-weight: bold;">T</span> = 0.5 * (<span style="color: #f8f8f2; font-weight: bold;">Y</span> + 1),
            <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>({1.0,1.0,1.0}, (1-<span style="color: #f8f8f2; font-weight: bold;">T</span>)),      <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Del color blanco {1,1,1}
</span>                      <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>({0.5,0.7,1.0},  <span style="color: #f8f8f2; font-weight: bold;">T</span>))         <span style="color: #6272a4;">% </span><span style="color: #6272a4;">al color azul {0.5,07,1.0}
</span>    <span style="color: #ff79c6; font-weight: bold;">end</span>.

<span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Calcula la direcci&#243;n de un nuevo rayo. El origen siempre es el
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">origen de la c&#225;mara.
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #50fa7b; font-weight: bold;">lanza_rayo</span>(<span style="color: #f8f8f2; font-weight: bold;">Cam</span>, <span style="color: #f8f8f2; font-weight: bold;">U</span>, <span style="color: #f8f8f2; font-weight: bold;">V</span>) -&gt;
    {<span style="color: #f8f8f2; font-weight: bold;">Origen</span>, <span style="color: #f8f8f2; font-weight: bold;">Eii</span>, <span style="color: #f8f8f2; font-weight: bold;">Horizontal</span>, <span style="color: #f8f8f2; font-weight: bold;">Vertical</span>} = <span style="color: #f8f8f2; font-weight: bold;">Cam</span>,
    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Eii + Hor*U + Ver*V - Origen
</span>    <span style="color: #f8f8f2; font-weight: bold;">Dir</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(
            <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(
              <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(
                <span style="color: #f8f8f2; font-weight: bold;">Eii</span>,
                <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">Horizontal</span>,<span style="color: #f8f8f2; font-weight: bold;">U</span>)),
              <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">Vertical</span>, <span style="color: #f8f8f2; font-weight: bold;">V</span>)),
            <span style="color: #f8f8f2; font-weight: bold;">Origen</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Rayo</span> = #<span style="color: #8be9fd; font-style: italic;">rayo</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">Origen</span>,dir=<span style="color: #f8f8f2; font-weight: bold;">Dir</span>},
    <span style="color: #8be9fd; font-style: italic;">color_rayo</span>(<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>).

<span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Env&#237;a tantos rayos como defina el valor de `Muestras` y los integra
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">calculandon el valor del pixel como suma de cada color obtenido
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">aplicando el factor 1/Muestras.
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #50fa7b; font-weight: bold;">toma_muestras</span>(<span style="color: #f8f8f2; font-weight: bold;">Pixel</span>, <span style="color: #f8f8f2; font-weight: bold;">_Estado</span>, <span style="color: #f8f8f2; font-weight: bold;">Color</span>, 0) -&gt;
    imagen ! {pixel_color,<span style="color: #f8f8f2; font-weight: bold;">Pixel</span>,<span style="color: #f8f8f2; font-weight: bold;">Color</span>};
<span style="color: #50fa7b; font-weight: bold;">toma_muestras</span>(<span style="color: #f8f8f2; font-weight: bold;">Pixel</span>, #<span style="color: #8be9fd; font-style: italic;">state</span>{imagen={<span style="color: #f8f8f2; font-weight: bold;">Ix</span>,<span style="color: #f8f8f2; font-weight: bold;">Iy</span>},camara=<span style="color: #f8f8f2; font-weight: bold;">Cam</span>,muestras=<span style="color: #f8f8f2; font-weight: bold;">Muestras</span>}=<span style="color: #f8f8f2; font-weight: bold;">Estado</span>, <span style="color: #f8f8f2; font-weight: bold;">Color</span>, <span style="color: #f8f8f2; font-weight: bold;">Contador</span>) -&gt;
    {<span style="color: #f8f8f2; font-weight: bold;">I</span>,<span style="color: #f8f8f2; font-weight: bold;">J</span>} = <span style="color: #f8f8f2; font-weight: bold;">Pixel</span>,
    <span style="color: #f8f8f2; font-weight: bold;">U</span> = (<span style="color: #f8f8f2; font-weight: bold;">I</span> + <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">random</span>()) / (<span style="color: #f8f8f2; font-weight: bold;">Ix</span> - 1),
    <span style="color: #f8f8f2; font-weight: bold;">V</span> = (<span style="color: #f8f8f2; font-weight: bold;">J</span> + <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">random</span>()) / (<span style="color: #f8f8f2; font-weight: bold;">Iy</span> - 1),
    <span style="color: #f8f8f2; font-weight: bold;">Ci</span> = <span style="color: #8be9fd; font-style: italic;">lanza_rayo</span>(<span style="color: #f8f8f2; font-weight: bold;">Cam</span>, <span style="color: #f8f8f2; font-weight: bold;">U</span>, <span style="color: #f8f8f2; font-weight: bold;">V</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Nuevo_Color</span> = <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #f8f8f2; font-weight: bold;">Color</span>, <span style="color: #8be9fd; font-style: italic;">rerl</span>:<span style="color: #8be9fd; font-style: italic;">dividir</span>(<span style="color: #f8f8f2; font-weight: bold;">Ci</span>, <span style="color: #f8f8f2; font-weight: bold;">Muestras</span>)),
    <span style="color: #8be9fd; font-style: italic;">toma_muestras</span>(<span style="color: #f8f8f2; font-weight: bold;">Pixel</span>, <span style="color: #f8f8f2; font-weight: bold;">Estado</span>, <span style="color: #f8f8f2; font-weight: bold;">Nuevo_Color</span>, <span style="color: #f8f8f2; font-weight: bold;">Contador</span> - 1).

<span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Llamada a la funci&#243;n recursiva para que procese cada pixel.
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">
</span><span style="color: #50fa7b; font-weight: bold;">procesa_pixel</span>(<span style="color: #f8f8f2; font-weight: bold;">Pixel</span>,#<span style="color: #8be9fd; font-style: italic;">state</span>{muestras=<span style="color: #f8f8f2; font-weight: bold;">Muestras</span>}=<span style="color: #f8f8f2; font-weight: bold;">Estado</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">toma_muestras</span>(<span style="color: #f8f8f2; font-weight: bold;">Pixel</span>, <span style="color: #f8f8f2; font-weight: bold;">Estado</span>, {0.0,0.0,0.0}, <span style="color: #f8f8f2; font-weight: bold;">Muestras</span>).
</pre>
</div>

<p>
Para mostrar cómo se va realizando el <i>render</i> por <i>teselas</i> adjunto
una imagen detenida en medio del proceso:
</p>


<figure id="org28a8b64">
<img src="./imagenes/imagen-teselas.png" alt="imagen-teselas.png">

</figure>
</div>
</div>
</div>
<div id="outline-container-orgcdc288a" class="outline-2">
<h2 id="orgcdc288a">Tiempos de ejecución</h2>
<div class="outline-text-2" id="text-orgcdc288a">
<p>
También le añadí un contador de tiempos a la imagen, desde el momento
en se que lanza hasta el momento en que se guarda la imagen a archivo.
Con este contador he conseguido averiguar algunas cosas interesantes
sobre el procesado paralelo de la generación de imagen. Por ejemplo,
lanzando 10 procesos y lanzando 100 he encontrado que el tiempo final
del <i>render</i> no varía mucho. Ambos valores sobrepasan la capacidad de
hilos que puede dar la máquina y lo que obtienes al final es un montón
de procesos parados esperando su turno para ejecutarse. Eso sí,
cuantos más procesos más memoria se gasta. No es muy importante con
dichas cantidades, que pueden variar entre los <code>0,8Kb</code> y <code>1,3Mb</code>, pero
cuando lanzas <code>100</code> procesos por pixel, puede llegar a desbordar la
memoria y bloquear la máquina.
</p>

<p>
Tal y como va el sistema ahora, con 100 muestras (<i>samples</i>) por
pixel, una imagen sencilla como la que está generando el proceso
tarda, en mi máquina, que ya tiene sus añitos, alrededor de minuto y
medio. Puede parecer mucho, sobre todo porque sin el refinado de las
muestras tarda apenas un par de segundos. Sin embargo, por comparar
veamos las dos imágenes juntas:
</p>

<p>
<img src="./imagenes/imagen-dos-esferas.png" alt="imagen-dos-esferas.png">
<img src="./imagenes/imagen-100-samples.png" alt="imagen-100-samples.png">
</p>
</div>
</div>
<div id="outline-container-org6d00b83" class="outline-2">
<h2 id="org6d00b83">Conclusiones</h2>
<div class="outline-text-2" id="text-org6d00b83">
<p>
Ya sé que el artículo de hoy ha sido un poco ladrillo y parece que
avanza poco en el objetivo. Pero...  De momento tengo un sistema que
funciona con procesos paralelos. No está afinado, todavía tengo que
afinarlo más. Los planes, de momento, son eliminar los procesos de los
objetos y el mundo para que los procesos de <i>render</i> por teselas no
tengan que estar llamando a sólo unos pocos procesos desperdiciando un
poco la <i>paralelización</i> del procedimiento. Es decir, que los datos
sean accesibles para todos de manera directa sin estar enviando
llamadas al mismo proceso creando un embudo o cuello de botella.  Por
otro lado, seguramente los procesos de <i>imagen</i>, <i>cámara</i> y
<i>controlador</i> terminen unificados. Sin embargo, mis planes siguientes
es avanzar un poco más en el <i>tutorial</i> del libro y abandonar un poco
el de los procesos. No por olvidarlos sino por no saturarme con el
<i>cómo</i> dejando de lado el <i>qué</i>. Seguramente haya algún avance más que
se pueda llevar a cabo en la generación de imágenes para ir, poco a
poco, avanzando también en el <i>cómo</i> más adelante. Además, conociendo
mejor el sistema y las necesidades que irá generando, y otras que me
gustaría ir probando: como por ejemplo, si consigo que el proceso
paralelo se pueda distribuir por una red de ordenadores de forma
sencilla y aumentar así la velocidad en la que se pueden realizar las
imágenes.
</p>

<p>
De ahí a montar una <i>granja de render</i> hay un abismo, pero sería uno
de los objetivos que me gustaría aunque no sea más que esbozar y poder
tener dos o tres máquinas generando la misma imagen y aprender cómo se
puede controlar un proceso distribuido como ese.
</p>

<p>
Me gustaría también, en un futuro, toquetear el tema de los diferentes
ficheros de entrada. Hacer, por ejemplo, que pudiera interpretar
diferentes datos que provengan de, por ejemplo, <code>povray</code>, <code>renderman</code>,
<code>vray</code>, etc.; además de su propio sistema. Y, por último, también me
gustaría explorar la vía de hacer algún <i>plugin</i> para <a href="https://www.blender.org/">Blender3D</a> o,
aprovechando que chufla también en <code>erlang</code>, para <a href="http://www.wings3d.com/">Wings3d</a>... pero para
estas cosas, primero hay que terminar lo básico.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Espero porque no lo he mirado, pero lo habitual en todos los
<i>raytracers</i> que conozco es así. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Una <i>librería</i> que proporciona aplicaciones estables y
escalables de una manera sencilla.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ya los enlacé en los otros artículos, pero lo vuelvo a hacer
aquí <a href="https://raytracing.github.io/">https://raytracing.github.io/</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En ambos sentidos con una sola palabra, <i>paralelo</i>, o con dos:
<i>para lelo</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Y también para no olvidarme de algunas cosas que me han hecho
darme muchos cabezazos contra el muro de la incomprensión de una mente
más inclinada a los procesos lineales. 
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>call</i> son llamadas que esperan que se devuelva un valor,
<i>cast</i> es una llamada asíncrona e <i>info</i> son eventos que llegan al
proceso, como una conexión <code>TCP</code> o el evento de un <i>timer</i>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.7" class="footnum" href="#fnr.7" role="doc-backlink">7</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Digo <i>al menos dos</i> porque aunque puede haber sólo 1 si el rayo
es tangente al objeto, lo más probable es que sean dos. Además en
figuras más complejas como los <i>toroides</i> o modelos poligonales, la
trayectoria puede encontrar la superficie del objeto más de dos veces.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/raytrace/index.html">raytrace</a> <a href="/tags/erlang/index.html">erlang</a> ]]></description>
  <category><![CDATA[raytrace]]></category>
  <category><![CDATA[erlang]]></category>
  <link>https://notxor.nueva-actitud.org/2020/11/16/rayos-y-centellas.html</link>
  <pubDate>Mon, 16 Nov 2020 21:16:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[org-roam en modo servidor]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-10-29</div>
<p>
Ya hablé en <a href="https://notxor.nueva-actitud.org/2020/07/17/tomar-notas-con-org-roam.html">otro artículo sobre org-roam</a> y hoy os lo traigo de nuevo.
Desde aquél artículo inicial han pasado algunos meses y el continuo
desarrollo que están poniendo en <code>org-roam</code> hace que haya evolucionado
bastante, además de subsanar algunos problemas con los que me tropecé
cuando empecé a utilizarlo hace algunos meses.
</p>

<p>
Como digo, el paquete ha madurado y han aparecido nuevas
funcionalidades. Entre ellas tenemos un <i>modo servidor</i> que hace de
<code>org-roam</code> una herramienta más visual y más moderna, si me permitís
esa expresión. Hace tiempo que no me guío por el aspecto de las
aplicaciones y todo lo he derivado hacia una existencia en <i>texto
plano</i> que me permite trabajar hasta con el más mínimo dispositivo al
que se le pueda enchufar un teclado decente. El aspecto <i>moderno</i> o
<i>gráfico</i> no es una de mis prioridades, sin embargo, ¿qué pasa si
trabajo con texto plano y tiene una <i>interface</i> gráfica agradable?
Eso me está pasando con <code>org-mode</code>, con su modo de trabajo en texto
plano, pero además proveen una asistencia gráfica mediante el paquete
<code>org-roam-server</code>.
</p>


<figure id="orgc52e92c">
<img src="./imagenes/org-roam-server-completo.png" alt="org-roam-server-completo.png">

</figure>

<p>
Las imágenes las he tomado de uno de los directorios de notas que
utilizo para un proyecto que se va haciendo cada vez más complejo. Es
un <i>cajón</i> de notas real. Así me aseguro de que los ejemplos visuales
sean reales y no forzarlos inventando notas vacías. Como se puede
apreciar en la imagen, casi no se pueden seguir las relaciones entre
las distintas anotaciones en ese modo gráfico. Lo bueno es que
<i>pinchando y arrastrando</i> cada nodo dibujado hace que los demás se
muevan y cambien de posición. De esa manera podemos conseguir que el
gráfico sea un poco más claro del que dibuja por defecto la
herramienta. Pero vamos por partes.
</p>
<div id="outline-container-org3f98baa" class="outline-2">
<h2 id="org3f98baa">Configuración</h2>
<div class="outline-text-2" id="text-org3f98baa">
<p>
Estoy partiendo del hecho de que no tienes ya instalado <code>org-roam</code>. Si
llevas un tiempo utilizándolo, seguro que ya encontraste este paquete
adicional antes. También, quizá, debas enterarte un poco cómo va el
asunto de la toma de notas con el método <i>zettelkasten</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. Si
estás convencido de probarlo, primero tienes que instalar el paquete
<code>org-roam</code> y después <code>org-roam-server</code> como es habitual:
</p>

<pre class="example" id="org26f2abb">
M-x package-install RET org-roam-server RET
</pre>

<p>
He hecho algunos cambios en la configuración de <code>org-roam</code> para
ajustar este paquete. Por ejemplo he añadido una combinación de teclas
para lanzar el servidor:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r b"</span>) 'org-roam)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r c"</span>) 'org-roam-capture)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r d"</span>) 'org-roam-doctor)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r f"</span>) 'org-roam-find-file)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r g"</span>) 'org-roam-graph)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r i"</span>) 'org-roam-insert)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r m"</span>) 'org-roam-mode)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r r"</span>) 'org-roam-find-ref)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r s"</span>) 'org-roam-server-mode)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r t"</span>) 'org-roam-buffer-toggle-display)
</pre>
</div>

<p>
En el listado puedes ver todas las combinaciones de teclas que utilizo
para tomar notas, y sólo cabe destacar desde el anterior artículo, la
aparición de <code>C-c r s</code> para lanzar el servidor. Si volvemos a pulsar
esa combinación, veremos un mensaje de <code>org-mode-server disabled</code>.
</p>


<figure id="org9cc3330">
<img src="./imagenes/emacs-org-roam-server.png" alt="emacs-org-roam-server.png">

</figure>

<p>
En la imagen se muestra, ─abajo en la lista de procesos─,
<code>org-roam-server</code> lanzado como un proceso <code>httpd</code>.  Como ya me ha
pasado alguna vez, este proceso puede interferir con el habitual uso
del servidor web local que utilizo para probar la buena visualización
de los artículos del <i>blog</i> antes de publicarlos. Ambos procesos
intentan utilizar el mismo puerto <code>8080</code>. Para solucionarlo, he
añadido una configuración adicional tal que:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-roam-server-port 8000)
</pre>
</div>

<p>
De esta manera, es posible levantar los dos procesos <code>httpd</code> de forma
simultánea, <code>org-roam-server</code> en el puerto <code>8000</code> y el <i>web local</i> en
<code>8080</code>.
</p>

<p>
Como se puede observar, se mantiene nuestra querida interfaz de texto
y podemos consultar las notas por su contenido, tener referencia de
los enlaces que apuntan a ella y de aquellas notas a las que ésta
apunta. Cualquier modificación que hagamos en ellas se refleja
también de manera <i>automágica</i> en el servidor: la información en ambos
modos es la misma, pero se presenta de manera diferente.
</p>
</div>
</div>
<div id="outline-container-org15c2f2e" class="outline-2">
<h2 id="org15c2f2e">Saturados de notas</h2>
<div class="outline-text-2" id="text-org15c2f2e">
<p>
A poco complejo que sea el tema que estés trabajando<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> la
información mostrada de forma gráfica hace que nos perdamos en las
múltiples conexiones, pero podemos filtrarlo de dos maneras.
</p>
</div>
<div id="outline-container-orgb723cc7" class="outline-3">
<h3 id="orgb723cc7">Filtrado por nodos</h3>
<div class="outline-text-3" id="text-orgb723cc7">
<p>
Comenzaré por la botonera de la esquina superior derecha. El modo más
simple es pulsar el botón <code>File Viewer</code>. Veremos que a la izquierda
nos aparece un selector para poder buscar la nota que queramos:
</p>


<figure id="orgc9891ee">
<img src="./imagenes/org-roam-server-file-viewer.png" alt="org-roam-server-file-viewer.png">

</figure>

<p>
Como veis, la información es la misma que obtenemos en modo texto: el
espacio grande reservado para la anotación y a la derecha vemos una
lista de notas que enlazan a esa. Vale, para eso tenemos ya el modo
texto en <i>Emacs</i>. Además no he conseguido aún poder modificar una nota
desde este modo gráfico, ─aunque tenga un botón <code>Edit</code> bien visible─,
pero eso es otro asunto.
</p>

<p>
El siguiente apartado en la <i>botonera</i> superior derecha es <code>Buffer
Network</code> que lo que hace es mostrar los enlaces de un determinado
archivo que podemos seleccionar en la lista desplegable de abajo a la
izquierda:
</p>


<figure id="org3f77b16">
<img src="./imagenes/org-roam-server-visor-nodo.png" alt="org-roam-server-visor-nodo.png">

</figure>

<p>
A poco que seamos observadores veremos un selector numérico. Ese
selector lo que hace es limitar las conexiones entre nuestro <i>nodo</i>
seleccionado y otros. Por ejemplo, si incrementamos el selector para
ver las etiquetas enlazadas de <i>segundo nivel</i> obtendríamos las
siguientes conexiones:
</p>


<figure id="orgac09631">
<img src="./imagenes/org-roam-server-visor-nodo-incremento.png" alt="org-roam-server-visor-nodo-incremento.png">

</figure>

<p>
Como podéis apreciar también, hay dos <i>estilos</i> de visualización:
<code>Dark Mode</code> y <code>Light Mode</code>. Se puede elegir el que más os guste
simplemente pinchando en el enlace que aparece en el centro de la
parte superior de la página.
</p>

<p>
Y también, a poco que observemos, podemos ver que el tamaño de los
círculos cambia de un nodo a otro. Cuantos más enlaces recibe una
nota, más grande es el círculo que la representa. También vemos que
hay distintos colores según las etiquetas que hayamos empleado y esto
nos lleva al siguiente apartado.
</p>
</div>
</div>
<div id="outline-container-org842bbe9" class="outline-3">
<h3 id="org842bbe9">Filtrado por etiquetas</h3>
<div class="outline-text-3" id="text-org842bbe9">
<p>
También vemos en la parte superior derecha el botón <code>Database
Network</code> que es el modo que está activado por defecto cuando
arrancamos el servidor. Este modo nos muestra toda la base de datos,
por defecto, pero también podemos filtrar toda esa información.
</p>


<figure id="orgf55e5f6">
<img src="./imagenes/org-roam-excluir-etiquetas.png" alt="org-roam-excluir-etiquetas.png">

</figure>

<p>
En ese modo vemos el selector de la esquina inferior izquierda, que
mostrará el mensaje <code>Filter</code>, y al lado hay un botón de color rojo que
muestra <code>Exclude</code>. Si pinchamos en el botón veremos que cambiará a
color verde con el mensaje <code>Include</code>. Con él podemos crearnos un
filtro que incluya sólo los nodos con unas determinadas etiquetas,
pero además que excluya otras. Cada etiqueta nos la mostrará en color
rojo o verde, según esté excluida o incluida en la búsqueda.  Así
podemos establecer complejos filtros de información hasta tener en
pantalla sólo unas pocas notas o incluso <i>una o ninguna</i>. A veces es
interesante llegar a un filtro y que arroje una pantalla en blanco
porque te hace pensar: <i>hay un vacío en todo este barullo de notas,
¿Qué esperaba encontrar? Quizá me falta algo</i>. Así he encontrado
alguna laguna en la información, pero supongo que cada cual tendrá su
estilo.
</p>
</div>
</div>
</div>
<div id="outline-container-orgef51898" class="outline-2">
<h2 id="orgef51898">Conclusiones</h2>
<div class="outline-text-2" id="text-orgef51898">
<p>
El paquete <code>org-roam</code> se ha convertido en mi preferido para tomar
notas y además de su potente <i>interface</i> de texto, nos proporciona un
magnífico servidor gráfico para que visualicemos la información de
maneras muy atractivas.
</p>

<p>
El otro día, hablando con un colega de profesión sobre el trabajo que
estamos haciendo en un grupo de trabajo (valga la <i>rebuznancia</i>) sobre
<i>abuso infantil</i> del COPPA<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>, le mostré estas mismas notas. Como
era sólo visualizarlas un poco por encima arranqué el servidor y lo
estuve manejando mientras hablábamos. Su pregunta fue: <i>¿cuánto cuesta
el programa este de notas?</i> Y a ver... es gratis, al final es gratis,
pero necesita un esfuerzo extra para la gente que no está acostumbrada
al <i>texto plano</i>.
</p>

<p>
Una herramienta tan <i>vistosa</i> casi que descuadra nuestro austero mundo
de texto y llama la atención a quien no lo conoce. Puede ser un
acicate para que otras personas se metan en este mundo de
independencia real de nuestros datos y de la información que nosotros
mismos generamos, de conseguir que ninguna corporación se apropie de
ellos y en un cambio de versión nos chantajee<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup> para que nos
dejemos los dineros en programas más nuevos que no necesitamos.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Puedes leer el artículo que enlazo en el primer párrafo de este
artículo o buscar información por Internet. También puedes leer el
artículo <a href="https://medium.com/voces-en-espa%C3%B1ol/zettelkasten-c%C3%B3mo-un-erudito-alem%C3%A1n-fue-tan-incre%C3%ADblemente-productivo-b16643e170cc">https://medium.com/voces-en-espa%C3%B1ol/zettelkasten-c%C3%B3mo-un-erudito-alem%C3%A1n-fue-tan-incre%C3%ADblemente-productivo-b16643e170cc</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En las imágenes podéis ver que estoy utilizando las notas que
necesito para un proyecto sobre <i>abuso infantil</i>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Colegio Oficial de Profesionales de la Psicología de Aragón. 
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
No deja de ser una forma admitida legalmente de un <i>ataque ramsonware</i>. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> <a href="/tags/org-roam/index.html">org-roam</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <category><![CDATA[org-roam]]></category>
  <link>https://notxor.nueva-actitud.org/2020/10/29/org-roam-en-modo-servidor.html</link>
  <pubDate>Thu, 29 Oct 2020 07:54:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Penso kaj lingvo]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-10-27</div>
<p>
Mi memoris kiam mi studis <i>Penso kaj Lingvo</i> dum mia universitata
tempo, temas pri <i>kogna psikologio</i>. Por mi ĝi estis, ─ankaŭ estas─,
tre interesa afero. Kiel la homoj pensas estas la sintezo de la homa
agado. La dubo ĉiam estas: ĉu oni pensas kiel agas aŭ ĉu oni agas kiel
pensas; ĉu ni pensas kiel ni parolas aŭ ĉu ni parolas kiel ni
pensas. Mi ŝatas multe legi pri tio sed, finfine, neniu klarigas al mi
tiujn aferojn. Multaj legaĵoj kontraŭdiras la aliajn. Kelkaj estas
proksimaj al mia penso, aliaj ne, sed mi ne volas lasu min eliri de
objektiveco. Mia cela demando estas <i>kiel ni funkcias?</i> Tiu demando
estas profesie, kiel psikologo, tre grava por mi. Mi avertas ke, eble,
mi povos kontraŭdiri kelkajn dogmojn, precipe religiaj, dum tiuj
pensoj. Tiuj aferoj, multefoje, alproksimiĝas al <i>spirito</i> kaj, ankaŭ
multefoje, la scienco ne havas klaran difinon aŭ respondon. Do, se vi
estas tro religia homo aŭ tro spirita, vi ne devus daŭri la
legadon. Mi parolos pri psiko, animo, pensoj kaj sentoj, eble ne tiel
kiel vi esperas aŭ kredas.
</p>
<div id="outline-container-orgb38e64c" class="outline-2">
<h2 id="orgb38e64c">Pensu malrapide, rapide agu</h2>
<div class="outline-text-2" id="text-orgb38e64c">
<p>
Dum mia universitata lernado mi multe trovis la metaforon de la
maŝino, kiu montras similon inter komputado kaj penso: ni ambaŭ havas
eniron de datumoj, poste ni procesas tiujn informojn, fine ni
respondas. Estas tre simpla metaforo, klara sed ne ĉiam certa aŭ
vera, ĉar ni ne nur pensas: ankaŭ sentas kaj tiu malsimileco estas
grava por mi. La samaj <i>datumoj</i> povas okazi malsimilajn respondojn,
ne nur en diversaj homoj, ankaŭ en la sama homo: ni estas maŝinoj.
</p>

<p>
Alia teorio diras ke nia penso estas <i>dua sekvo</i> de la evoluo de nia
nerva sistemo. Eĉ niaj pensoj kaj sentoj pri nia animo, eĉ niaj
religiaj bezonoj povas esti devitaj al tiu komplikeco de nia cerbo,
kiun alportis la evoluo. Eble, tiu teorio pravas, eble ne. Ĝi estas
simpla kaj eksplikas kaj klarigas de la plej simpla maniero kiel
evoluis nian pensoj kaj sentoj. Ni povas pensi, ─aŭ senti─, ke la
pensoj kaj sentoj evoluis aparte, sed mi ne pensas tion. La sentoj
evoluis kune kun inteligento kaj penso. Ni nur devas observi niajn
hejmbestojn por kompreni tion, ke ili ankaŭ havas sentojn; ili sentas
kaj agas simile al ni. La sentoj movas nin al agado; la sentoj motivas
al ni por fari pli ol la pensoj. Kelkaj sentoj faras tion rapide,
ekzemple la timo, preparas nian korpon por agi: ĉu forkuri, ĉu batali;
ĝi rapidigis nian koran batadon, alportanta sangon al niaj muskoloj;
ĝi fiksas nian atenton al timiga stimulo. Sed tiuj simptomoj estas tre
similaj en multaj sentoj. Ekzemple, la tuja enamigo havas similajn
simptomojn; sed nia penso eksplikas ilin malsame. Do, ĉu ni povas
apartigi unu el alia?
</p>

<p>
La penso ankaŭ rilatas kun inteligento. Multaj fojoj ni povas pensi
tion, ke ili estas la sama afero, sed mi ne multe konsentas. Kelkaj
fojoj, niaj pensoj estas uzita por trovi solvon al tiu problemo kiu ni
bezonas solvi. Pro tio mi memoras kiam mi estis psikologia instruisto
en mezlernejo. Mi demandis al miaj lernantoj se, eble, ili povas solvi
kvadratan ekvacion en eŭklida spaco kaj kiom da tempon ili bezonas por
tion. Kiam mi demandis se tiu afero estas por homoj inteligentaj ili
ĉiam jesis kaj ili aldonas <i>por tre inteligentaj kaj instruitaj homoj
sendube</i>. Poste mi ĵetis kelkan etan aĵon al unu el ili por ke li (aŭ
ŝi) trafis ĝin: estis averta movon kaj ne rapida; la aĵo faris belan
parabolon en la aero kaj kutime ili prenis ĝin. <i>Do</i>, mi diris, <i>vi
solvis kvadratan ekvacion en eŭklida spaco en tri sekundoj</i>, kelkaj
fojoj mi aldonis: «mia hundo ankaŭ prenas la ludilojn ke mi ĵetis
lin». <i>Do, ĉu estas inteligenta la inteligento?</i>, mi insistis al
ili. Vere, mi nur volis devigi la pensadon. <i>Mia hundo ankaŭ solvas</i>
kvaratan ekvacion <i>en eŭklida spaco kaj tre bone: li ĉiam trafas la
pilkon</i>.
</p>

<p>
La lastaj demandoj post tio estas: <i>Kio estas la inteligento?</i> kaj
ankaŭ <i>Kio estas la penso</i> kaj <i>kiaj aferoj estas inteligentaj aŭ ne?</i>
Por tiuj demandoj mi havas pli dubojn ol respondojn.
</p>

<p>
Mi pensas, plej bone: mi kredas, ke nia inteligento evoluis por
kontraŭdiri niajn sentojn. La sentoj havas, ─petas, se vi volas
esprimi tiel─, rapidan reagon. Oni sentas kaj tuj reagas sen pensi
plu. Ni timas kaj tuj ekkuras aŭ ekbatalas. La naturo selektis tiujn
respondojn per evoluo. Io atakis idon kaj ĝia patrino batalas
defende, sen pensi. La penso venis por moderigi tiujn reagojn: ne ĉiam
niaj instinktoj instigas al ni la plej bonajn agadojn.
</p>
</div>
</div>
<div id="outline-container-org391d392" class="outline-2">
<h2 id="org391d392">Penso kaj lingvo</h2>
<div class="outline-text-2" id="text-org391d392">
<p>
Estas teorio kiu diras ke nia lingvo modifas nian penson kaj percepton
de la mondo. Ekzemple, oni diras ke la inuita popolo havas centon da
vortoj kiuj signifas <i>blanka</i>, aŭ pro la bluaj lumoj en la semaforoj
de Japanio, ĉar la vorto por <i>verda</i> estas tro nova. Aŭ ankaŭ, la
<i>vinkolora maro</i> kiu aperas en <i>La Odiseado</i>, ĉar oni diras ke ne
estis vorto por <i>blua</i> kiam ĝi estis skribita.
</p>

<p>
Postaj studoj montras ke tiu influo estas malpli forta ol antaŭe
pensis. Sed nune, multaj el ni konsentas tiun teorion kaj pensas ke ĝi
estas vera aŭ tute vera.
</p>

<p>
Kiel mi diris, <i>penso</i> kaj <i>lingvo</i> estas interrilataj sed ne tiel
forte kiel ni pensis antaŭe. Ankaŭ estas la homoj kies penso estas
gvidita per imagaj bildoj, memoru la faman frazon de <i>Albert
Einstein</i>: «Se mi ne povas desegni ĝin, mi ne komprenas ĝin». Ankaŭ la
fama proverbo diras «pli valoras bildo ol mil vortoj»<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>

<p>
La penso influas en niaj vortoj; ankaŭ la vortoj limigas kelkajn
esprimojn malhelpante ilin, sed ne malpermesante. La manko de vortoj
ne blindigas la penson. Fine, sed per multaj pli vortoj oni povas
esprimi tiun, kiun oni volas diri. Ekzemple en la hispana estas
malsama <i>ser</i> (esti) kaj <i>estar</i> (esti), ne okazas tiel en aliaj
lingvoj. Ekzemple, kiam mi studis psikologion, al mi parolis pri la
<i>Teorio de la Trajtoj</i> de <i>Gordon Allport</i>. Multaj vortoj li devis uzi
por ekspliki kion estas <i>trajto</i> kaj kion estas <i>stato</i>. Por hispana
infano, de kiam li komencis paroli, komprenas kaj pensas aŭtomate, por
bone esprimi, per <i>trajtoj</i> (ser) kaj <i>statoj</i> (estar) kiam li
parolas, do, por ili multaj el tiuj vortoj skribitaj de <i>Allport</i>
estus superfluaj. Sed, finfine, ĉiu homo povas kompreni la koncepton
tra tiuj vortoj kaj tiun teorion de <i>Allport</i>.
</p>
</div>
</div>
<div id="outline-container-org58fc223" class="outline-2">
<h2 id="org58fc223">Konkludoj</h2>
<div class="outline-text-2" id="text-org58fc223">
<p>
Al mi tre ŝatas tiujn aferojn pri la <i>kogna psikologio</i>. Mi ne volas
skribi longajn artikolojn por ne lacigi la legantaron. Per venonta
artikolo mi volas priparoli pri inteligento: <i>homa inteligento</i> kaj
<i>artefarita inteligento</i>. Sed tio estos en alia artikolo.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Al mia lernantoj mi ĉiam aldonis al tiu frazon: <i>pli valoras
ago ol mil bildoj</i>.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/pensamiento/index.html">pensamiento</a> <a href="/tags/lenguaje/index.html">lenguaje</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[pensamiento]]></category>
  <category><![CDATA[lenguaje]]></category>
  <link>https://notxor.nueva-actitud.org/2020/10/27/penso-kaj-lingvo.html</link>
  <pubDate>Tue, 27 Oct 2020 09:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[La cámara de los rayos sin truenos]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-10-24</div>
<p>
Pues sigo con los apuntes de <i>raytracing</i>, ya me perdonaréis el
<i>cansinamiento</i> pero el libro éste y el picar código porque sí y no
por trabajo o necesidad, me está resultando gratificante. Quizá a
alguien que pueda leer ésto y no esté familiarizado con estas cosas
puede resultarle un poco árido: <i>¡Uff! A estas alturas hablando de matemáticas y programación con <code>erlang</code>. ¡Qué ganas de marear la perdiz!</i> Pues sí, quizá ese pensamiento sea correcto y hasta cierto,
según el punto de vista que se adopte, claro. En mi caso, ya lo
sabréis si leísteis el artículo anterior, es una forma de procrastinar
aprendiendo algo inútil para mi vida profesional, pero que llena de
orgullo y satisfacción mi yo más friki.
</p>

<p>
<a href="https://notxor.nueva-actitud.org/2020/10/21/un-pequeno-raytracer.html">Después del artículo del otro día</a> algunos lectores me han pedido el
código que voy haciendo. Por ello he decidido compartir el código que
vaya escribiendo en <a href="https://codeberg.org/Notxor/rerl">repositorio público en <i>codeberg.org</i></a>. Además,
otro par de lectores me han dicho que están más interesados en el
concepto, en la explicación teórica que subyace en estas herramientas,
más que en el código. Así pues, he decidido incluir también un poco de
matemáticas y otras explicaciones.  No demasiadas, sólo las
suficientes para que las cosas queden más o menos claras. Ya conocéis
mi natural tendencia a <i>pichorros</i> y <i>chismáticos</i> y quizá mi
explicación no sea tan rigurosa como a algunos les gustaría, pero esta
vez intentaré ser algo más preciso si es posible.
</p>

<p>
Lo primero es explicar un poco qué es un <i>raytracer</i> y por qué
consigue imágenes tan realistas. Y lo hace tan bien porque intenta
emular cómo funciona la luz en la vida real. Lo imita, pero dándole la
vuelta, es decir, en lugar de seguir la luz desde la fuente de luz
hasta rebotar en los objetos que correspondan y llegar hasta el ojo,
lo que hace es <i>trazar</i> ese camino desde el ojo hasta los objetos y
luego a las fuentes de luz. ¿Por qué lo hace al revés? Pues
básicamente porque no se puede lanzar los millones de millones de
fotones que lanza una fuente de luz para que sólo unos pocos cientos
de ellos lleguen a estimular el ojo durante ese mismo lapso de
tiempo. Por eso es más efectivo y rentable trabajar sólo <i>con los
fotones que llegan</i> en lugar de con los que salen de las fuentes de
luz.
</p>
<div id="outline-container-org307c015" class="outline-2">
<h2 id="org307c015">La cámara de los rayos sin truenos</h2>
<div class="outline-text-2" id="text-org307c015">
<p>
El concepto de <i>rayo</i> es muy simple: es una recta con <i>dirección</i>. Con
un dibujo quedará más claro:
</p>


<figure id="org8c0d7fa">
<img src="./imagen/rayo-concepto.png" alt="rayo-concepto.png">

</figure>

<p>
Una recta en el espacio <code>3D</code> se puede definir como aquella línea que
pasa por dos puntos. Un <i>rayo</i> se apoya en esa recta, tomando como
<i>origen</i> uno de esos puntos. Por tanto, un <i>rayo</i> es una semi-recta:
puesto que una línea es infinita sin principio ni fin, el rayo sería
su mitad, tiene principio en <code>origen</code> y continúa en la recta apoyado
pasando por el otro punto que llamamos <i>dirección</i> (en el código
<code>dir</code>). La fórmula matemática es \(\mathrm{P}(t)=\mathrm{A}+t\mathrm{b}\)
y como se puede ver en el dibujo, \(t\) permite desplazar el punto a lo
largo de toda la recta. Dicha fórmula se vuelca en el código en la
función <code>rayo:hacia/2</code>:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">hacia</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>,<span style="color: #f8f8f2; font-weight: bold;">T</span>) -&gt;
  <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.origen, <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir,<span style="color: #f8f8f2; font-weight: bold;">T</span>)).
</pre>
</div>

<p>
Bueno, vale, ya tenemos rayos que podemos trazar, con su origen, su
dirección y su correspondiente fórmula para <i>trazarse</i>. Es el momento
de recordar cómo funciona un <i>raytracer</i>. El proceso es muy sencillo:
</p>

<ol class="org-ol">
<li>Calcular el rayo que va desde la cámara al pixel.</li>
<li>Determinar los objetos con los que tiene intersección.</li>
<li>Según esas intersecciones, calcular el color del pixel.</li>
<li>Repetir para todos los pixels de la imagen.</li>
</ol>

<p>
La cámara es otra abstracción. En el libro la coloca en el punto
<code>(0,0,0)</code>. A partir de ese punto origen se trazarán los rayos hacia
los distintos pixels situados en el <i>viewport</i>, cuyo centro será el
<code>(0,0,-1)</code>. Como se puede ver en la imagen, el eje \(x\) estará
orientado horizontalmente, el eje \(y\) verticalmente y el \(z\) nos dará
la profundidad.  Veamos el gráfico:
</p>


<figure id="org78fc169">
<img src="./imagen/concepto-camara.png" alt="concepto-camara.png">

</figure>

<p>
Si suponemos que el origen de coordenadas está situado en nuestra
pantalla del ordenador, el eje \(y\) crece hacia arriba, el \(x\) hacia la
derecha y el \(z\) hacia nosotros y decrece alejándose.  El objetivo del
libro es conseguir la siguiente imagen de fondo trazando rayos:
</p>


<figure id="org4621f9b">
<img src="./imagen/fondo-trazado.png" alt="fondo-trazado.png">

</figure>

<p>
Repasamos el código
</p>
</div>
</div>
<div id="outline-container-org25ccc99" class="outline-2">
<h2 id="org25ccc99">Modificaciones al código del libro</h2>
<div class="outline-text-2" id="text-org25ccc99">
<p>
Adaptando el código a <code>erlang</code> he modificado algunas cosas para
conseguir el mismo resultado.
</p>
</div>
<div id="outline-container-orgc796272" class="outline-3">
<h3 id="orgc796272">Rayo</h3>
<div class="outline-text-3" id="text-orgc796272">
<p>
En <code>registros.erl</code> se añade un <code>record</code> para los rayos y también el
correspondiente módulo.
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-record</span>(<span style="color: #8be9fd; font-style: italic;">rayo</span>, {origen, dir}).
</pre>
</div>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-module</span>(rayo).

<span style="color: #ffb86c;">-include</span>(<span style="color: #f1fa8c;">"registros.hrl"</span>).

<span style="color: #ffb86c;">-export</span>([<span style="color: #8be9fd; font-style: italic;">nuevo/2</span>]).

<span style="color: #50fa7b; font-weight: bold;">nuevo</span>(<span style="color: #f8f8f2; font-weight: bold;">Origen</span>,<span style="color: #f8f8f2; font-weight: bold;">Direccion</span>) -&gt;
    #<span style="color: #8be9fd; font-style: italic;">rayo</span>{origen=<span style="color: #f8f8f2; font-weight: bold;">Origen</span>, dir=<span style="color: #f8f8f2; font-weight: bold;">Direccion</span>}.

<span style="color: #50fa7b; font-weight: bold;">hacia</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>, <span style="color: #f8f8f2; font-weight: bold;">T</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.origen, <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir, <span style="color: #f8f8f2; font-weight: bold;">T</span>)).
</pre>
</div>

<p>
De momento no hace falta comentar mucho más, veamos el código que
genera la imagen.
</p>
</div>
</div>
<div id="outline-container-org1d03928" class="outline-3">
<h3 id="org1d03928">Imagen</h3>
<div class="outline-text-3" id="text-org1d03928">
<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">color_rayo</span>(<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">DU</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">unidad</span>(<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir),
    <span style="color: #f8f8f2; font-weight: bold;">T</span> = 0.5 * (<span style="color: #f8f8f2; font-weight: bold;">DU</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.y + 1),
    <span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">nuevo</span>(1.0,1.0,1.0), 1-<span style="color: #f8f8f2; font-weight: bold;">T</span>),
               <span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">nuevo</span>(0.5,0.7,1.0), <span style="color: #f8f8f2; font-weight: bold;">T</span>)).
</pre>
</div>

<p>
Como antes dije, hay que calcular el color que tiene el rayo lanzado.
Esto lo hace la función anterior. Realmente lo que hace es mezclar
blanco y azul dependiendo de la altura. La fórmula que se emplea para
hacer la mezcla es la siguiente:
</p>

<p>
\[Color_{mezcla} = (1-t) \cdot Color_{inicial} + t \cdot Color_{final}\]
</p>

<p>
Los valores inicial y final son el blanco <code>rgb(1,1,1)</code> y el azul
<code>rgb(0.5,0.7,1.0)</code>. El valor lo determina el componente \(y\). Se
obtiene la dirección del rayo se distribuye el valor <code>T</code> uniformemente
de abajo a arriba. Cuando <code>T</code> tiene a <code>1</code> el color blanco tiende a
desaparecer y cuando tiende a cero, es el azul el que lo hace.
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">dibujar</span>(<span style="color: #f8f8f2; font-weight: bold;">Fichero</span>) -&gt;
    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Imagen
</span>    <span style="color: #f8f8f2; font-weight: bold;">Ratio</span> = 16 / 9,
    <span style="color: #f8f8f2; font-weight: bold;">Ancho</span> = 400,
    <span style="color: #f8f8f2; font-weight: bold;">Alto</span> = <span style="color: #8be9fd; font-style: italic;">round</span>(<span style="color: #f8f8f2; font-weight: bold;">Ancho</span> / <span style="color: #f8f8f2; font-weight: bold;">Ratio</span>),

    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">C&#225;mara
</span>    <span style="color: #f8f8f2; font-weight: bold;">Alto_Vista</span> = 2,
    <span style="color: #f8f8f2; font-weight: bold;">Ancho_Vista</span> = <span style="color: #f8f8f2; font-weight: bold;">Ratio</span> * <span style="color: #f8f8f2; font-weight: bold;">Alto_Vista</span>,
    <span style="color: #f8f8f2; font-weight: bold;">Foco</span> = 1,

    <span style="color: #f8f8f2; font-weight: bold;">Origen</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">nuevo</span>(0,0,0),
    <span style="color: #f8f8f2; font-weight: bold;">Horizontal</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">nuevo</span>(<span style="color: #f8f8f2; font-weight: bold;">Ancho_Vista</span>, 0, 0),
    <span style="color: #f8f8f2; font-weight: bold;">Vertical</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">nuevo</span>(0, <span style="color: #f8f8f2; font-weight: bold;">Alto_Vista</span>, 0),
    <span style="color: #f8f8f2; font-weight: bold;">Esquina_Inferior_Izquierda</span> =
        <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(
          <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(
            <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(<span style="color: #f8f8f2; font-weight: bold;">Origen</span>, <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">divi</span>(<span style="color: #f8f8f2; font-weight: bold;">Horizontal</span>,2)),
            <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">divi</span>(<span style="color: #f8f8f2; font-weight: bold;">Vertical</span>,2)),
          <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">nuevo</span>(0,0,<span style="color: #f8f8f2; font-weight: bold;">Foco</span>)),

    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Render
</span>    <span style="color: #f8f8f2; font-weight: bold;">Cabecera</span> = <span style="color: #8be9fd; font-style: italic;">io_lib</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"P3~n~p ~p~n255~n"</span>, [<span style="color: #f8f8f2; font-weight: bold;">Ancho</span>,<span style="color: #f8f8f2; font-weight: bold;">Alto</span>]),
    {ok,<span style="color: #f8f8f2; font-weight: bold;">F</span>} = <span style="color: #8be9fd; font-style: italic;">file</span>:<span style="color: #8be9fd; font-style: italic;">open</span>(<span style="color: #f8f8f2; font-weight: bold;">Fichero</span>, [write]),
    <span style="color: #f8f8f2; font-weight: bold;">Imagen</span> =
        <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(
          <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">J</span>) -&gt;
                  <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Faltan ~p filas  \e[36D"</span>, [<span style="color: #f8f8f2; font-weight: bold;">J</span>]),
                  <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(
                    <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">I</span>) -&gt;
                            <span style="color: #f8f8f2; font-weight: bold;">U</span> = <span style="color: #f8f8f2; font-weight: bold;">I</span> / (<span style="color: #f8f8f2; font-weight: bold;">Ancho</span> - 1 ),
                            <span style="color: #f8f8f2; font-weight: bold;">V</span> = <span style="color: #f8f8f2; font-weight: bold;">J</span> / (<span style="color: #f8f8f2; font-weight: bold;">Alto</span> - 1),
                            <span style="color: #f8f8f2; font-weight: bold;">Punto</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(
                                      <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(
                                        <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(
                                          <span style="color: #f8f8f2; font-weight: bold;">Esquina_Inferior_Izquierda</span>,
                                          <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">Horizontal</span>,<span style="color: #f8f8f2; font-weight: bold;">U</span>)),
                                        <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">Vertical</span>, <span style="color: #f8f8f2; font-weight: bold;">V</span>)),
                                      <span style="color: #f8f8f2; font-weight: bold;">Origen</span>),
                            <span style="color: #f8f8f2; font-weight: bold;">R</span> = <span style="color: #8be9fd; font-style: italic;">rayo</span>:<span style="color: #8be9fd; font-style: italic;">nuevo</span>(<span style="color: #f8f8f2; font-weight: bold;">Origen</span>, <span style="color: #f8f8f2; font-weight: bold;">Punto</span>),
                            <span style="color: #f8f8f2; font-weight: bold;">Color</span> = <span style="color: #8be9fd; font-style: italic;">color_rayo</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>),
                            <span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">escribe</span>(<span style="color: #f8f8f2; font-weight: bold;">Color</span>)
                    <span style="color: #ff79c6; font-weight: bold;">end</span>,
                    <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(0,<span style="color: #f8f8f2; font-weight: bold;">Ancho</span>))
          <span style="color: #ff79c6; font-weight: bold;">end</span>,
          <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(<span style="color: #f8f8f2; font-weight: bold;">Alto</span>,0,-1)),
    <span style="color: #8be9fd; font-style: italic;">file</span>:<span style="color: #8be9fd; font-style: italic;">write</span>(<span style="color: #f8f8f2; font-weight: bold;">F</span>, <span style="color: #f8f8f2; font-weight: bold;">Cabecera</span> ++ <span style="color: #f8f8f2; font-weight: bold;">Imagen</span>),
    <span style="color: #8be9fd; font-style: italic;">file</span>:<span style="color: #8be9fd; font-style: italic;">close</span>(<span style="color: #f8f8f2; font-weight: bold;">F</span>),
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"\nFin.\n"</span>).
</pre>
</div>

<p>
Si vemos el código, lo único que necesita un poco de explicación es la
creación del rayo. Como vemos el rayo se crea con origen en el
<code>Origen</code> de la cámara hasta el <code>Punto</code>.
</p>

<p>
\[Punto = EsquinaInferiorIzquierda + U \cdot Horizontal + V \cdot Vertical - Origen\]
</p>

<p>
Los valores <code>U</code> y <code>V</code> están representados en el esquema gráfico de la cámara.
</p>
</div>
</div>
</div>
<div id="outline-container-org53d6abc" class="outline-2">
<h2 id="org53d6abc">Dibujando la primera esfera</h2>
<div class="outline-text-2" id="text-org53d6abc">
<p>
Hasta aquí todo muy bonito, pero hemos venido a dibujar cosas y lo más
socorrido es un esfera. Calcular una esfera es sencillo: necesitas
sólo las coordenadas del centro y un radio. Es decir, siendo un poco
más preciso cumple con la siguiente fórmula: \(x^2 + y^2 + z^2 = R^2\).
</p>
</div>
<div id="outline-container-org5ab152c" class="outline-3">
<h3 id="org5ab152c">Cómo es una esfera (aparte de redonda)</h3>
<div class="outline-text-3" id="text-org5ab152c">
<p>
Otra historia es saber si un punto dado está dentro o fuera de
la esfera. Pero es sencillo, si dadas sus coordenadas \((x,y.z)\) cuando
\(x^2 + y^2 + z^2 > R^2\) y estará dentro si \(x^2 + y^2 + z^2 < R^2\)
</p>

<p>
Para complicarlo un poco más, necesitamos esa ecuación en formato
<i>vectorial</i>. Para ello si el centro de la esfera es \((C_x,C_y,C_z)\) la
cosa quedaría así, para cualquier punto en la superficie de la esfera:
\[(x-C_x)^2 + (y-C_y)^2 + (z-C_z)^2 = r^2\]
</p>

<p>
Puesto que podemos escribir el centro como \(\mathrm{C}=(C_x,C_y,C_z)\)
y siendo el punto \(\mathrm{P}=(x,y,z)\), podemos escribir que el radio
\(r\) es \((\mathrm{P}-\mathrm{C})\). Es decir:
</p>

<p>
\[(\mathrm{P}-\mathrm{C}) \cdot (\mathrm{P}-\mathrm{C}) = r^2\]
</p>

<p>
Hasta ahora tenemos la forma de saber qué punto satisface la esfera
nos falta saber si un punto satisface también el <i>rayo</i>. Si
recordamos, podemos escribir el rayo como
\[\mathrm{P}(t) 0 \mathrm{A} + t\mathrm{b}\]. Por lo que un punto que
satisfaga la esfera y el rayo a la vez se puede escribir como:
</p>

<p>
\[(\mathrm{P}(t)-\mathrm{C}) \cdot (\mathrm{P}(t)-\mathrm{C}) = r^2\]
</p>

<p>
Por lo tanto,
</p>

<p>
\[(\mathrm{A}+t\mathrm{b}-\mathrm{C}) \cdot (\mathrm{A}+t\mathrm{b}-\mathrm{C}) = r^2\]
</p>

<p>
y despejando todo, encontramos una ecuación de segundo grado:
</p>

<p>
\[t^2 \mathrm{b} \cdot \mathrm{b} + 2 t \mathrm{b} \cdot (\mathrm{A} - \mathrm{C}) + (\mathrm{A} - \mathrm{C}) \cdot (\mathrm{A} - \mathrm{C}) - r^2 = 0\]
</p>

<p>
Básicamente, por tanto, hay que resolver una ecuación de segundo grado
</p>

<p>
\[t = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}\]
</p>

<p>
Los posibles resultados son:
</p>

<ul class="org-ul">
<li>No existe ninguna solución válida para la ecuación. En este caso el
rayo no incide en la esfera.</li>
<li>Existe una solución única. En este caso el rayo es tangente a la
esfera y sólo cumple la ecuación en un punto.</li>
<li>Existen dos soluciones. En este caso el rayo atraviesa la esfera y
hay un <i>impacto de entrada</i> con <i>orificio de salida</i>.</li>
</ul>
</div>
</div>
<div id="outline-container-org0106d43" class="outline-3">
<h3 id="org0106d43">El código</h3>
<div class="outline-text-3" id="text-org0106d43">
<p>
Muy bonitas las matemáticas, parezco intelectual poniendo un par de
fórmulas. Ahora hay que traducirlo a código. La imagen que
buscamos es:
</p>


<figure id="orgf17eb1d">
<img src="./imagen/imagen-esfera.png" alt="imagen-esfera.png">

</figure>

<p>
Como el código de dibujar se repite<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> y en todo caso lo podéis
descargar del repositorio. Pondré el código de la función implica la
resolución de la esfera que lo llamará la función <code>color_rayo/1</code>:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">en_esfera</span>(<span style="color: #f8f8f2; font-weight: bold;">Centro</span>, <span style="color: #f8f8f2; font-weight: bold;">Radio</span>, <span style="color: #f8f8f2; font-weight: bold;">Rayo</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">OC</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.origen, <span style="color: #f8f8f2; font-weight: bold;">Centro</span>),
    <span style="color: #f8f8f2; font-weight: bold;">A</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">punto</span>(<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir, <span style="color: #f8f8f2; font-weight: bold;">Rayo</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir),
    <span style="color: #f8f8f2; font-weight: bold;">B</span> = 2.0 * <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">punto</span>(<span style="color: #f8f8f2; font-weight: bold;">OC</span>, <span style="color: #f8f8f2; font-weight: bold;">Rayo</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir),
    <span style="color: #f8f8f2; font-weight: bold;">C</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">punto</span>(<span style="color: #f8f8f2; font-weight: bold;">OC</span>,<span style="color: #f8f8f2; font-weight: bold;">OC</span>) - <span style="color: #f8f8f2; font-weight: bold;">Radio</span>*<span style="color: #f8f8f2; font-weight: bold;">Radio</span>,
    <span style="color: #f8f8f2; font-weight: bold;">Discriminante</span> = <span style="color: #f8f8f2; font-weight: bold;">B</span>*<span style="color: #f8f8f2; font-weight: bold;">B</span> - 4*<span style="color: #f8f8f2; font-weight: bold;">A</span>*<span style="color: #f8f8f2; font-weight: bold;">C</span>,
    <span style="color: #f8f8f2; font-weight: bold;">Discriminante</span> &gt; 0.

<span style="color: #50fa7b; font-weight: bold;">color_rayo</span>(<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Dis</span> = <span style="color: #8be9fd; font-style: italic;">en_esfera</span>(<span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">nuevo</span>(0,0,-1), 0.5, <span style="color: #f8f8f2; font-weight: bold;">Rayo</span>),
    <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">Dis</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
        true -&gt;
            <span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">nuevo</span>(1,0,0);
        false -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">DU</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">unidad</span>(<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir),
            <span style="color: #f8f8f2; font-weight: bold;">T</span> = 0.5 * (<span style="color: #f8f8f2; font-weight: bold;">DU</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.y + 1),
            <span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">nuevo</span>(1.0,1.0,1.0), 1-<span style="color: #f8f8f2; font-weight: bold;">T</span>),
                       <span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">nuevo</span>(0.5,0.7,1.0), <span style="color: #f8f8f2; font-weight: bold;">T</span>))
    <span style="color: #ff79c6; font-weight: bold;">end</span>.
</pre>
</div>

<p>
Como se puede apreciar, la función <code>en_esfera/3</code> resuelve la ecuación
de segundo grado y determina si tiene una o más soluciones. La función
<code>color_rayo/1</code> se ha modificado para devuelva el color rojo de la esfera
con <code>color:nuevo(1,0,0)</code> o en caso contrario devuelva el color de
fondo que corresponda.
</p>
</div>
</div>
</div>
<div id="outline-container-org9bd756a" class="outline-2">
<h2 id="org9bd756a">Dibujando <i>normales</i></h2>
<div class="outline-text-2" id="text-org9bd756a">
</div>
<div id="outline-container-org39a839e" class="outline-3">
<h3 id="org39a839e">Lo que es un vector <i>normal</i></h3>
<div class="outline-text-3" id="text-org39a839e">
<p>
El <i>vector normal</i> es un vector de módulo uno orientado de forma
perpendicular a una superficie. Dicho con otras palabras es un vector
que va «hacia afuera» de la superficie. Por ejemplo, en la esfera
quedaría más o menos así:
</p>


<figure id="orgfad17b4">
<img src="./imagen/normal-esfera.png" alt="normal-esfera.png">

</figure>

<p>
O dicho de otro modo si la esfera fuera la Tierra y te pones en pie,
tus pies estarán en el punto de la superficie terrestre y tu cabeza
sería «la flechita» de la punta.
</p>

<p>
¿Por qué son importantes? Pues porque nos indican hacia dónde están
orientadas las superficies.
</p>
</div>
</div>
<div id="outline-container-org165ef52" class="outline-3">
<h3 id="org165ef52">Las <i>normales</i> afectan al color</h3>
<div class="outline-text-3" id="text-org165ef52">
<p>
Como acabo de decir, las normales indican hacia dónde está orientada
la superficie, de manera que percibimos la forma del objeto porque
unas zonas reciben más luz que otras según estén más orientada hacia
la luz o no. Por eso, nuestro dibujo ha resultado plano, porque cuando
el rayo incidía en la esfera el color era siempre el mismo \((1,0,0)\).
</p>

<p>
Si cambiamos un poco el código y convertimos el color según la
<i>normal</i> al punto, con un poco de código adicional, modificando el
cálculo de la intersección del rayo con la esfera y color que se
devuelve, tal que:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">en_esfera</span>(<span style="color: #f8f8f2; font-weight: bold;">Centro</span>, <span style="color: #f8f8f2; font-weight: bold;">Radio</span>, <span style="color: #f8f8f2; font-weight: bold;">Rayo</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">OC</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.origen, <span style="color: #f8f8f2; font-weight: bold;">Centro</span>),
    <span style="color: #f8f8f2; font-weight: bold;">A</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">punto</span>(<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir, <span style="color: #f8f8f2; font-weight: bold;">Rayo</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir),
    <span style="color: #f8f8f2; font-weight: bold;">B</span> = 2.0 * <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">punto</span>(<span style="color: #f8f8f2; font-weight: bold;">OC</span>, <span style="color: #f8f8f2; font-weight: bold;">Rayo</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir),
    <span style="color: #f8f8f2; font-weight: bold;">C</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">punto</span>(<span style="color: #f8f8f2; font-weight: bold;">OC</span>,<span style="color: #f8f8f2; font-weight: bold;">OC</span>) - (<span style="color: #f8f8f2; font-weight: bold;">Radio</span>*<span style="color: #f8f8f2; font-weight: bold;">Radio</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Discriminante</span> = (<span style="color: #f8f8f2; font-weight: bold;">B</span>*<span style="color: #f8f8f2; font-weight: bold;">B</span>) - (4*<span style="color: #f8f8f2; font-weight: bold;">A</span>*<span style="color: #f8f8f2; font-weight: bold;">C</span>),
    <span style="color: #ff79c6; font-weight: bold;">if</span>
        <span style="color: #f8f8f2; font-weight: bold;">Discriminante</span> &lt; 0 -&gt;
            -1;
        true -&gt;
            (-<span style="color: #f8f8f2; font-weight: bold;">B</span> - <span style="color: #8be9fd; font-style: italic;">math</span>:<span style="color: #8be9fd; font-style: italic;">sqrt</span>(<span style="color: #f8f8f2; font-weight: bold;">Discriminante</span>)) / (2.0*<span style="color: #f8f8f2; font-weight: bold;">A</span>)
    <span style="color: #ff79c6; font-weight: bold;">end</span>.

<span style="color: #50fa7b; font-weight: bold;">color_rayo</span>(<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">R</span> = <span style="color: #8be9fd; font-style: italic;">en_esfera</span>(<span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">nuevo</span>(0,0,-1), 0.5, <span style="color: #f8f8f2; font-weight: bold;">Rayo</span>),
    <span style="color: #ff79c6; font-weight: bold;">if</span> <span style="color: #f8f8f2; font-weight: bold;">R</span> &gt; 0 -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">N</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">unidad</span>(<span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(<span style="color: #8be9fd; font-style: italic;">rayo</span>:<span style="color: #8be9fd; font-style: italic;">hacia</span>(<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>,<span style="color: #f8f8f2; font-weight: bold;">R</span>),<span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">nuevo</span>(0,0,-1))),
            <span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">nuevo</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.x+1,<span style="color: #f8f8f2; font-weight: bold;">N</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.y+1,<span style="color: #f8f8f2; font-weight: bold;">N</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.z+1),0.5);
       true -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">D</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">unidad</span>(<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir),
            <span style="color: #f8f8f2; font-weight: bold;">T</span> = 0.5 * (<span style="color: #f8f8f2; font-weight: bold;">D</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.y + 1),
            <span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">suma</span>(<span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">nuevo</span>(1.0,1.0,1.0), 1-<span style="color: #f8f8f2; font-weight: bold;">T</span>),
                       <span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">nuevo</span>(0.5,0.7,1.0), <span style="color: #f8f8f2; font-weight: bold;">T</span>))
    <span style="color: #ff79c6; font-weight: bold;">end</span>.
</pre>
</div>

<p>
Veamos la imagen que obtenemos con esos pequeños cambios:
</p>


<figure id="org3923674">
<img src="./imagen/esfera-normales.png" alt="esfera-normales.png">

</figure>

<p>
Si habéis trabajado con Blender3D o con otros programa similares os
sonará el concepto de <i>normals field</i> o <i>campo de normales</i>. Una
imagen, que aplicada después a un objeto, modifica las normales del
mismo haciéndolo más detallado. Es un truco muy habitual para dar
detalle a un objeto con pocos polígonos:
</p>

<ol class="org-ol">
<li>Se crea un objeto muy detallado con incluso millones de caras si se
quiere.</li>
<li>Se genera un campo de normales.</li>
<li>Se simplifica el modelo hasta dejarlo en unos pocos cientos de
caras.</li>
<li>Se aplica el campo de normales como textura consiguiendo con un
modelo <i>lowpoly</i> la apariencia detallada que se busca.</li>
</ol>

<p>
Bien, eso es lo que hemos hecho con ese código: visualizar el campo de
normales de la esfera como si fuera una textura de color.
</p>

<p>
En el libro, a continuación proponen una simplificación de los
cálculos. Ahorran un par de multiplicaciones y divisiones, pero
teniendo en cuenta que para generar una imagen de tamaño regular, los
rayos trazados pueden ser miles, cientos de miles e incluso millones,
lo que están ahorrando pueden ser millones de multiplicaciones y
divisiones. Me iba a ahorrar la explicación matemática, pero debido a
algunas peticiones de lectores, lo pongo también. Si te lo quieres
ahorrar te lo puedes saltar.
</p>

<p>
Lo que hace el autor es simplificar un poco la fórmula de resolución
de ecuaciones de segundo grado sustituyendo el término \(b\) por \(2h\),
es decir,
</p>

<p>
\[\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}\]
</p>

<p>
pasa a ser,
</p>

<p>
\[\frac{-2h \pm \sqrt{(2h)^2 - 4ac}}{2a}\]
</p>

<p>
Sacando el \(4\) de la raíz quedaría
</p>

<p>
\[\frac{-2h \pm 2 \sqrt{h^2 - ac}}{2a}\]
</p>

<p>
y simplificando
</p>

<p>
\[\frac{-h \pm \sqrt{h^2 - ac}}{a}\]
</p>

<p>
Volcando esto al código, queda:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">en_esfera</span>(<span style="color: #f8f8f2; font-weight: bold;">Centro</span>, <span style="color: #f8f8f2; font-weight: bold;">Radio</span>, <span style="color: #f8f8f2; font-weight: bold;">Rayo</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">OC</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">resta</span>(<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.origen, <span style="color: #f8f8f2; font-weight: bold;">Centro</span>),
    <span style="color: #f8f8f2; font-weight: bold;">A</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">punto</span>(<span style="color: #f8f8f2; font-weight: bold;">Rayo</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir, <span style="color: #f8f8f2; font-weight: bold;">Rayo</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir),
    <span style="color: #f8f8f2; font-weight: bold;">Medio_B</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">punto</span>(<span style="color: #f8f8f2; font-weight: bold;">OC</span>, <span style="color: #f8f8f2; font-weight: bold;">Rayo</span>#<span style="color: #8be9fd; font-style: italic;">rayo</span>.dir),
    <span style="color: #f8f8f2; font-weight: bold;">C</span> = <span style="color: #8be9fd; font-style: italic;">vec3</span>:<span style="color: #8be9fd; font-style: italic;">modulo_cuadrado</span>(<span style="color: #f8f8f2; font-weight: bold;">OC</span>) - (<span style="color: #f8f8f2; font-weight: bold;">Radio</span>*<span style="color: #f8f8f2; font-weight: bold;">Radio</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Discriminante</span> = (<span style="color: #f8f8f2; font-weight: bold;">Medio_B</span>*<span style="color: #f8f8f2; font-weight: bold;">Medio_B</span>) - (<span style="color: #f8f8f2; font-weight: bold;">A</span>*<span style="color: #f8f8f2; font-weight: bold;">C</span>),
    <span style="color: #ff79c6; font-weight: bold;">if</span>
        <span style="color: #f8f8f2; font-weight: bold;">Discriminante</span> &lt; 0 -&gt;
            -1;
        true -&gt;
            (-<span style="color: #f8f8f2; font-weight: bold;">Medio_B</span> - <span style="color: #8be9fd; font-style: italic;">math</span>:<span style="color: #8be9fd; font-style: italic;">sqrt</span>(<span style="color: #f8f8f2; font-weight: bold;">Discriminante</span>)) / <span style="color: #f8f8f2; font-weight: bold;">A</span>
    <span style="color: #ff79c6; font-weight: bold;">end</span>.
</pre>
</div>

<p>
Los cálculos están simplificados, pero el resultado de la imagen es la
misma.
</p>
</div>
</div>
</div>
<div id="outline-container-org98b6ae1" class="outline-2">
<h2 id="org98b6ae1">Conclusiones</h2>
<div class="outline-text-2" id="text-org98b6ae1">
<p>
Apenas llevamos un 27% del primer libro y ya tenemos un <i>raytracer</i>
funcionando. Bueno, vale, es muy limitado y sólo dibuja una esfera,
además no de forma realista. Pero está funcionando: trazamos rayos y
conseguimos una representación correcta.
</p>

<p>
A partir de aquí, el libro empieza a utilizar algunas características
de la POO más avanzadas y tengo que estudiar cómo hacer lo mismo,
─parecido o no─, con <code>erlang</code>. Porque hasta ahora nos hemos venido
arreglando con los registros o <i>records</i>, pero se mete en temas de
<i>clases virtuales</i> y otras abstracciones que tengo que «abstraer» de
otra manera.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Bueno, algún <i>bug</i> he arreglado por el camino. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/raytrace/index.html">raytrace</a> <a href="/tags/erlang/index.html">erlang</a> ]]></description>
  <category><![CDATA[raytrace]]></category>
  <category><![CDATA[erlang]]></category>
  <link>https://notxor.nueva-actitud.org/2020/10/24/trazando-rayos.html</link>
  <pubDate>Sat, 24 Oct 2020 09:16:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Un pequeño raytracer]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-10-21</div>
<p>
Hoy vengo a hablaros de un pequeño proyecto, ─otro─, referido a una de
mis <i>ancestrales</i> aficiones. Digo <i>ancestrales</i> porque viene de muy
atrás, de hace muchos años, de cuando el mundo era joven y los
ingenuos humanos no se conectaban con sus ordenadores a Internet nada
más encenderlos: había que encender el módem y escuchar una serie de
pitidos (y no otra) antes de ello. De cuando la información la
compartíamos en <i>disquetes</i> de forma habitual y el conocimiento lo
adquiríamos de los libros. Éste va a ser un proyecto de <i>porque sí</i>,
porque me apetece y porque no es necesario hacerlo, ni sirve para
nada: el típico proyecto que me gusta para aprender más.
</p>

<p>
Quien me conoce de hace tiempo sabe de mi pasión con los trazadores de
rayos. Algunos recordarán <a href="https://openlibra.com/es/book/tecnologias-libres-para-sintesis-de-imagen-digital-tridimensional">algún artículo publicado</a> junto con el autor
de <i>YafRay</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, en alguna jornada de <i>Blendiberia</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>, aunque mi
afición a este tipo de herramientas es muy anterior.
</p>


<figure id="org6b5534e">
<img src="./imagen/libro-povray.png" alt="libro-povray.png">

</figure>

<p>
En la imagen muestro un libro que aún conservo y que aún recuerdo cómo
lo compré allá por el 1996 o el 1997<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>. Recuerdo que fue en <i>La
Casa del Libro</i>, yo estaba de visita en Madrid, y sólo existían dos
<i>Casa del Libro</i>: la original de Gran Vía y otra de <i>baratillo</i> frente
a Cortilandia. Lo recuerdo porque me llamaron, de alguna manera, la
atención. Llegué a las estanterías con el ánimo de mirar libros de
<i>informática</i>. En aquel entonces estaba interesado más en
<i>programación</i> y trasteaba con C/C++ y ensamblador.  Recuerdo también
que mirando entre los libros me llamó la atención el subtítulo del
libro de arriba. Había tocado algo de <i>AutoCAD</i>, aunque no mucho. En
aquella época, dicha herramienta, era 2D, dibujabas planos para
imprimirlos en papel con un <i>plotter</i> y poco más. Lo del 3D me resultó
curioso. Lo cogí de la estantería, miré la portada y me pareció muy
prometedora: Una imagen resultona (impresionante en aquella época),
«código fuente para generar imágenes», «incluye disquete»... lo
abrí. Comencé a hojearlo casi página a página, tanto rato le eché que
terminé sentado en el suelo, mirando las imágenes, ─algunas
impresionantes─, las fórmulas matemáticas, los listados de código y
tanto tiempo estuve allí sentado que finalmente un empleado se acercó
a ver qué estaba haciendo. «¿Vas a comprarlo o te lo quieres aprender
ahí sentado?», me preguntó. A punto estuve de tirarle el libro a la
cabeza por distraerme, pero sonrió con la expresión de quien sabe que
tiene la venta hecha. Pagué con tarjeta, no llevaba efectivo
suficiente para pagar el libro y me fui. Recuerdo que había quedado
con unos amigos y me pasé el tiempo deseando que acabara el fin de
semana para irme a casa donde estaba mi ordenador para enchufarle mi
disquete de «Pov-Ray 2.2» y probarlo.
</p>

<p>
Desde entonces ha llovido mucho, pero siempre estas herramientas
siempre me han parecido <i>casi</i> mágicas. Sé cómo funcionan, entiendo
los entresijos del funcionamiento y las matemáticas que los
soportan. Incluso años después participé en un intento de hacer un
<i>raytracer</i> cuyo objetivo era simular más perfectamente el
funcionamiento de una cámara fotográfica. Había llegado a
<i>NicoDigital</i>, un foro sobre <i>Blender3D</i> ya desaparecido. Recuerdo que
aquel intento lo promovió Javier Belanche y quería llamarlo como su
pintor favorito: <i>vermeer</i>. Incluso me envió un paquetón de fotocopias
con artículos y capítulos de libros que había recolectado sobre cómo
hacer un <i>raytracer</i>, la mayoría en inglés.
</p>

<p>
Entre unas cosas y otras el tema se enfrió, los tres que estábamos no
teníamos muy claro cómo empezar: uno estudió psicología, otro bellas
artes y ningún informático en el equipo, acabó con un intento muy
fallido.
</p>

<p>
No fue el último. De vez en cuando, encuentro algún <i>tutorial</i> de cómo
hacer un <i>raytracer</i> donde encuentras mucho pseudocódigo y algo de
código, pero el poco código que hay no funciona, está obsoleto o te
faltan librerías; las explicaciones no son muy claras con
introducciones largas y farragosas plagadas de teoría y matemáticas
que yo puedo obviar, aunque las repase de todos modos. Cuando he
conseguido algo ha sido casi de casualidad y obteniendo un código poco
flexible y extensible, más digno de la basura que de comenzar un
proyecto serio.
</p>
<div id="outline-container-orgaa61f79" class="outline-2">
<h2 id="orgaa61f79">Nuevo intento</h2>
<div class="outline-text-2" id="text-orgaa61f79">
<p>
Hace poco llegué a otra página web: <a href="https://raytracing.github.io/">https://raytracing.github.io/</a>
donde presenta tres libros<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>. Después de ojearlos los tres (son muy
cortitos) comencé por el primero: <a href="https://raytracing.github.io/books/RayTracingInOneWeekend.html">Ray Tracing in One Weekend</a>.
</p>

<p>
En el título promete hacer un <i>raytracer</i> en un fin de semana... muy
poco tiempo me parece. No digo que no haya alguien capaz de hacerlo,
pero no creo que esté a mi alcance. Llevo un par de ratos leyendo y
picando código, pero estoy convencido que lo del fin de semana será si
picas código sin parar para dormir, ni comer, ni cagar.
</p>

<p>
El caso es que ya tengo algo picado, no mucho. Pero ha sido
prometedor: primera explicación, primer código metido y primera imagen
conseguida. Vale que aún no he trazado un sólo rayo pero me anima el
haber seguido las explicaciones y haber conseguido el resultado
esperado. Teniendo en cuenta además, que el código que el libro
propone es C++ y yo lo estoy haciendo en <code>erlang</code>. ¿Por qué? Porque al
verlo me he imaginado lo que puede ser un proceso <code>imagen</code> lanzando
procesos <code>rayos</code> que se distribuyen por varias máquinas en distintos
nodos de una red y conseguir hacer un <i>raytracer</i> distribuido sin las
complicaciones de otros lenguajes.
</p>

<p>
En contra me tropiezo con el problema de convertir el código POO de
C++ a código funcional de erlang.
</p>
</div>
</div>
<div id="outline-container-orgc847e4f" class="outline-2">
<h2 id="orgc847e4f">El ejemplo conseguido hasta ahora</h2>
<div class="outline-text-2" id="text-orgc847e4f">

<figure id="org5a40d35">
<img src="./imagen/prueba.png" alt="prueba.png">

</figure>

<p>
Vale, es poca cosa pero funcionó a la primera, a pesar de que a las
explicaciones que da el «libro» le he hecho algunos cambios.
Concretamente he separado la generación del gráfico, escribiéndolo
directamente a un fichero, del contador que muestra el avance del
<i>render</i>. En el libro, utiliza el flujo normal de salida para escribir
el fichero y el flujo de error para indicar el avance<sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>. Además,
le he añadido un lanzador de nombre <i>rerl</i>, que viene a ser
<i>raytracerl</i> más corto... y que lo he acortado también porque me
imaginaba a Joaquín Reyes presentándolo al grito de
<i>raytraceeeerrllll</i> imitando a cualquier informático famoso<sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup> con
acento manchego y no me resultaba serio.
</p>

<p>
El primer problema que me encontré es que al hacerlo en <code>erlang</code> había
que lanzar la máquina virtual, cargar el módulo y llamar a la función
que dibuja la imagen. La solución: hacer un lanzador que lo haga por
nosotros en forma de <code>escript</code>:
</p>

<div class="org-src-container">
<pre class="src src-erlang">#!/usr/bin/env escript
<span style="color: #6272a4;">%% </span><span style="color: #6272a4;">-*- erlang -*-
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">! -smp enable -sname lanzador
</span><span style="color: #50fa7b; font-weight: bold;">main</span>([<span style="color: #f8f8f2; font-weight: bold;">Nombre_Fichero</span>]) -&gt;
    <span style="color: #8be9fd; font-style: italic;">imagen</span>:<span style="color: #8be9fd; font-style: italic;">dibujar</span>(<span style="color: #f8f8f2; font-weight: bold;">Nombre_Fichero</span>);
<span style="color: #50fa7b; font-weight: bold;">main</span>([]) -&gt;
    <span style="color: #8be9fd; font-style: italic;">imagen</span>:<span style="color: #8be9fd; font-style: italic;">dibujar</span>().
</pre>
</div>

<p>
Como se ve, el módulo que lleva el cotarro se llama <code>imagen</code> y tiene
una función que se llama <code>dibujar</code>. Si se le pasa un nombre de
fichero, llama a <code>imagen</code> pasándole ese nombre donde debe escribir el
resultado. En otras ocasiones, cuando hago un <code>escript</code>, suelo
intentar controlar algún posible error, como que falte algún
parámetro. Sin embargo, en este caso, como es una herramienta de
lanzamiento para pruebas y cualquier fallo es importante, prefiero no
manejar error y que me informe de los detalles fallo que ha ocurrido.
</p>

<p>
Por otro lado, el código que genera la imagen que he mostrado más arriba
es el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-module</span>(imagen).

<span style="color: #ffb86c;">-define</span>(<span style="color: #f8f8f2; font-weight: bold;">ANCHO</span>,256).
<span style="color: #ffb86c;">-define</span>(<span style="color: #f8f8f2; font-weight: bold;">ALTO</span>,256).
<span style="color: #ffb86c;">-define</span>(<span style="color: #f8f8f2; font-weight: bold;">FICHERO</span>,<span style="color: #f1fa8c;">"imagen.ppm"</span>).

<span style="color: #ffb86c;">-export</span>([
          <span style="color: #8be9fd; font-style: italic;">dibujar/0</span>
        , <span style="color: #8be9fd; font-style: italic;">dibujar/1</span>]).

<span style="color: #50fa7b; font-weight: bold;">dibujar</span>() -&gt;
    <span style="color: #8be9fd; font-style: italic;">dibujar</span>(?<span style="color: #bd93f9;">FICHERO</span>).

<span style="color: #50fa7b; font-weight: bold;">dibujar</span>(<span style="color: #f8f8f2; font-weight: bold;">Fichero</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Cabecera</span> = <span style="color: #8be9fd; font-style: italic;">io_lib</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"P3~n~p ~p~n255~n"</span>, [?<span style="color: #bd93f9;">ANCHO</span>,?<span style="color: #bd93f9;">ALTO</span>]),
    {ok,<span style="color: #f8f8f2; font-weight: bold;">F</span>} = <span style="color: #8be9fd; font-style: italic;">file</span>:<span style="color: #8be9fd; font-style: italic;">open</span>(<span style="color: #f8f8f2; font-weight: bold;">Fichero</span>, [write]),
    <span style="color: #f8f8f2; font-weight: bold;">B</span> = 63,
    <span style="color: #f8f8f2; font-weight: bold;">Imagen</span> =
        <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(
          <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">G</span>) -&gt;
                  <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Faltan ~p filas  \e[36D"</span>, [<span style="color: #f8f8f2; font-weight: bold;">G</span>]),
                  <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(
                    <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>) -&gt;
                            <span style="color: #8be9fd; font-style: italic;">io_lib</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"~p ~p ~p~n"</span>, [<span style="color: #f8f8f2; font-weight: bold;">R</span>,<span style="color: #f8f8f2; font-weight: bold;">G</span>,<span style="color: #f8f8f2; font-weight: bold;">B</span>])
                    <span style="color: #ff79c6; font-weight: bold;">end</span>,
                    <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(0,255))
          <span style="color: #ff79c6; font-weight: bold;">end</span>,
          <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(255,0,-1)),
    <span style="color: #8be9fd; font-style: italic;">file</span>:<span style="color: #8be9fd; font-style: italic;">write</span>(<span style="color: #f8f8f2; font-weight: bold;">F</span>, <span style="color: #f8f8f2; font-weight: bold;">Cabecera</span> ++ <span style="color: #f8f8f2; font-weight: bold;">Imagen</span>),
    <span style="color: #8be9fd; font-style: italic;">file</span>:<span style="color: #8be9fd; font-style: italic;">close</span>(<span style="color: #f8f8f2; font-weight: bold;">F</span>),
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"\nFin.\n"</span>).
</pre>
</div>

<p>
Muy sencillo de entender: el módulo <code>imagen</code> está compuesto por dos
funciones con el mismo nombre, <code>dibujar</code>, que puede llevar el
parámetro del nombre de fichero o no. En caso de no llevar, utiliza la
constante <code>?FICHERO</code> para llamar a la función con parámetro.
</p>

<p>
Por el nombre del fichero por defecto se puede ver que utilizamos el
formato de imagen <code>ppm</code>, que es un formato de imagen definido mediante
texto ASCII y si no tienes muy claro cómo funciona, lo voy a explicar
más despacio. Veamos la cabecera:
</p>

<pre class="example" id="org835dda8">
P3
256 256
255
</pre>

<p>
La cabecera que genera el programa se divide en las siguiente líneas<sup><a id="fnr.7" class="footref" href="#fn.7" role="doc-backlink">7</a></sup>:
</p>

<ul class="org-ul">
<li><b>Número mágico</b>: en la familia de ficheros gráficos denominados como
<a href="https://en.wikipedia.org/wiki/Netpbm#File_formats"><i>portable pixel format</i> PPM</a>, los dos caracteres <code>P3</code> indican que es
un fichero ASCII que contiene valores RGB.</li>
<li><b>Ancho y alto</b>: en pixeles de la imagen. En este caso la imagen
tendrá \(256 \times 256\) es decir un cuadrado de <code>0</code> a <code>255</code> píxeles
de lado.</li>
<li><b>Valor máximo del color</b>: en este caso el valor de cada componente
puede llegar hasta <code>255</code>, el mínimo siempre es <code>0</code>.</li>
</ul>

<p>
A partir de ahí, en el ejemplo, cada punto será dibujado por una
combinación RGB tal que los componentes <code>R</code> y <code>G</code> se toman de dos
contadores obtenidos mediante <code>lists:seq</code> y el valor <code>B</code> se mantiene
constante en <code>63</code>.  Luego crea una cadena por cada punto, uno por
línea, con la instrucción <code>io_lib:format("~p ~p ~p~n", [R,G,B])</code>.
</p>

<p>
Al final, cuando tiene la cabecera y la imagen preparadas, las escribe
en un fichero y después lo cierra guardando el contenido.
</p>
</div>
</div>
<div id="outline-container-orgbefb28f" class="outline-2">
<h2 id="orgbefb28f">Simulando clases con erlang</h2>
<div class="outline-text-2" id="text-orgbefb28f">
<p>
Lo siguiente que hace el librillo es crearse algunas clases básicas:
en realidad una clase <code>vec3</code> para almacenar y operar valores
representados por 3 valores individuales. Lo utiliza tanto para
guardar valores de vectores, propiamente dichos, como para guardar
colores. En <code>erlang</code> podría utilizar <i>tuplas</i> con el formato <code>{A,B,C}</code>
y luego operar la tupla según el concepto que almacene. Sin embargo,
creo que me irá mejor no mezclar las churras y las merinas.
</p>

<p>
No lo he mirado, pero seguramente en el futuro, el autor, separará
esos conceptos derivando clases, por lo que voy desobedecer un poco la
línea argumental inicial del <i>tutorial</i> y voy crear los dos conceptos
separados. Podría, por ejemplo, crear tuplas del estilo
<code>{color,{r,g,b}}</code> o <code>{vec3,{x,y,z}}</code>, pero ésto es la definición de
un registro o <code>record</code>. Como además supongo que esas definiciones las
necesitaré en todos los módulos que se irán creando, las pongo en un
fichero aparte que llamo <code>registros.hrl</code> y que presenta el siguiente
contenido:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-record</span>(<span style="color: #8be9fd; font-style: italic;">vec3</span>,  {x,y,z}).
<span style="color: #ffb86c;">-record</span>(<span style="color: #8be9fd; font-style: italic;">color</span>, {r,g,b}).
</pre>
</div>
</div>
<div id="outline-container-orga71338d" class="outline-3">
<h3 id="orga71338d">La clase <code>vec3</code></h3>
<div class="outline-text-3" id="text-orga71338d">
<p>
Como digo, el autor crea la clase <code>vec3</code> que en mi caso, he decidido
separar en dos: <code>vec3</code> y <code>color</code>. En su código fuente, crea algunos
operadores para operar con ellos y también algunos alias como <code>point3</code>
y <code>color</code>, definiendo después algunas funciones auxiliares más: las
típicas de sumar vectores o multiplicarlos, operar también con
escalares, etc. Mi módulo lo he dejado así:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-module</span>(vec3).

<span style="color: #ffb86c;">-include</span>(<span style="color: #f1fa8c;">"registros.hrl"</span>).

<span style="color: #ffb86c;">-export</span>([
         <span style="color: #8be9fd; font-style: italic;">nuevo/3</span>
       , <span style="color: #8be9fd; font-style: italic;">suma/2</span>
       , <span style="color: #8be9fd; font-style: italic;">dife/2</span>
       , <span style="color: #8be9fd; font-style: italic;">mul/2</span>
       , <span style="color: #8be9fd; font-style: italic;">divi/2</span>
       , <span style="color: #8be9fd; font-style: italic;">cruz/2</span>
       , <span style="color: #8be9fd; font-style: italic;">punto/2</span>
       , <span style="color: #8be9fd; font-style: italic;">modulo_cuadrado/1</span>
       , <span style="color: #8be9fd; font-style: italic;">modulo/1</span>
       , <span style="color: #8be9fd; font-style: italic;">unidad/1</span>]).

<span style="color: #50fa7b; font-weight: bold;">nuevo</span>(<span style="color: #f8f8f2; font-weight: bold;">X</span>,<span style="color: #f8f8f2; font-weight: bold;">Y</span>,<span style="color: #f8f8f2; font-weight: bold;">Z</span>) -&gt;
    #<span style="color: #8be9fd; font-style: italic;">vec3</span>{x=<span style="color: #f8f8f2; font-weight: bold;">X</span>,y=<span style="color: #f8f8f2; font-weight: bold;">Y</span>,z=<span style="color: #f8f8f2; font-weight: bold;">Z</span>}.

<span style="color: #50fa7b; font-weight: bold;">suma</span>(<span style="color: #f8f8f2; font-weight: bold;">V1</span>,<span style="color: #f8f8f2; font-weight: bold;">V2</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">nuevo</span>(<span style="color: #f8f8f2; font-weight: bold;">V1</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.x + <span style="color: #f8f8f2; font-weight: bold;">V2</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.x,
          <span style="color: #f8f8f2; font-weight: bold;">V1</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.y + <span style="color: #f8f8f2; font-weight: bold;">V2</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.y,
          <span style="color: #f8f8f2; font-weight: bold;">V1</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.z + <span style="color: #f8f8f2; font-weight: bold;">V2</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.z).

<span style="color: #50fa7b; font-weight: bold;">dife</span>(<span style="color: #f8f8f2; font-weight: bold;">V1</span>,<span style="color: #f8f8f2; font-weight: bold;">V2</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">nuevo</span>(<span style="color: #f8f8f2; font-weight: bold;">V1</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.x - <span style="color: #f8f8f2; font-weight: bold;">V2</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.x,
          <span style="color: #f8f8f2; font-weight: bold;">V1</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.y - <span style="color: #f8f8f2; font-weight: bold;">V2</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.y,
          <span style="color: #f8f8f2; font-weight: bold;">V1</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.z - <span style="color: #f8f8f2; font-weight: bold;">V2</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.z).

<span style="color: #50fa7b; font-weight: bold;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">Vector</span>, <span style="color: #f8f8f2; font-weight: bold;">X</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">nuevo</span>(<span style="color: #f8f8f2; font-weight: bold;">Vector</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.x * <span style="color: #f8f8f2; font-weight: bold;">X</span>,
          <span style="color: #f8f8f2; font-weight: bold;">Vector</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.y * <span style="color: #f8f8f2; font-weight: bold;">X</span>,
          <span style="color: #f8f8f2; font-weight: bold;">Vector</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.z * <span style="color: #f8f8f2; font-weight: bold;">X</span>).

<span style="color: #50fa7b; font-weight: bold;">divi</span>(<span style="color: #f8f8f2; font-weight: bold;">Vector</span>, <span style="color: #f8f8f2; font-weight: bold;">X</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">Vector</span>, 1/<span style="color: #f8f8f2; font-weight: bold;">X</span>).

<span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Producto vectorial
</span><span style="color: #50fa7b; font-weight: bold;">cruz</span>(<span style="color: #f8f8f2; font-weight: bold;">V1</span>,<span style="color: #f8f8f2; font-weight: bold;">V2</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">nuevo</span>(<span style="color: #f8f8f2; font-weight: bold;">V1</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.x * <span style="color: #f8f8f2; font-weight: bold;">V2</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.x,
          <span style="color: #f8f8f2; font-weight: bold;">V1</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.y * <span style="color: #f8f8f2; font-weight: bold;">V2</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.y,
          <span style="color: #f8f8f2; font-weight: bold;">V1</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.z * <span style="color: #f8f8f2; font-weight: bold;">V2</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.z).

<span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Producto escalar
</span><span style="color: #50fa7b; font-weight: bold;">punto</span>(<span style="color: #f8f8f2; font-weight: bold;">V1</span>,<span style="color: #f8f8f2; font-weight: bold;">V2</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">V1</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.x * <span style="color: #f8f8f2; font-weight: bold;">V2</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.x +
    <span style="color: #f8f8f2; font-weight: bold;">V1</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.y * <span style="color: #f8f8f2; font-weight: bold;">V2</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.y +
    <span style="color: #f8f8f2; font-weight: bold;">V1</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.z * <span style="color: #f8f8f2; font-weight: bold;">V2</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.z.

<span style="color: #50fa7b; font-weight: bold;">modulo_cuadrado</span>(<span style="color: #f8f8f2; font-weight: bold;">V</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">V</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.x*<span style="color: #f8f8f2; font-weight: bold;">V</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.x + <span style="color: #f8f8f2; font-weight: bold;">V</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.y*<span style="color: #f8f8f2; font-weight: bold;">V</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.y + <span style="color: #f8f8f2; font-weight: bold;">V</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.z*<span style="color: #f8f8f2; font-weight: bold;">V</span>#<span style="color: #8be9fd; font-style: italic;">vec3</span>.z.

<span style="color: #50fa7b; font-weight: bold;">modulo</span>(<span style="color: #f8f8f2; font-weight: bold;">V</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">math</span>:<span style="color: #8be9fd; font-style: italic;">sqrt</span>(<span style="color: #8be9fd; font-style: italic;">modulo_cuadrado</span>(<span style="color: #f8f8f2; font-weight: bold;">V</span>)).

<span style="color: #50fa7b; font-weight: bold;">unidad</span>(<span style="color: #f8f8f2; font-weight: bold;">V</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">divi</span>(<span style="color: #f8f8f2; font-weight: bold;">V</span>, <span style="color: #8be9fd; font-style: italic;">modulo</span>(<span style="color: #f8f8f2; font-weight: bold;">V</span>)).
</pre>
</div>

<p>
Tengo que duplicar algo de código, aunque no todo, para el módulo
<code>color</code>. Por lo menos lo que el libro define en la cabecera y la que
luego utiliza para escribir el color en el fichero. El módulo me ha
quedado así:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-module</span>(color).

<span style="color: #ffb86c;">-export</span>([
          <span style="color: #8be9fd; font-style: italic;">nuevo/3</span>
        , <span style="color: #8be9fd; font-style: italic;">escribe/1</span>
        , <span style="color: #8be9fd; font-style: italic;">mul/2</span>
        , <span style="color: #8be9fd; font-style: italic;">suma/2</span>]).

<span style="color: #ffb86c;">-include</span>(<span style="color: #f1fa8c;">"registros.hrl"</span>).

<span style="color: #50fa7b; font-weight: bold;">nuevo</span>(<span style="color: #f8f8f2; font-weight: bold;">R</span>,<span style="color: #f8f8f2; font-weight: bold;">G</span>,<span style="color: #f8f8f2; font-weight: bold;">B</span>) -&gt;
    #<span style="color: #8be9fd; font-style: italic;">color</span>{r=<span style="color: #f8f8f2; font-weight: bold;">R</span>,g=<span style="color: #f8f8f2; font-weight: bold;">G</span>,b=<span style="color: #f8f8f2; font-weight: bold;">B</span>}.

<span style="color: #50fa7b; font-weight: bold;">escribe</span>(<span style="color: #f8f8f2; font-weight: bold;">C</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">io_lib</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"~p ~p ~p~n"</span>, [<span style="color: #8be9fd; font-style: italic;">round</span>(255*<span style="color: #f8f8f2; font-weight: bold;">C</span>#<span style="color: #8be9fd; font-style: italic;">color</span>.r),<span style="color: #8be9fd; font-style: italic;">round</span>(255*<span style="color: #f8f8f2; font-weight: bold;">C</span>#<span style="color: #8be9fd; font-style: italic;">color</span>.g),<span style="color: #8be9fd; font-style: italic;">round</span>(255*<span style="color: #f8f8f2; font-weight: bold;">C</span>#<span style="color: #8be9fd; font-style: italic;">color</span>.b)]).

<span style="color: #50fa7b; font-weight: bold;">mul</span>(<span style="color: #f8f8f2; font-weight: bold;">C</span>,<span style="color: #f8f8f2; font-weight: bold;">X</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">nuevo</span>(<span style="color: #f8f8f2; font-weight: bold;">C</span>#<span style="color: #8be9fd; font-style: italic;">color</span>.r * <span style="color: #f8f8f2; font-weight: bold;">X</span>,
          <span style="color: #f8f8f2; font-weight: bold;">C</span>#<span style="color: #8be9fd; font-style: italic;">color</span>.g * <span style="color: #f8f8f2; font-weight: bold;">X</span>,
          <span style="color: #f8f8f2; font-weight: bold;">C</span>#<span style="color: #8be9fd; font-style: italic;">color</span>.b * <span style="color: #f8f8f2; font-weight: bold;">X</span>).

<span style="color: #50fa7b; font-weight: bold;">suma</span>(<span style="color: #f8f8f2; font-weight: bold;">C1</span>,<span style="color: #f8f8f2; font-weight: bold;">C2</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">nuevo</span>(<span style="color: #f8f8f2; font-weight: bold;">C1</span>#<span style="color: #8be9fd; font-style: italic;">color</span>.r + <span style="color: #f8f8f2; font-weight: bold;">C2</span>#<span style="color: #8be9fd; font-style: italic;">color</span>.r,
          <span style="color: #f8f8f2; font-weight: bold;">C1</span>#<span style="color: #8be9fd; font-style: italic;">color</span>.g + <span style="color: #f8f8f2; font-weight: bold;">C2</span>#<span style="color: #8be9fd; font-style: italic;">color</span>.g,
          <span style="color: #f8f8f2; font-weight: bold;">C1</span>#<span style="color: #8be9fd; font-style: italic;">color</span>.b + <span style="color: #f8f8f2; font-weight: bold;">C2</span>#<span style="color: #8be9fd; font-style: italic;">color</span>.b).
</pre>
</div>

<p>
Por último, está el código del módulo <code>imagen</code>, es decir, el código
que genera el resultado final utilizando los módulos<sup><a id="fnr.8" class="footref" href="#fn.8" role="doc-backlink">8</a></sup> ha quedado
así:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-module</span>(imagen).

<span style="color: #ffb86c;">-define</span>(<span style="color: #f8f8f2; font-weight: bold;">ANCHO</span>,256).
<span style="color: #ffb86c;">-define</span>(<span style="color: #f8f8f2; font-weight: bold;">ALTO</span>,256).
<span style="color: #ffb86c;">-define</span>(<span style="color: #f8f8f2; font-weight: bold;">FICHERO</span>,<span style="color: #f1fa8c;">"imagen.ppm"</span>).

<span style="color: #ffb86c;">-include</span>(<span style="color: #f1fa8c;">"registros.hrl"</span>).

<span style="color: #ffb86c;">-export</span>([
          <span style="color: #8be9fd; font-style: italic;">dibujar/0</span>
        , <span style="color: #8be9fd; font-style: italic;">dibujar/1</span>]).

<span style="color: #50fa7b; font-weight: bold;">dibujar</span>() -&gt;
    <span style="color: #8be9fd; font-style: italic;">dibujar</span>(?<span style="color: #bd93f9;">FICHERO</span>).

<span style="color: #50fa7b; font-weight: bold;">dibujar</span>(<span style="color: #f8f8f2; font-weight: bold;">Fichero</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Cabecera</span> = <span style="color: #8be9fd; font-style: italic;">io_lib</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"P3~n~p ~p~n255~n"</span>, [?<span style="color: #bd93f9;">ANCHO</span>,?<span style="color: #bd93f9;">ALTO</span>]),
    {ok,<span style="color: #f8f8f2; font-weight: bold;">F</span>} = <span style="color: #8be9fd; font-style: italic;">file</span>:<span style="color: #8be9fd; font-style: italic;">open</span>(<span style="color: #f8f8f2; font-weight: bold;">Fichero</span>, [write]),
    <span style="color: #f8f8f2; font-weight: bold;">Imagen</span> =
        <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(
          <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">J</span>) -&gt;
                  <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Faltan ~p filas  \e[36D"</span>, [<span style="color: #f8f8f2; font-weight: bold;">J</span>]),
                  <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(
                    <span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">I</span>) -&gt;
                            <span style="color: #f8f8f2; font-weight: bold;">Color</span> = <span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">nuevo</span>(<span style="color: #f8f8f2; font-weight: bold;">I</span>/(?<span style="color: #bd93f9;">ANCHO</span> - 1), <span style="color: #f8f8f2; font-weight: bold;">J</span>/(?<span style="color: #bd93f9;">ALTO</span> - 1), 0.25),
                            <span style="color: #8be9fd; font-style: italic;">color</span>:<span style="color: #8be9fd; font-style: italic;">escribe</span>(<span style="color: #f8f8f2; font-weight: bold;">Color</span>)
                    <span style="color: #ff79c6; font-weight: bold;">end</span>,
                    <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(0,255))
          <span style="color: #ff79c6; font-weight: bold;">end</span>,
          <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(255,0,-1)),
    <span style="color: #8be9fd; font-style: italic;">file</span>:<span style="color: #8be9fd; font-style: italic;">write</span>(<span style="color: #f8f8f2; font-weight: bold;">F</span>, <span style="color: #f8f8f2; font-weight: bold;">Cabecera</span> ++ <span style="color: #f8f8f2; font-weight: bold;">Imagen</span>),
    <span style="color: #8be9fd; font-style: italic;">file</span>:<span style="color: #8be9fd; font-style: italic;">close</span>(<span style="color: #f8f8f2; font-weight: bold;">F</span>),
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"\nFin.\n"</span>).
</pre>
</div>

<p>
El código, de momento, no es nada <i>concurrente</i>, sigue el desarrollo y
las explicaciones del libro que están muy dirigidas por un lenguaje
POO como <code>C++</code>. El resultado obtenido con éstos últimos cambios es el
mismo que mostré al principio, pero se le ha añadido una capa de
modularidad con objetos. Desde el punto de vista de <code>erlang</code>
seguramente, el proceso estrella podría ser <code>imagen</code> que fuera
lanzando procesos <code>color</code> o <code>pixel</code> que calculen el valor para cada
punto de la imagen. De momento, no hay cálculos complejos y es todo
muy lineal, pero creo que puede ser una línea de desarrollo futuro. Ya
veremos por dónde continúa el libro y hacia dónde me obliga a tirar a
mí.
</p>

<p>
Otro problema sobrevenido es el tema de la compilación de los módulos.
Los cambios en este último procesamiento de la imagen me funcionaron
al tercer intento, no porque tuviera ningún error, sino porque había
módulos sin compilar. Necesito un <code>Makefile</code>. Además está todo metido
en el mismo directorio, los fuentes y los <code>.beam</code> y todo a mogollón.
La verdad es que es un poco farragoso. Para evitarlo he metido todo el
código fuente en un directorio <code>src</code> y creado un <code>Makefile</code> que lo
compila y lo guarda en un directorio <code>ebin</code>:
</p>

<div class="org-src-container">
<pre class="src src-makefile"><span style="color: #50fa7b; font-weight: bold;">.PHONY</span>: clean compilar all

<span style="color: #f8f8f2; font-weight: bold;">DIR_SRC</span> = ./src
<span style="color: #f8f8f2; font-weight: bold;">DIR_BIN</span> = ./ebin

<span style="color: #f8f8f2; font-weight: bold;">LANZADOR</span> = rerl

<span style="color: #f8f8f2; font-weight: bold;">SOURCES</span> = vec3.erl \
          imagen.erl \
          color.erl \
          $(<span style="color: #f8f8f2; font-weight: bold;">LANZADOR</span>)

<span style="color: #f8f8f2; font-weight: bold;">TARGETS</span> = $(<span style="color: #f8f8f2; font-weight: bold;">DIR_BIN</span>)/vec3.beam \
          $(<span style="color: #f8f8f2; font-weight: bold;">DIR_BIN</span>)/imagen.beam \
          $(<span style="color: #f8f8f2; font-weight: bold;">DIR_BIN</span>)/color.beam \
          $(<span style="color: #f8f8f2; font-weight: bold;">DIR_BIN</span>)/$(<span style="color: #f8f8f2; font-weight: bold;">LANZADOR</span>)

<span style="color: #50fa7b; font-weight: bold;">compilar</span>: $(<span style="color: #f8f8f2; font-weight: bold;">DIR_BIN</span>) $(<span style="color: #f8f8f2; font-weight: bold;">TARGETS</span>)

<span style="color: #50fa7b; font-weight: bold;">clean</span>:
        rm -rf $(<span style="color: #f8f8f2; font-weight: bold;">DIR_BIN</span>)

<span style="color: #50fa7b; font-weight: bold;">$(</span><span style="color: #50fa7b; font-weight: bold;">DIR_BIN</span><span style="color: #50fa7b; font-weight: bold;">)/%.beam</span>: $(<span style="color: #f8f8f2; font-weight: bold;">DIR_SRC</span>)/%.erl $(<span style="color: #f8f8f2; font-weight: bold;">DIR_SRC</span>)/registros.hrl
        erlc -o $(<span style="color: #f8f8f2; font-weight: bold;">DIR_BIN</span>) $<span style="color: #bd93f9;">&lt;</span>

<span style="color: #50fa7b; font-weight: bold;">$(</span><span style="color: #50fa7b; font-weight: bold;">DIR_BIN</span><span style="color: #50fa7b; font-weight: bold;">)/$(</span><span style="color: #50fa7b; font-weight: bold;">LANZADOR</span><span style="color: #50fa7b; font-weight: bold;">)</span>: $(<span style="color: #f8f8f2; font-weight: bold;">DIR_SRC</span>)/$(<span style="color: #f8f8f2; font-weight: bold;">LANZADOR</span>)
        cp $(<span style="color: #f8f8f2; font-weight: bold;">DIR_SRC</span>)/$(<span style="color: #f8f8f2; font-weight: bold;">LANZADOR</span>) $(<span style="color: #f8f8f2; font-weight: bold;">DIR_BIN</span>)/$(<span style="color: #f8f8f2; font-weight: bold;">LANZADOR</span>)

<span style="color: #50fa7b; font-weight: bold;">$(</span><span style="color: #50fa7b; font-weight: bold;">DIR_BIN</span><span style="color: #50fa7b; font-weight: bold;">)</span>:
        mkdir $(<span style="color: #f8f8f2; font-weight: bold;">DIR_BIN</span>)

<span style="color: #50fa7b; font-weight: bold;">all</span>: compilar
</pre>
</div>

<p>
Esto del <code>Makefile</code> y la organización de los directorios, no viene en
el libro, pero me parecía necesario para aclararme yo. De esta forma
sigo también las estructuras de directorios habituales en <code>erlang</code>:
los fuentes en un directorio <code>src</code> y los binarios listos para
ejecutarse en un directorio llamado <code>ebin</code>.
</p>

<p>
Sólo recordaros, si alguien copia el <code>Makefile</code> del código anterior
seguramente no os funcione. El pasar de texto a <code>html</code> y de <code>html</code> a
texto puede haber hecho desaparecer los tabuladores. Recordad que
<code>make</code> utiliza tabuladores y no se pueden sustituir por espacios,
editar el fichero, borrad la indentación y hacedla con tabuladores.
</p>

<p>
Y creo que por hoy ya os he <i>cansinado</i> lo suficiente con mis cosas y
proyectos de aprendizaje.
</p>
</div>
</div>
</div>
<div id="outline-container-org048eb21" class="outline-2">
<h2 id="org048eb21">Conclusiones</h2>
<div class="outline-text-2" id="text-org048eb21">
<p>
Primera aproximación a un tutorial que promete explicar, por lo menos
<i>a priori</i>, cada paso de forma clara y directa. No puedo afirmar si el
código que escribe el autor es correcto y compila en todos los casos,
porque estoy utilizando otro lenguaje para realizar los ejercicios que
propone y tengo que escribir mi propio código. Recordad: <i>en mi
máquina funciona</i>.
</p>

<p>
El utilizar <code>erlang</code> y no <code>C++</code> puede representar un problema
importante más adelante cuando se meta de lleno en el uso de clases y
otras características de la programación orientada a objetos que
tendré que adaptar a la programación funcional. Como ejercicio parece
un interesante juego intelectual. Al principio me preocupará más
entender cómo funciona todo el sistema y no tanto la eficiencia, sin
embargo, intentaré también ir preparando el código para optimizarlo.
</p>

<p>
El formato de salida del fichero se mantiene durante los tres libros,
por lo que he podido ver. No es un formato muy eficiente, ocupa
bastante en disco, pero es sencillo de escribir y de leer.
</p>

<p>
De momento es muy pronto para saber qué módulos se convertirán en el
futuro en procesos de <code>erlang</code> para ser procesados de forma
concurrente. A bote pronto, creo que serán los píxeles de imagen y los
rayos que se envían para calcular su color. Pero aún no hemos llegado
a <i>trazar</i> ningún rayo... que, espero, lo haré en una próxima entrega
de estos apuntes.
</p>

<p>
Por último, ya disculparéis si utilizo el <i>blog</i> como mi libreta de
notas. Alguien puede aburrirse con esto, pero quizá a otros les sirva
de inspiración o incluso para resolver alguna duda.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ahora llamado <i>Yafaray</i> <a href="https://www.yafaray.org">https://www.yafaray.org</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Cuando empezamos a reunirnos unos pocos aficionados, antes de
que se profesionalizara el evento.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
La fecha no la recuerdo de forma exacta, lo demás sí. 
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
No muy largos pero al parecer sí muy prácticos. 
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Es una solución ingeniosa, pero no me parece limpia. 
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Si te lo imaginas con Stallman es inquietante... habría que
proponérselo a Joaquín Reyes. 
</p></div></div>

<div class="footdef"><sup><a id="fn.7" class="footnum" href="#fnr.7" role="doc-backlink">7</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Pueden ser cadenas separadas por espacios simplemente, pero he
preferido dividirlas en líneas para visualizarlo mejor. 
</p></div></div>

<div class="footdef"><sup><a id="fn.8" class="footnum" href="#fnr.8" role="doc-backlink">8</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En realidad, de momento, sólo utiliza el módulo de <code>color</code>, sin
embargo en el código en <code>C++</code> es relevante, porque utiliza <code>vec3</code> para
colores también. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/erlang/index.html">erlang</a> <a href="/tags/raytrace/index.html">raytrace</a> ]]></description>
  <category><![CDATA[erlang]]></category>
  <category><![CDATA[raytrace]]></category>
  <link>https://notxor.nueva-actitud.org/2020/10/21/un-pequeno-raytracer.html</link>
  <pubDate>Wed, 21 Oct 2020 18:41:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Projektoj kaj planoj]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-10-18</div>
<p>
Hodiaŭ mi volas paroli al vi pri miaj nunaj projektoj. Mi esperas ne
enuigu vin per miaj aferoj.
</p>
<div id="outline-container-orgf21194b" class="outline-2">
<h2 id="orgf21194b">Blog</h2>
<div class="outline-text-2" id="text-orgf21194b">
<p>
Ĉi tiu blogo estas malnova. Kelkaj jarojn antaŭe mi komencis skribi
kiel ŝatokupo, nur por amuzo de ĝia verkisto. Eble, ne verkisto, sed
<i>literkunigisto</i>, se oni permesas tiun esprimon<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. Vi povos
konstati kiel mi skribas ankaŭ en Esperanto.
</p>

<p>
Jes, ja, mi daŭras en la ideo de skribi ankaŭ esperante. Se al vi ne
sufiĉas mian balbutadon per la hispana, vi devas suferi mian
esperantan balbutadon. Sed mi bezonas skribi Esperanton, ne nur kiel
frenezaĵo de freneza ulo, mi ne esperas multajn legantojn, kiuj
interesiĝos per la samaj aferoj, kiujn al mi interesas.
</p>

<p>
Mi diris ke mi <i>bezonas</i> skribi per Esperanto ĉar ĉi tiu stranga jaro
mi ne povis praktiki la paroladon de nia ŝatata lingvo. Pli kaj pli mi
perdis fluecon, kaj kiam mi intencas, ne nur skribi, sed ankaŭ paroli,
la vortoj neas veni al mia menso haltigante la fadenon de mia penso
kaj malhelpante la komunikadon.
</p>

<p>
Alia parto el miaj projektoj estas instrui Esperanton rete. La Frateco
de Zaragozo, asocio al kiu mi apartenas, demandis min pri la ebleco de
fari retajn kursojn por lernado de nia lingvo, ĉar la kronviruso
malhelpas la ĉeestantaj klasoj. Mi volonte jesis al tiu propono. Mi
jam havas <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html">la kurson duon preparita</a> sed mi volas plibonigui la retpaĝon
por ke ĝi ŝajnos pli facila: por trovi la lecionojn kaj la ekzercojn.
De nun mi preparis vortaron de la hispana al Esperanto.  Estas la sama
<a href="https://www.esperanto.es/hef/index.php/diccionario-esperanto">vortaron de la reto de HEF</a>, sed en tiu paĝo kiam la vorto havas
multajn signifojn aŭ subsignifojn, tiujn difinojn perdiĝis en (sub) la
kadro. Mia intenco estas povi legi ĉiujn difinojn, do mi metis en
<a href="https://notxor.nueva-actitud.org/esperanto/diccionario.html">propra retpaĝo la saman ligilon</a> sed mi permesis la eblon de flanka
ruluma skalo por povi vidi kaj legi la ceteran tekston. Do mi avertas
ke mi ne havas rajtojn super la vortaro, kiu apartenas al ĝiaj
kreantoj kaj ili konservis ĉiujn rajtojn super ilia programo. Tiu
vortaro estas la plej bona ol ĉiuj hispana/esperantaj vortaroj.  Eble
la rulumskalo estas malpli bela ol la neta kadro, sed pli utila.
</p>

<p>
Do miaj sekvantaj okupoj en la <i>esperanta</i> blogo estas plibonigi la
kuros kaj pli skribi en ĝi.
</p>
</div>
</div>
<div id="outline-container-org0574410" class="outline-2">
<h2 id="org0574410">Tradukado</h2>
<div class="outline-text-2" id="text-org0574410">
<p>
Alia afero kiu mi volas komenti estas mia ekzerco por plibonigi mian
Esperanton. Plej bone dirata: por plibonigi mian Esperanton kaj mian
scipovon de la anglan. Mi tradukas tekstojn de la angla al Esperanto.
</p>

<p>
Nune, mi tradukas la romano <i>Duno</i> (Dune en la angla), de Frank
Herbert kaj, kiel mi jam diris, la celo estas plibonigi miajn lingvajn
kapablojn.
</p>

<p>
Mi jam havas tradukita pli ol 60% de la romano kaj mi faros <i>epub</i>
dosieron por ŝarĝi ĝin en mia bitlibra ilo kaj trankvile legi ĝin
korektanta la erarojn sed ĝuanta la aferon pli ol la tradukado.  Mi
nur volas legi ĝin, finfine mi legis la romanon tiel hispane kiel
angle kaj mi volas legi ankaŭ esperante. Do kiel mi ne trovis la
romanon tradukita, mi tradukos ĝin. Nur pro mia ĝojo, ĝuo kaj uzo.  Ĝi
ne estos, mi pensas, interesa al aliaj homoj, finfine mi nek estas
profesia tradukisto, nek verkisto, nek mi konsideras ke mi sufiĉe
scipovas la anglan, por eldoni libron. Nur estas ŝatokupo.
</p>
</div>
</div>
<div id="outline-container-org7e748fd" class="outline-2">
<h2 id="org7e748fd">Praktiki Esperanton</h2>
<div class="outline-text-2" id="text-org7e748fd">
<p>
Kiel mi jam diris la fino de la tradukado estas nur praktiki
Esperanton. Sed ne nur mi praktikas ĝin per traduko de tekstoj, ankaŭ
mi ŝatas legi kaj skribi. Tiu ĉi blogo<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> apartenas al tia
kategorio de praktikado: libere esprimi miajn pensojn per ĉi tiu bela
lingvo.
</p>

<p>
Ankaŭ, por ne forgesi ĉiun muskolan memoron mi laŭtlegas kelkajn
esperantajn tekstojn du, aŭ tri, fojoj semajne. Do, tiu ne estas
perfekta praktikado de la lingvo, sed oni povas sufiĉe konservi la
prononcadon.
</p>

<p>
Al mi mankas, kontraŭe, la necesan fluadon por trovi la vortojn sen
prokrasti la respondon, respektante la sintakson, esprimante la
penson. Pro tiu ĉi, oni bezonas bonan konversacion kun amikoj.
</p>
</div>
</div>
<div id="outline-container-org58c2245" class="outline-2">
<h2 id="org58c2245">Konkludoj</h2>
<div class="outline-text-2" id="text-org58c2245">
<p>
Fine, tiuj estas miaj precipaj projektoj kaj planoj respekte la
Esperanto.  Ili ne estas tre imponaj projektoj. Sed precipe estas
tiuj, kiujn al mi ŝatas por okupi mian liberan tempon. Tempon kiu
estas preskaŭ plena de taskoj kaj pli okupata ol libera, sed bone, mi
elektis tiujn okupojn volonte.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En la hispana oni nomas ĝin «juntaletras». 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
La esperanta parto, kompreneble. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/proyectos/index.html">proyectos</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[proyectos]]></category>
  <link>https://notxor.nueva-actitud.org/2020/10/18/projektoj-kaj-planoj.html</link>
  <pubDate>Sun, 18 Oct 2020 10:15:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Algoritmos genéticos]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-10-13</div>
<p>
Hace un par de días alguien preguntó en el grupo de <i>Telegram</i> si
alguno de nosotros tenía experiencia con los algoritmos genéticos en
<code>erlang</code>. Fue una pregunta bastante directa y sorpresiva, porque en
general en el grupo se habla más de <i>Lisp</i> y <i>Emacs</i>. Alguien
preguntando por <code>erlang</code> y por <i>algoritmos genéticos</i>: dos <i>fricadas</i>
dignas de atención, fue todo un reto. No me he podido resistir.
</p>
<div id="outline-container-org0195e5e" class="outline-2">
<h2 id="org0195e5e">Definición</h2>
<div class="outline-text-2" id="text-org0195e5e">
<p>
Como sabéis un <i>algoritmo</i> es la descripción de un proceso o
procedimiento para conseguir un resultado. Formalmente, según la
RAE<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>:
</p>

<blockquote>
<p>
conjunto de instrucciones o reglas definidas y no ambiguas, ordenadas
y finitas que permite, típicamente, solucionar un problema, realizar
un cómputo, procesar datos y llevar a cabo otras tareas o actividades.
</p>
</blockquote>

<p>
El nombre proviene del matemático persa de nombre <i>Al-Juarismi</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.
Por los años que este señor habló de <i>algoritmos</i> evidentemente no
existían computadoras que echarse a la punta de los dedos, así que
quizá nos tengamos que modernizar un poco y repasarnos la <i>Tesis
Church-Turing</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>.
</p>

<p>
Sin embargo, en nuestro caso, el algoritmo lleva además el apellido
<i>genético</i>... y ese aspecto no está relacionado con matemáticos ni con
informáticos.  Curiosa, o naturalmente, el apellido a este tipo de
algoritmos se lo puso un biólogo: <i>Richard Dawkins</i><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>. En su libro
<i>el relojero ciego</i><sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup> propone un pequeño programa informático para
ilustrar cómo funciona el <i>algoritmo</i> de la <i>selección natural</i> y la
evolución.
</p>

<p>
El tema que intenta explicar Richard Dawkins es la intervención del
<i>azar</i> en el proceso de la selección natural. El programita que hace
el autor es muy simple de entender: toma aquella metáfora de los monos
y las máquinas de escribir escribiendo alguna obra literaria
completa... me refiero <i>al <a href="https://es.wikipedia.org/wiki/Teorema_del_mono_infinito">teorema del mono infinito</a> o de los
infinitos monos</i>. Viene a explicar, que el azar puro no soluciona
ningún problema<sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup>, sin embargo, el punto importante, más
importante que el de el azar, es el de la <i>selección</i>.
</p>

<p>
El algoritmo genético, lo podemos representar así:
</p>


<figure id="orgad528b4">
<img src="./imagen/algoritmo-genetico.png" alt="algoritmo-genetico.png">

</figure>

<p>
El procedimiento no es totalmente aleatorio, sino que tiene una
finalidad. En la selección natural, la finalidad es el mejor ajuste al
medio ambiente, en el proceso informático o de la ingeniería,
igualmente, es la mejora en el resultado.
</p>
</div>
<div id="outline-container-org6b22746" class="outline-3">
<h3 id="org6b22746">Algoritmos biológicos</h3>
<div class="outline-text-3" id="text-org6b22746">
<p>
También hay que advertir, que puedes encontrar por ahí información
sobre <i>algoritmos biológicos</i>. Realmente, el algoritmo genético es uno
de esos <i>algoritmos biológicos</i>. <a href="https://notxor.nueva-actitud.org/2020/09/21/un-art%C3%ADculo-introductorio-sobre-redes-neuronales.html">Hace poco hablaba de las redes
neuronales</a>, que podrían ser consideradas como una forma particular de
lo que es un algoritmo biológico. El <i>Algoritmo Genético</i> sería otra
de esas formas particulares.
</p>

<p>
Como se puede ver, hay veces en que <i>imitar</i> a la naturaleza para
resolver algún problema es la manera más directa de hacerlo. ¿Por qué?
Pues porque, realmente, la naturaleza nos lleva muchas iteraciones de
ventaja y ha encontrado soluciones para las cosas más dispares.
</p>

<p>
Para explicar cómo funciona el <i>algoritmo genético</i> veamos un ejemplo.
</p>
</div>
</div>
</div>
<div id="outline-container-orgbfcaee0" class="outline-2">
<h2 id="orgbfcaee0">Ejemplo</h2>
<div class="outline-text-2" id="text-orgbfcaee0">
<p>
Me vais a permitir que imite a Richad Dawkins y rehaga su ejemplo.
Cuando él lo escribió, estaba intentando demostrar que la <i>selección
natural</i>, aunque los cambios en el genoma se produzcan al azar, no es
un proceso puramente aleatorio, sino regido por un entorno selectivo.
Para ello, proponía encontrar una cadena de texto aplicando el
algoritmo genético a la selección de las sucesivas generaciones de
cadenas en las que se producen las mutaciones aleatorias.  Cada
carácter tendría la consideración de <i>un gen</i> individual y la cadena
completa sería el <i>genotipo</i>... estirando la analogía.
</p>

<p>
El ejemplo que aparecía en el libro de Dawkins utilizaba sólo
caracteres en mayúsculas, y sólo los que se emplean en inglés. En mi
ejemplo lo he extendido un poco a los caracteres imprimibles
ASCII. Tampoco contemplo las tildes y las eñes. Es decir, entre los
valores ASCII 32 y 126. Esto es, el conjunto de <i>genes</i> que puede
expresar nuestro <i>genoma</i> es:
</p>

<pre class="example" id="orgc64eccd">
!"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
</pre>

<p>
Atención, porque también está el espacio en blanco, pero como está al
principio, no se observa muy claramente. Por otro lado, prescindo de
los caracteres especiales como la «ñ» o las tildes, dejando la
inclusión de las mismas al lector más aventurero, si quiere hacer un
<i>script</i> que funcione en utf-8 ─por ejemplo─. Lo dejo así por no
añadir las complejidades de conversiones de códigos de caracteres y
que nos podamos despistar.
</p>

<p>
La cadena que he utilizado para la mayoría de las pruebas ha sido:
<i>Esto es un Ejemplo...</i> Sí, ya sé que no soy muy original, pero era
dar la tecla arriba para las distintas pruebas que he hecho. Aunque el
comando era muy sencillo:
</p>

<div class="org-src-container">
<pre class="src src-shell">./genoma <span style="color: #f1fa8c;">"Esto es un Ejemplo..."</span>
</pre>
</div>

<p>
Esa cadena del ejemplo, tiene 21 caracteres contando los espacios en
blanco, que como acabo de decir, entran en el <i>conjunto de
genes</i>. Como explica Dawkins cuando los <i>creacionistas</i> critican que
los cambios en la evolución se produzcan de forma aleatoria
─olvidándose del mecanismo de la selección─, porque calculan la
probabilidad de un cambio de <i>todo o nada</i>: conseguir la cadena
buscada en un tiempo razonable es casi imposible. Repitamos esos
cálculos con nuestro ejemplo:
</p>

<ol class="org-ol">
<li>Elegimos entre 94 genes (caracteres), luego la probabilidad de que
se exprese uno y no otro es de 1/94.</li>
<li>Por tanto, la probabilidad combinada de que aparezcan dos
caracteres determinados será \(1/94 \times 1/94\), el que aparezcan tres
será \(1/94 \times 1/94 \times 1/94 \dots\)</li>
<li><p>
Es decir, la probabilidad de que nuestra cadena aparezca tal cual
están escritos y completamente al azar es de \(1/94^{21}\) o dicho de
otro modo: habrá una posibilidad entre \(94^{21}\), es decir, una
posibilidad entre:
</p>
<pre class="example" id="org4b434b9">
272.699.866.663.574.113.970.678.989.393.688.730.271.744
</pre></li>
</ol>

<p>
Os pido perdón por ser incapaz de leer ese número con soltura... los
billones de billones se quedan cortos y, en teoría, tendríamos que
lanzar los dados todas esas veces para tener una sola oportunidad de
conseguir la frase propuesta. Es como jugar a la lotería, aunque creo
que en la lotería tienes más posibilidades de que toque... Tan ínfima
probabilidad, dicen los creacionistas, hace imposible la aparición
azarosa de organismos complejos<sup><a id="fnr.7" class="footref" href="#fn.7" role="doc-backlink">7</a></sup>. Pero repito, que eso es porque
no conocen, o si lo conocen lo obvian, el <i>algoritmo genético</i>.
</p>

<p>
Para demostrarlo, siguiendo las páginas escritas por <i>Richard
Dawkins</i>, me he hecho un pequeño <i>escript</i><sup><a id="fnr.8" class="footref" href="#fn.8" role="doc-backlink">8</a></sup> que <i>evoluciona
cadenas</i> en el rango de caracteres que dije antes. Lo he hecho correr
varias veces, y el resultado es que encuentra el <i>genoma</i> ─la cadena
buscada─, con entre 3.500 y 10.000 generaciones, iteraciones o
mutaciones, unos pocos segundos de proceso en un ordenador que ha
cumplido ya los 12 años. Incluso en el peor de los casos. Nada que ver
con las cifras calculadas para conseguir toda la cadena de una sola
tirada.
</p>
</div>
</div>
<div id="outline-container-orge4183e3" class="outline-2">
<h2 id="orge4183e3">El código</h2>
<div class="outline-text-2" id="text-orge4183e3">
<p>
Vamos a analizar las distintas partes que intervienen en el algoritmo
y el código que las implementa. Al final pondré todo el código del
programita para que, el que quiera, lo pueda trastear.
</p>
</div>
<div id="outline-container-orgea757aa" class="outline-3">
<h3 id="orgea757aa">Primera generación</h3>
<div class="outline-text-3" id="text-orgea757aa">
<p>
El mecanismo de la selección parte siempre de un organismo ya
existente y consiste en seleccionar aquellos individuos que mejoran o
se adaptan mejor a las circunstancias. No hablo sólo de <i>selección
natural</i> en la que el mecanismo está marcado por la naturaleza, no
sólo para sobrevivir, sino también para tener oportunidad de
reproducirse<sup><a id="fnr.9" class="footref" href="#fn.9" role="doc-backlink">9</a></sup>. Es el mecanismo que el hombre ha utilizado para
seleccionar al perro partiendo de otros cánidos salvajes. Por ello,
debemos partir de nuestra primera cadena y la generamos completamente
al azar:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">primera_generacion</span>(<span style="color: #f8f8f2; font-weight: bold;">Largo</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(<span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">_</span>) -&gt;
                   <span style="color: #8be9fd; font-style: italic;">obtener_caracter_al_azar</span>()
              <span style="color: #ff79c6; font-weight: bold;">end</span>,
              <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(1,<span style="color: #f8f8f2; font-weight: bold;">Largo</span>)).
</pre>
</div>

<p>
Esa función nos devuelve una cadena con el largo que expresa su
parámetro <code>Largo</code>. Como sabéis no hay bucles en <code>erlang</code> y la función
lo que hace es generar una lista secuencial de números del 1 hasta el
<code>Largo</code>: <code>lists:seq(1,Largo)</code>. A partir de ella genera una lista
formada por caracteres al azar.
</p>

<p>
La función <code>obtener_caracter_al_azar/0</code>, en la que se apoya la
anterior es muy sencilla:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">obtener_caracter_al_azar</span>() -&gt;
    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">con valores ASCII entre 32 y 126 al azar
</span>    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Los 94 caracteres imprimibles entre 32 y 126.
</span>    31 + <span style="color: #8be9fd; font-style: italic;">rand</span>:<span style="color: #8be9fd; font-style: italic;">uniform</span>(95).
</pre>
</div>

<p>
En <code>erlang</code> las cadenas son listas de caracteres, ─números enteros, al
fin y al cabo─, así pues, lo que hace es devolver un valor numérico
entre 32 y 126, que son los caracteres que nos hemos dado como <i>genes
básicos</i>.
</p>

<p>
Para generar dicha primera cadena, pues, lo que se hace en el inicio
es llamar a la función <code>primera_generacion/1</code> con la longitud de la
cadena empleada:
</p>

<div class="org-src-container">
<pre class="src src-erlang">Generacion = <span style="color: #8be9fd; font-style: italic;">primera_generacion</span>(<span style="color: #8be9fd; font-style: italic;">length</span>(<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>)),
</pre>
</div>
</div>
</div>
<div id="outline-container-org36a7b46" class="outline-3">
<h3 id="org36a7b46">Evolución</h3>
<div class="outline-text-3" id="text-org36a7b46">
<p>
La función que realiza la evolución tiene dos partes importantes, como
vengo explicando: la modificación azarosa y la selección de los
resultados de esas modificaciones. La he llamado <code>evoluciona/3</code>. Pongo
el código y la explico más despacio después, junto con sus funciones
<i>auxiliares</i>:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">evoluciona</span>(<span style="color: #f8f8f2; font-weight: bold;">Genoma</span>,<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>,<span style="color: #f8f8f2; font-weight: bold;">Generacion</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Valor_Genoma_Inicial</span> = <span style="color: #8be9fd; font-style: italic;">valor_genoma</span>(<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>, <span style="color: #f8f8f2; font-weight: bold;">Genoma</span>),
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Distancia genoma: ~p, genoma: ~p, generaci&#243;n: ~p~n"</span>, [<span style="color: #f8f8f2; font-weight: bold;">Valor_Genoma_Inicial</span>,<span style="color: #f8f8f2; font-weight: bold;">Genoma</span>,<span style="color: #f8f8f2; font-weight: bold;">Generacion</span>]),
    <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">Valor_Genoma_Inicial</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
        0 -&gt;
            <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Soluciona la secuencia del genoma en ~p generaciones.~n"</span>,[<span style="color: #f8f8f2; font-weight: bold;">Generacion</span>]);
       <span style="color: #f8f8f2; font-weight: bold;">_</span> -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">Nuevo_Genoma</span> = <span style="color: #8be9fd; font-style: italic;">mutar_genoma</span>(<span style="color: #f8f8f2; font-weight: bold;">Genoma</span>),
            <span style="color: #f8f8f2; font-weight: bold;">Valor_Genoma_Evolucionado</span> = <span style="color: #8be9fd; font-style: italic;">valor_genoma</span>(<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>, <span style="color: #f8f8f2; font-weight: bold;">Nuevo_Genoma</span>),
            <span style="color: #ff79c6; font-weight: bold;">if</span>
                <span style="color: #f8f8f2; font-weight: bold;">Valor_Genoma_Evolucionado</span> &lt; <span style="color: #f8f8f2; font-weight: bold;">Valor_Genoma_Inicial</span> -&gt;
                    <span style="color: #8be9fd; font-style: italic;">evoluciona</span>(<span style="color: #f8f8f2; font-weight: bold;">Nuevo_Genoma</span>, <span style="color: #f8f8f2; font-weight: bold;">Cadena</span>, <span style="color: #f8f8f2; font-weight: bold;">Generacion</span> + 1);
                true -&gt;
                    <span style="color: #8be9fd; font-style: italic;">evoluciona</span>(<span style="color: #f8f8f2; font-weight: bold;">Genoma</span>, <span style="color: #f8f8f2; font-weight: bold;">Cadena</span>, <span style="color: #f8f8f2; font-weight: bold;">Generacion</span> + 1)
            <span style="color: #ff79c6; font-weight: bold;">end</span>
    <span style="color: #ff79c6; font-weight: bold;">end</span>.
</pre>
</div>

<p>
Los parámetros que recibe son tres:
</p>

<ol class="org-ol">
<li><code>Genoma</code>: La cadena que está evolucionando.</li>
<li><code>Cadena</code>: La cadena de texto original buscada, para poder comparar.</li>
<li><code>Generacion</code>: Un simple contador para saber el número de
generaciones (iteraciones) que se han realizado en el <code>Genoma</code> para
que consiga igualarse a la <code>Cadena</code>.</li>
</ol>

<p>
Para que, tanto evolución como selección, funcionen me apoyo en otras
funciones <i>auxiliares</i>:
</p>

<ol class="org-ol">
<li><p>
Por un lado, necesitamos tener un modo de comparar un <i>genoma</i> con
otro para poder seleccionarlo. El mecanismo es muy básico y se
encuentra en la función <code>valor_genoma/2</code>:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">valor_genoma</span>(<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>,<span style="color: #f8f8f2; font-weight: bold;">Genoma</span>) -&gt;
    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Aprovechamos que en erlang las cadenas son listas de n&#250;meros
</span>    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">que representan los caracteres individuales.
</span>    <span style="color: #f8f8f2; font-weight: bold;">Distancia</span> =
        <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(<span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>) -&gt;
             <span style="color: #f8f8f2; font-weight: bold;">Valor</span> = <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">nth</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>,<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>) - <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">nth</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>,<span style="color: #f8f8f2; font-weight: bold;">Genoma</span>),
             <span style="color: #ff79c6; font-weight: bold;">if</span> <span style="color: #f8f8f2; font-weight: bold;">Valor</span> &lt; 0 -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span><span style="color: #f8f8f2; font-weight: bold;">Valor</span> * -1;
                true -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span><span style="color: #f8f8f2; font-weight: bold;">Valor</span>
             <span style="color: #ff79c6; font-weight: bold;">end</span>
        <span style="color: #ff79c6; font-weight: bold;">end</span>,
        <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(1,<span style="color: #8be9fd; font-style: italic;">length</span>(<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>))),
    <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">sum</span>(<span style="color: #f8f8f2; font-weight: bold;">Distancia</span>).
</pre>
</div>

<p>
Esta función compara las cadenas que recibe como parámetros
<code>Cadena</code> y <code>Genoma</code>. Lo hace carácter a carácter calculando la
distancia numérica entre ellos y después sumando las distancias
individuales. Si la distancia final, o valor del genoma, es <code>0</code>
tendremos que ambas cadenas recibidas son idénticas.
</p></li>
<li><p>
Establecido el criterio de <i>selección</i> en el punto anterior,
también necesitamos algún mecanismo de cambio, o <i>evolución</i>: eso
lo hago con la función <code>mutar_genoma/1</code>:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">mutar_genoma</span>(<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Mutar_gen</span> = <span style="color: #8be9fd; font-style: italic;">rand</span>:<span style="color: #8be9fd; font-style: italic;">uniform</span>(<span style="color: #8be9fd; font-style: italic;">length</span>(<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>)),   <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Mutamos s&#243;lo un gen (caracter) de la cadena
</span>    <span style="color: #f8f8f2; font-weight: bold;">Valor</span> = <span style="color: #8be9fd; font-style: italic;">obtener_caracter_al_azar</span>(),
    {<span style="color: #f8f8f2; font-weight: bold;">Inicio</span>, [<span style="color: #f8f8f2; font-weight: bold;">_</span>|<span style="color: #f8f8f2; font-weight: bold;">Cola</span>]} = <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">split</span>(<span style="color: #f8f8f2; font-weight: bold;">Mutar_gen</span> - 1, <span style="color: #f8f8f2; font-weight: bold;">Cadena</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Inicio</span> ++ [<span style="color: #f8f8f2; font-weight: bold;">Valor</span>|<span style="color: #f8f8f2; font-weight: bold;">Cola</span>].
</pre>
</div>

<p>
Básicamente lo que hace es decidir al azar qué <i>gen</i> se va a mutar,
obtener un valor al azar para ese <i>gen</i> y sustituirlo devolviendo
la cadena resultante.
</p></li>
</ol>

<p>
Como vemos en la función <code>evoluciona/3</code> el programa funciona mientras
el valor del <i>genoma</i> que está siendo <i>evolucionado</i> no sea <code>0</code>.
Cuando alcanzamos el <code>0</code> sabemos que se ha alcanzado la cadena
buscada. Para cualquier otro valor, se obtiene un nuevo genoma y su
correspondiente valor. Si dicho valor se aproxima más a cero que el
valor de la generación anterior, se itera con el <i>nuevo genoma</i> y si
no es así, se itera con el genoma anterior. Por tanto, y para resumir,
el factor de selección consiste en que sólo se cambia el genoma
evolucionado cuando está más cerca del ajuste, o lo que es lo mismo,
más parecida a la cadena propuesta.
</p>
</div>
</div>
<div id="outline-container-org7e9e6f3" class="outline-3">
<h3 id="org7e9e6f3">Disparador del escript</h3>
<div class="outline-text-3" id="text-org7e9e6f3">
<p>
Para lanzar todo el proceso se utiliza, además, un poco de código que,
siendo parte del <i>script</i>, no perteneces realmente al algoritmo, lo
único que aporta es leer la entrada desde la línea de comandos y
correr el resto del código:
</p>

<div class="org-src-container">
<pre class="src src-erlang">#!/usr/bin/env escript
<span style="color: #6272a4;">%% </span><span style="color: #6272a4;">-*- erlang -*-
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">! -smp enable -sname genoma
</span><span style="color: #50fa7b; font-weight: bold;">main</span>([<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>]) -&gt;
    <span style="color: #ff79c6; font-weight: bold;">try</span>
        <span style="color: #f8f8f2; font-weight: bold;">Generacion</span> = <span style="color: #8be9fd; font-style: italic;">primera_generacion</span>(<span style="color: #8be9fd; font-style: italic;">length</span>(<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>)),
        <span style="color: #8be9fd; font-style: italic;">evoluciona</span>(<span style="color: #f8f8f2; font-weight: bold;">Generacion</span>,<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>, 1)
    <span style="color: #ff79c6; font-weight: bold;">catch</span>
        <span style="color: #f8f8f2; font-weight: bold;">_</span>:<span style="color: #f8f8f2; font-weight: bold;">_</span> -&gt;
            <span style="color: #8be9fd; font-style: italic;">uso</span>()
    <span style="color: #ff79c6; font-weight: bold;">end</span>;
<span style="color: #50fa7b; font-weight: bold;">main</span>(<span style="color: #f8f8f2; font-weight: bold;">_</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">uso</span>().

<span style="color: #50fa7b; font-weight: bold;">uso</span>() -&gt;
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Uso: genoma \"cadena de texto\"\nNo se contemplan tildes ni otros caracteres especiales.\n"</span>),
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Los caracteres utilizables deben estar entre los siguientes:~n ~p~n"</span>, [<span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(32,126)]),
    <span style="color: #8be9fd; font-style: italic;">halt</span>(1).
</pre>
</div>

<p>
Como podemos ver, la cabecera establece qué programa debe ejecutar
dicho <i>script</i>:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #6272a4;">#</span><span style="color: #6272a4;">!/usr/bin/</span><span style="color: #ff79c6; font-weight: bold;">env</span><span style="color: #6272a4;"> escript</span>
</pre>
</div>

<p>
Después, las siguientes líneas son parámetros para otros programas.
Concretamente la primera le dice a <i>Emacs</i> que utilice el modo
<code>erlang</code> al editarlo y la segunda establece algunos parámetros para el
intérprete del lenguaje:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">-*- erlang -*-
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">! -smp enable -sname genoma</span>
</pre>
</div>

<p>
El resto del funcionamiento es fácil: la función <code>main/1</code> intenta
generar una primera generación en base a la <code>Cadena</code> que reciba desde
la línea de comandos y luego, evoluciona dicha generación hasta
encontrar, mediante selección, la cadena deseada. Si se produce algún
fallo se mostrará el mensaje de cómo usar el <i>script</i> llamando a la
función <code>uso/0</code>.
</p>
</div>
</div>
<div id="outline-container-org759d48a" class="outline-3">
<h3 id="org759d48a">El código completo</h3>
<div class="outline-text-3" id="text-org759d48a">
<p>
Analizadas las partes, no voy a dar más explicaciones sobre el
<i>script</i>, son 65 líneas de código y pienso que quien haya llegado
hasta aquí es capaz de entenderlo. No he puesto demasiados
comentarios, pues iba a explicar el funcionamiento detalladamente en
el artículo, aunque podéis encontrar algún comentario que no esté
explicado en este texto.
</p>

<div class="org-src-container">
<pre class="src src-erlang">#!/usr/bin/env escript
<span style="color: #6272a4;">%% </span><span style="color: #6272a4;">-*- erlang -*-
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">! -smp enable -sname genoma
</span><span style="color: #50fa7b; font-weight: bold;">main</span>([<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>]) -&gt;
    <span style="color: #ff79c6; font-weight: bold;">try</span>
        <span style="color: #f8f8f2; font-weight: bold;">Generacion</span> = <span style="color: #8be9fd; font-style: italic;">primera_generacion</span>(<span style="color: #8be9fd; font-style: italic;">length</span>(<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>)),
        <span style="color: #8be9fd; font-style: italic;">evoluciona</span>(<span style="color: #f8f8f2; font-weight: bold;">Generacion</span>,<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>, 1)
    <span style="color: #ff79c6; font-weight: bold;">catch</span>
        <span style="color: #f8f8f2; font-weight: bold;">_</span>:<span style="color: #f8f8f2; font-weight: bold;">_</span> -&gt;
            <span style="color: #8be9fd; font-style: italic;">uso</span>()
    <span style="color: #ff79c6; font-weight: bold;">end</span>;
<span style="color: #50fa7b; font-weight: bold;">main</span>(<span style="color: #f8f8f2; font-weight: bold;">_</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">uso</span>().

<span style="color: #50fa7b; font-weight: bold;">uso</span>() -&gt;
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Uso: genoma \"cadena de texto\"\nNo se contemplan tildes ni otros caracteres especiales.\n"</span>),
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Los caracteres utilizables deben estar entre los siguientes:~n ~p~n"</span>, [<span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(32,126)]),
    <span style="color: #8be9fd; font-style: italic;">halt</span>(1).

<span style="color: #50fa7b; font-weight: bold;">valor_genoma</span>(<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>,<span style="color: #f8f8f2; font-weight: bold;">Genoma</span>) -&gt;
    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Aprovechamos que en erlang las cadenas son listas de n&#250;meros
</span>    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">que representan los caracteres individuales.
</span>    <span style="color: #f8f8f2; font-weight: bold;">Distancia</span> =
        <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(<span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>) -&gt;
             <span style="color: #f8f8f2; font-weight: bold;">Valor</span> = <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">nth</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>,<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>) - <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">nth</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>,<span style="color: #f8f8f2; font-weight: bold;">Genoma</span>),
             <span style="color: #ff79c6; font-weight: bold;">if</span> <span style="color: #f8f8f2; font-weight: bold;">Valor</span> &lt; 0 -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span><span style="color: #f8f8f2; font-weight: bold;">Valor</span> * -1;
                true -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span><span style="color: #f8f8f2; font-weight: bold;">Valor</span>
             <span style="color: #ff79c6; font-weight: bold;">end</span>
        <span style="color: #ff79c6; font-weight: bold;">end</span>,
        <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(1,<span style="color: #8be9fd; font-style: italic;">length</span>(<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>))),
    <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">sum</span>(<span style="color: #f8f8f2; font-weight: bold;">Distancia</span>).

<span style="color: #50fa7b; font-weight: bold;">obtener_caracter_al_azar</span>() -&gt;
    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">con valores ASCII entre 32 y 126 al azar
</span>    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Los 94 caracteres imprimibles entre 32 y 126.
</span>    31 + <span style="color: #8be9fd; font-style: italic;">rand</span>:<span style="color: #8be9fd; font-style: italic;">uniform</span>(95).

<span style="color: #50fa7b; font-weight: bold;">mutar_genoma</span>(<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Mutar_gen</span> = <span style="color: #8be9fd; font-style: italic;">rand</span>:<span style="color: #8be9fd; font-style: italic;">uniform</span>(<span style="color: #8be9fd; font-style: italic;">length</span>(<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>)),   <span style="color: #6272a4;">% </span><span style="color: #6272a4;">Mutamos s&#243;lo un gen (caracter) de la cadena
</span>    <span style="color: #f8f8f2; font-weight: bold;">Valor</span> = <span style="color: #8be9fd; font-style: italic;">obtener_caracter_al_azar</span>(),
    {<span style="color: #f8f8f2; font-weight: bold;">Inicio</span>, [<span style="color: #f8f8f2; font-weight: bold;">_</span>|<span style="color: #f8f8f2; font-weight: bold;">Cola</span>]} = <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">split</span>(<span style="color: #f8f8f2; font-weight: bold;">Mutar_gen</span> - 1, <span style="color: #f8f8f2; font-weight: bold;">Cadena</span>),
    <span style="color: #f8f8f2; font-weight: bold;">Inicio</span> ++ [<span style="color: #f8f8f2; font-weight: bold;">Valor</span>|<span style="color: #f8f8f2; font-weight: bold;">Cola</span>].

<span style="color: #50fa7b; font-weight: bold;">primera_generacion</span>(<span style="color: #f8f8f2; font-weight: bold;">Largo</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(<span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">_</span>) -&gt;
                   <span style="color: #8be9fd; font-style: italic;">obtener_caracter_al_azar</span>()
              <span style="color: #ff79c6; font-weight: bold;">end</span>,
              <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">seq</span>(1,<span style="color: #f8f8f2; font-weight: bold;">Largo</span>)).

<span style="color: #50fa7b; font-weight: bold;">evoluciona</span>(<span style="color: #f8f8f2; font-weight: bold;">Genoma</span>,<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>,<span style="color: #f8f8f2; font-weight: bold;">Generacion</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">Valor_Genoma_Inicial</span> = <span style="color: #8be9fd; font-style: italic;">valor_genoma</span>(<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>, <span style="color: #f8f8f2; font-weight: bold;">Genoma</span>),
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Distancia genoma: ~p, genoma: ~p, generaci&#243;n: ~p~n"</span>, [<span style="color: #f8f8f2; font-weight: bold;">Valor_Genoma_Inicial</span>,<span style="color: #f8f8f2; font-weight: bold;">Genoma</span>,<span style="color: #f8f8f2; font-weight: bold;">Generacion</span>]),
    <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">Valor_Genoma_Inicial</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
        0 -&gt;
            <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Soluciona la secuencia del genoma en ~p generaciones.~n"</span>,[<span style="color: #f8f8f2; font-weight: bold;">Generacion</span>]);
       <span style="color: #f8f8f2; font-weight: bold;">_</span> -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">Nuevo_Genoma</span> = <span style="color: #8be9fd; font-style: italic;">mutar_genoma</span>(<span style="color: #f8f8f2; font-weight: bold;">Genoma</span>),
            <span style="color: #f8f8f2; font-weight: bold;">Valor_Genoma_Evolucionado</span> = <span style="color: #8be9fd; font-style: italic;">valor_genoma</span>(<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>, <span style="color: #f8f8f2; font-weight: bold;">Nuevo_Genoma</span>),
            <span style="color: #ff79c6; font-weight: bold;">if</span>
                <span style="color: #f8f8f2; font-weight: bold;">Valor_Genoma_Evolucionado</span> &lt; <span style="color: #f8f8f2; font-weight: bold;">Valor_Genoma_Inicial</span> -&gt;
                    <span style="color: #8be9fd; font-style: italic;">evoluciona</span>(<span style="color: #f8f8f2; font-weight: bold;">Nuevo_Genoma</span>, <span style="color: #f8f8f2; font-weight: bold;">Cadena</span>, <span style="color: #f8f8f2; font-weight: bold;">Generacion</span> + 1);
                true -&gt;
                    <span style="color: #8be9fd; font-style: italic;">evoluciona</span>(<span style="color: #f8f8f2; font-weight: bold;">Genoma</span>, <span style="color: #f8f8f2; font-weight: bold;">Cadena</span>, <span style="color: #f8f8f2; font-weight: bold;">Generacion</span> + 1)
            <span style="color: #ff79c6; font-weight: bold;">end</span>
    <span style="color: #ff79c6; font-weight: bold;">end</span>.
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-orga1b5806" class="outline-2">
<h2 id="orga1b5806">Conclusiones</h2>
<div class="outline-text-2" id="text-orga1b5806">
<p>
Los algoritmos genéticos se basan en un <i>script</i> similar, hecho en los
años 80, por un biólogo que intentaba explicar cómo funciona la
<i>evolución</i>, poniendo un ejemplo del algoritmo que subyace en ese
mecanismo.  Posteriormente, comprendiendo cómo funcionan estos
<i>chismáticos</i>, se han empleado en varias otras disciplinas, ─no sólo
la informática o la programación─, para trabajar sobre la optimización
de distintos procesos.
</p>

<p>
El <i>mecanismo de selección</i> puede ser también engañoso o no tan
optimizado como se espera. Parte siempre de las pequeñas mejoras
obtenidas con anterioridad y así pueden evolucionar también
aproximaciones no óptimas. Por ejemplo, en el libro de Dawkins aparece
el ejemplo del ojo humano. Brevemente explicado: en el ojo de los
mamíferos, nos encontramos los conos y bastones apuntando hacia el
interior del ojo<sup><a id="fnr.10" class="footref" href="#fn.10" role="doc-backlink">10</a></sup>. Por contra, en el ojo de los pulpos nos
encontramos los receptores de luz apuntando hacia afuera. Eso nos dice
que, al menos dos veces, han evolucionado órganos de visión
funcionales.  También, que las soluciones pueden necesitar evolucionar
de forma paralela y no sólo aquellas aproximaciones más cercanas, sino
también es posible que puedan requerir algo de supervisión por parte
del programador que las utiliza y probar con otras ramas evolutivas
<i>prometedoras</i> que a priori no sean tan efectivas pero tengan la
potencialidad de generar un resultado final más óptimo.
</p>

<p>
Desde luego, si intentara conseguir de un sólo golpe azaroso la cadena
propuesta podría estar iterando el intento durante el resto de mi vida
y con casi plena seguridad, no se conseguiría la <i>replicación</i> del
genoma. Sin embargo, utilizando el mecanismo de evolución y selección,
en relativamente pocas generaciones y unos pocos segundos se consigue
la cadena deseada.
</p>

<p>
Evidentemente, si la cadena que introducimos desde la línea de
comandos es más corta implicará menos generaciones y si es más larga
multiplicará las iteraciones necesarias. Sin embargo, siempre son más
asequibles esos procesos que el azar puro.
</p>

<p>
Y con esto y un bizcocho... <i>¡evolucionad, evolucionad, malditos!</i>
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Bueno, según el diccionario de la Real Academia de la Lengua. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Abu Abdallah Muḥammad ibn Mūsā al-Jwārizmī (Abu Yāffar)</i>,
supongo que lo conoceréis u os sonará. Allá por el año 800. Se le
considera el padre del <i>álgebra</i> y le debemos ese término, además del
de <i>algoritmo</i> o <i>guarismo</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
A Turing, supongo que lo conocéis todos. Y aqué <i>Church</i> es el
mismo del <i>cálculo lambda</i>, no una, o la, <i>Iglesia</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Quizá os suene como un activista defensor de la evolución y el
ateísmo enfrentándose al <i>creacionismo</i> y su teoría del <i>diseño
inteligente</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Rirchard Dawkins <i>The blind watchmaker</i>. 1986. Lectura muy
recomendable, si no lo has leído aún.
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
A no ser que te toque <i>la primitiva</i> que algún problema
solucionará, por lo menos lo que se solucionen con dinero: la tontería
no me la quita, pero puestos a elegir prefiero ser tonto con dinero
que tonto sin él.
</p></div></div>

<div class="footdef"><sup><a id="fn.7" class="footnum" href="#fnr.7" role="doc-backlink">7</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En eso tienen razón, pero obvian el mecanismo de selección que
consiste en que el azar sólo interviene en añadir pequeños cambios. Si
el cambio es beneficioso se perpetúa y si no lo es, desaparece.
</p></div></div>

<div class="footdef"><sup><a id="fn.8" class="footnum" href="#fnr.8" role="doc-backlink">8</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
sí, <i>script</i> con <i>e</i>, recordad que <code>escript</code> es la herramienta
de <i>scripting</i> de <code>erlang</code>.
</p></div></div>

<div class="footdef"><sup><a id="fn.9" class="footnum" href="#fnr.9" role="doc-backlink">9</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
La cola y los colores del macho de pavo real lo hacen una presa
más fácil que las hembras, porque tiene llamativos colores y vuela con
dificultad para alejarse de los depredadores. Sin embargo, si la cola
fuera más reducida o menos vistosa, las hembras no lo elegirían como
pareja reproductiva, así pues, el genoma del macho guardara un difícil
equilibrio entre la supervivencia y la posibilidad de reproducción del
individuo. Una optimización imposible de conseguir con azar puro.
</p></div></div>

<div class="footdef"><sup><a id="fn.10" class="footnum" href="#fnr.10" role="doc-backlink">10</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Los sensores de luz apuntando en dirección contraria a la
entrada del estímulo luminoso. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/erlang/index.html">erlang</a> <a href="/tags/algoritmo/index.html">algoritmo</a> <a href="/tags/evolución/index.html">evolución</a> ]]></description>
  <category><![CDATA[erlang]]></category>
  <category><![CDATA[algoritmo]]></category>
  <category><![CDATA[evolución]]></category>
  <link>https://notxor.nueva-actitud.org/2020/10/13/algoritmos-geneticos.html</link>
  <pubDate>Tue, 13 Oct 2020 00:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Reta komunikado]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-10-09</div>
<p>
Kaj tamen mi perseveras en la entrepreno de pli verki esperante kaj
serĉi diversajn temojn por priparoli neformale pri ili. Nun mi esperas
iomete interesigi al la legantaro<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> hodiaŭ per la temo <i>Reta
komunikado</i>. ¿Mi estas spertulo? Ne, tute ne: <a href="https://notxor.nueva-actitud.org/2020/10/04/sen-ideoj-sed-decideme.html">en la pasinta artikolon</a>
mi jam parolis pri mi. Resume: mi estas psikologo, kiu emas
teĥnologion kaj amas Esperanton. Miaj artikoloj nur estas miaj opinioj
kaj, eble ─aŭ certe─ mi povas esti erara. Sed ĉiam mi montros mian
vidpunkton, kiu ne estas dogmo kaj mi volonte ŝanĝiĝos kiam oni
argumente refutis ĝin. Sed, por povi fari tion oni devas alporti
kanalojn kaj ilojn. Certe vi ĉi tion legas rete, do la ilon ne estas
malproksima al vi.
</p>

<p>
Kiam mi komencis ĉi tiun <i>blogon</i> kelkaj jaroj antaŭe mi malfermis
ilon por komenti pri la artikoloj aŭ por sugesti temojn novajn ─aŭ
malnovajn─, sed la tempoj ŝanĝis kaj mi<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> suferis multajn
problemojn: <i>spamo</i>, <i>atakoj per SQL injektado</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>, <i>atako per
injektado de PHP</i><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup> kaj mi, finfine, decidis fermi tiun eblon kaj
komuniki kun la malmultaj homoj kiu legas ĉi tiun blogon rete, sed per
aliaj eksteraj iloj. La tuta retpaĝo estas statika... oni povas legi
ĝin sen ĝavoskripto. Jes, ja, en la paĝo estas iom da ĝavoskripto sed
nur por kelkaj iloj, kiel la <i>sintaksa kolorigado</i> de la programetoj
kiujn mi montras, aŭ la matematikaj formuloj, aŭ aliaj etaj aferoj.
Sed se al vi nur interesas la enhavon, vi povas legi libere sen tiuj
iloj.
</p>

<p>
Pro tio, mi malfermis la eblon de rekta komunikado per la <i>blogo</i> mem
kaj serĉi aliajn ilojn. Tamen, longe antaŭe ol mi prenis tiun decidon
mi jam partoprenis en diversaj sociaj retoj kaj mesaĝaj iloj, kiel
<i>Telegramo</i> aŭ XMPP.
</p>

<p>
Kelkaj aliaj legantoj sugestis forumoj de komentiloj por diversaj
<i>blogoj</i>, sed ili kolektas informojn pri la uzantoj por vendi ilin al
triaj organizoj, precipe grandaj firmaoj. Mi ne etike povas devigi la
legantoj partopreni ĉe tiu retpaĝoj kiu ne respektas la privatecon de
la uzantoj. Do, mi devis malfermi kelkajn aliajn vojojn: ĉu liberaj
retoj, ĉu malliberaj retoj; sed kie la leganto povas elekti kiun vojon
prenu kaj kie enmetas siajn datumojn. La problemo estas la dissemita
informo.
</p>
<div id="outline-container-orga0eec7d" class="outline-2">
<h2 id="orga0eec7d">Federitaj retoj</h2>
<div class="outline-text-2" id="text-orga0eec7d">
<p>
Mi pensas ke vi jam, certe, konas tiujn, kiujn nomiĝas la <i>federitaj
retoj</i>. Per alia nomo ankaŭ <i>fedeverso</i><sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>. Ja, mi, de longe
antaŭe, havis malferman konton ĉe <a href="https://diasp.org/people/15172490a88f01339a3f782bcb452bd5"><i>diaspora</i></a> aŭ <a href="https://mastodon.madrid/web/accounts/5588"><i>Mastodon</i></a>, kaj nun,
ankaŭ ĉe <a href="https://pleroma.hatthieves.es/Notxor"><i>Pleroma</i></a>. Tiuj kontoj mi povas profiti por komunikado.  Sed
lasu al mi priparoli iomete pri la <i>fedeverso</i>. Eble, vi bone konas
tiujn retojn, sed eble kelkaj el la legantoj ne konas ilin.
</p>

<p>
La kutimaj retoj, sociaj retoj, kiuj vi trovas tra la Interreto estas
centralaj retojn kiuj apartenas al granda firmao. Tiuj retoj kolektis
ĉiujn uzantoj en grandajn servilojn, tiele oni nomas ilin kiel
<i>centrigitaj retoj</i>. Kontraŭe, la <i>federitaj retoj</i> estis reto de etaj
nodoj interkomunikataj. Imagu se vi kolektas la homoj en granda urbo
aŭ en etaj vilaĝoj: la granda urbo havas grandajn enajn komunikilojn,
sed ne tiel bone eksterajn. La <i>fedeverso</i> kontraŭe bazas ĝian forton
pri la komunikado de la diversaj nodoj: ne gravas kie vi loĝas, vi
povas komuniki rete kun aliaj homoj tra la mondo, same, ne gravas kiun
nodon vi uzas, vi povas sekvi ─kaj estu sekvita─ pro (de) homoj de
ĉiuj aliaj nodoj<sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup>. La filozofio tra tiuj retoj estas ke ĉiu homo
povus elstari nodon, ─sian propran personan nodon, se oni volas─, kaj
komuniki kun la cetera mondo. Certe, ne ĉiu homo faras tion, precipe
oni konektiĝis al nodo jam disponigita de aliaj homoj. Ekzemple, mi
estas en <i>mastodona</i> nodo kiu nomiĝas <a href="https://mastodon.madrid">mastodon.madrid</a>. Tiu elstaris la
amiko <i>Fanta</i> kaj petis al mi por estu <i>moderiganto</i> de tiu nodo, kaj
mi akceptis. Nun tiu <i>vilaĝo</i> havas 400 loĝantoj, 60 el ili, pli
aktivaj, kaj apenaŭ mi devas kontroli aferojn.
</p>

<p>
Tiuj retoj estas pli afabla ol la kutimaj retoj. La homoj pli bone
kondutas kaj estas malpli malamanta ol ĉe Tvitero, ekzemple. Ankaŭ se
vi volas estas esperanta nodo: <a href="https://esperanto.masto.host/about">esperanto.masto.host</a> kun loĝantaro de
pli ol 500 homoj kaj 100 plene aktivaj. Mi sekvas kontojn de tiu nodo,
kaj kelkaj konto el tie sekvas min, malgraŭ ke ni estas en malsamaj
nodoj.
</p>
</div>
</div>
<div id="outline-container-orge279d7d" class="outline-2">
<h2 id="orge279d7d">Ne libera reto</h2>
<div class="outline-text-2" id="text-orge279d7d">
<p>
Kiel <i>ne libera reto</i> mi nur uzas <i>Telegramon</i>. Mi partoprenas ĉe
diversajn esperantajn grupojn; plej dirita: mi estas en tiuj grupoj,
ĉar mi malmulte skribas kutime. Ankaŭ, ne estas bona ideo komenti la
artikolojn de ĉi tiu <i>blogo</i> en tiuj grupojn: ne apartenas al mi, la
kreintoj havis aliajn celojn kaj ni povas perturbi la pacan
komunikadon inter la uzantoj.
</p>

<p>
Kelkaj monatoj antaŭe mi kreis grupon <a href="https://t.me/notxorblog">por ĉi tiu blogo</a> en
<i>Telegramo</i>. Estas eta grupo, malpli ol 60 partoprenantoj, kaj ni
precipe skribas en la hispana pri teĥnikaj aferoj. Sed mi scias ke
kelkaj el ili ankaŭ estas esperantistoj. Tiu grupo povas esti pli bona
loko kie ni povas komenti la artikolojn aŭ sugesti aliajn temojn.
</p>

<p>
Anstataŭe, se vi uzas <i>XMPP konton</i> vi ankaŭ povas eniri ĉe la <i>salo</i>:
<code>esperanto@salas.suchat.org</code>, mi kreis tiun salon longe antaŭe kaj
estas loĝita precipe de silentaj homoj, sed ĉiuj esperantistoj... eble
komenti la artikolojn de la <i>blogo</i> tie povus revivigi la salon.
</p>
</div>
</div>
<div id="outline-container-org6a345db" class="outline-2">
<h2 id="org6a345db">Konkludoj</h2>
<div class="outline-text-2" id="text-org6a345db">
<p>
Finfine, la celo estas havi informon pri la pensojn, ŝatojn kaj
sugestojn de la (eblaj) legantoj. Mi ne esperas multaj partoprenantoj
en tiuj iloj, sed mi proponas la antaŭajn manierojn por konekti min al
vi kaj interparoli rekte.
</p>

<p>
Vi havas liberajn kaj ne liberajn iloj por komenti la artikolojn.
Certe, estus pli bone, se ni povus fari ĝin rekte ĉe la sama paĝon kaj
havi kune la artikolon kaj ĝian respondon, sed ne eblas.
</p>

<p>
La venonta artikolo mi priparolos pri diversajn projektojn (miajn):
esperantaj kaj ne esperantaj, kelkaj el ili povus esti malfermaj al
kunlaboro aŭ helpo.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Jes, ĝi estos aro da du, paro estas <i>aro</i>: mi kaj eble kelka amiko :-). 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Bone, mi ne, la <i>blogon</i> sed mi suferis kiel responsulo.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ĉi tiuj estis vanaj atakoj, mi ne uzas datumbazon SQL.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ĉi tiuj estis pli seriozaj, la ilo estas PHP farita.
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Federacia Universo</i>, en la hispana «fediverso» aŭ en la angla
«fediverse».
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ne tiel klare, ĉar nodo povas bloki nodon pro diversaj kialoj,
sed tiu povas esti temo por alia artikolo ─aŭ serio de artikoloj─,
parolante pri libereco kaj ĝiaj limoj.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/komunikado/index.html">komunikado</a> <a href="/tags/blogo/index.html">blogo</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[komunikado]]></category>
  <category><![CDATA[blogo]]></category>
  <link>https://notxor.nueva-actitud.org/2020/10/09/reta-komunikado.html</link>
  <pubDate>Fri, 09 Oct 2020 22:34:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Entendiendo las funciones recursivas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-10-09</div>
<p>
Me vais a perdonar si dedico un artículo a un amigo que me pregunta
dudas. A su edad, que es muy cercana a la mía, le ha entrado de nuevo
el gusanillo de aprender a programar. Cuenta con algo de experiencia
de sus años mozos cuando hizo algún curso de <i>BASIC</i>, lenguaje que
afortunadamente, con el transcurso de los años ha olvidado
completamente<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. A estas alturas de la movida ha decidido echarle
un esfuerzo al <i>Python</i> con un par de libros que yo mismo le
recomendé.
</p>

<p>
El caso es que mi colega me preguntó sobre las funciones recursivas y
que para qué servían si ya hay <i>bucles</i>. Además se lía con ellas y
algún intento le ha salido rana entrando en bucle infinito. Decirle
que <i>las funciones recursivas son el martillo que clava el clavo del
procesamiento de listas</i> es una licencia poética pero no le explica
mucho. Le indiqué que <a href="https://notxor.nueva-actitud.org/2019/01/24/funciones-recursivas.html">ya hablé sobre ellas en este mismo <i>blog</i></a> hace
más de un año, pero utilizaba para la explicación <i>Lisp</i> y dice que se
lía con tanto paréntesis.
</p>

<p>
Con toda esta introducción no quiero informar más que, es posible, si
ya eres programador, o si ya leíste ese otro artículo, que el resto
del artículo te aburra, no son más que las explicaciones que le voy a
dar a alguien que está empezando con la programación sobre el tema de
la <i>recursión</i> o como dice él: <i>de esas funciones que se llaman a sí
mismas y son un puto lío</i>.
</p>

<p>
El movimiento se demuestra andando vamos a ello y como el <i>Python</i> lo
tengo un poco oxidado, te lo voy a explicar con <i>erlang</i>, que es otro
lenguaje, pero los principios son los mismos. Las idiosincrasias del
lenguaje intentaré explicarlas sobre la marcha.
</p>
<div id="outline-container-orgd3d2534" class="outline-2">
<h2 id="orgd3d2534">Función recursiva básica</h2>
<div class="outline-text-2" id="text-orgd3d2534">
<p>
Una función recursiva es una función que se llama a sí misma... las
dudas que se le plantean al programador es ¿cuándo y cómo se paran?
La respuesta fácil es <i>poniendo una condición</i>, exactamente igual que
en un bucle. Poner mal una condición en un bucle acarrea los mismos
efectos que poner mal una condición en una función recursiva, <i>los
mismos</i>: repetición infinita, sobrecarga de la memoria y el
procesador, en fin, un completo desastre.
</p>

<p>
Por poner un ejemplo, voy a poner el código en <code>erlang</code> que calcula el
factorial de un número... El mismo ejemplo que te puedes encontrar en
<i>siene' y siene'</i> de libros sobre cualquier lenguaje cuando se
explican las funciones recursivas, no voy a ser original en ésto.
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">factorial</span>(<span style="color: #f8f8f2; font-weight: bold;">X</span>) -&gt;
    <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">X</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
      0 -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span>1;
      <span style="color: #f8f8f2; font-weight: bold;">X</span> -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span><span style="color: #f8f8f2; font-weight: bold;">X</span> * <span style="color: #8be9fd; font-style: italic;">factorial</span>(<span style="color: #f8f8f2; font-weight: bold;">X</span>-1)
    <span style="color: #ff79c6; font-weight: bold;">end</span>.
</pre>
</div>

<p>
Son cinco líneas fáciles de entender:
</p>

<ol class="org-ol">
<li>Definición de la función con el nombre <code>factorial</code> que recibe un
sólo parámetro <code>X</code>. Los caracteres <code>-&gt;</code> indican que a partir de ahí
comienza el <i>cuerpo</i> de la función que finaliza en el carácter <code>.</code>.</li>
<li>La siguiente línea utiliza la estructura <code>case ... of</code> que es
idéntica a la <code>switch...case</code> a la que estás acostumbrado. Se le
pone el parámetro <code>X</code> para que compruebe su contenido.</li>
<li>En este caso el contenido es <code>0</code> y es importante entender que ésta
es la condición de escape de la recursión. Si hubiéramos hecho una
función con bucle, seguramente sería algo como <code>while (X!=0)</code>. Los
caracteres <code>-&gt;</code> indican el cuerpo de la condición, que en nuestro
caso se limita a devolver <code>1</code> y el cuerpo de la condición finaliza
con el carácter <code>;</code>.</li>
<li>En esta línea se contempla el <i>caso</i> para cualquier valor de <code>X</code>.
También tiene su bloque de código. En este caso se le pide que
multiplique <code>X</code> por el resultado de <code>factorial</code> pasándole el valor
de <code>X-1</code>. Esta es la línea que hace la recursión y actualiza el
contador a la vez. En una función con bucle, tienes que actualizar
el valor del índice también.</li>
<li>Línea de finalización del bloque de código. Si te fijas, en la
línea anterior no pusimos <code>;</code> y eso es porque al terminar con <code>end</code>
el <code>case...of</code> acaba también el bloque anterior. Por último, como
dije antes el <code>.</code> finaliza la definición del bloque de código de la
función.</li>
</ol>

<p>
Una forma más simplificada de la función sería:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">factorial</span>(0) -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span>1;
<span style="color: #50fa7b; font-weight: bold;">factorial</span>(<span style="color: #f8f8f2; font-weight: bold;">X</span>) -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span><span style="color: #f8f8f2; font-weight: bold;">X</span> * <span style="color: #8be9fd; font-style: italic;">factorial</span>(<span style="color: #f8f8f2; font-weight: bold;">X</span>-1).
</pre>
</div>

<p>
Una de las idiosincrasias de <code>erlang</code> que nos proporciona una sintaxis
más cercana a las condiciones como se expresan en matemáticas, cuando
veíamos teoremas y similares y nos decían cosas tan bonitas como:
<i>Para todo <code>x</code> igual 0</i> y perlas similares. Aunque en este caso
tendríamos que aplicarnos la definición de <i>para todo <code>X</code>, cuando <code>X</code>
es mayor que 0</i>... porque no hay factoriales de números negativos. La
cosa quedaría así.
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">factorial</span>(0) -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span>1;
<span style="color: #50fa7b; font-weight: bold;">factorial</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>) <span style="color: #ff79c6; font-weight: bold;">when</span> <span style="color: #f8f8f2; font-weight: bold;">N</span> &gt; 0 -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span><span style="color: #f8f8f2; font-weight: bold;">N</span> * <span style="color: #8be9fd; font-style: italic;">factorial</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>-1).
</pre>
</div>

<p>
Pero bueno, estos son cosas del <code>erlang</code>. En <code>Pyton</code> lo solucionarías
con un <code>if</code>. Explico esto, para se entienda mejor el siguiente
apartado, porque esta forma de definir funciones y comprobar qué
parámetros le llegan es una idiosincrasia del lenguaje.
</p>
</div>
</div>
<div id="outline-container-org163870d" class="outline-2">
<h2 id="org163870d">Recursión con función auxiliar</h2>
<div class="outline-text-2" id="text-org163870d">
<p>
Hay otra forma de recursión que se utiliza para simplificar
condiciones y aplanar el espacio de memoria y proceso que conlleva la
recursión. Lo que hace es contar el número de veces que aparece un
elemento en una lista. Por poner un ejemplo real, voy a poner aquí
código que hice para resolver un problema para un programa que estoy
haciendo:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">--------------------------------------------------------------------
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">@doc
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Dada una Lista de elementos, cuenta el n&#250;mero de veces que aparece
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">y devuelve una lista de tuplas ordenada de mayor a menor n&#250;mero de
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">apariciones, donde cada elemento de la tupla consta de dos
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">elementos, el primero es el valor buscado de la Lista original y el
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">segundo el n&#250;mero de veces que aparece en ella.
</span><span style="color: #6272a4;">%% </span><span style="color: #6272a4;">@end
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">--------------------------------------------------------------------
</span><span style="color: #50fa7b; font-weight: bold;">contar_elementos</span>(<span style="color: #f8f8f2; font-weight: bold;">Lista</span>) -&gt;
    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Nos apoyamos en la funci&#243;n recursiva contar_elementos/2
</span>    <span style="color: #8be9fd; font-style: italic;">contar_elementos</span>(<span style="color: #f8f8f2; font-weight: bold;">Lista</span>, #{}).

<span style="color: #50fa7b; font-weight: bold;">contar_elementos</span>([<span style="color: #f8f8f2; font-weight: bold;">H</span>|<span style="color: #f8f8f2; font-weight: bold;">T</span>], <span style="color: #f8f8f2; font-weight: bold;">X</span>) -&gt;
    <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #8be9fd; font-style: italic;">maps</span>:<span style="color: #8be9fd; font-style: italic;">is_key</span>(<span style="color: #f8f8f2; font-weight: bold;">H</span>,<span style="color: #f8f8f2; font-weight: bold;">X</span>) <span style="color: #ff79c6; font-weight: bold;">of</span>
        true -&gt;
            <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Si el elemento H existe en X suma 1 a su valor
</span>            <span style="color: #8be9fd; font-style: italic;">contar_elementos</span>(<span style="color: #f8f8f2; font-weight: bold;">T</span>, <span style="color: #8be9fd; font-style: italic;">maps</span>:<span style="color: #8be9fd; font-style: italic;">put</span>(<span style="color: #f8f8f2; font-weight: bold;">H</span>, <span style="color: #8be9fd; font-style: italic;">maps</span>:<span style="color: #8be9fd; font-style: italic;">get</span>(<span style="color: #f8f8f2; font-weight: bold;">H</span>,<span style="color: #f8f8f2; font-weight: bold;">X</span>) + 1, <span style="color: #f8f8f2; font-weight: bold;">X</span>));
        false -&gt;
            <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Si el elemento H no existe en X lo crea con valor 1
</span>            <span style="color: #8be9fd; font-style: italic;">contar_elementos</span>(<span style="color: #f8f8f2; font-weight: bold;">T</span>, <span style="color: #8be9fd; font-style: italic;">maps</span>:<span style="color: #8be9fd; font-style: italic;">put</span>(<span style="color: #f8f8f2; font-weight: bold;">H</span>, 1, <span style="color: #f8f8f2; font-weight: bold;">X</span>))
    <span style="color: #ff79c6; font-weight: bold;">end</span>;
<span style="color: #50fa7b; font-weight: bold;">contar_elementos</span>([],<span style="color: #f8f8f2; font-weight: bold;">X</span>) -&gt;
    <span style="color: #6272a4;">%% </span><span style="color: #6272a4;">Si no hay m&#225;s elementos convierte X en lista y la ordena
</span>    <span style="color: #f8f8f2; font-weight: bold;">R</span> = <span style="color: #8be9fd; font-style: italic;">maps</span>:<span style="color: #8be9fd; font-style: italic;">to_list</span>(<span style="color: #f8f8f2; font-weight: bold;">X</span>),
    <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">sort</span>(
      <span style="color: #ff79c6; font-weight: bold;">fun</span>({<span style="color: #f8f8f2; font-weight: bold;">_</span>,<span style="color: #f8f8f2; font-weight: bold;">N</span>},{<span style="color: #f8f8f2; font-weight: bold;">_</span>,<span style="color: #f8f8f2; font-weight: bold;">M</span>}) -&gt;
              <span style="color: #f8f8f2; font-weight: bold;">N</span> &gt; <span style="color: #f8f8f2; font-weight: bold;">M</span>
      <span style="color: #ff79c6; font-weight: bold;">end</span>,
      <span style="color: #f8f8f2; font-weight: bold;">R</span>).
</pre>
</div>

<p>
En la sintaxis de <code>erlang</code> son dos funciones distintas:
<code>contar_elementos/1</code> y <code>contar_elementos/2</code>, es decir, una función
recibe un parámetro y otra función ─con el mismo nombre─ recibe dos
parámetros y son funciones completamente distintas. La primera termina
en un <code>.</code> tras llamar a la segunda, que tiene dos partes, o dos
condiciones, o dos casos. Es decir, la primera utiliza una función
recursiva como función auxiliar para hacer su trabajo. Y como es un
ejemplo de la vida real, aunque sea corto, hay tela que cortar:
</p>

<dl class="org-dl">
<dt><code>cortar_elementos(Lista, #{})</code></dt><dd>Esta línea hace la llamada. Como
se puede ver le pasa a la función auxiliar la <code>Lista</code> que ha
recibido y un elemento que podemos llamar <i>acumulador</i>: <code>#{}</code>. Ese
símbolo equivale a pasar un <code>map</code> vacío. En <code>Python</code> se llaman
<i>diccionarios</i>. La utilidad de éste parámetro es ir guardando los
resultados del procesamiento de la lista.</dd>
<dt><code>contar_elementos([H|T],X) -&gt;</code></dt><dd>Definición de la función
<code>contar_elementos/2</code> para el caso en que llega una lista (<code>[H|T]</code>) y
<code>X</code> como parámetros. <code>[H|T]</code>. Todo lo que va entre los caracteres
<code>[...]</code> definen una lista<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. En este caso dividida en las partes
<code>H</code> y <code>T</code><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>. Es decir, que definiendo así la entrada, en
realidad me aprovecho de tres parámetros aunque la función reciba
sólo dos, porque troceo el primero.</dd>
<dt><code>case maps:is_key(H,X) of</code></dt><dd>Aprovecha el troceamiento que hemos
hecho de la lista al llegar y lo que hace es utilizar una función de
los <code>maps</code> que nos dice si una clave <code>H</code> está en una lista <code>X</code>. Los
valores que devuelve son sí o no: <code>true</code> o <code>false</code>. Por eso en el
case hay dos bloques de código, uno para cada una de las respuestas
posibles.
<ul class="org-ul">
<li><p>
<code>contar_elementos(T, maps:put(H, maps:get(H,X) + 1, X));</code>:
Quizá te resulte más claro si lo hacemos por partes:
</p>
<div class="org-src-container">
<pre class="src src-erlang">Valor = <span style="color: #8be9fd; font-style: italic;">maps_get</span>(<span style="color: #f8f8f2; font-weight: bold;">H</span>,<span style="color: #f8f8f2; font-weight: bold;">X</span>),
<span style="color: #f8f8f2; font-weight: bold;">Diccionario_actualizado</span> = <span style="color: #8be9fd; font-style: italic;">maps</span>:<span style="color: #8be9fd; font-style: italic;">put</span>(<span style="color: #f8f8f2; font-weight: bold;">H</span>, <span style="color: #f8f8f2; font-weight: bold;">Valor</span>+1, <span style="color: #f8f8f2; font-weight: bold;">X</span>),
<span style="color: #50fa7b; font-weight: bold;">contar_elementos</span>(<span style="color: #f8f8f2; font-weight: bold;">T</span>, <span style="color: #f8f8f2; font-weight: bold;">Diccionario_actualizado</span>);
</pre>
</div>
<p>
Es decir, toma el <code>Valor</code> existente, obtiene un diccionario
actualizado sumándole <code>1</code> al Valor asociado a la clave <code>H</code> y llama
de nuevo a la función con el resto de elementos de la lista <code>T</code> y
dicho <i>diccionario actualizado</i>.
</p></li>
<li><p>
<code>contar_elementos(T, maps:put(H, 1, X))</code>:
Básicamente es lo mismo pero en este caso, como no se ha
encontrado el elemento de clave <code>H</code> lo que se hace es crearlo con
el valor <code>1</code>... lo podríamos separar también como:
</p>
<div class="org-src-container">
<pre class="src src-erlang">Diccionario_actualizado = <span style="color: #8be9fd; font-style: italic;">maps</span>:<span style="color: #8be9fd; font-style: italic;">put</span>(<span style="color: #f8f8f2; font-weight: bold;">H</span>,1,<span style="color: #f8f8f2; font-weight: bold;">X</span>),
<span style="color: #50fa7b; font-weight: bold;">contar_elementos</span>(<span style="color: #f8f8f2; font-weight: bold;">T</span>, <span style="color: #f8f8f2; font-weight: bold;">Diccionario_actualizado</span>)
</pre>
</div></li>
</ul></dd>

<dt><code>contar_elementos([],X) -&gt;</code></dt><dd>La segunda parte de la definición de
la función: cuando la lista se ha vaciado... (parámetro <code>[]</code>, lista
vacía). Es decir, hemos alcanzado el final de la lista, no hay más
elementos en la <i>cola</i> para procesar. La forma directa hubiera sido
devolver <code>X</code> y hemos terminado. Sin embargo, me faltaban un par de
detalles por hacer: convertir el diccionario en una lista y
devolverla ordenada de mayor a menor.</dd>
<dt><code>R = maps:to_list(X),</code></dt><dd>Es una función de la librería de <code>maps</code> de
<code>erlang</code> que devuelve una <i>lista</i> a partir de un <i>map</i> o
<i>diccionario</i>.</dd>

<dt>(no term)</dt><dd><p>
Ordenar la lista y las funciones <code>lambda</code>:: El siguiente bloque de
código ordena la lista que obtuvimos en el paso anterior:
</p>
<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">sort</span>(
  <span style="color: #ff79c6; font-weight: bold;">fun</span>({<span style="color: #f8f8f2; font-weight: bold;">_</span>,<span style="color: #f8f8f2; font-weight: bold;">N</span>},{<span style="color: #f8f8f2; font-weight: bold;">_</span>,<span style="color: #f8f8f2; font-weight: bold;">M</span>}) -&gt;
          <span style="color: #f8f8f2; font-weight: bold;">N</span> &gt; <span style="color: #f8f8f2; font-weight: bold;">M</span>
  <span style="color: #ff79c6; font-weight: bold;">end</span>,
  <span style="color: #f8f8f2; font-weight: bold;">R</span>).
</pre>
</div>
<p>
Utilizamos la función <code>sort</code> de la librería <code>lists</code> de <code>erlang</code>.
Esta función ordena una lista tomando como parámetro una función que
determina qué elemento es mayor (o menor, según nos interese el
orden) que otro. En este caso está definida dentro de la propia
llamada al más puro estilo <code>lambda</code> de lenguajes como <code>Lisp</code>,
<code>scheme</code> y también las encontrarás (si no las has visto ya) en
<code>Python</code>. En este caso indica que dados dos grupos de datos formados
por tuplas del estilo <code>{Índice, Valor}</code>, será mayor la que posea un
<code>Valor</code> mayor... el carácter <code>_</code> le indica a <code>erlang</code> que hay algo,
pero que puede ignorarlo porque no es relevante.
</p></dd>
</dl>
</div>
</div>
<div id="outline-container-orge515a23" class="outline-2">
<h2 id="orge515a23">Alejándonos de la sintaxis para ver los conceptos</h2>
<div class="outline-text-2" id="text-orge515a23">
<p>
Quizá te hayas perdido en las explicaciones sintácticas. Necesitamos
un resumen de lo que viene a ser el tema recursivo sobre las listas.
Veamos un ejemplo alejado de la programación.
</p>

<p>
Hace años se vendían las legumbres al peso... ibas a la tienda de
ultramarinos pedías lentejas y el dependiente salía con una paleta,
hacía un cucurucho de papel y lo llenaba con las lentejas que cogía de
un saco de bordes que habían enrollado hasta que se pudiera ver el
género. <i>¡Lentejas pardinas de calidad, señora!</i>... El caso es que
llegaba un momento en que querías comértelas y lo habitual es que
hubiera que limpiarlas: quitar piedrecitas, ramitas y otros elementos
extraños a lo que vienen siendo las lentejas, propiamente dichas.
</p>

<p>
Como puedes imaginar, en este ejemplo nuestra <i>lista</i> es el montón de
lentejas que tenemos recién comprado y ahora vamos a procesarla:
cogemos un elemento del montón, si es una piedra o elemento extraño va
al montón de la <i>basura</i>, si es una lenteja va al montón de las
<i>lentejas limpias</i>. Proceso repetitivo que se ajusta a nuestros
parámetros de <i>cabeza</i> y <i>cola</i>: tomamos un elemento, decidimos sobre
su naturaleza y repetimos.
</p>

<p>
Con el procesamiento de listas es sencilla esa recursión de <i>cabeza</i> y
<i>cola</i>. Ahora imagina que en el ejemplo anterior de la lista de
números, hubiéramos cogido el sistema de coger el número y compararlo
con el resto de los valores de la lista para contar cuántos hay. Sería
como coger una lenteja (o piedra) y compararla con el resto de
elementos del montón antes de llevarlo a su sitio. Si hay 500 lentejas
tendrías que repasar el montón 499 veces cada vez... un procesamiento
ineficiente. Por eso, cuando limpiamos lentejas repasamos el montón
sólo una vez.
</p>
</div>
</div>
<div id="outline-container-orgd63d358" class="outline-2">
<h2 id="orgd63d358">Conclusiones</h2>
<div class="outline-text-2" id="text-orgd63d358">
<p>
No hay que asustarse con este tipo de funciones.
</p>

<p>
Repasar un montón de elementos se puede hacer de dos maneras:
recursiva o repetitivamente. En realidad, ambas, repasan todo el
montón, desde la primera lenteja a la última. Tienes que recodar que
repasar el montón con cada lenteja es tontería y lo demás es
secundario. Elegir un método u otro depende también del lenguaje y de
las costumbres del programador. Además, como digo siempre, si funciona
está bien y si lo hace rápido es excelente. Lo de la <i>elegancia</i> del
código siempre es una apreciación subjetiva.
</p>

<p>
Recuerda, las estructuras para hacer una reiteración o para hacer una
recursión son las mismas: una variable donde guardar los
cálculos<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>, un contador o una condición de final y en cada vuelta
hay que actualizar el contador. En el caso especial de la lista, el
contador son los mismos valores de la lista, por el mecanismo <i>cabeza</i>
y <i>cola</i>.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
No recuerdo quién dijo que quien aprende a programar en <code>BASIC</code>
es totalmente irrecuperable para la programación. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Igual que antes vimos que los caracteres <code>#{...}</code> definen un
<code>map</code> o diccionario. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Tradicionalmente se utilizan los nombres en inglés <i>Head</i> y
<i>Tail</i>. Cabeza y cola en español tienen la misma inicial y utilizar
<i>cabeza</i> y <i>rabo</i> implica <i>el que llevo aquí colgado</i>, (ya tu shabe').
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
en el caso del ejemplo del factorial lo que se utiliza es el
estado de cada llamada, cuando se resuelve la última se produce un
arrastre en cascada del valor y por eso no hay variable.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/programación/index.html">programación</a> <a href="/tags/erlang/index.html">erlang</a> ]]></description>
  <category><![CDATA[programación]]></category>
  <category><![CDATA[erlang]]></category>
  <link>https://notxor.nueva-actitud.org/2020/10/09/entendiendo-las-funciones-recursivas.html</link>
  <pubDate>Fri, 09 Oct 2020 09:52:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Sen ideoj, sed decideme]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-10-04</div>
<p>
Mi decidis verki <i>blogon</i> esperante. Bone, ne tiel, ĝi estus nur parto
de mian <i>blogon</i> precipe verkita en la hispana.  Eble mi skribas
nesufiĉe en ĉi tiu <i>blogon</i> esperante. Mi pensis de longe antaŭe
tion... mi volas korekti tiun aferon kaj finfine mi devigas min
skribi. La problemo, la precipa problemo, estas la mankon de temoj:
pri kion mi povas skribi? Kio povas interesi la homoj, ─la malmultaj
homoj─, kiuj povas alveni al ĉi tiu loko? Mi ne povas respondi ion
klaran al mi. Do mi faros tiel, kiel mi faris en la hispanaj
artikoloj: mi skribos pri tiuj diversaj aferoj, kiuj interesas min,
kaj mi esperas ke, eble, al iu ajn interesus ankaŭ. Al mi enuas legi
esperante nur pri <i>Esperanto</i> aŭ nur por politiko. Kaj mi esperas
trovi aliajn temojn. Mi nur volas konstati mian mankon de interesaj
temoj por priparoli esperante.
</p>

<p>
La pasintaj semajnoj mi jam skribis kelkan artikolon esperante. Vi
povas trovi ilin en ĉi tiu loko, ne tre diste de ĉi tiu skribaĵo. Sed,
por bone komenci la entreprenon, mi pensis ke, eble, vi ne sufiĉe
konas min kaj mi devas prezenti min kiel eble:
</p>

<p>
Mi estas <i>Notxor</i>. Certe, kiel vi imagas, tiu alianomo ne estas mian
veran nomon, sed preskaŭ: de multe antaŭe, tiel rete, kiel en aliaj
lokoj, oni konas min per tiu nomo. Kaj kiam mi diris <i>de multe
antaŭe</i>, mi signifas pli ol dudek jarojn kaj, por kelkaj homoj kiu
povas legi tion, tiu kvanto da jaroj povas esti tuta sia vivo. Do, ĝi
estas kiel mian propran nomon. Ja, mi adoptis ĝin kiel propra kaj mi
konscias pri la ebleco de trovi amikojn, kiuj ne konas mian veran
nomon... jes, malmultaj, sed ili estas.
</p>

<p>
Pri mia aferoj plej interesaj mi povas diri ke mi estas psiĥologo,
klinika psiĥologo, kaj ankaŭ enamigita de teĥnologio. Se vi tralegas
la hispanajn artikolojn en ĉi tiu <i>blogo</i> vi trovas pli skribaĵojn pri
komputilaj aferoj ol pri tiuj psiĥologiaj temoj. Sed precipe, ne pri
la lastaj teĥnologioj: mi estas <i>aĝulo</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> kaj mi amas ilojn kiel
<i>Emakso</i>, <i>Lispo</i>, <i>skemo</i>, ktp.<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>, aŭ tiuj kiuj permesas min
labori sen duumaj datumaranĝoj. Mi tiel, programas miajn proprajn
ilojn por labori kiel psiĥologo, korekti psiĥologiajn provojn kaj
lastatempe mi faras tion per <i>erlang</i>. Mia edzino diras ke <i>mi ŝatas
tion, kion neniu uzas</i>. Eble ŝi ne ŝveligis la aferon kaj ne tro
eraras ŝi. Sed mi amas la simplecon de la malnovaj programaj lingvoj
tiel, kiel <i>lisp</i> aŭ <i>smalltalk</i> kaj la efiko de <i>GNU/linukso</i>; do,
nek la plej uzataj lingvoj nek la plej uzata operaciumo. Ankaŭ mi
ŝatas paroli pri tiuj iloj kaj skribi pri miajn malkovrojn kaj miajn
ilojn.
</p>

<p>
Aliflanke, nek profesie nek ŝatokupe, mi ankaŭ kunlaboras kun Asocio
PICA<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> kiel psiĥologo kaj volontulo. Mi instruas aliajn
volontulojn pri homaj enhavoj kaj por pritakti kun specialaj infanoj
kaj iliaj familioj. Ankaŭ, mi laboras en la prevento de ĉikanado en la
lernejoj kaj ankaŭ desegnas programoj kontraŭ la ekskludo de diversaj
aroj. Finfine, mi partoprenas en ĉiu agado de la Asocio kie mi povas
kontribui per mia kono aŭ per mia agado.
</p>

<p>
Mia lasta projekto kunigis mian profesion kun mia ŝatokupo. Por nova
programo por la prevento de la ĉikanado en la lernejoj, mi programas
MUD<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup> aŭ plej bone dirita, ion similan al tiu, kiu estas MUD. Oni
devas scii ke multaj el tiuj preventaj programoj, kiuj ni laboris
antaŭe konsistas en rakonto (filmorakonto aŭ bildrakonto) kiu montras
historion al infanoj kaj poste ili laboras la konceptojn en la klaso
kune kun la gvida instruisto. Mi pensis same, sed la historio oni
povas esti ludata per la infanoj: interagi en imaga loko kun iliaj
kunpanoj el ilia lernejo aŭ ankaŭ el aliaj. Tiel ili <i>skribludos</i>
ilian propran rakonton por labori pli atentedum la taskoj en ilia
klasĉambro.
</p>

<p>
Mi programas la ilon kiam mia laboro permesas min, sed mi jam havas
preskaŭ finigita la bazan programon, ĉar tiuj pasintaj monatoj de
hejma restado mi havis sufiĉan tempon. Al mi mankas krei programe tiun
virtualan mondon, kie la infanoj devas malkovri sian aventuron. La
projekto estas programanta en la hispana per <i>erlang</i>, sed kiam mi
komencis mi memoris min dubi se ne estus pli gaja programi ĝin
esperante kaj finfine traduki la ilon al la hispana. Ekzemple, la
mondo desegnanta havas kvar lunojn: <i>Blanka</i>, <i>Blua</i>, <i>Ruya</i><sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup> kaj
<i>Bruna</i>; la planedo kie la agadoj okazos nomiĝas <i>Tero</i>; kaj tiel
pluraj nomoj de lokoj aŭ aliaj aĵoj.
</p>

<p>
Mi tre fieras tiun projekton, sed mi ne scias se finfine mi povos
plenumigi ĝin. Kiam mi parolis pri ĝi al responsuloj de la Asocio, al
ili tre ŝatas ankaŭ, sed por daŭrigi la laboron ni bezonas desegniston
por la ilustraĵoj, programiston kiu helpos min kun la programado,
psiĥologon kiu helpos min kun la ceteraj aferoj: la statistika taksado
de la preventan programon, la desegno de enketoj kaj de la <i>enhavoj</i>
de la aventuroj, ktp. Do, oni bezonas monon kaj la responsuloj
konscias pri ĝi: ili prokrastas ĉiun rendevuon por paroli pri la
projekto. Mi volas montri al ili, kiel multe la programon funkcias kaj
paroli pri tion, kion ankaŭ mankas; paroli pri la desegno de la agadoj
en la klaso; paroli pri la mono, ĉar mi pensas ke ĉi tiu estas la
problemo; kaj finfine pri kelkaj ideoj por financi la entreprenon,
kiel <i>amasfinancado</i><sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup> aŭ subvencio de sociaj aroj (oficialaj
entoj, kompanioj, aliaj asocioj pli riĉaj ol ni, ktp.).
</p>
<div id="outline-container-org06d32b6" class="outline-2">
<h2 id="org06d32b6">Konkludoj</h2>
<div class="outline-text-2" id="text-org06d32b6">
<p>
Kiel prezentado, mi pensas, sufiĉas tiu eta artikolo. Mi esperas,
tra la praktikado, ke mi plibonigos mian skriban fluadon kaj mi
atingos sufiĉan vortprovizon por paroli pri samajn aferojn de la
hispanaj artikoloj. Al mi tre enuas esperantajn skribaĵojn kiujn nur
parolas pri <i>Esperanto</i>, ŝajnas ke ĝi estis kreita nur por paroli pri
si mem... do, ne devas difini ĝin kiel <i>kreata lingvo</i> sed kiel
<i>metalingvaĝa lingvo</i>: lingvo kreata por paroli nur pri si. Ĉi tiu eta
artikolo okupis min dum horoj por esprimi kion mi volas kaj por
korekti tiujn sennumerajn erarojn, kiujn mi trovis en la antaŭaj
malnetoj (mi pensas ke mi ne forigis ĉiujn, sed ne volas prokrasti plu
la publikado).
</p>

<p>
Mi promesas ke mi faron intencon por skribi esperante pli ol
antaŭe<sup><a id="fnr.7" class="footref" href="#fn.7" role="doc-backlink">7</a></sup> kaj paroli pri aliaj temoj ol la kutimaj en esperantaj
<i>blogoj</i>, eble pli teĥnikaj, ─pri psiĥologio aŭ komputado─, kaj malpli
lingvemaj aŭ politikaj.
</p>

<p>
Se vi scipovas la hispanan kaj tralegas la hispanajn artikolojn vi
povos imagi tiujn temojn, kiujn mi ŝatas kaj proponi al mi ke mi
parolos pri ili esperante. Mi volonte verkos tiujn artikolojn.
</p>

<p>
Ĝis la sekvantan artikolon, kiu estos... ve, kiu scias?!
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Tion mi diras por eviti la vorton <i>maljuna</i>, ne konsideru mian
pekon. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Emacs</i>, <i>Lisp</i>, <i>scheme</i> en la angla. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Protección a la Infancia Contra el Abuso</i>: Protekto de
Infanecaro Kontraŭ la Perforto. Por mi estas malfacile traduki <i>abuso</i>
ĉar la hispana vorto havas plurajn sensojn esperante: misuzi,
ekspluati, trouzi, perforti... sed ŝajnas al mi ke <i>perforti</i> estas
precipe uzata kiel <i>seksa perforto</i>, kiam mi volas diri <i>ĉian
violenton aŭ perforton</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
MUD signifas <i>multi user domains</i> aŭ <i>multi user dungeon</i> en la
angla.
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Por imiti la sonon hispane de <i>Ruĝa</i>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Crowd funding</i> en la angla.
</p></div></div>

<div class="footdef"><sup><a id="fn.7" class="footnum" href="#fnr.7" role="doc-backlink">7</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Uff, tio sonas kiel politika promeso dum politika kampanjo.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <link>https://notxor.nueva-actitud.org/2020/10/04/sen-ideoj-sed-decideme.html</link>
  <pubDate>Sun, 04 Oct 2020 08:58:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Cambiando el blog a org-static-blog]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-10-02</div>
<p>
Pues estoy de cambios en el <i>blog</i> y ya tengo algo visible que subir a
la red para que se pueda ver. Me resistía al cambio, pues los sistemas
son distintos y me arriesgaba a dejar por el camino muchos enlaces
rotos, no sólo externos de otros <i>blogs</i> o redes sociales, sino
también internos.
</p>

<p>
Después de pelearme con mis reticencias me puse al tajo e, incluso, me
he dedicado a migrar también los diferentes artículos al formato de
cabecera nuevo. De esta manera, se podrá consultar el contenido en el
nuevo formato o en el antiguo... si al subir el contenido resulta todo
como espero.
</p>

<p>
¿Por qué el cambio? Básicamente tengo estas razones:
</p>

<ul class="org-ul">
<li><code>org-page</code> es un sistema complejo y por tanto también es más difícil
<i>hackearlo</i> para ajustarlo a tus necesidades.</li>
<li>Por contra, <code>org-static-blog</code> es mucho más sencillo y parece pensado
para que te lo adaptes a tus necesidades con poco esfuerzo.</li>
<li>Estaba cansado ya del tema oscuro que había hecho y aprovechando que
estoy de cambios también le he puesto un poco más de cariño al CSS.
Algo que aún no ha terminado del todo y no descarto ponerle un poco
más.</li>
<li>Cuando terminas un artículo y lanzas el comando de publicación de
<code>org-static-blog</code>, sólo genera ese HTML y actualiza los índices y
RSS.</li>
<li>Puedo tener borradores en proceso sin andarme por las ramas (de
<code>git</code>, se entiende).</li>
<li>Y por supuesto, el utilizar un control de versiones o no, es
problema mío, no me obliga a tener una rama de edición, otra con el
sitio generado, ni a tener que acordarme de generar el sitio cada
vez que hago algún cambio, porque si se pierde en la rama de <code>git</code>
no llega a materializarse. Este sistema detecta si el HTML es más
antiguo que el <code>org</code> y si es así lo genera de nuevo.</li>
</ul>

<p>
¿Todo son ventajas? Pues no. Hay inconvenientes que exigen atención,
como los <i>enlaces rotos</i>.
</p>
<div id="outline-container-org44a96f4" class="outline-2">
<h2 id="org44a96f4">Enlaces rotos</h2>
<div class="outline-text-2" id="text-org44a96f4">
<p>
A estas alturas, después de varios años escribiendo en el <i>blog</i> sobre
mis cosas, resulta que hay quien lo lee y todo. No sólo eso, sino
también que hay gente que lo enlaza y lo sigue por RSS.
</p>

<p>
El miedo al cambio viene, principalmente, de la cantidad de <i>enlaces
rotos</i> que quedan siempre sueltos por el mundo. Incluso dentro del
mismo <i>blog</i> o página. Por ello voy a intentar que esto no suceda o al
menos que sea en el menor grado posible.
</p>

<p>
Podría haber optado por encogerme de hombros y decir: «sistema nuevo,
adaptarse o morir». Pero no me ha parecido conveniente. Para pegar el
cerrojazo siempre hay tiempo, me parece.
</p>

<p>
De momento, como he dicho antes, he convertido todos los artículos del
sistema anterior, hecho con <code>org-page</code>, al nuevo sistema
<code>org-static-blog</code>. Ha sido un trabajo relativamente sencillo pues sólo
tenía que convertir algunos detalles de las cabeceras del fichero
<code>org</code>: en lugar de la etiqueta <code>tags</code> de <code>org-page</code>, utiliza
<code>filetags</code>, y también me encontré con alguna fecha que no cogía bien y
me dediqué a añadir a mano los paréntesis angulares <code>&lt;..-..-..&gt;</code> y con
eso está todo convertido... pero falta aún algo de trabajo.
</p>

<p>
Además, estoy escribiendo esto sin tener la certeza de que
efectivamente no romperé ningún enlace... tengo confianza en que así
sea, porque va a haber artículos duplicados para lo mismo. En las
pruebas que he hecho en local, todo ha parecido funcionar
correctamente... pero hasta que no lo pruebe subiéndolo todo al
servidor, no puedo estar seguro. De todas formas me guardo una copia
de seguridad del sitio viejo, por si tengo que replantear el tema.
</p>

<p>
El paquete lo puedes descargar por el procedimiento habitual, está en
<i>melpa</i> y si tienes configurado ese repositorio de paquetes basta con
el comando
</p>

<p>
<code>M-x package-install &lt;RET&gt; org-static-blog &lt;RET&gt;</code>
</p>

<p>
Yo soy algo más curioso y no lo he instalado: me he bajado el código
del <a href="https://github.com/bastibe/org-static-blog">repositorio</a> porque lo estoy cambiando un poco. De hecho no lo
tengo donde esté accesible a <i>Emacs</i>, cuando lo uso tengo que cargarlo
con <code>load-file</code>, pero aún no estoy en fase de <i>darle cariño</i>.
</p>
</div>
</div>
<div id="outline-container-org7ba698d" class="outline-2">
<h2 id="org7ba698d">El código que he cambiado</h2>
<div class="outline-text-2" id="text-org7ba698d">
<p>
El propio creador del sistema habla de que está pensado para que sea
fácil de leer, comprender y modificar.
</p>

<blockquote>
<p>
Above all, I tried to make org-static-blog as simple as
possible. There are no magic tricks, and all of the source code is
meant to be easy to read, understand and modify.
</p>
</blockquote>

<p>
Después de haberlo mirado un poco, he de coincidir con el autor: ha
sido fácil ajustar la funcionalidad a lo que quería conseguir sin
complicarme mucho.
</p>

<p>
Una de las cosas que es ajustable es «ignorar» variables como
<code>org-export-with-toc</code> o <code>org-export-with-section-numbers</code> y en su
lugar, he incluido una línea <code>#+options:</code>. La ventaja es que puedo
determinar si quiero números o índice en cada artículo, en lugar de
limitarlo en todos. La función de crear un nuevo artículo me ha
quedado así:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;;</span><span style="color: #6272a4;">###</span><span style="color: #ffb86c; background-color: #373844;">autoload</span><span style="color: #6272a4;">
</span>(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">org-static-blog-create-new-post</span> (<span style="color: #8be9fd; font-style: italic;">&amp;optional</span> draft)
  <span style="color: #6272a4;">"Creates a new blog post.
Prompts for a title and proposes a file name. The file name is
only a suggestion; You can choose any other file name if you so
choose."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (<span style="color: #ff79c6; font-weight: bold;">let</span> ((title (read-string (org-static-blog-gettext 'title))))
    (find-file (concat
                (<span style="color: #ff79c6; font-weight: bold;">if</span> draft
                    org-static-blog-drafts-directory
                    org-static-blog-posts-directory)
                (read-string (org-static-blog-gettext 'filename)
                             (concat (format-time-string <span style="color: #f1fa8c;">"%Y-%m-%d-"</span> (current-time))
                                     (replace-regexp-in-string <span style="color: #f1fa8c;">"\s"</span> <span style="color: #f1fa8c;">"-"</span> (downcase title))
                                     <span style="color: #f1fa8c;">".org"</span>))))
    (insert <span style="color: #f1fa8c;">"#+title:    "</span> title <span style="color: #f1fa8c;">"\n"</span>
            <span style="color: #f1fa8c;">"#+date:     "</span> (format-time-string <span style="color: #f1fa8c;">"&lt;%Y-%m-%d %H:%M&gt;"</span>) <span style="color: #f1fa8c;">"\n"</span>
            <span style="color: #f1fa8c;">"#+filetags: "</span> <span style="color: #f1fa8c;">"\n"</span>
            <span style="color: #f1fa8c;">"#+options:  H:3 num:nil toc:nil \\n:nil ::t |:t ^:nil -:nil f:t *:t &lt;:t"</span>)))
</pre>
</div>
</div>
<div id="outline-container-org6292284" class="outline-3">
<h3 id="org6292284">Estructuras fijas de los ficheros</h3>
<div class="outline-text-3" id="text-org6292284">
<p>
El código fundamental que falta en el <code>org-static-blog</code> son las
cabeceras y pies de página. El sistema <code>org-page</code> lleva soporte para
<a href="https://mustache.github.io/">plantillas mustache</a> que facilitan la vida en este sentido. Sin
embargo, en este sistema va en el mismo código.  Hay que cargar ese
código en sus correspondientes variables:
</p>

<ol class="org-ol">
<li><p>
Para la cabecera del <code>HTML</code>:
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defcustom</span> <span style="color: #f8f8f2; font-weight: bold;">org-static-blog-page-header</span>
  <span style="color: #f1fa8c;">"&lt;meta name=\"author\" content=\"Notxor\"&gt;
  &lt;meta name=\"referrer\" content=\"no-referrer\"&gt;
  &lt;link href= \"/medios/css/estilos.css\" rel=\"stylesheet\" type=\"text/css\" /&gt;
  &lt;link rel=\"icon\" href=\"/medios/img/favicon.png\"&gt;"</span>
  <span style="color: #6272a4;">"HTML to put in the &lt;head&gt; of each page."</span>
  <span style="color: #8be9fd; font-style: italic;">:type</span> '(string)
  <span style="color: #8be9fd; font-style: italic;">:safe</span> t)
</pre>
</div>

<p>
Básicamente establece el <i>autor</i>, la dirección del fichero de
estilos CSS y el <code>favicon</code> de la página. En mi caso, el autor lo
pone fijo, pero no costaría mucho establecer una variable que
cargue el contenido desde la cabecera, por ejemplo.
</p></li>

<li><p>
Para el encabezamiento de cada página:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defcustom</span> <span style="color: #f8f8f2; font-weight: bold;">org-static-blog-page-preamble</span>
  <span style="color: #f1fa8c;">"&lt;div&gt;
      &lt;header class=\"masthead\"&gt;
        &lt;h1 class=\"masthead-title\"&gt;&lt;a href=\"/\"&gt;Notxor tiene un blog&lt;/a&gt;&lt;/h1&gt;
        &lt;h2 class=\"masthead-subtitle\"&gt;Defenestrando la vida&lt;/h2&gt;
        &lt;img class=\"avatar\" src=\"/medios/img/abatar.png\" width=\"100px\"&gt;&lt;/img&gt;
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=\"/\"&gt;Blog&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=\"/tags/esperanto\"&gt;Esperanto&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=\"/tags/radio\"&gt;Radio&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=\"http://blog-antiguo.nueva-actitud.org\" target=\"_blank\"&gt;Blog antiguo&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=\"/etiquetas.html\"&gt;Etiquetas&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=\"/about/\"&gt;Acerca de...&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=\"/rss.xml\"&gt;RSS&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
        &lt;form method=\"get\" id=\"searchform\" action=\"//www.duckduckgo.com/\"&gt;
          &lt;input type=\"text\" class=\"field\" name=\"q\" id=\"s\" placeholder=\"Buscar en DuckDuckGo\"&gt;
          &lt;input type=\"hidden\" name=\"as_sites\" value=\"https://notxor.nueva-actitud.org\"&gt;
        &lt;/form&gt;
      &lt;/header&gt;
    &lt;/div&gt;"</span>
  <span style="color: #6272a4;">"HTML to put before the content of each page."</span>
  <span style="color: #8be9fd; font-style: italic;">:type</span> '(string)
  <span style="color: #8be9fd; font-style: italic;">:safe</span> t)
</pre>
</div>

<p>
Como se puede comprobar, la definición del «título» y el
«subtítulo», el habitual menú de secciones con sus correspondientes
enlaces y el formulario de buscar.
</p></li>

<li><p>
Para el pie de página:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defcustom</span> <span style="color: #f8f8f2; font-weight: bold;">org-static-blog-page-postamble</span>
   <span style="color: #f1fa8c;">"&lt;div&gt;
    &lt;script src=\"/medios/js/jquery-latest.min.js\"&gt;&lt;/script&gt;
    &lt;script src=\"https://polyfill.io/v3/polyfill.min.js?features=es6\"&gt;&lt;/script&gt;
    &lt;script id=\"MathJax-script\" async src=\"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js\"&gt;&lt;/script&gt;
    &lt;script src=\"/medios/js/main.js\"&gt;&lt;/script&gt;
    &lt;div class=\"footer\"&gt;
        &lt;p&gt;Generado con &lt;code&gt;org-static-blog&lt;/code&gt; en &lt;i&gt;Emacs&lt;/i&gt;&lt;/p&gt;
        &lt;p&gt;
            &lt;img style=\"display: inline-block;\" src=\"/medios/img/cc-by-nc-sa.png\" align=\"middle\" /&gt;
               &lt;br /&gt;2012 - &lt;span id=\"footerYear\"&gt;&lt;/span&gt; &lt;a href=\"mailto:notxor@nueva-actitud.org\"&gt;Notxor&lt;/a&gt;
            &amp;nbsp;&amp;nbsp;-&amp;nbsp;&amp;nbsp;
            Powered by &lt;a href=\"https://github.com/bastibe/org-static-blog\" target=\"_blank\"&gt;org-static-blog&lt;/a&gt;
            &lt;script type=\"text/javascript\"&gt;document.getElementById(\"footerYear\").innerHTML = (new Date()).getFullYear();&lt;/script&gt;
        &lt;/p&gt;
        &lt;table&gt;
            &lt;tr&gt;
                &lt;td&gt;
                    &lt;b&gt;Donar por Paypal&lt;/b&gt;
                &lt;/td&gt;
                &lt;td&gt;
                    &lt;b&gt;Donar por Liberapay&lt;/b&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;
                    &lt;!-- Inserci&#243;n de bot&#243;n pypal --&gt;
                    &lt;form action=\"https://www.paypal.com/cgi-bin/webscr\" method=\"post\" target=\"_top\"&gt;
                        &lt;input type=\"hidden\" name=\"cmd\" value=\"_s-xclick\" /&gt;
                        &lt;input type=\"hidden\" name=\"hosted_button_id\" value=\"29VXCW8SRNJ78\" /&gt;
                        &lt;input type=\"image\" src=\"https://www.paypalobjects.com/es_ES/ES/i/btn/btn_donateCC_LG.gif\" border=\"0\" name=\"submit\" title=\"PayPal - Donar online de forma segura.\" alt=\"Bot&#243;n Donar con PayPal\" /&gt;
                        &lt;img alt=\"\" border=\"0\" src=\"https://www.paypal.com/es_ES/i/scr/pixel.gif\" width=\"1\" height=\"1\" /&gt;
                    &lt;/form&gt;
                &lt;/td&gt;
                &lt;td&gt;
                    &lt;!-- Inserci&#243;n de bot&#243;n liberapay --&gt;
                    &lt;script src=\"https://liberapay.com/Notxor/widgets/button.js\"&gt;&lt;/script&gt;
                    &lt;noscript&gt;
                        &lt;a href=\"https://liberapay.com/Notxor/donate\"&gt;
                            &lt;img alt=\"Donate using Liberapay\" src=\"https://liberapay.com/assets/widgets/donate.svg\"&gt;&lt;/a&gt;
                    &lt;/noscript&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
        &lt;/table&gt;
    &lt;/div&gt;
&lt;/div&gt;"</span>
  <span style="color: #6272a4;">"HTML to put after the content of each page."</span>
  <span style="color: #8be9fd; font-style: italic;">:type</span> '(string)
  <span style="color: #8be9fd; font-style: italic;">:safe</span> t)
</pre>
</div>

<p>
Básicamente carga el poco javascript que utiliza el <i>blog</i>:
coloreado de sintaxis, visualización de fórmulas matemáticas y el
necesario para los botones de donación<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. También está la
información sobre la licencia y un enlace al código fuente que lo
anima.
</p></li>
</ol>
</div>
</div>
<div id="outline-container-org968b737" class="outline-3">
<h3 id="org968b737">Los <code>path</code></h3>
<div class="outline-text-3" id="text-org968b737">
<p>
Una de las cosas que me encontré fue la manía que tiene el sistema de
utilizar las URL de forma absoluta, comenzando por la dirección
pública de la página. Eso coarta en gran medida las pruebas de
visualización del sitio en local. Una costumbre que he adquirido tras
escribir un artículo... monto un servidor local, bien con <code>M-x
httpd-start</code> o desde una consola con <code>python3 -m http.server 8080</code>
luego lo abro con un navegador y lo pruebo. Veo si está todo correcto
en su sitio, si las imágenes las he puesto bien y aparecen todas.  Lo
leo despacio por si encuentro algún error<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.
</p>

<p>
Por todo ello, en muchos sitios he sustituido las llamadas a
<code>org-static-blog-get-absolute-url</code> por una llamada a
<code>org-static-blog-get-local-url</code>. Una función que la metí yo con un
calzador para la tarea.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">org-static-blog-get-local-url</span> (relative-url)
  <span style="color: #6272a4;">"Esta es m&#237;a...Returns local URL based on the RELATIVE-URL passed to the function."</span>
  (concat <span style="color: #f1fa8c;">"/"</span> (org-static-blog-get-relative-path relative-url)))
</pre>
</div>

<p>
¿Qué consigo con esto? Pues básicamente que el <i>blog</i> completo sea
navegable en local y no intente salir a Internet cada vez que pinches
un enlace.
</p>

<p>
Además, para poner un poco de coherencia en los <i>path</i> del sitio, me
empeñé en que las URL de los artículos se distribuyan por directorios
con el formato <code>año/mes/día</code> y el título del mismo.
</p>

<p>
Para esto he tenido que hacer un par de cambios más. Uno de ellos
viene recomendado en el mismo código:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">org-static-blog-generate-post-path</span> (post-filename post-datetime)
  <span style="color: #6272a4;">"Returns post public path based on POST-FILENAME and POST-DATETIME.

By default, this function returns post filepath unmodified, so script will
replicate file and directory structure of posts and drafts directories.

Override this function if you want to generate custom post URLs different
from how they are stored in posts and drafts directories.

For example, there is a post in posts directory with the
file path `hobby/charity-coding.org` and dated `&lt;2019-08-20 Tue&gt;`.

In this case, the function will receive following argument values:
- post-filename: '</span><span style="color: #bd93f9;">hobby/charity-coding</span><span style="color: #6272a4;">'
- post-datetime: datetime of &lt;2019-08-20 Tue&gt;

and by default will return '</span><span style="color: #bd93f9;">hobby/charity-coding</span><span style="color: #6272a4;">', so that the path
to HTML file in publish directory will be '</span><span style="color: #bd93f9;">hobby/charity-coding.html</span><span style="color: #6272a4;">'.

If this function is overriden with something like this:

(defun org-static-blog-generate-post-path (post-filename post-datetime)
  (concat (format-time-string \"%Y/%m/%d\" post-datetime)
          \"/\"
          (file-name-nondirectory post-filename)))

Then the output will be '</span><span style="color: #bd93f9;">2019/08/20/charity-coding</span><span style="color: #6272a4;">' and this will be
the path to the HTML file in publish directory and the url for the post.

Por defecto es:
   post-filename)"</span>
  (concat (format-time-string <span style="color: #f1fa8c;">"%Y/%m/%d"</span> post-datetime)
          <span style="color: #f1fa8c;">"/"</span>
          (file-name-nondirectory post-filename)))
</pre>
</div>

<p>
Meter ese código ahí tal cual funciona como se espera, se genera la
URL tal como dije antes y se crea el fichero <code>html</code> en un directorio
dentro de su día, que está dentro de su mes y que a la vez está dentro
de su año.
</p>

<p>
Lo que no avisa la documentación de la función es que luego tienes que
sustituir, allí donde se busque el contenido de un artículo que no lo
busque en el sitio por defecto con el formato por defecto:
</p>

<p>
<code>/YYYY-mm-dd-nombre-del-artículo.html</code>
</p>

<p>
En algunas funciones tenemos que sustituir también las formas que
generan <i>url's</i> de ese estilo, para que busquen en el sitio
correcto. Básicamente es sustituir la forma que añade la fecha al
nombre del archivo por algo así:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(concat <span style="color: #f1fa8c;">"/"</span> (format-time-string <span style="color: #f1fa8c;">"%Y/%m/%d"</span> post-date)
</pre>
</div>

<p>
No estoy seguro de haberlo hecho en todos los sitios oportunos, el
código está disperso por distintas funciones que generan código <code>html</code>
y es un poco enredoso encontrar los sitios adecuados. Lo he repasado
varias veces y he visto que todos los enlaces que he probado
funcionan. Sin embargo, hay tantos <i>pichorros</i> donde pinchar que no
estoy seguro de haberlos probado todos. Si alguien encuentra algún
enlace raro que no lleva a ningún lado le agradecería que me avisara.
</p>
</div>
</div>
<div id="outline-container-org671d5d3" class="outline-3">
<h3 id="org671d5d3">Estructura de directorios</h3>
<div class="outline-text-3" id="text-org671d5d3">
<p>
El sistema funciona de una manera bastante sencilla de entender: hay
un directorio configurable donde escribir los artículos y otro donde
escribir los borradores. Cuando generas el sitio, coge todo lo que
haya en el directorio de referencia y genera los ficheros <code>html</code>. No
los genera todos: sólo creará aquellos cuyo fichero <code>html</code>, si existe,
sea más antiguo que su fichero <code>org</code>. O dicho de otro modo: sólo
genera los modificados. En producción supongo que será mucho más
sencillo rápido y efectivo... <code>org-page</code> empezaba a hacerse pesado la
generación del sitio.
</p>

<p>
Otro aspecto sobre los directorios es que todo va al directorio raíz,
por defecto, ya he contado que hay que modificar algo el código para
conseguir que siga el formato de crear directorios (para fechas) y
para otras cosas.
</p>

<p>
Además se pueden generar listados de artículos según las etiquetas,
pero por defecto también las mete en el directorio raíz con el formato
<code>tag-etiqueta.html</code> y contribuye al caos del raíz de forma
considerable, sobre todo si te gustan la etiquetas como a mí. El caso
es que me pareció muchos más manejable la forma de hacerlo de
<code>org-page</code> que genera en un directorio <code>tags/</code> una estructura de
directorios, con el nombre de las etiquetas y dentro de ellos su
correspondiente fichero <code>index.html</code> con el contenido. Para ello,
modifiqué la función que genera esos ficheros de la siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">org-static-blog-assemble-tags</span> ()
  <span style="color: #6272a4;">"Render the tag archive and tag pages."</span>
  (org-static-blog-assemble-tags-archive)
  (<span style="color: #ff79c6; font-weight: bold;">dolist</span> (tag (org-static-blog-get-tag-tree))
    (org-static-blog-assemble-multipost-page
     (concat org-static-blog-publish-directory <span style="color: #f1fa8c;">"/tags/"</span> (downcase (car tag)) <span style="color: #f1fa8c;">"/index.html"</span>)
     (cdr tag)
     (concat <span style="color: #f1fa8c;">"&lt;h1 class=\"title\"&gt;"</span> (org-static-blog-gettext 'posts-tagged) <span style="color: #f1fa8c;">" \""</span> (car tag) <span style="color: #f1fa8c;">"\":&lt;/h1&gt;"</span>))))
</pre>
</div>

<p>
Evidentemente, luego, al generar los enlaces que los visiten hay que
modificar el código para que las encuentre con el mismo formato con
código tal que:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(concat <span style="color: #f1fa8c;">"/tags/"</span> (downcase tag) <span style="color: #f1fa8c;">"/index.html"</span>)
</pre>
</div>

<p>
Además, hay que tener en cuenta los archivos <code>rss.xml</code> que quiero que
se generen por etiqueta y hay que meterlos en algún sitio donde no se
pisen unos a otros... pero lo vemos más despacio a continuación.
</p>
</div>
</div>
<div id="outline-container-org2e8826a" class="outline-3">
<h3 id="org2e8826a">Fichero <code>rss.xml</code> por etiqueta</h3>
<div class="outline-text-3" id="text-org2e8826a">
<p>
Otro problema que me planteaba con el sistema nuevo y que me resultaba
una limitación es la generación de archivos RSS para cada etiqueta.
De la gente que tengo constancia que sigue el <i>blog</i>, no accediendo al
sitio, sino a través de lectores RSS, me constan, al menos tres de
esos ficheros: el de la radio, el de Esperanto y el de <i>Emacs</i>.
También sé que hay quien sigue el RSS general, no entiendo muy bien
por qué.
</p>

<p>
El caso es que necesitaba generar los RSS por etiquetas y eso no era
algo que contemplara el sistema, así que... ¿por qué no hacerlo yo?
Pues manos a la obra: me puse a mirar el código y encontré una función
que genera el RSS general (<code>org-static-blog-assemble-rss</code>). También
encontré otra que genera un ítem para cada artículo. que se llama
<code>org-static-blog-get-rss-item</code> y recibe como parámetro el
=post-filename).
</p>

<p>
Partí del código de la primera pero añadiendo el parámetro <code>tag</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">org-static-blog-rss-for-tag</span> (tag)
  <span style="color: #6272a4;">"Assemble the tag RSS feed.
The RSS-feed is an XML file that contains every blog post in a
machine-readable format."</span>
  (<span style="color: #ff79c6; font-weight: bold;">let</span> ((system-time-locale <span style="color: #f1fa8c;">"en_US.utf-8"</span>) <span style="color: #6272a4;">; </span><span style="color: #6272a4;">force dates to render as per RSS spec
</span>        (rss-filename (concat org-static-blog-publish-directory <span style="color: #f1fa8c;">"/tags/"</span> (car tag) <span style="color: #f1fa8c;">"/"</span> org-static-blog-rss-file))
        (rss-items nil))
    (<span style="color: #ff79c6; font-weight: bold;">dolist</span> (post-filename (cdr tag))
      (<span style="color: #ff79c6; font-weight: bold;">let</span> ((rss-date (org-static-blog-get-date post-filename))
            (rss-text (org-static-blog-get-rss-item post-filename)))
        (add-to-list 'rss-items (cons rss-date rss-text)))
    (<span style="color: #ff79c6; font-weight: bold;">setq</span> rss-items (sort rss-items (<span style="color: #ff79c6; font-weight: bold;">lambda</span> (x y) (time-less-p (car y) (car x)))))
    (org-static-blog-with-find-file
     rss-filename
     (concat <span style="color: #f1fa8c;">"&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\n"</span>
             <span style="color: #f1fa8c;">"&lt;rss version=\"2.0\"&gt;\n"</span>
             <span style="color: #f1fa8c;">"&lt;channel&gt;\n"</span>
             <span style="color: #f1fa8c;">"&lt;title&gt;&lt;![CDATA["</span> org-static-blog-publish-title <span style="color: #f1fa8c;">"]]&gt;&lt;/title&gt;\n"</span>
             <span style="color: #f1fa8c;">"&lt;description&gt;&lt;![CDATA["</span> org-static-blog-publish-title <span style="color: #f1fa8c;">"]]&gt;&lt;/description&gt;\n"</span>
             <span style="color: #f1fa8c;">"&lt;link&gt;"</span> org-static-blog-publish-url <span style="color: #f1fa8c;">"&lt;/link&gt;\n"</span>
             <span style="color: #f1fa8c;">"&lt;lastBuildDate&gt;"</span> (format-time-string <span style="color: #f1fa8c;">"%a, %d %b %Y %H:%M:%S %z"</span> (current-time)) <span style="color: #f1fa8c;">"&lt;/lastBuildDate&gt;\n"</span>
             org-static-blog-rss-extra
             (apply 'concat (mapcar 'cdr rss-items))
             <span style="color: #f1fa8c;">"&lt;/channel&gt;\n"</span>
             <span style="color: #f1fa8c;">"&lt;/rss&gt;\n"</span>)))))
</pre>
</div>

<p>
El parámetro <code>tag</code> llega como una lista de cadenas donde la primera es
el nombre de la etiqueta y las siguientes son los ficheros que la
llevan. Por tanto, monto el <code>rss.xml</code> en el mismo directorio que su
listado de ficheros, para no sobreescribir un fichero con otro y el
resto es idéntico a como se genera el RSS del blog.
</p>

<p>
Por un momento dudé si hacer la función interactiva o llamarla sólo
para cada etiqueta. Al final, me decidí por hacerlo de una manera
alternativa. Como no todas la etiquetas son relevantes, porque no
todas tienen seguimiento, generar siempre los ficheros es un poco
pérdida de tiempo. Así que lo solucioné de <i>manera manual</i>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">org-static-blog-assemble-rss-by-tag</span> ()
  <span style="color: #6272a4;">"Assemble the RSS for tags."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (mapcar 'org-static-blog-rss-for-tag (org-static-blog-get-tag-tree)))
</pre>
</div>

<p>
Es decir, cuando llamo a la función
<code>org-static-blog-assemble-rss-by-tag</code> se generarán todos los ficheros
<code>rss.xml</code> ─lo que lleva unos segundos─. ¿Por qué no generar sólo una
etiqueta o unas pocas? Pues porque hacer unas etiquetas y no otras
puede ser un poco confuso para los posibles lectores que lleguen al
<i>blog</i> cuando encuentren que tienen referencias de un tema determinado
y de otros no.
</p>

<p>
Como se ve, no es complicado adaptar un sistema tan sencillo: se
pueden hacer muchas otras cosas y con muy pocas líneas de código.
</p>
</div>
</div>
</div>
<div id="outline-container-org18fe1de" class="outline-2">
<h2 id="org18fe1de">El fichero CSS</h2>
<div class="outline-text-2" id="text-org18fe1de">
<p>
Por otro lado, también ha habido un cambio de aspecto. He cambiado
tipos de letras, colores y alguna cosilla más con la esperanza de
hacerlo un poco más atractivo. Sin embargo, como podéis ver, tampoco
es que mis capacidades de diseño sean sobresalientes. No ha quedado
mal del todo.
</p>

<p>
Me había cansado del tema oscuro y aprovechando que iba a hacer
cambios, me puse también manos a la obra con el aspecto. Aún me quedan
algunas cosas que pulir.
</p>
</div>
</div>
<div id="outline-container-orgc043def" class="outline-2">
<h2 id="orgc043def">El código completo</h2>
<div class="outline-text-2" id="text-orgc043def">
<p>
Sería muy largo poner aquí todo el código implicado. Se sale del
tamaño razonable de un artículo del <i>blog</i>. Si alguien quiere acceder
a él puede mirarlo en el siguiente repositorio:
</p>

<p>
<a href="https://codeberg.org/Notxor/org-static-blog">https://codeberg.org/Notxor/org-static-blog</a>
</p>
</div>
</div>
<div id="outline-container-org32bbed3" class="outline-2">
<h2 id="org32bbed3">Conclusiones</h2>
<div class="outline-text-2" id="text-org32bbed3">
<p>
Ha habido más cambios, por ejemplo en el código también he añadido la
traducción al Esperanto de las cadenas del sistema. Al principio de
comenzar a manejarlo pensé que debía utilizar dos <i>blogs</i> para cada
una de las lenguas. Después he visto que me podía ajustar de otros
modos.
</p>

<p>
Por supuesto el código que he subido al repositorio se puede utilizar
como mejor veáis. Si hago cambios en el sistema para ajustarlo, para
corregir algún <i>bug</i> o para dotarlo de alguna característica nueva, lo
subiré al repositorio, pero tampoco tengo el ánimo de convertirlo en
un proyecto que mantener... no me da de sí el tiempo como para
comprometerme.
</p>

<p>
Al final, el sistema es tan sencillo que me parece hermoso, se
entiende cómo funciona sin demasiado esfuerzo, es altamente
personalizable y hasta un psicólogo como yo lo puede hacer sin ayuda.
</p>

<p>
Si estáis pensando en hacer un <i>blog</i>, queréis un sistema estático y
sois usuarios de <i>Emacs</i>, es la alternativa estáis buscando... incluso
le podéis automatizar la vista previa de forma muy sencilla:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(httpd-serve-directory org-static-blog-publish-directory)
(httpd-start)
</pre>
</div>

<p>
Así no necesitas ni salir de <i>Emacs</i> para hacer las pruebas.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Que por cierto, a ver cuándo os estiráis y me puedo tomar mi
primer café a vuestra salud :'( 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Parece mentira, porque aún así se me cuelan <i>siene' y siene'</i>. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/blog/index.html">blog</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[blog]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2020/10/02/cambiando-el-blog-a-org-static-blog.html</link>
  <pubDate>Fri, 02 Oct 2020 08:53:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Futuros cambios en el blog]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-09-25</div>
<div id="outline-container-org40e1567" class="outline-2">
<h2 id="org40e1567">Para que todo siga igual</h2>
<div class="outline-text-2" id="text-org40e1567">
<p>
Ya sabéis que muchas veces hay que hacer cambios para que todo siga
igual y a eso le estoy dando vueltas.  Con el paso de los años el
sistema este de <code>org-page</code> se me está haciendo algo pesado. Generar
todo el sitio cuando cambio algo en las plantillas de algún espacio
compartido me tarda mucho tiempo. Además es un sistema complejo, donde
intervienen otras herramientas como <code>git</code> y creo que no es necesario,
─o no lo debía ser─. A ver, no me malinterpretéis, está muy bien tener
el <i>blog</i> mantenido en un repositorio <code>git</code>, pero la herramienta que
tenga que generar el sitio <code>html</code> desde <code>org</code>, no debería depender de
ello. O al menos, es una sensación que tengo instalada en mi
<i>pushconciente</i>.
</p>

<p>
El tema es que hace unos días, curioseando alternativas, encontré otra
herramienta aún más minimalista que <code>org-page</code>: <a href="https://github.com/bastibe/org-static-blog">org-static-blog</a>.
Dicho paquete esa disponible en <code>Melpa</code> y se puede instalar
directamente por el método habitual.
</p>
</div>
<div id="outline-container-orgd0ef3eb" class="outline-3">
<h3 id="orgd0ef3eb">¿Qué me gusta de ese sistema nuevo?</h3>
<div class="outline-text-3" id="text-orgd0ef3eb">
<p>
Minimalismo en estado puro. Todo está contenido en un mismo archivo
<code>org-static-blog.el</code> y ya está. Además no es largo ni farragoso. Es
sencillo de entender y me permitirá hacer algún que otro <i>hack</i> para
que todo me siga funcionando.
</p>
</div>
</div>
<div id="outline-container-org43aa638" class="outline-3">
<h3 id="org43aa638">¿Qué no me gusta?</h3>
<div class="outline-text-3" id="text-org43aa638">
<p>
Le tengo que hacer cambios para mantener el <i>blog</i> actual con todas
sus funcionalidades... Concretamente tres tareas:
</p>

<ol class="org-ol">
<li>No soporta «categorías» como el actual. Tengo que añadir un
<i>subblog</i>, por llamarlo de alguna manera, para incluir los
artículos en <i>Esperanto</i>. Ya puesto, lo mismo hasta traduzco el
<i>chismático</i> al <i>Esperanto</i> para esa sección.</li>
<li>No genera archivos <code>rss</code> por etiquetas. Lo que viene muy bien para
enlazar el <i>blog</i> en otro <i>compendiador</i> como
<a href="http://planet.emacs-es.org/">http://planet.emacs-es.org/</a> y me consta que algunos de los lectores
habituales de esta cosa, conocieron el sitio a través de él.</li>
<li><p>
Hay que ajustar todas las entradas que hay acumuladas hasta ahora
a las nueva exigencias de cabecera... muy pesado todo lo que he
escrito ─pensaba yo que escribía poco, pero ná una pasada de curro
ingrato─.
</p>

<p>
...
</p></li>

<li>(Vale dije tres, pero es que esto no es obligatorio). Viene sin
cosas como <i>temas</i> para la visualización. Tienes que enganchar tú
el <code>css</code> en las cabeceras. Nada que no solucione una línea de
código <code>html</code>. Además, aprovechando el asunto, se podría cambiar ya
el aspecto del <i>blog</i> (que ya me estoy cansando del tema oscuro).</li>
</ol>
</div>
</div>
</div>
<div id="outline-container-org1a27d51" class="outline-2">
<h2 id="org1a27d51">¿Cómo funciona?</h2>
<div class="outline-text-2" id="text-org1a27d51">
<p>
Por las pruebas que llevo hechas, es realmente minimalista. Contempla
la existencia de tres directorios: <code>blog</code>, <code>posts</code> y <code>drafts</code>... lo
podemos ver en su código:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defcustom</span> <span style="color: #f8f8f2; font-weight: bold;">org-static-blog-publish-directory</span> <span style="color: #f1fa8c;">"~/blog/"</span>
  <span style="color: #6272a4;">"Directory where published HTML files are stored."</span>
  <span style="color: #8be9fd; font-style: italic;">:type</span> '(directory))

(<span style="color: #ff79c6; font-weight: bold;">defcustom</span> <span style="color: #f8f8f2; font-weight: bold;">org-static-blog-posts-directory</span> <span style="color: #f1fa8c;">"~/blog/posts/"</span>
  <span style="color: #6272a4;">"Directory where published ORG files are stored.
When publishing, posts are rendered as HTML, and included in the
index, archive, tags, and RSS feed."</span>
  <span style="color: #8be9fd; font-style: italic;">:type</span> '(directory))

(<span style="color: #ff79c6; font-weight: bold;">defcustom</span> <span style="color: #f8f8f2; font-weight: bold;">org-static-blog-drafts-directory</span> <span style="color: #f1fa8c;">"~/blog/drafts/"</span>
  <span style="color: #6272a4;">"Directory where unpublished ORG files are stored.
When publishing, draft are rendered as HTML, but not included in
the index, archive, tags, or RSS feed."</span>
  <span style="color: #8be9fd; font-style: italic;">:type</span> '(directory))
</pre>
</div>

<p>
En el trabajo normal se ponen los ficheros <code>org</code> en el directorio que
se encuentra en la variable <code>org-static-blog-posts-directory</code> y cuando
se llama a <code>org-static-blog-publish</code> genera sólo los <code>html</code> que se
encuentren el directorio de <i>posts</i>.
</p>

<p>
Además, según leo <a href="https://github.com/bastibe/org-static-blog">en su sitio de <i>github</i></a> cuando generas un sitio,
sólo lo hace si no existe un fichero <code>html</code> ─más moderno─
correspondiente al fichero <code>org</code>.
</p>

<blockquote>
<p>
Individual blog entries are only re-rendered if no current HTML file
is available (i.e. the org file is older than the HTML file). If you
want to forcibly re-render an entry, delete the HTML file.
</p>
</blockquote>

<p>
Además, también se puede generar sólo la salida de un sólo fichero con
<code>org-static-blog-publish-file</code>. Que, supongo, que ser utilizará en el
caso de hacer correcciones en algún <i>post</i> antiguo.
</p>
</div>
</div>
<div id="outline-container-org24d317b" class="outline-2">
<h2 id="org24d317b">Posibles trabajos futuros</h2>
<div class="outline-text-2" id="text-org24d317b">
<p>
Para que pueda pasarme al nuevo sistema con todas las funcionalidades
que ahora tengo con <code>org-page</code> tengo que hacer un poco de trampa. Mi
primera idea es tener un fichero de configuración, quizá un <code>org</code> con
código diferente para cargarlo según el tipo de artículo que vaya a
escribir y que todo se publique en el mismo directorio.
</p>

<p>
La idea sería, por lo menos, tener separados los temas de <i>blog</i> y
<i>esperanto</i>, para simular las <i>categorías</i>. Las etiquetas también
podrían servir y poner un enlace al fichero <code>tag</code> correspondiente.
En cualquier caso, sí habría que hacerlo para el tema de generar un
fichero <code>rss</code>, pues hay quien está suscrito sólo a ese apartado.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defcustom</span> <span style="color: #f8f8f2; font-weight: bold;">org-static-blog-enable-tags</span> nil
  <span style="color: #6272a4;">"Show tags below posts, and generate tag pages."</span>
  <span style="color: #8be9fd; font-style: italic;">:group</span> 'org-static-blog
  <span style="color: #8be9fd; font-style: italic;">:type</span> '(boolean)
  <span style="color: #8be9fd; font-style: italic;">:safe</span> t)

(<span style="color: #ff79c6; font-weight: bold;">defcustom</span> <span style="color: #f8f8f2; font-weight: bold;">org-static-blog-rss-file</span> <span style="color: #f1fa8c;">"rss.xml"</span>
  <span style="color: #6272a4;">"File name of the RSS feed."</span>
  <span style="color: #8be9fd; font-style: italic;">:type</span> '(string)
  <span style="color: #8be9fd; font-style: italic;">:safe</span> t)
</pre>
</div>

<p>
Tengo que probar si se puede publicar a subdirectorios o quizá tenga
que hacerlo creando subdominio. Aprovechando el tema de los cambios,
incluso creo que debo cambiar el aspecto de esos <i>posts</i> para resaltar
su distinta categoría y que salte a la vista nada más abrir el
artículo.  Se podrían activar las etiquetas y cambiar el nombre del
<code>rss</code> de <code>rss.xml</code> a cualquier otro como, por ejemplo,
 <code>esperanto.xml</code> o <code>eo-rss.xml</code>.
</p>
</div>
</div>
<div id="outline-container-orgfcb2c8f" class="outline-2">
<h2 id="orgfcb2c8f">Conclusiones</h2>
<div class="outline-text-2" id="text-orgfcb2c8f">
<p>
Todo está muy incipiente y aún estoy haciendo pruebas. Lo escribo aquí
para que no penséis que está abandonado el <i>blog</i> si paso una
temporada sin escribir nada. O si poco a poco, veis que se van
realizando cambios o experimentáis alguna de las pegas que he
detallado antes.
</p>

<p>
Ahora queda el trabajo largo y pesado de convertir todos los <i>posts</i>
que hay ya hechos. Son algunos años ya escribiendo <i>tontás</i>. En
principio hay que cambiar las cabeceras y los enlaces a los ficheros
gráficos. Así que, paciencia.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/blog/index.html">blog</a> ]]></description>
  <category><![CDATA[blog]]></category>
  <link>https://notxor.nueva-actitud.org/2020/09/25/futuros-cambios-en-el-blog.html</link>
  <pubDate>Fri, 25 Sep 2020 19:37:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Un artículo introductorio sobre redes neuronales]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-09-21</div>
<div id="outline-container-orga244e0f" class="outline-2">
<h2 id="orga244e0f">De aquellos polvos, estos lodos</h2>
<div class="outline-text-2" id="text-orga244e0f">
<p>
La culpa de este artículo la tiene Alberto: en el grupo de <i>Telegram</i>
que está abierto para hacer comentarios sobre el <i>blog</i> lanzó la
siguiente <i>petición</i>, <i>propuesta</i>, <i>cosa</i> no sé muy bien para qué:
</p>


<figure id="orgb90f7df">
<img src="./imagen/Captura-pantalla-peticion-redes.png" alt="Captura-pantalla-peticion-redes.png">

</figure>

<p>
Bueno, vale. La respuesta fácil hubiera sido: <i>«no sé nada»</i> y haberme
quitado el marrón de encima por la vía de la ignorancia.  La respuesta
corta, pero sincera, sería: <i>«muy poco»</i>. Así que, falto de temas como
ando últimamente para el <i>blog</i>, voy a contaros lo poco que sé: sin
ánimo de ser exhaustivo y, sobre todo, queriendo ser breve.
</p>

<p>
Me presentaron las <i>neuronas artificiales</i> y las pandillas que forman
allá por el año 1982, cuando se lanzaba al mercado lo que fue lo más
parecido a un ordenador personal que hubo en las casas de la época: el
<a href="https://es.wikipedia.org/wiki/Sinclair_ZX_Spectrum"><i>Sinclair ZX Spectrum</i></a>... uff... 38 años nos contemplan. Insisto en
los años, porque nos parece que estas cosas de las <i>Inteligencias
Artificiales</i> son de ayer mismo, cuando se remontan por lo menos a
anteayer.
</p>


<figure id="orgc4b3f14">
<img src="./imagen/apuntes-primero.png" alt="apuntes-primero.png">

</figure>

<p>
Aún guardo como «oro en paño» los apuntes de primero de carrera de
<i>Fundamentos de Psicología Matemática</i>. Cuando compré aquellos
<i>apuntes</i> fotocopiados que nos dejó el profesor en repografía<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>,
empecé a ojearlos en la biblioteca y me llamaron la atención,
precisamente, los apartados que luego no veríamos. Quizá, porque el
resto del libro era básicamente el contenido que ya había visto en
COU<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. Al final no vimos nada de aquellos que me parecieron
interesantes: nos quedamos en el temario de COU. Muchos de mis
compañeros vinieron a la carrera de Psicología habiéndose pasado todo
el bachillerato huyendo de las matemáticas y se tropezaron con ella
durante toda la carrera: matemáticas en primero, en segundo
estadística, en tercero <i>teoría de tests</i>, en cuarto <i>psicología
experimental</i>. En fin... el caso es que me quedé con las ganas de
avanzar, entre otras cosas en la aplicación del cálculo matricial en
las «redes neuronales formales».  Pero nací como irredento curioso me
lo miré por mi cuenta.
</p>

<p>
En aquellos apuntes nos hablaban del primer modelo de <i>neurona
formal</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> de <i>McCulloch y Pitts</i> en 1943. Si alguien ha curioseado
sobre el tema le sonarán esos nombres porque es lo básico, pero
básico, de este campo.
</p>

<p>
Intentando imitar el funcionamiento de las <i>neuronas naturales</i>, esos
autores establecen los siguientes axiomas divididos en dos grupos:
</p>

<dl class="org-dl">
<dt>Axiomas estructurales</dt><dd><ol class="org-ol">
<li><b>La neurona es un mecanismo binario</b>. Es decir, puede tener dos
estados: <i>activa</i> o <i>inactiva</i>, o dispara o no, o es 1 o es 0.</li>
<li><b>Cada neurona tiene una salida conectada a una o más neuronas</b>. O
dicho de otro modo: o activa o no a todas las neuronas a las que
está conectada.</li>
<li><b>Cada neurona puede recibir un número cualquiera de <i>sinapsis</i>
excitadoras o inhibidoras</b>.</li>
<li><b>Cada neurona tiene un umbral de disparo</b> a partir del cual se la
considera <i>activa</i> y si no se alcanza se la considera <i>inactiva</i>.</li>
</ol></dd>
<dt>Axiomas funcionales</dt><dd><ol class="org-ol">
<li><b>La neurona puede cambiar de estado en momentos determinados por
la acción de las demás neuronas</b>.</li>
<li>Sean dos neuronas \(a_i\) y \(a_j\) tales que \(a_i\) está conectada
con \(a_j\). La neurona \(a_i\) ejercerá una acción excitadora o
inhibidora sobre \(a_j\) en el tiempo \(t+1\) sólo si \(a_i\) está
activa en el tiempo \(t\).</li>
<li>Una neurona está activa en el tiempo \(t\) sólo si la suma de las
sinapsis inhibidoras y excitadores que recibe en el tiempo \(t\)
sobrepasa el <i>umbral de disparo</i> de la neurona.</li>
<li>Una neurona no hace sinapsis sobre ella misma<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>.</li>
</ol></dd>
</dl>
</div>
<div id="outline-container-org30dcd37" class="outline-3">
<h3 id="org30dcd37">Críticas</h3>
<div class="outline-text-3" id="text-org30dcd37">
<p>
Como concepto básico, dichos axiomas, pueden resultar suficientes. El
problema desde mi punto de vista es que tampoco simulan con mucha
precisión el funcionamiento de las neuronas... Para empezar, desde el
punto de vista de la neurología:
</p>

<ol class="org-ol">
<li>Todas las neuronas naturales disparan cuando el nivel de excitación
supera el potencial mínimo de la membrana, y ese es una valor
estable y compartido por todas ellas.</li>
<li>Todas las neuronas naturales desactivan la electrificación de su
membrana si reciben una excitación demasiado potente. Eso las
protege de quedar <i>fritas</i>. Cuando se supera un determinado nivel
de activación, la membrana de la neurona deja de conducir la
electricidad y se convierte en una membrana celular normal, durante
unos milisegundos.</li>
<li>Las neuronas naturales no disparan por turnos en momentos
discretos: están funcionando de manera constante y disparan cuando
reciben el estímulo suficiente. Una vez han disparado, la membrana
queda también sin electrificar en lo que se conoce como <i>periodo
refractario</i>.</li>
</ol>

<p>
Vale, es una simulación para conseguir, conceptualmente, un
funcionamiento parecido a lo que sería una neurona natural. Sin
embargo, esas críticas quedarían en nada, si al menos el modelo fuera
lo suficientemente preciso como para conseguir que esa simulación
tenga un funcionamiento correcto y completo. Sin embargo, desde el
punto de vista del <i>proceso</i> de las redes neuronales nos encontramos
con otros problemas.
</p>

<p>
En las redes neuronales podemos encontrar que las neuronas pueden
establecer conexiones al estilo de las puertas lógicas.
</p>


<figure id="orgb21f610">
<img src="./imagen/puertas-logicas.png" alt="puertas-logicas.png">

</figure>

<p>
Podemos repasar el gráfico anterior con sus tablas lógicas, suponiendo
que establecemos el nivel mínimo de activación a <code>25</code> (para todas las
neuronas), vemos que no hay problema simular las puertas lógicas <code>and</code>
y <code>or</code>.
</p>

<table>


<colgroup>
<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-right">\(E_1\)</th>
<th scope="col" class="org-right">\(E_2\)</th>
<th scope="col" class="org-right">\(Y\)</th>
<th scope="col" class="org-left">&#xa0;</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-right">20</td>
<td class="org-right">20</td>
<td class="org-right">40</td>
<td class="org-left"><b>Activa</b></td>
</tr>

<tr>
<td class="org-right">20</td>
<td class="org-right">0</td>
<td class="org-right">20</td>
<td class="org-left">no activa</td>
</tr>

<tr>
<td class="org-right">0</td>
<td class="org-right">20</td>
<td class="org-right">20</td>
<td class="org-left">no activa</td>
</tr>

<tr>
<td class="org-right">0</td>
<td class="org-right">0</td>
<td class="org-right">0</td>
<td class="org-left">no activa</td>
</tr>
</tbody>
</table>

<table>


<colgroup>
<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-right">\(E_1\)</th>
<th scope="col" class="org-right">\(E_2\)</th>
<th scope="col" class="org-right">\(O\)</th>
<th scope="col" class="org-left">&#xa0;</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-right">25</td>
<td class="org-right">25</td>
<td class="org-right">50</td>
<td class="org-left"><b>Activa</b></td>
</tr>

<tr>
<td class="org-right">25</td>
<td class="org-right">0</td>
<td class="org-right">25</td>
<td class="org-left"><b>Activa</b></td>
</tr>

<tr>
<td class="org-right">0</td>
<td class="org-right">25</td>
<td class="org-right">25</td>
<td class="org-left"><b>Activa</b></td>
</tr>

<tr>
<td class="org-right">0</td>
<td class="org-right">0</td>
<td class="org-right">0</td>
<td class="org-left">no activa</td>
</tr>
</tbody>
</table>

<p>
Sin embargo, para la puerta lógica de «o exclusivo» es decir, debe
estar activa una o la otra, pero no las dos al tiempo, necesitamos el
concurso de una neurona auxiliar que quedaría oculta:
</p>

<table>


<colgroup>
<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-right">\(E_1\)</th>
<th scope="col" class="org-right">\(E_2\)</th>
<th scope="col" class="org-right">\(o\)</th>
<th scope="col" class="org-right">\(Ox\)</th>
<th scope="col" class="org-left">&#xa0;</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-right">25</td>
<td class="org-right">25</td>
<td class="org-right">-30</td>
<td class="org-right">20</td>
<td class="org-left">no activa</td>
</tr>

<tr>
<td class="org-right">25</td>
<td class="org-right">0</td>
<td class="org-right">0</td>
<td class="org-right">25</td>
<td class="org-left"><b>Activa</b></td>
</tr>

<tr>
<td class="org-right">0</td>
<td class="org-right">25</td>
<td class="org-right">0</td>
<td class="org-right">25</td>
<td class="org-left"><b>Activa</b></td>
</tr>

<tr>
<td class="org-right">0</td>
<td class="org-right">0</td>
<td class="org-right">0</td>
<td class="org-right">0</td>
<td class="org-left">no activa</td>
</tr>
</tbody>
</table>

<p>
Se ha marcado en el gráfico de manera distinta la <i>sinapsis</i> de la
neurona oculta, en azul con el rombo relleno para remarcar que cuando
se activa, su <i>peso</i> de sinapsis es negativo. Es decir, cuando las dos
neuronas de entrada se activan, además de activar la salida, activan
la oculta que al mismo tiempo inhibe la salida.
</p>

<p>
Dicho de otro modo, aunque en la vida real, las neuronas pueden
simular un circuito <code>xor</code> del mismo modo que lo hace con los otros. Es
decir, no se necesita una tercera neurona en el circuito para que la
puerta lógica funcione.
</p>

<p>
Si hubieran añadido un axioma más para la activación, como en la vida
real, y hubieran tenido en cuenta un límite máximo, se podría simular
un circuito <code>xor</code> con la misma cantidad de neuronas.  Por ejemplo,
suponiendo que el límite inferior es <code>25</code> y el superior es <code>100</code>, el
circuito podría ser:
</p>


<figure id="org3bb743d">
<img src="./imagen/xor-modificado.png" alt="xor-modificado.png">

</figure>

<table>


<colgroup>
<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-right">\(Ox_1\)</th>
<th scope="col" class="org-right">\(Ox_2\)</th>
<th scope="col" class="org-right">\(Ox\)</th>
<th scope="col" class="org-left">&#xa0;</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-right">75</td>
<td class="org-right">75</td>
<td class="org-right">150</td>
<td class="org-left">no activa</td>
</tr>

<tr>
<td class="org-right">75</td>
<td class="org-right">0</td>
<td class="org-right">75</td>
<td class="org-left"><b>Activa</b></td>
</tr>

<tr>
<td class="org-right">0</td>
<td class="org-right">75</td>
<td class="org-right">75</td>
<td class="org-left"><b>Activa</b></td>
</tr>

<tr>
<td class="org-right">0</td>
<td class="org-right">0</td>
<td class="org-right">0</td>
<td class="org-left">no activa</td>
</tr>
</tbody>
</table>
</div>
<div id="outline-container-org2c6ef88" class="outline-4">
<h4 id="org2c6ef88">¿Por qué esto es importante?</h4>
<div class="outline-text-4" id="text-org2c6ef88">
<p>
Pues todo tiene que ver con la economía de recursos. Una puerta lógica
debería funcionar de manera directa sin necesitar recursos adicionales
para ello. En este caso necesita una neurona adicional. No sólo eso,
sino que además tiene que ver con el encadenado de puertas lógicas.
Hay bastante más puertas lógicas y dejadme que haga un poco de
hincapié en alguna de ella. En concreto hay una puerta lógica que en
inglés se llama <code>NotXor</code> (¿de qué me sonará el nombre?) que se la
conoce como el <i>lógico universal</i>. Es decir, podemos crear todas las
demás puertas lógicas encadenando sólo puertas <code>notxor</code>, lo que viene
a decir que seríamos capaces de crear cualquier tipo de circuito
lógico sólo con un cajón cargado de «sienes y sienes» de <i>pichorros</i>
de mi puerta lógica favorita.
</p>
</div>
</div>
</div>
<div id="outline-container-orgff5de28" class="outline-3">
<h3 id="orgff5de28">Otras neuronas y redes neuronales</h3>
<div class="outline-text-3" id="text-orgff5de28">
<p>
Más allá de McCulloch y Pitts aparecieron otros modelos intentando
mejorar el original. En 1943 la propuesta de estos autores se basaban
en lo que se conoce como la <i>lógica del umbral</i>, pero, como hemos
visto, ésta se quedaba corta. Además no existía forma alguna de
<i>enseñar</i> o <i>entrenar</i> a nuestra red: había que programarle los pesos
a puro <i>huevo</i>, como he hecho yo en los ejemplos anteriores. Nada
complicado cuanto tienes tres neuronas, pero por cada neurona que
añadas la complejidad crece exponencialmente.
</p>

<p>
Así aparecieron pronto otras soluciones, no sobre las <i>neuronas
artificiales</i> en sí, sino sobre cómo reunirlas en redes y capas para
que hagan su trabajo. Pero principalmente, sobre el <i>entrenamiento</i> de
dichas redes.
</p>

<p>
Por aquellos años lo petaba un psicólogo (<i>Donald Hebb</i><sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>) cuyas
teorías, que él llamó <i>biopsicológicas</i>, basaban el comportamiento de
aprendizaje humano en la plasticidad de las neuronas. En la capacidad
que tienen para hacer nuevas sinapsis o en dejar de hacerlas. Esa
plasticidad hace, según el autor, que las neuronas establezcan redes
de <a href="https://es.wikipedia.org/wiki/Potenciaci%C3%B3n_a_largo_plazo">potenciación a largo plazo</a> que está en la base de lo que para las
redes neuronales artificiales se conoce como <a href="https://es.wikipedia.org/wiki/Aprendizaje_no_supervisado">aprendizaje no
supervisado</a>... pero me estoy adelantando un poco, voy a seguir un rato
más con las redes neuronales, luego ya veremos un poco el tema del
aprendizaje.
</p>

<p>
Históricamente podemos distinguir dos tipos de redes:
</p>

<ol class="org-ol">
<li>Redes de propagación hacia adelante o <a href="https://es.wikipedia.org/wiki/Red_neuronal_prealimentada">redes neuronales
prealimentadas</a> que consiste en que las neuronas se agrupan en capas
y se comunican hacia adelante en las capas, desde la entrada a la
salida conectándose siempre de una capa a la siguiente sin conectar
su axón con ninguna anterior. El ejemplo, más sencillo de este tipo
de redes es el <a href="https://es.wikipedia.org/wiki/Perceptr%C3%B3n">perceptrón de dos capas</a>, una capa de entrada y otra
de salida.</li>
<li>Redes de estado estocástico, como las redes de <a href="https://es.wikipedia.org/wiki/Hopfield_(RNA)">Hopfield</a> o la
<a href="https://es.wikipedia.org/wiki/M%C3%A1quina_de_Boltzmann">máquina de Boltzmann</a>. Estas redes contienen un conjunto de neuronas
completamente interconectadas y que introducen el concepto de
estados de mínima energía.</li>
</ol>

<p>
Básicamente, las primeras procesan y las segundas almacenan
estados<sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup>. Esas son además los tipos de redes neuronales
tradicionales e históricas. Sin embargo, en la actualidad hay más:
</p>

<ol class="org-ol">
<li><a href="https://es.wikipedia.org/wiki/Red_neuronal_de_impulsos">Las redes neuronales de impulsos</a> son redes neuronales más modernas
que intentan procesar la información de una manera más similar a
como lo hacen las redes neuronales biológicas.</li>
</ol>

<p>
Como se puede ver, hay varios tipos de redes y a veces es complicado
catalogar una determinada en un grupo o en otro, sin contar los casos
de utilizar dos tipos de redes conectados entre ellas para que una le
sirva a otra como entrada o como almacenamiento de información. Hay
otro tipo de redes que se llaman «recursivas» que almacenan respuestas
intermedias que luego se emplean también en la entrada, que me voy a
saltar para no marear más la perdiz.
</p>
</div>
</div>
<div id="outline-container-orgaa28664" class="outline-3">
<h3 id="orgaa28664">Otros tipos de Inteligencia Artificial</h3>
<div class="outline-text-3" id="text-orgaa28664">
<p>
El problema de las redes neuronales en la historia, es la manera en la
que aprenden. De hecho, históricamente se abandonaron en favor de
otros tipos de <i>Inteligencia Artificial</i> por la dificultad de
<i>adiestrar</i> o <i>entrenar</i> a la red para que hiciera lo que se esperaba
de ella.
</p>

<p>
Cuando hace unos años <a href="https://github.com/Notxor/Neuronal">hicimos un intento de crear una red neuronal</a> en
Python, el amigo <i>dddddd</i> y yo nos encontramos con esa misma
dificultad. Habíamos cambiado el modo en que funcionaba la red
neuronal y nos tropezamos con que los métodos clásicos no se ajustaban
a nuestra red (o nuestra red a esos métodos) y al final el proyecto
quedó abandonado por falta de algoritmo de entrenamiento efectivo.
</p>

<p>
Así, los modelos llamados entonces <i>sistemas expertos</i> tomaron la
delantera, adquirieron más inversión y más presencia en las
universidades y publicaciones científicas. <code>LISP</code> apareció como el
paradigma de lenguaje de programación para <i>IA</i>, pues el mismo código,
a base de listas, es en sí una base de datos y esa base de datos de
conocimiento, al final, es código <i>LISP</i>. Pero como esas cosas son más
carne de cañón para otros artículos, y este va de redes neuronales, lo
dejaremos para más adelante como otro posible tema para el blog. Ya me
perdonaréis las disculpas.
</p>
</div>
</div>
<div id="outline-container-orgbc6c1ba" class="outline-3">
<h3 id="orgbc6c1ba">Métodos de entrenamiento</h3>
<div class="outline-text-3" id="text-orgbc6c1ba">
<p>
Ocurrió que se inventó el método de <a href="https://es.wikipedia.org/wiki/Propagaci%C3%B3n_hacia_atr%C3%A1s">propagación hacia atrás</a> y el
<i>conexionismo</i> reapareció de nuevo en el campo de la <i>IA</i> arrollando
todo de nuevo a su paso. El método mencionado consiste en comparar el
resultado de nuestra red, ─típicamente un perceptrón multicapa─, con
el resultado esperado. Si el valor no coincide y/o se distancia de lo
esperado, se modifican los pesos de las <i>sinapsis</i> siguiendo las capas
hacia atrás y volviendo a probar.
</p>

<p>
Contado así es fácil de entender cómo funciona. Otro tema es
implementarlo, que es bastante más complejo.
</p>

<p>
Otra forma en realidad no es un método de entrenamiento, es la
utilización de algoritmos evolutivos, aprovechando que al final la
<i>selección natural</i> no deja de ser un buen mecanismo para producir
determinados resultados si conoces cuáles son los que buscas. También
se les conocen como métodos aleatorios, pues modifican los pesos al
azar y se van seleccionado aquellas modificaciones que se aproximan
más al resultado esperado, para repetir el proceso en sucesivas
<i>generaciones</i>, hasta alcanzar la salida deseada.
</p>
</div>
</div>
</div>
<div id="outline-container-org16e4ae6" class="outline-2">
<h2 id="org16e4ae6">Conclusiones</h2>
<div class="outline-text-2" id="text-org16e4ae6">
<p>
Bueno, esto es sólo arañar un poco la superficie del tema de las redes
neuronales, ─y eso sin profundizar mucho en las redes modernas y el
<i>Big Data</i>... uff─, un tema apasionante, pero muy complejo para verlo
completamente en un sólo artículo. Tampoco soy un experto, sólo soy un
curioso y las cosas que digo son las que creo saber. Espero no estar
muy errado en el fondo de la cuestión.
</p>

<p>
Estoy pensando ampliar el tema un poco y meterle algo de programación
al tema... pero como no sé qué pensarán los sufridos lectores de <i>mis
tontás</i> esperaré a los comentarios por redes sociales. Si os apetece,
lo mismo hago una serie sobre programar una red neuronal y practicar
lo poco que sé de <code>erlang/OTP</code> por el camino.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Era la forma de la época pre-informatizada para que los
profesores nos dejaran documentos a los alumnos... los llevaban a
repografía y luego tú comprabas allí las fotocopias. Muchas veces,
como ésta, eran los borradores de libros escritos preparados para
publicar. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
El <i>Curso de Orientación Universitaria</i> de entonces, o un curso
que se supone que te preparaba para la Universidad. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Fíjese el respetable que no es <i>neurona artificial</i>, sino
<i>formal</i>: está expresada mediante axiomas matemáticos ya que en 1943
no había mucha posibilidad de programar una <i>artificial</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Este es un planteamiento irreal, pues las neuronas naturales
hacen sinapsis sobre sí mismas, pero lo dejaremos estar. 
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
No me cayó nunca muy bien: lideró los estudios sobre privación
sensorial que luego aparecerían aplicados en los manuales de tortura
de la CIA. 
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Como esto lo lea un entendido de verdad se va a descojonar de
todas las burradas que puedo decir en aras de la simplificación...
pero para el caso nos sirve.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/ia/index.html">IA</a> <a href="/tags/neuronas/index.html">neuronas</a> ]]></description>
  <category><![CDATA[IA]]></category>
  <category><![CDATA[neuronas]]></category>
  <link>https://notxor.nueva-actitud.org/2020/09/21/un-artículo-introductorio-sobre-redes-neuronales.html</link>
  <pubDate>Mon, 21 Sep 2020 00:10:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Esperanto kaj Libera Programaro]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-09-18</div>
<p>
Mia intenco skribanta ĉi tiun artikolon estas por disvastigi senton,
aŭ percepton, tute subjektiva, ke mi havas pri la rilato de
<i>Esperanto</i> kun la <i>libera programaro</i>.  Mi pensas tion, ke la
procento de uzantoj de libera programaro inter esperantistoj estas
pli granda, proporcie, ol la ne uzantoj. Kaj inverse: la procento de
esperantistoj inter la uzantoj de libera programaro estas proporcie
pli granda ol inter la ne uzantoj.
</p>

<p>
Mi skribis ĉi tiun artikolon kelkaj tagoj antaŭe sed mi pensis ke,
eble, ĝi interesigos neniun.  Mi pensis restigi ĝin kiel malneta
skribaĵo, nur ĝi estus unu el la kvanto (granda), ke mi havas kaŝitajn
tra mia komputilo. Sed la lastaj tagoj mi ricevis ligilo al <a href="https://masgnulinux.es/esperanto-y-software-libre-pablo-busto/">artikolo
en la hispana verkita</a>, de la amiko Pablo Busto, kiu esprimas saman
senton. Mi atente legis ĝin kaj poste interparolis rete kun la
verkisto pri nia koincido. Mi komentis ke mi havis duonskribitan
artikolon pri la temo, sed esperante kaj li instigis min por finigi
kaj publikigi ĝin. Lian celon estis disvastigi la uzo de Esperanto
inter la komputilistoj kaj, eble, mi povos intenci disvastigi la
libera programaro inter la esperantistoj. Do, komplementaj aferoj.
</p>

<p>
Ne nur tio estas mia celo. Ankaŭ sur mi pezas bedaŭron pro la malmulta
praktikado de nia lingvo. Ĉi tiu jaro, la renkontiĝoj ĉe la Frateco
malaperis kaj mi pensas ke mi perdos ĉiun malmultan fluecon ke mi
havis. Do, mi devas skribi kaj esperi ke mi perdos malpli ol faranta
nenion. La renkontiĝoj revenos, mi esperas, sed ni devas zorgi pri
niaj maljunaj samideanoj, kelkaj el ili tre jaraĝaj: vivaj atestantoj
de kiam Esperanto kaj la esperantistoj estis persekutitaj, de kiam
poste komencis de nove naski komunumon kaj finfine de kiam la terura
reto kaj komputado surpasis la <i>movado</i>. Tiel ili sentas kiam ni
parolis pri komputado, inter mirigitaj, teruritaj kaj esperantaj pro
ke Esperanto daŭris kaj ne malaperos.
</p>

<p>
Sed eble, la <i>reto</i> mortigos la movadon kaj pro tio, mi esperas ke la
legantoj de ĉi tiu artikolo sentas ankaŭ la movadon kiel propra afero.
Finfine mi esperas tion, ke <i>la movado</i> trovos lokon en la reto.
</p>

<p>
Aliflanke, tiel Esperanto, kiel libera programaro, naskiĝis de grandaj
ideoj pri la plibonigo de Homaro. Mi ankaŭ nur memoras la unua frazo
ke mia instruisto proponis por <i>longa hejmtasko</i>:
</p>

<blockquote>
<p>
Mi estas homo, kaj por mi ekzistas nur idealoj pure homaj. Ĉiajn
idealojn kaj celadon gente-naciajn mi rigardas nur kiel grupan
egoismon kaj hommalamon, kiuj pli aŭ malpli frue devas malaperi kaj
kies malaperon mi devas akceladi laŭ mia povo.
</p>
</blockquote>

<p>
Jes, ja. Ĝi estas la <i>unua dogmo</i> de <i>homaranismo</i> verkita de
L.L. Zamenhof je la 1906. Oni transiris pli ol cent jaroj kaj tiu
frazo estas pli necesa ol tiam.
</p>

<p>
Finfine, tiuj ideoj pri homaranismo impregnis la Esperanton per
grandaj sentoj: egaleco, frateco, komunikado. Inter ni, homoj, kaj
inter niaj nacioj. Nur estas <i>Homaro</i> kaj ĉiu homo estas mia frato.
Do, la internacia lingvo naskis kun idealoj aŭ prenis ilin de sia
kreanto.
</p>

<p>
Tiel, ankaŭ, la libera programaro naskis impregnita de grandaj
idealoj: La kvar liberoj devas servi la homoj por antaŭiri, por evolui
niajn ilarojn kaj ĉiu devas povi, egale, atingi la kodon de siaj iloj
kaj ŝanĝi ĝin pro la adapto de la programo al sia propra bezono.
</p>

<p>
Ankaŭ la du iloj pensas unue pri la homoj, pri la uzantoj, pri
plibonigi la uzon, la komunikadon, la komunumon.
</p>

<p>
Ja, Esperanto komencis donante sin al komunumo. Ĝi ne estas nur mia aŭ
via, nek de la Akademio, sed de la uzantoj. Fiksitaj la unuajn
regulojn, la <i>Fundamenton</i>, por interkompreni nin, Esperanto estas
nia. Tio egalas ĉiun parolanton: ĉiu akcento estas permesata kaj
korekta aŭ ĝusta, la fina celo estas la preciza interkompreno. Same,
la libera programaro instigas la difinon kaj uzon de liberaj normoj:
vi povas uzi kion vi volus, sed se ĝi funkcias per liberaj normoj,
niaj programaroj povas interkomuniki kaj labori kune. Kontraŭe, la ne
liberaj iloj kaj lingvoj, kie la posedo intervenis, ofte sentas la
<i>fremdulojn</i> kiel minacoj, ne kiel kunpanoj. Oni pleniĝis per
antaŭjuĝoj bazitaj de ne realaj faktoj kaj tiuj antaŭjuĝoj estas
malfacile dispecigeblaj, ili facile elstarigis murojn de malamo kaj
malkompreno. Mia lingvo (mia programaro) estas mia kaj la aliajn ulojn
estas danĝeraj; ĉu ĝi sufiĉus la uzadon de <i>nia</i> anstataŭ <i>mia</i> por
devenigi la aliajn ulojn kiel kompanoj.
</p>

<p>
Mi ankaŭ revas tion: ke la Esperanto estus la lingvo de libera
programaro, kaj ĉiu programo libera estos komentita kaj farita de la
Esperanto kaj ne de la angla. Ĉu tiu revo estus <i>finvenkisma</i>?
Mi pensas ke ne: la <i>finvenkismo</i> estas kiel <i>ĉi tiu jaro estas la
jaro de linukso en la labortablo</i>... revoj. Mi ankaŭ, kiam mi
programas, mi kodas hispane aŭ angle, ĝi dependas de la aliaj homoj.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/software-libre/index.html">software-libre</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[software-libre]]></category>
  <link>https://notxor.nueva-actitud.org/2020/09/18/esperanto-kaj-libera-programaro.html</link>
  <pubDate>Fri, 18 Sep 2020 00:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Las tres herramientas de presentación que utilizo]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-09-11</div>
<p>
Ya hablé <a href="https://notxor.nueva-actitud.org/blog/2019/04/29/presentaciones-con-org-beamer-mode/">en otra ocasión de cómo hago presentaciones</a> en mi vida de
texto plano. Muchas veces utilizo <code>pdf</code> por la comodidad de que todos
los sistemas donde puedo enchufar un <i>pendrive</i> tienen algún lector de
este tipo de ficheros que permitan mostrar la presentación. Está
compacto todo en un mismo archivo sin directorios y dependencias por
ahí sueltas.
</p>

<p>
Sin embargo, estos últimos tiempos le he estado dando más a otros
sistemas de presentaciones. En concreto me encuentro utilizando más
otros dos <i>chismáticos</i> que se basan en <code>javascript</code> y, como es de
esperar, hay navegadores web en todos los sistemas que los pueden
mover. Aunque tienen la pega de que suelen ir en directorios cargados
con imágenes sueltas, <code>javascripts</code>, <code>css</code>, <code>fuentes</code>, etc.
</p>

<p>
Me he observa, y esto es lo curioso, que normalmente para <code>Beamer</code>
utilizo el paquete <code>org-beamer</code> con <i>Emacs</i> y exportar luego a <code>pdf</code>.
Pero para las otras dos herramientas edito normalmente el <code>html</code> a
mano y no utilizo los modos, que he visto que existen, de <i>Emacs</i>.
¿Por qué?  Pues no lo sé, quizá encuentro más sencilla la edición de
<code>html</code> o ya tengo demasiados paquetes instalados en mi <i>Emacs</i>, o
cualquier otra excusa que ahora mismo no se me ocurre, pero he de
confesar, que aún habiendo visto en la lista de paquetes los
correspondientes nunca me ha dado por probarlos.
</p>

<p>
Vamos al grano, trataré cada uno de ellos por separado, e intentaré
ser breve, ─que alguno se me queja cuando escribo <i>ladrillos</i> largos─.
</p>
<div id="outline-container-orge8e566b" class="outline-2">
<h2 id="orge8e566b">Beamer</h2>
<div class="outline-text-2" id="text-orge8e566b">
<p>
Para el que no lo conozca, <code>beamer</code> es un paquete de <i>LaTeX</i> que
permite hacer presentaciones generando un <code>pdf</code>. Si alguien tiene
curiosidad <a href="http://tug.ctan.org/macros/latex/contrib/beamer/doc/beameruserguide.pdf">hay una guía completa</a> donde explica todas las opciones que
se pueden utilizar. Básicamente consiste en bloques de texto <i>LaTeX</i>
marcado entre las etiquetas <code>\begin{frame}</code> y <code>\end{frame}</code>. En la
misma portada de la documentación viene el ejemplo que copio a
continuación:
</p>

<pre class="example" id="org9acd85e">
\begin{frame}
  \frametitle{There Is No Largest Prime Number}
  \framesubtitle{The proof uses \textit{reductio ad absurdum}.}
  \begin{theorem}
      There is no largest prime number.
  \end{theorem}
  \begin{proof}
      \begin{enumerate}
          \item&lt;1-| alert@1&gt; Suppose $p$ were the largest prime number.
          \item&lt;2-&gt; Let $q$ be the product of the first $p$ numbers.
          \item&lt;3-&gt; Then $q+1$ is not divisible by any of them.
          \item&lt;1-&gt; But $q + 1$ is greater than $1$, thus divisible by
              some primenumber not in the first $p$ numbers.\qedhere
      \end{enumerate}
  \end{proof}
\end{frame}
</pre>

<p>
En este ejemplo, podemos ver algunas características básicas. Como
decía ese código genera un <code>frame</code> o <code>slide</code> o una <code>traspa</code> que es
como las llamo habitualmente. Como se puede apreciar, podemos mostrar
un <i>título</i> con el comando <code>\frametitle</code> y un <i>subtítulo</i> con el
comando <code>\framesubtitle</code>. Además podemos utilizar algunos otros
entornos de <i>LaTeX</i> como <code>theorem</code> para definir teoremas y <code>proof</code>
para definir las pruebas.
</p>

<p>
Quizá si conocéis <i>LaTeX</i> os llamen la atención las etiquetas de los
ítem del entorno <code>enumerate</code>. Esas etiquetas controlan la presentación
de cada uno de ellos.  <code>&lt;1-| alert@1&gt;</code> tiene dos partes divididas por
el carácter <code>|</code> que permite poner varias secuencias a la vez. El
número <code>1-</code> indica el orden en que aparece el ítem y hasta cuándo se
está mostrando... Los tiempos para mostrar pueden tomar la forma <code>&lt;1&gt;</code>
que sólo mostrará el ítem en el paso 1; la forma <code>&lt;1-4&gt;</code> mantiene el
ítem mostrándose entre los pasos 1 y 4; y la forma <code>&lt;1-&gt;</code> muestra el
ítem desde el paso 1 hasta el final de la <i>traspa</i>. El código
<code>alert@1</code> hace que se coloree en rojo (o el color establecido para la
alerta por el tema que se esté utilizando) y el número indica en qué
paso adopta ese color.
</p>

<p>
También hay comandos para muchas otras cosas... pero las transiciones
dependen de la herramienta de visualización y por tanto no hay mucho
control sobre ellas. Además, en el apartado de los puntos en contra,
están cosas como meter sonido, o multimedia en general, porque depende
de otros paquetes externos que debes instalar y activar
<code>\usepackage{multimedia}</code>.
</p>

<p>
Quizá por esos inconvenientes y que cada vez más utilizo <i>pijadas</i>
como animaciones y vídeos para explicarme, y también, todo hay que
decirlo, para darle en los morros a los adelantados del <i>pogüerpoin</i>,
he ido abandonando <code>beamer</code> para adoptar alguno de los siguientes
sistemas.
</p>
</div>
</div>
<div id="outline-container-org5a13863" class="outline-2">
<h2 id="org5a13863">impress.js</h2>
<div class="outline-text-2" id="text-org5a13863">
<p>
El <a href="https://impress.js.org"><code>impress.js</code> es un paquete <code>javascript</code></a> que permite hacer
presentaciones con animaciones 3D, rotaciones, zoom y otros efectos
que son una auténtica pasada visual. Una presentación bien planificada
con <code>impress.org</code> suele asombrar a la audiencia acostumbrada al
<i>pogüerpoin</i> y herramientas similares. Si el ordenador tiene una
tarjeta gráfica decente y hace las animaciones suaves, impresiona.
</p>

<p>
Con esta herramienta <a href="https://nueva-actitud.org/manifiesto">hice el <i>manifiesto</i> de mi gabinete de psicología</a>
y quedó bastante apañado ─para ser de las primeras cosas que hice con
él─.
</p>

<p>
Mi forma de trabajar con esta herramienta consta de los siguientes
 pasos:
</p>

<ol class="org-ol">
<li><a href="https://github.com/impress/impress.js">bajar el código fuente más reciente</a>,</li>
<li>seleccionar alguna plantilla entre las demos que hay o coger
directamente la clásica que viene con el mismo código fuente y</li>
<li>modificar el <code>html</code> y el <code>css</code> hasta dejar la presentación a mi
gusto.</li>
</ol>

<p>
Comprender cómo funciona es relativamente fácil. Utiliza el <i>canvas
3D</i> por lo que si no especificas otra cosa la coordenada <code>z</code> siempre
será <code>0</code>. Eso facilita el que me imagine la presentación como una
serie de posiciones de la cámara que apuntan a un determinado lugar de
un plano... me recuerda a mis años mozos cuando me dedicaba a
<a href="http://povray.org/">hacer <i>tontás</i> con <code>povray</code></a>. Bueno, el caso es que nos podemos
encontrar tal que haciendo una <i>traspa</i> así:
</p>

<div class="org-src-container">
<pre class="src src-html">&lt;<span style="color: #50fa7b; font-weight: bold;">div</span> <span style="color: #f8f8f2; font-weight: bold;">id</span>=<span style="color: #f1fa8c;">"title"</span> <span style="color: #f8f8f2; font-weight: bold;">class</span>=<span style="color: #f1fa8c;">"step slice"</span> <span style="color: #f8f8f2; font-weight: bold;">data-x</span>=<span style="color: #f1fa8c;">"100"</span> <span style="color: #f8f8f2; font-weight: bold;">data-y</span>=<span style="color: #f1fa8c;">"0"</span> <span style="color: #f8f8f2; font-weight: bold;">data-scale</span>=<span style="color: #f1fa8c;">"4"</span>&gt;
    &lt;<span style="color: #50fa7b; font-weight: bold;">span</span> <span style="color: #f8f8f2; font-weight: bold;">class</span>=<span style="color: #f1fa8c;">"elemento"</span>&gt;Esto es un elemento que destacar.&lt;/<span style="color: #50fa7b; font-weight: bold;">span</span>&gt;
    &lt;<span style="color: #50fa7b; font-weight: bold;">h1</span>&gt;T&#237;tulo&lt;<span style="color: #50fa7b; font-weight: bold;">sup</span>&gt;*&lt;/<span style="color: #50fa7b; font-weight: bold;">sup</span>&gt;&lt;/<span style="color: #50fa7b; font-weight: bold;">h1</span>&gt;
    &lt;<span style="color: #50fa7b; font-weight: bold;">span</span> <span style="color: #f8f8f2; font-weight: bold;">class</span>=<span style="color: #f1fa8c;">"footnote"</span>&gt;&lt;<span style="color: #50fa7b; font-weight: bold;">sup</span>&gt;*&lt;/<span style="color: #50fa7b; font-weight: bold;">sup</span>&gt; Con una anotaci&#243;n al pie.&lt;/<span style="color: #50fa7b; font-weight: bold;">span</span>&gt;

    &lt;<span style="color: #50fa7b; font-weight: bold;">div</span> <span style="color: #f8f8f2; font-weight: bold;">class</span>=<span style="color: #f1fa8c;">"notes"</span>&gt;
        Este &lt;<span style="color: #50fa7b; font-weight: bold;">i</span>&gt;<span style="font-style: italic;">div</span>&lt;/<span style="color: #50fa7b; font-weight: bold;">i</span>&gt; no se muestra por pantalla, son notas del orador
        y se pueden consultar mientras se est&#225; presentando la presentaci&#243;n
        presentablemente.
    &lt;/<span style="color: #50fa7b; font-weight: bold;">div</span>&gt;
&lt;/<span style="color: #50fa7b; font-weight: bold;">div</span>&gt;
</pre>
</div>

<p>
El atributo <code>class</code> está fijado a <code>step slice</code>, luego en el fichero
<code>.css</code> está definida dicha clase de elementos. Por ejemplo, en la
presentación de demostración clásica, esa clase muestra un marco con
esquinas redondeadas para la <i>traspa</i>. Podemos definir los estilos que
queramos en nuestro <code>.css</code> y utilizarlos luego de esa manera tan
simple. Los atributos <code>data-x</code> y <code>data-y</code> indican el centro de la
<i>traspa</i> en el <i>canvas</i>. También hay un valor <code>data-z</code> que la mueve en
el eje <code>z</code>: en negativo para alejarla <i>hacia abajo</i> del plano del
<i>canvas</i> o en positivo para <i>levantarla</i> sobre el mismo. Eso son
posiciones absolutas, pero también podemos definir posiciones
relativas a la posición anterior con atributos como <code>data-rel-x</code>,
<code>data-rel-y</code> y <code>data-rel-z</code>. 
</p>

<p>
También se pueden rotar las transparencias con la característica
<code>data-rotate</code>, que girará el contenido de la <code>traspa</code> en
grados... bueno, la gira en el eje <code>z</code> para que se mantenga
perpendicular al plano del <i>canvas</i> pero también está la opción de
rotar por ejes individuales con <code>data-rotate-x</code>, <code>data-rotate-y</code> o
<code>data-rotate-z</code>.
</p>

<p>
Además, también se puede controlar el espacio relativo que ocupa cada
<i>traspa</i> en el <i>canvas</i> mediante el atributo <code>data-scale</code>. En el
ejemplo anterior, se puede ver que hemos querido que la <i>traspa</i> tenga
un tamaño <code>x4</code>. Cuando se visualiza en pantalla no se perciben
cambios, pues la cámara se ajusta, alejándose o acercándose, para que
se vea todo el contenido. Sólo se aprecian los cambios de tamaño al
verlas todas juntas en modo <i>overview</i>.
</p>

<p>
También podemos apreciar que hay dentro del espacio otro <code>div</code> cuya
clase es <code>notes</code>. Esto permite escribir las notas del orador. No se
muestran por pantalla, pero es que esta herramienta ha pensado en todo
y tiene un modo de «visor» para el orador, donde muestra la <i>traspa</i>
actual, la siguiente y el contenido de <code>notes</code> de la que está en
pantalla.
</p>

<p>
Opciones tiene muchas, es puro <code>javascript</code> con <code>html5</code> y <code>css3</code>.
Cualquier tipo de cosas que se pueden hacer con esos tres, se pueden
meter dentro de una <i>traspa</i>: sonido, vídeo, animación o cosas más
sofisticadas. Por ejemplo, llamar a otros <code>javascript</code> como <a href="https://github.com/mermaid-js/mermaid"><i>mermaid</i></a>
para dibujar diagramas, o <a href="https://www.mathjax.org/"><i>mathjax</i></a> para fórmulas matemáticas, o
<a href="https://highlightjs.org/"><i>highlightjs</i></a> para el resaltado de código.
</p>

<p>
En general, se puede hacer casi cualquier cosa que nos dicte nuestra
imaginación. Por ejemplo, en <a href="https://github.com/impress/impress.js/blob/master/examples/cube/index.html">una de las demos o plantillas</a> que podéis
encontrar montan una presentación pequeña de seis <i>traspas</i> en un
cubo, como si fuera un dado, rotándolo en 3D según avanza la
presentación.
</p>

<p>
Y si no te aclaras con la edición de <i>pichorros 3D</i> en modo texto,
también puedes encontrar <a href="https://github.com/henrikingo/impressionist">una herramienta que se llama <i>impressionist</i>
que permite</a> editar la presentación 3D de forma gráfica y visual.
Aunque yo sigo prefiriendo el método tradicional de editar el <code>html</code> y
el <code>css</code> con <i>Emacs</i> a mano: me basta tener el navegador abierto con
el archivo cargado, hacer una modificación, grabar cambios y ya estoy
viendo los efectos que los cambios han generado.
</p>

<p>
Vamos al siguiente.
</p>
</div>
</div>
<div id="outline-container-org5974083" class="outline-2">
<h2 id="org5974083">reveal.js</h2>
<div class="outline-text-2" id="text-org5974083">
<p>
Otra herramienta de <code>javascript</code> que llevarse a los dedos y hacer
presentaciones muy resultonas es <code>reveal.js</code>. Quizá sea más popular
que la anterior, aunque en funcionalidades, siendo ambas <code>html5</code> y
<code>css</code>, montado todo sobre una pila de <code>javascript</code>, son muy parecidas
o prácticamente las mismas. Luego explicaré por qué unas veces utilizo
una u otra opción.
</p>

<p>
En general, <a href="https://revealjs.com/">la documentación que acompaña</a> a <code>reveal.js</code> es bastante
más completa y clara que la que proporciona la herramienta anterior.
También <a href="https://slides.com/?ref=github">tiene un editor gráfico</a> para el que lo necesite, aunque éste
no lo descargas en plan aplicación, ya que es una herramienta
<i>online</i>.  También tienes acceso inmediato a toda la multimedia y los
ajustes que puedan proporcionar <code>html</code> y <code>css</code>. Y por supuesto, como
en la anterior, puedes aprovechar otros <code>javascript</code> para resaltar tu
código, escribir fórmulas matemáticas o dibujar diagramas... en este
caso debes cargar los <i>plugins</i> que los llaman.
</p>

<p>
¿Por qué utilizo dos herramientas en lugar de una? Pues básicamente,
porque para <code>impress.js</code> no he encontrado ninguna herramienta que me
genere un <code>pdf</code> con el contenido de la presentación y con <code>reveal.js</code>
sí puedo hacerlo.
</p>

<p>
La filosofía de uso que utilizo es muy parecida:
</p>

<ol class="org-ol">
<li>Bajarme <a href="https://github.com/hakimel/reveal.js">la última versión de la herramienta</a>.</li>
<li>Abrir alguna plantilla o demo</li>
<li>Modificar el código <code>html</code> y <code>css</code> a mi gusto.</li>
</ol>

<p>
Como veis, son los mismos pasos que con <code>impress</code>, aunque quizá sea
más sencilla la edición de <code>reveal</code> porque no necesita datos <i>3D</i>.
</p>

<p>
Si queremos podemos partir de una plantilla realmente básica y
sencilla:
</p>

<div class="org-src-container">
<pre class="src src-html">&lt;<span style="color: #50fa7b; font-weight: bold;">html</span>&gt;
  &lt;<span style="color: #50fa7b; font-weight: bold;">head</span>&gt;
    &lt;<span style="color: #50fa7b; font-weight: bold;">link</span> <span style="color: #f8f8f2; font-weight: bold;">rel</span>=<span style="color: #f1fa8c;">"stylesheet"</span> <span style="color: #f8f8f2; font-weight: bold;">href</span>=<span style="color: #f1fa8c;">"dist/reveal.css"</span>&gt;
    &lt;<span style="color: #50fa7b; font-weight: bold;">link</span> <span style="color: #f8f8f2; font-weight: bold;">rel</span>=<span style="color: #f1fa8c;">"stylesheet"</span> <span style="color: #f8f8f2; font-weight: bold;">href</span>=<span style="color: #f1fa8c;">"dist/theme/white.css"</span>&gt;
  &lt;/<span style="color: #50fa7b; font-weight: bold;">head</span>&gt;
  &lt;<span style="color: #50fa7b; font-weight: bold;">body</span>&gt;
    &lt;<span style="color: #50fa7b; font-weight: bold;">div</span> <span style="color: #f8f8f2; font-weight: bold;">class</span>=<span style="color: #f1fa8c;">"reveal"</span>&gt;
      &lt;<span style="color: #50fa7b; font-weight: bold;">div</span> <span style="color: #f8f8f2; font-weight: bold;">class</span>=<span style="color: #f1fa8c;">"slides"</span>&gt;
        &lt;<span style="color: #50fa7b; font-weight: bold;">section</span>&gt;Punto 1&lt;/<span style="color: #50fa7b; font-weight: bold;">section</span>&gt;
        &lt;<span style="color: #50fa7b; font-weight: bold;">section</span>&gt;
           &lt;<span style="color: #50fa7b; font-weight: bold;">section</span>&gt;Punto 2.1&lt;/<span style="color: #50fa7b; font-weight: bold;">section</span>&gt;
           &lt;<span style="color: #50fa7b; font-weight: bold;">section</span>&gt;Punto 2.2&lt;/<span style="color: #50fa7b; font-weight: bold;">section</span>&gt;
           &lt;<span style="color: #50fa7b; font-weight: bold;">section</span>&gt;Punto 2.3&lt;/<span style="color: #50fa7b; font-weight: bold;">section</span>&gt;
        &lt;/<span style="color: #50fa7b; font-weight: bold;">section</span>&gt;
        &lt;<span style="color: #50fa7b; font-weight: bold;">section</span>&gt;Punto 3&lt;/<span style="color: #50fa7b; font-weight: bold;">section</span>&gt;
      &lt;/<span style="color: #50fa7b; font-weight: bold;">div</span>&gt;
    &lt;/<span style="color: #50fa7b; font-weight: bold;">div</span>&gt;
    &lt;<span style="color: #50fa7b; font-weight: bold;">script</span> <span style="color: #f8f8f2; font-weight: bold;">src</span>=<span style="color: #f1fa8c;">"dist/reveal.js"</span>&gt;&lt;/<span style="color: #50fa7b; font-weight: bold;">script</span>&gt;
    &lt;<span style="color: #50fa7b; font-weight: bold;">script</span>&gt;
      Reveal.initialize();
    &lt;/<span style="color: #50fa7b; font-weight: bold;">script</span>&gt;
  &lt;/<span style="color: #50fa7b; font-weight: bold;">body</span>&gt;
&lt;/<span style="color: #50fa7b; font-weight: bold;">html</span>&gt;
</pre>
</div>

<p>
Esa plantilla es totalmente funcional y no presenta ninguna dificultad
para poder entenderla. Es bastante más sencilla, a simple vista, que
las movidas 3D de <code>impress.js</code> por lo que siempre digo que esta
herramienta de presentaciones está hecha para todos los públicos.
</p>

<p>
En este caso nos podemos imaginar la distribución de las distintas
<i>traspas</i> en el <i>canvas</i> con el siguiente esquema.<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>
</p>


<figure id="org3604fd3">
<img src="./imagen/distribucion-reveal.png" alt="distribucion-reveal.png">

</figure>

<p>
Por tanto, sólo hay animaciones a izquierda, derecha, abajo y arriba
sin muchas posibilidades de cambiarlo. Aunque podemos jugar con las
transiciones y otros efectos de <code>fade</code>, <code>zoom</code> y más como animaciones,
fondos, etc., y crear una presentación lo suficientemente resultona
</p>

<p>
Pero como digo, el único punto fuerte, que no he podido hacer con la
anterior y con esta sí, es la exportación a <code>pdf</code>.
</p>

<p>
También se pueden presentar contenidos de forma secuencial como en
<code>beamer</code> con código sencillo de entender:
</p>

<div class="org-src-container">
<pre class="src src-html">&lt;<span style="color: #50fa7b; font-weight: bold;">section</span>&gt;
  &lt;<span style="color: #50fa7b; font-weight: bold;">p</span> <span style="color: #f8f8f2; font-weight: bold;">class</span>=<span style="color: #f1fa8c;">"fragment"</span>&gt;Fade in&lt;/<span style="color: #50fa7b; font-weight: bold;">p</span>&gt;
  &lt;<span style="color: #50fa7b; font-weight: bold;">p</span> <span style="color: #f8f8f2; font-weight: bold;">class</span>=<span style="color: #f1fa8c;">"fragment fade-out"</span>&gt;Fade out&lt;/<span style="color: #50fa7b; font-weight: bold;">p</span>&gt;
  &lt;<span style="color: #50fa7b; font-weight: bold;">p</span> <span style="color: #f8f8f2; font-weight: bold;">class</span>=<span style="color: #f1fa8c;">"fragment highlight-red"</span>&gt;Resaltar en rojo&lt;/<span style="color: #50fa7b; font-weight: bold;">p</span>&gt;
  &lt;<span style="color: #50fa7b; font-weight: bold;">p</span> <span style="color: #f8f8f2; font-weight: bold;">class</span>=<span style="color: #f1fa8c;">"fragment fade-in-then-out"</span>&gt;Hacer Fade in y despu&#233;s out&lt;/<span style="color: #50fa7b; font-weight: bold;">p</span>&gt;
  &lt;<span style="color: #50fa7b; font-weight: bold;">p</span> <span style="color: #f8f8f2; font-weight: bold;">class</span>=<span style="color: #f1fa8c;">"fragment fade-up"</span>&gt;Desplazarse hacia arriba al entrar&lt;/<span style="color: #50fa7b; font-weight: bold;">p</span>&gt;
&lt;/<span style="color: #50fa7b; font-weight: bold;">section</span>&gt;
</pre>
</div>

<p>
Estos son sólo unos ejemplos. Hay toda una lista de efectos que mirar
en la documentación para emplearlos correctamente.
</p>

<p>
También podemos enlazar cualquier <i>traspa</i> y visitarla mediante un
enlace interno. Basta con poner un atributo <code>id</code> y en el otro sitio
una etiqueta <code>&lt;a/&gt;</code> con el <code>href</code> al nombre elegido... o si conocemos
su número, por ejemplo el <code>2</code>, podemos saltar poniendo como <code>href</code> la
cadena <code>"#/2"</code>.
</p>

<p>
En todo caso, todos estos detalles y muchos otros vienen explicados en
su documentación y no quiero <i>cansinaros</i> demasiado.
</p>
</div>
</div>
<div id="outline-container-org702e2d8" class="outline-2">
<h2 id="org702e2d8">Conclusiones</h2>
<div class="outline-text-2" id="text-org702e2d8">
<p>
Herramientas de presentaciones hay muchas. En mi caso y asistiendo a
mi vida en texto plano, las que utilizo son estas que he mencionado
arriba.  Desde la más deslumbrante <code>impress.js</code> hasta la más espartana
<code>beamer</code>.
</p>

<p>
Aunque <code>beamer</code> ha sido durante años mi opción, en la actualidad, me
estoy decantando más por las presentaciones con <code>javascript</code> porque me
dan un mayor control para mostrar lo que quiero sin complicarme la
vida. Aún no me he decantado por ninguna de las dos, a las dos les
encuentro debilidades y fortalezas y me obliga a pensar muy bien antes
de hacer una presentación cuál elegir, cuál será la más adecuada para
ese momento. Los puntos positivos de ambas son muy similares:
</p>

<ul class="org-ul">
<li>Flexibilidad del <code>html5</code> y el <code>css3</code>.</li>
<li>Buen impacto visual.</li>
<li>Sencillas de hacer, con un editor como <i>Emacs</i> basta.</li>
</ul>

<p>
Vale, estas son las cosas positivas...
</p>

<p>
¿Qué no me gusta de <code>impress.js</code>? Pues básicamente que no puedo
extraer fácilmente la información a <code>pdf</code>. Todo se puede convertir,
evidentemente, pero requiere más atención que con <code>reveal.js</code>. Y otro
problema es que muestra el pantallazo completo. Para ocultar
información puedes utilizar retardos con animaciones <code>css</code> pero es un
engorro.
</p>

<p>
¿Qué no me gusta de <code>reveal.js</code>? Pues básicamente que me mete algunas
opciones que necesitan de otro <code>javascript</code> en <i>plugins</i> y me
dificulta un poco el poder meter a mano cualquier otro que no esté
conformado como <i>plugin</i>.
</p>

<p>
Luego la diferencia fundamental entre los dos, desde el punto de vista
del usuario es qué tipo de cabeceras tienes que escribir. El contenido
que hay entre ellas puede ser prácticamente el mismo.
</p>

<p>
Por cierto, creo que lo he dicho ya, pero no viene mal recordarlo si
no es así, que tanto <code>impress</code> como <code>reveal</code> tienen modos y
exportadores desde <code>org-mode</code>. Quizá esto me facilitará la vida, pues
no los he probado. No descartéis otro artículo hablando de ello, pero
de momento, siguen sin llamarme la atención.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ya me perdonaréis pero he sido incapaz de que aparecieran las
flechas hacia abajo... os podéis imaginar que están cuando hay
<i>traspa</i> debajo.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/presentación/index.html">presentación</a> ]]></description>
  <category><![CDATA[presentación]]></category>
  <link>https://notxor.nueva-actitud.org/2020/09/11/las-tres-herramientas-de-presentacion-que-utilizo.html</link>
  <pubDate>Fri, 11 Sep 2020 23:40:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[La calculadora de Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-09-04</div>
<p>
A los que usan <i>Emacs</i> no les extraña que entre las muchas cosas que
trae nuestro editor favorito, aparezca una calculadora: <i>Calc</i>.  Sin
embargo, y yo entre ellos, no es fácil encontrar a alguien que la
utilice de forma asidua y se entretenga en explicar un poco cómo
funciona. Sólo un poco, porque en un artículo como este es imposible
abarcarlo todo.  Al principio me tenía que forzar a usarla, me costó
acostumbrarme a sus <i>idiosincrasias</i>, a la <i>notación polaca inversa</i> y
a sus modos de funcionamiento. Ahora me parece una de esas
herramientas imprescindibles para el día a día... bueno,
imprescindibles es una palabra muy amplia, antes me apañaba sin <i>Calc</i>
con una calculadora de escritorio como la de KDE (<i>Kcalc</i>), con una
interfaz gráfica a la que estamos más acostumbrados, con pulsar los
botones con el ratón, etc. Quiero decir que, puesto que tengo una
sesión de <i>Emacs</i> abierta casi el 100% del tiempo, me cuesta muy poco
acceder a ella. Aunque no funciona exactamente como esas otras
calculadoras: <i>Calc</i> tiene una <i>interface</i> de texto y tienes que
aprenderte <i>palabros</i> raros como <i>Notación Polaca Inversa</i> o <i>Pila</i>
(para los amantes del guiri: <i>Stack</i>).
</p>

<p>
Repito el aviso y paso ya al tema, que a lo mejor os interesa más que
mi palabrería: este artículo no pretende ser un manual completo, ni
tan siquiera un <i>tutorial</i> de uso de una herramienta tan compleja;
apenas es una introducción a su uso, el intento de aclarar algunos
conceptos básicos para hacerlo y una muestra de lo que puede hacer
<i>Emacs</i> para facilitarnos la vida.
</p>
<div id="outline-container-orgda9aefb" class="outline-2">
<h2 id="orgda9aefb">Calc</h2>
<div class="outline-text-2" id="text-orgda9aefb">
<p>
¿Qué es <i>Calc</i> y qué nos proporciona?<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> Pues si atendemos a su
documentación nos encontramos con algunas características:
</p>

<ul class="org-ul">
<li>Elección de modo algebraico o <i>Notación Polaca Inversa</i> (basada en
pila).</li>
<li>Selección de la precisión de enteros y números decimales.</li>
<li>Aritmética de números racionales, números complejos... vectores,
matrices, fechas y horas, infinitos, cantidades con unidades,
fórmulas algebraicas...</li>
<li>Operaciones matemáticas como logaritmos y funciones
trigonométricas.</li>
<li>Características para programadores: operaciones de bits y números no
decimales.</li>
<li>Funciones financieras.</li>
<li>Funciones de teoría de números, como la factorización de números
primos o el módulo aritmético.</li>
<li>Características de manipulación algebraica como el cálculo
simbólico.</li>
<li>Mover datos desde, o hacia, <i>buffers</i> de edición.</li>
<li>Modo de insertar y manipular fórmulas de <i>Calc</i> y datos directamente
en una <i>buffer</i> de edición.</li>
<li>Gráficos utilizando <code>GNUplot</code>.</li>
<li>Fácilmente programable utilizando macros de teclado, fórmulas
algebraicas o mediante <code>elisp</code>.</li>
</ul>

<p>
Pero, mierda, <i>si yo sólo quiero sumar unas pocas cantidades mientras
repaso las facturas</i>. Pues a eso voy, que, ni que decir tiene, es el
principal uso que le estoy dando, pero que sepáis que se pueden hacer
todas esas cosas... de momento vamos con un ejemplo sencillo. Un
cálculo sin muchas pretensiones, utilizando los dos modos principales
para comparar.
</p>

<p>
Primero voy a utilizar el modo algebraico y después el modo de pila, o
<i>polaco inverso</i>, para demostrar que ambos métodos llegan a las mismas
conclusiones. Para ilustrarlo utilizo un sencillo cálculo:
\(\sqrt{(2+3)}\) ... vamos a ello:
</p>

<ol class="org-ol">
<li><p>
Abre <i>Calc</i> con la combinación de teclas <code>C-x *</code> (yo suelo utilizar
el <code>*</code> del teclado numérido). Después pide que pulses otra tecla
normalmente será <code>c</code> para <i>Calc</i>, pero puedes investigar otros
modos con <code>?</code><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. Mostrará un <i>bufer</i> en la parte inferior de <i>Emacs</i>
tal que:
</p>
<pre class="example" id="org0ca2e66">
--- Emacs Calculator Mode ---
    .
</pre></li>
<li><p>
Para introducir la operación en modo algebraico: pulsa la tecla <code>'</code> y en
el minibuffer aparecerá el mensaje <code>Algebraic:</code>, a partir de los
dos puntos escribe <code>sqrt(2+3)</code> y pulsa <code>&lt;RET&gt;</code>.  El <i>buffer</i>
anterior ha cambiado a:
</p>
<pre class="example" id="org23a8153">
--- Emacs Calculator Mode ---
1:  2.2360679775
    .
</pre></li>
<li><p>
¿Cómo se haría en modo pila?: Pues vuelve a la ventana de <i>Calc</i> y
pulsa <code>2</code>, en el minibuffer aparecerá <code>Calc: 2</code>, pulsa <code>&lt;RET&gt;</code>:
</p>
<pre class="example" id="org97088e3">
--- Emacs Calculator Mode ---
2:  2.2360679775
1:  2
    .
</pre>

<p>
Repite el proceso con el número <code>3</code>:
</p>
<pre class="example" id="orgd25512e">
--- Emacs Calculator Mode ---
3:  2.2360679775
2:  2
1:  3
    .
</pre>
<p>
Fíjate que en la <i>pila</i> tenemos almacenados tres valores, el
cálculo que hicimos en modo algebraico y los números <code>2</code> y <code>3</code>.
Fíjate también en que ambos números ocupan las primeras dos
posiciones de abajo. Ahora cuando pulsemos <code>+</code> realizará la suma de
ambas.
</p>
<pre class="example" id="org7a7e715">
--- Emacs Calculator Mode ---
2:  2.2360679775
1:  5
    .
</pre>
<p>
No hace falta pulsar <code>&lt;RET&gt;</code> puesto que lo interpreta como un
comando de operación, en este caso necesita tener dos valores en la
pila, como las operaciones <code>+</code>, <code>-</code>,=*= y <code>/</code>, por ejemplo. Sin
embargo, la siguiente operación necesita sólo un valor: pulsa
<code>Q</code>... con atención a la mayúscula, porque <code>q</code> es el comando de
salir.
</p>
<pre class="example" id="org1381325">
--- Emacs Calculator Mode ---
2:  2.2360679775
1:  2.2360679775
    .
</pre></li>
</ol>

<p>
Algunos pensarán que el modo algebraico es el más directo y sencillo y
no hay que teclear tanto. En realidad no es así: si cuentas las
pulsaciones de teclas has salido perdiendo: <code>'</code>, <code>s</code>, <code>q</code>, <code>r</code>, <code>t</code>,
<code>(</code>, <code>2</code>, <code>+</code>, <code>3</code>, <code>)</code>, <code>&lt;RET&gt;</code>... en modo pila: <code>2</code>, <code>&lt;RET&gt;</code>, <code>3</code>,
<code>&lt;RET&gt;</code>, <code>+</code>, <code>Q</code>.
</p>

<p>
Pero si lo que necesitas es una calculadora con botones y demás,
también puedes tenerla si utilizas <i>Emacs</i> en modo gráfico. En lugar
de lanzar <i>Calc</i> con la combinación <code>C-x * c</code> lo haces con la
combinación <code>C-x * K</code> (modo <i>Keypad</i>). Y ya tienes un teclado sobre el
que pulsar con el ratón.
</p>

<p>
Si no estás en <i>Emacs</i> y quieres utilizar su calculadora porque ya le
has cogido vicio puedes llamarla desde la línea de comandos:
</p>

<div class="org-src-container">
<pre class="src src-shell">emacs -f full-calc
</pre>
</div>

<p>
o, si quieres que aparezca el teclado numérico:
</p>

<div class="org-src-container">
<pre class="src src-shell">emacs -f full-calc-keypad
</pre>
</div>
</div>
<div id="outline-container-org972ae5b" class="outline-3">
<h3 id="org972ae5b">Uso de andar por casa</h3>
<div class="outline-text-3" id="text-org972ae5b">
<p>
Cuando más utilizo <i>Calc</i> es cuando estoy liado con las facturas. Es
bastante agradecido el <i>modo pila</i> pues me permite ir almacenando
valores e incluso cambiar su orden pulsando <code>M-&lt;TAB&gt;</code>. Me permite
también, copiar valores ya introducidos. Como el camino se demuestra
andando, vamos con un ejemplo, también por pasos:
</p>

<ol class="org-ol">
<li><p>
Si no tienes activado <i>Calc</i> actívalo... si te molestan cálculos
anteriores borra con la tecla retroceso hasta que te aparezca el
habitual estado:
</p>
<pre class="example" id="orga85551d">
--- Emacs Calculator Mode ---
    .
</pre></li>
<li><p>
Introduce en la pila los número <code>1</code>, <code>2</code> y <code>3</code> por ese orden... te
quedará algo como:
</p>
<pre class="example" id="org8009317">
--- Emacs Calculator Mode ---
3:  1
2:  2
1:  3
    .
</pre></li>
<li><p>
Sólo por probar y para que se vea vamos a cambiar el orden pulsando
una vez <code>M-&lt;TAB&gt;</code>:
</p>
<pre class="example" id="org12c4dc9">
--- Emacs Calculator Mode ---
3:  2
2:  3
1:  1
    .
</pre></li>
<li><p>
Necesitamos copiar el valor <code>3</code>, que está situado en la posición
<i>2</i> de la pila: pulsa <code>M--</code> (sí, la tecla <i>Alt</i> con el guión <code>-</code>) y
después <code>2</code>, el número de orden en la pila.
</p>
<pre class="example" id="orge3ee9a8">
--- Emacs Calculator Mode ---
4:  2
3:  3
2:  1
1:  3
    .
</pre></li>
<li><p>
Por juguetear un poco más, imaginemos que necesitamos sumar los
últimos dos números pero sin que desaparezcan de la pila. Para ello
pulsamos <code>M-2</code>:
</p>
<pre class="example" id="org839f4bf">
--- Emacs Calculator Mode ---
6:  2
5:  3
4:  1
3:  3
2:  1
1:  3
    .
</pre>
<p>
vemos que ha copiado las dos primeras posiciones de la pila. Ahora
pulsamos <code>+</code> y obtenemos el resultado:
</p>
<pre class="example" id="org1d5f866">
--- Emacs Calculator Mode ---
5:  2
4:  3
3:  1
2:  3
1:  4
    .
</pre></li>
</ol>

<p>
¿Qué demuestra todo esto? Pues básicamente que puedo jugar con <i>la
pila</i> para almacenar los valores más habituales e implicarlos en los
cálculos, sin destruir lo almacenado. Algo bastante útil cuando en
tareas tediosas como la contabilidad se repiten los mismos valores
varias veces.
</p>

<p>
Además de jugar con <i>la pila</i> también se pueden almacenar valores en
variables de una manera sencilla. Por ejemplo, basta con pulsar <code>s s</code>
y nos pedirá un nombre de variable para guardar el valor de la
cabecera (<code>1</code>) de la pila en ella... para devolver el valor de dicha
variable a la cabecera basta con pulsar <code>s r</code>. Además con las
variables se pueden realizar también cálculos directos sin pasar por
la pila, pero eso ya cada uno que se lo mire en la documentación.
</p>

<p>
Además, por si no tienes suficiente con las variables, también se
pueden almacenar y recuperar valores desde los <i>registros</i> de
<i>Emacs</i>.
</p>
</div>
</div>
<div id="outline-container-org57704a5" class="outline-3">
<h3 id="org57704a5">Corrección de errores</h3>
<div class="outline-text-3" id="text-org57704a5">
<p>
Es posible que cuando estamos trabajando nos equivoquemos en alguna
operación y queramos deshacer alguna operación. Por ejemplo, porque
nos damos cuenta que hemos hecho una resta en lugar de una suma, o al
revés: pulsamos la tecla <code>U</code> en mayúscula (<i>undo</i> para los amantes
del guiri)... Si nos damos cuenta que, efectivamente lo habíamos hecho
bien podemos pulsar <code>D</code> (también en mayúscula) que repetirá la acción
(<i>redo</i> para los guiris).
</p>
</div>
</div>
<div id="outline-container-org2f1d8e8" class="outline-3">
<h3 id="org2f1d8e8">Precisión</h3>
<div class="outline-text-3" id="text-org2f1d8e8">
<p>
Por defecto, <i>Calc</i> suele arrancar con la precisión en 12 decimales,
que para la mayoría de cálculos son más que suficientes, pero se puede
cambiar a la precisión que se quiera.
</p>

<p>
Para saber qué precisión estamos utilizando basta ver la línea de
estado del <i>buffer</i> de <i>Calc</i> y veremos que pondrá un mensaje del tipo
<code>Calc: 12 Deg</code>. La precisión debe ser, al menos, de tres dígitos, sin
embargo, si le pedimos una precisión de 2300 decimales no va a
protestar.
</p>

<p>
También podemos cambiar el formato de los números a otros formatos
como el de <i>coma fija</i>, la <i>notación científica</i> (hay más modos pero
no los uso.
</p>

<ul class="org-ul">
<li><code>d n</code> para visualizar los números en <i>modo normal</i></li>
<li><code>d s</code> para visualizar los números en <i>modo científico</i></li>
<li><code>d f</code> para visualizar los números en <i>coma fija</i>.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org3db137f" class="outline-2">
<h2 id="org3db137f">Conclusión</h2>
<div class="outline-text-2" id="text-org3db137f">
<p>
Con esta introducción apenas he rascado un poco en la superficie de
esta herramienta. Suena casi a profanación utilizarla para sólo hacer
unas pocas sumas y productos; pero, como dice el refrán: <i>burro grande
ande o no ande</i>, y en este caso es así, sabes que es una herramienta
completa, compleja y potente. Parece que quieres matar moscas a
cañonazos, pero en realidad sirve para <i>lo mucho</i> y para <i>lo poco</i> y
cada uno la usará según sus necesidades.
</p>

<p>
Y si alguien tiene necesidades de cálculo más complejas sabrá que la
tiene a mano, para cálculos financieros, para cálculo de vectores o de
matrices, para cálculos trigonométricos... Todo sin salir de tu editor
favorito y sin separar los dedos del teclado.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
He de advertir que mi uso de <i>Calc</i> es mucho más prosaico.
Apenas realizo algunos cálculos sencillos y si alguien quiere
exprimirle todo el potencial que tiene, debería leerse la
documentación que viene con <i>Emacs</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Otro modo bastante utilizado es <code>K</code> para <i>keypad</i> que muestra
un teclado donde se puede utilizar el ratón (si estás en modo gráfico). 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2020/09/04/la-calculadora-de-emacs.html</link>
  <pubDate>Fri, 04 Sep 2020 20:46:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Problemas con Emacs 27 en OpenSuse Tumbleweed]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-08-28</div>
<p>
Llevo unos días, desde que apareció la versión 27.1 de <i>Emacs</i> en el
repositorio de OpenSuse Tumbleweed ─la distribución de GNU/Linux que
utilizo─, con un problema persistente durante la ejecución de mi
editor favorito: <i>Emacs</i>.
</p>

<pre class="example" id="org4bfd056">
Wrong type argument: stringp, (require . info)
</pre>

<p>
Además lo hacía de forma intermitente y no muy consistente. Por poner
un ejemplo, cuando lanzaba el editor en una consola proporcionándole
el fichero que quería editar, digamos tal que así:
</p>

<div class="org-src-container">
<pre class="src src-shell">emacs -nw ~/proyectos/miproyecto/fichero.erl
</pre>
</div>

<p>
El <code>erlang-mode</code> funcionaba sin ningún problema y podía editar el
código con la comodidad que proporciona <i>su modo</i> correspondiente...
Aparecían otros problemas, por ejemplo al abrir un directorio en
<code>Dired</code>, mostraba un <i>warning</i> tal que:
</p>

<pre class="example" id="org7f30646">
Warning (emacs): Fail create hash table
  buffer: #&lt;buffer :~/proyectos/miproyecto/&gt;
  stdout:
  reason: (end-of-file)
</pre>

<p>
No le di mucha importancia, porque pensaba que era algún paquete
obsoleto de versiones anteriores y no me puse a buscar por pereza:
cargar el depurador, ejecutar el <code>init.el</code> paso a paso a ver qué
paquete da por culo, intentar arreglar el fallo o condenarlo al
ostracismo hasta que el mantenedor lo arregle. En fin, un montón de
incomodidades que asumir cuando la molestia era mínima: podía trabajar
con normalidad.
</p>

<p>
El problema fue cuando hace dos días dejó de funcionar <code>magit</code>; esto
ya no era tolerable y me puse a indagar cómo solucionar el problema.
Y como he dicho antes, comencé a cargar el <code>init.el</code> poco a poco...
no encontré nada.
</p>

<p>
Cambié de filosofía: arrancar con <i>Emacs</i> pelado e ir haciendo la
carga de paquetes uno a uno, sólo los necesarios. El problema
persistía, sin inmutarse, incluso cargando <i>Emacs</i> con la opción <code>-q</code>.
</p>

<p>
Busqué información del error por los foros y la <i>wiki</i> de <i>Emacs</i> y no
encontré nada. Pregunté a algunos amigos que saben de esto mucho más
que yo y no encontré respuesta: a todo el mundo le funcionaba la
versión 2.7 perfectamente. La conclusión de esa investigación: «debo
ser yo»... bueno, más bien debe ser mi configuración o algo <i>¿Habré
depurado mal?</i>
</p>

<p>
<i>Pues nada, a insistir</i>. Habré depurado mi <code>init.el</code> como tres o
cuatro veces. No ha sido tiempo perdido porque encontré algunas cosas
mejorables que he aprovechando que por Valladolid pasa el Pisuerga...
sin embargo, el problema persistía contumaz. Tan cabezón él, que
estuvo a punto de ganarme en cabezonería.
</p>

<p>
De casualidad, me dio por arrancar una de las veces el <i>Emacs</i>
llamando a <code>/usr/bin/emacs-gtk</code> y... <i>el problema no existe</i>.  <i>¿Cómo?
¿Qué está pasando aquí?</i> Pues eso, que el problema no está en <i>Emacs</i>
sino en otro sitio. Investigando un poco, he visto que en mi sistema
están instalados varios ejecutables del editor, algo que ya conocía
pero que nunca le prestas atención. Concretamente están: <code>emacs-gtk</code>,
<code>emacs-x11</code> y <code>emacsclient</code>. Además, también hay un <i>script</i> en <code>bash</code>
que selecciona qué ejecutable lanzar según los parámetros y otras
circunstancias, que se llama <code>emacs</code>. Cuando llamo al <i>script</i> se
produce el error, cuando llamo directamente al ejecutable que sea,
está libre de errores y advertencias.
</p>

<p>
<b>Solución</b>: He creado mi propio <i>script</i> <code>emacs</code>. Para no interferir
con el paquete de la <i>distro</i> lo he colocado en mi directorio
<code>~/opt/bin/</code>. En el directorio <code>~/opt/</code> tengo todas esas aplicaciones
y herramientas que las instalo desde código fuente para mi usuario. Y
para la ejecución de programas, tiene preferencia sobre los más
generales del sistema. El <i>script</i> que me he hecho no puede ser más
fácil y simple, <i>no vayamos a cagarla de nuevo con la tontería</i>:
</p>

<div class="org-src-container">
<pre class="src src-shell">/usr/bin/emacs-gtk $<span style="color: #f8f8f2; font-weight: bold;">@</span>
</pre>
</div>

<p>
Ese simple <i>script</i> ha venido a solucionar un problema muy tonto,
permitiéndome seguir trabajando como hasta ahora.
</p>
<div id="outline-container-orga8b936e" class="outline-2">
<h2 id="orga8b936e">Conclusión</h2>
<div class="outline-text-2" id="text-orga8b936e">
<p>
Hoy más que un artículo es una anotación y no explico grandes
herramientas sino pequeños problemas con sus pequeñas soluciones. Lo
hago más para acordarme en sucesivas actualizaciones que estoy
corriendo una versión simplificada de un <i>script</i> que seguramente
arreglarán los mantenedores del paquete en breve. Y también, por si
acaso a otros usuarios les ha ocurrido lo mismo, y como yo, no han
encontrado nada, ninguna referencia, de cómo poder solucionarlo.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/opensuse/index.html">opensuse</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[opensuse]]></category>
  <link>https://notxor.nueva-actitud.org/2020/08/28/problemas-con-emacs-en-opensuse-tumbleweed.html</link>
  <pubDate>Fri, 28 Aug 2020 23:51:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[La pragmática y las conversacionales]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-08-26</div>
<p>
Hace algún tiempo ya comenté por aquí el proyecto personal en el que
me encuentro metido. Llevo un tiempo ya en él, de forma seria y
metódica apenas un mes.  Tengo planteados ya, creo, los principales
comandos de movimiento de los personajes. El sistema ya puede generar
nuevos personajes desde la misma consola y todo va según lo
previsto. Sin embargo, aún me falta mucho para alcanzar el objetivo
que me he planteado y una de las cosas que me falta es conseguir que
los PnJ<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> sean algo más creíbles en la interacción con los
PJ<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>, de lo que lo son en los MUDs convencionales.
</p>

<p>
Por supuesto, para ese objetivo me había planteado hacer que los PnJ,
o <i>bots</i> si lo preferís llamar así, sean <i>conversacionales</i>. Es decir,
tengan la capacidad de interactuar con los jugadores, lingüísticamente
de una manera más natural, cuanto más natural mejor y en estas me hayo
embarcado. Porque el tema podría resumirse a dejar que el <i>bot
conversacional</i> sea <a href="https://es.wikipedia.org/wiki/ELIZA">una especie de <i>Eliza</i></a> y poco más. Sin embargo,
como ya sabe quien esté leyendo esto, soy persona de complicarme la
vida y plantearme porqués. Además <i>Eliza</i> tira de convenciones de la
terapia humanista y no necesito que todos los personajes del MUD sean
psicólogos obsoletos técnicamente.
</p>

<p>
En los MUDs tradicionales, normalmente, los PnJ con los que te
encuentras tienen unas funciones lingüísticas muy limitadas: apenas
dos frases para simular un comerciante, un bancario; o incluso menos,
para simular un enemigo al que hay que <i>matar</i>. Esas conversaciones se
me quedan escasas cuando estoy planteando un mundo básicamente
<i>pacífico</i>, donde no se ha de <i>matar</i> a todo lo que se mueva para
<i>ganar experiencia</i> para ascender en el escalafón de <i>niveles</i>, sino
que se trata de explorar, principalmente, puntos de vista.
</p>
<div id="outline-container-org766a3b3" class="outline-2">
<h2 id="org766a3b3">Pragmática</h2>
<div class="outline-text-2" id="text-org766a3b3">
<p>
Así he llegado a toparme con la <i>pragmática</i>, que es una rama de la
lingüística que estudia la muy humana conducta de comunicación.
Supongo que a estas alturas del partido, el que más y el que menos ya
conoce lo básico sobre comunicación: el emisor, el receptor, el canal,
el código, el mensaje, el <i>feedback</i>, el contexto... la primera vez
que lo vieron seguramente fue en la escuela y para la mayoría de las
personas no representó más que algunas definiciones más que aprender y
poco más. Más adelante, habrán visto ese mismo contenido, espero que
ampliado, en cualquier ciclo de formación o curso que implique la
comunicación entre personas. Sin embargo, ese temario se limita a
establecer y describir los <i>elementos</i> que intervienen en la
comunicación (es decir, los <i>qués</i>), sin complicarse mucho en los
<i>cómos</i> o los <i>porqués</i>. Y aquí es donde aparece la <i>pragmática</i> para
explicarnos que cualquier comunicación humana está referida a un
contexto y parte de unos supuestos básicos y comunes.
</p>

<p>
Efectivamente, para lo que quiero hacer todo esto es bastante
relevante. Estoy simulando un <i>mundo completo</i>, no sólo con su
<i>terreno</i> o <i>localizaciones</i>, también con su <i>historia</i>, su
<i>mitología</i>, su <i>religión</i>. Si quiero coherencia en los personajes
debo partir del hecho de que los PnJ dentro del mundo deben hablar a
partir de conceptos previos que se dan por supuestos, pero que los PJ
no conocerán incluso aunque se hayan leído toda la documentación que
sobre dicho mundo se genere. Es decir, muchas horas de trabajo.
</p>

<p>
Para empezar, no escribimos como hablamos. En nuestro discurso escrito
no es tan fácil establecer <a href="https://es.wikipedia.org/wiki/Deixis">referencias relativas (<i>deixis</i>)</a> como
durante el discurso hablado. No es tan fácil, digo, emplear palabras
tan fundamentalmente ambiguas como todos los relativos: <i>aquí</i>,
<i>allí</i>, <i>hoy</i>, <i>ayer</i>...  Efectivamente, no podemos, ni debemos,
suponer que un texto será leído en el mismo momento en que fue
escrito, por lo que el desarrollo del discurso debe ser mucho más
preciso en los tiempos, los lugares, las referencias.
</p>

<p>
Como en todos los campos que intentan estudiar el comportamiento
humano, me encuentro con varias teorías, algunas de ellas
contrapuestas<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> y todas con su punto de razón. Así que voy a ver si me
aclaro yo mismo y soy capaz de encontrar el camino correcto entre
ellas diseñando las <i>conversaciones</i> de mis PnJ. Empezando por la que
me parece más relevante de explotar.
</p>
</div>
<div id="outline-container-orgea23dd6" class="outline-3">
<h3 id="orgea23dd6">Teoría de Grice</h3>
<div class="outline-text-3" id="text-orgea23dd6">
<p>
Esta teoría, formulada por <i>Herbert Paul Grice</i>, parte del supuesto de
que el principio básico de toda comunicación humana es el <i>principio
de cooperación</i>, es decir: cuando se produce una comunicación tanto el
oyente como el hablante cooperan para entenderse. Este principio de
cooperación, Grice, lo divide en cuatro partes o máximas:
</p>

<ul class="org-ul">
<li><b>Máxima de cualidad o calidad</b>: Esperamos que la comunicación se
basa en premisas verdaderas. Esta máxima es la que explotan los
<i>bulos</i> para difundirse, aprovechando la pulsión cooperativa del
interlocutor.
<ol class="org-ol">
<li>No digas nada que sepas que es falso.</li>
<li>No digas nada de lo que no tengas pruebas</li>
</ol></li>
<li><b>Máxima de cantidad</b>: va sobre la cantidad de información necesaria
para que se produzca la correcta comunicación, tanto por exceso como
por defecto.
<ol class="org-ol">
<li>Da toda la información necesaria.</li>
<li>No des más información de lo necesario, pesado.</li>
</ol></li>
<li><b>Máxima de relevancia</b>: Grice la expresa como <i>vaya usted al
grano</i>. Básicamente es que en una conversación esperamos recibir
información relevante sobre el tema tratado. Es decir, si
preguntamos por el estado de salud de un amigo y no responde que
«todos los días corro ocho kilómetros». Su respuesta no contesta a
nuestra pregunta directamente, pero basándonos en este principio,
inferimos que para correr 8 kilómetros todos los días hay que estar
sano y en forma<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>.</li>
<li><b>Máxima de modalidad</b>: Se refiere al modo en el que se produce la
comunicación, también lo podemos expresar como «sé claro»:
<ol class="org-ol">
<li>Evita la oscuridad.</li>
<li>Evita la ambigüedad.</li>
<li>Sé escueto.</li>
<li>Sé ordenado.</li>
</ol></li>
</ul>

<p>
Como vemos es una teoría bastante descriptiva de la conducta de
comunicación y podemos ver que en muchas ocasiones el humor se basa en
contradecir alguna de estas máximas, introduciendo doble sentido o
aplicando <i>literalidad</i>, o por ejemplo, en la serie de <i>Big Bang
Theory</i>, con la incapacidad de <i>Sheldon Cooper</i> de entender y seguir
esas convenciones comunicativas.
</p>

<p>
Además puede haber otras <i>limitaciones</i> de la conducta comunicativa
como <i>la cortesía</i>. La lingüista <i>Robin Lakoff</i> definió la cortesía
como una herramienta para suavizar los roces en la interacción social
y el mismo <i>Grice</i> reconoció que además de sus cuatro máximas podíamos
encontrar limitaciones en las interacciones con condicionantes como el
ser <i>cortés</i>.
</p>
</div>
</div>
<div id="outline-container-orgc675458" class="outline-3">
<h3 id="orgc675458">Teoría de los actos del habla</h3>
<div class="outline-text-3" id="text-orgc675458">
<p>
Como no podía se de otra forma, hay teorías que, en cierto modo, se
contraponen a la anterior. Pero para verlo, primero tenemos que
entender lo que es la <i>falacia descriptiva</i>: una afirmación puede ser
cierta, falsa o «sin sentido». Es decir, interviene una tercera
categoría de aquellas afirmaciones que no son <i>ciertas</i> ni <i>falsas</i>.
El problema se expande, además, porque algunas de las afirmaciones
<i>sin sentido</i> son tomadas como ciertas o falsas. Por ejemplo, si yo
hago la afirmación de «yo miento» en buena lógica debería ser
clasificada como <i>sin sentido</i>, no puedo mentir y decir la verdad al
mismo tiempo.
</p>

<p>
<i>John Langshaw Austin</i> además se dedica a estudiar esas comunicaciones
que no son meramente descriptivas, sino lo que él denomina
<i>performativas</i>, es decir: la comunicación que además de transmitir
información realiza acciones o cambia la misma realidad. Por ejemplo,
al hecho de decir «sí, quiero» durante una boda implica el acto de
contraer matrimonio cambiando tu estado civil. Si durante un acto
académico el Rector afirma «queda inaugurado el curso académico», no
sólo es una afirmación informativa, sino que legalmente, a partir de
ese momento, se entra en el nuevo curso.
</p>

<p>
Muchas de las expresiones <i>performativas</i> no son ni verdaderas ni
falsas y llegaríamos a la <i>Teoría de los infortunios</i> cuando son
falsas. Por ejemplo, si la expresión «queda inaugurado el curso
académico» la hiciera el conserje, la cual podría interpretarse desde
una intención irónica, carecería de sentido estricto.
</p>
</div>
</div>
</div>
<div id="outline-container-orgd79742b" class="outline-2">
<h2 id="orgd79742b">Conclusiones</h2>
<div class="outline-text-2" id="text-orgd79742b">
<p>
En otras palabras, me encuentro en fregado no sólo técnico sino
teórico. Quiero hacer un sistema más o menos realista. No espero que
supere el <i>test de Turing</i> como <i>bot conversacional</i>, o más bien
<i>bots</i>, porque los PnJ serán varios y entiendo que no todos deben ser
igual de comunicativos y además no deben tener los mismos
«conocimientos» previos.
</p>

<p>
Me encuentro devanándome los sesos de cómo aprovechar todas estas
cosas para implementar un sistema sencillo. Por ejemplo, <i>Eliza</i> se
basa en el máxima de relevancia estableciendo «temas» buscando
determinadas palabras clave para emitir su frase dentro del «tema» o
cambiando por completo de conversación si no puede determinar por la
entrada proporcionada por el humano el tema sobre el que se está
hablando.
</p>

<p>
Pero está claro que necesitaré generar una gran base de datos de
«frases» con conocimientos generales sobre el mundo en cuestión: su
geografía, su antropología, su mitología, etc. para poder responder a
las preguntas de carácter general que formulen los jugadores. Y esto
implica un diseño de mundo mucho más definido y concreto que muchos
MUDs cuando se inician... y eso es: <i>muchas horas de trabajo</i>.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Personaje no Jugador</i>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Personaje Jugador</i>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Seguramente diseñadas así para confundirme a mí. 
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Aunque puede estar en forma pero el colesterol salirle por las
orejas a borbotones.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/conversacionales/index.html">conversacionales</a> <a href="/tags/aventuras/index.html">aventuras</a> <a href="/tags/juegos/index.html">juegos</a> ]]></description>
  <category><![CDATA[conversacionales]]></category>
  <category><![CDATA[aventuras]]></category>
  <category><![CDATA[juegos]]></category>
  <link>https://notxor.nueva-actitud.org/2020/08/26/la-pragmatica-y-las-conversacionales.html</link>
  <pubDate>Wed, 26 Aug 2020 23:29:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Esperanton mi sopiras]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-08-21</div>
<p>
Ja: Esperanton mi sopiras. Ĉi tiuj lastaj monatoj hejme mi pensis pri
gravajn aferojn en la vivo.  Finfine mi nur konkludis kiel Miguel
Hernández: <i>trivundita mi venas: per la morto, per la amo, per la
vivo</i>. Kaj fakte tiel mi pensas. Mi pripensis pri la morto de tiuj,
kiuj la kronviruso forŝtelis, inter ili mian maljunan onklon. Ili
malaperis preskaŭ sen bruo, dum ni nur rigardis senvizaĝajn numerojn.
Dum ni nur aŭskultis senanimajn ciferojn.
</p>

<p>
Mi ankaŭ pensis pri la vivo, tiu ke la kronviruso rabis nin. La vivo
kiu malaperis tiel subite kiel nokto devenas tago por lasi al ni nur
la <i>novan realon</i>. Vivo kiu daŭras sed ne kiel ni planis, pensis aŭ
deziris.
</p>

<p>
Kaj ankaŭ mi pensis pri amo, pri amo inter la homoj ĉar ni devas varti
niajn maljunulojn. Ni devas zorgi nian komunan sanon. Mi vidas
egoistajn homojn, frenezulojn kiuj nur serĉas sian propran plezuron
kaj forgesis tion, ke la forto de la homoj estas la komunumo. Aĉaj
uloj kiuj meritas vivi solaj.
</p>

<p>
Mi finfine pensis pri ĉi tiuj aferoj kaj konkludas kiel Miguel
Hernández diris: <i>vivo, morto, amo tie restas en via lipo skribataj</i>.
</p>

<p>
Kiam mi pensis pri kion mi sopiras, mi trovis la mankon de miaj
<i>fratoj</i> de la Frateco el Zaragozo. Al mi mankas tiujn
liberapensulojn, tiujn bonkorajn amikojn kaj, ankaŭ, al mi mankas la
vortojn pro tia esprimo ĉar la malmulta praktiko. Mi, certe, sopiras
la rakontojn de niaj naŭdekjaraĝaj junuloj, plenaj de saĝeco kaj
avertoj, kiam ili rakontis pri tiuj jaroj, kiuj la esperantistoj estis
persekutataj, pri la vojaĝoj tra Eŭropoj kiam la vojoj ne estis tiel
malfermaj. Mi sopiras la revojn de tiuj frenezaj homoj, kiuj pensas
pri la plej bona homaro, pri la plej bona mondo.  Eble ni povas diri
tion, ke <i>ni vidis brili revojn en la mallumo ĉe la Pordo de
Tanhaŭsen' sed tiuj aferoj malaperos kiel larmoj en la pluvo</i>.  Ja,
tiujn revojn malaperos se ni ne povas kunrevi ilin.
</p>

<p>
Mi sopiras mian Esperanton. Ĉi tiuj lastaj monatoj mi perdis tiujn
vortojn, kiuj eble mi povus uzi por esprimi tiun senton. Mi korektis
ĉi tiun skribaĵon du fojoj kaj mi certas tion, ke ĝi estas plena de
eraroj. Pardonu mian mallerton, mi apenaŭ praktikis: mi sopiras
Esperanton.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <link>https://notxor.nueva-actitud.org/2020/08/21/esperanton-mi-sopiras.html</link>
  <pubDate>Fri, 21 Aug 2020 00:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Las conchas de tu madre]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-08-08</div>
<p>
Pues hoy vengo a hablar de <i>conchas</i> ─o <i>shells</i>, en inglés─ dentro
del entorno de <i>Emacs</i>. No pude resistirme a la tentación de escribir
el título así, ya me perdonará quien entienda otra cosa o piense que
va leer algún tipo de artículo soez o socarrón, quizá <i>campechano</i>,
sobre temas reproductivos humanos. Pero lamentablemente la cosa va de
herramientas que vienen con nuestro editor favorito.
</p>

<p>
Esto parte de una conversación en <a href="https://t.me/notxorblog">el canal de Telegram</a> del
<i>blog</i>. Patricio nos preguntó por qué no utilizábamos más <code>eshell</code> o
por qué no hablábamos de él. Nos hizo una pequeña demostración con un
par de ejemplos para demostrarnos su potencia y la cosa quedó
ahí... bueno, no del todo, porque ahora os vengo a <i>cansinar</i> yo con
<i>las conchas</i>.
</p>

<p>
Efectivamente, son las conchas, porque hay más de una opción y cada
una tiene su <i>clít</i>... cosa. Pero para resumir las enumero y luego
hacemos hincapié más despacio en ellas, con algunos trucos y todo.
</p>

<ul class="org-ul">
<li><code>shell</code>: Ejecuta el <i>shell</i> predeterminado del sistema, en mi caso
es <code>bash</code>, dentro de un <i>buffer</i> de <i>Emacs</i>. Se llama a esta función
con el comando <code>M-x shell</code>. Es una <i>subshell</i> y no podrá ejecutar
todos los comandos que se le pasen, por ejemplo, no funcionan
aquellos programas que funcionan sobre <code>curses</code> o cosas más
visuales.</li>
<li><code>term</code>: Ejecuta el <i>shell</i> que le digamos, pues pregunta antes de
lanzar un terminal. Este comando abre un terminal completo en un
<i>buffer</i> de <i>Emacs</i>. Es interactivo, como el anterior y además sí
funcionarán las aplicaciones basadas en <code>curses</code>. La forma de
invocarlo puede ser <code>M-x term</code> desde el <i>minibuffer</i> o <code>ansi-term
  bash</code> desde código (sustitúyase <code>bash</code> por <code>zsh</code> o cualquier otro
<code>shell</code> de nuestra preferencia).</li>
<li><code>eshell</code>: Este paquete es un emulador de terminal escrito
enteramente en <code>elisp</code>. Funciona sin recurrir a aplicaciones
externas para emular una consola y viene con varios programas que
sustituyen comandos externos. La ventaja de este emulador es que
evalúa cualquier comando <code>elisp</code> en la línea de comandos y nos
proporciona una manera sencilla de hacer nuestros <i>scripts</i> en
<code>elisp</code> en lugar de hacerlo en <code>bash</code> o <code>zsh</code> o...</li>
</ul>

<p>
Así pues, tenemos tres <i>conchas</i> que toquetear ¿cuál elegir? Pues
depende fundamentalmente de lo que queramos hacer. La forma más rápida
de ejecutar un comando de <i>shell</i> desde <i>Emacs</i> es utilizar el
<code>minibuffer</code> con <code>M-!</code>, esto llama al comando <code>shell-command</code> y nos
pregunta por un comando. La salida del mismo nos la muestra en un
<i>buffer</i> llamado <code>*Shell Command Output*</code>.  También es posible que la
salida se vuelque al <i>buffer</i> actual si le damos un argumento
numérico... por ejemplo si queremos que nos añada al <i>buffer</i> una
lista de los ficheros en el directorio, podemos teclear <code>M-1 M-! ls
-lh *.txt</code> y nos añadirá una lista de todos los ficheros con extensión
<code>.txt</code> que encuentre en el directorio de trabajo.
</p>

<p>
También en ocasiones lo que queremos es que se ejecute el comando pero
en segundo plano. Lo mismo que hacemos en el terminal cuando
ejecutamos cualquier comando finalizándolo con el carácter <code>&amp;</code>. En
este caso <i>Emacs</i> nos proporciona el comando <code>async-shell-command</code> y
lo podemos invocar con la combinación <code>M-&amp;</code> en lugar de <code>M-!</code>. Si ese
comando produce cualquier salida, la mostrará en un <i>buffer</i> con el
nombre <code>*Async Shell Command*</code>.
</p>

<p>
Pero bueno, en realidad todo esto no es <i>una concha</i>, sólo nos permite
acceder a los comandos del sistema sin necesidad de cerrar el entorno
de edición. Lo que queremos hacer es tener una terminal interactiva.
</p>
<div id="outline-container-orgdd7e12e" class="outline-2">
<h2 id="orgdd7e12e">Shell</h2>
<div class="outline-text-2" id="text-orgdd7e12e">
<p>
El terminal más a mano que tenemos en <i>Emacs</i> es el comando <code>shell</code>.
Como he dicho antes ejecuta la mayoría de los comandos pero tiene
limitaciones puesto que no constituye un <i>terminal</i> completo. Además
<i>Emacs</i> tiene la costumbre de abrir la concha en un <i>buffer</i> con
nombre <code>*shell*</code>, si ya tenemos uno abierto, lo que hace es llevarnos
a él, pero no abre uno nuevo. ¿Se pueden tener varios <i>buffers</i> con
distintas sesiones de <i>shell</i> abiertas? Pues sí. Además, para hacerlo,
tenemos varias alternativas. La primera consiste en renombrar el
<i>buffer</i> donde tenemos abierta la sesión con <code>M-x rename-uniquely</code> y
veremos que nos pondrá el nombre a algo como <code>*shell&lt;2&gt;*</code>, ahora
podemos llamar de nuevo a <code>M-x shell</code> y tendremos dos <i>buffers</i>
independientes, uno con nombre <code>*shell*</code> y otro con nombre
<code>*shell&lt;2&gt;*</code>.  La otra opción es utilizar el comando <code>C-u M-x
shell</code>. Este comando nos pregunta por un nombre para el <i>buffer</i>, si
le proporcionamos uno distinto de <code>shell</code> nos lo abrirá en un <i>buffer</i>
con ese nombre.
</p>

<p>
No voy a entrar en más profundidades. Podría poner una lista de
combinaciones de teclas que funcionan en este modo, pero no quiero
alargar innecesariamente el artículo, porque el objetivo son las dos
<i>conchas</i> más potentes. Pero siempre tenéis a mano la ayuda para
conocer los atajos.
</p>
</div>
</div>
<div id="outline-container-orgc3f0bec" class="outline-2">
<h2 id="orgc3f0bec">Term</h2>
<div class="outline-text-2" id="text-orgc3f0bec">
<p>
Básicamente <code>term</code> funciona como el anterior <code>shell</code> sin embargo,
tiene características que lo hacen más potente. Pero antes de seguir
tienes que recordar que la tecla que le sirve como <i>escape</i> es <code>C-c</code>.
</p>

<p>
¿Qué es capaz de hacer éste terminal? Pues cualquier cosa que pueda
hacer un terminal... el resumen es que un <i>buffer</i> de nuestro <i>Emacs</i>
se ha convertido en un <i>terminal</i> completo, como puede ser <code>xterm</code> o
<code>KiTTY</code> o <code>Terminator</code> o cualquier otro al uso.
</p>


<figure id="org0247b66">
<img src="./imagen/Captura-pantalla-meta-emacs.png" alt="Captura-pantalla-meta-emacs.png">

</figure>

<p>
Podemos ver en la imagen anterior, cómo incluso podemos ejecutar una
sesión de <i>Emacs</i> dentro de un terminal dentro de <i>Emacs</i>, sólo
tenemos que recordarle que funcione en modo texto con el comando
<code>emacs -nw</code> y funciona sin que se produzca una anomalía dentro del
espacio-tiempo, ni nada. Eso sí, para enviarle combinaciones de teclas
tenemos que <i>escaparlas</i> y el comando para salir, será por tanto <code>C-c
C-x C-c C-c</code>. O por poner otro ejemplo, que no necesitará escapar los
comandos, podemos ejecutar <code>vim</code> dentro de <i>Emacs</i>:
</p>


<figure id="org984d7e9">
<img src="./imagen/Captura-pantalla-emacs-vim.png" alt="Captura-pantalla-emacs-vim.png">

</figure>

<p>
En este caso, como digo, puesto que los comandos de <code>vim</code> no coinciden
con las combinaciones de <i>Emacs</i> no nos hará falta <i>escaparlos</i> para
que se ejecuten.
</p>

<p>
Hablando de estas cosas de <i>escapar</i> comandos, en el terminal tenemos
que tener en cuenta el modo de trabajo que tengamos establecido.
Podemos estar en <i>line mode</i> o en <i>char mode</i>. Si queréis apreciar la
diferencia sólo tenéis que hacer pruebas en el mismo terminal. Con
<code>C-c C-j</code> se entra en <code>term-line-mode</code> y con <code>C-c C-k</code> entramos en
<code>term-char-mode</code>. Algunos de los comandos sólo funcionan cuando
estamos en modo <code>char</code>, como <code>C-c C-c</code> que envía al programa que esté
ejecutando el terminal un <code>C-c</code>, o <code>C-c CHAR</code> que sería el equivalente
de enviar en el <i>Emacs</i> normal un comando <code>C-x CHAR</code>.
</p>

<p>
Además, el terminal también nos permite realizar conexiones remotas a
través de <code>ssh</code> o <code>telnet</code>. Y ya para rematar, también podemos
utilizar el terminal a través de un puerto serie con <code>M-x serial-term</code>
y comunicarnos con cualquier dispositivo que tengamos conectado a un
puerto serie. Nos preguntará por el nombre del puerto y por la
velocidad. Además podemos configurar el puerto serie pinchando en
<code>8N1</code> en la línea de modo, lo que significa que cada <code>byte</code> consiste
en 8 bits, sin paridad (<i>No parity</i>) y un <code>stopbit</code>. Si la velocidad
no está bien configurada, seguramente sólo obtendrás basura del
puerto, así que primero mirad bien el manual de instrucciones de lo
que quiera que conectéis... en mi caso probé en su día con un par de
lectoras de marcas y me permitió cargar configuración e incluso leer
formularios. Un lujo al alcance de todos.
</p>
</div>
</div>
<div id="outline-container-org6ea6f3b" class="outline-2">
<h2 id="org6ea6f3b">Eshell</h2>
<div class="outline-text-2" id="text-org6ea6f3b">
<p>
Pues aquí viene la joya de la corona de los terminales para <i>Emacs</i>.
<code>eshell</code> está escrito enteramente en <code>elisp</code>. ¿Qué nos proporciona?
pues toda la potencia de <i>Emacs</i> en el terminal. En el caso
anterior, debíamos ejecutar <code>term</code> indicando qué <i>concha</i> llamar
(<code>bash</code>, <code>zsh</code>, <code>fish</code>...), el <i>buffer</i> se convertía en
un intermediario entre ese comando y nosotros, por lo que estamos
limitados a hacer las cosas que hagamos en un terminal normal. O dicho
de otro modo, hemos cambiado una ventana de <code>xterm</code> por un <i>buffer</i> de
<i>Emacs</i> ─que ya está bien para muchas cosas─.
</p>

<p>
Pero para apreciar la diferencia, abre <code>eshell</code> con el comando <code>M-x
eshell</code> y teclea cualquier comando <code>elisp</code> o de <i>Emacs</i> y mira a ver
qué hace... por ejemplo: prueba a escribir <code>(+ 2 3)</code> y te devolverá
<code>5</code>. Pero mucho más interesante que eso: estás navegando por los
directorios y te gustaría abrir un fichero... tecleas <code>find-file
nombre-fichero.ext</code> y ¡eh! lo abre en un <i>buffer</i>... <code>dired</code>, <code>magit</code>,
cualquier comando responderá como se espera.
</p>

<p>
Funciona con todos los comandos que se invocan desde <code>M-x</code>. Incluso
puede llamar, si lo necesitas a un terminal <code>ansi</code> con el comando
<code>ansi-term bash</code> si fuera el caso. Con los comandos más gráficos
ocurre como con <code>shell</code> no funcionan algunos comandos más visuales, no
podemos tener <code>vim</code> corriendo en él, por ejemplo, pero tampoco es tan
grave, dado que ampliamos el terminal con la potencia de los comandos
de <i>Emacs</i>, y si bien <code>git log</code> no terminará de verse bien y funcionar
correctamente, puedes utilizar <code>magit-log</code> para abrir un <i>buffer</i> de
<code>magit</code>.
</p>

<p>
También, por supuesto, podemos ejecutar varios comandos separándolos
con <code>;</code> o en segundo plano terminándolos con <code>&amp;</code>, como en otros
terminales.
</p>
</div>
<div id="outline-container-org2fcecda" class="outline-3">
<h3 id="org2fcecda">Comandos internos</h3>
<div class="outline-text-3" id="text-org2fcecda">
<p>
<code>Eshell</code> define algunos comandos internos. En algunos casos para
sustituir a comandos externos del sistema operativo. Por ejemplo, si
estás ejecutando <code>eshell</code>, prueba el siguiente comando:
</p>

<div class="org-src-container">
<pre class="src src-bash">~ $ which ls
eshell/ls is a compiled Lisp function.
</pre>
</div>

<p>
y sin embargo, podemos seguir accediendo al comando del sistema:
</p>

<div class="org-src-container">
<pre class="src src-bash">~ $ which *ls
/usr/bin/ls
</pre>
</div>

<p>
Es decir, si queremos utilizar el comando correspondiente del sistema,
debemos ponerle un <code>*</code> delante. No voy a hacer una lista exhaustiva de
todos los comando, pero por nombrar algunos tenemos: <code>alias</code>, <code>clear</code>,
<code>date</code>, <code>diff</code>, <code>grep</code>, <code>info</code>, <code>kill</code>, <code>make</code> ...
</p>

<p>
Para nuestros <i>scripts</i> también cuenta con algunas variables internas
que podemos utilizar:
</p>

<dl class="org-dl">
<dt><code>$+</code></dt><dd>Directorio de trabajo actual.</dd>
<dt><code>$-</code></dt><dd>Directorio de trabajo anterior.</dd>
<dt><code>$_</code></dt><dd>El último argumento del último comando.</dd>
<dt><code>$$</code></dt><dd>El resultado del último comando interno, si el comando es
externo contendrá <code>t</code> o <code>nil</code>.</dd>
<dt><code>$?</code></dt><dd>Código de salida del último comando que puede ser <code>0</code> o
<code>1</code>.</dd>
</dl>

<p>
Además de las habituales variables <code>$*</code> para pasar todos los
argumentos o <code>$1</code>, <code>$2</code>... para pasar el argumento correspondiente.
</p>
</div>
</div>
<div id="outline-container-orgdd2e4b9" class="outline-3">
<h3 id="orgdd2e4b9">Aliases</h3>
<div class="outline-text-3" id="text-orgdd2e4b9">
<p>
<code>Eshell</code> nos permite tener también <i>alias</i> para nuestros comandos. Es
un poco distinto de cómo funcionan los <i>alias</i> en <code>bash</code>, pero no
demasiado. Para <code>eshell</code>, los argumentos se deben definir
explícitamente, es decir, en <code>bash</code> nos podemos encontrar algún alias
definido del estilo de:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #8be9fd; font-style: italic;">alias</span> ls = <span style="color: #f1fa8c;">"ls --color"</span>
<span style="color: #8be9fd; font-style: italic;">alias</span> ll = <span style="color: #f1fa8c;">"ls -l"</span>
</pre>
</div>

<p>
En <code>eshell</code> las definiciones serían más del estilo: <code>alias ls 'ls
--color $*'</code>, o <code>alias ll 'ls -l $*'</code>. Como se puede apreciar, hay que
especificar el uso de argumentos.
</p>

<p>
Manejar explícitamente los argumentos nos permite crear alias más
complejos como por ejemplo <code>alias mcd 'mkdir $1 &amp;&amp; cd $1'</code>, que lo que
hará si escribimos <code>mcd lo-que-sea</code> es crear un directorio con nombre
<code>lo-que-sea</code> y movernos a él.
</p>

<p>
Cuando utilizamos un <code>alias</code> en la línea de comandos, <code>eshell</code> lo
guarda para siguientes sesiones en un fichero y, por supuesto, también
podemos modificar nuestro fichero de <code>aliases</code> directamente. Dicho
fichero de <code>alias</code> será aquél que apunte la variable
<code>eshell-aliases-file</code>, que por defecto es <code>~/.emacs.d/eshell/alias</code>,
pero que, como todo en <i>Emacs</i> podemos configurarlo y cambiarlo.
</p>
</div>
</div>
<div id="outline-container-org8c2f293" class="outline-3">
<h3 id="org8c2f293">Redirección</h3>
<div class="outline-text-3" id="text-org8c2f293">
<p>
Los operadores de redirección son los habituales de un <code>shell</code>, es
decir, funcionan los habituales <code>&gt;</code> o <code>&gt;&gt;</code>. Esos operadores sirven
para guardar la salida de un comando en un fichero (<code>&gt;</code>) o para añadir
la salida de un comando a un fichero (<code>&gt;&gt;</code>). ¿Y si queremos llevar la
salida de un comando a un <i>buffer</i>? Pues para eso, <code>eshell</code> nos
proporciona el operador <code>&gt;&gt;&gt;</code>.
</p>

<p>
Por ejemplo: <code>echo "Hola Mundo!" &gt;&gt;&gt; #&lt;buffer *scratch*&gt;</code> insertará la
cadena «Hola Mundo!» en el <i>buffer</i> <code>*scratch*</code>. También servirá la
forma más corta del nombre del <i>buffer</i> <code>#&lt;*scratch*&gt;</code>. Y también,
atentos a las comillas, porque si no, es posible que la salida que nos
encontremos sea <code>("Hola" "Mundo!")</code>, que no era lo deseado ─o a lo
mejor sí, que nunca se sabe lo que quiere un usuario de /Emacs/─.
</p>
</div>
</div>
</div>
<div id="outline-container-org5c4630c" class="outline-2">
<h2 id="org5c4630c">Conclusión</h2>
<div class="outline-text-2" id="text-org5c4630c">
<p>
Tienes a tu alcance toda la potencia del <i>shell</i> sin salir de <i>Emacs</i>.
En ningún momento necesitas abandonar el editor para ejecutar lo que
quiera que necesites hacer en el Sistema Operativo. Lo tienes a un
golpe de tecla... y además con varias opciones para elegir la que
mejor se adapte a eso que quieres, o necesitas, hacer.
</p>

<p>
El <code>eshell</code> es un lujo cuando te acostumbras a él, pero cuidado: luego
intentarás abrir ficheros con <code>find-file</code> en tu terminal favorito,
fuera de <i>Emacs</i> y tendrás que obligarte a repensar lo que quieres
hacer sin los comandos de <i>Emacs</i> a mano. No puedes teclear <code>dired</code> en
un <code>xterm</code> y navegar por los directorios y los ficheros... no, no hace
falta que abras <i>Emacs</i> ─si no lo tienes abierto─ para lo que sea,
basta recordar que <i>ahí fuera</i> las cosas son distintas...
</p>

<p>
Cuando me preguntan por qué me gusta tanto <i>Emacs</i> es fácil: por cosas
como ésta. Flexibilidad, potencia, el poder adaptar la herramienta a
mí en lugar de adaptarme yo a la herramienta. Porque puedo ejecutar,
por ejemplo <code>vim</code>, en un <i>buffer</i> y trabajar como lo haría desde un
terminal normal. Y además hacerlo tanto en modo gráfico como en modo
texto, de la misma manera y con la misma efectividad.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/shell/index.html">shell</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[shell]]></category>
  <link>https://notxor.nueva-actitud.org/2020/08/08/las-conchas-de-tu-madre.html</link>
  <pubDate>Sat, 08 Aug 2020 17:55:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Repositorio de código en codeberg.org]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-07-29</div>
<p>
Hace unos días <a href="https://victorhckinthefreeworld.com/2020/07/06/codeberg-alternativa-github-gitlab/">leí un artículo del amigo <i>Victorhck</i></a>, sobre
<a href="https://codeberg.org">https://codeberg.org</a> que me hizo probarlo. Supongo que a estas alturas
la mayoría conocéis <a href="https://github.com/">Github</a> y <a href="https://gitlab.com">Gitlab</a>, algunos menos <a href="https://bitbucket.org">BitBucket</a> y habéis
echado en falta algún repositorio de esos que verdaderamente sea
libre. Pues eso, es precisamente <i>codeberg.org</i>. Se financian a través
de <a href="https://join.codeberg.org/">donaciones que puedes hacer en su página web</a> y también por
<a href="https://liberapay.com/codeberg">liberapay</a>.
</p>

<p>
Pongo el tema de la financiación en primer lugar para que esté
accesible a todo el que lea este pequeño artículo sobre esta
herramienta. Que siempre hay que recordar aquello de que <i>libre</i> no
significa <i>gratis</i>.
</p>

<p>
Comencé a probarlo el día 8 de julio, cuando se publique este artículo
hará, apenas 20 días que vengo usándolo. De momento, estoy probando
con un sólo repositorio, con el último proyecto de programación con el
que ando. Está en un <i>repositorio privado</i>, de manera que sólo tengo
acceso a él yo.
</p>

<p>
La configuración fue sencilla, si ya has tenido algunos repositorios
en este tipo de sitios. La <i>interface</i> es similar aunque muy sencilla,
casi minimalista comparada con los <i>siene' y siene'</i> de <i>pichorros</i>
que aparecen en los menús de este tipo de sitios.
</p>


<figure id="org2cf6841">
<img src="./imagen/Captura-pantalla-codeberg.png" alt="Captura-pantalla-codeberg.png">

</figure>

<p>
También se puede optar por un fondo oscuro, pero al contrario que a
<i>Victor</i> a mí me gusta más este tradicional tema claro.
</p>

<p>
Durante la configuración fue muy sencillo subir los certificados <code>SSH</code>
y <code>PGP</code> mediante un formulario.
</p>

<p>
Además partía de un repositorio que ya estaba creado y contenía código
y sin embargo, la herramienta de crear el repositorio me guió de
manera sencilla a crearlo sin demasiados problemas. Por tanto, se
puede afirmar que <code>codeberg</code> es apto para <i>patazas</i> como yo.
</p>


<figure id="org9c5b851">
<img src="./imagen/Captura-pantalla-repositorio.png" alt="Captura-pantalla-repositorio.png">

</figure>

<p>
En el repositorio, como se puede ver, no se echa de menos ningún
elemento importante. Muestra en <code>README</code>, en mi caso un <code>README.org</code>
como <i>Dios manda</i> y el resto de elementos para navegar por el código y
las <i>ramas</i> del mismo.
</p>

<p>
De momento, y puesto que soy el desarrollador único del proyecto y aún
está en fases tempranas del desarrollo, no hay <i>bugs</i> de los que
informar ni <i>trabajos</i> que asignar, ni nada de eso. Pero por lo que
veo en los menús, es muy similar a otras herramientas más
<i>privativas</i>. Después de navegar por todos los <i>pichorros</i> y
<i>chismáticos</i> que proporciona puedo decir que no he echado de menos ni
uno sólo de otras herramientas y que su funcionamiento es muy similar.
</p>
<div id="outline-container-org6a1061c" class="outline-2">
<h2 id="org6a1061c">Conclusión</h2>
<div class="outline-text-2" id="text-org6a1061c">
<p>
Esta entrada es cortita, mi único objetivo es informar que existe un
servicio <b>libre</b> donde alojar tus repositorios y que funciona con la
suficiente solvencia como para que me esté pensando migrar todos los
míos a esta herramienta.
</p>

<p>
Si lo hago, que tiene pinta de que sí, no me importará pagar un poco
de dinero que garantice la sostenibilidad y la independencia de la
herramienta y hacerlo de forma periódica, además. Aunque de momento
sigo con las pruebas ya me lo estoy planteando. De momento vengo
utilizando un servidor propio para mis cosas, como este <i>blog</i>. Sin
embargo, cada vez ocupan más y llevo tiempo planteándome migrarlos
hacia algún sitio que sea libre y me permita tener algunos, como los
de gestión personal: agenda <code>org-mode</code>, notas, bitácora, etc. en
repositorios privados. Y <code>codeberg</code> puede ser la opción definitiva.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/git/index.html">git</a> <a href="/tags/codeberg/index.html">codeberg</a> ]]></description>
  <category><![CDATA[git]]></category>
  <category><![CDATA[codeberg]]></category>
  <link>https://notxor.nueva-actitud.org/2020/07/29/repositorio-de-codigo-en-codeberg-org.html</link>
  <pubDate>Wed, 29 Jul 2020 16:07:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Mis impresiones sobre erlang]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-07-25</div>
<p>
Ya conocía <i>erlang</i> desde hace tiempo. Lo conocía de nombre, lo había
<i>cotilleado</i> con anterioridad e incluso quise aprenderlo hace unos
años, cuando estaba más metido en las cosas 3D y conocí <a href="http://www.wings3d.com/">Wings3d</a> (un
<i>modelador</i> 3D hecho en <i>erlang</i>). Creo que esto ya lo conté por aquí,
pero lo pongo en contexto por si alguien llega a leer este artículo de
nuevas.
</p>

<p>
No es el lenguaje más popular del mundo, más bien es un lenguaje
<i>raro</i>, con unas características un poco extrañas para quien se
aproxima(ba) por primera vez a él, que poco o nada sabía de esos
esotéricos lenguajes funcionales, más allá de las viejas referencias a
<i>LISP</i>. Y así, en su día, la sintaxis, acostumbrado a otras más
encerradas entre llaves o dominadas por bloques indentados, me pareció
un poco <i>marciana</i>; su forma de nombrar las funciones con la
estructura <code>nombre_función/0</code>, donde se especifica el número de
parámetros en el mismo nombre, me pareció hasta fea. Pero, después de
un tiempo utilizándolo todo cambia y, ahora, ha llegado el momento de
que os <i>cansine</i> con mis apreciaciones sobre el lenguaje. Pensaréis:
¿de qué me sirve la opinión de un psicólogo sobre un lenguaje de
programación? La respuesta es sencilla: <i>de nada... ¿qué haces leyendo
esto?</i> O sí, bueno, eres muy libre de seguir si quieres ;-þ
</p>
<div id="outline-container-org88e3498" class="outline-2">
<h2 id="org88e3498">erlang/OTP</h2>
<div class="outline-text-2" id="text-org88e3498">
<p>
Si nunca habéis utilizado <i>erlang</i> es posible que lo de <i>OTP</i> sea
nuevo para vosotros. Sin embargo, muchos de los programadores de
<i>erlang</i> lo consideran inseparable y usan el lenguaje precisamente por
las características de que le dota <i>OTP</i>, como otra capa de
abstracción.
</p>

<p>
Por decirlo de algún modo sencillo de entender, OTP es una librería
que viene a facilitar la vida del programador dotándolo de todas las
abstracciones que aprovechan las características de <i>erlang</i> sin
necesidad de reinventar la rueda en cada aplicación. Luego lo veremos
más despacio, pero empecemos por el principio.
</p>
</div>
<div id="outline-container-orgc397c4f" class="outline-3">
<h3 id="orgc397c4f">¿Qué es erlang?</h3>
<div class="outline-text-3" id="text-orgc397c4f">
<p>
<i>Erlang</i> es un lenguaje funcional, con tipado dinámico y asignación
única. Os sonará lo de <i>tipado dinámico</i> de otros lenguajes, pero
seguro que lo de la <i>asignación única</i> os suena marciano ─como a mí al
principio─. Esto último consiste en que una vez asignado un valor a
una variable, éste no puede cambiar. Y pensaréis: ¿De qué sirven
variables que son invariables? ¿unas variables, constantes? ... bueno,
yo me lo pregunté en su momento, luego ves que tiene sus ventajas
(como que no se produzcan errores porque una variable ha tomado un
valor que no debía) y te olvidas de los inconvenientes o más bien de
las costumbres que traes de otros lenguajes menos consistentes. Pero
veamos las características de las que hace gala:
</p>

<dl class="org-dl">
<dt>Concurrente</dt><dd>Las aplicaciones de <i>erlang</i> soportan gran cantidad
de procesos concurrentes, que no comparten memoria y se comunican
mediante mensajes entre ellos.</dd>
<dt>Distribuido</dt><dd>Una máquina virtual de <i>erlang</i> es un nodo. Un
sistema distribuido de <i>erlang</i> es una red de nodos cuyos procesos
se pueden intercomunicar exactamente igual como lo harían si
compartieran nodo. Por eso es fácil levantar varios nodos, incluso
en diversas máquinas y nuestra aplicación funcionaría igual que si
corriera sobre un sólo procesador.</dd>
<dt>Robustez</dt><dd>Una de las <i>máximas</i> de <i>erlang</i> dice: <i>Deja que
falle</i>. Los procesos pueden configurarse de manera que se pueden
derivar entre nodos y migrar a nodos que se han recuperado. Unos
procesos pueden monitorizar a otros y actuar en consecuencias cuando
un proceso falla.</dd>
<dt>Soft real-time</dt><dd><i>erlang</i> soporta sistemas que requieren tiempos de
reacción del orden de los milisegundos.</dd>
<dt>Actualización de código en caliente</dt><dd>Es posible modificar el
código que se está ejecutando sin necesidad de detener el sistema.</dd>
<dt>Interfaces externas</dt><dd>los procesos de <i>erlang</i> se pueden comunicar
con librerías y otros códigos, hechos en otros lenguajes, con el
mismo mecanismo que se utiliza internamente entre procesos. Además,
se pueden enlazar programas escritos, por ejemplo en C, dentro del
código <i>erlang</i>.</dd>
</dl>
</div>
</div>
<div id="outline-container-orgdccb5c1" class="outline-3">
<h3 id="orgdccb5c1">Programación funcional para línea de comandos</h3>
<div class="outline-text-3" id="text-orgdccb5c1">
<p>
Si tienes <i>erlang</i> instalado, verás que viene con algunas herramientas
con él: por ejemplo el <i>prompt interactivo</i> <code>erl</code> o su herramienta para
<i>scripts</i>: <code>escript</code>.
</p>

<p>
Vamos a ver un ejemplo, que viene en la misma página de manual de
<code>escript</code>, aunque le daremos también alguna vuelta, para ver cómo
podemos fabricarnos nuestros <i>scripts</i> en este lenguaje.
</p>

<div class="org-src-container">
<pre class="src src-erlang">#!/usr/bin/env escript
<span style="color: #6272a4;">%% </span><span style="color: #6272a4;">-*- erlang -*-
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">! -smp enable -sname factorial
</span><span style="color: #50fa7b; font-weight: bold;">main</span>([<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>]) -&gt;
    <span style="color: #ff79c6; font-weight: bold;">try</span>
        <span style="color: #f8f8f2; font-weight: bold;">N</span> = <span style="color: #8be9fd; font-style: italic;">list_to_integer</span>(<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>),
        <span style="color: #f8f8f2; font-weight: bold;">F</span> = <span style="color: #8be9fd; font-style: italic;">fact</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>),
        <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Factorial ~w = ~w\n"</span>, [<span style="color: #f8f8f2; font-weight: bold;">N</span>,<span style="color: #f8f8f2; font-weight: bold;">F</span>])
    <span style="color: #ff79c6; font-weight: bold;">catch</span>
        <span style="color: #f8f8f2; font-weight: bold;">_</span>:<span style="color: #f8f8f2; font-weight: bold;">_</span> -&gt;
            <span style="color: #8be9fd; font-style: italic;">uso</span>()
    <span style="color: #ff79c6; font-weight: bold;">end</span>;
<span style="color: #50fa7b; font-weight: bold;">main</span>(<span style="color: #f8f8f2; font-weight: bold;">_</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">uso</span>().

<span style="color: #50fa7b; font-weight: bold;">uso</span>() -&gt;
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Uso: factorial entero\n"</span>),
    <span style="color: #8be9fd; font-style: italic;">halt</span>(1).

<span style="color: #50fa7b; font-weight: bold;">fact</span>(0) -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span>1;
<span style="color: #50fa7b; font-weight: bold;">fact</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>) -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span><span style="color: #f8f8f2; font-weight: bold;">N</span> * <span style="color: #8be9fd; font-style: italic;">fact</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>-1).
</pre>
</div>

<p>
Vamos a analizar ese código. Lo puedes copiar en un fichero que se
llame <code>factorial</code> y hacerlo <i>ejecutable</i> con <code>chmod</code> si quieres
probarlo.
</p>

<p>
La <b>primera línea</b> es la clásica <i>llamada</i> al intérprete que debe
ejecutar el <i>script</i>, en nuestro caso <code>escript</code>. La <b>segunda línea</b> es
un aviso para nuestro editor favorito (<i>Emacs</i>) para advertirle que
debe iniciar <code>erlang-mode</code> al editar el fichero. Sí, hay un
<code>erlang-mode</code> para <i>Emacs</i> y parece que es el editor <i>oficioso</i> del
mismo. La <b>tercera línea</b> son opciones de configuración de la máquina
virtual:
</p>

<ul class="org-ul">
<li>el parámetro <code>-smp enable</code> se utiliza para compilar utilizando el
emulador <code>SMP</code>, que se utiliza para compilar código nativo que se
debe compilar con el mismo <i>runtime</i> que lo va a ejecutar.</li>
<li>El parámetro <code>-sname factorial</code>, da nombre al <i>proceso</i> que
ejecutará la máquina. Esto nos permite, por ejemplo, levantar un
proceso y llamarlo por su nombre. Tiene un equivalente <code>-name</code>, pero
en este último caso el formato será <code>nombre@host</code>. Y es muy útil
cuando nuestro <i>script</i> lo que hace es levantar un <i>servicio</i> y
queremos llamarlo desde otros procesos.</li>
</ul>

<p>
Después, la función <code>main/1</code> tiene dos partes, la primera se ejecuta
cuando la lista de parámetros viene con un <i>string</i> o cadena
(<code>[Cadena]</code>), lo que hace es intentar convertir la cadena a un entero
y si tiene éxito calcula y devuelve el factorial del número con
<code>fact/1</code>, y si no, remite a <code>uso/0</code> y la segunda significa <i>en
cualquier otro caso</i> llama a <code>uso/0</code>.
</p>

<p>
Cosas sobre la sintaxis que pueden llamar la atención, o al menos a mí
me llamaron la atención en su momento: Separa partes de la misma
función con el carácter <code>;</code>, las instrucciones dentro de cada una de
esas partes con <code>,</code> y se marca con un <code>.</code> el final de la definición de
una función. Sin embargo, cuando la instrucción es <code>end</code>, como ésta ya
es un delimitador, en la instrucción anterior no hay que marcarlo.
</p>

<p>
<i>Eso de definir la función en partes me resulta marciano</i>... eso pensé
en su momento. Y aún en día algunas veces me descubro tirando de otra
sintaxis más <i>espagueti</i>. Por ejemplo, el código anterior podría
haberse escrito también así:
</p>

<div class="org-src-container">
<pre class="src src-erlang">#!/usr/bin/env escript
<span style="color: #6272a4;">%% </span><span style="color: #6272a4;">-*- erlang -*-
</span><span style="color: #6272a4;">%%</span><span style="color: #6272a4;">! -smp enable -sname factorial
</span><span style="color: #50fa7b; font-weight: bold;">main</span>(<span style="color: #f8f8f2; font-weight: bold;">Args</span>) -&gt;
    <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">Args</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
        [<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>] -&gt;
            <span style="color: #ff79c6; font-weight: bold;">try</span>
                <span style="color: #f8f8f2; font-weight: bold;">N</span> = <span style="color: #8be9fd; font-style: italic;">list_to_integer</span>(<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>),
                <span style="color: #f8f8f2; font-weight: bold;">F</span> = <span style="color: #8be9fd; font-style: italic;">fact</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>),
                <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Factorial ~w = ~w\n"</span>, [<span style="color: #f8f8f2; font-weight: bold;">N</span>,<span style="color: #f8f8f2; font-weight: bold;">F</span>])
            <span style="color: #ff79c6; font-weight: bold;">catch</span>
                <span style="color: #f8f8f2; font-weight: bold;">_</span>:<span style="color: #f8f8f2; font-weight: bold;">_</span> -&gt;
                    <span style="color: #8be9fd; font-style: italic;">uso</span>()
            <span style="color: #ff79c6; font-weight: bold;">end</span>;
        <span style="color: #f8f8f2; font-weight: bold;">_</span> -&gt;
            <span style="color: #8be9fd; font-style: italic;">uso</span>()
    <span style="color: #ff79c6; font-weight: bold;">end</span>.

<span style="color: #50fa7b; font-weight: bold;">uso</span>() -&gt;
    <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Uso: factorial entero\n"</span>),
    <span style="color: #8be9fd; font-style: italic;">halt</span>(1).

<span style="color: #50fa7b; font-weight: bold;">fact</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>) -&gt;
    <span style="color: #ff79c6; font-weight: bold;">case</span> <span style="color: #f8f8f2; font-weight: bold;">N</span> <span style="color: #ff79c6; font-weight: bold;">of</span>
        0 -&gt;
            1;
        <span style="color: #f8f8f2; font-weight: bold;">N</span> <span style="color: #ff79c6; font-weight: bold;">when</span> <span style="color: #f8f8f2; font-weight: bold;">N</span> &gt; 0 -&gt;
            <span style="color: #f8f8f2; font-weight: bold;">N</span> * <span style="color: #8be9fd; font-style: italic;">fact</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>-1)
    <span style="color: #ff79c6; font-weight: bold;">end</span>.
</pre>
</div>

<p>
Como se puede ver, se ha metido la evaluación de los casos dentro de
la llamada a la función, dependiendo de los parámetros que llegan a
ella. Además he añadido un poco de <i>programación defensiva</i> en la
función <code>fact/1</code> de manera que cuando llega un número sólo calcule el
factorial si es positivo (<code>when N &gt; 0</code>). Lo mismo podríamos haber
hecho en el caso anterior. La última línea hubiera sido:
</p>

<p>
<code>fact(N) when N &gt; 0 -&gt; N * fact(N-1).</code>
</p>

<p>
Y por último, destacar el uso recursivo de las funciones. Puesto que
para calcular el factorial, la función <code>fact/1</code> se llama a sí misma
con otro argumento, hasta llegar a <code>0</code>, hay que darle una condición de
salida a la recursión. En este caso cuando el valor que llega es <code>0</code>
deja de llamarse a sí misma y devuelve un valor directo <code>1</code>.
</p>

<p>
Como se puede apreciar, <i>erlang</i> es un lenguaje muy flexible y parece
que siempre encuentras una manera alternativa de hacer las cosas.
</p>
</div>
</div>
<div id="outline-container-org3170c46" class="outline-3">
<h3 id="org3170c46">Intérprete de comandos y compilador</h3>
<div class="outline-text-3" id="text-org3170c46">
<p>
Además, también disponemos de un intérprete de comandos: <code>erl</code> que nos
permite introducir uno a uno los comandos de <i>erlang</i> que queramos
ejecutar. Básicamente levanta una máquina virtual y nos permite, por
ejemplo, lanzar nuestras aplicaciones o módulos. Podríamos llamarlo
como:
</p>

<div class="org-src-container">
<pre class="src src-shell">erl -pa ./binarios -eval <span style="color: #f1fa8c;">'mi_modulo:start().'</span>
</pre>
</div>

<p>
De esa manera podemos lanzar un módulo <code>mi_modulo</code> suponiendo que
exista una función <code>start/0</code> que sea la que inicie el proceso. El
parámetro <code>-pa ./binarios</code> lo que hace es añadir al <i>path</i> del
intérprete el directorio <code>./binarios</code> que es donde guardamos nuestros
ficheros compilados. O si lo que hemos hecho es una <i>aplicación OTP</i>
se podría llamar con:
</p>

<div class="org-src-container">
<pre class="src src-shell">erl -pa ./binario -eval <span style="color: #f1fa8c;">'application:start(mi_aplicacion).'</span>
</pre>
</div>

<p>
<i>Hmmm, un momento... ¿binarios?...¿ficheros compilados?...</i> Sí,
también compila el código a un formato intermedio llamado <i>beam</i> que
es lo que ejecuta la máquina virtual, que se llama <i>BEAM</i>. De hecho,
hay otros lenguajes que aprovechan las características de concurrencia
y demás bondades de <i>BEAM</i> compilando también a ese <i>bytecode</i>. Uno de
los más famosos es <i>elixir</i>.
</p>

<p>
El compilador que proporciona <i>erlang</i> es <code>erlc</code>. Nuestro código
anterior podría haberse reducido a un módulo con una función a la que
poder llamar:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-module</span>(factorial).
<span style="color: #ffb86c;">-export</span>([<span style="color: #8be9fd; font-style: italic;">fact/1</span>]).

<span style="color: #50fa7b; font-weight: bold;">fact</span>(0) -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span>1;
<span style="color: #50fa7b; font-weight: bold;">fact</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>) <span style="color: #ff79c6; font-weight: bold;">when</span> <span style="color: #f8f8f2; font-weight: bold;">N</span> &gt; 0 -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span><span style="color: #f8f8f2; font-weight: bold;">N</span> * <span style="color: #8be9fd; font-style: italic;">fact</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>-1).
</pre>
</div>

<p>
Analizando el código vemos primero dos líneas extrañas al comienzo.
<code>-module(factorial).</code> es una directiva que indica que ese módulo se
llama <code>factorial</code>. Ese nombre debe coincidir con el nombre del fichero
(sin la extensión <code>.erl</code>) que lo contiene. La otra directiva
<code>-export([fact/1]).</code> lo que hace es <i>exportar</i> una lista de funciones
que pueden llamarse desde fuera del módulo. En nuestro caso la lista
sólo contiene la función <code>fact/1</code>.
</p>

<p>
Si guardamos ese código en un fichero que se llame <code>factorial.erl</code> (si
el nombre del fichero y el módulo no coinciden, el compilador se
quejará), lo podemos compilar desde la línea de comandos:
</p>

<div class="org-src-container">
<pre class="src src-shell">erlc factorial.erl
</pre>
</div>

<p>
Y tendremos en el mismo directorio el fichero <code>factorial.beam</code> que es
el binario generado y que, a partir de ese momento, podemos llamar
desde el intérprete, por ejemplo:
</p>

<pre class="example" id="org4df6f20">
$ erl
Erlang/OTP 23 [erts-11.0.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Eshell V11.0.2  (abort with ^G)
1&gt; factorial:fact(5).
120
2&gt; halt().
</pre>

<p>
Como se puede apreciar, la llamada consiste en el nombre del módulo
<code>factorial</code> separado de la función que queremos llamar y sus
argumentos <code>fact(5)</code>, con <code>:</code>. Como es el final de la instrucción,
también debemos marcar el final con el <code>.</code>.
</p>

<p>
Otra forma de compilar es desde el propio intérprete:
</p>

<pre class="example" id="org07f16d9">
$ erl
Erlang/OTP 23 [erts-11.0.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Eshell V11.0.2  (abort with ^G)
1&gt; factorial:fact(5).
** exception error: undefined function factorial:fact/1
2&gt; c(factorial).
{ok,factorial}
3&gt; factorial:fact(5).
120
4&gt; halt().
</pre>

<p>
Si no existe el fichero binario e intentamos llamar a la función,
vemos que nos lanza una excepción diciendo que esa función
<code>factorial:fact/1</code> no existe. En el paso <code>2</code> llamamos al compilador
desde el intérprete con <code>c(factorial).</code>, véase que se omite la
extensión del fichero y devuelve una <i>tuple</i>: <code>{ok,factorial}</code>. Ya
tenemos el módulo cargado y lo podemos usar.
</p>
</div>
</div>
<div id="outline-container-orgc6907db" class="outline-3">
<h3 id="orgc6907db">Concurrencia</h3>
<div class="outline-text-3" id="text-orgc6907db">
<p>
Otros lenguajes de programación tienen un horror de consideraciones
para acceder de forma concurrente a los procesos y los recursos. Esos
procesos suelen compartir memoria y hay que ponerle <i>banderas</i> que
controlen qué proceso accede o tiene el control de ese recurso.
</p>

<p>
En <i>erlang</i> cualquier función puede convertirse en un proceso al que
llamar. Puesto que los procesos no comparten memoria, levantar y
llamar tiendo en cuenta apenas dos cosas. Como quizá se entienda mejor
con un ejemplo, vamos a ver el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-module</span>(proceso).
<span style="color: #ffb86c;">-compile</span>(export_all).

<span style="color: #50fa7b; font-weight: bold;">procesando</span>() -&gt;
    <span style="color: #ff79c6; font-weight: bold;">receive</span>
        holaaa -&gt;
            <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"&#161;que por el culo nooo, Manolo!~n"</span>),
            <span style="color: #8be9fd; font-style: italic;">procesando</span>();
        digame -&gt;
            <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"... que si quiere bolsa!~n"</span>),
            <span style="color: #8be9fd; font-style: italic;">procesando</span>();
        <span style="color: #f8f8f2; font-weight: bold;">_</span> -&gt;
            <span style="color: #8be9fd; font-style: italic;">io</span>:<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"Pesao'... no se te entiende.~n"</span>),
            <span style="color: #8be9fd; font-style: italic;">procesando</span>()
    <span style="color: #ff79c6; font-weight: bold;">end</span>.
</pre>
</div>

<p>
En cualquier otro lenguaje, las recursiones como la anterior serían la
pesadilla del programador. Un bucle que entra en recursión
infinita... y aquí los programadores lo hacen a propósito... esto es
un <i>sin dios</i>. Pero vamos a ver por qué, analicemos el siguiente
fragmento de llamadas:
</p>

<pre class="example" id="org3b00d6e">
~ $ erl
Eshell V11.0.2  (abort with ^G)
1&gt; c(proceso).
proceso.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,proceso}
2&gt; Proceso = spawn(proceso, procesando, []).
&lt;0.87.0&gt;
3&gt; Proceso ! digame.
... que si quiere bolsa!
digame
4&gt; Proceso ! "Hola mundo!".
Pesao'... no se te entiende.
"Hola mundo!"
5&gt; Proceso ! holaaa.
¡que por el culo nooo, Manolo!
holaaa
6&gt; halt().
~ $
</pre>

<p>
Una vez compilado el código en la línea <code>1</code>, levantamos un proceso con
la función <code>spawn/3</code>, a la que pasamos el módulo <code>proceso</code>, la función
<code>procesando</code> y la lista de argumentos <code>[]</code> en nuestro caso. Esa
función (<code>spawn</code>) nos devuelve el identificador de un proceso de
<i>erlang</i> <code>&lt;0.87.0&gt;</code> y luego podemos llamarlo con la sintaxis <code>!</code>.
Sencillo todo, ¿no?
</p>
</div>
</div>
<div id="outline-container-org451217f" class="outline-3">
<h3 id="org451217f">OTP</h3>
<div class="outline-text-3" id="text-org451217f">
<p>
<i>OTP</i> son las siglas de <i>Open Telecom Platform</i> y puede parecer que
por su nombre sólo serviría para hacer aplicaciones de
telecomunicaciones, pero no sólo para eso sirve. Al contrario, nos
proporciona una serie de <i>comportamientos</i> (<i>behaviours</i> lo llaman) de
nuestros procesos que nos facilitan mucho la vida. Hay varios de estos
<i>behaviours</i> (y se pueden programar propios), por ejemplo:
<code>application</code>, <code>gen_server</code> o <code>supervisor</code>. El primero nos encapsula
una <i>aplicación</i>, que levanta todos los procesos que necesita; el
segundo nos proporciona toda la funcionalidad de un servidor, con
llamadas síncronas y asíncronas; el tercero es un proceso que
<i>supervisa</i> el funcionamiento de otros procesos y puede hacer que se
reinicien tras un fallo, o que paren todos ante un error. Por ejemplo,
si echamos un vistazo a la estructura de la aplicación con la que ando
trasteando para aprender, podemos representarla como algo así:
</p>

<p>
Hay, por encima de todo una <i>aplicación</i> que levanta un <i>supervisor</i>
de nivel superior. Este supervisor, además, levanta un <i>gestor de
datos</i>, un <i>servidor</i> y otro <i>supervisor</i>. Éste último va levantando,
bajo demanda, otros procesos según se conecten los <i>clientes</i>. Aunque
se llamen <i>clientes</i> en realidad es un <i>behaviour</i> de tipo
<code>gen_server</code>, cada uno de esos procesos está dedicado a responder a
las peticiones que llegan desde una determinada conexión TCP por
<code>telnet</code>. En la estructura del MUD, que es lo que estoy programando,
el <i>servidor</i> representa el <i>mundo virtual</i> y envía mensajes a los
clientes con los eventos que ocurren en ese mundo: alguien entra en la
habitación donde estamos, alguien abre o cierra una puerta, amanece o
anochece... etc. Sin embargo, ni el mundo ni los clientes son los
<i>propietarios</i> de los datos: los pueden consultar, pero no
modificar. Cuando necesitan que un dato cambie, le envían la petición
al proceso que los gestiona que es <code>erlmud_datos</code>. Y durante todo el
tiempo, el <i>supervisor</i> de clientes se mantiene a la escucha, por si
llega una nueva conexión por TCP. En el momento en que llega, levanta
un proceso <i>cliente</i> y le pasa los <i>sockets</i> de conexión para que a
partir de ese momento el proceso <code>erlmud_cliente</code> se haga cargo de las
peticiones y =erlmud_sup» vuelve a quedarse de nuevo a la escucha.
</p>

<p>
Todo el proceso descrito antes apenas se realiza con unas decenas de
líneas de código que definen los <i>behaviours</i> y los conectan, las
partes escabrosas están encapsuladas por OTP. Luego hay que añadir el
código que hace que tu aplicación haga lo que tiene que hacer.
</p>
</div>
</div>
<div id="outline-container-org2e8cfee" class="outline-3">
<h3 id="org2e8cfee">Gestión de datos</h3>
<div class="outline-text-3" id="text-org2e8cfee">
<p>
En el apartado anterior no quise entrar en mucho detalle en el tema de
los datos, pero es una de las cosas que me tienen encantado. En
<i>erlang</i> la gestión de datos viene de fábrica. Se pueden emplear
<i>tablas</i> cargadas en memoria o en disco con las librerías ETS y DETS
(<i>Erlang Term Storage</i> y <i>Disk Erlang Term Storage</i>) respectivamente.
Y pueden almacenar gran cantidad de datos. No encuentro exactamente
cuánto, pues he visto autores que aseguran que son 4Gb por tabla y
otros lo reducen a 2Gb por tabla. En todo caso, para una aplicación
normal, puede ser suficiente para funcionar.
</p>

<p>
Además, las tablas pueden ser <i>privadas</i> (sólo las puede leer-escribir
el proceso propietario), pueden estar <i>protegidas</i> (las pueden leer
otros procesos pero sólo las puede modificar el propietario, como en
mi proyecto de MUD) o <i>públicas</i> (cualquier proceso puede leer y
escribir en ellas).
</p>

<p>
Cualquier tipo de datos que sea correcto para <i>erlang</i> puede meterse
en una tabla <i>ets</i>. Por ejemplo, si venimos almacenando los datos en
una <i>tuple</i> tipo:
</p>

<div class="org-src-container">
<pre class="src src-erlang">Datos = {12, [1,2,3,4], <span style="color: #f1fa8c;">"una cadena"</span>, {ok,42}, 132}.
{<span style="color: #f8f8f2; font-weight: bold;">_</span>,<span style="color: #f8f8f2; font-weight: bold;">_</span>,<span style="color: #f8f8f2; font-weight: bold;">Cadena</span>,<span style="color: #f8f8f2; font-weight: bold;">_</span>,<span style="color: #f8f8f2; font-weight: bold;">_</span>} = <span style="color: #f8f8f2; font-weight: bold;">Datos</span>.
<span style="color: #f8f8f2; font-weight: bold;">Lista</span> = <span style="color: #8be9fd; font-style: italic;">element</span>(2, <span style="color: #f8f8f2; font-weight: bold;">Datos</span>).
</pre>
</div>

<p>
Podemos ver que la <i>tuple</i> tiene varios campos: un entero, una lista,
una cadena, otra tuple y otro número. Podemos acceder a los datos
dentro por su posición: bien empleando su estructura mediante el
operador de asignación de <i>erlang</i> o bien, utilizando la función
<code>element/2</code>.
</p>

<p>
Sobre esta capa de almacenamiento <i>erlang</i> introduce otra que es el
<code>record</code>. Que lo que hace, básicamente, es ponerle nombres a los
campos. El equivalente de la <i>tuple</i> anterior sería un <i>record</i>
definido de la siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-record</span>(<span style="color: #8be9fd; font-style: italic;">dato</span>, {id, lista, cadena, tuple, entero}).
<span style="color: #f8f8f2; font-weight: bold;">Dato</span> = #<span style="color: #8be9fd; font-style: italic;">dato</span>{12, [1,2,3,4], <span style="color: #f1fa8c;">"una cadena"</span>, {ok,42},132}.
</pre>
</div>

<p>
¿Qué ventaja tiene escribir más? Pues que luego todo es más claro:
</p>

<div class="org-src-container">
<pre class="src src-erlang">Cadena = <span style="color: #f8f8f2; font-weight: bold;">Dato</span>#<span style="color: #8be9fd; font-style: italic;">dato</span>.cadena.
<span style="color: #f8f8f2; font-weight: bold;">Lista</span> = <span style="color: #f8f8f2; font-weight: bold;">Dato</span>#<span style="color: #8be9fd; font-style: italic;">dato</span>.lista.
</pre>
</div>

<p>
Además, si los datos los tenemos guardados en registros o <i>records</i>,
los podemos agrupar en tablas de manera muy sencilla:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #8be9fd; font-style: italic;">ets</span>:<span style="color: #8be9fd; font-style: italic;">new</span>(mis_datos, [set, named_table, protected,
                    {keypos, #<span style="color: #8be9fd; font-style: italic;">dato</span>.id},
                    {heir, <span style="color: #8be9fd; font-style: italic;">self</span>(), <span style="color: #f1fa8c;">"Mis Datos"</span>}]).
</pre>
</div>

<p>
El código anterior crea una tabla ETS llamada <code>mis_datos</code>. Es un
<code>set</code>, lo que quiere decir que sólo habrá un registro para cada valor
del índice. Se establece que se puede acceder a la tabla utilizando su
nombre con <code>named_table</code>, pero a la vez se establece que está
protegida (<code>protected</code>) y sólo la puede modificar el proceso que la
<i>herede</i> (<code>heir</code>, que este caso es <code>self()</code>, el proceso actual, pero
que podríamos pasárselo a cualquier otro). Y la posición de la clave
(<code>keypos</code>) viene determinada por el campo <code>#dato.id</code>.
</p>

<p>
Podemos tener tablas de varios tipos: <code>set</code>, <code>bag</code>... cada uno con sus
características, o si lo prefieres con sus ventajas e inconvenientes.
Esto nos permite almacenar nuestros datos de una manera muy accesible
a la par que flexible. En los <code>set</code> cada <i>key</i> sólo aparecerá una
vez, pero en los <code>bag</code> puede aparecer varias veces. En el primer caso,
al buscar una clave en la tabla devolverá una lista con sólo un
registro (si existe la clave en la tabla); y en el segundo caso
devolverá una lista con tantos registros como existan en la tabla, por
poner sólo dos ejemplos.
</p>
</div>
<div id="outline-container-orgdcbd5c0" class="outline-4">
<h4 id="orgdcbd5c0">mnesia</h4>
<div class="outline-text-4" id="text-orgdcbd5c0">
<p>
Si no has tenido bastante con las tablas ETS, <i>erlang</i> viene armado
con <code>mnesia</code> que es una base de datos que, como sus primas ETS y DETS,
puede guardar la información en memoria o en disco. Además tiene
limitaciones similares a ETS y DETS en cuanto a capacidad de las
tablas y podría considerarse como una «encapsulación» de ellas. Lo que
proporciona es una forma de consultar registros, guardar esas
consultas y llamarlas cuando lo necesitamos, cruzando tablas si es
preciso. Pero lo más interesante es que proporciona «transacciones»,
de manera que los cambios se producen como «un todo» y si hay algún
error, se anulan todos los cambios de la «transacción» para que no
queden datos inconsistentes.
</p>
</div>
</div>
</div>
<div id="outline-container-org95e8d97" class="outline-3">
<h3 id="org95e8d97">Lenguaje funcional</h3>
<div class="outline-text-3" id="text-org95e8d97">
<p>
Si miramos a qué tipo de programación pertenece el lenguaje <i>erlang</i>
encontraremos que en muchos textos lo engloban en los llamados
<i>lenguajes funcionales</i> y en general tiene muchas características que
hacen que esta clasificación sea adecuada. Aunque en algunos sitios
afirman que no es un lenguaje funcional puro, sino que tiene otras
características que lo hacen especial.
</p>

<p>
Entre las estructuras más funcionales tiene en su sintaxis la
capacidad de manejar listas mediante el constructo de «cabecera» y
«cola». El famoso <i>head</i>--<i>tail</i> y que en muchas partes del código de
<i>erlang</i> lo podemos encontrar en accesos marcados como <code>[H|T]</code>,
funciones <i>lambda</i> u otras funciones como el famoso <code>map</code>. Por
ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-module</span>(prueba).
<span style="color: #ffb86c;">-export</span>([<span style="color: #8be9fd; font-style: italic;">duplica/1</span>]).

<span style="color: #50fa7b; font-weight: bold;">duplica</span>(<span style="color: #f8f8f2; font-weight: bold;">Lista</span>) -&gt;
    <span style="color: #8be9fd; font-style: italic;">lists</span>:<span style="color: #8be9fd; font-style: italic;">map</span>(<span style="color: #ff79c6; font-weight: bold;">fun</span>(<span style="color: #f8f8f2; font-weight: bold;">X</span>) -&gt;<span style="color: #50fa7b; font-weight: bold;"> </span><span style="color: #f8f8f2; font-weight: bold;">X</span>*2 <span style="color: #ff79c6; font-weight: bold;">end</span>, <span style="color: #f8f8f2; font-weight: bold;">Lista</span>).
</pre>
</div>

<p>
Si lo llamamos y le trasladamos la lista <code>[1,2,3,4,5]</code> nos devolverá
la lista <code>[2,4,6,8,10]</code>. En el código podemos apreciar la función
<i>lambda</i> que realiza la multiplicación, que viene definida entre las
palabras claves <code>fun</code> y <code>end</code>.
</p>

<p>
Aunque también hubiéramos podido ahorrarnos toda esa sintaxis y
recurrir a la sintaxis de las <i>lists comprehensions</i>, que te sonarán
porque se las han copiado otros lenguajes como <i>Python</i>:
</p>

<div class="org-src-container">
<pre class="src src-erlang">Lista = [1,2,3,4,5],
[<span style="color: #f8f8f2; font-weight: bold;">X</span>*2 <span style="color: #ff79c6; font-weight: bold;">||</span> <span style="color: #f8f8f2; font-weight: bold;">X</span> <span style="color: #ff79c6; font-weight: bold;">&lt;-</span> <span style="color: #f8f8f2; font-weight: bold;">Lista</span>].
</pre>
</div>

<p>
Mucho más sencillo de leer y ver, ¿no?. O, otro ejemplo por utilizar
una función resumen de listas:
</p>

<pre class="example" id="org14ea053">
~ $ erl
Eshell V11.0.2  (abort with ^G)
1&gt; Lista = [1,2,3,4,5].
[1,2,3,4,5]
2&gt; lists:sum([X*2 || X &lt;- Lista]).
30
3&gt;
</pre>

<p>
También podemos filtrar qué elementos nos interesan de la lista, por
ejemplo, si queremos hacer las operaciones sólo sobre los impares:
</p>

<pre class="example" id="orgc1f17a5">
3&gt; [X || X &lt;- [1,2,3,4,5], X rem 2 /= 0].
[1,3,5]
4&gt; [X*2 || X &lt;- [1,2,3,4,5], X rem 2 /= 0].
[2,6,10]
5&gt; 
</pre>
</div>
</div>
<div id="outline-container-org4c8d194" class="outline-3">
<h3 id="org4c8d194">Optimizador del código compilado</h3>
<div class="outline-text-3" id="text-org4c8d194">
<p>
Me resisto en llamar a <code>HiPE</code> un <i>JIT</i>, sin embargo, funciona de
manera similar. <i>Hight Performance Erlang</i> es un módulo que puede ser
llamado al compilar para acelerar un poco el código. Sin embargo, esas
mejoras tienen algún inconveniente que hay que valorar y es mejor leer
la documentación para ver si nos compensa.
</p>

<p>
Llamarlo es sencillo, por ejemplo, al hacer la compilación del módulo
desde el <i>prompt interactivo</i>:
</p>

<pre class="example" id="orgf5ea3ca">
~ $ erl
Eshell V11.0.2  (abort with ^G)
1&gt; c(factorial, [native]).
{ok,factorial}
2&gt;
</pre>

<p>
Como se puede ver una forma sencilla de hacerlo, aunque se puede
afinar aún más utilizando las opciones de <code>HiPE</code> llamando a la
compilación con <code>[native, {hipe, Opciones}]</code>.
</p>
</div>
</div>
</div>
<div id="outline-container-org613b7c0" class="outline-2">
<h2 id="org613b7c0">Conclusiones</h2>
<div class="outline-text-2" id="text-org613b7c0">
<p>
Después de este ladrillo intentando escribir sobre todo <i>erlang</i> aún
sabiendo que es imposible, vienen las conclusiones:
</p>

<ol class="org-ol">
<li>Me gusta <i>erlang</i> y voy a seguir utilizándolo. Algunas de mis cosas
ya se están escribiendo en <i>erlang</i>. Aquellas que no necesitan una
<i>interface</i> (que esas siguen corriendo en <i>elisp</i>.</li>
<li>Es un lenguaje muy flexible y expresivo. Aunque al principio me
resultaba un poco marciana la sintaxis una vez acostumbrado a ella
me resulta agradable.</li>
<li>Cuando algo falla, sus informes de error son muy precisos y es muy
fácil saber qué ha fallado y dónde. Y los fallos suelen caer de
parte de la lógica del programador, porque el no poder modificar
las <i>variables</i> implica que nunca el error se debe a que tomen un
valor equivocado, ni tienes que estar trazando paso a paso a ver
cómo varían.</li>
<li>Cuando ejecuto el código y levanta varios procesos, estos se
adaptan automáticamente y usan todos los núcleos de la máquina sin
escribir ni una línea para preocuparme de los hilos... ya se ocupa
la <code>vm</code> de <i>erlang</i>. Lo cual es un descanso para mí.</li>
</ol>

<p>
Pues hasta aquí hemos llegado. Supongo que con un exceso de
información para un artículo del <i>blog</i>, pero a la vez escasa para
intentar aprender algo. Y todo esto, sólo mientras sigo aprendiendo,
porque esto es un mundo de aprendizaje nuevo. De un lenguaje
<i>marciano</i>, que no es de los más populares, pero sí uno de los más
potentes que he encontrado: capaz de montar sistemas distribuidos con
suma facilidad, de sustituir el código sin pararlo todo, de crecer y
escalar de forma casi «natural».
</p>

<p>
Sólo por probar levanté un nodo con cientos de miles de procesos y en
una prueba llegué a los dos millones (eso sí, casi quemo el procesador
con todos sus núcleos funcionando al 100% durante un buen rato). En
una máquina con más memoria y procesador ¿hasta dónde hubiera llegado?
No sé, me parece un lenguaje digno de destacar y de ponerlo en valor y
por eso he escrito este artículo. Espero que sea útil.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/erlang/index.html">erlang</a> <a href="/tags/programación/index.html">programación</a> ]]></description>
  <category><![CDATA[erlang]]></category>
  <category><![CDATA[programación]]></category>
  <link>https://notxor.nueva-actitud.org/2020/07/25/mis-impresiones-sobre-erlang.html</link>
  <pubDate>Sat, 25 Jul 2020 09:45:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Tomar notas con org-roam]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-07-17</div>
<p>
Si no conocéis <code>org-roam</code> no os preocupéis, vamos a verlo en este
artículo. Hace poco que lo descubrí, gracias a Patricio (¿Maxxcan?,
soy muy malo para los nombres y si me los cambiáis más ;-). En todo
caso, por alguna desconocida razón que no llego a comprender, es uno
de los lectores de mi <i>blog</i> y participa en el grupo de <i>Telegram</i> que
creé para hacer comentarios. Creo que fue el día 9 (julio de 2020),
cuando por la tarde, así como sin querer la cosa, habló del paquete de
<i>Emacs</i> <code>org-roam</code>. Enlazó el paquete y tuvimos una conversación en el
grupo sobre tomar notas y los distintos métodos de hacerlo.
</p>

<p>
Todos necesitamos tomar notas y yo hasta ahora lo había hecho con
<code>org-mode</code> a pelo. Ya he contado que tengo activado en el <code>init.el</code> un
registro para abrirlo con mi <i>bloc de notas</i>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(set-register ?a '(file . <span style="color: #f1fa8c;">"~/agenda/bloc-notas.org"</span>))
</pre>
</div>

<p>
Eso me permite abrir el <i>bloc</i> con <code>C-x r j a</code> y está siempre a mano
para anotar lo que necesite. Sin embargo, el método de las anotaciones
es básicamente jerárquico: lo tengo organizado por cabeceras y las
anotaciones van en otras cabeceras, divididas en temas y párrafos, que
aunque estén relacionados pueden estar perdidos en la jerarquía de los
títulos.
</p>

<p>
<code>org-roam</code> presenta una forma de tomar notas con <code>org-mode</code> de manera
no jerárquica, sino relacional. Quiere decir que las notas son todas
de la misma importancia y lo realmente interesante es la relación
entre las ideas anotadas, no tienes que pensar en qué <i>título</i> vas a
meterla, simplemente anotas la idea, le pones etiquetas y la enlazas
con otras notas relacionadas. El sistema te proporciona un método para
seguir esos enlaces en ambas direcciones: de nota <i>enlazante</i> a nota
enlazada y al revés, de nota enlazada a nota <i>enlazante</i>. ¿Qué método
de anotación es ese? <i>Zettelkasten</i>.
</p>
<div id="outline-container-org2b4a397" class="outline-2">
<h2 id="org2b4a397">Zettelkasten</h2>
<div class="outline-text-2" id="text-org2b4a397">
<p>
... con perdón! Ese es el método que viene a implementarse con el
paquete <code>org-roam</code>. Una traducción muy libre del nombrecito es «cajón
de fichas» y básicamente es un método analógico de tarjetas guardadas
en un cajón, o en una caja de zapatos, según los recursos. Mejor de lo
que yo lo pueda explicar, <a href="https://medium.com/voces-en-espa%C3%B1ol/zettelkasten-c%C3%B3mo-un-erudito-alem%C3%A1n-fue-tan-incre%C3%ADblemente-productivo-b16643e170cc">lo explican en este artículo enlazado</a>.
</p>

<p>
Resumiendo, el método consiste en tener las notas distribuidas en
fichas. Cada ficha representa una idea expresada de forma breve, está
numerada o identificada con un identificador único y se relaciona con
otras fichas por su correspondiente identificador único y se pueden
agrupar por «etiquetas». En algunos casos, la información es larga y
proviene de alguna otra fuente, por lo que en la ficha se guarda la
referencia y no hace falta copiar todo.
</p>

<p>
Como se puede ver es una forma de anotar donde cada anotación puede
moverse dentro del cajón en el orden que queramos. Son papeles
independientes y los podemos ordenar a nuestro gusto. ¿Qué aporta
<code>org-roam</code> a este sencillo método? Pues la facilidad de hacerlo
gracias a la magia de los enlaces, las etiquetas, las claves y todas
esos <i>pichorros</i> tan fáciles de hacer en <code>org-mode</code>. Para <code>org-roam</code>
cada ficha es un fichero <code>.org</code> que contiene las siguientes cosas:
</p>

<ol class="org-ol">
<li>Un título: este campo marcado como <code>#+title:</code> es obligatorio.</li>
<li>Unas etiquetas: marcadas como <code>#+roam_tags:</code>, son opcionales.</li>
<li>Un enlace: marcado como <code>#+roam_key:</code>, es opcional. Luego lo
podemos buscar mediante <code>org-roam-find-ref</code>.</li>
<li>El contenido de la anotación. Aquí podemos escribir cualquier tipo
de texto <code>org-mode</code>.</li>
<li>Una serie de enlaces a otras fichas relacionadas. A mí me gusta
agruparlos al final, pero nada impide que metas los enlaces
entremezclados con el contenido de la anotación.</li>
</ol>

<p>
Por ejemplo, para escribir este artículo he utilizado este sistema de
notas y una de las pijadas que me han gustado es que el propio
<code>org-roam</code> puede mostrar cómo se relacionan mis anotaciones mediante
un gráfico. Muestro el gráfico de las notas tomadas para escribir el
presente artículo y luego entraremos en detalles de las dependencias
necesarias para que lo haga:
</p>


<figure id="org2d0c0b2">
<img src="./imagen/articulo.svg" alt="relación entre notas" class="org-svg" title="relaciones" width="100%">

<figcaption><span class="figure-number">Figure 1: </span>Gráfico de relaciones entre anotaciones</figcaption>
</figure>
</div>
</div>
<div id="outline-container-orgaaf9d95" class="outline-2">
<h2 id="orgaaf9d95">Paquete <code>org-roam</code>, instalación, problemas y configuración</h2>
<div class="outline-text-2" id="text-orgaaf9d95">
</div>
<div id="outline-container-org9d1c636" class="outline-3">
<h3 id="org9d1c636">Instalación</h3>
<div class="outline-text-3" id="text-org9d1c636">
<p>
La instalación es sencilla, como cualquier paquete en <i>Emacs</i>; está en
<i>Melpa</i> y si tenéis enlazado ese repositorio, basta con:
</p>

<p>
<code>M-x package-install &lt;RET&gt; org-roam &lt;RET&gt;</code>
</p>

<p>
Normalmente el tema de la instalación de paquetes en <i>Emacs</i> es algo
que me salto, por lo sencillo que es. Sin embargo, en este caso me
encontré con algunas dependencias problemáticas que no se me
instalaron correctamente y tuve que instalar a mano <code>emacs-sqlite3</code>.
</p>

<p>
El funcionamiento de <code>org-roam</code> depende también de algunas
herramientas externas, como el mencionado <code>sqlite3</code> y, para generar
los gráficos como el anterior, de <code>graphviz</code>. No he visto que tenga
más dependencias externas. El resto, como <code>org</code>, son paquetes de
<i>Emacs</i> y se instalaron correctamente ─si no lo estaban ya─ durante la
instalación.
</p>
</div>
</div>
<div id="outline-container-orgea02d3b" class="outline-3">
<h3 id="orgea02d3b">Problemas</h3>
<div class="outline-text-3" id="text-orgea02d3b">
<p>
Superados los problemas de la instalación, que no me llevó más que
unos minutos me encontré otros problemas más serios y que en un
principio casi estuvieron a punto de que abandonara la utilización del
paquete. Persistí, porque en el grupo de <i>Telegram</i> me comprometí a
probar el «chismático» y a escribir el presente artículo.
</p>

<p>
El mayor problema se me presentó cuando editaba notas. Al crearlas no
había problema pero al modificarlas podía ocurrir, y lo más frustrante
era que unas veces lo hacía y otras no, que desaparecieran del
directorio. Al guardar los cambios aparecía un mensaje de <i>buffer de
sólo lectura</i>. Además, como tengo configurado que los ficheros
temporales me los guarde en <code>/tmp</code> resulta que el fichero <i>bloqueado</i>
lo guardaba allí y desaparecía del directorio donde debía estar. Tardé
un tiempo en darme cuenta de qué estaba pasando y me desesperó el
tema. En esos momentos hubiera desechado el <code>org-roam</code>, pero de
casualidad, encontré que yendo al final de la nota añadiendo una línea
y volviéndola a borrar ─lo que sería un <code>touch nota</code>, por lo directo─,
la volvía a guardar correctamente. Aún así, un engorro.
</p>

<p>
Sin embargo, éste, que era el mayor problema, se solucionó con la
actualización del día 11. Justo dos días después de haberme propuesto
a hacer pruebas y estar a punto de tirarlo por el sumidero del olvido,
resulta, que hay una actualización (2020-07-11) que solucionó el
problema y no me he vuelto a encontrar bloqueada una nota en un
<i>buffer de sólo lectura</i> que me haya forzado a los malabares de
guardar que había descubierto.
</p>

<p>
Otro problema que solucionó esa actualización era el tiempo de carga.
Las primeras pruebas eran desesperantes y me hicieron desistir de
configurar el paquete directamente en el <code>init.el</code>, tardaba en cargar
el <code>org-roam</code> más de medio minuto y según el volumen de notas, hasta
el minuto entero. Vale que no tengo la máquina más rápida del mundo
─todo lo contrario─, pero <i>Emacs</i> me carga, con todo lo que necesito,
en apenas unos segundos: más me tardan en cargar otros IDEs.
</p>

<p>
Por eso, saqué la configuración del paquete del inicio de <i>Emacs</i>. La
velocidad de carga, que fue el principal motivo para ello, lo
arreglaron también con la última actualización, pero encontré otras
ventajas a tener la configuración fuera y por eso lo mantengo así.
En seguida comento cómo tengo la configuración y por qué.
</p>

<p>
Por último, otro problema que me encontré es que el <i>buffer</i> de
<code>org-roam</code> no siempre mostraba la información adecuada.
</p>


<figure id="org76133ce">
<img src="./imagen/Captura-pantalla_org-roam.png" alt="Captura de pantalla" title="org-roam" width="100%">

<figcaption><span class="figure-number">Figure 2: </span>Captura de pantalla de <code>org-roam</code> funcionando</figcaption>
</figure>

<p>
Como se puede apreciar en la pantalla, el <i>buffer</i> de <code>org-roam</code> a la
derecha, debe mostrar aquellas notas que enlazan a la que tienes
abierta... pues bien, a veces no funciona. No funciona a la primera,
quiero decir. He descubierto, que cuando no actualiza bien, cierras el
modo con <code>org-road-mode</code> y lo vuelves a abrir con el mismo comando y
todo parece funcionar de nuevo. Sospecho que al cargar, tiene que
rehacer el índice de la base de datos <code>sqlite3</code> y parece que algo no
termina de ir bien cuando lo cargo como <code>(org-roam-mode t)</code>.
</p>
</div>
</div>
<div id="outline-container-orge187256" class="outline-3">
<h3 id="orge187256">Configuración</h3>
<div class="outline-text-3" id="text-orge187256">
<p>
Como dije antes, me hice la configuración del paquete aparte del
<code>init.el</code>. Al final tengo, en la actualidad, tres ficheros de
configuración en tres directorios distintos, porque me permite separar
las anotaciones de distintos proyectos sin que se mezclen. Cada
proyecto tiene su directorio de notas y en cada uno de ellos hay un
fichero <code>config.el</code> con un contenido similar a:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Ajustes para org-roam
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-roam-directory <span style="color: #f1fa8c;">"directorio/org-roam"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-roam-db-location <span style="color: #f1fa8c;">"directorio/org-roam/org-roam.db"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-roam-graph-viewer nil)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-roam-capture-function 'org-roam-capture)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-roam-completion-system 'ivy)
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Activar el modo
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-roam-mode t)
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Teclas para el modo
</span>(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r b"</span>) 'org-roam)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r c"</span>) 'org-roam-capture)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r d"</span>) 'org-roam-doctor)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r f"</span>) 'org-roam-find-file)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r g"</span>) 'org-roam-graph)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r i"</span>) 'org-roam-insert)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r m"</span>) 'org-roam-mode)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r r"</span>) 'org-roam-find-ref)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c r t"</span>) 'org-roam-buffer-toggle-display)
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Por si los fallos
</span>(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">buffer-backlinks</span> ()
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (counsel-ag (buffer-name) org-roam-directory))
</pre>
</div>

<p>
Básicamente lo que se modifica en el fichero es el directorio al que
apunta. Todo lo demás permanece igual. Leyendo el código no hay mucho
más que explicar. En el primer grupo se establecen algunas variables
como el <code>org-roam-directory</code>, la base de datos en
<code>org-roam-db-location</code>, el visor de gráficos en
<code>org-roam-graph-viewer</code> ─por defecto abre <i>firefox</i> y al ajustarlo al
valor <code>nil</code> lo hace en un <i>buffer svg</i> interno de <i>Emacs/─, la función
para realizar la /captura</i> de notas y el sistema de completado que
utilizas, en mi caso <code>ivy</code>.
</p>

<p>
Sobre la captura de notas he de decir que he intentado crear un par de
plantillas diferentes siguiendo la documentación que viene con el
paquete e incluso copiando la que viene por defecto en el propio
código de <code>org-roam</code> y me ha sido imposible ajustar nada. He intentado
hacerlo tanto para capturar con <code>org-capture</code> como para
<code>org-roam-capture</code> y en ninguna de las dos he tenido éxito. Cuando he
metido las definiciones propias, el sistema dejaba de capturar notas.
No sé si es porque me falta algo en la configuración o por algún <i>bug</i>
que no logro encontrar. El caso es que, de momento, me tengo que
apañar con la plantilla por defecto, que se me hace un poco escasa.
</p>

<p>
Luego, en el código, se activa el modo <code>org-roam-mode</code> y se añaden
algunas teclas para facilitar el trabajo.
</p>

<p>
Por último, he adaptado una función que Isidoro, otro lector del
<i>blog</i>, puso en el grupo de <i>Telegram</i>. Cuando no carga bien el modo y
no aparecen las notas que enlazan la que estás modificando, a veces me
viene mejor utilizar la función <code>buffer-backlinks</code> que andar cerrando
el modo y volviéndolo a abrir. O dicho de otra manera, si estoy
modificando una sola nota por algo y no voy a trabajar sobre el resto
de las anotaciones, me basta con llamar a esa función. Si el trabajo
es más de «documentación» y estoy haciendo anotaciones, enlazando y
demás, merece la pena el recargar el modo para que funcione como
debe. Como podéis ver, sólo utiliza <code>counsel-ag</code> para hacer una
búsqueda del nombre del <i>buffer</i> que estás editando en el directorio
de notas que está definido. Eso muestra una lista de archivos que
enlazan al <i>buffer</i> abierto y puedes seleccionar y abrir el que
necesites.
</p>

<p>
Con todo esto, cuando quiero tomar notas para alguno de los proyectos,
cargo el fichero <code>config.el</code> en le directorio correspondiente y ya lo
puedo utilizar con normalidad. Si cambio de proyecto, sólo tengo que
cargar su correspondiente configuración y todo lo demás permanece
igual. Quizá no sea lo más óptimo, pero funciona.
</p>
</div>
</div>
</div>
<div id="outline-container-org4c73729" class="outline-2">
<h2 id="org4c73729">Conclusiones</h2>
<div class="outline-text-2" id="text-org4c73729">
<p>
No sé aún si este método ha llegado para quedarse, como digo lo vengo
utilizando desde hace una semana y seguramente aún no he visto todos
sus <i>pros</i> y <i>contras</i> como para asegurar que voy a cambiar de método.
De momento, puedo asegurar que me gusta cómo funciona la relación
entre las notas, los temas, las etiquetas: los enlaces te llevan a
navegar las anotaciones de una manera distinta cada vez. ¿Hay alguna
nota relacionada con la idea que estás anotando? <code>C-c r i</code> y la
seleccionas para que incruste el enlace: automáticamente utiliza el
título de la nota y forma el enlace fácilmente a pesar de que se
guardan en fichero de nombres <i>rarunos</i> (/timestamp/+nombre de
fichero, que no tiene por qué coincidir con el título de la nota).
Todo muy a mano y muy sencillo de mantener.
</p>

<p>
Permite buscar rápidamente referencias o enlaces que hayas anotado, en
mi configuración con la combinación de teclas <code>C-c r f</code> se muestra la
lista de todas las notas que contienen una referencia <code>#+roam_key</code>, a
poco que hayas puesto un título suficientemente claro, encuentras el
enlace que buscas de manera inmediata.
</p>

<p>
Además, el tener la configuración como la tengo, de manera que me
permita separar la información por <i>proyectos</i> o <i>temas</i> me está
resultando muy útil. Supongo que una de las grandes ventajas de este
método es la capacidad de gestionar muchas ideas en un sólo sistema,
sin embargo en mi caso, con proyectos que van desde el <i>abuso
infantil</i> y otros temas que trabajo como psicólogo, pasando por cosas
de programación o de <i>Emacs</i>, y por los artículos de este <i>blog</i>. Son
asuntos tan dispares que no consigo nada mezclándolos, al contrario:
se me pierde la información entre demasiada otra no pertinente... y
esto sólo con una semana de trabajo normal, no quiero pensar lo que
puede acumular la anotación de años de uso.
</p>

<p>
Pues eso es todo. Os animo a que lo probéis y así podáis determinar si
el método se adecúa a vuestra forma de trabajar. Ya digo que, <i>a
priori</i> parece un método interesante para mejorar las anotaciones.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/org-mode/index.html">org-mode</a> <a href="/tags/org-roam/index.html">org-roam</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[org-mode]]></category>
  <category><![CDATA[org-roam]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2020/07/17/tomar-notas-con-org-roam.html</link>
  <pubDate>Fri, 17 Jul 2020 22:32:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Realidad virtual y psicología]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-07-08</div>
<p>
Estos días de atrás estuve hablando con un colega de la utilización de
la realidad virtual en la psicología moderna. De unos años para acá se
han publicado muchos artículos sobre el tema y sólo <a href="https://duckduckgo.com/?t=ffnt&amp;q=%22realidad+virtual%22+site%3Awww.infocop.es&amp;atb=v88-1&amp;ia=web">hace falta una
pequeña búsqueda en www.infocop.es para verlo</a>, nuestro buscador
favorito nos mostrará un interesante listado de artículos. No sólo
artículos independientes o investigaciones, también encontraremos
publicidad encubierta de algunas casas intentando vender algún
cacharro a los psicólogos.
</p>

<p>
Básicamente, por lo que se ve, la <i>realidad virtual</i> ofrece un entorno
seguro donde exponer al sujeto a las situaciones que le causan
problemas, por lo que esta tecnología se restringe en su mayoría a
trastornos como fobias o estrés situacional ─como hablar en público,
conducir, volar, etc─. Es decir, sólo para un reducido número de
trastornos o problemas que podemos ver en la clínica.
</p>

<p>
Sin embargo, y aunque comenzó con esas premisas, nuestra conversación
giró más hacia el aspecto lúdico de los aparatos, o concretamente la
proliferación de vídeos de gente dándose tortazos con <i>las gafas
puestas</i>. A mí me recuerdan a cuando se inventó el cine, esas
fotografías en movimiento de un tren que se acercaba y que hacían huir
al público mientras las damas se desmayaban en sus sillas ─más bien
creo que se desmayaban por la falta de oxígeno provocada por un corsé
demasiado apretado para estar sentadas, pero le venía bien a la
farándula─. Ahora nos sentamos impasibles en las salas de
cine. Nuestro humano cerebro se ha acostumbrado a situar lo que ve en
una pantalla <i>fuera de la realidad</i> y casi no se inmuta por lo que le
muestren físicamente. Durante los primeros momentos del cine 3D
tuvimos otro asalto más de cosas disparadas contra la percepción del
espectador para hacerle dar un respingo en el asiento, pero también a
eso nos hemos ido acostumbrando y esos efectos no son tan llamativos a
estas alturas, de hecho se han convertido en algo muy molesto para
mí. Sin embargo, tal como va la simulación efectista, parece que a
todo el mundo se le pasa por alto, que lo importante de esas imágenes
que percibimos <i>fuera</i> es que toquen los mecanismos de la empatía, los
sentimientos y la imaginación, para encontrarnos que cuanto más
realistas pretenden ser, más se escapan a esos mecanismos.
</p>

<p>
Desde mi punto de vista, el Hombre ─como especie─ ha estado rodeado de
virtualidad que, desde siempre, se ha empleado para <i>educarlo</i>. Esa
virtualidad que hace que seamos adictos a una buena historia. Los
primitivos contaban las suyas reunidos alrededor del fuego, con ellas
educaban a los más pequeños sobre cómo funciona el mundo, cómo se caza
o cómo los dioses pueden ser crueles. El contenido podía ser
inventado, como sus cosmologías y mitologías, o remitir con hechos más
o menos reales de qué se esperaba del comportamiento de un buen
proveedor de la tribu.
</p>

<p>
Quizá por eso, también, durante la infancia, estamos más dispuestos a
creer lo que nos digan y lo que nos dicen se marca a fuego en nuestro
intelecto como guía para los futuros aprendizajes. El contar historias
ha estado evolucionando junto con la tecnología que hemos ido
desarrollando: desde la transmisión oral, pasando por la escritura, la
radio, el cine y ahora la tecnología 3D. Por tanto, desde mi punto de
vista, la <i>virtualidad</i> se ha venido empleando durante mucho tiempo,
casi desde el principio de la Humanidad para modificar el
comportamiento del ser humano que debe enfrentarse a la realidad con
muchas menos herramientas instintivas que otras especies. Se han
escrito novelas, dramas, óperas sobre los más diversos temas del
comportamiento humano: ¿cómo debemos comportarnos en el <i>amor</i>, en la
<i>guerra</i>, en la <i>vida</i> o en la <i>muerte</i>? Encontrarás cientos de obras
que te lo cuenten, desde los muy diversos puntos de vista y con los
<i>anteojos</i> culturales de la época y la sociedad de cuando fuera
escrita la obra. En todos los casos el mecanismo reconocible era
generar en el lector, espectador, la suficiente identificación con el
protagonista para sufrir sus desventuras y gozar sus dichas
mostrándonos el camino <i>correcto</i> de cómo deberían ser las cosas.
</p>

<p>
La virtualización que estamos alcanzando no es más que una sublimación
de ese mecanismo. Coloca al sujeto en el centro de la virtualidad no
sólo como esa identificación intelectual con un protagonista externo,
sino que nos lo muestra <i>casi físicamente</i> como tal. Sin embargo, todo
ese aparato se queda en lo superficial, es decir: se simula el entorno
físico, pero ¿qué ha del resto? ¿Qué ocurrirá a todas esas terapias
basadas en la realidad virtual cuando nos acostumbremos a ella como
nos acostumbramos al cine? Si no conectan con el ámbito interior del
ser humano, de los sentimientos, la empatía y el pensamiento, no sólo
con la conducta externa, serán totalmente ineficaces.
</p>

<p>
Además aducen el problema de que cuanto más inmersivos son los
sistemas, más difícil es dotarles de realismo y, por tanto, la
percepción «aparato de diseño 3D» puede sacar al sujeto de la
«inmersión». Por supuesto, siempre se necesita a un psicólogo al lado
contando lo que tiene que hacer, sentir y demostrar el sujeto inmerso
en su situación de estrés.  Porque al final, el cambio viene no sólo
de la conducta externa, sino también de la interna: de pensamientos y
sentimientos. Y parece que esos, al final, <i>se tocan</i> con palabras.
</p>

<p>
Por establecer un paralelismo con los juegos, otro tema que también
apareció en la conversación, la tecnología ha ido generando cada vez
juegos más complejos de ejecución con entornos casi reales
donde... ¿se desarrolla una historia?  Por lo que he visto, pocos
juegos modernos con toda la tecnología 3D desarrollan una historia más
allá de «eres un combatiente en donde sea, mata a todo lo que se
mueva»... chimpún. ¿Qué ha ocurrido? Se podría utilizar esa tecnología
para hacer juegos mucho más sugestivos, que cuenten historias que se
muestren casi como películas delante de lo que hacemos. Sin embargo,
esos juegos serían un fracaso, casi un castigo: lentos e inactivos. Es
curioso que nuestra imaginación juegue a la inversa con estos temas, y
es que, creo, que cuanto más trabaja la imaginación más «inmersiva» es
la historia, cuanto más «inmersivo» es el entorno menos trabajamos la
imaginación.
</p>

<p>
Me explico. A los que nos gusta leer, solemos encontrar, salvo muy
raras excepciones, mejor el libro que la película: en el libro nos
<i>hablan</i> de cosas que en la película sólo se pueden inferir según lo
afortunados que estén los que allí trabajan mostrando emociones y
pensamientos; si en el libro nos cuentan sobre olores y sabores,
podemos casi sentir «el olor a tierra mojada mientras amanece en el
valle», en la película nos pondrán una foto casi fija del valle
amaneciendo y no más, porque no se puede hacer más, como mucho poner
una <i>voz en off</i> (palabras). Las novelas pueden detenerse a poner en
valor cualquier aspecto ínfimo del entorno que lo haga más real,
porque usa palabras dirigidas a la imaginación, el cine no. Las
películas de acción triunfan, las novelas de acción no tanto: porque
la acción puede ocurrir completamente en los pensamientos o la
imaginación de un personaje. Cuanto más avanza la tecnología para
simular la realidad, más aleja el interior de las personas de ello.
Porque en el más puro realismo, no podemos percibir, del todo, los
pensamientos y sentimientos de los demás. Podemos inferirlos,
aproximarnos a ellos desde los indicios que nos muestran sus gestos y
actos, pero para hacerlo, necesitamos esas acciones externas.
</p>

<p>
Esto me lleva a plantearme una vieja pregunta que me acompaña desde
hace años: ¿Podemos diseñar juegos terapéuticos? Algo así como
aventuras conversacionales hechas a medida del jugador, en la que
pueda practicar virtualmente la correcta forma de comportarse en las
situaciones estresantes, que apele a sentimientos, pensamientos y no
sólo a acciones externas. Deberían, creo yo, fomentar el uso de la
imaginación y para eso el «texto» viene mucho mejor recomendado que el
gráfico 3D, desde mi humilde punto de vista. Y estoy casi por
responder que si tal cosa pudiera hacerse, sería desde los viejos
juegos de texto: ficción interactiva o como lo queráis llamar y no
desde los más modernos juegos 3D.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/psicología/index.html">psicología</a> <a href="/tags/juegos/index.html">juegos</a> ]]></description>
  <category><![CDATA[psicología]]></category>
  <category><![CDATA[juegos]]></category>
  <link>https://notxor.nueva-actitud.org/2020/07/08/realidad-virtual-y-psicologia.html</link>
  <pubDate>Wed, 08 Jul 2020 00:03:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Control de tiempos con org-mode]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-06-27</div>
<p>
Estos días en que el teletrabajo ha tenido un impulso importante
empezamos a necesitar controlar un poco más el tiempo de trabajo, el
que dedicamos a nuestras tareas laborales que se nos está mezclando
con el propio personal.
</p>

<p>
En este <i>blog</i> ya se ha hablado muchas veces de <code>org-mode</code>, de la
agenda que proporciona, de cómo se gestionan las tareas, cómo podemos
etiquetarlas dividiendo proyectos, etc. En fin, una herramienta de
control de tiempo muy flexible, pero hasta ahora no había hablado de
cómo <i>cronometrar</i> el tiempo que dedicamos a cada una de esas tareas y
cómo registrarlo. ¿También proporciona <code>org-mode</code> algún <i>chismático</i> que
haga eso? Pues sí. Las herramientas que nos proporciona <i>emacs</i> para
hacer esta gestión son <code>logbook</code> y <code>clocktable</code>. Vamos a hacer el
proceso paso a paso y veremos lo sencillo que es en realidad llevar
una gestión de tiempo precisa.
</p>

<p>
Para no <i>guarrear</i> mi fichero de agenda, he preparado un fichero <code>org</code>
que contiene tareas inventadas para el ejemplo, si ya llevas tus
tareas con <code>org-mode</code> no necesitas crear ningún fichero, ya lo tienes
hecho. Pero si no quieres ensuciar tampoco tu fichero de agenda, copia
el siguiente código en un fichero <code>org</code>. Ten cuidado, porque al copiar
desde la web, es posible que ponga espacios en blanco delante de las
cabeceras, asegúrate que en las líneas que comienzan con <code>*</code> ese
asterisco no tiene ningún espacio en blando delante (las demás las
puedes dejar como caigan):
</p>

<pre class="example" id="orgf447c31">
* Trabajo
** Reuniones de organización
   :LOGBOOK:
   CLOCK: [2020-05-18 lun 08:01]--[2020-05-18 lun 08:50] =&gt;  0:49
   CLOCK: [2020-05-25 lun 08:01]--[2020-05-25 lun 08:55] =&gt;  0:54
   CLOCK: [2020-06-01 lun 08:00]--[2020-06-01 lun 09:13] =&gt;  1:15
   CLOCK: [2020-06-08 lun 08:01]--[2020-06-08 lun 09:00] =&gt;  0:59
   :END:

** HECHO Informe de estrategias futuras
   :LOGBOOK:
   CLOCK: [2020-06-25 jue 10:05]--[2020-06-25 jue 11:55] =&gt;  1:50
   CLOCK: [2020-06-26 vie 09:15]--[2020-06-26 vie 12:55] =&gt;  3:40
   :END:

** Comprobar correo electrónico
   :LOGBOOK:
   CLOCK: [2020-06-01 lun 12:10]--[2020-06-01 lun 12:15] =&gt;  0:05
   CLOCK: [2020-06-02 mar 12:10]--[2020-06-02 mar 12:15] =&gt;  0:05
   CLOCK: [2020-06-03 mié 12:10]--[2020-06-03 mié 12:15] =&gt;  0:05
   CLOCK: [2020-06-04 jue 12:10]--[2020-06-04 jue 12:15] =&gt;  0:05
   CLOCK: [2020-06-05 vie 12:10]--[2020-06-05 vie 12:15] =&gt;  0:05
   :END:

** Proyecto de Curso
*** Diseño de objetivos
    :LOGBOOK:
    CLOCK: [2020-05-26 mar 09:11]--[2020-05-26 mar 12:19] =&gt;  3:08
    CLOCK: [2020-05-28 jue 09:23]--[2020-05-28 jue 13:19] =&gt;  3:56
    :END:

*** Redacción del texto
    :LOGBOOK:
    CLOCK: [2020-06-24 mié 08:22]--[2020-06-24 mié 13:15] =&gt;  4:53
    :END:

** Proyecto de aplicación
*** Diseño de características necesarias
    :LOGBOOK:
    CLOCK: [2020-06-17 mié 08:00]--[2020-06-17 mié 13:00] =&gt;  5:00
    CLOCK: [2020-06-18 jue 08:00]--[2020-06-18 jue 13:00] =&gt;  5:00
    CLOCK: [2020-06-19 vie 08:00]--[2020-06-19 vie 13:00] =&gt;  5:00
    :END:
*** Programación de características
    :LOGBOOK:
    CLOCK: [2020-06-22 lun 08:00]--[2020-06-22 lun 13:00] =&gt;  5:00
    CLOCK: [2020-06-22 lun 14:00]--[2020-06-22 lun 17:00] =&gt;  3:00
    :END:

* Mantenimiento
** Administración del servidor
   :LOGBOOK:
   CLOCK: [2020-06-25 jue 08:15]--[2020-06-25 jue 14:15] =&gt;  6:00
   :END:

** Instalación de nueva aplicación web
   :LOGBOOK:
   CLOCK: [2020-06-26 vie 08:00]--[2020-06-26 vie 12:00] =&gt;  4:00
   :END:
</pre>

<p>
Si ahora no entiendes las anotaciones, no te preocupes, de eso voy a
hablar en este artículo, es sólo un fichero para hacer las pruebas.
Como ves sólo son unas cabeceras, que representan las tareas y en
algunas de esas cabeceras hay un bloque <code>:LOGBOOK</code> con una o varias
etiquetas <code>CLOCK:</code>, que en este caso son totalmente inventadas. Aún no
he hablado de cómo se generan esas etiquetas, lo haré a continuación.
</p>
<div id="outline-container-org81013eb" class="outline-2">
<h2 id="org81013eb">Contabilizar tiempos</h2>
<div class="outline-text-2" id="text-org81013eb">
<p>
Bien desde la ventana de la agenda, bien dentro del fichero de tareas
podemos poner en marcha el cronómetro. Basta situarnos en el título de
la tarea que vamos a iniciar y pulsar la combinación <code>C-c C-x i</code>, esto
pondrá en marcha el cronómetro. Bajo la tarea aparecerá, si no existe
ya, un bloque <code>:LOGBOOK:</code> y un campo <code>CLOCK:</code> con la fecha y la hora
de comienzo, con un formato parecido a:
</p>

<pre class="example" id="org36ba548">
** Tarea
    :LOGBOOK:
    CLOCK: [2020-05-27 mié 09:11]
    :END:
</pre>

<p>
Mientras está el cronómetro en marcha no debes cerrar la ventana de la
agenda ni la del fichero que contiene la tarea, o el cronómetro se
detendrá sin contabilizar tiempo. Bien, vale ¿Cómo paramos el
cronómetro y que nos cuente? Pues lo que debemos hacer es cuando
dejamos de trabajar, llamar a <code>C-c C-x o</code>. Hay otro modo, sin embargo,
para hacerlo y es, si tenemos un contador iniciado en una tarea con
alguna etiqueta <code>TODO</code>, al cambiar dicha etiqueta a <code>DONE</code> con la
habitual combinación <code>C-c C-t</code>, también detendrá <code>org-mode</code> el
contador y anotará fecha y hora de la parada:
</p>

<pre class="example" id="orgf9d8b36">
** Tarea
    :LOGBOOK:
    CLOCK: [2020-05-27 mié 09:11]--[2020-05-27 mié 12:19] =&gt;  3:08
    :END:
</pre>

<p>
Como se puede ver en el ejemplo, al añadir la etiqueta de
finalización, también añade una indicación del tiempo invertido en esa
tarea, después de un signo de flecha.
</p>

<p>
¿Qué pasa si no acabamos la tarea y la retomamos más adelante? Pues
nada, volvemos a realizar el proceso: cuando retomamos la tarea,
volvemos a pulsar <code>C-c C-x i</code> y cuando dejamos trabajar en ella
repetimos también el <code>C-c C-x o</code>.
</p>

<pre class="example" id="org3df4685">
** Tarea
    :LOGBOOK:
    CLOCK: [2020-05-27 mié 09:11]--[2020-05-27 mié 12:19] =&gt;  3:08
    CLOCK: [2020-05-28 jue 09:23]--[2020-05-28 jue 13:19] =&gt;  3:56
    :END:
</pre>

<p>
Como se puede apreciar, cada vez que trabajemos en ella y contemos el
tiempo, <code>org-mode</code> añadirá una etiqueta <code>CLOCK:</code> a su bloque
<code>:LOGBOOK:</code>. Tantas como necesitemos.
</p>

<p>
Bien, ya sabemos que en nuestra tarea hemos trabajado seis horas
y... vamos, 6:64... quería decir, digo 7:04. ¡Uff! ¿No hay una forma
más sencilla de hacerlo? Claro, lo que necesitamos es <code>clocktable</code>.
</p>
</div>
</div>
<div id="outline-container-orgc724f4b" class="outline-2">
<h2 id="orgc724f4b">clocktable</h2>
<div class="outline-text-2" id="text-orgc724f4b">
<p>
La forma sencilla de visualizar el tiempo que hemos cronometrado es
hacer un resumen de tiempos con una tabla <code>clocktable</code>. La puedes
poner en cualquier sitio del fichero, aunque yo tengo la tendencia de
ponerlas al principio del mismo. Si estás utilizando el fichero de
ejemplo que sugerí al principio del artículo, coloca el cursor en la
primera línea fichero, si no está en blanco, haz sitio con un par de
toques al <code>&lt;ENTER&gt;</code> y después pulsa la combinación <code>C-c C-x x</code>.
<i>Automágicamente</i>, aparecerá una tabla tal que:
</p>

<pre class="example" id="orgbcf173d">
#+BEGIN: clocktable :scope file :maxlevel 2
#+CAPTION: Clock summary at [2020-06-26 vie 13:17]
| Tarea                                   | Tiempo    |       |
|-----------------------------------------+-----------+-------|
| *Tiempo total*                          | *2d 6:47* |       |
|-----------------------------------------+-----------+-------|
| Trabajo                                 | 1d 20:47  |       |
| \_  Reuniones de organización           |           |  3:55 |
| \_  Informe de estrategias futuras      |           |  5:30 |
| \_  Comprobar correo electrónico        |           |  0:25 |
| \_  Proyecto de Curso                   |           | 11:57 |
| \_  Proyecto de aplicación              |           | 23:00 |
| Mantenimiento                           | 10:00     |       |
| \_  Administración del servidor         |           |  6:00 |
| \_  Instalación de nueva aplicación web |           |  4:00 |
#+END:
</pre>

<p>
Según dónde la generemos, es posible, que al llamarla, el <i>chismático</i>
nos coloque un valor diferente para la etiqueta <code>:scope</code>. Puede
mostrar, por ejemplo, el valor <code>subtree</code> que hará que los tiempos se
refieran sólo a la rama actual del árbol de tareas. También puede
mostrar el valor <code>file</code>, en cuyo caso, los tiempos se refieren al
fichero actual completo. O si lo deseamos, podemos cambiarlo al valor
<code>agenda</code> que nos contabilizará los tiempos de toda nuestra agenda.
Además, como ésta última es independiente del fichero que tengamos
abierto, podemos generar nuestra tabla de tiempos, e insertarla, en
cualquier <i>buffer</i> <code>org</code>: no necesitamos estar en la <i>agenda</i>.
</p>

<p>
Siguiendo con nuestro ejemplo, podemos darnos cuenta que en realidad,
nuestro árbol de tareas tiene tres niveles y sin embargo, sólo muestra
dos. Eso lo gestiona la etiqueta <code>:maxlevel</code>, si cambiamos ese valor a
<code>3</code>, y sin movernos de la primera línea (la del <code>#+BEGIN:</code>), pulsamos
<code>C-c C-c</code>. La tabla se recalculará completamente con los tres niveles
y una columna más.
</p>

<pre class="example" id="org9432f8e">
#+BEGIN: clocktable :scope file :maxlevel 3
#+CAPTION: Clock summary at [2020-06-27 sáb 13:29]
| Tarea                                      | Tiempo    |       |       |
|--------------------------------------------+-----------+-------+-------|
| *Tiempo total*                             | *2d 6:47* |       |       |
|--------------------------------------------+-----------+-------+-------|
| Trabajo                                    | 1d 20:47  |       |       |
| \_  Reuniones de organización              |           |  3:55 |       |
| \_  Informe de estrategias futuras         |           |  5:30 |       |
| \_  Comprobar correo electrónico           |           |  0:25 |       |
| \_  Proyecto de Curso                      |           | 11:57 |       |
| \_    Diseño de objetivos                  |           |       |  7:04 |
| \_    Redacción del texto                  |           |       |  4:53 |
| \_  Proyecto de aplicación                 |           | 23:00 |       |
| \_    Diseño de características necesarias |           |       | 15:00 |
| \_    Programación de características      |           |       |  8:00 |
| Mantenimiento                              | 10:00     |       |       |
| \_  Administración del servidor            |           |  6:00 |       |
| \_  Instalación de nueva aplicación web    |           |  4:00 |       |
#+END:
</pre>

<p>
Sí. Si comparamos las dos tablas, nos damos cuenta que la diferencia
es la cantidad de detalle en las entradas de la tabla. Los tiempos
generales son los mismos, pero ahora, los grupos de segundo nivel que
tenían subtareas de tercero están desglosadas en su nueva columna.
</p>

<p>
Otra de las cosas que podemos hacer es, por ejemplo, si necesitemos
contar los tiempos, no por tareas, sino durante un periodo de tiempo
determinado, podemos utilizar las etiquetas <code>:tstart</code> y <code>:tend</code>. Por
ejemplo, para mostrar el tiempo contabilizado durante el mes de mayo:
</p>

<pre class="example" id="org0974f66">
#+BEGIN: clocktable :scope file :maxlevel 2 :tstart "&lt;2020-05-01 vie&gt;" :tend "&lt;2020-05-31 dom&gt;"
#+CAPTION: Clock summary at [2020-06-27 sáb 14:33]
| Tarea                         | Tiempo |      |
|-------------------------------+--------+------|
| *Tiempo total*                | *8:47* |      |
|-------------------------------+--------+------|
| Trabajo                       | 8:47   |      |
| \_  Reuniones de organización |        | 1:43 |
| \_  Proyecto de Curso         |        | 7:04 |
#+END:
</pre>

<p>
Esas etiquetas pueden no ser absolutas, como en el ejemplo anterior.
Podemos utilizar, si nos interesa, especificaciones de tiempo
relativas. Para contabilizar los tiempos de la semana anterior
podemos utilizar <code>:tstart "&lt;-1w&gt;"</code> y <code>:tend "&lt;now&gt;"</code>.
</p>

<pre class="example" id="orge641a1b">
#+BEGIN: clocktable :scope file :maxlevel 2 :tstart "&lt;-1w&gt;" :tend "&lt;now&gt;"
#+CAPTION: Clock summary at [2020-06-27 sáb 14:41]
| Tarea                                   |    Tiempo |      |
|-----------------------------------------+-----------+------|
| *Tiempo total*                          | *1d 4:23* |      |
|-----------------------------------------+-----------+------|
| Trabajo                                 |     18:23 |      |
| \_  Informe de estrategias futuras      |           | 5:30 |
| \_  Proyecto de Curso                   |           | 4:53 |
| \_  Proyecto de aplicación              |           | 8:00 |
| Mantenimiento                           |     10:00 |      |
| \_  Administración del servidor         |           | 6:00 |
| \_  Instalación de nueva aplicación web |           | 4:00 |
#+END:
</pre>

<p>
O si nos interesa saber qué porcentaje de tiempo dedicamos a cada
tarea, podemos utilizar la etiqueta <code>:formula %</code>. Como podemos ver en
el siguiente ejemplo:
</p>

<pre class="example" id="org59dc5fc">
#+BEGIN: clocktable :scope file :maxlevel 2 :tstart "&lt;-1w&gt;" :tend "&lt;now&gt;" :formula %
#+CAPTION: Clock summary at [2020-06-27 sáb 14:43]
| Tarea                                   |    Tiempo |      |     % |
|-----------------------------------------+-----------+------+-------|
| *Tiempo total*                          | *1d 4:23* |      | 100.0 |
|-----------------------------------------+-----------+------+-------|
| Trabajo                                 |     18:23 |      |  64.8 |
| \_  Informe de estrategias futuras      |           | 5:30 |  19.4 |
| \_  Proyecto de Curso                   |           | 4:53 |  17.2 |
| \_  Proyecto de aplicación              |           | 8:00 |  28.2 |
| Mantenimiento                           |     10:00 |      |  35.2 |
| \_  Administración del servidor         |           | 6:00 |  21.1 |
| \_  Instalación de nueva aplicación web |           | 4:00 |  14.1 |
#+END:
</pre>

<p>
En realidad, en la etiqueta <code>:formula</code> se puede introducir entre
comillas cualquier fórmula que pondríamos en una etiqueta <code>#+TBLFM:"</code>
de una tabla. Eso añadirá una columna y la calculará.
</p>

<p>
Para ver cómo funcionan todos esos parámetros, lo mejor es jugar con
los valores e ir pulsando <code>C-c C-c</code> en la línea de definición para
observar los efectos que los cambios tienen en la tabla.
</p>
</div>
</div>
<div id="outline-container-org6263c1d" class="outline-2">
<h2 id="org6263c1d">Conclusiones</h2>
<div class="outline-text-2" id="text-org6263c1d">
<p>
La contabilidad del tiempo es importante, sobre todo para aquellos que
trabajando para terceros, tienen que facturar su tiempo. <i>Emacs</i>
proporciona una herramienta completa para hacerlo de una manera
sencilla y fácil.
</p>

<p>
Un detalle que he pasado por alto en el artículo y que no me voy a
detener mucho en explicar. A algunos les puede irritar, que generando
la mayoría de la tabla en español, la herramienta se empeñe en colocar
en <code>#+caption</code> la expresión <i>Clock summary at</i>. Si alguien lo quiere
cambiar, se puede hacer modificando la variable
<code>org-clock-clocktable-language-setup</code>.
</p>

<p>
Por mi parte, eso es todo. Hay más opciones que explorar y más
funciones a las que llamar (para eso está la ayuda de =org-mode), pero
en líneas generales esto es suficiente para llevar un control de
nuestro tiempo:
</p>

<ol class="org-ol">
<li>Consultar la agenda y situarnos en la tarea correspondiente.</li>
<li>Iniciar el contador de tiempo con <code>C-c C-x i</code> cuando comenzamos o
retomamos el trabajo en la tarea.</li>
<li>Parar el tiempo con <code>C-c C-x o</code> cuando terminamos o descansamos de
la tarea. O cuando marcamos como hecha la tarea en la agenda con
<code>C-c C-t</code>.</li>
<li>Generar la tabla resumen de tiempos con <code>C-c C-x x</code> donde la
necesitemos.</li>
</ol>

<p>
Cuatro pasos sencillos que nos permite tener controlado nuestro tiempo
en todo momento.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2020/06/27/control-de-tiempos-con-org-mode.html</link>
  <pubDate>Sat, 27 Jun 2020 16:52:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Programación y flujo de trabajo en Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-06-26</div>
<p>
Llevo un tiempo ocupado en proyectos personales y apenas saco tiempo
para escribir. He hablado ya sobre el proyecto de MUD que <a href="https://notxor.nueva-actitud.org/blog/2020/06/12/estos-aburridos-dias-de-confinamiento/">empecé
aquellos aburridos días de confinamiento</a> y que continúo con él. Como
ya expliqué, lo comencé con otra persona sólo por el ánimo de aprender
un poco de <i>erlang</i> y ahora lo estoy continuando yo solo.  De hecho,
me decidí a hablar sobre el proyecto porque cuando hablo de uno que
tenga entre manos se convierte en <i>vaporware</i> casi automáticamente,
dos o tres entradas de <i>blog</i> después.  Sin embargo, el presente
proyecto, de nombre provisional <i>erlmud</i>, continúa con buena salud y
casi se ha convertido en una obsesión. Hay cien mil detalles que atar
y mejorar, cada vez más comandos que soportar y parece no tener fin.
</p>

<p>
Cuando me quedé solo decidí utilizar del revés el criterio que
veníamos siguiendo con anterioridad: pasitos pequeños, pequeños
avances haciendo cada vez más grandes las capacidades del proyecto.
Así comenzamos con un programa básico de <i>erlang</i> que levantaba un
servidor escuchando un puerto, al que se podían conectar los clientes
e interactuar con él. Se implementaron varios comandos sencillos, que
no necesitaban muchas complicaciones de interpretación por parte del
programa y, poco a poco, se consiguió que entendiera comandos más
complejos que implicaban una acción que afectaba a varios objetos. La
filosofía que habíamos seguido era la de «pasitos cortos y medidos»,
cosas que parecían sencillas de implementar. Pero, al quedarme solo,
decidí que el tema era aprender. Total, el mundo no necesita otro MUD
y no tengo inconveniente en abandonar el proyecto si me estanco, así
que la pregunta que me hacía era: «¿Qué puede estancarme?». La
respuesta a esa pregunta fue la implementación de varios comandos que
pensé que sobrepasarían mis capacidades de programación o, por
ejemplo, el cambiar cómo el sistema almacena y maneja los datos. En
vista de que no termino de atascarme con esa filosofía, estoy
valorando el dar el salto definitivo. Si éste no me atasca tampoco, es
posible que quizá, después de todo, el proyecto no acabe en
<i>vaporware</i>. De momento, todo está hecho en un modo <i>erlang</i>
básico... ¿por qué no pasarlo al <i>framework</i> que proporciona <i>erlang</i>
para aplicaciones concurrentes: <i>OTP</i>?
</p>

<p>
De hecho, es un <i>rediseño</i> tan drástico que creo que será más
conveniente comenzar proyecto desde cero y así: volviendo a la
práctica de los «pasitos cortos y medidos» levantar otro proyecto más
sólido, aprendiendo de paso el <i>framework OTP</i>, mejorando las cosas
que se pudieron hacer mejor en el proyecto inicial.
</p>
<div id="outline-container-org1e49a5e" class="outline-2">
<h2 id="org1e49a5e">Flujo de trabajo</h2>
<div class="outline-text-2" id="text-org1e49a5e">
<p>
Hace poco, alguien me preguntó cómo es mi flujo de trabajo cuando
programo y, como una cosa es contarlo y otra verlo, he hecho una
captura de pantalla de cómo voy trabajando:
</p>

<video width="100%" controls>
    <source src="./prueba-captura.webm" type="video/webm">
    Tu navegador no soporta la etiqueta de vídeo, comprueba que soporta el formato webm
</video>

<p>
De todas formas lo cuento detalladamente para que no queden dudas.
</p>

<p>
En el vídeo se aprecia que trabajo con <i>Emacs</i> en una consola en modo
texto. <a href="https://notxor.nueva-actitud.org/blog/2020/03/13/utilizando-kitty-como-terminal/">Ya he contado por aquí que utilizo KiTTy</a>. Normalmente lo hago a
pantalla completa, pero en el vídeo está reducido a una ventana para
que sea más manejable el resultado de la captura. En la consola
trabajo con varias pestañas, la primera de ellas dedicada a <i>Emacs</i> y
luego voy abriendo y cerrando, según necesito, otras.
</p>

<p>
Cuando hago alguna modificación en el código y quiero probarlo, como
se puede apreciar en el vídeo, utilizo la combinación de teclas de
compilar de <i>Projectile</i>: <code>C-c p c</code>. Normalmente configurado a
ejecutar <code>make</code>, sin embargo, en el <code>Makefile</code> hice una opción que
compila y lanza el programa. Así que esa combinación de teclas, está
llamando a <code>make run</code>. Cuando lo lanzo, me abre un <i>buffer</i> de
compilación y si hay algún error, lo muestra. Desde ese <i>buffer</i> se
puede ir navegando por los errores para poder solucionarlos y volver a
compilar.
</p>

<p>
Si todo ha ido bien, la aplicación está funcionando y me paso a otra
pestaña donde hacer las pruebas del comando. Para el ejemplo, he
utilizado dos conexiones y mostrado algunos de lo comandos que soporta
el sistema. No tiene mucho más misterio, quizá lo que más guerra me
dio fue la parte de programar las salidas y que comprendiera tanto los
movimientos por nombre ─ir a sitio─, como los movimientos por puntos
cardinales ─norte, sur, etc─, implicando un cambio en la estructura de
los datos y el <i>parser</i> de comandos. El anuncio de «eventos» que
ocurren ─entrada y salida de personajes en la sala, etc─, fue una de
esas cosas que pensé que me iban a bloquear y que se resolvió en
apenas un par de ratos; aunque también tuve que convertir la lista de
conexiones en un diccionario que asociaba la conexión con el <i>PJ</i>.
</p>

<p>
¿Por qué utilizo el modo texto? Pues básicamente, porque el proyecto
corre en modo texto en una terminal <code>telnet</code>, aunque en este caso esté
utilizando <code>netcat</code>. Con ello no necesito cambiar de ventana ni de
escritorio, ni de nada. Una combinación de teclas me cambia de pestaña
o crea una nueva, ejecuto los comandos que necesito, la puede dividir
y todo sin salir del editor en el infinito bucle de «compilar, probar,
modificar, compilar...»
</p>
</div>
</div>
<div id="outline-container-orga759c23" class="outline-2">
<h2 id="orga759c23">Conclusión</h2>
<div class="outline-text-2" id="text-orga759c23">
<p>
Es sólo una muestra de cómo programo. Para otras funciones suelo
utilizar el modo gráfico, por ejemplo cuando utilizo <code>elfeed</code> para
leer las <code>rss</code>, o para escribir este artículo. Sin embargo, para
programar en el proyecto en el que estoy trabajando con <i>erlang</i>
encuentro más fluido el trabajo en modo texto combinando las
capacidades y potencialidades de <i>Emacs</i> y <i>KiTTy</i>.
</p>

<p>
¿Eso es mejor para todo el mundo? Pues supongo que cada uno tiene sus
manías y sus gustos. Algunos sustituirán <i>KiTTy</i> por una consola con
<code>tmux</code> o <code>screen</code>, otros sustituirán <i>Emacs</i> por su editor favorito.
Esas son mis manías y mis gustos. Supongo que es mejorable, según qué
punto de vista, pero de momento a mí me sirve y me encuentro cómodo.
Paso horas sin tocar el ratón y con los dedos en las teclas sin que
nada me distraiga.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2020/06/26/programacion-y-flujo-de-trabajo-en-emacs.html</link>
  <pubDate>Fri, 26 Jun 2020 19:30:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Formularios y datos con forms-mode de Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-06-23</div>
<p>
A veces echaba de menos la forma sencilla y eficiente que tenía el
<code>dbase</code> para proporcionar <i>formularios</i> que facilitaban la edición de
datos. Apenas cuatro comandos que disponían en la pantalla de texto
los campos de los registros y uno podía ponerse a introducir,
modificar y borrar datos de una base de datos.
</p>

<p>
En estos días me he visto en la tesitura de gestionar datos que me han
llegado en hojas de cálculo ─la navaja suiza de quien no conoce
Emacs─. Tenía que revisar y en su caso modificar algunos datos en una
tabla casi infinita, llena de columnas, que se perdían por los lados,
haciendo muy difícil saber dónde estabas. Me acordé de los formularios
de <i>Emacs</i> y decidí probarlos.
</p>

<p>
Para el ejemplo del artículo, muestro la gestión de una tabla grande
(con muchos registros), pero con muchas menos columnas, o campos, para
no liar las explicaciones. Ese ejemplo funciona sobre la biblioteca de
libros de la Frateco de Zaragoza.
</p>


<figure id="orga7e3cf5">
<img src="./imagen/Captura-forms-libroj.png" alt="Captura-forms-libroj.png">

</figure>

<p>
Captura de pantalla de cómo funciona el <code>forms-mode</code> de <i>Emacs</i>. En la
ventana se puede apreciar que hay cuatro campos (en amarillo) que nos
permiten modificar los contenidos. En este caso está modo edición, si
estamos en modo vista o <i>read only</i>, los campos no se destacan.
Además, si vemos lo que nos cuenta la línea de estado vemos varios
datos que nos pueden llamar la atención:
</p>

<ul class="org-ul">
<li>El nombre del fichero es <code>forms-libros.el</code>. Luego hablaré sobre él
más despacio y pondré el código completo.</li>
<li>Aparece el mensaje <code>Forms 2223/2613</code> que nos dice que está en modo
<code>Forms" y los números indican el =registro actual/total registros</code>.</li>
<li>Cuando está en modo vista o <i>read only</i> aparece la marca <code>View</code> al
lado del contador de registros.</li>
</ul>
<div id="outline-container-orgb624a5e" class="outline-2">
<h2 id="orgb624a5e">Estructura de los datos</h2>
<div class="outline-text-2" id="text-orgb624a5e">
<p>
Los datos para <code>forms-mode</code> tienen una estructura muy básica: son
ficheros de texto, conde cada registro se encuentra en una línea y
cada campo está separado por un carácter especial. Si no se especifica
cual, <code>forms-mode</code> entiende que es <code>\t</code> (un tabulador). Los campos
pueden mostrarse también en varias líneas. Esas líneas se separan
dentro del campo utilizando un carácter <code>"\^k"</code> (<code>C-k</code>), por defecto,
aunque se puede definir el que queramos con la variable
<code>forms-multi-line</code>. Si se establece ese valor a <code>nil</code> deshabilita los
campos en varias líneas.
</p>

<p>
Los campos son posicionales de izquierda a derecha y cuando definamos
la estructura del formulario en pantalla, los podemos insertar
mediante su número de orden en el fichero de datos. Sin embargo,
veremos que hay una forma más cómoda de hacerlo y dotar de <i>nombre</i> a
cada campo.
</p>

<p>
En el caso del ejemplo, se hizo un volcado de datos desde una hoja de
cálculo a <code>CSV</code>, pero utilizando como separador de campos el carácter
<code>|</code>, porque si se hubiera utilizado la prosaica <code>,</code> hubiera cortado
los títulos que contienen comas, aunque estén delimitados por
comillas, <code>forms</code> ignora esas estructuras y se fija sólo en el
separador establecido.
</p>
</div>
</div>
<div id="outline-container-org89ead4c" class="outline-2">
<h2 id="org89ead4c">Fichero de control</h2>
<div class="outline-text-2" id="text-org89ead4c">
<p>
El fichero de control que gestiona el formulario es el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">forms-mode por Frateca Biblioteko
</span>
(<span style="color: #ff79c6; font-weight: bold;">setq</span> forms-read-only t)

(<span style="color: #ff79c6; font-weight: bold;">setq</span> forms-field-sep <span style="color: #f1fa8c;">"|"</span>)

(<span style="color: #ff79c6; font-weight: bold;">setq</span> forms-file <span style="color: #f1fa8c;">"./FratecoBiblioteko.csv"</span>)

(<span style="color: #ff79c6; font-weight: bold;">setq</span> forms-number-of-fields
      (forms-enumerate
       '(kodo         <span style="color: #6272a4;">; </span><span style="color: #6272a4;">1
</span>         numero       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">2
</span>         a&#365;toro       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">3
</span>         titolo       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">4
</span>         )))

(<span style="color: #ff79c6; font-weight: bold;">setq</span> forms-format-list
      (list
       <span style="color: #f1fa8c;">"====== Biblioteko de Frateco el Zaragozo =======\n\n"</span>
       <span style="color: #f1fa8c;">"Kodo: "</span> kodo <span style="color: #f1fa8c;">" -- "</span> <span style="color: #f1fa8c;">"Numero: "</span> numero <span style="color: #f1fa8c;">"\n\n"</span>
       <span style="color: #f1fa8c;">"A&#365;toro: "</span> a&#365;toro <span style="color: #f1fa8c;">"\n"</span>
       <span style="color: #f1fa8c;">"Titolo: "</span> titolo <span style="color: #f1fa8c;">"\n\n"</span>
       <span style="color: #f1fa8c;">"=============== Klarigo de kodoj ===============\n\n"</span>
       <span style="color: #f1fa8c;">"F = Biblioteko Frateco -- O = Biblioteko Olavide\n\n"</span>
       <span style="color: #f1fa8c;">"ESE = Eseoj, filozofio, religio, politiko\n"</span>
       <span style="color: #f1fa8c;">"LER = Lernolibroj, legolibroj\n"</span>
       <span style="color: #f1fa8c;">"LIN = Lingvo, Interlingvistiko\n"</span>
       <span style="color: #f1fa8c;">"MOV = Movado, historio, esperantologio\n"</span>
       <span style="color: #f1fa8c;">"POE = Poezio\n"</span>
       <span style="color: #f1fa8c;">"ROM = Romanoj, noveloj, rakontoj\n"</span>
       <span style="color: #f1fa8c;">"SCI = Scienco\n"</span>
       <span style="color: #f1fa8c;">"TEA = Teatro\n"</span>
       <span style="color: #f1fa8c;">"VOJ = Vojagxoj,Geografio\n"</span>
       <span style="color: #f1fa8c;">"VOR = Vortaroj, Terminaroj\n"</span>
       <span style="color: #f1fa8c;">"KD = Kompakt-disko\n"</span>
       <span style="color: #f1fa8c;">"DVD = VideoDisko\n"</span>
       <span style="color: #f1fa8c;">"================================================\n\n"</span>
       ))
</pre>
</div>

<p>
Aunque es un código corto y suficientemente autoexplicativo lo cuento
más despacio. Con la variable <code>forms-read-only</code> establecemos que
inicie los datos en modo de sólo lectura ─luego veremos que podemos
cambiar ese estado con una simple combinación de teclas─. La variable
<code>forms-field-sep</code> se establece al carácter que hemos utilizado para
exportar el fichero <code>CSV</code>: <code>|</code>. La variable <code>forms-file</code> establece el
nombre del fichero donde se guardan los datos, en este caso
<code>./FratecoBiblioteko.csv</code>. En caso de no existir el fichero, <code>forms</code>
lo crea. La variable <code>forms-number-of-fields</code> estable el número de
columnas o campos que tiene cada línea. En este caso 4, pero se ha
utilizado la función <code>forms-enumerate</code> para establecer ese número de
columnas. Dicha función lo que hace es proveer de nombres, emparejando
cada nombre con su número de posición y devolviendo el número más alto
asignado. De esa manera, cuando en la definición de
<code>forms-format-list</code>, que establece la estructura del formulario,
podemos utilizar los nombres anteriores en lugar de su número
correspondiente ─como se puede apreciar en el código─, porque a veces
el orden de las columnas no es el que interesa mostrar.  El truco de
los nombres además nos ahorra muchos quebraderos de cabeza en caso de
que los campos no sigan el mismo orden que en el fichero de datos. En
la variable <code>form-format-list</code> se especifica el formato de los datos
en el fichero de datos.
</p>

<p>
En la lista de formato se pueden proporcionar una serie de valores
para especificar lo que se mostrará:
</p>

<ul class="org-ul">
<li><b>Cadena</b>: Una cadena se mostrará tal cual está escrita.</li>
<li><b>Número</b>: Indica el número de campo del registro. En nuestro
ejemplo, los hemos sustituido con <code>forms-enumerate</code> por <i>atoms</i> con
el nombre.</li>
<li><b>Lista</b>: O mejor dicho, una <i>forma</i>. Especifica una llamada a una
función. La función se la llama cada vez que se muestra un registro
y su resultado ─que debe ser una cadena─ se muestra en pantalla.</li>
</ul>

<p>
Si no se especifica una lista de formato, <code>forms</code> genera una simple
lista, cada campo en una línea con la etiqueta del número
correspondiente delante de cada campo.
</p>
</div>
</div>
<div id="outline-container-org42a712a" class="outline-2">
<h2 id="org42a712a">Iniciar <code>forms-mode</code></h2>
<div class="outline-text-2" id="text-org42a712a">
<p>
La manera directa de iniciar el modo es llamar a <code>M-x forms-find-file</code>
con el nombre de fichero de control, en el ejemplo <code>form-libros.el</code>.
Hacerlo de ese modo en lugar del habitual <code>find-file</code> con <code>C-x C-f</code>
inicia <code>forms-mode</code> de manera automática al cargarlo. Si lo abrimos
con <code>C-x C-f</code> nos lo abrirá como cualquier fichero de código <code>elisp</code>.
Si una vez abierto queremos iniciar el modo tendremos que lanzar <code>M-x
forms-mode</code>. Es decir, iniciamos el modo en dos pasos, en lugar de en
uno.
</p>

<p>
Podríamos saltarnos ese segundo paso colocando <code>-*- forms -*-</code> en la
primera línea del fichero, sin embargo, si quisiéramos modificar el
contenido del código del fichero, tendríamos problemas, porque
automáticamente entrará en modo <code>forms</code> y no en modo <code>elisp</code>. Como es
un fichero <code>elisp</code>, se le puede meter toda la magia <code>elisp</code> que
necesitemos y dotar a los datos de algo más de vida.
</p>
</div>
</div>
<div id="outline-container-org30e9b4d" class="outline-2">
<h2 id="org30e9b4d">Movernos y trabajar con los datos</h2>
<div class="outline-text-2" id="text-org30e9b4d">
<p>
Una vez situados en nuestro formulario podemos movernos por los
diferentes campos y registros:
</p>

<ul class="org-ul">
<li>Movimientos entre los campos:
<dl class="org-dl">
<dt><code>&lt;TAB&gt;</code></dt><dd>Mover el cursor al siguiente campo dentro del
formulario. También se puede utilizar <code>C-c &lt;TAB&gt;</code>.</dd>
<dt><code>S-&lt;TAB&gt;</code></dt><dd>Hace el movimiento contrario al anterior, con
mayúsculas+tabulador se va al campo anterior en el formulario.</dd>
</dl></li>

<li>Movimientos entre registros:
<dl class="org-dl">
<dt><code>C-c C-n</code></dt><dd>Muestra el siguiente registro <code>forms-next-record</code>.
También podemos utilizar <code>Av.Pág</code>. Si estamos en modo <code>View</code>
también podemos utilizar <code>n</code>, sin más.</dd>
<dt><code>C-c C-p</code></dt><dd>Muestra el registro anterior <code>forms-prev-record</code>.
También se puede usar <code>Re Pág</code>. Si estamos en modo <code>View</code>
también podemos utilizar <code>p</code>, sin más.</dd>
<dt><code>C-c C-l</code></dt><dd>Nos preguntará a qué registro debe saltar (en formato
numérico) con el comando <code>forms-jump-record</code>. Si estamos en modo
<code>View</code> también podemos utilizar <code>l</code>, sin más.</dd>
<dt><code>C-c &lt;</code></dt><dd>Va al primer registro con <code>forms-first-record</code>. Si
estamos en modo <code>View</code> también podemos utilizar <code>&lt;</code>, sin más.</dd>
<dt><code>C-c &gt;</code></dt><dd>Salta al último registro de la base de datos con el
comando <code>forms-last-record</code>. Si estamos en modo <code>View</code> también
podemos utilizar <code>&gt;</code>, sin más.</dd>
<dt><code>C-c C-s</code></dt><dd>Busca una expresión hacia adelante en la base de
datos con el comando <code>forms-search-forward</code>. Funciona como el
comando de búsqueda habitual. Si estamos en modo <code>View</code> también
podemos utilizar <code>s</code>, sin más.</dd>
<dt><code>C-c C-r</code></dt><dd>Busca una expresión hacia atrás en la base de datos
con el comando <code>forms-search-backward</code>. Funciona como el comando
de búsqueda hacia atrás. Si estamos en modo <code>View</code> también
podemos utilizar <code>r</code>, sin más.</dd>
</dl></li>

<li>Modificación de datos:
<dl class="org-dl">
<dt><code>C-c C-q</code></dt><dd>Intercambia el modo de sólo lectura con el comando
<code>forms-toggle-read-only</code>, es decir entre los modos de <code>View</code> y
edición. Esto nos permite movernos con libertad sin miedo a
cambiar nada accidentalmente, (por ejemplo, con la instintiva
pulsación de <code>n</code> en lugar de <code>C-c C-n</code>) y activar la edición
sólo cuando sea necesario. Cuando el formulario está en modo
<code>View</code>, también se puede utilizar <code>q</code>.</dd>
<dt><code>C-c C-o</code></dt><dd>Crea un nuevo registro y lo inserta justo antes del
registro actual con el comando <code>forms-insert-record</code>. Comienza
con los campos en blanco.</dd>
<dt><code>C-c C-k</code></dt><dd>Borra el registro actual con el comando
<code>forms-delete-record</code>. Pregunta para confirmar si realmente se
quiere borrar dicho registro. Si se utiliza con un parámetro
numérico, no preguntará.</dd>
<dt><code>C-x C-s</code></dt><dd>Guarda los cambios en los datos que se hayan
realizado.</dd>
</dl></li>

<li>Otras funciones
<dl class="org-dl">
<dt><code>M-x forms-print</code></dt><dd>Genera una impresión de la base de datos en
un <i>buffer</i> de nombre <code>*forms-print*</code> y lo intenta enviar a la
impresora asociada con el comando del sistema <code>/usr/bin/lpr</code>.
Cuidado con esto si tienes una impresora conectada y un fichero
de datos con 3.000 registros, porque imprimirá uno en cada
página.</dd>
<dt><code>C-c C-x</code></dt><dd>Sale del modo con el comando <code>forms-exit</code>. Si
estamos en modo <code>View</code> también podemos utilizar <code>x</code>, sin más.</dd>
</dl></li>
</ul>
</div>
</div>
<div id="outline-container-orga10f47b" class="outline-2">
<h2 id="orga10f47b">Conclusiones</h2>
<div class="outline-text-2" id="text-orga10f47b">
<p>
Este modo es bastante sencillo de configurar y de utilizar. ¿Es útil?
... pues eso depende. En mi caso me ha venido muy bien cuando he
tenido que trastear con una más que incómoda tabla hecha en una hoja
de cálculo. El poder distribuir los campos en toda la pantalla, con
etiquetas claras y la posibilidad de editar los datos, buscarlos sin
perder la noción de lo que rodea a «esa cadena que buscas» teniendo
toda la información de un vistazo. En fin, algo más amable que una
hoja de cálculo, en la que muchas veces el contenido de las celdas no
se veía de forma completa para evitar que el margen derecho de la
tabla se perdiera en el infinito.
</p>

<p>
Además, aunque no lo he mencionado antes, se puede especificar un
fichero <code>gpg</code> como fuente de los datos. Y esto es todo. Espero que os
sea útil.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2020/06/23/formularios-y-datos-con-forms-mode-de-emacs.html</link>
  <pubDate>Tue, 23 Jun 2020 19:33:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Estos aburridos días de confinamiento]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-06-12</div>
<p>
Hoy no tenía pensado escribir nada en el <i>blog</i>. Llevo tiempo sin
escribir nada coherente, y mira que he tenido tiempo para hacerlo
durante todo el confinamiento; sin embargo, por alguna razón no me he
puesto. Bueno sí cerré algún borrador para el <i>blog</i>, pero a la larga,
no eran más que labores de limpia y pule de temas que llevaban ya en
la recámara algún tiempo.
</p>

<p>
Ahora mismo me apetecía escribir algo, sin borrador, al estilo que
llamo <i>post suicida</i>: parido y escrito en el momento, sin reposar, sin
pulir y sin enmendar. Viendo que, por fin, el confinamiento parece que
se acaba, me encuentro haciendo un repaso de las cosas que he hecho
estos días en casa, encerrado con Internet como ventana al exterior.
Al principio del encierro participé en videoconferencias muy por
encima de mis posibilidades. Parecía que íbamos a morir de aislamiento
y teníamos que ver caras humanas y oír otras voces, aparte de las
familiares, <i>por sobre</i> todas las cosas. Luego me he ido relajando y
he procurado no conectarme a nada y aprovechar ese tiempo en mí, en mi
familia y en mis cosas. Durante aquellos primeros momentos de
conexiones y estrés relacional fue un «sin vivir» que no debía durar.
</p>

<p>
Así, he conseguido terminar algún proyecto, como un curso de
<i>Seguridad Informática Básica para Psicólogos</i> que el jueves pasado,
el 4 de junio, se abrió de forma gratuita para los colegiados del
COPPA (Colegio Profesional de Psicología de Aragón). El curso son unas
12 horas de formación y cuenta con su correspondiente certificado.
Aunque es un curso a distancia que cuenta con autoevaluación y los
alumnos se lo pueden distribuir como quieran, estoy en la plataforma
(<a href="https://moodle.org/?lang=es">Moodle</a>) como profesor y le estoy haciendo un seguimiento de cómo
avanzan los alumnos (a fecha de hoy 41 personas inscritas, de las
cuales 3 ya lo han terminado). También han reportado algún error en el
foro del curso y lo he podido subsanar. Me sorprende que no hayan
reportado más, dado que era la primera vez que hacía un curso de este
estilo, partiendo de cero. En principio, el curso lo hacía por
iniciativa propia y gratis, sólo por ver que los psicólogos en general
se preocuparan un poco de las herramientas que usan, de la
confidencialidad de sus datos y comunicaciones. Sin embargo, una vez
finalizado, el COPPA ha decido pagarme el trabajo, lo cual siempre es
de agradecer.
</p>

<p>
Otros proyectos en cambio se han quedado por el camino y a pesar de
cierto empeño en empujarlos hacia adelante, al final acaban encallando
contra escollos que nada tienen que ver con el proyecto en cuestión.
Esto ha pasado, por ejemplo, con el proyecto de aprendizaje que me
había planteado. Ya hablé aquí en el <i>blog</i> sobre aprender <code>erlang</code> y
hacer un proyecto para desarrollar los conocimientos adquiridos. No
quise hablar sobre ese proyecto porque tenía muchas ganas de
acabarlo, ─ya sabéis que cada vez que hablo de un proyecto y cuento de
qué va, acaba en <i>vaporware</i> de manera automática─. Esta vez, sin
necesidad de contar de qué iba, el proyecto está dando sus últimos
coletazos, ─o quizá mejor decir <i>bocanada</i>, por aquello del vapor─.
</p>

<p>
Es una lástima, porque me gustaba el proyecto. El caso es que el otro
desarrollador y yo no nos hemos entendido. Durante la mayor parte del
desarrollo conjunto he tenido la sensación anímica de ser gilipollas,
durante todo el rato. Llegaba a hacer los <i>commits</i> con miedo a la
bronca y a la frustración. Creo que en todo ese tiempo no he hecho
nada al gusto del otro desarrollador, <i>nunca</i>. Todos los días eran
discusiones sobre ─para mí─ cuestiones intrascendentes y detalles que
a mí se me escapaban y que el otro se empeñaba en que los viera por mí
mismo <i>porque eran importantísimos y fundamentales</i>. Al final, para lo
único que ha servido es para desgastar una amistad de años a través de
IRC. Porque durante todo ese periodo lo que he sentido es menosprecio
a mi trabajo y a mi inteligencia. Y cuando se lo dije, con la
esperanza de que se relajara con el tema, tampoco cambió de actitud,
añadiendo algún comentario más referente a la dureza de mi
personalidad. Después de todos estos días aún no sé dónde he fallado
ni por qué me he sentido atacado tan duramente. Seguramente será un
error de percepción mío. Intenté obviarlo, con el ánimo de continuar
el proyecto, pero al final me ha superado y he decidido abandonar.
Espero que pronto se me pase todo el rencor que el tema me ha hecho
acumular y que me estaba haciendo más daño del que pensaba. El
proyecto que comenzó para divertirme acabó convirtiéndose en una
tortura psicológica y en mal rollo.
</p>

<p>
El proyecto me sigue gustando: es un <a href="https://es.wikipedia.org/wiki/MUD_(videojuegos)">MUD</a>, o debería decir <i>iba a ser
un MUD</i>. Hecho desde cero en <code>erlang</code>: habíamos comenzado levantando
un <i>servidor</i>, porque la parte cliente se lleva a través de <code>telnet</code>,
aunque usáramos el más moderno <code>netcat</code>, se mantuvo la compatibilidad
con <code>telnet</code>. A ese servidor, le fuimos añadiendo características, de
modo que al recibir instrucciones del tipo «mirar objeto», nos
mostrara una descripción del mismo, etc. Si has jugado alguna vez en
algún MUD o alguna aventura conversacional sabes qué tipo de comandos
soportan.
</p>

<p>
La temática interna no estaba aún desarrollada, tenía en mente dos
posibilidades: una era algo <i>cyberpunk</i>, situándose en una estación
espacial en órbita alrededor de un agujero negro; la otra era el más
clásico formato de fantasía de capa y espada, que es lo que más suele
triunfar en el mundillo del MUD ─demasiado enfocado a temáticas de
rol─. Lo que más me interesaba del proyecto era el facilitar a los
usuarios las herramientas necesarias para ampliar y crear «mundos
paralelos» que pudieran completar el propio MUD, bien creando
«aventuras conversacionales» para que los demás pudieran disfrutarlas,
bien creando nuevos mundos o zonas dentro de los mundos, donde
interactuar con otros jugadores.
</p>

<p>
No iba a ser el típico MUD <i>rolero</i>, con puntos de vida y magia que al
final se convierten en un mata-mata de texto. La intención era
proporcionar un espacio para la creación de mundos paralelos. O, si no
hubiera usuarios finales, ─algo que sería lo más normal, porque ya
casi nadie se acuerda de este tipo de juegos─, al menos me daría a mí
la oportunidad de crear un mundo virtual completo, en el que
cualquiera se pudiera mover y disfrutar sin la presión de «subir de
nivel» y «matar al enemigo», que pudiera interactuar con otros
personajes, con otros jugadores y con los objetos del mundo. O por
decirlo de otro modo, crear una especie de historia no lineal en la
que los jugadores podrían decidir qué hacer o qué camino tomar en el
curso de los acontecimientos.
</p>

<p>
El proyecto acabará, seguramente como tantos otros, en <i>waporware</i>.
Pero aún no está abandonado, sigo con él aunque supongo que llegará un
momento en que me encallaré y no sabré salir de algún atolladero donde
me habré metido yo solito. Cuando decidí acabar con la colaboración,
cloné el repositorio en un <code>bare</code> más particular y cambié la URL del
<code>origin</code>, en el <code>config</code>. Voy haciendo cosas a mi manera, aunque sigo
un poco la estructura que veníamos trayendo durante la colaboración.
Pero ya no me preocupa el ir poco a poco, sino el hacer lo que creo
que podría bloquearme. Por ejemplo, antes de la separación entendía
algunos comandos sencillos, de «verbo» o «verbo+objeto». Pensé que un
escollo donde encallarían mis habilidades de programador sería
desarrollando comandos más complejos con estructura «verbo+objeto
directo+objeto indirecto», del tipo <i>pon la manzana en la mochila</i>.
Sin embargo, contra todo pronóstico, lo he conseguido sin mucha
dificultad, así que me he planteado el ir poniéndome ese tipo de
retos. De todas formas, acabará en <i>vaporware</i>, al menos voy a
probarme con ello... y si no encallo gravemente, lo mismo hasta sin
darme cuenta lo completo.
</p>

<p>
En otro orden de cosas, llevo también a rastras otro, en realidad no
puedo llamarlo porque no lo es, <i>proyecto</i>. Hace tiempo, para
practicar esperanto lo que hago es leer mucho y traducir. Aprovechando
la traducción, suelo hacerlo desde el inglés al esperanto y así, algo
mantengo de los dos idiomas. Para ello, normalmente elijo textos de
longitud media o capítulos sueltos de algún libro. Quizá por vagancia,
por ahorrarme el tiempo de búsqueda de textos, comencé a traducir
<i>Dune</i>, de Frank Herbert, del inglés y el otro día me di cuenta que ya
llevo traducido el 60% de la primera novela y me ha entrado el
gusanillo de terminar la traducción completa. Aunque sin ánimo de
hacer nada más con ella que montarme un <code>epub</code> y disfrutar de la
lectura de esa obra en esperanto.
</p>

<p>
No sé si disfrutaré de tal lectura, porque seguramente terminaré
fijándome más en ese acusativo que se me olvidó o en aquel error
gramatical. Pero bueno, ya veremos cómo acaba la traducción y su
posterior lectura.
</p>
<div id="outline-container-org66d59a1" class="outline-2">
<h2 id="org66d59a1">Conclusión</h2>
<div class="outline-text-2" id="text-org66d59a1">
<p>
En luces y sombras he estado estos días de confinamiento. Completando
algunos proyectos, retomando otros, pero no dejando en barbecho, de
momento ninguno.
</p>

<p>
Necesitaba, sin embargo, escribir sobre ello para ahuyentar algunos
demonios de mi cabeza y algún cabreo que otro.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/proyectos/index.html">proyectos</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[proyectos]]></category>
  <link>https://notxor.nueva-actitud.org/2020/06/12/estos-aburridos-dias-de-confinamiento.html</link>
  <pubDate>Fri, 12 Jun 2020 09:59:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Sobre Info y la ayuda de Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-06-07</div>
<p>
Hace unos días me llevé un susto con la ayuda de <i>Emacs</i>. Al abrirla
me encontré que apenas había contenido, todo había desaparecido,
incluidos el manual del editor, el manual de <code>elisp</code>, el de <code>org</code>.  Un
susto bastante grande, ya que utilizo la ayuda de forma habitual.  Ya
he dicho por aquí que suelo olvidar de una vez para otra cómo utilizar
los comandos y las herramientas si no los uso todos los días. Tengo
que refrescar mi memoria y es bastante habitual que consulte la ayuda,
que entre otras cosas, para eso está.
</p>

<p>
El caso es que había hecho una actualización del sistema operativo y
algo debió ir mal y de repente, sólo me aparecían los manuales de tres
o cuatro herramientas y ninguno de los de <i>Emacs</i>.
</p>

<p>
Si pulsaba <code>C-h r</code> me abría el manual, luego estar estaba. Sin
embargo, en la lista de <i>Info</i> que aparece al pulsar <code>C-h i</code> no
aparecía. Como sabéis en el menú <code>Help</code> hay una entrada para <code>Others
manuals</code> y al llamarlos desde allí, los manuales estaban, los abría y
podía consultarlos. Pero ya estoy muy acostumbrado a pulsar <code>C-h i</code> y
buscar lo que necesito, no a coger el ratón y tirar de menú.
</p>

<p>
Para mayor seguridad utilicé el comando <code>info</code> desde una terminal y
ocurría lo mismo. La página principal no mostraba apenas entradas. Si
llamaba a <code>info</code>, por ejemplo, como <code>info emacs</code>, abría el manual de
<i>Emacs</i> pero seguía sin listarlo en el directorio de ayuda principal.
</p>

<p>
A estas alturas supongo que las preguntas son: ¿he conseguido hacer
que aparecieran? y, si es así, ¿cómo? La respuesta a la primera
pregunta es <i>sí</i>. A la segunda pregunta, es un poco más larga y por
eso lo cuento en esta entrada del <i>blog</i>... pero la respuesta corta
podría ser: chapuceando un poco, como buen chapucero que soy.
</p>
<div id="outline-container-orgdceb40f" class="outline-2">
<h2 id="orgdceb40f">Archivos <code>info</code></h2>
<div class="outline-text-2" id="text-orgdceb40f">
<p>
La ayuda de <i>Emacs</i> como sabéis está basada en otra herramienta de
GNU: <code>info</code>. Esta herramienta consiste en una serie de archivos que se
escriben mediante un lenguaje llamado <code>texinfo</code> y que se generan y
guardan con la extensión <code>.info</code> o <code>.info.gz</code>. Pueden guardarse en
varios directorios y por ejemplo, en mi <code>.bashrc</code> tengo añadida la
línea
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #8be9fd; font-style: italic;">export</span> <span style="color: #f8f8f2; font-weight: bold;">INFOPATH</span>=/usr/share/info:/local/share/info:~/opt/share/info
</pre>
</div>

<p>
Se puede apreciar dónde se van a buscar los archivos <code>info</code>,
especialmente, cuando no procede de un paquete de la distribución,
sino que ha sido compilado desde código fuente a <code>local</code> o a <code>~/opt</code>,
según sea el caso.
</p>

<p>
Sabiendo dónde buscar, encontrar los ficheros fue fácil, estaban donde
cabía esperar y desde ahí, llamar a <code>info fichero</code> para cargarlos era
sencillo. Así pues, los archivos de información estaban en su sitio,
sin embargo, ni el sistema de ayuda de <i>Emacs</i> ni el directorio
general del comando <code>info</code> los encontraba.
</p>
</div>
<div id="outline-container-org2f0cc19" class="outline-3">
<h3 id="org2f0cc19">El archivo <code>dir</code></h3>
<div class="outline-text-3" id="text-org2f0cc19">
<p>
Dentro del directorio <code>/usr/share/info</code> me encontré un fichero de
nombre <code>dir</code> sin la extensión <code>.info</code>. Es un fichero de texto,
afortunadamente, y al abrirlo resultó ser el <i>directorio</i> de consulta
de los contenidos. Digo <i>afortunadamente</i>, porque un fichero de texto
se puede editar y el contenido, efectivamente, coincidía con el parco
listado de entradas de la ayuda. Así supuse que ese fichero era el
responsable de todo el problema.
</p>

<p>
Probé a añadir a mano una entrada de ayuda y funcionó, con una línea
tal que:
</p>

<pre class="example" id="orgfab69fe">
* Manual de Emacs: (emacs).     Manual de referencia de emacs.
</pre>

<p>
Me costó sólo un par de pruebas y el manual de referencia apareció en
el listado de entradas de ayuda de <code>C-h i</code>. La estructura, como se
puede apreciar es muy simple: un <code>*</code> en el primer carácter de la línea
y a continuación lo que será el nombre del enlace <code>Manual de Emacs</code> en
este caso. A continuación, y entre paréntesis, el nombre del fichero
<code>.info</code> sin la extensión, aquí <code>emacs</code>. El punto <code>.</code> a continuación
del paréntesis es importante, porque marca el final del enlace (esto
fue una de las pruebas). Si no se pone, tomará como enlace el
comentario, que lleva punto al final. Por último, en la columna 32
(para que esté alineada con el resto) una breve descripción del
contenido, o comentario.
</p>
</div>
</div>
</div>
<div id="outline-container-orgc7afeab" class="outline-2">
<h2 id="orgc7afeab">Conclusiones</h2>
<div class="outline-text-2" id="text-orgc7afeab">
<p>
Es un poco chapuza, seguramente habrá algún comando o <code>script</code> que
rehaga el directorio de ficheros <code>info</code> de alguna manera más o menos
automática. Sin embargo, después de haber estado investigando algo de
tiempo, no encontré la manera. Por eso probé a hacerlo a mano y
funcionó.
</p>

<p>
Seguramente me habré dejado algún fichero sin meter, supongo que me
daré cuenta cuando lo necesite. De momento he metido los más
habituales o los que consulto con más frecuencia.
</p>

<p>
Quizá me ponga en otro momento a hacer algún <code>script</code> que lo haga
automáticamente, por si vuelve a suceder algo parecido
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/info/index.html">info</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[info]]></category>
  <link>https://notxor.nueva-actitud.org/2020/06/07/sobre-info-y-la-ayuda-de-emacs.html</link>
  <pubDate>Sun, 07 Jun 2020 10:01:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Buscando texto más allá de grep]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-06-04</div>
<p>
Cuando necesito encontrar algo en mi ordenador, mis primeras opciones
son siempre <code>grep</code> y <code>find</code>... quizá soy de la vieja escuela porque
para sustituir a esas herramientas se han propuesto infinidad de
herramientas posteriores que han ido apareciendo, pero no me han ido
calando. Durante un tiempo utilicé <code>mlocate</code> para localizar ficheros,
pero posteriormente regresé a <code>find</code> de nuevo y continúo utilizándolo
de manera habitual.
</p>

<p>
Con <code>grep</code> no había probado alternativas hasta ahora. Supongo que como
todos, Había oído hablar de <code>ack</code>, que promete una búsqueda más
efectiva, pero nunca lo he probado, así que no puedo hablar, ─ni bien,
ni mal─, de esa herramienta. Sin embargo, el otro día tropecé con otro
de esos proyectos que prometen búsquedas rápidas y fáciles dentro del
contenido de los ficheros, de hecho se presenta no como un recambio de
<code>grep</code>, sino como un recambio de <code>ack</code>. <a href="https://github.com/ggreer/the_silver_searcher">El proyecto se llama <i>The
silver searcher</i> y el nombre me resultó curioso</a>. Además, encontré que
había paquete para la <i>distro</i> que utilizo: <i>OpenSuse Tumbleweed</i> y me
decidí a probarlo.
</p>

<p>
El comando utilizado es <code>ag</code> y tiene una forma sencilla:
</p>

<div class="org-src-container">
<pre class="src src-bash">ag [opciones] patr&#243;n [path/de/b&#250;squeda]
</pre>
</div>

<p>
Lo que hará será buscar el «patrón» de forma recursiva en el <code>path</code>
proporcionado o en el directorio actual si no se le proporciona
ninguno. Lo de recursivo es importante, porque lo hace por defecto
en 25 directorios anidados, pero lo podemos ajustar al valor que
queramos con la opción <code>--depth NUM</code>, donde <code>-1</code> significa hacerlo de
manera ilimitada.
</p>

<p>
Si lo que estamos buscando son nombres de fichero, podemos utilizar la
opción <code>-g</code>:
</p>

<div class="org-src-container">
<pre class="src src-bash">ag -g patr&#243;n
</pre>
</div>

<p>
Podemos ignorar aquellos ficheros o directorios que cumplan con un
patrón con la opción <code>--ignore PATRÓN</code>. También podemos decirle que
busque en un tipo determinado de archivos; por ejemplo, para buscar
sólo dentro de archivos <code>html</code> utilizaremos la opción <code>--html</code>. Para
obtener un listado completo de los distintos tipos de fichero que
reconoce, emplearemos el comando:
</p>

<div class="org-src-container">
<pre class="src src-bash">ag --list-file-types
</pre>
</div>

<p>
En fin, opciones tiene muchas, así que es aconsejable mirar su página
de manual para tener una idea de todas.
</p>
<div id="outline-container-orgf76d5f3" class="outline-2">
<h2 id="orgf76d5f3">¿Es tan rápido como lo pintan?</h2>
<div class="outline-text-2" id="text-orgf76d5f3">
<p>
Pues la sensación subjetiva, según qué búsquedas es bastante buena, no
me atrevo a decir inmediata, pero si está bien delimitada es
prácticamente así. Así que me propuse ponerlo a prueba con una
búsqueda poco acotada: tres caracteres, en varios gigas de
información. Para tener una referencia, comprobé los tiempos con
<code>grep</code> y con <code>ag</code> para poder comparar. Los comandos fueron:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #ff79c6; font-weight: bold;">time</span> ag --search-binary irc ~
<span style="color: #ff79c6; font-weight: bold;">time</span> grep -n -r -e <span style="color: #f1fa8c;">"irc"</span> ~
</pre>
</div>

<p>
De primeras, los tiempos fueron muy llamativos, demasiado, entre las
ejecuciones de <code>ag</code> y de <code>grep</code>. Con posterioridad, esas diferencias,
aunque las hay se redujeron bastante, principalmente, cuando me di
cuenta, por ejemplo, que <code>ag</code> no busca en los ficheros binarios si no
se le especifica y que <code>grep</code> no muestra el número de línea si no se
le pide. Así pues, en los comandos intenté igualar, tanto la
información suministrada, como la profundidad de la búsqueda de ambos
dos comandos.
</p>

<p>
Para evitar la influencia de cachés, cada comando lo ejecuté tres
veces seguidas, quedándome con el valor más pequeño de los tres. El
resultado de ejecución en mi máquina y con mis «gigas» de datos, se
puede apreciar en la siguiente tabla:
</p>

<table>
<caption class="t-above"><span class="table-number">Table 1:</span> Tabla de tiempos de búsqueda según muestra el comando <code>time</code>.</caption>

<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Tiempo</th>
<th scope="col" class="org-left">ag</th>
<th scope="col" class="org-left">grep</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">real</td>
<td class="org-left">1m44,387s</td>
<td class="org-left">4m0,660s</td>
</tr>

<tr>
<td class="org-left">user</td>
<td class="org-left">1m55,577s</td>
<td class="org-left">1m47,108s</td>
</tr>

<tr>
<td class="org-left">sys</td>
<td class="org-left">0m22,085s</td>
<td class="org-left">0m33,927s</td>
</tr>
</tbody>
</table>

<p>
Como es obvio, más rápido sí es. La explicación que me doy, para
explicar las diferencias tan abultadas, es que <code>ag</code> es multihilo y
utiliza todos los <i>cores</i> del procesador mientras que <code>grep</code> es
monohilo y por tanto sólo utiliza uno de ellos.
</p>
</div>
</div>
<div id="outline-container-org30ae8be" class="outline-2">
<h2 id="org30ae8be">Conclusiones</h2>
<div class="outline-text-2" id="text-org30ae8be">
<p>
De momento, a pesar de su mayor velocidad, no creo que sustituya todas
mis búsquedas por <code>ag</code>. Principalmente, porque la mayoría de las
veces, la búsqueda de contenidos la realizo desde <i>Emacs</i> para acceder
directamente a la información desde el editor y de momento, que yo
sepa, <code>ag</code> no tiene soporte en este editor, mientras que se entiende
perfectamente con <code>grep</code>.
</p>

<p>
De todas formas, dejo instalada la herramienta y desde línea de
comandos algunas veces la utilizaré, bien para buscar ficheros
sustituyendo a <code>find</code> o bien para buscar contenidos sustituyendo a
<code>grep</code>.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2020/06/04/buscando-texto-mas-alla-de-grep.html</link>
  <pubDate>Thu, 04 Jun 2020 13:15:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Reaprendiendo a programar]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-05-27</div>
<p>
Estos días ando un poco perdido y apenas tengo tiempo para escribir en
el <i>blog</i>. Como me consta que hay quien lo sigue y lee casi cualquier
cosa que escribo ─no entiendo muy bien las razones, pero alguna
tendrán─, he decidido contar un poco qué ando haciendo estos días para
estar tan ocupado... estos días de aislamiento y cuarentena, cuando se
supone que tenemos tiempo hasta para hacer pan o repostería.
</p>

<p>
Sin embargo, he estado liado, no creo que haga falta contaros toda mi
vida. El caso es que he estado muy liado con un curso de seguridad
informática para psicólogos, que ya está completo y colgado en la
plataforma virtual del Colegio de Psicólogos a la espera de que le den
el visto bueno y decidan abrir las inscripciones para el público. Es
el <a href="https://moodle.org/?lang=es">primer curso que realizo para la plataforma <code>moodle</code></a> y estoy
expectante, ─y también algo nervioso─, por ver si funciona bien o no.
</p>

<p>
El resto del tiempo lo he dedicado a largas siestas y a rascarme el
ombligo... bueno, no exactamente: alguna siesta ha caído,
evidentemente, pero también estoy en medio de otras cosas y proyectos
personales. <a href="https://notxor.nueva-actitud.org/blog/2020/04/05/aprendiendo-erlang-durante-la-cuarentena/">Ya hablé por aquí de que quería aprender <i>erlang</i></a> durante
esta cuarentena y en ello me hallo. Me leí un par de libros haciendo
ejercicios que proponían e intentando comprender cómo funciona el
lenguaje en sí. Pero la mejor forma de aprender es utilizándolo.
Durante el aprendizaje de <i>erlang</i> <a href="http://www.caad.es/">me acompañó un colega del CAAD</a> y ya
puestos nos metimos en un proyecto de aprendizaje. Me permitiréis que
no hable del mismo, porque cada vez que hablo de un proyecto acaba en
<i>vaporware</i>. Así pues, me guardo los detalles. Sólo diré, como se
puede deducir, que siendo <i>erlang</i> el lenguaje, tiene que ver con un
sistema concurrente cliente-servidor, y que, siendo ambos del CAAD, es
un proyecto lúdico.
</p>

<p>
Ese proyecto de aprendizaje me está obligando a redescubrir
herramientas, que si bien venía utilizando, lo hacía de una manera más
superficial o completamente distinta a como las estaba utilizando
hasta ahora. Por ejemplo, <i>emacs</i> se había convertido en mi editor por
defecto, pero curiosamente escribía poco código con él, lo que más
hacía era utilizarlo para escribir documentos, consultar la agenda,
etc. Igual que también utilizo <i>git</i>, pero no de la forma que lo estoy
haciendo ahora.
</p>
<div id="outline-container-orga6f0174" class="outline-2">
<h2 id="orga6f0174">Redescubriendo herramientas</h2>
<div class="outline-text-2" id="text-orga6f0174">
<p>
Como podéis suponer, mi editor de trabajo por defecto es <i>emacs</i>.
Bueno, <i>por defecto</i> y sin <i>defecto</i>, es mi editor y basta.  Realizar
un proyecto de programación trabajando con él me ha hecho redescubrir
muchas cosas que aunque ya las conocía y las utilizaba, la perspectiva
personal sobre las mismas se ha visto modificada por el uso continuo.
</p>

<p>
Sobre alguna de esas herramientas ya he hablado aquí y no quiero hacer
un artículo demasiado profuso y aburrido sobre algo de lo que ya hablé
en su día. Pero dejadme puntualizar algunas cosas.
</p>
</div>
<div id="outline-container-org151bde9" class="outline-3">
<h3 id="org151bde9">Git y Magit</h3>
<div class="outline-text-3" id="text-org151bde9">
<p>
Hasta ahora mi trabajo con <i>git</i> ha sido bastante plano y simple. Es
decir, aunque lo he utilizado en muchas de mis cosas, mis repositorios
apenas tienen ramas. Por ejemplo, la contabilidad, que la llevo con
<i>Ledger-Cli</i>, ya lo conté por aquí, tiene un repositorio <i>git</i> donde
voy actualizando los gastos y las facturas. Sin embargo, no hay
ramas, es un repositorio unipersonal muy sencillo: <code>git commit</code>, <code>git
push</code> y nada más.
</p>

<p>
Este <i>blog</i> también tiene su repositorio. Vale que tengo una rama para
borradores de artículos y la principal para publicarlos. Pero también
es un repositorio unipersonal y lineal: las ramas no se mezclan, no se
cruzan, hay dos ramas: una para escribir y otra para publicar. No hay
rebasado ni mezcla entre ellas.
</p>

<p>
El utilizar <i>git</i> para programar, en un repositorio compartido y con
una profusión de ramas a la que no estoy acostumbrado, me está
obligando a aprender cómo funciona <i>git</i> en realidad, con un ejemplo
concreto de lo que es un repositorio de desarrollo. Me obliga a
aprender a hacer <i>rebases</i> y <i>merges</i>.
</p>

<p>
Redescubrir <i>git</i> implica que estoy redescubriendo también <code>magit</code>.
Todo lo que aprendo nuevo lo hago desde la línea de comandos. Eso me
permite con posterioridad hacerlo desde <code>magit</code> con más conocimiento
de causa. Desde el <i>buffer</i> de <code>magit-status</code> se pueden lanzar un
montón de comandos pulsando una sola tecla: <code>commit</code>, <code>pull</code>, <code>fetch</code>,
<code>push</code>, <code>rebase</code>, <code>merge</code>, <code>log</code>...
</p>

<p>
También, me he encontrado algún problema. Es decir, no problemas por
mal funcionamiento de las herramientas sino por despiste del usuario:
como estar convencido de estar en una determinada rama y estar en
otra. Eso me recuerda que siempre, cada vez que voy a realizar alguna
acción tengo que pulsar <code>C-c g</code>, ─la combinación de teclas para el
comando <code>magit-status</code> que tengo asignada─, y comprobar que
efectivamente estoy en la <i>rama</i> que debo estar antes de hacer un
<code>merge</code> o un <code>rebase</code>.
</p>
</div>
</div>
<div id="outline-container-orgaccfaee" class="outline-3">
<h3 id="orgaccfaee">Projectile</h3>
<div class="outline-text-3" id="text-orgaccfaee">
<p>
Hasta ahora tenía instalado <i>Projectile</i> para la gestión de proyectos,
pero apenas lo utilizaba. Tampoco es que haya dando un salto
cuantitativo con él, creo que apenas lo utilizo un mínimo porcentaje
de toda su funcionalidad, tan sólo estoy utilizando unos pocos
comandos con profusión y con el nuevo proyecto le he encontrado
alguna función interesante:
</p>

<ul class="org-ul">
<li>Compilar: <code>C-c p c</code>. El proyecto cuenta con un <code>Makefile</code> que hace
todo el trabajo, incluso con un comando <code>make run</code> que compila y
lanza el proyecto de forma automática, pero lo veremos después. Le
puedes decir a <i>Projectile</i> que lo utilice en lugar del escueto
<code>make</code>. Si hay errores, en la ventana de compilación puedes navegar
por los errores de forma sencilla para solucionarlos.</li>
<li>Buscar en el proyecto: <code>C-c p s g</code>. Busca una expresión en todo el
proyecto. Bueno, esto lo utilizo más cuando escribo en el <i>blog</i>,
porque me permite buscar en todos los ficheros y saltar al que me
interesa desde la lista de resultados.</li>
<li>Abrir fichero: <code>C-c p f</code>. Muestra una lista de ficheros que
pertenecen al proyecto y es más fácil buscar el que te interesa, al
menos en proyectos pequeños, que navegando con <code>Dired</code>.</li>
<li>Ejecutar el proyecto: <code>C-c p u</code>. La primera vez que lo llamas pide
el comando para iniciarlo. En este caso <code>make run</code>, luego cada vez
que lo quiero lanzar es suficiente con la combinación de teclas. Hay
que tener en cuenta que en esta ocasión lanza también un entorno
<i>erlang</i> y que hay que pararlo para hacer más pruebas.</li>
<li>Cerrar los <i>buffers</i> del proyecto: <code>C-c p k</code>. Hace un <i>kill</i> de los
<i>buffers</i> abiertos del proyecto. Algo que me viene muy bien porque
suelo utilizar <i>emacs</i> en su modo <i>daemon</i>. Cuando cierras la
ventana de <i>emacs</i> los <i>buffers</i> siguen abiertos, por lo que cambiar
de actividad, pasar de un proyecto a otro puede sobrecargar el
editor con demasiados <i>buffers</i> abiertos. Cerrar de forma selectiva
un grupo de ellos es muy útil.</li>
</ul>
</div>
</div>
<div id="outline-container-orgacb12d1" class="outline-3">
<h3 id="orgacb12d1">Erlang y erlang.el</h3>
<div class="outline-text-3" id="text-orgacb12d1">
<p>
Cuando comencé con el <i>erlang</i> me pareció un lenguaje muy marciano.
Bueno, sigue pareciéndomelo, no es comparable a otros lenguajes que
conozco y tiene una sintaxis un tanto extraña.
</p>

<p>
Después de varias semanas trabajando con él me encuentro cómodo y poco
a poco mis esquemas mentales se van adaptando a otra forma de pensar y
hacer las cosas.
</p>

<p>
Un problema con el que me he encontrado es con el <i>indentado</i>, ya
sabéis lo especial que es <i>emacs</i> con los indentados, precisamente
porque delega en los modos este aspecto, resulta un poco caótico.
Depende de los gustos de quien haya programado el modo. No siempre
esos gustos coinciden con todo el mundo.
</p>

<p>
Concretamente, me estoy acostumbrando a no utilizar <code>TAB</code> para
realizar la indentación, porque lo hará al modo establecido en
<code>erlang.el</code> y sí a utilizar <code>M-i</code> que, tiendo <code>tab-width</code> establecido
a 4 espacios, realiza la identación sin llamar a lo establecido en el
modo y haciendo los saltos de cuatro en cuatro espacios.
</p>
</div>
</div>
</div>
<div id="outline-container-org908a022" class="outline-2">
<h2 id="org908a022">Conclusiones</h2>
<div class="outline-text-2" id="text-org908a022">
<p>
Pues a estas cosas me estoy dedicando y es curioso, redescubrir
herramientas que creía ya conocidas y cómo les encuentras ese detalle
que te facilita aún más la vida.
</p>

<p>
El comprobar que <i>emacs</i> tiene más recovecos que los que se ven a
simple vista tampoco es algo nuevo, a poco que hayas trabajado con
él. Sin embargo, cada vez que trabajo con él, tengo la sensación de
que apenas he rascado un poco en la superficie de las herramientas que
proporciona. Siempre aprendiendo, siempre descubriendo y eso hace que
mi curiosidad se vea incentivada.
</p>

<p>
No he querido hablar del proyecto en concreto, está en una fase muy
inicial y avanzamos muy despacio, intentando hacer las cosas
correctamente, con el lastre añadido de que es un proyecto de
aprendizaje. Efectivamente, estamos ─al menos yo─ aprendiendo mucho:
sobre programación funcional en general, sobre <i>erlang</i> en particular
y sobre <i>emacs</i> y sus herramientas, de modo tangencial.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2020/05/27/reaprendiendo-a-programar.html</link>
  <pubDate>Wed, 27 May 2020 00:04:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Renovación de los certificados web con dehydrated]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-05-17</div>
<p>
En estos días caducaban las claves <code>SSL</code> de la página web, tanto de la
matriz <a href="https://nueva-actitud.org">Nueva Actitud</a> como de este <i>blog</i>. Y como muchos sabréis, desde
hace tiempo vengo utilizando los <a href="https://letsencrypt.org/">certificados de <i>Let's encrypt</i></a> y
aunque es un proceso un poco tedioso, no es un proceso complicado. El
problema que me encontré es que la herramienta que venía utilizando
falló. Tenía que encontrar una nueva, y ahí di con otro problema:
todas las herramientas vienen preparadas o, al menos, explicadas para
funcionar en situaciones en que el usuario tiene acceso <code>root</code> al
servidor. En mi caso no es así, el sitio está subido a un <i>hosting</i> al
que sólo puedo acceder como usuario. La herramienta que venía
utilizando hasta ahora me permitía generar los certificados de una
manera sencilla y sin complicaciones, incluso me había hecho un
<code>script</code> con las diferentes llamadas, para generar todos los
certificados que necesito de forma automática, pero cuando fui a
hacerlo el otro día todo falló y me quedé colgado. Dicha herramienta,
está desarrollada en <code>Python</code> y un cambio en el servidor con las
versiones de las librerías de dicho lenguaje, la dejó fuera de combate
en el momento más inoportuno. Probé a instalar una versión más
moderna, pero el problema persistía. Temporalmente lo solucioné como
pude para salir del paso y me puse a averiguar cómo dar una solución
más a largo plazo, llevo unos días investigando cómo volver a los
certificados de <i>Let's encrypt</i> y mirando y contrastando varias
herramientas. No voy a contar todas las herramientas que hay: decenas,
por no decir centenares y no encontraba ninguna que se pudiera ajustar
a mis necesidades.
</p>

<p>
Finalmente, un amigo del IRC, Deesix, me comentó que él usa
<a href="https://github.com/dehydrated-io/dehydrated">Dehydrated</a>, una herramienta desarrollada en <code>bash</code> y que podría serme
útil, sobre todo porque no depende de ninguna librería intermedia. La
verdad es que tenía razón y me sirve. El problema que me he encontrado
es la falta de documentación de la misma: no hay una guía clara de
cómo funciona o qué hay que hacer para generar los certificados. Así
pues, mediante la técnica del ensayo y error he llegado a generar los
certificados que necesito. Lo escribo aquí porque estas cosas se hacen
cada tres meses y supongo que para la próxima ya habré olvidado todo
lo que hice en estos días de experimentación para terminar generando
los certificados, además: no todo lo que he hecho averiguando cómo
funciona el chismático, es necesario para generarlos. Y aquí estoy, en
el <i>blog</i>, contándole al <i>mí mismo</i> de dentro de tres meses lo que hay
que hacer. Y de paso dejándolo aquí por si a alguien le puede ser
útil.
</p>
<div id="outline-container-orgd63812c" class="outline-2">
<h2 id="orgd63812c">Antes de empezar</h2>
<div class="outline-text-2" id="text-orgd63812c">
<p>
Lo primero es descargar la herramienta y yo lo hice de su repositorio
<code>git</code>:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #8be9fd; font-style: italic;">cd</span> proyectos
git clone https://github.com/dehydrated-io/dehydrated.git
</pre>
</div>

<p>
Con la descarga en el directorio <code>doc</code> vienen unos documentos en
<code>markdown</code> donde se explican algunos aspectos de la herramienta. Sin
embargo, están sueltos, sin orden y tampoco proporcionan una guía
clara de cómo conseguir tus certificados.
</p>

<p>
En todo caso, como muchas de estas herramientas, está todo pensado
para funcionar desde el mismo lugar donde se encuentra el contenido de
la página, así que mediante <code>ssh</code> lo copié al servidor y lo metí en un
directorio creado precisamente para gestionar los certificados. Es un
<code>script</code> en <code>bash</code> aunque en su página afirman que es compatible
también con <code>zsh</code>.
</p>
</div>
<div id="outline-container-org2250045" class="outline-3">
<h3 id="org2250045">El fichero <code>config</code></h3>
<div class="outline-text-3" id="text-org2250045">
<p>
Para funcionar, <code>dehydrated</code> pide un fichero <code>config</code> donde podemos
configurar los diferentes parámetros de nuestros certificados y
también de todo el proceso.
</p>

<p>
En este caso, la única variable que me ha resultado interesante
configurar es la siguiente:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #f8f8f2; font-weight: bold;">WELLKNOWN</span>=<span style="color: #f1fa8c;">"public_html/.well-known/acme-challenge"</span>
</pre>
</div>

<p>
Esa variable indica el directorio, relativo, donde se almacenará el
contenido de comprobación para el <code>challenge http</code>, que le demuestra a
la entidad certificadora que nosotros somos los propietarios del
sitio. Para quien no lo sepa, dicho <i>challenge</i> consiste en escribir
un fichero de texto con un determinado <i>hash</i> que se pude comprobar
desde fuera del sitio. Es decir, la herramienta debe escribir desde el
interior del propio servidor una <i>etiqueta</i> que estará accesible desde
el acceso público para que la entidad certificadora compruebe que el
sitio pertenece a quien ha pedido generar los certificados.
</p>
</div>
</div>
</div>
<div id="outline-container-org1c87ee0" class="outline-2">
<h2 id="org1c87ee0">Generar certificados</h2>
<div class="outline-text-2" id="text-org1c87ee0">
<p>
Una vez preparado el tema de la instalación, necesitas una <i>clave de
cuenta</i> de <i>Let's encrypt</i>, si nunca has utilizado esta entidad
certificadora o, por el motivo que sea, no tienes dicha clave, hay que
generarla. El comando es:
</p>

<div class="org-src-container">
<pre class="src src-bash">./dehydrated --register --accept-terms -d nombre-del-sitio.com
</pre>
</div>

<p>
Donde <code>nombre-del-sitio.com</code> debe ser sustituido por la dirección para
la que deseamos realizar los certificados. Cuando el comando termina,
veremos que ha creado un directorio <code>accounts</code> y dentro encontraremos
varios ficheros entre los que se encuentra nuestra <i>clave de cuenta</i>.
El directorio donde están tiene un nombre bastante raro y lo podemos
renombrar, si queremos, a algo más manejable como
<code>nombre-del-sitio</code>. Esto es de lo poco que saqué en claro de la
documentación que viene con la herramienta. Porque en mi caso, como ya
tenía de antes, <i>clave de cuenta</i> para este mismo sitio, he utilizado
la antigua para generar los certificados.
</p>
</div>
<div id="outline-container-org9a0cbdd" class="outline-3">
<h3 id="org9a0cbdd">Generar los certificados para el sitio</h3>
<div class="outline-text-3" id="text-org9a0cbdd">
<p>
Para el sitio necesitas un certificado, pero es posible que el mismo
pueda tener dos nombres o <i>alias</i>, como por ejemplo:
</p>

<ul class="org-ul">
<li><code>nombre-sitio.com</code> y</li>
<li><code>www.nombre-sitio.com</code></li>
</ul>

<p>
En la documentación hablan de otro fichero donde podemos guardar esos
datos, <code>domains.txt</code>, sin embargo, no he sido capaz de que lo leyera
de forma correcta, porque no lo encontraba. Así pues, lo he obviado y
los nombres de los sitios se los digo en la línea de comandos.
</p>

<p>
Hay que recordar que es importante que la variable <code>WELLKOWN</code> esté
bien configurada en una dirección que sea accesible desde <code>http</code>. En
este caso, el directorio configurado. En nuestro caso ese directorio
que hemos configurado como <code>public_html/.well-known/acme-challenge</code> se
convertirá en <code>www.nombre-sitio.com/.well-known/acme-challenge</code> desde
fuera.
</p>

<div class="org-src-container">
<pre class="src src-bash">./dehydrated -c -p accounts/nombre-sitio/account_key.pem -f ./config -d nombre-sitio.com -d www.nombre-sitio.com
</pre>
</div>

<p>
Con este comando, el proceso se pone en marcha. Tarda algún tiempo en
terminar todo el trabajo, conectar con el servidor de claves,
identificarse, pedir que se generen claves nuevas, etc. Un poco de
paciencia, no es inmediato, pero tampoco se lleva una mañana de
espera.
</p>

<p>
Terminado el proceso, la herramienta habrá creado dos directorios
nuevos: <code>certs</code> y <code>chains</code>. El segundo podemos ignorarlo, porque no
nos afecta. El primero almacenará dentro un directorio con el nombre
del sitio y los certificados generados:
</p>

<pre class="example" id="org8400053">
$ ls -la
total 28
drwx------ 2 uxxxxxxxxx oxxxxxxxx 4096 may 17 09:53 .
drwx------ 5 uxxxxxxxxx oxxxxxxxx 4096 may 17 10:14 ..
-rw------- 1 uxxxxxxxxx oxxxxxxxx 1691 may 17 09:44 cert-1589708685.csr
-rw------- 1 uxxxxxxxxx oxxxxxxxx 2297 may 17 09:53 cert-1589708685.pem
lrwxrwxrwx 1 uxxxxxxxxx oxxxxxxxx   19 may 17 09:53 cert.csr -&gt; cert-1589708685.csr
lrwxrwxrwx 1 uxxxxxxxxx oxxxxxxxx   19 may 17 09:53 cert.pem -&gt; cert-1589708685.pem
-rw------- 1 uxxxxxxxxx oxxxxxxxx 1648 may 17 09:53 chain-1589708685.pem
lrwxrwxrwx 1 uxxxxxxxxx oxxxxxxxx   20 may 17 09:53 chain.pem -&gt; chain-1589708685.pem
-rw------- 1 uxxxxxxxxx oxxxxxxxx 3945 may 17 09:53 fullchain-1589708685.pem
lrwxrwxrwx 1 uxxxxxxxxx oxxxxxxxx   24 may 17 09:53 fullchain.pem -&gt; fullchain-1589708685.pem
-rw------- 1 uxxxxxxxxx oxxxxxxxx 3243 may 17 09:44 privkey-1589708685.pem
lrwxrwxrwx 1 uxxxxxxxxx oxxxxxxxx   22 may 17 09:53 privkey.pem -&gt; privkey-1589708685.pem
</pre>

<p>
Como se puede apreciar, algunos de ellos son enlaces a otros presentes
en el mismo directorio.
</p>
</div>
</div>
</div>
<div id="outline-container-orge4c1b78" class="outline-2">
<h2 id="orge4c1b78">Subir los certificados al sitio</h2>
<div class="outline-text-2" id="text-orge4c1b78">
<p>
En mi caso, el proveedor del <i>hosting</i> tiene un formulario donde subir
los certificados que acabamos de generar. En concreto, dicho formulario
para subir los certificados <code>SSL</code> pide tres tipos de datos:
</p>

<ul class="org-ul">
<li>Certificado (CRT): En nuestro caso corresponde al contenido de
<code>cert.pem</code>.</li>
<li>Clave privada (KEY): En nuestro caso corresponde con el contenido
<code>privkey.pem</code>.</li>
<li>Paquete de certificado de autoridad (CABUNDLE): En nuestro caso
corresponde con el contenido de <code>fullchain.pen</code>.</li>
</ul>

<p>
En todos los casos hay que recodar que hay que copiar todo el
contenido incluyendo las líneas de inicio y fin de contenido:
</p>

<pre class="example" id="org6ebc364">
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
</pre>
</div>
</div>
<div id="outline-container-org0f450d4" class="outline-2">
<h2 id="org0f450d4">Conclusión</h2>
<div class="outline-text-2" id="text-org0f450d4">
<p>
Puede parecer poca cosa lo que aquí cuento. El problema fundamental ha
sido la falta de documentación clara.
</p>

<p>
Al final, el resultado ha sido satisfactorio pero ha costado bastantes
pruebas intermedias hacerme con la herramienta. Dejo aquí el resumen
para recordarlo dentro de tres meses y por si a alguien le viene bien
el tema.
</p>

<p>
Si estabas buscando una herramienta sencilla, que funcione y que te
proporcione los certificados <code>SSL</code> que necesitas, <code>dehydrated</code> puede
ser tu herramienta.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/ssl/index.html">SSL</a> <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[SSL]]></category>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2020/05/17/renovacion-de-los-certificados-web-con-dehydrated.html</link>
  <pubDate>Sun, 17 May 2020 15:59:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Utilizando ediff]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-05-02</div>
<p>
Otra de las herramientas que viene de regalo con una instalación
básica de <i>Emacs</i> es <code>ediff</code>. Supongo que a la mayoría de los que
puedan leer este artículo les suena el comando <code>diff</code> y conocen varias
herramientas que lo manejan de forma más o menos gráfica.
</p>


<figure id="org64ac9be">
<img src="./imagen/Captura-comando-diff.png" alt="Captura-comando-diff.png">

</figure>

<p>
En la línea de comandos el comando <code>diff</code> es muy capaz de mostrar las
diferencias que encuentra entre dos ficheros de texto, tiene cientos
de opciones y puede mostrar esa información de muchas maneras. Sin
embargo, como se puede apreciar en la imagen, necesita bastante
entrenamiento mental para comprender de un vistazo qué ha sido
cambiado y dónde. Por eso han ido apareciendo muchas herramientas más
visuales que hacen de <i>frontend</i> del comando. Hasta hace poco yo
utilizaba una que viene de regalo en KDE, <i>Kompare</i>.
</p>

<p>
Sin embargo, estos días aprendiendo <i>erlang</i> y utilizando profusamente
nuestro editor favorito para programar me resultaba incómodo dejar
<i>Emacs</i>, lanzar <i>Kompare</i>, cargar los ficheros, etc. Recordé que
<i>Emacs</i> trae una herramienta para hacer lo mismo y me propuse
simplificar mi vida. La opción creo que ha sido la correcta y ahora se
ha convertido en mi herramienta <code>diff</code> por defecto.
</p>

<p>
No sólo se pueden comparar ficheros, también, también podemos comparar
directorios si en lugar de utilizar el comando <code>ediff</code> utilizamos el
comando <code>edir</code>. Y ambas herramientas tienen una versión para comparar
3 distintos, con <code>ediff3</code> o con <code>edir3</code>.
</p>
<div id="outline-container-orgae107ba" class="outline-2">
<h2 id="orgae107ba">Lanzar <code>ediff</code></h2>
<div class="outline-text-2" id="text-orgae107ba">

<figure id="org0c0cdaf">
<img src="./imagen/Captura-iniciando-ediff.png" alt="Captura-iniciando-ediff.png">

</figure>

<p>
No es una herramienta que se utilice de forma profusa y no creo que
merezca la pena asignarle una combinación de teclas para el
lanzamiento, por lo que yo sigo utilizando el habitual <code>M-x ediff</code> (o
sus variantes).
</p>

<p>
Como he dicho antes, es posible que queramos comparar el contenido de
tres ficheros a la vez. No se me ha dado el caso aún, pero todo es
posible. Si llamamos al comando <code>M-x ediff3</code> nos pedirá el nombre de
tres ficheros y se comportará como el <code>ediff</code> normal, pero, como se
puede apreciar en la imagen, con más diversión.
</p>


<figure id="orge83bc92">
<img src="./imagen/Captura-ediff-tres-ficheros.png" alt="Captura-ediff-tres-ficheros.png">

</figure>

<p>
Una vez lanzado nos va a preguntar por los dos, o tres, ficheros que
queremos comparar uno tras otro. La navegación hacia ellos es la
habitual en <i>Emacs</i> para <i>visitar</i> un fichero y no tiene más misterio,
si ya estamos acostumbrados a nuestro editor favorito. Sin embargo,
quiero llamar la atención sobre un comportamiento de <code>ediff</code> que al
principio me resultó chocante. Cuando se lanza <code>ediff</code> y carga los
ficheros nos aparece otro <code>frame</code> como se puede apreciar en la imagen
de captura. A ese marco lo llamo yo ─no he visto si tiene otro
nombre─, el <i>controlador</i> de <code>ediff</code>. Todos los comandos dirigidos a
<code>ediff</code> deben realizarse con el cursor situado en ese marco, porque
los <i>buffers</i> que abre la herramienta, son editables ─a no ser que los
marquemos como sólo lectura─. Al principio puede resultar incómodo,
pero la utilidad que nos proporciona la edición merece la pena. Además
cambiar de marco es sencillo: a los olvidadizos como yo les recuerdo
que la combinación de teclas es <code>C-x 5 o</code>.
</p>

<p>
Al principio de acostumbrarnos a la herramienta es posible que
necesitemos una guía de los comandos para manejarnos por
<code>ediff</code>. Basta con pulsar <code>?</code> para que el <i>controlador</i> muestre una
generosa lista de comandos que podemos utilizar.
</p>


<figure id="orgfcea49d">
<img src="./imagen/Captura-ediff-ayuda.png" alt="Captura-ediff-ayuda.png">

</figure>

<p>
Por defecto, cada fichero aparece en una ventana. Si nos aparecen una
encima de la otra y preferimos que aparezcan de manera vertical
pulsaremos la tecla <code>|</code> y tendremos una visión lateral de los cambios.
</p>


<figure id="org445111e">
<img src="./imagen/Captura-ediff-vertical.png" alt="Captura-ediff-vertical.png">

</figure>

<p>
Debemos fijarnos, también, que cada <i>buffer</i> está marcado con una
letra mayúscula <code>A</code> y <code>B</code> (y <code>C</code> si empleamos <code>ediff3</code>) y muchos
comandos estarán referidos a esas marcas o nombre.
</p>
</div>
</div>
<div id="outline-container-org66fcd1c" class="outline-2">
<h2 id="org66fcd1c">Navegar por las diferencias</h2>
<div class="outline-text-2" id="text-org66fcd1c">

<figure id="orgb052eb9">
<img src="./imagen/Captura-ediff-navegar-diferencias.png" alt="Captura-ediff-navegar-diferencias.png">

</figure>

<p>
Como en muchos modos de <i>Emacs</i> podemos navegar entre las diferencias
encontradas con los comandos <code>n</code> para siguiente (<i>next</i>) y <code>p</code> para
anterior (<i>previous</i>). Pero además podemos hacer que las dos ventanas
se muevan sincronizadas utilizando los comandos <code>v</code> para ir hacia
abajo y <code>V</code> (nótese la mayúscula) para ir hacia arriba. Para movernos
lateralmente podemos utilizar los comandos <code>&lt;</code> para ir a la izquierda
y <code>&gt;</code> para ir hacia la derecha. Así no se necesita situar el cursor en
ninguna de las ventanas de edición, a no ser que efectivamente
queramos editar algo.
</p>

<p>
También podemos copiar el código de un <i>buffer</i> a otro. Por ejemplo,
cuando estamos mezclando cambios en el código de varios ficheros, es
posible que nos interese mover esas diferencias para generar una
versión definitiva. Como hay muchos comandos que aprender y siempre es
molesto cuando consultas un artículo ir saltando de un lado a otro
para ver qué comando necesito, los agrupo en el siguiente punto para
tener una referencia más rápida.
</p>
</div>
</div>
<div id="outline-container-org5547f58" class="outline-2">
<h2 id="org5547f58">Comandos habituales</h2>
<div class="outline-text-2" id="text-org5547f58">
<dl class="org-dl">
<dt><code>|</code></dt><dd>Cambia entre ventanas verticales y horizontales.</dd>
<dt><code>n</code>, <code>&lt;SPC&gt;</code></dt><dd>Va a la siguiente diferencia entre los ficheros.</dd>
<dt><code>p</code>, <code>&lt;DEL&gt;</code></dt><dd>Va a la diferencia anterior.</dd>
<dt><code>A</code>, <code>B</code>, <code>C</code></dt><dd>Establece o quita el marcador de <i>solo lectura</i> en
el <i>buffer</i> indicado para evitar que se modifique accidentalmente.
Obsérvese que este comando utiliza las mayúsculas.</dd>
<dt><code>a</code>, <code>b</code></dt><dd>Copia el contenido de la diferencia actual de <i>buffer</i>
<code>A</code> al <i>buffer</i> <code>B</code> (o viceversa). Sólo funciona en sesiones con dos
ficheros.</dd>
<dt><code>ab</code>, <code>ac</code>, <code>ba</code>, <code>bc</code>, <code>ca</code>, <code>cb</code></dt><dd>Copia el contenido del primer
<i>buffer</i> de la combinación en el segundo. Es decir, el comando <code>bc</code>
copiará el contenido del área diferente del <i>buffer</i> <code>B</code> en el área
correspondiente del <i>buffer</i> <code>C</code>.</dd>
<dt><code>!</code></dt><dd>Recalcula las diferencias de nuevo para actualizar el
contenido en el caso de que se hayan modificado los <i>buffers</i>.</dd>
<dt><code>ra</code>, <code>rb</code>, <code>rc</code></dt><dd>Restaura el valor antiguo de la región diferente
del <i>buffer</i> <code>A</code>, o <code>B</code>, o <code>C</code> según el comando.</dd>
<dt><code>R</code></dt><dd>Muestra una lista de sesiones <code>ediff</code>. Si no tenemos acceso
al <i>controlador</i> de la herramienta, podemos hacer lo mismo con el
comando <code>M-x eregistry</code>.</dd>
<dt><code>z</code></dt><dd>Suspende la sesión de <code>ediff</code> para seguir utilizando nuestro
editor para otras acciones. Podemos volver a acceder a la sesión que
hemos abandonado con el comando <code>eregistry</code> o con <code>R</code> si tenemos
acceso al <i>controlador</i> de <code>ediff</code>.</dd>
<dt><code>q</code></dt><dd>Termina la sesión actual.</dd>
</dl>
</div>
</div>
<div id="outline-container-org806a0a2" class="outline-2">
<h2 id="org806a0a2">Conclusiones</h2>
<div class="outline-text-2" id="text-org806a0a2">
<p>
<code>ediff</code> es uno de esos redescubrimientos que realizamos de vez en
cuando los usuario de <i>emacs</i>. Es una de esas herramientas que vienen
incorporadas al editor, pero que no te das cuenta de la potencia que
tienen hasta que no empiezas a utilizarlas.
</p>

<p>
Cuando programas, es muy habitual encontrarte con varias versiones del
mismo fichero de código y también que necesites mover código de una
versión a otra. La herramienta que nos proporciona <i>Emacs</i> es una de
esas que de tantas opciones que tiene se hace muy difícil meterlas
todas en solo artículo. Por ello es recomendable recurrir a la
documentación que viene incorporada y tener una referencia más
detallada de todas las opciones.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/ediff/index.html">ediff</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[ediff]]></category>
  <link>https://notxor.nueva-actitud.org/2020/05/02/utilizando-ediff.html</link>
  <pubDate>Sat, 02 May 2020 10:29:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Utilizando emacs para programar en erlang]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-04-12</div>
<p>
Llevo unos días aprendiendo <i>Erlang</i>, leyendo libros y tutoriales,
mirando y copiando código y haciendo alguna pequeña aplicación de
ejemplo para aprender.
</p>

<p>
Cuando fui a utilizar <i>Emacs</i> para trabajar con <i>Erlang</i> me llevé una
pequeña decepción: siempre que instalo algún lenguaje nuevo para
trabajar con él busco el paquete de <code>babel</code> para poder escribir código
en <code>org-mode</code>, pero no existe. Pensé que quizá el paquete de <code>erlang</code>
se iba a quedar corto en prestaciones y que me gustaría hacer
programación literaria: <i>Erlang</i> tiene sus propios caminos. Sin
embargo, al instalar el <code>erlang.el</code> también instala otro paquete de
<i>herramientas</i> y una extensión para <code>ivy-mode</code>. Y después de probarlo
estos días, me he encontrado con que las herramientas son más que
suficientes para trabajar con el lenguaje.
</p>


<figure id="orgeca1b48">
<img src="./imagen/captura-emacs-erlang.png" alt="captura-emacs-erlang.png">

</figure>
<div id="outline-container-org1de5284" class="outline-3">
<h3 id="org1de5284">Instalación</h3>
<div class="outline-text-3" id="text-org1de5284">
<p>
Bueno, ya sabemos cómo se instala cualquier paquete en nuestro editor
favorito: <code>package-install RET erlang</code> y se instalará el paquete con
las dependencias que mencioné antes.
</p>

<p>
Lo único que hay que añadir en el <code>init.el</code> es el lugar donde se
encuentre instalado <i>Erlang</i>. En mi caso, de la siguiente forma:
</p>

<div class="org-src-container">
<pre class="src src-elisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">A&#241;adir el sitio de instalaci&#243;n de Erlang
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> erlang-root-dir <span style="color: #f1fa8c;">"/usr/lib64/erlang"</span>)
</pre>
</div>

<p>
Además, al instalar la documentación en <i>OpenSuse</i> encontré que se
instalan también páginas de manual en el directorio de <i>Erlang</i> y
quise acceder desde el comando <code>M-x man</code> para tener esa documentación
muy a mano, pero <i>Emacs</i> no las encontraba. Tampoco las encuentraba el
comando <code>man</code> del sistema operativo y eso me hizo sospechar que es un
problema con el paquete de la distribución. En otras distribuciones me
consta que las páginas mencionadas se instalan correctamente en el
sitio correspondiente y son accesibles. Para solucionar este problema
lo que hice fue añadir en mi fichero <code>.bashrc</code> la siguiente línea:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #8be9fd; font-style: italic;">export</span> <span style="color: #f8f8f2; font-weight: bold;">MANPATH</span>=$<span style="color: #f8f8f2; font-weight: bold;">MANPATH</span>:/usr/lib64/erlang/man
</pre>
</div>

<p>
A partir de ese momento, ya las encontraba tanto el comando <code>man</code> del
sistema operativo, como su equivalente en <i>Emacs</i>.
</p>

<p>
Para mí es muy interesante poder tener acceso a esos documentos,
porque más adelante veremos que podremos acceder a la documentación de
las funciones de la librería con una sola pulsación de teclas.
</p>
</div>
</div>
<div id="outline-container-org7199609" class="outline-3">
<h3 id="org7199609">Edición de código</h3>
<div class="outline-text-3" id="text-org7199609">
<p>
Las herramientas de edición son como cualquiera otras que se utilizan
en <i>Emacs</i>. Aparte del coloreado de la sintaxis de código,
autocompletado y otras tan habituales que ya ni las consideramos en su
valía, hay algunas mucho más interesantes. Por ejemplo, para acceder a
una consola de <i>Erlang</i> sin salir del editor, basta pulsar la
combinación <code>C-c C-z</code>. Pero no es la única forma de acceder a una
consola funcional. Por ejemplo, una de las convenciones en <i>Erlang</i> es
guardar el código en un subdirectorio <code>src</code> y los binarios compilados
a <code>.beam</code> en un directorio <code>ebin</code>, en el mismo nivel del directorio de
la aplicación (igual que la documentación en un directorio <code>doc</code>,
etc). Cuando estamos editando un módulo de <i>Erlang</i>, si pulsamos la
combinación de teclas <code>C-c C-k</code> lanza una consola, compila el módulo
y, si todo compila correctamente, guarda el binario en su directorio
correspondiente. Además, nos deja la consola de <i>Erlang</i> abierta,
preparada para que probemos el código que acabamos de compilar.
</p>

<p>
Pero, para la edición de código, lo realmente interesante es la
cantidad de <i>Skeletons</i> que nos proporciona. Son esquemas de código,
desde una simple estructura <code>if</code> a un esqueleto completo de aplicación
que nos ahorrarán un montón de pulsaciones de teclas. Pasando por
estructuras de comentarios de código que posteriormente la herramienta
<code>edoc</code> de <i>Erlang</i> convertirá en la documentación de nuestra
aplicación.
</p>

<p>
Además está el acceso a la documentación como veíamos en el apartado
anterior. Si nos encontramos en una determinada llamada a alguna
librería, basta con pulsar <code>C-c C-d</code> para que nos muestre la página de
manual donde se encuentra su documentación para que podamos hacernos
una idea de lo que hace. Además contaremos en el menú con una amplia
selección de información sobre módulos o sobre aplicaciones de
<i>Erlang</i>, bastante bien estructurada.
</p>

<p>
También, dada la idiosincrasia el lenguaje, el módulo tiene teclas de
función que mueven el cursor a lo largo de las cláusulas de <i>Erlang</i>,
que en algunos casos pueden ser muy largas y no siempre fáciles de
navegar:
</p>

<dl class="org-dl">
<dt><code>C-c M-a</code></dt><dd>Inicio de la cláusula.</dd>
<dt><code>C-c M-e</code></dt><dd>Fin de la cláusula.</dd>
<dt><code>C-c M-h</code></dt><dd>Seleccionar toda la cláusula.</dd>
</dl>

<p>
Esas funciones son muy útiles para trabajar con la edición de código
en <i>Erlang</i>.
</p>
</div>
</div>
<div id="outline-container-orgd7b6062" class="outline-2">
<h2 id="orgd7b6062">Conclusiones</h2>
<div class="outline-text-2" id="text-orgd7b6062">
<p>
La edición de código siempre es compleja. No es una edición tan lineal
como cuando escribes un texto. Demanda grandes saltos, muchas veces
para mover sólo una coma.
</p>

<p>
<i>Erlang</i> además es un lenguaje de programación peculiar en muchos
aspectos, su código cuando vienes de una programación más secuencial
es a veces difícil de entender. Usa sus propias convenciones, sus
propias librerías y se parece poco a cualquier otro lenguaje. Como ya
dije en otra entrega, me parecía un lenguaje <i>marciano</i>. Si bien, es
verdad, que según avanzo y voy entendiendo cómo se articulan los
procesos y cómo los maneja <i>Erlang</i>, se me hace más claro y fácil.
</p>

<p>
El contar con el módulo de <i>Emacs</i> para <i>Erlang</i> está siendo toda una
suerte para avanzar en el aprendizaje. Puedo lanzar el código que
estoy probando sin salir del editor y sin necesidad de nada más. El
resto de herramientas necesarias, el <code>observer</code> o el <code>debugger</code> para
visualizar nuestros procesos o depurar el código, los proporciona el
mismo lenguaje, así que son independientes de <i>Emacs</i>, sin embargo,
como se puede ver en la figura, no hace falta salir del editor para
lanzarlos.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/erlang/index.html">erlang</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[erlang]]></category>
  <link>https://notxor.nueva-actitud.org/2020/04/12/utilizando-emacs-para-programar-en-erlang.html</link>
  <pubDate>Sun, 12 Apr 2020 19:12:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Sobre el derecho a la intimidad]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-04-07</div>
<p>
Estos días de encierro vengo observando algunas actitudes un tanto
inquietantes por parte de la población, dicho así en general.  Por
ejemplo, la necesidad que tienen algunos de fiscalizar lo que hacen
sus vecinos, criticar si salen o no salen a aplaudir a «los
sanitarios» a las ocho de la tarde, vigilar que nadie salga de su casa
increpando e insultando al que lo hace. Sin reflexionar siquiera si
precisamente ese viandante que pasa bajo su balcón es uno de esos
sanitarios que regresa o se incorpora a su turno. Sospecho que <i>la
vieja del visillo</i> increpadora de viandantes además no tendrá ningún
problema ético en votar a quien recortó la Sanidad y lo seguirá
haciendo en un alarde de <i>coherencia</i>. Pero ahora se le hace muy
necesario salir, y obligar a todo el mundo a salir, a aplaudir a una
Sanidad que recortaron gracias a sus votos.
</p>

<p>
Confieso que no he salido ni un sólo día a aplaudir a nuestros
esforzados sanitarios. No es que piense que no se lo merecen, al
contrario. Lo que puedo asegurar, desde mi más profundo sentido ético,
es que nunca voté y nunca votaré a quien recorta en la Sanidad Pública
para favorecer los intereses de unos pocos en detrimento del resto de
la sociedad. Desde mi pensamiento de que debe primar el beneficio
común por encima del individual.
</p>

<p>
Afortunadamente vivo en un pueblo y las casas están más diseminadas.
Las manifestaciones de balcón y la algarabía me quedan lejos: no tengo
que soportar ni al <i>Dúo dinámico</i> ni a los <i>Chipiritifláuticos</i>
asaltando mi espacio sonoro durante las sesiones musicales
<i>post-aplauso</i> como en otros sitios. Lo cual es un descanso
para los oídos y un bálsamo para los nervios.
</p>

<p>
Por otro lado, en mis relaciones personales, ahora muchas de ellas
virtuales, hay quien se empeña en que me instale el <i>güasás</i> o que
abra cuenta en el <i>escaipe</i>. Se asombran, algunos incluso se
enfurecen, ante mi negativa a utilizar <i>las herramientas que todo el
mundo utiliza</i>, y parecen no entender que mi postura no es tecnológica
sino ética. Me explicaré.
</p>

<p>
El artículo 18 de la <i>Constitución Española</i> de 1978 habla sobre el
derecho al honor, a la intimidad personal y familiar y a la propia
imagen, estableciendo que:
</p>

<ol class="org-ol">
<li>Se garantiza el derecho al honor, a la intimidad personal y
familiar y a la propia imagen.</li>
<li>El domicilio es inviolable. Ninguna entrada o registro podrá
hacerse en él sin consentimiento del titular o resolución judicial,
salvo en caso de flagrante delito.</li>
<li>Se garantiza el secreto de las comunicaciones y, en especial, de
las postales, telegráficas y telefónicas, salvo resolución
judicial.</li>
<li>La ley limitará el uso de la informática para garantizar el honor y
la intimidad personal y familiar de los ciudadanos y el pleno
ejercicio de sus derechos.</li>
</ol>

<p>
Si sientes que ese artículo de la Constitución es papel mojado, no se
debe a que no haya legislación posterior, como la Ley de Protección de
Datos, como estable el punto cuatro, que protege esos derechos; es que
has aceptado sin leer las condiciones de uso de herramientas que se
limpian el culo con tu derecho al honor, a la intimidad personal y
familiar y a tu propia imagen. Esas herramientas proceden en su
mayoría de las cinco grandes empresas de <i>Internet</i>: Google, Amazon,
Facebook, Apple y Microsoft (en adelante <i>GAFAM</i>).
</p>

<p>
Querido amigo, eres muy libre de entregarle tus derechos a quien creas
oportuno, pero básicamente tu abandono de derechos también me afecta a
mí. Desde el momento en que guardas mi correo electrónico o mi
teléfono en una aplicación de <i>contactos</i> gestionada por una de esas
empresas, estás entregando <i>mis datos</i>, los míos personales, a quien
no se preocupa de mis derechos. El insolidario no soy yo, por no usar
la herramienta única que nos ata en las tinieblas, eres tú que con tu
abandono arrastras mis datos contigo.
</p>

<p>
<a href="https://victorhck.gitlab.io/privacytools-es/">Siempre opto por herramientas de <i>software libre</i></a> por la misma razón
ética. Sólo desde el control de tus dispositivos y la autogestión se
puede tener un poco de intimidad. Sólo un poco debido a que la mayoría
de personas desconocen otras herramientas que no pertenezcan <i>al
amo</i> (<i>el amo nos cuida</i>... ya tú sabes).
</p>

<p>
Mi teléfono y mi tablet funcionan gracias a <i>Ubuntu-touch</i>, mi
ordenador (un portátil con 10 años bajo sus teclas) funciona gracias a
GNU/Linux (OpenSuse Tumbleweed). <a href="https://jitsi.org/">Las videoconferencias procuro
hacerlas con <i>jitsi</i></a> y la mensajería instantánea con XMPP, donde por
cierto podéis encontrarme en la cuenta de nombre <i>notxor</i> en
<i>suchat.org</i>, por si queréis añadirme a vuestros contactos de XMPP.
</p>

<p>
Sin embargo, esta postura ética se encuentra muchas veces limitada por
problemas técnicos y hay cosas que se encuentran más limitadas. No
porque no se puedan hacer, sino porque algunas empresas (básicamente
GAFAM y los que quieren imitarlos) dedican muchos de sus recursos a
acotar las libertades personales. Para ellos trabajan no sólo los
mejores programadores, ingenieros de sistemas e informáticos en
general, también los mejores psicólogos, sociólogos y antropólogos con
el único objetivo de <i>atraerlos a todos y atarlos en las tinieblas</i>.
</p>

<p>
Estos días he tropezado con algunos <i>Borg</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> evangelizando:
<i>Ustedes serán asimilados, la resistencia es inútil</i>. Me han
protestado por el tema familiares y amigos y cuando les he comentado
el tema de los <i>Borg</i> hay hasta quien se ha ofendido. Pero uno de mis
principios es la salvaguarda de mi intimidad y eso sólo lo puede hacer
una comunidad concienciada con ello. No va a venir de ninguna empresa
que gane dinero vendiéndola al mejor postor. No te la van a dar porque
sí: los derechos se obtienen luchando por ellos. Mi camino tecnológico
no es el más sencillo de seguir, pero sí el más ético: tengo un
portátil de casi 10 años funcionando y actualizado, un teléfono móvil
de 5 años, funcionando y actualizado y una tablet de cuatro años,
funcionando y actualizada... No necesito cambiar de ordenador cada dos
años, ni de móvil cada año, no tropiezo con la <i>obsolescencia
programada</i>. No necesito duplicar la capacidad de procesamiento de mi
<i>hardware</i> cada seis meses ampliando memoria o disco duro. Hay quien
lo necesita, o incluso ve en ello el parangón del progreso. Yo sólo
veo despilfarro, abandono y control.
</p>

<p>
Así que no, no me planteo utilizar <i>güasás</i> ni <i>escaipe</i>, pero no
porque sea un atrasado tecnológico, sino porque la tecnología entra en
ámbito de la ética. Prefiero aplicaciones creadas y gestionadas por la
comunidad, para la comunidad, que me otorguen capacidad de decisión y
de autogestión. Si una herramienta no tiene en consideración mis
derechos no la utilizo y basta leerse las <i>condiciones de uso</i> de
todas esas herramientas para saber que básicamente se dedican a
pasarse un derecho, que tenemos reconocido por el artículo 18 de la
Constitución, por el forro del arco del triunfo. Cuando las aceptes,
las <i>condiciones de uso</i>, piensa que no sólo te perjudicas a ti,
también limitas los derechos a la intimidad de todas esas personas
cuyos datos tienes guardados en tu aplicación de <i>contactos</i>. Si me
tienes en esa lista, que sepas que estás limitando mis derechos: yo no
acepté las condiciones de uso, tú sí.
</p>

<p>
No, no voy a instalarme <i>güasás</i> ni a abrir cuenta en <i>escaipe</i>.
</p>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Al que no entienda la referencia cinematográfica le recomiendo
la lectura de <a href="https://es.wikipedia.org/wiki/Borg_(Star_Trek)">https://es.wikipedia.org/wiki/Borg_(Star_Trek)</a> 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/libertades/index.html">libertades</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[libertades]]></category>
  <link>https://notxor.nueva-actitud.org/2020/04/07/sobre-el-derecho-a-la-intimidad.html</link>
  <pubDate>Tue, 07 Apr 2020 09:43:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Aprendiendo erlang durante la cuarentena]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-04-05</div>
<p>
Durante estos días de encierro forzoso en casa y sin más obligaciones
que distraer la mente en algo para que el techo no nos caiga encima
sin haberse movido, decidí aprender otro lenguaje funcional.
</p>

<p>
Mi primera intención fue volver a intentarlo con <code>Haskell</code>, un
lenguaje que viene resistiéndose desde hace tiempo, pero me encontré
que cuando fui a instalarlo en mi sistema, pedía 1,8Gb de espacio... y
me pareció una exageración. Caber cabía, pero se me hace mucho
desperdicio para un mero aprendizaje.
</p>

<p>
Descartado <code>Haskell</code> me acordé de <code>erlang</code>. Hace unos años ya le eché
un ojo a ese lenguaje, pues hacia él me llevó la curiosidad de
encontrar <a href="http://www.wings3d.com/">una magnífica herramienta creada con él: wings 3D</a>, en una
época en que le eché muchas horas al tema del 3D. En aquella época el
código que yo escribía solía ser <code>C/C++</code> o <code>Java</code>. Empezaba a trastear
con <code>Python</code> y me divertía con <code>Smalltalk</code>, e incluso durante un año y
medio en el que trabajé como programador con <code>Delphi/Pascal</code>, nunca
había tratado con un lenguaje de los llamados <i>funcionales</i>. Entonces,
con aquellos conocimientos, o limitaciones ─dirán algunos─, <code>erlang</code>
me pareció un lenguaje <i>muy marciano</i> y después de echarle un vistazo
me olvidé de él.
</p>

<p>
Hace poco, salió un proyecto en el que podría colaborar y se
realizaría en <code>erlang</code>, base de datos <code>couchDB</code>, ─otra de las
herramientas punteras hechas con ese lenguaje─. El caso es que aquél
proyecto no salió: se lo adjudicaron a alguna consultora más <i>fuerte</i>
que cuatro animosos <i>frikis</i>. Comencé en aquellos días a repasar
<code>erlang</code> pero cuando se torció el proyecto lo dejé de nuevo y casi me
olvidé de su existencia.
</p>

<p>
Estos días, pensando en qué hacer y habiendo descartado las 1,8Gb que
pedía <code>Haskell</code>, me acordé de nuevo de ese lenguaje: <i>funcional</i>,
<i>marciano</i> y <i>friki</i> que promete muchas cosas buenas:
</p>

<ul class="org-ul">
<li>Concurrencia.</li>
<li>Distribución.</li>
<li>Escalado.</li>
<li>Resistencia a errores.</li>
<li>Sustitución de código <i>en caliente</i>.</li>
</ul>

<p>
Es un lenguaje que, como se puede apreciar, promete muchas buenas
cosas pero que, también supongo, me <i>tropezará</i> con algún problema o
pega.
</p>
<div id="outline-container-orgac99a03" class="outline-2">
<h2 id="orgac99a03">Un vistazo general</h2>
<div class="outline-text-2" id="text-orgac99a03">
<p>
Sin ánimo de ser exhaustivo quiero compartir una visión general sobre
el lenguaje y los pasos que he venido dando en mi proceso de
aprendizaje.  Lo primero que hice, como es de suponer es instalar
<code>erlang</code> en mi ordenador:
</p>

<div class="org-src-container">
<pre class="src src-shell">sudo zypper install erlang
</pre>
</div>

<p>
En otros sistemas, cada uno sabrá cómo hacerlo... pero lo que me llamó
la atención es que iba a descargar algunas dependencias y que entre
todo el tamaño de la descarga no superaba los 30Mb. Vale que una vez
descomprimido el <code>erlang</code> en mi sistema ocupa unas 50Mb, pero no son
la 1,8Gb que pedía <code>Haskell</code> sólo en la descarga, que instalado, sería
aún más. Este es el primer punto a su favor, no es un sistema
demasiado pesado. Tanto, que ya puestos, instalé algunas herramientas
para el desarrollo, como la <i>documentación</i> o el <i>debugger</i> o el
<i>observer</i>, que aún no sé utilizar pero que prometen ser útiles. Con
esos paquetes se instalaron también otras dependencias y en total,
entre unas cosas y otras, tengo ocupadas 98Mb de disco duro, que a
estas alturas de la vida, tampoco son un gasto significativo. Otros
lenguajes como Python, Ruby o Java ocupan bastante más que eso.
</p>
</div>
<div id="outline-container-org74b828e" class="outline-3">
<h3 id="org74b828e">Un ejemplo sencillo</h3>
<div class="outline-text-3" id="text-org74b828e">
<p>
No es un lenguaje funcional puro según dice la misma documentación de
<code>erlang</code>, sin embargo, es lo más funcional que he visto hasta ahora.
De hecho, ni siquiera tiene instrucciones para hacer bucles; nada de
<code>while</code> ni de <code>for</code>. Las tareas repetitivas se realizan mediante la
<i>recursión</i> sobre listas, por ejemplo. Para no hablar en vacío, pongo
un ejemplo sencillo, pero que muestra varias características del
lenguaje. Obsérvese el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-module</span>(factorial).
<span style="color: #ffb86c;">-export</span>([<span style="color: #8be9fd; font-style: italic;">factorial/1</span>]).

<span style="color: #50fa7b; font-weight: bold;">factorial</span>(1) -&gt;
    1;
<span style="color: #50fa7b; font-weight: bold;">factorial</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>) -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">N</span> * <span style="color: #8be9fd; font-style: italic;">factorial</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>-1).
</pre>
</div>

<p>
Lo explicaré a continuación, pero vamos a ver cómo trabaja <code>erlang</code>
compilando el código y ejecutándolo desde su herramienta interactiva
de <i>shell</i>: <code>erl</code>.
</p>

<pre class="example" id="org4c9e473">
$ erl
Erlang/OTP 22 [erts-10.7] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Eshell V10.7  (abort with ^G)
1&gt; c(factorial).
{ok,factorial}
2&gt; factorial:factorial(5).
120
3&gt; factorial:factorial(-5).
Terminado (killed)
$ _
</pre>

<p>
Vemos que al intentar calcular el factorial de un número negativo,
llega un momento en que bloquea y arrastra consigo al <i>prompt</i>
interactivo de <code>erlang</code>.
</p>

<p>
Si observamos el código vemos que los comandos de las primeras líneas
comienzan por <code>-</code>. Podríamos considerarlos como la <i>cabecera</i> del
módulo. En nuestro caso <code>-module(factorial).</code> lo que hace es definir
el fichero de código como un módulo de nombre <code>factorial</code>. También
es importante el <code>.</code> al final, pues es lo que delimita las expresiones
de <code>erlang</code>: toda expresión en este lenguaje va a terminar con un
punto. La segunda línea exporta una lista de funciones del módulo. En
nuestro caso sólo tenemos una función <code>factorial/1</code>, pero podemos
observar que aún así debemos delimitarlo como una lista <code>[...]</code>.  La
otra cosa que nos puede llamar la atención es la manera de referirse a
una función: el nombre de la misma y separado con una barra el número
de argumentos de la misma. Eso nos permite, por ejemplo, si tienen
distinto número de parámetros, trabajar con dos funciones con el mismo
nombre. Por último, tenemos la expresión que define la función:
comienza con <code>factorial(1)</code> y acaba donde está el punto, tres líneas
más abajo. Como vemos, está dividida en dos partes según el argumento
recibido: si es un <code>1</code> devuelve <code>1</code> y si no, devuelve el resultado de
multiplicar el argumento <code>N</code> por el factorial de <code>N-1</code>... es decir, la
típica función recursiva llamándose a sí misma. Pero vemos, que las
dos partes de la función están separadas por un carácter <code>;</code>.
</p>
</div>
</div>
<div id="outline-container-org5598ef8" class="outline-3">
<h3 id="org5598ef8">Entorno interactivo</h3>
<div class="outline-text-3" id="text-org5598ef8">
<p>
El entorno interactivo que nos presenta <code>erlang</code> es <code>erl</code>, como hemos
visto antes. Ahí podemos cargar los módulos que necesitemos y hacer
muchas más cosas, pero vamos poco a poco.
</p>

<p>
En el ejemplo anterior hemos visto que compilábamos el módulo que
habíamos creado mediante el comando <code>c(factorial).</code> antes de poder
utilizarlo con el comando <code>factorial:factorial(5).</code> y que nos permite
analizar cómo son las llamadas en este lenguaje. Para empezar es el
nombre del módulo y de la función separado por el carácter <code>:</code>.
</p>

<p>
Pero de momento, vamos a centrarnos en el <i>eshell</i>:
</p>

<pre class="example" id="org393264e">
$ erl
Erlang/OTP 22 [erts-10.7] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Eshell V10.7  (abort with ^G)
1&gt; _
</pre>

<p>
En la segunda línea nos dice <code>abort with ^G</code>, y puede parecer que
<code>C-g</code> (en notación de <i>emacs</i>) lo que haga solamente es parar el
proceso de <code>Eshell</code>, pero no es cierto. Si pulsamos esa combinación de
teclas nos aparecerá un <i>prompt</i> tal que <code>--&gt;</code>:
</p>

<pre class="example" id="orgef19857">
$ erl
Erlang/OTP 22 [erts-10.7] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Eshell V10.7  (abort with ^G)
1&gt; 
User switch command
 --&gt; _
</pre>

<p>
Antes del <i>prompt</i> vemos el mensaje <i>User switch command</i>. Si pulsamos
<code>h</code>, o <code>?</code>, y <code>enter</code> nos mostrará una lista de posibles comandos:
</p>

<pre class="example" id="org89f6f94">
1&gt; 
User switch command
 --&gt; h
  c [nn]            - connect to job
  i [nn]            - interrupt job
  k [nn]            - kill job
  j                 - list all jobs
  s [shell]         - start local shell
  r [node [shell]]  - start remote shell
  q                 - quit erlang
  ? | h             - this message
 --&gt; _
</pre>

<p>
Vamos a utilizar <code>j</code> y <code>enter</code> para ver la lista de trabajos, aunque
de momento sólo tenemos nuestro <code>eshell</code> funcionando, así que
contestará algo parecido a:
</p>

<pre class="example" id="orga22b5e9">
--&gt; j
  1* {shell,start,[init]}
--&gt; _
</pre>

<p>
Y si tenemos nuestra consola ocupada con cálculos complejos y tarda en
contestar, por poner un ejemplo, podemos necesitar otra consola, la
lanzaremos con <code>s</code>... paralelismo desde la propia línea de comandos:
</p>

<pre class="example" id="orga0d138f">
--&gt; s
--&gt; j
  1  {shell,start,[init]}
  2* {shell,start,[]}
--&gt; _
</pre>

<p>
Bien, vemos que ahora mismo tenemos 2 procesos <code>shell</code> corriendo y
estamos enlazados al 2, porque está marcado con el <code>*</code>. Si queremos
volver a la consola anterior utilizaremos el comando <code>c 1</code>. Si
utilizamos sólo la <code>c</code> conectaremos con la <i>shell</i> a la que estemos
enganchados. También, como se puede ver en el listado de comandos se
pueden hacer más cosas, como <i>matar</i> un proceso (<code>k</code>), levantar un
«nodo» para conexión remota (<code>r</code>), o salir del <code>shell</code> (<code>q</code>).
</p>
</div>
</div>
<div id="outline-container-orgd2c822f" class="outline-3">
<h3 id="orgd2c822f">Un poco de programación defensiva</h3>
<div class="outline-text-3" id="text-orgd2c822f">
<p>
Como vimos antes, el calcular el factorial de un número negativo
producía un bloqueo. Vamos a proteger un poco esa ejecución:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-module</span>(factorial).
<span style="color: #ffb86c;">-export</span>([<span style="color: #8be9fd; font-style: italic;">factorial/1</span>]).

<span style="color: #50fa7b; font-weight: bold;">factorial</span>(1) -&gt;
    1;
<span style="color: #50fa7b; font-weight: bold;">factorial</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>) <span style="color: #ff79c6; font-weight: bold;">when</span> <span style="color: #f8f8f2; font-weight: bold;">N</span> &gt; 0 -&gt;
    <span style="color: #f8f8f2; font-weight: bold;">N</span> * <span style="color: #8be9fd; font-style: italic;">factorial</span>(<span style="color: #f8f8f2; font-weight: bold;">N</span>-1).
</pre>
</div>

<p>
El resultado será el siguiente:
</p>

<pre class="example" id="org700dcde">
$ erl
Erlang/OTP 22 [erts-10.7] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Eshell V10.7  (abort with ^G)
1&gt; c(factorial).
{ok,factorial}
2&gt; factorial:factorial(5).
120
3&gt; factorial:factorial(-5).
** exception error: no function clause matching factorial:factorial(-5) (factorial.erl, line 4)
4&gt; _
</pre>

<p>
Como vemos la cláusula <code>when</code> establece que se haga el cálculo cuando
<code>N &gt; 0</code>, es decir, cuando es un número positivo y cuando es negativo
se lanza una excepción porque no hay ninguna cláusula que tenga en
cuenta ese caso. Sin embargo, esa excepción no se lleva consigo la
ejecución del <i>shell</i>, lo cual es de agradecer y entraría en la
filosofía de <code>erlang</code> que dice eso de <i>déjalo que falle</i>.
</p>
</div>
</div>
</div>
<div id="outline-container-org5b410dd" class="outline-2">
<h2 id="org5b410dd">Tipos de datos</h2>
<div class="outline-text-2" id="text-org5b410dd">
<p>
Están los típicos valores numéricos: enteros y de coma flotante que se
ven limitados al máximo que pueda determinar la máquina, pero luego
hay otros tipos que datos que vamos a ver resumidos.
</p>

<p>
Los primeros son los <i>átomos</i> o <code>atoms</code>, que algunos vienen definidos
en el propio lenguaje, como son <code>true</code>, <code>false</code>, <code>undefined</code>, <code>ok</code>,
<code>error</code>... Sin embargo, podemos definir los nuestros propios según los
necesitemos.
</p>

<p>
En los números cabe destacar que podemos trabajar en distintas bases,
como en otros lenguajes, pero en este caso la base se define con el
<i>operador</i> <code>#</code> y no sólo soporta las clásicas bases 2, 8 y 16. Se
pueden especificar bases entre 2 y 32. con la notación siguiente:
</p>

<pre class="example" id="org44d23ff">
7&gt; 2#1011.
11
8&gt; 8#123.
83
9&gt; 30#12a0e.
873014
10&gt; 
</pre>

<p>
Como en todos los lenguajes funcionales, las listas son <i>el tipo</i> de
datos. En <code>erlang</code> ocurre lo mismo, sin embargo, las listas vienen
cargadas con otro punto importante a tener en cuenta, por ejemplo:
</p>

<pre class="example" id="orgefb5fdb">
1&gt; [104, 111, 108, 97].
"hola"
2&gt; _
</pre>

<p>
¿Eh? ¿Cómo?... Pues eso, si es una lista de números y todos los
números equivalen a caracteres imprimibles, la lista y la cadena
unifican criterios. Sin embargo:
</p>

<pre class="example" id="orgf921da7">
1&gt; [104, 111, 108, 97].
"hola"
2&gt; [104, 111, 108, 97, 0].
[104,111,108,97,0].
3&gt; _
</pre>

<p>
Cuando se encuentra con algún valor que no pertenece a ningún carácter
imprimible, como es el <code>0</code>, la lista se comporta como en cualquier
otro lenguaje. Como vemos se definen con los caracteres <code>[]</code> y se
separan por comas. Si en lugar de los corchetes utilizamos las llaves
<code>{}</code>, lo que estamos definiendo es una <code>tupla</code>, que básicamente es una
lista con características especiales. Por ejemplo, cuando compilábamos
en el punto anterior el código del módulo <code>factorial</code> el resultado que
nos devolvía era <code>{ok,factorial}</code>. Es decir, una tupla que contenía
dos <code>atoms</code> uno que nos decía que todo ha ido bien en la compilación
(<code>ok</code>) y otro con el nombre del módulo.  Esto es algo muy habitual en
<code>erlang</code>, que el retorno de una función sea un tipo compuesto que
proporciona mucha más información que un simple valor numérico.
</p>

<p>
Además podemos definir nuestros propios datos gracias a los
<code>records</code>. Es decir, podemos definir un tipo tal que:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #ffb86c;">-record</span>(<span style="color: #8be9fd; font-style: italic;">listin</span>, {nombre, apellido1, apellido2, numero}).
</pre>
</div>

<p>
Desde la <code>shell</code> la sintaxis se reduce y en lugar de la forma
<code>-record</code> se utiliza la función <code>rd</code>:
</p>

<div class="org-src-container">
<pre class="src src-erlang"><span style="color: #50fa7b; font-weight: bold;">rd</span>(listin, {nombre, apellido1, apellido2, numero}).
</pre>
</div>

<p>
Por ejemplo:
</p>

<pre class="example" id="orgc1412fb">
1&gt; rd(listin, {nombre, apellido1, apellido2, telefono}).     
listin
2&gt; A = {listin, "Fulanito", "de Tal", "y Tal", 987654321}.
#listin{nombre = "Fulanito",apellido1 = "de Tal",
                   apellido2 = "y Tal",telefono = 987654321}
3&gt; A#listin.nombre.
"Fulanito"
4&gt; _
</pre>

<p>
Vemos que se utiliza la forma general de <code>variable#registro.campo</code>
para acceder a un dato determinado.
</p>

<p>
He leído por encima, que la instalación básica de <code>erlang</code> proporciona
una <i>base de datos</i> llamada <code>Mnesia</code>, que aún no sé cómo funciona pero
que supongo que será toda una ayuda en aplicaciones grandes. Y tampoco
he tocado el tema de conexión a través de red.
</p>
</div>
</div>
<div id="outline-container-org3e4a412" class="outline-2">
<h2 id="org3e4a412">Conclusiones</h2>
<div class="outline-text-2" id="text-org3e4a412">
<p>
De momento, el lenguaje <code>erlang</code> me está sorprendiendo y gustando.
Ahora mismo estoy en plena fase de aprendizaje, apenas he leído un
poco y más bien por encima, un libro para hacerme una idea general de
cómo funciona. Me he encontrado una sintaxis bastante simple, no hay
que aprenderse largos listados de comandos ─con sus excepciones─ que
nos compliquen la vida. Es un lenguaje expresivo y aunque de primeras,
si vienes acostumbrado de otros lenguajes, puede parecer un poco
<i>marciano</i>, como ya dije antes que me pasó a mí, pero con muy poco la
práctica hace que todo el código sea claro y fácil de entender.
</p>

<p>
Puesto en el camino, y para aprender realmente el lenguaje hay que
utilizarlo, así que estoy pensando alguna aplicación que utilice las
características del lenguaje con profusión y poner a prueba esa
capacidad de resistencia a fallos, recambio en caliente, concurrencia,
etc. Se me había ocurrido alguna especie de MUD, aunque aún no tengo
muy claro qué o cómo... en estos días de encierro forzoso espero
delinear un poco mejor la idea y ya veremos si la puedo poner en
marcha. De momento estoy utilizando algunos libros que he encontrado
por ahí para aprender cuantos más detalles mejor, que aún me falta un
poco para dar el salto hacia un proyecto.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/erlang/index.html">erlang</a> ]]></description>
  <category><![CDATA[erlang]]></category>
  <link>https://notxor.nueva-actitud.org/2020/04/05/aprendiendo-erlang-durante-la-cuarentena.html</link>
  <pubDate>Sun, 05 Apr 2020 19:09:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Dekdua leciono de la Kurso de Esperanto]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-03-28</div>
<p>
Hodiaŭ, finfine, ni atingas la lastan lecionon de la kurso, ĝi estas la
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#leciono-12">dekdua leciono</a>. La <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#ejercicios-12">ekzercoj de ĉi tiu leciono</a> devas esti sendita antaŭ
la sekvantan sabaton.
</p>

<p>
Ni estis preskaŭ tri monatoj laboranta en la lernado de Esperanto. Mi
esperas ke vi ĝuis la aferon kaj ke vi amu Esperanton tiel, kiel mi.
De la ses lernantoj kiuj finiĝos la kurseton, mi pensas, ke du el vi
─vi scias kiuj aŭ, pli bone, se vi estas unu el du─ estas pretaj por
komenci plibonigi vian Esperanton, por la aliaj kvar: du devas finigi
ĉi tiun kurson antaŭe (se vi volas finigi ĉi tiun kurson, vi devas
fari la prokrastitajn lecionojn, mi atendos viajn ekzercojn kaj
korektos ilin) kaj la aliaj du devas pli studi (Esperato estas la plej
facila lingvo kiun mi konas por lerni, sed finfine estas lingvo kaj
lerni lingvon ne estas tro facila afero, vi devas pli atente
labori). Al ĉiuj mi diris per retpoŝtoj kiam mi korektis viajn
ekzercojn, kiel al mi ŝajnas viajn laborojn, do vi povas pripensi se
vi povos eniri en la plibonigo de la lingvo aŭ eble fari alian
komencantan kurson.
</p>
<div id="outline-container-org1b1a306" class="outline-2">
<h2 id="org1b1a306">Plibonigo de Esperanto</h2>
<div class="outline-text-2" id="text-org1b1a306">
<p>
Mi <b>ne</b> proponas novan kurson. Mi nur preparis libron verkita de
<a href="https://eo.wikipedia.org/wiki/Claude_Piron">Claude Piron</a>. Tre fama esperanta verkisto, psiĥologisto, kiu verkis
kelkajn lernajn librojn, kiel <i>Gerda malaperis</i>. Tiu, kiu mi proponas,
<i>Vere aŭ Fantazie</i>, estis verkita por progresinta lernado. Do, kiun mi
proponas por la plibonigo? Plano en kvar punktoj:
</p>

<ol class="org-ol">
<li><b>Legu!</b> Vi povas legi la libron kiu mi proponas aŭ alia. Sed mi
konsilas vin serĉi facilan legadon tiel, kiel mi proponas.</li>
<li><b>Skribu!</b> Vi devas esprimi viajn ideojn, viajn pensojn per la
lingvo kiu vi volas lerni. Ne estas sufiĉe traduku viajn skribaĵojn
de via denaska lingvo al Esperanto, kiam vi faras tion vi, certe,
metos tro parolmanierojn de via denaska lingvo kun esperantaj
vortoj. Kaj tio estas tre insida eraro.</li>
<li><b>Aŭskultu!</b> Vi devas aŭskulti kaj kompreni la lingvon kiu vi volas
lerni. Kiel plej eble trovi parolantojn kaj praktiki la aŭskultado
kaj parolado, sed se vi konas neniun parolanton, vi povas uzi
servojn kiel <a href="https://tubaro.aperu.net/">tubaro</a> por serĉi videojn kaj praktiki la aŭskultado.
Ankaŭ estas grupoj kiuj uzas <i>skajpo</i> aŭ aliaj retiloj por paroli
kaj aŭskulti esperanton.</li>
<li><b>Parolu!</b> Vi devas paroli kaj kutimigi vian voĉon por prononci la
lingvon kiu vi volas lerni. Kiel antaŭe mi konsilas serĉi najbarajn
esperantistojn kiuj faciligos via praktiko, sed se vi ne trovas
ilin vi povas legi laŭtvoĉe metanta vian atenton sur la prononcado
ĝusta kaj taŭga.</li>
</ol>

<p>
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/vere-aux-fantazie.epub">La libro tituliĝas <i>Vere aŭ Fantazie</i></a>, kiel mi jam diris antaŭe, kaj
konsistas en rakontetoj, ne ĉiuj same longaj, kaj pli kaj pli uzas
novajn vortojn. La unuaj komencas per 250 bazaj radikoj kaj la lastaj
finiĝas per milo da vortoj kaj centmiloj de kunmetaĵoj.
</p>

<p>
Ĉi tio ne estas kurso, ne estas ekzercoj kaj mi ne demandos pri ilin.
Se vi volas plibonigi vian Esperanton, vi povas fari tiujn kvar aferoj
vi sola hejme. Sed se vi volas iu kiu korektos viajn skribaĵojn, iu
kiu parolu kun vi esperante kaj komenti viajn laboron, ĉar vi trovas
neniun lokan esperantiston, rekomendi legaĵon, ktp. Mi postulas min
por helpi vin: mi korektos viajn skribaĵojn aŭ interparolos rete kun
vi, se vi volas. Nur, mi petas, kontakti antaŭe kun mi por
interkonsenti kiam. Vi povas fari tion skribante al retpoŝto de ĉi tiu
kurso aŭ aliamaniere.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/kurso/index.html">kurso</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[kurso]]></category>
  <link>https://notxor.nueva-actitud.org/2020/03/28/dekdua-leciono-de-la-kurso-de-esperanto.html</link>
  <pubDate>Sat, 28 Mar 2020 18:51:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Matemáticas de andar por casa en una pandemia mundial]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-03-25</div>
<p>
Primero de todo aclarar que no soy epidemiólogo. Pero con tiempo para
reflexionar y echar cuentas he decidido hablar un poco de las cosas
que me sorprenden o, por lo menos, que me llaman la atención de todo
el asunto este del coronavirus.
</p>

<p>
Estos días leo desde el confinamiento que la cuarentena nos ha
impuesto mucha idea loca sobre el coronavirus, sobre cómo se combate,
sobre cómo se contagia o sobre qué medidas debemos llevar a cabo. Veo
también en general un comportamiento adecuado y solidario en la
mayoría de la población con una conducta ordenadamente cívica, pero
también algunos perturbadores casos de individualismo. No es que las
medidas coercitivas que limitan la movilidad de los ciudadanos sean
mis preferidas, pero en este caso no vamos a tener más remedio que
acatarlas.
</p>

<p>
También, veo que nadie explica de modo coherente cómo funciona esto
del aislamiento y para qué lo estamos haciendo. Así que, en este
artículo quiero explicar cómo lo veo yo y hacer unas pequeñas cuentas
de andar por casa de cómo serían las cosas si no hiciéramos nada y a
qué nos aboca lo del aislamiento social.
</p>
<div id="outline-container-org5bc8b25" class="outline-2">
<h2 id="org5bc8b25">La progresión geométrica es invisible al ojo humano hasta que es tarde</h2>
<div class="outline-text-2" id="text-org5bc8b25">
<p>
La mente humana no está preparada para entender directamente lo que es
una progresión geométrica, sin embargo, matemáticamente es como
podemos describir una situación de contagio (como la del
coronavirus). Por ejemplo:
</p>


<figure id="org4d84aac">
<img src="./imagen/contagios.png" alt="contagios.png">

</figure>

<p>
La figura anterior intenta poner un ejemplo de cómo crece el número de
afectados, suponiendo que cada uno de ellos contagia a sólamente a
otros dos. Si pensamos que cada fila de círculos son los infectados en
un día podemos ver que desde el día <code>1</code>, con un infectado llegamos al
día <code>5</code> con 31 infectados.
</p>

<p>
Sólo han pasado cinco días y el número de infectados se ha
multiplicado, hemos pasado de 1 a 31. Cuando me explicaban estas cosas
de las progresiones geométricas durante el bachillerato (creo que
fue), me contaron la historia del precio que pidió el inventor del
ajedrez. Supongo que a muchos os sonará:
</p>

<p>
Cuenta la leyenda que cuando se inventó el ajedrez por encargo de
algún mandamás de algún país remoto, preguntó al señor inventor qué
quería a cambio de tan magnífico juego. El inventor le dijo al
mandamás que quería que le pagaran con trigo, por cada una de las
casillas: por la primera un grano, el doble (dos granos) por la
segunda, el doble (cuatro granos) por la tercera, el doble (ocho
granos) por la cuarta... así hasta llegar a la sexagésimo cuarta
(porque ya sabemos que el tablero tiene 64 casillas). El mandamás
pensó que era un precio muy bajo y aceptó sin reflexionar mucho en las
implicaciones, pero dejadme que le haga yo las cuentas de lo que tiene
que pagar:
</p>


<figure id="orgc51a5f3">
<img src="./imagen/plantuml-mates.png" alt="plantuml-mates.png">

</figure>

<p>
Eso traducido en peso ¿cuánto sería? Pues no podría decirte, pero
déjame especular un poco. Primero debería saber cuántos granos de
trigo hay en un kilo y no tengo ni idea, así que voy a especular un
poco. Si encontráis ese dato, podéis rehacer los cálculos con él. Yo
voy a suponer que en un kilo de trigo hay <code>30.000</code> granos. No sé si me
quedo corto o me paso, pero es por poner una cifra. Así pues, sólo
tengo que dividir el número de granos que nos dio antes por la
cantidad de granos que hay en un kilo y obtendré cuánto pesa (en
kilos) el trigo que hay que pagarle al señor este:
<code>614.891.469.123.651Kg</code>... unos seiscientos catorce mil billones de
kilos o lo que es lo mismo <code>614.891.469.123Tm</code> de toneladas métricas
(seiscientas catorce mil ochocientas noventa y un millones de
toneladas métricas). Pues nada, vamos a buscar todo ese trigo para
pagarle...
</p>

<p>
Por curiosidad busqué la producción mundial de trigo del 2019 y
encontré que es de <code>731,46</code> millones de toneladas. ¡Espera! Con la
producción mundial de 2019 no podemos pagar al buen señor...
necesitamos saber, entonces cuántas cosechas mundiales de cuántos años
necesitamos comprar <code>614.891.469.123 / 731.460.000</code> y esto nos da que
debemos comprar el trigo cosechado en todo el mundo durante un poco
más de <code>840</code> años para pagar al buen hombre que inventó el ajedrez.
</p>

<p>
Como la mayoría de las personas, ese mandamás no tenía una mente
preparada para observar cómo afecta una progresión geométrica al
resultado final.
</p>

<p>
El coronavirus se está extendiendo por el mundo en progresión
geométrica de forma que alcanzará a toda la población del mundo
pronto.
</p>
</div>
</div>
<div id="outline-container-org4bc00de" class="outline-2">
<h2 id="org4bc00de">El problema del cálculo de fallecidos</h2>
<div class="outline-text-2" id="text-org4bc00de">
<p>
Hemos visto que algunos <i>líderes mundiales</i> quitaban hierro a esto del
coronavirus con argumentos un tanto pillados por los pelos: <i>no es una
enfermedad grave</i>, afecta a <i>ancianos</i> y a gente con <i>patologías
previas</i>, no pasa nada, todos los años tenemos una epidemia de gripe
que se lleva a unos pocos... Como al <i>mandamás del ajedrez</i> las
progresiones geométricas no les son fáciles de comprender.
</p>

<p>
Vamos a hacer una valoración de cuántos muertos puede ocasionar una
epidemia suelta para la que no tenemos cura ni vacuna. Ya tuvimos un
ejemplo en la mal llamada <i>Gripe Española</i>, pero desde entonces, hace
100 años, hemos aprendido muy poco o nada. Así pues, considerando que
tiene una mortalidad de un 4% más o menos, según países, la cuenta
rápida en España sería que con una población de 47 millones de
personas si se infectan todos, morirían 1.880.000 personas. Pero hay
otro problema para este cálculo, a los enfermos hay que cuidarlos y
eso representa que la sanidad se verá colapsada. El 14% de los
infectados necesitan cuidados especiales dada la gravedad de los
síntomas, de lo que pueden morir. Por lo tanto la ratio de mortalidad
crecerá: no habrá <i>sanidad para todos</i>.
</p>


<figure id="org735d5aa">
<img src="./imagen/saturacion-ss.svg" alt="saturacion-ss.svg" class="org-svg" width="100%">

</figure>

<p>
Por poner algo más visual vamos a fijarnos en esta figura de arriba.
La línea gruesa negra representa el número de casos. Si la población
se infecta de forma geométrica, el número de casos crecerá
rápidamente.  Al cabo de unos días comenzará a crecer de una manera
más lenta hasta que superado el <i>pico</i> comenzará a decrecer el número
de casos.  Los infectados que superen el contagio habrán conseguido
algo de inmunidad contra el virus, otros morirán, pero lo que sabemos
es que aproximadamente el 14% de los infectados necesitarán una cama
donde recibir <i>cuidados intensivos</i> y si no los reciben, la proporción
de muertos aumentará. Y ahí es donde radica el problema: ¿qué ocurre
cuando las camas de las UCI estén llenas? Pues básicamente que no se
puede atender a todo el mundo y morirá más gente: pero no sólo de
<i>coronavirus</i>, también aquellos que desafortunadamente tengan un
infarto de miocardio, o un accidente de tráfico, o un accidente
laboral, o una pulmonía bacteriana, o ...
</p>

<p>
Por tanto, no serían sólo los muertos por <i>coronavirus</i> los que hay
que contabilizar, sino que también hay que contar todos aquellos que
hubieran podido salvarse si la <i>sanidad</i> no hubiera estado colapsada.
</p>
</div>
</div>
<div id="outline-container-orgba17aa4" class="outline-2">
<h2 id="orgba17aa4">El confinamiento para parar el contagio</h2>
<div class="outline-text-2" id="text-orgba17aa4">
<p>
¿Qué efectos tendrá el confinamiento en nuestra <i>curva de afectados</i>?
Pues es difícil saberlo, porque depende de muchos factores. Pero
podemos hablar de lo que esperan las autoridades.
</p>


<figure id="org30abd4a">
<img src="./imagen/saturacion-confinamiento.svg" alt="saturacion-confinamiento.svg" class="org-svg" width="100%">

</figure>

<p>
Vamos a echar un ojo a las curvas anteriores.
</p>

<p>
Lo que ocurre es que impuestas las medidas de confinamiento es un poco
difícil saber cómo <i>se comportará</i> la curva de infectados. Dependerá
no sólo de cuándo se haya puesto sino también de cómo de estrictas
sean las medidas y de otros factores imponderables: ¿Cómo de infectada
está tal o cual zona o lugar? ¿Cómo de seriamente se lo ha tomado la
población? ¿Se tomó a tiempo esa medida?
</p>

<p>
La intención de todos es mantener la curva de infectados por debajo de
la línea de saturación de la sanidad. ¿Qué ocurre si no es así? Pues
hay que aumentar el número de camas disponible. Eso está ocurriendo ya
en algunas comunidades autónomas y ha ocurrido en otros países antes.
Se han creado camas en nuevos hospitales improvisados para atender esa
demanda.
</p>

<p>
¿Qué otras cosas ocurren cuando se han instaurado las normas de
confinamiento para controlar la pandemia? Pues básicamente que el
famoso <i>pico de contagio</i> se retrasa. ¿Cuánto? Pues no lo sé, mis
cuentas de andar por casa no son capaces de calcular eso, pero sí sé
que se retrasa.
</p>

<p>
Además hay que tener en cuenta muchas variables y supongo que quien
toma las decisiones tendrán a mano algún modelo de simulación que les
diga esas cosas teniendo en cuenta todas esas variables que a mí se me
escapan. Sin embargo, se pasan todas las ruedas de prensa hablando de
que ya vamos a <i>llegar al pico</i>, de que <i>el pico</i> ya está cerca... y
la gente está pensando que <i>alcanzar el pico</i> acaba con el problema y
ya se pueden relajar, pero es al contrario. Debemos estar concentrados
ahora, pero una vez hayamos pasado de una puta vez el famoso <i>pico</i>
tenemos que seguir concentrados y en confinamiento para evitar un
rebrote. De nada sirve hablarle a la población general del <i>pico de
contagios</i> si finalmente lo único que indica es que tenemos ante
nosotros al menos tanta confinación como hemos tenido hasta ahora. Que
sí, que las cifras de muertos e infectados irá descendiendo, pero
seguirá muriendo gente y seguirá infectándose. Lo que hay que hacer es
concienciar a todos que cuanto más actuemos como comunidad, y no como
individuos, más gente se salvará.
</p>
</div>
</div>
<div id="outline-container-orgd5d26f2" class="outline-2">
<h2 id="orgd5d26f2">Bulos, virus y grandes números</h2>
<div class="outline-text-2" id="text-orgd5d26f2">
<p>
Me he cansado de leer bulos. Los bulos tontos me hacían gracia al
principio, pero luego veo a gente quemándose la piel o la garganta
haciendo lavativas o gárgaras con los más extraños mejunjes. Algunos
tantos que relacionaban la ganadería con la pandemia, que si los
antibióticos que se dan al ganado han creado resistencia en los
microorganismos y se ha desatado la pandemia. ¿Te suena bien? Entonces
no entiendes cómo funcionan esos bichillos. Los virus siempre, repito
<i>siempre</i>, han sido resistentes a los antibióticos. Así que nada tiene
que ver el que den antibióticos al ganado con la pandemia pero
aprovechando que por Valladolid pasa el Pisuerga pues ya meto una
pullita vegana al tema.
</p>

<p>
La gente habla de matar al bicho de las maneras más variopintas y el
problema es que un virus, en realidad, no lo puedes matar porque no
está vivo. Un virus es apenas unas pocas proteínas recubiertas de <i>una
cáscara</i> de grasa. Para luchar contra ellos lo mejor que puedes hacer
es echarle jabón a esa cubierta de grasa, para deshacerla: !lávate las
manos y todo lo que toques!... y poco más hasta que encontremos un
remedio <i>antiviral</i> adecuado.
</p>

<p>
El problema que causa este virus es que es una <i>mutación</i> para el que
no estamos <i>vacunados</i> y no tenemos ni <i>inmunidad de grupo</i> ni
individual. Y el problema es que puede mutar de nuevo. No es algo que
el virus haga voluntariamente. Una mutación ocurre como una lotería:
incluso la mutación es menos probable que el que toque la lotería. Sin
embargo, aquí el ser humano tiene otra incapacidad natural, la de
percibir números <i>muy</i> grandes o <i>muy</i> pequeños. Ya ocurrió en la
famosa <i>Gripe Española</i>, el primer brote fue en 1914 y afectó, como
éste, principalmente a personas mayores. Campó a sus anchas y eso
significó que hubo muchos miles de millones y de trillones de copias
del virus pululando. En 1918 apareció una mutación mucho más dañina
que mató a jóvenes, niños, ancianos y quien se le puso por delante.
</p>

<p>
No podemos dejar que este virus pulule libremente y consiga hacer
miles de millones de millones de copias. Cualquier error en la
transcripción de las proteínas es una mutación potencialmente
peligrosa. Esos errores de copia son muy raros de una entre millones,
pero es que si lo dejamos libre habrá millones de copias y puede
aparecer esa que lo haga aún más peligroso.
</p>
</div>
</div>
<div id="outline-container-org81f57fb" class="outline-2">
<h2 id="org81f57fb">Conclusiones</h2>
<div class="outline-text-2" id="text-org81f57fb">
<p>
No estamos ante una situación que hayamos visto antes en el mundo. La
novedad de esa pandemia es que hay que pararla y los gobiernos están
teniendo reticencia a parar un país por ella, a pesar de haber visto
cómo, al final, otros países han tenido que hacerlo. Cuando se puso en
cuarentena a toda una ciudad en China, los demás estados deberían
haber previsto ya que tendrían que hacer lo mismo. Cuando llegó a
Italia se tardó en tomar las mismas medias, cuando ha llegado a España
ha ocurrido lo mismo, y ahora asistimos a cómo otros países siguen sin
escarmentar en cabeza ajena y piensan que con ellos no va esto, que lo
van a poder controlar sin hacer tanto aspaviento.
</p>

<p>
Hace dos días veía una entrevista hecha desde Holanda a un
epidemiólogo chileno y la entrevistadora comentaba que en Holanda
estaban seguros que estas cosas pasan en países como China, Italia o
España, más atrasados que ellos, que no han hecho los deberes antes.
No estaría mal recordarles el famoso refrán «cuando las barbas de tu
vecino veas pelar, pon las tuyas a remojar». Pero espero que tengan
razón y no se vean como nos vemos nosotros junto con italianos y parte
de los chinos.
</p>

<p>
La gente además espera que los resultados se vean ya. Parece que nadie
les ha explicado lo que es el <i>periodo de incubación</i>, que son los
días que transcurren entre que alguien se contagia y la aparición de
los primeros síntomas, que es cuando ya se es potencialmente
contagioso.  El problema es que ese periodo puede ser entre dos días y
catorce días, con una media de diez. Es decir, más o menos lo que
vemos en los números de hoy es el resultado de los contagios de hace
una semana.
</p>

<p>
Podemos apreciar que todos los países, en general estamos teniendo
evoluciones similares, de momentos estamos repitiendo los pasos de
otros países de nuestro entorno. Espero que el confinamiento tenga sus
beneficios y podamos imitar la curva de Corea del Sur lo antes posible
y vamos camino de ello, muy despacio, pero vamos. Otros países como
Estados Unidos y Reino Unido están actuando tarde, espero que lo
puedan controlar finalmente. Pero sólo puedo esperarlo, porque se les
ve desatados.
</p>


<figure id="org0d0e59d">
<img src="./imagen/evolucion-paises.svg" alt="evolucion-paises.svg" class="org-svg" width="100%">

</figure>

<p>
Pues poco más que decir, veo a gente hablando mucho y diciendo la
primera barbaridad que se les viene a la cabeza. Y conste que no es
que me guste cómo está gestionando el Gobierno las cosas, pero veo que
los hay todavía peores. Me imagino cómo nos estaría yendo a estas
alturas con Rajoy: el presidente que nunca hacía nada y guardaba los
problemas en el cajón hasta que caducaban... Menos me gusta cómo lo
están gestionando algunos(as) presidentes(as) de Comunidades
Autónomas, que lo están haciendo aún peor que el presidente nacional,
con la diferencia de que tienen a alguien por encima a quien echarle
la culpa mientras asegurar ser los <i>más leales</i> del mundo mundial.
</p>

<p>
Quizá otro Presidente podría hacer lo mismo y estarle echando la culpa
a Europa, y no le faltaría razón. Está claro que de esta crisis global
debemos salir unidos y Europa sigue jugando al juego de cada perro que
se lama su cipote. Lo que terminará por cargarse los pocos argumentos
europeístas que podían contarnos: si no estamos a las duras para qué
estar a las maduras, en las maduras también cada perro se puede lamer
su cipote.  Es precisamente en las duras cuando se hace <i>nación</i>, en
los momentos difíciles cuando hay que estar y fomentar esa <i>identidad
europea</i>. Vemos cómo a Italia le están ayudado más China, Rusia y Cuba
que la Unión Europea, y con España tiene pinta que va a ser más de lo
mismo.
</p>

<p>
Pues aquí lo dejo que no me quiero calentar y me ha salido un ladrillo
considerable... sólo un último consejo: <b>¡Quédate en tu puta casa!</b>
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/matemáticas/index.html">matemáticas</a> <a href="/tags/coronavirus/index.html">coronavirus</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[matemáticas]]></category>
  <category><![CDATA[coronavirus]]></category>
  <link>https://notxor.nueva-actitud.org/2020/03/25/matematicas-de-andar-por-casa-en-una-pandemia-mundial.html</link>
  <pubDate>Wed, 25 Mar 2020 21:13:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Dekunua leciono de la Kurso de Esperanto]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-03-21</div>
<p>
Hodiaŭ ni atingas la antaŭlastan lecionon de la kurso, ĝi estas la
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#leciono-11">dekuna leciono</a>. La <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#ejercicios-11">ekzercoj de ĉi tiu leciono</a> devas esti sendita antaŭ
la sabato dudek oka de ĉi tiu monato.
</p>

<p>
Mi esperas ke vi trovos neniun malfacilaĵon, ni estas preskaŭ la fino
de la kurso kaj ĉiuj la lernantoj kiu atingas ĉi tiun lecionon, sufiĉe
scias esperanton por fari la ekzercojn kiel plej eble.
</p>

<p>
Se vi volas plibonigi vian Esperanton (vi havas ĝis la kvara de aprilo
por pensi se vi volas aŭ ne), mi proponos esperantan legadon sufiĉe
facila por via nivelo. Mi jam trovis libron, kiu povas servi nin por
la plibonigo: estas eta libro de rakontetoj. Mi estas aranĝanta la
rakontoj en «epuba» eldono por vi.
</p>

<p>
Daŭru, ni jam estas preskaŭ la fino de la kurso.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/kurso/index.html">kurso</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[kurso]]></category>
  <link>https://notxor.nueva-actitud.org/2020/03/21/dekunua-leciono-de-la-kurso-de-esperanto.html</link>
  <pubDate>Sat, 21 Mar 2020 18:47:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Edición de archivos remotos con Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-03-14</div>
<p>
El paquete <code>TRAMP</code><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> viene instalado por defecto en <i>Emacs</i>, no
hay que instalar nada y es el paquete que nos permite editar ficheros
que no se encuentran en nuestra máquina.
</p>

<p>
El caso es que no lo había utilizado, pero estos días he tenido algún
problemilla con la configuración de mi <i>nube</i> que me han obligado a
tener que trastear por espacios «lejanos», o remotos, escribiendo en
ficheros situados en una máquina que no es la mía, aunque tenga acceso
mediante <code>ssh</code>. Pensé: «Bueno, es el momento de usar <code>TRAMP</code> y
escribir un artículo largo y sesudo de cómo funciona».
</p>

<p>
¡Qué triste! Pensaba que sería algo complicado, complejo y lleno de
detalles que tener en mente para abrir un túnel <code>ssh</code> y modificar el
fichero que queremos. Nada más lejos de la realidad: ¿Sabes cómo abrir
un fichero con <i>Emacs</i>? Si la respuesta es «sí» ya sabes abrir un
fichero remoto. Sólo necesitas comenzar el nombre del fichero con una
pequeña información. Por poner un ejemplo vamos a ver los siguientes
datos para conectar por <code>ssh</code>:
</p>

<ul class="org-ul">
<li><b>Usuario</b>: <code>nombre</code></li>
<li><b>Servidor</b>: <code>misitio.com</code></li>
<li><b>Puerto</b>: <code>12345</code></li>
<li><b>Password</b>: abcABC_123456</li>
<li><b>Fichero</b>: <code>~/fichero.txt</code></li>
</ul>

<p>
Para abrir un fichero en remoto lo único que tenemos que hacer es
utilizar la famosa combinación <code>C-x C-f</code>. A continuación pide el
nombre del fichero que queremos abrir, debemos teclear el siguiente
nombre:
</p>

<pre class="example" id="orgedd7fa7">
/ssh:nombre@misitio.com#12345:~nombre/fichero.txt
</pre>

<p>
<i>Emacs</i> nos pedirá el <i>password</i> y después de teclearlo establecerá la
conexión abriendo el fichero solicitado. Ya está, se ha terminado el
artículo...
</p>
<div id="outline-container-orgd5daebf" class="outline-2">
<h2 id="orgd5daebf">Algunos datos más para los curiosos</h2>
<div class="outline-text-2" id="text-orgd5daebf">
<p>
De forma general, podemos decir que la <code>URL</code> consta de los siguientes
elementos:
</p>

<pre class="example" id="orgf346c6a">
/método:usuario@servidor:path/al/fichero
</pre>

<p>
Además, si tenemos algún problema para recordar el nombre del fichero
exacto, podemos utilizar <i>completion</i> pulsando <code>&lt;TAB&gt;</code>.
</p>

<p>
Lo que me recuerda que ya había utilizado <code>TRAMP</code> sin saberlo, para
editar algún fichero local. Y algunos os preguntaréis: <i>¿Utilizar un
chismático de edición remota para edición local?</i> Pues sí. Recuerdo
haber modificado el fichero <code>/etc/hosts</code> desde una sesión abierta de
<i>Emacs</i> tecleando:
</p>

<pre class="example" id="orgefe0241">
C-x C-f /sudo::/etc/hosts
</pre>

<p>
<i>Emacs</i> me pidió el <i>password</i> de <code>root</code> y lo edité sin más
complicaciones.
</p>
</div>
<div id="outline-container-org3c04a83" class="outline-4">
<h4 id="org3c04a83">¿Cuáles protocolos tenemos disponibles?</h4>
<div class="outline-text-4" id="text-org3c04a83">
<p>
He de confesar que para rellenar un poco un artículo que me estaba
quedando un tanto desangelado, he mirado qué tipo de protocolos de
comunicación o método de conexión se pueden utilizar:
</p>

<ul class="org-ul">
<li><code>rsh</code>, <code>ssh</code>, <code>plink</code> (si estás utilizando PuTTY en <i>windows</i>),
<code>plinkx</code>, <code>telnet</code></li>
<li><code>su</code>, <code>sudo</code> (que ya hemos visto), <code>sg</code> (<i>switch group</i>), <code>doas</code>
(método utilizado por <code>OpenBSD</code> como <code>sudo</code>), <code>krlogin</code>, <code>ksu</code></li>
<li><code>smbclient</code> con una <code>URL</code> tal que
<code>/smb:usuario%dominio@servidor:/path/al/fichero</code>.</li>
<li><code>rcp</code>, <code>scp</code>, <code>rsync</code>, <code>scpx</code></li>
<li><code>pscp</code>, <code>psftp</code>, <code>sftp</code>, <code>afp</code>, <code>fcp</code>, <code>nc</code>, <code>ftp</code></li>
<li><code>dav</code> y <code>davs</code> por ejemplo para acceder a nuestra nube particular.</li>
<li><code>gdrive</code> para acceder a <i>Google Drive</i>.</li>
<li><code>adb</code> para acceder a un dispositivo con <code>android</code>.</li>
</ul>

<p>
Es decir, hay todo un abanico de conexiones que nos puede ser útiles a
la hora de conectarnos con nuestros ficheros de texto.
</p>
</div>
</div>
</div>
<div id="outline-container-orgbff7079" class="outline-2">
<h2 id="orgbff7079">Conclusiones</h2>
<div class="outline-text-2" id="text-orgbff7079">
<p>
Este es otro paquete de los que ya viene con <i>Emacs</i> que me había
pasado desapercibido y que después de haberlo probado creo que se
convertirá en un habitual de mi caja de herramientas.
</p>

<p>
De momento sólo lo he utilizado esta vez y con el protocolo <code>ssh</code>,
pero no descarto conectarme a otros ficheros mediante otros
protocolos.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Transparent Remote (file) Access, Multiple Protocol</i>
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2020/03/14/edición-de-archivos-remotos-con-emacs.html</link>
  <pubDate>Sat, 14 Mar 2020 18:59:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Deka leciono de la Kurso de Esperanto]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-03-14</div>
<p>
Hodiaŭ ni surpasas la tria kvarona parto de la kurso, ni atingas la
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#leciono-10">dekan lecionon</a>. La <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#ejercicios-10">ekzercoj de ĉi tiu leciono</a> devas esti sendita antaŭ
la sabato dudek unua de ĉi tiu monato.
</p>

<p>
En tiu ĉi leciono ne estas malfacilaĵoj, kiuj povas bari la progreson
de niaj lernantoj. Do, mi ne klarigos pli ĉi tie. Se unu el vi havas
iun ajn dubon, skribu ĝin al kutima retpoŝto.
</p>

<p>
Daŭru miaj karaj lernantoj, vi preskaŭ atingas la kursan finon.
</p>

<p>
Je la fino mi demandos se vi volos plibonigi vian esperanton. Miaj
planoj estas trovi facilan libron por pligrandigi viajn vortprovizojn,
kaj legi kaj skribi kaj traduki kaj pli detale studi la
gramatikon. Sed ankaŭ mi devas trovi tiun libron kiu estos la ilo por
la lernado. Pensu, mi petas, se vi estos preta ─libervole─ por daŭrigi
la lernado post la fina leciono de ĉi tiu kurso kaj diru al mi antaŭ
la fino.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/kurso/index.html">kurso</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[kurso]]></category>
  <link>https://notxor.nueva-actitud.org/2020/03/14/deka-leciono-de-la-kurso-de-esperanto.html</link>
  <pubDate>Sat, 14 Mar 2020 18:44:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Utilizando KiTTY como terminal]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-03-13</div>
<p>
Hace un tiempo que vengo utilizando <a href="https://sw.kovidgoyal.net/kitty/">kitty</a> como terminal por defecto
para trabajar. Sólo empecé a probarlo, pero es otra de las
herramientas que llegaron para quedarse. Hasta ahora utilizaba de
forma predeterminada el <code>konsole</code> de KDE, porque me permitía tener
pestañas abiertas y era más flexible, y altamente configurable, que
otros emuladores de terminales.
</p>

<p>
De hecho, es tan flexible que me estoy olvidando también de <code>tmux</code>, en
favor de las posibilidades que ofrece de tener varios <i>tabs</i> cada uno
con su <i>layout</i> de ventanas.
</p>

<p>
Mi fichero de configuración no puede ser más simple:
</p>

<pre class="example" id="org3173ccb">
font_family      Fira Code
font_size 10.0

# foreground #dddddd
background #222222

# color0 #000000
color0 #222222
# color8 #767676

# lanzar una ventana con fish shell
map ctrl+alt+enter new_window @ fish
</pre>

<p>
Como se puede observar, establezco el tipo de fuente que utilizo <i>Fira
Code</i> y el tamaño <code>10</code>. Pongo un color de fondo y otro de primer plano
y como colofón <i>mapeo</i> una combinación de teclas para lanzar una nueva
ventana con otra <i>shell</i>, en concreto <a href="https://fishshell.com/"><i>fish shell</i></a> (una <i>shell</i> muy
chula pero que no se queda permanente en mi caja de herramientas
porque interfiere con <code>rofi</code> y me bloquea mi lanzador de aplicaciones
favorito).
</p>

<p>
Como decía, <code>kitty</code> permite tener varias pestañas abiertas y cambiar
entre ellas, además nos permite abrir en cada pestaña varias ventanas
en las que trabajar. Todo con unas sencillas combinaciones de teclas.
</p>


<figure id="orgb5ad411">
<img src="./imagen/Captura-kitty.png" alt="Captura-kitty.png">

<figcaption><span class="figure-number">Figure 1: </span>Ventana de <code>kitty</code> con varias pestañas y ventanas abiertas.</figcaption>
</figure>

<p>
En la figura podemos apreciar las pestañas colocadas en la última
línea, resaltando la activa. Dentro de esa encontramos tres ventanas
de trabajo, una de ellas ─la inferior derecha─ con <code>fish</code> en lugar de
<code>bash</code>, que es la <i>shell</i> por defecto.
</p>

<p>
Las combinaciones de teclas que están configuradas por defecto, me
han sido fáciles de aprender y trabajar con ellas. Voy a enumerar las
más habituales, porque en la página web de <code>kitty</code> podéis encontrarlas
todas y hay algunas que no he utilizado nunca o muy pocas veces:
</p>

<ul class="org-ul">
<li><b>Ctrl+Shift+t</b> ─ Crear una pestaña nueva.</li>
<li><b>Ctrl+Shift+q</b> ─ Destruir una pestaña.</li>
<li><b>Ctrl+Shift+→</b> ─ Ir a la pestaña siguiente.</li>
<li><b>Ctrl+Shift+←</b> ─ Ir a la pestaña anterior.</li>
<li><b>Ctrl+Shift+.</b> ─ Mover a la derecha la pestaña.</li>
<li><b>Ctrl+Shift+,</b> ─ Mover a la izquierda la pestaña.</li>
</ul>

<p>
El trabajo con ventanas también tiene su conjunto de teclas:
</p>

<ul class="org-ul">
<li><b>Ctrl+Shift+enter</b> ─ Crea una ventana nueva.</li>
<li><b>Ctrl+Shift+n</b> ─ Crea un marco nuevo.</li>
<li><b>Ctrl+Shift+1..n</b> ─ Mueve el foco a la ventana <code>1..n</code>.</li>
<li><b>Ctrl+alt+enter</b> ─ Crea una nueva ventana con la <i>shell</i> <code>fish</code>
cargada (esto sólo es en mi caso, porque lo configuré así).</li>
<li><b>Ctrl+Shift+l</b> ─ Cambiar la distribución de las ventanas</li>
</ul>

<p>
Las combinaciones de teclas se pueden ajustar y adaptar a nuestros
gustos, como se ha visto más arriba.
</p>
<div id="outline-container-org5fa3cea" class="outline-3">
<h3 id="org5fa3cea">Distribución de ventanas</h3>
<div class="outline-text-3" id="text-org5fa3cea">
<p>
Además, las ventanas se pueden organizar según los determinados
<i>layouts</i> o distribución de ventanas que vienen preestablecidos:
</p>

<ul class="org-ul">
<li><b>Fat</b>: Una ventana se muestra arriba ocupando todo el ancho y las
demás se alinean una al lado de la otra en la fila de abajo.</li>
<li><b>Grid</b>: Se muestran las ventanas en una rejilla repartiendo el
espacio entre todas.</li>
<li><b>Horizontal</b>: Todas las ventanas se muestran unas al lado de las
otras.</li>
<li><b>Stack</b>: Las ventanas se muestran ocupando todo el marco en modo
«maximizado».</li>
<li><b>Tall</b>: Una ventana se muestra a la izquierda ocupando todo el alto
y el resto a la derecha apiladas unas encima de otras.</li>
<li><b>Vertical</b>: Las ventanas se muestran todas apiladas unas encima de
otras.</li>
</ul>

<p>
Para cambiar los distintos <i>layouts</i> se utiliza la combinación de
teclas <code>Ctrl+Shift+l</code>.
</p>
</div>
</div>
<div id="outline-container-orgfb590a0" class="outline-3">
<h3 id="orgfb590a0">Selección de texto</h3>
<div class="outline-text-3" id="text-orgfb590a0">
<p>
Bueno, selección de texto y otras cosillas que hacen que sea fácil
trabajar con este emulador de terminal. Por ejemplo, si pulso
<code>Ctrl+Shitf+click ratón</code> sobre una URL, la abrirá con el navegador. Si
con el ratón hago doble click sobre una palabra, la seleccionaré. Pero
también, si hago doble click sin soltar el segundo y muevo el ratón se
pueden seleccionar regiones de texto. Con triple click se selecciona
una línea entera y con triple click sin soltar el último puedo
seleccionar varias.
</p>

<p>
Además, tiene un funcionamiento muy similar a cómo se establecen los
diferentes registros de copiar y pegar en <code>vim</code> para tener varios
<i>buffers</i> de copiado.
</p>
</div>
</div>
<div id="outline-container-org3e2ec91" class="outline-2">
<h2 id="org3e2ec91">Conclusiones</h2>
<div class="outline-text-2" id="text-org3e2ec91">
<p>
<code>Kitty</code> es un emulador de terminal bastante rápido y configurable. Tan
flexible que me ha hecho olvidarme de <code>tmux</code> y arreglármelas sólo con
el emulador de terminal.
</p>

<p>
Es potente, permite varios modos de visualización y también es rápido,
quizá no el más rápido pero más de lo que es <code>konsole</code> con <code>tmux</code>. O
al menos esto es la sensación subjetiva que tengo.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/linux/index.html">linux</a> <a href="/tags/terminal/index.html">terminal</a> <a href="/tags/kitty/index.html">kitty</a> ]]></description>
  <category><![CDATA[linux]]></category>
  <category><![CDATA[terminal]]></category>
  <category><![CDATA[kitty]]></category>
  <link>https://notxor.nueva-actitud.org/2020/03/13/utilizando-kitty-como-terminal.html</link>
  <pubDate>Fri, 13 Mar 2020 10:34:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Utilizando Telegram para comentarios del blog]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-03-08</div>
<p>
Desde finales de diciembre pasado vengo experimentando con <a href="https://t.me/notxorblog">un grupo
reducido de seguidores en Telegram</a> y parece que está funcionando
correctamente. Al principio no me cuadraba mucho utilizar una red de
<i>mensajería instantánea</i> para comentarios de un <i>blog</i>, pero había
visto a varios <i>blogs</i> y <i>podcasts</i> hacerlo y me decidí a probarlo.
Al principio como un experimento a ver qué tal funcionaba la idea,
pero después de dos meses de uso la experiencia ha sido positiva y me
he decidido a hacerle publicidad.
</p>

<p>
Puesto que los comentarios en el <i>blog</i> los tuve que cancelar debido a
ataques continuados de intentos de <i>inyección de SQL</i> o de <i>inyección
de código PHP</i>. Los comentarios no utilizaban <code>SQL</code> así que esos
ataques no me preocupaban en absoluto, sin embargo sí utilizaban
<code>PHP</code>, por lo que esos ataques sí eran más peligrosos. Por fortuna,
ninguno de ellos estaba dirigido con la suficiente diligencia como
para tener éxito: parecían ataques de <i>bots</i> que van probando
diferentes ataques conocidos para encontrar sitios desprotegidos.
</p>

<p>
Al final, el caso es que, cerré los comentarios. No los usaba mucha
gente, a lo sumo había uno o dos comentarios. Curiosamente, al
desplazarme hacia las redes he visto que a la gente, los posibles
lectores del <i>blog</i>, les da menos «fatiga» el comentar por <i>Mastodon</i>
o por <i>Diaspora</i>, y desde hace dos meses por <i>Telegram</i>.
</p>

<p>
No soy un defensor de <i>Telegram</i>, ni pienso que sea una <i>red libre</i>,
soy consciente que la «parte servidor» del programa es propietaria.
Sin embargo, la parte cliente es libre y por eso hay aplicación nativa
para <i>Ubuntu Touch</i> que es el sistema operativo que uso en el móvil.
Como digo, soy consciente que no es <i>libre</i>, ni siquiera <i>de fuente
abierta</i> pero he decidido utilizarlo. Además, reflexionando sobre
estas cosas de las libertades y las redes he llegado a más
conclusiones que, ya puestos, quiero contar.
</p>

<p>
Siempre escribo los artículos casi convencido de que nadie lo leerá,
mi sorpresa es cuando obtengo <i>feedback</i> de las redes. Eso me está
ocurriendo, tanto en <i>Mastodon</i> como en <i>Telegram</i> y no tanto en
<i>Diaspora</i>. He de decir que tampoco estoy percibiendo <i>Mastodon</i> como
una red libre (o tan libre) como muchos piensan.
</p>

<p>
Me explico.
</p>

<p>
Como algunos sabréis desde hace algún tiempo cambié de nodo y me fui al
<code>mastodon.madrid</code> de nuestro amigo <i>Fanta</i>. Era un nodo pequeño y
recién creado. Además, recién llegado a dicho nodo <i>Fanta</i> me pidió y
me convenció (tampoco le costó excesivo trabajo) para ser moderador
del nodo. Lo hice en medio de una de las últimas avalanchas y era
también una forma de descargar el saturado nodo de <code>mastodon.social</code>.
</p>

<p>
El caso es que no sé muy bien cómo, ─yo supongo que sería por llamar
la atención a algún <i>tuitero revenío</i> sobre alguna falta de respeto─,
el caso es que me reportaron por «intransigente». Y también supongo,
que con el exceso de trabajo de esos días o que directamente el
administrador del nodo no habla español y los ayudantes vete a saber,
el caso es que coló y estoy bloqueado en <code>mastodon.social</code>. El
problema viene de que había hecho una migración desde ahí a
<code>mastodon.social</code> y no sólo me bloquearon la cuenta de <code>.social</code> sino
que también afecta dicho bloqueo a la cuenta de <code>.madrid</code>. Algunos
lectores del <i>blog</i> se han quejado de que no me leen por <i>Mastodon</i>,
así que tenía que explicar por qué.
</p>

<p>
Como decía, esta experiencia me ha hecho reflexionar sobre la
<i>libertad</i> de las <i>redes libres</i>, porque al final dicha libertad se
basa en el criterio de administradores y moderadores de los nodos. El
caso es que cuando bloqueas a un usuario, no hay sitio para la
defensa, ese usuario no puede defenderse si lo bloqueas, ni siquiera
hay modo de escuchar su queja: está bloqueado. Según explican se puede
ir a otro sitio o utilizar otro <i>nick</i> y abrirse otra cuenta en
cualquier otro nodo. Pero algunas veces no es tan fácil cuando llevas
años en el <i>fediverso</i> desde antes que existiera el propio <i>Mastodon</i>
con un <i>nick</i> que se ha convertido en tú mismo: ¿le están negando la
identidad a los usuarios? ¿Deben renunciar a ellos mismos por una
decisión de un tercero tomada demasiado a la ligera?
</p>

<p>
Desde mi punto de vista de <i>moderador</i> de un nodo (aunque no da
demasiado trabajo) soy consciente de lo que puede conllevar una
decisión de este tipo. Además tomada en un nodo grande, donde está una
gran parte de usuarios de la red.
</p>

<p>
El tamaño del nodo es también relevante, cuanto más grande (en número
de cuentas) sea un nodo, a más gente estás privando del acceso a otra
cuenta...
</p>

<p>
La conclusión es que el <i>fediverso</i> sólo puede ser libre si es
verdaderamente descentralizado, si los nodos son pequeños y
autogestionados por grupos de usuarios comprometidos con esa
libertad. Cuando el tamaño de un nodo se desmadra es difícil
administrarlo de manera justa para todos. Desde luego, en el caso de
que se produzca un bloqueo, afectará a un número reducido de cuentas
entre todo el <i>fediverso</i>, por lo que una decisión de ese tipo no es
tan lesiva para los usuarios; sin embargo, en nodos <i>mastodónticos</i>
esas decisiones serán verdaderamente lesivas para el usuario y por
tanto más injustas que en una verdadera red descentralizada.
</p>

<p>
Salir de redes sociales centralizadas por diseño, para caer en una red
social centralizada <i>de facto</i> no tiene nada de «liberación», sigues
estando en una red centralizada. O peor, porque tienes la sensación de
estar en una red libre, cuando no lo es: pertenece a un administrador,
que además no cuenta con los recursos necesarios para gestionarla
decentemente.
</p>

<p>
Por todo ello, no me parece un retroceso utilizar una <i>red
centralizada</i> como <i>Telegram</i> para gestionar comentarios de mi
<i>blog</i>: soy consciente que no es una <i>red libre</i>, que es <i>software
propietario</i>, que debería darme tanta urticaria como me da el
<i>güasás</i>, pero es una elección mía y que creo válida. <i>Mastodon</i> me ha
cerrado la puerta él solo; en <i>Diaspora*</i> la interacción es casi
marginal, sólo por número de usuarios; me queda, curiosamente, el uso
de una aplicación <i>propietaria</i> para abrir la posibilidad de
interacción <i>libre</i>.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/blog/index.html">blog</a> <a href="/tags/redes-sociales/index.html">redes-sociales</a> ]]></description>
  <category><![CDATA[blog]]></category>
  <category><![CDATA[redes-sociales]]></category>
  <link>https://notxor.nueva-actitud.org/2020/03/08/utilizando-telegram-para-comentarios-del-blog.html</link>
  <pubDate>Sun, 08 Mar 2020 00:07:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Naŭa leciono de la Kurso de Esperanto]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-03-07</div>
<p>
Hodiaŭ ni komencas la tria triona parto de nia kurso de Esperanto per
la <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#leciono-9">naŭa leciono</a>, se vi sekvas la kurson vi certe ne trovos
malfacilaĵojn en tiu ĉi leciono. <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#ejercicios-9">la ekzercoj de la leciono</a> estos
facilaj plenigitaj de la lernantoj. Vi debas eldoni la respondojn je
la 14a de ĉi tiu monato.
</p>

<p>
La pasintan semajnon mi proponis ludon por doni esperantan liblon de
«el Quijote», kiu mi havis. La gajnanto de tiu ludo, la lernanto, kiu
unue sendis al mi la ludan vortprovizon estis Ondiz. Mi jam sendis al
ŝi la libron kaj mi esperas ke ŝi ĝuis ĝin legante en la estonteco (ĝi
ne estas facila libro por komencantoj).
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/kurso/index.html">kurso</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[kurso]]></category>
  <link>https://notxor.nueva-actitud.org/2020/03/07/nauxa-leciono-de-la-kurso-de-esperanto.html</link>
  <pubDate>Sat, 07 Mar 2020 19:14:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Reflexiones sobre la tecnología y la edad]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-03-06</div>
<p>
Llevo unos días <a href="https://gitlab.com/notxor1/curso-de-seguridad-informatica-para-psicologos">trabajando en un curso sobre seguridad informática
para psicólogos</a> en la plataforma de educación del COPPA<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> donde
estoy colegiado. En el repositorio que enlazo voy subiendo también los
textos, aún en borrador, para posteriormente generar el curso en
formatos electrónicos como <code>pdf</code> o <code>epub</code> y distribuirlos de manera
gratuita a quien lo quiera leer. De momento me centraré en generar un
curso que se pueda quedar en el «aula virtual» del COPPA y que,
voluntariamente, pueda hacer o seguir el personal colegiado, con sus
autoevaluaciones y otras herramientas que permitan formar un poco a
profesionales cuyo trabajo fundamental se realiza manejando
información de terceros.
</p>

<p>
Además estos días, colaborando con la <a href="https://asociacionpica.org/">Asociación PICA</a> he hecho alguna
charla con alguna AMPA<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> de algún instituto y colegio. En estas
charlas hablamos sobre <i>acoso escolar</i> y también, no podíamos
olvidarnos del <i>ciberacoso</i>. El resumen de estas charlas es: los
padres han abandonado el tema de la tecnología. Tienen asumido que sus
hijos manejan los dispositivos tecnológicos mucho mejor que ellos, así
que no hacen nada. El <i>ciberacoso</i> se encuentra en abandono por la
mayoría de los padres.
</p>

<p>
Cuando hablamos en estas charlas con los alumnos me doy cuenta que
tienen el mismo conocimiento sobre tecnología que sus padres: cero o
ninguno. Saben instalar aplicaciones en dispositivos generalmente
móviles o <i>tablets</i>, pocos hablan de ordenadores (y esto es otro dato
preocupante). Como digo <i>saben toquetear los botones</i> de una
aplicación en una pantalla táctil y lo hacen sin miedo, sin el miedo
que seguramente tendrán sus padres <i>a borrar o estropear algo</i>. Sin
embargo, hablando con ellos, no saben cómo funcionan esas
aplicaciones, o Internet. Si les pregunto directamente reconocen que
les gustaría <i>hacer</i> un juego o <i>crear</i> contenido, sin embargo
rechazan el uso del ordenador... es un atraso, según ellos, un
teclado, un ratón, la pantalla no es táctil, es un engorro llevarlo
por ahí, esto aún siendo portátil o transportable. Además utilizan esa
tecnología para informarse... y eso es terrible.
</p>

<p>
Con el acceso a Internet generalizado se crea una curiosa paradoja.
Mientras mirar la televisión nos da la sensación de que esa
información nos llega de manera pasiva, con el uso de nuestro móvil
para lo mismo nos da la falsa sensación de que la búsqueda de
información es activa. Vamos a nuestras redes sociales favoritas, nos
muestran pantallazos de noticias, apenas titulares que nosotros
pinchamos y leemos. Damos de forma tácita el beneplácito de veracidad
a cualquier información que nos viene enlazada desde otra cuenta que
seguimos. Puede que leamos una o dos líneas tras el titular (redactado
siempre de la forma más amarillista posible, con el objeto de
viralizarse). Nos parece que interactuamos con esa información, que
nosotros la buscamos, porque hemos «pinchado» un enlace, porque
movemos la interminable lista de cosas que ver de arriba hacia abajo
con un dedo, porque da la impresión que hacemos algo para acceder a
esa información.
</p>

<p>
Soy consciente de lo malas que son las generalizaciones, pero me
atrevo a decir que la mayoría de los jóvenes, conscientemente, dejan
de lado el único dispositivo en el que podrían tener cierta <i>soberanía
electrónica</i>: el ordenador, en favor de otros dispositivos <i>más
intuitivos, más cómodos</i>, dicen ellos. Conceptos como la <i>seguridad</i>,
la <i>intimidad</i> les suenan de forma difusa, aunque la mayoría <i>delegan</i>
esas actuaciones al verdadero gestor del dispositivo: <i>gúguel</i>,
<i>micro$oft</i>, <i>ápel</i>... «Si instalas aplicaciones de la <i>store</i>
correspondiente no hay problema...». No consideran en ningún momento
los <i>permisos</i> que esas aplicaciones solicitan, porque «para algo lo
necesitará». No leen las condiciones de uso de ningún servicio: lo
aceptan sin más.
</p>

<p>
Sobre otros aspectos como la gestión de memoria o de espacio, saturan
el procesador, el acceso a red, con sus aplicaciones y cuando su
terminal se ralentiza piden (o exigen) uno nuevo, porque <i>este ya está
viejo y no sirve, se cuelga, es una patata</i>.
</p>

<p>
En los adultos, por el contrario veo rendición: asumen que <i>no
entienden</i> con demasiada facilidad. Lo asumen sin informarse o
haciéndolo en los sitios que les recomienda <i>feisbús</i>. La mayoría de
medios de comunicación actual abogan también como medida de seguridad
por «la tienda oficial» con una solvente empresa detrás con recursos
para mantenerla limpia... <i>Cuidado con lo gratuito</i> que seguro que es
peligroso y lleva <i>malware</i>. Con ese nivel de información está claro
que para esos medios todo el <i>Software Libre</i> es sospechoso. Y la
gente sin conocimiento, sin ganas de investigar o que ha abandonado el
camino de la tecnología a generaciones futuras, lo cree. Cuando les
comentas que con el <i>Software Libre</i> puedes ver lo que hace, mientras
que con el <i>propietario</i> no, necesitan más información (y muchas veces
no hay tiempo en las charlas para dársela).
</p>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Colegio Oficial de Profesionales de la Psicología de Aragón. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Asociación de Madres y Padres de Alumnos 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/tecnología/index.html">tecnología</a> <a href="/tags/seguridad/index.html">seguridad</a> ]]></description>
  <category><![CDATA[tecnología]]></category>
  <category><![CDATA[seguridad]]></category>
  <link>https://notxor.nueva-actitud.org/2020/03/06/reflexiones-sobre-la-tecnología-y-la-edad.html</link>
  <pubDate>Fri, 06 Mar 2020 10:13:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Pri la oka leciono de la Kurso de Esperanto]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-02-29</div>
<p>
Hodiaŭ ni atingas la duaj trionaj partoj de nia kurso de Esperanto.
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#leciono-8">La oka leciono</a> estas ankaŭ facila por kompreni kaj agi. Mi pensas ke
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#ejercicios-8">la ekzercoj de la leciono</a> estos facilaj por la lernantoj.
</p>

<p>
Tiun pasintan mardon, mi estis en Frateco de Zaragozo kaj Lorenzo, ĝia
prezidanto, donis al mi libron de «El Kiĥoto». Mi jam havis tiun
libron, papere kaj <a href="http://bitoteko.esperanto.es/jspui/handle/11013/5093">elektronike</a> kaj mi pensis doni ĝin al miaj
lernantoj. Ne estas facila libro por komencantoj, sed ĝi estas grava
libro por komenci bibliotekon en Esperanto.
</p>


<figure id="orge2b1545">
<img src="./imagen/libro.jpeg" alt="libro.jpeg" width="100%">

<figcaption><span class="figure-number">Figure 1: </span>Jen la libro</figcaption>
</figure>
<div id="outline-container-org36869d8" class="outline-2">
<h2 id="org36869d8">Ludeto</h2>
<div class="outline-text-2" id="text-org36869d8">
<p>
Por gajni la libron miaj lernantoj devos fari etan ludon. Lorenzo, la
pasintan mardon proponis en Frateco etan ludon por ni. Ĉar li donis
libron mi pensas proponi tiun ludon al miaj lernantoj. Ĝi estas ne
formalaj difinoj pri vortoj, kiel en krucvortoj sed sen la lokoj por
skribi la vortoj. La gajnanto estos la unua lernanto kiu sendos la
liston de la vortoj al kutima retpoŝto. Kelkaj el difinoj povas havi
pli ol unu vorton, mi akceptos ĉiujn logicajn respondojn.
</p>


<figure id="org0d953be">
<img src="./imagen/image20200229_103211992.jpg" alt="image20200229_103211992.jpg" width="100%">

<figcaption><span class="figure-number">Figure 2: </span>Jen la ludo</figcaption>
</figure>

<p>
Ĉar en la foto oni ne povas bone legi la difinojn mi metas ĉi tie la
difinojn:
</p>
</div>
<div id="outline-container-orgc3620b7" class="outline-3">
<h3 id="orgc3620b7">Difinoj</h3>
<div class="outline-text-3" id="text-orgc3620b7">
<ol class="org-ol">
<li>Dupieda besto, kiu flugas en la aero.</li>
<li>La ĉielo ploras.</li>
<li>Bildo, kion oni vidas per la oreloj.</li>
<li>Malploras; la buŝo iras al la oreloj.</li>
<li>Montras la amon per la buŝo; tuŝas per la buŝo.</li>
<li>Senpieda kaj silenta besto en la akvo.</li>
<li>La araba gumo de la frazoj.</li>
<li>La natura vesto de la homo.</li>
<li>Tero staranta en la maro.</li>
<li>Povas fari, kion li volas; ne havas edzinon.</li>
<li>Tre malgranda nokta lampo sur la ĉielo.</li>
<li>Homo, kiu sanigas aŭ mortigas la aliajn homojn.</li>
<li>La ruĝa akvo en la korpo.</li>
<li>Homo, kiu vidas la mondon en bela koloro.</li>
<li>Homo, kiu vidas la mondon en nigra koloro.</li>
<li>Blanka dolĉa akvo, la infanoj kaj la kato ŝatas ĝin.</li>
<li>Verda besto, kiu manĝas, trinkas kaj dormas, sed ne iras kaj ne
parolas, havas nur unu piedon kaj ĝi estas en la tero.</li>
<li>La videbla parto de la homo.</li>
<li>La nokta, malvarma lampo de la naturo; la lampo de la geamantoj.</li>
<li>Malgranda domo kun kvar ĉambroj en la homo; la loko de la amo.</li>
<li>Kvalito de la forno kaj de la juna koro.</li>
<li>Papero kun frazoj en la koverto; spegulo de la koro.</li>
<li>La fenestroj sur la kapo.</li>
<li>Strato same longa kiel larĝa.</li>
<li>Granda skatolo, en kiu vivas homoj.</li>
<li>En la dormo vidas bildojn.</li>
<li>La ĉielo en la ĉambro.</li>
<li>Akvo venas el la okuloj.</li>
<li>Loko kun arboj, kie la homoj promenas.</li>
<li>Sangrivero en la korpo.</li>
<li>La granda kaj plej grava pordo sur la kapo.</li>
<li>La plafono de la mondo.</li>
<li>Fabriko de belaj bildoj en la kapo.</li>
<li>Vortoj inter granda litero kaj punkto.</li>
</ol>
</div>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/kurso/index.html">kurso</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[kurso]]></category>
  <link>https://notxor.nueva-actitud.org/2020/02/29/pri-la-oka-leciono-de-la-kurso-de-esperanto.html</link>
  <pubDate>Sat, 29 Feb 2020 19:06:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Pri la sepa leciono de la Kurso de Esperanto]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-02-22</div>
<p>
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#leciono-7">La sepa leciono</a> temas pri facilaj aferoj. Mi pensas ke
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#ejercicios-7">la ekzercoj de la leciono</a> estos tre bone faritaj de la lernantoj.
</p>

<p>
Mi pensis montri kelkan muzikon. Unue mi pensis pri originalaj kantoj
aŭ tradukita, sed kantata per la originala kantisto. Mi bezonis famajn
kantojn aŭ, almenaŭ, kvalitajn. Finfine, mi ne povis elekti inter la
tri lastaj selektitaj.
</p>

<ol class="org-ol">
<li><b>Titolo</b>: <a href="https://invidious.snopyta.org/watch?v=56H1_2vDH6A">Memoro de la Ŝtono</a> -- <b>ĝenro</b>: ĥora muziko; lud-muziko de
la ludo <i>«Final Fantasy XI»</i>. Kanto en Esperanto kaj la angla.</li>
<li><b>Titolo</b>: <a href="https://invidious.snopyta.org/watch?v=7TxRQQfZKQ4">Heredo de la Post Milit'</a> -- <b>Kantisto</b>: baRok' --
<b>ĝenro</b>: Metala Roko.</li>
<li><b>Titolo</b>: <a href="https://invidious.snopyta.org/watch?v=fOBkKcbJUAE">La pluvo</a> -- <b>Kantisto</b>: María Villalón -- <b>Ĝenro</b>:
pop-muziko.</li>
</ol>

<p>
Do mi fine metas la tri el ili kaj la lernantoj povos elekti pli bone
ol mi, laŭ siaj emoj.
</p>

<p>
La lernantoj povas konstati la uzo de la apostrofo ('), kie kaj tie en
la kantoj (ankaŭ en la poemoj). Tiun uzon oni permesas kiam estas
klara kiun literon (ordinare, la «o») ĝi anstataŭas en verkoj por
zorgi la ritmon de la versoj. Funkcias kiel ne prononcata vokalo.
</p>

<p>
Fine mi vola ankaŭ mencii poemon ĉi tie. Certe la hispanaj legantoj
scias kial mi elektis ĉi tiun poemon verkita de <i>Miguel Hernández</i>
(tradukita de Miguel Fernández), kaj mi pli ne diros:
</p>
<div id="outline-container-org7c2d844" class="outline-2">
<h2 id="org7c2d844">La vundito</h2>
<div class="outline-text-2" id="text-org7c2d844">
<p class="verse">
Por la liber’ mi sangas, batalas, vivas plue.<br>
Por la liber’ okuloj kaj manoj miaj bonas.<br>
Mi ilin, karnan arbon en ĉel’, sindonan, ĝue<br>
al la kirurgoj donas.<br>
<br>
Por la libero sentas mi pli da koroj bruste,<br>
ol da sablejoj: donas la vejnoj ŝaŭmo-striojn,<br>
mi iras hospitalen kaj en kotonon ĝuste<br>
sam-kiel en liliojn.<br>
<br>
Por la libero pafe seniĝas mi je uloj<br>
trempintaj ĝian bildon en koto plej obstine.<br>
Kaj mi seniĝas bate je miaj brakoj, kruroj<br>
kaj dom’, je ĉio fine.<br>
<br>
Ĉar, se aperos iam du kavoj sekaj, haste<br>
liveros ĝi du ŝtonojn vidontajn, alt-kvalitajn,<br>
kaj igos novajn brakojn kaj krurojn kreski draste<br>
sur karnoj dishakitaj.<br>
<br>
Burĝonos kun flugiloj el limfa flu’ konstanta<br>
relikvoj mia-korpaj, kiuj travunde drivas.<br>
Ĉar estas mi frukt-arbo hakita burĝonanta:<br>
ĉar mi ankoraŭ vivas.<br>
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/kurso/index.html">kurso</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[kurso]]></category>
  <link>https://notxor.nueva-actitud.org/2020/02/22/pri-la-sepa-leciono-de-la-kurso-de-esperanto.html</link>
  <pubDate>Sat, 22 Feb 2020 19:04:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Sesa leciono de la Kurso de Esperanto]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-02-15</div>
<div id="outline-container-org836b6cd" class="outline-2">
<h2 id="org836b6cd">Pliaj klarigoj</h2>
<div class="outline-text-2" id="text-org836b6cd">
<p>
Dum la pasintaj lecionoj mi metis tekston por pli klarigi la lecionon
<i>hispane</i> kaj <i>esperante</i>. De nun, mi nur pliklarigos, respondos kaj
korektos la ekzercadojn esperante. Se vi havos problemojn por kompreni
min, petu pliajn klarigojn aŭ per la hispana (se vi bezonas ĝin).
</p>

<p>
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#leciono-6">Ni atingis la sesan lecionon</a> de nia baza esperanta
kurso. <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#ejercicios-6">La ekzerkadojn pro tiu ĉi leciono</a> estos eldonitaj antaŭ la 22an sabaton
de februaro. Mi memorigas vin ke iuj el vi malfruas viajn ekzercadojn
kaj mi petas al vi ke vi hastu kaj faru la pasintajn ekzercojn tiel,
kiel eble frue por estu ĝustaj en ordo. Dum semajna tempo legi
lecionon kaj fari la ekzercojn nur estas du momentetoj.
</p>

<p>
La leciono de ĉi tiu semajno ne havas malfacilaĵon. Eble la plej
rimarkinda estas la finaĵo <i>-iĝi</i>, kiu faras ke la ago de la verbo
revenu sur la subjekto. Io preskaŭ la refleksivaj verboj de la hispana
lingvo. Multaj fojoj la traduko de esperanta verbo finiĝanta per
<i>-iĝi</i> kaj ĝia koresponda hispana estas <i>hacerse</i> aŭ <i>ponerse</i> ian.
Ekzemple:
</p>

<ul class="org-ul">
<li><i>Riĉiĝi</i>: «enriquecerse», <i>«hacerse rico»</i>.</li>
<li><i>Maljuniĝi</i>: «envejecer», <i>«hacerse viejo»</i>.</li>
<li><i>Koleriĝi</i>: «encolerizarse», <i>«ponerse colérico»</i>.</li>
<li><i>Sidiĝi</i>: «sentarse», <i>«ponerse sentado»</i>.</li>
</ul>

<p>
Kiel oni povas rimarki, ne ĉiuj la verboj finiĝantaj per <i>-iĝi</i>
finiĝas hispane per <i>-se</i>. Alivorte, ĝi farigas la verbon
<i>netransitivan</i> faranta ke la subjekto kaj la objekto de la ago estos
la sama; pro tio neniu verbo finiĝanta per <i>-iĝi</i> montros akuzativon.
Mi ne volas konfuzi vin per pliaj klarigoj pri la verboj transitivaj
kaj netransitivaj. Nur memorigu vin ke ne ĉiam koincidas ke ambaŭ la
verbo esperanta kaj ĝia traduko hispana estu <i>transitivaj</i> aŭ
<i>intransitivaj</i>.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/kurso/index.html">kurso</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[kurso]]></category>
  <link>https://notxor.nueva-actitud.org/2020/02/15/sesa-leciono-de-la-kurso-de-esperanto.html</link>
  <pubDate>Sat, 15 Feb 2020 19:02:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Utilización de registros en Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-02-11</div>
<p>
Cuando crees que más o menos tienes todo controlado sobre la
herramienta que utilizas, en mi caso <i>Emacs</i>, resulta que te
sorprendes con una funcionalidad nueva que ni habías sospechado.  Eso
me ha pasado con los <i>registros</i>.
</p>

<p>
El problema es no haberlos necesitado, también porque tampoco conocía
que lo que hacen se podía hacer. Con el tiempo, les he cogido el aire,
un poco, y ahora me pregunto cómo podía editar documentos sin ellos.
</p>
<div id="outline-container-org60b931a" class="outline-2">
<h2 id="org60b931a">Registros</h2>
<div class="outline-text-2" id="text-org60b931a">
<p>
¿Qué son los <i>registros</i>? Pues si miramos el manual de <i>Emacs</i> nos
explica que los <i>registros</i> son compartimentos donde se puede guardar
texto, rectángulos de texto, posiciones u otras cosas para utilizarlas
luego.
</p>

<p>
Hasta hace poco utilizaba el «anillo de borrado» para guardar texto
que luego copiaba (recuperaba) de allí. En un momento dado me encontré
que necesitaba guardar varios textos y recuperarlos según el caso en
otro sitio. Me apañé, de alguna manera, creando un <i>buffer</i> con los
textos (en concreto 8) y los iba <i>corto-pegando</i> donde correspondía.
Mientras realizaba estas operaciones pensaba si no existiría una forma
mejor de hacer eso mismo. La hay, pero en ese momento lo desconocía y
me apañé como pude. Después, al investigar, encontré los <i>registros</i>.
</p>
</div>
<div id="outline-container-org855461d" class="outline-3">
<h3 id="org855461d">Funcionamiento de los registros</h3>
<div class="outline-text-3" id="text-org855461d">
<p>
Un registro puede almacenar una posición del cursor en un <i>buffer</i>, un
trozo de texto ─sea en rectángulo o no─, la configuración de una
ventana, un número o un nombre de fichero ─pero sólo una cosa cada
vez─. Además cada <i>registro</i> tiene un nombre, normalmente un carácter
o un número o, incluso, algunos caracteres especiales como <code>*</code>. Hay
que tener en cuenta que el registro «a» es distinto al «A». Es decir,
tenemos tantos registros como caracteres alfanuméricos en nuestro
teclado.
</p>

<p>
Para ver el contenido de un registro, pongamos por ejemplo el «a»,
podemos hacer:
</p>

<p>
<code>M-x view-register &lt;RET&gt; a</code>
</p>

<p>
Por ejemplo, si hubiéramos guardado en él una posición en un <i>buffer</i>
nos mostraría un <code>*Output*</code> similar a:
</p>

<pre class="example" id="orgfa14088">
Register a contains a buffer position:
    buffer texto-largo.org, position 1061
</pre>
</div>
</div>
<div id="outline-container-orgb6a5fc2" class="outline-3">
<h3 id="orgb6a5fc2">Registros para guardar posiciones</h3>
<div class="outline-text-3" id="text-orgb6a5fc2">
<p>
El uso de los registros se realiza con la combinación de teclas <code>C-x
r</code> seguida de algunas teclas con más funcionalidad. Por ejemplo, para
guardar una posición se utiliza <code>&lt;SPC&gt;</code> y nos preguntará por un
nombre. Por tanto, la función <code>point-to-register</code> lo activa la
secuencia:
</p>

<p>
<code>C-x r &lt;SPC&gt; a</code>
</p>

<p>
guardará en el registro de nombre «a» la posición del cursor en un
<i>buffer</i>, cuando queramos saltar a dicha posición, <code>jump-to-register</code>,
podemos recuperar el registro con la secuencia:
</p>

<p>
<code>C-x r j a</code>
</p>
</div>
</div>
<div id="outline-container-org3c22eeb" class="outline-3">
<h3 id="org3c22eeb">Guardar textos en registros</h3>
<div class="outline-text-3" id="text-org3c22eeb">
<p>
Este fue el <i>caso de uso</i> que necesité y que no supe llevar a cabo.
Como digo lo solventé con un <i>buffer</i> desde el que copiar los textos a
través del clásico «anillo de borrado».  Podía haber ahorrado algo de
trabajo, metiendo los textos en <i>registros</i> e ir recuperándolo según
lo necesitara.
</p>

<p>
Podemos guardar texto en un registro, pongamos el «R», seleccionando
el texto deseado y utilizar el comando <code>copy-to-register</code> o la
combinación de teclas asignada <code>C-x r s R</code> e insertarlo donde sea
necesario con el comando <code>insert-register</code> o la combinación de teclas
<code>C-x r i R</code>.
</p>

<p>
Si volvemos a utilizar un nombre de registro sobrescribiremos el
contenido, sin embargo, podemos modificarlo sin borrarlo utilizando
los comandos <code>append-to-register</code> o <code>prepend-to-register</code> con el texto
seleccionado previamente.
</p>
</div>
</div>
<div id="outline-container-org16f2def" class="outline-3">
<h3 id="org16f2def">Guardar rectángulos en registros</h3>
<div class="outline-text-3" id="text-org16f2def">
<p>
Copiar texto mediante rectángulos es una función que se usa mucho
menos. Pero cuando el texto está «tabulado» es una manera rápida de
seleccionar el contenido sin afectar al entorno. En este caso los
comandos son <code>copy-rectangle-to-register</code> o <code>C-x r r R</code>, para guardar
el contenido y <code>insert-register</code> o <code>C-x r i R</code>, justo el mismo
comando, para insertar el contenido desde el <i>registro</i>.
</p>
</div>
</div>
<div id="outline-container-org92c98dd" class="outline-3">
<h3 id="org92c98dd">Guardar configuraciones de ventanas</h3>
<div class="outline-text-3" id="text-org92c98dd">
<p>
La verdad es que esta opción la utilizo poco o nada aunque también
puede ser útil, por ejemplo, para los casos de que se quiera centrar
la atención en un determinado <i>buffer</i> cuando tenemos varios abiertos
pero sabemos que luego querremos recuperar la configuración de
ventanas que teníamos previamente.
</p>

<p>
Para restaurar la ventana utilizaremos el comando que ya hemos visto
para restaurar la posición dentro de un <i>buffer</i>: <code>C-x r j R</code>. Pero
para guardar dicha configuración tenemos dos opciones:
</p>

<p>
<code>C-x r w R</code> guardará en el registro «R» la configuración de las
ventanas en el marco que mantiene el foco. El comando sería
<code>window-configuration-to-register</code>.
</p>

<p>
<code>C-x r f R</code> guardará en el registro «R» la configuración de todos los
marcos abiertos y sus correspondientes ventanas y <i>buffers</i>.
</p>
</div>
</div>
<div id="outline-container-org488ded2" class="outline-3">
<h3 id="org488ded2">Guardar números</h3>
<div class="outline-text-3" id="text-org488ded2">
<p>
Como excepción, para guardar números (naturales) debemos utilizar un
prefijo, el habitual <code>C-u NUM</code>. Además, proporciona mecanismos para
incrementar esos números y, por tanto, se pueden utilizar los
registros como «contadores», por ejemplo.
</p>

<p>
<code>C-u NUM C-x r n R</code>, almacena en el registro «R» el número «NUM».
</p>

<p>
<code>C-u NUM C-x r + R</code>, si el registro «R» contiene un número
incrementará el contenido de dicho registro en «NUM».
</p>

<p>
Para recuperar el número que contiene el registro «R» utilizaremos el ya
conocido <code>C-u r i R</code>.
</p>

<p>
Hay que hacer notar que si utilizamos el comando <code>C-x r + R</code>,
<code>increment-register</code>, sin proporcionar un número, el incremento será
<code>+1</code>.
</p>
</div>
</div>
<div id="outline-container-org1dc5075" class="outline-3">
<h3 id="org1dc5075">Guardar nombres de fichero</h3>
<div class="outline-text-3" id="text-org1dc5075">
<p>
Una de las cosas que más utilizo con los registros es su capacidad
para guardar el nombre de un fichero y visitarlo mediante el habitual
comando de <i>saltar</i>: <code>C-x r j a</code>... y me abre un fichero que mantengo
para anotar diversos aspectos sobre mi trabajo diario, anotaciones,
trozos de código, etc.
</p>

<p>
En mi fichero <code>init.el</code> he añadido la siguiente línea. 
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(set-register ?a '(file . <span style="color: #f1fa8c;">"~/agenda/bloc-notas.org"</span>))
</pre>
</div>

<p>
Ese trozo de código guarda en el registro «a» el nombre de mi fichero
de notas. Cuando necesito anotar algo, o consultar alguna anotación
simplemente recupero <i>salto</i> al contenido del registro «a» y
<i>automágicamente</i> me abre mi fichero de notas.
</p>
</div>
</div>
</div>
<div id="outline-container-org1531b85" class="outline-2">
<h2 id="org1531b85">Conclusiones</h2>
<div class="outline-text-2" id="text-org1531b85">
<p>
También hay cómo asignar a un registro un «macro de teclado», pero
nunca lo he utilizado. Lo dejo para futuras entradas si fuera
necesario. Supongo que utilizarlo será muy similar al resto de casos
de uso de los registros.
</p>

<p>
Sólo puedo recomendar su uso. Si de momento no ves su utilidad no
importa, haz pruebas: seguro que mientras las haces se te ocurren
varios usos para los registros. Y al final, estoy casi seguro, que se
convertirá en una herramienta tan <i>imprescindible</i> como se me ha hecho
a mí.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2020/02/11/utilizacion-de-registros-en-emacs.html</link>
  <pubDate>Tue, 11 Feb 2020 00:20:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Kvina leciono de la Kurso de Esperanto]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-02-08</div>
<div id="outline-container-orgf5cd09a" class="outline-2">
<h2 id="orgf5cd09a">Hispana</h2>
<div class="outline-text-2" id="text-orgf5cd09a">
<p>
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#leciono-5">Hemos alcanzado la quinta lección</a> de nuestro curso de introducción al
<i>Esperanto</i>. <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#ejercicios-5">Los ejercicios de esta lección</a> se entregarán antes del
sábado 15 de febrero. En el tema de hoy se explica la lógica de los
correlativos mediante una tabla de doble entrada. Por esto, en
<i>Esperanto</i> suelen recibir el nombre de <i>tabelvortoj</i>.  <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#apendice-correlativos">La tabla la
tenéis en los apéndices</a> pero quiero recalcar un poco más la lógica.
</p>

<p>
Los correlativos tienen cinco <i>formas</i>: para preguntar, para señalar,
para negar, etc.
</p>

<ul class="org-ul">
<li><i>ki-</i>: <b>Pregunta</b>. Todo correlativo que comience por <i>ki-</i> significa
que se está preguntando sobre algo.</li>
<li><i>ti-</i>: <b>Indicación</b>. Todo correlativo que comience por <i>ti-</i> nos
está indicando algo. Suele ser la respuesta del interrogativo
anterior.</li>
<li><i>i-</i>: <b>Indefinido</b>. Todo correlativo que comience por <i>i-</i> indica
algo de manera indeterminada.</li>
<li><i>ĉi-</i>: <b>Universal</b>. Todo correlativo que comience por <i>ĉi-</i> indica
que afecta a todo el conjunto significado.</li>
<li><i>neni-</i>: <b>Negativo</b>. Todo correlativo que comience por <i>neni-</i>
indica una negación.</li>
</ul>

<p>
Estos <i>prefijos</i> se mezclan con los siguientes sufijos que les dan significado:
</p>

<ul class="org-ul">
<li><i>-o</i>: <b>cosa</b>. Estamos hablando de un objeto o cosa.</li>
<li><i>-u</i>: <b>individuo</b>. Estamos hablando de una persona o de una cosa concreta.</li>
<li><i>-e</i>: <b>lugar</b>. Estamos hablando de un sitio o lugar.</li>
<li><i>-a</i>: <b>cualidad</b>. Estamos hablando de alguna característica.</li>
<li><i>-el</i>: <b>manera</b>. Estamos hablando del modo o manera de algo.</li>
<li><i>-al</i>: <b>razón</b>. Estamos hablando de la razón o el motivo de algo.</li>
<li><i>-am</i>: <b>tiempo</b>. Estamos hablando de un momento en el tiempo.</li>
<li><i>-om</i>: <b>cantidad</b>. Estamos hablando sobre cantidades.</li>
<li><i>-es</i>: <b>posesión</b>. Estamos hablando sobre la posesión de algo.</li>
</ul>

<p>
Y así se forma la siguiente tabla con todos los correlativos:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">&#xa0;</th>
<th scope="col" class="org-left"><b>ki-</b></th>
<th scope="col" class="org-left"><b>ti-</b></th>
<th scope="col" class="org-left"><b>i-</b></th>
<th scope="col" class="org-left"><b>ĉi-</b></th>
<th scope="col" class="org-left"><b>neni-</b></th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><b>-o</b></td>
<td class="org-left">kio</td>
<td class="org-left">tio</td>
<td class="org-left">io</td>
<td class="org-left">ĉio</td>
<td class="org-left">nenio</td>
</tr>

<tr>
<td class="org-left"><b>-u</b></td>
<td class="org-left">kiu</td>
<td class="org-left">tiu</td>
<td class="org-left">iu</td>
<td class="org-left">ĉiu</td>
<td class="org-left">neniu</td>
</tr>

<tr>
<td class="org-left"><b>-e</b></td>
<td class="org-left">kie</td>
<td class="org-left">tie</td>
<td class="org-left">ie</td>
<td class="org-left">ĉie</td>
<td class="org-left">nenie</td>
</tr>

<tr>
<td class="org-left"><b>-a</b></td>
<td class="org-left">kia</td>
<td class="org-left">tia</td>
<td class="org-left">ia</td>
<td class="org-left">ĉia</td>
<td class="org-left">nenia</td>
</tr>

<tr>
<td class="org-left"><b>-el</b></td>
<td class="org-left">kiel</td>
<td class="org-left">tiel</td>
<td class="org-left">iel</td>
<td class="org-left">ĉiel</td>
<td class="org-left">neniel</td>
</tr>

<tr>
<td class="org-left"><b>-al</b></td>
<td class="org-left">kial</td>
<td class="org-left">tial</td>
<td class="org-left">ial</td>
<td class="org-left">ĉial</td>
<td class="org-left">nenial</td>
</tr>

<tr>
<td class="org-left"><b>-am</b></td>
<td class="org-left">kiam</td>
<td class="org-left">tiam</td>
<td class="org-left">iam</td>
<td class="org-left">ĉiam</td>
<td class="org-left">neniam</td>
</tr>

<tr>
<td class="org-left"><b>-om</b></td>
<td class="org-left">kiom</td>
<td class="org-left">tiom</td>
<td class="org-left">iom</td>
<td class="org-left">ĉiom</td>
<td class="org-left">neniom</td>
</tr>

<tr>
<td class="org-left"><b>-es</b></td>
<td class="org-left">kies</td>
<td class="org-left">ties</td>
<td class="org-left">ies</td>
<td class="org-left">ĉies</td>
<td class="org-left">nenies</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>
</tbody>
</table>

<p>
Algunos de esos correlativos tienen su correspondiente en español,
pero otros se traducen mediante una frase completa. Y también hay
algunos que pueden ser traducidos según el contexto en varias maneras,
como por ejemplo <i>ĉiu</i>, que puede ser traducido como <i>todos</i> (<i>ĉiuj
miaj lenrantoj</i> -- todos mis alumnos) o puede ser traducido como
<i>cada</i> (<i>ĉiu masto altenu ties velon</i> -- cada palo que aguante su
vela).
</p>
</div>
</div>
<div id="outline-container-org0ede073" class="outline-2">
<h2 id="org0ede073">Esperanto</h2>
<div class="outline-text-2" id="text-org0ede073">
<p>
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#leciono-5">Ni atingis la kvinan lecionon</a> de nia baza esperanta kurso. <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#ejercicios-5">La
ekzerkadojn pro tiu ĉi leciono</a> estos eldonitaj antaŭ la 15a sabaton de
frebuaro.  La hodiaŭa leciono temas pri la logikon de la korelativoj
per tablo de du variebloj. Tial, kutime, en <i>Esperanto</i> oni nomas la
korelativoj, <i>tabelvortoj</i>. <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#apendice-correlativos">La tablo estas en la apendicoj</a> sed mi
volas enfazi la logikon.
</p>

<p>
La tabelvortoj havas kvin <i>esprimojn</i>: por demandi, por signali, por
nei, ktp.
</p>

<ul class="org-ul">
<li><i>ki-</i>: <b>Demando</b>. Ĉiu tabelvorto kiu komencas per <i>ki-</i> signifas demandon.</li>
<li><i>ti-</i>: <b>Montrado</b>. Ĉiu tabelvorto kiu komencas per <i>ti-</i> signifas
montrado. Kutime estas la respondon por la antaŭa demando.</li>
<li><i>i-</i>: <b>nedefinita</b>. Ĉiu tabelvorto kiu komencas per <i>i-</i> signifas
nekonkreta aĵo.</li>
<li><i>ĉi-</i>: <b>Universala</b>. Ĉiu tabelvorto kiu komencas per <i>ĉi-</i> signifas
pri la tutan aron.</li>
<li><i>neni-</i>: <b>Nea</b>. Ĉiu tabelvorto kiu komencas per <i>neni-</i> signifas neado.</li>
</ul>

<p>
Ĉi tiuj <i>prefiksoj</i> miksiĝas kun la sekvantaj sufiksoj por signifi:
</p>

<ul class="org-ul">
<li><i>-o</i>: <b>aĵo</b>.</li>
<li><i>-u</i>: <b>ulo</b>. Ankaŭ konkreta afero</li>
<li><i>-e</i>: <b>loko</b>.</li>
<li><i>-a</i>: <b>kvalito</b>.</li>
<li><i>-el</i>: <b>maniero</b>.</li>
<li><i>-al</i>: <b>kialo</b>.</li>
<li><i>-am</i>: <b>tempo</b>.</li>
<li><i>-om</i>: <b>kvanto</b>.</li>
<li><i>-es</i>: <b>posedo</b>.</li>
</ul>

<p>
Tiel la sekvanta tabelo montras ĉiujn tabelvortojn:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">&#xa0;</th>
<th scope="col" class="org-left"><b>ki-</b></th>
<th scope="col" class="org-left"><b>ti-</b></th>
<th scope="col" class="org-left"><b>i-</b></th>
<th scope="col" class="org-left"><b>ĉi-</b></th>
<th scope="col" class="org-left"><b>neni-</b></th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><b>-o</b></td>
<td class="org-left">kio</td>
<td class="org-left">tio</td>
<td class="org-left">io</td>
<td class="org-left">ĉio</td>
<td class="org-left">nenio</td>
</tr>

<tr>
<td class="org-left"><b>-u</b></td>
<td class="org-left">kiu</td>
<td class="org-left">tiu</td>
<td class="org-left">iu</td>
<td class="org-left">ĉiu</td>
<td class="org-left">neniu</td>
</tr>

<tr>
<td class="org-left"><b>-e</b></td>
<td class="org-left">kie</td>
<td class="org-left">tie</td>
<td class="org-left">ie</td>
<td class="org-left">ĉie</td>
<td class="org-left">nenie</td>
</tr>

<tr>
<td class="org-left"><b>-a</b></td>
<td class="org-left">kia</td>
<td class="org-left">tia</td>
<td class="org-left">ia</td>
<td class="org-left">ĉia</td>
<td class="org-left">nenia</td>
</tr>

<tr>
<td class="org-left"><b>-el</b></td>
<td class="org-left">kiel</td>
<td class="org-left">tiel</td>
<td class="org-left">iel</td>
<td class="org-left">ĉiel</td>
<td class="org-left">neniel</td>
</tr>

<tr>
<td class="org-left"><b>-al</b></td>
<td class="org-left">kial</td>
<td class="org-left">tial</td>
<td class="org-left">ial</td>
<td class="org-left">ĉial</td>
<td class="org-left">nenial</td>
</tr>

<tr>
<td class="org-left"><b>-am</b></td>
<td class="org-left">kiam</td>
<td class="org-left">tiam</td>
<td class="org-left">iam</td>
<td class="org-left">ĉiam</td>
<td class="org-left">neniam</td>
</tr>

<tr>
<td class="org-left"><b>-om</b></td>
<td class="org-left">kiom</td>
<td class="org-left">tiom</td>
<td class="org-left">iom</td>
<td class="org-left">ĉiom</td>
<td class="org-left">neniom</td>
</tr>

<tr>
<td class="org-left"><b>-es</b></td>
<td class="org-left">kies</td>
<td class="org-left">ties</td>
<td class="org-left">ies</td>
<td class="org-left">ĉies</td>
<td class="org-left">nenies</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>
</tbody>
</table>

<p>
Iuj tabelvortoj havas konvenan hispanan vorton, sed aliaj bezonas
frazon por traduko. Kaj ankaŭ estas tiuj, kiuj estas tradukotaj laŭ la
konteksto, ekzemple <i>ĉiu</i>, podas traduki per <i>todos</i> (ĉiuj miaj
lenrantoj -- <i>todos mis alumnos</i>) aŭ per <i>cada</i> (ĉiu masto altenu ties
velon -- <i>cada palo que aguante su vela</i>).
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/kurso/index.html">kurso</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[kurso]]></category>
  <link>https://notxor.nueva-actitud.org/2020/02/08/kvina-leciono-de-la-kurso-de-esperanto.html</link>
  <pubDate>Sat, 08 Feb 2020 19:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Cambios en el blog]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-02-08</div>
<p>
Si acabas de entrar en el <i>blog</i> es posible que te haya sorprendido el
cambio de colores en el mismo. Todas estas cosas van por rachas:
estaba ya cansado de los colores claros. He hecho un cambio a colores
oscuros, con algún efecto en los títulos. Todo ello gracias a CSS,
apenas he cambiado un par de líneas en el fichero <code>main.css</code> y el
<i>blog</i> parece completamente distinto.
</p>

<p>
Todo lo demás sigue igual y no descarto volver a un tema más
claro. Soy consciente que los temas oscuros con letras claras se leen
peor que los temas claros con letras oscuras. Sin embargo, el conjunto
de colores anterior se me hacía ya un poco pesado.
</p>

<p>
El único efecto añadido ha sido en los títulos. Pretendía conseguir un
efecto de grabado:
</p>

<div class="org-src-container">
<pre class="src src-css"><span style="color: #50fa7b; font-weight: bold;">h1, h2, h3</span> {
    <span style="color: #ff79c6; font-weight: bold;">position</span>: relative;
    <span style="color: #ff79c6; font-weight: bold;">margin</span>: 30px 0 10px;
    <span style="color: #ff79c6; font-weight: bold;">color</span>: <span style="color: #ffffff; background-color: #202020;">#202020</span>;
    <span style="color: #ff79c6; font-weight: bold;">font-weight</span>: bold;
    <span style="color: #ff79c6; font-weight: bold;">font-family</span>: <span style="color: #f1fa8c;">'Veteran Typewriter'</span>, Helvetica, <span style="color: #f1fa8c;">'sans serif'</span>;
    <span style="color: #ff79c6; font-weight: bold;">text-shadow</span>:
        -1px -1px 1px <span style="color: #ffffff; background-color: #111;">#111</span>,
        2px 2px 1px <span style="color: #ffffff; background-color: #363636;">#363636</span>;
}
</pre>
</div>

<p>
Apenas un par de sombras con desplazamiento, como se puede ver en el
código anterior. La idea era aprovechar la tipografía habitual,
presente ya en el diseño anterior, la <code>Veteran Typewriter</code>, similar a
una máquina de escribir, para simular que «el papel» quedaba grabado
con las pulsaciones de las teclas.
</p>

<p>
Tengo un sentimiento ambivalente con ese efecto: a ratos me parece un
efecto chulo y a ratos no me gusta. Así que tampoco sé si durará mucho
en la página.
</p>
<div id="outline-container-org485f8c1" class="outline-2">
<h2 id="org485f8c1">Conclusión</h2>
<div class="outline-text-2" id="text-org485f8c1">
<p>
Hacía tiempo que no tocaba nada sobre el aspecto del <i>blog</i>. Los
cambios realizados a veces me resultan agradables y otras
desagradables. El <i>blog</i> mantiene su sencillez, sigue siendo <code>html5</code> y
<code>css</code> con muy poco <code>javascript</code>, sin embargo, la combinación de
colores es algo que da mucho juego con poco esfuerzo y de eso he
tratado de aprovecharme en estos cambios.
</p>

<p>
Espero que os guste, y si no es así: hacédmelo saber, que <i>para
gustos, los colores</i>.
</p>

<p>
De momento, y siguiendo los consejos de <i>Spectrumgomas</i> he cambiado el
color de fondo de las cabeceras <code>h1</code>, <code>h2</code> y <code>h3</code> para facilitar su
lectura. El efecto de grabado no se aprecia tan bien, pero gana en
legibilidad, que es de lo que se trata.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/blog/index.html">blog</a> <a href="/tags/css/index.html">css</a> ]]></description>
  <category><![CDATA[blog]]></category>
  <category><![CDATA[css]]></category>
  <link>https://notxor.nueva-actitud.org/2020/02/08/cambios-en-el-blog.html</link>
  <pubDate>Sat, 08 Feb 2020 15:56:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Kvara leciono de la Kurso de Esperanto]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-02-01</div>
<div id="outline-container-org68f3d49" class="outline-2">
<h2 id="org68f3d49">Hispana</h2>
<div class="outline-text-2" id="text-org68f3d49">
<p>
Hoy es el día en el que <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#leciono-4">vamos a ver la cuarta lección</a> de nuestro curso
y el tema principal del mismo son los números. Como veréis, la
formación de números también es completamente regular desde el primer
número de dos cifras: once (no «dieciuno») en <i>Esperanto</i> es «dek
unu».
</p>

<p>
Tenéis hasta el día 8 de febrero, el sábado que vienen, para
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#ejercicios-4">entregar los ejercicios</a> de la lección.
</p>

<p>
<a href="https://tubaro.aperu.net/v/ytb_gh9w7QpyQtY/">Os dejo un enlace a uno de los vídeos emblemáticos de los últimos
tiempos del <i>Esperanto</i></a>. Es una canción infantil escrita por el
español Pablo Busto y animada por <i>Babelo filmoj</i>. Escuchadla un par
de veces con los subtítulos en <i>Esperanto</i> para fijaros muy bien en la
pronunciación. Si la escucháis un par de veces luego os estará
taladrando el cerebro toda la tarde, pero es una forma simpática de
aprenderse los números. Cuatro (<i>kvar</i>) y cinco (<i>kvin</i>) tienen una
pronunciación difícil para hablantes de español. Es acostumbrarse a
ello.
</p>

<p>
Otra dificultad es el tema de la partícula <i>si</i> que se utiliza en
frases en tercera persona para referirse al sujeto de la acción. Es un
pronombre reflexivo, pero repito: <i>sólo para la tercera persona</i>. Sin
embargo, la forma acusativa <i>sin</i> se emplea con frecuencia como
prefijo para formar palabras con el significado de «mem»: «sí mismo».
</p>

<p>
Y la última dificultad es, de nuevo, el <i>acusativo</i>. En este caso, el
acusativo de dirección. Con un verbo de movimiento, muestra hacia
dónde se mueve el sujeto.
</p>
</div>
</div>
<div id="outline-container-org20d8d70" class="outline-2">
<h2 id="org20d8d70">Esperanto</h2>
<div class="outline-text-2" id="text-org20d8d70">
<p>
Hodiaŭ estas la tago por <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#leciono-4">vidi la kvaran lecionon</a> de nia kurso kaj la
precipa temo en ĝi estas la numeroj. Kiel vi vidos, la formado de la
numeroj estas tute regula de la unua numero de du ciferoj: «dek unu»
en <i>Esperanto</i> sed en la hispana «once» (ne «dieciuno»).
</p>

<p>
Vi havas ĝis la oka tago je februaro, la sekvanta sabato, por
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#ejercicios-4">aldoni la edzerkadojn</a> de la leciono.
</p>

<p>
<a href="https://tubaro.aperu.net/v/ytb_gh9w7QpyQtY/">Mi eldonas al vi unu el la plej emblema videoj en la lastaj tempoj de
<i>Esperanto</i></a>. Estas infana kanto verkita de la hispana Pablo Busto kaj
animigita de <i>Babelo filmoj</i>. Aŭskultu ĝis dufoje kun la subtitoloj
Esperante por preni atenton en la prononcado. Se vi aŭskultos ĝin du
fojoj poste ĝi daŭros bori la cerbon la tuta vespero, sed estas
simpatia maniero por memorigi la numerojn. <i>Kvar</i> kaj <i>kvin</i> havas
malfacilan prononcadon por la hispanaj parolantoj. Nur oni devas
kutimigi al ĝi.
</p>

<p>
Alia malfacilaĵo estas la temo pri la vorto <i>si</i>, kiu estas uzata por
frazoj en tria persono por resendi la agado je la subjekto. Estas
resenda pronomo, sed mi insistas: <i>nur por la tria persono</i>. Sed, en
akuzativa formo <i>sin</i> estas uzata kutime kiel prefikso por farigi
vortojn samsignifa kun «mem».
</p>

<p>
Kaj la lasta malfacilaĵo estas, denove, la <i>akuzativo</i>. En tiu okazo,
la direkta akuzativo. Kun mova verbo, indikas la direkton kie la
subjekto movas.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/kurso/index.html">kurso</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[kurso]]></category>
  <link>https://notxor.nueva-actitud.org/2020/02/01/kvara-leciono-de-la-kurso-de-esperanto.html</link>
  <pubDate>Sat, 01 Feb 2020 18:58:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Leciono 3 de la kurso de Esperanto]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-01-25</div>
<div id="outline-container-orge3b8bb8" class="outline-2">
<h2 id="orge3b8bb8">Hispana</h2>
<div class="outline-text-2" id="text-orge3b8bb8">
<p>
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#leccion-3">Lección 3 del curso de Esperanto</a>.
</p>

<p>
El plazo para entregar los ejercicios de esta lección acabará el 1 de
febrero. <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#ejercicios-3">Enlace a los ejercicios de la lección 3</a>.
</p>
</div>
<div id="outline-container-org5e466ee" class="outline-3">
<h3 id="org5e466ee">El teclado</h3>
<div class="outline-text-3" id="text-org5e466ee">
<p>
Hay quien me ha manifestado la dificultad para escribir los caracteres
especiales del Esperanto con su teclado. La mayoría de los alumnos
utilizáis GNU/Linux y no tenéis problemas con los caracteres «^» sin
embargo, os cuesta encontrar el «˘». En mi teclado está en
«Mayúsculas+AltGr+}». Haced pruebas o mirar la distribución de vuestro
teclado.
</p>

<p>
Sin embargo, ya Zamenhoff previó los problemas con las letras «con
sombrero» y propuso un método para escribir Esperanto sin la
tipografía adecuada.
</p>

<p>
Zamenhoff propuso utilizar dígrafos con la letra «h», para todos los
casos excepto para la «ŭ» que quedaba solamente como «u»:
</p>

<ul class="org-ul">
<li>ch -&gt; ĉ</li>
<li>gh -&gt; ĝ</li>
<li>hh -&gt; ĥ</li>
<li>jh -&gt; ĵ</li>
<li>sh -&gt; ŝ</li>
</ul>

<p>
La ventaja de este método es que proviene del <i>fundamento</i> de
Esperanto. Sin embargo, presenta otros inconvenientes que ha hecho que
la comunidad esperantista lo modificara: se dejaba un carácter
especial sin marca y además se está utilizando la «h», una letra
reconocida en Esperanto y es posible que se produzcan problemas por
ello.
</p>

<p>
La comunidad esperantista desde hace mucho tiempo, especialmente con
el uso de los ordenadores han extendido los dígrafos con «x». En
Esperanto no se utiliza la «x», no hay probabilidad de equivocarse y
además se utiliza para todos los caracteres especiales:
</p>

<ul class="org-ul">
<li>cx -&gt; ĉ</li>
<li>gx -&gt; ĝ</li>
<li>hx -&gt; ĥ</li>
<li>jx -&gt; ĵ</li>
<li>sx -&gt; ŝ</li>
<li>ux -&gt; ŭ</li>
</ul>

<p>
Muchas de las herramientas para Esperanto, como <a href="http://vortaro.net/">http://vortaro.net/</a> o
<a href="http://www.reta-vortaro.de/revo/">http://www.reta-vortaro.de/revo/</a> nos permiten utilizar los dígrafos y
automáticamente sustituyen esos caracteres.
</p>

<p>
<a href="http://esperanto.keyboard.su/">También hay teclados virtuales <i>online</i> que pueden ayudar</a>.
</p>

<p>
Pero recordad, que si no tenemos otro recurso al alcance, el utilizar
la opción de dígrafos con la «x» es la más completa y más generalizada
en la comunidad esperantista.
</p>
</div>
</div>
<div id="outline-container-org46cb473" class="outline-3">
<h3 id="org46cb473">Dificultades de la lección</h3>
<div class="outline-text-3" id="text-org46cb473">
<p>
Esta tercera lección es bastante sencilla y no hay demasiadas
dificultades para la comprensión del contenido teórico. Sólo recordad
que el Esperanto tiene bastantes más preposiciones que el español y
que por tanto, son más precisas. El hablante de español utilizará la
preposición «por» mientras que en Esperanto utilizaremos, según el
significado «per», «pro» o incluso «por».
</p>
</div>
</div>
</div>
<div id="outline-container-org63c0860" class="outline-2">
<h2 id="org63c0860">Esperanto</h2>
<div class="outline-text-2" id="text-org63c0860">
<p>
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#leccion-3">Leciono 3 de la kurso de Esperanto</a>.
</p>

<p>
La limtempo por aldoni la edzerkadoj de ĉi tiu leciono finiĝos la una
de februaro. <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#ejercicios-3">Ligilo al edzerkadoj de la leciono 3</a>.
</p>
</div>
<div id="outline-container-org7af0880" class="outline-3">
<h3 id="org7af0880">La klavaro</h3>
<div class="outline-text-3" id="text-org7af0880">
<p>
Iuj parolis al mi pri la malfacileco por skribi la ĉapelitaj literoj
de la Esperanto per sia klavaro. La plimulto de la lernantoj uzas
GNU/Linux kaj ne havas problemojn por la literoj «^», sed kelkaj el vi
ne trovis la «˘». En mia klavaro estas ĉe «Mayúsculas+AltGr+}». Provu
aŭ rigardu vian dispozicion de klavaro.
</p>

<p>
Sed jam Zamenhoff antaŭvidis la problemoj por la «ĉapelitarj» literoj
kaj proponis metodon por skribi Esperanton sen la taŭgan tipografion.
</p>

<p>
Zamenhoff proponis uzi dulitraĵoj per la litero «h», por ĉiuj la
literoj krom por la «ŭ» kiu restis nur kiel «u»:
</p>

<ul class="org-ul">
<li>ch -&gt; ĉ</li>
<li>gh -&gt; ĝ</li>
<li>hh -&gt; ĥ</li>
<li>jh -&gt; ĵ</li>
<li>sh -&gt; ŝ</li>
</ul>

<p>
La avantaĝo de ĉi tiu metodo estas ke ĝi elvenas de la esperanta
fundamento. Sed ĝi havas kelkajn malfacilaĵojn tiujn, kiuj devigis al
esperanta komunumo modifi ĝin: restis unu litero sen ĉapelo kaj ankaŭ
oni uzis literon «h», litero kiu estis uzata en Esperanto kaj eble oni
trovos problemoj.
</p>

<p>
La esperanta komunumo de multe antaŭe, precipe per la uzado de
komputiloj disvastigis la duliteraĵoj per «x». En Esperanto oni ne
uzas la literon «x», ne eblas erarojn kaj krome oni uzas ĝin por ĉiuj
la specialaj literoj:
</p>

<ul class="org-ul">
<li>cx -&gt; ĉ</li>
<li>gx -&gt; ĝ</li>
<li>hx -&gt; ĥ</li>
<li>jx -&gt; ĵ</li>
<li>sx -&gt; ŝ</li>
<li>ux -&gt; ŭ</li>
</ul>

<p>
La plimulto de la iloj por Esperanto, kiel <a href="http://vortaro.net/">http://vortaro.net/</a> aŭ
<a href="http://www.reta-vortaro.de/revo/">http://www.reta-vortaro.de/revo/</a> permesas nin uzi la duliteraĵoj kaj
automate anstataŭas ilin.
</p>

<p>
<a href="http://esperanto.keyboard.su/">Ankaŭ estas virtualaj klavaroj <i>rete</i>, kiuj povas helpi nin</a>.
</p>

<p>
Memoru ke se ni ne havas ilon, la uzo de la duliteraĵoj per la «x»
estas pli taŭga kaj disvastigita en la esperanta komunumo.
</p>
</div>
</div>
<div id="outline-container-orgbb0e7a2" class="outline-3">
<h3 id="orgbb0e7a2">Malfacilaĵoj de la leciono</h3>
<div class="outline-text-3" id="text-orgbb0e7a2">
<p>
Ĉi tiu tria leciono estas sufiĉe simpla kaj ne havas troajn
malfacilaĵojn por la kompreno de la teoria enhavo. Nur memoru ke la
Esperanto havas pli prepoziciojn ol la hispana kaj pro tiel ili estas
pli precizaj. La hispana parolanto uzos la prepozicion «por» dum
esperante ni uzos, laŭ ilia signifo: «per», «pro» aŭ eĉ «por».
</p>
</div>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/kurso/index.html">kurso</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[kurso]]></category>
  <link>https://notxor.nueva-actitud.org/2020/01/25/leciono-3-de-la-kurso-de-esperanto.html</link>
  <pubDate>Sat, 25 Jan 2020 00:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Leciono 2 de la kurso de Esperanto]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-01-18</div>
<div id="outline-container-orge353287" class="outline-2">
<h2 id="orge353287">Hispana</h2>
<div class="outline-text-2" id="text-orge353287">
<p>
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#leccion-2">Lección 2 del curso de Esperanto</a>.
</p>

<p>
Recordad que tenéis hasta el sábado 25 para entregar <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#ejercicios-2">los ejercicios de
la lección</a>.
</p>
</div>
<div id="outline-container-orgfdb141c" class="outline-3">
<h3 id="orgfdb141c">Aspectos a remarcar</h3>
<div class="outline-text-3" id="text-orgfdb141c">
<ol class="org-ol">
<li>En esta lección se incluye una de las principales dificultades para
los esperantistas de habla hispana. Bueno, en realidad de aquellos
que no hablan una lengua que se decline: el <b>Acusativo</b>. El tema lo
dice demasiado rápido y es uno de los temas que más dudas
suscitarán en adelante.</li>

<li>Después de esta lección ya sabréis conjugar todos los verbos en
Esperanto. Nos queda por ver el <i>volitivo-imperativo</i>, el
<i>condicional</i> y los participios. No hay subjuntivo, ni
pluscuamperfecto ni otros tiempos. Sólo recordad que el único verbo
auxiliar es <i>esti</i>.</li>
</ol>
</div>
</div>
<div id="outline-container-orga219285" class="outline-3">
<h3 id="orga219285">Videoconferencias</h3>
<div class="outline-text-3" id="text-orga219285">
<p>
Os recuerdo que podéis preguntar cualquier duda por los cauces
establecidos. Para las videoconferencias, algunos habéis mostrado
vuestras reticencias y el resto, no coincidís en horario. Si alguien
quiere practicar en directo que me lo diga y quedamos para una
conexión directa.
</p>

<p>
Por tanto, para entrenar el oído os sugiero escuchar algo como:
</p>

<p>
<a href="https://tubaro.aperu.net/v/ytb_gWiH8BlpU0U/">https://tubaro.aperu.net/v/ytb_gWiH8BlpU0U/</a>
</p>

<p>
Es un enlace que acaba en «youtube», pero <a href="https://tubaro.apero.net">https://tubaro.apero.net</a>
tiene la ventaja de aglutinar en un solo sitio los vídeos en
Esperanto. Recordad poner los subtítulos en Esperanto para practicar.
</p>
</div>
</div>
</div>
<div id="outline-container-org782b73a" class="outline-2">
<h2 id="org782b73a">Esperanto</h2>
<div class="outline-text-2" id="text-org782b73a">
<p>
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#leccion-2">Leciono 2 de la Kurso de Esperanto</a>.
</p>

<p>
Memoru ke vi havas ĝis la sabaton 25 por aldoni <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#ejercicios-2">la ekzercojn de
la leciono</a>.
</p>
</div>
<div id="outline-container-org1242d62" class="outline-3">
<h3 id="org1242d62">Aĵoj remarkindaj</h3>
<div class="outline-text-3" id="text-org1242d62">
<ol class="org-ol">
<li>En ĉi tiu leciono enhavas unu el la plej gravaj malfacilaĵoj por la
esperantistoj de la hispana. Nu, vere de tiuj, kiuj ne parolas
lingvon kun deklinado: la <b>Akusativon</b>. La leciono eksplikas tro
rapide kaj ĝi estas aĵo kiu faros kreski pli dubojn poste.</li>

<li>Poste de ĉi tiu leciono vi scios konjugacii ĉiujn la esperantajn
verbojn. Nur oni restas por vidi la <i>privola-imperativa</i>, la
<i>kondiĉa</i> kaj la participioj. Ne estas «subjuntivo», nek
«pluscuamperfecto», nek aliaj verbaj tempoj. Nur memorigu ke la
sola helpa verto estas <i>esti</i>.</li>
</ol>
</div>
</div>
<div id="outline-container-org74aa0d2" class="outline-3">
<h3 id="org74aa0d2">Videokonferencoj</h3>
<div class="outline-text-3" id="text-org74aa0d2">
<p>
Mi memorigas al vi ke vi povas demandi iu ajn dubon per la iloj al via
dispozicio. Por la videokonferencoj, iuj el vi montris viajn malemojn
kaj la cetero kunestos neniam. Se iu el vi volas praktiki rekte, diru
al mi por aranĝi rendevuon.
</p>

<p>
Do, por trejnigi la orelon, mi sugestas al vi aŭskulti ion:
</p>

<p>
<a href="https://tubaro.aperu.net/v/ytb_gWiH8BlpU0U/">https://tubaro.aperu.net/v/ytb_gWiH8BlpU0U/</a>
</p>

<p>
La ligilo finiĝas en «youtube», sed <a href="https://tubaro.apero.net">https://tubaro.apero.net</a>
havas la advantaĵon por kunigi en unu nura loko la videojn en
Esperanto. Memoru meti la subtekstojn en Esperanto por praktiki.
</p>
</div>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/kurso/index.html">kurso</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[kurso]]></category>
  <link>https://notxor.nueva-actitud.org/2020/01/18/leciono-2-de-la-kurso-de-esperanto.html</link>
  <pubDate>Sat, 18 Jan 2020 00:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Kie demandi dubojn dum la kurso?]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-01-14</div>
<div id="outline-container-orge0f12cc" class="outline-2">
<h2 id="orge0f12cc">Hispana</h2>
<div class="outline-text-2" id="text-orge0f12cc">
<p>
<i>¿Dónde preguntar dudas durante el curso?</i> Me lo han preguntado por
redes y ya expliqué que mi intención era hacer una especie de reunión
virtual por <a href="https://jitsi.org/">Jit.si</a> para explicar dudas y hacer ejercicios hablados,
lecturas y otras actividades.
</p>

<p>
Hay gente con reticencias a lo de la «reunión virtual» y prefieren no
entrar en ella. Bueno, es una postura respetable: por el motivo que
sea prefieren guardar su intimidad hasta ese grado. Así que se me
plantean dos opciones:
</p>

<ol class="org-ol">
<li>Eliminar las actividades que impliquen encuentros virtuales.</li>
<li>Mantener las actividades que impliquen encuentros virtuales, pero
sólo para aquellos que lo deseen y proporcionar otros medios para
preguntar dudas:

<ul class="org-ul">
<li>Se pueden preguntar dudas por correo, al mismo correo donde se
envían los ejercicios para corrección.</li>
<li>Hay habilitada una sala para acceder por XMPP:
<code>esperanto@salas.suchat.org</code>, de la que soy administrador (aunque
hay más gente).</li>
<li>He creado una sala en <i>Matrix.org</i> porque me lo han pedido:
<code>#esperanta-curso-notxor:matrix.org</code>.</li>
</ul></li>
</ol>

<p>
Supongo que con esas opciones hay suficientes herramientas para
solventar dudas.
</p>

<p>
¡Hasta pronto!
</p>
</div>
</div>
<div id="outline-container-orgfa01264" class="outline-2">
<h2 id="orgfa01264">Esperanto</h2>
<div class="outline-text-2" id="text-orgfa01264">
<p>
<i>Kie demandi dubojn dum la kurso?</i> Oni demandis al mi per sociaj retoj
kaj mi jam diris ke mi intencas fari virtualajn renkontiĝojn per
<a href="https://jitsi.org/">Jit.si</a> por ekspliki dubojn kaj kompleti parolantajn ekzerkojn, legadon
kaj aliajn aktivaĵojn.
</p>

<p>
Iuj homoj ne ŝatas tiun «virtualan renkontiĝon» kaj ili preferas ne
eniri tie. Nu, estas respektinda sinteno: ia ajn ili preferas teni
privatencon ĝis tiu grado. Al mi prezentas du elektojn:
</p>

<ol class="org-ol">
<li>Forigi la aktivaĵojn, kiuj bezonas virtualajn renkontiĝojn.</li>
<li>Elteni la aktivaĵojn, kiuj bezonas virtualajn renkontiĝojn, sed nur
por tiuj, kiuj volos kaj havigi aliajn metodojn por demandi dubojn:

<ul class="org-ul">
<li>Oni povas demandi dubojn per retpoŝto, al la sama poŝto, kie oni
sendas la ekzerkojn por korektado.</li>
<li>Jam estas virtuala ĉambro pro XMPP: <code>esperanto@salas.suchat.org</code>,
mi estas administrando, sed estas aliaj homoj.</li>
<li>Mi kreis virtuala ĉambro ĉe <i>Matrix.org</i>, ĉar oni petis al mi:
<code>#esperanta-curso-notxor:matrix.org</code>.</li>
</ul></li>
</ol>

<p>
Mi supozas ke tiuj elektoj estas sufiĉaj por solvi dubujn.
</p>

<p>
Ĝis!
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/kurso/index.html">kurso</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[kurso]]></category>
  <link>https://notxor.nueva-actitud.org/2020/01/14/kie-demandi-dubojn-dum-la-kurso.html</link>
  <pubDate>Tue, 14 Jan 2020 00:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Comienza el curso de Esperanto]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-01-11</div>
<p>
Como <a href="https://notxor.nueva-actitud.org/blog/2020/01/08/nova-dista-kurso-de-esperanto/">se anunció ya en esta misma página</a> comienza un nuevo curso de
<i>Esperanto</i> para aquellos interesados que quieran realizarlo.
</p>

<p>
Los temas irán apareciendo uno a uno, cada semana se actualizará el
enlace del curso. ¡Guárdalo!:
</p>

<p>
<a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo">https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo</a>
</p>

<p>
Cada semana se enlazará el apartado de ejercicios correspondientes al
tema.  <a href="https://notxor.nueva-actitud.org/esperanto/kurso/zagreba-metodo.html#ejercicios-1">Esta semana son los ejercicios de la lección 1</a> que podéis
encontrar en el enlace del curso. Una vez resueltos los ejercicios hay
que enviarlos al correo electrónico
<a href="mailto:kurso-esperanto@nueva-actitud.org">mailto:kurso-esperanto@nueva-actitud.org</a> que estará disponible
mientras dure el desarrollo del curso. Esta lección hay que enviarla
antes del sábado 18 de enero de 2020. Se ruega que en el mensaje se
diga también la disponibilidad de días y horas para poder hacer una
videoconferencia conjunta para contestar dudas sobre el tema, hacer
algo de lectura y repasar los puntos más importantes. Si no fuera
posible esa videoconferencia por incompatibilidad de horarios, las
dudas se contestarían vía <i>email</i> o se intentarían hacer varias
videoconferencias aunque fuera por grupos más pequeños.
</p>
<div id="outline-container-orgacbc85d" class="outline-2">
<h2 id="orgacbc85d">Consejos pedagógicos</h2>
<div class="outline-text-2" id="text-orgacbc85d">
<ol class="org-ol">
<li>Lee primero el apartado de <i>Gramática</i>. Es fácil de entender, pero
no intentes memorizarlo todo, algunos aspectos se fijan con la
práctica.</li>
<li>Observa el texto y mira en la lista de palabras el significado de
las mismas. Intenta comprender el texto.</li>
<li>Sigue el texto mientras escuchas el audio, aunque no lo entiendas
aún completamente, pon atención a cómo suenan las letras en el
<i>Esperanto</i>.</li>
<li>Anota todas las dudas que te surjan para preguntarlas durante la
corrección.</li>
</ol>
</div>
</div>
<div id="outline-container-org2606b96" class="outline-2">
<h2 id="org2606b96">Recursos</h2>
<div class="outline-text-2" id="text-org2606b96">
<p>
También se pueden consultar otros materiales y recursos, aunque todo
lo que se va a ver durante el curso está en el contenido que se va a
ir proporcionando. Hay recursos que se pueden consultar <i>on line</i> en
Internet y otros que se pueden descargar
</p>

<ol class="org-ol">
<li><i>On line</i>:
<ul class="org-ul">
<li>Diccionario español-esperanto: <a href="http://www.esperanto.es/hef/index.php/diccionario-esperanto">http://www.esperanto.es/hef/index.php/diccionario-esperanto</a></li>
<li>Diccionario multilingüe: <a href="http://www.reta-vortaro.de/revo/">http://www.reta-vortaro.de/revo/</a></li>
<li>Diccionario esperanto (Plena Vortaro): <a href="http://vortaro.net/">http://vortaro.net/</a></li>
<li><i>Plena Manlibro de Esperanta Gramatiko</i>: <a href="https://bertilow.com/pmeg/index.html">https://bertilow.com/pmeg/index.html</a></li>
</ul></li>
<li>Descargable:
<ul class="org-ul">
<li><i>La Zagreba Metodo</i> completo: <a href="./archivo/ZM-k12.pdf">ZM-k12.pdf</a></li>
<li>Método de Esperanto: <a href="./archivo/M.pdf">M.pdf</a></li>
<li><i>Plena Manlibro de Esperanta Gramatiko</i>: <a href="https://bertilow.com/pmeg/elshutebla/pmeg_15.0.13.zip">https://bertilow.com/pmeg/elshutebla/pmeg_15.0.13.zip</a></li>
</ul></li>
</ol>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/kurso/index.html">kurso</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[kurso]]></category>
  <link>https://notxor.nueva-actitud.org/2020/01/11/comienza-el-curso-de-esperanto.html</link>
  <pubDate>Sat, 11 Jan 2020 00:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Nova dista kurso de Esperanto]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-01-08</div>
<p>
Tiuj pasintaj tagoj komencis babili kun interretaj amikoj pri la eblo
de komenci etan kurson pri <i>Esperanto</i> kaj instrui kelkaj el ili en ĉi
tiu bela lingvo.
</p>

<p>
Finfine, ni interkonsentis la instruado kaj mi decidis uzi la
<i>Zagreban Metodon</i>, kiu estas libere rete. <a href="https://learn.esperanto.com/">Oni povas trovi ilon por
meminstrui <i>Esperanton</i> kaj studi pro si mem la lingvo</a>.
</p>

<p>
<a href="http://esperantofre.com/zagreb/zagrebh.htm">Ankaŭ estas ĉi tie</a>. Mi pensas ke mi faros en ĉi tiu modesta retpaĝo
veran version de la hispana eldono por elŝuti: <code>epub</code> kaj <code>pdf</code>. Sed
ankaŭ mi ne havis tempon por plenumi la taskon.
</p>

<p>
La kurso, ankaŭ, ne komencis vi ankaŭ povas montri vian intereson, sed
mi pensas, ke se vi estas leganta tion ĉi, vi ne bezonas la instruado
ke mi povos instrui.
</p>

<p>
La metodon havas enkondukon, kiu ne aperas en la reta versio. Mi volas
kopii ĉi tie por montri la ilon iomete pli bone, kiel eble.
</p>

<blockquote>
<p>

</p>

<div class="org-center">
<p>
<b>Enkonduko</b>
</p>
</div>

<p>
Tiu ĉi lernolibro ebligas al vi ekposedi Esperanton kaj ekkoni la
plej elementajn ideojn de la movado por la Internacia Lingvo. Laŭ sia
strukturo la lernolibro aplikeblas en kursoj kun instruanto (-isto),
en korespondaj kursoj samkiel por memlernantoj. La libro estas uzebla
ankaŭ en internaciaj kursoj.
</p>

<p>
La lingva parto de la lernolibro estis preparita helpe de novaj
metodoj kaj estis kontrolita en aro da eksperimentaj kursoj en
Jugoslavio kaj en eksterlando. Tiu ĉi eldono estas rezulto kaj sumo
de spertoj de la aŭtoroj mem, de multaj instruistoj kaj lernantoj kaj
bonintencaj laŭdoj aŭ kritikoj fare de pluraj sciencistoj kiuj
okupiĝas pri simila laboro. En antaŭaj variaĵoj, la lernolibro havis
kvin kroatserbajn eldonojn, kaj po unu eldonojn en la makedona,
slovena, germana, franca, itala, malta, kataluna, kirunda kaj
hungara, dum pretas por eldono en pluraj aliaj.
</p>

<p>
La lernolibro estas farita tiel ke surbaze de 500 plej oftaj radikoj
oni elekzercu la parolkapablon. La ofteco de vortoj estis konstatita
per komputila analizo de la ĉiutaga parolo ampleksanta ĉirkaŭ 60.000
vortojn. Plua lernado prezentas nur plivastigon de la vorttrezoro kaj
stilpliriĉigon kaj akiradon de lerteco en pli komplikaj sintaksaj
frazkonstruoj. Se oni konsideras ke sufiĉe multaj vortoj estas
konataj al meze edukita homo, tio ankoraŭ plifaciligas la akiron de
tiu ĉi facila kaj utila lingvo. Aliflanke tiu ĉi vort- kaj
gramatikamplekso prezentas la lingvan scion kiun Universala
Esperanto-Asocio postulas por akiri ateston pri la baza A-grada kono
de Esperanto.
</p>

<p>
Ĉiu lingvo estas ankaŭ portanto de kulturo de certa komunumo. La
parola komunumo de Esperanto estas la internacia Esperanto-movado. La
karakterizojn kaj valorojn de la kulturo de tiu ĉi movado vi plej
bone ekkonos enirante en ĝin, kaj la bazan faktojn kaj konojn vi
akiros el libreto "Esperanto - lingvo kaj movado" (nacilingve) aŭ
senpere, aliĝante al iu Esperanto-societo aŭ klubo.
</p>

<p>
Ni dankas al ĉiuj kiuj per siaj klopodoj aŭ konsiloj kontribuis al
tio ke tiu ĉi lernolibro efektiviĝu en ĝia nuna formo.
</p>

<p>
Al vi kiuj finlegis tiun ĉi enkondukon kun la intenco lerni
Esperanton, ni deziras sukceson kaj multajn amikecojn kaj
renkontiĝojn kun homoj, libroj kaj okazaĵoj tra la tuta mondo.
</p>

<p>
<i>La aŭtoroj</i>
</p>

<p class="verse">
Roger IMBERT<br>
Tibor SEKELJ<br>
Ivica SPOLJAREC<br>
Spomenka STIMEC<br>
ZLATKO TISLJAR<br>
</p>
</blockquote>

<p>
Ni komencos la kurson baldaŭ kaj mi esperas ĝi estu sufiĉe bona kaj la
lernantoj vere lernos kaj ekamos <i>Esperanton</i>.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/kurso/index.html">kurso</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[kurso]]></category>
  <link>https://notxor.nueva-actitud.org/2020/01/08/nova-dista-kurso-de-esperanto.html</link>
  <pubDate>Wed, 08 Jan 2020 00:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Escribir un correo electrónico]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2020-01-03</div>
<p>
Sí, desde <i>Emacs</i> también se pueden escribir ─y enviar─ correos
electrónicos. Y esto te puede venir bien en cualquier momento como me
ha sucedido a mí estos días que he estado fuera de casa. Lo que
sucedió es que estaba en un lugar donde las conexiones no eran muy
buenas... y torpe de mí, me dio por actualizar el ordenador creyendo
que contaba con 4G. Sin embargo, algo debió ir mal en la
actualización, o quizá tampoco fuera culpa de la conexión, el caso es
que el programa que suelo utilizar para el correo electrónico,
<i>Thunderbird</i>, dejó de funcionar.
</p>

<p>
El caso es que tenía que enviar un correo electrónico urgentemente,
por cuestiones de trabajo. Y no había posibilidad de enviarlo por el
método normal. El artículo de hoy va de uno de los paquetes que vienen
instalados por defecto con nuestro querido <i>Emacs</i>: <code>gnus</code>. Un paquete
que al ver su descripción parece destinado tan sólo para leer <i>news</i> y
listas de correo, pero que también sirve para enviar correos.
</p>
<div id="outline-container-orgb224af1" class="outline-2">
<h2 id="orgb224af1">Configuración mínima</h2>
<div class="outline-text-2" id="text-orgb224af1">
<p>
La configuración que necesitas apenas son cuatro líneas de nuestro
fichero <code>init.el</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> send-mail-function 'smtpmail-send-it)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> smtpmail-smtp-user   <span style="color: #f1fa8c;">"usuario@servidor.com"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> smtpmail-smtp-server <span style="color: #f1fa8c;">"smtp.servidor.com"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> smtpmail-smtp-service 587)
</pre>
</div>

<p>
Los nombres de las variables son suficientemente descriptivos.
Comprueba esos datos en tu servidor de corro, es posible que tu
proveedor utilice otro puerto y deberás poner el que corresponda en
<code>smtpmail-smtp-service</code> para que funcione.
</p>

<p>
Una vez que hayas recargado el fichero <code>init.el</code> con la información de
la configuración <code>smtpmail</code>, ya se podrán enviar mensajes. <i>Emacs</i>
envía los mensajes utilizando el programa <code>sendmail</code> por defecto,
aunque se pueden configurar otras herramientas. En mi caso, como lo
que utilizo es <code>sendmail</code> no he tenido que configurar nada más.
</p>

<p>
También es posible leer el correo con <code>gnus</code> configurando la variable:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> read-mail-command 'gnus)
</pre>
</div>

<p>
Pero no vamos a entrar en eso de momento, nos conformamos con poder
enviar un correo ante unas prisas. Haz pruebas y envía un par de
correos de prueba a alguna cuenta propia. El procedimiento es el
siguiente:
</p>

<ol class="org-ol">
<li>Lanza <code>gnus</code> con <code>M-x gnus</code>.</li>
<li><p>
Cuando aparezca el <i>buffer</i> de <code>gnus</code> pulsa <code>m</code> para escribir un
nuevo <i>mail</i>. Aparecerá un <i>buffer</i> con el siguiente texto (o
similar):
</p>

<pre class="example" id="org1d8b77c">
To: 
Subject: 
From: Usuario &lt;usuario@servidor.com&gt;
Gcc: nnfolder+archive:sent.2020-01
--text follows this line--
</pre></li>

<li>En la línea <code>To:</code> escribe la dirección de correo a la que quieras
enviar el mensaje.</li>
<li>En la línea <code>Subject:</code> escribe el asunto.</li>
<li>Debajo de la línea <code>--text follows this line--</code> escribe el
contenido del mensaje.</li>
<li>Añade algún adjunto con <code>C-c C-a</code>.</li>
<li>Para enviarlo pulsa <code>C-c C-c</code>.</li>
</ol>

<p>
Todas esas acciones son accesibles también desde la barra de botones
que tiene <code>gnus</code> para hacerlo.
</p>
</div>
</div>
<div id="outline-container-org49b4876" class="outline-2">
<h2 id="org49b4876">Desde línea de comandos</h2>
<div class="outline-text-2" id="text-org49b4876">
<p>
¿Qué ocurre si tengo que enviar un correo electrónico y tampoco tengo
<i>Emacs</i> para salir del apuro?
</p>

<p>
Si ese es el caso, es posible que tu sistema <i>GNU/Linux</i> tenga
instalado el paquete <code>mailx</code>. En ese caso puedes utilizar el comando:
</p>

<div class="org-src-container">
<pre class="src src-shell">mailx -v -s <span style="color: #f1fa8c;">"Esto es un correo de prueba"</span> <span style="color: #f1fa8c;">\</span>
 -S <span style="color: #f8f8f2; font-weight: bold;">smtp</span>=<span style="color: #f1fa8c;">"smtp.servidor.com:587"</span> <span style="color: #f1fa8c;">\</span>
 -S smtp-use-starttls <span style="color: #f1fa8c;">\</span>
 -S smtp-auth=login <span style="color: #f1fa8c;">\</span>
 -S smtp-auth-user=<span style="color: #f1fa8c;">"usuario@servidor.com"</span> <span style="color: #f1fa8c;">\</span>
 -S smtp-auth-password=<span style="color: #f1fa8c;">"la-contrase&#241;a-que-sea"</span> <span style="color: #f1fa8c;">\</span>
 -S ssl-verify=ignore <span style="color: #f1fa8c;">\</span>
 -r <span style="color: #f1fa8c;">"Fulanito <a href="mailto:usuario%40servidor.com">&lt;usuario@servidor.com&gt;</a>"</span> <span style="color: #f1fa8c;">\</span>
 -a ~/fichero.pdf <span style="color: #f1fa8c;">\</span>
 correo@al-que-enviar.com &lt; mensaje.txt 
</pre>
</div>

<p>
Lo he puesto en distintas líneas para que se aprecien las distintas
opciones. En ese caso se puede apreciar que en la última línea se
añade <code>&lt; mensaje.txt</code> que implica que el texto del mensaje lo hemos
escrito en ese fichero y volcamos su contenido al <code>mailx</code>.  Entenderlo
creo que es sencillo. Las opciones <code>-S</code> establecen diferentes
variables, como el <i>usuario</i> y el <i>password</i>. La opción <code>-r</code> establece
quién es el remitente y su correo, tal y como aparecerá en el
mensaje. La opción <code>-s</code> establece el asunto del mensaje. La opción
<code>-a</code> permite añadir adjuntos. Si no se carga con una <i>pipeline</i> el
contenido del mensaje, <code>mailx</code> permite que lo escribamos de forma
interactiva; al pulsar <code>C-d</code> termina la edición y envía el mensaje.
</p>
</div>
</div>
<div id="outline-container-orga9ffcd6" class="outline-2">
<h2 id="orga9ffcd6">Conclusión</h2>
<div class="outline-text-2" id="text-orga9ffcd6">
<p>
Se pueden enviar correos de muchas maneras: nuestro <i>Emacs</i> resulta
una de ellas, pero no la única y nunca sabes cuándo vas a necesitar
enviar un mensaje sin tener las herramientas gráficas más cómodas.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2020/01/03/escribir-un-correo-electronico.html</link>
  <pubDate>Fri, 03 Jan 2020 18:54:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Listas de tareas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-12-28</div>
<p>
Una de las primeras cosas que me sorprendieron cuando conocí
<code>org-mode</code> fue la facilidad de hacer <i>listas de tareas</i>, además de lo
completas que son. Pero para ver su potencia desde cero, vamos a ir
por partes.
</p>
<div id="outline-container-org61a252f" class="outline-2">
<h2 id="org61a252f">Creando una lista</h2>
<div class="outline-text-2" id="text-org61a252f">
<p>
Como el movimiento se aprende andando vamos a generar una lista de
tareas. Imagina que queremos organizar una pequeña fiesta con nuestros
amigos. Sigue los siguientes pasos:
</p>

<ol class="org-ol">
<li><i>Visita</i> un nuevo fichero que se llame <code>fiesta.org</code></li>
<li><p>
Escribe el siguiente texto, puedes copiar y pegar, pero estaría
mejor si lo escribes tú mismo, le haces variaciones y juegas un
poco con él:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #f8f8f2; background-color: #282a36;">&#8211;</span> Organizar fiesta <span style="color: #ffb86c; background-color: #373844; font-weight: bold;">[%]</span>
  &#8211; <span style="font-weight: bold;">[ ]</span> Llamar a los amigos <span style="color: #ffb86c; background-color: #373844; font-weight: bold;">[/]</span>
    &#8211; <span style="font-weight: bold;">[ ]</span> Fulanito
    &#8211; <span style="font-weight: bold;">[ ]</span> Menganita
    &#8211; <span style="font-weight: bold;">[ ]</span> Zutanito
  &#8211; <span style="font-weight: bold;">[ ]</span> Encargar cattering
  &#8211; <span style="font-weight: bold;">[ ]</span> Preparar m&#250;sica <span style="color: #ffb86c; background-color: #373844; font-weight: bold;">[/]</span>
    &#8211; <span style="font-weight: bold;">[ ]</span> Hacer lista en <span style="color: #f1fa8c; font-style: italic;">Mixxx</span>
    &#8211; <span style="font-weight: bold;">[ ]</span> Conseguir m&#250;sica que falte
  &#8211; <span style="font-weight: bold;">[ ]</span> Avisar a los vecinos
</pre>
</div>

<p>
Supongo que te llamará la atención las expresiones <code>[%]</code> o <code>[/]</code>,
pero vas a comprender enseguida para qué sirven.
</p></li>
<li><p>
Ve a la línea de <i>Menganita</i> y pulsa <code>C-c C-c</code>. El texto debe haber
cambiado <i>automágicamente</i> a:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #f8f8f2; background-color: #282a36;">&#8211;</span> Organizar fiesta <span style="color: #ffb86c; background-color: #373844; font-weight: bold;">[0%]</span>
  &#8211; <span style="font-weight: bold;">[-]</span> Llamar a los amigos <span style="color: #ffb86c; background-color: #373844; font-weight: bold;">[1/3]</span>
    &#8211; <span style="font-weight: bold;">[ ]</span> Fulanito
    &#8211; <span style="font-weight: bold;">[X]</span> Menganita
    &#8211; <span style="font-weight: bold;">[ ]</span> Zutanito
  &#8211; <span style="font-weight: bold;">[ ]</span> Encargar cattering
  &#8211; <span style="font-weight: bold;">[ ]</span> Preparar m&#250;sica <span style="color: #ffb86c; background-color: #373844; font-weight: bold;">[0/2]</span>
    &#8211; <span style="font-weight: bold;">[ ]</span> Hacer lista en <span style="color: #f1fa8c; font-style: italic;">Mixxx</span>
    &#8211; <span style="font-weight: bold;">[ ]</span> Conseguir m&#250;sica que falte
  &#8211; <span style="font-weight: bold;">[ ]</span> Avisar a los vecinos
</pre>
</div>

<p>
Interesante ¿no? Resulta que podemos poner casillas marcadas como
<code>[ ]</code>, cuando completamos esa tarea la marcamos con <code>C-c C-c</code> y
<code>org</code> hace los cálculos necesarios para indicarte cómo se va
desarrollando. Cuando una tarea está hecha en parte lo marca como
<code>[-]</code> y cuando está completada como <code>[X]</code>. La casilla que habías
escrito como <code>[%]</code> se ha convertido en el porcentaje completado.
</p></li>
<li><p>
De momento sólo hemos completado una parte de una tarea. Ve a la
línea <i>Avisar a los vecinos</i> y pulsa <code>C-c C-c</code>.
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #f8f8f2; background-color: #282a36;">&#8211;</span> Organizar fiesta <span style="color: #ffb86c; background-color: #373844; font-weight: bold;">[25%]</span>
  &#8211; <span style="font-weight: bold;">[-]</span> Llamar a los amigos <span style="color: #ffb86c; background-color: #373844; font-weight: bold;">[1/3]</span>
    &#8211; <span style="font-weight: bold;">[ ]</span> Fulanito
    &#8211; <span style="font-weight: bold;">[X]</span> Menganita
    &#8211; <span style="font-weight: bold;">[ ]</span> Zutanito
  &#8211; <span style="font-weight: bold;">[ ]</span> Encargar cattering
  &#8211; <span style="font-weight: bold;">[ ]</span> Preparar m&#250;sica <span style="color: #ffb86c; background-color: #373844; font-weight: bold;">[0/2]</span>
    &#8211; <span style="font-weight: bold;">[ ]</span> Hacer lista en <span style="color: #f1fa8c; font-style: italic;">Mixxx</span>
    &#8211; <span style="font-weight: bold;">[ ]</span> Conseguir m&#250;sica que falte
  &#8211; <span style="font-weight: bold;">[X]</span> Avisar a los vecinos
</pre>
</div>

<p>
Ya hemos completado el 25% de las tareas básicas y la lista nos
avisa.
</p></li>
</ol>

<p>
Podría seguir dando instrucciones de cómo funciona una lista simple de
tareas, pero mi sugerencia es que juegues con esta lista, añadas
items, completes opciones y veas que con una interfaz muy sencilla, un
árbol de listas, se puede tener de un vistazo el control de un
proyecto.
</p>
</div>
</div>
<div id="outline-container-orge8fc1e2" class="outline-2">
<h2 id="orge8fc1e2">Tareas: estados, prioridades y etiquetas</h2>
<div class="outline-text-2" id="text-orge8fc1e2">
<p>
En <code>org-mode</code> cualquier cabecera se convierte en un ítem. Vamos a
cambiar el texto de la anterior sección y utilizar cabeceras en lugar
de listas. El texto debería quedar como sigue:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #ff79c6; font-size: 130%; font-weight: bold;">*</span><span style="color: #ff79c6; font-size: 130%; font-weight: bold;"> Organizar fiesta</span>
<span style="color: #bebebe; background-color: #282a36;">*</span><span style="color: #bd93f9; font-size: 110%; font-weight: bold;">*</span><span style="color: #bd93f9; font-size: 110%; font-weight: bold;"> Llamar a los amigos</span>
<span style="color: #bebebe; background-color: #282a36;">**</span><span style="color: #50fa7b;">*</span><span style="color: #50fa7b;"> Fulanito</span>
<span style="color: #bebebe; background-color: #282a36;">**</span><span style="color: #50fa7b;">*</span><span style="color: #50fa7b;"> Menganita</span>
<span style="color: #bebebe; background-color: #282a36;">**</span><span style="color: #50fa7b;">*</span><span style="color: #50fa7b;"> Zutanito</span>
<span style="color: #bebebe; background-color: #282a36;">*</span><span style="color: #bd93f9; font-size: 110%; font-weight: bold;">*</span><span style="color: #bd93f9; font-size: 110%; font-weight: bold;"> Encargar cattering</span>
<span style="color: #bebebe; background-color: #282a36;">*</span><span style="color: #bd93f9; font-size: 110%; font-weight: bold;">*</span><span style="color: #bd93f9; font-size: 110%; font-weight: bold;"> Preparar m&#250;sica</span>
<span style="color: #bebebe; background-color: #282a36;">**</span><span style="color: #50fa7b;">*</span><span style="color: #50fa7b;"> Hacer lista en Mixxx</span>
<span style="color: #bebebe; background-color: #282a36;">**</span><span style="color: #50fa7b;">*</span><span style="color: #50fa7b;"> Conseguir m&#250;sica que falte</span>
<span style="color: #bebebe; background-color: #282a36;">*</span><span style="color: #bd93f9; font-size: 110%; font-weight: bold;">*</span><span style="color: #bd93f9; font-size: 110%; font-weight: bold;"> Hablar con los vecinos</span>
</pre>
</div>

<p>
Ve a la línea <code>*** Zutanito</code> y pulsa <code>C-c C-t</code> tres veces seguidas
¿Qué ocurre? Efectivamente, el título se marca la primera vez como
<code>TODO</code>, la segunda como <code>DONE</code> y la tercera vuelve a estar sin
marcar. Lo mismo lo podemos hacer también con las combinaciones
<code>S-&lt;LEFT&gt;</code>, en el mismo sentido, y <code>S-&lt;RIGHT&gt;</code>, en el sentido
inverso. ¿Y tiene que ponerlo en inglés? Pues no, se puede generar
cualquier tipo de estados. Se pueden configurar de forma general, pero
también establecer algunas particulares para un fichero. Por ejemplo,
escribe lo siguiente en la primera línea:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #6272a4;">#+TODO: Pendiente Esperando | Finalizado Cancelado</span>
</pre>
</div>

<p>
Recuerda no dejar ningún espacio en blanco delante del carácter <code>#</code>,
si lo haces, <code>org</code> lo tomará como un comentario. Para que tenga efecto
tendrás que recargar el fichero: guárdalo y vuelve a abrirlo. Ahora
podrás hacer el ciclo con los estados que has escrito. Puedes observar
que hay un carácter <code>|</code> para separar los estados <i>pendientes</i>, ─a la
izquierda─, de los estados <i>completados</i>, ─a la derecha─. Si quieres
profundizar más en la configuración de estados de las tareas ve a la
documentación de <code>org-mode</code> para aprender más detalles.
</p>
</div>
<div id="outline-container-org11636f0" class="outline-3">
<h3 id="org11636f0">Prioridad</h3>
<div class="outline-text-3" id="text-org11636f0">
<p>
En nuestra lista de tareas, también podemos establecer de forma visual
las prioridades. Nos deja establecer tres prioridades <code>A</code>, <code>B</code>, <code>C</code> de
más alta a más baja. Un ejemplo: Ve a la línea <code>Encargar cattering</code> y
pulsa la combinación <code>C-c , a</code>. La línea debe mostrar una prioridad
marcada como <code>[#A]</code>.
</p>

<p>
También puedes utilizar las combinaciones <code>S-&lt;UP&gt;</code>, para incrementar
prioridad, y <code>S-&lt;DOWN&gt;</code>, para reducir la prioridad.
</p>
</div>
</div>
<div id="outline-container-org994310a" class="outline-3">
<h3 id="org994310a">Etiquetas</h3>
<div class="outline-text-3" id="text-org994310a">
<p>
Las etiquetas son una herramienta poderosa para acotar las tareas. En
mi fichero de tareas utilizo tres etiquetas: <code>trabajo</code>, <code>personal</code> y
<code>asociación</code> para indicar que una tarea que tengo pendiente es para el
trabajo, para mí o para la asociación con la que colaboro. Pero, por
ejemplo, en un fichero de un proyecto de trabajo en equipo, puedes
utilizar etiquetas para saber a quién se le ha asignado cada tarea.
</p>

<p>
Si no tenemos configuradas las etiquetas que utilice el fichero,
podemos utilizar cualquiera. Al pulsar <code>C-c C-c</code> en cualquier cabecera
nos preguntará por la etiqueta y podemos escribir lo que queramos. Sin
embargo, podemos establecer una limitación para que las etiquetas sean
sólo las que necesitamos. Por ejemplo, si escribimos en nuestro
fichero, justo después de la línea <code>#+TODO:</code> la siguiente línea:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #6272a4;">#+TAGS: trabajo(t) personal(p) asociaci&#243;n(a)</span>
</pre>
</div>

<p>
Esa línea limitará las etiquetas a tres: <code>trabajo</code>, <code>personal</code> y
<code>asociación</code>, además vemos que hemos asignado una tecla entre
paréntesis para cada una de ellas. De esa forma, al pulsar <code>C-c C-c</code>
nos aparecerá un diálogo donde podemos señalar qué etiquetas queremos
utilizar. Por ejemplo:
</p>

<ol class="org-ol">
<li>Escribe la línea anterior en nuestro fichero de pruebas.</li>
<li>Guarda el fichero y recárgalo para tengan efecto los cambios en las
etiquetas.</li>
<li>Ve a cualquier línea de cabecera y pulsa <code>C-c C-c a</code>.</li>
<li>Observa que a la derecha habrá aparecido la etiqueta
<code>:asociación:</code>.</li>
<li>Ve a otra línea y pulsa <code>C-c C-c t p</code>.</li>
<li>Observa que la etiqueta que aparece en este caso es
<code>:trabajo:personal:</code>. Efectivamente, un ítem puede tener varias
etiquetas.</li>
</ol>

<p>
¿Qué ocurre si tengo etiquetas que son excluyentes? Por ejemplo,
imagina que has limitado las etiquetas de un trabajo en equipo con los
nombres del equipo, es muy probable que quieras limitar la asignación
de forma excluyente:
</p>

<ol class="org-ol">
<li><p>
Cambia la definición de las etiquetas en nuestro fichero de pruebas
a:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #6272a4;">#+TAGS: { Antonio(a) Bel&#233;n(b) Carlos(c) Diana(d) } tests(t) programa(p) mantenimiento(m)</span>
</pre>
</div></li>

<li>Guarda los cambios y recarga el fichero para que tengan efecto.</li>
<li>Fíjate que los nombres del equipo están situados entre <code>{...}</code>.</li>
<li>Ve a cualquier línea y pulsa <code>C-c C-c c t &lt;RET&gt;</code>.</li>
<li>Observa que aparece el par de etiquetas <code>:Carlos:tests:</code>.</li>
<li>En esa línea vuelve a pulsar <code>C-c C-c b &lt;RET&gt;</code>.</li>
<li>Observa que la etiqueta a cambiado a <code>:Belén:tests</code>:.</li>
<li>En la misma línea pulsa <code>C-c C-c m &lt;RET&gt;</code>.</li>
<li>Observa que la etiqueta cambia a <code>:Belén:tests:mantenimiento:</code>.</li>
</ol>

<p>
Como puedes observar, las etiquetas situadas entre llaves son
excluyentes entre sí, no pueden coexistir en la misma línea, mientras
las que se encuentran fuera, pueden etiquetar a la vez una cabecera.
</p>
</div>
</div>
</div>
<div id="outline-container-org909b60e" class="outline-2">
<h2 id="org909b60e">Conclusiones</h2>
<div class="outline-text-2" id="text-org909b60e">
<p>
Las listas de tareas son una sencilla y eficaz manera de
organizarnos. <code>Org</code> nos proporciona esta herramienta de una manera
sencilla de entender y utilizar. Tanto para hacer seguimientos como
para etiquetar y acotar las acciones. Seguro que con un poco de
práctica encontrarás cómo aplicarlas y verás lo sencillo que es
gestionar algunos proyectos con ellas.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2019/12/28/listas-de-tareas.html</link>
  <pubDate>Sat, 28 Dec 2019 18:52:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Agenda, fechas y configuración de teclas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-12-20</div>
<div id="outline-container-org5964df7" class="outline-2">
<h2 id="org5964df7">Configurar modos de texto</h2>
<div class="outline-text-2" id="text-org5964df7">
<p>
Cuando trabajamos con textos largos es conveniente tener configuradas
algunas cosas que nos facilitarán la vida. En general, los modos de
texto y los modos de programación difieren en cómo muestran las líneas
en el editor. Normalmente, en un modo de programación suele ser
adecuado el mostrar una instrucción por línea; aunque ésta sea larga y
supere por la derecha cualquier margen, al programador suele darle
igual, pues no suele imprimir en papel el código: donde este hecho
sería un inconveniente.
</p>

<p>
Sin embargo, para los modos de texto como pueden ser <i>Markdown</i>,
<i>org</i>, <i>LaTeX</i>, etc. la convención suele ser agrupar líneas en
párrafos, separándolos por líneas en blanco.
</p>

<p>
Hay varias variables que controlan el comportamiento de las líneas
dentro de los ficheros. Una de las más importantes es <code>fill-column</code>,
que por defecto está fijado en 70. Eso quiere decir, que cuando
pulsemos <code>M-q</code> en una línea muy larga, nos formará un párrafo que sus
líneas tendrán como máximo 70 caracteres. Esto es así, para permitir
imprimir un texto plano en papel y que no se pierda contenido por el
margen derecho de la hoja.
</p>

<p>
¿Ocurre algo por tener cada párrafo en una línea? Pues básicamente no,
si no se va a imprimir el texto en papel. Aparte de una pequeña
incomodidad si perdemos de vista contenido por el margen derecho de
nuestro marco. Además podemos hacer que nos muestre el contenido en
una sola línea o en varias con el comando <code>toggle-truncate-lines</code>. O
incluso, hacer que según escribamos texto vaya saltando a la línea
siguiente cuando alcance el valor <code>fill-column</code>, con el
<code>auto-fill-mode</code>... Pero déjame que explique un par de cosas de cómo
automatizar estas cosas desde nuestra configuración. Sólo un par:
</p>

<ol class="org-ol">
<li>Configurar nuestros propios atajos de teclado.</li>
<li>Añadir automatismos que cambien el comportamiento según el modo.</li>
</ol>
</div>
<div id="outline-container-org91c075c" class="outline-3">
<h3 id="org91c075c">Configurar teclas propias</h3>
<div class="outline-text-3" id="text-org91c075c">
<p>
Lo primero que hay que recomendar es que mires detenidamente si el
comportamiento que quieres automatizar tiene ya su propia combinación.
Si es así te recomiendo que utilices la que ya tiene asignada. Eso
minimizará la posibilidad de que utilices alguna combinación que ya
tenga asignada alguna otra función... ¿te acuerdas cómo?
Efectivamente, en <code>C-h m</code> podrás ver si la función que necesitas está
en la lista.
</p>

<p>
Voy a poner un ejemplo: Imagina que nos gusta tener todo el párrafo en
una sola línea, porque así nos facilita la carga del contenido en un
<i>script</i> o porque es una manía nuestra. A veces necesitamos visualizar
el contenido completo, pero se nos pierde por la derecha y a veces,
necesitamos ver la estructura de líneas pero con toda la información
se nos hace difícil. Por defecto, <i>Emacs</i> deja que se pierda el
contenido a la derecha del marco, añadiendo una línea donde aparece un
carácter <code>→</code>, indicando que la línea continúa. Si queremos que nos
muestre todo el texto podemos llamar al comando
<code>toggle-truncate-lines</code>, que cambiará el modo en que se muestra el
contenido y pondrá una ristra de caracteres <code>↲</code> en el margen derecho y
otra de caracteres <code>↳</code> en el izquierdo para mostrar el flujo del
contenido ajustado en el marco.
</p>

<p>
Bien, vale, eso es fácil pero ¿cómo puedes hacer que cambie desde una
simple combinación de teclas? Muy sencillo, abre el fichero de
configuración, como ya aprendiste en artículos anteriores y escribe la
siguiente línea en él<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>:
</p>

<p>
<code>(global-set-key (kbd "C-c t") 'toggle-truncate-lines)</code>
</p>

<p>
Guarda el fichero con <code>C-x C-s</code> y recárgalo con <code>M-x load-file &lt;RET&gt;
~/.emacs.d/init.el</code> y ya podrás utilizar ese atajo de teclas en tu
trabajo diario. ¿Difícil? Pues ahora voy a explicarte que lo que
acabas de hacer es escribir una línea de código de <code>elisp</code>.
</p>

<p>
En <code>elisp</code> cada comando, función o instrucción<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>, llámalo como
quieras, se encuentra rodeado por un par de caracteres <code>(...)</code>. En
realidad, estos caracteres conforman una <i>lista</i> y lo que hace
<code>LISP</code><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> es procesar una lista cuando la encuentra. Así, la forma
<code>global-set-key</code> lo que hace es asignar una combinación de teclas a
una función particular. Como puedes ver la expresión <code>(kbd "C-c t")</code>
es otra lista y la forma <code>kbd</code> lo que hace es convertir una cadena en
formato estándar de combinaciones, como es <code>C-c t</code> en esa combinación
de teclas que necesita <code>global-set-key</code> como primer <i>parámetro</i> o
<i>dato</i>. Lo siguiente que necesita, en otro parámetro es la función que
debe asignar a la tecla: <code>toggle-truncate-lines</code>. ¿Por qué tiene un
carácter <code>'</code> al principio? Pues para decirle a <code>elisp</code> que no evalúe
dicha forma ahora, que tome sólo el nombre.
</p>
</div>
</div>
<div id="outline-container-org78e1866" class="outline-3">
<h3 id="org78e1866">Añadir ganchos para comportamientos «automágicos»</h3>
<div class="outline-text-3" id="text-org78e1866">
<p>
Imagina que queremos editar un texto... eso si nuestra configuración
por defecto del editor está pensada para programar, requerirá que
perdamos un tiempo ajustando algunos parámetros que deberían cambiar
para editar texto plano. Por ejemplo:
</p>

<ol class="org-ol">
<li>Activar el ajuste de línea al valor <code>auto-fill</code>.</li>
<li>Activar el diccionario para la corrección de palabras.</li>
<li>Activar cualquier otra herramienta que te parezca útil.</li>
</ol>

<p>
Para estos casos, <i>Emacs</i> proporciona lo que se llaman <i>ganchos</i> o en
inglés <i>hooks</i>. Cuando nuestro editor entra en un modo lo que hace es
comprobar la lista de ganchos y ejecutar los que procedan. De esta
manera, si definimos en nuestro fichero <code>init.el</code> los ganchos que nos
van bien, el editor se configurará para responder de una determinada
manera. Por ejemplo, añade estas dos líneas a tu fichero de
configuración:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-hook 'text-mode-hook 'turn-on-auto-fill)
(add-hook 'text-mode-hook 'turn-on-flyspell)
</pre>
</div>

<p>
La forma <code>add-hook</code> lo que hace es añadir un gancho a una lista de
ganchos, en nuestro caso, podemos observar que la lista que
modificamos es <code>text-mode-hook</code> en ambos casos. En la primera línea,
el comando <code>turn-on-auto-fill</code> activa el salto de línea al alcanzar el
ancho fijado en <code>auto-fill</code> y el comando <code>turn-on-flyspell</code> de la
segunda línea, lo que hace es activar el corrector automático de
palabras; es decir, mostrará los errores subrayando en rojo la primera
aparición y en amarillo o naranja las siguientes. 
</p>
</div>
</div>
<div id="outline-container-org400db73" class="outline-3">
<h3 id="org400db73">Configurar el corrector ortográfico</h3>
<div class="outline-text-3" id="text-org400db73">
<p>
Lo del corrector ortográfico mola, pero es posible que no te funcione
a la primera, porque depende de herramientas externas y a lo mejor
tienes que instalar algo. <i>Emacs</i> depende de herramientas externas
para la corrección ortográfica. Tradicionalmente, el corrector es un
programa que se llama <code>ispell</code>, pero si estás utilizando <i>GNU/Linux</i>
es posible que lo tengas ya instalado, o quizá otros como <code>aspell</code> o
<code>hunspell</code>. Si es este caso, tendrás que decirle a <i>Emacs</i> que utilice
la herramienta correcta, poniendo el nombre del ejecutable en la
variable <code>ispell-program-name</code>. Puedes hacerlo de modo gráfico, como
expliqué en pasados artículos o añadiéndola a la lista en la forma
<code>custom-set-variables</code> a mano.
</p>

<p>
Si tienes que instalar algún programa de estos, recuerda también
instalar los diccionarios de las lenguas que utilices más
habitualmente. Lo normal es que te instala el diccionario de inglés y
el del idioma en el que esté configurado tu entorno, como por ejemplo
español. Si necesitas más idiomas, recuerda instalar también los
diccionarios que correspondan.
</p>

<p>
En mi caso, yo tengo en el apartado <code>custom-set-variables</code> una línea
que especifica:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">'(ispell-program-name <span style="color: #f1fa8c;">"aspell"</span>)
</pre>
</div>

<p>
Cuando necesites cambiar el diccionario puedes seleccionar el que
quieras con el comando <code>ispell-change-dictionary</code>.
</p>

<p>
Después ya podrás utilizar la corrección de palabras. Si pinchas con
el segundo botón del ratón sobre una palabra marcada como errónea te
desplegará un menú para que selecciones entre varias opciones. O si ya
estás metido en el modo texto, situándote en la palabra errónea y
pulsando <code>M-$</code> te mostrará un diálogo para que selecciones la
alternativa correcta en un marco. Si pulsas <code>C-.</code> sobre un error, lo
sustituirá por la primera de las opciones sin mostrarlas, también
podemos pulsar sucesivamente <code>C-.</code> para recorrer varias opciones.
</p>
</div>
</div>
</div>
<div id="outline-container-orgcfe0490" class="outline-2">
<h2 id="orgcfe0490">El calendario</h2>
<div class="outline-text-2" id="text-orgcfe0490">
<p>
Una de las herramientas que nos regala el <code>org-mode</code> es la agenda. Hay
quien, como yo, la utiliza para organizarse el trabajo, las citas, el
tiempo, las tareas, etc. 
</p>

<p>
Vamos a empezar por el principio: el <i>calendario</i>. Pulsa la
combinación de teclas <code>C-c .</code> para que aparezca el calendario de la
siguiente forma:
</p>

<pre class="example" id="org3b418c0">
   November 2019              December 2019               January 2020
Su Mo Tu We Th Fr Sa       Su Mo Tu We Th Fr Sa       Su Mo Tu We Th Fr Sa
                1  2        1  2  3  4  5  6  7                 1  2  3  4
 3  4  5  6  7  8  9        8  9 10 11 12 13 14        5  6  7  8  9 10 11
10 11 12 13 14 15 16       15 16 17 18 19 20 21       12 13 14 15 16 17 18
17 18 19 20 21 22 23       22 23 24 25 26 27 28       19 20 21 22 23 24 25
24 25 26 27 28 29 30       29 30 31                   26 27 28 29 30 31
</pre>

<p>
Bueno, se empeña en mostrarnos el calendario en inglés. Lo mismo lo
quieres personalizar y que te hable en tu idioma, para eso hay que
configurar algunas cosillas además.
</p>
</div>
<div id="outline-container-org148dbf3" class="outline-3">
<h3 id="org148dbf3">Formato de fechas</h3>
<div class="outline-text-3" id="text-org148dbf3">
<p>
En mi caso me gusta organizar las fechas en formato <i>ISO</i>:
año-mes-día. ¿Por qué? Pues porque me permite ordenarlas incluso
aunque no sean <i>fechas</i> sino <i>cadenas de texto</i>. No me voy a liar en
muchas explicaciones de los porqués, pero una vez te acostumbras al
formato ISO, las fechas son claras. Eso está configurado en la
variable <code>calendar-date-style</code>, donde puedes utilizar cualquiera de
los tres formatos permitidos:
</p>

<ol class="org-ol">
<li><i>ISO</i>: año-mes-día</li>
<li><i>european</i>: día-mes-año</li>
<li><i>american</i>: mes-día-año</li>
</ol>

<p>
Puedes elegir el que más se ajuste a tus hábitos.
</p>
</div>
</div>
<div id="outline-container-org6c39eb0" class="outline-3">
<h3 id="org6c39eb0">Nombres de los meses</h3>
<div class="outline-text-3" id="text-org6c39eb0">
<p>
Es posible también cambiar los nombres de los meses tal y como se
muestran en el calendario. Para ello debemos modificar dos variables:
<code>calendar-month-name-array</code> y <code>calendar-month-abbrev-array</code>. La
primera guarda los nombres completos de los meses y la segunda las
abreviaciones, algo que puedes haber supuesto dado el nombre de las
mismas.
</p>

<p>
Si la modificación la haces desde el entorno gráfico con el menú
<code>Options -&gt; Customize Emacs -&gt; Specific Option...</code> y dando el nombre
de la variable, verás que se pueden modificar escribiendo los nombres
al lado de su equivalente en inglés. Pero también puedes optar por
modificar el fichero de inicio. Necesitarás añadir las siguientes dos
entradas en el apartado <code>custom-set-variables</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">'(calendar-month-name-array
  [<span style="color: #f1fa8c;">"enero"</span> <span style="color: #f1fa8c;">"febrero"</span> <span style="color: #f1fa8c;">"marzo"</span> <span style="color: #f1fa8c;">"abril"</span> <span style="color: #f1fa8c;">"mayo"</span> <span style="color: #f1fa8c;">"junio"</span> <span style="color: #f1fa8c;">"julio"</span> <span style="color: #f1fa8c;">"agosto"</span> <span style="color: #f1fa8c;">"septiembre"</span> <span style="color: #f1fa8c;">"octubre"</span> <span style="color: #f1fa8c;">"noviembre"</span> <span style="color: #f1fa8c;">"diciembre"</span>])
'(calendar-month-abbrev-array
  [<span style="color: #f1fa8c;">"Ene"</span> <span style="color: #f1fa8c;">"Feb"</span> <span style="color: #f1fa8c;">"Mar"</span> <span style="color: #f1fa8c;">"Abr"</span> <span style="color: #f1fa8c;">"May"</span> <span style="color: #f1fa8c;">"Jun"</span> <span style="color: #f1fa8c;">"Jul"</span> <span style="color: #f1fa8c;">"Ago"</span> <span style="color: #f1fa8c;">"Sep"</span> <span style="color: #f1fa8c;">"Oct"</span> <span style="color: #f1fa8c;">"Nov"</span> <span style="color: #f1fa8c;">"Dic"</span>])
</pre>
</div>

<p>
Como puedes apreciar, los nombres de los meses están escritos en orden
dentro de un <i>array</i> delimitado por los caracteres <code>[...]</code>. Los he
escrito en minúsculas como corresponde a la norma del castellano (pero
siéntete libre de hacer lo que creas oportuno).
</p>
</div>
</div>
<div id="outline-container-org3bb8d76" class="outline-3">
<h3 id="org3bb8d76">Nombres de los días de la semana y el orden</h3>
<div class="outline-text-3" id="text-org3bb8d76">
<p>
Además también necesitarás especificar los nombres de los días de la
semana ajustándolos al idioma que quieras. Puedes optar por la versión
gráfica de la configuración, en todo caso, yo muestro aquí cómo queda
la cosa en el apartado <code>custom-set-variables</code>, como hemos visto en los
meses:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">'(calendar-day-name-array
  [<span style="color: #f1fa8c;">"domingo"</span> <span style="color: #f1fa8c;">"lunes"</span> <span style="color: #f1fa8c;">"martes"</span> <span style="color: #f1fa8c;">"mi&#233;rcoles"</span> <span style="color: #f1fa8c;">"jueves"</span> <span style="color: #f1fa8c;">"viernes"</span> <span style="color: #f1fa8c;">"s&#225;bado"</span>])
'(calendar-day-header-array [<span style="color: #f1fa8c;">"Do"</span> <span style="color: #f1fa8c;">"Lu"</span> <span style="color: #f1fa8c;">"Ma"</span> <span style="color: #f1fa8c;">"Mi"</span> <span style="color: #f1fa8c;">"Ju"</span> <span style="color: #f1fa8c;">"Vi"</span> <span style="color: #f1fa8c;">"Sa"</span>])
</pre>
</div>

<p>
Tienes que observar que ambos <i>arrays</i> comienzan por el <i>domingo</i> y
terminan en el <i>sábado</i>. Si estás acostumbrado a que tus semanas
comiencen en lunes, necesitas establecer también la variable
<code>calendar-week-start-day</code> a <code>1</code> (<i>lunes</i>). Por defecto, esa variable
es <code>0</code>, que corresponde al domingo.
</p>
</div>
</div>
</div>
<div id="outline-container-org3964a3e" class="outline-2">
<h2 id="org3964a3e">La agenda</h2>
<div class="outline-text-2" id="text-org3964a3e">
<p>
En realidad cualquier fichero <code>org</code> se puede mostrar como agenda, pero
mi recomendación es que tengas uno especial donde guardar tus
anotaciones. Si no tienes uno configurado, <i>Emacs</i> utilizará el
fichero <code>.notes</code> para guardar tu agenda. Pero si eres un poco
ordenado, seguramente te gustará guardarlo en algún otro sitio, con un
nombre más descriptivo. Para eso debes ajustar la variable
<code>org-agenda-files</code><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup> en el apartado <code>custom-set-variables</code> o
hacerlo en el modo gráfico, como ya sabes. En mi caso:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">'(org-agenda-files (<span style="color: #ff79c6; font-weight: bold;">quote</span> (<span style="color: #f1fa8c;">"~/agenda/agenda.org"</span>)))
</pre>
</div>

<p>
Lo tengo en un directorio que se llama <code>agenda</code> porque en él agrupo
una serie de ficheros relacionados con la agenda, como el <i>diario</i> o
el <i>archivo</i>. El diario guarda entradas sobre cumpleaños, días
festivos del año, o encuentros periódicos. Su sintaxis es sencilla y
seguramente lo veremos en otras entregas más adelante. Para activarlo
necesitas tener el fichero <code>org</code> que guarde esa información en la
variable <code>org-agenda-diary-file</code> y activar la variable
<code>org-agenda-include-diary</code>. Al activar el diario, aparecerán festivos
de los principales calendarios mundiales: cristiano, judío, musulmán,
bahá, chino...
</p>

<p>
El fichero de archivo lo tienes que señalar en la variable
<code>org-archive-location</code>. En el fichero señalado ahí guardará las
entradas que queramos quitar de nuestro fichero de agenda al pulsar
<code>a</code> en la ventana de agenda. Eso moverá la entrada desde el fichero
<code>agenda.org</code> al fichero <code>archivo.org</code> anotando cuándo se hizo dicho
traspaso. Quizá sea también materia para otra entrada sobre
<code>org-mode</code>.
</p>

<p>
Quizá sea más interesante dejar por ahora la configuración de
automatismos para ver la agenda y capturar datos. Pero como la captura
es muy compleja, te recomiendo leer
<a href="https://notxor.nueva-actitud.org/blog/2019/02/27/reorganizar-las-capturas-de-la-agenda-con-plantillas/">esta entrada del <i>blog</i> sobre una plantilla de captura algo compleja</a>.
</p>
</div>
</div>
<div id="outline-container-org89a071f" class="outline-2">
<h2 id="org89a071f">Conclusiones</h2>
<div class="outline-text-2" id="text-org89a071f">
<p>
De momento, vas viendo la versatilidad de nuestro editor: Todo se
puede configurar y la forma de hacerlo es proveer código escrito en
<i>elisp</i>, el lenguaje embebido en <i>Emacs</i>. Sin embargo, como puedes
ver, el código no es complejo y es texto plano.
</p>

<p>
He intentado que veas más la posibilidades que profundizar en
ellas.  Si necesitas alguna de las opciones, seguramente conseguirás
dominarlo a poco que leas la ayuda y trastees un poco. Sobre <code>org</code> te
recomiendo que le eches un vistazo al manual que viene con él. Pero en
<a href="http://www.davidam.com/docu/orgguide.es.html">español también puedes consultar la guía traducida</a>.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Cuida que esté fuera de otras estructuras de listas. Para
asegurarte que es así, puedes añadir ese texto en una línea en blanco
al final del archivo. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En realidad no son sinónimos, pero tampoco voy a entrar a estas
alturas en profundidades conceptuales sobre programación. Esto es sólo
para que veas que no hay que tenerle miedo a programar y que hay cosas
que de programación que están a tu alcance. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<code>LISP</code> significa <i>procesador de listas</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Fíjate que dicha variable pide <i>files</i> en plural, lo que
significa que se pueden tener varios ficheros para, por ejemplo,
separar los distintos conceptos en diferentes archivos. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2019/12/20/agenda-fechas-y-configuracion-de-teclas.html</link>
  <pubDate>Fri, 20 Dec 2019 18:50:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Herramientas para el sistema]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-12-04</div>
<p>
Como vengo diciendo en esta introducción a <i>Emacs</i>, nuestro editor
viene cargado con un arsenal de herramientas que nos van a facilitar
el trabajo con muchos tipos de ficheros o incluso acceder al sistema
operativo sobre el que corre sin necesidad de salir de nuestro entorno
de trabajo. Vamos a ver algunos, los más socorridos, y por último
introduciremos la manera de extender la funcionalidad de <i>Emacs</i>.
</p>
<div id="outline-container-org0ac2fe5" class="outline-2">
<h2 id="org0ac2fe5"><code>Dired</code></h2>
<div class="outline-text-2" id="text-org0ac2fe5">
<p>
Una de las herramientas que viene cargada en una instalación <i>por
defecto</i> de <i>Emacs</i> es <code>Dired</code>, que como su nombre indica es un
«editor de directorios». En realidad hace muchas más cosas que editar
directorios. Es una auténtica gozada cuando le coges el tranquillo.
Sin embargo, como seguramente no te convenceré con buenas palabras,
vamos a ver cómo sería trabajar con <code>Dired</code> en una sesión y luego ya
me dirás si no es así.
</p>

<p>
Pulsa <code>C-x d</code> y cuando pregunte ve hasta el directorio donde guardaste
nuestro primer fichero <code>org</code>: <code>primer-texto.org</code>. Te aparecerá una
lista de ficheros en ese directorio. Quizá sólo tengas ese en él, no
importa. Vamos a ver cómo podemos aprovechar <code>Dired</code> para trabajar
sobre los ficheros de nuestro disco. Por ejemplo:
</p>

<ol class="org-ol">
<li>Pulsa la tecla <code>+</code>. Verás que en el área de <i>prompt</i> aparece el
mensaje <code>Create directory</code>, seguido del <i>path</i> que tiene abierto
<code>Dired</code> y espera que tecleemos un nombre.</li>
<li>Escribe, por ejemplo: <code>directorio-prueba</code>. Ahora en <code>Dired</code> ha
aparecido un nuevo directorio.</li>
<li>Sitúa el cursor en el fichero <code>primer-texto.org</code>. Fíjate que te
sirven las teclas habituales <code>C-n</code> y/o <code>C-p</code>, pero también <code>n</code> y
<code>p</code>, sin tener pulsada la tecla <code>control</code>.</li>
<li>Pulsa <code>S-c</code> (<code>mayúsculas+c</code>): En el área de <i>prompt</i> aparecerá un
mensaje preguntando dónde copia el fichero <code>primer-texto.org</code>.</li>
<li>Escribe ahora el nombre del directorio que creamos en los pasos 1
y 2.</li>
</ol>

<p>
No estás impresionado, me consta... ¡copiar ficheros a estas alturas!
Bueno, vamos con otra intentona. Si estás situado en el fichero
<code>primer-texto.org</code>, que lo acabamos de copiar a otro sitio, pulsa
<code>&lt;RET&gt;</code>. Esto debería <i>visitar</i> el fichero y permitirte modificarlo.
Haz en él algunas modificaciones, las que consideres oportunas, cuando
hayas acabado guarda los cambios (<code>C-x C-s</code>) y cierra el <i>buffer</i>
(<code>C-x k</code>). ¿Estás en <code>Dired</code> de nuevo? Si no es así, cambia al
<i>buffer</i> de <code>Dired</code> y sitúa el cursor en el fichero que acabas de
modificar. Pulsa <code>=</code>. Ahora te preguntará en el área de <i>prompt</i> con
un mensaje que lo mismo es un poco críptico (<code>Diff nombre-fichero
width:</code>) que introduzcas el nombre de otro fichero. Vamos a escribir
el fichero que copiamos antes. ¿Lo tienes? ¿qué muestra? Efectivamente
todas las modificaciones que le hemos hecho al fichero vienen marcadas
con un código de colores, analizando el contenido de los archivos.
Para más especificaciones, mira la ayuda para el comando <code>diff</code> del
sistema operativo. Como veo que sigues sin estar impresionado, voy a
probar otra cosa:
</p>

<ol class="org-ol">
<li>Sitúa el cursor en el directorio que creamos antes y pulsa la tecla
<code>c</code> (antes utilizamos la <i>c mayúscula</i>, ahora la <i>c minúscula</i>).</li>
<li>En el área de <i>prompt</i> aparecerá un mensaje de <code>Compress
   to:</code>. Escribe el nombre que quieras, por ejemplo: <code>prueba.zip</code> o
<code>prueba.tar.gz</code> (observa que según la extensión que le demos,
utilizará una compresión u otra).</li>
<li>Navega con el cursor hasta el nuevo fichero comprimido creado y
visítalo... ¿lo abre? ¿Ves su interior? ¿Puedes visitar algún
fichero que esté dentro?</li>
</ol>

<p>
Ya no sé cómo impresionarte más, pero voy a hacer un último intento, a
ver:
</p>

<ol class="org-ol">
<li>Sitúa el cursor en nuestro fichero <code>primer-texto.org</code> y pulsa <code>: e</code>
(la secuencia <code>dos puntos</code> y <code>e</code>).</li>
<li>Nos aparecerá un diálogo, si tenemos instalado <code>gpg</code> y tenemos
algunas claves generadas, nos pedirá que seleccionemos aquellas con
las que queremos cifrar el fichero. Si no seleccionamos ninguna, el
cifrado será <i>simétrico</i> y nos pedirá después una palabra clave
para hacer el cifrado.</li>
<li>Si hemos hecho todos esos pasos deberíamos tener un fichero nuevo
llamado <code>primer-fichero.org.gpg</code> en el directorio.</li>
</ol>

<p>
¿Qué ocurre si nos vamos hasta ese fichero y lo abrimos? ¿Lo abre sin
preguntar nada? Mientras estemos en la misma sesión, el paquete <code>epa</code>,
que es el que se encarga del cifrado y descifrado de los archivos,
recordará la clave y no preguntará por ella. Tampoco lo hará si
utilizamos el cifrado de <i>clave pública</i> y detecta que el fichero está
cifrado con una clave que tenga en <code>gpg</code> en la lista.
</p>

<p>
<code>Dired</code> nos permite hacer sobre un fichero o directorio cualquier
operación que permita el sistema operativo: copiarlo, renombrarlo,
cambiarle el propietario (<code>chown</code>) o el modo (<code>chmod</code>), borrarlo,
crear enlaces, comprimirlo, cifrarlo, descifrarlo.
</p>
</div>
</div>
<div id="outline-container-orgfa171d4" class="outline-2">
<h2 id="orgfa171d4">Una consola en mi ventana</h2>
<div class="outline-text-2" id="text-orgfa171d4">
<p>
Para trabajar sobre directorios y ficheros tenemos <code>Dired</code>, pero hay
cosas que no siempre se hacen sobre un fichero o directorio. Para eso
tenemos el comando <code>eshell</code>. Al llamarlo mediante <code>M-x eshell</code> nos
mostrará el clásico <i>prompt</i> <code>$</code> donde podremos introducir cualquier
comando válido del sistema operativo.
</p>

<p>
Bueno, bien, no todo funcionará. Funcionarán los comandos típicos de
Unix: interactivos en consola, pero fallarán los programas que no
funcionan de forma interactiva, como por ejemplo, los que utilizan
<code>ncurses</code> o un entorno gráfico para funcionar.
</p>

<p>
Con un par de teclas consigue facilitarlos el trabajo con el entorno,
por ejemplo, si pulsamos <code>C-c C-l</code> (<code>eshell-list-history</code>) nos
mostrará un listado con el historial de comandos en un <i>buffer</i> por el
que podemos movernos y al pulsar <code>&lt;RET&gt;</code> nos permitirá ejecutar de
nuevo ese comando. Con <code>C-c C-s</code> nos muestra una lista de procesos que
están corriendo y nos permite mandar a esos procesos una señal de
<code>eof</code>, o interrumpirlo o incluso una señal <code>kill</code>.
</p>

<p>
Recordad, si quieres saber qué comandos tiene, en el <i>buffer</i> de
<code>eshell</code> pulsa <code>C-h m</code> y te dará una lista exhaustiva.
</p>
</div>
</div>
<div id="outline-container-orgb35ef9e" class="outline-2">
<h2 id="orgb35ef9e">Editor hexadecimal</h2>
<div class="outline-text-2" id="text-orgb35ef9e">
<p>
Ya que estás familiarizado con estas herramientas, abre un directorio
y navega hasta alguna imagen que tengas en tu disco. Cuando estés
sobre una imagen pulsa <code>&lt;RET&gt;</code>. Como verás <i>Emacs</i> identifica el tipo
de fichero y lo abre en un <i>buffer</i> de imagen. Si pulsas <code>C-c C-c</code>
alternará entre el modo imagen y su descripción. Ahora bien, si la
imagen que has abierto es un fichero <code>.svg</code> verás que muestra el texto
<code>XML</code> que define dicha imagen, pero si has abierto un <code>.png</code> o un
<code>.jpg</code>, por poner un ejemplo, la descripción es un poco confusa,
porque es binario.
</p>

<p>
¿Se puede abrir un fichero en formato binario? Sí, claro. Algunas
veces es necesario. Si estando situados en el <i>buffer</i> de la imagen
llamamos al modo hexadecimal con el comando <code>M-x hexl-mode</code>, nos
mostrará el contenido del fichero en filas de 16 bytes en formato
binario.
</p>

<p>
También se puede editar el fichero, pero ya entenderéis que las
posibilidades de éxito son bastante menores. <i>No modifiquéis nunca un
fichero binario a no ser que estéis muy seguros de los que estáis
haciendo</i>.
</p>
</div>
</div>
<div id="outline-container-orgab043b4" class="outline-2">
<h2 id="orgab043b4">Instalar paquetes</h2>
<div class="outline-text-2" id="text-orgab043b4">
<p>
A partir de ahora veremos la posibilidad de aumentar la funcionalidad
de <i>Emacs</i>. Si nuestro editor favorito ha llegado donde está, es
gracias a la infinidad de paquetes con los que cuenta. De hecho corre
el rumor de que si te has planteado alguna vez hacer algo con un
ordenador, seguramente <i>Emacs</i> tendrá un paquete que te facilitará la
tarea.
</p>

<p>
Antes de nada, advertir que vamos a modificar nuestro fichero de
inicio directamente, como auténticos expertos programadores ¿Difícil?
Verás como no. Sigue los siguientes pasos y todo irá bien.
</p>

<p>
Visita el fichero <code>~/.emacs.d/init.el</code>. Si no está fíjate que si está
el fichero <code>~/.emacs</code>. Si es así, renombra este último a
<code>~/.emacs.d/init.el</code> y después ábrelo.
</p>

<p>
La primera línea del archivo debe ser:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(package-initialize)
</pre>
</div>

<p>
Si no lo es, escribe el texto anterior tal y como está, con paréntesis
incluidos. Acabas de escribir tu primera sentencia en <i>elisp</i>, el
lenguaje de extensión de <i>Emacs</i>. Como puedes intuir, lo que hace es
iniciar el sistema de paquetes.
</p>

<p>
A continuación vamos a escribir un poco más de código. Si no te fías
de hacerlo bien, corta y pega lo siguiente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> package-archives '((<span style="color: #f1fa8c;">"gnu"</span> . <span style="color: #f1fa8c;">"http://elpa.gnu.org/packages/"</span>)
                         (<span style="color: #f1fa8c;">"marmalade"</span> . <span style="color: #f1fa8c;">"https://marmalade-repo.org/packages/"</span>)
                         (<span style="color: #f1fa8c;">"org"</span> . <span style="color: #f1fa8c;">"http://orgmode.org/elpa/"</span>)
                         (<span style="color: #f1fa8c;">"melpa"</span> . <span style="color: #f1fa8c;">"http://melpa.milkbox.net/packages/"</span>)))
</pre>
</div>

<p>
Básicamente le estamos dando una lista de sitios donde buscar
paquetes. Por defecto, buscará solamente en <code>gnu</code>, sin embargo hay
otros lugares que mantienen paquetes interesantes, especialmente
<code>melpa</code>.
</p>

<p>
Al copiar, ten cuidado con los paréntesis, no te vaya a faltar ninguno
(suele ser el error más habitual cuando escribes código en <i>elisp</i>).
</p>

<p>
Después de guardar los cambios con <code>C-x C-s</code> tienes dos opciones:
</p>

<ol class="org-ol">
<li>Cerrar <i>Emacs</i> y volver a abrirlo, para que los cambios se carguen.</li>
<li>Cargarlos con el comando <code>M-x load-file &lt;RET&gt; ~/.emacs.d/init.el</code></li>
</ol>

<p>
Si todo ha ido bien y utilizas el comando <code>M-x list-packages</code> deberían
aparecer un montón de paquetes. ¿Demasiados? No te preocupes, no
tienes que cargarlos todos, sólo los que utilices. De momento
cargaremos sólo dos más.
</p>
</div>
<div id="outline-container-orgd370243" class="outline-3">
<h3 id="orgd370243">Ayuda con las combinaciones de teclas</h3>
<div class="outline-text-3" id="text-orgd370243">
<p>
Bien, ya que estamos vamos a ver si hay algún modo de facilitarnos la
vida. Y la hay. ¿Es muy complicado aprenderse todas las teclas? ¿Hay
un sinfín de combinaciones y te resulta acordarte de qué secuencia es
la que te lleva a ejecutar el comando que quieres?
</p>

<p>
La respuesta directa sería: llámalo directamente desde <code>M-x</code>. Pero eso
no es una solución, si no conoces tampoco el comando. Así pues, vamos
a instalar un paquete, que por su nombre podemos intuir de qué va:
<code>which-key</code>; que sería algo así como «qué tecla».
</p>

<p>
La forma directa de instalar es utilizar el comando <code>package-install</code>
llamándolo desde <code>M-x</code>. Si prefieres también puedes buscarlo (recuerda:
<code>C-s</code>) en la lista de paquetes y hacerlo pinchando en los <i>pichorros</i>
y <i>chismáticos</i> gráficos.
</p>

<p>
El siguiente paso es activarlo de manera general. <code>which-key</code> es un
modo menor que nos informa de las combinaciones de teclas y, como ya
he dicho, podemos tener varios modos menores activos. Para hacerlo,
quiero que sepas otra manera de acceder a los ajustes sin el menú. El
comando es <code>customize-group</code>.
</p>

<ol class="org-ol">
<li>Pulsa <code>M-x</code> y escribe <code>customize-group</code> y pulsa <code>&lt;RET&gt;</code></li>
<li>En el <i>prompt</i> que aparece escribe <code>which-key</code>.</li>
<li>En el <i>buffer</i> de opciones, busca una que se llama <i>Which Key Mode</i>
y despliégala. Si no aparece, tendrás que recargar el <code>init.el</code>
para que sepa que existe.</li>
<li>Pincha en <code>Toggle</code> y el valor cambiará a <i>on (non-nil)</i>.</li>
<li>No olvides pinchar también en <i>Apply and Save</i>.</li>
</ol>

<p>
¿Ya está activado? Lo sabrás porque entre los modos menores aparecerá
<code>WK</code>.
</p>

<p>
También lo puedes hacer de forma directa, sin tantos pasos escribiendo
directamente en nuestro <code>~/.emacs.d/init.el</code>:
</p>

<ol class="org-ol">
<li>Visita el fichero de inicio.</li>
<li>Ve al apartado donde se definen <code>custom-set-variables</code>.</li>
<li>Añade una línea que ponga: <code>'(which-key-mode t)</code>.</li>
</ol>

<p>
¿Qué método elegir? En el que más seguro te encuentres. Si no te
encuentras cómodo con la edición de fichero de código o eres muy
despistado con los detalles<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> mejor utiliza el modo gráfico.
</p>

<p>
Recarga el fichero de inicio: <code>M-x load-file</code> y <code>~/.emacs.d/init.el</code>.
Ahora pulsa <code>C-x</code> y observa qué ocurre en el <i>minibuffer</i>.
</p>
</div>
</div>
<div id="outline-container-org23b598f" class="outline-3">
<h3 id="org23b598f">Lista de opciones</h3>
<div class="outline-text-3" id="text-org23b598f">
<p>
Ya que hemos aprendido con un paquete, vamos a ver uno equivalente.
<code>ivy</code> es otro modo menor de los que se hacen casi imprescindibles. Su
nombre viene de <i>Incremental Vertical completYon</i>... bueno sí, un poco
cogido por los pelos, pero tampoco nos vamos a molestar por ello.
</p>

<p>
Los pasos son similares en la instalación de todos los paquetes, así
que podemos hacer los mismos del apartado anterior, pero sustituyendo
donde dice <code>which-key</code> por <code>ivy</code>. Por si necesitas que te lo refresque
para no ir para arriba en el artículo: <code>M-x package-install</code> y pulsa
<code>&lt;RET&gt;</code>, en el <i>prompt</i> cuando pregunte escribe <code>ivy</code> y pulsa <code>&lt;RET&gt;</code>.
Ya lo tienes instalado en un momentito.
</p>

<p>
Para activarlo, los pasos son muy similares, pero te voy a dar otra
opción<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. Esta vez vamos a ir más al grano en el ajuste y en lugar
de pedir todas las opciones habidas y por haber, vamos a utilizar un
comando con más precisión:
</p>

<ol class="org-ol">
<li>Pulsa <code>M-x</code> y escribe el comando <code>customize-option</code>, pulsa <code>&lt;RET&gt;</code>.</li>
<li>En el <i>prompt</i> que aparece escribe <code>ivy-mode</code>.</li>
<li>Despliega la opción que aparece y pincha en <i>Toggle</i> para
activarlo.</li>
<li>Y por supuesto, no olvides pinchar en <i>Apply and Save</i>.</li>
</ol>

<p>
¿Ya está activado? Entre los modos menores debe aparecer <code>ivy</code>.
</p>

<p>
Bien, vamos a ver para qué sirve: pulsa <code>M-x</code> ¿Qué ha pasado? Pues es
sencillo, igual que <code>which-key</code> nos <i>chiva</i> la siguiente tecla, <code>ivy</code>
nos chiva y completa los comandos y opciones.
</p>
</div>
</div>
</div>
<div id="outline-container-orgb5d2f64" class="outline-2">
<h2 id="orgb5d2f64">Conclusiones</h2>
<div class="outline-text-2" id="text-orgb5d2f64">
<p>
Como hemos visto, <i>Emacs</i>, viene cargado con un arsenal de
funcionalidad que además se puede incrementar instalando los paquetes
que necesitemos. Sabiendo esos pasos creo que serás capaz de
instalarte cualquier paquete que necesites. Si eres programador
encontrarás detalladas guías por <i>Internet</i> de cómo convertir este
editor en el mejor <i>IDE</i> para trabajar con el lenguaje que necesites.
Sólo tendrás que instalar y configurar los paquetes necesarios.
</p>

<p>
Si no eres programador y sólo te atrae porque has oído la capacidad
que tiene el modo <code>org</code> para organizarte la vida o para generar
documentos complejos con el apoyo de LaTeX o incluso para tener un
<i>blog</i> como éste.
</p>

<p>
En la próxima entrega hablaremos de la <i>agenda</i> que viene incorporada
en <i>Emacs</i> y en cómo configurarla mínimamente para, por ejemplo, hacer
que nos muestre las fechas, meses y días de la semana, en español o en
cualquier lengua.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Los paréntesis y caracteres especiales como <code>'</code>, son
importantes y pueden hacer que nuestro fichero de inicio deje de
funcionar. Por eso, es recomendable que si no eres programador y no te
encuentras seguro con esas acciones, utilices el modo gráfico que
guardará el código necesario de forma correcta. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Será por opciones en <i>Emacs</i>. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/dired/index.html">dired</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[dired]]></category>
  <link>https://notxor.nueva-actitud.org/2019/12/04/herramientas-para-el-sistema.html</link>
  <pubDate>Wed, 04 Dec 2019 18:47:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Trabajo con ventanas y buffers]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-11-30</div>
<p>
Hemos tenido ya dos entregas anteriores de este «minicurso» o tutorial
de cómo empezar a utilizar <i>Emacs</i>. De momento hemos visto cómo
podemos abrir, modificar y guardar ficheros. También cómo movernos por
una ventana con el cursor.
</p>
<div id="outline-container-org27f2e3f" class="outline-2">
<h2 id="org27f2e3f">Plegado del texto en el modo org</h2>
<div class="outline-text-2" id="text-org27f2e3f">
<p>
Para continuar con el <i>tutorial</i> o cursillo que estamos haciendo sobre
<i>Emacs</i>, enfocado a los no programadores y gentes venidas de otros
entornos de trabajo, vamos a necesitar el fichero <code>org</code> que guardamos
el otro día. Tenemos que abrirlo, si no te acuerdas del comando, no te
preocupes: utiliza el ratón y el menú <code>File -&gt; Open File...</code>. Si
prefieres ir acostumbrándote a los comandos: <code>C-x C-f</code> (<code>find-file</code>),
recuerda que puedes utilizar <code>&lt;TAB&gt;</code> para completar el <i>path</i> y el
nombre.
</p>

<p>
¡Sorpresa! El <i>buffer</i> sólo contiene:
</p>

<pre class="example" id="org7ed8afd">
* Esto es un título de primer nivel...
</pre>

<p>
¡¿Cómo?! ¡Si lo tecleé entero!... No te apures. en esa línea pulsa
<code>&lt;TAB&gt;</code> y mira lo que aparece:
</p>

<pre class="example" id="org83ca4f2">
* Esto es un título de primer nivel

Esto es un párrafo normal. A partir de ahora puedes escribir
libremente en el editor. La separación entre párrafos es una línea en
blanco. Por eso, estas líneas son un párrafo.

Esto es el segundo párrafo. Como se puede ver está separado por una
línea en blanco del párrafo anterior. Si pulsamos =M-q= en un párrafo,
nos lo justifica y divide en líneas.

** Esto es un título de segundo nivel...
** Formato del texto...
** Bloques...
** Tablas...
</pre>

<p>
¡Ey! ¡Aparecen las cabeceras de segundo nivel! Vuelve a pulsar
<code>&lt;TAB&gt;</code>. ¡Ahora aparece todo el texto! Como nos indica el área de eco,
estamos cambiando entre <code>FOLDED</code>, <code>CHILDREN</code> y <code>SUBTREE</code>. Ya veremos
cómo se puede hacer que se muestre todo el texto al cargar el fichero
cuando veamos más cosas del modo <code>org</code> y sus infinitas
características. El tema es que veas que aunque tengas un fichero de
texto de cientos de líneas, puedes trabajar con cada apartado
ocultando el resto. Si te has fijado, cuando una cabecera está plegada
muestra al final <code>...</code><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>
</div>
<div id="outline-container-org5fc8c7e" class="outline-3">
<h3 id="org5fc8c7e">Una anotación sobre la ayuda</h3>
<div class="outline-text-3" id="text-org5fc8c7e">
<p>
A parte del manual de <i>Emacs</i> que viene con el editor, hay otras
formas de acceder a la ayuda. Por ejemplo, pulsa <code>C-h m</code>
(<code>describe-mode</code>) que mostrará en un <i>buffer</i> de ayuda las
combinaciones de teclas y acciones que tiene un <i>buffer</i> activadas
según los modos que tenga cargados. Aparecerán primero las teclas que
correspondan al modo mayor activo.
</p>

<p>
También podemos hacer la búsqueda al revés. Nos viene a la memoria una
combinación de teclas pero no estamos seguros de que es el que
necesitamos, ¿cómo nos aseguramos? Si pulsamos <code>C-h k</code> nos pedirá que
introduzcamos una combinación de teclas, al hacerlo nos mostrará un
<i>buffer</i> de ayuda explicándonos qué comando lanza esa combinación y la
ayuda que tenga asociada. Si sólo queremos que nos diga el comando,
podemos utilizar <code>C-h c</code>.
</p>

<p>
Hay muchas más combinaciones para acceder a distintos aspectos de la
ayuda, pero creo que te he contado las básicas y te las voy a resumir
de nuevo:
</p>

<dl class="org-dl">
<dt><code>C-h i</code></dt><dd>Ayuda al estilo <i>info</i> de Unix (<code>info</code>).</dd>
<dt><code>C-h r</code></dt><dd>Acceder al manual de <i>Emacs</i> (<code>info-emacs-manual</code>).</dd>
<dt><code>C-h m</code></dt><dd>Muestra documentación de los modos activos
(<code>describe-mode</code>).</dd>
<dt><code>C-h k</code></dt><dd>Muestra documentación sobre el comando (<code>describe-key</code>).</dd>
<dt><code>C-h c</code></dt><dd>Muestra el nombre del comando asociado
(<code>describe-key-briefly</code>).</dd>
</dl>
</div>
</div>
</div>
<div id="outline-container-orgb71a81b" class="outline-2">
<h2 id="orgb71a81b">Copiar, cortar y pegar</h2>
<div class="outline-text-2" id="text-orgb71a81b">
<p>
Como en otras cosas que hemos visto hasta ahora, <i>Emacs</i> no sigue las
convenciones en las acciones de cortar y pegar. ¿Por qué? Pues porque
cuando se estandarizaron para otros programas las combinaciones de
teclas <code>C-c</code>, <code>C-x</code> y <code>C-v</code>, <i>Emacs</i> ya llevaba muchos años utilizando
su complejo sistema de comandos y combinaciones de teclas. Las
acciones son las mismas, pero las teclas distintas.
</p>

<dl class="org-dl">
<dt><b>Cortar</b></dt><dd><code>C-w</code> (<code>kill-region</code>).</dd>
<dt><b>Copiar</b></dt><dd><code>M-w</code> (<code>kill-ring-save</code>).</dd>
<dt><b>Pegar</b></dt><dd><code>C-y</code> (<code>yank</code>).</dd>
</dl>

<p>
Tendría que hablar un poco de cómo funciona el borrado en <i>Emacs</i> para
explicar todas las posibilidades, y sobre todo del <i>kill ring</i>. Sin
embargo es muy complicado y son muchas las opciones no sólo las tres
anteriores que son las habituales en otros editores. Más adelante, es
posible que veamos cómo se pueden marcar zonas, mandarlas al anillo de
borrado y recuperarlas. De momento, nos vamos a quedar con que al
marcar el texto y borrarlo, lo manda a una zona de memoria especial
que se llama <i>Kill Ring</i>, ─o <i>anillo de borrado</i> si quieres una
traducción aproximada al significado─. Podrías pensar en el como una
especie de <i>portapapeles</i> porque se parecen conceptualmente. Ya te
adelanto que no es sólo eso, pero te sirve el símil para entenderlo
de primeras. Si alargamos mucho estas entradas de introducción,
prometo que hablaré con más detalle del <i>kill ring</i>.
</p>
</div>
</div>
<div id="outline-container-orge40a019" class="outline-2">
<h2 id="orge40a019">Buscar y reemplazar</h2>
<div class="outline-text-2" id="text-orge40a019">
<p>
Una de las funciones más importantes de cualquier editor es la de
buscar y sustituir texto de una manera eficiente y sencilla para el
usuario. Otros editores más gráficos despliegan un diálogo modal con
un campo de edición donde escribir lo que buscamos y por qué debemos
reemplazarlo. <i>Emacs</i> para eso tiene el <i>minibuffer</i>. Los comandos más
utilizados, podríamos decir: los más básicos, son <code>C-s</code>
(<code>isearch-forward</code>) y <code>C-r</code> (<code>isearch-backward</code>). Al invocarlos nos
pedirá que introduzcamos una cadena en el <i>minibuffer</i> y veremos cómo
el cursor va saltando a la siguiente ─o la anterior, según el comando─
cadena en el <i>buffer</i> que se corresponda con lo buscado. Como el
movimiento se aprende andando, vamos a verlo buscando algo, como por
ejemplo:
</p>

<ol class="org-ol">
<li>Pulsa la combinación <code>C-s</code>, fíjate que el área de <i>prompt</i> muestra
la cadena <code>I-search:</code>.</li>
<li>Pulsa una <code>s</code>, fíjate que el cursor salta a la siguiente «s» del
<i>buffer</i> y muestra todas las eses marcadas.</li>
<li>Pulsa una <code>o</code>, fíjate de nuevo, que salta a la siguiente ocurrencia
de «so» y marca todas las coincidencias.</li>
<li>Pulsa una <code>l</code>. De nuevo el cursor salta a la primera aparición de
la palabra «sol» y marca las otras ocurrencias.</li>
</ol>

<p>
Pulsa <code>C-g</code> para anular la búsqueda... el cursor vuelve donde estaba
¿Por qué? ¿Qué ha pasado? Este es uno de los casos en que la posición
del <i>punto</i> no sigue al cursor. Tenlo en cuenta si lo que haces es
buscar una cadena en particular para moverte hasta allí, tienes que
forzar que se desplace el punto una vez encuentres el sitio,
simplemente moviendo el cursor con <code>C-b</code> o <code>C-f</code> o con las teclas de
cursor, en el área de eco nos dirá <i>Mark saved where search started</i>.
</p>

<p>
Podemos reanudar la última búsqueda. Ahora si pulsamos <code>C-s C-s</code>,
vemos que reaparece «sol» en el espacio y salta a la siguiente
aparición de la cadena. Por supuesto, los mismos pasos son correctos
para una búsqueda hacia atrás, pero con la combinación <code>C-r</code>. Además,
si ahora pulsamos <code>C-r C-r</code>, <i>Emacs</i> asumirá que la cadena guardada
para la última búsqueda: «sol», es la adecuada para buscar hacia
atrás. Si un término no se encuentra el mensaje del <i>prompt</i> será
<i>Failing I-Search:</i> y nos dará opción a modificar la cadena de
búsqueda que estamos utilizando.
</p>

<p>
Además de esa búsqueda simple, podemos utilizar también otra búsqueda
más compleja y completa mediante expresiones regulares pulsando
<code>C-M-s</code> y <code>C-M-r</code>. Si no sabes qué son las <i>expresiones regulares</i> no
te preocupes, seguramente no las necesitarás para el trabajo que
puedas hacer con <i>Emacs</i>, pues son cosas más útiles para
programadores. Si sí sabes qué son y te interesa el tema, busca en la
ayuda (<code>C-h r</code>) el apartado sobre <code>regexp search</code> y recuerda que
puedes alternar entre una búsqueda <code>regexp</code> y <code>no-regexp</code> pulsando la
combinación <code>M-s</code> ó <code>M-s r</code> (<code>isearch-toggle-regexp</code>).
</p>

<p>
Sin embargo, aunque la búsqueda es importante, es más potente la
sustitución. Igual que con la acción de buscar, la acción de sustituir
también cuenta con su versión compleja mediante <code>regexp</code>, que no voy a
contar aquí, porque la mayoría de los usuarios apenas las
utilizamos.
</p>

<p>
Si buscamos modos de reemplazar una cadena en un texto en la ayuda,
seguramente tropecemos con el comando <code>replace-string</code>. Está muy bien,
porque eso reemplaza una cadena por otra... pero sólo una vez. Eso es
suficiente en muchas ocasiones, sin embargo, es habitual que esa
sustitución deba repetirse por todo el texto, para lo cual es más útil
el comando <code>M-%</code> (<code>query-replace</code>). Realiza los siguientes pasos:
</p>

<ol class="org-ol">
<li>Ve al principio del <i>buffer</i> <code>primer-texto.org</code> pulsando la
combinación <code>M-&lt;</code>.</li>
<li>Pulsa la tecla <code>M-%</code> y aparecerá en el área de <i>prompt</i> el mensaje:
<i>Query replace</i>.</li>
<li>Escribe la cadena «sol» (como verás ahora el cursor se mantiene
situado en el mismo sitio.</li>
<li>Al pulsar <code>&lt;RET&gt;</code> preguntará <i>Query replace sol with</i>.</li>
<li>Teclea «luna» y verás que al pulsar <code>&lt;RET&gt;</code> ha saltado a la primera
aparición de la cadena «sol»</li>
<li>Pulsa <code>y</code> y verás cómo se sustituye «sol» por «luna» y saltará a la
siguiente ocurrencia.</li>
</ol>

<p>
Así podremos saltar de una ocurrencia a otra pulsando <code>y</code> cuando
queremos sustituir y <code>n</code> cuando no. Si queremos sustituir todas las
apariciones sin que pregunte más, pulsaremos <code>!</code>. Si lo que queremos
es que deje de buscar pulsaremos <code>q</code> o si lo que queremos es que haga
esta última sustitución y salga, utilizaremos el <code>.</code>
</p>

<p>
Existen más teclas, como la posibilidad de arrepentirte de todas las
sustituciones con <code>U</code> o de la última con <code>u</code>, pero son menos
frecuentes y es mejor que las consultes en la ayuda.
</p>

<p>
También hay que recordar que:
</p>

<ol class="org-ol">
<li>las sustituciones pueden modificar la posición del punto, no como
la mera búsqueda, que como hemos visto antes sólo movía el cursor,</li>
<li>y no hay sustituciones hacia atrás, por lo que si quieres realizar
un <code>query-replace</code> te aconsejo que antes vayas al principio del
<i>buffer</i>.</li>
</ol>

<p>
¿Qué tal si practicas un poco la sustitución? Estamos toqueteando un
fichero de pruebas, siéntete libre de torturarlo hasta hacerlo
incomprensible.
</p>
</div>
</div>
<div id="outline-container-org4bc37e7" class="outline-2">
<h2 id="org4bc37e7">Obsesos de la posición del cursor y el control manual</h2>
<div class="outline-text-2" id="text-org4bc37e7">
<p>
Recuerdo una conversación con un amigo. Me vio trabajando en mi
ordenador, con <i>Emacs</i> escribiendo un texto sin preocuparme de otra
cosa que del contenido. Le llamó la atención esta manera de trabajar
<i>tan antigua</i>, habiendo editores que te permiten ver el texto como si
lo estuvieras imprimiendo en una hoja en blanco virtual. También
recuerdo que traía su parte de un trabajo común, escrita en un
maravilloso archivo y cuando lo abrimos en mi ordenador, su estructura
resultó del todo incomprensible: páginas a medio llenar, un montón de
líneas en blanco, ausencia de títulos de apartados, saltos de línea en
mitad de una. En fin, un caos de texto. Le intenté contar que lo
importante de un texto es su estructura, no cómo se imprimirá. Le
expliqué que lo de poner los títulos y marcarlos como tales es
importante, sobre todo cuando sabes que ese texto lo vas a llevar a
otro ordenador, que no tendrá los mismos tipos de letra o incluso la
misma versión del programa que utilice para la edición.
</p>

<p>
El caso es que aquel día <a href="https://pandoc.org/">pandoc</a>, con la inestimable ayuda de <a href="https://es.wikipedia.org/wiki/Iconv">iconv</a>
convirtieron el contenido que traía a texto plano al que luego nos
llevó un poco de tiempo en dotar de estructura. Recuerdo que mientras
lo hacíamos (bueno, lo iba haciendo yo, mientras él se sentaba a mi
lado nervioso porque no entendía nada), dijo que cómo sabía yo que
estaba llegando al final de una línea para saltar a la siguiente si no
hay una regla arriba que lo indique.
</p>

<p>
Mi amigo, parece ser, que metía los saltos de línea también donde él
quería, porque era lo que había aprendido cuando estudió
<i>mecanografía</i>, además, algunas veces incluso dividía alguna palabra
escribiendo un guión y un salto de línea... (Un infierno). El caso es
que cuando activé el <code>ruler-mode</code> parece que se tranquilizó un poco al
ver que había una regla superior donde se marcaba la posición del
cursor con el carácter <code>|</code>. Además, había dos caracteres <code>#</code> y <code>¶</code> que
marcaban la columna de comentarios (<code>comment-column</code>) y el salto de
línea (<code>fill-column</code>). El que yo tuviera activado el <code>auto-fill-mode</code>
y el texto saltara a la siguiente línea de forma automática y yo no me
preocupara de cómo, le chirriaba un poco.
</p>

<p>
Preguntó también cómo sabía yo cuándo venía un salto de página, que le
faltaba una regla vertical. Ahí no pude ayudarle tanto, no hay una
manera de mostrar una regla en algún margen, como mucho los números de
línea con <code>linum-mode</code>. En mi caso, cuando estoy escribiendo texto me
molestan los números de línea, prefiero activar <code>column-number-mode</code>,
que cambia en la línea de estado el mensaje de <code>L00</code> por un formato
<code>(Linea, columna)</code> y así está controlado el cursor de un vistazo. Y
dejo para los modos de programación el que muestre a la izquierda el
número de línea.
</p>
</div>
</div>
<div id="outline-container-orgdf02ca7" class="outline-2">
<h2 id="orgdf02ca7">Navegar entre ventanas</h2>
<div class="outline-text-2" id="text-orgdf02ca7">
<p>
En general, no sólo tenemos que modificar un fichero, al contrario, en
muchas ocasiones tenemos que trabajar con varios ficheros y para eso
tenemos que navegar entre ventanas, <i>buffers</i> y ficheros.
</p>

<p>
Ya he hablado sobre <i>buffers</i>, cómo abrirlos y cómo cambiar de un
<i>buffer</i> a otro. Recuerdo la combinación <code>C-x b</code> para cambiar de
<i>buffer</i>. Hay más formas de cambiar lo que estemos editando en
pantalla, por ejemplo con <code>C-x &lt;LEFT&gt;</code> o con <code>C-x &lt;RIGHT&gt;</code>.  Pero esto
ya lo vimos, ─aunque no viene mal recordarlo─.
</p>

<p>
Muchas veces necesitamos cambiar de <i>buffer</i> pero no queremos dejar de
ver el que tenemos ahora en ventana. La opción sería abrir otra
ventana y cambiar a ella mostrando el <i>buffer</i>. Para ello podemos
utilizar la combinación <code>C-x 4 b</code>. Si sustituimos el <code>4</code> por un <code>5</code> lo
que hacemos es abrir un nuevo <i>frame</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.
</p>

<p>
Voy a hacer un repaso de cómo abrir, cerrar <i>buffers</i>, <i>ventanas</i> y
<i>frames</i>, no es necesario que te aprendas todas las teclas de
memoria, lo harás con el uso, pero así reunidas se pueden consultar
de un vistazo:
</p>

<ul class="org-ul">
<li>Abrir una ventana al lado de la actual: <code>C-x 3</code>.</li>
<li>Abrir una ventana debajo de la actual: <code>C-x 2</code>.</li>
<li>Abrir un <i>buffer</i> en otra ventana: <code>C-x 4 b</code>.</li>
<li>Abrir un <i>buffer</i> en otro frame: <code>C-x 5 b</code>.</li>
<li>Obtener una lista de <i>buffers</i> y cambiarlo con <code>&lt;RET&gt;</code>: <code>C-x C-b</code>.</li>
<li>Cerrar ventanas sin cerrar el <i>buffer</i>:
<ul class="org-ul">
<li>Cerrar todas las ventanas menos la actual: <code>C-x 1</code>.</li>
<li>Cerrar la ventana actual: <code>C-x 0</code>.</li>
</ul></li>
<li>Cerrar el <i>frame</i> actual sin cerrar la sesión: <code>C-x 5 0</code>.</li>
<li>Cerrar todos los <i>frames</i> menos el actual: <code>C-x 5 1</code>.</li>
<li>Navegar entre <i>buffers</i> sin movernos de la ventana: <code>C-x &lt;LEFT&gt;</code> y
<code>C-x &lt;RIGHT&gt;</code>.</li>
<li>Cerrar un <i>buffer</i>: <code>C-x k</code>, por defecto cierra el actual.</li>
</ul>

<p>
Como hemos visto con <code>C-x 4 b</code> podemos abrir un <i>buffer</i> en una nueva
ventana, pero también podemos abrir (<i>visitar</i>) un fichero en otra
ventana con <code>C-x 4 f</code><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>, o un directorio con <code>C-x 4 d</code>.
</p>
</div>
</div>
<div id="outline-container-orgc93b11c" class="outline-2">
<h2 id="orgc93b11c">Otras acciones con los buffers</h2>
<div class="outline-text-2" id="text-orgc93b11c">
<p>
No voy a enrollarme mucho para no alargar inútilmente esta entrega:
</p>

<ul class="org-ul">
<li>Renombrar el <i>buffer</i> actual: <code>M-x rename-buffer</code>.</li>
<li>Renombrar el <i>buffer</i> actual añadiendo un número: <code>M-x
  rename-uniquely</code>.</li>
<li>Alternar entre modo de sólo lectura y edición de un <i>buffer</i>: <code>C-x
  C-q</code> (<code>read-only-mode</code>).</li>
<li>Añadir el contenido del <i>buffer</i> actual por encima del cursor/punto,
a otro <i>buffer</i>: <code>M-x append-to-buffer</code>.</li>
<li>Añadir el contenido de otro <i>buffer</i> en la posición del
cursor/punto: <code>M-x insert-buffer</code>.</li>
</ul>
</div>
</div>
<div id="outline-container-org4a7256e" class="outline-2">
<h2 id="org4a7256e">Conclusiones</h2>
<div class="outline-text-2" id="text-org4a7256e">
<p>
Es muy recomendable que comiences a jugar con los ficheros, buffers,
ventanas y marcos; que copies, cortes y pegues texto; que te
familiarices con la ayuda. Que juguetees con estas cosas sin miedo.
</p>

<p>
Si ves otros tutoriales, o artículos o cursos, verás que comienzan
recomendando que instales <i>tales o cuales</i> paquetes, o que configures
tal o cual funcionalidad de una determinada manera, y yo aún no he
hecho lo mismo. Mi intención es seguir así de momento hasta que
agotemos las funcionalidades que vienen de fábrica con <i>Emacs</i>.
Prefiero dedicar más tiempo a que te acostumbres al entorno y a la
ayuda. Porque el entorno, las ventanas, <i>buffers</i>, <i>frames</i> y ficheros
los vas a utilizar en todas las <i>sesiones</i> y la ayuda es lo que te
puede servir para salir de dudas en aspectos que no se tocan en los
tutoriales, artículos o cursos; o simplemente en esas raras ocasiones
que necesitas una determinada funcionalidad tan infrecuente que de una
vez a otra, no te acuerdas del comando, o la tecla.
</p>

<p>
No te preocupes por aprenderte las combinaciones de teclas, al final
te aprenderás las que utilices de una manera frecuente. Como resumen
me gustaría que te quedaras con una impresión general, ─que no siempre
es cierta, pero que puede ayudarte a reconocer comandos a simple
vista─. Normalmente, los comandos relacionados con el funcionamiento
relacionado con el editor, comienzan por <code>C-x</code>, mientras que las
funciones o comandos que se relacionan un modo, comienzan por <code>C-c</code>.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
También se puede cambiar, pero una vez te acostumbras no
necesitas nada más visual que los tres puntos para saber que esa
cabecera está plegada. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Algo muy útil cuando tienes varios monitores y quieres
utilizarlos todos. Recordando, que seguimos en la misma sesión, es
decir, tenemos todos los <i>buffers</i> abiertos a nuestra disposición en
todos los <i>frames</i> y en cualquiera de ellos podemos cerrar la sesión. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Si utilizamos <code>C-x 4 r</code> abriremos el fichero pero en modo de
sólo lectura.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2019/11/30/trabajo-con-ventanas-y-buffers.html</link>
  <pubDate>Sat, 30 Nov 2019 18:44:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Primeros pasos con el editor]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-11-28</div>
<p>
<a href="https://notxor.nueva-actitud.org/blog/2019/11/26/introduccion-a-emacs/index.html">El otro día vimos unos pocos conceptos</a> para tener clara la
terminología y aclararnos a la hora de trabajar. No te preocupes si no
has entendido algo de lo que hablé allí, porque con el uso lo
entenderás rápidamente.
</p>

<p>
En esta entrega vamos a continuar con el uso de nuestro editor
favorito, ─al menos el mío, el tuyo espero que lo sea─. Hablaba la
semana pasada de que <i>Emacs</i> tiene más de 40 años y sigue en la
brecha. En ese tiempo, hemos visto pasar por nuestro lado muchas
tecnologías para la edición de texto y la programación, mientras
algunas quedaban como pilares de uso diario: como <a href="https://www.vim.org/"><i>Vim</i></a> o <a href="https://www.gnu.org/software/emacs/"><i>Emacs</i></a>.
</p>

<p>
Si bien, <i>Emacs</i> ha sabido hacerse un hueco para usos que están más
allá de la programación, resulta un poco difícil ordenar las ideas y
funcionalidades para que el acercamiento de esa gente que pretende
usarlo para otras tareas, y que no son programadores, no desistan a
las primeras de cambio. Por eso me decidí a escribir esta serie de
artículos, pues me di cuenta de que la mayoría de la documentación,
entradas de <i>blogs</i>, instrucciones de instalación de paquetes, etc.,
están escritas para <i>iniciados</i>. Ahora me doy cuenta que, como ocurre
en todos los sistemas complejos, no hay explicaciones sencillas y
todos los conceptos están tan íntimamente relacionados que no se
pueden separar de ninguna manera simple.
</p>
<div id="outline-container-org68b75d6" class="outline-2">
<h2 id="org68b75d6">La ayuda</h2>
<div class="outline-text-2" id="text-org68b75d6">
<p>
<i>Emacs</i> viene con una documentación completa y vamos a utilizarla para
aprender a movernos por una ingente cantidad de información que nos
resultará útil para sacarle todo el partido a nuestro editor.  Sin
embargo, tanta información a veces abruma y no encontramos justo lo
que buscamos, hay que aprender a utilizarla.
</p>

<p>
Si ya has utilizado con anterioridad la herramienta <code>info</code> de <code>Unix</code>
estás de enhorabuena, porque la ayuda que viene con <i>Emacs</i> se basa en
ella. Si no lo has hecho, sigue estos sencillos pasos:
</p>

<ol class="org-ol">
<li>Pulsa <code>C-h r</code>, eso debería abrir un <i>buffer</i> con el manual de
<i>Emacs</i>. Si lo tuyo es el ratón: <code>Help -&gt; Read the Emacs Manual</code> te
llevará al mismo sitio.<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup></li>

<li><p>
Pulsa <code>h</code> directamente en ese <i>buffer</i>, debería llevarte a una
pequeña explicación de cómo funciona <code>info</code>.
</p>

<p>
Básicamente te cuenta que existen enlaces y que puedes navegar por
las distintas páginas con los comandos <code>(n)ext</code>, <code>(p)rev</code>,
<code>(u)p</code>... y alguno más que no voy a detallar ahora. Lo importante
es que te quedes que la navegación por los distintos apartados es
consistente con las teclas de movimiento de <i>Emacs</i> (no te
preocupes, las veremos enseguida).
</p></li>
</ol>

<p>
Para moverte por el <i>buffer</i> de ayuda puedes utilizar las teclas de
movimiento del editor o sus equivalentes del cursor.
</p>
</div>
</div>
<div id="outline-container-org1568307" class="outline-2">
<h2 id="org1568307">Un poco sobre configuración</h2>
<div class="outline-text-2" id="text-org1568307">
<p>
La mayoría de usuarios de <i>Emacs</i> preferimos modificar el código de
nuestro fichero de inicio, ese que carga todos nuestros <i>gadgets</i> y
los ajusta a nuestros gustos. Si vienes por primera vez a nuestra
herramienta de edición y no eres programador estarás preguntándote:
«¿tengo que aprender a programar para manejar el editor?». La mejor
respuesta que se me ocurre es: «es aconsejable, pero no
imprescindible». O dicho de otro modo, la configuración se puede
gestionar de un modo más gráfico. Y quiero explicar un poco, con un
par de ejemplos cómo se puede hacer, utilizando los menús y el ratón
para quien esté acostumbrado a ese uso.
</p>

<p>
Por ejemplo, vamos a cambiar el aspecto del editor modificando el
<i>tema</i>. Un <i>tema</i> es un conjunto de acciones visuales que modifican el
aspecto que tendrá nuestro editor en pantalla. Pincha en <code>Options -&gt;
Customize Emacs -&gt; Custom Themes</code>. Tras hacer eso, nos aparecerá un
<i>buffer</i> con las opciones disponibles.  Siéntete libre de seleccionar
el <i>tema</i> que más se ajuste a tus gustos y acuérdate de pulsar el
botón de guardar los cambios y así, cada vez que inicies el editor lo
verás con el tema que hayas seleccionado... ¿Qué te ha parecido raro?
¡Oh, sí! <i>Emacs</i> ha abierto un <i>buffer</i>. Quizá estés acostumbrado a
que los programas modernos abren marcos modales donde seleccionar las
opciones. Y aunque le has dado al botón, el <i>buffer</i> sigue ahí, en
pantalla. Si te molesta mucho tener un <i>buffer</i> abierto pulsa la
combinación <code>C-x k</code> y aparecerá en la última linea el siguiente texto:
<code>Kill buffer (default *Custom Themes*)</code>, si pulsas <code>&lt;RET&gt;</code> se borrará
de pantalla.
</p>


<figure id="org1b03af0">
<img src="./imagen/seleccion-theme.png" alt="seleccion-theme.png">

</figure>

<p>
Vamos con otro ejemplo, que no tiene una entrada en el menú de manera
directa. Lo que queremos hacer es ahorrarnos el <i>buffer</i> de la ventana
de inicio de <i>Emacs</i>. Para ello vamos a pinchar en <code>Options -&gt; 
Customize Emacs -&gt; Specific Option...</code>. En la última línea (línea de
eco o de <i>prompt</i>) habrá aparecido el texto <code>Customize variable:</code> y el
cursor allí, nos indica que está esperando que le digamos qué variable
queremos modificar. Nuestro objetivo es modificar la variable
<code>inhibit-startup-screen</code>, pero vamos a ver otra característica del
editor que nos facilita la vida: escribe <code>in</code> y pulsa <code>&lt;TAB&gt;</code>... ¡eh!
nos muestra un montón de opciones, pincha con el ratón en la que
estamos buscando. Si sólo ha movido el cursor a ella, pero sigue
mostrando las opciones, pulsa <code>&lt;RET&gt;</code> y te abrirá el <i>buffer</i> para
modificar la variable. Pincha en el botón <code>Toggle</code> y luego en <code>Apply
and Save</code>.
</p>

<p>
Si ahora cierras <i>Emacs</i> y vuelves a cargarlo, deberías verlo con el
tema seleccionado y la ventana de inicio es un <i>buffer</i> que, como
puedes apreciar en la línea de estado, se llama <code>*scratch*</code>.
</p>
</div>
</div>
<div id="outline-container-org31f978c" class="outline-2">
<h2 id="org31f978c">Mirando el código, abriendo un fichero</h2>
<div class="outline-text-2" id="text-org31f978c">
<p>
Los cambios que has realizado se han guardado en un fichero y vamos a
<i>visitarlo</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. Pulsa <code>C-x C-f</code> y te pedirá el nombre de un
fichero, también lo puedes hacer de forma gráfica con el menú <code>File -&gt;
Open File...</code>. Seguramente tu configuración se habrá grabado en el
fichero <code>~/.emacs</code> o en el fichero <code>~/.emacs.d/init.el</code>, dependiendo
de la versión. Es recomendable, desde la versión 24 del editor, que
todas las configuraciones se muevan a <code>init.el</code> dentro del directorio
<code>.emacs.d</code>, para tener todas las dependencias, paquetes y otras
herramientas en el mismo directorio. Por tanto, si te ha creado un
fichero <code>.emacs</code> muévelo a <code>.emacs.d/init.el</code>, con renombrarlo debería
ser suficiente.
</p>

<p>
Bien, si estás utilizando el modo gráfico y no ves ningún fichero de
los que te digo, selecciona <code>Show hidden files</code> en el diálogo de
selección de fichero.
</p>

<p>
¿Dos formas de abrir los ficheros? Sí, y aún te voy a presentar
otra. Pulsa: <code>C-x d</code>, en la línea de eco te pregunta por un
directorio, pulsa <code>&lt;RET&gt;</code> ¡Te presento a <code>Dired</code>! Mueve el cursor al
fichero o directorio que quieras con las flechas de cursor (luego
veremos cómo movernos con otras teclas) y pulsa <code>&lt;RET&gt;</code>. ¿Lo ha
abierto? Si has pulsado sobre un fichero lo habrá abierto en un
<i>buffer</i> de edición, si has pulsado sobre un directorio lo habrá
abierto en un <i>buffer</i> de <code>Dired</code>. Si el fichero era una imagen, la
habrá abierto en un <i>buffer</i> de imagen.
</p>

<p>
<code>Dired</code> tiene muchas más opciones y tendrá un artículo para él sólo en
un futuro no muy lejano. De momento, quédate con que existe y que te
permite moverte por los ficheros y directorios de una manera cómoda y
sin salir del editor. <code>Dired</code> es un <i>paquete</i><sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> de los que vienen
con <i>Emacs</i>, como <code>Org</code> y que le dan al editor una funcionalidad extra
convirtiéndolo en la <i>navaja suiza</i> que es.
</p>

<p>
Bien, en todo caso, el código que se ha generado es el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(custom-set-variables
 <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">custom-set-variables was added by Custom.
</span> <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">If you edit it by hand, you could mess it up, so be careful.
</span> <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Your init file should contain only one such instance.
</span> <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">If there is more than one, they won't work right.
</span> '(custom-enabled-themes (<span style="color: #ff79c6; font-weight: bold;">quote</span> (misterioso)))
 '(inhibit-startup-screen t))
(custom-set-faces
 <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">custom-set-faces was added by Custom.
</span> <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">If you edit it by hand, you could mess it up, so be careful.
</span> <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Your init file should contain only one such instance.
</span> <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">If there is more than one, they won't work right.
</span> )
</pre>
</div>

<p>
Como se puede ver, lo que hemos hecho gráficamente es establecer dos
variables en <code>custom-set-variables</code>: una se llama
<code>custom-enabled-themes</code> y se establece a «misterioso» y la otra es
<code>inhibit-startup-screen</code> y la pone a <code>t</code> (<i>true</i>), por lo que se
inhibirá la ventana de bienvenida.
</p>
</div>
<div id="outline-container-orgab68e98" class="outline-3">
<h3 id="orgab68e98">Moviéndonos por la ventana</h3>
<div class="outline-text-3" id="text-orgab68e98">
<p>
Para movernos por un <i>buffer</i> siempre vamos a utiliza las mismas
teclas. Sin ánimo de ser exhaustivo, voy a nombrar sólo las teclas más
habituales o utilizadas. Al menos las que yo más utilizo, aquí va una
lista de las teclas y su correspondiente <i>comando</i>:
</p>

<ul class="org-ul">
<li>Por líneas y caracteres:

<dl class="org-dl">
<dt><code>C-n</code></dt><dd>Ir a la siguiente línea (<code>next-line</code>).</dd>
<dt><code>C-p</code></dt><dd>Ir a la línea anterior (<code>previous-line</code>).</dd>
<dt><code>C-f</code></dt><dd>Ir al siguiente carácter (<code>forward-char</code>).</dd>
<dt><code>C-b</code></dt><dd>Ir al carácter anterior (<code>backwar-char</code>).</dd>
<dt><code>C-a</code></dt><dd>Ir al inicio de la línea (<code>move-beginning-of-line</code>).</dd>
<dt><code>C-e</code></dt><dd>Ir al final de la línea (<code>move-end-of-line</code>).</dd>
</dl></li>

<li>Por palabras:

<dl class="org-dl">
<dt><code>M-b</code>, <code>M-&lt;LEFT&gt;</code></dt><dd>Ir a la palabra anterior o izquierda
(<code>backward-word</code>, <code>left-word</code>)</dd>
<dt><code>M-f</code>, <code>M-&lt;RIGHT&gt;</code></dt><dd>Ir a la palabra siguiente o derecha
(<code>forward-word</code>, <code>right-word</code>).</dd>
</dl></li>

<li>En el <i>buffer</i>:

<dl class="org-dl">
<dt><code>M-&lt;</code></dt><dd>Ir al principio del <i>buffer</i> (<code>begining-of-buffer</code>)</dd>
<dt><code>M-&gt;</code></dt><dd>Ir al final del <i>buffer</i> (<code>end-of-buffer</code>).</dd>
<dt><code>M-g g</code>, <code>M-g M-g</code></dt><dd>Pide un número de línea al que saltar
(<code>goto-line</code>).</dd>
</dl></li>
</ul>

<p>
Hay más combinaciones de teclas, pero con estas, de momento, hay
suficientes. Si te sirve de regla nemotécnica, la tecla <code>C</code> avanza de
uno en uno mientras que la tecla <code>M</code> lo hace en cantidad... más o
menos.
</p>
</div>
</div>
<div id="outline-container-orgd47f835" class="outline-3">
<h3 id="orgd47f835">Abriendo y cerrando buffers</h3>
<div class="outline-text-3" id="text-orgd47f835">
<p>
Bueno vamos a escribir nuestro primer texto. Haz lo siguiente:
</p>

<ol class="org-ol">
<li>Pulsa <code>C-x C-f</code>.</li>
<li>En el área de entrada, donde pide un nombre de fichero, escribe
<code>primer-texto.org</code>. O cualquier nombre, pero termina con una
extensión <code>.org</code>.</li>
</ol>

<p>
Escribe un texto, por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #ff79c6; font-size: 130%; font-weight: bold;">*</span><span style="color: #ff79c6; font-size: 130%; font-weight: bold;"> Esto es un t&#237;tulo de primer nivel</span>

Esto es un p&#225;rrafo normal. A partir de ahora puedes escribir
libremente en el editor. La separaci&#243;n entre p&#225;rrafos es una l&#237;nea en
blanco. Por eso, estas l&#237;neas son un p&#225;rrafo.

Esto es el segundo p&#225;rrafo. Como se puede ver est&#225; separado por una
l&#237;nea en blanco del p&#225;rrafo anterior. Si pulsamos <span style="color: #f1fa8c; font-style: italic;">M-q</span> en un p&#225;rrafo,
nos lo justifica y divide en l&#237;neas.

<span style="color: #bebebe; background-color: #282a36;">*</span><span style="color: #bd93f9; font-size: 110%; font-weight: bold;">*</span><span style="color: #bd93f9; font-size: 110%; font-weight: bold;"> Esto es un t&#237;tulo de segundo nivel</span>

Por si t&#250; no te has dado cuenta, estamos editando un fichero <span style="color: #f1fa8c; font-style: italic;">Org</span>.

<span style="color: #bebebe; background-color: #282a36;">*</span><span style="color: #bd93f9; font-size: 110%; font-weight: bold;">*</span><span style="color: #bd93f9; font-size: 110%; font-weight: bold;"> Formato del texto</span>

Podemos utilizar <span style="font-style: italic;">cursiva</span>, <span style="font-weight: bold;">negrita</span>, <span style="text-decoration: underline;">subrayada</span>, <span style="text-decoration: line-through;">tachada</span>,
<span style="color: #f1fa8c; font-style: italic;">verbatim</span>, <span style="color: #50fa7b;">code</span>. Podemos indicar super&#237;ndices y sub&#237;ndices
empleando los caracteres &#171;^&#187; y &#171;_&#187;, por ejemplo:

&#8211; R_sol = 6,96 x 10^8 m
&#8211; R_{Alfa Centauri} = 1,28 x R_{sol}

Si pulsamos <span style="color: #f1fa8c; font-style: italic;">C-c C-x \</span> adem&#225;s veremos de forma gr&#225;fica los sub&#237;ndices
y super&#237;ndices.

Tambi&#233;n, como acabamos de ver, podemos utilizar listas:

&#8211; De &#237;tem normales.
&#8211; Tambi&#233;n podemos utilizar listas de n&#250;meros:
  <span style="color: #f8f8f2; background-color: #282a36;">1.</span> Uno
  <span style="color: #f8f8f2; background-color: #282a36;">2.</span> Dos
  <span style="color: #f8f8f2; background-color: #282a36;">3.</span> Tres
&#8211; Y tambi&#233;n de definiciones:
  &#8211; <span style="font-weight: bold;">Un concepto ::</span> Su definici&#243;n.
  &#8211; <span style="font-weight: bold;">Otro concepto ::</span> y su correspondiente definici&#243;n.

Y como se puede apreciar, podemos anidarlas unas dentro de otras.

<span style="color: #bebebe; background-color: #282a36;">*</span><span style="color: #bd93f9; font-size: 110%; font-weight: bold;">*</span><span style="color: #bd93f9; font-size: 110%; font-weight: bold;"> Tablas</span>

Tambi&#233;n tenemos una manera muy sencilla de organizar la informaci&#243;n en
tablas.

<span style="color: #bd93f9;">| una columna | otra columna |</span><span style="color: #bd93f9;">
</span><span style="color: #bd93f9;">|-------------+--------------|</span><span style="color: #bd93f9;">
</span><span style="color: #bd93f9;">| esto        | y aquello    |</span><span style="color: #bd93f9;">
</span>
Y lo vamos a dejar aqu&#237;, porque si no voy a escribir un tutorial de
<span style="color: #f1fa8c; font-style: italic;">org-mode</span> dentro de uno de <span style="font-style: italic;">Emacs</span>.
</pre>
</div>

<p>
Te aconsejo que vayas tecleando el texto, para que veas cómo va
reaccionando <i>Emacs</i>. Va cambiando los colores del texto ¿por qué?
¿qué está pasando?. Sencillamente, si has escrito correctamente la
extensión <code>.org</code>, <i>Emacs</i> ha entrado en <code>org-mode</code> y todo el texto que
estás escribiendo es automáticamente procesado por dicho modo.
Distingue los títulos, el marcado de texto, facilita su edición y
también lo muestra de modo que nosotros podamos distinguirlo de un
vistazo asignando colores.
</p>

<p>
Al llegar a la tabla, copia la primera fila y en la segunda introduce
sólo <code>|-</code> y pulsa <code>&lt;TAB&gt;</code>.
</p>

<p>
¿Cómo lo guardas? Pues puedes pulsar <code>C-x C-s</code> o con el ratón y el
menú pinchando en <code>File -&gt; Save</code>.
</p>
</div>
</div>
<div id="outline-container-orga660d45" class="outline-3">
<h3 id="orga660d45">La línea de estado</h3>
<div class="outline-text-3" id="text-orga660d45">
<p>
Una herramienta sobre la que quiero llamar la atención, que nos
servirá para ver qué estado tiene cada <i>buffer</i> es lo que <i>Emacs</i>
llama <i>the mode line</i>. Nos proporciona codificada toda la información
que necesitamos sobre el <i>buffer</i>.
</p>

<p>
Si vemos la siguiente imagen:
</p>


<figure id="org6515a8c">
<img src="./imagen/linea-estado.png" alt="linea-estado.png">

</figure>

<p>
Vemos ahí dos líneas de modo o de estado, una para cada <i>buffer</i>
abierto. Podemos ver la siguiente estructura:
</p>

<pre class="example" id="org1bd85be">
CS:CH-FR nombre-buffer      POS LÍNEA    (Mayor Menores)
</pre>

<p>
El campo <code>CS</code> es el código del sistema. Los valores habituales son <code>U</code>
para <i>unicode</i>, <code>1</code> para <code>ISO Latin-1</code>... si aparece un <code>-</code> significa
que no hay asignado para el <i>buffer</i> una página de códigos.
</p>

<p>
Después de ese campo suele haber un carácter <code>:</code>, si aparece otra
cadena nos indicará que el fin de línea no es el habitual. En marcos
creados por <code>emacsclient</code> el carácter que aparece es <code>@</code>, pero como
todavía no hemos visto cómo funciona <i>emacs</i> en modo servidor, no
entraré más allá.
</p>

<p>
El campo <code>CH</code> suele ser <code>--</code> que indica que el <i>buffer</i> coincide con
el fichero guardado en disco. Si aparece <code>**</code> indica que el <i>buffer</i>
se ha modificado y hay cambios sin guardar. Si aparece <code>%%</code> quiere
decir que el <i>buffer</i> es de sólo lectura. Es posible que aparezca
<code>%*</code>, lo que indicará que hemos modificado un <i>buffer</i> de sólo
lectura. Ha más variantes en este campo cuando se edita un fichero a
través de la red, pero no voy a entrar en ellas.
</p>

<p>
El campo <code>nombre-buffer</code> es normalmente el nombre del fichero que
tenemos cargado en el <i>buffer</i> y coincide con él. Hay casos en que ese
nombre varía; por ejemplo, si cargamos dos ficheros con el mismo
nombre pero que están en directorios diferentes, el nombre podría ser
<code>nombre-fichero&lt;directorio&gt;</code>. Además, algunos <i>buffers</i> especiales
mostrarán su nombre en formato <code>*nombre-buffer*</code>.
</p>

<p>
El campo <code>POS</code> nos indica la posición del <i>buffer</i> que vemos en la
ventana con respecto al total del contenido. Por ejemplo, si muestra
<code>All</code> quiere decir, que en ventana estamos visualizando todo el
contenido del <i>buffer</i>. También puede aparecer <code>Top</code>, que quiere decir
que estamos en la posición superior, <code>Bot</code> indica que estamos al final
del mismo y normalmente tendrá un formato de <code>00%</code>, es decir, el
porcentaje de <i>buffer</i> que hay por encima de la parte superior de la
ventana.
</p>

<p>
El campo <code>Línea</code> consiste en el carácter <code>L</code> seguido por la línea
donde está situado el punto.
</p>

<p>
Por último, entre paréntesis, se encuentran los modos activos. El
primero es el modo <code>Mayor</code> y sólo puede haber uno mayo. A continuación
aparecen los modos menores, que puede no haber o haber varios.
</p>
</div>
</div>
</div>
<div id="outline-container-org3b15958" class="outline-2">
<h2 id="org3b15958">Conclusiones</h2>
<div class="outline-text-2" id="text-org3b15958">
<p>
¿Muchas teclas? ¿Imposible aprendérselas todas? Pues hay más, en la
ayuda están todas detalladas. No obstante, para moverte cuentas
también con la ayuda del ratón. Como ya he dicho antes, puede
parecernos más rápido, pero no lo es, aunque quizá sí más intuitivo si
estás acostumbrado a utilizarlo en entornos gráficos.
</p>

<p>
Tómate tu tiempo en acostumbrarte a la <i>interface</i> del editor, juega
un poco con él, verás que enseguida lo tienes dominado.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Con el tiempo te darás cuenta que es más productivo no separar
los dedos de las teclas para ir hasta el ratón, mover el cursor y
pinchar en <i>pichorros</i> y <i>chismáticos</i> que no aportan valor añadido al
proceso. Te aprenderás las combinaciones de teclas más frecuentes y
hasta es posible que decidas quitarle el menú y la barra de
herramientas a tu <i>Emacs</i>, como hacen muchos usuarios. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En la terminología de <i>Emacs</i> cargar el contenido de un fichero
en un <i>buffer</i> se llama <i>visitar</i>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Oirás hablar de paquetes de <i>Emacs</i> muchas veces y aprenderás a
instalarlos también, pero de momento: no es el caso.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2019/11/28/primeros-pasos-con-el-editor.html</link>
  <pubDate>Thu, 28 Nov 2019 18:37:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Introducción a Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-11-26</div>
<div id="outline-container-org98be65d" class="outline-2">
<h2 id="org98be65d">Introducción a la Introducción de Emacs</h2>
<div class="outline-text-2" id="text-org98be65d">
<p>
Hace tiempo que <i>Emacs</i> se ha convertido en una herramienta
fundamental en mi trabajo diario. Prácticamente lo uso para todo,
gracias a <code>org-mode</code>. Y tanto he hablado de él, no sólo en este
<i>blog</i>, sino también en mi vida diaria, a mis conocidos, amigos y
familiares que hay quien se ha planteado el usarlo o por lo menos
probarlo. Supongo que por aquello de: <i>yo quiero de esa mierda que
fumas tú</i>. Y eso seguido de: <i>¿por dónde empiezo?</i>... yo, henchido de
autocomplacencia, podría recomendar mi <i>blog</i>, pero tú, que ya lo has
leído, o al menos hojeado, de sobra sabes que no hay siquiera un
<i>post</i> para «no iniciados» y lo dejas claro con un: <i>no m'entero de
ná</i>. También porque doy por supuesto que el lector utiliza <i>GNU/Linux</i>
y en muchas ocasiones lo que utilizas es <i>MS-Windows</i>.
</p>

<p>
Por tanto, y a petición popular, voy a comenzar una serie de artículos
que van a versar sobre <i>Emacs</i>, pero explicado para gente que viene
nueva a él y que no tiene por qué entender nada sobre informática.
Quizá los usuarios más avanzados que leéis el <i>blog</i> os aburráis un
poco, pero estaría bien que lo leyerais, para encontrar los errores
que sin duda cometeré y poder corregirlos.
</p>

<p>
<i>Emacs</i> es un <i>sistema</i>, ─algunos dicen que <i>operativo</i>, ni más ni
menos─, que en sus ratos libres sirve para editar texto. Quizá suene a
definición pretenciosa, pero es que decir que es un <i>editor de texto</i>
se queda efectivamente corto. Algún lector que esté interesado en
lenguajes de programación, también podría decir que es <i>un LISP
disfrazado de editor de texto</i>, debido a su lenguaje embebido. Pero
como esto último es más de usuarios avanzados, ya lo aclararemos más
adelante en este <i>minicurso</i> de <i>Introducción a EMACS</i>.
</p>

<p>
Su nombre equivale a <i>Editor de MACroS</i>, pero no voy a ponerme a
explicar lo que es un <i>macro</i> a estas alturas, no os preocupéis, es
algo que tiene que ver con la programación y no es necesario para
entenderlo, así que lo obviaré. Pero se puede observar, que en el
nombre lleva implícito el <i>editor</i>. Podemos, por tanto, referirnos a
él como tal.
</p>

<p>
Nació durante los años 70 del siglo pasado, en 1975 Richard Stallman y
Guy Steele hicieron la primera versión. Ya ha llovido desde entonces y
sigue funcionando, ahora mismo estoy escribiendo esto con la versión
de <i>GNU Emacs</i> 26.3. No voy a entrar mucho más en su historia, si
alguien está interesado, lo puede buscar fácilmente, pero sí quiero
decir algo sobre su antigüedad para explicar por qué no sigue las
convenciones de combinaciones de teclas o de nombres de otros
programas. Las interfaces gráficas estaban en experimentación y los
ratones eran un juguete que se estaba construyendo en los laboratorios
de <i>Xerox</i> en Paloalto.
</p>

<p>
Por tanto, quiero decir que utiliza sus propios nombres y
combinaciones de teclas y está fundamentalmente orientado a manejar
texto, porque cuando se inventó todo era texto. Los operarios
tecleaban en <i>terminales tontas</i> conectadas a un ordenador central con
un teclado ligeramente distinto a los actuales y unas pantallas
capaces sólo de mostrar texto.
</p>


<figure id="org1dabf04">
<img src="./imagen/terminal.jpg" alt="terminal.jpg">

</figure>

<p>
¡Pero vamos al lío! Para aprender a manejarlo hay que instalarlo y me
vas a permitir que me salte ese punto. Sería interminable hablar de
cómo instalarlo en todos los sistemas operativos y sus variantes y que
quede algo legible por el público. Pero seguro que no tendrás problema
en hacerlo. En todo caso, si tenéis algún problema al hacerlo, <a href="https://www.gnu.org/software/emacs/">podéis
encontrar en la red información de cómo superar todos esos escollos</a>.
</p>

<p>
En todo caso, mi consejo es que utilices el modo gráfico. Es decir,
lanzar <i>Emacs</i> en su ventana de escritorio y no desde la consola.  De
momento te será más fácil acostumbrarte a él, tiene menú y una barra
de herramientas que se ajustan a lo que estemos haciendo
<i>automágicamente</i>. Y aquí lo tenemos:
</p>


<figure id="orga19e38d">
<img src="./imagen/inicio-emacs.png" alt="inicio-emacs.png">

<figcaption><span class="figure-number">Figure 1: </span>Ventana (<i>Frame</i>) de inicio de <i>Emacs</i>.</figcaption>
</figure>
</div>
<div id="outline-container-org2596c82" class="outline-3">
<h3 id="org2596c82">Convenciones de teclas</h3>
<div class="outline-text-3" id="text-org2596c82">
<p>
Voy a utilizar los nombres y combinaciones tradicionales de <i>Emacs</i>
para las teclas. Podrías pensar que te sería más útil el que empleara
los nombres modernos: ¿Por qué llamar <i>Meta</i> a la tecla <i>Alt</i>, si todo
el mundo la conoce ahora como tal? Pues básicamente, porque toda la
documentación de <i>Emacs</i>, todos los <i>gurús</i> que hablan sobre <i>Emacs</i> y
todos los usuarios utilizan esa convención. Así, si quieres no liarte
con la terminología cuando leas algún tipo de ayuda o artículo sobre
<i>Emacs</i>, es mejor que te acostumbres a ella.
</p>

<p>
En muchos casos encontrarás abreviaturas como <code>C-x b</code>. Eso quiere
decir que se pulse y se mantenga pulsada la tecla <code>Control</code> mientras
se pulsa a la vez la tecla <code>x</code>, se suelte ambas y se pulse la tecla
<code>b</code>. Así nos permite cambiar de <i>buffer</i> (ya hablaremos de lo que es
en el siguiente apartado). Si eres de los que no puede evitar usar el
ratón y estás usando <i>Emacs</i> en un entorno gráfico con ratón y quieres
cambiar de <i>buffer</i>, lo mismo te hace más gracia <code>C-&lt;mouse 1&gt;</code>. Eso
significa que pulses y mantengas pulsada la tecla <code>Control</code> mientras
pulsas el botón izquierdo del ratón... (¡ahí va, aparece un menú con
nombres raros! El <i>Buffer menu</i>). Lo que quiero destacar es el modo de
describir algunas teclas o botones con <code>&lt;...&gt;</code>. Encontrarás con
frecuencia también ese tipo de notación, como <code>&lt;RET&gt;</code> para la tecla de
retorno, <code>&lt;SPC&gt;</code> para el espacio, <code>&lt;TAB&gt;</code> para el tabulador, <code>&lt;ESC&gt;</code>
para la tecla escape, etc.
</p>

<p>
Sin embargo, las más frecuentes en las combinaciones se suelen marcar
con un una letra en mayúsculas <code>C</code> para la tecla control, <code>M</code> para la
tecla <i>Alt izquierda</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, <code>S</code> para cualquiera de las teclas
mayúsculas (<i>Shift</i>)<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.
</p>

<p>
Como he explicado antes, cuando una de esas teclas se muestra separada
con un guión de otra, quiere decir que se deben pulsar a la vez. Por
ejemplo, <code>C-c</code> quiere decir que hay que pulsar la tecla <code>c</code> mientras
se tiene pulsada la tecla <code>Control</code>. <code>C-c s</code> quiere decir que se pulse
la tecla <code>c</code> mientras se tiene pulsada la tecla <code>Control</code> y después de
soltar se pulse la tecla <code>s</code>. <code>C-S-c</code> quiere decir que se pulse la
tecla <code>c</code> mientras se mantienen pulsadas las teclas <code>Control</code> y
<code>Mayúsculas</code>. También podemos utilizar la combinación <code>C-x C-c</code> sin
soltar la tecla <code>Control</code> entre las pulsaciones de <code>x</code> y <code>c</code>.
</p>
</div>
</div>
<div id="outline-container-org2ffcd04" class="outline-3">
<h3 id="org2ffcd04">Nombres del entorno</h3>
<div class="outline-text-3" id="text-org2ffcd04">
<p>
Una vez alcanzado el fácil criterio de las teclas, pues no son más que
convencionalismos de notación, viene lo complicado de llamar a las
cosas por un nombre al que no estamos acostumbrados. Por ejemplo, a lo
que tú llamas <i>ventana</i> en tu escritorio <i>Emacs</i> lo llama <i>Frame</i>. Si
nos fijamos en la figura <a href="#orga19e38d">1</a> podemos apreciar un <i>Frame</i>, con
elementos ordenados de arriba hacia abajo: su menú, su barra de
herramientas, un <i>marco</i> que muestra el <i>buffer</i> de <i>About Emacs</i>, su
barra de estado y la última línea, donde pone <i>For information
about...</i> es lo que conocemos como <i>área de eco</i>. ¿Demasiados
conceptos apelotonados en el mismo párrafo? Pues vamos uno a uno.
</p>

<dl class="org-dl">
<dt><i>Sesión</i></dt><dd>Invocación de <i>Emacs</i>. Se puede invocar al programa varias
veces de forma independiente.</dd>

<dt><i>Frame</i></dt><dd>Es lo que modernamente se llama <i>ventana</i>. Podemos tener
una sesión con varios <i>Frames</i>, para, por ejemplo, cuando
tenemos varias pantallas separar el trabajo entre distintas
pantallas sin necesitar otra <i>sesión</i>.</dd>

<dt><i>Window</i></dt><dd>En la era moderna lo llamaríamos <i>marco</i>. Básicamente es
un recuadro en la ventana, o expresado al modo de <i>Emacs</i>
es un <i>window en el Frame</i>.</dd>

<dt><i>Buffer</i></dt><dd>Es el contenido. <i>Emacs</i> trabaja con contenidos y los
muestra en <i>windows</i>. Pero en un <i>window</i> puedo hacer que
se muestre otro contenido (<i>buffer</i>) en cualquier
momento. Recuerda, que el contenido es independiente del
<i>window</i> en que lo vemos y también es independiente de los
ficheros. Hay <i>buffers</i> que podemos tener abiertos y no
tienen relación con ningún fichero de nuestro disco. Como
por ejemplo, el <i>buffer</i> de <code>*Messages*</code> o el de
<code>*scratch*</code>. Ese tipo de <i>buffer</i> es especial y vienen
marcados entre <code>*...*</code>, para indicárnoslo.</dd>

<dt><i>Fichero</i></dt><dd>Un fichero son los datos que guardamos en el disco duro.
Normalmente, al <i>visitar</i> uno cargamos su contenido en un
<i>buffer</i>, o guardamos los contenidos de un <i>buffer</i> en un
fichero para salvar nuestro trabajo.</dd>
</dl>
</div>
</div>
<div id="outline-container-orgaf69fdf" class="outline-3">
<h3 id="orgaf69fdf">Comandos y modos</h3>
<div class="outline-text-3" id="text-orgaf69fdf">
<p>
Es muy pronto para comenzar con los comandos, pero que sepas que
muchas convenciones vienen, precisamente por la ingente cantidad de
comandos que podemos utilizar en <i>Emacs</i>: toda acción que se pueda
hacer en el editor, se le puede asignar una combinación de teclas o
llamar a su comando mediante <code>M-x</code>. Al pulsar esa combinación de
teclas (<i>Alt</i> y <i>x</i>) puedes escribir cualquiera de los comandos de
<i>Emacs</i>.  Como iremos viendo en los siguientes capítulos con más
detalle esto, lo dejaré aquí. Pero por ejemplo, <code>forward-char</code>, que
podríamos llamar con <code>C-f</code> (o sustituir por la flecha derecha del
cursor).
</p>

<p>
Los <i>modos</i> al principio pueden parecer innecesarios, sin embargo,
toda la edición se basa en ese concepto. Un <i>modo</i> configura el editor
para ser utilizado para una función concreta. Por ejemplo, si lo voy a
utilizar para programar en un determinado lenguaje, cargará el <i>modo</i>
específico para él. Los comandos varían según el <i>modo</i> y eso al final
nos facilita la vida porque la misma operación se llama con la misma
combinación de teclas aunque se necesiten herramientas distintas. Ya
veremos que tenemos una combinación de teclas como <code>C-c C-c</code> que
realiza muchas acciones dependiendo del modo en el que se encuentre.
</p>

<p>
Además hay modos <i>mayores</i> y <i>menores</i>. No tienen nada que ver con el
tamaño a pesar de los nombres. Un modo mayor cambia la configuración
del <i>buffer</i> mientras que un modo menor añade funcionalidad. Como
hablaremos en otras entregas sobre estos detalles lo dejaremos de
momento.
</p>

<p>
Para los nuevos usuarios y los no programadores pueden parecer
características secundarias, pero en realidad es lo que le da toda la
potencia a nuestro editor.
</p>
</div>
</div>
<div id="outline-container-org8f63741" class="outline-3">
<h3 id="org8f63741">El cursor, el punto y la marca</h3>
<div class="outline-text-3" id="text-org8f63741">
<p>
A colación del movimiento, que lo veremos en la siguiente entrega,
sólo haré un apunte que es interesante conocer desde el principio.  Si
hemos utilizado otros editores más gráficos, estaremos acostumbrados a
pulsar mayúsculas y mover el cursor sin soltarlas para marcar una
zona. En <i>Emacs</i> esto no funciona así, sino que hay que tener en
cuenta los dos conceptos de <i>el punto</i> y <i>la marca</i>.<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>
</p>

<p>
Es fácil de entender que <i>el punto</i> es la posición donde está el
cursor en una ventana. Sin embargo, no es tan fácil. Porque cada
ventana tiene su punto y sólo coincide con el cursor cuando el cursor
está en la ventana del <i>buffer</i>. El cursor es único para todo el
programa y es el que da el foco al <i>frame</i> y a la <i>ventana</i>, cuando el
cursor entra en una ventana, se posiciona para coincidir con el
punto. Sin embargo, podemos tener cargado el mismo <i>buffer</i> en dos
<i>ventanas</i>, por lo que podremos editar y visualizar dos zonas
distintas del mismo <i>buffer</i>, y cada una tener su correspondiente
punto, pero la marca pertenece al <i>buffer</i> y es única... ¿un lío?
Verás como usándolo lo entiendes. Para resumir: El cursor pertenece al
<i>Frame</i>, la <i>marca</i> pertenece al <i>buffer</i> y el <i>punto</i> es la conexión
entre la <i>ventana</i> y el <i>buffer</i>.
</p>

<p>
Para establecer la marca hay varias teclas, pero la que suelo utilizar
yo es <code>C-&lt;SPC&gt;</code>. Cuando necesito marcar algo pulso <i>control+espacio</i> y
se activa la marca, me muevo hasta donde quiero marcar y realizo la
acción que quiero sobre lo marcado. Todas estas cosas las veremos más
adelante y no voy a extenderme más.
</p>

<p>
Para cambiar el punto sólo tenemos que mover el cursor en la ventana.
Normalmente, la marca se moverá con él también, habitualmente. Cuando
fijamos la marca y movemos el cursor es cuando seleccionamos el texto.
</p>

<p>
¿Que cómo anular el marcado? Pues con el anulador universal: <code>C-g</code>.
Esa combinación de teclas es la que nos salvará de bastantes meteduras
de pata y arrepentimientos.
</p>
</div>
</div>
<div id="outline-container-orgf1a8e48" class="outline-3">
<h3 id="orgf1a8e48">Conclusiones</h3>
<div class="outline-text-3" id="text-orgf1a8e48">
<p>
Este post no aclara mucho aún, es más una entrada para mostrar la
intención de hablar sobre <i>Emacs</i> desde un punto de vista de usuario.
Enseñar a utilizar el editor y sobre todo a manejar la ayuda: la
infinita ayuda con que viene cargado de serie.
</p>

<p>
Como dije en la introducción, <i>Emacs</i> no viene solo, proporciona el
modo <code>org</code> que es la navaja suiza de la computación. Sirve para
escribir documentos, para gestionar la agenda, para hacer cálculos y
sus gráficos... en fin, es la navaja suiza de la computación.
</p>

<p>
Si tienes prisa por empezar te aconsejo que hagas el tutorial, para
ello pulsa <code>C-h t</code> o si aún te sientes más cómodo con el ratón utiliza
el ratón para ir al menú y pincha en <code>Help -&gt; Emacs Tutorial</code>.  En la
próxima entrega hablaremos sobre cómo movernos por las ventanas y los
<i>buffers</i>, por las líneas y las palabras... así, si ya has hecho el
tutorial te servirá para fijar los conceptos.
</p>
</div>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<code>M</code> proviene del nombre original de la tecla: <code>META</code>. Con el
paso del tiempo se cambió la denominación. No voy a extenderme en las
razones históricas, sólo apréndete que <code>M</code> se refiere a la tecla
<i>Alt</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
No confundir con la tecla de bloqueo de mayúsculas, ─una tecla
que, en mi opinión, debería desaparecer de todos los teclados de los
ordenadores─. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
En realidad, se puede utilizar lo de marcar texto con las
mayúsculas y el cursor activando <code>org-support-shift-select</code>, pero no
hablaré de ello en un artículo introductorio. Ya hablaremos de cómo se
configura <i>Emacs</i> en posteriores entregas. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2019/11/26/introduccion-a-emacs.html</link>
  <pubDate>Tue, 26 Nov 2019 18:32:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Pasando de bbdb a org-contacts]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-11-19</div>
<p>
Llevo años utilizando <code>bbdb</code> como gestor de contactos y acumulo en esa
base de datos cientos de registros con las direcciones y teléfonos de
la gente con la que me cruzo en esta vida. Había una excepción y era
que los datos de mis <i>clientes</i> iban a otro lugar gestionándose para
interactuar con ellos desde <code>org-mode</code> y tener juntos los datos
personales y las <i>historias clínicas</i> con las visitas, pruebas,
avances en el tratamiento y anotaciones necesarias para gestionar
correctamente mi trabajo.
</p>

<p>
Así, pues, tenía duplicados algunos datos en el sistema y dos modos de
gestionar datos personales. Los tenía duplicados porque <code>bbdb</code> permite
exportar e importar datos desde ficheros externos estándar, como
<code>vcard</code>, mientras que <code>org-contacts</code> sólo permite la exportación.
</p>

<p>
Además, la captura de datos la tengo automatizada para realizarla a
<code>org-contacts</code> porque si la hacía para <code>bbdb</code> siempre se me olvidaba
desactivar <code>ivy-mode</code> y cuando estaba activo la captura de datos para
<code>bbdb</code> entraba en bucle y tenía que reiniciar el proceso. Capturando
para el modo <code>org</code> no había esos problemas, pero luego tenía que pasar
los datos a <code>bbdb</code>. Si alguien tiene curiosidad por el código que
utilizo para la captura de datos, aunque creo que ya lo puse alguna
vez por el <i>blog</i>, es éste:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"> [...]
 <span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Templates de captura para cosas que no son para la agenda
</span>        (<span style="color: #f1fa8c;">"n"</span> <span style="color: #f1fa8c;">"Capturas no para agenda"</span>)
        (<span style="color: #f1fa8c;">"nc"</span> <span style="color: #f1fa8c;">"Anotar (c) contacto"</span> entry (file+headline <span style="color: #f1fa8c;">"~/agenda/especiales/personal.org.gpg"</span> <span style="color: #f1fa8c;">"Sin ordenar"</span>)
         <span style="color: #f1fa8c;">"** %^{Nombre} %^{Apellidos}%?
   :PROPERTIES:
   :Nombre:     %\\1
   :Apellidos:  %\\2
   :Alias:      %^{Alias}
   :Grupo:      %^{Grupo}
   :F-nacim:    %^{F-nacim}u
   :M&#243;vil:      %^{M&#243;vil}
   :Tel&#233;fono:
   :Email:      %^{Email}
   :Web:
   :Direcci&#243;n:  %^{Direcci&#243;n}
   :Ciudad:     %^{Ciudad}
   :Provincia:  %^{Provincia}
   :C&#243;d.Pos:    %^{C&#243;digo Postal}
   :Compa&#241;&#237;a:
   :Notas:
   :END:"</span> <span style="color: #8be9fd; font-style: italic;">:empty-lines</span> 1)
[...]
</pre>
</div>

<p>
Como se puede apreciar pasan al fichero <code>personal.org.gpg</code> y se
almacenan directamente cifrados en él, en un apartado que se llama
<i>Sin ordenar</i> y que después serán movidos esos datos a la posición que
corresponda dentro del grupo de datos correspondiente, porque lo tengo
dividido en apartados como <i>Familia</i>, <i>Amigos</i>, <i>Trabajo</i>,
<i>Asociación</i>, etc. que viene también especificado por el <code>Grupo</code> que
se puede observar en la plantilla.
</p>
<div id="outline-container-orgb158def" class="outline-2">
<h2 id="orgb158def">Pasar los datos de una base de datos a otra</h2>
<div class="outline-text-2" id="text-orgb158def">
<p>
Para pasar todos los datos que tenía en <code>bbdb</code>, primero hay que
configurar y preparar el fichero de contactos para que se comporte de
una manera más amigable. En principio, <code>org-contacts</code> lo que hace es
organizar un <i>árbol</i> de entradas donde los datos se guardan como
propiedades. Si abres el documento con todos los datos desplegados,
cada registro consta de tantas líneas como campos, más la cabecera,
más los delimitadores de las propiedades. Esto hace que navegar por
los datos sea un poco tedioso. Personalmente, para la visualización
prefiero el <i>modo columnas</i>, que presenta cada <i>registro</i> en una línea
con los campos más habituales a la vista.
</p>
</div>
<div id="outline-container-org7a3d1a4" class="outline-3">
<h3 id="org7a3d1a4">Configurar los contactos</h3>
<div class="outline-text-3" id="text-org7a3d1a4">
<p>
El caso es que la duplicidad de datos y el tener que gestionar las dos
formas de almacenarlos, poco a poco, me han ido cansando y decidí
centralizarlo todo en <code>org-contacts</code>. Dicho paquete no se instala
independientemente, sino que pertenece a un <i>metapaquete</i> que se llama
<code>org-plus-contrib</code> donde podemos encontrar muchos paquetes
interesantes y útiles.
</p>

<p>
Para activar los datos de los contactos, hace falta algo de código en
nuestro <code>init.el</code>. Como podéis ver en la plantilla de captura, todos
los campos los nombro en español, así que tengo que decirle a
<code>org-contacts</code> a qué campo corresponde cada uno:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-contacts-address-property <span style="color: #f1fa8c;">"Direcci&#243;n"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-contacts-birthday-format <span style="color: #f1fa8c;">"Cumplea&#241;os: %04d-%02d-%02d"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-contacts-birthday-property <span style="color: #f1fa8c;">"F-nacim"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-contacts-email-property <span style="color: #f1fa8c;">"Email"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-contacts-files (<span style="color: #ff79c6; font-weight: bold;">quote</span> (<span style="color: #f1fa8c;">"~/agenda/especiales/personal.org.gpg"</span>)))
(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-contacts-matcher
  <span style="color: #f1fa8c;">"Email&lt;&gt;\"\"|Alias&lt;&gt;\"\"|M&#243;vil&lt;&gt;\"\"|F-nacim&lt;&gt;\"\""</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-contacts-note-property <span style="color: #f1fa8c;">"Notas"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-contacts-tel-property <span style="color: #f1fa8c;">"M&#243;vil"</span>)
</pre>
</div>

<p>
Además, en el fichero que guarda la base de datos, <code>personal.org.gpg</code>,
tengo establecido en su cabecera
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">#+COLUMNS: %25Nombre %25Apellidos %Alias %M&#243;vil %Email
</pre>
</div>

<p>
Así, cuando consulto la base de datos puedo establecer el <i>modo
columnas</i> pulsando la combinación <code>C-c C-x C-c</code> para visualizar los
datos en una tabla.
</p>
</div>
</div>
<div id="outline-container-orgef7bef0" class="outline-3">
<h3 id="orgef7bef0">Importar los datos desde <code>bbdb</code></h3>
<div class="outline-text-3" id="text-orgef7bef0">
<p>
El problema que me encontré es que no existe una manera de importar
grandes cantidades de registros a <code>org-contacts</code>. Sí los puedes
exportar a formato <code>vcard</code>, sin embargo, no importarlos. La opción de
meterlos uno a uno en el archivo aprovechando la plantilla de captura
es inviable cuando tienes cientos de registros.
</p>

<p>
La solución pasa por un poco de investigación y algo de código. Lo
primero que hice para no cargarme la base de datos de <code>bbdb</code> fue hacer
una copia y trabajar sobre ella. Al abrirla como si fuera un fichero
de texto normal, se puede apreciar que los datos se guardan ordenados
en una lista de <i>arrays</i>, una fila para cada registro o <i>array</i>.
</p>

<p>
Puesto que era una copia, lo encapsulé todo en una lista que llamé
<code>contactos</code> y renombré a <code>convertir.el</code> el fichero copia de los datos:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> contactos (list
   <span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Aqu&#237; todos los registros con los datos
</span>))
</pre>
</div>

<p>
Podría haber escrito el código en otro fichero e importar los datos
desde fuera, pero ya que los tenía en formato texto me pareció más
rápido encapsular los datos en una lista y no romperme la cabeza con
importaciones externas.
</p>

<p>
Posteriormente me dediqué a observar la estructura de los registros y
cómo extraer los datos. Lo más normal era utilizar la función <code>insert</code>
para abrir el fichero donde importarlos y que el código insertara los
datos de manera directa. Voy a poner todo el código fuente y ahora me
entretengo un poco en explicar cómo funciona:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> contactos (list
   <span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Aqu&#237; todos los registros con los datos
</span>))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">varios-telefonos</span> (cada-telefono)
  (aref cada-telefono 1))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">insertar-datos</span> (elem)
  (insert (concat <span style="color: #f1fa8c;">"** "</span> (aref elem 0) <span style="color: #f1fa8c;">" "</span> (aref elem 1) <span style="color: #f1fa8c;">"\n"</span>))
  (org-set-property <span style="color: #f1fa8c;">"Nombre"</span> (<span style="color: #ff79c6; font-weight: bold;">if</span> (eq (aref elem 0) nil)
                                 (aref elem 1)
                               (aref elem 0)))
  (org-set-property <span style="color: #f1fa8c;">"Apellidos"</span> (<span style="color: #ff79c6; font-weight: bold;">if</span> (eq (aref elem 0) nil)
                                    <span style="color: #f1fa8c;">""</span>
                                  (aref elem 1)))
  (org-set-property <span style="color: #f1fa8c;">"Alias"</span> <span style="color: #f1fa8c;">""</span>)
  (org-set-property <span style="color: #f1fa8c;">"Grupo"</span> (<span style="color: #ff79c6; font-weight: bold;">if</span> (eq (aref elem 4) nil)
                                <span style="color: #f1fa8c;">""</span>
                              (car (aref elem 4))))
  (org-set-property <span style="color: #f1fa8c;">"F-nacim"</span> (<span style="color: #ff79c6; font-weight: bold;">if</span> (<span style="color: #ff79c6; font-weight: bold;">or</span> (eq (aref elem 8) nil) (eq (cdr (assoc 'birthday (aref elem 8))) nil))
                                    <span style="color: #f1fa8c;">""</span>
                                (cdr (assoc 'birthday (aref elem 8)))))
  (org-set-property <span style="color: #f1fa8c;">"M&#243;vil"</span> (<span style="color: #ff79c6; font-weight: bold;">if</span> (eq (aref elem 5) nil)
                                <span style="color: #f1fa8c;">""</span>
                              (aref (car (aref elem 5)) 1)))
  (org-set-property <span style="color: #f1fa8c;">"Tel&#233;fono"</span> (<span style="color: #ff79c6; font-weight: bold;">if</span> (&gt; (length (aref elem 5)) 1)
                                   (mapconcat 'varios-telefonos (aref elem 5) <span style="color: #f1fa8c;">", "</span>)
                                 <span style="color: #f1fa8c;">""</span>))
  (org-set-property <span style="color: #f1fa8c;">"Email"</span> (mapconcat 'append (aref elem 7) <span style="color: #f1fa8c;">", "</span>))
  (org-set-property <span style="color: #f1fa8c;">"Direcci&#243;n"</span> (<span style="color: #ff79c6; font-weight: bold;">if</span> (eq (aref elem 6) nil)
                                    <span style="color: #f1fa8c;">""</span>
                                  (car (aref (car (aref elem 6)) 1))))
  (org-set-property <span style="color: #f1fa8c;">"Ciudad"</span> (<span style="color: #ff79c6; font-weight: bold;">if</span> (eq (aref elem 6) nil)
                                    <span style="color: #f1fa8c;">""</span>
                                  (aref (car (aref elem 6)) 2)))
  (org-set-property <span style="color: #f1fa8c;">"Provincia"</span> (<span style="color: #ff79c6; font-weight: bold;">if</span> (eq (aref elem 6) nil)
                                    <span style="color: #f1fa8c;">""</span>
                                  (aref (car (aref elem 6)) 3)))
  (org-set-property <span style="color: #f1fa8c;">"C&#243;d.Pos"</span> (<span style="color: #ff79c6; font-weight: bold;">if</span> (eq (aref elem 6) nil)
                                    <span style="color: #f1fa8c;">""</span>
                                (aref (car (aref elem 6)) 4)))
  (org-set-property <span style="color: #f1fa8c;">"Compa&#241;&#237;a"</span> <span style="color: #f1fa8c;">""</span>)
  (org-set-property <span style="color: #f1fa8c;">"Notas"</span> <span style="color: #f1fa8c;">""</span>)
  (insert <span style="color: #f1fa8c;">"\n"</span>))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">convertir-datos</span> ()
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (mapc 'insertar-datos contactos))
</pre>
</div>

<p>
La función que llamamos desde <code>M-x</code> será <code>convertir-datos</code>. No
necesita parámetros, porque toda la información la guarda en el mismo
<i>script</i>. Lo único que hace es una iteración (<code>mapc</code>) llamando a
<code>insertar-datos</code> para cada registro de <code>contactos</code>.
</p>

<p>
La función <code>insertar-datos</code> recibe un elemento en <code>elem</code> e inserta
(<code>insert</code>) una cadena de texto extrayendo el <i>nombre</i> (<code>aref elem 0</code>)
y los <i>apellidos</i> (<code>aref elem 1</code>) del registro. La función <code>aref</code>
extrae de un <i>array</i> el elemento designado por orden.
</p>

<p>
A continuación, comienza a insertar <i>propiedades</i> con el nombre y la
estructura que tiene la plantilla de captura. Siempre comprobando el
contenido para dejarlo en blanco (<code>""</code>) o extraer las cadenas
necesarias. Algunos campos además contienen listas, como por ejemplo
el <i>email</i> y por eso se extrajeron todos separándolos con <code>,</code> mediante
la función <code>mapconcat</code>.
</p>

<p>
El caso del campo «teléfono» era más complejo, porque está compuesto
por una lista de <i>arrays</i> y necesité un paso intermedio para extraer
las cadenas del número de cada <i>array</i>. Para eso utilicé la función
auxiliar <code>varios-telefonos</code>, que básicamente devuelve el número, dado
un registro de la lista de teléfonos.
</p>

<p>
Teniendo ya todos los datos cargados en el fichero toca ir
ordenándolos y acomodándolos. También ir abandonando <code>bbdb</code> hasta que
quede sólo el fichero de <code>org-contacts</code>.
</p>
</div>
</div>
</div>
<div id="outline-container-org6ee776f" class="outline-2">
<h2 id="org6ee776f">Conclusión</h2>
<div class="outline-text-2" id="text-org6ee776f">
<p>
El abandono de <code>bbdb</code> no se debe a un mal funcionamiento del sistema
de base de datos, sino a la comodidad de tenerlo todo junto y a la
posibilidad de realizar la toma de datos, incluso sin tener activado
<code>org-contacts</code> ni la plantilla de captura, porque al final los datos
se encuentran en formato de texto plano.
</p>

<p>
La capacidad de leer los datos desde otros <i>buffers</i>, gracias al
sistema de propiedades que <code>org-mode</code> utiliza, me facilita el trabajo
en mis tareas automatizadas mediante <i>emacs</i>. Esto ha hecho que me
decantara finalmente por este sistema, que a pesar de todo me parece
más lento que <code>bbdb</code> y también que ocupa bastante más espacio (algo
que para mí no es vital pero sí importante, pues es un sistema menos
optimizado de gestión de datos).
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> <a href="/tags/bbdb/index.html">bbdb</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <category><![CDATA[bbdb]]></category>
  <link>https://notxor.nueva-actitud.org/2019/11/19/pasando-de-bbdb-a-org-contacts.html</link>
  <pubDate>Tue, 19 Nov 2019 22:42:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[En qué ando tan enfrascado que ya casi no escribo]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-11-07</div>
<p>
Llevo tiempo sin actualizar el <i>blog</i>, ya casi no escribo. No es que
no quiera, es que cada vez tengo menos tiempo. Entre el programa de
radio los domingos, que podéis seguir a modo de <i>podcast</i> desde el
apartado de <i>radio</i> de este mismo <i>blog</i>, o desde <a href="https://www.ivoox.com/suscripciones_jb_24014611_1.html">el canal de iVoox</a>.
Y otras muchas actividades que se han ido comiendo mi tiempo libre
para dedicarlo al <i>blog</i> o a otras cosas.
</p>

<p>
El caso es que quería mostrar también un poco más, otro pasito con el
juego de las naves. Llevo un par de días montando una animación para
la <i>intro</i> del juego. Una animación 3D, hecha directamente en <i>Godot</i>
para poder lanzarla desde el mismo juego, que se puede adaptar a
pantallas y que no idealice los objetos que se mostrarán en el juego.
Quizá porque estamos un poco cansados de animaciones ultrarrealistas
que luego cuando llegas al juego producen esa sensación de haber sido
timado que algunos sentimos.
</p>

<p>
Pongo aquí una captura de vídeo de cómo se va trabajando esa animación
<i>pichorro</i> a <i>pichorro</i> y sin las facilidades que darían otros
<i>softwares</i> diseñados específicamente para ello, como <i>Blender3D</i>.  El
problema no es de <i>Godot</i>, a ver: resulta que estoy utilizando una
herramienta hecha para programar juegos, para hacer una animación. Es
normal que me encuentre con problemas para hacerla.
</p>

<video controls="" width="100%">
    <source src="./archivo/animacion-intro-hd.webm" type="video/webm">
    Tu navegador no soporta la etiqueta video, comprueba que soporta el formato webm.
</video>

<p>
La herramienta de animaciones de <i>Godot</i> es muy potente, más de lo que
me esperaba. Pero evidentemente, está diseñada para hacer la pequeñas
animaciones, normalmente cíclicas, que acompañan a personajes y
objetos de los juegos. No es una herramienta cómoda para hacer una
<i>película</i>. Siendo una animación de apenas 15 segundos para hacer una
pantalla de <i>intro</i> al juego, es abordable con esta herramienta.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/juegos/index.html">juegos</a> ]]></description>
  <category><![CDATA[juegos]]></category>
  <link>https://notxor.nueva-actitud.org/2019/11/07/en-que-ando-tan-enfrascado-que-ya-casi-no-escribo.html</link>
  <pubDate>Thu, 07 Nov 2019 22:19:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Nuevas naves en el juego]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-10-16</div>
<p>
Estaba trabajando en el juego que aún no tiene nombre y que nosotros
en clave llamamos «TBS» o «toboso». Poco a poco vamos avanzando y
haciendo más cosas y mejor. De momento quiero enseñaros las nuevas
naves con las que contamos.
</p>


<figure id="orga6ebf2d">
<img src="./imagen/nuevas-naves.png" alt="nuevas-naves.png">

</figure>

<p>
Poco a poco va tomando forma y aunque aún queda bastante por hacer,
parece que el proyecto marcha. He puesto juntas todas las naves en una
ventana de <a href="https://godotengine.org/">Godot</a> para que se aprecien las diferentes formas unas junto
a otras.
</p>

<p>
Tampoco quiero echar las campanas al vuelo, algunos proyectos aún más
avanzados que este han quedado en <i>vaporware</i>. Pero eso, si veis que
escribo poco por el <i>blog</i> o que estoy más desaparecido de las redes
sociales, quizá es porque estoy echándole algún rato más al proyecto.
Ninguno de los dos vivimos de esto y tenemos que pagar facturas, así
que no le dedicamos todo nuestro tiempo, sino ratos sueltos que vamos
teniendo. Así que el proyecto avanza despacio (pero avanza). También
hemos hablado sobre la posibilidad de hacer un <i>crowfunding</i> para el
proyecto, pero aún todo está en el aire. Seguramente lo poco que se
recaudara iría todo al mantenimiento de un servidor para el juego, si
conseguimos poder montar uno sin que tengamos que poner dinero de
nuestro bolsillo. De momento no hemos llegado a esos extremos así que
seguimos.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/juegos/index.html">juegos</a> <a href="/tags/godot/index.html">godot</a> ]]></description>
  <category><![CDATA[juegos]]></category>
  <category><![CDATA[godot]]></category>
  <link>https://notxor.nueva-actitud.org/2019/10/16/nuevas-naves-en-el-juego.html</link>
  <pubDate>Wed, 16 Oct 2019 22:26:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Niveles de configuración en Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-10-09</div>
<p>
Una de las primeras cosas que se ve cuando uno se acerca a <i>emacs</i> es
la pantalla de <code>about-emacs</code> y poco más. De primera vista lo único que
destaca es el aspecto antiguo, algunos dirán: <i>rancio</i>, del diseño.  A
quien diga lo de <i>rancio</i>, no le falta razón. <i>Emacs</i> es un editor con
mucho recorrido a la espalda y su diseño proviene de tiempos en los
que la <i>interface</i> más habitual era la consola de texto y no estaban
inventadas las teclas de <i>cortar</i>, <i>copiar</i> y <i>pegar</i>, ni tenían esos
nombres, cuando este editor ya contemplaba esas acciones.
</p>

<p>
Quien decide profundizar en <i>emacs</i>, a pesar de su inicial apariencia
de <i>software</i> desfasado, descubre un inmenso mundo de posibilidades
que exceden el mero hecho de editar texto plano.  El modo gráfico de
<i>emacs</i> no es equivalente a usar <code>gvim</code> para un usuario de <code>vim</code>.  El
modo gráfico de <i>emacs</i> te permite visualizar <code>pdf</code>, leer <code>epub</code>,
modificar <code>svg</code>, leer texto acompañado de sus gráficos y fotografías,
navegar por páginas <i>web</i> o jugar al <i>tetris</i>. Todo ello gracias al
lenguaje que viene con él y que permite hacer de todo; tanto, que hay
un gestor de ventanas que básicamente es <a href="https://github.com/ch11ng/exwm"><i>emacs</i> distribuyendo sus
<i>frames</i> en la pantalla</a>.
</p>

<p>
Si estás leyendo este artículo, seguramente ya conocerás las
maravillas de <i>emacs</i> y no voy a contarte nada nuevo. Si no las
conoces tienes todo el <i>blog</i> para enterarte, porque creo que hablo de
todas las cosas que hago con él. No voy a <i>cansinar</i> más con el tema y
vamos al lío... ¿Cuál es el <i>lío</i>? La <b>configuración</b>, sin duda. Toda
la potencia de <i>emacs</i> radica en una buena configuración.
Configuración tan flexible y potente que a veces se atraganta a los
nuevos usuarios, especialmente si desconocen <i>Lisp</i> en general y más
concretamente <i>emacs lisp</i>. Si es tu caso, estás leyendo esto y no te
aclaras muy buen con <i>elisp</i>, <a href="https://notxor.nueva-actitud.org/blog/2019/01/03/elisp-para-no-programadores/">hace unos meses escribí una serie de
artículos como introducción a la programación con <i>elisp</i></a>.
</p>
<div id="outline-container-orgcbc73fd" class="outline-2">
<h2 id="orgcbc73fd">Jerarquía de configuraciones</h2>
<div class="outline-text-2" id="text-orgcbc73fd">
<p>
¿Tan importante es <i>elisp</i>? La respuesta a esa pregunta podría ocupar
todo un artículo del <i>blog</i>, pero voy a dejarlo en un escueto <i>sí</i>.
Por supuesto, en <i>elisp</i> están escritos todos los paquetes que
extienden funcionalidad de <i>emacs</i> y también el fichero de
configuración. Así que sí, tienes que saber un poquito de ese
lenguaje: lo suficiente como para asignar un valor a una variable si
sólo lo vas a utilizar para configurar tu editor.
</p>
</div>
<div id="outline-container-org89f87b6" class="outline-3">
<h3 id="org89f87b6">Configuración general</h3>
<div class="outline-text-3" id="text-org89f87b6">
<p>
El fichero de configuración general se llama <code>init.el</code> y <i>emacs</i> lo
busca en el subdirectorio <code>.emacs.d</code> de tu directorio de usuario.  Al
principio no necesitas escribir una línea de código para
configurarlo.  Si estás acostumbrado a utilizar herramientas gráficas
encontrarás menús y botones en <code>Options</code>, para hacerlo. Pero con el
tiempo, estoy seguro que terminarás utilizando la edición directa del
código en lugar de trastear con menús y botones que andan por ahí
escondidos en la configuración <i>visual</i>.
</p>

<p>
Como ya he explicado varias veces cómo configurar paquetes, e incluso
he hablado alguna vez sobre mi <code>init.el</code> en este <i>blog</i>, no voy a
hacer más extensa esta parte.
</p>
</div>
</div>
<div id="outline-container-org6a7094d" class="outline-3">
<h3 id="org6a7094d">Configuración local</h3>
<div class="outline-text-3" id="text-org6a7094d">
<p>
Por si no había suficiente flexibilidad en la configuración <i>general</i>
también nos encontramos con la figura de la configuración <i>local</i>.
Básicamente consiste en meter un fichero llamado <code>.dir-locals.el</code> en
el directorio de trabajo. Eso afectará a la configuración de todos los
ficheros que se encuentren en el directorio y los subdirectorios que
cuelguen de él. ¿Para qué? Pues a veces ocurre que necesitas cambiar
los parámetros básicos tal y como te gustan a ti, para un proyecto en
particular.
</p>

<p>
Pongo dos ejemplos que me han ocurrido y donde la configuración local
me ha venido a salvar los trastos.  En el primer caso se trataba de un
proyecto de programación y se acordó entre los participantes que el
código debía utilizar tabuladores de ancho <code>4</code>.  Yo siempre utilizo
espacios y resultaría muy cansino cambiar la configuración general de
<i>emacs</i> cada vez que me ponía a programar. La solución fue meter en el
directorio raíz del proyecto un fichero <code>.dir-locals.el</code> con el
siguiente contenido:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">((nil
  (fill-column . 80))
 (c-mode
  (indent-tabs-mode .t)
  (tab-stop . 4)))
</pre>
</div>

<p>
Se puede apreciar que lo que contiene un fichero de configuración
local viene a ser un listado de variaciones para cada modo mayor que
se necesite. Cada uno de esos modos contiene una lista de nombres de
variables y sus valores para el proyecto. También se puede especificar
<code>nil</code> para el modo, lo que hará que se aplique en todos los modos
activados en ese directorio.
</p>

<p>
En este caso el cambio en la configuración venía impuesta por el
equipo de trabajo. Pero en el siguiente, la imposición venía de una
herramienta.
</p>

<p>
Alguna vez he contado que para traducir textos utilizo <a href="https://omegat.org/">una herramienta
en <code>Java</code> que facilita la gestión de ese trabajo</a>.  El tema es que esa
herramienta no reconoce la extensión <code>.org</code> como fichero que pueda
trabajar y tuve que renombrar los todos los ficheros de un proyecto a
la extensión <code>.txt</code>, pero así, cuando los abría con <i>emacs</i> los habría
en modo <code>Fundamental</code> en lugar de <code>org-mode</code>. La solución como lo
podéis imaginar fue crear un fichero en el directorio de fuentes. Al
tener la extensión <code>.el</code> y estar oculto, <i>OmegaT</i> no lo reconoce para
trabajarlo en la traducción, pero lo copiará al directorio de ficheros
traducidos porque interpreta que es parte del proyecto.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Directory Local Variables
</span><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">For more information see (info "(emacs) Directory Variables")
</span>
((org-mode
  (fill-column . 75)
  (eval . (org-show-all)))
 (text-mode
  (mode . org)))
</pre>
</div>

<p>
Viendo el código podéis suponer que <i>emacs</i> tiene alguna manera de
insertar las variables en ese fichero de forma más o menos automática
sin tener que recordar la sintaxis de la lista de listas y lo hay:
<code>add-dir-local-variable</code>. Preguntará por un <i>modo</i>, luego por una
<i>variable</i> y al final por un <i>valor</i>.  Por supuesto, también
encontraréis su contrario <code>delete-dir-local-variable</code>.
</p>

<p>
Quiero destacar también la expresión <code>(eval . (org-show-all))</code>, porque
como se puede ver, se puede ejecutar código también desde la
configuración de variables locales. En este caso, lo que hace es que
todos los ficheros que se abran en modo <code>org</code> se mostrarán en formato
desplegado. Sin embargo, <i>emacs</i> considera que no es seguro hacer esto
y preguntará al usuario si lo ejecuta o no, mostrando un diálogo y
esperando hasta que contestemos antes de abrir un archivo en un modo
en el que tenga que evaluar código.
</p>
</div>
</div>
<div id="outline-container-orgd21c0b9" class="outline-3">
<h3 id="orgd21c0b9">Configuración de fichero</h3>
<div class="outline-text-3" id="text-orgd21c0b9">
<p>
Y ¿qué ocurre si hay algún fichero que necesite algún tratamiento
especial?  Pues para ello existen las <i>variables de fichero</i>, que
igual que las variables de <i>directorio</i> o <i>locales</i> sobrescriben las
variables globales, las de <i>fichero</i> sobrescriben las <i>locales</i>.
</p>

<p>
Si llevas un tiempo utilizando <i>emacs</i> habrás visto en algunos
ficheros una primera línea tal que por ejemplo:
</p>

<pre class="example" id="org12d9c62">
# -*- mode: org-mode; coding: utf-8; -*-
</pre>

<p>
Esa línea informa a <i>emacs</i> que el fichero que se ha abierto en el
<i>buffer</i> tendrá que tratarlo como un fichero <code>org</code> y que debe utilizar
la codificación <code>utf-8</code>.
</p>

<p>
En lugar de utilizar una lista como esa, empaquetada en una sola
línea, que puede dificultar su lectura y comprensión, también
podríamos hacerlo en forma de listado:
</p>

<pre class="example" id="org6e655de">
# Local Variables:
# mode: org-mode
# coding: utf-8
# End:
</pre>

<p>
Hay que observar que la primera línea debe ser <code>Local Variables:</code> y
hay que acabar el listado con <code>End:</code>.  Podemos, como hemos visto en el
punto anterior evaluar algo de código, por ejemplo:
</p>

<pre class="example" id="org77bdff0">
# Local Variables:
# mode: org-mode
# eval: (org-show-all)
# End:
</pre>

<p>
Hará que el fichero sea tratado como <code>org</code> y además ejecutará la
función <code>org-show-all</code>. También, como he dicho en el apartado
anterior, antes de hacer esa ejecución preguntará al usuario si es
seguro realizarla o no. En el caso de este ejemplo el mismo efecto lo
conseguiríamos utilizando las herramientas que nos proporciona
<code>org-mode</code> para hacer lo mismo y la cosa la dejaríamos así:
</p>

<pre class="example" id="orged96042">
# Local Variables:
# mode: org-mode
# End:

#+STARTUP: showall
</pre>
</div>
</div>
</div>
<div id="outline-container-org1dccb4b" class="outline-2">
<h2 id="org1dccb4b">Conclusiones</h2>
<div class="outline-text-2" id="text-org1dccb4b">
<p>
Como se puede ver la forma de configuración que nos permite <i>emacs</i> es
mucho más precisa que simplemente establecer variables en un fichero
general. La jerarquía de configuraciones hace que podamos establecer
los modos hasta el nivel más bajo independientemente de las
establecidas de forma general.
</p>

<p>
Esta potencia y flexibilidad también puede aportar algo de inseguridad
pues abrir un fichero de texto puede implicar la ejecución de código
que podría ser malicioso.
</p>

<p>
En la documentación que viene con <i>emacs</i> están todos estos temas
mucho más detallados de lo que yo he descrito aquí, aunque quizá no
organizados de esta forma.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2019/10/09/niveles-de-configuracion-en-emacs.html</link>
  <pubDate>Wed, 09 Oct 2019 22:14:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[El infierno del identado]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-10-08</div>
<p>
Estos días he estado trabajando en un tema en <i>Python</i>. En otros
lenguajes, el indentado del código es más una cuestión estética que
funcional, pero ya sabéis que ese lenguaje utiliza, precisamente el
indentado, para establecer los bloques de código.  Es una forma
elegante de obligar al programador a escribir código legible, quiera o
no, pero viendo lo que suele ocurrir con ello, se convierte en el
origen de muchas frustraciones. ¿Por qué? Pues básicamente porque a
cada programador le gusta una forma de hacerlo y eso implica, también,
que los editores de texto lo hagan por defecto a la manera que le
guste a quien lo programó, que puede coincidir o no con el gusto del
usuario, y/o con el gusto del programador del lenguaje, y/o con el de
los que hicieran el <i>estándar</i> del mismo. Esto, básicamente, es lo que
yo llamo <i>el infierno del indentado</i>.
</p>

<p>
En <i>emacs</i> el indentado sigue siendo un infierno, además, no define
ninguna manera por defecto y se lo deja al usuario y al programador,
haciendo habitual que sea cada <i>modo mayor</i> el encargado de velar por
la correcta estructura del código que se esté trabajando. Esto tiene
sus ventajas y sus desventajas. Entre las ventajas, claro está, la
capacidad de que teniendo <i>buffers</i> abiertos con distintos lenguajes,
cada uno de ellos utilice el indentado que corresponda sin interferir
en los otros <i>buffers</i>. Y la principal entre las desventajas es que la
mayoría de programadores vienen acostumbrados de otros editores a
esperar un comportamiento uniforme en ese sentido y a tener que
cambiarlo cada vez que cambias de lenguaje... y a cambiarlo a su
gusto, naturalmente; encontrándose que después de haber gastado tiempo
en configurar los <i>espacios</i> y <i>tabuladores</i>, resulta que abren un
fichero de código y directamente <i>pasan</i> de sus configuraciones.
</p>

<p>
Hace tiempo que dejé de pegarme con el indentado en <i>emacs</i>,
simplemente espero que funcione correctamente, porque me tiene
acostumbrado a ello: pulsas <i>enter</i> cuando acabas una línea y el
cursor va a la posición que corresponda según los usos y costumbres
del lenguaje en el que estás programando y no me preocupo de
más. Hasta aquí todo correcto y si eres el único programador del
proyecto en el que estés y lo haces siempre con el mismo editor y no
hay interferencias de otros editores, todo funciona perfectamente.
Pero en un mundo ideal, si todo funcionara según las intenciones del
que actúa y no según sus acciones, nos aburriríamos demasiado.
</p>
<div id="outline-container-orgc0fbd76" class="outline-2">
<h2 id="orgc0fbd76">Descubriendo incongruencias en el indentado</h2>
<div class="outline-text-2" id="text-orgc0fbd76">
<p>
Como decía, había estado trabajando un poco con <i>Python</i> y siendo ese
lenguaje tan <i>especial</i> con el tema de los espacios al principio de
línea, me encontré con el <i>infierno del indentado</i> de nuevo.
</p>

<p>
Por poner un ejemplo y que se entienda, vamos a analizar el siguiente
código:
</p>

<div class="org-src-container">
<pre class="src src-python"><span style="color: #ff79c6; font-weight: bold;">def</span> <span style="color: #50fa7b; font-weight: bold;">con_argumento</span>( arg<span style="color: #ff79c6;">=</span><span style="color: #f1fa8c;">""</span> ):
<span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">if</span> arg:
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #8be9fd; font-style: italic;">print</span>(<span style="color: #f1fa8c;">"El argumento es: "</span>, arg)
<span style="background-color: #373844;"> </span>   <span style="color: #ff79c6; font-weight: bold;">else</span>:
<span style="background-color: #373844;"> </span>   <span style="background-color: #373844;"> </span>   <span style="color: #8be9fd; font-style: italic;">print</span>(<span style="color: #f1fa8c;">"No hay argumento"</span>)

con_argumento(<span style="color: #f1fa8c;">"Hola"</span>)
con_argumento()
</pre>
</div>

<p>
Mientras esperas que la salida sea algo como:
</p>

<pre class="example" id="orgb6af9d0">
$ python3 prueba.py 
El argumento es: Hola
No hay argumento
</pre>

<p>
Resulta que lo que lanza es algo como:
</p>

<pre class="example" id="org2a4a592">
$ python3 prueba.py 
  File "prueba.py", line 3
    print("El argumento es: ", arg)
                                  ^
TabError: inconsistent use of tabs and spaces in indentation
</pre>

<p>
<i>¡Mierda! ¡Ya estamos!</i> ... A ver; vamos por partes y os lo explico
todo ─al menos lo poco que yo sé─.
</p>
</div>
<div id="outline-container-org3475420" class="outline-3">
<h3 id="org3475420">Preferencias personales</h3>
<div class="outline-text-3" id="text-org3475420">
<p>
Cuando uno tiene que lidiar con este tema, termina haciéndose una idea
de cómo le gusta o no le gusta a él el indentado. En <i>emacs</i>, como
en otros editores se pueden establecer esos gustos por defecto en el
fichero <code>init.el</code>. Por poner mi ejemplo, yo tengo establecidos los
siguientes parámetros en la lista de <code>custom-set-variables</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">'(indent-tabs-mode nil)
'(tab-width 4)
</pre>
</div>

<p>
También se podría establecer fuera de dicha lista con:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> indent-tabs-mode nil)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> tab-width 4)
</pre>
</div>

<p>
La primera variable estable que no se utilicen tabuladores para el
indentado y que sean reemplazados por espacios y la segunda
variable, establece que cada tabulador tenga un ancho de <code>4</code>. El
evitar que utilice tabuladores evita que al pasar de un editor a otro,
o cuando ves el código en <i>github</i>, por ejemplo, todo el indentado
se haya ido al garete.
</p>

<p>
Como ya he dicho, luego cada <i>modo mayor</i> establece sus parámetros al
gusto del programador del <i>modo</i>, que suele coincidir con lo más
habitual de cada lenguaje. Pero es interesante establecer los valores
por defecto, para los casos en que los <i>modos</i> no tratan el
indentado en su código.
</p>

<p>
¿Y qué ocurre si mis gustos personales no coinciden con los que tenga
quien programó el <i>modo</i> de <i>emacs</i>? Pues tienes dos opciones, te
acostumbras a lo que diga el <i>modo</i> o te creas un <i>gancho</i>, del
estilo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-hook 'python-mode-hook
          (<span style="color: #ff79c6; font-weight: bold;">function</span>
           (<span style="color: #ff79c6; font-weight: bold;">lambda</span> ()
             (<span style="color: #ff79c6; font-weight: bold;">setq</span> indent-tabs-mode nil)
             (<span style="color: #ff79c6; font-weight: bold;">setq</span> tab-width 4))))
</pre>
</div>

<p>
Ese código se ejecutará después de establecerse el <i>modo Python</i>, por
ejemplo, y ajustará los valores deseados a como tú los quieras.  Pero
es muy cansino hacerlo para todos y cada uno de los <i>modos</i> que puedes
utilizar.
</p>
</div>
</div>
<div id="outline-container-org29e82b7" class="outline-3">
<h3 id="org29e82b7">Visualizar los espacios en emacs</h3>
<div class="outline-text-3" id="text-org29e82b7">
<p>
Todo esto, está muy bien: ya tenemos controlada ─un poco─ la fiera del
indentado... ¿Qué pasa cuando nos llega código de otros, escrito con
otros editores o con otros ajustes o gustos? Primero de todo es
identificar dónde está el problema visualizándolo de manera directa.
Si estás acostumbrado a programar en <i>Python</i> y a utilizar editores
diseñados para la programación en dicho lenguaje, estarás más que
harto de ver cómo el editor te muestra los saltos de tabulación y los
espacios para delimitar los bloques de código. Eso también se puede
visualizar de forma sencilla en <i>emacs</i> con el <i>modo menor</i>
<code>whitespace-mode</code>.
</p>

<p>
En este caso, no hay que instalar nada, pues es uno de los modos que
se incluyen en la base de <i>emacs</i>, sólo hay que activarlo llamando a
<code>whitespace-mode</code> (o desactivarlo, con el mismo comando). Al activarse
mostrará <code>ws</code> en la línea de estado.
</p>

<p>
Si lo activas y no lo has utilizado nunca, ni lo has configurado de
otra manera, verás los espacios marcados por un carácter <code>·</code>, los
saltos de línea con <code>$</code>, los tabuladores con <code>»</code>. Todo eso se puede
configurar, no sólo los colores que utilizará, sino también los
caracteres por otros más a tu gusto o costumbre... En mi caso en su
día utilicé el carácter <code>|</code> para el tabulador y el <code>←</code> para el final
de línea, pero quité los ajustes en una remodelación de mi <code>init.el</code> y
ya me he acostumbrado a los valores por defecto.
</p>

<p>
Todo esto al final también es una cuestión de gustos, o más que
gustos, de costumbre... pero que sepáis que poder se puede.
</p>
</div>
</div>
</div>
<div id="outline-container-orgfab53ca" class="outline-2">
<h2 id="orgfab53ca">Cambiar el indentado sin morir en el intento</h2>
<div class="outline-text-2" id="text-orgfab53ca">
<p>
Hemos activado el modo y descubierto que nuestro código luce más o
menos así:
</p>

<pre class="example" id="org2ab11b3">
def·con_argumento(·arg=""·):$
····if·arg:$
»   ····print("El·argumento·es:·",·arg)$
····else:$
········print("No·hay·argumento")····$
····$
con_argumento("Hola")$
con_argumento()$
</pre>

<p>
Además lo marca con colores y vemos que tenemos algunas líneas que
tienen al final espacios en blanco que sobran y que la tercera línea
está mezclando caracteres <code>»</code> y <code>·</code>, lo cual indica que los primeros
cuatro espacios son un tabulador y los siguientes cuatro son espacios
en blanco. ¿Cómo se quita? Muy fácil, con un sencillo par de pasos:
</p>

<ol class="org-ol">
<li>Marcamos las líneas que queremos modificar.</li>
<li>Llamamos al comando <code>untabify</code>, ─si queremos utilizar espacios en
blanco─, o al comando <code>tabify</code>, ─si queremos utilizar tabuladores─,
ya sabéis: va en gustos.</li>
</ol>

<p>
Cuando utilizamos <code>tabify</code> (o <code>untabify</code>) es posible que no veamos que
<i>emacs</i> hace algo, porque el alineamiento puede estar mostrando por
pantalla las cosas de manera normal: como hemos visto en el ejemplo,
si el tabulador está fijado a <code>4</code> y el código está escrito para
ajustarse a esos cuatro espacios, visualmente no se apreciará el
cambio, a no ser que tengamos activado el modo <code>whitespace</code>. Algo más
habitual de lo que se cree, porque los errores cuando no coinciden el
ancho de tabuladores y los espacios, saltan a la vista; pero cuando
coinciden y no se ven a simple vista, suele ser cuando más molestos de
encontrar son.
</p>

<p>
Y ya está explicado todo lo que sé sobre <i>el infierno del indentado</i> y
cómo enfrentarse a él desde <i>emacs</i>.
</p>
</div>
</div>
<div id="outline-container-org39cdd62" class="outline-2">
<h2 id="org39cdd62">Conclusión</h2>
<div class="outline-text-2" id="text-org39cdd62">
<p>
Es algo que hace que me rechinen los dientes cuando tropiezo en
ello. Cada vez que me encuentro con un problema de estos me da vueltas
el higadillo y la bilis lo salpica todo. Tengo que respirar hondo un
par de veces y luego ya, activo <code>whitespace-mode</code> para visualizar los
errores. Como ya habéis visto, es fácil corregirlos e inviertes sólo
un rato, pero un rato que deberías estar dedicando a otra cosa
importante: como comer, dormir, etc.
</p>

<p>
También quiero destacaros que no os dejéis llevar por las prisas y
marquéis todo el <i>buffer</i> con <code>C-x h</code> y llaméis al comando
<code>(un)tabify</code> para cambiar todo de golpe. A ver, poder se puede, pero
esos comandos no distinguen si los espacios están o no al principio de
las líneas y puedes estar modificando también espacios o tabuladores
puestos para hacer una <i>tabla</i> en los comentarios u otros <i>formateos</i>
de texto, como alinear las entradas de variables para visualizarlas
mejor, etc. Dicho de otro modo: «Usadlo con cuidado».
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2019/10/08/el-infierno-del-identado.html</link>
  <pubDate>Tue, 08 Oct 2019 19:55:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Configuración de awesomewm y conky]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-10-01</div>
<p>
Normalmente me gusta escribir los artículos y tenerlos un tiempo en
cuarentena, releerlos y corregirlos, antes de publicarlos. Hoy voy a
hacer una excepción y este artículo está escrito el mismo día de su
publicación y con una relectura básica que puede hacer pensar al
lector que se me ha olvidado toda regla básica de la gramática.  Me lo
han pedido hoy y hoy voy a complacer la demanda, también por
experimentar un poco el modo «blog-kamicace».
</p>

<p>
Pido disculpas anticipadas si algo no se entiende correctamente o
encuentran alguna falta gramatical (o de «horrografía»).
</p>
<div id="outline-container-org176662d" class="outline-2">
<h2 id="org176662d">Configuración de awesomewm y conky</h2>
<div class="outline-text-2" id="text-org176662d">
<p>
Llevo ya un tiempo utilizando <a href="https://awesomewm.org/">awesomewm</a> como mi gestor de ventanas.
Aquí, <a href="https://notxor.nueva-actitud.org/blog/2019/08/01/probando-el-gestor-de-ventanas-awesome/">en este mismo blog ya hablé de ello</a> hace un par de meses. Ayer
en <a href="https://mastodon.social/web/getting-started">Mastodon</a> salió la conversación de escritorios y <a href="https://victorhckinthefreeworld.com/">el amigo
<i>Victorhck</i></a> pidió una captura de pantalla de mi escritorio.  Subí a
esa <i>red social</i> una captura de mi escritorio para la etiqueta
<code>#unixporn</code>, --que es una forma de agrupar nuestras capturas de
pantalla en esa red--. La pongo aquí también para no obligar a quien
lea esto a buscarla por una red que lo mismo no utiliza.
</p>


<figure id="org0183a96">
<img src="./imagen/captura-awesome.png" alt="captura-awesome.png">

</figure>
</div>
</div>
<div id="outline-container-org82eba7c" class="outline-2">
<h2 id="org82eba7c">En cuanto a Conky</h2>
<div class="outline-text-2" id="text-org82eba7c">
<p>
<a href="https://mastodon.social/web/statuses/102883302684472713">En el hilo de <i>Mastodon</i> me piden</a> el código del <i>Conky</i> que se aprecia
a la derecha con un resumen de toda la información de la máquina.  El
<i>conky</i> no aparecía en capturas anteriores, quizá porque lo rescaté
después de no utilizarlo durante el tiempo que <a href="https://i3wm.org/">usaba <i>i3wm</i></a>, porque
acababa siempre sepultado por las ventanas. En la captura que muestro
de mi escritorio podéis ver que eso en <i>awesomewm</i> no tiene por qué
ser así. De hecho, tengo reservado (<i>mentalmente</i>), el segundo
escritorio para la consola y no quiero que ocupe toda la pantalla.
Cuando compilo o lanzo un proceso, puedo tener de un vistazo lo que
estoy haciendo y cómo reacciona la máquina: consumo de CPU, consumo de
RAM, de disco, etc.  Por no liarme con más explicaciones pongo el
código de <i>conky</i> aquí por si a alguien le puede servir: básicamente
también lo copié de algún sitio y lo modifiqué a mi gusto.
</p>

<div class="org-src-container">
<pre class="src src-lua"><span style="color: #6272a4;">-- </span><span style="color: #6272a4;">conky configuration
</span>
conky.config = {
   background = <span style="color: #bd93f9;">false</span>,
   use_xft = <span style="color: #bd93f9;">true</span>,
   font = <span style="color: #f1fa8c;">'Fira Code:size=9'</span>,
   font1 = <span style="color: #f1fa8c;">'Fira Code:size=20'</span>,
   font2 = <span style="color: #f1fa8c;">'Fira Code:size=15'</span>,
   xftalpha = 0.8,
   update_interval = 2.0,
   total_run_times = 0,
   own_window = <span style="color: #bd93f9;">false</span>,
   own_window_hints = <span style="color: #f1fa8c;">"below"</span>,
   double_buffer = <span style="color: #bd93f9;">true</span>,
   draw_shades = <span style="color: #bd93f9;">false</span>,
   draw_outline = <span style="color: #bd93f9;">false</span>,
   draw_borders = <span style="color: #bd93f9;">false</span>,
   stippled_borders = 0,
   border_margin = 4,
   border_width = 1,
   default_color = <span style="color: #f1fa8c;">'white'</span>,
   default_shade_color = <span style="color: #f1fa8c;">'brown'</span>,
   default_outline_color = <span style="color: #f1fa8c;">'white'</span>,
   alignment = <span style="color: #f1fa8c;">'top_right'</span>,
   top_cpu_separate = <span style="color: #bd93f9;">true</span>,
   gap_x = 10,
   gap_y = 10,
   no_buffers = <span style="color: #bd93f9;">true</span>,
   uppercase = <span style="color: #bd93f9;">false</span>,
   cpu_avg_samples = 2,
   net_avg_samples = 2,
   override_utf8_locale = <span style="color: #bd93f9;">true</span>,
   use_spacer = <span style="color: #f1fa8c;">'none'</span>,
}

conky.text = <span style="color: #f1fa8c;">[[
$hr
${alignc}${color #FF9922}${font1}${time %e}
${alignc}${color white}${font}${time %B} ${color #AA9922}${time %Y}
${alignc}${color yellow}${font}${time %a}
${color yellow}${time %Z: }${alignc}${color #AA9922}${font2}${time %H:%M}${font}
${color white}$hr
${color yellow}UpTime: ${color #AA9922}$uptime

${color yellow}CPU:${color #AA9922} $cpu% ${alignr} ${exec sensors | grep "Core 0" | cut -c15-22}
${cpugraph 20,400 FFFFFF AA9922}
${color yellow}Load: ${color #AA9922}$loadavg
${color yellow}Procesos: ${color #AA9922}$processes
${color yellow}Running: ${color #AA9922}$running_processes
${color white}Cores:
${color white}Core 1: ${color #AA9922}${cpubar cpu1 6,220}${color white} ${freq 1} MHz ${cpu cpu1}%
${color white}Core 2: ${color #AA9922}${cpubar cpu2 6,220}${color white} ${freq 2} MHz ${cpu cpu2}%
${color white}Core 3: ${color #AA9922}${cpubar cpu3 6,220}${color white} ${freq 3} MHz ${cpu cpu3}%
${color white}Core 4: ${color #AA9922}${cpubar cpu4 6,220}${color white} ${freq 4} MHz ${cpu cpu4}%

${color white}$hr
${color yellow}Uso CPU:
${color #AA9922}Nombre                           PID   CPU%   MEM%
${color white}${top name 1}               ${top pid 1} ${top cpu 1} ${top mem 1}
${color white}${top name 2}               ${top pid 2} ${top cpu 2} ${top mem 2}
${color white}${top name 3}               ${top pid 3} ${top cpu 3} ${top mem 3}
${color white}${top name 4}               ${top pid 4} ${top cpu 4} ${top mem 4}

${color yellow}Uso MEM:
${color #AA9922}Nombre                          MEM%
${color white}${top_mem name 1}              ${top_mem mem 1}
${color white}${top_mem name 2}              ${top_mem mem 2}
${color white}${top_mem name 3}              ${top_mem mem 3}
${color white}${top_mem name 4}              ${top_mem mem 4}

${color white}$hr
${color white}MEM: ${color #AA9922}$memperc% ${alignr}$mem/$memmax
${memgraph 20,400 FFFFFF AA9922}
${color white}SWAP: ${color #AA9922}$swapperc% ${alignr}$swap/$swapmax
${swapbar 6,400}
${if_running cmus}
${color white}$hr
${color white}${cmus_artist}: ${color yellow}${cmus_album}
${color white}${cmus_track}-${color yellow}${cmus_title}
${color #AA9922}${cmus_timeleft} ${cmus_progress 10,300} ${endif}
${if_running mocp}
${color white}$hr
${color white}${moc_state}
${color white}${moc_artist}: ${color yellow}${moc_album}
${color white}${moc_curtime}-${color yellow}${moc_song}
${color #AA9922}${moc_timeleft}-${moc_totaltime} ${endif}
${color white}$hr
${color white}ROOT: ${color #AA9922}${fs_free_perc /}% ${alignr}${color #AA9922}${fs_free /}/${fs_size /}
${fs_bar 6,400 /}
${color white}HOME: ${color #AA9922}${fs_free_perc /home}% ${alignr}${color #AA9922}${fs_free /home}/${fs_size /home}
${fs_bar 6,400 /home}
${color white}$hr
${if_existing /sys/class/net/wlp8s0b1/operstate up}
${color yellow}WIFI: ${color white}${wireless_essid wlp8s0b1}${color #AA9922}${alignr}${addr wlp8s0b1}
${color white}Bajada: ${alignr}${color #AA9922}${downspeed wlp8s0b1}
${downspeedgraph wlp8s0b1 20,400 FFFFFF AA9922}
${color white}Subida: ${alignr}${color #AA9922}${upspeed wlp8s0b1}
${upspeedgraph wlp8s0b1 20,400 FFFFFF AA9922}
${endif}
${if_existing /sys/class/net/eth0/operstate up}
${color yellow}NET:${alignr}${color #AA9922}${addr eth0}
${color white}Bajada: ${alignr}${color #AA9922}${downspeed eth0}${color}
${downspeedgraph eth0 20,400 FFFFFF AA9922}
${color white}Subida: ${alignr}${color #AA9922}${upspeed eth0}
${upspeedgraph eth0 20,400 FFFFFF AA9922}
${endif}
${if_existing /sys/class/net/enp9s0u1/operstate up}
${color yellow}USB:${alignr}${color #AA9922}${addr enp9s0u1}
${color white}Bajada: ${alignr}${color #AA9922}${downspeed enp9s0u1}${color}
${downspeedgraph enp9s0u1 20,400 FFFFFF AA9922}
${color white}Subida: ${alignr}${color #AA9922}${upspeed enp9s0u1}
${upspeedgraph enp9s0u1 20,400 FFFFFF AA9922}
${endif}
]]</span>
</pre>
</div>

<p>
Algunas cosas, evidentemente, deben cambiarse para ajustarse a otra
máquina.  Por ejemplo, los nombres de las conexiones físicas de red.
También es posible que se pueda obtener alguna información de forma
más directa, como en la temperatura del procesador, que no encontré
modo de conseguirlo de <i>sensors</i> y lo que hice fue un apaño tal que:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #ff79c6; font-weight: bold;">exec</span> sensors | grep <span style="color: #f1fa8c;">"Core 0"</span> | cut -c15-22
</pre>
</div>

<p>
Quería la información de la temperatura de la CPU, pero como soy torpe
no encontré ningún sitio de donde extraer el dato de forma directa.
Así que lo que hice fue tirar de <code>sensors</code> y de allí obtener la
información de uno de los <i>cores</i> con <code>grep</code>, cortando la cadena
obtenida con <code>cut</code> para que me muestre sólo la temperatura.
</p>

<p>
El otro cambio a subrayar es que cuando copié de algún sitio esa
configuración, quien la hiciera, utilizaba como reproductor de música
<code>moc</code>. A mí me gusta más, y lo utilizo frecuentemente, <code>cmus</code> así que
escribí un poco de código para añadir soporte para él.
</p>

<p>
Otro de los cambios que hice sobre el original que copié es el uso de
bastantes condicionales para mostrar la información. Por ejemplo, en
la información de uso de la red, dependiendo de qué dispositivo esté
activo. O en el caso del reproductor de música, de qué reproductor de
música (<code>cmus</code> o <code>moc</code>) tenga activo.
</p>
</div>
</div>
<div id="outline-container-org92ab42e" class="outline-2">
<h2 id="org92ab42e">Soporte multimonitor</h2>
<div class="outline-text-2" id="text-org92ab42e">
<p>
Normalmente trabajo en un portátil y no lo enchufo a ningún otro
monitor. Sin embargo, de vez en cuando doy alguna charla y lo tengo
que enchufar a algún proyector.  No suele haber problema cuando me
llevo el mío propio, pues me tengo hecho ya un <i>script</i> que me lo
ajusta nada más enchufarlo:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #6272a4;">#</span><span style="color: #6272a4;">!/bin/</span><span style="color: #ff79c6; font-weight: bold;">sh</span><span style="color: #6272a4;">
</span>xrandr --output LVDS-1 --primary --mode 1920x1080 --pos 0x0 --rotate normal --output HDMI-1 --mode 1600x1200 --pos 1920x0 --rotate normal --output VGA-1 --off 
<span style="color: #6272a4;"># </span><span style="color: #6272a4;">proyector.sh</span>
</pre>
</div>

<p>
Después de conectarlo y encenderlo, desde una consola llamo a
<code>proyector.sh</code> y ya está listo para trabajar, con la pantalla del
ordenador a la izquierda y la del proyector a la derecha.
</p>

<p>
La cosa es algo más complicada cuando tengo que utilizar un proyector
que no es el mío. En ese caso, depende de qué salida conectes HDMI,
VGA, de la resolución del aparato y de otras variables que complican
el tenerlo todo preparado en un <i>script</i> sencillo, como el anterior.
Para lidiar con esos problemas utilizo un programita que se llama
<code>arandr</code> (acrónimo de <i>Another XrandR GUI</i>) que me facilita hacer la
configuración de un modo más visual para después aplicarla o incluso
guardarla en un directorio <code>~/.screenlayouts</code> desde donde llamarla (de
ahí llamo a los más habituales para mí, incluyendo el anterior).
</p>

<p>
Cuando he activado el modo multipantalla en <code>awesomewm</code> he visto que
cada pantalla es independiente de las demás. Cada una de ellas
conserva todos los escritorios que tengas definidos. En <code>i3wm</code>
recuerdo que asignaba el <code>1</code> a la pantalla principal y el <code>2</code> a la
secundaria y luego el resto los va abriendo según qué pantalla <i>tenga
el foco</i> cuando lo crees. Esto acelera el modo en que puedes acceder a
un escritorio concreto, pues no se repiten. <code>awesomewm</code>, sin embargo,
lo que hace es seguir el puntero del ratón para establecer <i>el foco</i>
de qué pantalla responderá a tus comandos.
</p>

<p>
Básicamente, y por resumir, el cambio que he hecho desde que presenté
mis inicios con <code>awesomewm</code> sobre este aspecto, es una combinación de
teclas que activa mi proyector, sin necesidad de recurrir a llamarlo
desde la línea de comandos.
</p>
</div>
</div>
<div id="outline-container-org2e3a0c5" class="outline-2">
<h2 id="org2e3a0c5">Manejo de ventanas</h2>
<div class="outline-text-2" id="text-org2e3a0c5">
<p>
Cuando presenté hace un par de meses mis primeros acercamientos a
<code>awesomewm</code> las ventanas tenían un icono de aplicación, un título y
una ristra de botones para manejarlas, pero he prescindido de ello. A
cambio, el icono de aplicación lo muestro en la barra de estado (la
llaman <i>wibox</i> en <code>awesome</code>). Al desaparecer los botones de manejo,
las ventanas sólo cuentan con las opciones por teclado. En mi caso he
configurado las siguientes teclas:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Tecla</th>
<th scope="col" class="org-left">Función</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">Meta+Mayús.+q</td>
<td class="org-left">Cerrar la ventana</td>
</tr>

<tr>
<td class="org-left">Alt+Mayús.+m</td>
<td class="org-left"><i>Magnify mode</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup></td>
</tr>

<tr>
<td class="org-left">Meta+f</td>
<td class="org-left">Pantalla completa</td>
</tr>

<tr>
<td class="org-left">Meta+Control+espacio</td>
<td class="org-left">cambiar el modo de la ventana flotante</td>
</tr>

<tr>
<td class="org-left">Meta+t</td>
<td class="org-left">mantener la ventana siempre visible (<i>on top</i>)</td>
</tr>

<tr>
<td class="org-left">Meta+m</td>
<td class="org-left">maximizar la ventana</td>
</tr>

<tr>
<td class="org-left">Meta+n</td>
<td class="org-left">minimizar la ventana</td>
</tr>
</tbody>
</table>

<p>
Esos son los atajos que más utilizo cuando trabajo y los más
necesarios.  Hay definidos algunos más (para mover ventanas entre
pantallas, por ejemplo) que no menciono ahí.
</p>

<p>
Para hacer desaparecer los títulos de las ventanas, sólo tuve que
encontrar una línea que decía:
</p>

<div class="org-src-container">
<pre class="src src-lua">properties = { titlebars_enabled = <span style="color: #bd93f9;">true</span> }
</pre>
</div>

<p>
y ponerla a:
</p>

<div class="org-src-container">
<pre class="src src-lua">properties = { titlebars_enabled = <span style="color: #bd93f9;">false</span> }
</pre>
</div>
</div>
</div>
<div id="outline-container-org46cb662" class="outline-2">
<h2 id="org46cb662">Otros cambios</h2>
<div class="outline-text-2" id="text-org46cb662">
<p>
Se han producido algunos otros cambios, básicamente en lo que
<code>awesomewm</code> llaman <code>wibox</code> que es la barra de estado de toda la
vida. Empezando de izquierda a derecha los voy a ir enumerando.
</p>
</div>
<div id="outline-container-orgaa8fa4f" class="outline-3">
<h3 id="orgaa8fa4f">Iconos de escritorio</h3>
<div class="outline-text-3" id="text-orgaa8fa4f">
<p>
En lugar de mantener las etiquetas numéricas lo cambié por unos
<del>iconos muy molones</del> símbolos para distinguirlos. En <code>i3wm</code> el nombre
numérico se corresponde con la combinación que accede a cada
escritorio, sin embargo en <code>awesomewm</code> el nombre es sólo una etiqueta
y se accede según la posición en la que esté colocado. Por eso, se me
hacía confuso algunas veces que, sin darme cuenta, había cambiado las
posiciones, tenía que acceder al escritorio llamado «2» con la
combinación <code>Meta+3</code>, por ejemplo. Puesto, que solo son nombres, o
etiquetas, decidí marcarlas con algún icono más significativo y
repartir funciones entre ellas, adecuando también el <i>layout</i> de
distribución de las ventanas un poco.
</p>

<p>
Los iconos en realidad son caracteres que se pueden encontrar en 
<a href="https://fontawesome.com/cheatsheet">https://fontawesome.com/cheatsheet</a> Para activarlos sólo tuve
que modificar los <code>tagnames</code> en el fichero <code>theme.lua</code>.
</p>

<div class="org-src-container">
<pre class="src src-lua"><span style="color: #6272a4;">-- </span><span style="color: #6272a4;">http://fontawesome.io/cheatsheet
</span>awful.util.tagnames = { <span style="color: #f1fa8c;">"&#61911;"</span>, <span style="color: #f1fa8c;">"&#61728;"</span>, <span style="color: #f1fa8c;">"&#62057;"</span>, <span style="color: #f1fa8c;">"&#61637;"</span>, <span style="color: #f1fa8c;">"&#61639;"</span>, <span style="color: #f1fa8c;">"&#61573;"</span>, <span style="color: #f1fa8c;">"&#61744;"</span>, <span style="color: #f1fa8c;">"&#61675;"</span>, <span style="color: #f1fa8c;">"&#61904;"</span> }
</pre>
</div>

<p>
Simplemente son etiquetas de un carácter. Lo que hice fue buscar entre
los infinitos códigos que muestra la página los que me podrían servir
y hacer un «corta-pega» del carácter en la correspondiente cadena de
texto. Así, ya sé que es un <i>nombre</i> y para acceder a él tengo que
utilizar el número de escritorio según el orden.
</p>

<p>
Necesita más detalle el significado de la <i>etiqueta</i>.  Para explicarlo
rápidamente, los tres modos que más utilizo son los tres primeros. En
el primero abro las aplicaciones de comunicación en un <i>layout</i>
maximizado: <code>Gajim</code>, <code>Telegram desktop</code> y <code>hexchat</code>. En el segundo
suelo abrir la consola, normalmente abro una sesión de <code>tmux</code>, cargo
el reproductor de música <code>cmus</code> cuando quiero concentrarme en algo y
así tengo la posibilidad de ir abriendo consolas según necesito. Aquí
es donde suelo compilar o hacer alguna otra acción que necesita
seguimiento de qué hace la máquina (por ejemplo, lanzar servidores web
para pruebas y cosas como esas) y por eso el <i>layout</i> de esta etiqueta
es «flotante» permitiéndome ver el <code>conky</code> de fondo.  En el tercer
escritorio suelo lanzar los navegadores: de forma habitual es
<i>firefox</i>, por eso elegí ese icono, pero hago pruebas de visualización
con otros.
</p>

<p>
Los demás escritorios tienen etiquetas que, en principio, no se
relacionan demasiado con lo que suelo hacer en ellos, aunque <code>emacs</code>
suelo abrirlo en el cuarto y <code>audacity</code> en el séptimo; es posible que
mueva las aplicaciones de uno a otro para cosas tan básicas como
consultar algo en el navegador mientras escribo en el editor, etc.
</p>
</div>
</div>
<div id="outline-container-orgf0488ba" class="outline-3">
<h3 id="orgf0488ba">Indicador de Layout</h3>
<div class="outline-text-3" id="text-orgf0488ba">
<p>
En el tema original el indicador de <i>layout</i> estaba situado a la
derecha del todo y decidí cambiarlo a una zona más visible,
cambiándole también el color de fondo y poniéndole un marco angulado
más por razones estéticas que prácticas. Pero el resultado se puede
ver a simple vista y no entraré en más detalles. Por dejarlo más
claro, en el apartado de código que utiliza el <i>theme</i> para crear el
<code>wibox</code> dejé el código de la siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-lua">{ <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">Left widgets
</span>    layout = wibox.layout.fixed.horizontal,
    s.mytaglist,
    arrl_rd,     <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">&#225;ngulo a la derecha color oscuro
</span>    wibox.container.background(s.mylayoutbox, theme.bg_focus),  <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">mostrar el icono del layout
</span>    arrl_dr,     <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">&#225;ngulo a la derecha color claro
</span>    s.mypromptbox,
    spr,
},
</pre>
</div>
</div>
</div>
<div id="outline-container-org008895b" class="outline-3">
<h3 id="org008895b">Dejar el icono de las aplicaciones en el taglist</h3>
<div class="outline-text-3" id="text-org008895b">
<p>
En el tema que utilicé para ajustar y personalizar el mío, sólo se
utilizaban los títulos o nombres de las tareas para mostrarlo en el
<code>taglist</code>. Aprovechando que existe el <code>taglist</code> puedes utilizarlo como
<i>botones</i> para cambiar de una aplicación a otra dentro de un mismo
escritorio, aunque en mi caso particular ya venía utilizando <code>rofi</code> en
modo <code>window</code> para hacer esos saltos. También me he acostumbrado ya a
las combinaciones de <code>awesomewm</code>:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Combinación</th>
<th scope="col" class="org-left">Acción</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">Alt+h</td>
<td class="org-left"><i>focus left</i></td>
</tr>

<tr>
<td class="org-left">Alt+j</td>
<td class="org-left"><i>focus down</i></td>
</tr>

<tr>
<td class="org-left">Alt+k</td>
<td class="org-left"><i>focus up</i></td>
</tr>

<tr>
<td class="org-left">Alt+l</td>
<td class="org-left"><i>focus right</i></td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>
</tbody>
</table>

<p>
El caso es que añadí los iconos de las aplicaciones simplemente
poniendo a <code>true</code> la variable <code>theme.tasklist_disable_icon</code> 
</p>
</div>
</div>
</div>
<div id="outline-container-org2eaaeb3" class="outline-2">
<h2 id="org2eaaeb3">Conclusión</h2>
<div class="outline-text-2" id="text-org2eaaeb3">
<p>
De momento, mi manera de trabajar se ha visto facilitada por
<code>awesomewm</code> y mi adaptación ha sido rápida. He de reconocer que ya
venía adaptado a los gestores de ventana de tipo mosaico gracias a
otro magnífico gestor como es <code>i3wm</code>. ¿Por qué me he cambiado?  Podría
enumerar varias razones como las estéticas; sin embargo, sobre todas
las cosas está la manera de mantener el foco en la ventana activa.
</p>

<p>
Cuando abres una aplicación en sus modos de mosaico siempre utiliza,
al menos, media pantalla apilando el resto de ventanas en pequeño,
pero dándole a la última la preponderancia de espacio necesario.
Puedes moverte por las aplicaciones con las teclas que he descrito en
el punto anterior o cambiar la posición de las mismas añadiendo la
tecla de <code>mayúsculas</code> a la combinación.  Además, está el modo
<i>magnify</i> en el que puedes traer a primer plano la aplicación que
quieras con la combinación <code>Alt+Mayús.+m</code> y devolverla a su sitio con
la misma. De todas formas, lo mejor para esa forma de trabajar es
utilizar el <i>layout magnify</i>, pues al cambiar de aplicación con
<code>Alt+j</code>, por ejemplo, cambia qué ventana pasa a primer plano y
mantiene en mosaico el resto en el fondo.
</p>

<p>
Ademñas, los modos de mosaico son variados y las ventanas se ajustan
automáticamente al <i>layout</i> seleccionado, por lo que es fácil cambiar
la distribución de ventanas con <code>Meta+espacio</code> para ir según el orden
de <i>layouts</i> y <code>Meta+Mayús.+espacio</code> para hacerlo al contrario.
</p>

<p>
Y por todo eso, terminé cambiándome a <code>awesomewm</code>. Pero como cada uno
somos un mundo y tenemos nuestras manías, no recomiendo especialmente
un gestor de ventanas u otro. Entiendo que haya gente que se ponga de
los nervios si las ventanas no tienen un título, o una «x» para
cerrarlas, o no soportan las fechas en formato ISO, o no quieran
gastar ni un ciclo de CPU para mostrar la información en pantalla con
<code>conky</code>. Pero para eso utilizamos GNU/Linux, para adaptarlo a nosotros
y no tener que adaptarnos nosotros a lo que alguien decide que es la
forma correcta de trabajar.
</p>

<p>
Hasta aquí, mi repaso rápido a <code>awesomewm</code> y <code>conky</code>
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
El <i>Magnify mode</i> es un modo en que la ventana se presenta
centrada en la pantalla en primer plano, distribuyendo el resto según
el modo que tenga activado ese escritorio.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/linux/index.html">linux</a> <a href="/tags/awesome/index.html">awesome</a> <a href="/tags/conky/index.html">conky</a> <a href="/tags/configuración/index.html">configuración</a> ]]></description>
  <category><![CDATA[linux]]></category>
  <category><![CDATA[awesome]]></category>
  <category><![CDATA[conky]]></category>
  <category><![CDATA[configuración]]></category>
  <link>https://notxor.nueva-actitud.org/2019/10/01/configuracion-de-awesomewm-y-conky.html</link>
  <pubDate>Tue, 01 Oct 2019 16:36:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Intervuo de la tago 2019-09-22]]></title>
  <description><![CDATA[
<div class="post-author">Frateco</div>
<div class="post-date">2019-09-22</div>
<p>
La dimanĉo 22 de septembro, ni iris al radiostacio <i>Radio MAI</i> por
paroli pri Esperanto. Mi ĉi tie ligis la aŭdadon, sed la elparolado
estas en la hispana:
</p>

<audio controls>
    <source src="https://ia601509.us.archive.org/13/items/esperanto-20190922/esperanto-20190922.mp3">
    <a href="https://ia601509.us.archive.org/13/items/esperanto-20190922/esperanto-20190922.mp3" title="Intervuo-pri-esperanto">Elŝuti</a>
    </audio>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/radio/index.html">radio</a> <a href="/tags/esperanto/index.html">esperanto</a> ]]></description>
  <category><![CDATA[radio]]></category>
  <category><![CDATA[esperanto]]></category>
  <link>https://notxor.nueva-actitud.org/2019/09/22/intervuo-de-la-tago-2019-09-22.html</link>
  <pubDate>Sun, 22 Sep 2019 00:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Plegando el código]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-09-20</div>
<p>
Cuando programo me gusta ver todo el código. A veces en ficheros
largos los desplazamientos pueden ser largos, pero me apaño bien
poniendo marcas donde saltar o utilizando <code>M-g g</code> (<code>goto-line</code>) para
saltar a la línea deseada, o <code>M-g c</code> (<code>goto-char</code>) para ir a un
carácter determinado --pero esto es más complicado de saber a
priori--. Se puede uno mover  de forma directa a otros sitios (al
siguiente error, al error previo o a una posición determinada de la
línea actual. Pero como ya digo, lo que más utilizo es la función
<code>goto-line</code>.
</p>

<p>
¿Por qué estoy contando esto? Pues hace unos días un amigo ha hecho un
cambio de trabajo. Hasta ahora programaba utilizando IDE's y
herramientas muy concretas desde el «güindón del Bili Puertas» y ahora
se encontraba en otro mundo. Puede utilizar el S.O. que prefiera con
las herramientas que quiera para escribir el código. Él, habiéndome
leído bastante lo <i>pesadico</i> que me pongo con el <i>software libre</i> en
general y <i>emacs</i> en particular, ha decidido que probará a cambiar de
herramientas y pasarse a la vía de los libres.  Principalmente, porque
eso le permite llevarse al trabajo un ordenador viejo en lugar del
<i>carísimo de la muerte</i> y si se le escacharra en el tranvía pues
tampoco pierde mucho. El caso es que hablando con él me dice que se ha
repasado todos los artículos de mi <i>blog</i> sobre <i>emacs</i> y <code>org-mode</code>:
se ha configurado la agenda, se ha configurado el correo electrónico,
se ha pasado a <code>i3wm</code> como entorno de ventanas (<code>awesomewm</code> no le ha
convencido), carga el editor con <code>emacsclient</code>, incluso ha configurado
el <code>powerline</code> y el <code>tree-mode</code>, y se ha instalado <code>orgzly</code> en el
móvil.  Vamos, que va el tío y sigue todos mis consejos,
personalizándose algunas cosas incluso metiendo algo de código en
<code>elisp</code> que dice haber aprendido de mi <i>minicurso</i>. Y al final va y me
hace una pregunta tonta: <i>Oye, tú que sabes mucho de esto ¿Cómo se
pliega el código?</i>
</p>

<p>
Al principio no supe bien a qué se refería... <i>¿plegar código?</i>.
</p>

<blockquote>
<p>
─ Seguro que se puede. <code>org-mode</code> te lo muestra plegado por defecto si
no le especificas otra cosa en el <code>#+STARTUP</code> ─me dijo.
</p>

<p>
─ ¡Oh! ¡Vaya! ¿¡Te refieres al <code>outline</code>!? ¡Vale! Escribo una
<i>minientrada</i> en mi <i>blog</i> para explicarlo, pero la respuesta corta
es: <i>activa el <code>outline-minor-mode</code> y podrás plegarlo</i>.
</p>

<p>
─ ¡Otro paquete que instalar!
</p>

<p>
─ No, no. <code>outline</code> viene de serie con <i>emacs</i>, no tienes que instalar
nada. Lo único que tienes que hacer es configurar las teclas si
quieres, pero eso ya te lo explico en el <i>blog</i> que es más largo.
</p>
</blockquote>

<p>
Bueno, el caso es que estoy aquí para explicar básicamente eso y no
mucho más. Como he dicho, es un modo que no suelo utilizar porque yo
soy de los que les gusta tener todo el código a la vista, pero alguna
vez lo he utilizado para <i>plegar</i> comentarios enormes que te hacen
perder el hilo del código (es lo que tiene intentar hacer
<i>programación literaria</i> escribiéndolo todo en el mismo fichero del
código).
</p>

<p>
Y lo primero un aviso: no confundáis <code>outline-minor-mode</code> con
<code>outline-mode</code>.  Esto es un modo mayor y por tanto te cerrará el modo
en el que estés trabajando para ponerse él. Lo normal, cuando
programas es utilizar el <i>minor</i>, que te permite tener activado un
modo mayor para <i>Python</i>, por ejemplo, y el plegado de código a la
vez.
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Comando</th>
<th scope="col" class="org-left">Acción</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>M-x outline-minor-mode</code></td>
<td class="org-left">Establece el modo</td>
</tr>

<tr>
<td class="org-left"><code>C-c @ C-t</code></td>
<td class="org-left">oculta todo el <i>buffer</i> excepto cabeceras</td>
</tr>

<tr>
<td class="org-left"><code>C-c @ C-a</code></td>
<td class="org-left">muestra el texto completo del <i>buffer</i></td>
</tr>

<tr>
<td class="org-left"><code>C-c @ C-q</code></td>
<td class="org-left">oculta todo menos las cabeceras principales</td>
</tr>

<tr>
<td class="org-left"><code>C-c @ TAB</code></td>
<td class="org-left">muestra todas las subcabeceras de la actual</td>
</tr>

<tr>
<td class="org-left"><code>C-c @ C-k</code></td>
<td class="org-left">muestra las subcabeceras pero no los cuerpos</td>
</tr>

<tr>
<td class="org-left"><code>M-x outline-previous-heading</code></td>
<td class="org-left">va a la cabecera anterior</td>
</tr>

<tr>
<td class="org-left"><code>M-x outline-next-heading</code></td>
<td class="org-left">va a la siguiente cabecera</td>
</tr>

<tr>
<td class="org-left"><code>C-c @ C-p</code></td>
<td class="org-left">va a la anterior cabecera visible</td>
</tr>

<tr>
<td class="org-left"><code>C-c @ C-n</code></td>
<td class="org-left">va a la siguiente cabecera visible</td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>
</tbody>
</table>

<p>
Como se puede ver la combinación <code>C-c @</code> no es precisamente de las
cómodas, pero en la documentación del paquete se propone o se sugiere,
para quien utilice este modo con profusión otra configuración que
puede facilitar el acceso un poco, copio el siguiente código de allí
(no lo he probado, pero entiendo que estando en la ayuda del paquete
del modo, debe ser correcto):
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">; </span><span style="color: #6272a4;">Outline-minor-mode key map
</span>(define-prefix-command 'cm-map nil <span style="color: #f1fa8c;">"Outline-"</span>)
<span style="color: #6272a4;">; </span><span style="color: #6272a4;">HIDE
</span>(define-key cm-map <span style="color: #f1fa8c;">"q"</span> 'hide-sublevels)    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Hide everything but the top-level headings
</span>(define-key cm-map <span style="color: #f1fa8c;">"t"</span> 'hide-body)         <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Hide everything but headings (all body lines)
</span>(define-key cm-map <span style="color: #f1fa8c;">"o"</span> 'hide-other)        <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Hide other branches
</span>(define-key cm-map <span style="color: #f1fa8c;">"c"</span> 'hide-entry)        <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Hide this entry's body
</span>(define-key cm-map <span style="color: #f1fa8c;">"l"</span> 'hide-leaves)       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Hide body lines in this entry and sub-entries
</span>(define-key cm-map <span style="color: #f1fa8c;">"d"</span> 'hide-subtree)      <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Hide everything in this entry and sub-entries
</span><span style="color: #6272a4;">; </span><span style="color: #6272a4;">SHOW
</span>(define-key cm-map <span style="color: #f1fa8c;">"a"</span> 'show-all)          <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Show (expand) everything
</span>(define-key cm-map <span style="color: #f1fa8c;">"e"</span> 'show-entry)        <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Show this heading's body
</span>(define-key cm-map <span style="color: #f1fa8c;">"i"</span> 'show-children)     <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Show this heading's immediate child sub-headings
</span>(define-key cm-map <span style="color: #f1fa8c;">"k"</span> 'show-branches)     <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Show all sub-headings under this heading
</span>(define-key cm-map <span style="color: #f1fa8c;">"s"</span> 'show-subtree)      <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Show (expand) everything in this heading &amp; below
</span><span style="color: #6272a4;">; </span><span style="color: #6272a4;">MOVE
</span>(define-key cm-map <span style="color: #f1fa8c;">"u"</span> 'outline-up-heading)                <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Up
</span>(define-key cm-map <span style="color: #f1fa8c;">"n"</span> 'outline-next-visible-heading)      <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Next
</span>(define-key cm-map <span style="color: #f1fa8c;">"p"</span> 'outline-previous-visible-heading)  <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Previous
</span>(define-key cm-map <span style="color: #f1fa8c;">"f"</span> 'outline-forward-same-level)        <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Forward - same level
</span>(define-key cm-map <span style="color: #f1fa8c;">"b"</span> 'outline-backward-same-level)       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Backward - same level
</span>(global-set-key <span style="color: #f1fa8c;">"\M-o"</span> cm-map)
</pre>
</div>

<p>
De ese modo establece <code>M-o</code> como la combinación para el plegado y
además añade configuración para todas las posibles acciones. Si os
fijáis en la tabla anterior, había dos que la forma de acceder era con
el comando completo desde el <i>minibuffer</i>. Es una combinación bastante
<i>apañá</i>, porque no recuerdo ningún modo que mapee <code>M-o</code> para ninguna
acción (así que tendrás pocas colisiones) y la <code>o</code> es fácil recordarlo
por lo de <i>outline</i>.
</p>

<p>
Por último, si vas a utilizar este modo con bastante asiduidad como
para configurar las teclas de acceso, lo mismo también quieres que se
active cuando abras un archivo de código:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-hook 'prog-mode-hook 'outline-minor-mode)
</pre>
</div>

<p>
Y esto es todo. Espero haber sido de ayuda.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/programación/index.html">programación</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[programación]]></category>
  <link>https://notxor.nueva-actitud.org/2019/09/20/plegando-el-codigo.html</link>
  <pubDate>Fri, 20 Sep 2019 23:25:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Revuo de la Frateco el Zaragozo]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-09-18</div>
<p>
Kelkaj monatoj antaŭe en Frateco (el Zaragozo) ni faris provon por
revivigi revuon de la Asocio. Ni pretis la unuan numeron kaj ties
desegnon mi kreis.
</p>

<p>
Mi ne scias tute bone kial ni ne pli disvastigas la numeron. Unue ni
pensis printi kelkajn revuojn papere, sed la plej kutima disvastigado
estos elektronika.
</p>

<p>
Mi lasas tie por certigi la laboron, kiun ni faris kaj montri ĝin al
esperantujo. Mi esperas la daŭron de la projekto kaj ke mi povos
publikigi multajn novajn numerojn ĉi tie.
</p>

<p>
Ankaŭ ni satus komentojn. Kion ŝajnas la revuon, kion vi ŝatas aŭ
kontraŭe: kion vi ne ŝatas. Eble ankaŭ, pri kiuj temoj vi volus legi.
</p>


<figure id="org40b448e">
<img src="./imagen/portada-01.png" alt="portada-01.png">

<figcaption><span class="figure-number">Figure 1: </span>Fronta kovrilo de la revuo.</figcaption>
</figure>

<p>
<a href="./archivo/revuo-n01.pdf">Ligilo al revuo en PDF.</a>
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/revuo/index.html">revuo</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[revuo]]></category>
  <link>https://notxor.nueva-actitud.org/2019/09/18/revuo-de-la-frateco-el-zaragozo.html</link>
  <pubDate>Wed, 18 Sep 2019 00:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Avances en el jeugo de las naves]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-09-17</div>
<p>
Pensabas que me había olvidado del <i>blog</i>, pues no. Pero a estas
alturas tengo el tiempo libre casi agotado para destinarlo y
repartirlo entre todos los proyectos que tengo abiertos.  Pero
intentaré retomar el <i>blogueo</i> tan pronto como pueda. Hoy sólo me he
pasado por aquí para mostrar una perlita pequeña de cosas que voy
haciendo.
</p>

<p>
<a href="https://notxor.nueva-actitud.org/blog/2019/07/17/naves-vaporosas/">Ya hablé por aquí en otra ocasión de un proyecto</a> de juego con naves en
el que estoy participando. Traigo hoy un avance de cómo están
marchando las cosas.
</p>

<p>
Somos lentos pero ya se puede enseñar algo más, así que os pongo
algunas capturas para que lo veáis por vosotros mismos:
</p>


<figure id="orgdec3afc">
<img src="./imagen/naves-nuevas-texturas.png" alt="naves-nuevas-texturas.png">

<figcaption><span class="figure-number">Figure 1: </span>Una formación de los distintos tipos de naves con diferentes colores</figcaption>
</figure>


<figure id="org51ed1f4">
<img src="./imagen/Captura-naves.png" alt="Captura-naves.png">

<figcaption><span class="figure-number">Figure 2: </span>Naves en combate</figcaption>
</figure>


<figure id="orgb7aef9e">
<img src="./imagen/Captura-pantalla-victoria.png" alt="Captura-pantalla-victoria.png">

<figcaption><span class="figure-number">Figure 3: </span>¡Victoria!</figcaption>
</figure>

<p>
A pesar de no disponer de mucho tiempo para dedicárselo al juego, el
resultado está quedando aceptable. De momento me estoy encargando del
tema de texturas, gráficos, diseño de naves y demás. Espero poder
echar una mano con el código también.
</p>

<p>
De momento no pasa de ser una prueba de concepto que queremos
terminar... para que fuera un juego completo necesitaría muchas horas
y un equipo completo de personas: diseñadores, programadores, etc.
Nosotros somos dos y no nos dedicamos a esto más que en nuestro tiempo
libre (que cada vez es menos).
</p>

<p>
Se agradecerán los comentarios y sugerencias. Ahora estamos depurando
algunos errores, diseñando pantallas y menús, refactorizando el
comportamiento de las armas para simplificar su acción, especialmente
al impactar contra las naves... etc. Esperamos que antes de fin de año
haya una prueba jugable, para probar qué le parece a la gente el juego
y si hay que hacer cambios en la dinámica o cualquier otro aspecto
mejorable.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/proyectos/index.html">proyectos</a> <a href="/tags/juegos/index.html">juegos</a> <a href="/tags/godot/index.html">godot</a> ]]></description>
  <category><![CDATA[proyectos]]></category>
  <category><![CDATA[juegos]]></category>
  <category><![CDATA[godot]]></category>
  <link>https://notxor.nueva-actitud.org/2019/09/17/avances-en-el-juego-de-las-naves.html</link>
  <pubDate>Tue, 17 Sep 2019 10:19:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Una plantilla para exportar documentos desde Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-08-29</div>
<p>
Hace un tiempo, a raíz de presentar unos documentos, me preguntaron
cómo me las apaño para que queden tan bien hechos. El secreto se llama
<i>LaTeX</i>, como muchos sabéis, pero ayer mismo un amigo me preguntó por
detalles más técnicos y la respuesta en ese momento se me quedó
realmente corta. Aquí traigo una explicación más detallada de las
cosas que tengo ya <i>pre-paradas</i> a la espera de la generación de
documentos.
</p>

<p>
Los formatos que suelo trabajar para los documentos largos son <code>PDF</code> y
<code>epub</code>. Utilizo <code>PDF</code> cuando necesito imprimir el documento en papel y
utilizo <code>epub</code> cuando sólo requiere la lectura por pantalla. A veces,
ni siquiera monto el <code>epub</code> y lo dejo en <code>HTML</code>, como por ejemplo,
para las entradas de este <i>blog</i>.
</p>
<div id="outline-container-org3e48a2e" class="outline-2">
<h2 id="org3e48a2e">Exportar a <code>PDF</code></h2>
<div class="outline-text-2" id="text-org3e48a2e">
<p>
Como sabéis, y también lo dije antes, la exportación a <code>PDF</code> se hace a
través de <code>LaTeX</code>. En mi caso venía ya de antes trabajando con esta
herramienta para generar documentos y no necesité aprenderla aparte.
Para abreviar, como esto va de plantillas, pongo la cabecera que tengo
en un fichero en el directorio <code>~/Plantillas</code> para iniciar los textos
largos:
</p>

<pre class="example" id="org8f90ce9">
#+TITLE:         Título
#+SUBTITLE:      Subtítulo
#+DATE:          \today
#+AUTHOR:        Notxor
#+EMAIL:         notxor@nueva-actitud.org
#+LANGUAGE:      es
#+OPTIONS:       d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t
#+OPTIONS:       p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t
#+OPTIONS:       timestamp:t title:t toc:t todo:t |:t
#+LATEX_CLASS:   book
#+LATEX_CLASS_OPTIONS: [a4paper, 10pt, doubleside]

#+LATEX_HEADER: \usepackage[left=2.5cm,top=2.5cm,right=2.5cm,bottom=2.5cm]{geometry} 
#+LATEX_HEADER: \usepackage[spanish]{babel}

#+LATEX_HEADER: \usepackage{bbding}       %fuentes con iconos
# +LATEX_HEADER: \usepackage{enumitem}

# Personalizar las cabeceras
#+LATEX_HEADER: \usepackage[Bjornstrup]{fncychap}

# Las siguientes lineas para cambiar de fuente el pdf
# +LATEX_HEADER: \usepackage{mathpazo}    %fuente palatino
#+LATEX_HEADER: \usepackage{charter}      %fuente charter
#+LATEX_HEADER: \linespread{1.05}         %separa un poco las líneas para que no quede apelotonado

# Numerar las líneas de la página en los márgenes para referencias de corrección
#+LATEX_HEADER: \usepackage[switch,pagewise]{lineno}
#+LATEX: \linenumbers
</pre>

<p>
En ese código hay algunos paquetes <i>preparados</i> pero no activados, por
el simple hecho de añadir un espacio después del <code>#</code>. Quizá necesite
explicar algunos paquetes menos habituales:
</p>

<pre class="example" id="orgcc94b0f">
\usepackage{bbding}
</pre>

<p>
Permite utilizar <i>iconos</i> mediante una fuente. En ocasiones le añado
el paquete
</p>

<pre class="example" id="orge15112d">
\usepackage{enumitem}
</pre>

<p>
Ese paquete hace que podamos modificar a nuestro gusto las etiquetas
de nuestras listas, para conseguir un poco más de personalidad en
nuestros listados:
</p>

<pre class="example" id="org727152e">
\begin{itemize}[label=\HandRight]
    \item Prueba
    \item Prueba
\end{itemize}
</pre>

<p>
o incluso
</p>

<pre class="example" id="org8041efb">
\begin{itemize}[label=\HandRight]
\item abc
\item[\PencilRight] def
\end{itemize}
</pre>

<p>
Y con esos dos bloques de código se consigue la siguiente salida:
</p>


<figure id="org22100d7">
<img src="./imagen/captura-latex-itemize.png" alt="captura-latex-itemize.png">

</figure>

<p>
o también, ya que he importado la fuente en cuestión, se pueden hacer
algunos separadores gráficos entre partes del documento y si tenemos
que hacerlos tanto para <code>epub</code> como para <code>PDF</code> se puede utilizar algo
como:
</p>

<pre class="example" id="org4e1f201">
#+BEGIN_CENTER
#+HTML:  &lt;p style="text-align:center"&gt;&amp;#10054;  &amp;#10052; &amp;#10054;&lt;/p&gt;
#+LATEX:   \SnowflakeChevron { } \SnowflakeChevronBold { } \SnowflakeChevron
#+END_CENTER
</pre>

<p>
En muchas ocasiones lo que necesito impreso debe ser corregido antes
de ser entregado. Para eso utilizo el siguiente código:
</p>

<pre class="example" id="org0c363ca">
# Numerar las líneas de la página en los márgenes para referencias de corrección
#+LATEX_HEADER: \usepackage[switch,pagewise]{lineno}
#+LATEX: \linenumbers
</pre>

<p>
Lo que hace el paquete <code>lineno</code> de <i>LaTeX</i> es escribir en los márgenes
un número de referencia de cada línea. Las opciones <code>switch</code> y
<code>pasewise</code> hace que se impriman en márgenes alternos para las páginas
pares e impares y que reinicie el contador en cada página. Así
encontrar los errores es más fácil, sobre todo si el corrector es otra
persona. Con hacer referencia al número de página y de línea es
suficiente.
</p>
</div>
</div>
<div id="outline-container-org58995d3" class="outline-2">
<h2 id="org58995d3">Exportar a <code>epub</code> directamente</h2>
<div class="outline-text-2" id="text-org58995d3">
<p>
Un fichero <code>epub</code> no es más que un <code>zip</code> que contiene dentro ficheros
<code>html</code> o <code>xhtml</code>, imágenes, <code>css</code>, etc. Básicamente es <i>un sitio web
encapsulado</i> con la estructura de un libro. La forma más <i>de andar por
casa</i> para realizar un <code>epub</code> es exportar a <code>html</code> desde <i>emacs</i> y
luego <a href="https://sigil-ebook.com/">importarlo a alguna de las herramientas como <i>Sigil</i></a> para hacer
la edición electrónica.
</p>

<p>
Desde <code>org-mode</code> de <i>emacs</i> podemos generar directamente una
exportación de contenido a un fichero <code>epub</code>. Para eso necesitamos dos
sencillos pasos. El primero es instalar el paquete <code>ox-epub</code> por el
procedimiento habitual.
</p>

<p>
<code>M-x package-install RET ox-epub</code>
</p>

<p>
Una vez instalado, cuando queremos generar un <code>epub</code> activamos la
exportación con el comando <code>org-epub-export-to-epub</code>. Esto hace que en
nuestro menú <code>C-c C-e</code> aparezca el correspondiente apartado, por lo
que completando <code>C-c C-e E e</code> se genera un fichero <code>epub</code>.
</p>

<p>
Igual que podemos añadir opciones para <i>LaTeX</i> cuando queremos
exportar a <code>PDF</code>, también podemos añadir opciones al <code>html</code> a lo largo
de nuestro código. Incluso, si utilizamos un <code>css</code> personalizado,
podemos cargarlo y el exportador lo meterá en el <code>epub</code>.
</p>
</div>
</div>
<div id="outline-container-orgeaf0b73" class="outline-2">
<h2 id="orgeaf0b73">Conclusión</h2>
<div class="outline-text-2" id="text-orgeaf0b73">
<p>
Generar documentos complejos con <code>org-mode</code> es sencillo. Por defecto,
<i>emacs</i> realiza una exportación sencillo a <code>PDF</code> a través de <i>LaTeX</i> y
a <code>html</code>. Sin embargo, el uso de lectores <i>ebook</i> y otras herramientas
similares, hacen que el formato <code>PDF</code> sea incómodo y el <code>html</code> para
ajustarse a pantalla necesita algo más de estructura. El formato
<code>epub</code> vino a cubrir esas deficiencias y podemos hacer que <i>emacs</i> nos
genere los contenidos de forma sencilla.
</p>

<p>
Cada uno tiene sus manías y es posible que los paquetes que utilizo
para <i>LaTeX</i> no los utilices y prefieras tener otros, pero siempre es
una buena idea tener nuestras cabeceras <i>básicas</i> guardadas en una
plantilla para iniciar los documentos nuevos sin pensar demasiado,
luego personalizar el resultado será más sencillo.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> <a href="/tags/latex/index.html">latex</a> <a href="/tags/epub/index.html">epub</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <category><![CDATA[latex]]></category>
  <category><![CDATA[epub]]></category>
  <link>https://notxor.nueva-actitud.org/2019/08/29/una-plantilla-para-exportar-documentos-desde-emacs.html</link>
  <pubDate>Thu, 29 Aug 2019 23:07:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Elegir los temas del blog]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-08-27</div>
<p>
A veces siento la necesidad de escribir algo en este <i>blog</i>, pero de
una forma difusa e insustancial, vaga o borrosa, sin un tema concreto
sobre el que dirigir mis pensamientos. <i>Hoy es uno de esos días</i>.
</p>

<p>
Me ocurre a veces que cuando me siento delante del ordenador parece
como si me picaran los dedos intentando escribir algo, expresar alguna
idea u obligarme a pensar. Me pierdo en cientos de lecturas que tengo
dispersos por esos mundos de <i>Internet</i>, nuevos <i>posts</i>, nuevas ideas
─o incluso las mismas, pero presentadas de nuevas maneras─. Poco a
poco se van agotando los borradores sobre los diferentes temas que he
ido acumulando durante la racha maníaca de <i>todo es interesante</i> para
el <i>blog</i> y este es uno de esos días de <i>descartes</i>.
</p>

<p>
Me canso.
</p>

<p>
Como decía antes todo esto va en rachas: días en que se te ocurren
varios temas e inicias varios borradores, aunque sea con poco más que
un título y una lista de posibles líneas de argumentación. En otras
ocasiones, la racha es todo lo contrario, no aparece ningún tema lo
suficientemente interesante y rebuscando entre los borradores son más
los descartados y borrados ─valga la <i>rebuznancia</i>, que para algo es
un borrador─. Siendo éste un <i>blog</i> personal, sus vaivenes se
acompasan con los temas que me emocionan en un momento dado. Cuando
algo deja de hacerlo y mi interés decae, la cosa empieza a flojear en
el índice de entradas.
</p>

<p>
En la mayoría de las ocasiones no es porque eso de lo que he venido
escribiendo haya dejado de ser interesante, sino porque tengo la
sensación de que ya he dicho todo lo que podía decir de ese «algo» sin
resultar pesado. O porque el tema me parece demasiado sencillo o banal
como para dedicarle una entrada. En este caso, con frecuencia, me
encuentro con posterioridad con algún artículo sobre el tema y pienso
que podría haberlo escrito yo unos días, semanas o meses antes y no lo
hice no sé muy bien por qué. Por ejemplo, <a href="https://es.wikipedia.org/wiki/Conky_(software)">ayer mismo vi un artículo
sobre conky</a> en el <a href="https://www.atareao.es/podcast/personalizacion-extrema-de-linux-con-conky/"><i>blog-podcast</i> del Atareao</a> ─uno de los sitios por
<i>Internet</i> que merece la pena seguir─. Estuve toqueteando <code>conky</code> días
antes y pensé que a lo mejor podría escribir contando mi experiencia
sobre la configuración de mi escritorio, igual que hice con <code>awesome</code>,
pero al final lo descarté considerándolo de poco interés ─por sencillo
de hacer─, que lo dejé pasar.
</p>


<figure id="org47311dc">
<img src="./imagen/pantallazo.png" alt="pantallazo.png">

</figure>

<p>
Hay cosas que no sé si serían interesantes. Me he puesto ventanas sin
marco ni título, poniendo barras de estado con <code>powerline</code> y
configurando todo para hacerlo práctico a la par que estético.
</p>

<p>
También he descartado otros artículos sobre la configuración de
<code>powerline</code>, <a href="https://github.com/powerline/powerline">una herramienta para ornamentar las líneas de estado de
aplicaciones habituales</a>. Supongo, que habiéndome costado tan poco
trabajo el hacerlo, mi sensación de <i>esto es de perogrullo</i> vence mi
primaria necesidad de explicarlo todo. Que también puede ser
interpretada como el <i>mira lo que sé hacer y tú no</i>, un tanto
soberbio.
</p>

<p>
También se me han acabado las ganas de escribir sobre las <i>bondades</i>
del Software Libre. Y no es porque no crea en ellas o esté
desencantado de él, es que ya las he enumerado muchas veces. Mi época
de <i>talibán</i> fue hace muchos años ya. Entiendo que a mucha gente que
acaba de llegar a este mundo del <i>SL</i>, le llame el alzar las banderas
y cerrar filas al rededor de una buena causa. Olvidando que la gente
tiene derecho a utilizar la herramienta que quiera.
</p>

<p>
Y así pasan los días sin escribir en el <i>blog</i> por falta de temas y
por descarte de los que en su día me parecieron interesantes. En estas
estoy, esperando otra racha de temas que traer al <i>blog</i> en otro
arranque <i>maníaco</i> de contenido <i>bloguero</i>.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2019/08/27/elegir-los-temas-del-blog.html</link>
  <pubDate>Tue, 27 Aug 2019 17:29:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Prueba de concepto para crear un asistente de voz]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-08-22</div>
<p>
Llevo un tiempo dándole vueltas al tema de los <i>asistentes de voz</i>.
Veo a algunos dándole órdenes a sus <i>ordenadores de bolsillo</i> muy
contentos con la reacción de sus <i>chismáticos</i>.  No voy a entrar en si
son conscientes de lo barato que venden su alma, sino en si merece la
pena uno de esos asistentes.
</p>

<p>
La manera de saber cómo funcionan y de probar uno es <i>hacerlo yo
mismo</i>. Por eso estoy en este berenjenal. De primeras pensé en hacerlo
para <i>emacs</i>, me he acostumbrado tanto al <code>elisp</code> y me encuentro tan
cómodo que me puse a investigar paquetes que me pudieran ser útiles
para mi <i>prueba de concepto</i>.
</p>
<div id="outline-container-org07fb105" class="outline-2">
<h2 id="org07fb105">Mi primera idea</h2>
<div class="outline-text-2" id="text-org07fb105">
<p>
De primeras pensé que no debería ser muy complicado: no tiene que
hacer muchas cosas. En principio lo pensé hacer en <i>emacs</i> como he
dicho y como mucho había pensado en que entendiera comandos del tipo:
<i>ir al párrafo anterior</i>, <i>atrás</i>, <i>ir a línea 27</i> y cuatro cosas más.
</p>

<p>
Básicamente me planteaba hacer tres módulos que dependieran de un
<i>modo menor</i> de <i>emacs</i>: el primero convertiría la voz en texto para
pasárselo al segundo, el <i>parser</i> que analizaría ese texto para
convertirlo en un comando o realizar alguna acción; el tercero
convertiría el texto en sonido para llamar la atención sobre algún
punto o responder a alguna posible pregunta.
</p>

<p>
La conversación no tiene que ser excesivamente compleja, no se trata
de crear una <i>inteligencia artificial</i> (IA) que pase por humana.
Incluso sistemas conversacionales básicos, como puede ser <i>Eliza</i> o un
derivado cumplirían de sobra con la tarea. Realmente, ese <i>asistente</i>
sería algo tan básico como un <i>interfaz</i> de voz para algunos comandos.
</p>

<p>
¿Para qué me serviría en <i>emacs</i>? Pues básicamente para nada: tardo
menos tiempo en pulsar una tecla que en decir su nombre o su función y
además limitaría el posible uso de mi asistente. Como mucho podría
emplearse para que me lea un <i>buffer</i> de texto. Para esto, encontré un
paquete de <i>emacs</i> que lo hace de forma eficiente.
</p>
</div>
<div id="outline-container-org70e0692" class="outline-3">
<h3 id="org70e0692">El paquete de Emacs <code>greader</code></h3>
<div class="outline-text-3" id="text-org70e0692">
<p>
En mi búsqueda de <i>interfaces</i> voz-texto y texto-voz encontré un
paquete de <i>emacs</i> que es capaz de leerte un <i>buffer</i> y lo probé.  La
instalación, como siempre, no puede ser más sencilla:
</p>

<p>
<code>M-x install-package RET greader RET</code>
</p>

<p>
Depende de que tengas instalado algún paquete de conversión de texto a
sonido (me duele llamar a lo que sale por los altavoces <i>habla</i> o
<i>voz</i>), para funcionar. Dos son los que se pueden configurar por
defecto: <code>speech-dispatcher</code> y <code>espeak</code>. El primero es en realidad una
<i>interface</i> que puede utilizar varios motores de conversión. En mi
caso, y como sólo tengo instalado <code>espeak</code> utilicé éste en la
configuración del paquete para <i>emacs</i>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Configuraci&#243;n para greader
</span>(add-to-list 'load-path <span style="color: #f1fa8c;">"~/.emacs.d/elpa/greader-0.1"</span>)
(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">greader</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> greader-actual-backend 'greader-espeak)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> greader-espeak-language <span style="color: #f1fa8c;">"es"</span>)
</pre>
</div>

<p>
Después de esa simple configuración en nuestro <code>init.el</code> podemos
cargar el modo <code>greader-mode</code> en cualquier <i>buffer</i> de texto y al
pulsar <code>C-r ESP</code> para iniciar y parar la lectura. También podemos
utilizar los comandos <code>greader-read</code> y <code>greader-stop</code> para hacer lo
mismo.
</p>

<p>
Estas pruebas no me sirvieron para avanzar demasiado en mi proyecto
pero no deja de ser una curiosidad. A estas alturas y con la cantidad
de paquetes que tiene <i>emacs</i> siempre encuentro algo relacionado con
lo que busco o lo que quiero hacer que, al menos, sirva como
inspiración.
</p>
</div>
</div>
</div>
<div id="outline-container-orgf84160b" class="outline-2">
<h2 id="orgf84160b">El estado del proyecto</h2>
<div class="outline-text-2" id="text-orgf84160b">
<p>
Visto que el <i>chismático</i> no lo iba a hacer como <i>modo de emacs</i>
elegir lenguaje también me ha supuesto un poco de reflexión. Hace un
tiempo hubiera elegido <code>Python</code> sin pensarlo mucho. <a href="https://es.wikipedia.org/wiki/ELIZA">Alguna vez
programé otra prueba de concepto tipo <i>Eliza</i></a>, para destriparlo en una
charla-conferencia sobre IA y lo hice con <code>Python</code>. Sin embargo,
últimamente me está resultando más cómoda la programación con <code>lisp</code> y
<code>scheme</code>. Al final he decidido, que como es una prueba de concepto y
se trata de hacer algo sencillo y facilón, sintiéndome cómodo al
hacerlo, <a href="https://www.gnu.org/software/guile/">voy a utilizar <code>Guile</code></a>, que es lo que más a mano tengo.
</p>
</div>
<div id="outline-container-orgec2ed01" class="outline-3">
<h3 id="orgec2ed01">Conversión de voz a texto</h3>
<div class="outline-text-3" id="text-orgec2ed01">
<p>
En este apartado encontré algunas herramientas que pueden ayudar a la
conversión de voz a texto. <a href="https://cmusphinx.github.io/">La más prometedora es <code>PocketSphinx</code></a>, con
la que estoy haciendo pruebas aún, comprobando cómo funciona y las
distintas opciones de configuración. La instalación en <a href="https://www.opensuse.org/#Tumbleweed">OpenSuse
Tumbleweed</a> es sencilla:
</p>

<div class="org-src-container">
<pre class="src src-bash">zypper install pocketsphinx pocketsphinx-devel
</pre>
</div>

<p>
Básicamente funciona, parece, empaquetando el sonido entre dos
<i>silencios</i>, lo que sería una frase, en un fichero <code>wav</code> temporal que
luego analiza para convertirlo en texto.
</p>

<p>
De momento lo encuentro algo impreciso, aunque no estoy seguro de si
es algún problema de configuración o del mismo <i>chismático</i>. Viendo la
documentación, hay un <code>Sphinx</code> más preciso, pero más lento. Seguiré
con las pruebas a ver si consigo un poco más de precisión, no necesito
mucha más.
</p>
</div>
</div>
<div id="outline-container-org1703985" class="outline-3">
<h3 id="org1703985">Salida de texto a voz</h3>
<div class="outline-text-3" id="text-org1703985">
<p>
Como ya he hablado de las dos opciones principales en este apartado
para <code>GNU/Linux</code> antes hablando del paquete para <i>emacs</i>, no abundaré
mucho más. Creo que lo que me falta por decir en este aparatado es
sólo el porqué utilizaré <code>espeak</code>. Alternativas hay, pero he
encontrado que éste tiene salida para las distintas lenguas que me
interesan; principalmente, el español y el esperanto, además del
inglés que soportan todas.
</p>
</div>
</div>
<div id="outline-container-org1d98fd5" class="outline-3">
<h3 id="org1d98fd5">El meollo</h3>
<div class="outline-text-3" id="text-org1d98fd5">
<p>
La parte del meollo, el <i>parser</i> aún está todo en el aire. El objetivo
principal es aprender a escribir un módulo para enganchar el <code>Guile</code>
con la librería <code>libpocketsphinx</code> escrita en <code>C</code>, y otro para conectar
con otra llamada <code>libspeak-ng</code> para hacer la salida. Aunque lo más sea
realizar la salida mediante el habitual <code>stdout</code>.
</p>

<p>
Lo demás debería ser bastante fácil. Recibir entrada, procesarla y
producir una salida (respuesta hablada) o una acción (respuesta a un
comando).
</p>

<p>
Todo está en mantillas y empezando.
</p>
</div>
</div>
</div>
<div id="outline-container-orgfe21949" class="outline-2">
<h2 id="orgfe21949">Conclusión</h2>
<div class="outline-text-2" id="text-orgfe21949">
<p>
No hay mucho que concluir, está todo en una fase tan temprana que lo
más probable es que termine en vapor, pero bueno, por lo menos me hace
preguntarme cómo funcionan, o podrían funcionar, estas cosas.
</p>

<p>
¿Para qué podría servirme? Pues no para mucho, estoy tan acostumbrado
a la <i>interface</i> teclado-pantalla, que la <i>interface</i> de voz se me
presenta un poco engorrosa para manejar un ordenador... justo lo
contrario de que en los móviles. Es posible que el uso más normal es
para las ocasiones en que se tiene que manejar el ordenador a
distancia; por ejemplo, el momento en que estás en una charla y te
encuentras cerca de la pantalla y quieres buscar una diapositiva en
concreto o avanzar y retroceder. Hasta ahora tengo un par de
<i>chismáticos</i> que me ayudan: uno es un mando a distancia que alguna
vez me ha dejado tirado por agotarse las pilas (o que me se ha quedado
olvidado en casa); el otro es utilizar el <code>KDE Connet</code> desde el móvil.
</p>

<p>
Y <a href="https://marvelcinematicuniverse.fandom.com/es/wiki/J.A.R.V.I.S.">como hay que ponerle un nombre y <i>Jarvis</i> está ya cogido</a>, pues lo
llamaré <b>Fermín</b>: <i>Funcionalidad de Escaso Raciocinio, Memoria o
Inteligencia Natural</i>... que ha sido el primer nombre que me ha venido
a la cabeza.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/scheme,/index.html">scheme,</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[scheme,]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2019/08/22/prueba-de-concepto-para-crear-un-asistente-de-voz.html</link>
  <pubDate>Thu, 22 Aug 2019 23:54:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Estudiando org-page]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-08-10</div>
<div id="outline-container-org6dc9165" class="outline-2">
<h2 id="org6dc9165">Sobre <code>org-page</code></h2>
<div class="outline-text-2" id="text-org6dc9165">
<p>
Son varios los que me han preguntado por el hecho de que utilizo
<code>org-page</code> para escribir este <i>blog</i> y el <i>chismático</i> se ha quedado
sin soporte. Es decir, que el autor no va a hacerle más casito al tema
y no habrá mantenimiento ni corrección de <i>bugs</i>, ni nada. ¿Eso
asusta? A mí no (es la respuesta fácil). Pero no porque sea yo
especialmente valiente o porque crea que soy mejor que otros que
corren a refugiarse en otras alternativas ante el caos y el abandono.
Simplemente el <i>chismático</i> funciona y si funciona ¿para qué
cambiarlo? Ahora bien, ¿esto implica que te recomiendo la herramienta?
Pues dicho así: <i>no</i>, pero un <i>no</i> con matices.
</p>

<p>
Entiendo que hay quien le teme al <i>barbecho informático</i> percibiéndolo
como un retroceso para el uso de una herramienta. No creo yo que sea
tan malo, sobre todo en un sistema que está funcionando correctamente.
Y no es por no recomendarlo, pero entiendo que es un motivo para
pensárselo dos veces antes de lanzarse a iniciar un proyecto con una
tecnología que puede que no evolucione.
</p>

<p>
A ver si soy capaz de explicarme. Cada uno tiene derecho a utilizar el
<i>software libre</i> que considere oportuno, pero hay que advertir que el
camino no siempre es fácil. He visto quienes se desesperaban con
<code>org-page</code> por sus peculiaridades y no terminaban de entender cómo
funcionaba, quizás influenciados por los modos de otros <i>chismáticos</i>
que generan <i>webs</i> estáticas. He de reconocer que, aunque al final
parece que lo he dominado, me costó al principio entender cómo
gestionar todo. Yo, a estas alturas, me encuentro cómodo utilizándolo
y he encontrado la manera de hacerlo funcionar sin excesivo
esfuerzo. Pero ¿es así en todos los casos? <i>No</i>, por esto no te lo
recomiendo a no ser que estés dispuesto a hacer un esfuerzo que quizá
otros sistemas te ahorran.  Además la documentación es más bien escasa
y algunas cosas no quedan demasiado claras en esa documentación.
</p>
</div>
</div>
<div id="outline-container-org2858715" class="outline-2">
<h2 id="org2858715">¿Cómo funciona?</h2>
<div class="outline-text-2" id="text-org2858715">
<p>
Mi intención al escribir esto es también profundizar un poco más en
cómo funciona. Mi objetivo es comprenderlo suficientemente por si
hiciera falta algo de mantenimiento y me tuviera que buscar las
habichuelas. La última actualización de <code>org-page</code> fue el 7 de agosto
de 2017, hace más de dos años. Todavía no me he encontrado con la
necesidad de arreglar o cambiar nada, pero nunca se sabe. El
<i>chismático</i> funciona.
</p>

<p>
Básicamente, el código fuente se apoya también en otros ficheros que
componen las páginas <code>html</code>: las plantillas y lo <i>formatean</i> con
<code>css</code>. Para actualizar el <i>blog</i> de forma progresiva, se apoya en
<code>git</code>. Todas esas opciones hay que configurarlas adecuadamente para
que funcione, pero como <a href="https://notxor.nueva-actitud.org/blog/2018/10/18/sobre-como-utilizo-org-page-para-hacer-este-blog/">ya lo he contado en otros artículos, no voy a
hacerlo de nuevo</a>.
</p>
</div>
<div id="outline-container-org315ef94" class="outline-3">
<h3 id="org315ef94">Ficheros</h3>
<div class="outline-text-3" id="text-org315ef94">
<p>
No voy a entrar en las plantillas, que al final es lo que proporciona
la uniformidad visual al <i>blog</i>. La idea de este artículo es meterse
más en el funcionamiento y por ello me quedaré en el código fuente que
mueve gestiona todo. El código está distribuido en los siguientes
ficheros:
</p>

<ul class="org-ul">
<li><code>op-enhance.el</code> obtiene el tema configurado o utiliza el definido
por defecto, <code>mdo</code>.</li>
<li><code>op-export.el</code> comprueba los cambios en el repositorio y genera los
<code>html</code> que formarán el sitio.</li>
<li><code>op-git.el</code> gestiona todo el repositorio <code>git</code>.</li>
<li><code>op-template.el</code> genera cada <code>html</code> en base a las plantillas
definidas que luego utilizará <code>op-export.el</code> para generar el sitio.</li>
<li><code>op-util.el</code> agrupa funciones útiles para el resto de módulos, como
el formateo de fechas o <i>emails</i>.</li>
<li><code>op-vars.el</code> contiene las definiciones de las constantes y variables
de todo el sistema</li>
<li><code>org-page.el</code> aquí está el meollo del código fuente y lo que
gestiona todo el proceso mediante los <i>comandos</i> o funciones
interactivas que se definen aquí.</li>
<li><code>org-page-pkg.el</code> define el nombre del paquete, la versión y las
dependencias.</li>
</ul>
</div>
</div>
<div id="outline-container-org1711f02" class="outline-3">
<h3 id="org1711f02">Configuración</h3>
<div class="outline-text-3" id="text-org1711f02">
<p>
Dentro del fichero <code>org-page.el</code> nos encontramos una función
fundamental que comprueba que todo esté configurado correctamente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">op/verify-configuration</span> ()
  <span style="color: #6272a4;">"Ensure all required configuration fields are properly configured, include:
`</span><span style="color: #bd93f9;">op/repository-directory</span><span style="color: #6272a4;">': &lt;required&gt;
`</span><span style="color: #bd93f9;">op/site-domain</span><span style="color: #6272a4;">': &lt;required&gt;
`</span><span style="color: #bd93f9;">op/personal-disqus-shortname</span><span style="color: #6272a4;">': &lt;optional&gt;
`</span><span style="color: #bd93f9;">op/personal-duoshuo-shortname</span><span style="color: #6272a4;">': &lt;optional&gt;
`</span><span style="color: #bd93f9;">op/export-backend</span><span style="color: #6272a4;">': [optional](default 'html)
`</span><span style="color: #bd93f9;">op/repository-org-branch</span><span style="color: #6272a4;">': [optional] (but customization recommended)
`</span><span style="color: #bd93f9;">op/repository-html-branch</span><span style="color: #6272a4;">': [optional] (but customization recommended)
`</span><span style="color: #bd93f9;">op/site-main-title</span><span style="color: #6272a4;">': [optional] (but customization recommanded)
`</span><span style="color: #bd93f9;">op/site-sub-title</span><span style="color: #6272a4;">': [optional] (but customization recommanded)
`</span><span style="color: #bd93f9;">op/personal-github-link</span><span style="color: #6272a4;">': [optional] (but customization recommended)
`</span><span style="color: #bd93f9;">op/personal-google-analytics-id</span><span style="color: #6272a4;">': [optional] (but customization recommended)
`</span><span style="color: #bd93f9;">op/theme</span><span style="color: #6272a4;">': [optional]
`</span><span style="color: #bd93f9;">op/highlight-render</span><span style="color: #6272a4;">': [optional](default 'js)"</span>
...)
</pre>
</div>

<p>
Las variables para una correcta configuración las encontramos ahí. Hay
otras que se pueden definir, pero básicamente las necesarias son esas:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Para el blog en org-mode
</span>(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">org-page</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/repository-directory <span style="color: #f1fa8c;">"~/proyectos/blog-org-page/"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/site-domain <span style="color: #f1fa8c;">"https://notxor.nueva-actitud.org"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/site-main-title <span style="color: #f1fa8c;">"Notxor tiene un blog"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/site-sub-title <span style="color: #f1fa8c;">"Defenestrando la vida"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/theme-root-directory <span style="color: #f1fa8c;">"/home/notxor/proyectos/themes-org-page"</span>) <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Temas propios
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/theme (<span style="color: #ff79c6; font-weight: bold;">quote</span> notxor))   <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Ajustes personales del tema
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/tag-rss t)              <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Hacer que se creen los feed por etiquetas.
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/hashover-comments t)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/personal-github-link <span style="color: #f1fa8c;">""</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/site-preview-directory <span style="color: #f1fa8c;">"~/public_html"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/confound-email nil)     <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Evitar el ofuscado del email, porque lo hace mal.</span>
</pre>
</div>

<p>
Si comparamos los dos listados se puede apreciar que hay algunas
variables que son fundamentales que no están en el listado que luego
configuro en mi sitio. Al contrario, hay otras que el creador
considera fundamentales, como <code>op/personal-google-analytics-id</code>, que
yo no configuro (y de hecho he eliminado los enlaces al
correspondiente <i>javascript</i> en las plantillas sin que el sistema se
vea perjudicado. Además configuro el sistema de comentarios
<code>hashover</code>.
</p>
</div>
</div>
<div id="outline-container-org0088117" class="outline-3">
<h3 id="org0088117">Interacción</h3>
<div class="outline-text-3" id="text-org0088117">
<p>
Pero lo fundamental del código son los comandos que se definen y que
son los que el usuario termina utilizando y los que disparan todos los
automatismos para generar el sitio final:
</p>
</div>
<div id="outline-container-orge06fec2" class="outline-4">
<h4 id="orge06fec2">Comandos</h4>
<div class="outline-text-4" id="text-orge06fec2">
<ul class="org-ul">
<li><code>op/do-publication</code> realiza la publicación de los cambios en el
repositorio <code>git</code> para actualizar el sitio.</li>
<li><code>op/new-repository</code> inicia un repositorio y nuevo <i>blog</i>.</li>
<li><code>op/insert-options-template</code> establece una cabecera estándar para el
artículo que se está escribiendo. Normalmente no es necesario, a no
ser que se quiera convertir en <i>post</i> un fichero <code>org</code> que no se ha
iniciado como tal.</li>
<li><code>op/new-post</code> crea una nueva entrada para el <i>blog</i>.</li>
<li><code>op/do-publication-and-preview-site</code> además de generar el sitio con
los cambios realizados levanta el servidor <code>http</code> para pruebas que
viene con <i>emacs</i>.</li>
</ul>
</div>
</div>
<div id="outline-container-org1859113" class="outline-4">
<h4 id="org1859113">Funciones no interactivas:</h4>
<div class="outline-text-4" id="text-org1859113">
<ul class="org-ul">
<li><code>op/verify-configuration</code> comprueba la configuración mínima y lanza
los errores que encuentre.</li>
<li><code>op/generate-readme</code> genera un fichero <code>readme</code> para el <i>blog</i>
nuevo.</li>
<li><code>op/generate-index</code> genera un fichero <code>index</code> para el <i>blog</i> nuevo.</li>
<li><code>op/generate-about</code> genera un fichero <code>about</code> para el <i>blog</i> nuevo.</li>
</ul>

<p>
Básicamente, el usuario sólo utiliza el comando <code>new-repository</code>
cuando inicia el <i>blog</i> y después, para cada actualización utilizará
<code>op/new-post</code> y <code>op/do-publication</code>... y no hay nada más.
</p>
</div>
</div>
</div>
</div>
<div id="outline-container-orgc664c7c" class="outline-2">
<h2 id="orgc664c7c">Conclusión</h2>
<div class="outline-text-2" id="text-orgc664c7c">
<p>
Un primer vistazo superficial al código fuente de <code>org-page</code> te da una
idea de lo sencillo que es su funcionamiento. Mirando detenidamente el
código he podido apreciar cierta tendencia al <i>código choricero</i> con
funciones muy largas y no demasiado bien documentadas, por lo que
espero que me costará trabajo terminar de entender qué hacen algunas
de ellas.
</p>

<p>
Mi intención es mantenerme yo el código para mi uso personal. De
momento, no tengo intención de iniciar un <i>fork</i> ni nada parecido, no
me han ocurrido errores y tampoco veo que haya características que
necesite de forma perentoria. Mientras el código funcione no creo que
lo toque, pero si lo hago, me plantearía el hecho de publicarlo
continuando con <code>org-page</code>, poniéndome en contacto con el creador para
actualizar mediante <i>patch</i> y recurriendo al <i>fork</i> sólo en caso de
que no haya más remedio para publicar los cambios.
</p>

<p>
Espero que los que me han preguntado sobre el futuro de <code>org-page</code> y
de mi <i>blog</i> como usuario, hayan quedado satisfechos con la
explicación de mi postura.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> <a href="/tags/org-page/index.html">org-page</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <category><![CDATA[org-page]]></category>
  <link>https://notxor.nueva-actitud.org/2019/08/10/estudiando-org-page.html</link>
  <pubDate>Sat, 10 Aug 2019 10:03:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Probando el gestor de ventanas awesome]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-08-01</div>
<p>
Me he aficionado a los entornos de escritorio de estilo mosaico. Mi
favorito <code>i3wm</code> ha tenido la culpa. Sin embargo, hace unos días que
<a href="https://awesomewm.org/">vengo probando <code>awesomewm</code>, otro entorno de ese tipo</a>, del que voy a
hablar en este artículo. No demasiado profundamente, pues llevo
utilizándolo tan sólo tres días y he gastado prácticamente uno entero
en acondicionarlo un poco a mis gustos --algo que considero importante
en cualquier herramienta que utilizo--. El problema es que he gastado
bastante tiempo en pegarme con la configuración, incluso antes de
saber muy bien cómo funciona el sistema, así que empecé con algunos
palos de ciego de los que prefiero ahorrarme el esfuerzo de contarlos
aquí para centrarme en el meollo.
</p>
<div id="outline-container-orgd921ce5" class="outline-2">
<h2 id="orgd921ce5">Instalación</h2>
<div class="outline-text-2" id="text-orgd921ce5">
<p>
La instalación fue fácil: tiré de <code>zypper</code> y <i>OpenSuse</i> hizo el
resto; en cada distribución tirarán de su herramienta de instalación,
en la mía me bastó con escribir un escueto:
</p>

<div class="org-src-container">
<pre class="src src-shell">sudo zypper install awesome
</pre>
</div>

<p>
Sólo tuve un problema con el paquete de <code>awesome</code> que viene con
<i>OpenSuse</i>, la configuración <i>por defecto</i>. Lo digo o escribo así, tal
cual, con cursivas porque efectivamente es un <i>defecto</i>: no he visto
cosa más fea, ya me perdonará quien lo hiciera, pero el tema ese
es... <b>feo</b>. No encuentro otra palabra más <i>políticamente correcta</i>
porque lo primero que vino a la mente tras ver ese diseño es que el
que lo hizo tenía el gusto en el mismo sitio que las avispas su
<i>gracia</i>. Esto me llevó directamente al siguiente punto: la
configuración.
</p>
</div>
</div>
<div id="outline-container-orgc306270" class="outline-2">
<h2 id="orgc306270">Configuración</h2>
<div class="outline-text-2" id="text-orgc306270">
<p>
Antes de que mi ordenador agarrara un virus, o algo más gordo por
tamaño despropósito, me decidí a ponerme con la configuración del
<i>chismático</i>. Algo sencillo en cuanto <a href="https://github.com/lcpz/awesome-copycats/tree/master/themes">encontré algunos <i>themes</i> que
llevar al disco duro</a>. Cuando los abrí me encontré un montón de código
escrito en <code>lua</code>. Algo debí haber sospechado, porque quien me
recomendó este entorno es un <i>fan</i> de ese lenguaje.
</p>

<p>
El entorno busca el archivo de configuración
<code>~/.config/awesome/rc.lua</code> en nuestro disco duro, por eso utilicé la
plantilla que viene con los <i>themes</i> que he mencionado arriba con la
idea de modificarlo --siempre es más sencillo que empezar uno desde
cero--. Además, la plantilla de la que partí está bastante bien
estructurada y genera algunas características que me han resultado
curiosas y útiles.
</p>

<p>
Lo primero que hice fue probar <i>todos los themes</i> que me había
descargado, uno a uno. Algunos más bonitos, otros más feos, pero eso
va en gustos. Más o menos, todos funcionaban de manera similar y
cualquiera de ellos era infinitamente mejor que el que viene <i>por
defecto</i> con <i>OpenSuse</i>. El funcionamiento es parecido, como digo,
porque la mayoría de la funcionalidad está situada en el fichero
<code>rc.lua</code> mientras que saca todos los temas de color, fondo de
pantalla, iconos, etc., al directorio <code>themes</code> donde cada uno de ellos
tiene su correspondiente <code>theme.lua</code>.
</p>

<p>
Como era de esperar, lo primero que eché de menos al arrancar
<code>awesome</code> fueron las combinaciones de teclas que tengo configuradas en
<code>i3wm</code> y a las que estoy más que acostumbrado. Mis atajos para las
aplicaciones más habituales no funcionaban (todas), aunque sí algunas
como <code>mod-Enter</code> para lanzar el terminal. Encontré además que viene con
un <i>pichorro</i> para lanzar el menú de aplicaciones --en la configuración
<i>por defecto</i> de <i>OpenSuse</i> además lo colocan en la barra de
<i>widgets</i>--; sin embargo, estoy acostumbrado a los que proporciona
<code>rofi</code>. Eso fue de las cosas que primero configuré. Aún así, muchas
combinaciones me salen automáticamente como las de <code>i3wm</code>, la memoria
muscular es lo que tiene.
</p>

<p>
Después de trastearlo un poco la configuración me ha quedado como
muestro en la imagen:
</p>


<figure id="orga3f2310">
<img src="./imagen/captura-awesome-1.png" alt="captura-awesome-1.png">

</figure>

<p>
En el punto 1, en el centro de la imagen, se puede ver el menú de
acceso a las aplicaciones. Es el menú de <i>escritorio</i> que puedes ver
en otros entornos como <i>XFce</i> o <i>Gnome</i> o <i>Plasma</i>.
</p>

<p>
En el 2 marco los <i>escritorios</i>, bueno, en realidad sus etiquetas,
porque se pueden mover independientemente de la combinación de
teclas. A ver si lo explico mejor: si utilizo la combinación de teclas
para intercambiar las <i>etiquetas-escritorios</i>, digamos por ejemplo 2 y
3, dejando las etiquetas tal que «1 3 2 4...» tendré que acceder al
escritorio con la etiqueta «3» con la combinación «mod-2». En algunos
de los <i>themes</i> se utilizan iconos o textos, pero yo he seguido con la
inercia de <code>i3wm</code> de nombrarlos por números.
</p>

<p>
Además, en su propia página <i>web</i> hablan no de <i>desktops</i> sino de
<i>tags</i> por <i>screen</i>, con lo que parece que el soporte multipantalla es
bastante aceptable, --no lo puedo afirmar con conocimiento de causa,
porque no lo he probado en modo XRandR--, pero al menos eso parece.
</p>

<p>
En algunos <i>themes</i> he visto que configuran varias barras, algunas con
aspecto de <i>dockers</i>, laterales, que desaparecen cuando el cursor se
aleja. En fin, muchas posibilidades que lo hacen muy flexible.
</p>

<p>
En el 3, marco un <i>pichorro</i> que me indica el tipo de configuración
del <i>escritorio</i>. En <code>i3wm</code> las ventanas se distribuían básicamente de
tres manera y mantiene estable el tamaño una vez distribuidas. Esto es
muy similar a cómo funciona, casi siempre, el asunto en <code>awesome</code>, sin
embargo, hay algunos modos como el <i>magnifier</i> que centra en pantalla
la ventana que tenga el foco y distribuye en el fondo el resto de
ventanas abiertas. Además, como se puede ver en la captura, se puede
poner un <i>pichorro</i> para que nos lo diga. Aparte de eso, cada ventana
se puede colocar como «flotante», «maximizada» u otras opciones que
ahora veremos. Los iconos también dependen del <i>theme</i> así que puedes
ajustarlos a tu gusto.
</p>

<p>
Con el 4 marco la barra de información. Como se puede apreciar es
bastante más sencillo que mi barra de <code>bumblebee-status</code>. Sin embargo,
resulta que eso también aligera la carga de memoria, porque no
necesito una herramienta externa que dibuje dicha barra. A esto le
achaco que <code>awesomewm</code> sea ligeramente más ligero en memoria (unos
16Kb, comprobados con <code>free</code>), que <code>i3wm</code>.
</p>

<p>
Las partes que añadido al código han sido mínimas. Por ejemplo, como
ya dije, estoy tan acostumbrado a utilizar los menús de <code>rofi</code>, que me
lo he metido también en este entorno, con las mismas combinaciones de
teclas:
</p>

<div class="org-src-container">
<pre class="src src-lua"><span style="color: #6272a4;">-- </span><span style="color: #6272a4;">rofi
</span>awful.key({ modkey }, <span style="color: #f1fa8c;">"d"</span>, <span style="color: #ff79c6; font-weight: bold;">function</span> ()
     <span style="color: #8be9fd; font-style: italic;">os</span>.<span style="color: #8be9fd; font-style: italic;">execute</span>(<span style="color: #8be9fd; font-style: italic;">string</span>.<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"rofi -modi %s -show %s"</span>, <span style="color: #f1fa8c;">'run'</span>, <span style="color: #f1fa8c;">'run'</span>))
                      <span style="color: #ff79c6; font-weight: bold;">end</span>,
     {description = <span style="color: #f1fa8c;">"menu rofi"</span>, group = <span style="color: #f1fa8c;">"launcher"</span>}),
awful.key({ modkey }, <span style="color: #f1fa8c;">"i"</span>, <span style="color: #ff79c6; font-weight: bold;">function</span> ()
     <span style="color: #8be9fd; font-style: italic;">os</span>.<span style="color: #8be9fd; font-style: italic;">execute</span>(<span style="color: #8be9fd; font-style: italic;">string</span>.<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"rofi -modi %s -show %s -show-icons"</span>, <span style="color: #f1fa8c;">'run'</span>, <span style="color: #f1fa8c;">'drun'</span>))
                      <span style="color: #ff79c6; font-weight: bold;">end</span>,
     {description = <span style="color: #f1fa8c;">"show rofi"</span>, group = <span style="color: #f1fa8c;">"launcher"</span>}),
awful.key({ modkey }, <span style="color: #f1fa8c;">"Tab"</span>, <span style="color: #ff79c6; font-weight: bold;">function</span> ()
     <span style="color: #8be9fd; font-style: italic;">os</span>.<span style="color: #8be9fd; font-style: italic;">execute</span>(<span style="color: #8be9fd; font-style: italic;">string</span>.<span style="color: #8be9fd; font-style: italic;">format</span>(<span style="color: #f1fa8c;">"rofi -show %s -show-icons"</span>, <span style="color: #f1fa8c;">'window'</span>))
                      <span style="color: #ff79c6; font-weight: bold;">end</span>,
     {description = <span style="color: #f1fa8c;">"show windows"</span>, group = <span style="color: #f1fa8c;">"launcher"</span>}),
</pre>
</div>

<p>
He cambiado algunas cosas más: por ejemplo, todo parecía configurado
para utilizar <code>vim</code> y lo he cambiado a <i>emacs</i> y algunas otras manías,
como cambiar el formato de fecha al estilo <code>ISO</code> <i>año-mes-día</i>, añadir
<i>etiquetas</i> hasta el «0» en lugar de hasta el «5» que venían por
defecto.
</p>
</div>
</div>
<div id="outline-container-orge9d3047" class="outline-2">
<h2 id="orge9d3047">Características</h2>
<div class="outline-text-2" id="text-orge9d3047">
<p>
En mi caso, acostumbrado ya a <code>i3wm</code> el funcionamiento de <code>awesome</code> no
me ha sorprendido. Resulta un entorno tipo mosaico bastante flexible y
parecido al que estoy acostumbrado, exceptuando que, en ocasiones, el
modo de distribución del escritorio me sorprende situando una ventana
donde no espero. En <code>i3wm</code> cuando abres una ventana nueva, por defecto
divide la pantalla en horizontal y la sitúa a la derecha de la
actual. Sin embargo, aquí depende de qué modo tengamos activado y la
puede poner horizontal abajo, horizontal arriba, vertical a la
izquierda, centrada en la pantalla, etc.
</p>

<p>
De las características generales y de diseño de <i>software</i> no puedo
hablar mucho, aparte de lo ya dicho sobre el lenguaje <code>lua</code>. Quizá, lo
más destacable que he encontrado por su página web es el tema de que
está basado en la librería asíncrona <i>XCB</i> en lugar de la síncrona
<i>Xlib</i>.
</p>

<p>
Desde el punto de vista del usuario, muchas de las características son
definidas por el mismo <i>theme</i>, pero aún así las voy a destacar en el
artículo, porque me parecen interesantes.
</p>


<figure id="orgc12b2ef">
<img src="./imagen/captura-awesome-ayuda.png" alt="captura-awesome-ayuda.png">

</figure>

<p>
Una que estoy aún empleando más de lo que debiera en la que muestro en
la pantalla. La combinación <code>mod-s</code> me muestra una ventana modal con
las combinaciones de tecla definidas en el entorno y alguna
información extra, como teclas de funciones para <code>tmux</code>.
</p>

<p>
Todo lo demás es muy similar, --incluso en cuanto a atajos--, a lo que
viene siendo <code>i3wm</code>.
</p>

<p>
Las ventanas, además, tienen una definición que también depende del
<code>theme</code>. Por ejemplo, el modo en el que está configurando el título de
las ventanas es el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-lua"><span style="color: #6272a4;">-- </span><span style="color: #6272a4;">Add a titlebar if titlebars_enabled is set to true in the rules.
</span>client.connect_signal(<span style="color: #f1fa8c;">"request::titlebars"</span>, <span style="color: #ff79c6; font-weight: bold;">function</span>(<span style="color: #f8f8f2; font-weight: bold;">c</span>)
    <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">Custom
</span>    <span style="color: #ff79c6; font-weight: bold;">if</span> beautiful.titlebar_fun <span style="color: #ff79c6; font-weight: bold;">then</span>
        beautiful.titlebar_fun(c)
        <span style="color: #ff79c6; font-weight: bold;">return</span>
    <span style="color: #ff79c6; font-weight: bold;">end</span>

    <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">Default
</span>    <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">buttons for the titlebar
</span>    <span style="color: #ff79c6; font-weight: bold;">local</span> <span style="color: #f8f8f2; font-weight: bold;">buttons</span> = my_table.join(
        awful.button({ }, 1, <span style="color: #ff79c6; font-weight: bold;">function</span>()
            c:emit_signal(<span style="color: #f1fa8c;">"request::activate"</span>, <span style="color: #f1fa8c;">"titlebar"</span>, {raise = <span style="color: #bd93f9;">true</span>})
            awful.mouse.client.move(c)
        <span style="color: #ff79c6; font-weight: bold;">end</span>),
        awful.button({ }, 2, <span style="color: #ff79c6; font-weight: bold;">function</span>() c:kill() <span style="color: #ff79c6; font-weight: bold;">end</span>),
        awful.button({ }, 3, <span style="color: #ff79c6; font-weight: bold;">function</span>()
            c:emit_signal(<span style="color: #f1fa8c;">"request::activate"</span>, <span style="color: #f1fa8c;">"titlebar"</span>, {raise = <span style="color: #bd93f9;">true</span>})
            awful.mouse.client.resize(c)
        <span style="color: #ff79c6; font-weight: bold;">end</span>)
    )

    awful.titlebar(c, {size = dpi(16)}) : setup {
        { <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">Left
</span>            awful.titlebar.widget.iconwidget(c),
            buttons = buttons,
            layout  = wibox.layout.fixed.horizontal
        },
        { <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">Middle
</span>            { <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">Title
</span>                align  = <span style="color: #f1fa8c;">"center"</span>,
                widget = awful.titlebar.widget.titlewidget(c)
            },
            buttons = buttons,
            layout  = wibox.layout.flex.horizontal
        },
        { <span style="color: #6272a4;">-- </span><span style="color: #6272a4;">Right
</span>            awful.titlebar.widget.floatingbutton (c),
            awful.titlebar.widget.maximizedbutton(c),
            awful.titlebar.widget.stickybutton   (c),
            awful.titlebar.widget.ontopbutton    (c),
            awful.titlebar.widget.closebutton    (c),
            layout = wibox.layout.fixed.horizontal()
        },
        layout = wibox.layout.align.horizontal
    }
<span style="color: #ff79c6; font-weight: bold;">end</span>)
</pre>
</div>

<p>
Podemos analizar el resultado del código en la siguiente imagen:
</p>


<figure id="orgd25fc4e">
<img src="./imagen/2019-08-01-captura-awesome-ventana.png" alt="2019-08-01-captura-awesome-ventana.png">

</figure>

<p>
La captura de pantalla se ha realizado con el modo <i>magnifier</i> que
hace flotar la ventana activa al centro de la pantalla mientras el
resto de las ventanas abiertas forman un mosaico tras ella.
</p>

<p>
Los nombres de los botones creo que son suficientemente descriptivos:
</p>

<ul class="org-ul">
<li><code>floatingbutton</code> hace que si está activado, la ventana se comporte
de modo flotante independientemente del modo en que esté configurado
el escritorio.</li>
<li><code>maximizedbutton</code> hace que una ventana esté maximizada
independientemente del modo configurado.</li>
<li><code>stickybuttom</code> hace que cuando esté activado, la ventana se muestre
en todos los escritorios, haciéndola omnipresente.</li>
<li><code>ontopbutton</code> hace que la ventana marcada permanezca encima del
resto de las ventanas.</li>
<li><code>closebutton</code> cierra la ventana.</li>
</ul>

<p>
Además, podemos observar que en la barra de estado, entre las
etiquetas de los escritorios y la información que hemos configurado,
aparecen dos <i>botones</i> o <i>chismáticos</i> con el título de las ventanas
activas. Funcionan también como un atajo para activar la ventana
correspondiente si utilizamos el ratón, o si utilizamos el teclado,
también nos indica cuál está activa --por si no quedara claro con su
posición y/o colores en la pantalla--.
</p>
</div>
</div>
<div id="outline-container-org153f031" class="outline-2">
<h2 id="org153f031">Conclusión</h2>
<div class="outline-text-2" id="text-org153f031">
<p>
La verdad es que lo instalé y lo probé sin muchas expectativas. Estoy
contento con <code>i3wm</code> y su rendimiento, pero en estos pocos días que lo
llevo utilizando el <code>awesomewm</code> me ha sorprendido gratamente. De
momento lo seguiré utilizando unos días, dándole una oportunidad. En
realidad, es más complejo de configurar que <code>i3wm</code> porque hay que
dominar <code>lua</code>. Sin embargo, el mismo hecho le da potencia y
flexibilidad. Literalmente en un fichero <code>rc.lua</code> puedes hacer
realmente lo que quieras<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>

<p>
Si alguien tiene alguna duda y quiere preguntar de manera específica:
están abiertos los comentarios. Quizá mi brevedad en la entrada deje
en el aire más dudas que certidumbres.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Lo que me recuerda por temas de seguridad, no deberías confiar
en ninguna configuración que no hayas escrito tú mismo, o por lo menos
revisado de forma concienzuda. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/linux/index.html">linux</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[linux]]></category>
  <link>https://notxor.nueva-actitud.org/2019/08/01/probando-el-gestor-de-ventanas-awesome.html</link>
  <pubDate>Thu, 01 Aug 2019 23:45:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Convertir un pdf en imágenes a texto en org-mode]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-07-25</div>
<p>
Llega el verano y estoy preparando mi lector de libros electrónicos y
mi <i>tablet</i> para la lectura estival. Normalmente leo mucho, pero en
verano aún más. Tengo toda una lista de libros para cargar en los
dispositivos, la mayoría en formato <code>epub</code>, otros en <code>pdf</code>. Aquí es
donde empiezan los problemas con los formatos: <code>pdf</code> es un formato que
se inventó para imprimir en papel; si tienes una pantalla del tamaño
mínimo de una hoja de papel lo verás bien; si no, leer un libro en
<code>pdf</code> se convertirá en un suplicio. De hecho, en la <i>tablet</i> según qué
ficheros los puedo leer más o menos decentemente, pero otros no. El
contenido del archivo no se ajusta a la pantalla y se hace incómodo
leer, pasar página, etc. En el <i>libro electrónico</i>, ese cacharrito con
pantalla de «tinta electrónica» del tamaño de un móvil grande o de una
<i>tablet</i> pequeña, los <code>pdf</code> se convierten en una tortura.
</p>

<p>
Se pueden convertir los <code>pdf</code> a texto de forma fácil, si el <code>pdf</code>
contiene texto. Que puede parecer una tontería, pero hay muchos <code>pdf</code>
que en realidad son una serie de imágenes de páginas escaneadas y
cuando los abres para mirar sólo contienen una ristra de imágenes.
</p>

<p>
Me gustaría que existiera algún modo de hacer que el <code>pdf</code> se
convirtiera en <code>epub</code> de forma «automágica», pero no conozco ninguna
herramienta que lo haga. Por otro lado, después de pegarme con el
asunto un poco, la complejidad del problema es grande, porque envuelve
tener una conversión de imagen a texto utilizando <code>OCR</code> y aunque los
<code>OCR</code> han avanzado mucho, la salida del texto está plagada de errores:
manchas en el escaneo, saltos de línea en medio de palabras, errores
de codificación como confundir la «m» con «ni» o la «l» con el «1», o
al revés.
</p>

<p>
La conversión por tanto la debemos hacer por pasos y supervisar los
resultados:
</p>

<ol class="org-ol">
<li>Extraer las imágenes.</li>
<li>Convertir en texto</li>
<li>Supervisar y corregir los errores.</li>
</ol>

<p>
Así pues, vamos por partes.
</p>
<div id="outline-container-org361720e" class="outline-2">
<h2 id="org361720e">Proceso manual</h2>
<div class="outline-text-2" id="text-org361720e">
<p>
Vamos a suponer que lo hacemos todo a mano, página a página. Los pasos
serían los siguientes.
</p>
</div>
<div id="outline-container-orgb41ae19" class="outline-3">
<h3 id="orgb41ae19">Extraer las imágenes con <code>poppler-tools</code></h3>
<div class="outline-text-3" id="text-orgb41ae19">
<p>
Estas son unas herramientas similares a <code>pdftk</code>, concretamente un
<i>fork</i> de <code>xpdf</code> y entre otras cosas nos permitirá extraer las
imágenes que componen el <code>pdf</code> utilizando la herramienta <code>pdfimages</code>.
</p>

<p>
Para extraer páginas con <code>pdfimages</code> la línea de comandos es sencilla
de explicar:
</p>

<div class="org-src-container">
<pre class="src src-shell">pdfimages -png -f 41 -l 50 archivo-origen.pdf nombre-base
</pre>
</div>

<p>
Suponiendo que el <code>archivo-origen.pdf</code> es el que deseamos convertir,
la opción <code>-png</code> indica el tipo de fichero gráfico que se generará. La
opción <code>-f 41</code> indica que comience a extraer (<i>first</i>) en la página 41
y la opción <code>l 50</code> indica que deje de hacerlo (<i>last</i>) en la 50. El
parámetro <code>nombre-base</code> hará que las páginas convertidas en gráficos
tengan los nombres de fichero <code>nombre-base-000.png</code> hasta
<code>nombre-base-009.png</code>. Como se puede apreciar, la herramienta comienza
la cuenta siempre desde cero, por lo que tenemos que tener cuidado si
no queremos sobrescribir los ficheros con otros.
</p>
</div>
</div>
<div id="outline-container-orgf4aabdc" class="outline-3">
<h3 id="orgf4aabdc">Convertir la imagen en texto con <code>tesseract</code></h3>
<div class="outline-text-3" id="text-orgf4aabdc">
<p>
En el momento en que hemos extraído una imagen con el texto es el
momento de que el <code>OCR</code> haga su magia y lo convierta en algo legible.
</p>

<div class="org-src-container">
<pre class="src src-shell">tesseract -l lang pagina.png fichero-salida
</pre>
</div>

<p>
También es una línea sencilla de entender, está el comando <code>tesseract</code>
y las opciones <i>casi</i> se explican solas: la opción <code>-l lang</code>
especifica el idioma en el que se encuentra el texto que se debe
extraer. La opción <code>pagina.png</code> es la imagen escaneada y
<code>fichero-salida</code> es el nombre de fichero que se convertirá en
<code>fichero-salida.txt</code> cuando el <code>OCR</code> haya terminado.
</p>

<p>
Con esos dos comandos, <code>pdfimages</code> y <code>tesseract</code>, consigo el texto
plano. Pero la pregunta fundamental es: <i>¿Página a página?</i>.
</p>
</div>
</div>
</div>
<div id="outline-container-org5f3ec7d" class="outline-2">
<h2 id="org5f3ec7d">Automatizar el proceso</h2>
<div class="outline-text-2" id="text-org5f3ec7d">
<p>
Ir página a página está bien si son ficheros cortos de tres o cuatro
páginas. Sin embargo, un libro es harina de otro costal, cientos, o
quizá miles, de páginas una a una es la muerte a pellizcos. Así que
habrá que hacer un procesamiento por lotes.
</p>

<p>
Voy a explicar todo el proceso según lo voy haciendo desde cero,
comenzando por análisis del problema hasta la codificación de un
sencillo módulo <code>.el</code> que nos haga el trabajo más o menos
«automágicamente».
</p>
</div>
<div id="outline-container-org7c92e25" class="outline-3">
<h3 id="org7c92e25">Análisis del problema</h3>
<div class="outline-text-3" id="text-org7c92e25">
<p>
Un libro tiene una estructura de árbol en su índice (también puede
tener forma de <i>árbol muerto</i> en su construcción, pero de momento nos
quedaremos con los electrónicos). Es decir, se estructura en <i>partes</i>,
en capítulos y secciones, subsecciones, párrafos. Algo que explora muy
bien <code>org-mode</code> y que no hace falta que nos detengamos demasiado en
ello. En mi caso he decidido que cada capítulo de un libro vaya en un
documento <code>org</code> aparte.
</p>

<p>
Estoy tomando uno de los libros que tengo para convertir y haremos un
capítulo para las pruebas:
</p>


<figure id="orgfa6555d">
<img src="./imagen/Captura-pantalla-inicio-conversor.png" alt="Captura-pantalla-inicio-conversor.png">

</figure>

<p>
En el visor de la derecha, <code>zathura</code>, nos indica que el capítulo que
queremos convertir comienza en la página 20 así que podemos darle a
nuestra entrada del árbol una propiedad con <code>C-c C-x P</code> y luego
teclearemos en la línea <code>desde: 20</code> y repetir el proceso con todas las
propiedades que necesitamos. En un principio, el nombre del fichero
original, dónde empezar la conversión, dónde parar y el idioma en el
que está el texto. Esto último es importante porque el <code>OCR</code> se
adaptará al alfabeto y ortografía del texto. Nos deberá quedar algo
así:
</p>


<figure id="orgf88c828">
<img src="./imagen/Captura-pantalla-fin-conversor.png" alt="Captura-pantalla-fin-conversor.png">

</figure>

<p>
Como se puede apreciar el texto para convertir los documentos es
bastante sensible:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">:PROPERTIES:
:desde:    20
:hasta:    34
:fichero:  ./la-mastro-de-la-ringoj.pdf
:idioma:   epo
:END:
</pre>
</div>

<p>
Vamos al código que hará la conversión por lotes y lo analizaré con
todo detalle:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">procesar-ocr.el
</span>
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Variables globales para el proceso
</span>
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">fichero</span> <span style="color: #f1fa8c;">""</span>
  <span style="color: #6272a4;">"Variable que contiene el nombre de fichero a convertir."</span>)
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">inicio</span> 0
  <span style="color: #6272a4;">"N&#250;mero de p&#225;gina donde comenzar la conversi&#243;n."</span>)
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">fin</span> 0
  <span style="color: #6272a4;">"N&#250;mero de p&#225;gina donde finalizar la conversi&#243;n."</span>)
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">idioma</span> <span style="color: #f1fa8c;">""</span>
  <span style="color: #6272a4;">"Lenguaje de la lista de `tesseract --listlangs`"</span>)

<span style="color: #6272a4;">; </span><span style="color: #6272a4;">TODO - Habr&#237;a que comprobar que existen esas propiedades
</span>(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">iniciar</span> ()
  <span style="color: #6272a4;">"Iniciar las variables globales para el proceso."</span>
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> fichero (org-entry-get (point) <span style="color: #f1fa8c;">"fichero"</span>))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> inicio  (string-to-number (org-entry-get (point) <span style="color: #f1fa8c;">"desde"</span>)))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> fin     (string-to-number (org-entry-get (point) <span style="color: #f1fa8c;">"hasta"</span>)))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> idioma  (org-entry-get (point) <span style="color: #f1fa8c;">"idioma"</span>)))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">procesar-pagina</span> (num)
  <span style="color: #6272a4;">"Inserta el texto obtenido al procesar una imagen en el /point/."</span>
  (message <span style="color: #f1fa8c;">"Procesando la p&#225;gina %s"</span> num)
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Obtener la imagen con el texto
</span>  (call-process-shell-command (format <span style="color: #f1fa8c;">"pdfimages -png -f %d -l %d %s pagina"</span> num num fichero))
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Obtener el texto de la imagen
</span>  (call-process-shell-command (format <span style="color: #f1fa8c;">"tesseract -l %s pagina-000.png temporal"</span> idioma))
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Meter el texto en el punto
</span>  (insert-file-contents <span style="color: #f1fa8c;">"temporal.txt"</span>)
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Borrar los ficheros temporales
</span>  (shell-command <span style="color: #f1fa8c;">"rm pagina-000.png temporal.txt"</span>))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">procesar-ocr</span> ()
  <span style="color: #6272a4;">"Procesa las p&#225;ginas especificadas del documento dado en el buffer actual."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (iniciar)       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Establece las variables globales
</span>  (mapc 'procesar-pagina (number-sequence fin inicio -1)))
</pre>
</div>
</div>
</div>
<div id="outline-container-orgd652b2e" class="outline-3">
<h3 id="orgd652b2e">Iniciar el proceso</h3>
<div class="outline-text-3" id="text-orgd652b2e">
<p>
La función <i>interactiva</i>, la que se convierte en <i>comando</i> de <i>emacs</i>
es la función <code>procesar-ocr</code>. Es muy sencilla, sólo hace tres cosas:
</p>

<ol class="org-ol">
<li>Se declara como <i>interactiva</i>.</li>
<li>Inicia los datos con los valores de las propiedades expresadas en
el <i>buffer</i> desde el que se llama.</li>
<li>Genera una lista con los números de página que tiene que
procesar.</li>
</ol>

<p>
Este último punto lo explicaré más despacio: esto es <i>Lisp</i>, esconde
un <i>bucle</i>. Si vienes de otros lenguajes de programación es posible
que viendo <code>procesar-pagina</code> estés esperando algún tipo de bucle. Sin
embargo, en este caso lo que hacemos es utilizar <code>mapc</code> para que
aplique <code>procesar-pagina</code> a una lista con el número de páginas.  Los
números se los pasamos en una lista generada por la forma
<code>(number-sequence fin inicio -1)</code>  que devuelve una lista desde <code>fin</code>
a <code>inicio</code> con un paso -1.  ¿Por qué lo hago al revés? Pues porque
luego, al insertar el texto en el lugar del cursor, <i>emacs</i> irá
empujando hacia abajo lo insertado. Pero no adelantemos
acontecimientos.
</p>
</div>
</div>
<div id="outline-container-org1fd18ee" class="outline-3">
<h3 id="org1fd18ee">El proceso de la página</h3>
<div class="outline-text-3" id="text-org1fd18ee">
<p>
La función <code>procesar-pagina</code> sólo necesita el parámetro con el número
de página.
</p>

<p>
He utilizado la forma <code>call-process-shell-command</code> porque la llamada a
<code>shell-command</code> que suele ser más habitual se hace de forma
asíncrona. Eso hace que, dado que el sistema <code>OCR</code> tarda unos segundos
en hacer la conversión y como utilizamos siempre los mismos ficheros
intermedios, una llamada los sobrescribiría cuando aún no ha terminado de
procesarlos la anterior.
</p>

<p>
Una vez generado el texto se inserta en la posición del punto
(<i>point</i>) con la forma <code>insert-file-contents</code>.
</p>

<p>
<i>Et voilà</i>
</p>
</div>
</div>
<div id="outline-container-org9504bb1" class="outline-3">
<h3 id="org9504bb1">Conseguida la conversión</h3>
<div class="outline-text-3" id="text-org9504bb1">

<figure id="orgf022a16">
<img src="./imagen/Captura-pantalla-texto-convertido.png" alt="Captura-pantalla-texto-convertido.png">

</figure>

<p>
Ahora toca arreglar todos los errores de conversión, eliminar los
espacios en blanco sobrantes, los guiones que marcan la continuidad de
las palabras en la línea siguiente, los signos de puntuación mal
colocados o equivocados, arreglar los párrafos, introducir los
formatos de texto: cursivas, negritas, etc. Un trabajo largo y
aburrido, pero más sencillo que ir haciéndolo página a página. Y
bastante más corto que pasar todo el texto a mano, por supuesto.
</p>
</div>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2019/07/25/convertir-un-pdf-en-imágenes-a-texto-en-org-mode.html</link>
  <pubDate>Thu, 25 Jul 2019 22:48:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Algunas reflexiones sobre el blog]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-07-20</div>
<p>
Llevo un tiempo dándole vueltas al <i>blog</i>. Lo he venido cuidando desde
hace años, tanto en su primera versión con <a href="https://blog.getpelican.com/"><i>Pelican</i></a> como su evolución
con <a href="https://github.com/sillykelvin/org-page">org-page</a> y seguiré haciéndolo mientras aguante el cuerpo --y la
mente, por supuesto--.
</p>

<p>
El <i>blog</i> ha ido dando bandazos en base a mis intereses personales del
momento. Hablo de casi cualquier cosa que me emocione aprender, ya sea
de psicología, de informática o de cualquier aspecto que me parezca
relevante. Eso puede ser un problema, porque no hay un tema fijo o una
coherencia editorial definida. Lo califico de <i>problema</i>, aunque yo no
lo vea así desde mi punto de vista subjetivo. Mientras se mantiene
como mi <i>blog</i> personal hablo en él sobre lo que quiero.
</p>

<p>
Una de las cosas que he pensado es poner un botón de esos «de <i>limosna</i>
para el autor». Considerando que éste no es un <i>blog</i> con <i>ánimo de
lucro</i> lo más que pondría es un botón, pequeño en una esquina o en el
pie de las páginas para que done el que quiera... y pienso que
seguiría siendo sin «ánimo de lucro», porque el contenido seguiría
siendo abierto: se podría leer sin activar el <i>javascript</i> (por lo que
el botón sería invisible para el posible lector), seguiría siendo
accesible. Donaría el que quisiera sin presiones y sin ponerme cansino
con el «dame argo pa' un bocata de chorizo».
</p>
<div id="outline-container-orgc59347a" class="outline-2">
<h2 id="orgc59347a">Consideraciones</h2>
<div class="outline-text-2" id="text-orgc59347a">
</div>
<div id="outline-container-orgcdf061b" class="outline-3">
<h3 id="orgcdf061b">¿El objetivo?</h3>
<div class="outline-text-3" id="text-orgcdf061b">
<p>
Financiar el <i>hosting</i>. No es que sea muy caro, con obtener unos pocos
euros al año sería suficiente de momento para compensar que es un
subdominio que chupa recursos de un <i>dominio padre</i> y en un futuro,
--espero que próximo--, migrar a un dominio propio y dejar de molestar
en otros sitios.
</p>
</div>
</div>
<div id="outline-container-orga874cc3" class="outline-3">
<h3 id="orga874cc3">¿Dónde irá lo obtenido?</h3>
<div class="outline-text-3" id="text-orga874cc3">
<p>
En principio no espero obtener mucho de ello, seguramente me tocará
añadir dinero de mi bolsillo en el caso de que finalmente ponga el
<i>pichorro</i> de donaciones. Sin embargo, es posible, aunque poco
probable, que obtenga más de lo necesario para mantener el sitio. En
ese caso había pensado en <i>donar</i> los excedentes a las herramientas
que utilizo en el <i>blog</i>: <i>emacs</i>, <i>blender</i>, la <i>Free Software
Fundation</i>, o cualquier otro proyecto que redunde en el desarrollo de
<i>software libre</i> hecho por y para la comunidad.
</p>
</div>
</div>
<div id="outline-container-org5e43d35" class="outline-3">
<h3 id="org5e43d35">Herramientas</h3>
<div class="outline-text-3" id="text-org5e43d35">
<p>
Cuando hablamos de monetizar con donativos algún proyecto, viene a la
mente el sitio típico de <a href="https://www.patreon.com/"><i>Patreon</i></a>, pero hay otros sitios como <a href="https://www.ko-fi.com/">ko-fi</a>.
Hay muchos más, pero esos dos son los que estoy considerando.
</p>

<p>
El primero, <i>Patreon</i>, es el más conocido y por tanto el más familiar
para la gente. Sin embargo, cobran comisión y sus condiciones, si
tenemos en cuenta los impuestos, al final es posible que no se reciba
nada. El segundo, <i>ko-fi</i>, es menos conocido: la versión gratuita
afirma que entregan el 100% de lo recaudado sin comisiones. En cambio,
la aportación mínima son 3€ y, yo sinceramente, no creo que nadie en
su sano juicio aporte tres euros tan fácilmente. Se pueden cambiar los
mínimos, pero sólo en las cuentas <i>gold</i> que son de pago y ya hay
comisiones y esas cosas.
</p>
</div>
</div>
</div>
<div id="outline-container-org5d331cc" class="outline-2">
<h2 id="org5d331cc">Conclusiones</h2>
<div class="outline-text-2" id="text-org5d331cc">
<p>
Pues eso, no me decido, lo haré o no. Dentro de unas semanas veremos.
En realidad, no creo que moleste mucho un botón de donaciones por ahí
en algún rincón. Veremos.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/blog/index.html">blog</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[blog]]></category>
  <link>https://notxor.nueva-actitud.org/2019/07/20/algunas-reflexiones-sobre-el-blog.html</link>
  <pubDate>Sat, 20 Jul 2019 00:18:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Naves vaporosas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-07-17</div>
<p>
Es posible que alguien se pregunte si no me habré equivocado al
escribir el título porque le suene más aquello de <i>nubes vaporosas</i>.
Sin embargo, no me he equivocado, ya disculparéis mi irritante
tendencia a hablar de todo proyecto que acaba en <i>vapor</i>, --sobre todo
juegos--.
</p>

<p>
Traigo otro entre manos y he venido corriendo a contarlo: empezó hace
cuatro años, más o menos, quedando abandonado y contra todo pronóstico,
ha regresado. Ha vuelto un tanto cambiado; el proyecto original era
una especie de juego de naves 2D, donde dos oponentes se enfrentaban
en un combate <i>por turnos</i> en un tablero.  La idea original era
sencilla con algunos <i>sprites</i> moviéndose por la pantalla y creando la
ilusión de un combate singular.
</p>

<p>
Lo tenía casi olvidado, fue mi primer contacto con <a href="https://godotengine.org/"><i>Godot Engine</i></a> y no
pensé en retomarlo. Teníamos unos gráficos penosos, el código era
apenas cuatro menús y dos animaciones de las naves y sus chorros de
reacción que funcionaba a duras penas. Hablo en plural porque no estoy
sólo en esto: otro amigo, --empezamos juntos el proyecto hace cuatro
años--, hace poco se puso en contacto conmigo y me dijo aquello de <i>Y
si...</i> y en ello estamos.
</p>

<p>
Hay algunos avances, las naves han pasado a ser cosas en 3D que se
moverán por un espacio simulado para crear la ilusión de combate
singular entre los jugadores.
</p>

<p>
Os mostraré los diseños que he hecho para las pruebas.
</p>
<div id="outline-container-orgf9dfc48" class="outline-2">
<h2 id="orgf9dfc48">Naves</h2>
<div class="outline-text-2" id="text-orgf9dfc48">

<figure id="org4d92a12">
<img src="./imagen/Captura-pantalla-laser-o.png" alt="Captura-pantalla-laser-o.png"> 

</figure>

<p>
Esa es la nave más ligera, bautizada como <i>laser-o</i>. Rápida pero
escasamente armada.
</p>


<figure id="org6ebfbc5">
<img src="./imagen/Captura-pantalla-fighter.png" alt="Captura-pantalla-fighter.png">

</figure>

<p>
Esto es un caza simple que pondera velocidad y armamento.
</p>


<figure id="org8841e8f">
<img src="./imagen/Captura-pantalla-tetraala.png" alt="Captura-pantalla-tetraala.png">

</figure>

<p>
Es, de momento, la nave más pesada, menos maniobrable y más armada de
las tres.
</p>

<p>
También contamos con cosas como <i>disparos de láser</i>, <i>minas</i> y todas
esas cosas necesarias para simular una batalla.
</p>
</div>
</div>
<div id="outline-container-org1a0e0d6" class="outline-2">
<h2 id="org1a0e0d6">Juego</h2>
<div class="outline-text-2" id="text-org1a0e0d6">
<p>
El modo de juego está aún un poco verde, no hemos decidido algunos
términos, pero en principio queremos establecer dos modos de juego:
Uno de ellos sería el <i>combate singular</i> que podría reunir hasta seis
u ocho jugadores, donde vencería el que quedara con alguna nave en el
espacio de juego. El otro modo sería el denominado <i>campaña</i>, donde el
jugador de forma individual o en equipos, se enfrentarían a toda una
serie de misiones encadenadas donde además habrá una historia.
</p>
</div>
</div>
<div id="outline-container-org6318757" class="outline-2">
<h2 id="org6318757">Conclusión</h2>
<div class="outline-text-2" id="text-org6318757">
<p>
De momento no hay mucho más que contar... de hecho lo cuento aquí
porque estos días los he invertido en modelar las navecillas esas, que
no siendo gran cosa, nos servirán para poner el código necesario para
ver las posibilidades del juego. Pero me ha absorbido el tiempo y
llevo ya mucho tiempo saltando de un proyecto a otro sin encontrar el
momento para sentarme a escribir algo en el <i>blog</i>.
</p>

<p>
No hay muchas pretensiones con él: es más una prueba de concepto para
ver si somos capaces de hacer algo interesante con <i>Godot</i>.
Posiblemente, como otros proyectos más, se convierta en <i>vaporware</i>.
Aunque espero que no.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/juegos/index.html">juegos</a> ]]></description>
  <category><![CDATA[juegos]]></category>
  <link>https://notxor.nueva-actitud.org/2019/07/17/naves-vaporosas.html</link>
  <pubDate>Wed, 17 Jul 2019 22:11:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Gestionar bibliografía con Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-06-30</div>
<p>
Llevo tiempo utilizando documentos en formato texto para todo. La
documentación, como ya he contado muchas veces en este blog, la
escribo utilizando <i>LaTeX</i> y como sabéis, la bibliografía de esos
documentos se guarda normalmente en ficheros <code>.bib</code>. Hasta ahora
<a href="https://www.jabref.org/">utilizaba la herramienta <i>JabRef</i></a> para gestionar esas <i>bases de datos</i>
y todo funcionaba perfectamente: es una gran aplicación.  Pero de un
tiempo a esta parte, las versiones que van sacando de <i>JabRef</i> me han
dejado de funcionar. No tengo muy claro por qué, lo estoy achacando a
la versión de <i>OpenJDK</i>, --y todo su entorno--, que instala
<i>Tumbleweed</i>.
</p>

<p>
El otro día, escribiendo un documento, me di cuenta que <i>JabRef</i> no me
funcionaba. Afortunadamente, cuando abrí el fichero <code>.bib</code> con <i>Emacs</i>
se me abrió un modo que se llama <code>BibTex</code>. Colorea sintaxis y agrega
una gran lista de funciones para gestionar las entradas en la base de
datos. Además, era una lista pequeña, sólo había cinco documentos que
citar y se podía gestionar a mano de forma fácil.
</p>

<p>
Probé varias veces a recuperar <i>JabRef</i>, lanzándolo desde línea de
comandos, descargando varias versiones para al final llegar a la
conclusión de que no me funcionaba y que haría bien en buscar una
alternativa y, puesto que, últimamente mis herramientas tienen a
orbitar alrededor de <i>Emacs</i> miré alternativas con mi editor
favorito.
</p>

<p>
Como ya dicho podemos modificar el fichero de texto, algo que puede
ser útil para bibliografías pequeñas pero que puede ser un infierno
para las grandes, sobre todo buscando una entrada concreta. Tenía que
encontrar algo mejor y rebuscando un poco me topé con el paquete
<code>ebib</code> y decidí probarlo. Escribo este artículo desde el
descubrimiento, es decir: lo estoy probando para ver si me es útil y
no conozco al 100% la herramienta. A diferencia de <code>BibTex</code>, <code>ebib</code> no
es un modo, ni mayor ni menor, sino una aplicación que corre teniendo
<i>emacs</i> como entorno... pero empecemos por el principio.
</p>
<div id="outline-container-orgd6c52d5" class="outline-2">
<h2 id="orgd6c52d5">Instalación y primeros pasos</h2>
<div class="outline-text-2" id="text-orgd6c52d5">
<p>
<code>ebib</code> se puede instalar desde el gestor de paquetes de <i>emacs</i> y no
tiene mayor misterio. En el manual de la herramienta recomienda
definir una combinación de teclas para acceder directamente a la
herramienta (<code>C-c e</code>). Yo no he definido ninguna combinación de teclas
y llamo a la aplicación desde la general <code>M-x</code>.
</p>

<p>
Para salir de la aplicación se pueden utilizar varias teclas según lo
que queramos hacer. Lo primero que sorprende es que desaparecen las
ventanas que tenemos abiertas y aparecen sólo dos. La de arriba es una
lista para las entradas de la(s) base(s) de datos y la de abajo son
los detalles de cada una de esas entradas.
</p>

<p>
Si queremos volver a los <i>buffers</i> con los que estábamos trabajando
sin cerrar <code>ebib</code>, podemos pulsar <code>z</code> y si realmente queremos salir
utilizaremos <code>q</code>.
</p>
</div>
</div>
<div id="outline-container-orgcdf7a57" class="outline-2">
<h2 id="orgcdf7a57">Abrir un fichero <code>.bib</code></h2>
<div class="outline-text-2" id="text-orgcdf7a57">
<p>
Una vez lanzado el programa con la combinación <code>M-x ebib</code>, podemos
abrir cualquier fichero <code>.bib</code> pulsando la tecla <code>o</code>. Una de las cosas
que me ha gustado es que se pueden abrir simultáneamente varios
ficheros y saltar de una base de datos a otra pulsando las teclas del
1 al 9. Además, las teclas de movimiento dentro del fichero se
corresponde con las habituales en <i>emacs</i> <code>p</code> (o <code>C-p</code>) para ir al
registro anterior y <code>n</code> (o <code>C-n</code>) para ir al siguiente, también se
pueden utilizar las teclas de cursor. Para cerrar una base de datos
basta con pulsar <code>c</code> para hacerlo, aunque sin cerrar <code>ebib</code>.
</p>

<p>
Si hemos pulsado <code>o</code> y le damos un nombre de fichero que no existe,
<code>ebib</code> creará una nueva base de datos.
</p>
</div>
</div>
<div id="outline-container-orge1cdbc2" class="outline-2">
<h2 id="orge1cdbc2">Trabajar con las referencias</h2>
<div class="outline-text-2" id="text-orge1cdbc2">
<p>
Las operaciones más habituales son las de crear, editar y borrar
entradas, como en todas las bases de datos. Para añadir una referencia
en la ventana de <code>ebib</code> pulsaremos la tecla <code>a</code>. Esto creará una nueva
entrada y nos pasará el control a la ventana de campos, donde podemos
modificar cada uno de ellos pulsando <code>enter</code> sobre él. Cuando
terminemos la edición, pulsaremos <code>q</code> y volveremos a la lista de
entradas. Si ya tenemos la entrada y lo que queremos es modificarla,
pulsaremos la tecla <code>e</code>.
</p>

<p>
Podemos también borrar una entrada pulsando <code>k</code>, este comando pasará
dicha entrada al anillo de borrado: podemos recuperar lo borrado
pulsando <code>y</code>. Esto es bastante útil cuando estamos trabajando con
varios ficheros, porque podemos recuperar entradas entre distintas
bases de datos. Aunque sería más recomendable que se utilizara el
comando <code>M-x ebib-copy-entry</code>.
</p>

<p>
Si queremos insertar una cita en un <i>buffer</i> en el que estemos
trabajando, podemos buscar la referencia que necesitamos pulsando la
tecla <code>/</code> y después la cadena de búsqueda. Una vez encontrada la
referencia que buscamos pulsaremos <code>i</code>, nos preguntará el <i>buffer</i> y
siguiendo las instrucciones <code>ebib</code> insertará la referencia.
</p>
</div>
</div>
<div id="outline-container-orgea235cf" class="outline-2">
<h2 id="orgea235cf">Guardar la base de datos</h2>
<div class="outline-text-2" id="text-orgea235cf">
<p>
Pulsando la tecla <code>s</code> guardará la base de datos que se haya
modificado, aunque también funciona la combinación habitual de <i>emacs</i>
<code>C-x C-s</code>. Si utilizamos la tecla <code>w</code>, como su equivalente de <i>emacs</i>
<code>C-x C-w</code> nos permitirá guardar el fichero con cualquier otro nombre.
</p>
</div>
</div>
<div id="outline-container-org0e100fb" class="outline-2">
<h2 id="org0e100fb">Filtros</h2>
<div class="outline-text-2" id="text-org0e100fb">
<p>
Si estamos trabajando con una base de datos muy grande y queremos
reducir el número de entradas a algo más manejable, pero sin borrar
nada, podemos establecer filtros pulsando la tecla <code>&amp;</code>. Por ejemplo,
si queremos que muestre sólo las entradas de un determinado autor,
haríamos las siguientes acciones:
</p>

<ol class="org-ol">
<li>Pulsamos <code>&amp;</code></li>
<li>Seleccionamos <code>author</code> en la lista (por defecto, filtra por el tipo
de documento)</li>
<li>Escribimos el autor que nos interesa y pulsamos <code>enter</code>.</li>
</ol>

<p>
En realidad, el carácter <code>&amp;</code> añade una condición <code>and</code> al filtro
establecido por defecto, que normalmente está vacío. Además, en la
<i>barra de estado</i> de la base de datos nos indicará qué filtro tiene
activado. Para acceder las funciones de <i>filtro</i> utilizaremos la tecla
<code>F</code>. Por ejemplo, para cancelar el filtro utilizaremos la combinación
<code>F c</code> o para guardar el filtro para posteriores usos, podemos utilizar
la combinación <code>F s</code>. El fichero donde se guardan esos filtros, según
la documentación es <code>~/.emacs.d/ebib-filters</code>.
</p>
</div>
</div>
<div id="outline-container-org690a508" class="outline-2">
<h2 id="org690a508">Impresión de la base de datos</h2>
<div class="outline-text-2" id="text-org690a508">
<p>
Una funcionalidad que encontré de casualidad es la capacidad de
imprimir el fichero <code>.bib</code>. Bueno, en realidad no lo imprime, lo que
hace <code>ebib</code> es generar un fichero <i>LaTeX</i> que luego se puede
imprimir. Tiene dos modos que se pueden acceder desde el menú de
<i>emacs</i> o lanzando los comandos <code>ebib-print-*</code>.
</p>
</div>
</div>
<div id="outline-container-orgfbc46de" class="outline-2">
<h2 id="orgfbc46de">Conclusión</h2>
<div class="outline-text-2" id="text-orgfbc46de">
<p>
No he utilizado la herramienta en profundidad por eso tampoco voy a
pronunciarme sobre <code>ebib</code> de una forma rotunda. Resulta un poco
decepcionante después de haber utilizado durante años <code>JabRef</code>, con
cientos de funciones y facilidades, tener sólo unas pocas en la
herramienta. A favor cuenta la integración con nuestro editor
favorito. Parece una aplicación bastante potente, a pesar de su
sencillez, pero echo de menos <code>JabRef</code>, veremos el uso que consigo
darle a <code>ebib</code>.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2019/06/30/gestionar-bibliografia-con-emacs.html</link>
  <pubDate>Sun, 30 Jun 2019 18:27:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Primer informe de Amnistía Internacional sobre Acoso Escolar]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-06-28</div>
<blockquote>
<p>
En España, son miles los casos de acoso escolar entre iguales que no
se documentan debido a la ausencia de datos, una formación inadecuada
y una rendición de cuentas deficiente.
</p>
</blockquote>

<p>
Con esta frase comienza Amnistía Internacional su informe sobre <i>Acoso
Escolar</i>. <a href="https://www.es.amnesty.org/en-que-estamos/noticias/noticia/articulo/espana-acoso-escolar-un-problema-invisible-que-precisa-un-sistema-de-denuncias-util-de-verdad/">Podéis consultar su página directamente</a>.
</p>

<p>
Hay quien puede preguntarse que hace <i>Amnistía Internacional</i>
ocupándose del tema del <i>acoso escolar</i>: ¿Esos no se dedicaban a los
Derechos Humanos? Y sí, es cierto que se dedican a los Derechos
Humanos pero ¿es que todavía queda alguien que piense que el <i>acoso
escolar</i> es cosa de niños?
</p>

<p>
Los principales puntos encontrados por Amnistía Internacional son muy
familiares, --demasiado--, para los que nos venimos dedicando a este
tema desde hace algún tiempo.
</p>

<ul class="org-ul">
<li>Las víctimas de acoso <b>se sienten indefensas</b> pero aún así <b>temen
denunciarlo</b> para evitar que el problema se agrave, porque piensan
que la denuncia es inútil o incluso contraproducente.</li>

<li>Los padres y las madres de los chicos que sufren acoso sienten un
<b>profundo sentimiento de culpa</b>.</li>

<li>Hay una gran presión entre los adolescentes para <b>ajustarse a los
roles sociales de género</b>.</li>

<li>En este estudio se repite el esquema de <b>abusos físicos</b> en los
chicos y <b>abuso social y exclusión</b> en las chicas.</li>

<li>Algo preocupante es que los menores no identifican los insultos por
la red y otras acciones incluidas en el <b>ciberacoso</b> como parte del
acoso, aunque sus padres o profesores sí lo hagan. Y <i>normalicen</i>
esas conductas.</li>

<li>En opinión de Amnistía Internacional, <b>las autoridades no están
adoptando todas las medidas necesarias para proteger a niños y
niñas</b>.</li>

<li>El <i>Plan Estratégico de Convivencia Escolar 2016-2020</i>, no se ha
implementado en su integridad: el <b>Observatorio Estatal de la
Convivencia Escolar</b>, sólo existe de manera nominal.</li>

<li>Las formas <i>no físicas</i> de acoso: los insultos, la exclusión social
y el hostigamiento suelen pasar desapercibidas.</li>

<li>El número de casos documentados por las autoridades educativas es
significativamente inferior al que se puede suponer por los
testimonios de niños, educadores y padres.</li>

<li>El acoso escolar es un problema que preocupa mucho a educadores,
psicólogos, padres y niños, pero sin el apoyo institucional, esa
preocupación sirve de muy poco.</li>

<li>La dirección de los centros educativos tiene la responsabilidad
disciplinaria, pero se sienten cada vez menos respaldados por la
inspección educativa y si no hay denuncia, prefieren mirar hacia
otro lado.</li>

<li>Los centros y las autoridades educativas deberían confiar más en los
niños y adolescentes para identificar los problemas y buscar las
soluciones.</li>
</ul>

<p>
Como venimos diciendo desde hace bastante tiempo: la educación debe
ser una de las prioridades para evitar este tipo de problemas y los
centros, los padres, los profesores y todos debemos transmitir un
inequívoco mensaje de <i>tolerancia cero</i> al acoso entre iguales.
</p>

<p>
<a href="https://nube.es.amnesty.org/index.php/s/8yAyJ7j3YtLy9De#pdfviewer">El informe se puede descargar directamente de la página de Amnistía
Internacional</a>.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/psicología/index.html">psicología</a> <a href="/tags/acoso/index.html">acoso</a> ]]></description>
  <category><![CDATA[psicología]]></category>
  <category><![CDATA[acoso]]></category>
  <link>https://notxor.nueva-actitud.org/2019/06/28/primer-informe-de-amnistia-internacional-sobre-acoso-escolar.html</link>
  <pubDate>Fri, 28 Jun 2019 20:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Sin saber qué hacer]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-06-27</div>
<p>
Llevo muchos días sin escribir en el blog nada de nada. Me he puesto a
escribir más por la necesidad de escribir, por no abandonar este
proyecto que por tener claro un tema o un objetivo para esta entrada.
Sólo necesitaba el ponerme a junta palabras de nuevo, a ver si mis
neuronas vuelven a su ser.
</p>

<p>
He pasado estas semanas <a href="https://www.eccouncil.org/programs/certified-ethical-hacker-ceh/">preparándome para aprobar el curso de
«juasker»</a>... y oye, el esfuerzo ha dado sus frutos y he aprobado.
Ahora hay una empresa en EEUU que dice que soy un «juasker» y además
<i>ético</i> (y tó y tó), y lo certifica para que otras empresas sepan que
tengo algunos conocimientos, no sé muy bien si avanzados o rarunos, de
informática. A partir de este momento en mi currículo pondré eso de
<i>informática nivel usuario</i> que nunca se sabe.
</p>

<p>
El caso es que me puesto a pensar en todo lo que significa esto que he
conseguido y me encuentro algunos puntos que tiran de mis carnes como
si fueran los de la apendicitis.
</p>
<div id="outline-container-org374ee89" class="outline-2">
<h2 id="org374ee89">Ética</h2>
<div class="outline-text-2" id="text-org374ee89">
<p>
Sí, bueno el curso lo nombra en su título <i>Certified Ethical Hacker</i>,
lo que quiere decir que estoy certificado como <i>hacker ético</i>. De
hecho en el examen (tipo test) las preguntas del apartado «ético» las
acerté todas sin fallar una. Claro que siendo sólo dos si hubiera
fallado una hubiera fallado el 50% del apartado.
</p>

<p>
Sin embargo, no sé si el concepto que tiene esa empresa estadounidense
sobre la ética es lo mismo que entiendo yo. En realidad sí lo sé: No.
Lo que yo entiendo por ética no es lo mismo que se entendía en ese
curso.  Lo que te enseñan en el curso sobre ética es básicamente: <i>«No
ataques ningún sistema si no tienes un contrato firmado antes con el
propietario de ese sistema»</i>.
</p>

<p>
Eso no es la ética como yo la entiendo. Quizá soy demasiado cándido,
pero para mí la ética está referida a comportamientos personales y
principios morales y no se reduce a contratos mercantiles. Lo más
importante no es <i>qué</i> poner en un contrato: lo más importante es
<i>qué</i> soy yo y <i>cuáles</i> son mis principios.
</p>
</div>
</div>
<div id="outline-container-org6b845b2" class="outline-2">
<h2 id="org6b845b2">Certificaciones</h2>
<div class="outline-text-2" id="text-org6b845b2">
<p>
Un tema que creo más cercano a especulación pura que a algo de valor.
Todo alrededor del examen de certificación es dinero.  Si te presentas
por libre te piden 1.100$ ... no tengo presente a cómo está el cambio
en estos momentos, pero voy a redondearlo a 1.000€. Después de pagar
ese dineral, además, si quieres que te envíen el certificado en papel
a casa, son 75$ más. Es válido por tres años, por lo que si quieres
mantener la certificación tienes que volver a pasar por caja. Y así
una detrás de otra: el negocio está muy bien montado, todo son
beneficios. Esto no es como ir a una <i>escuela</i> o <i>facultad</i> a
estudiar, no gastan en profesores ni en instalaciones. Lo más que
hacen es producir un montón de documentación tan protegida por DRM que
muchas veces ni los interesados pueden leer y unas máquinas virtuales
para hacer los ejercicios... y ya está. Mínima inversión, máximos
beneficios. Sobre todo, cuando te das cuenta de que muchos de los
conceptos ya los tenías o, por lo menos, te sonaban. Tampoco tienes
que registrar un título, porque lo que haces no es dar una titulación,
sino <i>certificar</i> que alguien tiene unos conocimientos mínimos sobre
algún tema.
</p>

<p>
Creo que todo al final se resume a lo mismo: <i>dinero</i>.
</p>
</div>
</div>
<div id="outline-container-orgdbc5948" class="outline-2">
<h2 id="orgdbc5948">Y esto ¿para qué?</h2>
<div class="outline-text-2" id="text-orgdbc5948">
<p>
La verdad es que pedí el curso mirando sólo el título entre la lista
de cursos gratuitos que proporciona el INAEM<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.  Eché la
preinscripción donde me hicieron un examen previo, entregué un
currículo con mis experiencias con las tecnologías informáticas, me
preguntaban mi nivel de inglés --algo que es fundamental, porque toda
la documentación está en inglés y el examen es en inglés--. La empresa
no se ha molestado en traducirlo a ningún otro idioma: minimizar
gastos, maximizar beneficios.
</p>

<p>
Al comenzar el curso presencial me enteré de los precios y que son los
contribuyentes los que corren con los gastos. En este caso los fondos
vienen de Europa y me sabía mal gastar ese pastizal sin aprobar.
Supongo que son mis propias consideraciones <i>éticas</i> porque soy
consciente que el dinero que se han gastado en ese curso viene
de mis impuestos, pero también de los impuestos de otros. Yo no tengo
inconveniente en derrochar mi dinero, pero me sabe muy mal derrochar
el de los demás.
</p>

<p>
Sin embargo, una vez comenzado el curso ya no podía arrepentirme y
cederle la plaza a alguien que lo aprovechara profesionalmente más que
yo.  Alguien que se dedique a la <i>seguridad informática</i> o temas
similares. Además, los contenidos me gustan una barbaridad, así que
tiré para adelante sin mirar a los lados, aún sin tener claro para qué
puedo utilizar esa certificación yo --aparte de que otra gente tenga
la certeza de los conocimientos que poseo, aún siendo psicólogo--.
</p>
</div>
</div>
<div id="outline-container-orgb3e1f5f" class="outline-2">
<h2 id="orgb3e1f5f">Resumen</h2>
<div class="outline-text-2" id="text-orgb3e1f5f">
<p>
Supongo que la forma más directa de resumir todo esto es contestar a
la pregunta <i>¿Merece la pena hacer el curso?</i>... y me encuentro con un
dilema ético. Por un lado sí, porque me lo he pasado como un enano en
las prácticas. Pero por otro no es más que sostener un chiringuito
pseudo formativo cuyo objetivo claro no es nada más que hacer caja por
todo y además en $ y no en €.
</p>

<p>
Al final, sigo sin saber qué hacer con la certificación, pero oye: <i>la
tengo</i>.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Instituto Aragonés de Empleo 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2019/06/27/sin-saber-que-hacer.html</link>
  <pubDate>Thu, 27 Jun 2019 09:41:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Impresión sobre el curso CEH]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-05-27</div>
<p>
Ya conté que estaba haciendo un curso de <i>hacking ético</i>, pagado por
el INAEM y subvencionado con fondos europeos.  Las clases presenciales
acabaron la semana pasada, pero aún me queda el examen de
certificación que será entre el día 24 y el 26 de junio.  El examen...
Bueno, le tengo algo de miedo al examen: aunque sea <i>tipo test</i> es en
inglés y hay que conseguir un 75% mínimo para conseguir la
certificación. Un compañero del curso preguntó para examinarse en
otras fechas porque le venía mal la fecha y le pedían unos 1200$ (sí,
en dólares) por el examen. Y pensé: <i>¡uff! ¡qué de pasta!</i> y a partir
de ese momento mi «síndrome del impostor» se vio aún más acentuado.
</p>

<p>
Cuando solicité el curso me pidieron hacer un examen y entregar
currículo. No salí muy convencido de allí: había mucha gente y las
plazas eran pocas. Mientras esperaba para entrar escuchaba
conversaciones sobre administración de sistemas, seguridad informática
y todas esas cosas que yo ignoro. El caso es que <i>yo aprobé y he hecho
el curso</i> y de vez en cuando me lo recuerdo cuando aprieta el <i>ánimo
de impostor</i> para bajarme la moral. A estas alturas: <i>que me quiten lo
bailao</i>, el curso ya lo he hecho.
</p>

<p>
Los laboratorios han sido lo mejor: abrir los ojos sobre lo inseguro
que es tener un ordenador conectado a Internet. Se hacían en una red
virtual con un montón de máquinas virtuales, todo muy <i>virtual</i> porque
algunas de las cosas que se hacen están <i>muy prohibidas</i> legalmente
(no sabía que la legislación española prohíbe la <i>inyección de SQL</i> y
algunas cosas más). No deja de ser curioso porque <i>sufrimos</i> un ataque
de <i>iSQL</i> en el <i>wiki</i> que monté para compartir apuntes entre
nosotros. Era un sitio cerrado, que seguimos compartiendo, con
nuestros esquemas y enlaces a otra información, como legislación
española y esas cosas. Una mañana aparecieron cientos de intentos de
rellenar el formulario de alta en el <i>wiki</i> intentando inyectarle algo
de SQL. Supongo que sería algún <i>Script Kiddie</i> que lo encontró por
casualidad, pero hay que ser muy torpe para intentar un <i>iSQL</i> contra
una <i>aplicación web</i> que no utiliza SQL. Hay mucho impresentable por
ahí suelto con acceso a herramientas que disparan automáticamente a
todo lo que se menea, tenga sentido o no.
</p>

<p>
Ahora me toca estudiar y tengo mucho que estudiar: el temario son
miles de páginas en perfecto inglés y aunque tengo un mes para
estudiar tengo la sensación de estar preparando un final.  Por este
motivo quizá estas semanas que faltan hasta el examen escriba poco en
el <i>blog</i>, pero después prometo retomar el ritmo e ir publicando más
cosas. De momento os dejo una foto del título que asegura que he hecho
60 horas y que las he aprovechado:
</p>


<figure id="org7ed6a65">
<img src="./imagen/foto-titulo-ceh-inaem.png" alt="foto-titulo-ceh-inaem.png">

</figure>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2019/05/27/impresion-sobre-el-curso-ceh.html</link>
  <pubDate>Mon, 27 May 2019 17:07:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[NTFS Streams o cómo ocultar información sensible al usuario]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-05-11</div>
<p>
Estos días en el curso sobre <i>hacking</i> que ando haciendo uno de los
laboratorios consistía en ocultar un <i>rootkit</i> al usuario estándar de
<i>windows</i> ─bueno, al estándar y al no estándar, porque a estas alturas
creo que abren la consola una, o ninguna, vez al año─. Si hay algún
usuario de <i>windows</i> presente, le ruego que haga conmigo los
siguientes pasos:
</p>

<ol class="org-ol">
<li><b>Abrir una consola</b>. Es esa ventana negra con letras blancas... no
hay que asustarse, es así de fea sin <i>pichorros</i> ni <i>chismáticos</i>.
Si no la encontráis, en el buscador de la barra poned <code>cmd</code> y
aparecerá <i>automágicamente</i>.</li>

<li><p>
<b>Escribe los siguientes comandos</b>:
</p>

<pre class="example" id="org358a67e">
c:\&gt;notepad mifichero.txt:leon.txt
</pre>

<p>
Dale a <code>Aceptar</code> o a <code>Yes</code> y tendrás una ventana perfectamente
funcional de <code>notepad</code>. <code>notepad</code> es un editor de texto plano, por
si nunca lo has utilizado. Cuando escribas algo, cualquier cosa,
porque esto es una prueba de concepto, dale a <code>guardar</code>.
</p>

<p>
Siguiente paso:
</p>

<pre class="example" id="orgc94ad21">
c:\&gt;notepad mifichero.txt:tigre.txt
</pre>

<p>
Repite el mismo proceso que antes con <code>mifichero.txt:leon.txt</code>.
</p></li>

<li><b>Comprueba el tamaño del fichero <code>mifichero.txt</code></b>... ¿cómo? ¿es
cero? ¿y los contenidos que has escrito? Pues están ahí, sólo
tienes que abrir de nuevo con <code>notepad</code> los ficheros
<code>mifichero.txt:leon.txt</code> y <code>mifichero.txt:tigre.txt</code>.</li>
</ol>

<p>
¿A que es divertido? Lo bueno de todo es que no es un error de diseño,
es una característica buscada en <i>windows</i> vete tú a saber para qué.
</p>

<p>
El ejercicio que teníamos que hacer en el curso era algo más complejo:
consistía en ocultar un troyano en un fichero <code>Readme.txt</code> para
abrirnos una puerta trasera o <i>backdoor</i>.  Si alguien tiene
curiosidad, explotando esta <i>característica</i> de <i>windows</i> son tres
comandos ─una vez creados los ejecutables, claro─:
</p>

<pre class="example" id="org395f025">
C:\&gt;type c:\troyano.exe &gt; c:\Readme.txt:Troyano.exe
C:\&gt;mklink backdoor.exe Readme.txt:Troyano.exe
</pre>

<p>
Y luego para ejecutar el troyano oculto en <code>Readme.txt</code>:
</p>

<pre class="example" id="orgdfb4dee">
C:\&gt;backdoor
</pre>

<p>
Vale, se pueden ver los <i>NTFS Streams</i> tecleando <code>dir /r</code> en la
consola, pero como decía antes: ¿cuántos usuarios de <i>windows</i> se
plantean abrir una consola para ver qué ficheros hay en un directorio
(bueno, ellos ya lo llaman <i>carpeta</i>)? Como mucho uno o ninguno... y
así es <i>amigüitos</i> cómo los señores de <i>micro$oft</i> mantienen seguros
nuestros ordenadores, porque en ningún otro Sistema Operativo se puede
hacer algo tan tonto.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/seguridad/index.html">seguridad</a> <a href="/tags/windows/index.html">windows</a> ]]></description>
  <category><![CDATA[seguridad]]></category>
  <category><![CDATA[windows]]></category>
  <link>https://notxor.nueva-actitud.org/2019/05/11/ntfs-streams-o-como-ocultar-informacion-sensible-al-usuario.html</link>
  <pubDate>Sat, 11 May 2019 22:24:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Mis labores]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-05-08</div>
<p>
Hace ya días que tenía ganas de escribir por aquí, por el blog.  Es
posible que alguien haya pensado en abandono, pero ese no es mi caso.
Es sólo que ando ocupado con <i>mis labores</i>... y es que se me ocurren
cosas de <i>bombero torero</i> y ando arrastrando mis reales por ese
proceloso mundo sin tiempo para nada.  De hecho, estoy escribiendo
éste artículo con el remordimiento de <i>deberías estar estudiando</i>. Y
es cierto, debería estar estudiando.
</p>

<p>
Algunos, los que se tropiezan conmigo por esas redes, saben que
encontré un curso interesante del INAEM<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> que se llama <i>Certified
Ethical Hacker</i>. Eché los papeles y me presenté a la prueba: era un
examen de 20 preguntas (cuatro alternativas y los fallos descontaban
0,33 puntos). Cuando vi la cantidad de informáticos que allí estaban
pensé que no iba a sacar plaza: conté más de cien y sólo había 32
plazas (16 por la mañana y 16 por la tarde). Contesté quince de las
veinte y pensé que no entraba. Había preguntas sobre redes,
criptografía, administración de Windows y administración de GNU/Linux
(adivinad cuáles dejé en blanco). Pero he aquí, que contra todo
pronóstico fui seleccionado. Aún me pregunto cómo ─hay quien me dice
que tengo el <i>síndrome del intruso</i>; a mí me gustaría darle la razón,
pero no es <i>síndrome</i> si eres, de verdad, un <i>intruso</i> real─.
</p>

<p>
El caso es que tengo que estudiar (<i>mucho</i>), porque tengo que
compensar lo que se da por supuesto en el curso y que a mí me falta,
un poquito.  También tengo que estudiar más, porque toda la
documentación (y el examen) está en inglés. También tengo que
estudiar, porque la documentación está cifrada, no con <i>DRM</i>, sino
cifrada de verdad y no hay lector para GNU/Linux que lo descifre... lo
tengo que leer en el móvil y hacerme un resumen.  <a href="https://www.eccouncil.org/wp-content/uploads/2016/07/CEHv10-Brochure.pdf">Se puede ver que el
curso en cuestión</a> es, <i>a priori</i>, muy interesante.
</p>

<p>
El caso es que he empezado el curso y aunque estoy siguiéndolo en
presencial y me entero de las explicaciones y hago los laboratorios
sin perderme (<i>demasiado</i>), o al menos eso creo, tengo que estudiar
(<i>mucho</i>). Así que hasta después del examen, no creo que pueda
escribir mucho por aquí. Intentaré escaparme aunque supongo que según
se acerque el fatídico día lo podré hacer menos, crecerán los nervios
y el <i>síndrome del intruso</i> se disparará aún más.
</p>

<p>
Es posible que amplíe los temas que trato en este <i>blog</i> y también me
dé por escribir algo sobre seguridad con las cuatro cosas que termine
aprendiendo. Así que nada, avisados estáis.
</p>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>INstituto Aragonés de EMpleo</i>. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2019/05/08/mis-labores.html</link>
  <pubDate>Wed, 08 May 2019 22:01:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Presentaciones con org-beamer-mode]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-04-29</div>
<p>
Ya hablé de <a href="https://notxor.nueva-actitud.org/blog/2019/04/07/ventajas-del-texto-plano/">cómo me apaño para tener todo en modo texto</a> y uno de los
apartados sobre el que pasé muy por encima fue el de hacer
presentaciones en modo texto. Aprovechando que el día 12 tengo una
charla para la Asociación con quien colaboro, me he decidido a
escribir un poco y mostrar la presentación que he preparado para la
ocasión.
</p>
<div id="outline-container-orgd8fe2c3" class="outline-2">
<h2 id="orgd8fe2c3">Generando la presentación</h2>
<div class="outline-text-2" id="text-orgd8fe2c3">
<p>
El modo <code>org-beamer-mode</code> de <i>Emacs</i> es un <i>modo menor</i> que debemos
cargar cuando queramos hacer una presentación desde <code>org-mode</code>.
Básicamente lo que hace es añadir algunas facilidades al modo
principal y también los pichorros de exportación.
</p>

<p>
Si estás acostumbrado a utilizar directamente <i>Beamer</i> para generar
esas presentaciones, también lo puedes hacer modificando el archivo
<i>LaTeX</i> en lugar de el <code>org</code>. Sin embargo, me detendré a explicarlo
desde el formato de <i>Emacs</i>.
</p>

<p>
Si alguien quiere descargarse el fichero completo,
<a href="./archivo/redes-sociales.html">lo puede encontrar junto a este artículo</a>.
</p>
</div>
<div id="outline-container-org5feb355" class="outline-3">
<h3 id="org5feb355">Cabecera</h3>
<div class="outline-text-3" id="text-org5feb355">
<p>
Hay que recordar que es necesario cargar el modo <code>org-beamer-mode</code>
para tener acceso a todas las opciones de <i>Beamer</i>. Para que lo haga
automáticamente <i>Emacs</i> podemos añadir a la cabecera una línea que 
contenga <code>#+STARTUP: beamer</code>.
</p>

<p>
En la cabecera, las líneas más importantes son <code>LATEX_CLASS</code> y sus
opciones en <code>LATEX_CLASS_OPTIONS</code>: en nuestro caso <code>beamer</code> y
<code>[presentation]</code>. Esas dos líneas se convertirán en el fichero <code>tex</code>
generado en:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6; font-weight: bold;">\documentclass</span>[<span style="color: #f8f8f2; font-weight: bold;">presentation</span>]{<span style="color: #50fa7b; font-weight: bold;">beamer</span>}
</pre>
</div>

<pre class="example" id="orga5c7b24">
#+TITLE: Redes Sociales
#+AUTHOR: Notxor
#+DATE: 2019-05-12
#+OPTIONS: H:2 toc:nil num:t notes:t
#+LATEX_CLASS: beamer
#+LATEX_CLASS_OPTIONS: [presentation]
</pre>

<p>
Para modificar el aspecto se utiliza algún tema de <i>Beamer</i>. <a href="http://www.deic.uab.es/~iblanes/beamer_gallery/index_by_theme.html">Siempre
es bueno echar un ojo a las opciones</a> con las que podemos jugar. En mi
caso he utilizado el <i>theme</i> que se llama <code>Madrid</code>, pero lo he
personalizado a mi manera para cambiarle los colores: el fondo, las
cabeceras, los bloques, etc.
</p>

<pre class="example" id="org180c2a0">
#+BEAMER_THEME: Madrid
</pre>

<p>
Para la personalización sólo hay que encabezar cada una de las
siguientes líneas con su correspondiente <code>LATEX_HEADER</code>:
</p>

<div class="org-src-container">
<pre class="src src-latex"><span style="color: #ff79c6;">\usecolortheme</span>[RGB={20,20,20}]{structure}
<span style="color: #ff79c6;">\definecolor</span>{AmarilloClaro}{RGB}{250,250,150}
<span style="color: #ff79c6;">\beamertemplateshadingbackground</span>{yellow!50}{AmarilloClaro!50}
<span style="color: #ff79c6;">\setbeamertemplate</span>{blocks}[rounded][shadow=true]
<span style="color: #ff79c6;">\setbeamercolor</span>{title}{fg=yellow}
<span style="color: #ff79c6;">\setbeamercolor</span>{frametitle}{fg=yellow}
<span style="color: #ff79c6;">\setbeamercolor</span>{blockhead}{fg=yellow}
<span style="color: #ff79c6;">\institute</span>[PICA]{Protecci&#243;n a la Infancia Contra el Abuso}
<span style="color: #ff79c6;">\logo</span>{<span style="color: #ff79c6;">\includegraphics</span>[width=1cm]{escudo-pica.png}}
</pre>
</div>

<p>
Una de las manías que tiene el <code>org-beamer-mode</code> cuando genera el
documento es llamar <i>Outline</i> a los contenidos; por eso los desactivo
en <code>OPTIONS</code> poniendo <code>toc:nil</code> y luego los genero con:
</p>

<pre class="example" id="org979b143">
#+BEAMER: \begin{frame}{Contenidos}
#+BEAMER: \tableofcontents
#+BEAMER: \end{frame}
</pre>

<p>
Como se puede apreciar, se puede introducir cualquier comando y
<code>#+BEAMER:</code> se convierte en un sinónimo de <code>#+LATEX:</code>.
</p>

<p>
La última línea de la cabecera es una de las opciones que nos
proporciona <code>org-mode</code> para definir las columnas en las que se
mostrarán las propiedades si queremos:
</p>

<pre class="example" id="orgfc9cc39">
#+COLUMNS: %40ITEM %10BEAMER_env(Env) %9BEAMER_act(Act) %4BEAMER_col(Col) %10BEAMER_extra(Extra)
</pre>

<p>
Así, por ejemplo, si dejamos la visualización como se muestra por
defecto, veremos el documento de la siguiente manera:
</p>


<figure id="orga172117">
<img src="./imagen/visor-sin-columnas.png" alt="visor-sin-columnas.png">

</figure>

<p>
Sin embargo, para visualizar los datos de una manera más rápida suelo
activar el modo de visualización de columnas con <code>C-c C-x C-c</code> o lo
que es lo mismo, el comando <code>org-columns</code>:
</p>


<figure id="org834e30d">
<img src="./imagen/visor-con-columnas.png" alt="visor-con-columnas.png">

</figure>

<p>
Si nos estorban las columnas y la queremos desactivar utilizamos el
comando <code>org-columns-quit</code> y volvemos al modo normal.
</p>
</div>
</div>
<div id="outline-container-org65d149a" class="outline-3">
<h3 id="org65d149a">Las transparencias con bloques</h3>
<div class="outline-text-3" id="text-org65d149a">
<p>
El tema de las transparencias es sencillo cuando se entiende. En la
cabecera hemos definido en las opciones <code>H:2</code>, lo cual quiere decir
que las cabeceras principales son 2. Las de primer nivel marcarán los
apartados dentro de la charla y luego, las de segundo nivel definen
cada transparencia. Es decir, al exportar la presentación, las de
primer nivel se traducirán por <code>\section</code> mientras que las de segundo
nivel crearán un entorno <code>frame</code>; esto es: una <i>transparencia</i>.
</p>

<p>
Las entradas de tercer nivel y posteriores, son partes de una
transparencia. Se controlan mediante las propiedades de cada
cabecera. Por ejemplo, si tenemos el siguiente código:
</p>

<pre class="example" id="org40d923f">
*** Cabecera
    :PROPERTIES:
    :BEAMER_ACT: &lt;2-&gt;
    :BEAMER_ENV: block
    :END:
Esto es un texto
</pre>

<p>
El <i>Emacs</i> generará el siguiente código <i>LaTeX</i>:
</p>

<p>
En <code>beamer_env</code> pueden ir las opciones <code>block</code>, <code>alert</code>, <code>example</code> o
<code>note</code>. El contenido que se encuentre en una cabecera marcada como
<code>note</code>, no aparecerá en la presentación (a no ser que se fuerce) sino
que se visualizará con la herramienta que tenga capacidades para
mostrar las anotaciones durante la presentación.
</p>
</div>
</div>
<div id="outline-container-org6e55068" class="outline-3">
<h3 id="org6e55068">Uso de columnas</h3>
<div class="outline-text-3" id="text-org6e55068">
<p>
Las transparencias también se pueden usar dividiéndolas en columnas y
cada columna puede contener cualquier tipo de contenido, incluso un
bloque. Por ejemplo, para tener una transparencia con un gráfico y un
texto explicativo, podríamos utilizar el siguiente código:
</p>

<pre class="example" id="org76eab2d">
** Título de la transparencia
*** Imagen
    :PROPERTIES:
    :BEAMER_COL: 0.48
    :END:
[[fichero-de-imagen]]
*** Texto                            :B_block:
    :PROPERTIES:
    :BEAMER_ENV: block
    :BEAMER_COL: 0.48
    :END:
Este es el texto explicativo de la imagen.
*** Notas                            :B_note:
    :PROPERTIES:
    :BEAMER_ENV: Note
    :END:
Aquí puedes escribir lo que quieras y se corresponderá con las anotaciones
para la transparencia
</pre>

<p>
Como se puede apreciar, dentro de la columna también se pueden
utilizar las estructuras de bloque.
</p>
</div>
</div>
<div id="outline-container-org4f1dfba" class="outline-3">
<h3 id="org4f1dfba">Presentación de una transparencia por partes</h3>
<div class="outline-text-3" id="text-org4f1dfba">
<p>
Es habitual en las presentaciones que no se muestre toda la
información de un golpe. Sobre todo en las listas es muy frecuente que
cada elemento o grupo de elementos se muestren de forma escalonada.
</p>

<p>
Si utilizamos bloques, por ejemplo, podemos utilizar una propiedad
<code>beamer_act</code> para seleccionar el cuándo estará visible una parte de la
transparencia. Lo normal es que la información esté oculta hasta que
se muestra y permanezca visible hasta el final de la visualización,
para eso utilizaremos una estructura <code>&lt;3-&gt;</code>, por ejemplo, que mostrará
el ítem que afecte desde el tercer paso hasta el final. Si nos
interesara que se mostrara sólo en determinados pasos podríamos
utilizar el formato <code>&lt;2,5&gt;</code> que mostrará la información sólo durante
los pasos 2 y 5. Si utilizamos el formato <code>&lt;2-4&gt;</code> mostrará la
información los pasos del 2 al 4.
</p>

<p>
Podemos utilizarlo en una cabecera como hemos visto antes, pero
también lo podemos hacer en una simple lista colocando delante de ella
sin ninguna línea en blanco entre <code>#+ATTR_BEAMER: overlay &lt;+-&gt;</code> y el
primer guión. Por ejemplo:
</p>

<pre class="example" id="org6ba7a60">
#+ATTR_BEAMER: :overlay &lt;+-&gt;
- El primer elemento
- El segundo elemento
- El tercer elemento
</pre>

<p>
Sin embargo, veremos que cuando se cargue la <i>transparencia</i> será
visible el primer elemento de la lista, lo que nos puede resultar
inconveniente. Si queremos controlar cuándo se mostrará cada elemento,
podemos utilizar el <i>marcado en línea</i>. El código quedará como sigue:
</p>

<pre class="example" id="orgb4e6883">
#+ATTR_BEAMER: :overlay &lt;+-&gt;
- @@beamer:&lt;2-&gt;@@ El primer elemento
- @@beamer:&lt;3-&gt;@@ El segundo elemento
- @@beamer:&lt;4-&gt;@@ El tercer elemento
</pre>
</div>
</div>
</div>
<div id="outline-container-orge593149" class="outline-2">
<h2 id="orge593149">Presentación por pantalla</h2>
<div class="outline-text-2" id="text-orge593149">
<p>
Una vez que tenemos nuestra presentación preparada es el momento de
generarla y mostrarla por pantalla. El comando de exportación es <code>C-c
C-e l P</code>  para generar el fichero <code>pdf</code> que contiene nuestro flamante
trabajo.
</p>

<p>
Muchos visores de documentos <code>pdf</code> tienen, a estas alturas, un modo
<i>presentación</i>. Algunos, como <i>Okular</i>, permiten dibujar en la
transparencia según está proyectándose, activar las <i>transiciones</i> y
efectos. En los ordenadores de otros, normalmente se encuentra
instalado el <i>Acrobat reader</i> y también permite esas opciones. Sin
embargo, cuando utilizo mi ordenador, normalmente, suelo lanzar dos
aplicaciones para la línea de comandos: <i>Impressive</i> y <i>pdfpc</i>.
</p>
</div>
<div id="outline-container-orgce5a285" class="outline-3">
<h3 id="orgce5a285">Impressive</h3>
<div class="outline-text-3" id="text-orgce5a285">
<p>
Básicamente, <i>Impresive</i> es una aplicación que utiliza <code>mupdf</code> como
<i>rederer</i> de <code>pdf</code>, visualizando los resultados con la librería de
<i>Python</i>, <code>pygame</code>. Sin embargo, tiene algunas opciones que son
bastante resultonas cuando lo utilizas para presentar el trabajo.
Entre ellas la posibilidad de establecer transiciones entre las
transparencias es destacable porque las hace muy bien.
</p>

<p>
Durante la presentación puedes utilizar una serie de comandos que te
facilitan las cosas:
</p>

<dl class="org-dl">
<dt>q</dt><dd>Sale de la presentación.</dd>
<dt>Tab</dt><dd>muestra todas las transparencias en miniatura para poder
seleccionar la que quieres.</dd>
<dt>f</dt><dd>Cambia el modo de pantalla completa.</dd>
<dt>t</dt><dd>Muestra u oculta el tiempo en una esquina de la pantalla</dd>
<dt>enter</dt><dd>Muestra un círculo entorno al cursor del ratón mientras
difumina el resto de la transparencia para centrar la
atención en lo que quieres remarcar.</dd>
<dt>z</dt><dd>activa y desactiva el modo <i>zoom</i>.</dd>
</dl>

<p>
También se pueden remarcar zonas de una transparencia con el ratón, e
incluso se puede guardar la información de esas cajas pulsando la
tecla <code>s</code> para que la próxima vez que se utilice esa presentación, las
cajas ya estén cargadas.
</p>

<p>
He mencionado las opciones más habituales, pero tiene muchas opciones
más y es una lista muy larga, por lo que remito a quien quiera ampliar
la referencia <a href="http://impressive.sourceforge.net/">a su página web para explorar todas esas opciones</a>.
</p>
</div>
</div>
<div id="outline-container-org22fc34b" class="outline-3">
<h3 id="org22fc34b">pdfpc</h3>
<div class="outline-text-3" id="text-org22fc34b">
<p>
Esta herramienta está basada en las librerías <code>GTK</code> para realizar las
presentaciones. En este caso, tiene visualización con dos monitores y
también puede reproducir vídeo incrustado en la presentación. Permite
la visualización de las notas incrustadas y hacer nuevas anotaciones
que se guardarán en un fichero de texto con extensión <code>pdfpc</code>.
</p>

<p>
<a href="https://pdfpc.github.io/">Remito a su página web</a> para investigar todas las opciones con las que
viene esta herramienta. De todas ellas, las que más utilizo son las
siguientes:
</p>

<dl class="org-dl">
<dt>8</dt><dd>activa y desactiva el modo láser para remarcar cosas en la
pantalla.</dd>
<dt>5</dt><dd>activa y desactiva el modo dibujo para dibujar directamente
sobre la transparencia.</dd>
<dt>6</dt><dd>Borra el dibujo.</dd>
<dt>2</dt><dd>Alterna entre el borrador y el lápiz de dibujo.</dd>

<dt>b</dt><dd>Apaga la pantalla de presentación, la pone en negro. Muy útil
cuando alternamos entre una presentación y una pizarra.</dd>
<dt>h</dt><dd>Oculta la ventana de presentación y nos permite utilizar otras
aplicaciones y herramientas.</dd>
<dt>f</dt><dd>Congela la pantalla de presentación, lo que nos permite buscar
entre las transparencia la que queremos sin marear al
personal.</dd>
<dt>Tab</dt><dd>Muestra una miniatura de todas las transparencias para poder
seleccionar la que queremos.</dd>
<dt>S</dt><dd>Guardar la sesión actual. Guarda en el fichero con extensión
<code>pdfpc</code> la transparencia en la que estamos.</dd>
<dt>R</dt><dd>Restaura la última sesión guardada.</dd>
</dl>

<p>
Esta herramienta es mejor cuando trabajamos con un proyector, pero si
vamos a utilizar sólo la pantalla del ordenador para realizar la
presentación, es mejor utilizar <i>impressive</i>.
</p>
</div>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2019/04/29/presentaciones-con-org-beamer-mode.html</link>
  <pubDate>Mon, 29 Apr 2019 23:32:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Una hoja de cálculo con sus celdas en mi Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-04-21</div>
<p>
He aprovechado la Semana Santa para desconectar en el pueblo, con su
olor a campo y a leña quemada en el hogar. La intención era haberme
movido algo más, salir a pasear al campo o a la anual recolecta de
espárragos o cardillos. Sin embargo, la climatología tenía otros
planes y me ha tenido en casa encerrado. Ya le hacía falta al campo un
poco de agua, pero a mí no hacía falta regarme, no voy a crecer
estando ya agostado... En fin, a lo que iba. Que como he tenido tiempo
estuve cotilleando un modo de <i>Emacs</i> que me había comentado alguien a
raíz de <a href="https://notxor.nueva-actitud.org/blog/2019/04/07/ventajas-del-texto-plano/">mi artículo sobre el uso del texto plano</a> y que hasta ahora no
había probado.
</p>
<div id="outline-container-org8fbf423" class="outline-2">
<h2 id="org8fbf423">Utilizando una hoja de cálculo SES</h2>
<div class="outline-text-2" id="text-org8fbf423">
<p>
En ese artículo comentaba que utilizo las <i>tablas</i> de <code>org-mode</code> como
si de hojas de cálculo se tratasen y la verdad es que dan bastante
juego para editar, calcular e imprimirlas en nuestros documentos; o
incluso para realizar gráficos desde ellas con <code>gnuplot</code>. Al poco de
publicar aquel artículo, alguien me habló del modo <code>SES</code><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> que
viene por defecto con nuestro querido <i>Emacs</i>.
</p>

<p>
La diferencia fundamental con el uso de las <i>tablas</i> de <code>org-mode</code> es
que <code>SES</code> monta un <i>buffer</i> especial que se ordena en filas y columnas
como lo hace una hoja de cálculo al uso... Pero no esperéis grandes
cosas: lo de <i>Simple</i> que lleva en el nombre no es por falsa modestia.
Es todo muy sencillo y muy básico. Voy a hacer un ejemplo, bastante
similar al que viene en la documentación de <code>SES</code> pero luego lo
destriparé un poco más para ver cómo funciona el formato.
</p>

<p>
Imaginemos que lo he utilizado para controlar algunos gastos de esta
<i>Semana Santa</i> y me he hago una tabla como sigue:
</p>

<ol class="org-ol">
<li>Crear ─o visitar─ mediante <code>C-x C-f</code> un archivo que se va a llamar
<code>gastos.ses</code>: hay que observar que la extensión <code>.ses</code> es
importante para que <i>Emacs</i> entre en modo <code>SES</code>. Al hacerlo me
encuentro un <i>buffer</i> casi vacío con una etiqueta <code>A</code> y una zona
subrayada, con el cursor allí situado... nuestra hoja sólo tiene,
de momento, una celda: la <code>A1</code>. Si observamos la línea de estado,
nos mostrará en qué celda está situado el cursor... ¡seguimos!</li>
<li>Pulso <code>"</code>, las comillas dobles, y me pregunta por una <i>cadena de
texto</i>. Escribo <code>Concepto</code> y de nuevo <code>&lt;RET&gt;</code>. Ahora en la celda
<code>A1</code> aparece el texto <code>Concept</code>, no nos cabe todo ello en una celda
de 7 caracteres.</li>
<li>Pulso <code>&lt;TAB&gt;</code> y vemos que aparece una etiqueta para la columna
<code>B</code>. El cursor se sitúa en la celda <code>B1</code>. De nuevo, para introducir
una cadena pulso la tecla <code>"</code> y escribo <code>Cantidad</code>, cuando me lo
pregunta.</li>
<li>Como también me lo corta, vamos a dimensionar la columna pulsando
<code>w</code> (<i>width</i>), y cuando pregunta le doy <code>10</code> de ancho.</li>
<li>Me sitúo de nuevo en la columna <code>A</code> y la dimensiono, también con
<code>w</code> a 25.</li>
<li>Al pulsar <code>&lt;RET&gt;</code> en cualquiera de las celdas, nos muestra en el
<i>minibuffer</i> su contenido y podemos editarlo.</li>
<li>Bajo una línea con <code>C-n</code>, o la flecha abajo, y el cursor parece
haberse salido de la tabla. Pulso <code>C-o</code> para insertar otra línea de
celdas. El cursos se nos ha situado en la casilla <code>A2</code> y podemos
empezar a meter un <i>concepto</i>, como hemos hecho antes con las dos
celdas anteriores. Por ejemplo, <i>Refrescos en el bar</i>.</li>
<li>Pulso <code>&lt;TAB&gt;</code> y el cursos se sitúa en la celda <code>B2</code>. Ahora voy a
introducir un número y la cosa cambia: hay que pulsar <code>=</code>.</li>
</ol>

<p>
Bien ahora hay que repetir el proceso para crear todas las <i>filas</i>
que necesite, hasta crear algo parecido a lo siguiente:
</p>

<pre class="example" id="org9425573">
A                        B
                Concepto   Cantidad
     Refrescos en el bar       7.25
   Comida en restaurante       35.8
             Combustible      52.15
              ---------- ----------
                   Total __________
</pre>

<p>
Bien, ya tenemos algunos valores en nuestra tabla: ¿Cómo los sumamos?
Pues metiendo en la celda donde irá el total una expresión <i>elisp</i> que
haga la suma: <code>(+ B1 B2 B3)</code>. Nos arroja un valor de <code>95.2</code>... pero
queremos cambiarle el formato, para que nos lo dé de manera más
legible. Al pulsar <code>M-p</code> nos dice que el formato de columna es <code>nil</code>,
así que introducimos <code>"%.2f€"</code> y el resultado será algo así:
</p>

<pre class="example" id="orgadfc1d8">
A                        B
                Concepto   Cantidad
     Refrescos en el bar      7.25€
   Comida en restaurante     35.80€
             Combustible     52.15€
              ---------- ----------
                   Total     95.20€
</pre>

<p>
Como se puede apreciar, con <code>M-p</code> se modifica el formato de toda la
columna, si queremos cambiar sólo algunas de las celdas también lo
podemos hacer pulsando <code>p</code> en cada una de las que queremos afectar.
</p>

<p>
Para el cálculo, también hubiéramos podido utilizar un <i>rango</i> de
celdas que sumar. Lo haríamos mediante la fórmula <code>(apply '+
(ses-range B2 B4 !))</code>. El símbolo <code>!</code> hace que de la lista de celdas
devueltas por <code>ses-range</code>, se eliminen las que estén vacías.
</p>

<p>
En general, para introducir contenidos en las celdas vemos que se
pueden utilizar diversos caracteres:
</p>

<dl class="org-dl">
<dt>«0..9»</dt><dd>Pulsar sobre cualquier número hace que se ponga en modo
<code>ses-read-cell</code>, utilizando un número.</dd>
<dt>«-»</dt><dd>Para introducir un número negativo.</dd>
<dt>«.»</dt><dd>Para introducir una fracción decimal.</dd>
<dt>«"»</dt><dd>Para introducir una cadena.</dd>
<dt>«(»</dt><dd>Para introducir una expresión o fórmula.</dd>
<dt><code>&lt;RET&gt;</code></dt><dd>Editar el contenido de la celda.</dd>
<dt><code>C-c C-c</code></dt><dd>Recalcular el contenido de la celda (o el rango
marcado).</dd>
<dt><code>C-c C-l</code></dt><dd>Recalcular la hoja entera.</dd>
</dl>

<p>
Otras teclas sirven para redimensionar la hoja:
</p>

<dl class="org-dl">
<dt><code>C-o</code></dt><dd>Insertar una fila.</dd>
<dt><code>M-o</code></dt><dd>Insertar una columna.</dd>
<dt><code>C-k</code></dt><dd>Eliminar una fila.</dd>
<dt><code>M-k</code></dt><dd>Eliminar una columna.</dd>
<dt><code>&lt;TAB&gt;</code></dt><dd>Se mueve a la siguiente columna, si hay una, o añade una
columna si está el cursor en la última.</dd>
</dl>

<p>
No voy a mostrar muchas más opciones que hay, porque la ayuda está
suficientemente clara. Además se pueden utilizar otras muchas teclas y
combinaciones de las habituales de <i>Emacs</i>.
</p>

<p>
También se pueden poner nombres a algunas celdas, para utilizarlos en
fórmulas o como enlace para saltar a ellas. O cambiar la línea de
cabecera, que normalmente muestra letras como nombres para las
columnas.
</p>
</div>
</div>
<div id="outline-container-org7a3c6f4" class="outline-2">
<h2 id="org7a3c6f4">¿Cómo funciona?</h2>
<div class="outline-text-2" id="text-org7a3c6f4">
<p>
El contenido del fichero cuando lo abrimos con otro editor de texto
que no sea <i>Emacs</i> es el siguiente.
</p>

<pre class="example" id="orgaa39aa3">
                 Concepto   Cantidad
      Refrescos en el bar      7.25€
    Comida en restaurante     35.80€
              Combustible     52.15€
               ---------- ----------
                    Total     95.20€



(ses-cell A1 "Concepto" nil nil nil)
(ses-cell B1 "Cantidad" nil nil nil)

(ses-cell A2 "Refrescos en el bar" nil nil nil)
(ses-cell B2 7.25 nil nil (B6))

(ses-cell A3 "Comida en restaurante" nil nil nil)
(ses-cell B3 35.8 nil nil (B6))

(ses-cell A4 "Combustible" nil nil nil)
(ses-cell B4 52.15 nil nil (B6))

(ses-cell A5 "----------" nil nil nil)
(ses-cell B5 "----------" nil nil nil)

(ses-cell A6 "Total" nil nil nil)
(ses-cell B6 95.19999999999999 (apply (quote +) (ses-range B2 B4 !)) nil nil)

(ses-column-widths [25 10])
(ses-column-printers [nil "%.2f€"])
(ses-default-printer "%.7g")
(ses-header-row 0)

( ;Global parameters (these are read first)
 2 ;SES file-format
 6 ;numrows
 2 ;numcols
)
</pre>

<p>
Como se puede observar, las primeras líneas del fichero se
corresponden a la visualización que tenemos de nuestra hoja y tras una
línea en blanco, otra que contiene <code>^L</code>, como marca de separación,
viene una serie de definiciones de celdas. Si tomamos, por ejemplo la
expresión:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(ses-cell B2 7.25 nil nil (B6))
</pre>
</div>

<p>
Ahí, se define la celda <code>B2</code>, con un contenido <code>7.25</code>. El siguiente
valor <code>nil</code> se refiere a la fórmula para calcular el contenido (en
nuestro caso es <code>nil</code> porque no hay ninguna fórmula). El siguiente
valor <code>nil</code> se refiere a que esa celda no tiene asignada ninguna
cadena de formato. Lo definimos para la columna entera y por tanto lo
encontramos en la expresión <code>ses-column-printers</code> más adelante. El
último valor <code>(B6)</code> es una lista de las celdas que se verían afectadas
por un cambio en el valor de la celda.
</p>
</div>
</div>
<div id="outline-container-orgb319780" class="outline-2">
<h2 id="orgb319780">Conclusión</h2>
<div class="outline-text-2" id="text-orgb319780">
<p>
El sistema <code>SES</code> es muy sencillo, como se puede ver. Tiene a su favor
que nos movemos por filas y columnas como lo haríamos en una hoja de
cálculo convencional; que podemos utilizar cualquier expresión válida
de <i>elisp</i> en el contenido de una celda para calcular su contenido, lo
que le da una potencia enorme, a pesar de su sencillez.
</p>

<p>
Sin embargo, a la hora de presentar contenido integrado dentro de
documentos creo que seguiré utilizando las tablas de <code>org-mode</code>,
aunque sea más críptico el modo de uso o cómo se establecen las
fórmulas de las celdas a través de comentarios especiales, dan más
flexibilidad a la hora de <i>ajustarlas</i> a un documento, o hacer
gráficos con <code>gnuplot</code> a partir de las mismas.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Simple Emacs Spreadshet</i> o «Sencilla Hoja de Cálculo de Emacs».
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/ses/index.html">ses</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[ses]]></category>
  <link>https://notxor.nueva-actitud.org/2019/04/21/una-hoja-de-calculo-con-sus-celdas-en-mi-emacs.html</link>
  <pubDate>Sun, 21 Apr 2019 22:05:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Cómo trabajar con SQLite3 desde Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-04-12</div>
<p>
<a href="https://notxor.nueva-actitud.org/blog/2019/04/07/ventajas-del-texto-plano/">En mi último artículo</a> hablé de cómo trabajo en formato texto con
<i>Emacs</i> y son varios los que me han preguntado por el apartado de
<i>base de datos</i>. ¿Cómo me las apaño para tener las bases de datos de
SQLite en modo texto?
</p>

<p>
Lo primero es confesar que no tengo todas, sino sólamente aquellas que
quiero tener controladas en repositorios <code>git</code>. La otras las guardo en
el fichero de base de datos que genera <i>SQLite</i>, porque es más
sencillo y rápido acceder a los datos así. Pero aunque no las tenga en
formato de texto, sí hay consultas, en mi fichero de consultas, que
las referencias.
</p>

<p>
Para explicar mejor el proceso que sigo, voy a contar desde cero y
pondré también capturas de pantalla, paso a paso.
</p>
<div id="outline-container-org4fc85db" class="outline-2">
<h2 id="org4fc85db">Crear una base de datos</h2>
<div class="outline-text-2" id="text-org4fc85db">
<p>
Lo primero que hago es crear un fichero con el nombre que quiero ─en
el ejemplo lo llamaré <code>base-de-datos</code>, por ejemplo─ y le añado una
extensión <code>sql</code>. Al abrir este fichero, <i>Emacs</i> entrará en modo <code>SQL</code>,
y por defecto se colocará en modo <code>ANSI</code>.
</p>


<figure id="org51091ae">
<img src="./imagen/base-datos-vacia.png" alt="base-datos-vacia.png">

</figure>

<p>
Como se puede ver en la imagen, la barra de estado marca el modo
<code>SQL[ANSI]</code>, aunque el archivo aún está vacío. Lo primero es decirle
al editor que vamos a utilizar, concretamente <code>SQLite</code>. Para ello
utilizo el comando <code>M-x sql-set-product RET sqlite RET</code>.
</p>

<p>
Estando en el <i>buffer</i> del fichero <code>sql</code>, que permanece vacío, vamos a
levantar también un entorno interactivo para <code>SQLite</code> dentro de
<i>Emacs</i>: así no tenemos que estar entrando y saliendo del editor, sino
sólo cambiando de <i>buffer</i>. Para lanzarlo utilizo la combinación de
teclas <code>C-c TAB</code> también se podría llamar mediante <code>M-x
sql-product-interactive</code>. Al lanzarlo nos pide un nombre para la base
de datos, en mi ejemplo <code>base-de-datos.db</code> y nos mostrará el típico
<i>prompt</i> de <code>SQLite</code>.
</p>


<figure id="org79ef5e7">
<img src="./imagen/sqlite-lanzado.png" alt="sqlite-lanzado.png">

</figure>

<p>
Ahora podemos dar el siguiente paso en cualquier de los dos <i>buffers</i>
pero para mí resulta mucho más sencillo hacerlo directamente en el
interactivo de <code>SQLite</code>. Vamos a crear una <i>tabla</i> dentro de nuestra
base de datos.
</p>

<div class="org-src-container">
<pre class="src src-sql"><span style="color: #ff79c6; font-weight: bold;">CREATE</span> <span style="color: #ff79c6; font-weight: bold;">TABLE</span> <span style="color: #50fa7b; font-weight: bold;">Gente</span> (
    id       <span style="color: #8be9fd; font-style: italic;">integer</span> <span style="color: #ff79c6; font-weight: bold;">primary</span> <span style="color: #ff79c6; font-weight: bold;">key</span> autoincrement,
    Nombre   text,
    Telefono text);
</pre>
</div>

<p>
Y para que no esté vacía la base de datos, voy a añadir un par de
registros a esa tabla:
</p>

<div class="org-src-container">
<pre class="src src-sql"><span style="color: #ff79c6; font-weight: bold;">insert</span> <span style="color: #ff79c6; font-weight: bold;">into</span> Gente(Nombre, Telefono) <span style="color: #ff79c6; font-weight: bold;">Values</span>(<span style="color: #f1fa8c;">'Pepe'</span>, <span style="color: #f1fa8c;">'123456789'</span>);
<span style="color: #ff79c6; font-weight: bold;">insert</span> <span style="color: #ff79c6; font-weight: bold;">into</span> Gente(Nombre, Telefono) <span style="color: #ff79c6; font-weight: bold;">Values</span>(<span style="color: #f1fa8c;">'Juan'</span>, <span style="color: #f1fa8c;">'987654321'</span>);
</pre>
</div>

<p>
Bien, vamos a hacer una consulta y como me gusta ver las cosas
ordenadas, también añado los comandos <code>.mode column</code> y <code>.headers on</code>
para que se muestren las consultas, como por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-sql"><span style="color: #ff79c6; font-weight: bold;">SELECT</span> * <span style="color: #ff79c6; font-weight: bold;">FROM</span> Gente;
</pre>
</div>

<pre class="example" id="org5e7c6e8">
id          Nombre      Telefono  
----------  ----------  ----------
1           Pepe        123456789 
2           Juan        987654321
</pre>

<p>
Como vemos, hasta ahora hemos trabajado como si lo hiciéramos desde la
herramienta interactiva de <code>SQLite3</code>, y además tenemos dos ficheros,
la base de datos <code>db</code> con una <i>tabla</i> y dos <i>registros</i> y un fichero
<code>sql</code> vacío:
</p>


<figure id="org9db73be">
<img src="./imagen/crear-base-datos.png" alt="crear-base-datos.png">

</figure>
</div>
</div>
<div id="outline-container-org2387296" class="outline-2">
<h2 id="org2387296">Convertir la base de datos a texto</h2>
<div class="outline-text-2" id="text-org2387296">
<p>
Cuando tenemos la base de datos creada la podemos pasar a formato
texto desde el mismo <i>buffer</i> de <code>SQLite</code> con dos sencillos comandos:
</p>

<div class="org-src-container">
<pre class="src src-sql">.<span style="color: #ff79c6; font-weight: bold;">output</span> base-de-datos.<span style="color: #ff79c6; font-weight: bold;">sql</span>
.dump
</pre>
</div>

<p>
Esos dos comandos, primero lo que hacen es <i>dirigir</i> la salida de
<code>SQLite</code> al fichero <code>base-de-datos.el</code> y luego volcar toda la base de
datos (también soporta hacerlo por tablas). Si ahora recargamos el
fichero de texto, veremos lo siguiente:
</p>


<figure id="orgf9fef4d">
<img src="./imagen/volcado-texto.png" alt="volcado-texto.png">

</figure>

<p>
Ahora, podemos borrar el fichero binario de base de datos y trabajar
sólo con el <code>sql</code>. Por ejemplo, me he dejado un par de detalles que en
formato de texto se pueden modificar sobre la marcha. En nuestra base
de datos no tendría sentido tener teléfonos sin nombre, o nombres sin
teléfonos, así que debería haber marcado esos campos como <code>NOT
NULL</code>. Así, he modificado el fichero de texto para dejarlo como sigue:
</p>

<div class="org-src-container">
<pre class="src src-sql">PRAGMA foreign_keys=<span style="color: #ff79c6; font-weight: bold;">OFF</span>;
<span style="color: #ff79c6; font-weight: bold;">BEGIN</span> <span style="color: #ff79c6; font-weight: bold;">TRANSACTION</span>;
<span style="color: #ff79c6; font-weight: bold;">CREATE</span> <span style="color: #ff79c6; font-weight: bold;">TABLE</span> <span style="color: #50fa7b; font-weight: bold;">Gente</span> (
  id       <span style="color: #8be9fd; font-style: italic;">integer</span> <span style="color: #ff79c6; font-weight: bold;">primary</span> <span style="color: #ff79c6; font-weight: bold;">key</span> autoincrement,
  Nombre   text    <span style="color: #ff79c6; font-weight: bold;">not</span> <span style="color: #ff79c6; font-weight: bold;">null</span>,
  Telefono text    <span style="color: #ff79c6; font-weight: bold;">not</span> <span style="color: #ff79c6; font-weight: bold;">null</span>);
<span style="color: #ff79c6; font-weight: bold;">INSERT</span> <span style="color: #ff79c6; font-weight: bold;">INTO</span> Gente <span style="color: #ff79c6; font-weight: bold;">VALUES</span>(1,<span style="color: #f1fa8c;">'Pepe'</span>,<span style="color: #f1fa8c;">'123456789'</span>);
<span style="color: #ff79c6; font-weight: bold;">INSERT</span> <span style="color: #ff79c6; font-weight: bold;">INTO</span> Gente <span style="color: #ff79c6; font-weight: bold;">VALUES</span>(2,<span style="color: #f1fa8c;">'Juan'</span>,<span style="color: #f1fa8c;">'987654321'</span>);
<span style="color: #ff79c6; font-weight: bold;">DELETE</span> <span style="color: #ff79c6; font-weight: bold;">FROM</span> sqlite_sequence;
<span style="color: #ff79c6; font-weight: bold;">INSERT</span> <span style="color: #ff79c6; font-weight: bold;">INTO</span> sqlite_sequence <span style="color: #ff79c6; font-weight: bold;">VALUES</span>(<span style="color: #f1fa8c;">'Gente'</span>,2);
<span style="color: #ff79c6; font-weight: bold;">COMMIT</span>;
</pre>
</div>

<p>
Si borramos la base de datos binaria la podremos recargar desde ese
fichero de texto, generado antes. Vamos a hacer la prueba para
demostrar lo sencillo que es. Volvemos a lanzar el entorno interactivo
desde el <i>buffer</i> de nuestro código <code>sql</code> con <code>C-c TAB</code> y el nombre
del fichero, que podemos utilizar, que puede ser el mismo u otro. Una
vez hecho, si pedimos que nos muestre el <code>.schema</code> de la base de datos
nos dirá que está vacía, pero si desde nuestra base de datos en <code>sql</code>
le <i>lanzamos</i> el <i>buffer</i> con <code>C-c C-b</code> y volvemos a preguntar, ya
veremos nuestra estructura cargada.
</p>

<p>
Así mismo, si por algún casual una base de datos va a gestionarse
desde un entorno de base de datos, como puede ser <i>MariaDB</i> o
<i>PostgreSQL</i> o el cualquier otro que comprenda el <code>sql</code>, bastaría con
modificar mínimamente ese fichero para ajustarse a las idiosincrasias
de cada base de datos y convertirla con facilidad. Por eso es
recomendable que utilicemos siempre código <code>sql</code> lo más estándar
posible para facilitar luego la exportación de datos.
</p>
</div>
</div>
<div id="outline-container-org76e472d" class="outline-2">
<h2 id="org76e472d">Fichero para consultas</h2>
<div class="outline-text-2" id="text-org76e472d">
<p>
Ya he explicado un poco por encima cómo funciona el <i>Emacs</i> en modo
<code>sql</code>. En este caso sobre <code>SQLite3</code>, pero se puede conectar a un buen
puñado de bases de datos relacionales.
</p>

<p>
Además suelo tener en <i>«el cargador»</i> otro fichero que guarda código
para hacer determinadas consultas. La mayoría de esas consultas se
hacen sin cargar el entorno interactivo sin abrir el fichero <code>sql</code> y
es lo que mostré en el artículo anterior, por lo que no me extenderé
en ello demasiado. Por ejemplo:
</p>

<pre class="example" id="org1a99638">
#+begin_src elisp :export code
(require 'sqlite)
(let ((db (sqlite-init "~/proyectos/tutorial-sqlite/base-de-datos.db")))
  (sqlite-query db ".headers on")
  (setq resultado (sqlite-query db "select * from Gente"))
  (sqlite-bye db)
  resultado)
#+end_src

#+RESULTS:
| id | Nombre | Telefono   |
|  1 | Pepe   | 123456789  |
|  2 | Juan   | 987654321  |
</pre>

<p>
Guardarlo así me permite generar tablas complejas y que son devueltas
en un formato muy próximo al que puede gestionar <code>org-mode</code>. En el
ejemplo, puesto que se tratan de datos muy básicos y no hay datos
cruzados entre diferentes tablas, puede parecer innecesario. Sin
embargo, cuando la base de datos se complica y/o las consultas
implican varios <code>join</code> o necesitas trabajar los resultados de otra
forma, como llevarlos a un informe, por ejemplo; el tener ese <i>fichero
de consultas</i> es un ahorro de tiempo y quebraderos de cabeza.  El
código de consulta <code>sql</code> lo tienes a mano, lo puedes modificar para
ajustarlo a la consulta que necesitas en ese momento y los resultados
los tienes inmediatamente al pulsar <code>C-c C-c</code> en el bloque de código.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/bbdd/index.html">bbdd</a> <a href="/tags/sqlite/index.html">sqlite</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[bbdd]]></category>
  <category><![CDATA[sqlite]]></category>
  <link>https://notxor.nueva-actitud.org/2019/04/12/como-trabajar-con-sqlite3-desde-emacs.html</link>
  <pubDate>Fri, 12 Apr 2019 10:07:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Ventajas del texto plano]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-04-07</div>
<p>
Desde hace un buen tiempo me he ido pasando a tenerlo todo en fichero
de texto plano y utilizar toda una serie de programas para la gestión
de todo. La estrella de todo este sistema es sin duda <i>Emacs</i>, por su
<code>org-mode</code> y por tener modos para casi todo. Y es que plantearse
utilizar algo en formato de texto pasa por poder editar el texto, y en
ese sentido <i>Emacs</i> tiene «pichorros» y «chismáticos» para todo.
</p>

<p>
Algunos me han preguntado que por qué tengo esta manía, que qué más me
da si el documento es binario... y no, no me da igual por varias
razones:
</p>

<ul class="org-ul">
<li>En caso de que un fichero se corrompa es más fácil recuperar el
error o salvar lo que pueda ser salvado en un fichero de texto que
en uno binario.</li>
<li>No dependes de ningún programa externo, ni ocurre nada por abrir el
fichero con una versión anterior del mismo programa.</li>
<li>Los sistemas de control de versiones suelen estar enfocados a los
ficheros de texto y permiten consultar cambios, revertirlos, y
puedes aprovechar toda esa potencia que dan los sistemas de control
de versiones en general y <code>git</code> en particular.</li>
<li>Con el texto plano te concentras en el contenido y no en cómo
quedará en un papel impreso o visualizado en pantalla.</li>
<li>Se puede buscar fácilmente en el contenido con herramientas de
búsqueda, mientras que buscar contenido en ficheros binarios es la
muerte a pellizcos.</li>
</ul>

<p>
<b>«Sí»</b>, dirán algunos, <b>«pero no puedes hacer todo lo que se puede
hacer en modo gráfico»</b>.
</p>

<p>
Es cierto, para hacer animación 3D, diseño gráfico o edición de vídeo
necesitas un sistema gráfico, pero para todo lo demás no.
Efectivamente, me he encontrado con algunas dificultades en el ámbito
de las bases de datos de andar por casa, para las que utilizo <code>sqlite</code>
y los ficheros que genera esa herramienta son binarios, sin embargo,
con el comando <code>.dump</code>, puedes pasarla a texto de forma sencilla (que
es como meto alguna en el control de versiones).
</p>
<div id="outline-container-orgb9ca387" class="outline-2">
<h2 id="orgb9ca387">Ofimática en formato texto</h2>
<div class="outline-text-2" id="text-orgb9ca387">
<p>
Para lo que suele utilizar el usuario medio el ordenador es lo que
hace años se conocía por el genérico nombre de <i>Ofimática</i>.  El tema
de la automatización de la oficina ha sido una revolución desde que se
popularizaron los ordenadores personales. Aún recuerdo los tiempos de
editores de texto como el <i>Wordstar</i> o el <i>Wordperfect</i>, de la <i>hoja
de cálculo</i> de <i>Lotus 1 2 3</i> o de bases de datos como <i>dBase</i>, de
cuando antes de que <i>Micro$oft</i> impusiera su músculo monopolístico
para imponer su <i>office</i>.
</p>

<p>
Pero voy a hacer un repaso de las cosas que utilizo para mis
documentos y la gestión de mis cosas.
</p>
</div>
<div id="outline-container-orgcbd5cbd" class="outline-3">
<h3 id="orgcbd5cbd">Edición de textos</h3>
<div class="outline-text-3" id="text-orgcbd5cbd">
<p>
Desde hace mucho tiempo utilizo <i>LaTeX</i> para mis documentos
escritos. <a href="https://tecdigital.tec.ac.cr/revistamatematica/Libros/LaTeX/LaTeX_2018.pdf">Decargué el mejor manual de <i>LaTeX</i> que encontré en español</a>
y lo utilizo con frecuencia para consultar dudas.
</p>

<p>
Sin embargo, últimamente ─desde que descubrí el <code>org-mode</code> de <i>Emacs</i>,
al que me aficionado para casi todo─, con un lenguaje de marcas
sencillo para la edición:
</p>

<pre class="example" id="orgb806758">
* Título de primer nivel

** Título de segundo nivel

*** Título de tercer nivel

En el texto se puede marcar *negritas*, /cursivas/, =tipo fijo=,
~código~, +tachado+. Los listados se marcan con «-» y si son numéricos
como «1.», «2.»...

Los enlaces se marcan con [[destino][etiqueta]] y también se puden
tener notas al pie
</pre>

<p>
Para editar texto esas sencillas marcas nos facilitan la vida. Este
<i>blog</i> está escrito enteramente con <code>org-mode</code>, lo he contado muchas
veces ya.
</p>

<p>
La ventaja que le veo a este formato de texto es que al final lo
puedes exportar desde <i>Emacs</i> con un par de teclas. Y uno de mis
formatos preferidos, como ya he dicho es <i>LaTeX</i>, pero también lo hace
directamente a <code>pdf</code> o a <code>html</code>. De hecho, los acabados de cualquier
documento impreso con <i>LaTeX</i> tienen una presencia profesional que es
difícil dársela «a mano» con herramientas tipo «güord» o «gruait».
</p>
</div>
</div>
<div id="outline-container-orgd2f348d" class="outline-3">
<h3 id="orgd2f348d">Hoja de cálculo</h3>
<div class="outline-text-3" id="text-orgd2f348d">
<p>
Otra de las herramientas que se popularizaron con la <i>ofimática</i> son
las hojas de cálculo. La primera, que a mediados de los 80 del siglo
pasado, se convirtió en lo que ahora denominaríamos <i>killer
application</i> fue <i>Lotus 1-2-3</i>. Y es un concepto muy sencillo que se
puede utilizar para muchas cosas. De hecho se pueden hacer <i>hojas</i> que
sustituirán a programas completos y las puede hacer cualquiera, sin
necesidad de saber programar, habiendo comprendido sólo cómo funciona
una hoja de cálculo.
</p>

<p>
El sistema es sencillo, una hoja se divide en columnas y filas
formando celdas que por tanto se pueden señalar mediante la
combinación de coordenadas. Esas celdas pueden contener datos
directos, normalmente cadenas o números; o contener una fórmula que
mostrará el resultado del cálculo correspondiente.
</p>

<p>
Cómo utilizar el <i>modo tabla</i> dentro de <code>org-mode</code>
<a href="https://notxor.nueva-actitud.org/blog/2018/04/15/tablas-org-mode/">ya lo conté en el <i>blog</i> y no me gustaría repetirme</a>. Pero algunas
veces necesitas convertir en gráficos los datos que puedas manejar en
esas tablas. Algo que las hojas de cálculo popularizaron fue la
facilidad para mostrar los datos de forma gráfica.
</p>

<p>
Utilizo para los gráficos de este tipo y para dar un vistazo rápido
<code>gnuplot</code>. Así por ejemplo, podemos ver que se pueden realizar
gráficos mediante el siguiente código:
</p>

<pre class="example" id="org7012527">

#+begin_src gnuplot :exports code :file formulas-plot.png
reset

set title "Cálculo de fórmulas"

set xlabel "X"
set xrange [-8:8]
set xtics -8,2,8

set ylabel "Y"
set yrange [-20:70]
set ytics -20,10,70

f(x) = x**2
g(x) = x**3
h(x) = 10*sqrt(abs(x))

plot f(x) w l lw 1, g(x) w l lw 2, h(x) w l lw 3
#+end_src

</pre>

<p>
Y genera un gráfico tal que:
</p>


<figure id="org8fad9cc">
<img src="./imagen/2019-04-07-formulas-plot.png" alt="2019-04-07-formulas-plot.png">

</figure>

<p>
Pero también podemos generar gráficos a partir de tablas como por
ejemplo:
</p>

<pre class="example" id="org663561c">
#+tblname: plot-basico
|   x |         y1 |         y2 |
|-----+------------+------------|
| 0.1 |      0.425 |      0.375 |
| 0.2 |     0.3125 |     0.3375 |
| 0.3 | 0.24999993 | 0.28333338 |
| 0.4 |      0.275 |    0.28125 |
| 0.5 |       0.26 |       0.27 |
| 0.6 | 0.25833338 | 0.24999993 |
| 0.7 | 0.24642845 | 0.23928553 |
| 0.8 |    0.23125 |     0.2375 |
| 0.9 | 0.23333323 |  0.2333332 |
|   1 |     0.2225 |       0.22 |

#+begin_src gnuplot :var data=plot-basico :exports code :file tabla-plot.png
set title "Dibujo de una tabla"

set xlabel "X"
set xrange [0:1]
set xtics 0,0.1,1

set ylabel "Y"
set yrange [0.2:0.5]
set ytics 0.2,0.05,0.5

plot data u 1:2 w l lw 2 title 'y1', \
     data u 1:3 w lp lw 1 title 'y2'
#+end_src
</pre>

<p>
Dibuja un gráfico así:
</p>


<figure id="org79dc140">
<img src="./imagen/tabla-plot.png" alt="tabla-plot.png">

</figure>

<p>
No voy a profundizar mucho más en <code>gnuplot</code>, porque <a href="http://www.gnuplot.info/">para eso está su
página web</a> y seguro que lo explican allí mejor de lo que puedo hacerlo
yo en un apartado de un artículo.
</p>

<p>
La otra característica que aporta la hoja de cálculo, que es la de
sustituir la programación en base a complejas relaciones entre celdas,
fórmulas, líneas y columnas, añadiendo además una amplia librería de
funciones para ello, en mi caso ya he demostrado que lo compenso con
creces con <i>elisp</i>. Vale sí, es programar pero por eso permite hacer
muchas cosas más.
</p>
</div>
</div>
<div id="outline-container-org94e28b1" class="outline-3">
<h3 id="org94e28b1">Agenda</h3>
<div class="outline-text-3" id="text-org94e28b1">
<p>
La agenda la gestiono con <code>org-mode</code> de <i>Emacs</i>, lo he contado en el
<i>blog</i> y no voy a darle más vueltas. Pero también, se puede tener una
gestión mínima de proyectos con algo tan simple como lo siguiente:
</p>

<pre class="example" id="org01e3963">
* Proyecto muy complicado [33%]
** TODO Llamar a la gente [1/2]
*** TODO Pedro
*** DONE Juan
** TODO Alquilar las herramientas
** DONE Comprar los suministros
</pre>

<p>
Lo bueno de esto es que con un par de teclas se van actualizando las
cabeceras para convertirse y pasar de un valor al siguiente, completar
resultados, etc. El modo <code>org-mode</code> es una fuente inagotable de
herramientas que se pueden personalizar y que están ahí para echar una
mano. La única crítica que me han hecho a mi manera de gestionar mi
agenda es que «es fea», porque las interfaces de texto son menos
vistosas, tengo que reconocerlo. Pero ya le gustaría a otras
herramientas visuales tener la potencia que tiene: puedes gestionar la
agenda, tomar notas, gestionar calendarios, manejar tablas, editar
texto (incluso libros) y todo con eficacia y sencillez.
</p>
</div>
</div>
<div id="outline-container-orgb5ba9d2" class="outline-3">
<h3 id="orgb5ba9d2">Contabilidad: ledger</h3>
<div class="outline-text-3" id="text-orgb5ba9d2">
<p>
Otra de las aplicaciones de gestión en modo texto que manejo para mis
cosas. Al final de la forma más sencilla. La filosofía no puede ser
más simple: una buena contabilidad parte de un buen <i>libro diario</i>. Y
eso es lo que hace <code>ledger</code>, una aplicación de línea de comandos que
partiendo de un fichero de texto plano, con una <i>sintaxis</i> muy
sencilla permite consultar cuentas, controlar gastos, generar
informes, etc.
</p>

<p>
<a href="https://notxor.nueva-actitud.org/blog/2018/10/30/ledger-cli-y-el-ledger-mode-de-emacs/">Alguna vez ya escribí en el <i>blog</i> sobre el tema</a> así que voy a dejar
el tema aquí. Pero que sepáis que se pueden utilizar las cosas que ya
hemos visto, como <code>gnuplot</code> para visualizar los datos que arrojen las
consultas de <code>ledger</code>, por poner sólo un ejemplo.
</p>
</div>
</div>
<div id="outline-container-org0b8b83d" class="outline-3">
<h3 id="org0b8b83d">Bases de datos con sqlite3</h3>
<div class="outline-text-3" id="text-org0b8b83d">
<p>
Otro de los aspectos de la <i>ofimática</i> son las bases de datos. No voy
a entrar en los servidores de bases de datos concurrentes,
multiusuario. A todos les sonarán <i>MariaDB</i> (antes <i>MySQL</i>), o la
incombustible <i>PostgreSQL</i>. Pero yo hablo de bases de datos para
llevarte el fichero en el bolsillo en un <i>pendrive</i>. Para eso he
utilizado dos bases de datos distintas: <a href="https://firebirdsql.org/">firebird</a> y <a href="https://sqlite.org">sqlite</a>. Utilizaba
<i>firebird</i> porque permite tener ficheros de bases de datos a los que
acceder de manera separada o también instalarse y hacerla funcionar en
modo servidor. Luego he visto que <i>LibreOffice</i> la utiliza también
como uno de los motores internos.
</p>

<p>
Sin embargo, me cambié a <i>sqlite3</i> cuando empecé a trastear con
<i>Emacs</i> porque sí hay un <code>sqlite.el</code> que echarse al directorio de
<code>elpa</code> pero no existe ningún <code>firebird.el</code>, lo que es una lástima.
Total, tampoco es que utilice el modo servidor y <code>sqlite</code> es un
proyecto más generalizado y se lo pueden encontrar en todos los
sistemas.
</p>

<p>
Acceder a una base de datos es fácil desde nuestro editor favorito. Si
os parece hacemos un ejemplo sencillo y lo vemos sobre la marcha:
</p>

<pre class="example" id="orga5ff14c">
#+begin_src elisp :export code
(require 'sqlite)
(let ((db (sqlite-init "~/miDatabase.db")))
  (sqlite-query db "create table gente(id int, Nombre text, Telefono text)")
  (sqlite-query db "insert into gente values(1, 'Pepe', '123456789')")
  (sqlite-query db "insert into gente values(2, 'Juan', '987654321')")
  (sqlite-query db ".headers on")
  (setq resultado (sqlite-query db "select * from gente"))
  (sqlite-bye db)
  resultado)
#+end_src

#+RESULTS:
| id | Nombre | Telefono   |
|  1 | Pepe   | 123456789  |
|  2 | Juan   | 987654321  |
</pre>

<p>
Es algo sencillo de entender para una base de datos, <code>sqlite-init</code>
equivale a conectar con la base de datos <code>db</code>, luego los
<code>sqlite-query</code> se conectan a ella. Se puede enviar cualquier consulta
que se pueda hacer en la línea de comandos, incluidas las que
comienzan con un «.», que son las internas de <code>sqlite</code>. El comando
<code>.headers on</code> hace que se muestren los nombres de los campos en la
primera línea.
</p>

<p>
Como se puede apreciar, se utiliza el carácter <code>|</code> como separador de
campos, lo que facilita el crear tablas en el modo <code>org-mode</code>. También
podemos guardar toda la base de datos en modo de texto haciendo un
<code>dump</code> de la misma. En <code>sqlite3</code> con nuestra mini base de datos
abierta, el comando <code>.dump</code> mostrará la siguiente salida:
</p>

<pre class="example" id="org901ebe9">
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE gente(id int, Nombre text, Telefono text);
INSERT INTO gente VALUES(1,'Pepe','123456789');
INSERT INTO gente VALUES(2,'Juan','987654321');
COMMIT;
</pre>

<p>
Es decir, ha volcado toda la información de la base de datos a texto
plano, abriendo una transacción y ejecutando los comandos necesarios
para generar las tablas, índices e introducir los datos que tenga
volcada. Como es texto plano, la puedes llevar así a cualquier
repositorio <code>git</code> o editar con un editor de texto, procurando no
<i>cagarla</i> para luego poder regenerar el fichero de base de datos sin
problemas.
</p>

<p>
¿Cuál es la ventaja de tener la base de datos en ese formato de texto?
Pues es sencillo: como se puede apreciar es código <code>sql</code> por lo que
puedo cargarlo en cualquier aplicación que comprenda dicho lenguaje y
gestionar mis datos con ella.
</p>
</div>
</div>
</div>
<div id="outline-container-org840d0a8" class="outline-2">
<h2 id="org840d0a8">Gráficos en modo texto</h2>
<div class="outline-text-2" id="text-org840d0a8">
<p>
Ya he hablado de los gráficos para mostrar datos con <code>gnuplot</code>, aunque
muy de pasada. Pero no sólo de esos gráficos vive la documentación, a
veces se necesitan cosas más complejas o distintos tipos de esquemas o
dibujos.
</p>

<p>
Podríamos hablar aquí también de la capacidad de modificar gráficos
vectoriales tipo <code>svg</code>, porque son archivos de texto <code>XML</code> y hay quien
lo modifica a mano <a href="https://notxor.nueva-actitud.org/blog/2017/02/10/grafico-de-perfil-en-el-minimult/">es algo que ya he hecho por aquí con código</a> y lo
mismo no hace falta repetir.
</p>
</div>
<div id="outline-container-org12112b6" class="outline-3">
<h3 id="org12112b6">Graphviz</h3>
<div class="outline-text-3" id="text-org12112b6">
<p>
<a href="https://notxor.nueva-actitud.org/blog/2018/01/31/gr%c3%a1ficos-y-org-mode-de-nuevo/">Cuando hablé de gráficos en el modo <code>org-mode</code> de <i>Emacs</i> mencioné
<code>graphviz</code> pero no hice nada con él</a> y eso es imperdonable. Por lo
menos debería haber mostrado algún ejemplo de cómo se utiliza. Así que
voy a poner un par de ejemplos para que se vea el potencial y luego
cada uno <a href="https://www.graphviz.org/">pueda investigar en la página web de <code>graphviz</code> las infinitas
opciones que tiene</a>. He tomado un par de ejemplos que muestro a
continuación:
</p>

<pre class="example" id="org46a62b6">
#+begin_src dot :file procesos-graphviz.png :export code :cmdline -Tpng
digraph G {

  subgraph cluster_0 {
    style=filled;
    color=lightgrey;
    node [style=filled,color=white];
      a0 -&gt; a1 -&gt; a2 -&gt; a3;
      label = "process #1";
    }

  subgraph cluster_1 {
    node [style=filled];
    b0 -&gt; b1 -&gt; b2 -&gt; b3;
    label = "process #2";
    color=blue
  }
  start -&gt; a0;
  start -&gt; b0;
  a1 -&gt; b3;
  b2 -&gt; a3;
  a3 -&gt; a0;
  a3 -&gt; end;
  b3 -&gt; end;

  start [shape=Mdiamond];
  end [shape=Msquare];
}
#+end_src
</pre>

<p>
Dibujará un gráfico como:
</p>


<figure id="org540143b">
<img src="./imagen/procesos-graphviz.png" alt="procesos-graphviz.png">

</figure>

<pre class="example" id="org0647636">
#+begin_src dot :file structs-graphviz.png :export code :cmdline -Tpng
digraph structs {
  node [shape=record];
  struct1 [label="&lt;f0&gt; izqda|&lt;f1&gt; centro|&lt;f2&gt; decha"];
  struct2 [label="&lt;f0&gt; uno|&lt;f1&gt; dos"];
  struct3 [label="hola\nmundo |{ b |{c|&lt;esta&gt; d|e}| f}| g | h"];
  struct1:f1 -&gt; struct2:f0;
  struct1:f2 -&gt; struct3:esta;
}
#+end_src
</pre>

<p>
Dibuja el siguiente gráfico:
</p>


<figure id="org0d70291">
<img src="./imagen/structs-graphviz.png" alt="structs-graphviz.png">

</figure>

<p>
Como se puede apreciar es una herramienta muy potente, pero no la
única. Hay otras herramientas, <a href="http://www.texample.net/tikz/">como el paquete <i>TikZ</i> de <i>LaTeX</i></a> que
proporcionan otra gran cantidad de gráficos en modo texto.
</p>
</div>
</div>
<div id="outline-container-org9f5788d" class="outline-3">
<h3 id="org9f5788d">PlantUML y Ditaa</h3>
<div class="outline-text-3" id="text-org9f5788d">
<p>
No voy a extenderme en estos, <a href="https://notxor.nueva-actitud.org/blog/2018/01/31/gr%c3%a1ficos-y-org-mode-de-nuevo/">porque tienen su propio artículo en el
blog</a> y no es cuestión de repetirme constantemente. Pero tenía que
mencionarlos en su correspondiente apartado. Aunque algunas veces me
resulta cargante la lentitud del proceso, mientras se carga <code>java</code>, se
llama al <code>jar</code> y se realiza el gráfico, sin embargo las posibilidades
están ahí. <code>PlantUML</code> tiene todos los <i>pichorros</i> y <i>chismáticos</i>
necesarios para realizar los gráficos <i>UML</i> ─como su nombre indica─, y
<code>ditaa</code> nos permite <i>dibujar a mano alzada</i> bloques de color con texto.
</p>
</div>
</div>
<div id="outline-container-org96d668b" class="outline-3">
<h3 id="org96d668b">3D</h3>
<div class="outline-text-3" id="text-org96d668b">
<p>
Había dicho antes que para hacer <i>3D</i> necesitaba el entorno gráfico y
la verdad es que también se pude hacer en modo texto, pero ¿quién se
acuerda de <code>povray</code>? Bueno, yo... lo siento, pero le tengo vicio. Por
poner un ejemplo sencillo:
</p>

<div class="org-src-container">
<pre class="src src-povray">#include "colors.inc"

background { color Cyan }

camera {
  location &lt;3,3,-3&gt;  // posición de la cámara
  look_at  &lt;0,0,0&gt;   // punto hacia el que mira
}

light_source {
  &lt;3,3,3&gt;
  color White}       // posición y color de una fuente de luz

sphere {
  &lt;0,1,0&gt;, 1         // posición y radio de una esfera
  texture {          // la textura más sencilla que hay: un color
    pigment { color Yellow} }
}

plane { &lt;0,1,0&gt;      // vector normal
        , 0          // distancia del origen
    pigment {        // con colores tipo «tablero de ajedrez»
      checker color White, color Blue
    }
}
</pre>
</div>

<p>
Se puede ver que con ese poco de texto plano se puede generar una figura
como la siguiente:
</p>


<figure id="org385ca03">
<img src="./imagen/ejemplo-pov-emacs.png" alt="ejemplo-pov-emacs.png">

</figure>

<p>
Si alguien piensa que sólo sirve para hacer figuras simples puede
echarle un ojo a <a href="http://www.ignorancia.org">http://www.ignorancia.org</a> donde encontrará múltiples
ejemplos de lo que se puede hacer con <code>povray</code>.  <a href="http://www.ignorancia.org/index.php/galleries/old-images/spanish-patio/">Una de mis imágenes
favoritas es el patio español</a>, que se pude apreciar como a partir de
texto plano se pueden generar complejas imágenes realistas.
</p>

<p>
Pero no es el único sistema de visualización 3D que funciona en modo
texto, hay otros <a href="http://www.yafaray.org/"><i>raytracer</i> como <i>yafray</i></a> o sistemas como el olvidado
lenguaje VRML. Recuerdo haber escrito un par de ponencias para las
primeras jornadas de <i>Blendiberia</i>, que se <a href="https://openlibra.com/es/book/download/tecnologias-libres-para-sintesis-de-imagen-digital-tridimensional">recogieron en un libro para
las terceras jornadas de Ciudad Real</a>, aunque allí firmé con mi
verdadero nombre, hace <i>un siglo parece</i>. De la que me acuerdo
especialmente fue de la primera, en Barcelona sobre programación de
<i>plugins</i> para <a href="http://www.blender3d.org">Blender</a>, en las que toda la tecnología falló y no pude
hacer la demostración de importación y <i>renderizado</i> de un fichero
VRML en <i>Blender</i>... solté un ladrillo teórico improvisado sobre uno
práctico que llevaba preparado. Y también recuerdo el traducir y
hacerle los gráficos a un artículo sobre <i>Iluminación con Yafray</i> del
mismísimo creador de la herramienta.
</p>
</div>
</div>
</div>
<div id="outline-container-org875fbbe" class="outline-2">
<h2 id="org875fbbe">Presentaciones</h2>
<div class="outline-text-2" id="text-org875fbbe">
<p>
Otra de las cosas que suele la gente necesitar son programas para
hacer <i>presentaciones</i>. Programas como el <i>pogüerpoin</i> del <i>ofis</i> del
Billy Puertas o del <i>imprés</i> de <i>LibreOffice</i>.
</p>

<p>
Mi experiencia con este tipo de herramientas ha sido una frustración
tras otra. Te pasas horas poniéndole y ajustando <i>pichorros</i> con
animaciones y gráficos vistosos para que luego cambias de máquina y te
encuentras que ni siquiera abre el fichero de presentación o lo hace
mal.
</p>

<p>
Hace tiempo me pasé a un par de formatos de presentación que no tienen
nada que envidiar a las presentaciones realizadas por otros
sistemas. Una de ellas es tener la presentación en formato <code>pdf</code> y así
poder mostrarla en cualquier máquina con cualquier visor de <code>pdfs</code>,
claro. La mayoría a estas alturas también soportan el modo
<code>presentación</code> y es una forma de ahorrarme muchos dolores de cabeza.
</p>

<p>
Uno de los <i>chismáticos</i> que suelo utilizar es el <i>Beamer</i> de <i>LaTeX</i>,
del que existe mucha documentación. Yo voy a recomendar el tutorial
que escribió <a href="https://ondiz.github.io/cursoLatex/Contenido/12.Presentacion.html">Ondiz en su curso sobre LaTeX</a>, porque es sencillo y fácil
de entender, va al grano y sin rodeos muestra todo el código por si
hay alguna duda. También mencionaré que <code>org-mode</code> tiene un <i>modo
beamer</i>, para hacer las presentaciones y que funciona muy bien.
</p>

<p>
Si necesito presentaciones más vistosas, de esas que entran por los
ojos suelo utilizar <code>html5</code>, <code>css</code> y un poco/mucho de <code>javascript</code>.
Hay muchas librerías <i>javascript</i> que hacen esta tarea.  <a href="https://impress.js.org">Mi preferida
es <code>impress.js</code></a> cuyo código fuente podemos encontrar en
<a href="https://github.com/impress/impress.js/">https://github.com/impress/impress.js/</a> y que vienen algunos ejemplos,
que pueden servir de guía <a href="https://impress.js.org/examples/classic-slides">para mostrar todas las opciones que tenemos
a nuestro alcance</a> con ésta herramienta.
</p>

<p>
Al utilizar <code>html</code> cualquier navegador moderno, las mueve con
facilidad, sobre todo si nos acordamos de utilizar fuentes de letra
locales (para no estar en problemas parecidos que con sistemas
cerrados) y no abusamos de las animaciones. Además genera una
visualización tan vistosa que se produce el <i>efecto hala</i> (equivalente
al <i>wow efect</i>) y no es raro que en el turno de <i>ruegos y preguntas</i>
alguien pregunte <i>¿con qué programa está hecha la presentación?</i> y que
se sorprenda que la respuestas sea <i>Emacs</i>.
</p>

<p>
Normalmente utilizo <i>Beamer</i> cuando necesito imprimir las <i>traspas</i> en
papel, pero si no, utilizo el <code>impress.js</code>.
</p>
</div>
</div>
<div id="outline-container-org2d4ae49" class="outline-2">
<h2 id="org2d4ae49">Conclusiones</h2>
<div class="outline-text-2" id="text-org2d4ae49">
<p>
El modo texto me permite hacer de todo. No he mencionado algunas
formas de edición de vídeo (<code>ffmpeg</code>) o de sonido (<code>sox</code>) o de imagen
(<code>magick</code>) desde la línea de comandos, pero que sepáis que poder se
puede.
</p>

<p>
Quizá mi camino es más tortuoso y/o difícil para el no <i>iniciado</i>, sin
embargo es más efectivo. Tener toda una panoplia de <i>chismáticos</i> y
<i>pichorros</i> a la vista para pinchar sobre ellos, ─en algunas ocasiones
de forma aleatoria─, puede parecer más sencillo. Sin embargo, yo
encuentro que lo que realmente es más sencillo es cuando el usuario
hace las cosas sabiendo lo que hace y porqué, sabiendo cómo funcionan
las herramientas que tiene en la punta de los dedos ─o del ratón, que
hay gente que no sabe ya vivir sin él─ y actuando en consecuencia.
</p>

<p>
Ese es <i>mi</i> camino y <i>mi</i> forma de trabajar y hago hincapié en el
<i>mi</i>, porque entiendo que no es la única y cada cual puede encontrar
sus sinergias con sus herramientas. Cada uno se encuentra cómodo con
unos programas y no con otros.
</p>

<p>
No critico a quien no conoce otros modos y sigue utilizando <i>las
herramientas del Amo</i> para sus cosas. Ni tampoco a quien conoce otros
modos y decide no utilizarlos. Sólo expreso que mi modo es éste, que
puedo hacer todo lo que hacen otros, incluso en ocasiones más rápido y
de manera más efectiva, e incluso vistosa. Tengo todas las
aplicaciones de una ofimática y más:
</p>

<ul class="org-ul">
<li>Tratamiento de textos</li>
<li>Hoja de cálculo</li>
<li>Agenda</li>
<li>Bases de datos</li>
<li>Gráficos (incluso 3D)</li>
<li>Presentaciones</li>
</ul>

<p>
Y todos mis ficheros están en texto plano, no dependen de la versión
de ningún <i>software</i> y los puedo modificar-actualizar sin necesidad de
ninguna herramienta <i>privativa</i> dispuesta a <i>apoderarse</i> de mis datos
y obligarme mediante el <i>chantaje de las versiones</i> a comprar un
programa que no necesito. Los puedo abrir en cualquier sistema
operativo y ocupan mucho menos que la misma información en otros
formatos, porque no necesitan y no guardan, el peso de la
<i>visualización</i> con ellos.
</p>

<p>
Me he dejado en el tintero algunas (muchas) otras herramientas, pero
como no las uso no las he mencionado. Me he limitado a nombrar sólo
aquello que utilizo para mis cosas.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2019/04/07/ventajas-del-texto-plano.html</link>
  <pubDate>Sun, 07 Apr 2019 10:37:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Utilizando Dired para reemplazar cadenas en varios ficheros]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-03-30</div>
<p>
Hasta ahora, le había echado pocas cuentas a <code>dired</code>. Es un paquete de
<i>emacs</i> que se utiliza para trabajar con los ficheros del disco. Sin
embargo, estoy acostumbrado a hacerlo casi todo desde la línea de
comandos. Si necesito algo más visual en modo gráfico utilizo el
<i>Dolphin</i> de <i>KDE-plasma</i> y en modo texto utilizo el incombustible
<i>mc</i>.
</p>

<p>
El caso es que estaba trabajando en una traducción que implica varios
ficheros y son bastantes. En el texto, había dejado sin traducir el
nombre de un lugar y su gentilicio, porque pensaba que no había
traducción y a medio proyecto, encontré que sí... ¿Cambiar ahora todo
lo que ya está traducido en varios ficheros? ¿Uno a uno? ¿No hay un
medio más rápido? Pues sí, en <i>emacs</i> lo hay: una breve búsqueda por
<i>Internet</i> y un poco de buceo por la ayuda me dijo cómo. Así, vengo
aquí a contarlo para que no se me olvide.
</p>
<div id="outline-container-org78d99e6" class="outline-2">
<h2 id="org78d99e6">Dired y sus cosas</h2>
<div class="outline-text-2" id="text-org78d99e6">
<p>
Alguna vez he contado ya que utilizo <code>dired-sidebar</code> cuando trabajo en
proyectos que implican varios ficheros porque me permite abrirlos con
un par de <i>clicks</i>, borrar ficheros secundarios que se generan al
convertir de <i>LaTeX</i> a <i>pdf</i>, etc. Sin embargo, esta vez necesitaba
otras cosas que no suelo utilizar. Por ejemplo, seleccionar algunos
ficheros y otros no. El método habitual de selección que utilizo es la
combinación de teclas <code>% m</code> poniendo luego la extensión de los
ficheros con los que quiero trabajar, por ejemplo: <code>.org</code>. Si quiero
desmarcar alguno, me sitúo en él y pulso <code>u</code> (o <code>U</code> si quiero
desmarcarlos todos). Si quiero marcar alguno más, me pongo sobre él y
pulso <code>m</code>. Cuando los tengo todos marcados realizo sobre ellos la
acción que quiero realizar. Hasta ahora no me había fijado en que la
opción <code>Q</code> realiza la acción <code>dired-do-find-regexp-and-replace</code>, que
como su nombre indica buscará una expresión a lo largo de los ficheros
marcados en <code>dired</code> y la reemplazará con otra. Básicamente, lo mismo
que hace la función <code>query-replace-regexp</code> en un fichero, lo repite en
todos ellos.
</p>

<p>
Una vez que hemos pulsado <code>Q</code> en el <i>buffer</i> de <i>dired</i>, nos pregunta
por las expresiones que queremos utilizar: la primera será la que
buscará en los ficheros seleccionados y la segunda su reemplazo. Las
combinaciones de teclas que podemos utilizar son muy similares a las
de <code>query-replace</code>: <code>y</code> para que reemplace la cadena, <code>n</code> para que la
salte, <code>!</code> para que reemplace todas sin preguntar más en el fichero
actual. Además, se añaden alguna tecla más: <code>N</code> deja de reemplazar en
el fichero actual y pasa al siguiente y <code>Y</code> lo hace en todos los
ficheros sin volver a preguntar más.
</p>

<p>
Como no hice capturas de pantalla mientras hacía el trabajo para
utilizarlas luego en este artículo (cuando lo hice tampoco pensé en
escribirlo en el <i>blog</i>). He hecho una captura con un búsqueda en los
ficheros del <i>blog</i> para sustituir <code>elisp</code> por <code>emacs lisp</code>. No voy a
sustituir nada, pero me servirá para explicar algunas cosas más.
</p>
</div>
</div>
<div id="outline-container-orgb49e6b7" class="outline-2">
<h2 id="orgb49e6b7">Trabajando en el reemplazo</h2>
<div class="outline-text-2" id="text-orgb49e6b7">

<figure id="org6a05715">
<img src="./imagen/captura-pantalla-dired-replace.png" alt="captura-pantalla-dired-replace.png">

</figure>

<p>
Como se puede apreciar en la captura, se abren un par de <i>buffers</i>
para realizar la sustitución. Hay uno llamado <code>*xref*</code> que es
básicamente un listado de ficheros en los que se ha encontrado la
expresión buscada, junto con las líneas en las que se encuentran.
</p>

<p>
Ese <i>buffer</i> nos sirve para reanudar el trabajo de sustitución ─en
caso de que lo perdamos─, pulsando <code>r</code> y nos preguntará de nuevo por
las expresiones a buscar. También podemos movernos por sus líneas con
<code>n</code> y <code>p</code>. Eso nos irá llevando en otro <i>buffer</i> a la posición
marcada del fichero.
</p>
</div>
</div>
<div id="outline-container-org51dc710" class="outline-2">
<h2 id="org51dc710">Guardando lo cambiado</h2>
<div class="outline-text-2" id="text-org51dc710">
<p>
Una vez hechas las modificaciones hay que guardarlas. Si se han
modificado dos o tres ficheros, no hay problema por darle un par de
veces a la <code>y</code> para guardar cuando cerramos, pero si son muchos los
ficheros modificados, también puede hacerse tediosa esa operación.
¿Alguna sugerencia? Pues sí: <code>ibuffer</code>. El comando <code>ibuffer</code> trabaja
con los <i>buffers</i> de modo similar a como <i>dired</i> trabaja con ficheros
del disco.
</p>

<p>
En ese caso si después de llamar a <code>M-x ibuffer</code> pulsamos <code>S</code> guardará
los cambios en los <i>buffers</i> abiertos que se hayan modificado y
posteriormente podemos cerrarlos con <code>D</code>. El modo <code>ibuffer</code> es
parecido a la lista de <i>buffers</i> que se obtiene con <code>C-x C-b</code>, aunque
cambian las opciones que puedes realizar a golpe de tecla.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2019/03/30/utilizando-dired-para-reemplazar-cadenas-en-varios-ficheros.html</link>
  <pubDate>Sat, 30 Mar 2019 17:20:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[La relación entre la felicidad y los dispositivos electrónicos]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-03-22</div>
<p>
La <i>felicidad</i> es uno de esos temas que como psicólogo me importan no
sólo de forma personal, sino también profesional. No soy el único al
que le importa ese tema, de hecho, la Organización de las Naciones
Unidas en 2013 instauró el <i>día internacional de la felicidad</i>. De
hecho en 2015, la ONU estableció 17 Objetivos de Desarrollo Sostenible
que pretenden acabar con la pobreza, reducir la desigualdad y proteger
nuestro planeta. Esos tres aspectos parecen ser clave para el
bienestar y la felicidad.
</p>

<p>
El caso es que mirando estos temas, y otros, <a href="http://worldhappiness.report/ed/2019/">tropecé con el <i>World
Happiness Report</i> por la web</a>. La encuesta, como dice su web, se ha
realizado en los 156 países miembros, para clasificarlos según lo
felices que se sienten sus ciudadanos.
</p>

<p>
En esta séptima edición el informe se centra en <b>la felicidad y la
comunidad</b>: cómo ha evolucionado la felicidad en los últimos doce
años, el uso de las tecnologías, las normas sociales, los conflictos y
las políticas gubernamentales.
</p>

<p>
Los <i>seis factores clave</i> que se han tenido en cuenta:
</p>

<ol class="org-ol">
<li>PIB per cápita.</li>
<li>Apoyo social.</li>
<li>Esperanza de vida saludable.</li>
<li>Libertad.</li>
<li>Generosidad.</li>
<li>Ausencia de corrupción.</li>
</ol>

<p>
Además, también se han incluido el <b>análisis de las evaluaciones de
vida</b>, lo que viene a ser la percepción subjetiva de los habitantes de
su vida y las <b>emociones</b>.
</p>

<p>
El ranking viene a ser el esperado. Los primeros puestos son para
Finlandia, Dinamarca, Noruega e Islandia ─por ese orden─. Para los
curiosos: España se queda en el puesto 30. Los años anteriores la
tendencia fue negativa, sin embargo en esta entrega repuntamos seis
puestos. Y como decía, de resultados esperados, la cola es para
Tanzania (153), Afghanistan (154), República Centroaficana (155) y
Sudán del Sur (156); dejando al continente africano como el menos
feliz de todos.
</p>

<p>
Siguiendo con España, parece que hemos repuntado otros tres puestos en
lo que respecta a las expectativas de vida saludable, situándonos en
la tercera posición de los países evaluados.
</p>

<p>
En el informe, los capítulos del 5 al 7 analizan los <b>Cambios en la
tecnología de la información</b>. El capítulo 5 analiza los efectos en la
felicidad del uso de la tecnología digital. El capítulo 6 trata sobre
el <i>Big Data</i> y el capítulo 7 describe una epidemia en los Estados
Unidos, ampliando lo encontrado en el capítulo 5.
</p>

<p>
Parece ser que han encontrado una relación inversa entre la felicidad
de los adolescentes y las nuevas tecnologías: al parecer, la gran
cantidad de tiempo que pasan los jóvenes interactuando con
dispositivos electrónicos tiene efectos directos sobre su infelicidad.
</p>

<p>
De hecho, de acuerdo con los datos, la <b>marcada disminución del
bienestar de los adolescentes desde el 2011</b>, podría justificarse por
el cambio de forma en que los jóvenes pasan su tiempo libre. También
parece que entre los adultos puede haber influido, sin embargo las
conclusiones con los adultos son menos claras. La recomendación del
estudio es que las organizaciones que se dedican a mejorar <i>la
felicidad</i> de la gente, centren su atención al modo en que las
personas pasan su tiempo libre.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/psicología/index.html">psicología</a> <a href="/tags/felicidad/index.html">felicidad</a> ]]></description>
  <category><![CDATA[psicología]]></category>
  <category><![CDATA[felicidad]]></category>
  <link>https://notxor.nueva-actitud.org/2019/03/22/la-relacion-entre-la-felicidad-y-los-dispositivos-electronicos.html</link>
  <pubDate>Fri, 22 Mar 2019 19:28:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[La usabilidad y la psicología]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-03-15</div>
<p>
Estaba <i>cacharreando</i>, por no decir procrastinando, hace unos días por
esas <i>webs</i> perdidas y me tropecé con un <a href="http://www.copmadrid.org/wp/psicologia-y-usabilidad-en-informatica-ux/">enlace en un <i>blog</i> sobre
psicología</a> que hablaba sobre <i>usabilidad</i> en informática.  La <i>web</i> a
la que me refiero es <a href="https://lawsofux.com/">https://lawsofux.com/</a>. En ella se pueden
encontrar, no sólo las leyes, sino también amplias explicaciones y
referencias donde ampliar la información.  Si te interesa el tema es
mejor que consultes esa <i>web</i> y profundices en cada uno de los 19
principios de la usabilidad:
</p>

<ol class="org-ol">
<li><p>
<b>Efecto de la estética en la usabilidad</b>: Habitualmente los
usuarios perciben las interfaces estéticas como <i>más usables</i>.
</p>

<p>
Diseños estéticos pueden hacer al usuario más tolerante con una
menor usabilidad. Pueden enmascarar problemas de usabilidad y hacer
que no se descubran esos problemas durante las pruebas.
</p></li>

<li><b>El umbral de Doherty</b>: La productividad aumenta cuando el usuario
y su ordenador interaccionan al mismo ritmo (&lt;400ms) que asegura
que ninguno de los dos tiene que esperar al otro.</li>

<li><p>
<b>La ley de Fitts</b>: El tiempo para alcanzar un objetivo es una
función de la distancia y el tamaño del objetivo.
</p>

<p>
Hacer que los elementos a los que se quiera facilitar el acceso
sean más grandes y más cercanos al usuario.
</p>

<p>
Esta ley se aplica especialmente a botones, con el propósito de
hacerlos más fáciles de encontrar y seleccionar.
</p></li>

<li><p>
<b>La ley de Hick</b>: El tiempo que lleva tomar una decisión se
incrementa con el número y complejidad de las opciones.
</p>

<p>
Muchas decisiones se convierten en largo proceso de pensamiento
sobre las opciones y sobre la propia toma de decisión.
</p>

<p>
Para evitarlo, se recomiendan dos vías de trabajo: primero,
simplificar las elecciones del usuario dividiendo las tareas
complejas en pasos más pequeños; segundo, prevenir que el usuario
se sienta apabullado destacando las opciones recomendadas.
</p></li>

<li><p>
<b>La ley de Jakob</b>: Los usuarios gastan mucho tiempo en otros
sitios. Esto significa que los usuarios prefieren que tu sitio
trabaje de manera similar a los otros sitios que ya conoce.
</p>

<p>
Puedes simplificar el proceso de aprendizaje de los usuarios
proporcionando patrones de diseño que le sean familiares.
</p></li>

<li><p>
<b>Ley de la región común</b>: Los elementos tienen a percibirse
formando parte de un mismo grupo cuando comparten un área
claramente definida por un marco.
</p>

<p>
Añadir bordes creando regiones comunes alrededor de un grupo de
elementos es la forma más fácil de separarlo de los elementos
circundantes.
</p></li>

<li><p>
<b>Ley de Prägnanz</b>: Las personas percibirán e interpretarán
complejas o ambiguas imágenes como la forma más sencilla posible,
porque es la interpretación que requiere menos esfuerzo cognitivo
de ellos.
</p>

<p>
Al ojo humano le gusta encontrar simplicidad y orden en formas
complejas porque le previene contra verse saturado con información.
</p></li>

<li><p>
<b>Ley de Proximidad</b>: Los objetos que se encuentran cerca, o más
próximos que otros, tienden a parcibirse como formando un grupo
juntos.
</p>

<p>
La ley de proximidad es adecuada para proporcionar a los usuarios
un grupo de diferentes tipos de información de un vistazo.
</p></li>

<li><p>
<b>Ley de la Similitud</b>: El ojo humano tiende a percibir los
elementos similares en un diseño como una imagen o forma completa,
o como un grupo, incluso se esos elementos están separados.
</p>

<p>
Asegúrate que los <i>links</i> y el sistema de navegar son visualmente
diferentes de los elementos normales de texto y tienen estilos
consistentes.
</p></li>

<li><p>
<b>Ley de la Conectividad Uniforme</b>: Los elementos que están
visualmente conectados son percibidos más relacionados que los
elementos sin conexión.
</p>

<p>
Agrupar funciones de naturaleza similar mediante conexiones
visuales de colores, lineas, marcos u otras formas gráficas.
</p></li>

<li><p>
<b>Ley de Miller</b>: Una persona media sólo puede mantener 7 (±2)
ítems en su memoria de trabajo.
</p>

<p>
Una forma efectiva de agrupar información para los usuarios es
organizarla en grupos de entre 5 y 9 ítems.
</p></li>

<li><p>
<b>La navaja de Occam</b>: Entre hipótesis en competencia que
predicen igualmente bien, se debe elegir aquella que haga el menor
número de suposiciones.
</p>

<p>
Analizar cada elemento y eliminar todos los que se pueda, sin
comprometer la funcionalidad.
</p></li>

<li><p>
<b>El Principio Pareto</b>: El principio <i>pareto</i> establece que, para
muchos eventos, alrededor del 80% de los efectos provienen del 20%
de las causas.
</p>

<p>
Enfocar la mayoría de los esfuerzos en las áreas que producirán la
mayoría de los beneficios para la mayoría de los usuarios.
</p></li>

<li><b>Ley de Parkinson</b>: Cualquier tarea se puede inflar hasta que todo
el tiempo disponible se haya gastado.</li>

<li><p>
<b>Ley de Postel</b>: Se liberal en lo que aceptas y conservador en lo
que envías.
</p>

<p>
Hay que ser empático y tolerante con cualquier acción que el
usuario pueda hacer. Esto significa aceptar una entrada variable
de los usuario, trasladar esa entrada al encuentro de los
requerimientos, definiendo el marco para la entrada y proveyendo
un claro <i>feedback</i> al usuario.
</p></li>

<li><p>
<b>Efecto de posición en la serie</b>: Los usuarios suelen recordar
mejor el primer y el último ítem de una serie.
</p>

<p>
Colocar los ítems menos importantes en el centro de una lista
puede ayudar porque esos ítems tienden, con menos frecuencia, a
almacenarse en las memorias a largo plazo y de trabajo.
</p>

<p>
Posicionar las acciones clave en los extremos derecho e izquierdo
de una serie de elementos puede incrementar la memorización.
</p></li>

<li><b>La ley de Tesler</b>: También conocida como la <i>Ley de Conservación
de la Complejidad</i>, establece que para cualquier sistema hay una
cierta cantidad de complejidad que no se puede reducir.</li>

<li><b>Efecto Von Restorff</b>: También conocido por el <i>Efecto del
Aislamiento</i>, predice que cuando hay varios objetos similares, el
objeto que difiera del resto es el que mejor será recordado.</li>

<li><b>Efecto Zeigarnik</b>: La gente recuerda mejor las tareas incompletas
o interrumpidas mejor que las terminadas.</li>
</ol>
<div id="outline-container-org63128d5" class="outline-2">
<h2 id="org63128d5">Conclusión</h2>
<div class="outline-text-2" id="text-org63128d5">
<p>
La mayor parte de estas leyes provienen del mundo de la psicología,
sobre todo de campos relacionados con la <b>percepción</b> y algunas son
realmente antiguas (de principios del siglo XX) con la <i>Gestalt</i> a la
vanguardia de las escuelas que se preocuparon por estos fenómenos.  Su
aplicación posterior a la informática llegó de la mano del diseño,
donde ya se venían utilizando de manera más o menos consciente.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/psicología/index.html">psicología</a> <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[psicología]]></category>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2019/03/15/la-usabilidad-y-la-psicología.html</link>
  <pubDate>Fri, 15 Mar 2019 10:24:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Creación de un modo mayor para Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-03-14</div>
<p>
Hacía que no me ponía a escribir en el <i>blog</i>, y no es por falta de
ganas o por abandono, sino que he estado a otras cosas, que han
acabado relacionándose también con el tema de la serie.
</p>

<p>
Resulta que hemos empezado otro <del>vaporware</del> juego, en forma de
<i>aventura conversacional</i> y con la intención de probar <a href="http://www.ngpaws.com/">otra
herramienta para crearlas</a> para <i>web</i> que de momento no había utilizado
nunca: <code>ngPAWS</code>. Después de iniciar el proyecto con la versión
<i>estable</i> (0.9), nos dimos cuenta que en el repositorio de <i>github</i>
había algunos de los errores, que nos estábamos encontrando,
corregidos. Así pues, descargamos la versión del repositorio y
compilamos. En el paquete estable, en binario, se distribuye un <i>IDE</i>
para manejar el fichero de <i>base de datos</i> en modo texto que luego se
compilará en la aventura, pero las piezas fundamentales para hacerlo
son otros dos binarios:
</p>

<ul class="org-ul">
<li><a href="http://www.caad.es/baltasarq/prys/txtpaws/txtpaws.html">El <code>txtPaws</code> de baltasarq</a> que básicamente es un <i>preprocesador</i> que
toma la base de datos y cambia los <code>#define</code> por sus valores,
elimina comentarios y otras cosas que facilitan un poco las cosas al
programador. Por lo que programar con <i>PAWS</i> se convierte en algo
más llevadero que tratar con los códigos numéricos que utiliza.</li>

<li>El binario <code>ngpc</code> es un compilador que convertirá el fichero de
texto generado por el <code>txtPaws</code> al código <code>javascript</code> que será el
juego.</li>
</ul>

<p>
Como decía, la versión estable cuenta con un <i>IDE</i> que facilita la
modificación de la base de datos accediendo de manera directa a los
distintos apartados y con unos «chismáticos» de los habituales en todo
<i>IDE</i> para guardar, compilar y lanzar el juego. Sin embargo, al
descargar los fuentes y compilar, vimos que el <i>IDE</i> es independiente,
de hecho está programado en otro lenguaje: <i>Pascal</i>, mientras que el
compilador lo está en <i>C</i>. No tengo compilador de <i>Pascal</i>, <i>Lazarus</i>
ocuparía más sitio del que puedo permitirme en mi viejo disco duro.
Algo habrá que hacer.
</p>

<p>
Resumiendo, no tenemos <i>IDE</i>, pero tenemos <i>Emacs</i>. Total, el fichero
de <i>base de datos</i> es texto plano. Vale, pero queremos que nos
facilite la vida: que salte a las secciones correspondientes, como el
<i>IDE</i>, que resalte la sintaxis y que compile. ¿Podemos hacer que
<i>Emacs</i> haga todas esas cosas para nosotros? Pues sí, pero necesitamos
programar <i>un modo mayor de Emacs</i>.
</p>

<p>
Un <i>modo mayor</i> es algo más complicado que uno menor, que ya lo
habíamos visto en anteriores entregas. Por eso, la forma
recomendada en el manual de <i>elisp</i> ese hacerlo <i>derivando</i> el nuevo
modo de otro modo <i>primigenio</i>. Quizá con el código se vea más claro:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Definici&#243;n del modo 
</span><span style="color: #6272a4;">;;;</span><span style="color: #6272a4;">###</span><span style="color: #ffb86c; background-color: #373844;">autoload</span><span style="color: #6272a4;">
</span>(<span style="color: #ff79c6; font-weight: bold;">define-derived-mode</span> <span style="color: #50fa7b; font-weight: bold;">paws-mode</span>
  prog-mode <span style="color: #f1fa8c;">"Paws"</span>
  <span style="color: #6272a4;">"Toggle Paws mode.
Interactivamente sin argumento, este comando des/activa el modo."</span>
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Colorear sintaxis
</span>  (<span style="color: #ff79c6; font-weight: bold;">setq</span> font-lock-defaults '((paws-font-lock-keywords))))
</pre>
</div>

<p>
Antes de explicar nada quiero llamar la atención sobre el comentario
<i>«automágico»</i> <code>;;;###autoload</code>. <i>Autoload</i> es un mecanismo por el
cual <i>Emacs</i> conoce la existencia de, en este caso, <code>paws-mode</code> y lo
puede cargar la primera vez que es llamado el modo, aún sin tenerlo
cargado previamente en memoria. Es un poco de <i>azúcar sintáctico</i> para
la forma <code>(autoload ...)</code>. Si tenéis curiosidad en el manual viene
mejor explicado de lo que puedo hacer en cuatro líneas. 
</p>

<p>
Pero vamos a lo que estamos: en este caso, el <code>paws-mode</code> se ha
derivado del <code>prog-mode</code>, un modo básico que proporciona bastante
comportamiento esperado por los programadores. Además, si utilizas
algunos <i>hooks</i>, que yo utilizo en mi <code>init.el</code>, como por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-hook 'prog-mode-hook 'display-line-numbers-mode)
(add-hook 'prog-mode-hook 'auto-complete-mode)
</pre>
</div>

<p>
para activar el autocompletado y los números de línea, al
abrir cualquier archivo de cualquier lenguaje de programación, también
funcionarán en el nuevo modo.
</p>

<p>
Se pueden derivar otros tipos de <i>modo</i>, pues hay varios modos básicos
como, por ejemplo, <code>text-mode</code>, para distintos estilos de texto: de él
se derivan modos para <code>html</code> o <i>LaTeX</i>. También el modo <code>special-mode</code>
que está, principalmente, pensado para <i>buffers</i> generados por emacs
más que para contener un fichero.  Incluso hay otro modo
<code>tabulated-list-mode</code> para contener información en forma de tablas,
como pueden ser, por ejemplo, la lista de paquetes o varias de las
listas que genera <code>magit</code>. Pero no vamos a entrar más allá de informar
que existen y están ahí para ayudar.
</p>
<div id="outline-container-orgc0c5cd9" class="outline-2">
<h2 id="orgc0c5cd9">Coloreado de sintaxis</h2>
<div class="outline-text-2" id="text-orgc0c5cd9">
<p>
En nuestro caso, como es modo sencillo lo derivamos como he dicho
antes de <code>prog-mode</code> y en su definición lo único que necesitamos es
activar el <i>coloreado de sintaxis</i>. Y para eso asignamos a
<code>font-lock-defaults</code> una variable que hemos creado con los distintos
tipos de <i>palabras especiales</i> del lenguaje. Esa variable
<code>paws-font-lock-keywords</code> la definimos como sigue:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> paws-font-lock-keywords
      (<span style="color: #ff79c6; font-weight: bold;">let*</span> (
            <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">definir algunas categor&#237;as de keywords
</span>             (x-keywords '(<span style="color: #f1fa8c;">"define"</span> <span style="color: #f1fa8c;">"DONE"</span> <span style="color: #f1fa8c;">"GET"</span> <span style="color: #f1fa8c;">"DROP"</span> <span style="color: #f1fa8c;">"WEAR"</span> <span style="color: #f1fa8c;">"REMOVE"</span> <span style="color: #f1fa8c;">"CREATE"</span> <span style="color: #f1fa8c;">"DESTROY"</span> <span style="color: #f1fa8c;">"SWAP"</span>
                           <span style="color: #f1fa8c;">"PLACE"</span> <span style="color: #f1fa8c;">"PUTO"</span> <span style="color: #f1fa8c;">"PUTIN"</span> <span style="color: #f1fa8c;">"TAKEOUT"</span> <span style="color: #f1fa8c;">"DROPALL"</span> <span style="color: #f1fa8c;">"AUTOG"</span> <span style="color: #f1fa8c;">"AUTOD"</span> <span style="color: #f1fa8c;">"AUTOW"</span> <span style="color: #f1fa8c;">"AUTOR"</span>
                           <span style="color: #f1fa8c;">"AUTOP"</span> <span style="color: #f1fa8c;">"AUTOT"</span> <span style="color: #f1fa8c;">"BREAK"</span> <span style="color: #f1fa8c;">"COPYOO"</span> <span style="color: #f1fa8c;">"COPYOF"</span> <span style="color: #f1fa8c;">"COPYFO"</span> <span style="color: #f1fa8c;">"WHATO"</span> <span style="color: #f1fa8c;">"WEIGH"</span> <span style="color: #f1fa8c;">"SET"</span> <span style="color: #f1fa8c;">"BSET"</span>
                           <span style="color: #f1fa8c;">"OSET"</span> <span style="color: #f1fa8c;">"CLEAR"</span> <span style="color: #f1fa8c;">"OCLEAR"</span> <span style="color: #f1fa8c;">"PLUS"</span> <span style="color: #f1fa8c;">"MINUS"</span> <span style="color: #f1fa8c;">"LET"</span> <span style="color: #f1fa8c;">"ADD"</span> <span style="color: #f1fa8c;">"SUB"</span> <span style="color: #f1fa8c;">"COPYFF"</span> <span style="color: #f1fa8c;">"RANDOM"</span>
                           <span style="color: #f1fa8c;">"MOVE"</span> <span style="color: #f1fa8c;">"GOTO"</span> <span style="color: #f1fa8c;">"WEIGHT"</span> <span style="color: #f1fa8c;">"ABILITY"</span> <span style="color: #f1fa8c;">"MODE"</span> <span style="color: #f1fa8c;">"LINE"</span> <span style="color: #f1fa8c;">"GRAPHIC"</span> <span style="color: #f1fa8c;">"PROMPT"</span> <span style="color: #f1fa8c;">"INPUT"</span>
                           <span style="color: #f1fa8c;">"TIME"</span> <span style="color: #f1fa8c;">"PROTECT"</span> <span style="color: #f1fa8c;">"PRINT"</span> <span style="color: #f1fa8c;">"TURNS"</span> <span style="color: #f1fa8c;">"SC0RE"</span> <span style="color: #f1fa8c;">"CLS"</span> <span style="color: #f1fa8c;">"NEWLINE"</span> <span style="color: #f1fa8c;">"MES"</span> <span style="color: #f1fa8c;">"MESSAGE"</span>
                           <span style="color: #f1fa8c;">"SYSMESS"</span> <span style="color: #f1fa8c;">"PICTURE"</span> <span style="color: #f1fa8c;">"PAPEL"</span> <span style="color: #f1fa8c;">"TINTA"</span> <span style="color: #f1fa8c;">"BORDER"</span> <span style="color: #f1fa8c;">"CHARSET"</span> <span style="color: #f1fa8c;">"SAVEAT"</span>
                           <span style="color: #f1fa8c;">"BACKAT"</span> <span style="color: #f1fa8c;">"PRINTAT"</span> <span style="color: #f1fa8c;">"LISTOBJ"</span> <span style="color: #f1fa8c;">"LISTAT"</span> <span style="color: #f1fa8c;">"INVEN"</span> <span style="color: #f1fa8c;">"DESC"</span> <span style="color: #f1fa8c;">"END"</span> <span style="color: #f1fa8c;">"DONE"</span>
                           <span style="color: #f1fa8c;">"NOTDONE"</span> <span style="color: #f1fa8c;">"OK"</span> <span style="color: #f1fa8c;">"SAVE"</span> <span style="color: #f1fa8c;">"LOAD"</span> <span style="color: #f1fa8c;">"RAMSAVE"</span> <span style="color: #f1fa8c;">"RAMLOAD"</span> <span style="color: #f1fa8c;">"ANYKEY"</span> <span style="color: #f1fa8c;">"PAUSA"</span>
                           <span style="color: #f1fa8c;">"PARSE"</span> <span style="color: #f1fa8c;">"NEWTEXT"</span> <span style="color: #f1fa8c;">"SYNONYM"</span> <span style="color: #f1fa8c;">"BEEP"</span> <span style="color: #f1fa8c;">"PROCESS"</span> <span style="color: #f1fa8c;">"DOALL"</span> <span style="color: #f1fa8c;">"RESET"</span> <span style="color: #f1fa8c;">"EXTERN"</span>))
            (x-types '(<span style="color: #f1fa8c;">"noun"</span> <span style="color: #f1fa8c;">"verb"</span> <span style="color: #f1fa8c;">"adjective"</span> <span style="color: #f1fa8c;">"adverb"</span> <span style="color: #f1fa8c;">"preposition"</span> <span style="color: #f1fa8c;">"pronoun"</span> <span style="color: #f1fa8c;">"conjunction"</span>))
            (x-constants '(<span style="color: #f1fa8c;">"const"</span> <span style="color: #f1fa8c;">"pic"</span> <span style="color: #f1fa8c;">"grf"</span> <span style="color: #f1fa8c;">"msc"</span> <span style="color: #f1fa8c;">"snd"</span> <span style="color: #f1fa8c;">"flg"</span> <span style="color: #f1fa8c;">"obj"</span> <span style="color: #f1fa8c;">"loc"</span>))
            (x-events '(<span style="color: #f1fa8c;">"OREF"</span> <span style="color: #f1fa8c;">"ACTION"</span> <span style="color: #f1fa8c;">"WRITE"</span> <span style="color: #f1fa8c;">"WRITELN"</span> <span style="color: #f1fa8c;">"OBJECT"</span> <span style="color: #f1fa8c;">"ATTR"</span> <span style="color: #f1fa8c;">"LISTCONTENTS"</span>))
            (x-functions '(<span style="color: #f1fa8c;">"AT"</span> <span style="color: #f1fa8c;">"NOTAT"</span> <span style="color: #f1fa8c;">"ATGT"</span> <span style="color: #f1fa8c;">"ATLT"</span> <span style="color: #f1fa8c;">"PRESENT"</span> <span style="color: #f1fa8c;">"ABSENT"</span> <span style="color: #f1fa8c;">"WORN"</span> <span style="color: #f1fa8c;">"NOTWORN"</span> <span style="color: #f1fa8c;">"CARRIED"</span>
                           <span style="color: #f1fa8c;">"NOTCARR"</span> <span style="color: #f1fa8c;">"ISAT"</span> <span style="color: #f1fa8c;">"ISNOTAT"</span> <span style="color: #f1fa8c;">"ZERO"</span> <span style="color: #f1fa8c;">"OZERO"</span> <span style="color: #f1fa8c;">"NOTZERO"</span> <span style="color: #f1fa8c;">"ONOTZERO"</span> <span style="color: #f1fa8c;">"EQ"</span> <span style="color: #f1fa8c;">"NOTEQ"</span>
                           <span style="color: #f1fa8c;">"GT"</span> <span style="color: #f1fa8c;">"LT"</span> <span style="color: #f1fa8c;">"SAME"</span> <span style="color: #f1fa8c;">"NOTSAME"</span> <span style="color: #f1fa8c;">"ADJECT1"</span> <span style="color: #f1fa8c;">"ADVERB"</span> <span style="color: #f1fa8c;">"PREP"</span> <span style="color: #f1fa8c;">"NOUN2"</span> <span style="color: #f1fa8c;">"ADJECT2"</span> <span style="color: #f1fa8c;">"CHANCE"</span>
                           <span style="color: #f1fa8c;">"TIMEOUT"</span> <span style="color: #f1fa8c;">"QUIT"</span> <span style="color: #f1fa8c;">"ISNOTLIGHT"</span> <span style="color: #f1fa8c;">"OBJAT"</span> <span style="color: #f1fa8c;">"WHATOX"</span> <span style="color: #f1fa8c;">"WHATOX2"</span> <span style="color: #f1fa8c;">"BZERO"</span> <span style="color: #f1fa8c;">"BNOTZERO"</span>))

            <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">generar las cadenas regex para cada categor&#237;a de keywords
</span>            (x-keywords-regexp (regexp-opt x-keywords 'words))
            (x-types-regexp (regexp-opt x-types 'words))
            (x-constants-regexp (regexp-opt x-constants 'words))
            (x-events-regexp (regexp-opt x-events 'words))
            (x-functions-regexp (regexp-opt x-functions 'words)))

        `(
          (,x-types-regexp . font-lock-type-face)
          (,x-constants-regexp . font-lock-constant-face)
          (,x-events-regexp . font-lock-builtin-face)
          (,x-functions-regexp . font-lock-function-name-face)
          (,x-keywords-regexp . font-lock-keyword-face)
          )))
</pre>
</div>

<p>
Aún tenemos que depurar en qué categoría meteremos cada una de las
<i>keywords</i>, pero el código como se puede ver es muy fácil de entender
y muy básico: se definen una serie de variables locales que
representan las diferentes categorías, con <code>let*</code> y se rellenan con
las palabras que queremos que se coloreen. Después esas listas se
convierten con la función <code>regexp-opt</code> en las <i>expresiones regulares</i>
(<code>regexp</code>), que espera el código y se almacenan luego en una lista de
pares que asigna a cada uno su fuente correspondiente: <code>(regexp
. font)</code>.
</p>

<p>
Vale, la sintaxis de la lista de pares es rara y no la hemos visto
hasta ahora en nuestro <i>minicurso</i> de programación con <i>elisp</i>, pero
la explico en dos patadas:
</p>

<ul class="org-ul">
<li>Lo primero que llama la atención es que utilizamos el signo «`» en
lugar del habitual <code>quote</code> «'». Eso indica que dentro de la lista
encontraremos elementos que no son constantes, sino que se deben
calcular (en nuestro caso sustituir la variable por la cadena que
contiene: por su valor).</li>
<li>Luego, cada elemento que se tenga que calcular va precedido de un
carácter «,».</li>
</ul>

<p>
Con ese formato, por ejemplo, podemos hacer cosas como:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">`(una lista de ,(+ 2 3) elementos)
</pre>
</div>

<p>
que se convertirá en:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(una lista de 5 elementos)
</pre>
</div>

<p>
En nuestro caso, como he dicho antes, se ha utilizado esta sintaxis
para sustituir el nombre de cada variable, en cada uno de los
elementos por su valor correspondiente, pero sólo del primer término
de cada par.
</p>
</div>
<div id="outline-container-org56353c7" class="outline-3">
<h3 id="org56353c7">Comentarios</h3>
<div class="outline-text-3" id="text-org56353c7">
<p>
Ya hemos visto cómo hacer que las palabras especiales de <i>paws</i> se
coloreen, pero aún no hemos hecho nada con los comentarios. En este
caso me volví un poco loco (es el primer <i>modo mayor</i> que hago), y no
sabía que colorear los comentarios está separado del coloreado de
sintaxis como tal. Se mete en otra lista o tabla de sintaxis. Al final
también es sencillo de entender y fácil de hacer. El código es el
siguiente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> paws-mode-syntax-table
      (<span style="color: #ff79c6; font-weight: bold;">let</span> ((tabla (make-syntax-table)))
        (modify-syntax-entry ?\; <span style="color: #f1fa8c;">"&lt;"</span> tabla)
        (modify-syntax-entry ?\n <span style="color: #f1fa8c;">"&gt;"</span> tabla)
        tabla))
</pre>
</div>

<p>
Ese código lo que hace es crear una tabla de sintaxis mediante la
forma <code>make-syntax-table</code> y una vez creada se modifican dos elementos
con la forma <code>modify-syntax-entry</code>:
</p>

<ul class="org-ul">
<li>El carácter <code>;</code> indica en <code>paws</code> el inicio de los comentarios y se
marca con la expresión <code>"&lt;"</code> en la tabla para indicar que inicia el
comentario.</li>
<li>En <code>paws</code> el comentario se extiende hasta el final de la línea, por
tanto cuando se produce un salto de línea, <code>\n</code>, es el final de un
comentario, cuando acaba la línea, y se marca con la expresión
<code>"&gt;"</code>.</li>
</ul>
</div>
</div>
<div id="outline-container-orgbf5fbf7" class="outline-3">
<h3 id="orgbf5fbf7">Haciéndolo funcionar</h3>
<div class="outline-text-3" id="text-orgbf5fbf7">
<p>
Tenemos ya establecido las sintaxis y los comentarios en sus
correspondientes tablas, ahora necesitamos hacer que funcione:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">paws-mode-variables</span> (<span style="color: #8be9fd; font-style: italic;">&amp;opcional</span> syntax keywords-case-insensitive)
  (<span style="color: #ff79c6; font-weight: bold;">when</span> syntax
    (set-syntax-table paws-mode-syntax-table)))
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-org3695e54" class="outline-2">
<h2 id="org3695e54">Buscar código en la base de datos</h2>
<div class="outline-text-2" id="text-org3695e54">
<p>
Una de las cosas que facilita esa búsqueda es que todos los apartados
están marcados con una cabecera tipo <code>/XXX</code>; por ejemplo, por poner
sólo tres: <code>/CTL</code>, <code>/OTX</code> u <code>/OBJ</code>. Al buscar esos textos la marca se
moverá dentro del fichero con el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">buscar-apartado</span> (apartado)
  <span style="color: #6272a4;">"Busca el apartado correspondiente, dado por la cadena de texto."</span>
  (goto-char 1)
  (search-forward apartado))
</pre>
</div>

<p>
El sistema es sencillo, se va al primer carácter del <i>búffer</i> con
<code>goto-char</code> y luego se hace un <code>search-forward</code> hasta el apartado
correspondiente. Luego, llamaremos a esta función con algo tan simple
como <code>(buscar-apartado "/OBJ")</code> y ya está desvelado todo el secreto.
</p>
</div>
</div>
<div id="outline-container-org27ab5cb" class="outline-2">
<h2 id="org27ab5cb">Compilar</h2>
<div class="outline-text-2" id="text-org27ab5cb">
<p>
Para no irme por las ramas, pongo primero el código y luego lo
explico. El código es el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">compilar</span> ()
  <span style="color: #6272a4;">"Compila el fichero asociado con el buffer."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (message <span style="color: #f1fa8c;">"Compilando: %s"</span> (buffer-file-name))
  (<span style="color: #ff79c6; font-weight: bold;">if</span> (eq 0 (shell-command (concat paws-directorio-txtpaws <span style="color: #f1fa8c;">"/txtpaws "</span> (buffer-file-name))))
      (shell-command (concat paws-directorio-ngpc <span style="color: #f1fa8c;">"/ngpc "</span> (file-name-sans-extension buffer-file-name) <span style="color: #f1fa8c;">".sce"</span>))
    (message <span style="color: #f1fa8c;">"Fall&#243; el preprocesador de %s"</span> (buffer-file-name))))
</pre>
</div>

<p>
Bueno, tampoco hay mucho que explicar: se lanzan los binarios con
<code>shell-command</code>. Primero el <i>preprocesador</i>, comprobando si ha tenido
éxito con <code>eq 0</code>. Como decíamos antes, el preprocesador es <code>txtpaws</code> y
trabaja directamente con el fichero que editamos: <code>buffer-file-name</code>.
Si tiene éxito, luego hay que lanzar el compilador <code>ngpc</code>; sin
embargo, hay que hacerlo, no con el fichero que estamos editando, sino
con el fichero generado por el paso anterior, que tiene el mismo
nombre que el fichero del <i>buffer</i> (<code>file-name-sans-extension</code>) pero
con la extensión <code>.sce</code>.
</p>
</div>
</div>
<div id="outline-container-org20e916f" class="outline-2">
<h2 id="org20e916f">Otros pichorros y chismáticos</h2>
<div class="outline-text-2" id="text-org20e916f">
<p>
Pues eso, para facilitarnos la vida con esto de los modos es
conveniente crear combinaciones de teclas y menús que llevarse al
cursor del ratón. Esto es muy parecido, por no decir igual, que cuando
lo vimos en el ejemplo del modo menor, pero lo repito aquí:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Definir las combinaciones de teclas del modo
</span>(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">paws-mode-map</span>
  (<span style="color: #ff79c6; font-weight: bold;">let</span> ((paws-mode-map (make-keymap)))
    (define-key paws-mode-map <span style="color: #f1fa8c;">"\C-c\C-fd"</span> 'ir-define)
    (define-key paws-mode-map <span style="color: #f1fa8c;">"\C-c\C-fc"</span> 'ir-ctl)
    (define-key paws-mode-map <span style="color: #f1fa8c;">"\C-c\C-fv"</span> 'ir-voc)
    (define-key paws-mode-map <span style="color: #f1fa8c;">"\C-c\C-fs"</span> 'ir-stx)
    (define-key paws-mode-map <span style="color: #f1fa8c;">"\C-c\C-fm"</span> 'ir-mtx)
    (define-key paws-mode-map <span style="color: #f1fa8c;">"\C-C\C-ft"</span> 'ir-otx)
    (define-key paws-mode-map <span style="color: #f1fa8c;">"\C-C\C-fl"</span> 'ir-ltx)
    (define-key paws-mode-map <span style="color: #f1fa8c;">"\C-C\C-fn"</span> 'ir-con)
    (define-key paws-mode-map <span style="color: #f1fa8c;">"\C-C\C-fo"</span> 'ir-obj)
    (define-key paws-mode-map <span style="color: #f1fa8c;">"\C-C\C-fp"</span> 'ir-pro)
    (define-key paws-mode-map <span style="color: #f1fa8c;">"\C-C\C-j"</span>  'compilar)
    paws-mode-map)
  <span style="color: #6272a4;">"Kaymap para paws-mode."</span>)

(<span style="color: #ff79c6; font-weight: bold;">easy-menu-define</span> paws-menu paws-mode-map
  <span style="color: #6272a4;">"Men&#250; para el modo paws-mode."</span>
  '(<span style="color: #f1fa8c;">"Paws"</span>
    (<span style="color: #f1fa8c;">"Buscar secci&#243;n"</span>
     [<span style="color: #f1fa8c;">"Ir a defines"</span> ir-define]
     [<span style="color: #f1fa8c;">"Ir a /CTL"</span> ir-ctl]
     [<span style="color: #f1fa8c;">"Ir a /VOC"</span> ir-voc]
     [<span style="color: #f1fa8c;">"Ir a /STX"</span> ir-stx]
     [<span style="color: #f1fa8c;">"Ir a /MTX"</span> ir-mtx]
     [<span style="color: #f1fa8c;">"Ir a /OTX"</span> ir-otx]
     [<span style="color: #f1fa8c;">"Ir a /LTX"</span> ir-ltx]
     [<span style="color: #f1fa8c;">"Ir a /CON"</span> ir-con]
     [<span style="color: #f1fa8c;">"Ir a /OBJ"</span> ir-obj]
     [<span style="color: #f1fa8c;">"Ir a /PRO"</span> ir-pro])
    [<span style="color: #f1fa8c;">"--"</span> nil]
    [<span style="color: #f1fa8c;">"Compilar"</span> compilar]
    ))
</pre>
</div>

<p>
Básicamente, consiste en asociar las funciones que hemos definido con
los <i>pichorros</i> y <i>chismáticos</i> correspondiente. Creo que el código es
muy sencillo de entender y no voy a darle más vueltas.
</p>
</div>
</div>
<div id="outline-container-org802a342" class="outline-2">
<h2 id="org802a342">Instalación</h2>
<div class="outline-text-2" id="text-org802a342">
<p>
Sólo nos falta instalarlo y ajustarlo a nuestro sitio. Para funcionar,
el modo necesita conocer dónde se encuentran los binarios a los que
tiene que llamar. Para ello se han creado dos variables:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">paws-directorio-txtpaws</span> nil)
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">paws-directorio-ngpc</span>    nil)
</pre>
</div>

<p>
El tema es que están vacías, por lo que luego en nuestro <code>init.el</code>
debemos establecer esos parámetros para que funcione la
compilación. El código de configuración podría quedar de la siguiente
manera:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-to-list 'load-path <span style="color: #f1fa8c;">"~/proyectos/paws-mode"</span>)            <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Sitio donde est&#225; &#171;paws-mode&#187;
</span>(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">paws-mode</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> paws-directorio-ngpc <span style="color: #f1fa8c;">"~/proyectos/ngpaws"</span>)            <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Sitio donde est&#225; el binario &#171;ngpc&#187;
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> paws-directorio-txtpaws <span style="color: #f1fa8c;">"~/proyectos/ngpaws"</span>)         <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Sitio donde est&#225; el binario &#171;txtpaws&#187;
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> auto-mode-alist                                       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Hacer que la extensi&#243;n &#171;.txp&#187; enlace el modo paws
</span>      (append '((<span style="color: #f1fa8c;">"\\.txp\\'"</span> . paws-mode)) auto-mode-alist))
</pre>
</div>

<p>
Básicamente le decimos a <i>Emacs</i> dónde está instalado el modo y le
pedimos que lo cargue. Luego le decimos dónde están los ejecutables y
por último añadimos a la lista de modos automáticos la extensión de
los ficheros de <code>paws</code>: <code>.txp</code>. Cada vez que abramos un archivo con
extensión <code>.txp</code>, la que utiliza <code>paws</code>, se activará el modo
<code>paws-mode</code>.
</p>
</div>
</div>
<div id="outline-container-org15a14e6" class="outline-2">
<h2 id="org15a14e6">Conclusión</h2>
<div class="outline-text-2" id="text-org15a14e6">
<p>
Ha sido una casualidad que necesitara un modo mayor. Recuerdo que dije
que era algo más complicado y que no lo tocaríamos de momento, pero ya
metido en el tema, tenía que explicarlo. Espero que se haya entendido
todo.
</p>

<p>
Aparte de en el manual de <i>elisp</i>, podéis encontrar también
<a href="http://ergoemacs.org/emacs/elisp_syntax_coloring.html">más información sobre programar modos y coloreado de sintaxis</a> en los
sitios habituales de <i>Internet</i>.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/elisp/index.html">elisp</a> <a href="/tags/conversacionales/index.html">conversacionales</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[elisp]]></category>
  <category><![CDATA[conversacionales]]></category>
  <link>https://notxor.nueva-actitud.org/2019/03/14/creacion-de-un-modo-mayor-para-emacs.html</link>
  <pubDate>Thu, 14 Mar 2019 18:15:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Un informe desvela que el 80% de los niños y adolescentes con trastorno de ansiedad no recibe tratamiento]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-03-01</div>
<p>
<a href="http://www.infocop.es/view_article.asp?id=7689">Leo con preocupación en la página de Infocop</a> que el Instituto de la
Mente Infantil (<i>Child Mind Institute</i>), una organización
estadounidense sin ánimo de lucro que se preocupa por la salud mental
de los niños y por los trastornos de aprendizaje, afirma en la edición
de 2018 que <b>los diagnósticos de trastornos de ansiedad en menores de
17 años ha aumentado</b> en los últimos 10 años, pasando de un 3,5% un
4,1% en la actualidad.
</p>

<p>
La sintomatología de la ansiedad es amplia, algunos niños reaccionan
con miedo o evitación de determinadas situaciones u objetos, mientras
otros pueden mostrar comportamiento explosivo que se pude interpretar
erróneamente como hostil.
</p>

<p>
En casos en que los jóvenes presentan fobias o trastorno de ansiedad
antes situaciones sociales, sus problemas se pueden atribuir a
«timidez», ya que muy pocos reconocen la grave angustia que
experimentan. Incluso muchos de ellos no se dan cuenta de que sus
reacciones derivan de un problema que puede tratarse de manera
eficaz.
</p>

<p>
Las conclusiones que copio de dicho artículo son las siguientes:
</p>

<ul class="org-ul">
<li>En la infancia y la adolescencia, <b>los trastornos de ansiedad son
los más habituales</b>, tanto en los Estados Unidos como en todo el
mundo. De hecho, su reconocimiento clínico ha aumentado en la última
década, registrándose un aumento de los diagnósticos de trastorno de
ansiedad en jóvenes menores de 17 años, que han pasado del 3,5% a un
4,1% en la actualidad.</li>

<li>Aproximadamente, 117 millones de niños y adolescentes en todo el
mundo han sufrido un trastorno de ansiedad. Aunque cerca del 10% de
los jóvenes de 6 a 17 años presentan actualmente un trastorno de
ansiedad, <b>al inicio de su edad adulta, casi el 20% tendrá
dificultades funcionales</b> relacionadas con la ansiedad en al menos
una área de su vida. En los niños, los trastornos de ansiedad pueden
afectar todos los aspectos de su vida, pero particularmente su
funcionamiento social y educativo.</li>

<li>El <b>porcentaje de adolescentes</b> estadounidenses que cumplirán los
criterios para un trastorno de ansiedad es del 13% para la fobia
específica, 9% para un Trastorno de ansiedad social, 8% para la
ansiedad por separación, 2% para el trastorno de pánico, y 2% para
el trastorno de ansiedad generalizada. Sin tratamiento, muchos
subtipos persisten en la edad adulta.</li>

<li><p>
Actualmente, los estudiantes de secundaria presentan más síntomas de
ansiedad, y tienen el doble de probabilidades de acudir a un
profesional de salud mental que en la década de los 80.
</p>

<p>
La ansiedad es la <b>principal causa de preocupación en los servicios
de orientación universitaria</b>, superando a la depresión como la
principal demanda entre los estudiantes universitarios que acuden a
los servicios de salud mental, siendo la ansiedad la preocupación
más frecuente (48%), seguida del estrés (39%).
</p></li>

<li>Uno de los <b>factores de riesgo</b> más fuerte y que se detecta en
primer lugar, es el temperamento. Algunas investigaciones ponen de
relieve el vínculo entre el temperamento temprano y los patrones de
comportamiento posteriores: la inhibición de la conducta en los
primeros años de vida predice el aislamiento social en la
infancia. Los datos al respecto sugieren que el 15% de los
adolescentes que presentan una conducta inhibida, tienen cinco veces
más probabilidades de desarrollar ansiedad social que aquellos que
no la tienen. Asimismo, el 61% de los adolescentes que a los 2 años
ya mostraban una conducta inhibida, presentan signos de ansiedad
social a la edad de 13 años, al interactuar con adultos
desconocidos.</li>

<li>Muchos niños cuya ansiedad es causante de una angustia severa, por
ejemplo, aquellos con mutismo selectivo, son etiquetados como «niños
tímidos». A este respecto, el informe advierte «de la preocupación
generalizada por medicalizar toda timidez». Por ello, subraya la
importancia de <b>distinguir entre timidez normal y ansiedad clínica</b>,
recordando que, según algunos estudios, alrededor del 50% de los
adolescentes se consideran «tímidos», y, sin embargo, solo el 12% de
esos adolescentes tímidos cumplen criterios para un trastorno de
ansiedad social.</li>

<li>Los trastornos de ansiedad se manifiestan en <b>diferentes momentos de
la infancia y la adolescencia</b>. La ansiedad por separación afecta
principalmente a los niños más pequeños (10,6 años), mientras que la
ansiedad social se presenta más adelante, cuando las relaciones
entre iguales cobran más importancia (14 años). En el caso del
trastorno de ansiedad social, una edad más temprana de inicio se
relaciona con una mayor severidad en años ulteriores.</li>

<li>Con respecto al <b>género</b>, las mujeres tienen un mayor riesgo de
trastornos de ansiedad, y esta diferencia de género comienza en la
pubertad. Las adolescentes tienen el doble de probabilidades de
tener un trastorno de ansiedad.</li>

<li>Los <b>factores de riesgo genéticos</b> juegan un papel particularmente
importante en el trastorno de pánico y el trastorno de ansiedad
generalizada. Los hijos de padres ansiosos tienen cinco veces más
probabilidades de desarrollar un trastorno de ansiedad.</li>

<li>El inicio del trastorno de ansiedad social en adolescentes se
relaciona con un <b>evento estresante</b>. La mitad de todos los adultos
con trastorno de ansiedad social puede señalar un evento embarazoso
específico durante su adolescencia que lo inició, mientras que un
tercio identifica un evento extremadamente estresante que
probablemente desempeñó un rol esencial.</li>

<li><p>
Los trastornos de ansiedad <b>se asocian con frecuencia a problemas
médicos</b>. Hay estudios que ponen de manifiesto una asociación
significativa entre el asma y los trastornos de ansiedad, cuyas
tasas se incrementan con la gravedad de los síntomas físicos.
</p>

<p>
Las afecciones alérgicas y los trastornos de ansiedad pueden ser el
resultado de factores de riesgo subyacentes comunes. Algunas
investigaciones revelan una relación entre los trastornos atópicos
(incluidos el eccema y la fiebre del heno) y la ansiedad. Asimismo,
la ansiedad a los 5 años se asocia con asma severa y persistente en
la adolescencia.
</p></li>

<li>Los trastornos de ansiedad en la infancia están estrechamente
relacionados con un mayor riesgo de depresión, ansiedad, problemas
de conducta y abuso de sustancias posteriores:

<dl class="org-dl">
<dt>Depresión</dt><dd>El trastorno de ansiedad social tiene una elevada
correlación con el desarrollo de depresión: el doble
que en otros trastornos de ansiedad y el triple en
comparación con los jóvenes sin ansiedad. El
trastorno de ansiedad social con inicio en la
infancia y la adolescencia provoca un inicio más
temprano de la depresión y un funcionamiento social
deficiente. En la adolescencia, cuando la depresión
cursa simultáneamente con la ansiedad social, está
fuertemente asociada con ideas suicidas, intentos de
suicidio y más síntomas depresivos.</dd>

<dt>Ansiedad a largo plazo</dt><dd>La ansiedad infantil es un fuerte
predictor de un trastorno de ansiedad durante la adolescencia:
el trastorno de ansiedad por separación infantil predice la
ansiedad de separación adolescente. El trastorno de ansiedad
generalizada se asocia también con ansiedad y ataques de pánico
posteriores. El trastorno de ansiedad social en los niños está
asociado con el trastorno de ansiedad generalizada de los
adolescentes, la ansiedad social continua y el TDAH.</dd>

<dt>Abuso de sustancias</dt><dd>El riesgo de trastorno por uso de
sustancias se duplica en los trastornos de ansiedad. Los
trastornos de ansiedad en la niñez, incluidos el pánico y la
ansiedad social, están relacionados con un mayor riesgo de
consumo de sustancias, en particular el abuso y la dependencia
del alcohol.</dd>

<dt>Problemas de conducta</dt><dd><p>
Múltiples estudios han evidenciado
también un vínculo entre los síntomas de ansiedad temprana y el
desarrollo posterior de problemas de comportamiento y conductas
disruptivas.
</p>

<p>
La fobia social no tratada se asocia con una serie de
consecuencias negativas, entre ellas, un bajo rendimiento
escolar y laboral, el abandono escolar y el desempleo.
</p>

<p>
Los niños cuya ansiedad se manifiesta en forma de rabietas,
oposición o arrebatos violentos, se encuentran, a menudo, con
problemas disciplinarios, con visitas a emergencias, etc.
</p></dd>
</dl></li>

<li><p>
Existe una creciente obsesión entre los adolescentes con el entorno
que les permite conectarse con sus amigos. Los datos de 2018
referentes a la <b>prevalencia y hábitos del uso de las redes sociales</b>
entre adolescentes, revelan que el 95% tiene un teléfono inteligente
y el 45% están online «casi constantemente» (en comparación con el
24% en 2014).
</p>

<p>
El 24% de los adolescentes considera que las redes tienen un impacto
negativo, siendo la razón principal la propagación de rumores y el
<i>bullying</i>. Para el 31%, las redes sociales tienen un efecto
mayormente positivo, al facilitar la conexión con amigos y
familiares.
</p></li>

<li><p>
El 97% de los jóvenes de entre 11 y 17 años utilizan las redes
sociales. El 35% de ellos, revelan problemas de sueño, y el 47%
ansiedad. De hecho, una <b>mayor inversión emocional en las redes
sociales, se correlaciona fuertemente con niveles más elevados de
ansiedad</b>: la cantidad de tiempo dedicado al uso de las redes
sociales se relaciona directamente con mayores síntomas de ansiedad
y una alta probabilidad de cumplir los criterios para un trastorno
de ansiedad.
</p>

<p>
Los autores del informe sugieren dos teorías que podrían explicar
este fenómeno: las redes sociales pueden ser una fuente de estrés
que contribuye a los síntomas de ansiedad, o los jóvenes con
ansiedad elevada tienden a involucrarse en un mayor uso de las redes
sociales, tal vez, como una forma de reafirmación que busca aliviar
los síntomas de ansiedad.
</p></li>

<li><p>
En cuanto a la <b>detección y prevención</b>, la mayoría de las personas
que experimentan un trastorno de ansiedad no buscan tratamiento,
particularmente aquellos con síntomas menos severos. De acuerdo con
este informe, es fundamental garantizar que los casos leves y
moderados accedan a la atención basada en la evidencia, evitando así
una carga sustancial.
</p>

<p>
Desafortunadamente, los trastornos de ansiedad a menudo pasan
desapercibidos: <b>tan solo el 1% de los jóvenes con ansiedad busca
tratamiento</b> en el año en que comienzan sus síntomas, y la mayoría de
los síntomas de ansiedad no se tratan durante años.
</p>

<p>
A pesar de que se diagnostican más niños, aún hay muchos que no se
detectan ─y, por tanto, no reciben tratamiento─, debido a la falta
de signos externalizantes y/o porque los jóvenes tienen dificultades
para identificar cuándo la ansiedad que presentan no es normal.
</p>

<p>
El primer paso para ayudar a los jóvenes es <b>identificar
correctamente los síntomas de ansiedad</b>. Esta suele confundirse con
otros trastornos, lo que resulta en un tratamiento ineficaz. Algunos
errores comunes de diagnóstico son los Trastornos del aprendizaje,
el TDAH, la Depresión, el Autismo, la Psicosis y el trastorno
negativista desafiante.
</p>

<p>
Hay algunas investigaciones que sugieren que la prevención
(intervención antes de que un niño en riesgo o ansioso desarrolle un
trastorno de ansiedad completo) es eficaz en niños en edad escolar y
adultos jóvenes. Las intervenciones con programas de prevención
comunitarios dirigidos a jóvenes adultos han mostrado su eficacia,
reduciendo los síntomas de ansiedad en un 60%.
</p></li>

<li><p>
Con respecto al tratamiento, los datos ponen de manifiesto que los
adolescentes y sus padres están comenzando a reconocer que los
trastornos de ansiedad pueden llegar a ser graves, y cada vez son
más familias las que buscan atención y tratamiento. Sin embargo,
pese a la creciente conciencia, <b>la proporción de jóvenes que
reciben tratamiento sigue siendo la más baja de todas las
principales categorías de trastornos de salud mental</b>, muy por
debajo de la prevalencia de ansiedad en la población: «en algún
momento, el 30% de los niños y adolescentes cumplirán los criterios
para un trastorno de ansiedad, pero el 80% nunca recibirá ayuda».
</p>

<p>
En este punto, el informe pone de relieve el <b>papel de la terapia
cognitivo-conductual</b> en el tratamiento de los trastornos de
ansiedad. En esta línea, la exposición y prevención de respuesta es
un tipo de TCC que funciona al ayudar a los niños a abordar su
ansiedad y sus temores en pasos incrementales, dentro de un entorno
seguro y controlado. Los beneficios del tratamiento cognitivo
conductual se mantienen a largo plazo en el 93% de los niños y
adolescentes.
</p>

<p>
En relación con las intervenciones cognitivo conductuales online,
algunas investigaciones han demostrado que los pacientes son más
abiertos y honestos con respecto a sus síntomas cuando interactúan
con «humanos virtuales» y no creen que sean observados o juzgados.
</p>

<p>
La <b>meditación con conciencia plena</b> se está introduciendo cada vez
más en una amplia variedad de contextos (escuela, salud mental
clínica) para ayudar a los jóvenes a manejar el estrés, la
emotividad y las conductas problemáticas.
</p>

<p>
La familia juega un papel esencial en la respuesta al
tratamiento. La <b>terapia con pautas para padres y madres</b> está
mostrando resultados beneficiosos, produciendo una alta satisfacción
en los padres, que informan de una reducción en los síntomas
infantiles (el 60% de los niños presentan mejores resultados después
de que sus padres sigan una terapia parental).
</p></li>
</ul>

<p>
El informe se encuentra disponible a través de la página
<a href="https://childmind.org/our-impact/childrens-mental-health-report/2018report/">Web del Instituto</a>, o bien a través del siguiente enlace:
</p>

<div class="org-center">
<p>
<a href="http://www.infocoponline.es/pdf/ANSIEDAD.pdf">Understanding Anxiety in Children and Teens</a>
</p>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/psicología/index.html">psicología</a> <a href="/tags/infancia/index.html">infancia</a> ]]></description>
  <category><![CDATA[psicología]]></category>
  <category><![CDATA[infancia]]></category>
  <link>https://notxor.nueva-actitud.org/2019/03/01/un-informe-desvela-que-el-80-de-los-ninos-y-adolescentes-con-trastorno-de-ansiedad-no-recibe-tratamiento.html</link>
  <pubDate>Fri, 01 Mar 2019 19:58:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Reorganizar las capturas de la agenda con plantillas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-02-27</div>
<p>
Llevo tiempo oyendo hablar de GTD<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> como una forma de organizarse
las tareas y flujo de trabajo que consigue aumentar la productividad y
reducir el estrés. Sin embargo, no ha sido hasta hace unas semanas que
me he propuesto empezar a aplicarlo a mi caso. Mi vida se ha ido
complicando ─complicándomela yo sólo, se entiende─ y necesito un mejor
control de las cosas que debo hacer. Entiendo que GTD me servirá para
eso ─y algunos ya me han dicho que o me sirve o no habrá nada que me
sirva─. Llevo muy poco estudiado sobre el tema de cómo funciona el
sistema, pero lo poco que llevo hace énfasis en la captura de tareas.
</p>

<p>
Tengo que anotar tareas para varios aspectos de mi vida: las cosas del
<i>trabajo</i>, las cosas de la <i>asociación</i> con la que colaboro, otras
cosas que son <i>personales</i> y otras relacionadas con la <i>Frateco</i> de
esperanto. Las tareas por tanto, llevarán las etiquetas
correspondientes a esos aspectos y se anotarán todas en la agenda,
para que estén juntas, pero no revueltas.
</p>

<p>
Ayer mismo, el amigo <i>Rui Figueiredo</i> me enlazaba <a href="https://github.com/sk8ingdom/.emacs.d/blob/master/org-mode-config/org-capture-templates.el">un fichero de
captura bastante interesante y completo</a> que me ha hecho replantearme
lo que tenía ya hecho, añadiendo algunas cosas y cambiando el cómo lo
hacía también. El resultado completo, de cómo han quedado mis
plantillas para hacer la captura, lo pongo al final del artículo.
</p>

<p>
La primera decisión ha sido sacar las plantillas de captura del
<code>init.el</code> y las he puesto en un fichero, dentro del mismo directorio
donde tengo la agenda. ¿Por qué? Pues básicamente porque de momento lo
quiero compartir entre dispositivos, igual que comparto la agenda,
para ir haciendo modificaciones según vaya aprendiendo cómo funciona
el GTD. Además, ha quedado un listado bastante largo y hace más
confuso el fichero de configuración de <i>Emacs</i> así que la decisión
redunda también en mayor claridad del código.
</p>

<p>
Básicamente, las plantillas están divididas en tres grupos
principales:
</p>

<ol class="org-ol">
<li><b>Tareas pendientes</b>. Son las tareas que hay que hacer pero no
tienen una fecha determinada para hacerlas. Son ese tipo de cosas
que me he responsabilizado a hacer (<i>no hace falta que me lo
recuerdes cada seis meses</i>).</li>
<li><b>Tareas a la espera</b>. Son las tareas que hay que hacer pero no
dependen de uno mismo, bien porque están delegadas en otras
personas, bien porque dependen de otra tarea anterior, o por
cualquier otro motivo, están esperando que se las complete.</li>
<li><b>Tareas con fecha límite</b>. Algunas de las tareas tienen una fecha
concreta en las que tienen que estar realizadas, o bien un momento
concreto en las que hacerlas. Por ejemplo, las reuniones, las
conferencias y algunas otras cosas que hago, como charlas en
colegios o sesiones clínicas, son las típicas que se encontrarán
aquí.</li>
</ol>

<p>
Además, como he dicho antes, necesito saber cuándo una tarea pertenece
a qué <i>aspecto</i> de mi vida. Y tengo varios:
</p>

<ol class="org-ol">
<li><i>Trabajo</i>. Todas las acciones y tareas destinadas a ingresar dinero
en mi cuenta corriente.</li>
<li><i>Asociación</i>. Colaboro con una asociación que se llama <i>Protección
a la Infancia Contra el Abuso</i>. Les echo una mano como psicólogo,
aunque también con otras tareas.</li>
<li><i>Personal</i>. Todas las demás acciones, que no son del trabajo ni de
la asociación. Por ejemplo, todas las cosas que hago relacionadas
con el <i>Esperanto</i>.</li>
</ol>
<div id="outline-container-orgeeafa93" class="outline-2">
<h2 id="orgeeafa93">Capturas que no son para la agenda</h2>
<div class="outline-text-2" id="text-orgeeafa93">
<p>
Teniendo ya la inercia de capturar cosas y copiándome un poco de los
sistemas de captura que he encontrado por ahí, decidí tener también la
posibilidad de capturar información que no tiene que ver con la
agenda, o con las tareas. También puedo capturar anotaciones en un
fichero especial que he llamado <code>bitacora.org</code>. En él tengo dos tipos
de anotaciones:
</p>

<ol class="org-ol">
<li><p>
<b>Notas</b>. En el <i>diario</i> se pueden hacer anotaciones que me gusta
ordenar por fechas y por eso, lo he metido de la siguiente forma:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #f1fa8c;">"nd"</span> <span style="color: #f1fa8c;">"Anotar (d) diario"</span> entry (file+headline <span style="color: #f1fa8c;">"~/agenda/bitacora.org"</span> <span style="color: #f1fa8c;">"Diario"</span>)
<span style="color: #f1fa8c;">"** %U
%?"</span> <span style="color: #8be9fd; font-style: italic;">:empty-lines</span> 1)
</pre>
</div></li>

<li><p>
<b>Ideas</b>. Hay veces que se me ocurre alguna idea que no puedo
desarrollar en ese momento. Ideas, por ejemplo, para artículos del
<i>blog</i>, o para los <i>sienes y sienes</i> de proyectos, aventuras
conversacionales y otras historias que tengo.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #f1fa8c;">"ni"</span> <span style="color: #f1fa8c;">"Anotar (i) idea"</span> entry (file+headline <span style="color: #f1fa8c;">"~/agenda/bitacora.org"</span> <span style="color: #f1fa8c;">"Ideas"</span>)
 <span style="color: #f1fa8c;">"** Idea para %^{Tema}
  :PROPERTIES:
  :Tema:      %\\1
  :fecha:     %U
  :END:
%?"</span> <span style="color: #8be9fd; font-style: italic;">:empty-lines</span> 1)
</pre>
</div></li>
</ol>

<p>
Al utilizar esta última plantilla, el sistema de captura me preguntará
por el <i>Tema</i> y luego me dejará escribir lo que sea, marcándolo con la
fecha correspondiente.
</p>

<p>
Sin embargo, el gran avance de lo que he copiado (<i>adaptado</i>) de otros
sistemas de captura es la posibilidad de tomar datos personales.
Aunque utilizo como base de datos el <code>BBDB</code>. Porque funciona, porque
está completo, me permite importar y exportar a <code>vcard</code>, mientras que
otros sistemas en <code>org-mode</code> sólo me permiten importar.  Normalmente,
cuando tomo notas de datos personales lo hago directamente a la base
de datos, pero en ocasiones no la tengo a mano, porque está guardada
en un disco externo encriptado y a veces no lo tengo montado. Así que
he planteado la siguiente solución con las plantillas de captura:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #f1fa8c;">"nc"</span> <span style="color: #f1fa8c;">"Anotar (c) contacto"</span> entry (file <span style="color: #f1fa8c;">"~/agenda/especiales/personal.org.gpg"</span>)
 <span style="color: #f1fa8c;">"* %^{Nombre} %^{Apellidos}%?
  :PROPERTIES:
  :Nombre:     %\\1
  :Apellidos:  %\\2
  :F-nacim:    %^{F-nacim}u
  :M&#243;vil:      %^{M&#243;vil}
  :Email:      %^{Email}
  :Web:
  :Direcci&#243;n:  %^{Direcci&#243;n}
  :Ciudad:     %^{Ciudad}
  :Provincia:  %^{Provincia}
  :C&#243;d.Pos:    %^{C&#243;digo Postal}
  :Compa&#241;&#237;a:
  :Trab-Grupo:
  :Trab-puesto:
  :Trab-Tel.:
  :Trab-Email:
  :Trab-Web:
  :Trab-Direcci&#243;n:
  :Trab-Oficina:
  :Trab-ciudad:
  :Trab-Provincia:
  :Trab-CP:
  :Notas:
  :END:"</span> <span style="color: #8be9fd; font-style: italic;">:empty-lines</span> 1)
</pre>
</div>

<p>
Como se puede ver, la captura va a un fichero especial que he llamado
<code>personal.org.gpg</code> porque se encuentra cifrado con <code>GPG</code>.  Los datos
se guardan, por tanto a buen recaudo hasta que los pueda pasar a la
base de datos junto con todos los demás.
</p>

<p>
Los códigos del estilo <code>%^{Nombre}</code> lo que hacen es decirle a
<code>org-capture</code> que debe preguntar por un dato <code>Nombre</code> que el usuario
debe introducir en el <i>buffer</i>. Los códigos del estilo <code>%\\1</code> lo que
hace es sustituir ese código por el parámetro <code>1</code>, en nuestro caso el
nombre, que introduzca el usuario.
</p>

<p>
Y por último, el cursor se quedará, una vez introducidos todos los
campos que se han marcado interactivamente, en la posición indicada
por los caracteres <code>%?</code>.
</p>
</div>
</div>
<div id="outline-container-orgcae3494" class="outline-2">
<h2 id="orgcae3494">El fichero de plantillas completo</h2>
<div class="outline-text-2" id="text-orgcae3494">
<p>
Este es el resultado:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Capturar cualquier cosa a formato org-mode
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> org-capture-templates
              <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Es una lista de listas as&#237; que vamos por partes
</span>      '((<span style="color: #f1fa8c;">"t"</span> <span style="color: #f1fa8c;">"Tarea Pendiente"</span>)
        (<span style="color: #f1fa8c;">"tt"</span> <span style="color: #f1fa8c;">"Tarea Simple    (t) trabajo"</span> entry (file <span style="color: #f1fa8c;">"~/agenda/agenda.org"</span>)
         <span style="color: #f1fa8c;">"* PENDIENTE %? \t :trabajo:
   :PROPERTIES:
   :CREATE:      %U
   :END:
   :LOGBOOK:
   - State  \"PENDIENTE\"            from \"\"      %U
   :END:"</span> <span style="color: #8be9fd; font-style: italic;">:empty-lines</span> 1)
        (<span style="color: #f1fa8c;">"ta"</span> <span style="color: #f1fa8c;">"Tarea Simple    (a) asociaci&#243;n"</span> entry (file+headline <span style="color: #f1fa8c;">"~/agenda/agenda.org"</span> <span style="color: #f1fa8c;">"Asociaci&#243;n"</span>)
         <span style="color: #f1fa8c;">"* PENDIENTE %? \t :asociaci&#243;n:
   :PROPERTIES:
   :CREATE:       %U
   :END:
   :LOGBOOK:
   - State  \"PENDIENTE\"            from \"\"      %U
   :END:"</span> <span style="color: #8be9fd; font-style: italic;">:empty-lines</span> 1)
        (<span style="color: #f1fa8c;">"tp"</span> <span style="color: #f1fa8c;">"Tarea Simple    (a) personal"</span> entry (file+headline <span style="color: #f1fa8c;">"~/agenda/agenda.org"</span> <span style="color: #f1fa8c;">"Personal"</span>)
         <span style="color: #f1fa8c;">"* PENDIENTE %? \t :personal:
   :PROPERTIES:
   :CREATE:       %U
   :END:
   :LOGBOOK:
   - State  \"PENDIENTE\"            from \"\"      %U
   :END:"</span> <span style="color: #8be9fd; font-style: italic;">:empty-lines</span> 1)
 <span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Capturar tareas que pasan a estar a la espera
</span>        (<span style="color: #f1fa8c;">"e"</span> <span style="color: #f1fa8c;">"Tarea a la espera"</span>)
        (<span style="color: #f1fa8c;">"et"</span> <span style="color: #f1fa8c;">"Tarea Simple    (t) trabajo"</span> entry (file <span style="color: #f1fa8c;">"~/agenda/agenda.org"</span>)
         <span style="color: #f1fa8c;">"* ESPERANDO %? \t :trabajo:
   :PROPERTIES:
   :CREATE:      %U
   :END:
   :LOGBOOK:
   - State  \"ESPERANDO\"            from \"\"      %U
   :END:"</span> <span style="color: #8be9fd; font-style: italic;">:empty-lines</span> 1)
        (<span style="color: #f1fa8c;">"ea"</span> <span style="color: #f1fa8c;">"Tarea Simple    (a) asociaci&#243;n"</span> entry (file+headline <span style="color: #f1fa8c;">"~/agenda/agenda.org"</span> <span style="color: #f1fa8c;">"Asociaci&#243;n"</span>)
         <span style="color: #f1fa8c;">"* ESPERANDO %? \t :asociaci&#243;n:
   :PROPERTIES:
   :CREATE:       %U
   :END:
   :LOGBOOK:
   - State  \"ESPERANDO\"            from \"\"      %U
   :END:"</span> <span style="color: #8be9fd; font-style: italic;">:empty-lines</span> 1)
        (<span style="color: #f1fa8c;">"ep"</span> <span style="color: #f1fa8c;">"Tarea Simple    (p) personal"</span> entry (file+headline <span style="color: #f1fa8c;">"~/agenda/agenda.org"</span> <span style="color: #f1fa8c;">"Personal"</span>)
         <span style="color: #f1fa8c;">"* ESPERANDO %? \t :personal:
   :PROPERTIES:
   :CREATE:       %U
   :END:
   :LOGBOOK:
   - State  \"ESPERANDO\"            from \"\"      %U
   :END:"</span> <span style="color: #8be9fd; font-style: italic;">:empty-lines</span> 1)
 <span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Capturas que tienen &#171;deadline&#187; asociada
</span>        (<span style="color: #f1fa8c;">"l"</span> <span style="color: #f1fa8c;">"Tarea con fecha l&#237;mite"</span>)
        (<span style="color: #f1fa8c;">"lt"</span> <span style="color: #f1fa8c;">"Tarea    (t) trabajo"</span> entry (file <span style="color: #f1fa8c;">"~/agenda/agenda.org"</span>)
         <span style="color: #f1fa8c;">"* PENDIENTE %? \t :trabajo:
   DEADLINE: %(substring (call-interactively 'org-deadline) 12)
   :PROPERTIES:
   :CREATE:      %U
   :END:
   :LOGBOOK:
   - State  \"PENDIENTE\"            from \"\"      %U
   :END:"</span> <span style="color: #8be9fd; font-style: italic;">:empty-lines</span> 1)
        (<span style="color: #f1fa8c;">"la"</span> <span style="color: #f1fa8c;">"Tarea    (a) asociaci&#243;n"</span> entry (file+headline <span style="color: #f1fa8c;">"~/agenda/agenda.org"</span> <span style="color: #f1fa8c;">"Asociaci&#243;n"</span>)
         <span style="color: #f1fa8c;">"* PENDIENTE %? \t :asociaci&#243;n:
   DEADLINE: %(substring (call-interactively 'org-deadline) 12)
   :PROPERTIES:
   :CREATE:       %U
   :END:
   :LOGBOOK:
   - State  \"PENDIENTE\"            from \"\"      %U
   :END:"</span> <span style="color: #8be9fd; font-style: italic;">:empty-lines</span> 1)
        (<span style="color: #f1fa8c;">"lp"</span> <span style="color: #f1fa8c;">"Tarea    (p) personal"</span> entry (file+headline <span style="color: #f1fa8c;">"~/agenda/agenda.org"</span> <span style="color: #f1fa8c;">"Personal"</span>)
         <span style="color: #f1fa8c;">"* PENDIENTE %? \t :personal:
   DEADLINE: %(substring (call-interactively 'org-deadline) 12)
   :PROPERTIES:
   :CREATE:       %U
   :END:
   :LOGBOOK:
   - State  \"PENDIENTE\"            from \"\"      %U
   :END:"</span> <span style="color: #8be9fd; font-style: italic;">:empty-lines</span> 1)
 <span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Templates de captura para cosas que no son para la agenda
</span>        (<span style="color: #f1fa8c;">"n"</span> <span style="color: #f1fa8c;">"Capturas no para agenda"</span>)
        (<span style="color: #f1fa8c;">"nc"</span> <span style="color: #f1fa8c;">"Anotar (c) contacto"</span> entry (file <span style="color: #f1fa8c;">"~/agenda/especiales/personal.org.gpg"</span>)
         <span style="color: #f1fa8c;">"* %^{Nombre} %^{Apellidos}%?
  :PROPERTIES:
  :Nombre:     %\\1
  :Apellidos:  %\\2
  :F-nacim:    %^{F-nacim}u
  :M&#243;vil:      %^{M&#243;vil}
  :Email:      %^{Email}
  :Web:
  :Direcci&#243;n:  %^{Direcci&#243;n}
  :Ciudad:     %^{Ciudad}
  :Provincia:  %^{Provincia}
  :C&#243;d.Pos:    %^{C&#243;digo Postal}
  :Compa&#241;&#237;a:
  :Trab-Grupo:
  :Trab-puesto:
  :Trab-Tel.:
  :Trab-Email:
  :Trab-Web:
  :Trab-Direcci&#243;n:
  :Trab-Oficina:
  :Trab-ciudad:
  :Trab-Provincia:
  :Trab-CP:
  :Notas:
  :END:"</span> <span style="color: #8be9fd; font-style: italic;">:empty-lines</span> 1)
        (<span style="color: #f1fa8c;">"nd"</span> <span style="color: #f1fa8c;">"Anotar (d) diario"</span> entry (file+headline <span style="color: #f1fa8c;">"~/agenda/bitacora.org"</span> <span style="color: #f1fa8c;">"Diario"</span>)
         <span style="color: #f1fa8c;">"** %U
%?"</span> <span style="color: #8be9fd; font-style: italic;">:empty-lines</span> 1)
        (<span style="color: #f1fa8c;">"ni"</span> <span style="color: #f1fa8c;">"Anotar (i) idea"</span> entry (file+headline <span style="color: #f1fa8c;">"~/agenda/bitacora.org"</span> <span style="color: #f1fa8c;">"Ideas"</span>)
         <span style="color: #f1fa8c;">"** Idea para %^{Tema}
   :PROPERTIES:
   :Tema:      %\\1
   :fecha:     %U
   :END:
%?"</span> <span style="color: #8be9fd; font-style: italic;">:empty-lines</span> 1)
<span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Lista de templates de captura para Frateco
</span>        (<span style="color: #f1fa8c;">"f"</span> <span style="color: #f1fa8c;">"Tareas para Frateco Esperanto"</span>)
        (<span style="color: #f1fa8c;">"ff"</span> <span style="color: #f1fa8c;">"Tarea    (f) Frateco"</span> entry (file+headline <span style="color: #f1fa8c;">"~/agenda/agenda.org"</span> <span style="color: #f1fa8c;">"Esperanto"</span>)
         <span style="color: #f1fa8c;">"* PENDIENTE %? \t :personal:
   DEADLINE: %(substring (call-interactively 'org-deadline) 12)
   :PROPERTIES:
   :CREATE:       %U
   :END:
   :LOGBOOK:
   - State  \"PENDIENTE\"            from \"\"      %U
   :END:"</span> <span style="color: #8be9fd; font-style: italic;">:empty-lines</span> 1)
        ))
</pre>
</div>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Acrónimo de <i>Getting Things Done</i>. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2019/02/27/reorganizar-las-capturas-de-la-agenda-con-plantillas.html</link>
  <pubDate>Wed, 27 Feb 2019 22:29:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Variables de modo, keymaps y menús]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-02-20</div>
<p>
Estamos acostumbrados a ajustar los paquetes que instalamos para que
se comporten de una u otra forma y eso es lo que vamos a hacer ahora
con nuestro modo de ejemplo <code>datos-mode</code>. El código de ejemplo
utilizará dos variables para ello.
</p>

<p>
Imaginaos que estamos muy cansados de escribir el día de la fecha y el
pie de firma en los documentos que escribo y quiero que lo haga
<i>Emacs</i> por mí, porque soy así de vago y lo automatizo todo. Voy a
crear una función que lo haga por mí. <i>¡Eso está «chupao»!¡Al lío!</i>
El <i>pie de firma</i> suele tener un formato más o menos fijo: Normalmente
el lugar donde se firma, la fecha y a continuación <i>quién</i> lo firma.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">escribe-pie-firma</span> ()
  <span style="color: #6272a4;">"Escribe el pie de firma en el lugar del punto."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (insert (concat <span style="color: #f1fa8c;">"En Macondo, a "</span>
                  (format-time-string <span style="color: #f1fa8c;">"%d de %B de %Y"</span>)
                  <span style="color: #f1fa8c;">"\nFdo: Aureliano Buend&#237;a"</span>)))
</pre>
</div>

<p>
La función es sencilla y se explica sola: inserta una cadena que ha
formado <code>concat</code> juntando varias cadenas, el lugar, el día y la
firma. Las he puesto en tres líneas para que se vean a simple vista y
no se nos despisten.
</p>
<div id="outline-container-orga54f513" class="outline-2">
<h2 id="orga54f513">Variables</h2>
<div class="outline-text-2" id="text-orga54f513">
<p>
Pero ¿qué ocurre si quiero que mi modo lo utilice también otra
persona? ¿Y si tengo que firmar estando en otro lugar? Pues nada más
fácil que poner eso en variables, de manera que cambiando el valor de
la variable, cambia el texto que se introducirá.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Definir variables globales
</span>(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">datos-lugar</span>
  <span style="color: #f1fa8c;">"Macondo"</span>
  <span style="color: #6272a4;">"Lugar que se escribir&#225; con la funci&#243;n de pie de firma."</span>)

(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">datos-usuario</span>
  <span style="color: #f1fa8c;">"Aureliano Buend&#237;a"</span>
  <span style="color: #6272a4;">"Usuario que es escribir&#225; con la funci&#243;n de pie de firma."</span>)
</pre>
</div>

<p>
Hemos definido dos variables, <code>datos-lugar</code> y <code>datos-usuario</code>, para
guardar aquellas cadenas que pueden variar. Se puede apreciar que las
he inicializado con dos valores. Lo habitual es que se dejaran vacías
o <code>nil</code> y luego en el código controlar qué comportamiento es el
adecuado por defecto. Pero eso añadía complejidad a la función de
ejemplo con varias formas <code>if</code> que podían confundir al novato
pareciendo que la función definitiva es más compleja de lo que en
realidad es:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">escribe-pie-firma</span> ()
  <span style="color: #6272a4;">"Escribe el pie de firma en el lugar del punto."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (insert (concat <span style="color: #f1fa8c;">"En "</span> datos-lugar <span style="color: #f1fa8c;">", a "</span>
                  (format-time-string <span style="color: #f1fa8c;">"%d de %B de %Y"</span>)
                  <span style="color: #f1fa8c;">"\nFdo: "</span> datos-usuario)))
</pre>
</div>

<p>
De este modo, la función es idéntica a la anterior, pero colocando las
variables en el lugar adecuado. Si la utilizamos directamente veremos
que el resultado es equivalente... ¿pero qué ocurre si en nuestro
<code>init.el</code> colocamos el siguiente código después de la importación del
paquete?
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> datos-lugar <span style="color: #f1fa8c;">"Notxer&#237;a"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> datos-usuario <span style="color: #f1fa8c;">"Notxor de la Notxer&#237;a"</span>)
</pre>
</div>

<p>
<i>¡Ahí va! !Así es como funcionan las configuraciones de Emacs¡</i>
Algunos pensarán: <i>¡Qué tontería, eso ya lo sabíamos!</i> Por contra
otros acabarán de comprender que realmente <code>init.el</code> no es más que un
fichero de <i>elisp</i> que funciona ajustando los distintos paquetes al
comportamiento que queremos de ellos.
</p>
</div>
</div>
<div id="outline-container-orgd31a413" class="outline-2">
<h2 id="orgd31a413">Keymap</h2>
<div class="outline-text-2" id="text-orgd31a413">
<p>
También habrá quien piense que al final escribir <code>M-x escribe-dia</code> o
<code>M-x escribe-pie-firma</code> no me ahorran mucho trabajo porque sigo
teniendo mucho que escribir. Quizá se estén preguntado o incluso estén
tentados a establecer combinaciones de teclas para las funciones. Eso
lo podemos hacer también desde el mismo modo, pero además me
facilitará que pueda explicar algunas cosas más adelante.
</p>

<p>
Definir <code>keymap</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Definir las combinaciones de teclas del modo
</span>(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">datos-mode-map</span>
  (<span style="color: #ff79c6; font-weight: bold;">let</span> ((datos-mode-map (make-keymap)))
    (define-key datos-mode-map <span style="color: #f1fa8c;">"\C-c\C-f"</span> 'escribe-dia)
    (define-key datos-mode-map <span style="color: #f1fa8c;">"\C-c\C-p"</span> 'escribe-pie-firma)
    datos-mode-map)
  <span style="color: #6272a4;">"Kaymap para datos-mode."</span>)
</pre>
</div>

<p>
Como se puede ver nuestro <code>keymap</code> lo llamamos <code>datos-mode-map</code> y lo
metemos en una variable con ese nombre. Se utiliza la forma <code>let</code> para
crear con <code>make-keymap</code> un <code>keymap</code> local al que añadir las
combinaciones que necesito con la forma <code>define-key</code>. Esta forma
necesita como primer argumento el <code>keymap</code> en el que definirá la
combinación que se pasa en forma de cadena y por último la función que
debe llamar. Cuando se han añadido todas las combinaciones que
necesitamos, la forma <code>let</code> evalúa el <code>keymap</code> que se ha modificado
para que se establezca en la variable... creo que es más complicado de
explicar que de entender viendo el código.
</p>

<p>
Ahora hay que decirle al <i>modo</i> cuál es su <code>keymap</code>, por tanto
modifico la definición para añadirlo. La definición quedará así:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Definici&#243;n del modo menor
</span>(<span style="color: #ff79c6; font-weight: bold;">define-minor-mode</span> <span style="color: #50fa7b; font-weight: bold;">datos-mode</span>
  <span style="color: #6272a4;">"Toggle Datos mode.
Interactivamente sin argumento, este comando des/activa el modo."</span>
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">El valor inicial.
</span>  <span style="color: #8be9fd; font-style: italic;">:init-value</span> nil
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Indicador de modo en la l&#237;nea.
</span>  <span style="color: #8be9fd; font-style: italic;">:lighter</span> <span style="color: #f1fa8c;">" Datos"</span>
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Keymap para el modo
</span>  <span style="color: #8be9fd; font-style: italic;">:keymap</span> datos-mode-map)
</pre>
</div>

<p>
Como se puede apreciar, sólo he añadido <code>:keymap datos-mode-map</code>. Y
ahora cuando recargo el mi modo ya puedo utilizar la combinación de
teclas que está definida (y que puedo cambiar en la configuración de
<code>init.el</code> si quiero).
</p>
</div>
</div>
<div id="outline-container-orga15ef3a" class="outline-2">
<h2 id="orga15ef3a">Menú</h2>
<div class="outline-text-2" id="text-orga15ef3a">
<p>
Hace tiempo que dejé de utilizar los menús con profusión, aunque de
vez en cuando los miro y los uso, más con el objeto de <i>memorizar</i> la
combinación de teclas que por comodidad. Pero hay gente que se pierde
con estas cosas de la tecnología y <i>necesita</i> un buen menú en el que
pinchar. Para ellos es más claro y siempre <i>mi modo</i> parecerá mucho
más «pofesioná» (a ojos del público común) si tiene un menú.
</p>

<p>
Para definir el menú hay varios modos, pero el que recomiendo para
novatos como yo es el <i>macro</i> <code>easy-menu-define</code>. Pongo el código y lo
explico:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">easy-menu-define</span> datos-menu datos-mode-map
  <span style="color: #6272a4;">"Men&#250; para el modo datos-mode."</span>
  '(<span style="color: #f1fa8c;">"Datos"</span>
    [<span style="color: #f1fa8c;">"Escribir d&#237;a"</span> escribe-dia]
    [<span style="color: #f1fa8c;">"Escribir pie de firma"</span> escribe-pie-firma]))
</pre>
</div>

<p>
El macro define <code>datos-menu</code> como el menú para el modo y utiliza para
ello <code>datos-mode-map</code> como <code>keymap</code>. Luego vemos que está el
comentario para documentar <i>qué</i> es y una lista. La primera cadena
<code>"Datos"</code> será la que se muestre en el menú superior de <i>Emacs</i> y
luego están dos vectores para cada uno de los <i>widgets</i> de menú que
aparecerán. Se define la cadena que mostrará el menú y la función a la
que asociarlo.
</p>
</div>
</div>
<div id="outline-container-orga2b8774" class="outline-2">
<h2 id="orga2b8774">Conclusión</h2>
<div class="outline-text-2" id="text-orga2b8774">
<p>
Como vemos, con muy poco código tentemos un <i>modo</i> funcional y que da
el pego, con <i>chismáticos</i> en los que pinchar quien sea más pusilánime
y necesite llevar la flechita por toda la pantalla para asegurarse en
su lentitud que lo está haciendo correctamente.
</p>

<p>
Pongo también el código completo tal y como ha quedado en el fichero
<code>datos-mode.el</code> por si alguien se ha perdido desde las explicaciones
de la anterior entrega y ésta.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Inicio de datos-mode
</span>(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">datos-mode-hook</span> nil)

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Definir las combinaciones de teclas del modo
</span>(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">datos-mode-map</span>
  (<span style="color: #ff79c6; font-weight: bold;">let</span> ((datos-mode-map (make-keymap)))
    (define-key datos-mode-map <span style="color: #f1fa8c;">"\C-c\C-f"</span> 'escribe-dia)
    (define-key datos-mode-map <span style="color: #f1fa8c;">"\C-c\C-p"</span> 'escribe-pie-firma)
    datos-mode-map)
  <span style="color: #6272a4;">"Kaymap para datos-mode."</span>)

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Definir variables globales
</span>(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">datos-lugar</span>
  <span style="color: #f1fa8c;">"Macondo"</span>
  <span style="color: #6272a4;">"Lugar que se escribir&#225; con la funci&#243;n de pie de firma."</span>)

(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">datos-usuario</span>
  <span style="color: #f1fa8c;">"Aureliano Buend&#237;a"</span>
  <span style="color: #6272a4;">"Usuario que es escribir&#225; con la funci&#243;n de pie de firma."</span>)

(<span style="color: #ff79c6; font-weight: bold;">easy-menu-define</span> datos-menu datos-mode-map
  <span style="color: #6272a4;">"Men&#250; para el modo datos-mode."</span>
  '(<span style="color: #f1fa8c;">"Datos"</span>
    [<span style="color: #f1fa8c;">"Escribir d&#237;a"</span> escribe-dia]
    [<span style="color: #f1fa8c;">"Escribir pie de firma"</span> escribe-pie-firma]))

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Definici&#243;n del modo menor
</span>(<span style="color: #ff79c6; font-weight: bold;">define-minor-mode</span> <span style="color: #50fa7b; font-weight: bold;">datos-mode</span>
  <span style="color: #6272a4;">"Toggle Datos mode.
Interactivamente sin argumento, este comando des/activa el modo."</span>
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">El valor inicial.
</span>  <span style="color: #8be9fd; font-style: italic;">:init-value</span> nil
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Indicador de modo en la l&#237;nea.
</span>  <span style="color: #8be9fd; font-style: italic;">:lighter</span> <span style="color: #f1fa8c;">" Datos"</span>
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Keymap para el modo
</span>  <span style="color: #8be9fd; font-style: italic;">:keymap</span> datos-mode-map)

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">escribe-dia</span> (<span style="color: #8be9fd; font-style: italic;">&amp;opcional</span> cadena-formato)
  <span style="color: #6272a4;">"Escribe el d&#237;a de la fecha en lugar del punto."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span> <span style="color: #f1fa8c;">"P\nsCadena de formato: "</span>)
  (<span style="color: #ff79c6; font-weight: bold;">if</span> (&gt; (length cadena-formato) 0)
      (insert (format-time-string cadena-formato))
    (insert (format-time-string <span style="color: #f1fa8c;">"%Y-%m-%d"</span>))))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">escribe-pie-firma</span> ()
  <span style="color: #6272a4;">"Escribe el pie de firma en el lugar del punto."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (insert (concat <span style="color: #f1fa8c;">"En "</span> datos-lugar <span style="color: #f1fa8c;">", a "</span>
                  (format-time-string <span style="color: #f1fa8c;">"%d de %B de %Y"</span>)
                  <span style="color: #f1fa8c;">"\nFdo: "</span> datos-usuario)))

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Informa que este fichero proporciona el modo datos-mode
</span>(<span style="color: #ff79c6; font-weight: bold;">provide</span> '<span style="color: #bd93f9;">datos-mode</span>)
<span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Fin de datos-mode</span>
</pre>
</div>

<p>
Como se puede ver, contamos ya con una plantilla para hacer un modo
muy sencilla que podemos abarcar aún de un vistazo.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/elisp/index.html">elisp</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[elisp]]></category>
  <link>https://notxor.nueva-actitud.org/2019/02/20/variables-de-modo-keymaps-y-menus.html</link>
  <pubDate>Wed, 20 Feb 2019 18:18:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Creando un modo menor, sencillo y sin muchas pretensiones]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-02-15</div>
<p>
Para seguir con el <i>cursillo</i> de <i>elisp</i> voy a crear un nuevo modo.
Va a ser un <code>minor mode</code>, es decir, un modo que se puede activar como
secundario a otros modos generales. Lo primero que necesito es un
fichero que guarde el código en él y que se cargue desde la
configuración de <i>Emacs</i>.
</p>
<div id="outline-container-org8a1e42b" class="outline-2">
<h2 id="org8a1e42b">Crear el fichero de modo</h2>
<div class="outline-text-2" id="text-org8a1e42b">
<p>
Tengo la costumbre de ir metiendo todos mis proyectos en un directorio
con ese nombre dentro de mi directorio <code>home</code>. Es decir, voy a crear
un directorio de proyecto que me sirva para trabajar programando.
Obvio aquí toda la configuración de <code>git</code> o cualquier otra herramienta
de programación que se utilice de manera externa al propio <i>Emacs</i>.
El resultado final es crear un fichero que se llamará
<code>~/proyectos/datos-mode/datos-mode.el</code>
</p>

<p>
Para que lo cargue <i>Emacs</i> cuando arranque, debemos definir algunas
cosas en el fichero <code>init.el</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Configuraci&#243;n de prueba de creaci&#243;n de datos-mode
</span>(add-to-list 'load-path <span style="color: #f1fa8c;">"~/proyectos/datos-mode"</span>)
(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">datos-mode</span>)
</pre>
</div>

<p>
He añadido básicamente dos instrucciones: la primera añade a la lista
de <code>paths</code> el lugar donde guardo el fichero; la segunda solicita
cargar el modo <code>datos-mode</code>. Bien, muy bonito, pero de momento carga
<i>en vacío</i>. ¿Qué código tengo que meter en el fichero <code>datos-mode</code>
para que funcione?
</p>

<p>
De momento, cargo el siguiente código, que me sirve como <i>plantilla</i>
de modos:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Definici&#243;n del modo menor
</span>(<span style="color: #ff79c6; font-weight: bold;">define-minor-mode</span> <span style="color: #50fa7b; font-weight: bold;">datos-mode</span>
  <span style="color: #6272a4;">"Toggle Datos mode.
Interactivamente sin argumento, este comando des/activa el modo."</span>
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">El valor inicial.
</span>  nil
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Indicador de modo en la l&#237;nea.
</span>  <span style="color: #f1fa8c;">" Datos"</span>)

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Informa que este fichero proporciona el modo datos-mode
</span>(<span style="color: #ff79c6; font-weight: bold;">provide</span> '<span style="color: #bd93f9;">datos-mode</span>)
</pre>
</div>

<p>
La primera forma, <code>define-minor-mode</code>, es la que crea el modo. Sin
entrar en todas las opciones que soporta, de momento vemos que le
decimos que comience desactivado con <code>nil</code> y que el nombre que
aparecerá en la línea de estado será <code>" Datos"</code>.  Hay que remarcar el
espacio inicial para que no se pegue al modo que se liste antes.
</p>

<p>
La segunda forma, <code>provide</code>, es el <i>espejo</i> del <code>require</code> que hemos
puesto en el <code>init.el</code>, le informa a <i>Emacs</i> que el modo requerido en
la configuración lo proporciona nuestro fichero o paquete.
</p>

<p>
Podemos mejorarlo si en lugar de utilizar el modo posicional, utilizamos los
nombres de los argumentos:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">define-minor-mode</span> <span style="color: #50fa7b; font-weight: bold;">datos-mode</span>
  <span style="color: #6272a4;">"Toggle Datos mode.
Interactivamente sin argumento, este comando des/activa el modo."</span>
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">El valor inicial.
</span>  <span style="color: #8be9fd; font-style: italic;">:init-value</span> nil
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Indicador de modo en la l&#237;nea.
</span>  <span style="color: #8be9fd; font-style: italic;">:lighter</span> <span style="color: #f1fa8c;">" Datos"</span>)
</pre>
</div>
</div>
</div>
<div id="outline-container-org6cb18ed" class="outline-2">
<h2 id="org6cb18ed">Algo de contenido para probar</h2>
<div class="outline-text-2" id="text-org6cb18ed">
<p>
Vale, muy bonito todo, pero tengo un modo que no hace nada. Eso sí, si
recargo <i>Emacs</i> resulta que puedo llamar hacer <code>M-x datos-mode</code> y me
aparece el modo en la línea de estado. 
</p>

<p>
Pero aún no hace nada y eso no sirve de mucho, vamos a hacer que tener
instalado nuestro «modo» en el sistema sirva de algo. Algo que suelo
necesitar bastante cuando trasteo con los datos es introducir el día
de la fecha, normalmente en formato ISO. Entre las formas
<code>define-minor-mode</code> y <code>provide</code> defino una función que me ayude a
introducir la fecha con un <i>comando</i>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">escribe-dia</span> ()
  <span style="color: #6272a4;">"Escribe el d&#237;a de la fecha en el lugar del punto."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (insert (format-time-string <span style="color: #f1fa8c;">"%Y-%m-%d"</span>)))
</pre>
</div>

<p>
Si recargamos <i>Emacs</i> podemos llamar a <code>M-x escribe-dia</code> y en el lugar
donde esté el cursor escribirá <code>2019-02-15</code>, utilizando la forma
<code>insert</code> después de llamar a <code>format-time-string</code> con una cadena de
formato concreta, la ISO, <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Time-Parsing.html#Time-Parsing">se pueden consultar los formatos que vienen
en el manual</a> por si nos viniera mejor otro formato. Todo esto está muy
bien, pero tampoco es una mejora sustancial... ¿qué tendría que hacer
si necesito escribir la fecha en modo largo, o europeo, o americano?
¿Puedo hacer que la función me pregunte cómo quiero la salida en lugar
de una función para cada formato de los que uso? La respuesta es sí,
pongo el código y lo explico más despacio:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">escribe-dia</span> (<span style="color: #8be9fd; font-style: italic;">&amp;opcional</span> cadena-formato)
  <span style="color: #6272a4;">"Escribe el d&#237;a de la fecha en lugar del punto."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span> <span style="color: #f1fa8c;">"P\nsCadena de formato: "</span>)
  (<span style="color: #ff79c6; font-weight: bold;">if</span> (&gt; (length cadena-formato) 0)
      (insert (format-time-string cadena-formato))
    (insert (format-time-string <span style="color: #f1fa8c;">"%Y-%m-%d"</span>))))
</pre>
</div>

<p>
Analizando los cambios entre las dos versiones. Lo primero que puede
llamar la atención es el uso de <code>&amp;opcional</code> en los argumentos, lo que
hace que <code>cadena-formato</code> pueda existir o no. Si no existe o es una
cadena vacía <code>""</code>, se llama a la función con el formato.
</p>

<p>
Lo siguiente que llama la atención es cómo está escrita la forma
<code>interactive</code> donde se añade una cadena que puede parecer un tanto
extraña. Así que ahí va elemento a elemento: <code>P</code> indica que es
interactivo y admite un argumento que proporcionará el usuario. <code>\n</code>
equivale a pulsar <code>&lt;RET&gt;</code> cuando interactuamos. <code>s</code> especifica que el
argumento será una cadena (<code>string</code>). Y por último una cadena que
funciona como <i>prompt</i> de la función.
</p>

<p>
A continuación se evalúa si <code>cadena-formato</code> tiene contenido y si es
así se lo pasará a la función; en caso contrario, se utiliza una
cadena de formato que devuelve la cadena en formato ISO.
</p>

<p>
Si ahora recargamos <i>Emacs</i> y llamamos a la función <code>escribe-dia</code> nos
aparecerá el mensaje <i>Cadena de formato:</i> en el <i>buffer</i> y podemos
meter cualquier texto en él. Por ejemplo, si introduces <code>a %d de %B de
%Y</code> devolverá una cadena como <code>a 15 de febrero de 2019</code>. Si no
introducimos ninguna cadena, el <i>prompt</i> devolverá una vacía y la
función utilizará la que hemos puesto por defecto.
</p>
</div>
</div>
<div id="outline-container-org45f1610" class="outline-2">
<h2 id="org45f1610">Conclusión</h2>
<div class="outline-text-2" id="text-org45f1610">
<p>
Un pequeño paso hacia hacer un modo. Hay algunos problemas que nos
podemos encontrar y muchas cosas por hacer aún. No sólo en el <i>modo</i>
sino también en nuestra función de insertar fecha, si hay algo que
puede fallar es la cadena que el usuario introduzca en nuestra
función, aunque en realidad lo que hará <code>insert</code> será introducir «la
mejor cadena posible.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/elisp/index.html">elisp</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[elisp]]></category>
  <link>https://notxor.nueva-actitud.org/2019/02/15/creando-un-modo-menor-sencillo-y-sin-muchas-pretensiones.html</link>
  <pubDate>Fri, 15 Feb 2019 18:21:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Sí, soy yo]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-02-14</div>
<p>
Esto de no querer <i>esnifar</i> los datos de nadie, ni siquiera para
contabilizar lectores, me hace pensar que esto que escribo no lo lee
nadie, o casi nadie (<i>que no es lo mismo pero es igual</i>, cantaba
Silvio Rodríguez).  Quizá por eso agradezco un comentario, cuando lo
hay, como si fuera fiesta y si te lo hacen en persona es como una
fiesta <i>de guardar</i>.
</p>

<p>
El caso es que el otro día hablando con alguien por casualidad, salió
el tema del blog en la conversación, concretamente a raíz de <i>Emacs</i>.
Era alguien al que fui presentado como <i>Notxor</i> (pronunciado <i>Nochor</i>)
y que me comentó acto seguido que él utiliza <i>Emacs</i> para todo y que
seguía este <i>blog</i> «de alguien que se llama como tú pero con "tx" en
el nombre». Yo le dije que efectivamente, es con «tx», siempre lo he
escrito así.
</p>

<p>
Así que: «Sí, soy yo». Lo afirmo dada tu cara de incredulidad las tres
veces que dije que era el mismo <i>Notxor</i>. Sí, el de «Notxor tiene un
blog», el de «defenestrando la vida» y el que tiene la foto de un
malamute (Kant, que en paz descanse) en el <i>chismático</i> de
búsquedas. El mismo que utiliza indiscriminadamente las palabras
<i>chismático</i> y <i>pichorro</i>, que tanta gracia te hacen.
</p>

<p>
Debo decir que agradezco que te declararas <i>fan</i> del blog y que
incluso me lo recomendaras cuando ya te había dicho que era yo la
primera vez. Supongo que esperabas o te imaginabas a alguien distinto:
alguien más alto, más rubio, más guapo, más joven, pero la realidad es
cabezona como si fuera <i>maña</i> y las cosas son como son: o las cambias
o las aceptas, y hay cosas que no se pueden cambiar.
</p>

<p>
Por cierto, fue un placer hablar contigo de <i>emacs</i>, de motos, de
educación y de otras muchas cosas... Ahora te toca a ti. Eres <i>fan</i>
del <i>blog</i>, supongo que leerás esto y no te costará poner un
comentario por aquí abajo. No he querido decir nombres, ni sitios, no
te estoy obligando, recuerdo que dijiste que <i>te da cosa</i> comentar en
los <i>blogs</i>, pero sería sólo por no dejarme mal... y lo puedes hacer
como anónimo, que tampoco pasa nada ;)
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2019/02/14/si-soy-yo.html</link>
  <pubDate>Thu, 14 Feb 2019 10:05:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Proyecto de ejemplo para seguir avanzando con elisp]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-02-08</div>
<p>
Estoy en un punto muerto y no me decido en cómo continuar hablando
sobre <i>elisp</i>. Creo que lo mejor sería hacer un pequeño ejemplo que
implique un poco de programación y que sirva para repasar todo lo que
hemos ido viendo hasta ahora.
</p>

<p>
No me resulta fácil encontrar un ejemplo, quizá porque estoy
acostumbrado a programar por necesidad. Se me plantea un problema o
dificultad que quiero solucionar y lo hago. Pero plantear algo que
resolver, sin que sea realmente un problema el problema.
</p>

<p>
Así que me inclino más a preguntar a los que están siguiendo la serie
de programación con <i>elisp</i>, si tienen algún problema que quieran
solucionar o algo que les inquiete. Si no recibo sugerencias haré un
ejemplo que consistirá en crear un <i>modo menor</i> de <i>Emacs</i> para
gestionar datos personales desde un fichero <code>org-mode</code>. No será un
ejemplo completo con todas las posibilidades, sino un <i>modo</i> en que
con una combinación de teclas abra un <i>formulario</i> que rellenar para
crear, editar y guardar los datos en concreto que nos interesan.
</p>

<p>
Recuerda, si estás siguiendo esta serie y tienes alguna sugerencia,
aquí abajo están los comentarios, comenta qué te vendría bien tratar o
hacer para solucionar tu problema, o al menos para encauzar esfuerzos
para que lo soluciones.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/elisp/index.html">elisp</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[elisp]]></category>
  <link>https://notxor.nueva-actitud.org/2019/02/08/proyecto-de-ejemplo-para-seguir-avanzando-con-elisp.html</link>
  <pubDate>Fri, 08 Feb 2019 17:57:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Interacción con el usuario y widgets]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-02-03</div>
<div id="outline-container-org615cc37" class="outline-2">
<h2 id="org615cc37">Interacción básica</h2>
<div class="outline-text-2" id="text-org615cc37">
<p>
Ya vimos cómo se podían hacer funciones que nos sirvieran de
<i>comandos</i> y que se pudieran hacer de modo interactivo. Pero si la
interacción se limita a llamar a una función, es posible que nos
quedemos cortos, porque lo que necesitan los programas para funcionar
son datos y la mayor fuente de datos es el propio usuario.
</p>

<p>
La interacción más sencilla es informar de algo al usuario. Para esos
menesteres utilizamos la función <code>message</code>, que ya ha salido alguna
vez en este minicurso. Sin embargo, <code>message</code> tiene algunas variantes
que pueden servirnos para otras cosas. Por ejemplo, vamos a ver las
diferencias en los siguientes mensajes:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(message <span style="color: #f1fa8c;">"Esto es un mensaje que informa al usuario de que el c&#243;digo hace algo."</span>)
(message-box <span style="color: #f1fa8c;">"Esto tambi&#233;n informa, pero casi salta a la vista."</span>)
(message-or-box <span style="color: #f1fa8c;">"Esto tambi&#233;n lo hace pero adem&#225;s elige c&#243;mo hacerlo."</span>)
(<span style="color: #ff79c6; font-weight: bold;">message-y-or-n-p</span> <span style="color: #f1fa8c;">"Con este mensaje podemos responder adem&#225;s."</span> t)
(<span style="color: #ffb86c; background-color: #373844;">error</span> <span style="color: #f1fa8c;">"&#161;Se ha producido un error!"</span>)
</pre>
</div>

<p>
Podemos ver cuatro formas de enviar un mensaje. La primera es la más
sencilla, sólo informa de algo sin más. Además, como lo hace en el
área de eco, desaparecerá a los pocos segundos y es posible que al
usuario se le pase y no llegue a leerlo. Si estamos en un entorno
gráfico, podemos emplear la segunda forma <code>message-box</code>, que mostrará
el mensaje en un diálogo con un botón de aceptar. La tercera forma
dependerá de nuestra configuración y entorno, puede mostrarse en forma
de diálogo o en el área de eco. Y por último, la cuarta alternativa
nos permite mostrar un mensaje y esperar una respuesta. Si el usuario
pulsa <i>y</i> la forma devolverá <code>t</code> y si pulsa <i>n</i>, devolverá <code>nil</code>.
</p>

<p>
La forma <code>error</code> envía un mensaje y abre un <i>buffer</i> <code>*Backtrace*</code> y
lo podemos utilizar como una forma de detener el programa informando
al usuario de lo que ha pasado.
</p>

<p>
Para las peticiones de confirmación además, <i>emacs</i> nos proporciona
dos formas más: <code>y-or-n-p</code> y <code>yes-or-no-p</code>. Básicamente hacen lo mismo
que <code>message-y-or-n-p</code> pero con sutiles diferencias:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(y-or-n-p <span style="color: #f1fa8c;">"&#191;Es mejor que te pregunten antes de hacer algo?"</span>)
(yes-or-no-p <span style="color: #f1fa8c;">"&#191;Escribir m&#225;s implica menos accidentes?"</span>)
</pre>
</div>

<p>
La primera forma, se contesta como ya se ha explicado, pulsando <i>y</i> o
<i>n</i>. Sin embargo, la segunda forma solicita que se escriba de modo
completo <i>yes</i> o <i>no</i>. El manual recomienda utilizar esta función
cuando se vaya a realizar alguna acción irreversible, como por ejemplo
el borrado de un fichero o un texto.
</p>

<p>
Otras veces necesitamos que el usuario elija entre varias
alternativas, por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(completing-read <span style="color: #f1fa8c;">"Elige fruta: "</span> '(<span style="color: #f1fa8c;">"manzana"</span> <span style="color: #f1fa8c;">"naranja"</span> <span style="color: #f1fa8c;">"pera"</span> <span style="color: #f1fa8c;">"pl&#225;tano"</span>))
(completing-read <span style="color: #f1fa8c;">"Introduce un n&#250;mero: "</span> nil)
</pre>
</div>

<p>
Como vemos, <code>completing-read</code> abre más aún la interacción con el
usuario. En la primera forma del ejemplo, vemos que podemos dar una
lista de alternativas para seleccionar entre ellas. Esas alternativas
podemos darlas en cualquier orden, la forma las ordenará
alfabéticamente. Además podemos solicitar que el usuario proporcione
cualquier entrada, en el ejemplo se solicita un número. Al
introducirlo nos daremos cuenta que la función <i>siempre</i> devuelve una
cadena. Así que si lo que deseamos es un número deberíamos convertir
la entrada:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(string-to-number
  (completing-read <span style="color: #f1fa8c;">"Introduce un n&#250;mero: "</span> nil))
</pre>
</div>
</div>
</div>
<div id="outline-container-org77940d0" class="outline-2">
<h2 id="org77940d0">Widgets</h2>
<div class="outline-text-2" id="text-org77940d0">
<p>
<code>widgets</code> nos proporciona una forma de interacción más completa con el
usuario: nos permite crear <i>formularios</i>. Los <i>widgets</i> son
chismáticos que nos sirven para establecer datos en esos
<i>formularios</i>.
</p>

<p>
Los tipos de <i>widgets</i> básicos que podemos trabajar son los
siguientes:
</p>

<dl class="org-dl">
<dt><code>link</code></dt><dd>Es un área de texto asociado con una acción. Se muestran
como <i>hipertexto</i> en el texto.</dd>
<dt><code>push-button</code></dt><dd>Es un <i>link</i> dibujado como un botón.</dd>
<dt><code>editable-field</code></dt><dd>Un campo de texto editable que puede tener un
tamaño variable o fijo.</dd>
<dt><code>menu-choice</code></dt><dd>Permite seleccionar una opción de un menú de
opciones múltiples. Cada opción es a su vez un
<i>widget</i>. Sólo es visible una opción en el
<i>buffer</i>.</dd>
<dt><code>radio-button-choice</code></dt><dd>Permite al usuario seleccionar una entre
múltiples opciones activando los <i>radio botones</i>. Las opciones se
implementan también como <i>widgets</i>.</dd>
<dt><code>item</code></dt><dd>Un <i>widget</i> para utilizarlo en <code>menu-choice</code> y
<code>radio-button-choice</code>.</dd>
<dt><code>toggle</code></dt><dd>Un interruptor de tipo <i>on</i>-<i>off</i>.</dd>
<dt><code>checkbox</code></dt><dd>Una caja para marcar, de forma <code>[ ]</code> - <code>[X]</code>.</dd>
<dt><code>editable-list</code></dt><dd>Una lista editable donde el usuario puede añadir
y borrar <i>ítems</i>, cada uno de los cuales es también un <i>widget</i>.</dd>
</dl>

<p>
¿Complicado? Vamos a hacer un ejemplo sencillo para que podamos
hacernos una idea de su potencia.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">widget</span>) <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Declaramos que necesita &#171;widget&#187; para funcionar
</span>
(<span style="color: #ff79c6; font-weight: bold;">eval-when-compile</span>
  (<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">wid-edit</span>)) <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Y si lo compilamos, necesita tambi&#233;n &#171;wid-edit&#187;
</span>
(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">lista-campos</span> '()
  <span style="color: #6272a4;">"Una variable que utilizaremos para devolver el contenido del formulario."</span>)

(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">lista-resultados</span> '()
  <span style="color: #6272a4;">"Una variable en la que almacenaremos los resultados."</span>)

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">formulario-datos</span> ()
  <span style="color: #6272a4;">"Funci&#243;n que dibuja nuestro formulario en un buffer."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)                                            <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Ya sab&#233;is, para poder llamarla desde &#171;M-x&#187;
</span>  (switch-to-buffer <span style="color: #f1fa8c;">"*Formulario de datos*"</span>)               <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Nos creamos un buffer
</span>  (kill-all-local-variables)                               <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Nos cargamos todas las variables locales que haya de antes.
</span>  (make-local-variable 'lista-campos)                      <span style="color: #6272a4;">; </span><span style="color: #6272a4;">hacemos local la variable donde guardaremos en contenido.
</span>  (<span style="color: #ff79c6; font-weight: bold;">let</span> ((inhibit-read-only t))                             <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Inhibir el &#171;s&#243;lo lectura&#187;
</span>    (erase-buffer))                                        <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Poner el buffer en blanco para escribir en &#233;l.
</span>  (widget-insert <span style="color: #f1fa8c;">"Esto es un texto que podemos utilizar para explicar para qu&#233; es el formulario.\n\n"</span>)
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> lista-campos                                       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">A&#241;adir el siguiente campo a la lista
</span>        (cons (widget-create 'editable-field               <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Campo de edici&#243;n para el nombre
</span>                             <span style="color: #8be9fd; font-style: italic;">:size</span> 25                      <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Tama&#241;o en caracteres del campo
</span>                             <span style="color: #8be9fd; font-style: italic;">:format</span> <span style="color: #f1fa8c;">"Nombre:     %v "</span>     <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Dejar espacio para el texto tras el campo
</span>                             <span style="color: #f1fa8c;">"Mi nombre"</span>)                  <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Etiqueta del campo
</span>              lista-campos))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> lista-campos
        (cons (widget-create 'menu-choice                  <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Un men&#250; para seleccionar g&#233;nero
</span>                             <span style="color: #8be9fd; font-style: italic;">:tag</span> <span style="color: #f1fa8c;">"G&#233;nero"</span>                 <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Etiqueta del campo
</span>                             <span style="color: #8be9fd; font-style: italic;">:value</span> <span style="color: #f1fa8c;">"Femenino"</span>             <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Valor por defecto
</span>                             '(item <span style="color: #f1fa8c;">"No binario"</span>) '(item <span style="color: #f1fa8c;">"Femenino"</span>) '(item <span style="color: #f1fa8c;">"Masculino"</span>))
              lista-campos))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> lista-campos
        (cons (widget-create 'editable-field               <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Campo de edici&#243;n para el primer apellido
</span>                             <span style="color: #8be9fd; font-style: italic;">:size</span> 50
                             <span style="color: #8be9fd; font-style: italic;">:format</span> <span style="color: #f1fa8c;">"Apellido 1: %v"</span>
                             <span style="color: #f1fa8c;">"Primer Apellido"</span>)
              lista-campos))
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> lista-campos
        (cons (widget-create 'editable-field               <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Campo de edici&#243;n para el segundo apellido
</span>                             <span style="color: #8be9fd; font-style: italic;">:size</span> 50
                             <span style="color: #8be9fd; font-style: italic;">:format</span> <span style="color: #f1fa8c;">"\nApellido 2: %v \n"</span>
                             <span style="color: #f1fa8c;">"Segundo Apellido"</span>)
              lista-campos))
  (widget-insert <span style="color: #f1fa8c;">"\n"</span>)                                     <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Separador de la l&#237;nea de botones
</span>  (widget-create 'push-button
                 <span style="color: #8be9fd; font-style: italic;">:notify</span> (<span style="color: #ff79c6; font-weight: bold;">lambda</span> (<span style="color: #8be9fd; font-style: italic;">&amp;rest</span> ignore)
                           (<span style="color: #ff79c6; font-weight: bold;">dolist</span> (elemento lista-campos lista-resultados)
                             (message-box (widget-value elemento))))
                 <span style="color: #f1fa8c;">"Aceptar"</span>)
  (widget-insert <span style="color: #f1fa8c;">" "</span>)                                      <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Separador entre botones
</span>  (widget-create 'push-button
                 <span style="color: #8be9fd; font-style: italic;">:notify</span> (<span style="color: #ff79c6; font-weight: bold;">lambda</span> (<span style="color: #8be9fd; font-style: italic;">&amp;rest</span> ignore)
                           (kill-buffer <span style="color: #f1fa8c;">"*Formulario de datos*"</span>))
                 <span style="color: #f1fa8c;">"Cerrar Formulario"</span>)
  (use-local-map widget-keymap)                            <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Activar la edici&#243;n de los campos
</span>  (widget-setup))
</pre>
</div>

<p>
He puesto bastantes comentarios para saber qué hace cada cosa.
Básicamente lo que hace el código es establecer un par de listas, una
de campos y otra de resultados. Se crean los <i>widgets</i> y luego se
muestra el formulario.
</p>

<p>
Es de destacar el diferente comportamiento de algunos <i>widgets</i> según
se acceda desde teclado o con el ratón, por ejemplo en el
<code>menu-choice</code>.  En el primer caso se activará un <i>buffer-popup</i> con
las alternativas mientas que en el segundo aparecerá un menú gráfico.
</p>

<p>
Además, los <i>widgets básicos</i> se pueden combinar en <i>widgets</i> más
complejos, pero de momento no nos meteremos en esto.
</p>
</div>
</div>
<div id="outline-container-orga839165" class="outline-2">
<h2 id="orga839165">Funciones lambda</h2>
<div class="outline-text-2" id="text-orga839165">
<p>
A destacar también los <code>:notify</code> de los dos botones que hemos colocado
al final del formulario. En general, las funciones se definen con
<code>defun</code> tomando así un <i>nombre</i> con el que llamar a la forma. Sin
embargo, en algunas situaciones las funciones no necesitan ser
llamadas y se puede emplear una <i>función anónima</i> que se definen como
se ve en el código:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">lambda</span> (argumentos)
  <span style="color: #6272a4;">"Documentaci&#243;n en forma de cadena."</span>
  cuerpo-de-la-funcion)
</pre>
</div>

<p>
En el modo en que se utilizan en el código, se lanzarán cada vez que
se pulse en el botón.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/elisp/index.html">elisp</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[elisp]]></category>
  <link>https://notxor.nueva-actitud.org/2019/02/03/interaccion-con-el-usuario-y-widgets.html</link>
  <pubDate>Sun, 03 Feb 2019 17:59:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Comandos, módulos, marca, punto y otras zarandajas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-01-26</div>
<p>
Hasta ahora hemos venido trabajando directamente en el <i>buffer</i>
<code>*scratch*</code> y todo ha ido funcionando bien, aunque nuestras funciones
y llamadas eran más bien <i>efímeras</i>. En este artículo vamos a guardar
el código, por primera vez, en un módulo, librería, fichero, o como lo
queráis llamar.
</p>

<p>
Tradicionalmente los ficheros que nos sirven de <i>librerías</i> o módulos,
para marcarlos como <i>elisp</i>, llevan una extensión <code>.el</code>. Cargar uno de
esos módulos o librerías se puede hacer de muchas maneras.  Por
ejemplo, <i>Emacs</i> cuando se inicia busca el código en el fichero
especial <code>init.el</code>. Si queremos que nuestro código esté siempre
accesible, ese es el lugar apropiado para configurarlo. No voy a
entrar ahora a detallar cómo hacer un módulo para establecer un <i>modo</i>
de <i>Emacs</i>, me quedaré en algo más básico: crear un par de <i>funciones
interactivas</i> o <i>comandos</i> que nos permitan llamarlas desde el
<code>minibuffer</code> con <code>M-x</code>.
</p>
<div id="outline-container-orgd3cec12" class="outline-2">
<h2 id="orgd3cec12">Un poco de código en un fichero</h2>
<div class="outline-text-2" id="text-orgd3cec12">
<p>
Voy a poner un ejemplo sencillo, y por tanto inútil, de lo que puede
representar un módulo o librería. Supongamos que quiero solucionar un
problema, acelerando la inserción de etiquetas en mis ficheros <code>html</code>.
Concretamente las etiquetas de negrita, que es muy cansado escribir
<code>&lt;b&gt;&lt;/b&gt;</code> cada vez que toca. Lo suyo además es que me deje el cursor,
lo que en <i>emacs</i> se llama <i>punto</i>, situado entre las etiquetas para
escribir cómodamente lo que sea. Veamos el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">insertar-etiqueta-negrita</span> ()
  <span style="color: #6272a4;">"Inserta un par de etiquetas &lt;b&gt;&lt;/b&gt; en el punto del cursor."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (insert <span style="color: #f1fa8c;">"&lt;b&gt;&lt;/b&gt;"</span>)
  (backward-char 4))
</pre>
</div>

<p>
Definimos una función llamada <code>insertar-etiqueta-negrita</code> que hace
justo lo que dice su <i>cadena de documentación</i>. Es una función
sencilla y no necesitará que se le introduzcan datos a través de
parámetros, por eso su lista de parámetros está vacía. Lo primero que
vemos en el cuerpo de la función es <code>interactive</code>, <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Using-Interactive.html">una <i>forma</i>
especial que hace que nuestra función se convierta en un comando</a> al
que se le puede llamar desde <code>M-x</code>. La siguiente forma <code>insert</code>
insertará la cadena que queremos, en nuestro caso, la cadena contiene
las etiquetas de apertura y cierre de negrita en <code>html</code>. Por último le
decimos que retrase el <i>punto</i> cuatro caracteres para que se quede
entre ambas. Bien, ese código lo vamos a guardar en un fichero que
podemos llamar, por ejemplo, <code>negrita.el</code>.
</p>

<p>
Una vez guardado, sin haber <i>evaluado</i> el código si pulsamos <code>M-x</code> y
llamamos a <code>insertar-etiqueta-negrita</code> nos dará un error. El sistema
no encontrará dicha función. ¿Cómo puedo cargarla desde el fichero?
Podríamos por ejemplo, abrir el fichero y evaluar el código, pero lo
que nos facilita el proceso es que con <code>load-file</code> <i>emacs</i> hace las
dos cosas sobre la marcha. Así si utilizamos <code>M-x load-file</code> y le
decimos que cargue el fichero <code>negrita.el</code>, <i>automágicamente</i>
tendremos disponible nuestra función.
</p>

<p>
Vamos a seguir con el ejemplo un poco... Vamos a suponer que se da el
siguiente caso: ya he escrito todo el texto que debería ir en negrita
y no he escrito las etiquetas, porque soy así de torpe. Lo puedo
solucionar de dos maneras. La primera sería escribirlas manualmente al
principio y al final. La segunda escribir las dos etiquetas juntas en
un extremo y <i>corto-pegar</i> la otra en el otro... o una tercera,
teniendo como tenemos el poder en la punta de los dedos, escribir una
función que lo haga por mí. La forma debería escribir en el <i>inicio</i>
la etiqueta <code>&lt;b&gt;</code> y en el final la etiqueta <code>&lt;/b&gt;</code>. Veamos el
siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">marcar-negrita-region</span> (inicio fin)
  <span style="color: #6272a4;">"Inserta una marca &lt;b&gt;&lt;/b&gt; en torno a una regi&#243;n."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span> <span style="color: #f1fa8c;">"r"</span>)
  (<span style="color: #ff79c6; font-weight: bold;">save-excursion</span>
    (goto-char fin)   (insert <span style="color: #f1fa8c;">"&lt;/b&gt;"</span>)
    (goto-char inicio) (insert <span style="color: #f1fa8c;">"&lt;b&gt;"</span>)))
</pre>
</div>

<p>
Vemos una función marcada como <code>interactive</code>, aunque es un poco
distinta a la anterior, lleva aparejada una <code>"r"</code> para marcar que es
de una clase especial. <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Interactive-Codes.html#Interactive-Codes">La forma <code>interactive</code> tiene varios códigos
según lo que se quiera hacer</a> con ella. Si miramos qué es lo que
significa esa <code>r</code> en el enlace anterior nos dirá que se utilizarán el
<i>punto</i> y la <i>marca</i> como parámetros para la función.
</p>

<p>
El <i>punto</i> he dicho ya que es la posición del <i>cursor</i> dentro del
<i>buffer</i>, pero ¿qué es la <i>marca</i>? La <i>marca</i> es otro valor que está
en el <i>buffer</i>, lo activamos con el comando <code>set-mark-command</code>,
normalmente asociada a la combinación <code>C-&lt;SPC&gt;</code>, para marcar el texto
que se sitúe entre los dos valores.
</p>

<p>
Bien, la siguiente forma que nos encontramos es <code>save-excursion</code>.
Básicamente lo que hace es guardar los valores de posición del cursor
─o punto─ para poder recuperarlo y dejarlo como estaba aunque en su
cuerpo se mueva el mismo, como hacemos con las llamadas a
<code>goto-char</code>. En esta función, lo que se hace es saltar al final,
proporcionado por el argumento <code>fin</code> para introducir la etiqueta de
cierre de negrita y luego al <code>inicio</code> para introducir la etiqueta de
comienzo de negrita. Cuanto <code>save-excursion</code> termina, tanto el <i>punto</i>
como la <i>marca</i> están en el sitio que tenían antes de llamar a nuestra
función.
</p>

<p>
Si hemos guardado el código en nuestro fichero, lo podemos recargar de
nuevo llamando al comando <code>load-file</code> y nuestra nueva función estará
disponible.
</p>

<p>
Alguien dirá que no hemos avanzado mucho: en lugar de escribir
<code>&lt;p&gt;&lt;/p&gt;</code> tenemos que escribir <code>M-x nombre-de-la-función</code>, que es
bastante más largo, así que no hemos ganado nada. Se olvidan que
podemos establecer en nuestro código los atajos que queramos. Es
habitual que en <i>emacs</i> se dejen las combinaciones de <code>C-c</code> para este
tipo de cosas. Cada <i>modo</i> utiliza los suyos, y vemos que según el
tipo de archivo que estemos editando <code>C-c C-c</code>, la combinación de
teclas <i>superocupada</i> hace cosas distintas. En nuestro caso, podemos
por ejemplo establecer los siguientes atajos en el código:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Asignaci&#243;n de combinaciones de teclas globales
</span>(global-set-key (kbd <span style="color: #f1fa8c;">"C-c b"</span>) 'insertar-etiqueta-negrita)
(global-set-key (kbd <span style="color: #f1fa8c;">"C-c B"</span>) 'marcar-negrita-region)
</pre>
</div>
</div>
</div>
<div id="outline-container-org983d3a4" class="outline-2">
<h2 id="org983d3a4">Conclusión</h2>
<div class="outline-text-2" id="text-org983d3a4">
<p>
Ha sido un repaso muy rápido a las funciones que vamos a emplear como
<i>comandos</i> de nuestros programas. Pero los conceptos, ─dados así a
grandes rasgos─, son sencillos de entender.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/elisp/index.html">elisp</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[elisp]]></category>
  <link>https://notxor.nueva-actitud.org/2019/01/26/comandos-modulos-marca-punto-y-otras-zarandajas.html</link>
  <pubDate>Sat, 26 Jan 2019 18:05:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Lout, un lenguaje de marcas ligero]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-01-24</div>
<p>
Hace unos años, allá por el 2002-2003, me dio por intentar estudiar
<i>criminología</i>.  Vivía entonces en Jerez de la Frontera, que era
precisamente donde la Universidad de Cádiz impartía esa carrera.  Para
matricularme me convenció un compañero, y sin embargo amigo, que venía
desde Puerto Real y asistimos a clase sin faltar un solo día, hasta
que yo me vine a Zaragoza por motivos de trabajo y él, habiéndose
«solo» lo fue dejando.
</p>

<p>
Recuerdo esto, porque rebuscando entre trastos viejos encontré los
apuntes de <i>Medicina Legal</i>. Las horas que le eché a pasar a limpio e
incluso hacer los dibujos a mano y luego escanearlos. Esos apuntes se
convirtieron en los más fotocopiados del curso, del mío y de por lo
menos el posterior, según me contaron algunos compañeros que
continuaron los estudios. Al encontrar esos apuntes me acorde de cómo
los hice.
</p>

<p>
Entonces, mi ordenador era muy limitado, no tenía mucha capacidad y
una instalación de LaTeX no entraba. Estuve buscando cómo hacer para
pasar mis apuntes sin recurrir al <i>Güor del güindón</i> que tenía en el
trabajo. En mi ordenador de casa no había ninguna <i>suit ofimática</i>,
creo que tenía instalada una Debian o una Mandrake: en aquella época
era cuando más trasteé probando <i>distros</i>.
</p>

<p>
Mi salvación vino de <i>Lout</i>: <a href="http://savannah.nongnu.org/projects/lout">un lenguaje de marcas diseñado para
formatear documentos</a> que diseñó Jeffrey Kingston en la Universidad de
Sydney, en Australia. Hoy me lo he vuelto a descargar, pensando que no
compilaría. En <i>OpenSuse</i> está en el repositorio, pero me acuerdo que
en aquel entonces me lo tuve que compilar. Lo he descargado, la
friolera de 2Mb, y, contra todo pronóstico, lo he compilado e
instalado en mi directorio personal.
</p>

<p>
Recuerdo que estaba muy limitado en cuanto a opciones: apenas unos
pocos tipos de letra, apenas unos pocos tipos de documentos<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, no
hay extensiones que hagan otra cosas. Sin embargo, los ficheros de
configuración eran muy fáciles de modificar y de ajustar al documento
que querías generar.
</p>

<p>
Tampoco era una sintaxis demasiado clara, hasta que te acostumbras,
porque hay muchas palabras y códigos que inician y terminan <i>bloques</i>
de información, anidadas unas dentro de otras y algunas veces era
arduo saber exactamente dónde podías dividir o insertar o unir. El
código era del estilo:
</p>

<div class="org-src-container">
<pre class="src src-lout"># Esto es un comentario

# Utilizar el tipo de documento «doc» con su estilo por defecto
@SysInclude { doc }

@Document
  @InitialFont { Times Base 10p }
//

# Aquí comienzan los contenidos del documento
@Text @Begin

@PP
En este párrafo se puede utilizar por ejemplo el tipo en @B { negrita }
o en @I { itálica }. También se podía cambiar el tipo de texto con de la
siguiente manera: { Helvetica Base } @Font { este texto se mostrará en
Helvetica }.

@BeginSections
@Section @Title { Primera sección }
@Begin

@PP
Un parrafo que es el contenido de la sección, aunque también lo podríamos
dividir en sub-secciones.

@End @Section
@EndSections

@End @Text
</pre>
</div>

<p>
Una de las particularidades de ese sistema es, como en <i>Haskell</i>, la
<a href="https://es.wikipedia.org/wiki/Evaluaci%C3%B3n_perezosa">forma de evaluar las expresiones de forma <i>perezosa</i></a> y que la salida
suele ser <i>postscript</i>, porque la salida a <i>pdf</i> era muy
limitada<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.
</p>
<div id="outline-container-org6d5cd74" class="outline-2">
<h2 id="org6d5cd74">Conclusión</h2>
<div class="outline-text-2" id="text-org6d5cd74">
<p>
No hay mucho más que contar, sólo ha sido un ataque de
nostalgia... pero no descargo utilizarlo para algún proyectillo, nunca
se sabe.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Sólo <i>doc</i>, <i>report</i>, <i>book</i> y <i>slides</i>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Esta última versión no he probado aún la generación de
documentos y es posible que hayan mejorado. 
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2019/01/24/lout-un-lenguaje-de-marcas-ligero.html</link>
  <pubDate>Thu, 24 Jan 2019 20:54:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Funciones recursivas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-01-24</div>
<div id="outline-container-org8e9f585" class="outline-2">
<h2 id="org8e9f585">Funciones recursivas: llamándose a sí mismas</h2>
<div class="outline-text-2" id="text-org8e9f585">
<p>
En la entrega anterior hable sobre <i>iteración</i>, hoy hablaré sobre un
mecanismo <i>iterativo</i> que se llama <i>recursión</i>.  La recursión consiste
en una función que se llama a sí misma para resolver la iteración.
Normalmente la estructura recursiva implica que la función tenga una
estructura similar a la siguiente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">funcion-recursiva</span> (lista-par&#225;metros)
  (<span style="color: #ff79c6; font-weight: bold;">if</span> (condici&#243;n-de-parada)
      (devolver-valor definitivo)
    (llamar funcion-recursiva)))
</pre>
</div>

<p>
Es muy importante la parte de <code>condición-de-parada</code>, porque si no, la
función recursiva entrará en bucle infinito. Vemos un ejemplo que
bastante habitual en los textos sobre <i>Lisp</i>, pero en general sobre
cualquier lenguaje que soporte la <i>recursión</i>.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">factorial</span> (num)
  <span style="color: #6272a4;">"Calcula de forma recursiva el factorial de un n&#250;mero."</span>
  (<span style="color: #ff79c6; font-weight: bold;">if</span> (&lt;= num 1)
      1
    (* num (factorial (1- num)))))
</pre>
</div>

<p>
La función se llama <code>factorial</code> y admite un número <code>num</code> como
argumento para calcular su factorial. En el bloque <code>if</code> la condición
de parada es cuando <code>num</code> es igual a 1, en ese caso, la función
devuelve 1. En otro caso, lo que se hace es multiplicar el valor de
<code>num</code> por el <code>factorial</code> de <code>num-1</code>. Si probamos esa función con un
<code>num</code> igual a 5, nos devolverá el valor de su factorial: 120.
</p>
</div>
<div id="outline-container-org3b80662" class="outline-3">
<h3 id="org3b80662">Funciones recursivas aplicadas sobre listas</h3>
<div class="outline-text-3" id="text-org3b80662">
<p>
Es muy habitual encontrar en el código de <i>Lisp</i> una forma de
iteración que utiliza las propiedades de las listas para la
iteración. Consideremos el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">lista-numeros</span>
  <span style="color: #f1fa8c;">"Una lista de cadenas con los primeros n&#250;meros enteros."</span>
  '(<span style="color: #f1fa8c;">"uno"</span> <span style="color: #f1fa8c;">"dos"</span> <span style="color: #f1fa8c;">"tres"</span> <span style="color: #f1fa8c;">"cuatro"</span>))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">imprimir</span> (lista)
  (<span style="color: #ff79c6; font-weight: bold;">when</span> lista
    (princ (concat (car lista) <span style="color: #f1fa8c;">".\n"</span>))
    (imprimir (cdr lista))))
</pre>
</div>

<p>
Se puede ver que la recursión se extiende por la lista aprovechando
las propiedades <code>car</code> y <code>cdr</code> de la misma. El valor que condiciona la
recursión es <code>lista</code>, es decir, mientras el argumento pasado a la
función no sea una lista vacía <code>'()</code>, que sabemos es equivalente a
<code>nil</code>. En el ejemplo se imprime el primer elemento obtenido mediante
<code>(car lista)</code>,<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> y se llama recursivamente a <code>imprimir</code> con el resto de
la misma <code>(imprimir (cdr lista))</code>.
</p>
</div>
</div>
</div>
<div id="outline-container-org8a9fbe3" class="outline-2">
<h2 id="org8a9fbe3">Desenrollando la recursión</h2>
<div class="outline-text-2" id="text-org8a9fbe3">
<p>
Si tomamos el ejemplo del cálculo de factorial anterior veamos cómo
evoluciona la función:
</p>

<pre class="example" id="orgc47a929">
(factorial 5)
(* 5 (factorial 4))
(* 5 (* 4 (factorial 3)))
(* 5 (* 4 (* 3 (factorial 2))))
(* 5 (* 4 (* 3 (* 2 (factorial 1)))))
(* 5 (* 4 (* 3 (* 2 1))))
(* 5 (* 4 (* 3 2)))
(* 5 (* 4 6))
(* 5 24)
120
</pre>

<p>
Como vemos, la recursión se <i>desenrolla</i> expandiéndose a una expresión
más simple que luego vuelve a plegarse realizando el cálculo.
</p>

<p>
Hay ocasiones en que tanto anidamiento no es lo que queremos. Porque
en realidad lo que hace es ir «retrasando» el cálculo hasta que se ha
<i>desenrollado</i> toda la expresión. Podemos evitar eso haciendo una
función con un bucle <code>while</code> o <code>do</code> o <code>loop</code>, pero si queremos
recursión, podemos hacerlo también con una función <i>ayudante</i>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">factorial</span> (num)
  <span style="color: #6272a4;">"Devuelve el factorial del n&#250;mero expresado por NUM."</span>
  (factorial-ayudante 1 1 num))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">factorial-ayudante</span> (resul contador num)
  <span style="color: #6272a4;">"Devuelve RESUL, utilizando CONTADOR, con el NUMERO incluido."</span>
  (<span style="color: #ff79c6; font-weight: bold;">if</span> (&gt; contador num)
      resul
    (factorial-ayudante (* resul contador)
                        (1+ contador)
                        num)))
</pre>
</div>

<p>
Si hacemos como con la función recursiva anterior, los pasos serían
los siguientes:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(factorial 5)
(factorial-ayudante 1 1 5)
(factorial-ayudante 1 2 5)
(factorial-ayudante 2 3 5)
(factorial-ayudante 6 4 5)
(factorial-ayudante 24 5 5)
(factorial-ayudante 120 6 5)
120
</pre>
</div>

<p>
Como se puede apreciar no hay anidamiento y el resultado se va
acumulando de una llamada a otra de la misma función.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
No te dejes despistar con la forma <code>concat</code> que sirve para
<i>concatenar</i> cadenas de caracteres. En el ejemplo se añade <code>".\n"</code>, es
decir, un punto y un salto de línea.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/elisp/index.html">elisp</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[elisp]]></category>
  <link>https://notxor.nueva-actitud.org/2019/01/24/funciones-recursivas.html</link>
  <pubDate>Thu, 24 Jan 2019 18:08:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Condicionales, bucles e iteración]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-01-18</div>
<p>
Un programa es un proceso que ejecuta la máquina con la instrucción
que toca en ese momento ─obviando el <i>procesamiento paralelo</i> que
puede ejecutar varias cosas a la vez─. Si todo, el 100% del código, se
ejecutara a la vez, el programa no funcionaría y seguramente la
máquina no sobreviviría a tamaño calentón. Eso ocurre también con
nuestro cerebro, que está activado sobre el 10% o 15% y hay quien
piensa que sólo usamos eso de él. En realidad lo usamos todo, el 100%,
pero sólo cuando toca. También existen personas que tienen episodios
de una activación mayor y pueden llegar hasta el 40%. A esa activación
extraordinaria la llamamos <i>epilepsia</i> y los síntomas son los propios
de activaciones de conjuntos neuronales funcionando cuando no toca.
</p>

<p>
Si nuestro programa ejecuta una instrucción tras otra, siempre en el
mismo orden y siempre de la misma forma, nuestro programa será tan
<i>rígido</i> que seguramente será poco útil. Necesitamos que nuestro
código sea más <i>flexible</i> y según las condiciones que se den, realice
unas acciones u otras, adaptándose a las diferentes circunstancias.
Hoy toca hablar de esos <i>pichorros</i> que nos permiten hacer que nuestro
programa haga cosas distintas <i>tomando decisiones</i> según las
circunstancias, o las hagan varias veces.
</p>
<div id="outline-container-org9ce3fc5" class="outline-2">
<h2 id="org9ce3fc5">Variables globales y locales</h2>
<div class="outline-text-2" id="text-org9ce3fc5">
<p>
Antes de meternos con el tema del control de ejecución hay que hacer
una puntualización sobre la definición de variables. Hasta ahora hemos
utilizado en nuestros ejemplos el comando <code>set</code>, y su primo-hermano
monocigótico <code>setq</code>, para definir y establecer las variables y sus
valores.
</p>

<p>
Las variables ocupan espacio y hay ocasiones en las que necesitamos
guardar un determinado valor sólo durante los momentos en que se
realizan los cálculos, por lo que gastar el espacio que ocupa una
variable durante toda la sesión cuando sólo la hemos necesitado unos
pocos segundos es un derroche de medios que debemos evitar.
</p>

<p>
En otras ocasiones, efectivamente, necesitaremos valores durante más
tiempo y eso merece que le hagamos un hueco de forma más permanente a
esa variable. ¿Cuándo debemos emplear una u otra? Pues nos lo dirá el
sentido común y la necesidad.
</p>
</div>
<div id="outline-container-orgdd295d9" class="outline-3">
<h3 id="orgdd295d9">Globales</h3>
<div class="outline-text-3" id="text-orgdd295d9">
<p>
Para definir variables globales en nuestro código es recomendable
utilizar la instrucción <code>defvar</code>, con el siguiente formato:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">mi-variable</span> 4
    <span style="color: #6272a4;">"Esta variable se utiliza para almacenar un entero."</span>)
</pre>
</div>

<p>
En realidad, lo único necesario sería <code>(defvar mi-variable)</code>. Eso solo
ya reserva el espacio y nuestro programa ─y <i>Emacs</i> en general─, la
reconocerá como válida. Sin embargo yo he utilizado la definición
completa. ¿Por qué? La respuesta es obvia se después de evaluar el
código anterior evaluamos <code>(apropos "mi-variable")</code>. ¿Lo
ves?... ¡efectivamente! <code>apropos</code> nos mostrará la cadena de
documentación que hayamos escrito.
</p>

<p>
Puedes seguir utilizando <code>set</code>, nada te lo impide, pero al escribir
código será mucho más evidente que has querido crear una variable
global ─si además documentas para qué la usas es ya de premio─ si
utilizas la forma <code>defvar</code>.
</p>

<p>
También existe una forma <code>defconst</code>, que como su nombre indica implica
el deseo de definir una <i>constante</i>, ─es decir, un valor que se
mantendrá fijo durante la ejecución de nuestro programa─. Pero tiene
un problema estructural básico: Sólo es un deseo, no es
efectivo... sólo hay que comprobarlo con el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defconst</span> <span style="color: #f8f8f2; font-weight: bold;">MI-CONSTANTE</span> 3
  <span style="color: #6272a4;">"Una constante cualquiera que quiero definir."</span>)  <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; mi-constante = 3
</span>
(set 'MI-CONSTANTE 4)                              <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; mi-constante = 4</span>
</pre>
</div>

<p>
No hay ningún aviso de error ni nada que bloquee el que cambiemos el
valor de una <i>constante</i>, lo cual no parece tener mucho sentido. En
<i>Emacs</i> los símbolos <code>mi-constante</code> y <code>MI-CONSTANTE</code> son distintos. Yo
suelo utilizar las <i>constantes</i> en mayúsculas para ver a simple vista
que estoy intentando modificar algo que pensé como <i>constante</i> en el
código y no se me crucen las cosas. También suelo utilizar <code>defconst</code>
aún siendo de poca utilidad, porque cuando leo el código <i>estoy
seguro</i> que quise definir algo como constante y mis motivos tenía ─los
suelo escribir en la cadena de <i>documentación</i> de la definición─.
</p>
</div>
</div>
<div id="outline-container-orgdd60550" class="outline-3">
<h3 id="orgdd60550">Variables locales</h3>
<div class="outline-text-3" id="text-orgdd60550">
<p>
Para las ocasiones en las que sólo necesitamos las variables durante
el tiempo que evaluamos el código y no lo necesitaremos fuera de él,
podemos utilizar las formas <code>let</code> y <code>let*</code>, que como <code>set</code> y <code>setq</code>
son primas-hermanas monocigóticas, para declarar variables. Tanto
<code>let</code> como <code>let*</code> tienen una estructura similar:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">let</span> (variables) (cuerpo))
</pre>
</div>

<p>
Quizá con un ejemplo se vea más claro:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">let</span> ((x 3)
      (y 5))    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">aqu&#237; se cierra el bloque de &#171;variables&#187;
</span>  (+ x y))      <span style="color: #6272a4;">; </span><span style="color: #6272a4;">aqu&#237; est&#225; el bloque &#171;cuerpo&#187; y se cierra la forma let</span>
</pre>
</div>

<p>
Si evaluamos el código anterior el resultado será 8. Vale, ¿y qué lo
diferencia de <code>let*</code>? Vemos el siguiente ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">let*</span> ((x 3)
      (y (+ x 2)))
  (+ x y))
</pre>
</div>

<p>
Prueba el código con el <code>*</code> y sin él. ¿Qué ocurre cuando no está? ¿Un
error? ¿Qué error? ... algo así como «la variable x no existe». ¿Por
qué con el asterisco sí existe? Pues básicamente, porque <i>Lisp</i> va
evaluando el código de la definición de las variables según se las va
encontrando, así, ha podido definir <code>y</code> en base al valor de <code>x</code>. En el
caso de no utilizar asterisco, simplemente <code>x</code> no está disponible
hasta que no se cierre el bloque de las variables.
</p>

<p>
Si evaluamos el símbolo <code>x</code> o <code>y</code> fuera de la forma <code>let</code>, <i>elisp</i> nos
dirá que esa variable no existe, porque sólo existen <i>dentro</i> de la
forma <code>let</code>.
</p>
</div>
</div>
<div id="outline-container-org45dcf98" class="outline-3">
<h3 id="org45dcf98">Formas</h3>
<div class="outline-text-3" id="text-org45dcf98">
<p>
Lo he traducido como <i>formas</i>, en <i>Lisp</i> se llama <code>form</code> a todo lo que
se mete entre paréntesis con el fin de ser evaluado. Lo bueno de estas
formas es que se pueden meter unas dentro de otras, como se puede
intuir de los ejemplos anteriores. Es muy habitual que veamos cosas
como por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">simbolo-funcion</span> ...
  (<span style="color: #ff79c6; font-weight: bold;">let</span> (variables)
    (cuerpo)))
</pre>
</div>

<p>
Se puede ver cómo se van acumulando paréntesis en algunos sitios. Al
principio te preocupa tanto paréntesis junto, temes olvidar alguno,
sin embargo, con la práctica verás que es fácil de entender: sólo son
formas dentro de formas que están dentro de formas y tu pensamiento se
centrará en esas formas y no en los paréntesis.
</p>
</div>
</div>
</div>
<div id="outline-container-org9800bb3" class="outline-2">
<h2 id="org9800bb3">Condicionales</h2>
<div class="outline-text-2" id="text-org9800bb3">
</div>
<div id="outline-container-orge8ad9b0" class="outline-3">
<h3 id="orge8ad9b0">If</h3>
<div class="outline-text-3" id="text-orge8ad9b0">
<p>
La forma <code>if</code> es la más sencilla de todos los condicionales. Su
estructura es muy fácil:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">if</span> (condici&#243;n)
    (bloque evaluado si es &#171;t&#187;)
  (bloque evaluado si es nil))
</pre>
</div>

<p>
Vemos un ejemplo para ver cómo funciona:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">if</span> (y-or-n-p <span style="color: #f1fa8c;">"&#191;T&#250; que dices?"</span>)
    (message <span style="color: #f1fa8c;">"&#161;&#161;&#161;Has dicho que s&#237;iii!!!"</span>)
  (message-box <span style="color: #f1fa8c;">"Pues no, pues vale."</span>))
</pre>
</div>

<p>
He utilizado dos formas <i>interactivas</i> para mostrar un mensaje dentro
de una <code>if</code>. La forma <code>y-or-no-p</code> muestra un mensaje en el
<i>minibuffer</i> de <i>emacs</i>, el que le pasamos como cadena de caracteres,
y espera a que el usuario pulse <code>y</code> si está de acuerdo o <code>n</code> si no lo
está. Devolverá <code>t</code> en el primer caso y <code>nil</code> en el segundo. La forma
<code>message</code> simplemente muestra un mensaje en el <i>minibuffer</i>. La forma
<code>message-box</code> muestra el mensaje en un diálogo de ventana con su botón
y todo.
</p>
</div>
</div>
<div id="outline-container-orge118067" class="outline-3">
<h3 id="orge118067">When y unless</h3>
<div class="outline-text-3" id="text-orge118067">
<p>
Podríamos decir que <code>when</code> y <code>unless</code> son formas resumidas de <code>if</code>. La
primera, <code>when</code> equivale a utilizar sólo el bloque <i>cierto</i> de la
expresión. Dicho de otro modo, sólo se ejecutará el bloque de código
si la condición es cierta. La forma <code>unless</code>, al contrario, sólo
ejecutará el código si resulta la condición falsa.
</p>

<p>
Podríamos escribir <code>when</code> como:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">when</span> (condici&#243;n) (bloque de c&#243;digo))

<span style="color: #6272a4;">; </span><span style="color: #6272a4;">ser&#225; completamente equivalente a
</span>
(<span style="color: #ff79c6; font-weight: bold;">if</span> (condici&#243;n)
    (bloque de c&#243;digo)
  nil)
</pre>
</div>

<p>
Y también podríamos escribir <code>unless</code> como
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">unless</span> (condici&#243;n) (bloque de c&#243;digo))

<span style="color: #6272a4;">; </span><span style="color: #6272a4;">ser&#225; completamente equivalente a
</span>
(<span style="color: #ff79c6; font-weight: bold;">if</span> (condici&#243;n)
    nil
  (bloque de c&#243;digo))
</pre>
</div>
</div>
</div>
<div id="outline-container-org0d6f918" class="outline-3">
<h3 id="org0d6f918">Cond</h3>
<div class="outline-text-3" id="text-org0d6f918">
<p>
Hemos visto que <code>if</code> evalúa sólo una <i>condición</i> para actuar en
consecuencia. La forma <code>cond</code> lo que hace es evaluar una condición
tras otra mientras y ejecuta sólo el cuerpo de la primera condición
que se cumpla.
</p>

<p>
A ver, más despacio para no perdernos:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">cond</span> (lista de condiciones))
</pre>
</div>

<p>
donde cada condición tiene la forma:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(condici&#243;n forma-c&#243;digo)
</pre>
</div>

<p>
Vamos a poner un ejemplo a ver cómo funciona:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">cond</span> ((numberp x) (message <span style="color: #f1fa8c;">"x es un n&#250;mero"</span>))
      ((stringp x) (message <span style="color: #f1fa8c;">"x es una cadena"</span>))
      (t           (message <span style="color: #f1fa8c;">"x no es ni una cadena ni un n&#250;mero"</span>)))
</pre>
</div>

<p>
Y para probarlo podemos ir evaluándolo con los siguientes valores:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(set 'x 4)
(set 'x <span style="color: #f1fa8c;">"Hola"</span>)
(set 'x nil)
</pre>
</div>

<p>
Bien, también aprovecho para contar que la tercera forma dentro de la
lista de condiciones de <code>cond</code> que he puesto en el ejemplo, se
evaluará siempre si ninguna de las anteriores es evaluada como cierta.
Si no se pone, la forma <code>cond</code> devolverá un <code>nil</code>, que a veces no
será un valor esperado.
</p>
</div>
</div>
<div id="outline-container-orgd28eaf9" class="outline-3">
<h3 id="orgd28eaf9">Condiciones compuestas</h3>
<div class="outline-text-3" id="text-orgd28eaf9">
<p>
Hay ocasiones en que las condiciones pueden ser más complejas que un
<i>sí</i> o un <i>no</i>, sino una combinación de valores o cláusulas
<i>booleanas</i>. Las funciones <i>booleanas</i> son <code>and</code>, <code>or</code> y <code>not</code>.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(not t)         <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; nil
</span>(not nil)       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; t
</span>
(<span style="color: #ff79c6; font-weight: bold;">and</span> t   t)     <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; t
</span>(<span style="color: #ff79c6; font-weight: bold;">and</span> t   nil)   <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; nil
</span>(<span style="color: #ff79c6; font-weight: bold;">and</span> nil t)     <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; nil
</span>(<span style="color: #ff79c6; font-weight: bold;">and</span> nil nil)   <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; nil
</span>
(<span style="color: #ff79c6; font-weight: bold;">or</span> t   t)      <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; t
</span>(<span style="color: #ff79c6; font-weight: bold;">or</span> t   nil)    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; t
</span>(<span style="color: #ff79c6; font-weight: bold;">or</span> nil t)      <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; t
</span>(<span style="color: #ff79c6; font-weight: bold;">or</span> nil nil)    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; nil</span>
</pre>
</div>

<p>
Vamos a evaluar un par de expresiones para ver cómo funcionan:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">and</span> (message-box <span style="color: #f1fa8c;">"Hola 1"</span>) (message-box <span style="color: #f1fa8c;">"Hola 2"</span>) nil (message-box <span style="color: #f1fa8c;">"Hola 3"</span>))
(<span style="color: #ff79c6; font-weight: bold;">or</span> (message-box <span style="color: #f1fa8c;">"Hola 1"</span>) (message-box <span style="color: #f1fa8c;">"Hola 2"</span>) nil (message-box <span style="color: #f1fa8c;">"Hola 3"</span>))
</pre>
</div>

<p>
Si evaluamos la expresión <code>and</code> veremos que nos aparecen dos
<code>message-box</code> y se detiene en tercer elemento, devolviendo <code>nil</code>. Sin
embargo, en la expresión <code>or</code> sólo muestra el primero y devuelve la
cadena <code>"Hola 1"</code> evaluando la expresión, por tanto como verdadera.
</p>
</div>
</div>
</div>
<div id="outline-container-org962a3b0" class="outline-2">
<h2 id="org962a3b0">Bucles</h2>
<div class="outline-text-2" id="text-org962a3b0">
<p>
Los bucles sirven para ejecutar código de forma repetitiva. El bucle
más habitual es <code>while</code>. Pongo un ejemplo y lo destripamos:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">let</span> ((num 0))
  (<span style="color: #ff79c6; font-weight: bold;">while</span> (&lt; num 4)
    (princ (format <span style="color: #f1fa8c;">"Iteraci&#243;n %d.\n"</span> num))
    (<span style="color: #ff79c6; font-weight: bold;">setq</span> num (1+ num))))
</pre>
</div>

<p>
Veremos que al evaluar el código escribe lo siguiente:
</p>

<pre class="example" id="org391959d">
Iteración 0.
Iteración 1.
Iteración 2.
Iteración 3.
nil
</pre>

<p>
En el ejemplo el bloque de código es muy simple, sólo utiliza la forma
<code>princ</code> para escribir una cadena de formato para mostrarnos la
<i>vuelta</i> en la que está. En general, es habitual encontrar una
estructura del <code>while</code> de la siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(... establecer-contador
  (<span style="color: #ff79c6; font-weight: bold;">while</span> (condici&#243;n contador)
    (bloque-de-c&#243;digo)
    (actualizar-contador)))
</pre>
</div>

<p>
En otros lenguajes podemos un bucle adicional, que primero ejecuta el
código y luego evalúa la condición. A esos bucles se les suele llamar
<code>while-until</code> y aunque en <i>Lisp</i> no hay una forma equivalente con
nombre podemos simularla poniendo una forma <code>progn</code> justo dentro de la
cláusula <i>condición</i> del <code>while</code> de esta manera:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">let</span> ((num 0))
  (<span style="color: #ff79c6; font-weight: bold;">while</span>
      (<span style="color: #ff79c6; font-weight: bold;">progn</span>
       (princ (format <span style="color: #f1fa8c;">"Iteraci&#243;n %d.\n"</span> num))
       (set 'num (1+ num))
       (y-or-n-p <span style="color: #f1fa8c;">"&#191;Repetir otra vez?"</span>))))
</pre>
</div>

<p>
Si lo evaluamos mostrará el mensaje mientras contestemos <code>y</code> a la
pregunta de si repetimos otra vez.
</p>

<p>
Hay otras formas de iteración como <code>dolist</code> que repite el proceso a lo
largo de los elementos de una lista o <code>dotimes</code> que lo repite el
número de veces que se establezca. Los dejaré para más adelante cuando
las necesitemos en algún ejemplo.
</p>
</div>
</div>
<div id="outline-container-org8c1fbce" class="outline-2">
<h2 id="org8c1fbce">Conclusión</h2>
<div class="outline-text-2" id="text-org8c1fbce">
<p>
He dejado para otro artículo una forma de construir bucles más
compleja, que se llama <i>iteración</i>. Son funciones que se llaman a sí
mismas para hacer un determinado proceso. Pero como lo veremos en otra
entrega no diré más aquí.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/emacs-lisp/index.html">emacs-lisp</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[emacs-lisp]]></category>
  <link>https://notxor.nueva-actitud.org/2019/01/18/condicionales-bucles-e-iteracion.html</link>
  <pubDate>Fri, 18 Jan 2019 18:11:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Tipos de datos]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-01-13</div>
<p>
Cuando escribimos un <i>programa</i> es porque necesitamos tratar la
información como nosotros necesitamos que sea tratada. Esa información
es lo que llamamos <i>datos</i>.
</p>

<p>
En otros lenguajes, los datos y los programas son cosas separadas, sin
embargo, en <i>Lisp</i>, los datos y los programas son la misma cosa.
Dicho de otro modo, los programas pueden ser tratados como si fueran
un tipo de datos más. Ese es el motivo principal de que, como vimos en
el artículo anterior, usáramos el «'» para advertir a <i>Lisp</i> cuándo
una estructura es un <i>programa</i> o es un <i>dato</i>... ya me perdonaréis
por utilizar <i>programa</i> como sinónimo de <i>código ejecutable</i>.
</p>

<p>
En el código, aparte de <i>programas</i> y <i>datos</i>, existe otro tipo de
información: los <i>comentarios</i>.  Un comentario es un texto que se
añade en el código con el objeto de hacer anotaciones o aclaraciones
sobre el funcionamiento del mismo. En una línea, todo texto que
aparezca tras un carácter «;», será ignorado por <i>Lisp</i>.
</p>
<div id="outline-container-org197d4d0" class="outline-2">
<h2 id="org197d4d0">Tipos de datos básicos</h2>
<div class="outline-text-2" id="text-org197d4d0">
<p>
Voy a explicar los tipos más habituales y sencillos: <i>números</i>,
<i>caracteres</i>, <i>cadenas</i>, <i>cons</i>, <i>secuencias</i>, <i>símbolos</i>. Dejaré los
de edición, propios de <i>Emacs</i>, para más adelante en algún ejemplo. Si
alguno de los presentes tiene prisa, en la ayuda de <i>Emacs</i>, en el
manual de <i>Elisp</i> hay todo un capítulo dedicado a ese tipo de datos.
</p>
</div>
<div id="outline-container-orgeae3a0d" class="outline-3">
<h3 id="orgeae3a0d">Datos lógicos</h3>
<div class="outline-text-3" id="text-orgeae3a0d">
<p>
En realidad, todos los datos pueden funcionar como lógicos. También se
llaman datos <i>booleanos</i> en referencia al <i>álgebra de Bool</i>.  Sólo hay
dos valores posibles: <i>verdadero</i> y <i>falso</i>.
</p>

<p>
Algunos os habréis fijado que en algunos valores que se establecen en
el fichero de configuración de <i>Emacs</i> aparecen expresiones como:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> variable1 nil)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> variable2 t)
</pre>
</div>

<p>
En ese caso, <code>nil</code> es el valor lógico para <i>falso</i> y <code>t</code> es el valor
lógico para <i>verdadero</i>.
</p>
</div>
</div>
<div id="outline-container-org2e5825a" class="outline-3">
<h3 id="org2e5825a">Números</h3>
<div class="outline-text-3" id="text-org2e5825a">
<p>
En <i>elisp</i> podemos trabajar con <i>enteros</i> o con <i>decimales</i>. Los
números enteros pueden contener un rango mínimo de -536.870.912 a
536.870.911. Es decir, el rango que se pueden utilizar con 30
<i>bits</i>. Si necesitamos números más grandes, <i>Lisp</i> añadirá espacio
para contenerlos, por ejemplo, podemos evaluar el siguiente código en
el <i>buffer <b>scratch</b></i> sin obtener un mensaje de error:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(1+ 536870911)
</pre>
</div>

<p>
Claro, que lo que hace lo que hace <i>Emacs</i> para cargar ese resultado
es utilizar un <i>número de coma flotante</i> y aunque muestre <code>536870912</code>
internamente se utilizará el número <code>536870912.0</code>.
</p>

<p>
La forma de definir un entero (en base diez) es mediante una secuencia
de cifras precedidas de un signo (<code>+</code> o <code>-</code>), opcional si el número es
positivo, o también seguido de un <code>.</code> final. Por ejemplo, son números
enteros válidos, junto con lo que devuelven si los evaluamos:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">+12       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 12
</span>-3        <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; -3
</span>4.        <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 4
</span>200       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 200</span>
</pre>
</div>

<p>
Los números de <i>coma flotante</i> tienen una parte <i>entera</i> y una parte
<i>decimal</i>. Veamos cinco formas de escribir el mismo número:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">700.0
+7e2
7.0e+2
+7000000e-4
.7e3
</pre>
</div>

<p>
Donde <code>e</code> indica una potencia de <code>10</code>.
</p>
</div>
</div>
<div id="outline-container-orgfe16581" class="outline-3">
<h3 id="orgfe16581">Caracteres</h3>
<div class="outline-text-3" id="text-orgfe16581">
<p>
Los <i>caracteres</i> los he puesto aparte de los números, no porque
internamente sean algo distinto a un número, sino porque representan
otros contenidos: letras, signos ortográficos o caracteres de control,
por ejemplo. En <i>Emacs</i> los valores que representan caracteres tienen
32 <i>bits</i>. Si el valor es menor de 127 se considera un carácter
<code>ASCII</code>; el resto de valores se consideran <code>no-ASCII</code>.
</p>

<p>
Hay algunos caracteres especiales que si estás utilizando <i>Emacs</i> y
lees sus manuales, estarás acostumbrado a ver escritos en ellos:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">?\a    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 7   control-g,               &#8216;</span><span style="color: #bd93f9;">C-g</span><span style="color: #6272a4;">&#8217;
</span>?\b    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 8   backspace,        &lt;BS&gt;,  &#8216;</span><span style="color: #bd93f9;">C-h</span><span style="color: #6272a4;">&#8217;
</span>?\t    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 9   tabulador,       &lt;TAB&gt;,  &#8216;</span><span style="color: #bd93f9;">C-i</span><span style="color: #6272a4;">&#8217;
</span>?\n    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 10  salto de l&#237;nea,          &#8216;</span><span style="color: #bd93f9;">C-j</span><span style="color: #6272a4;">&#8217;
</span>?\v    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 11  tab. vertical,           &#8216;</span><span style="color: #bd93f9;">C-k</span><span style="color: #6272a4;">&#8217;
</span>?\f    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 12  formfeed,                &#8216;</span><span style="color: #bd93f9;">C-l</span><span style="color: #6272a4;">&#8217;
</span>?\r    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 13  retorno de carro, &lt;RET&gt;, &#8216;</span><span style="color: #bd93f9;">C-m</span><span style="color: #6272a4;">&#8217;
</span>?\e    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 27  escape,           &lt;ESC&gt;, &#8216;C-[&#8217;
</span>?\s    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 32  espacio,          &lt;SPC&gt;
</span>?\\    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 92  contrabarra,       &#8216;\&#8217;
</span>?\d    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 127 delete,           &lt;DEL&gt;</span>
</pre>
</div>

<p>
Evidentemente, la forma más habitual de expresar un carácter en
<i>Emacs</i> es escribir el carácter en cuestión anteponiendo un <code>?</code>, si
evaluamos <code>?A</code> en el <i>buffer <b>scratch</b></i> nos devolverá 65, pero también
podemos conseguir ese carácter expresándolo como <code>?\o101</code>, <code>?\x41</code>, en
formatos octal y hexadecimal, también puedes utilizar el valor
<i>Unicode</i> <code>?\u0041</code> o incluso el nombre de la letra en cuestión, como
en <code>?\N{latin capital letter A}</code>.
</p>

<p>
Más interesante que aprenderse la tabla de caracteres <i>unicode</i> es
conocer los caracteres de <i>control</i>. Para ellos podemos utilizar la
notación <code>^</code>. Por ejemplo, si tomamos el último carácter de la lista
anterior, <code>&lt;DEL&gt;</code>, además de <code>?\d</code>, podemos utilizar la secuencia
<code>?\^?</code> o incluso la secuencia <code>?\C-?</code>.
</p>

<p>
Igual que los caracteres <code>control</code> también podemos acceder a los
caracteres <i>escapados</i> con <code>&lt;META&gt;</code>. Por ejemplo, podemos escapar el
valor <code>?\M-x</code> o incluso mezclar ambas formas para escribir <code>C-M-c</code>
como <code>?\M-\C-c</code>, o <code>?\C-\M-c</code>, o <code>?\M-\003</code>.
</p>

<p>
Del mismo modo podemos utilizar las teclas <code>hyper</code>, <code>super</code> y <code>alt</code>,
con los modificadores <code>\H-</code>, <code>\s-</code> y <code>\A-</code>. Por ejemplo, la secuencia
de teclas <i>Alt-Hyper-Meta-x</i> podemos tenerla con <code>?\H-\M-\A-x</code>.
Numéricamente, los valores son 2^22 para <code>alt</code>, 2^23 para <code>super</code> y
2^24 para <code>hyper</code>.
</p>
</div>
</div>
<div id="outline-container-org7f0935c" class="outline-3">
<h3 id="org7f0935c">Símbolos</h3>
<div class="outline-text-3" id="text-org7f0935c">
<p>
Un símbolo podemos definirlo como la manera de referirnos a un objeto
mediante un nombre.
</p>

<p>
Un símbolo puede contener cualquier carácter. Lo recomendable es
utilizar letras, dígitos y algún signo de puntuación normal, como
<code>-+=*/</code> para nombrar nuestras variables y funciones. Aunque tampoco
necesitan una notación especial, los caracteres <code>_~!@$%^&amp;:&lt;&gt;{}?</code>
suelen ser menos utilizados. Cualquier otro carácter se puede utilizar
en un símbolo escapándolo con un carácter <code>\</code>. Pero teniendo en cuenta
que mientras <code>\t</code> en una cadena significa un tabulador, en un símbolo
será sólo la letra <code>t</code>. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> al\t 22)     <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 22
</span>alt                <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 22</span>
</pre>
</div>

<p>
Tenemos que tener en cuenta alguna limitación. Si escribimos <code>+1</code>
<i>Emacs</i> lo interpretará como el número 1 entero; sin embargo, no habrá
problema en utilizar como nombre <code>22+</code>, por ejemplo.
</p>

<p>
Otro detalle a tener en cuenta es que en otros <i>Lisp</i>, como el <i>common
lisp</i> los símbolos <code>uno</code> y <code>UNO</code> son equivalentes, sin embargo en
<i>elisp</i> son dos símbolos diferentes.
</p>

<p>
En todo caso, siempre es recomendable utilizar nombres que sean
fácilmente leídos, escritos y comprendidos; a poder ser, que el nombre
sea consecuente con el contenido que le va a ser asignado.
</p>
</div>
</div>
<div id="outline-container-orged2a317" class="outline-3">
<h3 id="orged2a317">Diccionarios o listas asociativas</h3>
<div class="outline-text-3" id="text-orged2a317">
<p>
<a href="https://notxor.nueva-actitud.org/blog/2019/01/05/sobre-listas-y-atoms/">En otro artículo de la serie</a> ya hablé de las <i>cons cells</i> y las listas
y vimos cómo se pueden crear. Pero hoy voy a hablar de otro de los
usos que nos puede ser muy útil: los <i>diccionarios</i> o <i>listas
asociativas</i>. Vemos un ejemplo para explicarlo un poco mejor.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> colores '((rosa . rojo)
                (margarita . amarillo)
                (lirio . blanco)
                (violeta . azul)))

(cdr (assoc 'rosa colores))            <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; rojo
</span>
(car (rassoc 'blanco colores))         <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; lirio
</span>
</pre>
</div>

<p>
Como ya hablé de <code>car</code> y <code>cdr</code> no lo repito aquí, se puede uno ir a
ese otro artículo o consultar la ayuda de <i>Emacs</i> (que será más rápido
y exacto).
</p>

<p>
Como se puede ver, al principio creamos una variable que consiste en
una lista de <i>cons cell</i> asignadas al símbolo <code>colores</code>. Dentro de la
lista podemos buscar el <i>par</i> por el primer elemento o por el
segundo. Si lo hacemos por el primer elemento (o <code>car</code>) utilizamos la
función <code>assoc</code> que devolverá el primer elemento que coincida con el
símbolo buscado. Si buscamos por el segundo elemento (el <code>cdr</code>) hará
lo mismo.
</p>

<p>
Como <code>(assoc 'rosa colores)</code> devolverá <code>(rosa . rojo)</code>, si a mí sólo
me interesa el valor del color, que he almacenado en la posición
<code>cdr</code>, lo que haré será pedirlo con la función <code>cdr</code>. Y al revés, si
busco por colores con <code>(rassoc 'blanco colores)</code>, devolverá <code>(lirio
. blanco)</code>; si a mí sólo me interesa el nombre de la flor de ese
color, que hemos almacenado en la posición <code>car</code> del par, la pido con
la instrucción <code>car</code>.
</p>
</div>
</div>
<div id="outline-container-org5dc2601" class="outline-3">
<h3 id="org5dc2601">Listas de propiedades</h3>
<div class="outline-text-3" id="text-org5dc2601">
<p>
Las <i>listas de propiedades</i> (<i>property list</i> o <i>plist</i> para acortar)
es una lista de pares de elementos. Normalmente, el nombre de la
propiedad es un símbolo que se asociará al valor correspondiente.
</p>

<p>
Lo vemos también con un ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> contacto '(nombre <span style="color: #f1fa8c;">"Fulanito"</span>
                 apellidos <span style="color: #f1fa8c;">"de Tal y Tal"</span>
                 telefono <span style="color: #f1fa8c;">"987654321"</span>))

(plist-get contacto 'nombre)          <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; "Fulanito"
</span>(plist-get contacto 'telefono)        <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; "987654321"
</span>(plist-get contacto 'apellidos)       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; "de Tal y Tal"
</span>
(plist-put contacto 'poblacion <span style="color: #f1fa8c;">"Madrid"</span>)

(plist-get contacto 'poblacion)       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; "Madrid"</span>
</pre>
</div>

<p>
Como vemos, una lista de propiedades también trabaja asociando valores
de pares, pero lo hace sobre cualquier tipo de lista. En el ejemplo se
utilizan <i>símbolos</i> para las propiedades y <i>cadenas de texto</i> para los
contenidos, pero se pueden utilizar cualquier tipo de datos válidos en
<i>elisp</i>, tanto para uno como para el otro.
</p>
</div>
</div>
<div id="outline-container-orgbb206cd" class="outline-3">
<h3 id="orgbb206cd">Secuencias</h3>
<div class="outline-text-3" id="text-orgbb206cd">
<p>
En <i>Lisp</i> es habitual encontrar estructuras de datos que son
secuencias. Las más habituales son las <i>cadenas de texto</i> (para
abreviar <i>cadenas</i> a secas), los <i>arrays</i> y los <i>vectores</i>.
</p>

<p>
El siguiente diagrama muestra la relación entre distintos tipos de
secuencia.
</p>


<figure id="orge2b5428">
<img src="./imagen/secuencias.png" alt="secuencias.png">

</figure>

<p>
Acceder a cualquier elemento se puede hacer como sigue a continuación:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(elt '(1 2 3 4) 2)      <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 3</span>
</pre>
</div>

<p>
Puede llamar la atención que pidiendo la posición 2, nos devuelva
el 3. A estas alturas, los lectores programadores tienen la neurona
acostumbrada a comenzar a contar índices por el 0. Si no eres
programador y te cuesta imaginarte cómo, fíjate en el siguiente
esquema:
</p>


<figure id="org99fbc5e">
<img src="./imagen/indices.png" alt="indices.png">

</figure>

<p>
Uno puede pensar en los índices como los indicadores que señalan no a
las posiciones sino a la «imaginaria separación» entre ellas.
</p>
</div>
<div id="outline-container-orgd67ca8d" class="outline-4">
<h4 id="orgd67ca8d">Arrays</h4>
<div class="outline-text-4" id="text-orgd67ca8d">
<p>
Un <i>array</i> es un objeto de <i>elisp</i> que tiene una secuencia de
<i>espacios</i> donde almacenar otros objetos <i>Lisp</i>. En un <i>array</i>, puesto
que los elementos se almacenan de forma secuencial, el tiempo de
acceso a cada uno de esos elementos es constante. Como podemos ver en
el gráfico anterior, los <i>vectores</i> y las <i>cadenas</i> son dos tipos
especiales de <i>array</i>.
</p>

<p>
Las funciones más socorridas en conjuntos de datos de tipo array son
las de obtener o modificar un elemento:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(aref conjunto &#237;ndice)
(aset conjunto &#237;ndice valor)
</pre>
</div>
</div>
</div>
<div id="outline-container-org7b30db9" class="outline-4">
<h4 id="org7b30db9">Cadenas</h4>
<div class="outline-text-4" id="text-org7b30db9">
<p>
Una <i>cadena de texto</i> es una secuencia de caracteres, como podríamos
definir como <i>array de caracteres</i>. Podríamos definir una cadena por
ejemplo como:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> cadena (string ?H ?o ?l ?a))       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; "Hola"
</span>
(substring cadena 0 2)                   <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; "Ho"
</span>(substring cadena -4 -2)                 <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; "Ho"
</span>
(string= <span style="color: #f1fa8c;">"Hola"</span> cadena)                  <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; t
</span>(string= <span style="color: #f1fa8c;">"hola"</span> cadena)                  <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; nil
</span>
(aref cadena 3)                          <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt;  97 -- ?a
</span>(aset cadena 3 ?o)                       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 111 -- cadena == "Holo"</span>
</pre>
</div>

<p>
Como se ve en el ejemplo, se pueden acceder a los caracteres que
forman una cadena por su posición.  Si comenzamos a contar la posición
desde el inicio, los números de índice son positivos. Si comenzamos
por el final, los números serán negativos.
</p>

<p>
Otra forma muy socorrida de conseguir cadenas bien formadas son las
<i>cadenas con formato</i>. Suelen utilizarse para mostrar mensajes de
aviso dando formato legible a nuestros datos. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(format <span style="color: #f1fa8c;">"El valor del m&#225;rgen derecho es %d."</span> fill-column)
</pre>
</div>

<p>
Los valores que se pueden utilizar para ser sustituidos.
</p>

<dl class="org-dl">
<dt><code>%s</code></dt><dd>será reemplazada por una cadena.</dd>
<dt><code>%o</code></dt><dd>lo sustituye un número entero en base octal.</dd>
<dt><code>%d</code></dt><dd>lo sustituye un número entero en base decimal.</dd>
<dt><code>%x</code></dt><dd>lo sustituye un número entero en base hexadecimal.</dd>
<dt><code>%e</code></dt><dd>lo sustituye un número en notación exponencial.</dd>
<dt><code>%f</code></dt><dd>lo sustituye un número decimal.</dd>
</dl>

<p>
Hay más comodines para dar formatos a los datos, pero esos son los más
habituales y los más usados, pues son los correspondientes a mostrar
cadenas y números.
</p>
</div>
</div>
<div id="outline-container-org3e8544c" class="outline-4">
<h4 id="org3e8544c">Vectores</h4>
<div class="outline-text-4" id="text-org3e8544c">
<p>
Un <i>vector</i> es básicamente un <i>array</i> que puede contener cualquier
tipo de objetos <i>Lisp</i> en su interior. Para distinguirlo claramente de
las listas, se utilizan los corchetes en la notación. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> mi-vector [1 dos '(tres) <span style="color: #f1fa8c;">"cuatro"</span> [cinco]])
</pre>
</div>

<p>
Como se puede observar, los vectores, como los números y las cadenas,
se consideran datos estáticos para la evaluación, es decir, cuando
<i>Lisp</i> los evalúa el valor devuelto es el mismo <i>vector</i>.
</p>
</div>
</div>
</div>
<div id="outline-container-org3bb4340" class="outline-3">
<h3 id="org3bb4340">structs</h3>
<div class="outline-text-3" id="text-org3bb4340">
<p>
Un <code>struct</code> es tipo de datos definido por el usuario. Mejor, lo vemos
con un ejemplo. Voy a imaginar que quiero definir, a bote pronto y no
con mucho arte, una estructura que albergue datos sobre <i>cuentas</i>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">cl-defstruct</span> <span style="color: #8be9fd; font-style: italic;">cuenta</span> id balance)       <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; cuenta
</span>
(<span style="color: #ff79c6; font-weight: bold;">setq</span> a
  (make-cuenta <span style="color: #8be9fd; font-style: italic;">:id</span> 7 <span style="color: #8be9fd; font-style: italic;">:balance</span> 17.12))  <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; #s(cuenta 7 17.12)
</span>
(cuenta-id a)                          <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 7
</span>
(<span style="color: #ff79c6; font-weight: bold;">setf</span> (cuenta-balance a) 0)            <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; 0 -- cuenta == #s(cuenta 7 0)
</span>
</pre>
</div>

<p>
En la definición he utilizado la <i>macro</i> <code>cl-defstruct</code>. Internamente,
un <i>struct</i> es muy similar a un <i>array</i>, sin embargo, viene aderezado,
como se puede ver en el ejemplo de funciones <i>automágicas</i> que nos
permiten acceder a los <i>campos</i> del registro.
</p>
</div>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/elisp/index.html">elisp</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[elisp]]></category>
  <link>https://notxor.nueva-actitud.org/2019/01/13/tipos-de-datos.html</link>
  <pubDate>Sun, 13 Jan 2019 17:52:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Un poco más sobre funciones]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-01-09</div>
<div id="outline-container-org2438b43" class="outline-2">
<h2 id="org2438b43">Un poco de historia para comenzar</h2>
<div class="outline-text-2" id="text-org2438b43">
<p>
Una de las bellezas de <i>Lisp</i>, o de <i>Smalltalk</i>, es que se basan en un
concepto claro y lo llevan hasta sus últimas consecuencias.  En
<i>Smalltalk</i> todo el sistema se basa en <i>objetos</i> enviándose <i>mensajes</i>
entre ellos. Así, por ejemplo, en <i>Smalltalk</i> la forma de ejecutar
código de manera condicional no depende de una palabra clave del
lenguaje, sino que es un <i>mensaje</i> que se manda a un <i>objeto lógico</i>.
Otros lenguajes recurren en su <i>sintaxis</i> a expresiones definidas por
el intérprete o el compilador con lo que se llaman <i>palabras
reservadas</i>. No voy a darle muchas vueltas más al tema de las
<i>palabras reservadas</i>.
</p>

<p>
Sólo comentar que Alan Kay, desarrollador principal de <i>Smalltalk</i>
afirmó verse muy influenciado por <i>Lisp</i>, y también remarcar que
<i>Smalltalk</i> influyó en <i>Lisp</i> haciendo que se pudiera utilizar POO
(Programación Orientada a Objetos).  La clave fundamental de ambos
sistemas es que están pensados para que un programador ─que sepa lo
que hace─ pueda redefinir todo el sistema y también en ambos, se puede
hacer <i>en caliente</i>, mientras se está ejecutando.  Por lo tanto, todo
el código del sistema es accesible para el programador. Lo digo por
propia experiencia, me he cargado unas cuantas imágenes de trabajo de
<i>Smalltalk</i>, intentando hacer lo que no debía. Lo bueno, es que a
pesar de eso nunca pasa nada: reinicias el trabajo, quitas lo que has
puesto o metes lo que has quitado y las cosas se suelen arreglar, no
tengáis miedo. Al contrario, equivocándote aprendes más que no
haciendo y si no eres capaz de arreglarlo, siempre puedes
reinstalarlo (que tampoco es tan grave).
</p>

<p>
El <i>Lisp</i> fue presentado por John McCarthy en 1960 en el MIT en un
artículo con el título <i>«Funciones recursivas de expresiones
simbólicas y su cómputo a máquina, Parte I»</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, demostrando en él
que con algunos operadores simples y una notación para las funciones,
se puede construir un lenguaje de programación completo para procesar
algoritmos.
</p>
</div>
<div id="outline-container-org09e8f0e" class="outline-3">
<h3 id="org09e8f0e">Buenas maneras</h3>
<div class="outline-text-3" id="text-org09e8f0e">
<p>
También comparten, ambos sistemas, algunas buenas costumbres de
programación. Por ejemplo, el documentar bien su código. Ambos parten
del hecho de que el código se escribe una vez y se lee muchas para
modificarlo algunas, así pues el código suele estar
documentado. Además, aunque sea un <i>lenguaje interpretado</i> los
comentarios no disminuyen la efectividad del código, porque el sistema
lo compila a un <i>byte code</i> que interpreta la <i>máquina</i> del
sistema. No seáis rácanos con los comentarios, lo que ahora sentado
con tranquilidad haciendo nuestras cosas es lógico, deja de serlo unos
meses, o semanas, o días después, cuando el problema que nos llevó a
escribir ese código dejó de estar en nuestra cabeza, porque lo dejamos
<i>solucionado</i>.
</p>

<p>
Otra de las cosas que aprendí con <i>Smalltalk</i> y que mantengo desde
hace tiempo son las <i>pruebas unitarias</i> o <i>Units tests</i>.  Algo muy
lógico cuando lo entiendes pero a lo que no se llega con el <i>sentido
común</i>. Las pruebas unitarias se basan en que hay que escribir primero
<i>código suplementario</i> que pruebe que nuestro <i>código productivo</i>
funciona. Lo iremos viendo cuando nos metamos en faena.
</p>
</div>
</div>
</div>
<div id="outline-container-orgc92c108" class="outline-2">
<h2 id="orgc92c108">Listas, funciones y cálculo lambda</h2>
<div class="outline-text-2" id="text-orgc92c108">
<p>
<i>Lisp</i> se desarrolló basándose en el <i>cálculo lambda</i>, que es un
sistema formal presentado en 1930 por Alonzo Church y Stephen Kleene
para investigar la definición de <i>función</i>, la noción de aplicaciones
de funciones y la recursión.
</p>

<p>
Como estos son conceptos matemáticos que van mas allá de lo que puede
abarcar éste artículo, lo dejaremos aquí. Sólo avanzar que el <i>cálculo
lambda</i> tiene una gran influencia en los lenguajes llamados
<i>funcionales</i> como <i>Lisp</i> o <i>Haskell</i>.
</p>

<p>
El elemento fundamental de <i>Lisp</i> son las listas. Dado que en <i>Lisp</i>
las listas se delimitan con paréntesis, hay quien dice que LISP es un
acrónimo de <i>Lost In Stupid Parentheses</i>. Y la verdad es que a los que
se acercan por primera vez al lenguaje les puede llamar la atención la
profusión de los mismos.
</p>
</div>
<div id="outline-container-org9b71afa" class="outline-3">
<h3 id="org9b71afa">Definir funciones</h3>
<div class="outline-text-3" id="text-org9b71afa">
<p>
Una función se define llamando a <code>defun</code> de la siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">incremento</span> (num)
  <span style="color: #6272a4;">"Realiza el incremento de un n&#250;mero."</span>
  (+ 1 num))
</pre>
</div>

<p>
Podemos ver una serie de elementos que se van a repetir siempre en la
estructura de <code>defun</code>. El primero tras la llamada es el <i>nombre</i> de la
función que estamos creando, en nuestro caso <code>incremento</code>. A
continuación viene una lista que son los <i>argumentos</i> de la función,
en nuestro caso sólo hay uno y lo llamamos <code>num</code>, lo podríamos haber
llamado <i>número</i>, pero es más largo. El tercer elemento de la
definición es una cadena de texto que describe qué es lo que hace
nuestra función<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. La última parte es el <i>cuerpo</i> de la función,
en nuestro caso el cálculo de sumar uno al número que le hemos
pasado. En <i>emacs-lisp</i> ya existe una función que hace lo mismo: <code>1+</code>, pero
esto sólo es para nuestro ejemplo. Un ejercicio sencillo: teclea el
texto de la definición anterior y cuando lo tengas evalúalo, con <code>C-j</code>
o con <code>C-x C-e</code>. Cuando lo tengas haz la siguiente prueba:
</p>

<ol class="org-ol">
<li>Teclea <code>M-x apropos</code> y <code>&lt;RET&gt;</code>.</li>
<li>Teclea <code>incremento</code>... ¿Qué sucede?</li>
</ol>

<p>
Efectivamente, la cadena que hemos escrito en nuestra función pasa a
estar disponible en uno de los sistemas de ayuda de <i>Emacs</i>:
<code>apropos</code>.  Recuérdalo, porque muchas veces la forma de enterarse de
para qué sirve una variable o cómo funciona una función (valga la
«rebuznancia») es llamar a <code>apropos</code>. Y es muy frustrante acudir a la
ayuda y no encontrar nada, así que recuerdo: <i>Documenta todo el código
que escribas, por tu propio bien</i>.
</p>
</div>
</div>
<div id="outline-container-org98d469b" class="outline-3">
<h3 id="org98d469b">Usar funciones</h3>
<div class="outline-text-3" id="text-org98d469b">
<p>
Vamos con un ejemplo y sobre él explicaré algunas cosas más delicadas
o detalles. Vamos a aprovechar que tenemos definida ya la función
<code>incremento</code> y vamos a teclear el siguiente código. De momento iremos
evaluando cada expresión al finalizarla en el <i>buffer</i> <code>*scratch*</code>.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(set 'lista1 '(1 5 9))
(<span style="color: #ff79c6; font-weight: bold;">setq</span> lista2 (list 1 5 9))
</pre>
</div>

<p>
Estoy definiendo dos listas diferentes con el mismo contenido. Lo hago
de dos maneras para apreciar el detalle del apóstrofe en el código. Ya
he comentado que el apóstrofe se coloca sólo en los casos en que
queramos que <i>Lisp</i> no interprete el elemento como <i>ejecutable</i>. En
ambos casos definimos una variable global que contendrá una lista con
los elementos 1, 5 y 9. Ambas definiciones tienen tres elementos: la
función de asignación: <code>set</code> y <code>setq</code>; el nombre de la variable:
<code>lista1</code> y <code>lista2</code> y el contenido que se asigna a ellas. Si nos
fijamos, vemos que en algunos lugares hemos añadido un carácter «'».
¿Cuándo se pone y cuándo no? Pues como he dicho antes, se pone cuando
queremos que <i>Lisp</i> no evalúe la expresión que le pasamos. Por
ejemplo, no queremos que evalúe la expresión <code>lista1</code>, así que le
ponemos el «'»; en el segundo caso <code>lista2</code> no lleva porque <code>setq</code>
hace lo mismo que <code>set</code> pero no evalúa la siguiente expresión, o dicho
de otro modo (no exacto): pone por nosotros ese apóstrofe (<i>quote</i> en
inglés). Si vemos cómo formamos la expresión que asignamos, en el
primer caso se lo damos hecho, es la lista <code>(1 5 9)</code>, mientras que en
el segundo caso llamamos a la función <code>list</code> para que forme la lista
con los elementos que le pasamos. En el primer caso, no queremos que
<i>Lisp</i> evalúe la lista<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>, sin embargo, en el segundo, queremos que
evalúe <code>list</code> y nos devuelva su valor. ¿Lioso? Al principio puede
serlo, pero con la práctica se verá que es sencillo de entender.
</p>
</div>
</div>
<div id="outline-container-org8a542d0" class="outline-3">
<h3 id="org8a542d0">Un apunte sobre macros</h3>
<div class="outline-text-3" id="text-org8a542d0">
<p>
No quiero liarnos con las <i>macros</i>. Los menciono sólo porque <i>Emacs</i>
se llama <i>editor de macros</i> y algo hay que saber sobre ellas. Pero
¿qué es una macro?
</p>

<p>
Vamos a ver un ejemplo de <i>macro</i>: <code>defun</code>. Sí, <code>defun</code> no es una
función es una <i>macro</i> que define el símbolo que le pasamos como
función, crea una expresión lambda y la asigna al símbolo creado. Su
estructura es la siguiente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">nombre</span> (argumentos)
  <span style="color: #6272a4;">"documentaci&#243;n"</span>
  cuerpo)
</pre>
</div>

<p>
La documentación es opcional, claro, pero muy recomendable
utilizarla.<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>
</p>

<p>
Tampoco hay que preocuparse demasiado por las macros si ahora no se
entienden. Una macro es una estructura que se parece mucho a una
función: tiene un <i>nombre</i> al que llamar y una lista de elementos que
son los <i>argumentos</i> de la macro. La diferencia fundamental es que los
argumentos que se pasan a la macro no se evalúan, se pasan tal cual con
la expresión que se suministre; sin embargo, los argumentos de una
función son el resultado de evaluar los elementos que se le pasen como
argumentos. Un lío a estas alturas ¿no?
</p>

<p>
Digo que no hay que preocuparse demasiado por ellas, porque
normalmente se utilizan para <i>extender</i> el lenguaje <i>Lisp</i> y no
estamos en ese nivel aún.
</p>

<p>
Vemos un ejemplo sencillo con nuestro incrementador para aplicarlo a
variables:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defmacro</span> <span style="color: #50fa7b; font-weight: bold;">inc</span> (var)
  (list 'setq var (list 'incremento var)))
</pre>
</div>

<p>
Si lo probamos en el <i>buffer</i> <code>*scratch*</code> veremos que no funciona
llamándolo con <code>(inc 4)</code>, porque trabaja con variables (por eso, el
argumento lo hemos llamado <code>var</code>). ¿Cómo trabaja la macro? Supongamos
que tenemos una variable <code>x</code> con valor 4. Lo que hace la macro es
convertir su <i>cuerpo</i> en la siguiente expresión:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> x (incremento x))
</pre>
</div>

<p>
Esta expresión es la que evalúa <i>Lisp</i> para devolvernos la variable
<code>x</code> incrementada.
</p>
</div>
</div>
</div>
<div id="outline-container-org8c9809a" class="outline-2">
<h2 id="org8c9809a">Un pequeño apunte sobre tipos de datos</h2>
<div class="outline-text-2" id="text-org8c9809a">
<p>
Vamos a hacer un experimento con nuestra función <code>incremento</code>. Como
vemos el parámetro que trabaja lo hemos llamado <code>num</code>, lo podríamos
haber llamado <code>pepe</code> como mi vecino o <code>juan</code> como mi cuñado, pero no
es la función de los nombres. Es aconsejable que utilicemos los
nombres también para dar una pista de lo que es: en nuestro caso un
número. Si a nuestra función le enviamos un valor numérico no hay
problema. Evaluad las siguientes expresiones una a una:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(incremento 2)
(incremento 0.5)
</pre>
</div>

<p>
No hay problema. La primer nos devolverá <code>3</code> y la segunda <code>1.5</code>.
Funciona como esperamos, pero ¿qué ocurre si le pasamos una cadena?
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(incremento <span style="color: #f1fa8c;">"hola"</span>)
</pre>
</div>

<p>
Evalúa la expresión anterior y verás qué sucede... Aparecerá un
<i>buffer</i> de error que nos dirá algo así:
</p>

<pre class="example" id="org591f817">
Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p "hola")
  +(1 "hola")
  incremento("hola")
  eval((incremento "hola") nil)
  elisp--eval-last-sexp(t)
  eval-last-sexp(t)
  eval-print-last-sexp(nil)
  funcall-interactively(eval-print-last-sexp nil)
  call-interactively(eval-print-last-sexp nil nil)
  command-execute(eval-print-last-sexp)
</pre>

<p>
A destacar el <code>wrong-type-argument</code>... es decir, que el tipo del
argumento no concuerda con algo que espera utilizar en una función
<code>+</code>.
</p>

<p>
¿Podéis suponer qué ocurrirá si evaluamos la expresión <code>(incremento
?A)</code>? Probadlo... <code>66</code> ¿qué...? ¡Esto es un sindiós!
</p>

<p>
Bueno, no lo es: la expresión <code>?A</code> es la forma de pasar a la máquina
el carácter <code>A</code>, lo que ha hecho nuestra función es coger el carácter
A, cuyo valor numérico es 65 y sumarle 1. En la próxima entrega,
veremos más despacio esto de los tipos.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Nunca se publicó la parte II. 
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ese texto aparecerá una vez definida y cargada nuestra función
si utilizamos el <code>apropos</code> de <i>Elisp</i>. 
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Si <i>elisp</i> evalúa esa lista, lanzará un error diciendo que no
es una función válida y no la puede evaluar. 
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Hay otras estructuras opcionales en la definición de una
función, pero ya las veremos más adelante, cuando toque.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/elisp/index.html">elisp</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[elisp]]></category>
  <link>https://notxor.nueva-actitud.org/2019/01/09/un-poco-mas-sobre-funciones.html</link>
  <pubDate>Wed, 09 Jan 2019 17:32:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Sobre listas y atoms]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-01-05</div>
<p>
Hoy toca ver un poco más sobre la programación en <i>elisp</i>.
Concretamente cómo funcionan las <i>listas</i> y los tipos de datos que
pueden contener. Hablaré también un poco sobre algunas funciones
básicas para <i>procesar</i> listas.
</p>
<div id="outline-container-org797c073" class="outline-2">
<h2 id="org797c073">El primer programa: “Hola Mundo”</h2>
<div class="outline-text-2" id="text-org797c073">
<p>
Es tradición en los textos sobre programación incitar al lector a
hacer un primer programa muy sencillo que consiste en imprimir por
pantalla un mensaje que diga <code>Hola Mundo!</code>. Para no faltar a la
tradición, aunque esto ya lo hicimos en el artículo anterior sobre
<i>elisp</i>, escribiremos lo siguiente en el <i>buffer</i> <code>*scratch*</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(message <span style="color: #f1fa8c;">"Hola Mundo!"</span>)
</pre>
</div>

<p>
Es un programa muy sencillo y consiste sólo en usar una <i>función</i>
que muestra el mensaje cuando pulsamos <code>C-x C-e</code>.  Bueno, vale, era
sólo para refrescar un poco la memoria al repasar lo del primer día,
vamos con el tema de hoy.
</p>
</div>
</div>
<div id="outline-container-org4deda61" class="outline-2">
<h2 id="org4deda61">Listas</h2>
<div class="outline-text-2" id="text-org4deda61">
<p>
¿Qué es una lista? Pues básicamente todo lo que se encuentra encerrado
entre paréntesis. Es decir, en el ejemplo anterior hemos empleado una
<i>lista</i>. Si la observamos bien veremos que consta de dos elementos, el
primero es la función <code>message</code> y el segundo la cadena <code>Hola Mundo!</code>,
separados por un espacio.
</p>

<p>
El concepto de <i>lista</i> es central en <i>elisp</i>, como en cualquier otro
<i>Lisp</i> ─que recuerdo que significa básicamente <i>procesador de listas</i>...
si añadimos que <i>emacs</i> significa <i>editor de macros</i>, podemos decir
que <i>elisp</i> significará <i>procesador de listas del editor de macros</i>, o
algo así─.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">'(uno 2 <span style="color: #f1fa8c;">"tres"</span>)        <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Una lista de tres elementos
</span>'()                    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Una lista vac&#237;a</span>
</pre>
</div>
</div>
<div id="outline-container-org8c1d721" class="outline-3">
<h3 id="org8c1d721">Cómo están construidas las listas</h3>
<div class="outline-text-3" id="text-org8c1d721">
<p>
Las listas se construyen encadenando lo que se llaman <i>cons cell</i>.  Un
<i>cons cell</i> es un <i>objeto</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> que consiste en dos partes que se llaman la
parte <code>CAR</code> y la parte <code>CDR</code>.  Cada una de las partes puede contener
cualquier tipo de objeto soportado por <i>Lisp</i>.  Un esquema gráfico de
una lista sería el siguiente:
</p>


<figure id="org98ad0e7">
<img src="./imagen/diagrama-bloques.png" alt="diagrama-bloques.png">

</figure>

<p>
Obsérvese el último <code>cdr</code> apunta a <code>nil</code>. En <i>Lisp</i> una lista vacía es
equivalente a <code>nil</code>. Es decir, las siguientes expresiones son iguales:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">'(1 ())
'(1 nil)
</pre>
</div>

<p>
Una de las cosas que más puede liar a la gente es el uso del apóstrofe
«'». ¿Por qué lo llevan unas listas y otras no? ¿Cuándo hay que
ponerlo? Pues es fácil: lo usamos cuando queremos que <i>elisp</i> acepte
ese dato tal cual, sin intentar interpretarlo.
</p>

<p>
<i>Lisp</i> intenta <i>ejecutar</i> como función el primer elemento de una lista
utilizando el resto como los parámetros de la misma. Cuando no
necesitamos o no queremos que interprete una lista de esa manera se le
debe poner el «'», tal que <code>'elemento</code> en lugar del más largo <code>(quote
elemento)</code>, que es una <i>lista</i> que devuelve <code>elemento</code>. Hay quien
llamaría a eso <i>azúcar sintáctico</i> (cada vez que alguien habla de ese
tema me imagino a Celia Cruz cantando eso de «Asssúcar»).
</p>
</div>
</div>
<div id="outline-container-orgbc40e1b" class="outline-3">
<h3 id="orgbc40e1b">Atoms</h3>
<div class="outline-text-3" id="text-orgbc40e1b">
<p>
Las listas ya hemos visto que se basan en los <i>cons cell</i> y también
sabemos cómo funcionan.  Algún adelantadillo que lea esto dirá, pero
si son las <i>listas enlazadas</i> de toda la vida.  Bueno, sí, son listas
y están enlazadas pero no me voy a poner a estas alturas a hablar de
punteros y otros chismáticos de más bajo nivel. ¿Y esto qué tiene que
ver con los <i>Atoms</i>? Pues básicamente un <i>Atom</i> es toda otra
estructura o dato (véase la nota nº 1) que <i>Lisp</i> reconoce, que no se
basa en los <i>cons cell</i>.  Dicho a lo bruto ─y no siendo demasiado
preciso─ lo que no es una lista, es un <i>Atom</i>. Por lo que podríamos
decir también que los <i>Atoms</i> son <i>pichorros</i> que se pueden almacenar
en una <i>lista</i>.
</p>

<p>
Los hay de muchos tipos: números, cadenas, vectores, <i>hashs</i>,
<i>arrays</i>, en fin muchos tipos y sería largo ponerme a enumerar
todos. Mejor los dejamos en que existen y cuando los necesitemos nos
detenemos a explicarlos con más detalle. Si alguien tiene prisa por
conocerlos la ayuda de <i>Emacs</i> está ahí para algo.
</p>
</div>
</div>
<div id="outline-container-org9bc3aa2" class="outline-3">
<h3 id="org9bc3aa2">Jugando un poco con las listas</h3>
<div class="outline-text-3" id="text-org9bc3aa2">
<p>
Bueno, vamos a ver cómo funcionan los <i>cons cell</i> y las listas con un
poco de código.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(cons 'a 'b)                      <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; (a . b)
</span>(cons 'a (cons 'b 'c))            <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; (a b . c)
</span>(cons 'a (cons 'b (cons 'c nil))) <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; (a b c)</span>
</pre>
</div>

<p>
Como se puede ver la función <code>cons</code> utiliza un <i>cons cell</i> para
endosar en sus huecos los valores que le pasamos. Vamos a imaginarlo
gráficamente para ver si nos aclaramos mejor. El gran disléxico
Einstein decía: <i>Si no lo puedo dibujar no lo entiendo</i>.
</p>


<figure id="org9b8907d">
<img src="./imagen/cons-cell-lista.png" alt="cons-cell-lista.png">

</figure>

<p>
La última de las opciones se puede conseguir también con la función
<code>list</code>, que utilizará todos los argumentos que le pasemos para formar
una lista:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(list 'a 'b 'c) <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; (a b c)</span>
</pre>
</div>

<p>
También podemos utiliza <code>cons</code> para añadir elementos a una lista por
el inicio. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(cons 'c (list 'a 'b))  <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; (c a b)</span>
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-orgfa7c62e" class="outline-2">
<h2 id="orgfa7c62e">Funciones funcionales</h2>
<div class="outline-text-2" id="text-orgfa7c62e">
<p>
Muchos lenguajes de los llamados <i>funcionales</i> utilizan el concepto
iniciado por <i>Lisp</i> para obtener la cabecera de una lista y el resto
de la lista por separado. Esas funciones son <code>car</code> y <code>cdr</code>.
</p>

<p>
Primero, para este ejemplo un poco más de información sobre cosas
básicas, como dotar de valor a una variable. En <i>Lisp</i> una de las
cosas que me desconcertaron al principio fue que las variables y las
funciones pueden llamarse igual. En otros derivados de <i>Lisp</i> como
<i>scheme</i>, no. <i>Lisp</i> tiene dos <i>espacios de nombres</i> y <i>scheme</i> uno.
</p>
</div>
<div id="outline-container-org181b997" class="outline-3">
<h3 id="org181b997">set y setq</h3>
<div class="outline-text-3" id="text-org181b997">
<div class="org-src-container">
<pre class="src src-emacs-lisp">(set 'primera (list 'a 'b 'c)) <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; primera == (a b c)
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> segunda (list 'd 'e 'f)) <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; segunda == (d e f)</span>
</pre>
</div>

<p>
Las dos funciones hacen básicamente lo mismo: establecer el valor de
una variable. La diferencia entre las dos es que la primera tenemos
que marcar el nombre de la variable también con el apóstrofe (<i>quote</i>
en inglés) y la segunda lo hace ella por nosotros.  La mayoría del
código que podemos encontrar en el fichero de configuración de <i>Emacs</i>
utiliza alguna de estas dos funciones para establecer valores que
luego utiliza una determinada librería o módulo para ajustar su
funcionamiento.
</p>
</div>
</div>
<div id="outline-container-org8413b62" class="outline-3">
<h3 id="org8413b62">car y cdr</h3>
<div class="outline-text-3" id="text-org8413b62">
<p>
Estas dos funciones son la base del trabajo con listas. <code>car</code> devuelve
el primer <b>elemento</b> de una lista, por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(car primera)    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; a
</span>(car segunda)    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; d</span>
</pre>
</div>

<p>
Por el contrario, <code>cdr</code> nos devuelve una <b>lista</b> con la <i>cola</i>, es
decir la lista que contiene el resto del argumento.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(cdr primera)              <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; (b c)
</span>(cdr (cdr primera))        <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; (c)
</span>(cdr segunda)              <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; (e f)
</span>(cdr (cdr (cdr segunda)))  <span style="color: #6272a4;">; </span><span style="color: #6272a4;">==&gt; () == nil</span>
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-orge7bab57" class="outline-2">
<h2 id="orge7bab57">Conclusión</h2>
<div class="outline-text-2" id="text-orge7bab57">
<p>
Hoy hemos avanzado un poco más con el <i>elisp</i>. No mucho, pero lo
suficiente como para ir entendiendo cómo funciona. Así a brochazos
gordos todo es fácil, luego el diablo lo encontraremos en los
detalles.
</p>

<p>
De momento no hemos hecho nada más que rascar un poquito la superficie
del lenguaje. Pero ya se puede observar la belleza del mismo. Todo en
él es una <i>lista</i>, llamar a una función es utilizar una lista con el
nombre de la misma y los argumentos que necesita, pero los argumentos
pueden ser listas que procesan otras listas más internas. Eso hará que
aparezcan paréntesis por todos lados, que es lo primero que llama la
atención cuando estamos aprendiendo el lenguaje (y la principal
crítica de los que no lo conocen... ¿alguien a quien le intimidan los
paréntesis puede llamarse programador?( ¡Ooopppsss!
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Conste que acabo de reprimir las ganas de llamarlo <i>pichorro</i> o
<i>chismático</i>.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/elisp/index.html">elisp</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[elisp]]></category>
  <link>https://notxor.nueva-actitud.org/2019/01/05/sobre-listas-y-atoms.html</link>
  <pubDate>Sat, 05 Jan 2019 17:38:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Elisp para no programadores]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2019-01-03</div>
<div id="outline-container-orgd5f91b0" class="outline-2">
<h2 id="orgd5f91b0">Avisado quedas</h2>
<div class="outline-text-2" id="text-orgd5f91b0">
<p>
Uno de mis propósitos para año nuevo era escribir una introducción a
<i>elisp</i> para no programadores como yo. El objetivo es aprender: tengo
comprobado que aprendo más cuando explico las cosas que cuando me las
explican. Además, la documentación que encuentro sobre el tema en
español es escasa. Si alguien decide leer esta serie de <i>posts</i> le
debo advertir primero de una serie de hechos que pueden resultarle
extraños:
</p>

<ol class="org-ol">
<li>Soy psicólogo, no informático. No espere rigor en el vocabulario
informático ni se extrañe de que llame <i>pichorros</i> o <i>chismáticos</i>
a cosas que para un <b>no programador</b> se llaman <i>pichorro</i> o
<i>chismático</i>. No obstante procuraré ser lo más preciso en el
lenguaje y utilizar los términos correctamente.</li>
<li>Debido a lo anterior, es posible que se encuentre uno explicaciones
<i>automágicas</i> o no demasiado precisas, pero tal y como las entiende
o puede entender un profano.</li>
<li>También es posible que alguien haga las cosas de otra manera más
lógica, más sencilla, más mejor o más <i>friki</i>. Para eso están
abiertos los comentarios ─pero le recuero al <i>supuesto lector</i> que
la lógica, la sencillez o el <i>frikismo</i> son subjetivos─. Si quieres
que entienda otra lógica a la mía tendrás que explicar tu lógica de
programación como para que lo entienda un psicólogo, no un
informático.</li>
<li>No esperes tampoco una explicación concienzuda y sistemática sobre
todos los aspectos del lenguaje. Sólo hablaré sobre los temas que
más utilizo o sobre los que quiero utilizar o los que conozco, para
lo demás está el manual que viene incluido con <i>emacs</i>.</li>
</ol>

<p>
Pues eso, avisado quedas.
</p>
</div>
</div>
<div id="outline-container-org3fe5512" class="outline-2">
<h2 id="org3fe5512">¿Qué necesito para hacer los ejercicios de este minicurso?</h2>
<div class="outline-text-2" id="text-org3fe5512">
<p>
¿Tienes <i>Emacs</i> instalado?
</p>

<p>
Si la respuesta es <b>sí</b>, no necesitarás nada más. Si la respuesta es
<b>no</b> ¿para qué estás leyendo esto?: Instala <i>Emacs</i>.
</p>

<p>
Cuando lo tengas instalado seguramente te gustará configurarlo a tu
manera, si lo haces te encontrarás que tienes que escribir tu primer
programa en <code>elisp</code>, aunque aún no sepas muy bien cómo funciona todo,
conseguirás hacerlo. Al principio copiarás código de donde lo
encuentres sin saber muy bien qué estás haciendo
</p>
</div>
<div id="outline-container-org3ca82e2" class="outline-3">
<h3 id="org3ca82e2">Lisp</h3>
<div class="outline-text-3" id="text-org3ca82e2">
<p>
<i>Lisp</i> es uno de esos lenguajes viejunos que me gustan. De hecho, es
el segundo más antiguo. Cuando empezaba en esto de programar lo
petaban lenguajes como <i>Smalltalk</i>, <i>Fortran</i> o <i>Lisp</i>. En aquellos
años me decanté más por <i>Smalltalk</i>, aunque aprendí esos tres, los dos
últimos los olvidé por desuso. Luego vinieron otros lenguajes a
ocupar sitio en mi cabeza, <i>Pascal</i>, <i>C/C++</i>, <i>Python</i>... y
desplazaron incluso a mi querido <i>Smalltalk</i>.
</p>

<p>
<i>Lisp</i> significa <i>LISts Processor</i>, que viene a ser como un
<i>procesador de listas</i>. Algo de lo que hablaré más en profundidad
cuando llegue al tema de los tipos de datos, pero lo dejo aquí
apuntado.
</p>

<p>
El caso es que <i>Lisp</i> volvió a aparecer en mis necesidades en el
momento en que descubrí <code>org-mode</code> y me cambié a <i>Emacs</i> como
herramienta de edición de cabecera. <i>Emacs</i> es un entorno <i>Lisp</i> y yo
me resisto a llamarlo <i>editor</i>: es un entorno de programas <i>Lisp</i> que
sirve para editar ficheros de texto. Por algún sitio leí, que los
programas de <i>Lisp</i> en realidad son <i>entornos Lisp</i> que simulan ser
otra cosa, como <i>Autocad/® o /Emacs</i>.
</p>
</div>
</div>
<div id="outline-container-orgeb1b2c9" class="outline-3">
<h3 id="orgeb1b2c9">Emacs-Lisp</h3>
<div class="outline-text-3" id="text-orgeb1b2c9">
<p>
Como entorno <i>Lisp</i> que es, <i>Emacs</i> viene cargado con un lenguaje
orientado al manejo de ficheros de texto, ventanas, <i>buffers</i>, bloques
de texto y todo lo necesario para simular que es un <i>editor de texto</i>.
Conlleva la ejecución de un lenguaje <i>Lisp</i> que conocemos todos como
el <i>elisp</i>. No es un <i>Lisp completo</i> como podría ser el <i>clisp</i>, sino
uno enfocado a la edición de texto. Sin embargo, se pueden utilizar
aspectos más completos del <i>clisp</i> utilizando el módulo <code>cl.el</code>.
</p>

<p>
También se puede utilizar como un lenguaje de <i>script</i> más, pero lo
habitual es que cualquier cosa que programemos con <i>elisp</i> se ejecute
dentro del entorno de <i>Emacs</i>.
</p>
</div>
</div>
</div>
<div id="outline-container-org1578261" class="outline-2">
<h2 id="org1578261">Manos a la obra</h2>
<div class="outline-text-2" id="text-org1578261">
<p>
Bueno, pues manos a la obra. Vamos a trabajar un poco pero antes vamos
a ver con qué herramientas contamos: <i>Emacs</i> nos proporciona todo un
sistema de elementos para trabajar y que no necesitemos ninguna
herramienta externa para programar. Si eres de los que cree que
<i>Emacs</i> es un editor me gustaría que te replantearas la cuestión.
Si utilizas <i>Emacs</i> sólo como editor, te estás perdiendo muchas
posibilidades de la herramienta: apenas le estás sacando rendimiento.
</p>
</div>
<div id="outline-container-org9ed1db8" class="outline-3">
<h3 id="org9ed1db8">Buffers</h3>
<div class="outline-text-3" id="text-org9ed1db8">
<p>
Es posible confundir lo que es un <i>buffer</i> con un fichero. Si sólo
editas ficheros con él, lo que hace <i>emacs</i> es cargar el texto en un
<i>buffer</i> de edición. Pero hay muchos más tipos de <i>buffers</i> que
descubres cuando utilizas algunas herramientas. Un <i>buffer</i> es el
espacio que utiliza <i>emacs</i> para interactuar con la información. El
primero que nos encontramos es <code>*scratch*</code>.
</p>
</div>
</div>
<div id="outline-container-org2a09d00" class="outline-3">
<h3 id="org2a09d00">scratch para todo</h3>
<div class="outline-text-3" id="text-org2a09d00">
<p>
Este es el <i>buffer</i> para probar cosas, como expresiones, funciones,
hacer cálculos sencillos, etc. Para ver cómo funciona, vamos a hacer
una prueba muy sencilla. Vamos al <i>buffer</i> de <code>*scratch*</code> y
escribimos, por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(message <span style="color: #f1fa8c;">"Esto es un mensaje de prueba en scratch."</span>)
</pre>
</div>

<p>
Ahora, con el cursor situado en el final de esa <i>expresión</i>, vamos a
pulsar la combinación de teclas <code>C-x C-e</code>. Al hacerlo estamos llamando
al comando <code>eval-last-sexp</code>, que traducido es algo así como <i>evaluar
la última S-expresión</i>. También podemos utilizar el más corto y
socorrido <code>C-j</code>, que llamará al comando <code>eval-print-last-sexp</code>. ¿En qué
se diferencia además de añadir un <i>print</i> en el nombre? Pues
básicamente en que nos muestra en el mismo <i>buffer</i> <code>*scratch*</code> el
resultado de evaluar la expresión. El primero nos lo muestra sólo en
el <i>minibuffer</i>, esto es: mira en la línea inferior de <i>emacs</i> la que
está por debajo de la línea de estado. Si te has perdido el mensaje
que has lanzado, puedes ver que también está escrito en el <i>buffer</i>
<code>*Messages*</code>. Sin embargo, cuando lleva el apellido <code>print</code> además de
mostrarlo allí, lo muestra en el mismo <i>buffer</i> <code>*scratch*</code>.
</p>

<p>
Algo muy socorrido cuando queremos hacer algún cálculo sencillo. Por
ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(+ 9 5)
</pre>
</div>

<p>
Si pulsamos <code>C-x C-e</code> veremos que en la última línea nos muestra algo
parecido a <code>14 (#o16, #xe, ?\C-n)</code>. El primer número nos dice el valor
decimal y luego, entre paréntesis, el valor octal, el hexadecimal y el
valor del carácter. En este caso, como el número es muy bajo, el valor
que nos muestra es un valor especial que significa <code>C-n</code>. Si el valor
fuera, por ejemplo, 65, el carácter representado sería la letra
<i>A</i>. Sin embargo, si utilizamos el atajo <code>C-j</code> se limitará a
escribirnos en el mismo <i>buffer</i> <code>*scratch*</code> el resultado en decimal y
no nos dará más información.
</p>
</div>
</div>
</div>
<div id="outline-container-org218d3bd" class="outline-2">
<h2 id="org218d3bd">Conclusión</h2>
<div class="outline-text-2" id="text-org218d3bd">
<p>
El artículo de hoy es sólo una introducción a las herramientas y
quedan muchas cosas, más de las que me gustaría, pero sería demasiado
largo explicar más cosas. De momento me quedo con que tenemos entre
manos un entorno de programación completo funcionando, un entorno
vivo, que permite que le pasemos código sobre la marcha, que nos
permite guardar ese código en ficheros y cargarlo cuando lo
necesitemos.
</p>

<p>
El ejemplo de este tipo de ficheros es el de configuración de
<i>emacs</i>. Quizá intimide un poco al principio pensar que para usar el
editor hay que programar, sin embargo es más sencillo de lo que parece
a primera vista y mucha gente sin conocimientos de programación es
capaz de configurarlo.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/elisp/index.html">elisp</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[elisp]]></category>
  <link>https://notxor.nueva-actitud.org/2019/01/03/elisp-para-no-programadores.html</link>
  <pubDate>Thu, 03 Jan 2019 17:48:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Mi configuración de i3wm]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-12-23</div>
<p>
A raíz de publicar algunas capturas de pantalla de mi escritorio,
hablando de <i>Emacs</i>, las preguntas que me han llegado no han sido
sobre el editor, sino sobre mi configuración de <code>i3wm</code>. En algunas
ocasiones ya he mencionado que utilizo ese gestor de ventanas. La
mayoría de las configuraciones son las que se ponen por defecto, pero
he personalizado todo lo que he podido para adaptarlo a mis manías.
</p>

<p>
Lo detallo por puntos en lugar de poner todo el fichero de
configuración, porque supongo que no todos los ajustes que yo he hecho
para mí, le sirvan o sean agradables para el resto. Algunos sí, otros
no. La mayoría son combinaciones de teclas para lanzar las
aplicaciones que utilizo más frecuentemente y eso es algo muy
personal. El resto lo detallo.
</p>
<div id="outline-container-orga6680a1" class="outline-2">
<h2 id="orga6680a1">Escritorios</h2>
<div class="outline-text-2" id="text-orga6680a1">
<p>
Uno de los cambios que tengo hechos me lo sugirió «deesix» un buen
amigo del IRC y el CAAD. Consistía en cambiar el acceso a los
escritorios. Por defecto, la mayoría de las configuraciones utilizan
las teclas numéricas para cambiar de escritorio. Yo configuré las
teclas de función. Eso me permite utilizar hasta 12 escritorios.
</p>

<pre class="example" id="orgfb5fb0d">
# switch to workspace
bindsym $mod+F1 workspace 1
bindsym $mod+F2 workspace 2
bindsym $mod+F3 workspace 3
bindsym $mod+F4 workspace 4
bindsym $mod+F5 workspace 5
bindsym $mod+F6 workspace 6
bindsym $mod+F7 workspace 7
bindsym $mod+F8 workspace 8
bindsym $mod+F9 workspace 9
bindsym $mod+F10 workspace 10
bindsym $mod+F11 workspace 11
bindsym $mod+F12 workspace 12

# move focused container to workspace
bindsym $mod+Shift+F1 move container to workspace 1
bindsym $mod+Shift+F2 move container to workspace 2
bindsym $mod+Shift+F3 move container to workspace 3
bindsym $mod+Shift+F4 move container to workspace 4
bindsym $mod+Shift+F5 move container to workspace 5
bindsym $mod+Shift+F6 move container to workspace 6
bindsym $mod+Shift+F7 move container to workspace 7
bindsym $mod+Shift+F8 move container to workspace 8
bindsym $mod+Shift+F9 move container to workspace 9
bindsym $mod+Shift+F10 move container to workspace 10
bindsym $mod+Shift+F11 move container to workspace 11
bindsym $mod+Shift+F12 move container to workspace 12

# cycle workspaces
bindsym Ctrl+$alt+Right workspace next
bindsym Ctrl+$alt+Left workspace prev
</pre>

<p>
Todo bastante simple de entender, así que no daré más explicaciones
para no ponerme muy pesado. Añadí también un par de combinaciones de
teclas para «ciclar» escritorios, que suelo utilizar bastante para
cambiar rápidamente entre ellos combinada con el ciclado de ventanas,
o directamente por el menú de ventanas que cuento en el siguiente
apartado.
</p>
</div>
</div>
<div id="outline-container-org7f85cd7" class="outline-2">
<h2 id="org7f85cd7">Menú de aplicaciones</h2>
<div class="outline-text-2" id="text-org7f85cd7">
<p>
Otro cambio que he realizado es la utilización de <code>rofi</code> en lugar de
<code>dmenu</code>. ¿Por qué utilizo <code>rofi</code>? Pues porque me permite más juego que
el simple ─aunque efectivo─, <code>dmenu</code>. La instalación es sencilla y
como dependerá de cada <i>sabor</i> de GNU/Linux, lo dejo al lector. Aquí
está la configuración que yo utilizo:
</p>

<pre class="example" id="org3c2f349">
# start rofi
bindsym $mod+d exec rofi -modi run -show run
bindsym $mod+i exec rofi -modi run -show drun -show-icons
bindsym $mod+Tab exec rofi -show window -show-icons
</pre>

<p>
Como se puede ver está configurado para funcionar con tres
combinaciones de teclas distintas. La habitual de todas las
configuraciones con <code>dmenu</code> que es <code>$mod+d</code> y muestra un menú de todas
las aplicaciones y <i>scripts</i> ejecutables que puedan estar en el
<i>path</i>:
</p>


<figure id="orgba30565">
<img src="./rofi-run.png" alt="rofi-run.png">

</figure>

<p>
También está definida una combinación para que muestre las
aplicaciones que se pueden encontrar en el menú de aplicaciones de
GNU/Linux con su correspondiente icono.
</p>


<figure id="org5c5a4d0">
<img src="./rofi-drun.png" alt="rofi-drun.png">

</figure>

<p>
Y también otra que muestra una lista de ventanas de aplicaciones
abiertas.
</p>


<figure id="org30a3d60">
<img src="./rofi-windows.png" alt="rofi-windows.png">

</figure>

<p>
Si los colores de <code>rofi</code> no gustan o no se ajustan a lo que queremos,
está la utilidad de <code>rofi-theme-selector</code> para encontrar la que más se
ajuste a nuestras necesidades.
</p>
</div>
</div>
<div id="outline-container-org07634e8" class="outline-2">
<h2 id="org07634e8">Fondo de pantalla</h2>
<div class="outline-text-2" id="text-org07634e8">
<p>
El fondo de pantalla es algo que no se ve demasiado, porque suele
estar tapado por las aplicaciones que estés utilizando en ese
escritorio. Y cuando cambias a otro lo que suele ocurrir es que sea
para lanzar casi inmediatamente otra aplicación que lo tapará. Sin
embargo, el tener una foto o algo debajo que dé más sensación de
<i>escritorio</i> o lo que la gente espera en un <i>escritorio</i>.
</p>

<p>
Para mostrar la imagen utilizo <code>feh</code>. Utilizo una fotografía de no
mucha calidad que hice en el monasterio de Veruela con el móvil.
</p>

<pre class="example" id="org8a611c8">
exec --no-startup-id feh --bg-fill /home/notxor/Imágenes/fondo-Veruela.jpg
</pre>
</div>
</div>
<div id="outline-container-orgbbd2d4c" class="outline-2">
<h2 id="orgbbd2d4c">Barra de estado</h2>
<div class="outline-text-2" id="text-orgbbd2d4c">
<p>
He probado todas las opciones de línea de estado que hay para
<code>i3wm</code>. Tanto <code>i3blocks</code>, como <code>i3status</code> o <code>py3status</code>. A todos les
he encontrado ventajas e inconvenientes y supongo que todo va en
gustos. Lo que estoy utilizando últimamente es el <code>bumblebee-status</code>.
Es bastante más agradecido visualmente, pero tiene pocas ventajas más
sobre otras opciones.
</p>

<p>
De los <i>themes</i> que trae por defecto no me cuadraba ninguno con los
colores que suelo configurar en los escritorios. De todos los temas
probados el que más se acercaba a mis gustos fue el llamado
<code>powerline</code>, pero le cambié los colores para ajustarlo a los de mi
escritorio. Nada complicado, porque los temas se definen en archivos
<code>json</code>.
</p>

<p>
La configuración en el fichero <code>config</code> de <code>i3wm</code> es la siguiente:
</p>

<pre class="example" id="org5f537ea">
bar {
 	position bottom
	tray_output none
	status_command bumblebee-status -m nic disk:root disk:home cpu load sensors memory battery cmus pasink pasource date time -p interval=2.5 date.format="%a, %Y-%m-%d" time.format="%H:%M" root.path=/ home.path=/home cpu.left-click="i3-sensible-terminal -e htop" date.left-click="kdialog --calendar 'Calendario'" nic.states=^down sensors.path=/sys/class/thermal/thermal_zone1/temp -t propio-powerline
}
</pre>

<p>
<code>Bumblebee</code> permite añadir acciones de ratón y he añadido algunos,
pero como al final la pereza de separar los dedos del teclado me vence
hace tiempo que no los uso. Tampoco uso muchas aplicaciones con <i>tray
icons</i>.
</p>

<p>
Es recomendable <a href="https://github.com/tobi-wan-kenobi/bumblebee-status/wiki">leer el wiki de <code>bumblebee-status</code> para ver todas las
opciones y módulos que podemos configurar</a>. Algunos son muy especiales,
como por ejemplo <code>cmus</code> que es el reproductor de sonido preferido y
que siendo un reproductor para consola, no es del gusto de todo el
mundo.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/linux/index.html">linux</a> <a href="/tags/i3wm/index.html">i3wm</a> ]]></description>
  <category><![CDATA[linux]]></category>
  <category><![CDATA[i3wm]]></category>
  <link>https://notxor.nueva-actitud.org/2018/12/23/mi-configuracion-de-i3wm.html</link>
  <pubDate>Sun, 23 Dec 2018 19:49:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Personalizando Emacs a mi manera]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-12-20</div>
<p>
Estoy escribiendo este artículo para comprobar cómo funcionan mis
ajustes personales de <i>Emacs</i>. Más adelante haré una captura de como
ha quedado todo, aunque supongo que esto de personalizarlo es un no
acabar nunca, siempre habrá un detalle que pulir o algo que cambiar.
Si algo distingue al auténtico <i>friki</i> es que no termina nunca de
<i>cacharrear</i> con sus juguetitos: hoy es el día de <i>toquetear los
colorines</i> de mi editor favorito.  No sólo los colorines, también he
tocado algunas cosas más y he añadido algún paquete especial para
mejorar la «vista». Hay que recordar que los <i>themes</i> son ficheros de
código <code>elisp</code>, es decir: para cambiar las características o el
comportamiento de las cosas, hay que <i>ejecutar un programa</i>.  La mayor
parte de las veces se limitará a establecer el valor de algunas
variables para ajustar tipo de letra y/o color; pero hay que estar
atentos a lo que haga. De hecho, <i>Emacs</i>, cuando instalas un tema
externo pregunta si lo marca como <i>seguro</i>.
</p>
<div id="outline-container-orgd572154" class="outline-2">
<h2 id="orgd572154">Los colores</h2>
<div class="outline-text-2" id="text-orgd572154">
<p>
Definir los colores a gusto de todos es imposible, bien lo deben saber
todos aquellos que se hayan currado un <i>theme</i> de cualquier cosa, ya
sea una página web o, ─en este caso─, uno para <i>Emacs</i>. Queda dicho,
porque espero, como es lo normal, que no le guste a todo el mundo. Lo
bueno de personalizar algo es que lo pones a tu gusto o a tus
necesidades.  Sin embargo, en los <i>temas</i> de <i>Emacs</i> hay tantas cosas
que ajustar, tantos colores que se pueden modificar que hacerlo desde
cero se presenta como una tarea ardua, o casi infinita.  Por ello, he
partido de un <i>theme</i> ya hecho. Conste que antes de decidirme a hacer
esto he probado decenas de temas a los que siempre terminaba
encontrando un <i>pero</i>. Al final, los he desinstalado todos y me he
quedado con mi opción, ─no porque sea la mejor, sino porque es mía y
la puedo retocar todo lo que quiera─.
</p>

<p>
Como decía, he partido de un <i>theme</i> ya hecho: <i>leuven-theme</i> viene
como uno de los temas de mi instalación por defecto de <i>Emacs</i>. Sólo
que viene una versión antigua: <code>20170912.2328</code>. <a href="https://github.com/fniessen/emacs-leuven-theme">En su página web se
puede encontrar una versión más moderna y con más opciones</a>. El caso es
que <a href="./notxor-theme.el">partiendo de él he ido haciendo pruebas hasta conseguir un tema
propio</a> que sólo hay que cargar en nuestro <code>init.el</code> para que funcione,
con las siguientes instrucciones.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Tema personalizado
</span>(add-to-list 'custom-theme-load-path <span style="color: #f1fa8c;">"~/.emacs.d/themes"</span>)
(load-theme 'notxor t)
</pre>
</div>

<p>
En mi caso, se puede apreciar que lo he metido en el directorio
<code>themes</code> dentro de <code>.emacs.d</code>; lo he tenido que crear porque no
existía, pero lo hago así, porque a partir de este momento, puedo
instalar en él los <i>temas</i> que quiera probar y cargarlos sólo haciendo
referencia a su nombre.
</p>
</div>
<div id="outline-container-orge48024a" class="outline-3">
<h3 id="orge48024a">¿Por qué utilicé <i>leuven</i>?</h3>
<div class="outline-text-3" id="text-orge48024a">
<p>
Básicamente porque ya se ajustaba en muchas cosas a lo que busco en
una configuración para <i>Emacs</i>:
</p>

<ol class="org-ol">
<li>Me suelen gustar los colores claros en mi pantalla. Ahora en la
versión que tiene en su web también hay un <code>leuven-dark</code>, pero no
creo que lo pruebe.</li>
<li>Marca de forma <i>muy</i> diferenciada qué <i>buffer</i> es el activo. Así de
un vistazo puedo saber dónde estoy sin perderme por los tres o
cuatro que tenga abiertos en ventana.</li>
<li>Su patrón de colores ya se ajustaba bastante a los que tengo
configurados, por ejemplo en la barra de estado de <code>i3wm</code>, así que
tenía que modificar menos cosas.</li>
<li>Marca muy bien los bloques de texto en <code>org-mode</code>, algo que me
viene muy bien cuando hago <i>literate programming</i> de forma que los
bloques de código me saltan a la vista.</li>
</ol>

<p>
Cosas que he cambiado del tema original:
</p>

<ol class="org-ol">
<li>El color de fondo. Me gustan los temas claros, pero el blanco
original es agotador. Paso muchas horas delante del ordenador y
necesitaba un color claro que no agotara mi vista. El resultado ha
sido establecer el color <code>#FEFE9A</code>, que es un amarillo muy
claro. Eso ha permitido que no tenga que tocar muchos colores de
primer plano y que mi vista descanse un poco. Además combina bien
con el «azul» de la barra de información de <i>Emacs</i>.</li>
<li>No soporto los cambios de tamaño en los títulos de <code>org-mode</code> o en
los de LaTeX. Así que he eliminado todos los «sobredimensionados»
que he visto en el tema. Supongo que habrá gente a las que les
guste esos cambios de tamaño, pero mi cerebro en un editor de texto
normal espera que todas las líneas tengan el mismo alto. Además,
sería útil si esas cabeceras tuvieran el mismo estilo que las
generadas posteriormente, pero no es así.</li>
<li>Cuando escribo texto tengo configurado que se active
automáticamente el modo <code>flyspell</code>. El tema original va subrayando
las palabras en color rojo cuando encuentra un error y verde cuando
encuentra una repetición. La linea de subrayado es recta y me gusta
más cuando es ondulada, así que puse esas líneas onduladas y cambié
el color de repetición a un color <code>orange</code>, aunque estoy sopesando
la idea de cambiarlo a algún valor de azul.</li>
<li>Algunos colores más que he ido encontrando que no terminaban de
cuadrar con los definidos. Seguramente tendré que cambiar más,
porque hay algunos colores con <code>magit</code> que no me terminan de
convencer, pero de momento lo dejo así y más adelante ya veremos.</li>
</ol>
</div>
</div>
</div>
<div id="outline-container-org4cd561a" class="outline-2">
<h2 id="org4cd561a">Barra de estado de <i>Emacs</i></h2>
<div class="outline-text-2" id="text-org4cd561a">
<p>
No es la primera vez que pruebo <code>powerline</code> y seguramente la acabaré
quitando tarde o temprano, porque es algo que a ratos me gusta y a
ratos me parece insuficiente. Me explico: es más bonita, en general,
que la barra por defecto de <i>Emacs</i>, pero por ejemplo, la barra
general me informa cuándo estoy en una sesión <code>emacsclient</code> y cuándo
estoy en una normal. Esa información la obvia, no aparece, pero
tampoco es demasiado grave.
</p>

<p>
La configuración no puede ser más sencilla una vez instalado el
paquete, en el <code>init.el</code> añadir las siguientes líneas:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Mejorando la visualizaci&#243;n de la l&#237;nea de info
</span>(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">powerline</span>)
(powerline-default-theme)
</pre>
</div>
</div>
</div>
<div id="outline-container-orga2cbd98" class="outline-2">
<h2 id="orga2cbd98">Lista de ficheros</h2>
<div class="outline-text-2" id="text-orga2cbd98">
<p>
Una de las cosas que echaba de menos de otros editores era la
posibilidad de navegar por directorios y ficheros en su
correspondiente ventana. En <i>Emacs</i> también existe esa posibilidad con
el paquete <code>dired-sidebar</code>. Para configurarlo, en el apartado
<code>custom-set-variables</code> del fichero <code>init.el</code> hay que añadir el tema
que queramos, en mi caso:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">'(dired-sidebar-theme (<span style="color: #ff79c6; font-weight: bold;">quote</span> icons))
</pre>
</div>

<p>
Para visualizar los iconos también necesitas instalar el paquete
<code>all-the-icons-dired</code>, y si hay algún problema al visualizar los
iconos en <code>dired-mode</code>, es posible que tengas que instalar también las
fuentes de los iconos, el proceso viene en la ayuda del paquete, pero
básicamente se limita a llamar a la función
<code>all-the-icons-install-fonts</code> que preguntará si quieres descargar las
fuentes e instalarlas. También, para visualizarlos, es posible que
necesites añadir un <i>hook</i> también:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-hook 'dired-mode-hook 'all-the-icons-dired-mode)
</pre>
</div>

<p>
Aquí me encontré un problema con los iconos. Resulta que sin el <i>hook</i>
no me los carga en el modo <code>dired</code> normal. Tampoco tendría mucha
importancia, pero ya que están me gustaría verlos. El caso es que
cuando carga en modo <code>sidebar</code> me duplica los iconos. Cuando refresca
el <i>buffer</i> desaparece y queda sólo uno, pero es un detalle que me
falta por pulir.
</p>

<p>
El modo <code>dired-sidebar</code> tampoco lo quiero abierto permanentemente,
sólo cuando lo necesite, así que no lo activo por defecto sino que le
he asignado. Así sólo lo abro ─y lo cierro─ cuando lo necesito con
<code>C-c s</code>.
</p>

<p>
Como se puede apreciar en las imágenes, la visualización de los iconos
en modo texto es imperfecta y se corta según qué fuente utilices en el
terminal.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(global-set-key (kbd <span style="color: #f1fa8c;">"C-c s"</span>) 'dired-sidebar-toggle-sidebar)
</pre>
</div>
</div>
</div>
<div id="outline-container-org502d233" class="outline-2">
<h2 id="org502d233">Números de línea</h2>
<div class="outline-text-2" id="text-org502d233">
<p>
Me ocurren dos cosas, normalmente, con los números de línea: me
molestan cuando escribo, pero los <i>necesito</i> cuando programo. Bueno,
tampoco hay que ser exagerado: puedo vivir sin ellos, porque <i>Emacs</i>
me muestra el número de línea en su barra, sin embargo, me gusta
tenerlos a mano cuando programo (y sólo cuando programo). Pues otro
<i>hook</i> y ya está:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(add-hook 'prog-mode-hook 'display-line-numbers-mode)
</pre>
</div>

<p>
Con <code>prog-mode-hook</code> activa el número de línea en la mayoría de los
modos de programación.
</p>
</div>
</div>
<div id="outline-container-orgf5341bd" class="outline-2">
<h2 id="orgf5341bd">Imágenes</h2>
<div class="outline-text-2" id="text-orgf5341bd">
<p>
Dicen que una imagen vale más que mil palabras y yo pongo dos, una en
modo gráfico y otra en un terminal de texto.
</p>

<p>
En modo gráfico:
</p>


<figure id="orgad65d7e">
<img src="./imagen/tema-grafico.png" alt="tema-grafico.png">

</figure>

<p>
En modo texto:
</p>


<figure id="orgf1fe73d">
<img src="./imagen/tema-texto.png" alt="tema-texto.png">

</figure>

<p>
Y puestas las imágenes: <i>ni mil palabras más</i>.
</p>
</div>
</div>
<div id="outline-container-org9e24fba" class="outline-2">
<h2 id="org9e24fba">Conclusiones</h2>
<div class="outline-text-2" id="text-org9e24fba">
<p>
No he conseguido un tema perfecto, ni siquiera bonito, pero me sirve
para lo que lo quiero. Creo que no he visto nunca un <i>theme</i> que tenga
un fondo amarillo <i>tan horrendo</i>. Pero no cansa tanto la vista como el
fondo blanco ni es tan soso como un fondo gris claro y el resto de
funcionalidades las voy sacando poco a poco.
</p>

<p>
Hay quien prefiere instalarse <a href="http://spacemacs.org/">spacemacs</a> que lo hace todo, pero yo
prefiero enterarme de todo lo que necesito, lo que no, cómo funciona y
cómo lo puedo cambiar... y en esas estoy.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2018/12/20/personalizando-emacs-a-mi-manera.html</link>
  <pubDate>Thu, 20 Dec 2018 22:54:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Capacidad lectora y redes sociales]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-12-19</div>
<p>
He venido observando que cada vez leo peor y menos. Es como si no
pudiera concentrarme en la lectura y fijar mi atención en ella.
Podríamos decir que el problema es de concentración, pero no lo creo.
Es decir, cuando estoy haciendo cualquier otra cosa: editar un vídeo,
modelar algo en 3D, escribir algo, programar, o resumiendo: <i>en todo 
aquello que necesita mi atención</i>, me concentro con facilidad.  Sin
embargo, leyendo soy un desastre.  Mis ojos saltan por el texto y
tengo que hacer verdaderos esfuerzos para concentrarme en la lectura,
tanto que incluso puedo perder el concepto de lo que leo.
</p>

<p>
Por IRC, hay quien dice que <i>paso de su culo</i>, porque me ha escrito
algo y no le he hecho caso. La realidad es que no lo he visto. Cuando
se me juntan más de quinientos caracteres mi vista comienza a saltar
de un punto a otro incapaz de seguir una línea. Además, si la línea
tiene más de 70 caracteres, mi vista saltará a la siguiente sin haber
llegado al final.
</p>
<div id="outline-container-org3bc5b16" class="outline-2">
<h2 id="org3bc5b16">¿Qué está pasando?</h2>
<div class="outline-text-2" id="text-org3bc5b16">
<p>
En realidad no sé qué es lo que me pasa, tengo empezados varios libros
y simplemente los abandono. No me divierten, no me distraen, no me
entero de nada. Hay veces que pienso que debería volver al método de
señalar con el dedo el sitio por el que voy leyendo, quizá ese
ancestral, aunque infantil, sistema me ayude a mantener la coherencia
de la secuencialidad lectora.
</p>

<p>
Tampoco ayuda el que mis géneros favoritos sean la ciencia-ficción y
la fantasía. Para leer eso, uno tiene que estar dispuesto a suspender
su sentido de la realidad; algo que siempre me ha parecido interesante
para usar la lectura, precisamente, como un evasor de la realidad sin
efectos secundarios, para descubrir mundos nuevos y nuevas realidades
aunque imaginarios, no menos interesantes.  Sin embargo, cada vez más,
me cuesta <i>suspender</i> momentáneamente mi sentido crítico y admitir
como <i>normales</i> algunos postulados de la ficción. Si le añadimos que
me cuesta concentrarme en la lectura, tendremos el cóctel perfecto
para no haber encontrado ningún libro que me enganche en meses... he
pasado de un ritmo de tres o cuatro al mes a uno o dos al trimestre.
Ya ni las relecturas disfruto.
</p>

<p>
No tengo explicaciones para estos hechos, pero es lo que hay. Y no
tengo claro a qué achacarlo, pero me ronda la idea que quizá sea el
uso y abuso de las <i>redes sociales</i>. Sería curioso si fueran la causa,
pues también me ocurre cuando las miro. Hay ocasiones que <i>leo</i> un
<i>post</i> días después de haberlo visto. Evidentemente, el <i>post</i> ha
estado ahí siempre, incluso lo he visto, ─sé que lo he visto─ pero no
he alcanzado el mensaje.
</p>

<p>
Como digo, voy a dejar una temporada las redes sociales (todas).
Volveré a obligarme a leer todo y a conseguir concentrarme en la
lectura como lo hacía antes.
</p>
</div>
</div>
<div id="outline-container-org3a8b269" class="outline-2">
<h2 id="org3a8b269">¿Cómo he llegado a esa conclusión?</h2>
<div class="outline-text-2" id="text-org3a8b269">
<p>
No sé si serán ciertas mis conclusiones, quizá me estoy columpiando y
no tiene nada que ver, sin embargo hay una serie de <i>hechos probados</i>
que me llevan a esa conclusión:
</p>

<ol class="org-ol">
<li>En otras actividades soy capaz de concentrarme.</li>
<li>Coincide con mi <i>enganche</i> a las redes sociales.</li>
<li>No es una pérdida de hábito lector sino una modificación de sus
pautas.</li>
</ol>

<p>
Me paso el día leyendo y desorientado con lo que leo, me da la
impresión de que mis ojos y mi mente saltan de un sitio a otro cuando
se junta mucha información por una mala habituación a los mensajes
cortos, típicos de las redes sociales. Eso es todo: tengo que
deshabituarme y el momento correcto es <b>ya</b>.  No lo puedo dejar como
propósito para el año que viene.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2018/12/19/capacidad-lectora-y-redes-sociales.html</link>
  <pubDate>Wed, 19 Dec 2018 16:34:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Nombres de días y meses en español en Emacs org-mode]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-12-14</div>
<p>
Espero que esta entrada sea corta, es un tema sencillo que creo que ya
ha aparecido por algún sitio en este <i>blog</i> y que está perfectamente
documentada en multitud de sitios.  Sin embargo, alguno de los
<i>iniciandos</i> en el mundo de <i>Emacs</i> y concretamente en el de
<code>org-mode</code>, me hacen a veces una pregunta tal que: <i>¿Cómo haces para
que te aparezcan las fechas en español?</i>.
</p>

<p>
Algunas veces se refieren sólo a hacer que <i>Emacs</i> introduzca la fecha
del día en el texto, y eso es bastante sencillo si utilizamos el
comando <code>date</code> de <i>GNU/Linux</i>:
</p>

<pre class="example" id="org57ebd30">
C-u M-! date
</pre>

<p>
Ese comando nos devolverá el día y la hora del sistema.  Si queremos
un formato más específico podemos decírselo acompañándolo de una
cadena específica.
</p>

<pre class="example" id="org83a954b">
C-u M-! date +"%d de %B de %Y"
</pre>

<p>
Ese comando mostrará una fecha del estilo <code>14 de diciembre de 2018</code>.
En este modo, la cadena la pone el comando de la consola y la fecha
aparecerá en nuestro documento con la misma forma que la devuelva
<code>bash</code>.  Si lo utilizamos frecuentemente, podríamos automatizarlo un
poco con una función de <code>elisp</code> en nuestra configuración, por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">insert-current-date</span> () (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
    (insert (shell-command-to-string <span style="color: #f1fa8c;">"echo -n $(date +%Y-%m-%d)"</span>)))
</pre>
</div>

<p>
Podemos utilizar, el comando del sistema, también podríamos aprovechar
las facilidades que nos da el paquete <code>calendar</code> para trabajar con
fechas:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">calendar</span>)
</pre>
</div>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">insdate-insert-current-date</span> (<span style="color: #8be9fd; font-style: italic;">&amp;optional</span> omit-day-of-week-p)
    <span style="color: #6272a4;">"Insertar la fecha del d&#237;a con el formato local establecido.
  A&#241;adiendo una opci&#243;n se puede omitir el d&#237;a de la semana de la
  cadena devuelta."</span>
    (<span style="color: #ff79c6; font-weight: bold;">interactive</span> <span style="color: #f1fa8c;">"P*"</span>)
    (insert (calendar-date-string (calendar-current-date) nil
                            omit-day-of-week-p)))
</pre>
</div>

<p>
En mi caso, esa función me devolverá una cadena del estilo
<code>2018-12-14</code>. ¿Por qué lo devuelve en formato ISO?  Pues básicamente
porque es el formato que tengo configurado es ese.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">'(calendar-date-style (<span style="color: #ff79c6; font-weight: bold;">quote</span> iso))
</pre>
</div>

<p>
También se podría sustituir ese <code>iso</code>, que ordena «año - mes - día»
por, <code>european</code> que ordena en «día - mes - año», o <code>american</code> que
ordenará como «mes - día - año».
</p>
<div id="outline-container-orgfaf03ba" class="outline-2">
<h2 id="orgfaf03ba">Ajustes del calendario</h2>
<div class="outline-text-2" id="text-orgfaf03ba">
<p>
Vale, vale... <i>¿pero cómo haces para que el calendario te ponga los
nombres de meses y días de la semana en español?</i>
</p>

<p>
Sencillo: en mi <code>init-el</code> tengo configuradas las siguientes variables para
«hispanizar» el nombre de meses y días.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">'(calendar-day-header-array [<span style="color: #f1fa8c;">"Do"</span> <span style="color: #f1fa8c;">"Lu"</span> <span style="color: #f1fa8c;">"Ma"</span> <span style="color: #f1fa8c;">"Mi"</span> <span style="color: #f1fa8c;">"Ju"</span> <span style="color: #f1fa8c;">"Vi"</span> <span style="color: #f1fa8c;">"Sa"</span>])
'(calendar-day-name-array
   [<span style="color: #f1fa8c;">"domingo"</span> <span style="color: #f1fa8c;">"lunes"</span> <span style="color: #f1fa8c;">"martes"</span> <span style="color: #f1fa8c;">"mi&#233;rcoles"</span> <span style="color: #f1fa8c;">"jueves"</span> <span style="color: #f1fa8c;">"viernes"</span> <span style="color: #f1fa8c;">"s&#225;bado"</span>])
'(calendar-month-abbrev-array
   [<span style="color: #f1fa8c;">"Ene"</span> <span style="color: #f1fa8c;">"Feb"</span> <span style="color: #f1fa8c;">"Mar"</span> <span style="color: #f1fa8c;">"Abr"</span> <span style="color: #f1fa8c;">"May"</span> <span style="color: #f1fa8c;">"Jun"</span>
    <span style="color: #f1fa8c;">"Jul"</span> <span style="color: #f1fa8c;">"Ago"</span> <span style="color: #f1fa8c;">"Sep"</span> <span style="color: #f1fa8c;">"Oct"</span> <span style="color: #f1fa8c;">"Nov"</span> <span style="color: #f1fa8c;">"Dic"</span>])
'(calendar-month-name-array
   [<span style="color: #f1fa8c;">"enero"</span> <span style="color: #f1fa8c;">"febrero"</span> <span style="color: #f1fa8c;">"marzo"</span>
    <span style="color: #f1fa8c;">"abril"</span> <span style="color: #f1fa8c;">"mayo"</span> <span style="color: #f1fa8c;">"junio"</span>
    <span style="color: #f1fa8c;">"julio"</span> <span style="color: #f1fa8c;">"agosto"</span> <span style="color: #f1fa8c;">"septiembre"</span>
    <span style="color: #f1fa8c;">"octubre"</span> <span style="color: #f1fa8c;">"noviembre"</span> <span style="color: #f1fa8c;">"diciembre"</span>])
'(calendar-week-start-day 1)
</pre>
</div>

<p>
Se puede apreciar que hay dos <i>arrays</i> por cada grupo de nombres, los
abreviados y los largos.  No hay que explicar mucho más<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>

<p>
Además, me gustaría llamar la atención sobre la línea
<code>'(calendar-week-start-day 1)</code> que establece que la semana comience en
el día 1 (los lunes); por defecto comienzan el día 0 (el domingo).
Por eso, también, los <i>arrays</i> de los nombres comienzan por el
<i>domingo</i> y no por el <i>lunes</i> como estamos acostumbrados por estas
latitudes.
</p>
</div>
</div>
<div id="outline-container-orga474538" class="outline-2">
<h2 id="orga474538">Conclusiones</h2>
<div class="outline-text-2" id="text-orga474538">
<p>
Tener bien ajustadas los formatos de fecha en nuestro <code>init.el</code> hará
que nuestro trabajo, con <code>org-mde</code>, con nuestra agenda y nuestro
calendario sea más suave.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Sólo recordar que en español, efectivamente, el nombre de los
días y los meses se escriben en minúscula. Alguien ya me ha llamado la
atención por las mayúsculas en algunos de los <i>arrays</i>, pero entiendo
que esos son abreviaturas y por tanto la falta ortográfica sería la
carencia del «.» al final y no la mayúscula.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2018/12/14/nombres-de-dias-y-meses-en-espanol-en-emacs-org-mode.html</link>
  <pubDate>Fri, 14 Dec 2018 17:15:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[La desesperanza en las redes sociales]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-12-01</div>
<p>
Anoche jugaba una conversacional a través de un experimento <i>web</i> en
el que está trabajando <i>deesix</i>.  Es una cosa un tanto extraña que
muestra la salida y da opciones de entrada a una aventura
conversacional a través de <i>web</i>.  De momento admite <code>glulx</code> y quizá
también algo de máquina <code>Z</code>.  <i>Webot</i> ─o <i>güevón</i> como me empeño en
llamarlo yo─ está en fase <i>alfa</i> y nos dio la oportunidad de reiniciar
el juego en alguna ocasión.  Éramos tres jugadores interactuando con
la conversacional y me recordó los tiempos en que quedabas con algún
amigo para echar la partida «a los videojuegos».  El espíritu
revoltoso ─algunos lo llaman <i>troll</i> o cosas peores─ se apoderó de mí
y apareciendo la <i>Dama Arwen</i> en la historia intenté tocar
virtualmente su culo sindarin<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> un par de veces.  Nunca he sido lo
que se llama «políticamente correcto» y menos cuando se trata de
jugar.
</p>

<p>
Mientras me iba a dormir reflexionaba sobre el rato que compartimos
virtualmente, pero en directo, tres personas alejadas físicamente pero
cercanas gracias a Internet. Echamos un rato de conversación alrededor
de un juego, intercambiamos ideas, propusimos soluciones, nos quejamos
de varias de las <i>sorderas</i> que encontramos en el juego y también de
una redacción un tanto pedante en algunos sitios de la aventura (esto
principalmente yo, que soy extremadamente sensible a la pedantería y
me vi afectado en un par de ocasiones por una desmesurada reacción
alérgica).
</p>

<p>
El caso que quería comentar, y esto es sólo una reflexión, es que
necesitamos ese tipo de herramientas, en las que Internet facilita la
relación humano-humano de forma directa, sin filtros, sin algoritmos y
sin IA<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.  Lo pasé bien anoche interactuando
con personas, lo de probar el <i>güevón</i> y jugar una conversacional
quizá fue lo de menos.
</p>

<p>
Veo en lo que se han convertido las redes sociales, especialmente las
multitudinarias, y me produce una profunda desesperanza.  El único
medio de sobrevivir en ellas es el <i>postureo</i>.  En lugar de acercar
personas, en lugar de acercar sentimientos, ratos agradables o ideas,
se han convertido en el modo de mostrarle al mundo lo felices que
somos.  «¡Que no se entere el mundo de mi sufrimiento! ¡Que vean lo
feliz que soy! ¡Que se jodan!».
</p>

<p>
Veo, quizá por eso, mucha alma perdida, anegada de bilis y pena que
quizá sólo necesita una palabra de apoyo, o incluso sólo un abrazo
─aunque sea virtual─, y no se atreve a decir nada para no ser
machacada: <i>Que se jodan</i>, grita la bilis mientras añora un toque
humano, una mano amiga, una palabra cariñosa.  Sólo obtendrá <i>likes</i> y
desafecto.  Los <i>likes</i> no paliarán la pena y el desafecto sólo
aumentará la bilis.  ¿Por qué la Internet, pudiendo unir personas,
está separándolas?  ¿Qué estamos haciendo mal para que nos deshumanice
lo que debería humanizarnos, unirnos, hacer una Humanidad?  ¿Por qué a
la gente no le importa ser tratado como una <i>pila de datos</i> enchufada
al <i>Matrix</i> de grandes corporaciones?
</p>

<p>
Es curiosa esa imagen de la pastilla roja y la pastilla azul.  ¿Qué
elegiría la mayoría?  Si nos detenemos en la película, todo el que la
haya visto quiere pensar que elegiría la pastilla <i>correcta</i>.  Si
eliges esa pastilla las cosas quizá no sean tan bonitas, pero son
reales, no es fácil sobrevivir en la realidad.  Sin embargo, la
mayoría no la elegiría, prefiere vivir engañado por oscuros algoritmos
en una irrealidad de postureo y manipulación, intentando aparentar
felicidad y alegría, criticando a los que nos salimos de ese círculo,
los que elegimos hace un tiempo <i>la pastilla roja</i>, volviendo su bilis
<i>azul</i> hacia nosotros, los que amenazamos su desesperanzada
ignorancia.
</p>

<p>
¿Qué podemos hacer?  Lo único que se me ocurre es ofrecer herramientas
de intercambio <i>real</i> donde interactuemos personas.  La <i>pastilla
roja</i> la seleccionará la gente porque al final será más gratificante
que la velada manipulación que proporciona la <i>pastilla azul</i>.  Somos
humanos, no máquinas y necesitaremos interactuar con humanos o nos
convertiremos en máquinas sin alma, desalmados que vagan repletos de
pena y bilis buscando un lugar donde verterla y donde recibir algo
parecido a una caricia humana.
</p>

<p>
Desde aquí, a quien pueda leer esto le envío un abrazo, te recomiendo
que comiences a abandonar las <i>redes sociales privativas</i>, te olvides
de los <i>likes</i> y del número de seguidores. No significan nada: sólo
que un algoritmo te ha seleccionado y te ha mostrado a más gente (o
<i>bots</i>) que no te han leído, sólo le han dado a un botón.  Prueba las
<i>redes sociales libres</i>, no porque estén mejor sino porque son más
reales; no están apantalladas tras un algoritmo que decide lo que
debes leer.  No importa el número de seguidores, la amistad no es una
competición, seguirás teniendo los mismos amigos, los de verdad no
cambiarán porque cambies de red social y si pierdes a alguno en
realidad no lo estás perdiendo: nunca lo fue, sólo has salido de la
psicosis ilusoria para toparte con la realidad, que a veces es dura y
fría.
</p>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Los <i>Sindarin</i> son una clase de elfos de «el Señor de los
anillos».
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<i>Istupidez Artificial</i>.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2018/12/01/la-desesperanza-en-las-redes-sociales.html</link>
  <pubDate>Sat, 01 Dec 2018 13:05:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Usando «magit»]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-11-29</div>
<p>
Ya he hablado otras veces por aquí de <code>git</code> y cómo, a estas alturas,
se ha convertido en una herramienta indispensable para mí.  La verdad
es que ahora prácticamente no utilizo la línea de comandos para
usarlo.  La mayor parte de las cosas que hago orbitan alrededor de
<i>emacs</i> y <code>git</code> ha caído también en esa órbita.
</p>

<p>
El tema es que, como <i>emacs</i> se ha convertido en la herramienta que
más utilizo para casi todo: escribir documentos, programar, llevar la
contabilidad, la agenda.  En fin, un montón de cosas.  Además luego
muchos de esos ficheros que genero van a un repositorio <code>git</code> y así
puedo acceder desde todos mis dispositivos, me sirve de copia de
seguridad también y me permite estudiar cuándo se hizo una
modificación y por qué.
</p>

<p>
Cuando comencé en estas cosas de los repositorios era muy caótico.  Lo
sigo siendo, sobre todo en la forma de expresarme.  Mis imprecisiones
en el lenguaje técnico lo sufre especialmente el amigo Deesix que
tiene la costumbre de darme los tirones de orejas que me merezco.
Algo loable, por su paciencia y que yo le agradezco infinitamente.  Si
alguien lee este escrito como «iniciación» al uso de <code>magit</code> en
<i>emacs</i>, tiene que agradecerle que yo haya prestado una especial
atención a la terminología intentando no confundir al lector.  Me
permitiréis que os cite una frase suya: «bastante difícil es
comunicarse como para complicarlo», escrita a las 22:46:05 del día 28
de noviembre de 2018 a través del IRC.
</p>

<p>
Dicho esto, entraré en materia.
</p>
<div id="outline-container-orgaa4f3ec" class="outline-2">
<h2 id="orgaa4f3ec"><code>magit</code></h2>
<div class="outline-text-2" id="text-orgaa4f3ec">
<p>
La herramienta para manejar repositorios <code>git</code> en <i>emacs</i> se llama
<code>magit</code>.  Otra de las herramientas que merecen la pena de mi entorno
de trabajo favorito<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>
</div>
<div id="outline-container-orgd221f39" class="outline-3">
<h3 id="orgd221f39">Instalar <code>magit</code></h3>
<div class="outline-text-3" id="text-orgd221f39">
<p>
Seguramente este paso se podría dar por sabido.  Cualquiera que haya
trabajado mínimamente con <i>emacs</i> sabe cómo instalar un paquete.  De
todas formas lo escribo aquí:
</p>

<pre class="example" id="org357e88b">
M-x package-install &lt;RET&gt; magit &lt;RET&gt;
</pre>

<p>
Con eso, ya podemos disponer de la herramienta.  La única dependencia
es que <code>git</code> tiene que estar instalado en el sistema.
</p>

<p>
La única línea de código que tengo en el <code>init.el</code> es la siguiente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(global-set-key (kbd <span style="color: #f1fa8c;">"C-c g"</span>) 'magit-status)
</pre>
</div>
</div>
</div>
<div id="outline-container-orgd4c6ea5" class="outline-3">
<h3 id="orgd4c6ea5">Uso de <code>magit</code></h3>
<div class="outline-text-3" id="text-orgd4c6ea5">
<p>
Voy a utilizar éste artículo como fuente para mostrar cómo vengo
utilizando la herramienta.  ¿Será éste un artículo o un
<i>metaartículo</i>?  Bueno, da igual, imaginemos que queremos añadir el
artículo al repositorio.  Lo primero que podemos hacer es llamar a
<code>magit-status</code>, en mi caso pulsando la combinación de teclas <code>C-c g</code>
porque lo tengo fijado así en la configuración de <i>emacs</i>.  Ese
comando dividirá la ventana y aparecerá el <i>buffer</i> de <code>magit-status</code>
en el que me informa de que hay un fichero <i>untraked</i>:
<code>blog/magit.org</code>.  Pongo la imagen para ser más visual:
</p>


<figure id="orga7ce5ea">
<img src="./imagen/buffer-magit-status.png" alt="buffer-magit-status.png">

</figure>

<p>
Como vemos también nos indica en las dos primeras líneas de los
valores de <code>Head</code> y <code>Merge</code>.  En este caso, nuestros repositorios:
<i>local</i> y <i>origin</i>, tienen la rama <code>source</code> sincronizados en el mismo
<i>commit</i>.
</p>

<p>
Siguiente paso: añadir el fichero al proyecto pulsando <code>s</code> con el
cursor situado sobre la línea.  Esto hará <i>stage</i> y preguntará si debe
guardar el fichero si ha detectado que hay cambios sin guardar.  Si
hubiera varios ficheros o cambios se puede hacer también que añada
todos los cambios pulsando <code>s</code> sobre el título que los agrupa.  El
resultado quedaría así:
</p>


<figure id="org8bfd733">
<img src="./imagen/staged-changes.png" alt="staged-changes.png">

</figure>

<p>
Aparecerá una ventana que nos permite escribir el mensaje asociado con
el <i>commit</i> junto a un <i>buffer</i> que nos muestra los cambios que se
asocian con él. Al pulsar <code>c</code> en el <i>buffer</i> de <code>magit-status</code>, el
sistema abre un menú con todas las acciones que podemos realizar en el
<i>commit</i>:
</p>


<figure id="orgf8403a9">
<img src="./imagen/menu-commit.png" alt="menu-commit.png">

</figure>

<p>
Como sólo queremos hacer el <i>commit</i> volvemos a pulsar <code>c</code> y nos
aparecerá un <i>buffer</i> en el que podemos escribir el mensaje asociado
con el <i>commit</i> y otro con todos los cambios que se corresponderán con
él.
</p>


<figure id="orgd1ab4e3">
<img src="./imagen/escribiendo-commit.png" alt="escribiendo-commit.png">

</figure>
</div>
</div>
<div id="outline-container-org7babb98" class="outline-3">
<h3 id="org7babb98">¿Y si no lo quiero meter todo en el mismo <i>commit</i>?</h3>
<div class="outline-text-3" id="text-org7babb98">
<p>
Hay ocasiones en las que no quieres asociar todos los cambios que se
han hecho en un archivo en el mismo <i>commit</i>.  Antes de descubrir cómo
se hace en <code>magit</code> lo hacía desde la línea de comandos con <code>git commit
-p</code> o con el entorno gráfico que proporciona el mismo <code>git</code>: <code>git-tk</code>.
Suponía que debía haber un modo (normalmente siempre lo hay), para
hacerlo sin salir de <i>emacs</i>.  Y lo encontré.  Pero voy a mostrar los
pasos con un ejemplo, a parte de lo añadido al final del artículo
también he cambiado la fecha en la cabecera para actualizar la fecha.
Quiero separar los <i>commits</i>, porque uno se realiza por un cambio en
el contenido mientras el otro es un cambio en los «metadatos».
</p>

<p>
Vuelvo al <i>buffer</i> de <code>magit-status</code> y me encuentro que sólo he
modificado un archivo: <code>blog/magit.org</code>.  Si hago <i>stage</i> pulsando <code>s</code>
sobre él, lo hará sobre todos los cambios que tenga. En lugar de
pulsar <code>s</code>, pulsaré <code>&lt;TAB&gt;</code>. El resultado es que me despliega todos
los cambios de ese fichero en un formato <code>diff</code> para analizar qué se
ha cambiado, así:
</p>


<figure id="org71911c6">
<img src="./imagen/diff-cambios.png" alt="diff-cambios.png">

</figure>

<p>
Ahora me iré con el cursor hacia la línea donde cambié la fecha y voy
a hacer el <i>stage</i>, pulsando <code>s</code> sobre esos cambios.  En la imagen
siguiente podemos ver que el mismo fichero <code>blog/magit.org</code> tiene
cambios en estado <i>staged</i> y en estado <i>unstaged</i>. 
</p>


<figure id="orgf3a4241">
<img src="./imagen/staged-unstaged.png" alt="staged-unstaged.png">

</figure>

<p>
Ahora es cuando hacemos el <i>commit</i> del modo anterior. Repetiremos el
proceso las veces que necesitemos para dejar todos los cambios
preparados y listos para el siguiente paso.
</p>
</div>
</div>
<div id="outline-container-org7972e2e" class="outline-3">
<h3 id="org7972e2e">Subir cambios al repositorio remoto</h3>
<div class="outline-text-3" id="text-org7972e2e">
<p>
Mientras hemos ido haciendo <i>commits</i> podemos habernos dado cuenta que
las dos primeras líneas, que marcan el <code>head</code> y el <code>merge</code> junto con
nuestros repositorios <code>source</code> (local) y <code>origin/source</code> (remoto), no
apuntan al mismo <i>commit</i>.  Es decir, no están sincronizados.  Para
sincronizarlos debemos subir todos esos cambios, que hemos hecho en el
<i>local</i> al remoto haciendo un <code>push</code>.  Para hacerlo, tengo por
costumbre comprobar primero que en el remoto no hay cambios que no
estén en el local.  Cuando trabajas como único «mantenedor» del
repositorio, es habitual que no haya nada en el remoto que no esté en
el local, pero si trabajas con varios dispositivos algunas veces te
puedes llevar alguna «sorpresa», y mucho más cuando varias personas
trabajan sobre el mismo repositorio remoto.  Resumiendo, para hacer el
<code>pull</code> hay que pulsar <code>F</code> ─obsérvese que es mayúscula, la minúscula
corresponde a <code>fetch</code> y abrirá otro diálogo─ para que se muestre el
diálogo de <code>pull</code>.
</p>


<figure id="org90e7d92">
<img src="./imagen/haciendo-pull.png" alt="haciendo-pull.png">

</figure>

<p>
Si todo está correcto, continuamos con el siguiente paso: hacer el
<code>push</code>.  Para ello, pulsaremos en el <i>buffer</i> de <code>magit-status</code> la
tecla <code>P</code> ─obsérvese también la mayúscula─ y nos abrirá el diálogo.
Como lo quiero subir al repositorio <code>origin/source</code> pulsaré después la
tecla <code>u</code>
</p>


<figure id="orgc830778">
<img src="./imagen/haciendo-push.png" alt="haciendo-push.png">

</figure>

<p>
A estos pasos, para desesperación de los más técnicos, yo los llamo «un
mete-saca rapidito» y si todo ha ido bien, ya tendremos el repositorio
local y el remoto sincronizados de nuevo.
</p>
</div>
</div>
<div id="outline-container-orga53108d" class="outline-3">
<h3 id="orga53108d">Cambiando de rama</h3>
<div class="outline-text-3" id="text-orga53108d">
<p>
Algunas veces no estás en la rama adecuada o simplemente quieres
cambiar a otra.  No hace falta que salgas de <i>emacs</i> cambies la rama y
vuelvas a entrar en <i>emacs</i>.  Simplemente hay que ejecutar un comando
<code>magit-checkout</code> con <code>M-x magit-checkout</code> y te situará en la rama
adecuada.  Se puede percibir que en la línea de <i>status</i> de <i>emacs</i>
cuando estamos editando un fichero perteneciente a un repositorio
<code>git</code>, automáticamente lo muestra diciéndonos además en qué rama
estamos.  Por ejemplo, mientras edito este fichero <i>emacs</i> muestra el
mensaje <code>Git:source</code> en su barra de estado informándome que hay un
repositorio <code>git</code> y está señalando a la rama <code>source</code>.
</p>
</div>
</div>
</div>
<div id="outline-container-org8f34c3f" class="outline-2">
<h2 id="org8f34c3f">Conclusión</h2>
<div class="outline-text-2" id="text-org8f34c3f">
<p>
Hay muchas más opciones, tantas como tiene <code>git</code>.  Sin embargo me he
limitado a contar las que más utilizo y cómo.  <code>magit</code> es una gran
herramienta para gestionar los repositorios <code>git</code>, cada vez encuentro
más y más funcionalidades; ha conseguido que deje la línea de comandos
para hacer muchas cosas.  Sólo espero que acostumbrado a la facilidad
que proporciona no se me olviden los comandos y me encuentre
imposibilitado de trabajar cuando me falte.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Obsérvese que evito llamar «editor» a <i>emacs</i>.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/git/index.html">git</a> <a href="/tags/magit/index.html">magit</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[git]]></category>
  <category><![CDATA[magit]]></category>
  <link>https://notxor.nueva-actitud.org/2018/11/29/usando-magit.html</link>
  <pubDate>Thu, 29 Nov 2018 20:57:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Mumbleada sobre conversacionales]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-11-27</div>
<p>
El domingo pasado (25 de noviembre de 2018) hubo una <i>mumbleada</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>
algo peculiar.  Peculiar por varios motivos que explicaré más tarde,
porque primero voy a poner un <i>chismático</i> por si quieres escucharla
(ya te advierto que tampoco te pierdes nada).
</p>

<audio controls>
    <source src="./archivo/notxor-mumbleada-aventuras-conversacionales.ogg" type="audio/ogg">
    Tu navegador no soporta la etiqueta audio, comprueba que soporta el formato ogg.
</audio>

<p>
Mi aterciopelada voz y mi verbo fluido se pueden apreciar en la
grabación respondiendo preguntas, como si yo realmente supiera de algo
de lo que me preguntan, pero bueno, eligieron ellos al entrevistado.
Insistieron tanto.
</p>

<p>
Me animó el hecho de que el tema eran las <i>aventuras conversacionales</i>
o la <i>ficción interactiva</i>, si se quiere emplear un término más
amplio.  Sin embargo, intenté que otros más conocedores del tema, con
más experiencia, participaran también en el asunto y no verme solo
ante las preguntas de los asistentes.  El caso es que cometí algunas
inexactitudes que tampoco voy a mencionar aquí, el que entienda del
tema ya las oirá, si escucha el audio, y para el que no entienda
tampoco tiene demasiada importancia, y si no escuchas el audio ¿para
qué querrías saberlo si ni siquiera te interesa el tema?
</p>

<p>
Para mí fue la primera vez que utilizaba <i>mumble</i> y me pareció una
locura.  Quería estar atento a lo que se hablaba, a lo que se escribía
y a lo que quería contestar.  Mi neurona se saturó en algunos momentos
justo cuando algunas palabras aprovecharon para jugar al escondite
cuando más las necesitaba.
</p>

<p>
Bueno, aquello ya pasó y el resultado es lo que hay ahí.
</p>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://wiki.mumble.info/wiki/Main_Page">Una conversación a través de <i>mumble</i></a>, que es una herramienta
para conversar a través de <i>Internet</i>.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/conversacionales/index.html">conversacionales</a> ]]></description>
  <category><![CDATA[conversacionales]]></category>
  <link>https://notxor.nueva-actitud.org/2018/11/27/mumbleada-sobre-conversacionales.html</link>
  <pubDate>Tue, 27 Nov 2018 22:08:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Calcular la hora por la posición de las estrellas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-11-20</div>
<p>
Hoy voy a salirme de lo que son los temas habituales que suelo
tratar.  El caso es que estos días hablando con alguien de los
múltiples <i>chats</i> en los que entro, me comentaban con incredulidad la
costumbre de algunos autores de novelas de fantasía de poner algún
personaje capaz de decir la hora por la posición de las estrellas.
Más o menos, según mi interlocutor, hay que tener un doctorado en
astronomía para hacerlo y sin embargo a mí me parece relativamente
sencillo.  Le expliqué cómo se hace y la explicación no me quedó
demasiado clara.  Por ello, lo retomo aquí y he considerado el hacer
también unos dibujos para que sean más claras las explicaciones.
</p>

<p>
Ya sé que es la Tierra la que gira y la hora dependerá de ese giro.
Pero permitidme la licencia si en alguna de las explicaciones hablo
del <i>giro de las estrellas</i>.
</p>
<div id="outline-container-org604b28f" class="outline-2">
<h2 id="org604b28f">Localizar la <i>Estrella Polar</i></h2>
<div class="outline-text-2" id="text-org604b28f">
<p>
Polaris tiene la particularidad de estar alineada, aproximadamente,
con el eje de rotación de la Tierra, sobre el extremo que hemos venido
en llamar <i>Norte</i>.  Por eso, parece mantenerse estática sobre el norte
mientras todas las demás giran alrededor de ella.  Puesto que está
siempre aproximadamente sobre la misma posición, vamos a considerarla
como el centro de nuestro <i>reloj</i>.  Pero primero tenemos que
localizarla y no hay nada más fácil.  Todo el mundo conoce las dos
constelaciones que necesitamos: La Osa Mayor (o el carro) y la Osa
Menor.  La <i>Estrella Polar</i> es la del extremo de la Osa Menor y como
esta constelación tiene estrellas menos luminosas, a veces se nos
puede desdibujar un poco.  En esas ocasiones podemos aprovechar que la
Osa Mayor posee estrellas más luminosas y utilizarla de guía.
</p>


<figure id="org207bd67">
<img src="./imagen/estrella-polar.png" alt="estrella-polar.png">

</figure>

<p>
En el gráfico podemos apreciar que si alargamos cinco veces el
segmento del extremo de la Osa Mayor, nos topamos con la estrella
polar.  Además como necesitaremos también una aguja, marcador o dial
para nuestro reloj, ya tenemos uno.
</p>
</div>
</div>
<div id="outline-container-org2d0167c" class="outline-2">
<h2 id="org2d0167c">Nuestra esfera del reloj</h2>
<div class="outline-text-2" id="text-org2d0167c">
<p>
Ya tenemos un centro y una aguja que nos marca.  Efectivamente el
resto del cielo ejercerá de esfera del reloj, pero para que marque
debemos establecer las marcas dividiendo toda la circunferencia en 24
partes porque son las horas en las que se divide el día.
</p>

<p>
Quedaría algo así:
</p>


<figure id="org653e64b">
<img src="./imagen/esfera-reloj.png" alt="esfera-reloj.png">

</figure>
</div>
</div>
<div id="outline-container-org4d9d797" class="outline-2">
<h2 id="org4d9d797">Nuestro reloj adelanta</h2>
<div class="outline-text-2" id="text-org4d9d797">
<p>
En un mundo perfecto, cuando nuestro dial marque las 12 (o las 0)
deberían ser las 12 de la noche, como se aprecia en la figura.
</p>


<figure id="org2930adc">
<img src="./imagen/hora-0.png" alt="hora-0.png">

</figure>

<p>
Tenemos un problema: En realidad, a cada día de 24 horas le faltan
cuatro minutos; es decir la Tierra da una vuelta completa cada 23
horas y 56 minutos. El que lo haga con precisión es lo nos permite
calcular que cada 15 días adelanta una hora y dos horas cada mes.
<i>Esto es muy importante para nuestros cálculos</i>.
</p>

<p>
De hecho, la fecha en la que coincide que nuestro reloj marca las doce
de la noche y efectivamente son las doce de la noche es el 6 de marzo.
Esa noche la hora solar serán las doce cuando nuestro reloj
astronómico también lo marca; quince días después nuestro reloj
astronómico marcará las doce cuando el reloj solar estará en las once.
</p>

<p>
Hay que poner hincapié en la <i>hora solar</i> porque luego hay que
ajustarla a la <i>hora legal</i>, según los horarios de invierno y de
verano.
</p>
</div>
</div>
<div id="outline-container-orgb35744f" class="outline-2">
<h2 id="orgb35744f">Los cálculos</h2>
<div class="outline-text-2" id="text-orgb35744f">
<p>
Como hemos dicho cada día nuestro reloj se adelanta cuatro minutos.
Para ser exactos deberíamos calcular la cantidad de días que han
pasado desde el 6 de marzo, multiplicarlo por cuatro y restar todos
esos minutos de la hora que marque nuestro reloj astronómico.  También
podemos simplificar y contar dos horas por cada mes.  Voy a poner un
par de ejemplos de cómo hacerlo.
</p>
</div>
<div id="outline-container-org988e2dc" class="outline-3">
<h3 id="org988e2dc">Ejemplo 1</h3>
<div class="outline-text-3" id="text-org988e2dc">
<p>
Hoy es 21 de noviembre y cuando miramos al cielo nuestro reloj
astronómico marca así:
</p>


<figure id="org04c3058">
<img src="./imagen/ejemplo-1.png" alt="ejemplo-1.png">

</figure>

<p>
Es decir, nos marca las 12 del mediodía (algo imposible si estamos
viendo las estrellas).  Desde el 6 de marzo han pasado 8 meses y 15
días.  Los cálculos serían:
</p>

<pre class="example" id="org1e9867d">
 8 meses × 2 h/mes   = 16 horas
15 días  × 4 min/día = 60 min = 1 hora
</pre>

<p>
Si sumamos nuestro adelanto, nos dan 17 horas que tendremos que
retrasar el reloj, luego (12-17 = -5) ... <i>¿-5?</i>, <i>¿qué hora es esa?</i>
Esto sucede porque ha dado una vuelta completa.  Cuando nuestros
cálculos arrojan resultados negativos tenemos que complementar a 24,
luego (12-17+24 = 19).  Esto quiere decir que serán las 19, hora solar o
las 7 de la tarde.  Es decir, que como en España hay que sumar una
hora en horario de invierno, nuestro reloj de pulsera marcará las 8
de la tarde (y recordar que en horario de verano hay que sumar 2).
</p>
</div>
</div>
<div id="outline-container-org0cba880" class="outline-3">
<h3 id="org0cba880">Ejemplo 2</h3>
<div class="outline-text-3" id="text-org0cba880">
<p>
Otro ejemplo para que queden claros los conceptos.  Vamos a suponer
que estamos 12 de agosto y vemos el siguiente reloj astronómico:
</p>


<figure id="orgcb0d698">
<img src="./imagen/ejemplo-2.png" alt="ejemplo-2.png">

</figure>

<p>
Los cálculos para ese día serán:
</p>

<pre class="example" id="orgef75090">
5 meses × 2 h/mes   = 10 horas
6 días  × 4 min/día = 24 min
</pre>

<p>
El reloj astronómico marca aproximadamente las 15 horas, luego la hora
solar será (15-10 = 5h - 24min = 4h 36min). Es decir serán
aproximadamente las cuatro y media de la mañana hora solar, a la que
tendremos que sumar dos horas más por el horario de verano... es decir
serán las seis y media, aproximadamente, en el reloj de pulsera.
</p>
</div>
</div>
</div>
<div id="outline-container-org2ba2c64" class="outline-2">
<h2 id="org2ba2c64">Conclusión</h2>
<div class="outline-text-2" id="text-org2ba2c64">
<p>
Los cálculos, como se ve no son difíciles de hacer y con un poco de
práctica se convierten en casi automáticos.  Tan sólo hay que recordar
algunas cosas como que la fecha clave es el 6 de marzo (en el
meridiano 0 o de <i>Greenwich</i>), hay que corregir 1 minuto por cada
grado, sumándolo si se está al oeste y restándolo si se está al este.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2018/11/20/calcular-la-hora-por-la-posicion-de-las-estrellas.html</link>
  <pubDate>Tue, 20 Nov 2018 19:43:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[¿Por qué uso GNU/Linux? y otras perlas similares]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-11-14</div>
<p>
Mi mujer dice que siempre utilizo lo que no usa nadie; que si todo el
mundo usa algo yo dejo de hacerlo, si alguna vez llegué a usarlo.  He
de reconocer que parece que no le falta razón, pero el motivo no es
<i>ser especial</i> o <i>el raro</i> ni nada parecido, como parece decir ella.
Por eso quiero dar mis razones.
</p>

<p>
Recuerdo cuándo comencé a trastear con GNU/Linux de forma asidua. La
Internet era sólo un sueño y sólo tenía acceso a las <i>distros</i> que
venían con revistas. En la informática de consumo lo petaba MS-DOS y
windows 3.1.  Recuerdo aún aquellas tardes de exploración y
aprendizaje que tuve en aquella época, descubriendo trucos, comandos y
aplicaciones, cuando todo se hacía desde la consola y la instalación
de cualquier aplicación era el famoso:
</p>

<div class="org-src-container">
<pre class="src src-shell">./configure
make
make install
</pre>
</div>

<p>
Mi primera <i>distro</i>, mi primera instalación exitosa, recuerdo que fue
una <i><a href="https://www.slackware.com">Slackware</a></i> y la mantuve durante bastante tiempo.  También probé
otras: <i>Red Hat</i>, <i>Mandracus</i>, <i>Debian</i>, <i>SuSE</i>...
</p>

<p>
No existían ni <i>Gnome</i> ni <i>KDE</i>. Recuerdo instalar un engendro que era
un <i>port</i> del <i>CDE</i> de <i>Unix</i> con <i>OpenMotif</i> y para mí fue un <i>¡Oh!
¡Ah! Ventanitas como en güindón. ¡Qué monas!</i>. Luego vino la guerra o
el <i>flame</i> de <i>KDE-Qt</i> contra <i>Gnome-GTK</i>.
</p>
<div id="outline-container-org5b4d209" class="outline-2">
<h2 id="org5b4d209">El incidente de «no me toques los güevos»</h2>
<div class="outline-text-2" id="text-org5b4d209">
<p>
Hubo un momento en que mi relación con los sistemas operativos cambió
por culpa de un monumental rebote.  Recuerdo que había comprado un
tiempo antes un <i>windows 95</i> original y lo tenía instalado en mi
ordenador. En aquella época me parecía natural tener que instalar
ampliaciones de memoria, mejorar discos duros y otras cuantas cosas
para «mantenerte al día». Como he dicho había comprado un <i>w95</i> y con
él venía la opción de una actualización a la siguiente versión
(<i>windows 98</i>) gratis. Cuando se publicó el <i>w98</i> recuerdo que esperé
algunos días mientras me enteraba si merecía la pena y terminé
solicitando mi ampliación porque me pareció ─haciendo caso a la
publicidad de la casa─, «mucho más mejor».
</p>

<p>
Recuerdo que me puse con la instalación del <i>w98</i> tranquilamente.
Había hecho la copia de seguridad de los datos, como decían las
instrucciones y lancé el instalador. Recuerdo que en un momento dado
me preguntó si quería formatear el disco duro y le dije que no, que
utilizara la partición que yo tenía reservada para el «güindón del Bili
Puertas».
</p>

<p>
Cuando terminé la instalación comprobé que había formateado todo el
disco duro para instalarse él, pasándose las particiones por el forro
del arco del triunfo y yo pensé: <i>¿Pa'qué coño preguntas si luego
haces lo que te sale los güevos?</i>. Realmente no había perdido nada
importante, salvo la partición donde estaba probando una <i>SuSE</i> que
había instalado también de alguna revista.
</p>

<p>
Lo siguiente que hice fue un acto de rebeldía puro y duro, formateé el
disco e instalé la <i>SuSE</i> que tenía a mano. Desde entonces no he
vuelto a instalar ningún <i>güindón</i>. Desde entonces me he dedicado a
aprender y a no mirar lo que hacen mis vecinos, sino a buscar mis
caminos y maneras de forma independiente.
</p>


<figure id="org6820355">
<img src="./imagen/foto-distros.png" alt="foto-distros.png">

</figure>

<p>
En la foto pongo mi tesoro de <i>distros</i> originales. La que está
desplegada fuera de la caja es una <i>SuSE</i> «pofesional y tó y tó». La
otra eran unos discos grabados por la revista «Muy Linux», la <i>Debian</i>
3.0, prometieron darle a la distribución lo correspondiente... espero
que fuera así, porque si no hice el canelo. Las compré porque el
<i>software</i> debe ser libre, pero no tiene por qué ser gratis.
</p>

<p>
Resumiendo un poco el motivo por el que sigo con GNU/Linux es que
puedes estar seguro de que hacer funcionar las cosas puede ser fácil o
difícil, porque hay cosas fáciles y cosas difíciles. En <i>güindón</i>
también: las cosas fáciles son fáciles, pero las difíciles son
imposibles. Son imposibles porque es el sistema el que decide cómo lo
tienes que configurar y algunas veces no hay manera de cambiar lo que
ha decidido él.
</p>
</div>
</div>
<div id="outline-container-org55bd535" class="outline-2">
<h2 id="org55bd535">Más allá de las libertades del <i>software libre</i></h2>
<div class="outline-text-2" id="text-org55bd535">
<p>
No voy a darle vueltas a las libertades del <i>software libre</i>. Desde
que a finales de los años 80 del siglo pasado, Richard Stallman
fundara la <i>FSF</i> (<i>Free Software Fundation</i>) los principios éticos del
<i>software libre</i> siguen vigentes.
</p>

<p>
Para mí existe una libertad muy básica: hacer lo que considero
oportuno y lo que yo quiero, no lo que decide una corporación por mí.
Y ahora mismo ─más que nunca─, necesitamos esa libertad que sólo puede
otorgar el <i>software libre</i>. La sociedad actual se ha reestructurado
entorno a la tecnología y ahora mismo no podemos entender muchas de
nuestras relaciones, sociales, profesionales o de cualquier índole,
sin el concurso de la tecnología como puente de comunicación. Yo me
pregunto por qué he de confiar mis relaciones sociales, profesionales
o de cualquier índole, a los mensajes que decida mostrarme, enviarme o
filtrarme una determinada corporación.
</p>

<p>
¿Os acordáis cuando el <i>moto</i> de <i>Google</i> era <i>don't be evil</i>? Pero
qué <i>hi'de puta más resalaos</i> son: «No seas malo», decían. Ahora se
dedican a <i>castrar</i> nuestras búsquedas con un algoritmo para tener las
herramientas de conocimiento e influencia suficientes para dirigir la
sociedad hacia donde ellos quieran ─que no será una finalidad
altruista sino aquella donde puedan repartir más beneficios─. Lo mismo
me ocurre con las redes sociales mayoritarias. No uso <i>feisfús</i>, ni
<i>güasá</i>, ni <i>tuister</i>, por el mismo motivo: tengo una intimidad que
defender, no porque tenga nada que ocultar sino porque mi intimidad es
lo que me hace ser yo. Si mi intimidad la manejan corporaciones
mediante oscuros algoritmos ¿hasta qué punto puedo estar seguro de que
mis opiniones son mías o han sido sembradas por intereses externos a
mí?
</p>

<p>
Entiendo que hay gente que prefiere que le organicen las cosas y le
digan lo que tiene que pensar. Algunos se enchufan a ciertas cadenas
televisivas donde el principal contenido es el «argumentario» de su
partido político favorito. Lo entiendo: es fácil hacer eso y te
desgastas mucho más teniendo que leer, informarte y creándote tu
propia opinión. Es muy sencillo dejarme filtrar la información, sea
veraz o no, sólo tengo que entrar en mi <i>muro</i> y ver lo que me deja
ver el algoritmo de la empresa que sea. Es pasivo como ver la
televisión, te tragas lo que te digan y punto.
</p>
</div>
</div>
<div id="outline-container-org83270f0" class="outline-2">
<h2 id="org83270f0">La bendita eficiencia</h2>
<div class="outline-text-2" id="text-org83270f0">
<p>
Otro motivo es que tengo cierta tendencia al caos y me disperso con
bastante facilidad.  Me pongo a trastear, a aprender y pierdo de vista
otros asuntos, como la <i>eficiencia</i>, la <i>productividad</i> y otras
zarandajas destinadas a convertir en dinero nuestras actividades. Mi
tendencia está siendo regresar al uso del texto plano para todo. Desde
hace mucho tiempo vengo prefiriendo LaTeX a la <i>ofimática</i> y <i>emacs</i>
ha sido mi «penúltimo» descubrimiento.
</p>

<p>
No me malinterpretéis: me gustan unos buenos gráficos como al que
más.  Recuerdo cuando mostraba a mis amistades mi escritorio con
<i>Compiz</i> activado, rotando el famoso cubo, haciendo temblar las
gelatinosas ventanas al arrastrarlas o desaparecer en un vórtice hacia
la barra de tareas. Pero sólo era para darles en las raíces dentales a
los que decían que <i>Linux es feo</i>.
</p>

<p>
Mis gustos ahora mismo se han dado la vuelta, como gestor de ventanas
utilizo <i>i3wm</i>: minimalista, con atajos de teclado que configuro yo,
con una forma de funcionar que todo lo tienes en la punta de los dedos
sin perder tiempo en mover la mano del ratón fuera del teclado. La
mayoría de las aplicaciones las utilizo desde terminales virtuales:
<i>tmux</i> es mi amigo desde hace tiempo. Casi todo lo gestiono y guardo
en texto plano: <i>org-mode</i> de <i>emacs</i> tiene la culpa.
</p>

<p>
GNU/Linux me gusta porque no satura el <i>hardware</i>, no necesito una
ampliación de memoria cada tres meses ni un disco duro nuevo cada dos
por tres. Mi portátil ya tiene una edad y con el <i>güindón</i> estaría
jubilado hace algunos años. Sin embargo, aquí está el campeón
tragándose el trabajo con una velocidad que ya quisieran muchos de sus
primos modernos.
</p>
</div>
</div>
<div id="outline-container-orgcf5e306" class="outline-2">
<h2 id="orgcf5e306">Aprendizaje</h2>
<div class="outline-text-2" id="text-orgcf5e306">
<p>
Desde que utilizo GNU/Linux conozco mejor cómo funcionan los
ordenadores y he aprendido muchas cosas. Vale que aprendí a programar
y conozco varios lenguajes de programación, algo que siempre me
recuerdan los que no se pusieron a aprender a programar. También
trabajé de «analista-programador» y lo hice para aplicaciones
<i>windows</i>, que se vendían, pero fue la época de mi vida en la que
menos aprendí sobre informática en general.
</p>

<p>
A lo largo del tiempo he ido encontrando maneras de hacer las cosas
que al final me han ido haciendo más independiente de las
herramientas, especialmente de pegarme con las versiones de las
herramientas ─algo que los usuarios del <i>güindón</i> admiten como natural
cuando guardan un fichero de texto con una versión del <i>güor</i> y lo
intentan abrir con otra─. Aprendí también a hacer muchas cosas, con un
poco más de esfuerzo que la gente de mi entorno, porque muchas veces
me hacía mis propias herramientas. Por ejemplo, haciendo funcionar
«lectoras de marcas» fabricadas cuando Julio César cruzó el Rubicón y
que habían quedado obsoletas no porque no funcionaran o estuvieran
estropeadas; sino porque el <i>software</i> que las controlaba dejaba de
funcionar por incompatibilidad con el sistema operativo. Llamabas a la
casa y te decían que te compraras una nueva, que «esa ya tal».
</p>
</div>
</div>
<div id="outline-container-orgb7aea0f" class="outline-2">
<h2 id="orgb7aea0f">Comunidad</h2>
<div class="outline-text-2" id="text-orgb7aea0f">
<p>
Si algo me gusta del <i>software libre</i> es el sentido de comunidad: el
saber que no caminas solo en ese mundo. Al principio, cuando te
encuentras inmerso de primeras en el mundo de la <i>Libertad</i> ─con
mayúsculas, porque en la vida tecnológica que nos espera representará
el único camino hacia ella─ intentas que todo el mundo se convierta y
se convenza de las maravillas que representa el <i>software libre</i>. Sin
embargo, no te conviertes en un <i>profeta</i> como tú piensas, sino en el
<i>pesao'del linux</i>. Ahora mismo lo hago al revés: si alguien me
pregunta le ayudo a instalar GNU/linux si no, me callo: <b>cada uno
tiene el sistema operativo que se merece</b>, es mi lema.
</p>

<p>
Sin embargo, mi sentimiento de comunidad no vino del mundo GNU, sino
de la quiebra de la empresa NaN. Para que haya comunidad tiene que
haber comunicación entre sus miembros y sentimiento de pertenencia. La
Internet vino a mi casa con un poco de retraso allá por el 2000... y
coincidió con una llamada de socorro de Tom Roosendaal, creador de
<i>Blender</i>. La empresa creadora, NaN, cerraba por quiebra y el
programador principal de la <i>suite 3D</i> libre por excelencia pedía
dinero ─en tiempos donde no conocíamos el término <i>crowfunding/─, para
comprar los derechos del código y liberarlo a la comunidad. Recuerdo
poner algo en la campaña, la verdad es que no mucho, ahora quizá
hubiera puesto más, pero entonces no tenía. Cuando Tom reunió
suficiente dinero y cumplió su palabra de hacer de /Blender</i> una
herramienta libre me sentí parte de eso, de una comunidad que había
liberado una aplicación que merecía ser de todos.
</p>
</div>
</div>
<div id="outline-container-orgfe2b2d9" class="outline-2">
<h2 id="orgfe2b2d9">De vuelta al modo texto</h2>
<div class="outline-text-2" id="text-orgfe2b2d9">
<p>
Sigo utilizando IRC, algo que la gente parece haber ido abandonando.
También los foros y otras herramientas <i>viejunas</i>. Soy consciente de
que para la mayoría de los que ahora no pueden vivir sin la <i>Internet</i>
la red se compone sólo de grandes corporaciones que la dominan y que
para muchos la <i>deepweb</i> consiste en teclear la dirección de una
página directamente en la barra del navegador en lugar de en la barra
del buscador. Con ese nivel, cualquiera que abrimos una consola de
texto para teclear comandos nos convertimos en <i>hacker</i>, de forma
automática (si además, <i>feisbús</i> no sabe tu nombre cuando apareces en
una foto que algún imbécil sube sin pedirte permiso, te conviertes en
<i>anonimus</i>, también automáticamente).
</p>

<p>
Últimamente estoy volviendo la formato de texto plano, como he dicho
antes. Comencé en esto de GNU/Linux cuando se arrancaba por defecto en
modo texto y luego si querías entorno gráfico lanzabas la llamada
desde la consola con <code>xinit</code>, que era lo primero que hacíamos la
mayoría. Al contrario, ahora arranca por defecto en modo gráfico y
normalmente la primera acción que hago es abrir una consola. Sí, me he
convertido en usuario capicúa: comencé con consola→gráficos para
acabar con gráficos→consola.
</p>

<p>
La mayor parte de mis documentos se imprimen pasando por LaTeX.
Aprendí a usarlo a pelo y cuando lo hice, mi editor favorito era
<code>vim</code>. Pero las cosas han cambiado: descubrí el <code>org-mode</code> de
<i>emacs</i>. Nunca me ha gustado entrar en los <i>flames</i>: <i>vim - emacs</i>,
<i>gnome - kde</i> y otras muchas que todos conocemos. Yo me declaraba
forofo de <i>vim</i> y <i>emacs</i> me parecía pesado y sobredimensionado como
editor. ¿Algo ha cambiado? Pues no especialmente. Me sigue pareciendo
mejor editor <i>vim</i>, pero es que <i>emacs</i> no es un editor.
</p>

<p>
Para mí, <i>emacs</i> es un entorno <i>Lisp</i> que permite editar texto. Lo
presentan como un editor, pero es mucho más que eso: es un <i>Lisp</i>
corriendo que permite que le añadas código y lo hagas funcionar. Al
final es un entorno de trabajo. Te proporciona una <i>interfaz</i> de texto
para hacer lo que quieras programando con <code>elisp</code>. Eso es lo que me ha
enamorado de <i>emacs</i>, que me deja hacer lo que necesito sin salir del
entorno. Y la obra cumbre de todo ese entorno es el <code>org-mode</code>, que
permite hacer <i>casi</i> de todo. Desde gestionar la agenda hasta escribir
un libro, si te pones. Permite desde ordenar información de manera
estructurada a hacer cálculos en tablas. Todo con un lenguaje de
marcado muy sencillo para escribir textos y que permite generar los
documentos en casi cualquier formato: pdf, epub, odt...  Y no necesito
más... Bueno, sí <i>pandoc</i> para convertir los documentos a los formatos
que no soporta <i>emacs</i>, como <code>.doc</code> o <code>.docx</code>.
</p>
</div>
</div>
<div id="outline-container-orgdead129" class="outline-2">
<h2 id="orgdead129">Flexibilidad</h2>
<div class="outline-text-2" id="text-orgdead129">
<p>
No sólo por el sistema operativo. Si miramos entre las 500
megacomputadoras del mundo, las 500, el 100 % de ellas, utilizan
GNU/Linux. Pero también lo puedes instalar en una «raspi», por
ejemplo. Si miramos entre los servidores de <i>Internet</i> vemos que
también gana con diferencia. No contaré los dispositivos
<i>Android/Linux</i> que hay por el mundo.
</p>

<p>
Pero no me refiero sólo a la capacidad de adaptación a distintos
<i>hardwares</i>, sino también a que siempre hay más de una manera de hacer
las cosas. Puedo escribir un texto con muchas herramientas diferentes
y tengo la libertad de elegir la que me parece. No me obligan a
utilizar un navegador u otro, una <i>suite ofimática</i> u otra.
</p>

<p>
Al final se trata de que el sistema se adapta a mi manera de trabajar
y no al revés.
</p>
</div>
</div>
<div id="outline-container-org44635ed" class="outline-2">
<h2 id="org44635ed">Conclusión</h2>
<div class="outline-text-2" id="text-org44635ed">
<p>
Es sencilla: Uso GNU/Linux porque puedo. He comprobado que a mucha
gente le da miedo la consola de texto pero para mí es precisamente <i>La
Herramienta</i>.
</p>

<p>
Y estos son mis motivos para usar GNU/Linux y no dar ni un paso atrás a
sistemas privativos. He soportado estoicamente que me señalen como <i>el
raro</i> y lo seguiré soportando, porque no pienso dar ni un paso atrás
con el <i>software privativo</i>. Soy <i>el raro</i>, pero he conseguido que ya
nadie me pida que le arregle el ordenador con <i>güindón</i>, saben que no
lo haré. Pero sí me piden que les instale el <i>linux ese que es muy
difícil</i>.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/linux/index.html">linux</a> ]]></description>
  <category><![CDATA[linux]]></category>
  <link>https://notxor.nueva-actitud.org/2018/11/14/por-que-uso-gnu-linux-y-otras-perlas-similares.html</link>
  <pubDate>Wed, 14 Nov 2018 10:26:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Configuración de Jabber en Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-11-10</div>
<p>
Este post va a ser muy corto.  El tema es que estaba hablando ayer con
Ángel de <a href="https://ugeek.github.io">uGeek, un <i>blog-podcast</i> sobre tecnología</a>.  Estábamos hablando
sobre <i>Jabber</i> o XMPP y los programas que lo soportan.  Y apareció el
comentario de <a href="http://emacs-jabber.sourceforge.net/">«existe un paquete para <i>emacs</i> que soporta <i>Jabber</i> o
XMPP</a>. Y aquí he venido yo a <i>cansinar</i> otra vez con el <i>emacs</i> y esta
vez va de comunicaciones y mensajería.
</p>
<div id="outline-container-org09dc84f" class="outline-2">
<h2 id="org09dc84f">¿Qué es <i>Jabber</i> (<code>XMPP</code>)?</h2>
<div class="outline-text-2" id="text-org09dc84f">
<p>
<code>XMPP</code> es un estándar abierto de mensajería, también se le conoce como
<i>Jabber</i>.  Lo bueno de este sistema es que puedes montarte tu propio
servidor de mensajería y conectarlo a una red federada de servidores,
de modo que puedes conversar con otras personas sean cuales sean sus
servidores.  Por ejemplo, en la conversación del otro día, Ángel
hablaba <a href="https://cloud.disroot.org">desde su cuenta de <i>Disroot</i></a> mientras yo lo hacía <a href="https://www.suchat.org">desde mi
cuenta de <i>suchat</i></a> con toda normalidad.  Se intercambiaron no sólo
conversaciones escritas, también mensajes de sonido en un entorno
<a href="https://conversations.im/omemo/">cifrado con <code>OMEMO</code></a>.
</p>

<p>
La funcionalidad, como cualquier sistema de mensajería instantánea, no
hace falta explicarla.  Basta pensar en aplicaciones tipo «güasá»,
para saber lo que hace este sistema; solo que lo hace desde un punto
de vista descentralizado.  Lo viene haciendo desde 1999 y una de las
críticas que he visto por <i>Internet</i> es que debería actualizarse el
protocolo.  Sin embargo, como dice el famoso aforismo: <i>Si funciona,
no lo toques</i>.
</p>
</div>
<div id="outline-container-orge9caaff" class="outline-3">
<h3 id="orge9caaff">Clientes de <i>Jabber</i> (<code>XMPP</code>)</h3>
<div class="outline-text-3" id="text-orge9caaff">
<p>
Lo único que necesitas para utilizar este sistema de mensajería es una
cuenta.  Las cuentas parecen direcciones de correo, tienen un símbolo
<code>@</code> separando el nombre del servidor del estilo <code>nick@servidor.com</code>.
Si queréis añadirme a vuestra lista de contactos podéis darme un toque
con el <i>nick</i> «notxor» en «suchat.org».
</p>

<p>
Hay clientes para todos los sistemas operativos.  Como en el entorno
en el que han tenido más éxito este tipo de aplicaciones es en la
telefonía móvil, recomiendo <a href="https://f-droid.org/es/packages/eu.siacs.conversations/">la aplicación <i>Conversations</i></a> que se puede
encontrar en el repositorio libre <a href="https://f-droid.org">https://f-droid.org</a>, aunque también
en la tienda de la gran G.
</p>

<p>
En GNU/Linux también se puede utilizar algunas aplicaciones como <a href="https://gajim.org/">gajim</a>
o <a href="https://github.com/psi-plus">Psi+</a>. Es posible que existan también aplicaciones (o versiones de
éstas) para el «Güindón del Bili Puertas», pero como las desconozco no
hablaré sobre ellas.  En todo caso, recomiendo sólo las que estoy
seguro que soportan encriptación <code>OMEMO</code>, por razones de seguridad.
</p>

<p>
Pero hoy he venido a hablar del paquete <code>jabber.el</code> para <i>emacs</i>.
</p>
</div>
</div>
</div>
<div id="outline-container-org5e6a6ba" class="outline-2">
<h2 id="org5e6a6ba">El paquete <code>jabber.el</code></h2>
<div class="outline-text-2" id="text-org5e6a6ba">
</div>
<div id="outline-container-orge188535" class="outline-3">
<h3 id="orge188535">Instalación</h3>
<div class="outline-text-3" id="text-orge188535">
<p>
Como cualquier paquete de <i>emacs</i> que está en <code>MELPA</code>.  Supongo que la
mayoría de los que puedan leer este artículo sabe cómo.  Sin embargo,
lo pongo aquí por si alguien nuevo en el mundillo de <i>emacs</i> aparece a
leerlo: <code>M-x package-install RET jabber.el RET</code>.
</p>
</div>
</div>
<div id="outline-container-org96c7af4" class="outline-3">
<h3 id="org96c7af4">Configuración</h3>
<div class="outline-text-3" id="text-org96c7af4">
<p>
Una vez instalado se puede utilizar llamando directamente al comando
<code>jabber-connect</code> desde <code>M-x</code>.  <i>Emacs</i> interrogará sobre la cuenta y
la contraseña y se conectará sin más necesidad de configuración.  Si
quieres automatizar todo y que haciendo la conexión <i>emacs</i> sepa a qué
servidor y con qué cuenta se debe conectar hay que hacer algo con la
configuración.
</p>

<p>
Sólo hay que rellenar la variable <code>jabber-account-list</code> con los datos
de las cuentas que se quieran configurar.  Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Configuraci&#243;n de jabber
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> jabber-account-list '(
                            (<span style="color: #f1fa8c;">"notxor@suchat.org"</span>
                             (<span style="color: #8be9fd; font-style: italic;">:password</span> . <span style="color: #f1fa8c;">""</span>)
                             (<span style="color: #8be9fd; font-style: italic;">:port</span> . 5222)
                             (<span style="color: #8be9fd; font-style: italic;">:connection_type</span> . starttls))
                            (<span style="color: #f1fa8c;">"notxor@ingobernable.net"</span>
                             (<span style="color: #8be9fd; font-style: italic;">:password</span> . <span style="color: #f1fa8c;">""</span>)
                             (<span style="color: #8be9fd; font-style: italic;">:connections_type</span> . ssl))
                            ))

</pre>
</div>

<p>
Yo las he rellenado con mis dos cuentas... se pueden ver (excepto las
contraseñas, por razones evidentes), los parámetros de conexión.
</p>

<p>
Me sirven además, porque me conecto a cada una de ellas de una manera
distinta: a la cuenta <i>suchat.org</i> utilizo el protocolo <code>starttls</code> al
puerto <code>5222</code>, mientras que a la otra hago una conexión por <code>ssl</code> al
puerto por defecto (que es el <code>5223</code>, si no recuerdo mal.
</p>

<p>
Se pueden configurar muchos más parámetros, como <code>avatar</code>,
notificaciones y muchas otras cosas.  Recomiendo leer la documentación
para conocer todos los detalles.
</p>

<p>
Si configuras la variable <code>jabber-account-list</code> aparecerá en el menú
de <i>emacs</i> un desplegable de <i>Jabber</i>, para conectar, desconectar y
demás opciones del servicio de mensajería.  Como yo no lo quiero
permanente allí, lo que he hecho es guardarlo en fichero que he
llamado <code>cuentas-jabber.el</code>.  Cuando quiero conectarme cargo ese
fichero con <code>load-file</code> y después hago el <code>jabber-connect-all</code>, para
que me conecte a todas.
</p>
</div>
</div>
<div id="outline-container-orge890c15" class="outline-3">
<h3 id="orge890c15">Uso del paquete</h3>
<div class="outline-text-3" id="text-orge890c15">
<p>
Lo mejor es leer la documentación, pero voy a dar un par de pinceladas
para usarlo así de primeras.  Ya, ya.  Esa frase ha sonado a «lee el
puto manual» de siempre, pero con más mano izquierda.  Voy a suponer
que el usuario <i>nunca</i> ha utilizado <i>Jabber</i> (XMPP) como mensajería, y
menos en <i>emacs</i>.
</p>

<p>
Si, como en el punto anterior cuento, ya has hecho la conexión con el
comando <code>M-x jabber-connect-all</code>, o <code>C-x C-j C-c</code>, o con el menú ─si
somos aficionados al ratón─, ya estás en condiciones de hablar con tus
contactos.  Como en otras aplicaciones tenemos una «ventana» con la
lista de nuestros contactos (en <i>emacs</i> es un <i>buffer</i> de nombre
<code>jabber-roster</code><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.  Si pulsamos <code>RET</code> en cualquiera de nuestros
contactos, <code>jabber.el</code> nos abrirá un <i>buffer</i> con el nombre
<code>jabber-chat-nombre@servidor</code><sup><a id="fnr.1.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> donde podemos hablar directamente
con el contacto seleccionado.  Pongo una captura de pantalla, en mi
sesión <code>i3wm</code>, con <i>emacs</i> escribiendo este artículo a la vez que
<i>chateo</i> conmigo mismo.  Se ve en la barra superior, donde aparece con
quién estamos hablando ─el <i>avatar</i> incluido si tiene alguno el
usuario─, el estado de conexión y demás.  Luego hay un espacio con los
mensajes intercambiados y después de una línea <code>---</code> podemos escribir.
Escribir mensajes largos es complicado, porque pulsar <code>RET</code> enviará lo
escrito bajo los tres guiones, aunque se puede hacer el salto de línea
con <code>C-j</code>.  También destaco que el último mensaje ha llegado cifrado
con <code>OMEMO</code> para que se vea que se muestra un mensaje de aviso, pero
no el mensaje.
</p>


<figure id="orgd25cec9">
<img src="./imagen/captura-jabber-emacs.png" alt="captura-jabber-emacs.png">

</figure>

<p>
Vista la imagen: ¡ni mil palabras más!
</p>
</div>
</div>
</div>
<div id="outline-container-org2d4a107" class="outline-2">
<h2 id="org2d4a107">Conclusiones</h2>
<div class="outline-text-2" id="text-org2d4a107">
<p>
<code>jabber.el</code> es una herramienta sencilla y <i>casi</i> completa.  No soporta
cifrado <code>OMEMO</code>, pero supongo que eso no será demasiado importante si
el «güasá» ha sido la principal aplicación de mensajería sin ningún
tipo de cifrado durante muchos años.  Además <i>Jabber</i> (XMPP) no está
asociada a ningún dato personal, como el número de teléfono.  Por lo
tanto es un sistema bastante más anónimo y descentralizado que merece
la pena explorar.
</p>

<p>
Ahora también lo podemos utilizar sin salir de nuestro editor
favorito.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
He omitido los pares <code>*-</code> y <code>-*</code> en el nombre del <i>buffer</i> por
problemas en la generación del código <code>html</code> desde <code>org-mode</code>.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/xmpp/index.html">xmpp</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[xmpp]]></category>
  <link>https://notxor.nueva-actitud.org/2018/11/10/configuracion-de-jabber-en-emacs.html</link>
  <pubDate>Sat, 10 Nov 2018 20:05:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Correo electrónico con Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-11-08</div>
<p>
Normalmente utilizo <i>Mozilla Thunderbird</i> como gestor de correo y como
mi agenda de contactos la gestiono con <code>bbdb</code>, también desde <i>emacs</i>,
he tenido alguna vez la necesidad de enviar algún correo directamente
con <i>emacs</i>.
</p>

<p>
Configurar el correo fue una asignatura pendiente, leía <i>tutoriales</i>
de cómo configurar complejos sistemas de correo: que si <i>mutt</i>, que si
<i>neomutt</i>, que si <i>sendmail</i> y lo iba dejando. Hasta que un día,
<a href="https://elbinario.net/2018/07/02/semana-negra-2/">impulsado por una semana negra de «el binario»</a>, encontré que <i>emacs</i>
viene con una librería incluida que se llama <code>smtpmail</code> y la configuré
en mi <code>init.el</code> tan fácil como sigue:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Configuraci&#243;n de la librer&#237;a SMTP
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> send-mail-function 'smtpmail-send-it)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> smtpmail-smtp-user   <span style="color: #f1fa8c;">"nombre-de-usuario"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> smtpmail-smtp-server <span style="color: #f1fa8c;">"servidor-smtp"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> smtpmail-smtp-service 000)
</pre>
</div>

<p>
Esas cuatro líneas me permitían enviar mensajes sin complicarme la
vida. Buscar en la lista de contactos de <code>bbdb</code> el que necesitaba,
pulsar <code>m</code> y ya podía redactar y enviar un correo electrónico.
</p>

<p>
Pero siempre me faltaba el poder leer los correos que me llegan y eso
lo fui dejando hasta que <a href="https://mew.org">hace unos días alguien me habló de <code>mew</code></a>.
</p>
<div id="outline-container-org9aa1d73" class="outline-2">
<h2 id="org9aa1d73">Gestor de correo <code>mew</code> para <i>emacs</i>.</h2>
<div class="outline-text-2" id="text-org9aa1d73">
<p>
La verdad es que llevo poco tiempo usándolo pero no me tuve que pegar
con complejas configuraciones, como hasta ahora. Siguiendo su manual,
fui capaz de leer y enviar correo a la primera.
</p>

<p>
Lo primero que dice el manual de <code>mew</code> para configurar el correo es
añadir a nuestro <code>init.el</code> el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Configuraci&#243;n de Mew
</span>(autoload 'mew <span style="color: #f1fa8c;">"mew"</span> nil t)
(autoload 'mew-send <span style="color: #f1fa8c;">"mew"</span> nil t)

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Opcional setup (Read Mail menu):
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> read-mail-command 'mew)

<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Opciontal setup (e.g. C-xm for sending a message):
</span>(autoload 'mew-user-agent-compose <span style="color: #f1fa8c;">"mew"</span> nil t)
(<span style="color: #ff79c6; font-weight: bold;">if</span> (boundp 'mail-user-agent)
    (<span style="color: #ff79c6; font-weight: bold;">setq</span> mail-user-agent 'mew-user-agent))
(<span style="color: #ff79c6; font-weight: bold;">if</span> (fboundp 'define-mail-user-agent)
    (define-mail-user-agent
      'mew-user-agent
      'mew-user-agent-compose
      'mew-draft-send-message
      'mew-draft-kill
      'mew-send-hook))
</pre>
</div>
</div>
<div id="outline-container-org1b4ddac" class="outline-3">
<h3 id="org1b4ddac">Configuración de las cuentas IMAP</h3>
<div class="outline-text-3" id="text-org1b4ddac">
<p>
Cuando arrancas <code>mew</code> desde <code>M-x</code> se conectará al servidor, pero para
ello necesita cargar los datos de conexión y los busca en el archivo
<code>~/.mew.el</code>. El contenido sería algo así.:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Configuraci&#243;n del correo
</span>
(<span style="color: #ff79c6; font-weight: bold;">setq</span> mew-charset-m17n '(<span style="color: #f1fa8c;">"utf-8"</span> <span style="color: #f1fa8c;">"iso-8859-15"</span>))

(<span style="color: #ff79c6; font-weight: bold;">setq</span> mew-name        <span style="color: #f1fa8c;">"Notxor"</span>) <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">(user-full-name)
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> mew-user        <span style="color: #f1fa8c;">"usuario-mail"</span>) <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">(user-login-name)
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> mew-mail-domain <span style="color: #f1fa8c;">"dominio.com"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> mew-imap-user   <span style="color: #f1fa8c;">"usuario-imap"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> mew-ssl         t)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> mew-ssl-port    993)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> mew-smtp-user   <span style="color: #f1fa8c;">"usuario-smtp"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> mew-smtp-port   587)

(<span style="color: #ff79c6; font-weight: bold;">setq</span> mew-smtp-server <span style="color: #f1fa8c;">"smtp.servidor.es"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> mew-proto       <span style="color: #f1fa8c;">"%"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> mew-imap-server <span style="color: #f1fa8c;">"imap.servidor.es"</span>)
</pre>
</div>

<p>
Aunque he visto que <code>mew</code> suele seleccionar correctamente los códigos
de caracteres, me he permitido añadir la línea:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> mew-charset-m17n '(<span style="color: #f1fa8c;">"utf-8"</span> <span style="color: #f1fa8c;">"iso-8859-15"</span>))
</pre>
</div>

<p>
Seguramente, si no la añades tampoco pasará nada. De momento, parece
que me está funcionando y muestra correctamente los caracteres. Antes
de ponerla, la visualización de mensajes encontraba en ocasiones
problemas de codificación (especialmente con el símbolo del «€»).
</p>

<p>
Como se puede ver en el código se puede también configurar el acceso
<code>ssl</code> y los puertos a los que conectarse.
</p>

<p>
Se pueden configurar muchas más cosas pues soporta no solo IMAP y
SMTP, también <i>mbox</i>, POP, NNTP, y muchas más cosas como cifrado GPG.
</p>

<p>
El sistema creará un directorio <code>Mail</code> en el directorio <code>home</code> del
usuario para que actúe de directorio local.
</p>
</div>
</div>
</div>
<div id="outline-container-org0f90605" class="outline-2">
<h2 id="org0f90605">Conclusiones</h2>
<div class="outline-text-2" id="text-org0f90605">
<p>
<code>mew</code> es un paquete sencillo de configurar y potente para la gestión
de correo electrónico. Aún no le he encontrado todos los resquicios y
posibilidades pero ya tengo funcionando la lectura y escritura de
correos electrónicos a través de IMAP y SMTP.
</p>

<p>
El siguiente paso será poder acceder al correo cifrado, tanto de
lectura como envío. Aunque tengo que trastear también si se puede
compartir los directorios locales donde se almacenan los correos con
<i>Thunderbird</i> y <i>mew</i>. Si alguien sabe el cómo de estas cosas, que lo
ponga en los comentarios, con algún enlace donde se explique como «para
psicólogos».
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2018/11/08/correo-electronico-con-emacs.html</link>
  <pubDate>Thu, 08 Nov 2018 18:57:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Recomendaciones para hablar con menores cuando necesitan ayuda]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-11-05</div>
<p>
Hace un tiempo la APA (American Psychological Association) publicó una
<i>hoja de hechos</i> o pequeña guía para <a href="https://www.apa.org/helpcenter/help-kids.pdf">hablar con los menores cuando
tienen problemas</a>.
</p>

<p>
Son apenas unos puntos en los que tampoco profundizan demasiado pero
me ha parecido interesante traducir el documento y ponerlo aquí.
</p>
<div id="outline-container-org47627d8" class="outline-2">
<h2 id="org47627d8">Hablar con menores cuando necesitan ayuda</h2>
<div class="outline-text-2" id="text-org47627d8">
<p>
Como padre o profesor, eres la primera línea de apoyo para niños y
adolescentes.  Es importante tener abierta una línea de comunicación
con ellos y construir un sentimiento de confianza.  Cuándo tus niños y
adolescentes tienen dificultades, quieres que se sientan cómodos
recurriendo a ti para buscar ayuda.
</p>

<p>
Es muy importante la habilidad de identificar cuándo los menores están
luchando emocionalmente.  Los niños y adolescentes tienden a
interiorizar sus sentimientos.  Si algo les preocupa, no suelen
manifestarlo y pedir apoyo.  A veces no son conscientes de tener esa
ayuda disponible.  Así pues, es esencial para padres y profesores ser
capaces de detectar cuándo va mal algo y cómo acercarse a niños y
adolescentes.
</p>

<p>
Puedes percibir como un reto conseguir que tus hijos se abran y hablen
contigo.  Los siguientes consejos pueden ser útiles para empezar una
conversación y entender qué está ocurriendo en sus vidas.
</p>

<p>
<b>Hazle sentirse seguro</b>. Quieres facilitar que los menores se sientan
cómodos hablando contigo.  Es esencial dejar claro por qué estás
hablando con ellos.  Los niños especialmente temen tener problemas o
ser castigados si se ven forzados a hablar en privado.
Tranquilízalos, ese no es el caso; estás ahí ofreciendo apoyo.  Los
padres podrían considerar reservar un poco de tiempo para hablar cara
a cara regularmente, como almorzar con tu hijo semanalmente o cada dos
semanas.
</p>

<p>
<b>Escúchalos</b>. Tomate el tiempo de escuchar activamente por qué tu hijo
tiene un bajón de rendimiento escolar o habla de la muerte o lo que un
adolescente tiene que decir.  Muchas veces, todo lo que quieren los
niños o adolescentes es alguien que les escuche.  Intenta entender su
punto de vista antes de hacer sugerencias.  A veces tu propia ansiedad
te puede empujar a intentar arreglarlo todo.  Pero en muchos casos, la
mejor ayuda que puedes ofrecer es escuchar atentamente.
</p>

<p>
<b>Acepta y apoya su necesidad de ayuda</b>.  Si un niño o adolescente te
dice que está sintiendose triste o molesto, por ejemplo, diles que
estás orgulloso de que comparta sus sentimientos.  Hazles saber que
aprecias el esfuerzo que representa para ellos hablar contigo y
confiar en ti para buscar ayuda.  Si tu hijo parece necesitar más
ayuda de la que tú puedes proporcionar, consulta con un profesional
adecuado.  Puedes comenzar por hablar con el psicólogo del colegio.
</p>

<p>
<b>Sé auténtico</b>.  Intenta no hablar desde un guion.  Los adolescentes
saben cuándo no estás siendo genuino.  Si eres abierto, auténtico y
relajado, les ayudará a comportarse de la misma manera.
</p>

<p>
<b>No tengas miedo de decir «no lo sé»</b>.  Como padre o profesor, está
bien admitir que no tienes todas las respuestas.  Aun así, si un niño
o adolescente te pregunta algo, tendrías que hacer el esfuerzo de
encontrar una respuesta o alguien que pueda ayudar.
</p>

<p>
La Asociación Psicológica Americana agradece a Laurie D.  McCubbin,
PhD; Stephanie S. Smith, PsyD; Lynn Schiller, PhD; Andrew J. Adler,
EdD; y Diane C. Marti, PhD, por contribuir a esta <i>hoja de hechos</i>.
</p>
</div>
<div id="outline-container-orgb0bd679" class="outline-3">
<h3 id="orgb0bd679">Cuidado con las señales de suicidio</h3>
<div class="outline-text-3" id="text-orgb0bd679">
<p>
<i>El suicidio es evitable</i>.  Los dos pasos más importantes para impedir
el suicidio es reconocer las señales de aviso y conseguir ayuda.  Las
señales de advertencia pueden incluir un importante uso de drogas o
alcohol, haciéndose daño a ellos mismos.  Si crees vuestro niño o
estudiante está en peligro, llama al 112 inmediatamente y permanece
con él mientras la ayuda viene en camino.
</p>
</div>
</div>
<div id="outline-container-orgd4f03c6" class="outline-3">
<h3 id="orgd4f03c6">Fuente</h3>
<div class="outline-text-3" id="text-orgd4f03c6">
<p>
<a href="https://www.apa.org/helpcenter/help-kids.aspx">https://www.apa.org/helpcenter/help-kids.aspx</a>
</p>
</div>
</div>
</div>
<div id="outline-container-org6e92786" class="outline-2">
<h2 id="org6e92786">Conclusión</h2>
<div class="outline-text-2" id="text-org6e92786">
<p>
No soy traductor profesional, pero he hecho lo que he podido con
ello.  He intentado ser lo más fiel al original posible, pero algunas
frases y expresiones las he traducido más libremente porque en español
sonaban muy raros.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/psicología/index.html">psicología</a> <a href="/tags/ayuda/index.html">ayuda</a> <a href="/tags/menores/index.html">menores</a> ]]></description>
  <category><![CDATA[psicología]]></category>
  <category><![CDATA[ayuda]]></category>
  <category><![CDATA[menores]]></category>
  <link>https://notxor.nueva-actitud.org/2018/11/05/recomendaciones-para-hablar-con-menores-cuando-necesitan-ayuda.html</link>
  <pubDate>Mon, 05 Nov 2018 19:38:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Prueba generando librojuego desde org-mode]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-11-04</div>
<p>
Ayer estuve conversando sobre <i>aventuras conversacionales</i> y temas
similares y en un arrebato hice una especie de <i>librojuego</i> para la
<i>web</i> generando todo desde <code>org-mode</code>. Desde que lo hice, he
modificado algunas cosas en los ficheros para dejarlos algo más
organizados y resultones, como quitar la numeración de los títulos y
cambiar el diseño de la página.
</p>

<p>
Como se verá no tiene demasiada dificultad, pero con cuatro sencillos
ficheros se pueden crear tres hilos de narración con dos finales
distintos según el lector elija las opciones. Utilizar <code>org-mode</code> es
un atajo porque no hay que escribir las tediosas etiquetas <code>html</code> sino
que lo genera directamente la exportación.
</p>

<p>
<a href="../../../chaman/index.html">Podéis encontrar la obra en esta misma página</a> y leerla tranquilamente
explorando todas las opciones, que no son muchas. También están y se
pueden descargar los ficheros <code>org</code>, ofrecidos con
<a href="https://creativecommons.org/publicdomain/zero/1.0/deed.es_ES">licencia de Dominio público</a>.
</p>

<p>
A destacar algunos puntos en los que no voy a entrar demasiado, porque
se pueden estudiar los fuentes, que son muy sencillos:
</p>
<div id="outline-container-org6b2d7b4" class="outline-2">
<h2 id="org6b2d7b4">Cabeceras</h2>
<div class="outline-text-2" id="text-org6b2d7b4">
<p>
Los ficheros fuente presentan la siguiente cabecera:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">#+TITLE: Chamán
#+HTML_HEAD: &lt;link rel="stylesheet" type="text/css" href="./css/org.css"/&gt;
#+OPTIONS: toc:nil num:nil

# Esta obra se ofrece como de dominio público: Puede copiar, modificar,
# distribuir la obra y hacer comunicación pública, incluso para fines
# comerciales, sin pedir permiso.
#
# Puede consultar más detalles en
# https://creativecommons.org/publicdomain/zero/1.0/deed.es_ES
</pre>
</div>

<p>
Hay dos bloques, de los cuales el segundo es sólo un comentario que
hace referencia a la licencia: en este caso <i>dominio público</i>. Más
interesante es el primer bloque, donde se establece un título:
<i>Chamán</i>. Se le dice al exportador que utilice un determinado fichero
<code>css</code> para dar color y forma a lo exportado y que elimine la tabla de
contenidos (<code>toc:nil</code>) y la numeración en las cabeceras (<code>num:nil</code>).
</p>
</div>
</div>
<div id="outline-container-org5f5c37c" class="outline-2">
<h2 id="org5f5c37c">Enlaces</h2>
<div class="outline-text-2" id="text-org5f5c37c">
<p>
Otro aspecto interesante que explicar son los enlaces entre ficheros.
Siempre es recomendable leerse el apartado de <i>hyperlinks</i> de la
documentación de <code>org-mode</code>, pero básicamente lo que se ha hecho es
marcar los enlaces a los ficheros <code>org</code>:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">... [[file:./tienda.org][entrar en la tienda]] ...
</pre>
</div>

<p>
En el enlace se especifica el acceso <code>file:</code> indicando que se dirige a
un fichero externo pero un <code>org</code>. Cuando se exporte a <code>html</code> ese
código se traducirá a:
</p>

<div class="org-src-container">
<pre class="src src-html">&lt;<span style="color: #50fa7b; font-weight: bold;">a</span> <span style="color: #f8f8f2; font-weight: bold;">href</span>=<span style="color: #f1fa8c;">"./tienda.html"</span>&gt;entrar en la tienda&lt;/<span style="color: #50fa7b; font-weight: bold;">a</span>&gt;
</pre>
</div>
</div>
</div>
<div id="outline-container-org2862ce6" class="outline-2">
<h2 id="org2862ce6">Fuentes</h2>
<div class="outline-text-2" id="text-org2862ce6">
<ol class="org-ol">
<li><a href="./chaman/index.org">index.org</a></li>
<li><a href="./chaman/milano.org">milano.org</a></li>
<li><a href="./chaman/tienda.org">tienda.org</a></li>
<li><a href="./chaman/madre.org">madre.org</a></li>
</ol>

<p>
El fichero <code>org.css</code> lo encontré por algún sitio hace un tiempo y no
recuerdo exactamente dónde, por eso no pongo enlace al original. Lo he
modificado un poco para este proyecto y también se pude acceder para
consultarlo.
</p>

<ol class="org-ol">
<li><a href="./chaman/css/org.css">org.css</a></li>
</ol>
</div>
</div>
<div id="outline-container-orga1df707" class="outline-2">
<h2 id="orga1df707">Conclusiones</h2>
<div class="outline-text-2" id="text-orga1df707">
<p>
El <code>org-mode</code> es un medio potente y ágil de generar cualquier tipo de
documentación, lúdica o formal. Sus herramientas de exportación
producen de forma flexible los documentos sin necesidad de modificar
complejos ficheros repletos de etiquetas que rompen la lectura
directa.
</p>

<p>
El ejemplo mostrado se escribió en apenas 20 minutos y deja bastante
que desear en cuanto a historia e interacción para ser un
<i>librojuego</i>. Pero su objeto no es en sí la lectura interactiva sino
mostrar que con las herramientas más sencillas se puede conseguir algo
decente. Para cosas más complejas se debería utilizar <code>javascript</code>
para poder guardar <i>partidas</i> o <i>puntos</i> o <i>logros</i> o un largo
etcétera de características que mejorarían la experiencia, como una
<i>hoja de personaje</i>, por ejemplo.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> <a href="/tags/conversacionales/index.html">conversacionales</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <category><![CDATA[conversacionales]]></category>
  <link>https://notxor.nueva-actitud.org/2018/11/04/prueba-generando-librojuego-desde-org-mode.html</link>
  <pubDate>Sun, 04 Nov 2018 23:57:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Ledger-cli y el ledger-mode de Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-10-30</div>
<p>
<a href="https://notxor.nueva-actitud.org/blog-antiguo/contabilidad-friki.html">Hace un tiempo ya hablé de <code>ledger-cli</code>, una herramienta de gestión contable</a> que funciona desde la línea de comandos y consiste
básicamente en guardar la información en texto plano en un fichero
<i>ledger</i>. <i>Ledger</i> se traduciría al «español contable» como <i>libro
diario</i>, <i>diario</i> o <i>mayor</i>. Por lo tanto, todo el trabajo consiste
básicamente en introducir los datos de forma ordenada con cualquier
editor y luego extraerlos con <code>ledger-cli</code> de forma ordenada.
</p>

<p>
No quiero que este artículo sea específicamente <i>contable</i>. Mi idea es
mostrar cómo voy haciendo para llevar un poco de control en mis
cuentas con herramientas potentes pero que se manejan perfectamente en
texto plano. ¿Por qué texto plano y contabilidad? Pues básicamente
porque eso me permite acceder a mis datos siempre, desde cualquier
dispositivo con cualquier editor que sea capaz de cargar texto.
Además, el ejecutable <code>ledger</code> también lo puedes instalar en el
<code>termux</code> de android® y sincronizar tu libro diario con cualquier
herramienta que se te ocurra (yo lo hago con <code>git</code>, porque me permite
controlar cuándo se hacen qué cambios y revertirlos si es necesario).
</p>

<p>
<a href="./prueba-ledger.ledger">El fichero que se ha generando al escribir este artículo también se
puede descargar del blog</a>.
</p>

<p>
<i>Emacs</i> se ha convertido en mi editor favorito para todo y por tanto
lo utilizo también para realizar mis apuntes contables. Además, tiene
un <i>modo</i> que me facilita la vida. Lo primero será tener instalado en
nuestro sistema la herramienta <code>ledger-cli</code>. Como eso depende
básicamente de cada sistema operativo digo sólo las dos que yo he
utilizado en mi OpenSuse y en el <code>termux</code> de android®:
</p>

<div class="org-src-container">
<pre class="src src-shell">sudo zypper install ledger
</pre>
</div>

<p>
o en <code>termux</code>
</p>

<div class="org-src-container">
<pre class="src src-shell">apt install ledger
</pre>
</div>

<p>
Después lo que necesitamos es instalar el <i>modo</i> de <i>emacs</i> que nos
facilitará la vida:
</p>

<p>
<code>M-x package-install RET ledger-mode RET</code>
</p>

<p>
Y con esto ya tenemos todas las herramientas para comenzar a llevar
nuestra contabilidad.
</p>
<div id="outline-container-org65f5cfc" class="outline-2">
<h2 id="org65f5cfc">Crear nuestro <i>libro mayor</i></h2>
<div class="outline-text-2" id="text-org65f5cfc">
<p>
Hay una serie de pasos que dar, aunque muy sencillos. Lo primer será
crear un fichero de texto plano. Si en el nombre añadimos la extensión
<code>.ledger</code>, <i>emacs</i> activará el modo mayor automáticamente. Sin
embargo, es posible hacer lo mismo sin necesidad de poner esa
extensión añadiendo como primera línea del fichero la siguiente:
</p>

<pre class="example" id="orgfc57790">
; -*- Ledger -*-
</pre>

<p>
Y ya está. Ya tienes tu fichero dispuesto a recoger todos los datos
que podamos meter. Pero para que las cosas funcionen mejor podemos
ajustar aún más las entradas.
</p>
</div>
<div id="outline-container-org8197b35" class="outline-3">
<h3 id="org8197b35">Ajuste de moneda</h3>
<div class="outline-text-3" id="text-org8197b35">
<p>
<code>ledger-cli</code> soporta cualquier tipo de moneda, porque no tiene
predefinida ninguna y por tanto es bueno configurar las monedas en las
que trabajaremos. Lo digo en plural, porque podemos trabajar en varias
a la vez en el mismo libro y llevar también un registros de valores de
cambio y muchas otras cosas que exceden un artículo como éste. Para
resumir comento el código que utilizo yo para trabajar (sólo en
euros).
</p>

<pre class="example" id="org3490c43">
commodity €
    note Euros
    format 1.000,00€
    default
</pre>

<p>
La divisa (<i>commodity</i>) es el símbolo € como dice la primera linea. No
tiene más misterio: cualquier cifra que lleve un símbolo € se
considerará una cantidad en esa divisa. La línea <code>note</code> la podemos
ahorrar, es sólo un comentario que nos ayuda a saber qué tipo de
divisa utilizamos. Con una moneda y su símbolo no tiene mucho sentido,
pero es que podemos contabilizar con «latas de cerveza» y al definir su
<code>commodity</code> necesitaremos más explicaciones de lo que significa y por
qué lo utilizamos. La opción <code>format</code> establece con esa sintaxis tan
simple que el separador de miles es el «.» y el de decimales la «,» y
además que el símbolo lo colocaremos detrás. <code>default</code> le dice a
<code>ledger</code> que si hay una cifra en algún sitio que no lleva el símbolo
monetario, por defecto tomará esa como su <code>commodity</code>.
</p>
</div>
</div>
<div id="outline-container-orgcc31f39" class="outline-3">
<h3 id="orgcc31f39">Definición de cuentas</h3>
<div class="outline-text-3" id="text-orgcc31f39">
<p>
Cuando definimos las cuentas tenemos a nuestro alcance muchas
opciones, como definir qué tipo de moneda utilizaremos en esa cuenta.
En mi caso, como sólo me manejo en euros no tiene mucho sentido todas
esas opciones y lo más complicado que utilizo son algunos <code>alias</code> y
algunas <code>note</code>. Pero lo más importante, es tenerlas ordenadas en los
grupos principales contables y los nombres aquí, como todo en <code>ledger</code>
son arbitrarios: lo que quiere decir que puedes utilizar los que
quieras, pero para tener una contabilidad ajustada debes ser
consistente con el nombre elegido.
</p>

<p>
Concretamente tengo las cuentas agrupadas en <code>Activo</code>, <code>Pasivo</code>,
<code>Ingresos</code>, <code>Gastos</code> y <code>Patrimonio</code>.
</p>

<p>
Voy a poner un ejemplo de cuenta para que se vea cómo las tengo
configuradas.
</p>

<pre class="example" id="orgc52e32a">
account Gastos:Otros Gastos:Metálico
    note Cuenta para anotar los gastos en metálico sin justificar
    alias Menudencias
</pre>

<p>
Definir una cuenta es importante porque luego podemos exigir a
<code>ledger</code> que sólo admita al extraer los datos las cuentas que tenemos
en la cabecera. Eso hace que nos obliguemos a ser consistentes, que
los errores tipográficos aparezcan a la primera de cambio y que los
resúmenes de gastos o cualquier otro listado no sean infinitos con
multitud de cuentas similares con leves matices.
</p>

<p>
Para aquellos que quieran ajustarse al Plan General Contable, nada nos
impide nombrar una cuenta con números. Por ejemplo:
</p>

<pre class="example" id="org1127899">
account 5.Cuentas financieras
    note Grupo 5 del Plan General Contable

account 5.Cuentas financieras:521.Deudas a corto plazo
    note Cuentas para las deudas a corto plazo del Grupo 5 del PGC
</pre>

<p>
Pero eso es más técnico contable y no vamos a entrar en ello. Basta
con saberlo, por si queremos utilizar <code>ledger</code> para asuntos más serios
que llevar un poco de control sobre gastos que es para lo que lo
utilizo yo.
</p>
</div>
</div>
<div id="outline-container-org470d261" class="outline-3">
<h3 id="org470d261">Balance de apertura</h3>
<div class="outline-text-3" id="text-org470d261">
<p>
¿Cómo iniciamos nuestro registro contable? Pues por el principio,
obviamente. Pero si no lo hemos hecho desde el inicio de los tiempos,
o por lo menos desde que tenemos uso de razón, lo más probable es que
tengamos que iniciar la contabilidad no desde cero, sino de la
situación donde nos encontremos. Por ejemplo, podríamos suponer una
situación como la siguiente:
</p>

<pre class="example" id="org4966475">
2018/10/30 Balance de apertura
    Activo:Bancos:Ladrones y cia               6,54€
    Activo:Bancos:El saqueador y cia         -25,84€
    Activo:Inmuebles:Casa                  2.160,04€
    Activo:Metálico                            0,47€
    Activo:Plan de Pensiones                  82,65€
    Pasivo:Hipoteca                       -1.372,23€
    Patrimonio:Balance Apertura
</pre>

<p>
Lo que nos lleva a tener ya un asiento en nuestro <i>diario</i>, sin
embargo, aún no he explicado cómo se hace eso de los <i>asientos</i> que no
son para sentarse.
</p>
</div>
</div>
<div id="outline-container-orge729554" class="outline-3">
<h3 id="orge729554">Anotar un asiento</h3>
<div class="outline-text-3" id="text-orge729554">
<p>
Lo primero es saber qué es un <i>asiento</i>. Pues básicamente es la
anotación de una transacción. Seguro que en cualquier manual de
contabilidad se pueden encontrar mejores definiciones de las que yo
puedo dar. Pero lo que necesitamos para definir esa transacción son
básicamente: fecha, descripción, cuenta de entrada y cuenta de
salida.
</p>

<p>
Vamos a suponer que comprado un poco de fruta y lo quiero anotar en mi
diario y que me ha costado 1,27€. El comando para anotar es
<code>ledger-add-transaction</code> y la podemos llamar con <code>M-x</code> de la línea de
comandos de <i>emacs</i>, el atajo de teclado es <code>C-c C-a</code>. <i>Emacs</i>
preguntará por una fecha, si no hemos introducido antes más
transacciones nos sugerirá la fecha actual, pero si hemos metido más,
nos sugerirá la última fecha introducida. También se pude ir al final
del fichero y hacerlo a mano, escribiendo todo el texto a falta del
automatismo, pero mejor dejar que <i>emacs</i> busque el sitio
correspondiente a esa fecha para mantener ordenado el diario por
fechas.
</p>

<pre class="example" id="org482baff">
2018/10/30 Compra en la frutería
    ; Me he comprado un poco de fruta para variar
    Gastos:Alimentación                         1,27€
    Activo:Metálico                            -1,27€
</pre>

<p>
En un fichero <code>ledger-cli</code> se comienza un asiento en una nueva línea
comenzando por la fecha y una descripción de la transacción. Como se
ve la fecha está ajustada en la izquierda y luego vienen tres líneas
indentadas. La primera es un comentario porque su primer símbolo es
<code>;</code>. La siguiente línea anota 1,27€ a la cuenta de
<code>Gastos:Alimentación</code>. Por tanto, la siguiente anotará -1,27€ en la
cuenta de <code>Activo:Metálico</code>. <code>Ledger</code> también permite que la última
línea aparezca sin valor, lo que hará es calcular el valor de la
transacción y lo anotará balanceado en la última cuenta. Como vemos en
el <code>balance de apertura</code> lo que ocurrirá es que el sistema anotará en
<code>Patrimonio:Balance Apertura</code> el valor de -851,63€.
</p>

<p>
Mi recomendación es escribir y cuadrar el asiento manualmente para
evitar errores. Porque, como se puede ver, el valor final de un
asiento siempre es 0. Una transacción se llama transacción porque el
dinero que entra por un lado sale por el otro. O dicho de otro modo,
viendo el ejemplo, se han ido a <code>Gastos:Alimentación</code> 1,27€ que han
salido como -1,27€ de <code>Activo:Metálico</code>.
</p>

<p>
He anotado la compra en una cuenta genérica de <i>alimentación</i>, si
quiero ser más fino en las anotaciones, para saber cuánto gasto en
cada tienda o con cada proveedor de servicios o con lo que sea, podría
haber hecho una cuenta <code>Gastos:Alimentación:Frutería</code> y así en los
informes de gastos que puedo generar me aparecerá el desglose con más
detalles.
</p>
</div>
</div>
<div id="outline-container-org3dc297e" class="outline-3">
<h3 id="org3dc297e">Anotaciones múltiples, diferidas y virtuales</h3>
<div class="outline-text-3" id="text-org3dc297e">
<p>
Una anotación múltiple es similar a la que ya hemos visto en el
<i>balance de apertura</i>. Se hacen anotaciones en diversas cuentas, unas
suman otras restan, pero al final todo debe sumar 0 (eso sí es
importante, hay que grabárselo a fuego en la memoria).
</p>

<p>
Pero puede ser que tengamos que hacer alguna anotación múltiple
distinta, por ejemplo, cuando pagamos un bien con dinero de dos
cuentas distintas, pero también puede ser una transacción con la misma
cuenta. Imaginemos por ejemplo que jugamos a la lotería, bonoloto,
primitiva o lo que sea, todas las semanas y un día nos pagan un premio
de 30,00€. Podríamos hacer un asiento como el siguiente:
</p>

<pre class="example" id="orge0ba7a9">
2018/10/31 Lotería
    Gastos:Lotería                             14,00€
    Gastos:Lotería                            -30,00€
    Activo:Metálico                            16,00€
</pre>

<p>
Hay que hacer notar que los ingresos se anotan con un menos delante.
Eso es porque se <i>detraen</i> de otra cuenta. Para no liarme pienso en
esas cuentas como cuentas <i>externas</i>, aparecen en mi libro pero son de
otra persona o ente. En este caso <code>Gastos:Lotería</code> es una cuenta la
empresa pública <i>Loterías y Apuestas del Estado</i>, a la que yo le
<i>sumo</i> activos cuando compro lotería y le resto activos cuando <i>me
pagan</i> premios. Como estoy <i>quitando activos</i>, el premio, la cantidad
la anoto en negativo. El caso es que al final en mi bolsillo han
aparecido 16,00€; mi bolsillo se llama <code>Activo:Metálico</code> (por si había
alguna duda). En el ejemplo, utilizo dos veces la misma cuenta para
mostrar que aunque después de echar la lotería yo sólo veré 16€, en
realidad la transacción ha sido más compleja: me tenías que pagar 30€
pero se han cobrado de ahí la lotería que he comprado.
</p>

<p>
En otras ocasiones no pagamos en el acto. Las tarjetas de crédito es
lo que tienen, que las compras las realizamos hoy pero lo anotan en tu
cuenta dentro de unos días (aunque sean de débito). Si eres ordenado
con la contabilidad cuando haces un gasto, lo anotas en el diario. El
problema es que luego vas a ajustar tus cuentas, consultas con el
banco y como aún no han anotado esa compra que hiciste con tarjeta,
las cuentas no te cuadran. Para eso se puede hacer una anotación que
yo llamo <i>diferida</i>. Se hace la anotación pero se le advierte al
programa que está pendiente de realizar. Vamos a poner un ejemplo: voy
al supermercado y hago la compra semanal y como me ha subido mucho
decido utilizar mi tarjeta de crédito porque no llevo efectivo
suficiente, haré una anotación como la siguiente:
</p>

<pre class="example" id="org09aeb69">
2018/10/31 * Compra semanal
    Gastos:Alimentación:Mencabrona             85,49€
    Activo:Bancos:Ladrones y cia              -85,49€
</pre>

<p>
Nótese el <code>*</code> entre la fecha y la descripción. Además observaremos
también que <i>emacs</i> ha cambiado los colores de esa entrada y la hace
distinta para destacarla de las otras. Cuando hablemos de <i>generar
informes</i> y hacer listados de las cuentas, veremos que podemos pedirle
a <code>ledger-cli</code> que contabilice esas entradas o no y cómo podemos hacer
para encontrarlas rápido y quitarles el <code>*</code> cuando ya son anotaciones
efectivas. Hay mucho más juego con este tipo de anotaciones (pero yo
aún no he necesitado de ello), siempre es bueno echarle un ojo a la
documentación de <code>ledger-cli</code> para saber la cantidad de cosas que se
pueden hacer.
</p>

<p>
También es posible que necesitemos utilizar alguna cuenta <i>virtual</i>.
Voy a poner un ejemplo chorra: Contabilizo una hipoteca que tengo
contratada y voy pagando mes a mes. Parte de lo que pago va a
amortizar el préstamo hipotecario que lo tengo anotado en la cuenta
<code>Pasivo:Hipoteca</code> y otra parte a pagar los intereses al banco. El caso
es que al final, de mi cuenta bancaria desaparece la cantidad de
259,50€. Sin embargo, cuando hago una relación de gastos, el sistema
sólo me contabilizará los <code>Gastos:Intereses Hipoteca</code>... Lo otro <i>no
es un gasto, es una inversión</i>, me diría el director de la sucursal y
yo le creí.
</p>

<pre class="example" id="org365da62">
2018/10/31 Pago de hipoteca
    Pasivo:Hipoteca                           235,47€
    Gastos:Intereses Hipoteca                  24,03€
    Activo:Bancos:El saqueador y cia         -259,50€
</pre>

<p>
¿Cómo hago para que cuando saque mi relación de gastos mensuales me
contabilice lo que amortizo? Porque a final de mes sí lo tengo
descontado de mis ingresos y tengo que contar con ello. Una solución
posible es anotarlo <i>virtualmente</i>. Podemos abrir una cuenta
<code>Gastos:Hipoteca amortizado</code>, por ejemplo y decirle al programa que lo
tenga en cuenta, pero sólo como un recordatorio para mí. La anotación
quedaría como sigue:
</p>

<pre class="example" id="orga36ebef">
2018/10/31 Pago de hipoteca
    Pasivo:Hipoteca                           235,47€
    Gastos:Intereses Hipoteca                  24,03€
    Activo:Bancos:El saqueador y cia         -259,50€
    (Gastos:Hipoteca amortizado)              235,47€
</pre>

<p>
En este caso vemos que todas las anotaciones no suman 0, pero es que
la última no es una anotación real. Al poner la cuenta entre
paréntesis le estamos diciendo al programa que es una cuenta <i>virtual</i>
que la utilizaremos para realizar cálculos de forma sencilla, pero que
en realidad no hay transacción. Podríamos incluso tener varias cuentas
virtuales, en el caso, por ejemplo, de que la hipoteca está a nombre
de dos personas y cada una paga su parte.
</p>

<p>
Como vemos el sistema de anotación es muy flexible y permite hacer
muchas cosas. Cosas financiaras y complicadas que si queréis avanzar
en ellas tendréis que leer en la documentación de <code>ledger-cli</code>. Para
llevar mi control <i>diario</i> sobre mis gastos, con lo que he contado
será suficiente.
</p>
</div>
</div>
<div id="outline-container-org1b5e7bf" class="outline-3">
<h3 id="org1b5e7bf">Autocompletado</h3>
<div class="outline-text-3" id="text-org1b5e7bf">
<p>
La tarea de hacer las anotaciones puede ser ardua y proclive a fallos
si tengo que escribirlo todo. Sin embargo, el <code>ledger-mode</code> me
proporciona una herramienta imprescindible: el <i>autocompletado</i>.
</p>

<p>
Se basa en que muchas transacciones son repetidas la mayor parte de
las veces. Por ejemplo, si voy al supermercado a hacer la compra
semanal tendré que hacer una anotación cada semana. Con un ejemplo lo
veremos más claro.
</p>

<ol class="org-ol">
<li>Inicio una transacción con <code>C-c C-a</code> aceptando la fecha corregida o
escribiendo la correspondiente.</li>
<li>A continuación de la fecha escribo <code>Comp</code> y pulso <code>&lt;TAB&gt;</code>.
<i>Automágicamente</i> <code>ledger-mode</code> completa a «Compra en la frutería»,
pero como eso no es lo que quiero vuelvo a pulsar <code>&lt;TAB&gt;</code> y ahora
sí aparece el buscado «Compra semanal».</li>
<li>Ahora necesito que me escriba las cuentas correspondientes: <code>C-c
   TAB</code> y tengo copiada la última transacción.</li>
<li>Modifico los valores y ya tengo la anotación hecha</li>
</ol>

<p>
Hay veces que la transacción es nueva y no hay ningún asiento que
copiar. En esos casos <code>ledger-mode</code> también facilita la anotación
sugiriendo las cuentas. Por ejemplo, hemos comprado algo que no es una
compra periódica y queremos anotarlo. Vamos a probar anotando que
hemos comprado unas castañas en el puesto de la esquina, pero nos da
igual el detalle, lo vamos a anotar a nuestra cuenta de gastos en
metálico sin justificar, porque es una menudencia.
</p>

<ol class="org-ol">
<li>Inicio de la transacción con <code>C-c C-a</code> y completamos la fecha.</li>
<li>Escribimos "Compra de castañas asadas" y <code>&lt;RET&gt;</code></li>
<li>Pulsamos <code>&lt;TAB&gt;</code> para indentar, pulsamos <code>G &lt;TAB&gt;</code> y el
<code>ledger-mode</code> lo completará a <code>Gastos:</code>.</li>
<li>Si no tenemos claro a qué subcuenta de <code>Gastos</code> vamos a anotarlo
podemos ir dando a <code>&lt;TAB&gt;</code> para que vaya sugiriendo una tras otra.</li>
<li>Como nosotros tenemos claro que la subcuenta será <code>Otros Gastos</code>,
pulsamos <code>O &lt;TAB&gt;</code> y <code>ledger-cli</code> completará a <code>Gastos:Otros
   Gastos:</code> y si volvemos darle <code>&lt;TAB&gt;</code> añadirá el <code>Metálico</code> (porque
no hay otras subcuentas de la subcuenta, si no hará un recorrido
por ellas).</li>
</ol>

<p>
El procedimiento contado así parece engorroso pero a la segunda vez
que lo utilizas todo ya sabes cómo funciona, porque es muy intuitivo.
Es una forma de aligerar el trabajo cuando hay muchas anotaciones que
realizar.
</p>
</div>
</div>
<div id="outline-container-orgfac99d1" class="outline-3">
<h3 id="orgfac99d1">Generar informes</h3>
<div class="outline-text-3" id="text-orgfac99d1">
<p>
Hasta ahora hemos visto cómo introducir los datos en nuestro libro
diario, ahora toca sacar de él información. Como antes comenzamos por
las cuentas, vamos a hacer lo mismo. Hemos ido haciendo apuntes y
anotando a cuentas que en realidad no hemos definido en la cabecera.
¿Cómo sabemos cuántas hay, cuántas he necesitado para la contabilidad
hasta ahora? Muy fácil, se lo preguntaré a <code>ledger-cli</code> desde la linea
de comandos:
</p>

<div class="org-src-container">
<pre class="src src-shell">ledger -f prueba-ledger.ledger accounts
</pre>
</div>

<p>
Llamo al ejecutable <code>ledger</code> diciéndole que utilice el fichero de
entrada <code>-f prueba-ledger.ledger</code> y que me liste las cuentas
<code>accounts</code>.
</p>

<p>
El resultado será:
</p>

<pre class="example" id="orgd0bdfaa">
Activo:Bancos:El saqueador y cia
Activo:Bancos:Ladrones y cia
Activo:Inmuebles:Casa
Activo:Metálico
Activo:Plan de Pensiones
Gastos:Alimentación
Gastos:Alimentación:Mencabrona
Gastos:Hipoteca amortizado
Gastos:Intereses Hipoteca
Gastos:Lotería
Gastos:Otros Gastos:Metálico
Pasivo:Hipoteca
Patrimonio:Balance Apertura
</pre>

<p>
Podemos utilizar este listado para generar nuestra lista de cuentas
(si no las hemos ido definiendo cuando comenzamos la contabilidad).
Como ya he dicho, una opción para encontrar errores de tecleo es
utilizar la opción <code>--strict</code> cuando hagamos consultas de nuestras
cuentas, eso hará que sólo se tengan en cuenta las anotaciones a
cuentas definidas en la cabecera y que lance un error en las demás
transacciones. Si no fuera un error, que hubiéramos decidido anotar en
una nueva cuenta y se nos ha olvidado definirla, es el recordatorio
perfecto para hacerlo.
</p>

<p>
El sistema de informes de <code>ledger-cli</code> es muy completo y extenso.
Puede hacer también cálculos financieros, estudios de gastos, por
meses, anuales, y un largo etcétera que se nos iría del objetivo de
este <i>minitutorial</i>. Si alguien tiene curiosidad o necesidad de este
tipo de cosas, la documentación de <code>ledger-cli</code> es muy completa y
exhaustiva con ejemplos que ayudan a clarificar todas las cosas que
puede hacer.
</p>

<p>
En mi caso tengo una serie de informes que me utilizo habitualmente,
así que me he creado un archivo <code>informes.el</code> que puedo cargar cuando
lo necesito. El contenido es el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Listados para ledger-mode
</span>(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">ledger-mode</span>)

(<span style="color: #ff79c6; font-weight: bold;">setq</span> ledger-reports
       (<span style="color: #ff79c6; font-weight: bold;">quote</span>
        ((#(<span style="color: #f1fa8c;">"asiento apertura"</span> 0 1
          (idx 0))
          <span style="color: #f1fa8c;">"%(binary) -f %(ledger-file) equity --real --strict Activo Pasivo"</span>)
         (#(<span style="color: #f1fa8c;">"balance"</span> 0 1
            (idx 1))
          <span style="color: #f1fa8c;">"%(binary) -f %(ledger-file) bal --strict --real -y %Y/%m/%d"</span>)
         (#(<span style="color: #f1fa8c;">"registro"</span> 0 1
            (idx 2))
          <span style="color: #f1fa8c;">"%(binary) -f %(ledger-file) reg --strict --real -y %Y/%m/%d"</span>)
         (#(<span style="color: #f1fa8c;">"cuenta"</span> 0 1
            (idx 3))
          <span style="color: #f1fa8c;">"%(binary) -f %(ledger-file) reg %(account) --real -y %Y/%m/%d"</span>)
         (#(<span style="color: #f1fa8c;">"por meses"</span> 0 1
            (idx 4))
          <span style="color: #f1fa8c;">"%(binary) -f %(ledger-file) reg %(account) -M --real -y %Y/%m/%d"</span>)
         (#(<span style="color: #f1fa8c;">"resumen"</span> 0 1
            (idx 5))
          <span style="color: #f1fa8c;">"%(binary) -f %(ledger-file) bal Gastos Ingresos --collapse-if-zero -y %Y/%m/%d"</span>)
         (#(<span style="color: #f1fa8c;">"cierre"</span> 0 1
            (idx 6))
          <span style="color: #f1fa8c;">"%(binary) -f %(ledger-file) bal --real --strict --format \"    %-40(account) %10(market(display_total) * -1)\n%/\" --no-total --flat"</span>)
         (#(<span style="color: #f1fa8c;">"comparado"</span> 0 1
            (idx 7))
          <span style="color: #f1fa8c;">"%(binary) -f %(ledger-file) --real --strict cleared"</span>)
         (#(<span style="color: #f1fa8c;">"estudio de gastos"</span> 0 1
            (idx 8))
          <span style="color: #f1fa8c;">"%(binary) bal -f %(ledger-file) Gastos --current --format \"%-35((depth_spacer)+(partial_account)) %10(percent(market(display_total), market(parent.total))) %16(market(display_total))\n%/\""</span>))))
</pre>
</div>

<p>
Lo tengo en un fichero diferente y en código <code>elisp</code> para facilitar su
carga cuando es necesario. Se puede tener en el fichero <code>init.el</code>,
pero los informes suelen ser algo puntual, no necesito tener ese
código cargado cada vez que inicio <i>emacs</i>, ni siquiera cuando estoy
en <code>ledger-mode</code>, porque la mayor parte de las veces sólo se
introducen datos. Necesitaré ver los informes, sólo cuando debo
compara cuentas con las anotadas en el banco, por ejemplo. O cuando
necesito saber en qué se ha gastado el dinero. Tan sólo hay que cargar
el código con <code>M-x load-file</code>.
</p>

<p>
No voy a explicar todos los aspectos de los informes, porque cada uno
tiene sus manías y le gusta ver la información de una forma distinta y
hay tantas que son motivo de un capítulo completo en la documentación
de <code>ledger-cli</code>. Sólo destacaré algunos aspectos muy concretos y
útiles.  Por ejemplo, una opción que se repite bastante en los
informes es el formato de fecha <code>-y %Y/%m/%d</code> para ver las fechas en
el formato ISO.  Otra opción que se repite bastante es <code>--real</code> que le
dice al sistema que tenga en cuenta sólo las transacciones reales y
deje a un lado las virtuales, como vimos antes en la entrada que
marcábamos como <code>(Gastos:Hipoteca amortizado)</code>. La que más se repite
es, sin duda, la opción <code>--strict</code> para que sólo haga listado con
cuentas definidas.
</p>

<p>
Para comprobarlo vamos a hacer un <code>balance</code> habiendo introducido un
error en una cuenta a propósito como sigue a continuación:
</p>

<pre class="example" id="org86d6fe8">
2018/10/31 Compra de chuches
    Gastos:Otros Gastos:Metálco                 2,30€
    Activo:Metálico
</pre>

<p>
Si ahora lanzamos una consulta de <code>balance</code> que tenemos en ese
fichero, el resultado será el siguiente:
</p>

<pre class="example" id="orgf59c419">
Report: balance
Command: ledger -f /home/notxor/Sync/prueba-ledger.ledger bal --strict --real -y %Y/%m/%d
===================================================================================================================

Warning: "/home/notxor/Sync/prueba-ledger.ledger", line 61: Unknown account 'Gastos:Otros Gastos:Metálco'
           1.890,05€  Activo
            -364,29€    Bancos
            -285,34€      El saqueador y cia
             -78,95€      Ladrones y cia
           2.160,04€    Inmuebles:Casa
              11,65€    Metálico
              82,65€    Plan de Pensiones
              98,34€  Gastos
              86,76€    Alimentación
              85,49€      Mencabrona
              24,03€    Intereses Hipoteca
             -16,00€    Lotería
               3,55€    Otros Gastos
               2,30€      Metálco
               1,25€      Metálico
          -1.136,76€  Pasivo:Hipoteca
            -851,63€  Patrimonio:Balance Apertura
--------------------
                   0
</pre>

<p>
Como vemos, lo hace, sin embargo nos aparece una línea de <code>Warning</code>
que nos dice el fichero y la línea donde ha encontrado una cuenta
desconocida.
</p>

<p>
Uno de los informes que más se utiliza es el que muestra un listado de
una cuenta en concreto, por ejemplo, para cuadrar el valor que nos
dice el banco que tenemos en la cuenta, con el valor que tenemos
anotado, que como ya dije antes, no tiene por qué coincidir. Vamos a
hacer un ejemplo:
</p>

<ol class="org-ol">
<li>Lanzamos un informe con <code>C-c C-o C-r</code> seleccionamos <code>cuenta</code>.</li>
<li>Decimos qué cuenta queremos, en nuestro caso:
<code>Activo:Bancos:Ladrones y cia</code>. Además si estamos en el <i>buffer</i> de
<code>ledger</code> situados en una línea con una cuenta determinada,
<code>ledger-mode</code> nos sugerirá esa cuenta como primera opción.  El
resultado nos aparece en un <i>buffer</i> de informe:</li>
</ol>

<pre class="example" id="orga259c2a">
Report: cuenta
Command: ledger -f /home/notxor/Sync/prueba-ledger.ledger reg Activo\:Bancos\:Ladrones\ y\ cia --real -y %Y/%m/%d
==================================================================================================================

2018/10/30 Balance de apertura           Activo:Bancos:Ladrones y cia                   6,54€             6,54€
2018/10/31 Compra semanal                Activo:Bancos:Ladrones y cia                 -85,49€           -78,95€
</pre>

<p>
Como vemos, sólo hay dos registros y sabemos que tenemos un
descubierto de -78,95€ aunque el banco nos dice que tenemos 6,54€ en
ella. ¿Dónde está el descuadre? Si recordamos, habíamos anotado la
<i>Compra semanal</i> como pendiente de anotar, que es lo que ha sucedido
ahora. Para comprobar que es así:
</p>

<ol class="org-ol">
<li>Situados en el <i>buffer</i> <code>*Ledger Report*</code> y pulsamos <code>e</code>.</li>
<li>Modificamos el comando de informe añadiendo la opción <code>-U</code> y
<code>&lt;RET&gt;</code>. Eso ocultará las transacciones pendientes de anotar.</li>
</ol>

<p>
Si no coincide volvemos a editar la consulta para que aparezcan y
punteamos con la cuenta a ver qué transacciones se han anotado
ya. Situados en el <i>buffer</i> de informe, pulsando <code>&lt;RET&gt;</code> en una de las
líneas del informe, <code>ledger-mode</code> nos llevará al asiento
correspondiente. Por lo que buscar una transacción es más sencillo de
lo que parece cuando tenemos un fichero conteniendo la contabilidad de
varios años, si podemos acotar por fechas: por ejemplo, para que sólo
salgan las transacciones del mes de enero de este año se pueden
utilizar las opciones <code>-b 2018/01/01</code> y <code>-e 2018/01/31</code>. Como es
lógico <code>-b</code> para el inicio (<i>begin</i>) y <code>-e</code> para el final (<i>end</i>) del
periodo.
</p>
</div>
</div>
<div id="outline-container-orge8b9eb7" class="outline-3">
<h3 id="orge8b9eb7">Cierre contable</h3>
<div class="outline-text-3" id="text-orge8b9eb7">
<p>
Con periodicidad anual, generalmente, se hace un <i>cierre contable</i>
para observar cómo van las cosas. Bueno, realmente se puede hacer cada
vez que uno necesite echar un vistazo al estado de las cuentas. Para
eso me creé un informe que llamé <code>cierre</code>. Lo destacable de este
informe es que me hace el asiento de cierre automáticamente utilizando
la opción <code>--format</code> que va acompañada de una expresión algo más
compleja y por eso la explicaré aquí. El código en <code>elisp</code> se
convertirá en 
</p>

<pre class="example" id="orgbd8555a">
"    %-40(account) %10(market(display_total) * -1)\n"
</pre>

<p>
El formato, primero deja cuatro espacios en blanco y luego hay una
columna definida como <code>%-40(account)</code> es decir: el nombre de la cuenta
con cuarenta caracteres de ancho alineados a la izquierda (por eso el
-). La siguiente columna es <code>%10(market(display_total) * -1)\n</code>. Es
decir: 10 caracteres de ancho y un cálculo que básicamente es cambiar
de signo el valor total de la cuenta. El resultado en nuestro caso
será:
</p>

<pre class="example" id="org9cd4c45">
Activo:Bancos:El saqueador y cia            285,34€
Activo:Bancos:Ladrones y cia                 78,95€
Activo:Inmuebles:Casa                    -2.160,04€
Activo:Metálico                             -11,65€
Activo:Plan de Pensiones                    -82,65€
Gastos:Alimentación                         -86,76€
Gastos:Alimentación:Mencabrona              -85,49€
Gastos:Intereses Hipoteca                   -24,03€
Gastos:Lotería                               16,00€
Gastos:Otros Gastos:Metálico                 -3,55€
Pasivo:Hipoteca                           1.136,76€
Patrimonio:Balance Apertura                 851,63€
</pre>

<p>
Sin embargo, si la anotamos tal cual y actualizamos la consulta nos
saltará un error, porque en la cuenta de <code>Gastos:Alimentación</code> está
contada dos veces la compra en el <code>Mencabrona</code> de 85,49€ por lo que
tendremos que ajustar esos errores antes de hacer el cierre anual.
</p>

<p>
Una vez hecho el ajuste contable queda hacer la apertura, y para ello
también creé un informe que lo hace.
</p>
</div>
</div>
</div>
<div id="outline-container-orgc45e8b9" class="outline-2">
<h2 id="orgc45e8b9">Conclusión</h2>
<div class="outline-text-2" id="text-orgc45e8b9">
<p>
Con mi intención de llevar toda mi información en ficheros de texto
plano, <code>ledger-cli</code> me facilita el trabajo contable. No necesito
sofisticados programas de entorno gráfico con formatos cerrados y un
gran gasto de recursos gráficos y de memoria.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/contabilidad/index.html">contabilidad</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[contabilidad]]></category>
  <link>https://notxor.nueva-actitud.org/2018/10/30/ledger-cli-y-el-ledger-mode-de-emacs.html</link>
  <pubDate>Tue, 30 Oct 2018 20:48:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Ajuste del calendario y la visualización de documentos en emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-10-29</div>
<p>
Estos días me han preguntado cómo hacía para abrir los documentos que
genero desde <i>emacs</i> y por qué a mí en el calendario me aparecen los
meses y los días es español y a mi interlocutor no. Aunque son dos
temas distintos los meto en el mismo artículo y añado otra respuesta
que fue juzgada como <i>menos urgente o importante</i>, porque no dan una
extensión que necesite el espacio de dos <i>posts</i>.
</p>
<div id="outline-container-org278b07b" class="outline-2">
<h2 id="org278b07b">Visualizador de documentos</h2>
<div class="outline-text-2" id="text-org278b07b">
<p>
Básicamente exporto desde <i>emacs</i> a dos tipos de documentos <i>pdf</i> y
<i>html</i>. Para hacerlo tengo el siguiente código en mi <code>init.el</code> dentro
del apartado <code>custom-set-variables</code>:
</p>

<div class="org-src-container">
<pre class="src src-elisp">'(TeX-view-program-selection
   (<span style="color: #ff79c6; font-weight: bold;">quote</span>
    (((output-dvi has-no-display-manager)
      <span style="color: #f1fa8c;">"dvi2tty"</span>)
     ((output-dvi style-pstricks)
      <span style="color: #f1fa8c;">"dvips and gv"</span>)
     (output-dvi <span style="color: #f1fa8c;">"xdvi"</span>)
     (output-pdf <span style="color: #f1fa8c;">"Zathura"</span>)
     (output-html <span style="color: #f1fa8c;">"xdg-open"</span>))))
</pre>
</div>

<p>
Quiero destacar únicamente <a href="https://pwmt.org/projects/zathura/">el uso de <i>Zathura</i> como visualizador de
los documentos <i>pdf</i></a>. Ese software es muy liviano y aporta además el
matiz de que detecta cuándo hemos modificado el documento para
visualizar los cambios automáticamente. Por ejemplo, encuentro un
error en el documento y me doy cuenta al visualizarlo en <i>pdf</i>. Sin
cerrar la visualización voy al fichero LaTeX, guardo el cambio
corregido <code>C-x C-s</code> y genero el nuevo <i>pdf</i> <code>C-c C-c</code>. Al modificarse
el fichero, <i>Zathura</i> lo recargará y visualizará la última versión ya
corregida.
</p>
</div>
</div>
<div id="outline-container-org878d1e2" class="outline-2">
<h2 id="org878d1e2">Ajustes del calendario</h2>
<div class="outline-text-2" id="text-org878d1e2">
<p>
Los ajustes en el calendario también tienen que ver con el apartado de
<code>custom-set-variables</code>, concretamente las siguientes:
</p>

<div class="org-src-container">
<pre class="src src-elisp">'(calendar-date-style (<span style="color: #ff79c6; font-weight: bold;">quote</span> iso))
'(calendar-day-header-array [<span style="color: #f1fa8c;">"Do"</span> <span style="color: #f1fa8c;">"Lu"</span> <span style="color: #f1fa8c;">"Ma"</span> <span style="color: #f1fa8c;">"Mi"</span> <span style="color: #f1fa8c;">"Ju"</span> <span style="color: #f1fa8c;">"Vi"</span> <span style="color: #f1fa8c;">"Sa"</span>])
'(calendar-day-name-array
   [<span style="color: #f1fa8c;">"domingo"</span> <span style="color: #f1fa8c;">"lunes"</span> <span style="color: #f1fa8c;">"martes"</span> <span style="color: #f1fa8c;">"mi&#233;rcoles"</span> <span style="color: #f1fa8c;">"jueves"</span> <span style="color: #f1fa8c;">"viernes"</span> <span style="color: #f1fa8c;">"s&#225;bado"</span>])
'(calendar-month-abbrev-array
   [<span style="color: #f1fa8c;">"Ene"</span> <span style="color: #f1fa8c;">"Feb"</span> <span style="color: #f1fa8c;">"Mar"</span>
    <span style="color: #f1fa8c;">"Abr"</span> <span style="color: #f1fa8c;">"May"</span> <span style="color: #f1fa8c;">"Jun"</span>
    <span style="color: #f1fa8c;">"Jul"</span> <span style="color: #f1fa8c;">"Ago"</span> <span style="color: #f1fa8c;">"Sep"</span>
    <span style="color: #f1fa8c;">"Oct"</span> <span style="color: #f1fa8c;">"Nov"</span> <span style="color: #f1fa8c;">"Dic"</span>])
'(calendar-month-name-array
   [<span style="color: #f1fa8c;">"enero"</span> <span style="color: #f1fa8c;">"febrero"</span> <span style="color: #f1fa8c;">"marzo"</span>
    <span style="color: #f1fa8c;">"abril"</span> <span style="color: #f1fa8c;">"mayo"</span> <span style="color: #f1fa8c;">"junio"</span>
    <span style="color: #f1fa8c;">"julio"</span> <span style="color: #f1fa8c;">"agosto"</span> <span style="color: #f1fa8c;">"septiembre"</span>
    <span style="color: #f1fa8c;">"octubre"</span> <span style="color: #f1fa8c;">"noviembre"</span> <span style="color: #f1fa8c;">"diciembre"</span>])
'(calendar-week-start-day 1)
</pre>
</div>

<p>
La variable <code>calendar-date-style</code> está ajustada para mostrar las
fechas según el modo <code>ISO</code>, es decir, en el formato <code>año/mes/día</code>, tal
que por ejemplo, el día de hoy será <code>2018/10/29</code>. Eso permite un
ordenamiento de las fechas automático en formato texto y una vez te
acostumbras es tan sencillo como ordenarlas al inverso.
</p>

<p>
La variable <code>calendar-day-header-array</code> muestra los nombres del día de
la semana que se muestran en las cabeceras del <i>buffer</i> calendario,
donde sólo caben dos caracteres. Sin embargo, cuando emacs necesite el
nombre completo del día utilizará los nombres guardados en
<code>calendar-day-name-array</code>. De igual modo, el nombre abreviado de los
meses se guardan en la variable <code>calendar-month-abbrev-array</code> y los
nombres largos en <code>calendar-month-name-array</code>.
</p>

<p>
La última variable es para que las semanas comiencen en lunes (día 1)
en lugar de en domingo (día 0).
</p>
</div>
</div>
<div id="outline-container-orgacb4b2c" class="outline-2">
<h2 id="orgacb4b2c">Avisos de la agenda para que recuerde cumpleaños y efemérides</h2>
<div class="outline-text-2" id="text-orgacb4b2c">
<p>
Otro de los aspectos que me han preguntado es cómo hacer para que la
agenda recuerde las fechas de cumpleaños o las efemérides que desees
recordar. En el fichero <code>init.el</code> debes configurar un fichero
<i>diario</i> también en el apartado <code>custom-set-variables</code>:
</p>

<div class="org-src-container">
<pre class="src src-elisp">'(org-agenda-diary-file <span style="color: #f1fa8c;">"ruta/al/fichero/diario.org"</span>)
</pre>
</div>

<p>
Como se ve, puedes configurar el nombre y la ruta que se quiera
(siempre que <i>emacs</i> lo encuentre). ¿Qué hay que meter dentro de ese
archivo para que haga los recordatorios? Muy fácil:
</p>

<div class="org-src-container">
<pre class="src src-elisp">%%(org-anniversary 2018 10 29) Este post cumple %d a&#241;os de su publicaci&#243;n.
</pre>
</div>

<p>
Se observa el comando <code>org-anniversary</code> con tres parámetros el <code>año</code>,
el <code>mes</code> y el <code>día</code> y una cadena a continuación con el texto que
queramos y en el que se puede incluir <code>%d</code> para que <code>org-mode</code> lo
sustituya por el número de años. El próximo año, en la agenda me
aparecerá una reseña diciéndome que este artículo se publicó hace un
año, por ejemplo.
</p>
</div>
</div>
<div id="outline-container-org1c6f371" class="outline-2">
<h2 id="org1c6f371">Conclusión</h2>
<div class="outline-text-2" id="text-org1c6f371">
<p>
Son detalles que muchos usuarios ya conocen y que pongo aquí porque
quien me preguntó es un nuevo usuario de <i>emacs</i>. De todas formas, al
resto de usuarios, también les puede servir de repaso.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2018/10/29/ajuste-del-calendario-y-la-visualizacion-de-documentos-en-emacs.html</link>
  <pubDate>Mon, 29 Oct 2018 13:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Cómo ayudar a los niños a enfrentarse al «cyberbullying»]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-10-23</div>
<p>
En este artículo pretendo dar unas nociones básicas de cómo ayudar a
los menores que están sufriendo <i>cyberbullying</i>. En general, hablaré
sobre el acoso, pero en los últimos años el <i>acoso</i> que antes se
quedaba en la calle viaja en el bolsillo de nuestros hijos.
</p>
<div id="outline-container-org9c8a82c" class="outline-2">
<h2 id="org9c8a82c">¿Qué es el <i>Cyberbullying</i>?</h2>
<div class="outline-text-2" id="text-org9c8a82c">
<p>
El <i>Cyberbullying</i> es la utilización de herramientas de comunicación
basadas en Internet o telefonía móvil para acosar a otra persona.
Suelen considerarse varios tipos de acciones, como el envío de
mensajes acosadores o hirientes, publicación de fotos o vídeos en
redes sociales, difusión de rumores difamantes en <i>Internet</i> o en
grupos de aplicaciones de mensajería.
</p>

<p>
El <a href="https://childmind.org/article/help-kids-deal-cyberbullying/?utm_source=newsletter&amp;utm_medium=email&amp;utm_content=Dealing%20With%20Cyberbullying&amp;utm_campaign=Weekly-10-02-18"><i>Child Mind Institute</i> en un artículo lo define como</a>:
</p>

<blockquote>
<p>
Cyberbullying is the use of digital-communication tools (such as the
Internet and cell phones) to make another person feel angry, sad, or
scared, usually again and again. Examples of cyberbullying include
sending hurtful texts or instant messages, posting embarrassing photos
or video on social media, and spreading mean rumors online or with
cell phones.
</p>
</blockquote>
</div>
</div>
<div id="outline-container-org6cc2e33" class="outline-2">
<h2 id="org6cc2e33">Pautas para el primer momento</h2>
<div class="outline-text-2" id="text-org6cc2e33">
<p>
Para los adultos, los padres, suele haber un <i>shock</i> emocional cuando
descubren que su hijo o hija sufre acoso. Es posible que la primera
reacción al enterarse sea tomar represalias sobre esos hechos y se
olvidan de lo más importante: <b>ayudar al menor</b> a desactivar la
situación, a protegerse a sí mismo y a buscar soluciones racionales
que ayuden a detener ese acoso.
</p>

<p>
Es difícil mantener la calma cuando afecta a uno de nuestros hijos,
tenemos que reaccionar. Pero lo más seguro es que sin estar preparados
para enfrentar estos casos, nuestra reacción sea desproporcionada, a
destiempo e incluso contraproducente cuando caemos en la
sobreprotección. ¿Qué podemos hacer?
</p>

<ul class="org-ul">
<li>Lo primero es mostrar nuestro apoyo incondicional al menor. Lo
queremos, hay que hacérselo saber.</li>
<li>Ayudar al menor a mantenerse alejado de los medios electrónicos por
el que le llega el acoso. <i>Ayudar</i>, no prohibir. Podemos organizar
actividades paralelas: realizar con él juegos <i>analógicos</i>, ayudarlo
a desinstalar las aplicaciones que pueden molestar, etc.</li>
<li>Si se puede identificar a los acosadores y son menores también,
puede considerarse la opción de hablar con los padres. Considéralo,
pero ten en cuenta que este tipo de encuentros si no se saben
manejar terminan normalmente en un cruce de reproches que no
arreglan nada o incluso pueden empeorar la situación.</li>
<li>Valora ponerte en contacto con el Centro Educativo de tu hijo o
hija. Aunque sólo tengas referencia de acoso <i>online</i>, es posible
que sea una extensión que se arrastra desde otras situaciones como
la escolar.</li>
</ul>

<p>
Muchas veces los chicos no cuentan que están sufriendo acoso. Algunas
veces es por vergüenza, pero en muchas ocasiones es por miedo a
empeorar la situación involucrando a los adultos. La mayoría de los
acosos pasan desapercibidos, por ello, para los padres. Tanto es así
que si los padres llegan a enterarse de una de estas situaciones es
que el problema será lo suficientemente importante como para
intervenir.
</p>

<p>
Intervenir no significa entrar como un elefante en una cacharrería.
Intervenir significa comenzar por <b>recabar cuantos más datos, mejor</b>.
Tenemos que hablar de la situación con nuestro hijo, pactar las
acciones que vamos a tomar y elaborar un plan de acción conjunto.
Dejar que nos exprese sus temores y miedos sobre las consecuencias y
aclararle el alcance de las acciones para que la defensa sea eficaz.
</p>

<p>
Uno de los objetivos que suelen tener los acosadores es aislar a la
víctimas para que no reciban ayuda. Es una buena idea animar al menor
a <b>buscar el apoyo de compañeros</b>, porque puede convertirse en una
defensa eficaz.
</p>

<p>
Pautas que debemos explicar y pactar con nuestros menores, según el
<i>Children Mind Institute</i> son las siguientes:
</p>

<ul class="org-ul">
<li><i>Apagar el móvil o el ordenador</i>. Hay que ignorar los ataques y otra
opción si se quiere mantener el uso de esos dispositivos es
desinstalar las aplicaciones por las que llega el acoso, o
bloquearlas.</li>
<li><i>No responder ni tomar represalias</i>. Normalmente cuando contestamos
en caliente podemos decir o hacer cosas de las que más tarde nos
arrepentimos. Normalmente los acosadores buscan obtener una reacción
de nosotros, es lo <i>divertido</i> de acosar. No les demuestres que su
plan ha funcionado.</li>
<li><i>Bloquear al acosador</i>. Muchas de las aplicaciones que utilizamos
tienen herramientas para <i>bloquear</i> cuentas de las que no queremos
tener conocimiento. Si no puedes hacer eso, borra esos mensajes sin
leerlos.</li>
<li><i>Guarda e imprime los mensajes de acoso</i>. Si la situación se alarga
en el tiempo, guarda la evidencia porque lo necesitarás para
mostrárselo a padres y maestros, para denunciar la situación.</li>
<li><i>Cuéntale todo a un adulto de confianza</i>. El adulto de confianza no
tiene por qué ser uno de los padres. El adulto de confianza será
aquél en el que confíe el menor porque considere que lo escuchará y
que tiene las habilidades, la predisposición y la autoridad para
ayudarlo. Revelar esta situación a un adulto no es <i>chivarse</i>, es
defenderse.</li>
</ul>

<p>
Hay que tener en cuenta además, que si existen amenazas reales contra
la seguridad del menor, hay que interponer denuncia en la comisaría
más cercana.
</p>
</div>
</div>
<div id="outline-container-org891af69" class="outline-2">
<h2 id="org891af69">Estrategias positivas</h2>
<div class="outline-text-2" id="text-org891af69">
<p>
En las situaciones de acoso las reacciones que conllevan peores
resultados son las que terminan en confrontación y los mejores las que
señalan la situación en su justo término.
</p>

<p>
Nuestra obligación es enseñarle a nuestros hijos que construir
un mundo y una sociedad seguros es responsabilidad de todos. Hay
que darles herramientas para que, por ejemplo:
</p>

<ul class="org-ul">
<li>denuncien también las situaciones de acoso que presencien,</li>
<li>que censuren comentarios crueles en redes sociales,</li>
<li>a no enviar fotos humillantes si las reciben,</li>
<li>no reír las gracias que impliquen falta de respeto o sean
humillantes para otros,</li>
<li>...</li>
</ul>

<p>
Así, entre todos podremos detener episodios de crueldad que de otra
forma hubieran ido magnificándose como en una gran bola de nieve.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/psicología/index.html">psicología</a> ]]></description>
  <category><![CDATA[psicología]]></category>
  <link>https://notxor.nueva-actitud.org/2018/10/23/como-ayudar-a-los-ninos-a-enfrentarse-al-cyberbullying.html</link>
  <pubDate>Tue, 23 Oct 2018 16:44:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Sobre cómo utilizo org-page para hacer este blog]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-10-18</div>
<p>
Este artículo va de cómo estoy utilizando <code>org-page</code> para hacer éste
<i>blog</i>. Lo haré con pelos y señales, porque me lo ha pedido así Ángel,
<a href="https://ugeek.github.io/">del <i>blog</i> y <i>podcast</i> uGeek</a> que se está planteando emplear el sistema
para sus proyectos.  <a href="https://notxor.nueva-actitud.org/blog/2017/10/30/esto-es-un-desastre/">Sobre cómo ponerlo en marcha ya hablé en otra
ocasión</a> y no voy a reincidir, aunque haré alguna puntualización.
</p>

<p>
Hay algunos cambios en la configuración desde que lo inicié. Copio
aquí la configuración que tengo en el <code>init.el</code>.
</p>

<div class="org-src-container">
<pre class="src src-elisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Para el blog en org-mode
</span>(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">org-page</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/repository-directory <span style="color: #f1fa8c;">"~/proyectos/blog-org-page/"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/site-domain <span style="color: #f1fa8c;">"https://notxor.nueva-actitud.org"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/site-main-title <span style="color: #f1fa8c;">"Notxor tiene un blog"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/site-sub-title <span style="color: #f1fa8c;">"Defenestrando la vida"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/theme-root-directory <span style="color: #f1fa8c;">"/home/notxor/proyectos/themes-org-page"</span>) <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Temas propios
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/theme (<span style="color: #ff79c6; font-weight: bold;">quote</span> notxor))   <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Ajustes personales del tema
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/tag-rss t)              <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Hacer que se creen los feed por etiquetas.
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/hashover-comments t)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/personal-github-link <span style="color: #f1fa8c;">""</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/site-preview-directory <span style="color: #f1fa8c;">"~/public_html"</span>)
</pre>
</div>

<p>
Quiero recordar nada más que todo el blog está en un repositorio
<i>git</i>. Es un repositorio particular y privado sobre un servidor
propio. <a href="https://about.gitlab.com/">No utilizo ni <i>gitlab</i></a> ni <a href="https://github.com/">tampoco github</a> ni ningún otro
repositorio externo.
</p>

<p>
El repositorio del <i>blog</i> tiene dos ramas: <code>master</code> y <code>source</code>. Los
<i>html</i> que se publican se guardan en la rama <code>master</code> y los ficheros
<code>org</code> que son los que escribo están en la rama <code>source</code>.
</p>
<div id="outline-container-org96d4377" class="outline-2">
<h2 id="org96d4377">Flujo de trabajo</h2>
<div class="outline-text-2" id="text-org96d4377">
<p>
Escribir un artículo y publicarlo tiene un proceso muy sencillo. El
sistema lo describo a continuación.
</p>
</div>
<div id="outline-container-org56f1421" class="outline-3">
<h3 id="org56f1421">Escribir el artículo</h3>
<div class="outline-text-3" id="text-org56f1421">
<p>
Antes de comenzar a escribir me aseguro de que el repositorio <i>git</i>
está en la rama <code>source</code> que es la destinada a recoger los textos que
escribes en formato <code>org</code>. Si no estamos en la rama adecuada, hay que
hacer en una consola situada en el repositorio:
</p>

<div class="org-src-container">
<pre class="src src-shell">git chekout source
</pre>
</div>

<p>
En un primer momento creé también una rama <code>drafts</code> para guardar los
borradores de los artículos según se me iban ocurriendo. Esa rama al
final la abandoné. Los borradores son los artículos que aún no he
guardado en el repositorio <code>git</code>. Pero para iniciar la escritura de un
artículo es muy sencillo, utilizo el siguiente comando de <i>emacs</i>
</p>

<div class="org-src-container">
<pre class="src src-nil">M-x op/new-post
</pre>
</div>

<p>
Ese comando inicia una serie de preguntas, como la categoría del
artículo, en mi caso están la mayoría en la categoría <i>blog</i> aunque
tengo otros en la categoría <i>esperanto</i>. Pregunta también un nombre de
archivo, unas etiquetas y palabras clave, un título y una <code>URL</code>. Estos
datos componen la cabecera del fichero <code>org</code>. Relleno todos los campos
lo mejor que sé, tampoco me preocupo mucho, pues esos datos se pueden
modificar más tarde. Lo que suelo tener en cuenta es que en la <code>URL</code>
no haya caracteres especiales con tildes o eñes.
</p>
</div>
</div>
<div id="outline-container-org7b38f3d" class="outline-3">
<h3 id="org7b38f3d">Subirlo al repositorio</h3>
<div class="outline-text-3" id="text-org7b38f3d">
<p>
Para manejar el repositorio utilizo <code>magit</code> desde el mismo <i>emacs</i>,
pero empecé utilizando directamente <i>git</i> y la línea de comandos. En
ambos casos hacía básicamente lo mismo y puedes utilizar para manejar
el repositorio la herramienta con la que mejor te entiendas:
</p>

<ol class="org-ol">
<li>Comprobar el estado del repositorio con <code>status</code>.
<img src="./articulo-blog-magit.png" alt="articulo-blog-magit.png"></li>
<li>Añadir los cambios con <code>add</code> o con <code>stage</code>.</li>
<li>Meterlos en el repositorio local con <code>commit</code>.
<img src="./articulo-blog-commit.png" alt="articulo-blog-commit.png"></li>
<li>Sincronizar el repositorio remoto con <code>push</code>.</li>
</ol>

<p>
Bien, ya tenemos la información subida al <i>repositorio local</i>. Esto es
importante porque el sistema sólo genera las páginas de lo que esté
subido e ignora los demás ficheros.
</p>
</div>
</div>
<div id="outline-container-org69fbc14" class="outline-3">
<h3 id="org69fbc14">Publicar en local los cambios realizados</h3>
<div class="outline-text-3" id="text-org69fbc14">
<p>
Antes de subirlo donde lo pueda ver la gente, primero lo publico en
<i>local</i>. Es decir, en mi ordenador monto un equivalente al sitio <i>web</i>
para comprobar que está todos bien, que funcionan todo, que las
imágenes, o vídeos o sonido, enlazan correctamente.
</p>

<p>
Para hacer la publicación se utiliza el comando
</p>

<div class="org-src-container">
<pre class="src src-nil">M-x op/do-publication
</pre>
</div>

<p>
Nos preguntará si publica todos los archivos <code>org</code> y si lo hace en un
directorio local. Yo lo hago sobre el <code>~/public_html</code>. Allí, en el
directorio que indiquemos, colocará todos los archivos como se verán
en la <i>web</i>. Si queremos consultarla como si lo hiciéramos en una
remota, hay que montar un servidor. Podemos utilizar el de <i>emacs</i> o
cualquier otro.  <a href="https://docs.python.org/3/library/http.html">Yo utilizo el que proporciona Python</a>, por tanto
utilizo los siguientes comandos desde una consola:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #8be9fd; font-style: italic;">cd</span> ~/public_html
python3 -m http.server 8080
</pre>
</div>

<p>
Para comprobar que todo funciona abro los navegadores; normalmente lo
compruebo con tanto con <i>firefox</i> como con <i>iridium</i>. <i>Iridium</i> es un
navegador basado en <i>chromium</i> que no se chiva de nuestras cosas a
<i>Google</i>. Una vez que <i>creo</i> que todo está correcto, llega el momento
de subir las páginas al sitio de <i>Internet</i> y actualizar la rama
<code>master</code> del repositorio.
</p>
</div>
</div>
<div id="outline-container-org8f2f9ba" class="outline-3">
<h3 id="org8f2f9ba">Guardar las páginas generadas</h3>
<div class="outline-text-3" id="text-org8f2f9ba">
<p>
Si todo está correcto, primero meto los cambios en el repositorio. Pero
hay que recordar cambiar la rama sobre la que trabajamos:
</p>

<div class="org-src-container">
<pre class="src src-shell">git checkout master
</pre>
</div>

<p>
y copio los ficheros desde <code>~/public_html</code> al directorio de trabajo
<code>~/proyectos/blog-org-page</code>. Se puede utilizar la herramienta <code>rsync</code>
pero últimamente me he acostumbrado a utilizar el gestor de archivos
<code>mc</code>, porque es la herramienta que utilizo también para subir los
ficheros al sitio de <i>Internet</i>.
</p>


<figure id="org0ff50e8">
<img src="./imagen/articulo-blog-copiar.png" alt="articulo-blog-copiar.png">

</figure>

<p>
Una vez tengo los ficheros en el directorio del repositorio local,
toca actualizar el repositorio <i>git</i> con los mismos pasos que hemos
visto al trabajar con la rama <code>source</code>. El único cambio es que lo
haremos sobre la rama <code>master</code>.
</p>
</div>
</div>
<div id="outline-container-org74c14d9" class="outline-3">
<h3 id="org74c14d9">Subir los cambios a Internet</h3>
<div class="outline-text-3" id="text-org74c14d9">
<p>
Igual que he hecho para guardar el sitio generado por el sistema en
mi repositorio, paso los ficheros que lo componen por <code>ftp</code> al sitio
en Internet.
</p>


<figure id="orgfeec22d">
<img src="./imagen/articulo-blog-ftp.png" alt="articulo-blog-ftp.png">

</figure>
</div>
</div>
</div>
<div id="outline-container-orge8fe8d0" class="outline-2">
<h2 id="orge8fe8d0">Conclusiones</h2>
<div class="outline-text-2" id="text-orge8fe8d0">
<p>
Contado así, con tanto detalle puede parecer un poco farragoso el
sistema. En realidad es bastante sencillo. Tienes los ficheros
generados como html estático. Yo además lo tengo de manera que el
<i>javascript</i> no llame ni se comunique con sitios externos, ni siquiera
para regalarle los datos de visitas a <i>Google</i>. Así no puedo saber
quién entra, ni cuántos son, pero es que en realidad me da igual. No
pienso poner publicidad ni ganar dinero con ello, así pues ¿para qué
regalarle a una gran corporación americana los datos que generan los
que aquí vienen a leerme?
</p>
</div>
<div id="outline-container-orge4cf757" class="outline-3">
<h3 id="orge4cf757">Respuestas a algunas dudas planteadas</h3>
<div class="outline-text-3" id="text-orge4cf757">
<p>
La mayoría de las dudas son sobre el funcionamiento de <i>git</i>. No soy
un experto en <i>git</i>, lo
<a href="https://openlibra.com/es/collection/search/term/git/">único que puedo hacer es recomendar un buen manual sobre esa
herramienta</a>.
</p>

<p>
La otra duda que me han preguntado es cómo parar el servidor <code>http</code>
de <i>emacs</i>. No suelo utilizarlo, pero hay un comando <code>M-x httpd-stop</code>
que supongo que lo detendrá.
</p>

<p>
La parte de utilizar otro editor para escribir los artículos no
termino de pillar el porqué. Concretamente <code>org-mode</code> es potente por
todo el <code>elisp</code> que lo mueve sin que lo veamos. A ver, es texto plano,
lo puedes escribir con cualquier editor. El hacerlo con <i>emacs</i> es más
rápido, me parece a mí:
</p>

<ol class="org-ol">
<li>Escribes o modificas el artículo.</li>
<li>Metes los cambios en el repositorio local. (Si no quieres mezclar
herramientas y que se abran un montón de <i>buffers</i> usas <i>git</i> desde
una consola.)</li>
<li>Generas el sitio con <code>M-x op/do-publication</code>.</li>
</ol>

<p>
Ya te puedes olvidar de <i>emacs</i> si quieres y usar las herramientas que
quieras para guardar el sitio generado en el repositorio y subirlo a
<i>Internet</i>.
</p>
</div>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> <a href="/tags/org-page/index.html">org-page</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <category><![CDATA[org-page]]></category>
  <link>https://notxor.nueva-actitud.org/2018/10/18/sobre-como-utilizo-org-page-para-hacer-este-blog.html</link>
  <pubDate>Thu, 18 Oct 2018 09:53:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Buscando cadenas de texto en emacs con grep]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-10-15</div>
<p>
Cuando un proyecto se expande y comienza a crecer, como este blog, es
complicado encontrar dónde hablaste sobre algo. Los sistemas Unix, de
los que GNU/Linux es un heredero directo, proveen la herramienta
<code>grep</code> que permite buscar texto dentro de un fichero, o de varios.
</p>
<div id="outline-container-orgb262443" class="outline-2">
<h2 id="orgb262443"><code>grep</code> desde línea de comandos.</h2>
<div class="outline-text-2" id="text-orgb262443">
<p>
Al principio, utilizaba <code>grep</code> desde línea de comandos. Muchas veces,
lo único que necesitaba era saber cuántas veces aparece un término o
una expresión en una serie de ficheros. Si necesito buscar cuántas
veces aparece el término <code>emacs</code> en los artículos del <i>blog</i> puedo
lanzar el comando
</p>

<div class="org-src-container">
<pre class="src src-shell">grep -c <span style="color: #f1fa8c;">"emacs"</span> ~/proyectos/blog-org-page/blog/*
</pre>
</div>

<p>
El resultado que muestra será similar a
</p>

<pre class="example" id="org05e9bc6">
~/proyectos/blog-org-page/blog/avances-isla-godot.org:0
~/proyectos/blog-org-page/blog/calculadora-guile.org:0
~/proyectos/blog-org-page/blog/cambios-en-mi-prompt.org:1
~/proyectos/blog-org-page/blog/cifrado-con-emacs.org:13
~/proyectos/blog-org-page/blog/codigo-minimult-por-pantalla.org:2
~/proyectos/blog-org-page/blog/como-uso-git-2.org:4
~/proyectos/blog-org-page/blog/como-uso-git.org:0
~/proyectos/blog-org-page/blog/comparacion-schemes.org:0
~/proyectos/blog-org-page/blog/compilar-chicken-android.org:1
~/proyectos/blog-org-page/blog/crei-terminar-minimult.org:6
~/proyectos/blog-org-page/blog/ejercicio-scheme.org:2
~/proyectos/blog-org-page/blog/emacs-client.org:36
~/proyectos/blog-org-page/blog/emacs-grep.org:5
~/proyectos/blog-org-page/blog/en-que-ando-2018.org:2
~/proyectos/blog-org-page/blog/entrevista-radio.org:0
~/proyectos/blog-org-page/blog/escalas-plantillas.org:2
~/proyectos/blog-org-page/blog/escribir-en-emacs.org:13
~/proyectos/blog-org-page/blog/feeds-elfeed-emacs.org:12
~/proyectos/blog-org-page/blog/hablar-de-suicidio.org:0
~/proyectos/blog-org-page/blog/importar-fichero-entre-ramas.org:2
~/proyectos/blog-org-page/blog/inicio-nuevo-blog.org:8
~/proyectos/blog-org-page/blog/me-gusta.org:0
~/proyectos/blog-org-page/blog/minimult-2.org:3
~/proyectos/blog-org-page/blog/minimult-corregido.org:2
~/proyectos/blog-org-page/blog/minimult-perfil-grafico.org:2
~/proyectos/blog-org-page/blog/mmpi.org:3
~/proyectos/blog-org-page/blog/orgzly.org:4
~/proyectos/blog-org-page/blog/otro-avance.org:1
~/proyectos/blog-org-page/blog/pasar-minimult-por-pantalla.org:3
~/proyectos/blog-org-page/blog/plantuml.org:2
~/proyectos/blog-org-page/blog/plataformas-enganosas.org:0
~/proyectos/blog-org-page/blog/quiza.org:0
~/proyectos/blog-org-page/blog/servidor-local.org:4
~/proyectos/blog-org-page/blog/simplificaciones.org:0
~/proyectos/blog-org-page/blog/tablas-org-mode.org:4
~/proyectos/blog-org-page/blog/toki-pona.org:0
~/proyectos/blog-org-page/blog/utilizando-emacs-para-otras-cosas.org:3
~/proyectos/blog-org-page/blog/viaje-a-ciria.org:0
~/proyectos/blog-org-page/blog/video-isla.org:0
</pre>

<p>
Como se puede apreciar toma todos los ficheros que le hemos pasado en
el directorio. En algunos resultados muestra <code>0</code> y en otras aparece el
número de veces que la cadena (o expresión regular) que debe
buscar. Si nos fijamos en el listado devuelto los nombres de los
ficheros aparecen ordenados alfabéticamente, aunque puede ser que esa
ordenación sea circunstancial y sería mejor, si lo queremos ordenado,
utilizar el comando <code>sort</code>, o por ejemplo si quisiéramos ordenarlo en
el orden contrario:
</p>

<div class="org-src-container">
<pre class="src src-shell">grep -c <span style="color: #f1fa8c;">"emacs"</span> ~/proyectos/blog-org-page/blog/* | sort -r
</pre>
</div>

<p>
Pero la mayor parte de las veces necesito saber, no cuántas veces
aparece, sino dónde. Normalmente busco qué los ficheros que contienen el
término buscado y luego para ponerle contexto, miro en el fichero
concreto que necesito. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-shell">grep -n <span style="color: #f1fa8c;">"emacs"</span> ~/proyectos/blog-org-page/blog/tablas-org-mode.org
</pre>
</div>

<pre class="example" id="org09e1eb6">
6:#+KEYWORDS:    emacs
7:#+TAGS:        emacs
74:Normalmente, el ancho de columna lo calcula directamente /emacs/, pero
230:esté soportada por el modo ~calc~ de emacs. En este caso ~sqrt~ para
</pre>

<p>
Como se puede ver, el parámetro <code>-n</code> nos dice qué línea contiene la
cadena buscada.
</p>
</div>
</div>
<div id="outline-container-orgfe63ff3" class="outline-2">
<h2 id="orgfe63ff3">Uso del comando <code>grep</code> de <i>emacs</i></h2>
<div class="outline-text-2" id="text-orgfe63ff3">
<p>
Hasta hace poco las búsquedas las hacía desde una consola y luego
abría el archivo con <i>emacs</i> para ir hasta las líneas que quería
modificar o consultar con el comando <code>goto-line</code>. Una pérdida de
tiempo teniendo la posibilidad de hacer la búsqueda desde el propio
editor, que abre un <i>buffer</i> que permite saltar directamente al sitio
apropiado.
</p>

<p>
Por ejemplo, para hacer la consulta del primer ejemplo de este
artículo sólo tenemos que seguir los siguientes pasos:
</p>

<ol class="org-ol">
<li>Utilizar el comando <code>M-x grep</code> y pulsar <code>&lt;RET&gt;</code>.</li>
<li><p>
Introducir las opciones que queramos de <code>grep</code>, el editor sugiere
el comando <code>grep --color -nH --null -e</code> para que añadamos la
expresión que debemos buscar. La opción <code>--color</code> creo que no hace
falta explicarla; <code>-nH</code> hace que se muestren los números de línea
junto con el nombre del fichero; <code>--null</code> hace que la salida sea
clara incluso si los nombres de fichero llevan caracteres extraños
como saltos de línea, por ejemplo; y por último <code>-e</code> pide un patrón
que buscar. Yo voy a añadir un nombre de fichero, el que estoy
utilizando ahora. Quedaría la línea como sigue:
</p>

<p>
<code>grep --color -nH --null -e emacs ./emacs-grep.org</code>
</p></li>

<li>Si necesito buscar el término en una serie de archivos, el <code>PATH</code>
puede ser cualquier cadena de búsqueda habitual, por ejemplo
podríamos utilizar <code>./*.org/</code> para que busque el patrón determinado
por <code>-e emacs</code> en todos los ficheros <code>org</code>.</li>
<li><p>
Cuando aparece el <i>buffer</i> <code>*grep*</code> vemos que la lista de
apariciones muestra tiene la forma:
</p>

<p>
<code>./nombre-fichero:núm:texto de la línea</code>
</p>

<p>
La parte <code>nombre-fichero:núm</code> son enlaces. Es decir, si voy al
<i>buffer</i> <code>*grep*</code> y pulso <code>&lt;RET&gt;</code> sobre ese encabezado de la línea,
<i>emacs</i> abrirá el fichero en un <i>buffer</i> con el cursor situado en
la línea marcada.
</p></li>
</ol>
</div>
</div>
<div id="outline-container-orgd2b97cf" class="outline-2">
<h2 id="orgd2b97cf">Conclusiones</h2>
<div class="outline-text-2" id="text-orgd2b97cf">
<p>
Una forma de acelerar el trabajo, las consultas, las modificaciones en
proyectos con muchos ficheros implicados, como un <i>blog</i>.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2018/10/15/buscando-cadenas-de-texto-en-emacs-con-grep.html</link>
  <pubDate>Mon, 15 Oct 2018 18:29:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Usando emacsclient]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-10-13</div>
<p>
Hace tiempo que vengo utilizando <i>emacs</i> para casi todo y eso hace que
lo tenga abierto casi todo el rato. Algunas veces lo cierro,
evidentemente. Pasados unos minutos tengo que hacer algo: repasar la
agenda, actualizar la contabilidad, escribir un artículo en el
blog... casi cualquier cosa, en mi actualidad, pasa por iniciar
<i>emacs</i>.
</p>

<p>
Por eso llegué al uso de <i>emacsclient</i>. En realidad consiste en tener
una sesión de emacs abierta siempre en modo <i>daemon</i> y lanzar el
editor con un cliente que lo que hace es conectarse a esa sesión, por
lo que sólo tiene que dibujar una ventana en el sistema y se gana en
velocidad de inicio.
</p>
<div id="outline-container-orgba7eb5b" class="outline-2">
<h2 id="orgba7eb5b">Lanzar <i>emacs</i> en modo servidor</h2>
<div class="outline-text-2" id="text-orgba7eb5b">
<p>
Para lanzar <i>emacs</i> en modo servidor sólo tenemos que utilizar el
comando
</p>

<div class="org-src-container">
<pre class="src src-shell">emacs --daemon
</pre>
</div>

<p>
En mi caso, <a href="https://i3wm.org/">como el gestor de ventanas que utilizo es i3wm</a> lo que he
hecho es añadir una línea en el fichero de configuración
<code>~/.config/i3/config</code> como la siguente:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #ff79c6; font-weight: bold;">exec</span> emacs --daemon
</pre>
</div>

<p>
Eso hace que al arrancar la sesión de <code>i3wm</code> cargue <i>emacs</i> y lo tenga
disponible de forma rápida cuando lo necesito.
</p>
</div>
</div>
<div id="outline-container-org5a5593b" class="outline-2">
<h2 id="org5a5593b">Acceder al demonio <i>emacs</i> con <i>emacsclient</i></h2>
<div class="outline-text-2" id="text-org5a5593b">
<p>
Una vez cargado <i>emacs</i> en memoria tenemos que lanzar el cliente que
pueda conectarse a ese servicio. La misma instalación de <i>emacs</i>
provee el comando <code>emacsclient</code>. Conviene mirarse la página de manual
de la herramienta para conocer todas las opciones, aunque yo lo
utilizo como explico a continuación.
</p>
</div>
<div id="outline-container-org0d84cdb" class="outline-3">
<h3 id="org0d84cdb">Lanzarlo desde <code>i3wm</code></h3>
<div class="outline-text-3" id="text-org0d84cdb">
<p>
Como he dicho antes, utilizo el gestor de ventanas <code>i3wm</code> que me
permite olvidarme del ratón para muchas cosas y trabajar con
combinaciones de teclas que me facilitan y aceleran los accesos a las
ventanas, los escritorios y las aplicaciones mucho más rápido que
cualquier sistema de menús gráficos.
</p>

<p>
Antes de utilizar <i>emacsclient</i> había creado una combinación de teclas
que lanzaba <i>emacs</i> en el fichero de configuración del entorno
<code>i3wm</code>. La forma de hacerlo es muy sencilla:
</p>

<pre class="example" id="org5511877">
set $alt Mod1
...
...
bindsym Ctrl+$alt+e exec emacs
</pre>

<p>
Eso hacía que pulsando las teclas <code>C-M-e</code> (siguiendo la notación
habitual de nuestro editor favorito) se lanzara una sesión de
<i>emacs</i>. Algo sencillo, rápido y cómodo. Al cambiar utilizar
<i>emacsclient</i> la línea ha cambiado a:
</p>

<pre class="example" id="org0bf0883">
bindsym Ctrl+$alt+e exec emacsclient -c -a emacs
</pre>

<p>
Básicamente llamamos a <i>emacsclient</i> diciéndole que inicie una sesión
gráfica, con el parámetro <code>-c</code> y que si hay algún problema utilice
como editor alternativo (parámetro <code>-a &lt;editor&gt;</code>) el propio <i>emacs</i> en
su modo completo.
</p>
</div>
</div>
<div id="outline-container-org87e1a47" class="outline-3">
<h3 id="org87e1a47">Variables de entorno</h3>
<div class="outline-text-3" id="text-org87e1a47">
<p>
Otro de los puntos que he modificado son las variables de entorno para
que el sistema sepa qué editor tiene que lanzar. En mi fichero
<code>.bashrc</code> tengo las líneas siguientes:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #8be9fd; font-style: italic;">export</span> <span style="color: #f8f8f2; font-weight: bold;">EDITOR</span>=<span style="color: #f1fa8c;">"emacsclient -t"</span>
<span style="color: #8be9fd; font-style: italic;">export</span> <span style="color: #f8f8f2; font-weight: bold;">VISUAL</span>=<span style="color: #f1fa8c;">"emacsclient -c -a emacs"</span>
</pre>
</div>

<p>
El valor de <code>VISUAL</code> ya lo he comentado antes, sólo nos falta decir
que el parámetro <code>-t</code> que utilizo en la variable <code>EDITOR</code>, abre la
sesión en una consola de texto. También se podría utilizar el
parámetro <code>-nw</code> del <i>emacs</i> genérico y funcionaría del mismo modo.
</p>
</div>
</div>
</div>
<div id="outline-container-orgd5c3965" class="outline-2">
<h2 id="orgd5c3965">Cambios en el modo de trabajo</h2>
<div class="outline-text-2" id="text-orgd5c3965">
<p>
He tenido que cambiar algunos hábitos de trabajo teniendo una única
sesión de <i>emacs</i> lanzada, puesto que no se cierran los <i>buffers</i> al
cerrar con <code>C-x C-c</code>, sólo se cierra el cliente que hayas abierto,
pero <i>emacs</i> sigue trabajando con ellos en segundo plano.
</p>
</div>
<div id="outline-container-org9d24702" class="outline-3">
<h3 id="org9d24702">Inconvenientes</h3>
<div class="outline-text-3" id="text-org9d24702">
<p>
Si termino la edición de un fichero y estoy convencido de que no voy a
necesitarlo más, que no voy a modificarlo ni consultarlo, tengo que
recordar cerrar el <i>buffer</i> con <code>C-x k</code>. Si no, el fichero seguirá
cargado en memoria.
</p>

<p>
Otro inconveniente es tener siempre cargado en memoria una sesión de
<i>emacs</i>. Aunque la cantidad de memoria consumida ha dejado de
preocuparme, en realidad es mínimo y después de comprobarlo, incluso
editando varios archivos resulta más ligero que algunos otros demonios
que tengo en el sistema, como el cliente de <i>nextcloud</i>, por
ejemplo. Y si nos fijamos en el gasto de CPU, el tiempo de procesador
es mínimo mientras está inactivo, por lo que tampoco me preocupa.
</p>
</div>
</div>
<div id="outline-container-org725d9e2" class="outline-3">
<h3 id="org725d9e2">Ventajas</h3>
<div class="outline-text-3" id="text-org725d9e2">
<p>
El tiempo de inicio del cliente es mínimo. Es pulsar la combinación de
teclas y la ventana de <i>emacs</i> aparece sin ningún tipo de dilación, no
tiene que cargar ninguna configuración, porque ya la tiene cargada.
</p>

<p>
Modificar los ficheros desde distintos clientes a la vez. Puesto que
el <i>emacs</i> es único, cualquier cambio que hagamos en un <i>buffer</i> desde
un cliente se refleja automáticamente en los demás clientes abiertos;
y siempre que se cierra un cliente te pregunta si quieres guardar los
cambios. Esto me viene bien, porque suelo trabajar en modo texto
normalmente. A veces necesito visualizar gráficos, o pdf, o consultar
<i>webs</i>, o leer los <i>feeds</i>, o... y para eso me apaño mejor con la
versión gráfica de <i>emacs</i>. Sin cerrar, ni guardar nada; sin abrir, ni
cargar nada, abro un cliente gráfico y sigo trabajando con los mismos
<i>buffers</i> que tengo abiertos en el modo texto. Veo lo que necesito,
luego cierro lo que no necesito y me vuelvo al modo texto.
</p>
</div>
</div>
</div>
<div id="outline-container-orgbf2b1d8" class="outline-2">
<h2 id="orgbf2b1d8">Conclusiones</h2>
<div class="outline-text-2" id="text-orgbf2b1d8">
<p>
Aún, después de unos días, me estoy acostumbrando a una dinámica
diferente a la que llevo haciendo toda la vida. El cambio está siendo
rápido y me siento más productivo. Aunque aún me pasa que se me
olvidan cerrar algunos <i>buffers</i> y me los encuentro abiertos cuando
vuelvo a abrir el cliente. Algunas veces para bien, porque estaba
trabajando en algo antes de irme a comer, por ejemplo, y me encuentro
que ya lo tengo abierto cuando vuelvo. Otras veces, sin embargo, me
encuentro una ristra de <i>buffers</i> secundarios de <code>magit</code> abiertos, de
distintos repositorios de proyectos y cosas y tengo que emplear un
poco de tiempo en <i>matar</i> todo lo innecesario.
</p>

<p>
Si al final encuentro cómoda esta forma de trabajar supongo que
modificaré el modo para que sea el propio sistema el que lance <i>emacs</i>
en modo servidor y así poder tenerlo en cualquier situación, cualquier
entorno de ventanas o incluso en la consola de texto. Supongo que
<code>systemctrl</code> tendrá algún modo de hacerlo. De momento seguiré con el
modo de <i>andar por casa</i> que me he montado a ver qué tal.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://notxor.nueva-actitud.org/2018/10/13/usando-emacsclient.html</link>
  <pubDate>Sat, 13 Oct 2018 18:23:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Cifrado de archivos con emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-10-05</div>
<p>
En una conversación el otro día salió el tema de la seguridad en
nuestros ficheros. Mi interlocutor se limitaba a poner una contraseña
en un documento «güor» y se quejaba de que algunas veces se le
olvidaba la clave y no podía abrir el archivo. Me contaba que había
encontrado una herramienta que la averiguaba y que le venía fenomenal
en esos casos: ya no había preocupación (¿?). Como psicólogo tengo la
obligación de guardar confidencialidad de todos los datos de mis
clientes. Horrorizado le pregunté por qué confiaba en un sistema que
cualquiera podría descifrar teniendo la misma herramienta y no supo
qué contestarme, salvo vaguedades sobre <i>juaskers</i> y que deberían
hacer algo las autoridades con ellos. Le pregunté que si no había
pensado si él «siendo un negado para la informática» ─como se definía
a sí mismo─ era capaz de saltarse la protección con clave del «güor»,
es porque en definitiva no está protegiendo sus documentos. Y él
contestó que, al fin y al cabo no es psicólogo clínico como yo, <i>sólo</i>
profesor de primaria, como si los datos de los niños fueran menos
importantes.
</p>

<p>
<i>¿Y tú qué haces?</i>, me preguntó. Mi contestación fue algo larga y algo
friki, sobre <i>GnuPG</i> y <i>emacs</i>. Creo que le solté un ladrillo para el
que no estaba preparado y, ahora pienso, no llegó a entender ni la
primera frase donde le comentaba que utilizaba cifrado asimétrico con
un par de claves <i>pública-privada</i>. <i>Gestor de contraseñas</i>, <i>anillo
de claves</i>, firmar y verificar documentos son cosas a las que asintió,
como el que da la razón a un <i>friki</i>, para al final soltarme el
consabido: <i>Ná, si al final todo se puede descifrar</i>. Me callé un:
<i>Hombre, sí, pero consiste en ponerlo difícil, no en regalarlo</i>.
</p>

<p>
De todas maneras, pensé en escribir este post por si a alguien más se
le ocurre preguntarme, le pasaré el enlace y que se apañe, si
quiere. Aquí va la cosa más o menos explicada con más detalle.
</p>
<div id="outline-container-orgd0f236a" class="outline-2">
<h2 id="orgd0f236a">Texto plano: org-mode</h2>
<div class="outline-text-2" id="text-orgd0f236a">
<p>
Toda la información la guardo en texto plano, en un disco duro externo
dentro de una partición cifrada con contraseña. Dentro de los formatos
de texto plano el formato de <i>org-mode</i> sirve para muchas cosas y yo
utilizo muchas de ellas: desde escribir notas o llevar la agenda y
gestionar información jerarquizada, hasta escribir libros. Puede
producir muchos tipos de archivos de salida: html, pdf, odt,
epub... Por lo que con poco esfuerzo puedo gestionar toda la
información que luego tengo que volcar en un informe, en un artículo,
o en una carta (o <i>email</i>). Hay manuales completos de muchos cientos
de páginas explicando qué es el formato <i>org</i> y cómo se utiliza así
que no entraré en ello ahora. Sólo decir que desde hace una temporada
lo utilizo para todo: incluso tengo algunas rutinas hechas en <i>elisp</i>
para corregir algunos <i>tests</i> y que me guarde la información en
formato <i>org-mode</i>, dentro del archivo <code>org</code> que guarda la <i>historia
clínica</i>. Esas informaciones, que tratan sobre las intimidades más
íntimas de las personas que confían en mí, deben ser guardadas con
toda la confidencialidad que yo sea capaz de proporcionar. Al
principio, utilizaba directamente el comando <code>gpg</code> para cifrar esos
archivos. Incluso, creé un par de claves <i>pública─privada</i>, sólo para
hacer esos cifrados de manera exclusiva. Guardaba los cambios, cerraba
el editor y cifraba el archivo borrando el original. Para abrir los
ficheros después, primero lo descifraba con <code>gpg</code> y luego abría con el
editor. Un proceso un poco cargante.
</p>
</div>
</div>
<div id="outline-container-org60c8cfa" class="outline-2">
<h2 id="org60c8cfa">EasyPG: <i>emacs</i> facilitando el trabajo</h2>
<div class="outline-text-2" id="text-org60c8cfa">
<p>
Un día por casualidad abrí un fichero que tenía la extensión
<code>.org.gpg</code> (<code>gpg</code> para recordarme a mí que está cifrado y <code>org</code> porque
el formato interno es <i>org-mode</i>). El caso es que fue grande mi
sorpresa cuando <i>emacs</i> abrió el fichero y el <i>buffer</i> estaba
perfectamente claro. Él solo detectó gracias a la extensión <code>gpg</code> que
era un archivo cifrado y lo descifró. Al principio me puse nervioso
¿Estoy haciendo las cosas bien? ¿Por qué <i>emacs</i> lo ha descifrado sin
despeinarse?. Mirando en la documentación del editor encontré un el
paquete <i>EasyPG</i>, una mina para el cifrado, descifrado y gestión de
<i>claves GnuPG</i>. Respiré un poco más tranquilo, lo había descifrado
automáticamente porque tenía la <i>clave privada</i> para hacerlo.
</p>

<p>
Otro de los puntos que encontré que me gustan de este modo es que
puedes hacer que un fichero <b>nunca</b> haya estado descifrado (<i>en
claro</i>) en el disco duro. Simplemente tienes que crear un <i>buffer</i> con
un nombre que termine en <code>.gpg</code>. Bien llamando desde línea de comandos
al editor, por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-bash">emacs texto-secreto.org.gpg
</pre>
</div>

<p>
O bien abriendo un <i>buffer</i> nuevo con <code>C-x C-f</code> y escribiendo un
nombre de archivo que no exista. Cuando le digas a <i>emacs</i> que lo
guarde mostrará una lista de claves para que elijas cuál quieres usar
para el cifrado: seleccionas una con <code>m</code>, pulsas en <i>Ok</i> y de la
memoria del <i>buffer</i> pasará al disco ya cifrado. Cuando lo abres con <code>C-x
C-f</code> lo descifra para mostrarlo en el <i>buffer</i>, cuando lo guardas de
nuevo con <code>C-x C-s</code> vuelve a guardar la información cifrada (esta vez
ya no pregunta por la clave). Por lo tanto, en el disco duro <b>siempre</b>
se guarda cifrada la información. Aunque alguien pudiera acceder al
disco duro o incluso hacer una copia a bajo nivel del mismo, la
información nunca aparecerá <i>en claro</i>, sólo cifrada.
</p>

<p>
Si tenéis a mano el emacs y utilizáis claves <i>gnupg</i> probad los comandos:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">M-x epa-list-keys
</pre>
</div>

<p>
y
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">M-x epa-list-secret-keys
</pre>
</div>

<p>
El primer comando muestra la lista de claves públicas del sistema y el
segundo la lista de claves privadas. Esas listas permiten gestionar
las claves, por ejemplo al situar el cursor sobre una de las claves y
pulsar <code>&lt;enter&gt;</code> mostrará información sobre la misma: fecha de
creación, fecha de expirado, si puede cifrar, si puede firmar, etc.
</p>

<p>
Otro comando que puede ser útil es <code>epa-file-select-keys</code>, que permite
seleccionar la clave(s) pública(s) con la(s) que se cifrará el fichero
cargado en el <i>buffer</i>.
</p>
</div>
</div>
<div id="outline-container-org11157b6" class="outline-2">
<h2 id="org11157b6">Cifrar partes del fichero</h2>
<div class="outline-text-2" id="text-org11157b6">
<p>
En ocasiones no necesito cifrar todo, sólo la parte que contiene datos
personales u otro tipo de contenido que quiero (necesito) ocultar. En
ese caso simplemente selecciono la región de texto que quiero cifrar y
ejecuto el comando:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">M-x epa-encrypt-region
</pre>
</div>

<p>
Dentro del fichero de texto aparecerá una región con un aspecto
parecido a lo siguiente:
</p>

<pre class="example" id="org252f007">
-----BEGIN PGP MESSAGE-----

hQEMA/RDkQmHJoMPAQgAwrI+z1VToRnUxHarUHuiwzd5ah07yTN7LnmhdLWGaLeq
wIoO0bRvYZmyOAS0fbRWxGj7uLcyW3KNIwrQWi4UFnujfhSsqR8qK+G5haFsapk7
mQEqAkX6qLjIp7P104uyytd1bZSm+wK01f94gdaXEwmtwWxKmhjZcksw8QnPum8l
WvTnkWjeI1MZOIlG/NxcjbPPRQQv/ISZD+L3DbzmbMyQZuxgmCDeiazAkDWE5056
+xahCwLjllLwXLlBKOQYb39PVBh9myVqqT2fmbvQj2gld4yDL1DbNOojyCsmQ7VT
sOM0EA0yg2OCWj0axG/4wnojm86D2grIY5BoK8EBldJmAcpR8DXXc9o3c67Py4gf
/lmyg14KA1l/6ba35pY86WUTTxiTu+tZGjnDemSKnwdEuo6Q+RC5pgLThd2T8/Wg
Q5G6xGsrJtUypp1byCguIGDgiKmXkPnpsLwnjrD/8mnUngK8tF3X
=oDMU
-----END PGP MESSAGE-----
</pre>

<p>
También se puede meter la «zona» cifrada dentro de un fichero
cifrado. Aunque en este caso no le veo más utilidad que tener algunos
párrafos cifrados con otro par de claves, por si acaso la general del
fichero se viera comprometida o no confiáramos completamente en
ella. Luego sólo hay que marcar las líneas de <code>BEGIN PGP MESSAGE</code> a
<code>END PGP MESSAGE</code> y utilizar el comando <code>M-x epa-decrypt-region</code>,
preguntará si sustituye el texto cifrado. Si contestamos que sí,
desaparecerá el texto cifrado sustituido por su versión <i>en claro</i> y
si contestamos que no, nos mostrará el texto <i>en claro</i> en un <i>buffer</i>
temporal. Por lo que es recomendable, contestar que sí cuando queremos
hacer modificaciones y que no cuando sólo estamos consultando los
datos. Lo digo, porque alguna vez puede ocurrir que una vez
consultados los datos cerremos <i>bufferes</i> y no nos acordemos de volver
a cifrar lo descifrado.
</p>
</div>
</div>
<div id="outline-container-org3b89ff8" class="outline-2">
<h2 id="org3b89ff8">Integración con <i>Dired</i></h2>
<div class="outline-text-2" id="text-org3b89ff8">
<p>
Una de las cosas que también se pueden hacer es <i>firmar</i> los archivos
y <i>verificarlos</i>. Los comandos <code>epa-sign-file</code> y <code>epa-verify-file</code>
sirven para estos menesteres. Por supuesto, también podemos utilizar
<code>epa-encrypt-file</code> y <code>epa-decrypt-file</code> para cifrar y descifrar
cualquier fichero del disco. Además, nos permite realizar todas estas
operaciones desde <i>Dired</i>, el gestor de ficheros de <i>emacs</i>. Tan fácil
como marcar los archivos con los que vamos a trabajar, pulsar <code>: e</code> y
nos pedirá las claves para cifrar. Los comandos en <i>Dired</i> son:
</p>

<dl class="org-dl">
<dt><code>: d</code></dt><dd>Descifrar archivos marcados.</dd>
<dt><code>: v</code></dt><dd>Verificar archivos marcados.</dd>
<dt><code>: s</code></dt><dd>Firmar (<i>sign</i>) archivos marcados.</dd>
<dt><code>: e</code></dt><dd>Cifrar (<i>encrypt</i>) archivos marcados.</dd>
</dl>
</div>
</div>
<div id="outline-container-orga15ce46" class="outline-2">
<h2 id="orga15ce46">Dudas que tengo</h2>
<div class="outline-text-2" id="text-orga15ce46">
<p>
No estoy muy puesto en cómo funciona <i>GnuPG</i> más allá de necesitar una
clave y poder generarla. Estos días de atrás busqué a alguien que me
solucionara una duda sobre la caducidad de las claves. Lo pongo aquí
por si alguien de los que lleguen a leer esto sabe la contestación y
lo puede aclarar en los comentarios<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>

<p>
La clave que tengo configurada como principal está a punto de caducar,
le falta un mes. Tengo bastantes ficheros cifrados con esa clave y se
me plantean dos opciones: Extender la caducidad de la clave, que sería
la opción que se me ocurre de primeras. Crear una nueva y pasar los
ficheros a estar cifrados con ella (supongo que lo podría automatizar
con algún <i>script</i> con <i>elisp</i> o <i>guile</i> para no pasarme un par de
días sin hacer otra cosa).
</p>

<p>
¿Qué es más aconsejable? De momento pienso que alargaré la vida de la
clave un añito más, y si fuera más aconsejable el cambio iré haciendo
el modo durante ese tiempo.
</p>

<p>
Como he dicho antes, los archivos cifrados los guardo en un disco duro
externo dentro de una partición también cifrada por contraseña. El
tiempo de acceso es un poco lento, no desesperante, pero lento. ¿Hay
alguna forma ─sin perder seguridad─ de acelerar el proceso de carga y
guardado?
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Ten en cuenta que si ha pasado más de un mes desde la fecha de
publicación de este artículo, llegas tarde a dar consejos: la
contraseña habrá caducado. ;-)
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2018/10/05/cifrado-de-archivos-con-emacs.html</link>
  <pubDate>Fri, 05 Oct 2018 16:04:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[¿Cómo hablar de suicidio con los jóvenes?]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-09-27</div>
<p>
En esta página ya he hablado sobre <i>depresión</i>. De una manera
un poco informal y sin entrar demasiado en profundidad en un gran
problema humano. Hay que recordar, además, que la depresión mata. El
suicidio es un problema asociado que puede tener consecuencias
fatales. <a href="http://www.infocop.es/view_article.asp?id=7667&amp;amp;cat=50">Leo preocupado en la página de información del Consejo
General de la Psicología Español</a>, haciéndose eco de las
recomendaciones de la APA (<i>American Psychological Association</i>)
que abordan el tema del suicidio en niños y adolescentes. En dicho
artículo abren con la siguiente frase:
</p>

<blockquote>
<p>
El suicidio es la segunda causa de muerte entre los jóvenes de 15 a 24
años de edad. A pesar de la creencia común de que solo los
adolescentes y los adultos llevan a cabo comportamientos suicidas, los
niños más pequeños también pueden estar en riesgo.
</p>
</blockquote>

<p>
Hay que sensibilizar a padres y
profesores para que estén atentos a las señales de advertencia que
pueden lanzar nuestros niños y adolescentes. Los
<b>factores</b> son muchos pero podemos resumirlos en la
siguiente lista:
</p>

<ul class="org-ul">
<li>problemas de salud mental como la depresión,</li>
<li>la ansiedad y otros trastornos del estado de ánimo,</li>
<li>alcohol y uso de sustancias,</li>
<li>comportamientos compulsivos,</li>
<li>historia previa de trauma o abuso,</li>
<li>historia familiar de suicidio,</li>
<li>intento de suicidio previo</li>
<li>...</li>
</ul>

<p>
Si tratamos con menores con alguno de
esos factores debemos estar atentos a las <b>señales de 
advertencia</b>. Entre ellas podemos destacar, pero no son las
únicas:
</p>

<ul class="org-ul">
<li>cambios físicos en la apariencia o en los hábitos de higiene,</li>
<li>aumento en el consumo de alcohol o drogas,</li>
<li>disminución en las calificaciones escolares,</li>
<li>aislamiento social,</li>
<li>discursos sobre el suicidio o preocupación manifiesta por la muerte,</li>
<li>comportamientos peligrosos o imprudentes (como conducir de forma
imprudente o practicar sexo inseguro),</li>
<li>comportamientos autolesivos,</li>
<li>expresar sentimientos de desesperanza o manifestar no tener motivos
para vivir,</li>
<li>búsqueda de métodos de suicidio y/o adquisición de armas
(<i>evidentemente la preocupación por las armas es mayor en USA que en
nuestro país</i>).</li>
</ul>

<p>
Y si los padres detectan algunas de estas señales y/o comienzan a
temer que su hijo/a puede estar en un proceso autodestructivo ¿qué
pueden hacer? De la misma fuente se extraen algunas <b>acciones que
pueden poner en práctica para prevenir el suicidio</b>:
</p>

<ul class="org-ul">
<li><i><b>Dígaselo</b></i>: Expresar abiertamente su preocupación por el hecho
envía un claro mensaje de que hay alguien que cuida de él, a quien
le importa y quien se preocupa. No hay que hacer caso de quien dice
que hablar de <i>suicidio</i> con los jóvenes puede sembrar la idea en
ellos.</li>
<li><i><b>Escuche</b></i>: En muchas ocasiones los padres evitan las
conversaciones molestas, cambian de conversación e incluso llegan a
prohibir ciertos temas. Es muy importante escuchar cómo se siente
nuestro hijo/a y qué le está sucediendo.</li>
<li><i><b>Mantenga las relaciones sociales</b></i>: Una reacción lógica, inmediata
y, sin embargo, equivocada es «sobreproteger» al hijo o hija,
prohibiéndole salir, por ejemplo. Al contrario, debemos ayudarlo a
mantener sus relaciones sociales con amigos y demás gente
querida. Además, lo que podemos hacer es pasar más tiempo con él o
ella.</li>
<li><i><b>Comprensión</b></i>: Debemos estar al lado de nuestros hijos de forma
incondicional en estos momentos. Necesitan que les expresemos
nuestro amor y apoyo, necesitan saber que vamos a buscar la ayuda
que sea necesaria y que estaremos a su lado durante todo el proceso.</li>
<li><i><b>Confíe en su intuición</b></i>: Un joven que tenga pensamientos suicidas
siempre va a negarlos, si tiene sospechas de que esos pensamientos
pueden estar ahí, confíe en su intuición. Tome medidas,
especialmente las encaminadas a la seguridad (ver el punto
siguiente).</li>
<li><i><b>Priorice la seguridad</b></i>: Elimine cualquier medio que pueda tener
al alcance el menor para llevar a cabo el suicidio. Asegúrese de que
el niño o adolescente no se quede solo y consulte cuanto antes con
un profesional de la salud mental.</li>
</ul>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/depresión/index.html">depresión</a> <a href="/tags/suicidio/index.html">suicidio</a> ]]></description>
  <category><![CDATA[depresión]]></category>
  <category><![CDATA[suicidio]]></category>
  <link>https://notxor.nueva-actitud.org/2018/09/27/como-hablar-de-suicidio-con-los-jovenes.html</link>
  <pubDate>Thu, 27 Sep 2018 19:41:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Un poco más sobre magit]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-08-14</div>
<p>
Hace tiempo que vengo usando <code>magit</code> como una de esas cosas que
proporciona <i>Emacs</i> para facilitarnos la vida. Aún hace más tiempo
que, también, vengo tropezando con <code>git</code> y aunque lo uso para casi
todo, mi torpeza habitual evita que termine de entender exactamente
cómo funciona y cómo puedo aprovecharlo del todo. Por otro lado,
también he de confesar que desconozco muchos de sus comandos y
posibilidades.  Sin embargo, con el uso normal que vengo haciendo
últimamente de <code>git</code> he ido aprendiendo algunas pocas cosas. Con uso
<i>normal</i> me refiero a que últimamente lo estoy utilizando que para lo
que fue diseñado: para gestionar el código y sus versiones, con sus
ramas de desarrollo y demás <i>chismáticos</i>.
</p>

<p>
Hasta ahora mis repositorios venían siendo muy lineales, como el de la
contabilidad <a href="https://www.ledger-cli.org/">que llevo con <code>ledger-cli</code></a>, básicamente es una sola rama
<i>master</i> donde voy anotando gastos, facturas, ingresos y demás
apuntes. Vale que me permite saber no sólo cuándo se ha hecho un pago
o cobrado una factura, sino también, <code>git</code> me permite saber cuándo lo
he contabilizado y, ésto me ha ahorrado algún que otro quebradero de
cabeza buscando ese apunte en el que me confundí al escribir los
decimales, simplemente acotando cuándo dejaron de cuadrar las cuentas.
</p>

<p>
Sin embargo, eso aunque es utilizar <code>git</code>, no es un uso completo. Y no
es que haya avanzado mucho, pero he aprendido unas pocas cosas más y,
sobre todo, las he aprendido a hacer también utilizando <code>magit</code>.
</p>

<p>
Ya he hablado en alguna ocasión sobre <code>magit</code> y sus bondades, pero me
vais a permitir que me repita y hable un poco más sobre ello, desde
cero y haciendo un pequeño ejemplo de cómo puede ir el funcionamiento
de un repositorio desde su creación. Porque hay quien, no siendo
programador, quiere tener una idea más visual de lo que le hablo y me
ha preguntado directamente.
</p>

<p>
Los que vengan a este artículo y ya utilicen <code>git</code> quizá se aburran un
poco de mis explicaciones para novatos. Pero el caso es que escribo
esto para quien me ha preguntado y está recién llegado al control de
versiones.
</p>
<div id="outline-container-orgbbe84b6" class="outline-2">
<h2 id="orgbbe84b6">Iniciar repositorio</h2>
<div class="outline-text-2" id="text-orgbbe84b6">
<p>
Pues el inicio es sencillo si queremos iniciar un pequeño repositorio:
<code>magit-init</code> pregunta dónde y le damos un <code>path</code> donde debe iniciarlo:
</p>


<figure id="orgfa2e480">
<img src="./imagen/Captura-pantalla-crear-repositorio.png" alt="Captura-pantalla-crear-repositorio.png">

</figure>

<p>
Si le hemos dado un <i>path</i> que no existe, lo crea y genera dentro de
él un repositorio <code>git</code> vacío... aunque propone algo para rellenarlo
de momento:
</p>


<figure id="org48b5d25">
<img src="./imagen/Captura-pantalla-repositorio-creado.png" alt="Captura-pantalla-repositorio-creado.png">

</figure>

<p>
En el caso del ejemplo, he creado un repositorio en un directorio
llamado <code>~/proyectos/repositorio-prueba</code>. Está vacío, no he escrito
nada, no hay ningún fichero ni contiene nada. Si miramos el directorio
veremos que contiene sólo el subdirectorio oculto <code>.git</code> con los datos
del repositorio.
</p>

<p>
A ese repositorio le vamos a dar otro repositorio <i>origen</i>, que podría
ser el compartido. Me vais a permitir que yo utilice para las pruebas
directorios locales del ordenador, pero cuando se crea un repositorio
<i>bare</i>, pregunta por la localización del mismo: podemos seleccionar
entre una URL, un directorio o un repositorio <i>local</i>.
</p>


<figure id="org4c14e86">
<img src="./imagen/Captura-pantalla-clone-bare.png" alt="Captura-pantalla-clone-bare.png">

</figure>

<p>
y nos permite clonarlo en cualquier sitio. Para las pruebas lo he
clonado en <code>~/repositorio-prueba</code>... y el resultado es el siguiente:
</p>


<figure id="org1747327">
<img src="./imagen/Captura-pantalla-repositorios.png" alt="Captura-pantalla-repositorios.png">

</figure>

<p>
Como se puede apreciar en la imagen, a la derecha tenemos un
repositorio <i>bare</i> (es decir, por explicarlo de otra manera para quien
aún sepa menos que yo sobre <code>git</code>, no tiene los ficheros de código
directamente, pero guarda los objetos que lo contienen). Este tipo de
repositorios se utilizan, no para editar código sino para guardarlo y
por tanto suelen tener la función de <i>repositorios remotos</i>. De hecho,
<code>magit</code> preguntará al crear el <i>bare</i> si lo queremos usar como
<code>origin</code> ─que es el nombre que se le da normalmente al repositorio
remoto original─.
</p>
</div>
</div>
<div id="outline-container-orgd204ebc" class="outline-2">
<h2 id="orgd204ebc">Modificar algo en el repositorio</h2>
<div class="outline-text-2" id="text-orgd204ebc">
<p>
Para nuestro ejemplo necesitamos crear algún fichero que gestionar con
nuestro flamante repositorio. Así pues, vamos a crear un fichero de
texto en nuestro directorio de trabajo (que vuelvo a recordar que es
<code>~/proyectos/repositorio-prueba</code>, por si alguien se despista).
</p>

<p>
Una vez creado el texto, que no tiene por qué ser muy largo para hacer
las pruebas, vamos a incorporarlo a nuestro repositorio. Primero, al
acceder a <code>magit</code> nos dice que el fichero no está siendo gestionado
por <code>git</code>.
</p>


<figure id="org07dab17">
<img src="./imagen/Captura-pantalla-untracked-files.png" alt="Captura-pantalla-untracked-files.png">

</figure>

<p>
Bien, situándonos en la línea de nuestro fichero, el que queremos
añadir pulsamos <code>s</code> (<i>stage</i>):
</p>


<figure id="org8e52510">
<img src="./imagen/Captura-pantalla-staged-file.png" alt="Captura-pantalla-staged-file.png">

</figure>

<p>
Ya tenemos los cambios aceptados, vamos a decirle al repositorio
<i>local</i> que los guarde haciendo un <code>commit</code>. Para eso, siguiendo en la
ventana de <code>magit</code> pulsamos <code>cc</code> (sí, dos veces <code>c</code>, la primer <code>c</code>
muestra el menú de <code>commit</code> y la segunda inicia el <code>commit</code>, porque en
este ejemplo no necesitamos otras opciones) y nos mostrará una ventana
como ésta o similar:
</p>


<figure id="org8e8d630">
<img src="./imagen/Captura-pantalla-haciendo-commit.png" alt="Captura-pantalla-haciendo-commit.png">

</figure>

<p>
Como podemos ver, nos muestra una ventana de <code>diff</code> donde podemos ver
los cambios que vamos a incluir en el <code>commit</code> y, en este caso abajo,
nos pide un texto para el <code>commit</code>. Sólo tenemos que introducir el
texto explicativo de lo que sea que estamos subiendo y cuando acabemos
pulsar <code>C-c C-c</code>... si en este paso nos arrepentimos, por ejemplo,
porque se nos ha olvidado añadir algo o nos damos cuenta de que algo
no anda bien, podemos pulsar <code>C-c C-k</code> y se detiene el proceso del
<code>commit</code>. También lo podemos hacer por partes, dividir los cambios en
diversos <i>commits</i>, etc., pero lo dejamos para los usuarios <i>pro</i>. De
momento, todo anda bien así que aceptamos los cambios:
</p>


<figure id="orgdd96db6">
<img src="./imagen/Captura-pantalla-primer-commit.png" alt="Captura-pantalla-primer-commit.png">

</figure>

<p>
Podemos ver, que por defecto, nos encontramos en la rama <code>master</code> (y
recordad, que si sólo aparece la cabecera <code>Recent commits</code> podéis
desplegar la lista pulsando <code>&lt;TAB&gt;</code> sobre ella).
</p>

<p>
Hasta ahora los cambios sólo han afectado al repositorio <i>local</i>. Pero
en la primera parte del artículo, habíamos creado un <i>bare</i> con la
intención de utilizarlo de <i>remoto</i>. Y nuestros cambios están muy bien
en nuestro repositorio local, pero si compartimos el remoto con
alguien más, necesitamos que esos colaboradores puedan acceder a
ellos.
</p>
</div>
<div id="outline-container-orgef0aadc" class="outline-3">
<h3 id="orgef0aadc">Añadir un repositorio remoto</h3>
<div class="outline-text-3" id="text-orgef0aadc">
<p>
Para añadir un repositorio remoto utilizamos el comando
<code>magit-remote-add</code>, nos pedirá una URL. En nuestro caso, creamos en
pasos anteriores un repositorio <i>bare</i> en <code>~/repositorio-prueba</code> para
que nos sirva de remoto. Nos preguntará también por un nombre y el más
preferible para el repositorio principal suele ser <code>origin</code>, aunque
podemos utilizar otros.
</p>
</div>
</div>
<div id="outline-container-org796ce42" class="outline-3">
<h3 id="org796ce42">Sincronizar los dos repositorios</h3>
<div class="outline-text-3" id="text-org796ce42">
<p>
Para subir cambios a un repositorio remoto pulsamos <code>P</code>, o <code>S-p</code>, si lo
preferís así... vamos lo que viene a ser una <i>pe</i> con mayúsculas. Nos
aparecerá un diálogo como el siguiente:
</p>


<figure id="org4542ce7">
<img src="./imagen/Captura-pantalla-iniciando-push.png" alt="Captura-pantalla-iniciando-push.png">

</figure>

<p>
Es el primer <code>push</code> que vamos a hacer y necesitamos fijar dónde, vamos
a pulsar <code>u</code>, nos preguntará algo como <i>Set upstream of master and
push there</i> y puesto que ya habíamos establecido el repositorio
remoto con el nombre <code>origin</code> nos muestra lo siguiente:
</p>


<figure id="orgb69e731">
<img src="./imagen/Captura-pantalla-primer-push.png" alt="Captura-pantalla-primer-push.png">

</figure>

<p>
Y al pulsar <code>&lt;RET&gt;</code>:
</p>


<figure id="orgd836ebf">
<img src="./imagen/Captura-pantalla-repositorios-sincronizados.png" alt="Captura-pantalla-repositorios-sincronizados.png">

</figure>

<p>
Como vemos, nuestro <code>HEAD</code> está en el mismo <code>commit</code> que el
<code>origin/master</code> y, además, en los <i>commits</i> recientes nos marca ambos
en el mismo lugar.
</p>

<p>
Quizá si hacemos cambios podemos ver la diferencia cuando dejan de
estar sincronizados. Escribo un par de líneas más y repito el proceso
del <code>commit</code> en local para ver la diferencia:
</p>


<figure id="org6026077">
<img src="./imagen/Captura-pantalla-commit-sin-subir.png" alt="Captura-pantalla-commit-sin-subir.png">

</figure>

<p>
Como vemos, nuestro <code>HEAD</code> local está en un <code>commit</code> mientras que el
repositorio remoto está en el anterior. <code>Magit</code> además nos avisa de
que hay algunos <i>commits</i>, ─en concreto <code>(1)</code>, dice─ que están sin
subir al remoto. ¿Cómo los sincronizamos de nuevo? Pues como hicimos
antes, pero más fácil: <code>P u</code>... si nuestro remoto es de verdad y nos
conectamos a él por <code>SSH</code> o por cualquier otro método, nos pedirá la
contraseña correspondiente y todo vuelve a estar sincronizado.
</p>
</div>
</div>
</div>
<div id="outline-container-org348e2ec" class="outline-2">
<h2 id="org348e2ec">Ramas</h2>
<div class="outline-text-2" id="text-org348e2ec">
<p>
El proceso hasta ahora ha sido sencillo y lineal, crear un
repositorio, hacer modificaciones, subir cambios al remoto... para
muchas cosas sirve, pero es posible que necesitemos más potencia a
esto de los cambios. ¿Qué ocurre si necesitamos probar algo pero
sabemos que los cambios que debemos hacer para probarlo son difíciles
de revertir? Estaría bien, poder hacer pruebas y sin embargo, que el
código no se vea afectado por dichas pruebas hasta estar seguros de
que es lo que queremos y funcionan. Para eso se inventaron las ramas
(<i>branch</i> en inglés). Otro ejemplo, que podríamos considerar con ramas
fácilmente es uno que en la vida real nos da mucho trabajo: cuando
tenemos entre manos un informe y nos piden que modifiquemos algo para
presentarlo en otro lugar o a otra institución o a otro cliente. El
<i>instinto básico</i> copiaría el mismo informe en otro sitio, con otro
nombre, se harían los cambios necesarios y se guardarían en otro
sitio, con otro nombre. Pero, si hubiera cambios en algún apartado
común tendrías que estar buscando en cada una de esas copias y
haciendo los cambios que correspondan. Bien, un control de versiones
como <code>git</code> nos facilitará mucho ese <i>versionado</i>, atendiendo a las
ramas, cada informe estaría en una rama con nombre adecuado. Los
aparados de cada uno en su correspondiente rama, y los generales en la
rama <code>master</code>. Y así es cómo estoy gestionando estas cosas ahora: los
contenidos suelo hacerlos en <code>org-mode</code> o <i>LaTeX</i>, según el caso, pero
ambos son texto plano que puedo meter en un repositorio, aunque sea
local o en <i>mi nube</i> particular o en un repositorio compartido (si es
el caso).
</p>
</div>
<div id="outline-container-org3236f95" class="outline-3">
<h3 id="org3236f95">Crear una rama</h3>
<div class="outline-text-3" id="text-org3236f95">
<p>
En el momento en que creamos una rama, todos los cambios que hagamos
en ella no afectarán al <i>tronco</i> del que nace. Vamos a crear en nuestro
proyecto una rama con <code>magit</code>, paso a paso, como hemos venido haciendo
hasta ahora:
</p>


<figure id="orge1fa66c">
<img src="./imagen/Captura-pantalla-crear-rama-punto-partida.png" alt="Captura-pantalla-crear-rama-punto-partida.png">

</figure>

<p>
Si nos fijamos en la línea de estado, nos especifica que estamos en
<code>Git-master</code>. A mí me gusta crear una rama y cambiarme a ella
inmediatamente, por eso suelo utilizar <code>magit-branch-and-checkout</code> más
que <code>magit-branch-create</code>... pero se puede crear la rama y permanecer
en la anterior, hacer lo que se necesite y cambiar a la rama creada
posteriormente. Cuando iniciamos el comando, después de solicitar la
creación de la rama, nos preguntará en cuál otra queremos basar la
nueva rama:
</p>


<figure id="org5166ec7">
<img src="./imagen/Captura-pantalla-crear-rama-punto-partida.png" alt="Captura-pantalla-crear-rama-punto-partida.png">

</figure>

<p>
No tenemos mucho donde elegir, sólo una: <code>master</code>. Así pues, la
seleccionamos y después nos preguntará por el nombre de la nueva
rama. En mi caso he seleccionado uno tan descriptivo como
<code>rama-nueva</code>. Pero recuerda que en el caso de ser un repositorio de
trabajo, es recomendable utilizar nombres más descriptivos para no
liarnos. Sobre todo si se van a utilizar muchas ramas.
</p>


<figure id="org986a9a7">
<img src="./imagen/Captura-pantalla-dar-nombre-rama.png" alt="Captura-pantalla-dar-nombre-rama.png">

</figure>

<p>
¿Cómo afecta todo esto a nuestro repositorio? Pues lo vemos en la
siguiente imagen:
</p>


<figure id="org7fa06fd">
<img src="./imagen/Captura-pantalla-rama-creada.png" alt="Captura-pantalla-rama-creada.png">

</figure>

<p>
Los cambios remarcables son sencillos:
</p>

<ol class="org-ol">
<li>La barra de estado nos avisa que estamos en la rama
<code>Git-nueva-rama</code>.</li>
<li>Nuestro <code>HEAD</code> está en <code>nueva-rama</code> y también nos avisa de que no
existe la rama remota <code>origin/nueva-rama</code>.</li>
<li>El <i>commit</i> actual es el mismo en el que creamos la rama. Así que
ahora mismo el estado de <code>rama-actual</code> coincide con las ramas
<code>master</code> y <code>origin/master</code>, porque es en el que hemos basado la
rama nueva.</li>
</ol>

<p>
Para que todo fluya, vamos a hacer cambios en esta rama y compararemos
qué ocurre con esos cambios. Por ejemplo, vamos a crear otro fichero
de texto nuevo y a añadirlo al proyecto.
</p>


<figure id="orgf656221">
<img src="./imagen/Captura-pantalla-nuevo-fichero-rama.png" alt="Captura-pantalla-nuevo-fichero-rama.png">

</figure>

<p>
El proceso de <i>stage</i> → <i>commit</i> → <i>push</i> es idéntico al que hemos
hecho para el fichero anterior. La diferencia es que la rama remota no
existe y vamos a crearlo. Al hacer el <i>push</i> seleccionamos <code>u</code>
</p>


<figure id="orge0f85ad">
<img src="./imagen/Captura-pantalla-push-nueva-rama.png" alt="Captura-pantalla-push-nueva-rama.png">

</figure>

<p>
Nos dirá que la rama remota no existe y que qué rama utiliza para el
<i>push</i> y entre las opciones aparecerá una con la opción con el nombre
<code>origin/nueva-rama</code>
</p>


<figure id="orgab07ba3">
<img src="./imagen/Captura-pantalla-crear-rama-remota.png" alt="Captura-pantalla-crear-rama-remota.png">

</figure>

<p>
Al seleccionar dicha opción creará una nueva rama en el repositorio
remoto con nuestro contenido. ¿Qué nos dice <code>magit</code> sobre todo esto?
Pues vamos a fijarnos en la siguiente imagen.
</p>


<figure id="org1708c90">
<img src="./imagen/Captura-pantalla-rama-avanzada.png" alt="Captura-pantalla-rama-avanzada.png">

</figure>

<p>
Si nos fijamos nuestro <code>HEAD</code> sigue en <code>nueva-rama</code>, un <i>commit</i> más
avanzado que antes. Si miramos los <i>commits</i> recientes veremos que
atrás, ─un <i>commit</i> por debajo─, se queda la rama <code>master</code>, tanto la
local como la remota.
</p>

<p>
¿Qué ocurre si cambiamos de rama? Pues vamos a verlo: <code>magit-checkout</code>
y nos dejará seleccionar a qué rama queremos mudarnos. En nuestro caso
seleccionaremos <code>master</code> que es una rama local y obtendremos algo como
</p>


<figure id="org6b973a2">
<img src="./imagen/Captura-pantalla-cambiar-a-master.png" alt="Captura-pantalla-cambiar-a-master.png">

</figure>

<p>
¿Eh? El fichero nuevo que con tanta dedicación he hecho, ¡ha
desaparecido! ¡Maldición! ¡Córcholis! ¡Cáspita! (Hmmm, no se me
ocurren más <i>tontás</i> que decir, ya si eso otro día sigo con las
imprecaciones ñoñas).
</p>

<p>
Pues eso, han desaparecido todos los cambios que hubiéramos hecho en
la rama... NO, simplemente están en la otra rama. Si volvemos a
cambiar de rama volverán a aparecer. Ahora mismo tenemos dos versiones
independientes, por decirlo de algún modo, de nuestro trabajo.
</p>
</div>
</div>
<div id="outline-container-org0e891ea" class="outline-3">
<h3 id="org0e891ea">Fetsh y pull</h3>
<div class="outline-text-3" id="text-org0e891ea">
<p>
Pues como suponemos que nuestro repositorio es compartido, es posible
que alguien suba modificaciones al mismo. Ese hecho hará que nuestro
repositorio local esté fuera de sincronía también: ¿cómo volvemos a
sincronizar el repositorio local con el remoto? Pues tenemos dos
opciones <code>fetsh</code> o <code>pull</code>... veamos cómo hacerlo desde <code>magit</code>:
</p>

<ol class="org-ol">
<li><p>
Desde la ventana de <code>magit</code>, pulsamos <code>f</code>, si queremos hacer
<code>fetch</code>, o <code>F</code>, si queremos hacer <code>pull</code>.
</p>


<figure id="org803e159">
<img src="./imagen/Captura-pantalla-inicio-fetch.png" alt="Captura-pantalla-inicio-fetch.png">

</figure></li>

<li><p>
El diálogo que aparece nos permite seleccionar el repositorio, si
hubiera más de uno, del que queremos bajar los cambios remotos.
Pulsamos <code>u</code> para que baje los de <code>origin</code>. Y nuestro repositorio
nos informa, de que efectivamente tenemos cambios sin actualizar,
véase el apartado de <code>Unpulled from...</code> en la ventana:
</p>


<figure id="org6eb6763">
<img src="./imagen/Captura-pantalla-fetch-unpulled.png" alt="Captura-pantalla-fetch-unpulled.png">

</figure></li>

<li><p>
Mirando los cambios que han hecho decidimos que son correctos y los
importamos a nuestro repositorio con <code>F</code>, que como he dicho antes,
lo que hace es un <code>pull</code>.
</p>


<figure id="org9619bc0">
<img src="./imagen/Captura-pantalla-pull-hecho.png" alt="Captura-pantalla-pull-hecho.png">

</figure></li>
</ol>

<p>
Ya tenemos nuestro repositorio local de nuevo sincronizado con el
remoto. Además hemos introducido la imponderable variable del trabajo
en equipo y vemos que podemos trabajar en paralelo. Aunque seguro que
encontraremos ocasiones en las que nuestros cambios entren en
conflicto con los cambios de otros... no nos precipitemos.
</p>
</div>
</div>
<div id="outline-container-org9f61d9e" class="outline-3">
<h3 id="org9f61d9e">Rebase</h3>
<div class="outline-text-3" id="text-org9f61d9e">
<p>
Al principio entendía <code>rebase</code> como <i>superar</i> o <i>adelantar</i> y el
concepto se me rompía en las entendederas. Al final, me he
acostumbrado a entenderlo como <i>poner base de nuevo</i> o <i>cambiar la
base</i> de la rama (gracias a <i>deesix</i> del IRC, que supo darle el
enfoque al concepto que hizo <code>click</code> en mi cuadriculada mente).
</p>

<p>
Como hemos visto antes, nuestra rama <code>master</code> ha cambiado y nuestra
rama tiene cosas que no están allí y por otro lado la rama <code>master</code>
tiene cosas que nuestra rama de trabajo local no tiene. ¿Podemos hacer
que esos cambios vengan a mi rama de trabajo para tenerlos en cuenta?
</p>

<p>
Pues sí, podemos hacerlo con un <code>rebase</code>. Atención: para modificar el
contenido de cualquier rama debemos situarnos en la rama que debe
cambiar. En nuestro caso, la rama <code>rama-nueva</code> va a cambiar su
contenido base, se va a <i>rebasar</i> (volver a basar) en <code>master</code>. Por
tanto, vamos a asegurarnos que estamos en la rama adecuada:
<code>magit-checkout</code> y seleccionamos <code>rama-nueva</code>. Todo debe cambiar a
algo como:
</p>


<figure id="org5c041c4">
<img src="./imagen/Captura-pantalla-inicio-rebase.png" alt="Captura-pantalla-inicio-rebase.png">

</figure>

<p>
Observa que la rama en la línea de estado del fichero que está abierto
es, efectivamente <code>Git-nueva-rama</code> y además en nuestra ventana de
<code>magit</code> el <code>HEAD</code> apunta a la misma rama. Pues nada, hechas las
comprobaciones necesarias pulsamos <code>r</code> y nos aparece el menú de
opciones del <code>rebase</code>
</p>


<figure id="org1b2e0a0">
<img src="./imagen/Captura-pantalla-menu-rebase.png" alt="Captura-pantalla-menu-rebase.png">

</figure>

<p>
Seleccionamos <code>e</code> (<i>elsewhere</i>) y después la rama <code>master</code> y...
¡Mierda! ¡Ya han «tocao argo» y falla el rebase! ¿Pero qué ha fallado?
pues pulsamos <code>$</code> como nos dice el aviso de error y vamos a ver:
</p>


<figure id="orgf0d9113">
<img src="./imagen/Captura-pantalla-rebase-error.png" alt="Captura-pantalla-rebase-error.png">

</figure>

<p>
Bien, parte del contenido se ha añadido, pero tenemos otra parte que
no en el apartado <code>Unstaged changes</code> del <code>magit</code>. Pulsamos <code>&lt;RET&gt;</code>
sobre dicha cabecera y nos mostrará el conflicto:
</p>


<figure id="org65f9fc4">
<img src="./imagen/Captura-pantalla-conflicto-rebase.png" alt="Captura-pantalla-conflicto-rebase.png">

</figure>

<p>
Bien vale, ahí está el problema (ya se ve que está hecho a propósito
para que falle... pero hay veces que no y el problema no lo puede
resolver el programa él solo y necesita que lo resolvamos nosotros).
¿Cuál es el texto bueno? Pues en esa ventana de <code>diff</code> volvemos a
pulsar <code>&lt;RET&gt;</code>... esto nos debe llevar al fichero que ha generado el
conflicto.
</p>


<figure id="org3b07635">
<img src="./imagen/Captura-pantalla-arreglar-conflicto-antes.png" alt="Captura-pantalla-arreglar-conflicto-antes.png">

</figure>

<p>
Vemos que <i>Emacs</i> nos remarca las partes que entran en conflicto con
colores, aprovechando que <code>git</code> nos los marca entre las etiquetas
<code>&lt;&lt;&lt;&lt;&lt;&lt;&lt;</code> y <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt;</code> y además separados por la etiqueta <code>=======</code>
</p>

<pre class="example" id="org83a094b">
&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD
Esto es un texto nuevo que debería entrar en conflicto con el ya
existente.

Ahora veremos si colisiona.
=======
Este texto, es nuevo y viene a ilustrar cómo funcionan estas cosas de
las ramas.

Tampoco voy a escribir mucho más para no perder el tiempo.
&gt;&gt;&gt;&gt;&gt;&gt;&gt; 1b03c62... Nuevo fichero en la rama «repositorio-prueba»
</pre>

<p>
Cambiamos el texto corrigiendo lo que haga falta. Cuando quitemos esas
etiquetas, el texto dejará de marcarse en colores. Para el ejemplo, lo
he modificado a algo así:
</p>

<pre class="example" id="org06da8af">
Esto es un texto nuevo que debería entrar en conflicto con el ya
existente.

Ahora veremos si colisiona...

Efectivamente han colisionado y lo tenemos que arreglar a mano.

Este texto, es nuevo y viene a ilustrar cómo funcionan estas cosas de
las ramas.

Tampoco voy a escribir mucho más para no perder el tiempo.
</pre>


<figure id="org8018821">
<img src="./imagen/Captura-pantalla-conflicto-corregido.png" alt="Captura-pantalla-conflicto-corregido.png">

</figure>

<p>
Bien, ya hemos corregido el error ¿y ahora qué? Pues vamos, lo primero
a guardar los cambios y después vamos a la etiqueta <code>Unstaged changes</code>
que mencionamos antes y pulsamos <code>s</code> (<i>stage</i> en inglés) para
indicarle a <code>git</code> que ya hemos resuelto los cambios y lo tenemos todo
listo para continuar nuestro <i>accidentado</i> rebase. ¿Os acordáis de qué
tecla lanzaba el <code>rebase</code>? ¿Sí? efectivamente, pulsamos la misma tecla
<code>r</code> y nos aparece el siguiente menú:
</p>


<figure id="org9f22f60">
<img src="./imagen/Captura-pantalla-continuar-rebase.png" alt="Captura-pantalla-continuar-rebase.png">

</figure>

<p>
Efectivamente, entre las opciones debemos elegir <code>continuar</code> el rebase
pulsando de nuevo la tecla <code>r</code> y nos pedirá hacer un <i>commit</i> con el
contenido que hemos tenido que arreglar a mano.
</p>


<figure id="org7ad2d51">
<img src="./imagen/Captura-pantalla-commit-resolucion-conflicto.png" alt="Captura-pantalla-commit-resolucion-conflicto.png">

</figure>

<p>
Podemos dejar el mensaje tal cual, pero a mí me gusta avisar que he
tenido que resolver los conflictos a mano, también para avisar a quien
haya hecho los cambios, que algunas cosas que encuentre en su código o
fichero, no coincidirán con lo que escribió.
</p>
</div>
</div>
<div id="outline-container-org46929bc" class="outline-3">
<h3 id="org46929bc">Merge</h3>
<div class="outline-text-3" id="text-org46929bc">
<p>
Resueltos todos los conflictos que encontremos podemos seguir con
nuestras modificaciones, hacer nuestros <code>commits</code>, y todo el trabajo
como hasta ahora. Pero llega un momento que nuestro trabajo va a
necesitar estar en <code>master</code>... ¿cómo hacemos para llevar nuestra rama
a otra? (en este caso a <code>master</code>). Pues para eso se inventó el <code>merge</code>
que es el proceso por el que los contenidos se <i>mezclan</i>. Igual que
antes con el <code>rebase</code>, vamos a situarnos en la rama que recibe los
cambios, en nuestro caso <code>master</code>... y también tienes que estar
preparado para que aparezcan conflictos (pero como ya sabes que es
relativamente sencillo sobreponerse a ellos, pues adelante sin miedo).
</p>

<p>
Por pasos:
</p>

<ol class="org-ol">
<li>Nos situamos en la rama que recibe los cambios: <code>magit-checkout</code> y
seleccionamos <code>master</code>.</li>
<li><p>
En la ventana de <code>magit</code>, pulsamos <code>m</code> (<i>merge</i> en inglés).
</p>


<figure id="orgab061c8">
<img src="./imagen/Captura-pantalla-menu-merge.png" alt="Captura-pantalla-menu-merge.png">

</figure></li>

<li>En este caso utilizo la combinación <code>-n</code>, para añadir el
equivalente de línea de comandos <code>--no-ff</code> y después <code>m</code> para
realizar el <code>merge</code>.</li>

<li>Nos pregunta qué rama queremos «mergear» y en nuestro caso
seleccionamos <code>rama-nueva</code>.</li>
</ol>

<p>
Si todo ha ido bien, como es de esperar en el ejemplo, porque los
conflictos venían resueltos de antes y nadie más (es decir, yo
haciendo de mi <i>alter ego</i> el <i>enano cabrón que me jode los commits</i>)
pues hemos acabado el <code>merge</code>.
</p>

<p>
Si se presentaran conflictos, pues tendríamos que hacer como antes:
arreglar el texto a mano, ir guardando, hacer más <code>commits</code>... lo que
necesitemos para dejar todo listo y suave.
</p>
</div>
</div>
<div id="outline-container-orgf4026d0" class="outline-3">
<h3 id="orgf4026d0">Log</h3>
<div class="outline-text-3" id="text-orgf4026d0">
<p>
Una forma de tener de un vistazo el repositorio con su historial de
<i>commits</i> es el comando <code>magit-log</code> que como su nombre indica, igual
que todos los comandos que venimos viendo es el equivalente de <code>git
log</code>. ¿Qué ventajas tiene la <i>interface</i> de <i>Emacs</i>? Vamos a ver cómo
está nuestro repositorio pulsando <code>l</code> (<i>log</i> en inglés), en la ventana
de <code>magit</code>. Nos aparecerá el menú para abrir la pantalla de <code>log</code>:
</p>


<figure id="org2daafc3">
<img src="./imagen/Captura-pantalla-menu-log.png" alt="Captura-pantalla-menu-log.png">

</figure>

<p>
Aprovechando este menú, remarco las opciones que están activadas. Si
pulsamos un <code>-</code> se supone que queremos introducir alguna opción,
limitando la búsqueda u otros parámetros. En nuestro caso, vamos a
pulsar <code>b</code> para que nos muestre todas las ramas y nos aparecerá una
lista con los <code>commits</code> que hemos ido haciendo. Nuestra lista es muy
simple, pero cuando empiezan a aparecer ramas, la cosa se complicará
más.
</p>


<figure id="org53f576b">
<img src="./imagen/Captura-pantalla-magit-log.png" alt="Captura-pantalla-magit-log.png">

</figure>

<p>
Pulsando <code>&lt;RET&gt;</code> en cualquiera de la línea nos mostrará los detalles
del <code>commit</code>:
</p>


<figure id="org4632127">
<img src="./imagen/Captura-pantalla-log-visual-commit.png" alt="Captura-pantalla-log-visual-commit.png">

</figure>
</div>
</div>
</div>
<div id="outline-container-org5a0d514" class="outline-2">
<h2 id="org5a0d514">Conclusiones</h2>
<div class="outline-text-2" id="text-org5a0d514">
<p>
<code>git</code> es una excelente herramienta y no sólo sirve para gestionar
código. Cualquier cosa, sobre todo si está en texto plano, puede
beneficiarse de las ventajas que esta herramienta nos proporciona.
Puedes hacer modificaciones sin miedo, siempre puedes revertir los
cambios, volver a un <code>commit</code> anterior, abandonar una rama que no da
los resultados esperados, etc.
</p>

<p>
He explicado apenas unas pocas cosas, sin meterme en complicaciones de
pasar archivos entre ramas o cosas de pro... como hacer los <code>stages</code>
por partes (si eres curioso, tan sólo pulsa <code>&lt;TAB&gt;</code> en los cambios que
esperan ser cargados, muévete a la parte que quieras y pulsa <code>s</code>
(<i>stage</i>) en las líneas que quieras. Verás que el resto sigue marcado
como <code>unstaged</code>). Aún, a pesar de no haber profundizado mucho, este
artículo es uno de los más largos que he escrito en el <i>blog</i>. También
porque está dirigido a personal <i>no-programador</i> que me ha preguntado
por esta herramienta, y creo que la guía visual de los pasos le vendrá
muy bien para manejarse, junto con un poco de <code>git</code> que ya sabe, con
la herramienta de <code>magit</code> de <i>Emacs</i>.
</p>

<p>
A los programadores que lean esto, les parecerá, quizá, un artículo
muy básico, porque hablo de herramientas que quizá ellos utilizan
todos los días y a las que están acostumbrados. Siento haberos
aburrido.
</p>

<p>
Y aquí acabo otro de esos artículos suicidas escritos a toda prisa sin
que reposen en el estado de borradores. Ya me perdonarán las
disculpas.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/git/index.html">git</a> <a href="/tags/magit/index.html">magit</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[git]]></category>
  <category><![CDATA[magit]]></category>
  <link>https://notxor.nueva-actitud.org/2018/08/14/un-poco-mas-sobre-magit.html</link>
  <pubDate>Tue, 14 Aug 2018 21:01:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Avances en el proyecto de la isla]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-08-01</div>
<div id="outline-container-org232014f" class="outline-2">
<h2 id="org232014f">Primer <i>post</i> del año nuevo</h2>
<div class="outline-text-2" id="text-org232014f">
<p>
Aprovechando la paz que deja la primera mañana del año: todo el mundo
duerme en casa mientras yo ya ando por ahí «con mis cosas», quería
escribir el primer <i>post</i> del año 2018. Espero que este año sea
propicio a todo el Mundo.
</p>
</div>
</div>
<div id="outline-container-org4ffb009" class="outline-2">
<h2 id="org4ffb009">El proyecto</h2>
<div class="outline-text-2" id="text-org4ffb009">
<p>
Bueno, no quiero liarme demasiado con las felicitaciones del año
nuevo, en realidad supongo que, aunque lo desee, no habrá cambios
sustanciales en cómo marcha el mundo. Por eso lo dejaremos estar y
mejor me concentro en el motivo de este <i>post</i>.
</p>

<p>
Ya hablé de él en un <a href="https://notxor.nueva-actitud.org/blog-antiguo/un-poco-de-abandono.html">primer <i>post</i> sobre el proyecto</a>, y seguí
haciéndolo en un <a href="https://notxor.nueva-actitud.org/blog/2017/11/02/viaje-a-una-isla-imaginaria/">segundo <i>post</i> sobre el proyecto</a>. Este será por tanto
el tercer <i>post</i>... y como veis, sé contar hasta tres.
</p>

<p>
Ha habido algunos avances, sobre todo en guión y cosas no visibles. El
equipo de personas va aumentando. Se añade gente voluntariosa que le
va gustando lo que ve. A algunos les hemos pasado un vídeo, hecho con
una captura de pantalla algo torpe que he hecho estos días para que se
vea lo que tenemos en movimiento.
</p>

<video width="100%" controls>
    <source src="./archivo/2018-01-01-video-isla.webm" type="video/webm">
    Tu navegador no soporta la etiqueta video, comprueba que soporta el formato webm.
</video>

<p>
Lo enlazo aquí con la intención de tenerlo a mano. Es un vídeo
aburrido, sin sonido y tan sólo ilustra uno de los pocos comandos que
tenemos implementados: el de <i>ir</i> a los sitios. El modelado <i>lowpoly</i>
se puede apreciar, a pesar de la mala calidad del vídeo.
</p>

<p>
Quedan mucho por modelar, terminar el guión y el diseño de los puzles,
animaciones, detalles que pulir, mucho código que escribir... pero
poco a poco seguimos avanzando.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/conversacionales/index.html">conversacionales</a> <a href="/tags/juegos/index.html">juegos</a> <a href="/tags/blender/index.html">blender</a> ]]></description>
  <category><![CDATA[conversacionales]]></category>
  <category><![CDATA[juegos]]></category>
  <category><![CDATA[blender]]></category>
  <link>https://notxor.nueva-actitud.org/2018/08/01/avances-en-el-proyecto-de-la-isla.html</link>
  <pubDate>Wed, 01 Aug 2018 10:43:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Viaje a Ciria]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-07-15</div>
<p>
Alguien me pidió que si iba a Ciria a unas jornadas de tecnología
contara mis impresiones y que, como agradecía la extensión, lo hiciera
en un <i>post</i> del <i>blog</i>. El resultado de cumplir la palabra dada es el
presente artículo (no periodístico: no esperéis <i>verdad</i> o <i>hechos</i> en
él más allá de la subjetividad humana. Ya me disculparán los
asistentes si mis puntos de vista no coinciden puntualmente con los
suyos. También me perdonará quien me pidió la crónica, pues supongo
que esperaba otra cosa).
</p>

<p>
Estuve, así lo cuento, pero disculpad que no me meta, tampoco, en
temas técnicos que se trataron allí: sólo pude asistir a la primera
parte de la charla titulada <i>Googlent'</i>. Y bueno, ya os he hablado
alguna vez sobre servicios alternativos que utilizo en lugar de los
que <i>regala</i> la <i>gran G</i> y otros que se pueden utilizar. Pero ese día
me sirvió para conocer gente de la categoría de «los raros esos que
usan lo que no usa /nadie/».
</p>

<p>
No es importante, pero intentaré seguir un orden cronológico de los
hechos. Como digo conocí a gente (muy) interesante, a algunos de los
cuales «desvirtualicé» y me «desvirtualizaron», aunque ahora ─al día
siguiente del evento─, algunos nombres y caras las tendré confundidas
y desordenadas, incluso equivocadas, como resultado de mi habitual
torpeza para los nombres.
</p>
<div id="outline-container-org628395b" class="outline-2">
<h2 id="org628395b">Impresiones del viaje de ida</h2>
<div class="outline-text-2" id="text-org628395b">
<p>
Amanecí temprano, los pájaros se llamaban unos a otros en el sauce que
se ve desde mi ventana, y (casi) me obligaron a levantarme antes que
sonara la alarma del móvil. Desayuné tranquilo con tanto tiempo de
antelación que casi me subí en la moto porque no sabía en qué gastar
el tiempo que me sobraba. Salí antes de tiempo, con la idea de tomarme
un café cuando parara a repostar. Recordaba que la gasolinera de
Fuendejalón tiene un bar adosado. Lo tiene, pero cuando llegué, ambos
dispensadores, ─el de gasolina y el de bebidas─, estaban cerrados y yo
con sólo «una rayita» antes de que se encendiera «la reserva» de la
moto.
</p>

<p>
Bueno, «despacio y dejando ir la moto; sin acelerones ni frenazos;
ahorrando gasolina» pensé, «En Illueca, repostaré»... No había salido
de Fuendejalón por la carretera hacia Tabuenca cuando «la reserva»
comenzó a parpadear. «Dejo la moto ir, sin acelerones. Con la reserva
llego, son sólo 35Km». Y así empecé el viaje, con el Moncayo a mi
derecha. El sol de la mañana aún no agobiaba y avanzaba sin prisa, sin
apresurarme, trazando curvas sin sobresaltos en una carretera donde
los kilómetros compiten para ver cuál tiene más cambios de dirección y
enlazan una curva tras otra impidiendo que el motorista se mantenga en
vertical más de un segundo.
</p>

<p>
La naturaleza me rodea y a esa velocidad puedo disfrutar de ese milano
que comienza a seguir la moto con la esperanza de que el ruido de mi
motor espante ese conejo que se oculta en la cuneta antes de decidirse
a cruzar. Mientras, descansado y sin tener que hacer ningún esfuerzo
para «meter por su sitio» la moto, me deleito en analizar cómo tumba y
se levanta la máquina con sólo una ligera presión en el
manillar. Farallones de piedra con pedicura de carrasca y encina me
reciben cuando acabo la ascensión y me dejo caer hacia el siguiente
valle. Casi bailando con la carretera. Un vals que va girando ladera
abajo, como <i>surfeando</i> las olas de asfalto, la quilla de la moto se
ajusta a cada curva y siento que lo hace prácticamente sola, sin yo
tener que pensar dónde o cómo, la moto tumba y se levanta para tumbar
al otro lado. Cayendo hacia Tierga me alcanza un grupo de
motos. «¿Dónde irán con tanta prisa?», pienso, «A por unos huevos
fritos», me contesto. Luego me doy cuenta, que estoy
<i>viajando</i>. Muchas veces nos desplazamos, vamos de un lugar a otro,
para hacer vete tú a saber qué cosas y el tiempo que gastamos para ir
y venir lo desaprovechamos. Es un intermedio de «nada» en medio de la
actividad. Esa mañana, con tranquilidad y observando lo que hay a mi
alrededor, me siento viajero, observador de paisajes. Otras veces
pasando por la misma carretera muy ocupado con las curvas, la moto, la
trazada, la gravilla en el suelo, el coche con el que te cruzas que no
se aparta dejando sitio y el que adelantas sin que le haya dado tiempo
a verte, apenas puedes disfrutar nada de eso.
</p>

<p>
La carretera deja de bajar y comienza de nuevo a subir. Miro el
indicador de la gasolina que sigue parpadeando impaciente. Subo y subo
sin prisa y tras una curva un cartel me indica que estoy cambiando la
demarcación: «Aranda». El valle correcto, sólo me queda dejarme caer
hasta Illueca y la tengo a tiro aunque no la vea aún. Allá abajo, la
carretera se pierde entre rocas, almendros y monte bajo. Arriba en el
cielo un grupo de buitres despereza sus alas girando una térmica que
ha levantado el sol de la mañana. La reserva sigue sin estar fija.
</p>

<p>
Los pueblos aquí se acurrucan a los pies de sus castillos. En invierno
huelen a leña y en el verano a vuelo de golondrina. Illueca no es
distinto, salvo por la buena conservación del Palacio del Papa Luna,
convertido en Parador Nacional. Sin embargo, la primera gasolinera que
me encontré no tenía bar adosado donde reposar.
</p>

<p>
Con el depósito lleno y sin motivo para retrasarlo más, comencé a
subir a lo largo del valle del Aranda. Esperaba una carretera estrecha
y bacheada como por la que había llegado, sin embargo, la mayor parte
era asfalto nuevo y algo más ancha, y por tanto más rápida, de lo que
había previsto. Llegué a Ciria casi sin enterarme y con mucho tiempo
antes de la hora fijada.
</p>
</div>
</div>
<div id="outline-container-org6d0ce32" class="outline-2">
<h2 id="org6d0ce32">En Ciria</h2>
<div class="outline-text-2" id="text-org6d0ce32">
<p>
Primero fui hasta la iglesia y la plaza donde después
comeríamos. Saludé a algunos lugareños, la mayoría gente mayor que
entiende que los humanos se saludan cuando se cruzan, se conozcan o
no. Después salí de nuevo con la moto en dirección a la nacional para
dar una vuelta y ver el castillo desde abajo. Volví al pueblo
dispuesto a tomar un café para hacer tiempo y aparqué junto a la plaza
donde habíamos quedado ─y donde estaba el bar─.
</p>

<p>
Me dirigía hacia el bar cuando un lugareño me informó que estaría
cerrado: «hasta las doce o así no abre», me dijo. Me senté a esperar
mientras observaba el vuelo de vencejos y aviones atareados en la caza
de insectos para sus crías. «Debe estar perdido», me dijo una lugareña
tras saludar. Y no, no lo estaba, el lugar era el correcto sólo que
con una hora de antelación.
</p>

<p>
Sentado allí se presentó Jordi. Ya nos habíamos cruzado cuando visité
la iglesia, pero yo lo había tomado por un lugareño con su sombrero de
paja y supongo que él a mí igual. «¿Tú eres <i>Nostor</i>?» fue la frase
que me sacó de mi error y «sí, soy <i>Notxor</i>...» la que intentaba
sacarlo a él del suyo. Me habló de que él ya había estado más veces en
el pueblo y que le encantaba. Me habló de lo que disfrutaba los paseos
siguiendo la orilla del río, que la tarde anterior, cuando llegaron
habían subido al castillo a ver la puesta de sol y otras muchas
cosas. De estas conversaciones nos sacó el mismo vecino que me dijo
que el bar estaba cerrado, para anunciarnos que ya debía estar abierto,
porque el coche aquél, «ese que está allí» es el conduce «el del bar».
</p>

<p>
Un refresco y un té después, Jordi y yo, nos acercamos a la casa de
los padres de Nuria, «donde estaban los demás». Bueno, sólo los que
habían llegado: aún faltaban por llegar David y Jordi (otro Jordi)
─ambos vitales para la hora de la comida, las tortillas que traía
David desde Logroño y la butifarra que trajo Jordi fueron
fundamentales para comer─. Visitamos un poco el pueblo: «las escuelas»
donde luego se realizarían las charlas, «la Casa de Tía Julia». Es la
típica casa <i>única</i> de pueblo, ─o irrepetible, más bien─: una casa que
se adapta al terreno, que no lo aplana para construir cubos rectos e
impersonales. Las escaleras son irregulares de escalones pintados de
rojo y blanco, con un umbral donde aún se conservan las pisadas de un
joven gato en un cemento que fue fresco hace muchas decenas de
años. Entramos por una puerta y salimos por otra que conecta la casa
con la sombra de un gran olmo, ─«la olma» la llaman en el pueblo─ de
los pocos que la <i>grafiosis</i> ha respetado.
</p>

<p>
Comimos a los pies de la iglesia. Una plaza a la sombra de un grupo de
chopos, esos árboles que mi mente asocia siempre a las orillas del río
como escribió Juan Ramón Jiménez en su poema «álamo blanco»:
</p>

<p class="verse">
Arriba canta el pájaro<br>
y abajo canta el agua.<br>
Arriba y abajo<br>
se me abre el alma.<br>
¡Entre dos melodías<br>
la columna de plata!<br>
</p>

<p>
Pero estoy divagando tanto que quizá debería concretar un poco.
<a href="http://casatiajulia.com/como-librarse-de-google-linux-impresion-3d-y-bitcoin-para-anarquistas/#formulario">Por cierto, el evento al que asistía era uno en la Casa de la Tía
Julia</a> un proyecto muy interesante que ya había conocido a través de
internet pero que tendría la oportunidad de conocer de primera mano
contado por su impulsora principal: Nuria.
</p>
</div>
</div>
<div id="outline-container-org9f65d03" class="outline-2">
<h2 id="org9f65d03">Las charlas del evento</h2>
<div class="outline-text-2" id="text-org9f65d03">
<p>
Pues mal, muy mal: no me pude quedar más tiempo y abandoné el evento
con el regusto de «tenía que haberme quedado», apenas pude disfrutar
nada. Andoni comenzó a hablarnos de Google, los servicios que regala y
cómo evitarlos. Donde se cruzaron temas de ética y de información, de
privacidad y de negocio en una conversación agradable y participativa.
Al principio me resistía a irme y lo pospuse todo lo que pude, pero
tuve que irme. Me dolió tener que dejarlo justo cuando comenzaba. No
puedo hablar, por tanto de mucho. Me hubiera gustado poder terminar la
charla, toquetear la impresora 3D que habían montado y estar presente
en la de Ekaitz sobre criptomonedas y aprender muchas cosas.
</p>
</div>
</div>
<div id="outline-container-org2819266" class="outline-2">
<h2 id="org2819266">El regreso</h2>
<div class="outline-text-2" id="text-org2819266">
<p>
Al salir para regresar a casa, hablé con Nuria sobre la posibilidad de
organizar otro evento ─con una temática más psicológica─ a ver si
concretamos y en un futuro podemos hacer algo.
</p>

<p>
La vuelta a casa no fue tan divertida. El cansancio del día hacía que
la carretera no fluyera, quizá yo no estaba ya en el modo <i>viajar</i> y
en el de <i>desplazarse</i> las buenas carreteras no me parecieron tan
agradables. Eran nacionales e incluso un tramo de autovía, pero no los
sentí como a la ida. El día estaba llegando a los rojizos del
anochecer y el sol a mi espalda se empeñaba en ir alargando mi sombra.
Poco más puedo contar del evento.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2018/07/15/viaje-a-ciria.html</link>
  <pubDate>Sun, 15 Jul 2018 10:42:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Comparación entre schemes]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-06-21</div>
<p>
Llevo un tiempo con el <i>blog</i> en barbecho. No es que no hiciera nada
entre medias, estoy con mis cosas y cuando abandonas la costumbre de
escribir en un medio que requiere periodicidad, parece que cuesta más
retomarlo de nuevo y poco a poco lo vas dejando más, hasta que te das
cuenta que ha pasado ya, quizá, demasiado tiempo desde el último post.
</p>

<p>
Para no <i>procrastinar</i> más escribo este artículo de una de las cosas
que voy haciendo: <i>Aprender scheme</i>.
</p>
<div id="outline-container-org3c8bc26" class="outline-2">
<h2 id="org3c8bc26">Aprendiendo <i>scheme</i></h2>
<div class="outline-text-2" id="text-org3c8bc26">
<p>
Llevo ya un tiempo queriendo aprender <i>programación funcional</i> y
concretamente <i>scheme</i>. De hecho estoy trasteando con dos <i>sabores</i>
del lenguaje sin terminar de decidirme por uno de los dos. Pensé que
hacer una prueba de trabajo entre las dos me ayudaría a tomar esa
decisión, pero me encuentro en la misma situación que antes. No puedo
establecer cuál me gusta más, si <i>Racket</i> o <i>Chicken</i>.
</p>

<p>
De <i>Racket</i> me gusta su documentación y las facilidades que pone al
aprendizaje. Viene con un entorno de programación para un entorno
gráfico que facilita el depurado y la ejecución de scripts. De
<i>Chicken</i> me gusta la optimización y que he podido compilarlo también
en <i>android</i> en el entorno <i>termux</i>, así que puedo tener el mismo
programa funcionando en mi ordenador y en mi <i>tablet</i> o teléfono sin
necesidad de modificar una coma. Sin embargo, <i>Racket</i> supera con
mucho la documentación que viene con <i>Chicken</i>, que tampoco es mala,
pero está escrita para quien ya sabe el lenguaje.
</p>
</div>
</div>
<div id="outline-container-orgefb6bcd" class="outline-2">
<h2 id="orgefb6bcd">Banco de pruebas</h2>
<div class="outline-text-2" id="text-orgefb6bcd">
<p>
En realidad no es un <i>banco de pruebas</i> como tal, pues sólo he
trabajado con un <i>script</i> muy normal, que hace cálculos <i>reiterativos</i>
que pueden poner a prueba los tiempos de ejecución. Esperaba, desde el
principio que <i>Chicken</i> obtuviera mejores resultados de ejecución, no
en vano en su web lo primero que encuentras es:
</p>

<blockquote>
<p>
CHICKEN is a compiler for the Scheme programming language. It produces
portable and efficient C and supports the R5RS and R7RS (work in
progress) standards, and many extensions.
</p>
</blockquote>

<p>
Es decir, el objetivo de <i>Chicken</i> proveer un compilador de <i>scheme</i>
eficiente, mientras que el objeto de <i>Racket</i> es:
</p>

<blockquote>
<p>
Racket is a general-purpose programming language as well as the
world’s first ecosystem for developing and deploying new languages.
</p>
</blockquote>

<p>
Además, para instalar <i>Chicken</i> en mi máquina bajé el código fuente y
lo compilé. Por tanto está optimizado para mi máquina mientras que
<i>Racket</i> es un paquete distribuido genéricamente para OpenSuse. No
daré más información sobre ellos, pues sus páginas web son bastante
ilustrativas de qué persiguen y hacen cada uno de ellos. El caso es
que aunque sean ambos dos <i>sabores</i> de <i>scheme</i> parece como comparar
<i>peras con manzanas</i>.
</p>
</div>
<div id="outline-container-org2f16031" class="outline-3">
<h3 id="org2f16031">El(los) código(s) de marras</h3>
<div class="outline-text-3" id="text-org2f16031">
<p>
Al principio me las prometí muy felices haciendo un <i>script</i> y
poniéndolo en marcha conseguir los datos de ejecución. La primera
versión del código es la siguiente:
</p>

<div class="org-src-container">
<pre class="src src-scheme"><span style="color: #6272a4;">; </span><span style="color: #6272a4;">Calcular pi con la f&#243;rmula de Bailey-Borwein-Plouffe
</span>
(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">ochok</span> k) (* 8 k))

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">termino</span> k)
  (<span style="color: #ff79c6; font-weight: bold;">let</span> ([n (ochok k)])
    (- (/ 4 (+ n 1))
       (/ 2 (+ n 4))
       (/ 1 (+ n 5))
       (/ 1 (+ n 6)))))

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">bbp</span> i)
  (* (/ 1 (expt 16 i)) (termino i)))

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">calcular-pi</span> precision)
  (<span style="color: #ff79c6; font-weight: bold;">if</span> (&lt; precision 0)
      0
      (+ (bbp precision) (calcular-pi (- precision 1)))))

(display (calcular-pi 10000))
(newline)
</pre>
</div>

<p>
Como se puede ver utilizo la fórmula de <i>Bailey-Borwein-Plouffe</i> para
calcular <b>pi</b>. Esta <a href="https://es.wikipedia.org/wiki/F%C3%B3rmula_de_Bailey-Borwein-Plouffe">fórmula está mejor explicada en su
correspondiente artículo de la wikipedia</a> de lo que yo podría
explicarla aquí, no entraré, pues, en esos detalles.
</p>

<p>
El código funcionó con ambos <i>scheme</i> sin modificar un paréntesis. Sin
embargo, las primeras pruebas me parecieron tan escandalosamente
dispares que me entretuve en pensar que quizá estaba siendo <i>injusto</i>
con uno de los entornos. La salida de cada uno de los <i>schemes</i> era
muy distinta: <i>Chicken</i> devolvía un escueto 3.14159265358979 y ya
está, mientras <i>Racket</i> devolvía un cociente de números enormes que
tardaban segundos en ser escritos en pantalla. La única línea que se
añadió en el fichero <code>pi-decimales.rkt</code> que no está en el
<code>pi-decimales.scm</code> fue la definición del lenguaje que necesita
<i>Racket</i> para ejecutar el código:
</p>

<div class="org-src-container">
<pre class="src src-nil">#lang racket/base
</pre>
</div>

<p>
Sin embargo, la diferencia que había en la salida de los dos
<i>scripts</i>, el <code>.rkt</code> y el <code>.scm</code> seguía pareciéndome <i>muy</i>
significativa y quizá debía corregirlo. Lo que hice fue forzar a
<i>Racket</i> para que calculara también <b>pi</b> de forma <i>inexacta</i> y para
eso utilicé el siguiente código:
</p>

<div class="org-src-container">
<pre class="src src-scheme">#lang racket/base

<span style="color: #6272a4;">; </span><span style="color: #6272a4;">Calcular pi con la f&#243;rmula de Bailey-Borwein-Plouffe
</span>
(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">ochok</span> k) (exact-&gt;inexact (* 8 k)))

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">termino</span> k)
  (<span style="color: #ff79c6; font-weight: bold;">let</span> ([n (ochok k)])
    (- (/ 4 (+ n 1))
       (/ 2 (+ n 4))
       (/ 1 (+ n 5))
       (/ 1 (+ n 6)))))

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">bbp</span> i)
  (* (/ 1 (expt 16 i)) (termino i)))

(<span style="color: #ff79c6; font-weight: bold;">define</span> (<span style="color: #50fa7b; font-weight: bold;">calcular-pi</span> precision)
  (<span style="color: #ff79c6; font-weight: bold;">if</span> (&lt; precision 0)
      0
      (+ (bbp precision) (calcular-pi (- precision 1)))))

(display (calcular-pi 10000))
(newline)
</pre>
</div>

<p>
Básicamente es el mismo código, pero en la función <code>ochok</code> se fuerza
el cálculo con <code>exact-&gt;inexact</code>. El resto de cálculos arrastran esa
conversión y el resultado final es el esperado 3.141592653589793.
</p>

<p>
Además me encontré con otra diferencia fundamental a la hora de hacer
los compilados: el tamaño. Y también es normal que <i>Chicken</i> genere
compilados más pequeños, pero la diferencia es amplísima, porque
entiendo que mete en el ejecutable todas las librerías (sean usadas o
no) y el intérprete del código, mientras en <i>Chicken</i> no. Al final, se
pudo optimizar algo más el tamaño utilizando como lenguaje
<code>racket/base</code> en lugar de <code>racket</code> a secas.
</p>
</div>
</div>
</div>
<div id="outline-container-org56944aa" class="outline-2">
<h2 id="org56944aa">Resultados</h2>
<div class="outline-text-2" id="text-org56944aa">
<p>
Como son pruebas de andar por casa, no he tenido en cuenta cosas como
la gestión de memoria y los tiempos sólo los he medido con el comando
<code>time</code>. Por tanto, estos resultados deben ser tomados como lo que son:
pruebas de aficionado.
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">ejecución</th>
<th scope="col" class="org-right">tamaño</th>
<th scope="col" class="org-right">t real</th>
<th scope="col" class="org-right">t user</th>
<th scope="col" class="org-right">t sys</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">pi-chicken</td>
<td class="org-right">27 Kb</td>
<td class="org-right">0,021s</td>
<td class="org-right">0,019s</td>
<td class="org-right">0,002s</td>
</tr>

<tr>
<td class="org-left">pi-racket</td>
<td class="org-right">6,7 Mb</td>
<td class="org-right">0,490s</td>
<td class="org-right">0,413s</td>
<td class="org-right">0,078s</td>
</tr>

<tr>
<td class="org-left">pi-raco-exact</td>
<td class="org-right">0,9 Mb</td>
<td class="org-right">36,200s</td>
<td class="org-right">36,095s</td>
<td class="org-right">0,126s</td>
</tr>

<tr>
<td class="org-left">pi-raco-inexact</td>
<td class="org-right">0,9 Mb</td>
<td class="org-right">0,192s</td>
<td class="org-right">0,166s</td>
<td class="org-right">0,026s</td>
</tr>

<tr>
<td class="org-left">interpretado Chicken</td>
<td class="org-right">&#xa0;</td>
<td class="org-right">0,046s</td>
<td class="org-right">0,041s</td>
<td class="org-right">0,005s</td>
</tr>

<tr>
<td class="org-left">interpretado Racket exacto</td>
<td class="org-right">&#xa0;</td>
<td class="org-right">38,679s</td>
<td class="org-right">38,507s</td>
<td class="org-right">0,185s</td>
</tr>

<tr>
<td class="org-left">interpretado Racket inexacto</td>
<td class="org-right">&#xa0;</td>
<td class="org-right">2,834s</td>
<td class="org-right">2,724s</td>
<td class="org-right">0,114s</td>
</tr>
</tbody>
</table>

<p>
Los tamaños en la ejecución de entornos interpretados se obvian. Los
comandos para realizarlos respectivamente son:
</p>

<div class="org-src-container">
<pre class="src src-nil">time racket -c pi-decimales-exact.rkt
</pre>
</div>

<p>
Para la versión exacta de <i>Racket</i>.
</p>

<div class="org-src-container">
<pre class="src src-nil">time racket -c pi-decimales.rkt
</pre>
</div>

<p>
Para la versión inexacta de <i>Racket</i> y por último, para la versión de
<i>Chicken</i> se empleó:
</p>

<div class="org-src-container">
<pre class="src src-nil">time csi -s pi-decimales.scm
</pre>
</div>

<p>
Para compilar los distintos ejecutables he utilizado las herramientas
que ambos entornos proporcionan <code>raco</code> y <code>csc</code>.
</p>
</div>
</div>
<div id="outline-container-org8cef8a3" class="outline-2">
<h2 id="org8cef8a3">Conclusiones</h2>
<div class="outline-text-2" id="text-org8cef8a3">
<p>
Bueno, pues los resultados están ahí si sólo buscas velocidad está
claro que <i>scheme</i> debes elegir. Sin embargo, no todo es velocidad: si
todo fuera velocidad sólo se venderían coches deportivos, pero se ven
coches familiares con más frecuencia. Y es el caso en el que me
encuentro.
</p>

<p>
El rendimiento es claramente de <i>Chicken</i>; sin embargo, todo el
entorno que rodea a <i>Racket</i>, especialmente su documentación me hacen
mantenerlo como entorno de aprendizaje y aunque no me encuentro cómodo
con <i>DrRacket</i> (el entorno gráfico que viene con él) puedo utilizarlo
también como entorno interactivo, tanto en consola con el comando
<code>racket</code>, en entorno gráfico con el comando <code>gracket</code> o con el mismo
<i>DrRacket</i>, que proporciona editor, entorno interactivo, depurador y
permite también compilar.
</p>

<p>
También hay varias herramientas que vienen con <i>Chicken</i>, depurador,
profiler, etc. En este sentido tampoco viene manco.
</p>

<p>
No puedo recomendar ninguno de los dos por delante del otro. Es decir,
utilizo los dos, a ambos les encuentro ventajas e inconvenientes y voy
a seguir utilizándolos, los dos. Mientras se mantiene el código en el
ámbito más estándar, el código escrito para uno sirve directamente
para el otro. Pues eso: ahí lo dejo.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/scheme/index.html">scheme</a> <a href="/tags/programación/index.html">programación</a> ]]></description>
  <category><![CDATA[scheme]]></category>
  <category><![CDATA[programación]]></category>
  <link>https://notxor.nueva-actitud.org/2018/06/21/comparacion-entre-schemes.html</link>
  <pubDate>Thu, 21 Jun 2018 16:27:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Tablas en org-mode: cómo tener una hoja de cálculo en modo texto]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-04-15</div>
<p>
Una forma muy habitual de ordenar la información que nos llega es
meterla en una tabla. Si cogemos datos al azar y podemos organizar una
tabla con ellos nos facilitará el acceso a ellos en posteriores
ocasiones. En esto se basan la mayoría de las aplicaciones que
gestionan información, como las bases de datos --que se suelen ordenar
en tablas--, o las hojas de cálculo --que realizan cálculos con
información ordenada en filas y columnas: tablas--.
</p>

<p>
En <code>org-mode</code> el fichero puede contener también ese tipo de
información guardada y ordenada en filas y columnas. No sólo contener
tablas, sino también hacer cálculos dentro de ellas. Pero vamos por
pasos.
</p>
<div id="outline-container-orgdb9061d" class="outline-2">
<h2 id="orgdb9061d">Crear tablas</h2>
<div class="outline-text-2" id="text-orgdb9061d">
<p>
Crear una tabla es muy sencillo. en un párrafo nuevo podemos teclear
una cabecera separada por caracteres <code>|</code>. Por ejemplo, en un párrafo
nuevo escribimos lo siguiente:
</p>

<pre class="example" id="org378ae90">
|Nombre|Apellidos|Teléfono|
|-
</pre>

<p>
Cuando lo hayamos hecho, estando el cursor inmediatamente detrás del
último guión se pulsa <code>&lt;TAB&gt;</code> y la tabla aparece. Cada vez que
pulsemos <code>&lt;TAB&gt;</code> el cursor saltará a la siguiente celda en la misma
línea y cada vez que pulsemos <code>&lt;RET&gt;</code> saltaremos a la siguiente
línea. Si cambia el ancho de columna se reajustará toda la tabla al
hacerlo.
</p>

<p>
En ocasiones tenemos datos que queremos tabular. Si los tenemos
ordenados en una lista separada por comas (CSV) podemos tabular toda
la información. Por ejemplo:
</p>

<pre class="example" id="orgec7205e">
Perico,de los Palotes,123456789
Fulanito,de Tal,987654321
</pre>

<p>
Nos dará como resultado:
</p>

<pre class="example" id="orgcb98133">
| Perico   | de los Palotes | 123456789 |
| Fulanito | de Tal         | 987654321 |
</pre>

<p>
Para ello debemos marcar las líneas que deseamos convertir en tabla y
pulsamos <code>C-c |</code>. La misma combinación de teclas pulsada en cualquier
otro sitio nos preguntará por la distribución de una tabla nueva. Por
ejemplo, <code>C-c |&lt;RET&gt;2x2&lt;RET&gt;</code> creará una tabla vacía de dos por dos.
</p>

<p>
También se puede cambiar el orden de las columnas si te sitúas en una
columna pulsas <code>M-&lt;dcha&gt;</code> o <code>M-&lt;izda&gt;</code>. Igualmente, se pueden mover la
filas pulsando <code>M-&lt;arriba&gt;</code> o <code>M-&lt;abajo&gt;</code>.
</p>

<p>
Además, se pueden añadir columnas pulsando <code>M-S-&lt;dcha&gt;</code> y eliminarlas
con <code>M-S-&lt;izda&gt;</code>. O crear filas con <code>M-S-&lt;abajo&gt;</code> o eliminarlas con
<code>M-S-&lt;arriba&gt;</code>.
</p>
</div>
<div id="outline-container-org458396d" class="outline-3">
<h3 id="org458396d">Ancho de columna y alineamiento</h3>
<div class="outline-text-3" id="text-org458396d">
<p>
Normalmente, el ancho de columna lo calcula directamente <i>emacs</i>, pero
también podemos forzarlo en algunas ocasiones insertando en la primera
fila una cadena de formato con el ancho, por ejemplo:
</p>

<pre class="example" id="org22ca8a1">
|   |                                                                    |
|---+--------------------------------------------------------------------|
| 1 | Uno                                                                |
| 2 | Dos                                                                |
| 3 | tres                                                               |
| 4 | Esta es una entrada demasiado larga para que entre en una columna. |
|---+--------------------------------------------------------------------|
</pre>

<p>
se convierte en
</p>

<pre class="example" id="orga33a903">
|   |            |
|---+------------|
|   | &lt;10&gt;       |
| 1 | Uno        |
| 2 | Dos        |
| 3 | tres       |
| 4 | Esta es =&gt; |
|---+------------|
</pre>

<p>
Limitando la columna es más difícil modificar el contenido que no cabe
en el ancho estipulado. Para hacerlo de una manera cómoda, viene al
rescate la combinación de teclas <code>C-c `</code>, que abrirá una ventana donde
se puede editar el contenido cómodamente.
</p>

<p>
Además del ancho, se puede establecer la alineación añadiendo al
número un prefijo de una letra: <code>&lt;r10&gt;</code> alineará la columna a la
derecha, <code>&lt;c10&gt;</code> la centrará y <code>&lt;l10&gt;</code> la alineará a la izquierda.
</p>
</div>
</div>
</div>
<div id="outline-container-orgeb3b0d5" class="outline-2">
<h2 id="orgeb3b0d5">Haciendo cálculos con las tablas.</h2>
<div class="outline-text-2" id="text-orgeb3b0d5">
<p>
Los cálculos recuerdan mucho a como funciona una hoja de cálculo. Una
celda está determinada por una fila y una columna. En las hojas de
cálculo, desde los tiempos del «Lotus 123», las columnas se nombran
con una letra y las filas con un número, de forma que la primera celda
de la primera columna se llama <code>A1</code> y la segunda <code>A2</code>. En las tablas
de <code>org-mode</code> las filas se marcan con el signo <code>@</code> y un número y las
columnas con el signo <code>$</code> y un número. Es decir, una celda se nombra
como <code>@FILA$COLUMNA</code>. Pero si tienes dudas de qué celda es,
simplemente te puedes situar en ella y pulsar <code>C-c ?</code>.
</p>

<p>
Además en las fórmulas se pueden utilizar números relativos. Por
ejemplo, <code>@-1</code> se refiere a la fila anterior a la actual o <code>@+2</code> a la
fila posterior a la siguiente. Pero para acostumbrarse a todas estas
cosas lo mejor es utilizarlo.
</p>
</div>
</div>
<div id="outline-container-org93d041b" class="outline-2">
<h2 id="org93d041b">Calculando</h2>
<div class="outline-text-2" id="text-org93d041b">
<p>
Para no alargarme mucho, voy a utilizar una tabla que viene en la
documentación de <code>org-mode</code>. Pero lo voy a hacer paso a paso poniendo
los resultados intermedios para mostrar cómo lo utilizo yo.
</p>

<p>
Escribo:
</p>

<pre class="example" id="org7bcd540">
|N|N^2|N^3|N^4|~sqrt(n)~|~sqrt[4](N)~|
|-
</pre>

<p>
y pulso <code>&lt;TAB&gt;</code> obteniendo
</p>

<pre class="example" id="orgdccf2c2">
| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
|   |     |     |     |           |              |
</pre>

<p>
La tabla se ha creado y está vacía, a parte de la cabecera. La única
fila que hay no tiene contenido. En el ejemplo hay una fila especial
que marca grupos de columnas para dibujar líneas verticales
</p>

<pre class="example" id="orga5de39b">
| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / | &lt;   |     | &gt;   | &lt;         | &gt;            |
</pre>

<p>
Cuando el primer campo contiene únicamente un carácter <code>/</code>, los
siguientes campos marcan con <code>&lt;</code> el inicio de un grupo de columnas y
con <code>&gt;</code> el final de un grupo. Si el grupo está formado por una sola
columna se puede utilizar <code>&lt;&gt;</code> para marcar a la vez el inicio y el
final de un grupo de columnas. Al exportar el documento se dibujarán
las líneas que separan los grupos.
</p>

<p>
Pero vamos con los cálculos. Introduzco el primer número y la primera
fórmula que calcularemos en la segunda columna.
</p>

<pre class="example" id="org35d575f">
| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / | &lt;   |     | &gt;   | &lt;         | &gt;            |
| 1 | :=$1^2 |     |     |           |              |
</pre>

<p>
Para introducir la fórmula he utilizado la combinación <code>:=</code> a
continuación le indico que tome el valor de la columna anterior con
<code>$1</code> y lo elevo al cuadrado con el operador <code>^</code>. Al pulsar <code>&lt;RET&gt;</code> el
resultado se muestra es:
</p>

<pre class="example" id="orgb5a37ec">
| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / | &lt;   |     | &gt;   | &lt;         | &gt;            |
| 1 | 1   |     |     |           |              |
|   |     |     |     |           |              |
#+TBLFM: @3$2=$1^2
</pre>

<p>
como se puede ver donde he escrito la fórmula ha aparecido el
resultado del cálculo y la fórmula se guarda en una línea de comando
<code>#+TBLFM:</code>, y en ella aparece que la celda <code>@3$2</code> se calcula con el
valor de la columna anterior <code>$1</code> elevado al cuadrado <code>$1^2</code>. Como el
valor lo vamos a querer utilizar en filas sucesivas podemos eliminar
<code>@3</code> que identifica la línea y así se tratará en toda la columna. En
las hojas de cálculo hay que copiar explícitamente la fórmula a cada
celda. Aquí, quedaría como sigue:
</p>

<pre class="example" id="org5c8fc7c">
| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / | &lt;   |     | &gt;   | &lt;         | &gt;            |
| 1 | 1   |     |     |           |              |
|   |     |     |     |           |              |
#+TBLFM: $2=$1^2
</pre>

<p>
Vamos con las siguientes columnas:
</p>

<pre class="example" id="org29bd135">
| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / | &lt;   |     | &gt;   | &lt;         | &gt;            |
| 1 | 1   |     |     |           |              |
|   |     |     |     |           |              |
#+TBLFM: @3$2=$1^2
</pre>

<pre class="example" id="org49dd737">
| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / |   &lt; |     |   &gt; |         &lt; |            &gt; |
| 1 |   1 |   1 |   1 |           |              |
|   |     |     |     |           |              |
#+TBLFM: @3$2=$1^2::$3=$1^3::$4=$1^4
</pre>

<p>
Como se puede apreciar cada fórmula se separa de la anterior con un
doble carácter <code>:</code>. Me he detenido en esa columna para explicar que al
introducir fórmulas podemos utilizar cualquier fórmula matemática que
esté soportada por el modo <code>calc</code> de emacs. En este caso <code>sqrt</code> para
calcular raíces cuadradas.
</p>

<pre class="example" id="org19c6bf1">
| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / |   &lt; |     |   &gt; |         &lt; |            &gt; |
| 1 |   1 |   1 |   1 |         1 |            1 |
|   |     |     |     |           |              |
#+TBLFM: $2=$1^2::$3=$1^3::$4=$1^4::$5=sqrt($1)::$6=sqrt(sqrt($1))
</pre>

<p>
Ya he introducido la primera línea y las fórmulas que calculan cada
celda de ella. También se pueden introducir fórmulas en <i>elisp</i>. Las
fórmulas deben ir marcadas con un apóstrofe. Las fórmulas <i>elisp</i>
devuelven por defecto cadenas, por lo que si queremos que sea tratado
como un número se debe marcar un <code>N</code>. Por ejemplo, si queremos sumar
dos columnas la fórmula tendrá el formato <code>'(+ $1 $2);N</code>.
</p>

<p>
Pero seguiré con la tabla. Más valores para la columna <code>N</code>.
</p>

<pre class="example" id="orgbcdd5b5">
| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / |   &lt; |     |   &gt; |         &lt; |            &gt; |
| 1 |   1 |   1 |   1 |         1 |            1 |
| 2 |     |     |     |           |              |
| 3 |     |     |     |           |              |
| 4 |     |     |     |           |              |
|---+-----+-----+-----+-----------+--------------|
#+TBLFM: $2=$1^2::$3=$1^3::$4=$1^4::$5=sqrt($1)::$6=sqrt(sqrt($1))
</pre>

<p>
Es hora de calcular toda la tabla. Coloco el cursor en la línea
<code>#+TBLFM:</code> y pulso <code>C-c C-c</code>. El resultado:
</p>

<pre class="example" id="org5d45b9a">
| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / |   &lt; |     |   &gt; |         &lt; |            &gt; |
| 1 |   1 |   1 |   1 |         1 |            1 |
| 2 |   4 |   8 |  16 | 1.4142136 |    1.1892071 |
| 3 |   9 |  27 |  81 | 1.7320508 |    1.3160740 |
| 4 |  16 |  64 | 256 |         2 |    1.4142136 |
#+TBLFM: $2=$1^2::$3=$1^3::$4=$1^4::$5=sqrt($1)::$6=sqrt(sqrt($1))
</pre>

<p>
¿Se puede hacer algo con el formato de los resultados? Algunas
columnas no tienen decimales y otras tienen siete. Pero sí, se puede
dar un poco de formato añadiendo un <i>flag</i> <code>%.4f</code> detrás de la fórmula
que queremos ajustar, separándolo con un carácter <code>;</code>. Por ejemplo:
</p>

<pre class="example" id="orga6bbd89">
| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / |   &lt; |     |   &gt; |         &lt; |            &gt; |
| 1 |   1 |   1 |   1 |         1 |            1 |
| 2 |   4 |   8 |  16 | 1.4142136 |    1.1892071 |
| 3 |   9 |  27 |  81 | 1.7320508 |    1.3160740 |
| 4 |  16 |  64 | 256 |         2 |    1.4142136 |
#+TBLFM: $2=$1^2::$3=$1^3::$4=$1^4::$5=sqrt($1);%.4f::$6=sqrt(sqrt($1));%.5f
</pre>

<p>
Volvemos a pulsar <code>C-c C-c</code> sobre la línea de fórmulas y el resultado
es:
</p>

<pre class="example" id="orga8d73e2">
| N | N^2 | N^3 | N^4 | ~sqrt(n)~ | ~sqrt[4](N)~ |
|---+-----+-----+-----+-----------+--------------|
| / |   &lt; |     |   &gt; |         &lt; |            &gt; |
| 1 |   1 |   1 |   1 |    1.0000 |      1.00000 |
| 2 |   4 |   8 |  16 |    1.4142 |      1.18921 |
| 3 |   9 |  27 |  81 |    1.7321 |      1.31607 |
| 4 |  16 |  64 | 256 |    2.0000 |      1.41421 |
#+TBLFM: $2=$1^2::$3=$1^3::$4=$1^4::$5=sqrt($1);%.4f::$6=sqrt(sqrt($1));%.5f
</pre>

<p>
La tabla, tal y como queda en el documento es la siguiente:
</p>

<table>


<colgroup>
<col  class="org-right">
</colgroup>

<colgroup>
<col  class="org-right">

<col  class="org-right">

<col  class="org-right">
</colgroup>

<colgroup>
<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-right">N</th>
<th scope="col" class="org-right">N^2</th>
<th scope="col" class="org-right">N^3</th>
<th scope="col" class="org-right">N^4</th>
<th scope="col" class="org-right">sqrt(n)</th>
<th scope="col" class="org-right">sqrt[4](N)</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-right">1</td>
<td class="org-right">1</td>
<td class="org-right">1</td>
<td class="org-right">1</td>
<td class="org-right">1.0000</td>
<td class="org-right">1.00000</td>
</tr>

<tr>
<td class="org-right">2</td>
<td class="org-right">4</td>
<td class="org-right">8</td>
<td class="org-right">16</td>
<td class="org-right">1.4142</td>
<td class="org-right">1.18921</td>
</tr>

<tr>
<td class="org-right">3</td>
<td class="org-right">9</td>
<td class="org-right">27</td>
<td class="org-right">81</td>
<td class="org-right">1.7321</td>
<td class="org-right">1.31607</td>
</tr>

<tr>
<td class="org-right">4</td>
<td class="org-right">16</td>
<td class="org-right">64</td>
<td class="org-right">256</td>
<td class="org-right">2.0000</td>
<td class="org-right">1.41421</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2018/04/15/tablas-en-org-mode:-como-tener-una-hoja-de-calculo-en-modo-texto.html</link>
  <pubDate>Sun, 15 Apr 2018 10:11:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Aprendiendo scheme: un ejercicio simple]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-04-14</div>
<div id="outline-container-org2c8a2fb" class="outline-2">
<h2 id="org2c8a2fb">Un ejercicio simple</h2>
<div class="outline-text-2" id="text-org2c8a2fb">
<p>
El otro día un amigo (dddddd, en las redes) me comentó un ejercicio
sencillo que se podría hacer en <i>scheme</i> para ir aprendiendo. El caso
es que él está con el diseño de un procesador de 12 <i>bits</i> junto con
otra persona. Ya tiene un emulador funcionando y me comentó que estaba
con un código que convertía la cadena que llegaba en valores de 12
<i>bits</i>. Él lo hizo en <i>ensamblador</i> de su máquina, sin embargo me dijo
que sería un buen ejercicio para hacerlo en <i>scheme</i>. Las premisas son
sencillas:
</p>

<ol class="org-ol">
<li>Llega una cadena alfanumérica que hay que convertir en su
correspondiente valor numérico o devolver una lista de valores si
la cadena es más larga.</li>
<li>Entre los valores numéricos pueden aparecer espacios en blanco que
hay que ignorar.</li>
<li>Es una función <i>máquina</i> así que no debería depender de ninguna
librería.</li>
</ol>

<p>
El punto 3, como veremos a continuación me lo salté. ¿Por qué?
Básicamente me interesa a mí, aprender <i>scheme</i>, seguir la lógica de
programación de <i>ensamblador</i> no me ayuda. Así que puse mis
condiciones:
</p>

<ol class="org-ol">
<li>Iba a utilizar <i>chicken scheme</i> con el mínimo de «librerías
posible», pero de más alto nivel que el <i>ensamblador</i>.</li>
<li>Iba a utiliza <i>programación literaria</i> utilizando el modo <i>org</i> de
<i>emacs</i>: básicamente para saber cómo funciona y cómo de útil es
este tipo de programación.</li>
<li>Iba a utilizar la <i>programación funcional</i> todo lo que pudiera con
el objeto de acostumbrar mi cerebro mononeuronal a ese tipo de
programación (y porque también es uno de los objetivos de aprender
<i>scheme</i>).</li>
</ol>
</div>
</div>
<div id="outline-container-orgbf6018b" class="outline-2">
<h2 id="orgbf6018b">Las pruebas</h2>
<div class="outline-text-2" id="text-orgbf6018b">
<p>
Comencé escribiendo unas pruebas sencillas. Lo primero, hacer una
función que devolviera el valor numérico de cada <i>char</i>. Es decir, si
llega un carácter '3' debería devolver el valor 3. Tampoco voy a
detallar todos los ciclos de desarrollo y refactorizaciones del código
para llegar al código final. Pero pongo aquí el fichero de pruebas que
he utilizado para hacer un desarrollo TDD del código.
</p>

<pre class="example" id="org3d2bc98">
(require-extension test)
(require "conversor.scm")

(test-group "Convertir un char a su valor numérico"
            (test 0 (convertir-char #\0))
            (test 1 (convertir-char #\1))
            (test 2 (convertir-char #\2))
            (test 3 (convertir-char #\3))
            (test 4 (convertir-char #\4))
            (test 5 (convertir-char #\5))
            (test 6 (convertir-char #\6))
            (test 7 (convertir-char #\7))
            (test 8 (convertir-char #\8))
            (test 9 (convertir-char #\9))
            (test 10 (convertir-char #\a))
            (test 10 (convertir-char #\A))
            (test 11 (convertir-char #\b))
            (test 11 (convertir-char #\B))
            (test 12 (convertir-char #\c))
            (test 12 (convertir-char #\C))
            (test 13 (convertir-char #\d))
            (test 13 (convertir-char #\D))
            (test 14 (convertir-char #\e))
            (test 14 (convertir-char #\E))
            (test 15 (convertir-char #\f))
            (test 15 (convertir-char #\F)))

(test-group "Caracteres no numéricos"
            (test '() (convertir-char #\n))
            (test '() (convertir-char #\m)))

(test-group "Convertir una cadena de tres cifras a su valor numérico"
            (test 0 (calcular-numero "000"))
            (test 256 (calcular-numero "100"))
            (test 257 (calcular-numero "101")))

(test-group "Dividir una cadena en grupos de tres"
            (test '("000") (dividir-cadena "000"))
            (test '("111" "222" "333") (dividir-cadena "111222333"))
            (test '("100" "010" "001") (dividir-cadena "100010001"))
            (test '("ddd" "ddd") (dividir-cadena "dddddd"))
            ;; Una cadena de menos de tres caracteres devolverá una lista vacía
            (test '() (dividir-cadena "12")))

(test-group "Convertir cadena en una lista de números"
            (test '(563 288 255) (conversor "23 3120 0 f f"))
            (test '(0 16 256) (conversor "00 0 01 010 0")))

;; Asegurarnos de que las pruebas automáticas pueden distinguir un fallo de un cierre normal
(test-exit)
</pre>
</div>
</div>
<div id="outline-container-orgc6ee0c1" class="outline-2">
<h2 id="orgc6ee0c1">El código</h2>
<div class="outline-text-2" id="text-orgc6ee0c1">
<p>
El código final lo pongo a continuación.
</p>

<pre class="example" id="orgf4442ab">
(require-extension srfi-13)  ; &lt;- extensión necesaria para trabajar con cadenas

;; Devuelve el valor numérico de un char
(define (convertir-char c)
  (case c
    ((#\0) 0)
    ((#\1) 1)
    ((#\2) 2)
    ((#\3) 3)
    ((#\4) 4)
    ((#\5) 5)
    ((#\6) 6)
    ((#\7) 7)
    ((#\8) 8)
    ((#\9) 9)
    ((#\a #\A) 10)
    ((#\b #\B) 11)
    ((#\c #\C) 12)
    ((#\d #\D) 13)
    ((#\e #\E) 14)
    ((#\f #\F) 15)
    (else '())))

;; Devuelve el valor numérico de una cadena de tres cifras
(define (calcular-numero cadena)
  (apply + (map * '(256 16 1)
      	  (map convertir-char
      	       (string-&gt;list cadena)))))

;; Devuelve una lista de cadenas de tres caracteres
(define (dividir-cadena cadena)
  (if (&lt; (string-length cadena) 3)
      '()
      (cons (string-take cadena 3) (dividir-cadena (string-drop cadena 3)))))

;; Devuelve una lista de números dada una cadena alfanumérica
(define (conversor cadena)
  (map calcular-numero (dividir-cadena (string-delete #\space cadena))))
</pre>

<p>
Destacar que conseguí evitar toda tentación de escribir un sólo bucle,
especialmente en la función <code>dividir-cadena</code>, donde el bucle necesario
se implementó con una función recursiva.
</p>
</div>
</div>
<div id="outline-container-org8329f4d" class="outline-2">
<h2 id="org8329f4d">Programación literaria</h2>
<div class="outline-text-2" id="text-org8329f4d">
<p>
No me voy a poner a explicar lo que es la <i>programación literaria</i> y
todas sus implicaciones. Básicamente consiste en escribir un documento
donde se cuenta qué hace el código, con el código
intercalado. Después, una aplicación separa el texto del código. En mi
caso ha sido <i>emacs</i> y su <i>org-mode</i> el que me ha permitido hacer todo
el proceso.
</p>

<p>
El punto positivo lo ha demostrado cuando he dejado el ejercicio
durante tiempo. Cuando retomas un código que hace días que no has
trabajado tienes que repasarlo entero e intentar acordarte de qué
estabas pensando en el momento que lo escribiste. Con la programación
literaria es más fácil, porque he escrito lo que estaba pensando antes
de escribir el código, cómo se podría refactorizar, cómo se debería
continuar, etc. Cuando retomaba el trabajo, leía lo que había escrito
y rápidamente sabía qué hacía el código, qué había querido hacer yo y
qué había que hacer para continuar.
</p>

<p>
La sensación es positiva en general, sin embargo, hay ocasiones en las
que una refactorización deja obsoleto texto que has escrito antes y
que en una posterior lectura puede provocar confusiones. Hay que ser
muy cuidadoso y revisar todo el texto en las refactorizaciones si no
se quiere arrastrar inconsistencias en las explicaciones. Eso,
requiere un poco de trabajo extra. En contrapartida, tienes la mejor
documentación posible sobre el código, la haces a la vez que el código
en el mismo proceso. Eso evitará la pereza de escribir documentación
después y siempre es más llevadero revisar algo escrito que redactar
de cero todo.
</p>
</div>
</div>
<div id="outline-container-org9cf7b04" class="outline-2">
<h2 id="org9cf7b04">Conclusión</h2>
<div class="outline-text-2" id="text-org9cf7b04">
<p>
Estoy contento con el resultado del experimento. La forma de trabajar
ha sido fluida: los ratos en que me he podido poner con ello enseguida
cogía el hilo. A ello contribuía tanto la explicación como la
sencillez de cada función; código escueto con mucha literatura que lo
explica.
</p>

<p>
Los ciclos de escribir <i>tests</i>, escribir código que supere los <i>tests</i>
y refactorizar, se han hecho muy sencillos y rápidos.
</p>

<p>
Así que, bueno, ahí van mis adelantos con <i>scheme</i> y mis cambios en
mis hábitos de escribir código.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/scheme/index.html">scheme</a> <a href="/tags/programación/index.html">programación</a> ]]></description>
  <category><![CDATA[scheme]]></category>
  <category><![CDATA[programación]]></category>
  <link>https://notxor.nueva-actitud.org/2018/04/14/aprendiendo-scheme-un-ejercicio-simple.html</link>
  <pubDate>Sat, 14 Apr 2018 17:26:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Explorando las posibilidades de Orgzly]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-03-24</div>
<p>
Llevo tiempo viendo cómo podría sincronizar las notas y agenda de
<code>org-mode</code> con el móvil. Hace un par de días encontré <i>Orgzly</i>.
</p>
<div id="outline-container-org4b16797" class="outline-2">
<h2 id="org4b16797">La aplicación</h2>
<div class="outline-text-2" id="text-org4b16797">
<p>
<a href="https://f-droid.org/packages/com.orgzly/">La aplicación se puede descargar de f-droid</a>. Según la ayuda de la
aplicación permite crear y borrar notas y tareas. Se pueden crear a su
vez subnotas. Soporta propiedades, etiquetas y prioridades.
</p>

<p>
Los ficheros se guardan en formato <code>org</code>, por tanto en texto plano. El
problema es la sincronización. <i>Orgzly</i> utiliza como <i>repositorio</i> un
directorio local del dispositivo donde se instale. Si quieres ─como
yo─, utilizar la aplicación con otros dispositivos y tenerlos
sincronizados hay que trabajar un poco.
</p>

<p>
La primera idea, que la sugiere la misma aplicación en su
documentación es tener las notas en directorios compartidos en la
nube, por ejemplo en <i>dropbox</i>, <i>nextcloud</i> o cualquiera de todos esos
servicios. Pero yo, que por costumbre tiendo a complicarme la vida, ya
tenía los archivos <code>org</code> que utilizo como agenda en un repositorio
<code>git</code>. Así que, puesto que también los gestiono a través del <i>emacs</i>
que puedes instalar en <code>termux</code>, sólo tuve que darle el <code>path</code> donde
se encuentran los ficheros (en mi caso
<code>sd-interno/Android/data/repos/agenda</code>) pero supongo que cada uno lo
podrá guardar donde quiera (también <a href="https://f-droid.org/packages/com.manichord.mgit/">se podrían utilizar otras
aplicaciones estilo <code>Mgit</code></a>).
</p>
</div>
</div>
<div id="outline-container-org89f64db" class="outline-2">
<h2 id="org89f64db">Las búsquedas</h2>
<div class="outline-text-2" id="text-org89f64db">
<p>
Las búsquedas son un poco enrevesadas, pero se pueden guardar. Por
defecto vienen guardadas algunas, como la vista de semana que tiene la
agenda en <code>org-mode</code>.
</p>

<p>
Las expresiones de búsqueda consisten en un comando de una o dos
letras. En la ayuda hay una tabla con esos comandos
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Expresión</th>
<th scope="col" class="org-left">Buscar notas</th>
<th scope="col" class="org-left">Ejemplo</th>
<th scope="col" class="org-left">.</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">s.PERIODO</td>
<td class="org-left">Programados (scheduled) en el periodo</td>
<td class="org-left">s.today</td>
<td class="org-left">N</td>
</tr>

<tr>
<td class="org-left">d.PERIODO</td>
<td class="org-left">Caducan (deadline) en el periodo</td>
<td class="org-left">d.le.2d</td>
<td class="org-left">N</td>
</tr>

<tr>
<td class="org-left">c.PERIODO</td>
<td class="org-left">Cerrado (closed) en el periodo</td>
<td class="org-left">c.le.-3d</td>
<td class="org-left">N</td>
</tr>

<tr>
<td class="org-left">i.ESTADO</td>
<td class="org-left">Con el estado</td>
<td class="org-left">i.todo</td>
<td class="org-left">S</td>
</tr>

<tr>
<td class="org-left">it.TIPO</td>
<td class="org-left">Con el tipo de estado TIPO</td>
<td class="org-left">.it.done</td>
<td class="org-left">S</td>
</tr>

<tr>
<td class="org-left">b.FICHERO</td>
<td class="org-left">Desde el fichero especificado</td>
<td class="org-left">.b.Trabajo</td>
<td class="org-left">S</td>
</tr>

<tr>
<td class="org-left">t.ETIQUETA</td>
<td class="org-left">Con la etiqueta (también heredadas)</td>
<td class="org-left">t.pendiente</td>
<td class="org-left">S</td>
</tr>

<tr>
<td class="org-left">tn.ETIQUETA</td>
<td class="org-left">Con la etiqueta (sin heredadas)</td>
<td class="org-left">tn.revisar</td>
<td class="org-left">N</td>
</tr>

<tr>
<td class="org-left">p.PRIORIDAD</td>
<td class="org-left">Que tiene la prioridad</td>
<td class="org-left">.p.c</td>
<td class="org-left">S</td>
</tr>

<tr>
<td class="org-left">ps.PRIORIDAD</td>
<td class="org-left">Establecida la prioridad</td>
<td class="org-left">ps.b</td>
<td class="org-left">S</td>
</tr>

<tr>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>
</tbody>
</table>

<p>
El formato de consulta puede llevar delante un punto «.» que invierte
la búsqueda (lo que viene a ser un <code>not</code> lógico). En la tabla anterior
se marcan las consultas que lo soportan en la columna del punto.
</p>

<p>
Además se pueden establecer otras condiciones:
</p>

<ul class="org-ul">
<li><b>eq</b> : igual (equal) a <code>TIEMPO</code></li>
<li><b>ne</b> : no igual (not equal) a <code>TIEMPO</code></li>
<li><b>lt</b> : menor que (less than) a <code>TIEMPO</code></li>
<li><b>le</b> : menor o igual (less or equal) a <code>TIEMPO</code></li>
<li><b>gt</b> : mayor (greater) que <code>TIEMPO</code></li>
<li><b>ge</b> : mayor o igual (greater or equal) a <code>TIEMPO</code></li>
</ul>

<p>
El periodo <code>TIEMPO</code> se expresa con un número, que puede ser negativo,
y un sufijo de una letra. <code>h</code> para horas, <code>d</code> para días, <code>w</code> para
semanas (weeks), <code>m</code> para meses, <code>y</code> para años (years). También se
pueden utilizar nombres como <code>tomorrow</code>, <code>today</code>, <code>now</code>, <code>yesterday</code>.
</p>

<p>
Por ejemplo, <code>i.todo t.trabajo</code> buscará todas las entradas marcadas
como <code>TODO</code> que tengan la etiqueta <code>trabajo</code>. No sé si al utilizar
otras etiquetas para los estados <code>TODO</code> se podrá filtrar también por
esas etiquetas; yo utilizo las clásicas <code>&lt;TODO | DONE&gt;</code>. Si alguien
utiliza sus propias etiquetas personalizadas se pueden configurar en
las opciones del programa. Por defecto, están configuradas como <code>&lt;TODO
NEXT | DONE&gt;</code>.
</p>

<p>
En las búsquedas también se puede limitar el periodo de búsqueda con
la etiqueta <code>ad.DIAS</code> y hará que la lista se agrupe por días. En este
caso <code>DIAS</code> es el número de días que queremos que se muestre. Por
ejemplo <code>(t.trabajo or t.ong) ad.5</code> mostrará las notas etiquetadas con
<code>trabajo</code> o con <code>ong</code> en los siguientes 5 días.
</p>
</div>
</div>
<div id="outline-container-org7dc3c12" class="outline-2">
<h2 id="org7dc3c12">Captura, organización de notas y enlaces</h2>
<div class="outline-text-2" id="text-org7dc3c12">
<p>
También se pude configurar para que aparezca un <i>pichorro</i> en el área
de notificaciones del teléfono para crear una nota rápidamente o
sincronizar el repositorio, si ha cambiado algo, con la aplicación.
</p>

<p>
Cuando hacemos una captura, nos abre por defecto el primer archivo
<code>org</code> que tengamos configurado en el repositorio, sin embargo, podemos
cambiarlo seleccionando en la lista qué fichero queremos que guarde
nuestra anotación. También nos permite asignarle un estado (<code>TODO</code>) y
una prioridad si hace falta. Nos permite escribir un título, asignarle
una fecha de caducidad o una programación. Podemos establecerle
también propiedades y el texto es libre.
</p>

<p>
En el listado de archivos del repositorio también podemos abrir el que
queramos y nos mostrará un listado con nuestras anotaciones. Si
desplazamos una de ellas hacia la derecha aparecerá un menú que nos
permite hacer varias operaciones: por ejemplo, cambiarle la fecha,
ciclar por las etiquetas <code>TODO</code> o establecer a <code>DONE</code> con sólo una
pulsación.
</p>

<p>
Además si mantenemos un par de segundos pulsada una de las notas
aparecerá otro menú que nos permite copiar, cortar o pegar notas entre
ficheros. También aparece un icono con flechas que hará que se muestre
otro menú que permite organizarlas jerárquicamente.
</p>

<p>
Las jerarquías de notas se pueden desplegar pulsando el icono «+» ó
«-» que aparece a la derecha del título de la nota. Si una nota
contiene notas subordinadas las ocultará mostrando sólo el título de
la principal.
</p>

<p>
Por supuesto, también está permitido el formato en el texto para
<b>negrita</b>, <i>cursiva</i>, <span class="underline">subrayada</span>, <code>literal</code>, <code>código</code> o <del>tachada</del>.
</p>

<p>
Los enlaces habituales en <code>org-mode</code> para acceder a web o a otros
ficheros se pueden emplear de forma natural. Además se pueden añadir
otros enlaces más específicos para el uso con teléfono móvil. Por
ejemplo, si el enlace tiene la forma <code>tel:numero</code> permite hacer una
llamada pulsándolo, o enviar un SMS con <code>sms:numero</code>, o enviar un
correo con <code>mailto:contacto@direccion.com</code>.
</p>

<p>
Lo que para mí es un auténtico ahorro de tiempo, porque muchas tareas
de las que hago diariamente son enviar mensajes o llamar por teléfono
a gente.
</p>
</div>
</div>
<div id="outline-container-orgbccb83a" class="outline-2">
<h2 id="orgbccb83a">Conclusión</h2>
<div class="outline-text-2" id="text-orgbccb83a">
<p>
Es una aplicación muy completa. Por ponerle una pega, me falta el
soporte a las tareas divididas en subtareas marcando que está hecha
con el clásico <i>widget</i> <code>[x]</code> y que controle también el porcentaje de
tarea completado mediante el recuento. Algo que hace <code>org-mode</code> y que
suelo utilizar en proyectos más o menos largos. Pero bueno, esto
más que una queja es por no decir todo positivo.
</p>

<p>
Los dos días que llevo trasteando con <i>Orgzly</i> me ha convencido como
aplicación para captura de notas. Recomendable para todos los usuarios
de <i>emacs</i> que gestionan sus agendas con <code>org-mode</code> y lo quieran
toquetear también con el móvil.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/agenda/index.html">agenda</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[agenda]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2018/03/24/explorando-las-posibilidades-de-orgzly.html</link>
  <pubDate>Sat, 24 Mar 2018 22:37:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Utilizando elfeed-mode de Emacs]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-03-10</div>
<div id="outline-container-org6e434ce" class="outline-2">
<h2 id="org6e434ce">Problemas</h2>
<div class="outline-text-2" id="text-org6e434ce">
<p>
Como más vale una imagen que mil palabras, pues ni mil palabras más:
</p>


<figure id="orgcdaa9a8">
<img src="./imagen/akregrator-negro.png" alt="akregrator-negro.png">

</figure>

<p>
Efectivamente, tras una actualización del sistema, la aplicación que
suelo utilizar para leer los <i>feeds</i> de los sitios que sigo, se fue a
negro. Pero a negro, <i>muy negro</i>.
</p>

<p>
Y me planteé cómo podía leer las entradas de blogs y páginas de
noticias que suelo leer, que son decenas.
</p>
</div>
</div>
<div id="outline-container-orgf3a00ee" class="outline-2">
<h2 id="orgf3a00ee"><code>emacs</code> al rescate</h2>
<div class="outline-text-2" id="text-orgf3a00ee">
<p>
Recordé que emacs tiene una herramienta llamada <code>elfeed</code> para estos
menesteres. Lo que me dolía era tener que volver a cargar las decenas
de direcciones de <i>feeds</i> que sigo habitualmente: sobre informática,
sobre psicología, sobre Esperanto (y en Esperanto), sobre
programación, sobre diseño 3D, sobre aventuras conversacionales...
</p>

<p>
En fin, lo que más pereza me daba: ¿tendría que rehacer toda la lista?
La respuesta es <i>«no»</i>; encontré un modo de cargar toda la lista desde
la de <i>Akregrator</i>. Pero vamos por partes.
</p>
</div>
<div id="outline-container-org0331f7c" class="outline-3">
<h3 id="org0331f7c">Instalar <code>elfeed</code></h3>
<div class="outline-text-3" id="text-org0331f7c">
<p>
Esta es la parte más fácil. Lo hice buscando el término <i>feed</i> en la
lista de paquetes: <code>Alt-x list-packages</code>, <code>enter</code> en <code>elfeed</code> y
<code>enter</code> en instalar. Lo descarga, lo compila y ya está todo listo para
usarse, sólo hace falta configurarlo un poco: por ejemplo diciéndole
que <i>feeds</i> tiene que descargar.
</p>
</div>
</div>
<div id="outline-container-orgd64445a" class="outline-3">
<h3 id="orgd64445a">Configurar <code>elfeed</code></h3>
<div class="outline-text-3" id="text-orgd64445a">
<p>
Ahora es cuando hay que configurar la lista de sitios a los que tiene
que conectarse la herramienta y bajar el contenido que nos
interesa. <code>elfeed</code> ha creado un directorio <code>~/.elfeed</code> donde guardará
la base de datos con los <code>feeds</code>.
</p>

<p>
Leyendo la documentación veo que hay que añadir algunas cosas a
nuestro fichero <code>.emacs</code>. Por lo menos, los <i>feeds</i>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">'(elfeed-feeds
  (<span style="color: #ff79c6; font-weight: bold;">quote</span>
   (<span style="color: #f1fa8c;">"https://notxor.nueva-actitud.org/rss.xml"</span> <span style="color: #6272a4;">; </span><span style="color: #6272a4;">este no lo sigo pero no iba a dejar la mejor mula sin manta :-P
</span>    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">blogs que sigo
</span>    <span style="color: #f1fa8c;">"https://victorhckinthefreeworld.com/feed/"</span> 
    <span style="color: #f1fa8c;">"https://ondahostil.wordpress.com/feed/"</span>
    <span style="color: #f1fa8c;">"https://izaroblog.com/feed/"</span>
    <span style="color: #f1fa8c;">"https://elpinguinotolkiano.wordpress.com/feed/"</span>
    <span style="color: #f1fa8c;">"http://www.lapipaplena.org/feed/"</span> 
    <span style="color: #f1fa8c;">"https://lamiradadelreplicante.com/feed/"</span> 
    <span style="color: #f1fa8c;">"https://colaboratorio.net/feed/"</span> 
    <span style="color: #f1fa8c;">"http://www.maxxcan.com/feed/"</span> 
    <span style="color: #f1fa8c;">"https://mierda.tv/feed/"</span> 
    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">(...)
</span>    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Psicolog&#237;a
</span>    <span style="color: #f1fa8c;">"http://www.infocop.es/AreaRSS/"</span> 
    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">(...)
</span>    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Linux
</span>    <span style="color: #f1fa8c;">"https://lwn.net/headlines/newrss"</span>
    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">(...)
</span>    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Esperanto
</span>    <span style="color: #f1fa8c;">"http://www.esperanto.es/hef/index.php?format=feed&amp;type=rss"</span> 
    <span style="color: #f1fa8c;">"http://www.liberafolio.org/feed/"</span> 
    <span style="color: #f1fa8c;">"http://revuoesperanto.org/rss.xml"</span>
    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">(...)
</span>    <span style="color: #6272a4;">; </span><span style="color: #6272a4;">Divulgaci&#243;n cient&#237;fica
</span>    <span style="color: #f1fa8c;">"http://feeds.feedburner.com/CuadernoDeCulturaCientfica"</span> 
    <span style="color: #f1fa8c;">"https://lacienciaysusdemonios.com/feed/"</span>)))
</pre>
</div>

<p>
He puesto sólo algunos, pues la lista es bastante más larga, pero
espero que sea suficiente para mostrar la magnitud del trabajo de
configurar todo, si hubiera que hacerlo a mano aunque fuera
<i>corta-pegando</i> las URL. También me sirve para documentar que no es
una simple lista, la tengo agrupada por temas y ordenada ─según mis
gustos─ para encontrar rápidamente las cosas que luego puedo
necesitar.
</p>

<p>
Para ahorrar tiempo en la configuración <code>elfeed</code> cuenta con el comando
<code>elfeed-load-opml</code>. Ese comando te pedirá el nombre de un fichero
<code>.opml</code> que cargar. Busqué si el fichero existía en algún sitio:
</p>

<div class="org-src-container">
<pre class="src src-shell">find ~ -name <span style="color: #f1fa8c;">"*.opml"</span>
</pre>
</div>

<p>
y me devolvió
</p>

<pre class="example" id="org904da5c">
~/.local/share/akregator/data/feeds.opml
</pre>

<p>
y se lo pasé al comando <code>elfeed-load-opml</code>. Él sólo cargó toda la
lista en mi fichero <code>.emacs</code>. Recargar la configuración, llamar a
<code>elfeed</code> y aparece toda la lista de artículos.
</p>

<p>
Para usarlo, remito a la ayuda que viene junto con el paquete que lo
explica todo.
</p>
</div>
</div>
</div>
<div id="outline-container-org43027ce" class="outline-2">
<h2 id="org43027ce">Conclusión</h2>
<div class="outline-text-2" id="text-org43027ce">
<p>
El paquete <code>elfeed</code> es muy potente, permite filtrar los artículos de
muchas maneras: por tiempo, leídos o no leídos, establecer etiquetas
para facilitar la búsqueda, buscar términos concretos, etc.
</p>

<p>
Sin embargo, estoy acostumbrado a tenerlo todo ordenado en forma de
árbol, donde cada rama principal la tengo etiquetada según el tema
general del que se trata. Con <code>elfeed</code> aparece la lista por orden
cronológico mezclando los temas. Bien, bueno: es cierto que puedo
establecer filtros por esos tema, pero eso implica ya una acción por
mi parte, cuando con la otra herramienta lo tenía de un vistazo.
</p>

<p>
De todas formas ─y mientras no vuelva a funcionarme <i>akregrator</i> de
nuevo─ estaré utilizando <code>elfeed</code> como lector de <i>feeds</i>, quizá con el
uso le encuentre otras ventajas que ahora mismo se me
escapan. Teniendo en cuenta que no llevo aún ni un día utilizándolo.
</p>

<p>
Por cierto, es recomendable utilizar el modo gráfico de <code>emacs</code> e
instalar <code>elfeed-web</code>. Los <i>feeds</i> se cargan y se visualizan en el
navegador web de emacs, las imágenes así se visualizan también.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2018/03/10/utilizando-elfeed-mode-de-emacs.html</link>
  <pubDate>Sat, 10 Mar 2018 19:24:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Compilar chicken scheme en la aplicación termux de android]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-03-05</div>
<div id="outline-container-org4e42879" class="outline-2">
<h2 id="org4e42879">Chicken scheme</h2>
<div class="outline-text-2" id="text-org4e42879">
<p>
Llevo unas semanas trasteando con <i>Chicken scheme</i> y haciendo
pruebas. La penúltima fue compilarlo en mi portátil (OpenSuse
Tumbleweed) y tenerlo funcionando sin problemas. Eso me llevó a pensar
que sería posible compilarlo en termux, el terminal de texto de
Android. Al fin y al cabo, cuando hice la primera intentona en mi
portátil me dijo:
</p>

<div class="org-src-container">
<pre class="src src-shell">&gt; make
Please select your target platform by running one of the following commands:

make <span style="color: #f8f8f2; font-weight: bold;">PLATFORM</span>=solaris
make <span style="color: #f8f8f2; font-weight: bold;">PLATFORM</span>=mingw-msys
make <span style="color: #f8f8f2; font-weight: bold;">PLATFORM</span>=mingw
make <span style="color: #f8f8f2; font-weight: bold;">PLATFORM</span>=macosx
make <span style="color: #f8f8f2; font-weight: bold;">PLATFORM</span>=linux
make <span style="color: #f8f8f2; font-weight: bold;">PLATFORM</span>=ios
make <span style="color: #f8f8f2; font-weight: bold;">PLATFORM</span>=hurd
make <span style="color: #f8f8f2; font-weight: bold;">PLATFORM</span>=haiku
make <span style="color: #f8f8f2; font-weight: bold;">PLATFORM</span>=cygwin
make <span style="color: #f8f8f2; font-weight: bold;">PLATFORM</span>=cross-linux-mingw
make <span style="color: #f8f8f2; font-weight: bold;">PLATFORM</span>=bsd
make <span style="color: #f8f8f2; font-weight: bold;">PLATFORM</span>=android
make <span style="color: #f8f8f2; font-weight: bold;">PLATFORM</span>=aix

<span style="color: #ff79c6; font-weight: bold;">for</span> more information, consult the README file.
GNUmakefile:64: *** No PLATFORM given.. Alto.
</pre>
</div>

<p>
Básicamente pide una plataforma para la que compilar y me fijé en que
estaba Android entre ellas utilizando la variable <code>PLATFORM</code>. También
es importante tener en mente otra variable que necesitará: <code>PREFIX</code>.
Esta variable le indica al sistema dónde instalarlo. En mi caso,
puesto que me topé con problemas de permisos compilé en GNU/linux
con un <code>PREFIX=~/opt</code>.
</p>
</div>
</div>
<div id="outline-container-orgf58a527" class="outline-2">
<h2 id="orgf58a527">Compilar en termux</h2>
<div class="outline-text-2" id="text-orgf58a527">
<p>
Hay varias cosas a tener en cuenta y algunas cosas que hay que
instalar antes de comenzar la compilación. Evidentemente lo primero
que necesitamos es descargar <i>Chicken</i> y descomprimirlo. En este caso
he preferido bajar la versión estable en un archivo comprimido en
lugar de la copia del repositorio <i>git</i>. La versión que he descargado
es la 4.13.0
</p>

<p>
También hay que instalar algunas herramientas para compilar en termux.
</p>

<div class="org-src-container">
<pre class="src src-shell">apt install make clang gdb cgdb
</pre>
</div>

<p>
He de decir que antes de instalar éstas aplicaciones ya tenía
instaladas algunas otras como <i>emacs</i>, <i>htop</i>, <i>openssh</i> y <i>mc</i>,
además de algunas librerías de las que dependen esas aplicaciones y
quizás por ello no me ha pedido instalar ninguna dependencia más.
</p>

<p>
Con todo listo, compilar e instalar, que lo hice en dos pasos
</p>

<div class="org-src-container">
<pre class="src src-shell">make <span style="color: #f8f8f2; font-weight: bold;">PLATFORM</span>=android <span style="color: #f8f8f2; font-weight: bold;">PREFIX</span>=~/opt
</pre>
</div>

<p>
y tras compilar si todo ha ido bien lo instalamos:
</p>

<div class="org-src-container">
<pre class="src src-shell">make <span style="color: #f8f8f2; font-weight: bold;">PLATFORM</span>=android <span style="color: #f8f8f2; font-weight: bold;">PREFIX</span>=~/opt install
</pre>
</div>

<p>
He instalado en un subdirectorio del directorio personal por problemas
de permisos. La tablet (una bq M10 fhd) se niega a ser <i>rooteada</i> y no
tendría permisos de escritura en los directorios del sistema.
</p>

<p>
Para poder comenzar a utilizar las herramientas hace falta que el
sistema sepa dónde están. Para ello añadí dos líneas al fichero
<code>.bashrc</code> de mi usuario en <i>termux</i>:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #8be9fd; font-style: italic;">export</span> <span style="color: #f8f8f2; font-weight: bold;">PATH</span>=$<span style="color: #f8f8f2; font-weight: bold;">PATH</span>:~/opt/bin
<span style="color: #8be9fd; font-style: italic;">export</span> <span style="color: #f8f8f2; font-weight: bold;">LD_LIBRARY_PATH</span>=$<span style="color: #f8f8f2; font-weight: bold;">LD_LIBRARY_PATH</span>:~/opt/lib:~/opt/lib/chicken/8
</pre>
</div>

<p>
La segunda línea me costó un poco de tiempo darme cuenta del
problema. Cuando compilé en GNU/linux <code>ldconfig</code> funciona
perfectamente, pero en <i>termux</i> no existe tal herramienta. Por eso hay
que decirle, manualmente dónde se encuentran las librerías locales.
</p>

<p>
La verdad es que todo ha sido más fácil de lo que me esperaba cuando
empecé a hacerlo y ni siquiera sabía si se podía. Tengo el <i>chicken
scheme</i> funcionando en la tablet, ¡qué cosas!
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/scheme/index.html">scheme</a> <a href="/tags/programación/index.html">programación</a> ]]></description>
  <category><![CDATA[scheme]]></category>
  <category><![CDATA[programación]]></category>
  <link>https://notxor.nueva-actitud.org/2018/03/05/compilar-chicken-scheme-en-la-aplicacion-termux-de-android.html</link>
  <pubDate>Mon, 05 Mar 2018 16:31:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Qué ando haciendo este 2018]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-03-04</div>
<p>
Desde hace un tiempo no escribo nada en el <i>blog</i> y constantemente
llegaba a mi apartado de <i>pendientes</i> ─en el escaso cerebro que tengo─
el tema de <i>tengo que escribir algo para el blog</i>. Hay que tener en
cuenta que este aparente abandono no es porque no haga nada, sino todo
lo contrario: he estado haciendo muchas cosas y comenzando algunos
proyectos.
</p>
<div id="outline-container-orgb169fb7" class="outline-2">
<h2 id="orgb169fb7">Cosas que voy haciendo</h2>
<div class="outline-text-2" id="text-orgb169fb7">
</div>
<div id="outline-container-orge821d05" class="outline-3">
<h3 id="orge821d05">Escribir</h3>
<div class="outline-text-3" id="text-orge821d05">
<p>
Últimamente escribo todos los días. De momento no escribo nada
publicable que se pueda poner por aquí o por cualquier otro canal. Si
alguna vez me animo a publicar algo ya avisaré a ver si entre los
habituales del <i>blog</i> consigo uno o dos lectores más... bueno, uno o
dos lectores en total no estaría mal.
</p>
</div>
</div>
<div id="outline-container-orgf1af00b" class="outline-3">
<h3 id="orgf1af00b">Limpiando la tablet</h3>
<div class="outline-text-3" id="text-orgf1af00b">
<p>
Cuando me desplazo ─normalmente en moto─ es muy incómodo llevar el
ordenador portátil en la mochila. Poder se puede, para eso es
portátil, pero pesa demasiado y a los veinte minutos de llevarlo
colgado en la espalda en la moto, me sobra todo el ordenador. Por eso,
me compré una <i>tablet</i> baratilla una «bq M10» y un miniteclado
<i>bluetooth</i> para escribir con más soltura que con el teclado virtual
en pantalla, que es un engorro.
</p>

<p>
Llevo tiempo pegándome con ella intentando retirar todo vestigio de
<i>gúgel</i> del <i>chismático</i>. Sigue resistiéndose al <i>rooteo</i> y no consigo
desinstalar todas las mierdas que trae del <i>Gran Hermano</i>, pero de
momento he conseguido deshabilitar bastantes. Ahora mismo sólo estoy
utilizando aplicaciones que se puedan descargar desde <a href="https://f-droid.org">f-droid</a>. He
conseguido sustituir el <i>launcher</i> que venía por defecto: de momento
estoy probando <a href="https://f-droid.org/packages/com.quapp.launchtime/">Launch time</a> y parece funcionar correctamente. Me
permite ordenar por categorías las aplicaciones. La traducción es
terrible y he modificado las categorías y los colores. Además me
permite ocultar las aplicaciones que no quiero utilizar, por ejemplo,
todas las que no me ha dejado <i>android</i> inhabilitar, han pasado a la
categoría «escondido».
</p>

<p>
Pero no descarto, conseguir en algún momento el <i>rooteo</i> de la máquina
y quitar todo lo que sobra. El ideal sería poder instalarle alguna
<i>distro</i> GNU/Linux para ARM. Pero bueno, de momento me conformo con
<a href="https://f-droid.org/packages/com.termux/">termux</a> que permite instalar <i>git</i>, <i>openssh</i>, <i>emacs</i>, <i>ledger</i> y
muchas más aplicaciones que utilizo en el día a día.
</p>
</div>
</div>
<div id="outline-container-orgaf7b623" class="outline-3">
<h3 id="orgaf7b623">Scheme</h3>
<div class="outline-text-3" id="text-orgaf7b623">
<p>
Llevo trasteando un tiempo con el <i>scheme</i>, que como la mayoría
sabréis ya de sobra, es uno de los herederos del paradigma iniciado
por <i>lisp</i>. El objetivo es cambiar un poco mis (dos) neuronas,
oxidadas y bloqueadas en la <i>programación orientada a objetos</i>, hacia
la <i>programación funcional</i>. Después de intentar varias veces entender
cómo funciona <i>Haskell</i> me parece que primero tengo que «desaprender»
algunas cosas y cambiar mi forma de aproximarme a los problemas de
programación.
</p>

<p>
He trasteado en tiempos pasados con <i>emacs-lisp</i> para aprender a hacer
algunas cosas con él ─y sigo utilizándolo─ pero me atrae
<i>scheme</i>. Comencé con <a href="https://www.gnu.org/software/guile/"><i>guile</i></a> y sigo utilizándolo ─no me entendáis
mal─, es un buen <i>scheme</i>. Sin embargo, por algún sitio que ahora no
recuerdo alguien recomendó <a href="https://call-cc.org"><i>chicken scheme</i></a> y decidí probarlo... ¿por
qué?: Pues porque tiene <i>eggs</i> la cosa. Incluso encontré paquete
precompilado para <i>OpenSuse</i>. Pero no funcionó a la primera. Bueno sí,
funcionó pero me daba de bruces siempre cuando quería instalar alguna
librería que no viene con la instalación básica. En <i>chicken</i> esas
librerías se llaman <i>eggs</i> y para mí era básico instalar la <i>utf8</i> y
alguna más. Una de las características que más me atrajo de chicken es
la posibilidad de compilar a C y generar ejecutables independientes.
</p>

<p>
Después de varios intentos de compilarme yo el sistema, lo conseguí y
lo tengo instalado, funcionando y pudiendo instalar y desintalar
<i>eggs</i> para ampliar aún más su funcionalidad. De hecho estoy
intentando compilarlo dentro de <i>termux</i> de <i>android</i>. Sin éxito de
momento, pero aún no he tirado la toalla.
</p>
</div>
<div id="outline-container-org1cc6c86" class="outline-4">
<h4 id="org1cc6c86">El proyecto</h4>
<div class="outline-text-4" id="text-org1cc6c86">
<p>
Para aprender cualquier lenguaje de programación, hay que
practicar. Por eso he pensado en hacer algo, algún proyecto,
obligándome a utilizar el lenguaje en cuestión. He decidido que lo
haré con <i>chicken</i>.
</p>

<p>
El proyecto que se me ha ocurrido es complejo y no sé si conseguiré
llevarlo a término. Desde que era joven y estudiaba en la facultad de
psicología me fascinaban las «inteligencias artificiales». Recuerdo
que me hablaron de algunas en la asignatura de «pensamiento y
lenguaje». Sin embargo, dada la <i>peculiaridad</i> del catedrático y su
cohorte esa asignatura y toda la «psicología cognitiva» se convirtió,
en esa facultad, en una de las materias más odiadas de todo el
programa educativo. Para mí, la «disonancia cognitiva» era
impresionante: me atraía lo mismo que odiaba. Con el tiempo aprendí a
separar a las personas de la materia que (no) enseñaban.
</p>

<p>
Mi idea de proyecto es hacer una <i>inteligencia artificial</i>, algo para
lo que <i>lisp</i> se ha utilizado con mucha frecuencia. Pero qué hará esa
inteligencia artificial aún no lo sé, desde luego no conducir mi coche
─creo que el seguro no me lo perdonaría─. De hecho, los sistemas que
más me llamaban la atención son los que hacen tareas propiamente
humanas donde se supone que no hay posibilidad de «automatizar»
tareas. Eso pensaba con el ajedrez y el go, y ya hay máquinas que
juegan mejor que los campeones humanos. También leí por ahí que se ha
publicado un libro con poemas escritos por una inteligencia
artificial, he leído alguno de esos poemas y no están mal ─aunque sé
que están escogidos, la máquina generará miles de poemas para elegir
unos pocos─. También he leído por ahí sobre algunas IA que escribe
prosa siguiendo parámetros como «personajes» y «escenarios». Incluso
una que escribió un capítulo completo de «Juego de Tronos» dándole
como entrada las novelas y guiones de la serie.
</p>

<p>
<a href="https://es.wikipedia.org/wiki/Test_de_Turing">Mi objetivo no es hacer una IA que supere el <i>Test de Turing</i></a>, pues me
conformo con aprender <i>scheme</i> y la <i>programación
funcional</i>. Seguramente no conseguiré nada aprovechable de ello, salvo
aprender algunas cosas. De momento estoy leyendo y documentándome por
la página web de la <a href="https://www.sepln.org">Sociedad Española para el Procesamiento del Lenguaje Natural</a> a ver si aprendo algo. Y también me estoy leyendo
─para aprender algo─
<a href="https://www.gelbukh.com/libro-procesamiento-2/">Procesamiento automático del español con enfoque en recursos léxicos grandes</a>.
</p>
</div>
</div>
</div>
</div>
<div id="outline-container-orgbaddc6e" class="outline-2">
<h2 id="orgbaddc6e">Otras cosillas pendientes</h2>
<div class="outline-text-2" id="text-orgbaddc6e">
</div>
<div id="outline-container-org683f538" class="outline-3">
<h3 id="org683f538">Proyectos pendientes</h3>
<div class="outline-text-3" id="text-org683f538">
<p>
Además sigo con el proyecto de la isla, que ha sufrido un parón al
pasar de <i>BlenderEngine</i> a <i>Godot Engine</i>. Sin embargo, sigue ahí
pendiente a que aprendamos cómo va el nuevo sistema.
</p>
</div>
</div>
<div id="outline-container-orgb04f552" class="outline-3">
<h3 id="orgb04f552">Nuklear</h3>
<div class="outline-text-3" id="text-orgb04f552">
<p>
Trasteando con los <i>eggs</i> de <i>chicken</i>, por casualidad... Bien bueno,
he de admitir que por torpeza, quise pinchar en <i>ncurses</i> en la lista
de <i>eggs</i> y pinché en <i>nuklear</i>, que era el siguiente de la
lista. Bueno, el caso es que acabé mirando de qué iba y me encontré
una librería curiosa. <a href="https://github.com/vurtum/nuklear/">Nuklear</a> es una librería GUI minimalista
autocontenida en un sólo fichero cabecera de C. Ahí va el código, la
documentación y todo, sólo tienes que enlazar tu programa con
él. Además las <i>screenshots</i> que se muestran en el sitio del código
están bastante curiosas y producen GUI's, bastante agradables de
ver. Así que nada... otra cosa que se añade a pendientes.
</p>

<p>
De hecho no descarto que si al proyecto de la IA en marcha decido
ponerle un <i>UI</i>, más allá del <i>CLI</i> que había pensado desde el
principio, seguramente aproveche para echarle un ojo.
</p>

<p>
Pues en esas cosas ando.
</p>
</div>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/proyectos/index.html">proyectos</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[proyectos]]></category>
  <link>https://notxor.nueva-actitud.org/2018/03/04/que-ando-haciendo-este-2018.html</link>
  <pubDate>Sun, 04 Mar 2018 19:01:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Convirtiendo el proyecto de la isla a Godotengine]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-02-03</div>
<p>
Después de trabajar un poco más en el proyecto de la isla, del que ya
he hablado por aquí unas pocas de veces y vistas las limitaciones que
nos hemos encontrado con el <i>gameengine</i> de <i>Blender</i>, hemos decidido
dar un paso más y probar con el <a href="https://godotengine.org/">prometedor <i>gameengine</i> godot</a>, en su
novísima versión 3.0.
</p>


<figure id="orgcae0216">
<img src="./imagen/captura-isla-godot.png" alt="captura-isla-godot.png">

</figure>

<p>
He puesto ahí una captura de cómo va el tema de la importación y
comentar algunos problemas que me he encontrado. Especialmente con el
tema de los materiales.
</p>

<p>
Básicamente, los materiales que estábamos utilizando eran colores
planos. Un color de material y un color de brillo. Los materiales más
complejos eran, apenas, un mapa UV. Sin embargo, el problema que me he
encontrado al hacer la importación es que algunos materiales se van
directamente a <i>negro</i>. Estoy investigando aún por qué ocurre eso y si
podemos arreglarlo.
</p>

<p>
El trabajo de importación está siendo un poco ensayo-error y poco a
poco vamos avanzando. Ahora estoy con el «muñecajo» que es más
complejo pues además lleva incorporadas animaciones.
</p>

<p>
Poco a poco, espero ir aprendiendo, no sólo a exportar desde <i>blender</i>
e importar desde <i>godot</i>, sino también, y mucho más importante, que
empecemos a encontrarnos cómodos con la herramienta del <i>engine</i>. De
momento no soy nada productivo con ella. Veo en ella muchos
<i>pichorros</i> pero aún no sé para qué sirve cada una exactamente. Paso
más tiempo mirando documentación que haciendo algo productivo.
</p>

<p>
Así pues, sin prisa, pero sin pausa.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/juegos/index.html">juegos</a> <a href="/tags/programación/index.html">programación</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[juegos]]></category>
  <category><![CDATA[programación]]></category>
  <link>https://notxor.nueva-actitud.org/2018/02/03/convirtiendo-el-proyecto-de-la-isla-a-godotengine.html</link>
  <pubDate>Sat, 03 Feb 2018 13:07:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Gráficos y org-mode (de nuevo)]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-01-31</div>
<p>
Hace un tiempo que utilizo <code>org-mode</code> para casi todo y también utilizo
<i>ditaa</i>, <i>PlantUML</i> y <i>graphviz</i> para realizar los gráficos que
necesito. <i>Ditaa</i> es un sistema que convierte un gráfico <i>ASCII</i> en un
fichero gráfico de diagramas.
</p>

<div class="org-src-container">
<pre class="src src-nil">+-----------+   +-------+    +----------+
|           |   |       |    |          |
|           +---+ ditaa +---&gt;|          |
| Documento |   +-------+    | diagrama |
| de texto  |   |¡magia!|    |          |
|     {d}   |   |       |    |          |
+------+----+   +-------+    +----------+
       :                         ^
       |       Mucho trabajo     |
       \-------------------------/
</pre>
</div>
<div id="outline-container-org5ad740e" class="outline-2">
<h2 id="org5ad740e">Problemas con <i>ditaa</i></h2>
<div class="outline-text-2" id="text-org5ad740e">
<p>
Hace unos días me di cuenta que <i>Ditaa</i> no me funciona. Debe haber
alguna incompatibilidad con la versión de <i>java</i> que tengo en el
ordenador. En alguna actualización el <code>jar</code> compilado compilado de la
herramienta dejó de funcionar y ahora no lo puedo llamar
directamente. Sin embargo, he encontrado el modo de hacerlo a través
de otra de las herramientas que utilizo habitualmente: <i>PlantUML</i>.
</p>

<p>
Efectivamente, con <i>PlantUML</i> puedo <i>renderizar</i> ─qué palabra más fea─
el gráfico de <i>Ditaa</i>. Por ejemplo, el caso anterior lo meto entre
etiquetas <code>startditaa</code> y <code>endditaa</code>.
</p>

<p>
El código quedaría de la siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-org">#+BEGIN_SRC plantuml :file plantuml-ditaa.png :cmdline -charset UTF-8 -tpng
@startditaa
<span style="color: #bd93f9;">+-----------+   +-------+    +----------+</span><span style="color: #bd93f9;">
</span><span style="color: #bd93f9;">|           |   |       |    |          |</span><span style="color: #bd93f9;">
</span><span style="color: #bd93f9;">|           +---+ ditaa +---&gt;|          |</span><span style="color: #bd93f9;">
</span><span style="color: #bd93f9;">| Documento |   +-------+    | diagrama |</span><span style="color: #bd93f9;">
</span><span style="color: #bd93f9;">| de texto  |   |&#161;magia!|    |          |</span><span style="color: #bd93f9;">
</span><span style="color: #bd93f9;">|     {d}   |   |       |    |          |</span><span style="color: #bd93f9;">
</span><span style="color: #bd93f9;">+------+----+   +-------+    +----------+</span><span style="color: #bd93f9;">
</span>       <span style="color: #50fa7b;">:                         ^
</span><span style="color: #bd93f9;">       </span><span style="color: #bd93f9;">|       Mucho trabajo     |</span><span style="color: #bd93f9;">
</span>       \-------------------------/
@endditaa
</pre>
</div>
<p>
#+END_SRC
</p>


<figure id="org9f993f0">
<img src="./imagen/plantuml-ditaa.png" alt="plantuml-ditaa.png">

</figure>

<p>
Me resulta curioso que <i>Ditaa</i> no me funcione directamente y sin
embargo, <i>PlantUML</i> sea capaz de hacer su trabajo. Así pues, de
momento prescindo de aquella herramienta para quedarme con la más
completa.
</p>
</div>
</div>
<div id="outline-container-org4b00140" class="outline-2">
<h2 id="org4b00140">PlantUML y LaTeX</h2>
<div class="outline-text-2" id="text-org4b00140">
<p>
Estos días necesité integrar algunas fórmulas matemáticas en un
esquema <i>UML</i>. Y casi me vuelvo loco, porque la herramienta a la que
me estoy acostumbrando es <i>PlantUML</i> integrada en <code>org-mode</code>. Sin
embargo, el trabajo con fórmulas matemáticas es habitual que lo haga
con <i>LaTeX</i> y resulta que encontré el modo en la documentación de
<i>PlantUML</i> para meter las matemáticas en los gráficos: Algo tan
sencillo como rodear el código con las etiquetas <code>&lt;math&gt;...&lt;/math&gt;</code> o
<code>&lt;latex&gt;...&lt;/latex&gt;</code> del siguiente modo.
</p>

<div class="org-src-container">
<pre class="src src-nil">#+BEGIN_SRC plantuml :file plantuml-mates.png :cmdline -charset UTF-8 -tpng
@startuml
:&lt;math&gt;int_0^1f(x)dx&lt;/math&gt;;
note left
Hecho con asciimath
ASCIIMathTeXImg.js
integrado en PlantUML
end note
:&lt;latex&gt;x^{2}+y_{1}+z_{12}^{34}&lt;/latex&gt;;
note left
Hecho con JLatexMath
hay que descargar los jar
a parte.
end note
:Probar también;
note right
&lt;latex&gt;\frac{d}{dx} f(x) = \lim_{h \to 0} \frac{f(x+h) - f(x)}{h}&lt;/latex&gt;
&lt;latex&gt;P(y|\mathbf{x}) \mbox{ or } f(\mathbf{x})+\epsilon&lt;/latex&gt;
end note
@enduml
</pre>
</div>
<p>
#+END_SRC
</p>


<figure id="org395a5c2">
<img src="./imagen/plantuml-mates.png" alt="plantuml-mates.png">

</figure>

<p>
Cada etiqueta está gestionada por una librería distinta. La etiqueta
<code>&lt;math&gt;</code> la gestiona <code>ASCIIMathTeXImg.js</code> y está integrado en la misma
herramienta <i>PlantUML</i>. Sin embargo, la etiqueta <code>&lt;latex&gt;</code> está
gestionada por la librería <code>JLatexMath</code>, yo la instalé en sistema
porque no la tenía, pero además pide que esté en el mismo directorio
donde se encuentra el <code>jar</code> de <i>PlantUML</i>. Probé, pero me dio algunos
problemas. No sé si porque utilicé un enlace en lugar de copiar el
fichero al directorio. Al final, leyendo la (breve) documentación en
la <i>web</i> de <i>PlantUML</i> indica un enlace donde descargar la librería
dividida en cuatro ficheros <code>jar</code>. Lo descomprimí y el resultado se
puede ver en el ejemplo anterior.
</p>
</div>
</div>
<div id="outline-container-org345b2b5" class="outline-2">
<h2 id="org345b2b5">Conclusión</h2>
<div class="outline-text-2" id="text-org345b2b5">
<p>
Cada vez me encuentro más cómodo con <code>org-mode</code> y sus (casi) infinitas
posibilidades. En este caso porque <i>suma</i> con las posibilidades de
otras herramientas como <i>PlantUML</i>. ¿Alguna aplicación monolítica es
capaz de sumar así? Es decir, claro, puedo utilizar cualquier
herramienta, generar el gráfico en importarlo. Pero no <i>suma</i> o en
caso de poder hacer algún <code>macro</code> o <code>plugin</code>, tengo que liarme en
cosas mucho más complicadas.
</p>

<p>
Y ─no recuerdo con quién─ hablaba el otro día con un amigo sobre la
filosofía <i>Unix</i> y la filosofía <i>güindón</i>. Mi argumentación era que me
quedaba con las cosas sencillas, con programas simples que hacen muy
bien y rápido lo que tienen que hacer y me permiten unirlos. En ese
sentido veo también <code>org-mode</code> como un <i>pegamento</i> de diferentes
herramientas. Quizás, por esto también, me apetecía mantener <i>Ditaa</i>,
más sencilla que <i>PlantUML</i>, sin embargo, la falta de funcionamiento
ha sido crítica, pues lleva sin actualizarse ya algunos años.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/varios/index.html">varios</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2018/01/31/graficos-y-org-mode-de-nuevo.html</link>
  <pubDate>Wed, 31 Jan 2018 23:13:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Terapio de akcepto kaj sindevigo]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-01-16</div>
<p>
Antaŭ mi komencos ti ĉiun artikolon mi devas peti al vi etan aferon:
la ciferoj estas 1, 2, 3. Rediru: la ciferoj estas 1, 2 kaj 3. Sed vi
devas forgesi tiujn ciferojn, mi rediras al vi ke vi devas forgesi ke
la ciferoj estas 1, 2 kaj 3.
</p>

<p>
Se vi vere forgesos ke la ciferoj estas 1, 2 kaj 3, vi havos donacon
fine.
</p>
<div id="outline-container-org97a6bb5" class="outline-2">
<h2 id="org97a6bb5"><i>ACT</i> (Terapio de akcepto kaj sindevigo)</h2>
<div class="outline-text-2" id="text-org97a6bb5">
<p>
<i>Terapio de akcepto kaj sindevigo</i> estas terapio de tiaj nomataj <i>de
tria generacio</i>. Ĝia nomo <i>ACT</i> devenas el sia nomo en la angla
<i>Acceptance and Commitment Therapy</i> kaj oni devas prononci, kiel <i>act</i>
(agu) en la angla. Ĝi estas bazita sur la empiria laboro en
terapio. Sed unue ni devas pensi pri la <i>feliĉo</i>. Multaj el homaj
problemoj venas de konataj mispensoj. Ofte, la klientoj de psiĥologia
kabineto diras: «mi nur volas esti feliĉa» aŭ «mi volas esti tiel
feliĉa kiel la aliaj ŝajnas». Sed, kio estas feliĉo?
</p>
</div>
</div>
<div id="outline-container-orgcd87c86" class="outline-2">
<h2 id="orgcd87c86">La feliĉo</h2>
<div class="outline-text-2" id="text-orgcd87c86">
<p>
Pri kio ni parolas kiam ni parolas pri feliĉo? Tiu demando estas
grava, ĉar kelkaj fojoj ni povas miskompreni la vortojn. Ofte ni uzas
«feliĉon» por paroli pri sentoj agrablaj, ĝojaj, gajaj kaj
kontentiĝaj. Tiuj sentoj ni nomas «pozitivajn sentojn», kaj ni
serĉas tiajn sentojn. Sed tiuj sentoj estas nedaŭraj, efemeraj. La
alia signifo de feliĉo estas «vivo plena, riĉa kaj signifoplena». Tiu
dua senco estas pli daŭra kaj ankaŭ pli ĝusta por nia vivo. Sed ni,
ofte nur volas la unuan kaj forgesas la duan.
</p>

<p>
La afero estas ja facila: ni devas forgesi la unuan kaj serĉi la
duan. Sed kial ni ne trovas la vojon? En la okcidenta kulturo ni
trovas multajn kaptilojn. Komence, la feinorakontoj kiuj kutime
finiĝis tiel: «... kaj vivis feliĉaj por ĉiam». Sed ĉu la vivo estas
tia, kia feinorakontoj?
</p>
</div>
<div id="outline-container-org9129a6b" class="outline-3">
<h3 id="org9129a6b">Unua mito: feliĉo estas la natura stato de ĉiu homo</h3>
<div class="outline-text-3" id="text-org9129a6b">
<p>
Preskaŭ 30% el la homoj suferas psiĥiatran malsanon dum sia vivo. Kaj
ni ne parolu pri aliaj problemoj: la soleco, divorco,
hejma perforto, streso, kolero, ĉikanado.
</p>

<p>
Multaj homoj vivas pensantaj ke ĉiuj estas pli feliĉaj ol ili mem, kaj
ĉi tio faris ilin pli malfeliĉaj.
</p>
</div>
</div>
<div id="outline-container-org4acc47a" class="outline-3">
<h3 id="org4acc47a">Dua mito: se vi ne estas feliĉa vi havas iun difekton</h3>
<div class="outline-text-3" id="text-org4acc47a">
<p>
La okcidenta socio supozas ke la mensa sufero estas malsano aŭ difekto
kaj ĝi estas rezulto el malsana aŭ difekta menso. Sed por la <i>ACT</i>, la
problemo ne estas havi negativajn pensojn, sed lerni kiel fari por
vivi kun tiaj pensoj.
</p>
</div>
</div>
<div id="outline-container-org35a3044" class="outline-3">
<h3 id="org35a3044">Tria mito: ni devas lasi la negativajn pensojn por havi pli bonan vivon</h3>
<div class="outline-text-3" id="text-org35a3044">
<p>
En la okcidenta socio, oni pensas ke ni devas forgesi la negativajn
pensojn por havi bonan vivon. Sed kiel oni povas lasi tiajn pensojn?
Kiel oni povas forgesi la malbonajn pensojn?
</p>

<p>
Kiuj estas la ciferoj? Ĉu vi memoras ilin aŭ ĉu ne? Kiel oni faras por
forgesi ion? La unua konsilo kiun donas homoj al kiu suferas
estas: «ne pensu tion, forgesu»; sed neniu povas diri kiel oni povas
forgesi ion. Kaj oni ne povas diri tion, ĉar ni povas forgesi nenion
propravole.
</p>
</div>
</div>
<div id="outline-container-org18efc84" class="outline-3">
<h3 id="org18efc84">Kvara mito: vi devas kontroli, kion vi sentas, kaj, kion vi pensas</h3>
<div class="outline-text-3" id="text-org18efc84">
<p>
La plimulto de la memhelpaj programoj pensas ke ni povas kontroli
penson kaj senton. Tio estas malvero. La pensoj kaj la sentoj evoluis
por prepari nin por la sovaĝa vivo. La sentoj estas rapidaj, oni timas
aŭ ĝojas nur je sekundoj. La pensoj estas pli malrapidaj sed pli
insidaj. Nia menso laboras ĉiam, neniam haltas, nur pensas, ĝi
rimarkas danĝerojn, problemojn. Tiu estas sia temo.
</p>

<p>
Dum miloj da jaroj, niaj mensoj kaj niaj sentoj evoluis por labori
tiel. Kaj bone: kiel oni povas ŝanĝi ilin post miloj da jaroj de
evoluo? Ĉu ni estus pli frenezaj pensantaj male?
</p>
</div>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <link>https://notxor.nueva-actitud.org/2018/01/16/terapio-de-akcepto-kaj-sindevigo.html</link>
  <pubDate>Tue, 16 Jan 2018 00:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Plataformas enañosas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-01-13</div>
<div id="outline-container-orgac39cd7" class="outline-2">
<h2 id="orgac39cd7">Leer gratis</h2>
<div class="outline-text-2" id="text-orgac39cd7">
<p>
El otro día me llegó <a href="https://luluvonflama.wordpress.com/2018/01/06/leer-gratis-es-posible-y-deberias/">un enlace que me pareció interesante</a> y decidí
seguirlo. Además, el <i>blog</i> de Coral Carracedo ─o Lulú von Flama, como
firma en su faceta de escritora─, me pareció interesante y estuve
echándole un ojo.
</p>

<p>
El enlace que me llegó lo titula <i>«Leer gratis es posible (y
deberías)»</i>. ¡Fantástico! Y nos cuenta que lleva un año leyendo libros
gratis. Algunos, se los envía alguna editorial para que haga reseña,
corrija, etc. Lo que no deja de ser un trabajo. Estupendo. Pero a mí
las editoriales no me mandan nada, así que esa vía para mí está
cerrada. No pasa nada, vamos a las otras...
</p>

<p>
En el siguiente texto hay enlaces a muchos relatos. El primero que veo
es uno titulado <i>Trigo17</i>. Pincho, lo leo y me gusta ─vale, tampoco es
la octava maravilla del mundo, pero está aceptablemente escrito y no
deja de ser un punto de vista curioso del abandono del campo a favor
de las ciudades─. Sigo con los otros relatos y me encuentro que no
puedo leer ninguno.
</p>
</div>
</div>
<div id="outline-container-org166609b" class="outline-2">
<h2 id="org166609b">Lektu</h2>
<div class="outline-text-2" id="text-org166609b">
<p>
No es que esté muy a favor de los sitios de autoedición. La mayoría me
parecen una panda de aprovechados. Pero siguiendo las lecturas del
artículo resultó que la mayoría de los enlaces están referidos una
página donde puedes <i>autoeditar</i> tus libros, <a href="https://lektu.com/unete">allí afirman</a>:
</p>

<blockquote>
<p>
Aquí los <b>creadores</b> podéis <b>subir vuestro contenido digital</b> para
ponerlo a disposición de los clientes. <b>Sin cuotas de alta ni
mantenimiento</b>. Sólo cobramos comisión si hay transacción económica.
</p>

<p>
Si tus productos son gratuitos no te cobraremos nada.
</p>
</blockquote>

<p>
Y después añaden de forma entusiasta:
</p>

<blockquote>
<p>
<b>Sin DRM</b>. Una de nuestras banderas es la justa comercialización del
 contenido digital que ofrecemos, sin barreras que impidan el disfrute
 del mismo.
</p>
</blockquote>

<p>
Después de leer eso pensé que realmente era un sitio comprometido y
abierto. Pinché en el <i>pichorro</i> de registro y quedé impactado. Puedes
registrarte de cuatro modos, por <i>facebook</i>, por <i>Twitter</i>, por
<i>Google</i> o por correo electrónico. ¡Uff! ¡Qué pereza! Bueno, voy por
el modo del <i>email</i>.
</p>

<p>
Tampoco. Si tienes el <i>javascript</i> de la <i>gran G</i> bloqueado ─porque no
tengo nada que ocultar, pero aprecio mucho mi privacidad─, la <i>gran G</i>
informa sistemáticamente que eres un <i>bot</i> y no te dejan
registrarte. Nada, pues no me registro, no leeré nada de esa página,
tampoco subiré nada a esa página, pero que no digan que no tienen
<i>barreras que impidan el disfrute</i> del contenido. No las tienen si
estás dispuesto a informar a la <i>gran G</i>, o al <i>caralibro</i>, o al
<i>tuister</i> de lo que haces, de lo que lees, de lo que te interesa y
ellos puedan contrastar con sus algoritmos con quién te relacionas,
cuánto dinero ganas y qué pueden venderte.
</p>
</div>
</div>
<div id="outline-container-org9489258" class="outline-2">
<h2 id="org9489258">Redes sociales</h2>
<div class="outline-text-2" id="text-org9489258">
<p>
Ya me había leído las <i>condiciones de uso</i> y todo. Me había llamado la
atención el primer párrafo del punto <i>7- Redes sociales</i>:
</p>

<blockquote>
<p>
Las redes sociales son servicios de la sociedad de la información
prestados por terceros proveedores que permiten a los usuarios
participar en una comunidad virtual con otros usuarios a través de la
que pueden generar su propio perfil público, crear y compartir
contenidos, informaciones y datos personales con otros usuarios de la red.
</p>
</blockquote>

<p>
Yo hubiera puesto entre comillas lo de <i>comunidad</i>. Para que haya
realmente comunidad debe haber un compromiso y un deseo de
encuentro. Las redes sociales a las que se refiere ese párrafo no
forman <i>comunidades</i>, son básicamente una <i>granja de datos</i> para la
empresa que gestiona el entramado. No les interesa la interacción real
o social, no les interesa que esas relaciones fluyan entre redes, sino
concentrar cuanta más información posible encapsulada en sus propios
servidores. A esas empresas no las interesa el compromiso y el
encuentro de las personas. Sus páginas están diseñadas no para
beneficio de sus usuarios, sino para beneficio propio. Aprovechan
<a href="https://notxor.nueva-actitud.org/blog/2017/12/12/me-gusta/">algunos <i>fallos</i> del cerebro humano</a> para obtener cuantos más datos
mejor.
</p>

<p>
Me pregunto qué pensará <i>Lektu</i> sobre las redes sociales libres como
<i>Diaspora*</i>, <i>GNUsocial</i>, <i>Mastodon</i>, etc. ¿Estarían dispuestos a
facilitar el registro a su página con esas redes sociales y no con las
privativas de tres empresas estadounidenses?
</p>
</div>
</div>
<div id="outline-container-orgc400fc7" class="outline-2">
<h2 id="orgc400fc7">Conclusión</h2>
<div class="outline-text-2" id="text-orgc400fc7">
<p>
Bueno, seguiré leyendo gratis. Al fin y al cabo sigue existiendo
<a href="https://epublibre.org">https://epublibre.org</a> para los libros que leo de ficción y
<a href="https://openlibra.org">https://openlibra.org</a> para los libros técnicos que necesito.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/libertad-digital/index.html">libertad-digital</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[libertad-digital]]></category>
  <link>https://notxor.nueva-actitud.org/2018/01/13/plataformas-enganosas.html</link>
  <pubDate>Sat, 13 Jan 2018 23:21:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Cambios en mi prompt]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2018-01-09</div>
<div id="outline-container-org0179467" class="outline-2">
<h2 id="org0179467">Utilizar un <i>prompt</i> más informativo</h2>
<div class="outline-text-2" id="text-org0179467">
<p>
Llevo ya un tiempo utilizando <i>git</i> para casi todo y a veces me lío yo
sólo con las ramas y para saber dónde estoy en cada
momento. Normalmente trabajo con <i>emacs</i>, lo que me facilita mucho el
trabajo: cuando editas un fichero que está incluido en un repositorio
muestra en qué rama y tengo <i>magit</i> para desplegar el contenido de
todo el <i>git</i>. Sin embargo, muchas veces me encuentro en un terminal y
ahí ando algo perdido... vale, puedo comprobar en qué rama estoy con
el comando correspondiente, bien :
</p>

<div class="org-src-container">
<pre class="src src-bash">&gt; git checkout
</pre>
</div>

<p>
o bien:
</p>

<div class="org-src-container">
<pre class="src src-bash">&gt; git branch
</pre>
</div>

<p>
Yo estaba buscando algo más visible, <a href="https://kate-editor.org/2018/01/08/fancy-terminal-prompt/">lo encontré ayer</a> y decidí
probarlo. Es un <i>script</i> sencillo para generar el
<i>prompt</i>. Normalmente lo pones en el fichero <code>~/.bashrc</code> y es el
siguiente:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #6272a4;"># </span><span style="color: #6272a4;">utilizar un prompt informativo
</span><span style="color: #f8f8f2; font-weight: bold;">PS1</span>=<span style="color: #f1fa8c;">"\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\W\[\033[00m\]"</span>
<span style="color: #f8f8f2; font-weight: bold;">PS1</span>=<span style="color: #f1fa8c;">"$PS1 \`if [ \$? = 0 ]; then echo -e '\[\033[01;32m\]:)';"</span>
<span style="color: #f8f8f2; font-weight: bold;">PS1</span>=<span style="color: #f1fa8c;">"$PS1 else echo -e '\[\033[01;31m\]:(' \$?; fi\`\[\033[00m\]"</span>
<span style="color: #f8f8f2; font-weight: bold;">PS1</span>=<span style="color: #f1fa8c;">"$PS1 \$(</span><span style="color: #fa8072;">__git_ps1 \"(%s</span><span style="color: #f1fa8c;">)\")&gt; "</span>
</pre>
</div>

<p>
Llevo probándolo desde que lo encontré y me parece que se va a quedar
tiempo (por lo menos hasta que me apañe mejor con <i>git</i>). Le he hecho
unas mínimas modificaciones, como «desnarigar» el emoticono que
muestra y cambiar el último carácter con «&gt;» en lugar del «$».
</p>
</div>
<div id="outline-container-orgd361e0c" class="outline-3">
<h3 id="orgd361e0c">Ventajas que le veo</h3>
<div class="outline-text-3" id="text-orgd361e0c">
<p>
Soy de natural torpe y muchas veces me aprendo fórmulas que aplico con
prisas y no leo lo que debería leer, como las salidas de los
comandos. Ahora voy con mucho cuidado con <i>git</i> y leo muy
detenidamente toda salida que produce, pero ya me noto la tendencia a
ignorar la salida de algunos comandos que utilizo con asiduidad.
</p>

<p>
La ventaja principal es que el <i>prompt</i>, cuando entro en un directorio
que está gestionado por un repositorio <i>git</i>, muestra entre paréntesis
el nombre de la rama activa. Para mí esa es una gran ayuda,
especialmente en la gestión de este <i>blog</i> donde gestiono normalmente
tres ramas y muchas veces me puedo perder un poco de en cuál estoy.
</p>

<p>
La otra ventaja es que muestra un emoticono según el último comando
haya tenido éxito o no. Si el último comando devuelve «0» mostrará un
emoticono verde «:)» y si ha fallado un emoticono rojo
«:(». Visualmente me da la pista de si el último comando ha funcionado
o no y me obliga a leer la salida.
</p>

<p>
El inconveniente es que muestra sólo el último directorio local de
todo el <i>path</i>. La mayoría de las veces es suficiente y si alguna vez
necesito más información siempre tendré a mano el <code>pwd</code>. Esto, no es
ventaja ni inconveniente, pues algunas veces te mueves por según que
directorios que en consolas pequeñas tiene que saltar de línea. Y al
contrario, habrá veces que muestre un directorio <code>src</code> pero vete tú a
saber de cuál de todos los proyectos que puedo tener abiertos.
</p>
</div>
</div>
</div>
<div id="outline-container-org2806b46" class="outline-2">
<h2 id="org2806b46">Conclusión</h2>
<div class="outline-text-2" id="text-org2806b46">
<p>
De momento me ha costado poco acostumbrarme a los cambios en el
<i>prompt</i>. Me parece un <i>script</i> útil, sobre todo cuando utilizas <i>git</i>
y tienes varias ramas de trabajo.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/linux/index.html">linux</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[linux]]></category>
  <link>https://notxor.nueva-actitud.org/2018/01/09/cambios-en-mi-prompt.html</link>
  <pubDate>Tue, 09 Jan 2018 16:01:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Rakonto de la du monaĥoj trairantaj la arbaron]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-12-16</div>
<div id="outline-container-orgeb369be" class="outline-2">
<h2 id="orgeb369be">Tasko</h2>
<div class="outline-text-2" id="text-orgeb369be">
<p>
Verki rakonton per minimune 200 vortoj.
</p>
</div>
</div>
<div id="outline-container-org17146a2" class="outline-2">
<h2 id="org17146a2">Rakonto</h2>
<div class="outline-text-2" id="text-org17146a2">
<p>
Iam, monaĥo kaj novico frue trairadis arbaron. La mateno estis luma
post multaj pluvantaj tagoj. Tiel, ĉio estis verda kaj freŝa, kiel
lavita. Ĝi ŝajnis nova mondo por ekuzi ĝin. Ili piediris per nudaj
piedoj kaj silente por observi siajn votojn. La koto montriĝis ĉe la
randoj de la vojo kaj ĝi ne baris iliajn paŝojn. Ilia celo estis la
bazaro, kiu okazos por la ĉefa festo de la vilaĝo, kie ili provos peti
monon por sia monaĥejo. Ili ne tro hastis laŭ la vojo. Ili ĝuis la
belan kaj vigligantan naturon, sed ili ankaŭ ne prokrastigis la
marŝon.
</p>

<p>
Tiam, ili ekvidis virinon diste antaŭe en la vojo. Ŝi rigardis
malsupren kaj ŝi moviĝis maltrankvile tien kaj tie. Kiam ili pli
proksimiĝis al ŝi, ili vidis rivereton, kutime seka, kiu trairis la
vojon. Ne estis profunda rivereto, oni povis travadi ĝin piede, kaj la
akvo nur atingus la maleolojn. Sed la juna virino portis blankan
festan veston, tre puran kaj brilan kaj ŝi ne volis malpurigi
ĝin. Tial ŝi dubis antaŭ la kotaj bordoj de la rivereto kaj ŝi ne
kuraĝis travadi ĝin.
</p>

<p>
Kiam la monaĥo atingis la bordon, prenis la junan virinon brake kaj li
alportis ŝin ĝis la alia flanko, kie li lasis ŝin denove al tero. La
juna virino tre dankis la agon al la monaĥo, kiu silente akceptis la
dankon per riverenco kaj li daŭrigis sian vojon sekvita de
maltrankvila novico.
</p>

<p>
Dum la sekvantaj du leŭgoj, la novico estis pli kaj pli maltrankvila
kaj perturbita, sed li ne kuraĝis paroli. La monaĥo daŭrigis la ĝuon
de la freŝa naturo kaj la vojo, sed la novico flank-rigardis la
monaĥon maltrankvile, kvazaŭ li volus diri ion al li.
</p>

<p>
La monaĥo haltis antaŭ la enirejo de la vilaĝo kaj rigardis la
novicon.
</p>

<p>
-- Diru! --Diris la monaĥo.
</p>

<p>
-- Patro, --diris la novico--, vi pekis kontraŭ niaj votoj: vi tuŝis
virinon kaj alportis ŝin tra la rivereto!
</p>

<p>
-- Eble, --respondis la monaĥo-- sed mi forgesis ŝin tuj, kiam mi
lasis ŝin denove al grundo. Vi ankoraŭ alportis ŝin du leŭgoj pli.
</p>
</div>
</div>
<div id="outline-container-orgf3b64be" class="outline-2">
<h2 id="orgf3b64be">Kvanto da vortoj</h2>
<div class="outline-text-2" id="text-orgf3b64be">
<table>


<colgroup>
<col  class="org-left">

<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Parto</th>
<th scope="col" class="org-right">Vortoj</th>
<th scope="col" class="org-right">Literoj</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">Nur rakonto</td>
<td class="org-right">340</td>
<td class="org-right">1937</td>
</tr>

<tr>
<td class="org-left">Kun la parto tasko</td>
<td class="org-right">347</td>
<td class="org-right">1987</td>
</tr>

<tr>
<td class="org-left">Totalaj</td>
<td class="org-right">366</td>
<td class="org-right">2218</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> <a href="/tags/rakonto/index.html">rakonto</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <category><![CDATA[rakonto]]></category>
  <link>https://notxor.nueva-actitud.org/2017/12/16/rakonto-de-la-du-monahxoj-trairantaj-la-arbaron.html</link>
  <pubDate>Sat, 16 Dec 2017 00:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Me gusta]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-12-12</div>
<p>
Algunas veces me han preguntado si la <i>tontería</i> de los «puntos
amarillos» de <i>Supernani</i> da resultado, casi mofándose de que un
mecanismo tan simple sea efectivo para modificar la conducta de un
niño. Ahora mi contestación es muy sencilla: «Ha millones de personas
adultas dándole al "me gusta": ese es el mecanismo». La capacidad de
los mamíferos de recibir recompensas, en el caso de los humanos además
esas recompensas pueden ser <i>virtuales</i>.
</p>

<p>
Cada vez que alguien me habla sobre alguna <i>red social</i>, sobre lo
gratificante que es la <i>red social</i>, siempre traduzco <i>red social</i> por
<i>empresa</i>... y me acuerdo del experimento que hicieron en 1954 Olds y
Milner implantando un electrodo en lugar preciso del cerebro de unas
ratas. Las ratas (pobrecitas mías) accionaban una palanca que
estimulaba su cerebro con descargas de alta frecuencia y baja
duración. Tanto ahínco le ponían en esa autoestimulación que llegaban
a morir de inanición.
</p>

<p>
La diferencia entre las dos situaciones, quiero decir entre las
planteadas en las <i>redes sociales</i> frente a <i>Supernani</i>, es la
finalidad del empleo de estos mecanismos. Un mecanismo, como se puede
apreciar, capaz de modificar la conducta humana. Mientras <i>Supernani</i>
busca la adecuación del comportamiento del niño a lo que se considera
como una <i>conducta adaptada</i>, no sabemos a qué nos está condicionando
el botón de <i>me gusta</i> de las redes sociales. Esto es importante,
porque la Sociedad depende de qué conductas se consideran <i>adaptadas o
normales</i> y la percepción de las mismas por parte del individuo desde
distintos canales de información, para ajustar sus conductas a lo
socialmente aceptable.
</p>

<p>
La idea de utilizar las herramientas modernas, como la Internet, para
ampliar las posibilidades relacionales de los seres humanos es
buena. El problema viene dado cuando se confían esas relaciones a
empresas privadas con intereses propios y particulares. Lo que veo en
general me disgusta, porque los mensajes no son comunicativos, sólo
buscan impactar y conseguir muchos «me gusta», que le den muchas veces
a <i>la palanquita del placer</i>. En realidad, no necesito ni estar de
acuerdo con lo que pone el mensaje, sólo <i>intuir</i> que será aceptado
por mucha gente.
</p>

<p>
Ese tipo de comportamiento, en realidad, no es comunicación, es un
<i>mercadeo de clicks</i>. La gente no comparte (creyendo que sí lo hace),
la gente no colabora (creyendo que sí lo hace), la gente no se
relaciona (creyendo que sí lo hace). La gente me recuerda a los
<i>yonkis</i> y su frase estrella: «yo controlo, lo puedo dejar cuando
quiera», pero siguen dándole al «me gusta» cada pocos minutos. Porque
los contenidos <i>parecen cambiar</i> y hay que estar atento en darle al
botón o en repetir el último eslogan curioso. Formar una cohorte de
gente que le da a mis mensajes la ración correspondiente de
<i>dopamina</i>.
</p>

<p>
Y me pregunto ¿dónde va una sociedad atrapada en el «me gusta»? ¿Quién
está dirigiendo esos «me gusta»? Todo discurso es resumido a una
frase, cuanto más corta y más contundente mejor. No nos interesa la
información, sólo el <i>titular</i> que pueda impactar y recolectar maś «me
gusta», no tiene ni que ser verdad, sólo intuir que recibirá muchos
<i>clicks</i> por parte de mi cohorte. Si recibo muchos «me gusta» es que
es verdad, no tengo que preguntar: mi <i>dopamina</i> me lo asegura. No
pueden demostrarme lo contrario, porque no hay racionalidad en lo que
siento. Si la noticia no coincide con mis canales dopaminérgicos es
que es una manipulación, o incluso no llego a percibirla, no existe.
</p>

<p>
Gana las elecciones en EE.UU. un impresentable como Trump y nos
preguntamos cómo ha sido posible. ¿Cómo es posible estar informado en
la era de la <i>postverdad</i> donde lo importante no es lo que sucede sino
los <i>clicks</i> en «me gusta»? ¿Cómo se puede analizar y reflexionar
sobre la información que llega a través de un sistema diseñado para
durar tanto como las décimas de segundo que tardas en pulsar el «me
gusta»? En algunos conflictos que se han disparado últimamente veo dos
canales dopaminérgicos enfrentados, lanzándose sus eslóganes unos a
los otros, repitiéndolos una y otra vez, incapaces de darse cuenta de
que el <i>otro bando</i> no percibe nada en un eslogan ajeno, sólo
manipulación y desinformación, porque lo correcto es <i>lo que diga mi
canal dopaminérgico</i>. «Yo siempre estoy dispuesto a <i>negociar</i>, pero
sólo si me das la garantía de que vamos a hacer lo que yo diga; si no,
es que no tienes intención de <i>negociar/». Así puedo lanzar el eslogan
de «yo soy negociador, pero los otros nunca han querido» y conseguir
muchos «me gusta» de mi cohorte... y si preguntas de forma
independiente a un /miembro</i> de cada cohorte, te dirán que el que
nunca ha querido negociar es el <i>otro</i>, no porque lo digan los datos:
«me lo dice mi dopamina, que nunca falla».
</p>

<p>
¡Qué tristes se me hacen estas reflexiones! Lo malo es que ahora
pondré el aviso de este artículo en las <i>redes sociales</i> que
frecuento, como <a href="https://quitter.es/notxor">GNUsocial</a>, <a href="https://diasp.org/people/15172490a88f01339a3f782bcb452bd5">Diaspora*</a> y <a href="https://mastodon.social/web/accounts/215082">Mastodon</a> en busca de mi ración
de «me gusta». ¿Seré yo también un <i>yonki de las redes sociales</i>?
¿Quién me manipulará a mí? ¿Acaso los <i>asociales</i> que hemos terminado
en estas redes somos otra <i>cohorte dopaminérgica</i>? ¿El preocuparme por
estas cosas es importante o es sólo una forma de sentirme superior al
resto de ratas con nuestro electrodo implantado? Ains, si yo
supiera...
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/psicología/index.html">psicología</a> <a href="/tags/redes-sociales/index.html">redes-sociales</a> ]]></description>
  <category><![CDATA[psicología]]></category>
  <category><![CDATA[redes-sociales]]></category>
  <link>https://notxor.nueva-actitud.org/2017/12/12/me-gusta.html</link>
  <pubDate>Tue, 12 Dec 2017 21:22:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Escribir con textos con un editor de código]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-12-07</div>
<div id="outline-container-org84a7320" class="outline-2">
<h2 id="org84a7320">Procesadores de texto</h2>
<div class="outline-text-2" id="text-org84a7320">
<p>
Desde que descubrí <i>LaTeX</i> he venido abandonando los procesadores de
texto. En general, los <i>procesadores de texto</i> son aplicaciones
monolíticas que tienen muchas herramientas con el fin de trabajar con
documentos, fundamentalmente de texto, pero no sólo de texto.
</p>

<p>
¿Qué tipo de ventajas tienen que hacen que la gente haya admitido los
<i>procesadores de texto</i> como herramientas fundamentales para trabajar
con sus documentos? Pues desde mi punto de vista son tres:
</p>

<ol class="org-ol">
<li><i>WYSIWYG</i><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> El usuario tiene a la vista el documento tal y como
quedará al imprimir.</li>
<li>Herramienta o diccionario de corrección ortográfica.</li>
<li>Herramienta básica de corrección sintáctica.</li>
</ol>

<p>
La primera <i>ventaja</i> al final no es tal. El usuario suele distraerse
con el «aspecto» que está tomando el documento en lugar de con el
contenido, que es siempre lo importante. He visto, y he tenido que
corregir, documentos que no utilizaban cabeceras de sección o
apartados. En su lugar utilizan el cambio de tamaño y/o tipo de letra,
<b>negritas</b> y <i>cursivas</i>. Un <i>sistema de estilos</i> que sólo está en la
cabeza del que está haciendo el documento y que además tiende a
olvidar entre una sesión de trabajo y otra, dejando un montón de
inconsistencias imposibles de seguir. En otras ocasiones, el escritor
decide que un apartado debe comenzar en la siguiente página y no hay
nada más a mano que dar al <i>enter</i> tantas veces como sea necesario,
para que dicho apartado <i>se vea</i> tal y como él quiere. Cualquier
edición posterior del documento puede hacer que el <i>paginado</i>, tan
bien hecho, se convierta en un auténtico desastre. Me voy a ahorrar
detallar lo que normalmente se ve en el tratamiento de gráficos,
imágenes, tablas y cuadros de texto.
</p>

<p>
Además, el <i>wysiwyg</i> sólo es efectivo si el documento se crea y se
imprime con el mismo ordenador. Cambiar a otro dispositivo implica que
las fuentes de tipos cambien, cambiando así también el ancho de las
mismas y esos paginados hechos <i>a mano</i> suelen resultar en el más puro
caos. He tenido que corregir documentos en los que incluso el índice
de contenidos estaba hecho <i>a mano</i>, sobre títulos de secciones
inconsistentes en paginados caóticos. Son esos <i>documentos</i> los que me
han hecho abandonar poco a poco esos <i>procesadores de texto</i> en favor
de otros sistemas. Quizá, el <i>wysiwyg</i> sólo sea útil para diseñadores
gráficos o gente acostumbrada a trabajar con <i>css</i> y/o estilos.
</p>
</div>
</div>
<div id="outline-container-org628fcaa" class="outline-2">
<h2 id="org628fcaa">Diccionario de corrección ortográfica</h2>
<div class="outline-text-2" id="text-org628fcaa">
<p>
Es bastante útil que la herramienta que utilizas para escribir te vaya
avisando de errores al teclear, errores que pueden ser mecanográficos
u ortográficos. Esa herramienta no es exclusiva de los <i>procesadores
de texto</i>, existen en muchos otros sistemas. En <i>emacs</i> y su
<code>org-mode</code> están también presentes, pero no como un «componente» del
editor, sino como un componente del sistema operativo.
</p>

<p>
<a href="https://es.wikipedia.org/wiki/Ispell"><i>Ispell</i></a> es un sistema de corrección ortográfica creado para sistemas
<i>Un*x</i>. El beneficio de utilizar una herramienta del sistema consiste
en que puede ser compartido por varios programas. Además de <i>ispell</i>
existen otros sistemas similares que pueden sustituirlo, por ejemplo,
<a href="https://en.wikipedia.org/wiki/GNU_Aspell">aspell</a> o <a href="https://es.wikipedia.org/wiki/Hunspell">hunspell</a>, que serían los más populares.
</p>

<p>
Configurar <i>emacs</i> para utilizar un diccionario es tan sencillo como
añadir en el fichero de configuración de <code>.emacs</code> la siguiente línea:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> ispell-program-name <span style="color: #f1fa8c;">"aspell"</span>)
</pre>
</div>

<p>
En mi caso estoy utilizando <i>aspell</i> y eso es lo único que necesita
saber <i>emacs</i> para utilizar el diccionario. A partir de ahí se puede
utilizar el modo <code>flyspell</code>. Ese modo va comprobando <i>al vuelo</i> la
corrección de lo escrito, pero también se puede corregir el documento
con el comando <code>M-x ispell</code> o una determinada palabra con <code>M-x
ispell-word</code>. Incluso se puede cambiar el diccionario si estamos
escribiendo en otros idiomas con el comando <code>M-x
ispell-change-dictionary</code>. Existen más funciones, pero esas son las
que más he utilizado.
</p>
</div>
</div>
<div id="outline-container-org094fd4b" class="outline-2">
<h2 id="org094fd4b">Herramienta de corrección sintáctica</h2>
<div class="outline-text-2" id="text-org094fd4b">
<p>
<a href="https://languagetool.org/"><i>LanguageTool</i></a> es una herramienta de corrección sintáctica que puede
trabajar sobre las lenguas principales. Puedes utilizarlo como parte
de varias herramientas, como por ejemplo el <i>plugin</i> de <a href="https://www.mozilla.org/es-ES/firefox/">firefox</a> que
permite corregir la gramática de los textos que escribamos en foros,
blogs, wikis o cualquier otro servicio a través de nuestro navegador.
</p>

<p>
Para escritorio, dicha aplicación está hecha en java y necesitarás
tener instalado java 1.8. Desde <i>emacs</i> se puede utilizar como
herramienta externa teniéndolo configurado. Para ello, primero
necesitas tener instalado el paquete de <i>emacs</i> <code>langtool</code> y después
decirle dónde encontrar los ficheros <code>.jar</code> de la herramienta. En
resumen, en el fichero de configuración de <i>emacs</i> escribimos:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;;; </span><span style="color: #6272a4;">Activar LanguageTool
</span>(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">langtool</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> langtool-language-tool-jar <span style="color: #f1fa8c;">"/path/a/LanguageTool/languagetool-commandline.jar"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> langtool-default-language <span style="color: #f1fa8c;">"es_ES"</span>)
</pre>
</div>

<p>
Una vez configurado <i>emacs</i> podemos utilizar la herramienta
directamente en el <i>buffer</i> en el que estemos trabajando. Podemos
utilizar <code>M-x langtool-check-buffer</code>, una vez hecho esto en un
<i>buffer</i> queda activada la herramienta. Podemos reactivarla con <code>M-x
langtool-check</code> para volver a corregir, o desactivarla con <code>M-x
langtool-check-done</code>.
</p>

<p>
También podemos utilizar <i>LanguageTool</i> lanzando su aplicación de
escritorio, con el comando <code>java -jar languagetool.jar</code>. Aparece una
ventana con espacio para copiar el texto con el que estamos
trabajando, otro espacio donde nos detallará los errores encontrados
(si los hubiera), un selector de idioma (aunque también lo podemos
configurar para que intente identificar la lengua en base al texto
escrito) y un menú para el resto de opciones y operaciones. En
definitiva, una buena herramienta que tener en cuenta. Además, siendo
una aplicación <i>java</i> la podemos utilizar en cualquier sistema
operativo.
</p>
</div>
</div>
<div id="outline-container-org530bb18" class="outline-2">
<h2 id="org530bb18">Conclusión</h2>
<div class="outline-text-2" id="text-org530bb18">
<p>
La ventaja fundamental de las herramientas que utilizo proviene del
acrónimo <i>KISS</i><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. Aunque <i>emacs</i> es una herramienta no
precisamente simple, es mucho menos «monolítica» que los <i>procesadores
de texto</i>. Utilizo <code>org-mode</code> para escribir mis documentos y
«automágicamente» consigo resultados muy buenos. Tanto para textos
impresos y <code>pdf</code>, donde obtengo mucha mejor calidad que cualquier
usuario medio de <i>procesadores de textos</i>; como para textos destinados
a la <i>web</i>, donde el <code>html</code> que genera <i>emacs</i> es bastante más claro
que el generado por ningún <i>procesador de texto</i> que intenta imponer
los «estilos» definidos en él por encima de cualquier otro
«estilo». Además, para posicionamiento SEO<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> me facilita el
trabajo de forma automática: genera cabeceras, gestiona etiquetas y
metadatos, enlaza de manera sencilla, etc.
</p>

<p>
En algunos casos me piden un documento en algún formato para estos
<i>procesadores de texto</i> y aunque sé que en general les debería bastar
con un <i>html</i> bien hecho, que lo pueden abrir con cualquier
<i>procesador</i>; también sé que hay quien no sabe cómo hacerlo sin <i>hacer
doble click</i> en el icono correspondiente. En estos casos utilizo
<a href="https://pandoc.org/"><i>pandoc</i></a>, una herramienta muy versátil y completa que comprende muchos
formatos de documentos. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-shell">pandoc -i archivo.org -o archivo.docx
</pre>
</div>

<p>
El comando anterior me proporciona un fichero apto para ser abierto
por <i>word</i> y si cambio <code>.docx</code> por <code>.odt</code> el archivo que obtengo es
compatible con <i>LibreOffice</i> y otras aplicaciones de ofimática
(OpenOffice, Calligra, AbiWord, etc.).
</p>

<p>
Y por último, quiero que conste que no me quejo de los <i>procesadores
de texto</i> o tengo algo contra estas herramientas. Simplemente, obtengo
mejores resultados con otras. Y en general, los problemas que me
encuentro con los documentos generados por <i>procesadores de texto</i> no
son culpa de la herramienta, sino de la persona que la utiliza, en la
mayoría de los casos, con más voluntad que conocimientos.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
acrónimo de <i>What You See Is What You Get</i>, que significa «lo
que ves es lo que obtienes».
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
acrónimo de <i>Keep It Simple, Stupid</i>, que diría algo así como
«mantenlo sencillo, estúpido». O para qué vas a complicarlo si siendo
sencillo funciona mejor.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
SEO significa <i>Search Engine Optimization</i>. Normalmente
comprende acciones tan simples como utilizar metadatos de etiquetas,
cabeceras de sección identificables y, en fin, elementos que sean
fácilmente reconocibles por los buscadores a la hora de indexar los
contenidos.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/escritura/index.html">escritura</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[escritura]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2017/12/07/escribir-con-textos-con-un-editor-de-codigo.html</link>
  <pubDate>Thu, 07 Dec 2017 19:21:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Entrevista en la radio el 2017-12-03]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-12-04</div>
<p>
Ayer domingo día 3 de diciembre de 2017 asistí a un espacio
radiofónico en <a href="http://radiomai.com/">Radio MAI</a> en el que charlamos un poco sobre
Esperanto. Enlazo aquí un mp3 con el contenido.
</p>

<audio controls>
    <source src="./archivo/entrevista-radio-20171203.mp3" type="audio/mp3">
    Tu navegador no soporta la etiqueta audio, comprueba que soporta el formato mp3.
</audio>

<p>
Si has terminado de oír este <i>podcast</i> habrás escuchado que nos
emplazan a otro encuentro a finales de enero, ya informaré sobre el
asunto más adelante.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">Esperanto</a> <a href="/tags/radio/index.html">radio</a> ]]></description>
  <category><![CDATA[Esperanto]]></category>
  <category><![CDATA[radio]]></category>
  <link>https://notxor.nueva-actitud.org/2017/12/04/entrevista-en-la-radio-el-2017-12-03.html</link>
  <pubDate>Mon, 04 Dec 2017 19:03:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Utilizar guile como calculadora]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-11-26</div>
<p>
Los que me conocen saben que llevo tiempo hablándoles de las
maravillas de algunas herramientas como <code>bc</code>, una gran calculadora que
he utilizado durante años y que sigo utilizando, aunque cada vez
menos. <code>bc</code> se está viendo desplazada en mi línea de comandos como
calculadora por <code>guile</code>, pero ¿qué es <code>guile</code>?
</p>
<div id="outline-container-org3ef00f9" class="outline-2">
<h2 id="org3ef00f9"><code>guile</code> ¿Eso no es un lenguaje de programación?</h2>
<div class="outline-text-2" id="text-org3ef00f9">
<p>
Pues sí, <i>guile</i> es un <i>scheme</i>. Su nombre son las siglas de <i>GNU's
Ubiquitous Intelligent Language for Extensions</i>. Que como indican es
un lenguaje creado para proporcionar extensiones a otros programas y
de hecho consiste, principalmente, en una librería pensada para ser
ensamblada con cualquier otro programa y ser utilizada para escribir
<i>scripts</i> que amplíen la funcionalidad del mismo.
</p>

<p>
Como he dicho antes, es un <i>scheme</i>, lenguaje derivado de <i>LISP</i>. Iba
a decir del <i>antiguo LISP</i> pero es mejor puntualizar a <i>eterno LISP</i>.
</p>

<p>
Además, para mi propósito de hoy, <i>guile</i> viene con un intérprete y se
puede lanzar desde línea de comandos y utilizarlo de forma
interactiva.
</p>
</div>
</div>
<div id="outline-container-org58277de" class="outline-2">
<h2 id="org58277de">Calculadora para la línea de comandos</h2>
<div class="outline-text-2" id="text-org58277de">
<p>
Utilizo en mi ordenador como gestor de ventanas <i>i3vm</i>. Es un buen
gestor, muy eficaz, pero para serlo se basa mucho en el uso del
teclado minimizando el uso del ratón. Para utilizarlo procuro tener
las aplicaciones que más utiliza a un golpe de teclas (o dos, si
contamos con la tecla <i>mod</i>). Por ejemplo, una consola la abro
pulsando <i>mod+enter</i>.
</p>

<p>
Por ello, me es mucho más sencillo cuando necesito una calculadora
pulsar <i>mod+enter</i> y teclear <code>bc</code> que buscar la calculadora <i>gráfica</i>
que haya instalada y manejarla con el ratón. <code>bc</code> además proporciona
una calculadora programable muy potente, incluso puedes definir
funciones para realizar cálculos complejos como si un lenguaje de
programación fuera. Pero ¿por qué estoy sustituyendo <code>bc</code> con <i>guile</i>?
Lo mejor para explicarlo es ver un ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-scheme">&gt; bc
bc 1.07.1
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
(2/3)+(1/3)
0
scale=2
(2/3)+(1/3)
.99
scale=5
(2/3)+(1/3)
.99999
quit
</pre>
</div>

<p>
El primer resultado de <code>(2/3)+(1/3)</code> es totalmente inexacto. Se va
ajustando según modificamos el valor de la variable <code>scale</code> que nos
dice qué cantidad de decimales debe calcular. Sin embargo, vemos que
son en realidad <i>aproximaciones</i>. Vamos al mismo ejemplo desde
<i>guile</i>:
</p>

<div class="org-src-container">
<pre class="src src-scheme">GNU Guile 2.0.14
Copyright (C) 1995-2016 Free Software Foundation, Inc.

Guile comes with ABSOLUTELY NO WARRANTY<span style="color: #6272a4;">; </span><span style="color: #6272a4;">for details type `,show w'.
</span>This program is free software, and you are welcome to redistribute it
under certain conditions<span style="color: #6272a4;">; </span><span style="color: #6272a4;">type `,show c' for details.
</span>
Enter `,help' for help.
scheme@(guile-user)&gt; (+ (/ 2 3) (/ 1 3))
$1 = 1
</pre>
</div>

<p>
Si comparamos las dos formas de cálculo veremos que <i>guile</i> es más
preciso, todos sabemos que <code>(2/3)+(1/3)</code> son <code>(3/3)</code> o lo que es lo
mismo <code>1</code>. La primera respuesta de <code>bc</code> es <code>0</code> algo inaceptable, pero
empieza a acercarse según el valor de la variable <code>scale</code> que
determina cuántos decimales se calcularán.
</p>
</div>
</div>
<div id="outline-container-orgd2d08ad" class="outline-2">
<h2 id="orgd2d08ad">Usando <i>guile</i> como calculadora</h2>
<div class="outline-text-2" id="text-orgd2d08ad">
<p>
Muchas veces descarto temas sobre los que escribir porque me da la
sensación de que son tan básicos que todo el mundo los conoce ya, o
son tan sencillos que no merece la pena escribir sobre ellos. Luego
veo esos mismos temas en otro <i>blog</i> y pienso que quizá podría haberlo
escrito yo, porque no era tan básico o tan simple para la mayoría de
la gente. Este es uno de esos casos en los que tengo casi descartado
el borrador y he pensado al revés: a lo mejor no es tan básico y tan
simple o a alguien le puede interesar.
</p>

<p>
Cualquier lenguaje interpretado se puede utilizar como calculadora. He
utilizado también <i>Python</i> alguna vez para lo mismo, aunque
generalmente he venido usando más <i>bc</i> como <i>calculadora de consola</i>.
</p>
</div>
<div id="outline-container-org966bcca" class="outline-3">
<h3 id="org966bcca">Cálculos sencillos</h3>
<div class="outline-text-3" id="text-org966bcca">
<p>
La peculiaridad de <i>guile</i>, como cualquier otro <i>scheme</i> o
descendiente de <i>LISP</i> utiliza una notación rara para la mayoría de
los mortales y hay que acostumbrarse a ella. En este tipo de lenguajes
todo es una <i>lista</i> y todo se presenta en una lista. El primer
elemento de la lista es la <i>función</i> que evaluará el intérprete y los
demás elementos son los datos que necesita la función para ser
evaluada. Un ejemplo de cálculos sencillos con <i>guile</i>.
</p>

<div class="org-src-container">
<pre class="src src-scheme">scheme@(guile-user)&gt; (+ 2 3)
$1 = 5
scheme@(guile-user)&gt; (- 4 2)
$2 = 2
scheme@(guile-user)&gt; (- $1 $2)
$3 = 3
scheme@(guile-user)&gt; (+ $1 2)
$4 = 7
scheme@(guile-user)&gt; (+ 1 2 3 4)
$5 = 10
scheme@(guile-user)&gt; (- $5 $3 1 1)
$6 = 5
</pre>
</div>

<p>
Para realizar el cálculo de <code>(2+3)</code> se utiliza una <i>notación</i> que
puede parecer extraña. En realidad es muy sencilla de entender, la
expresión <code>(+ 2 3)</code> la podemos desglosar en sus componentes más
sencillos. Para empezar está la pareja de <code>()</code>. Esos signos nos
delimitan una lista. Como he dicho antes, el intérprete evaluará el
primer elemento de la lista, lo que quiere decir que el intérprete
espera que sea una expresión «ejecutable». En nuestro caso, hay una
<i>función</i> que se llama <code>+</code> que lo que hace al ser evaluada es sumar la
lista de argumentos que se le pasen, en este caso 2 y 3.
</p>

<p>
Pero además, vemos que <i>guile</i> va guardando los resultados en
<i>variables</i> que marca con un carácter <code>$</code> y esas variables se pueden
utilizar en los cálculos. Algo muy interesante cuando los cálculos son
complejos y los divides en partes o cuando quieres almacenar alguna
constante que emplearás en varios cálculos.
</p>

<div class="org-src-container">
<pre class="src src-scheme">scheme@(guile-user)&gt; (/ 21 3)
$3 = 7
scheme@(guile-user)&gt; (/ 21 3 7)
$4 = 1
scheme@(guile-user)&gt; (/ 21 3 7 2)
$5 = 1/2
</pre>
</div>

<p>
Otro de los puntos a tener en cuenta es que las divisiones no se
efectúan para convertir a <i>decimal</i> sino que las operaciones con
enteros que no den otro entero, se guardan como fracciones.
</p>

<p>
Este hecho es fundamental para mantener la exactitud en los cálculos,
no se emplean las aproximaciones decimales de las fracciones. Y por
eso vemos que el resultado de la serie de divisiones <code>(/ 21 3 7 2)</code> se
realiza de la siguiente manera:
</p>

<pre class="example" id="org176a1a6">
21 / 3 → 7 / 7 → 1 / 2 → 1/2
</pre>
</div>
</div>
<div id="outline-container-org7c1510f" class="outline-3">
<h3 id="org7c1510f">Cálculos no tan sencillos</h3>
<div class="outline-text-3" id="text-org7c1510f">
<p>
Hay algunos otros cálculos que no son operaciones básicas sino cosas
más complicadas. Por ejemplo, algunas operaciones especiales sobre la
división, como calcular el <i>cociente</i> o el <i>resto</i>.
</p>

<div class="org-src-container">
<pre class="src src-scheme">scheme@(guile-user)&gt; (quotient 7 3)
$1 = 2
scheme@(guile-user)&gt; (modulo 7 3)
$2 = 1
scheme@(guile-user)&gt;
</pre>
</div>

<p>
También hay funciones para cálculo de exponentes (<code>exp</code>) o logaritmos
(<code>log</code>), o para las funciones trigonométricas <code>sin</code>, <code>cos</code>, <code>tan</code>,
<code>asin</code>, <code>acos</code>, <code>atan</code>. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-scheme">scheme@(guile-user)&gt; (* 4 (atan 1))
$3 = 3.141592653589793
scheme@(guile-user)&gt;
</pre>
</div>
</div>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/scheme/index.html">scheme</a> <a href="/tags/programación/index.html">programación</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[scheme]]></category>
  <category><![CDATA[programación]]></category>
  <link>https://notxor.nueva-actitud.org/2017/11/26/utilizar-guile-como-calculadora.html</link>
  <pubDate>Sun, 26 Nov 2017 13:18:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Cómo importar un fichero de otra rama en un repositorio git]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-11-18</div>
<div id="outline-container-orgf2578e0" class="outline-2">
<h2 id="orgf2578e0">El problema</h2>
<div class="outline-text-2" id="text-orgf2578e0">
<p>
Desde que comencé el nuevo formato de blog utilizando <i>emacs</i> había
algo que me rechinaba en todo el sistema. La herramienta utilizada es
un modo de <i>emacs</i> que se llama <code>org-page</code>. Y como ya expliqué cuando
me vi obligado a cambiar la manera en la que gestiono el blog, se basa
fuertemente en la utilización de <code>git</code> para gestionar todo. En la
documentación de <code>org-page</code> habla de dos ramas: una <code>master</code> donde se
guardan los archivos que se van subir al espacio <i>web</i> y la rama
<code>source</code> donde se van a poner los ficheros <code>org</code> que generarán la
<code>master</code>.
</p>

<p>
El sistema anterior está bien pero desde el principio me rechinaba
algo: la gestión de borradores. Si ponía los borradores en algún sitio
en la rama <code>source</code> el sistema los reconocía y los trataba como
artículos acabados. Lo mejor era tenerlos separados de esa rama. Para
hacerlo se me ocurrían sólo dos alternativas: tener una rama
<code>borrador</code> o en otro directorio.
</p>

<p>
Mi escaso conocimiento de <code>git</code> me hizo comenzar con la segunda de las
alternativas, lo tenía todo en otro directorio. Digo lo <i>tenía</i> porque
ahora ya no lo tengo, encontré el modo de tener todo lo referente al
<i>blog</i> en un sólo sitio, todo bien encerrado y gestionado por <i>git</i>.
</p>

<p>
El problema principal para no haberlo hecho desde el principio es el
modo de funcionamiento del sistema. Hasta ahora pensaba en las ramas
como algo que se bifurca, pero que está destinado a formar parte del
tronco principal tarde o temprano. La manera que se me había ocurrido
era abrir una rama para cada borrador de artículo y fusionarla a
<code>source</code> cuando se diera por finalizada la edición. Eso permitiría
tenerlo todo en un mismo repositorio, pero un poco lioso de gestionar,
sobre todo, porque algunos borradores están en <i>proceso</i> durante mucho
tiempo, otros nunca ven la luz y otros apenas duran en ese
proceso. Memorizar todas las ramas, saber en qué estado está cada
borrador, era un engorro, pero lo que peor llevaba es que al
mantenerlos en ramas separadas no podría tenerlos en edición a la vez.
</p>

<p>
De momento mantenía barios borradores en otro directorio y cuando
acababa el artículo lo pasaba a mano al directorio de la rama
<code>source</code>. Pero ahora mismo he abierto una rama <code>borrador</code> donde tengo
los futuros artículos en el mismo lugar.
</p>
</div>
</div>
<div id="outline-container-orgc81a2cb" class="outline-2">
<h2 id="orgc81a2cb">Las posibles soluciones</h2>
<div class="outline-text-2" id="text-orgc81a2cb">
<p>
Mirando la documentación de <code>git</code> no terminaba de encontrar una
solución y me puse a buscar en <i>blogs</i> y otros lugares buscando a
alguien que tuviera el mismo problema y al final estuve barajando
varias alternativas.
</p>
</div>
<div id="outline-container-orgaf4675b" class="outline-3">
<h3 id="orgaf4675b">El comando <code>cherry-pick</code></h3>
<div class="outline-text-3" id="text-orgaf4675b">
<p>
La situación de tener los archivos en otra rama hace que sea <i>git</i>
quien tenga que gestionar el «alta» de un nuevo artículo. No se puede
copiar el fichero y añadirlo al hilo de la rama. Lo primero que se me
ocurrió y probé, pero no me transmitió una buena sensación fue
utilizar el comando <code>cherry-pick</code> para mover un <code>commit</code> de una rama a
otra.
</p>

<p>
La idea fundamental con este comando era hacer el <code>commit</code> con los
cambios y luego traspasar dicho <code>commit</code> a la rama <code>source</code>. En
principio funciona, pero da algunos quebraderos de cabeza, porque es
al final es un <code>commit</code> que rompe la lógica <i>lineal</i> del hilo de una
rama.
</p>
</div>
</div>
<div id="outline-container-org18b2bb7" class="outline-3">
<h3 id="org18b2bb7">El comando <code>checkout</code></h3>
<div class="outline-text-3" id="text-org18b2bb7">
<p>
Hasta ahora había utilizado el comando <code>checkout</code> sólo para cambiar de
rama. Pero resulta que sirve para muchas cosas y principalmente para
la que me interesa a mí. Por ejemplo, si hacemos lo siguiente:
</p>

<pre class="example" id="orgc0a0e55">
~/proyectos/blog&gt; git checkout source
Cambiando a rama 'source'
Tu rama está actualizada con 'origin/source'.
~/proyectos/blog&gt; git checkout borrador -- path/al/nuevo-archivo.org
~/proyectos/blog&gt; git status
En la rama source
Tu rama está actualizada con 'origin/source'.

Cambios a ser confirmados:
  (usa "git reset HEAD &lt;archivo&gt;..." para sacar del area de stage)

        nuevo archivo:  nuevo-archivo.org
</pre>

<p>
A partir de aquí tengo el archivo que quería en la rama <code>source</code>. Se
lo añado con <code>add</code> y hago el <code>commit</code> y el <code>push</code> como se haría
habitualmente. Todo el trabajo realizado en los borradores se gestiona
por tanto de forma paralela y en la rama <code>source</code> sólo se realiza la
actualización con la versión <i>definitiva</i>. 
</p>
</div>
</div>
</div>
<div id="outline-container-org419b330" class="outline-2">
<h2 id="org419b330">Conclusión</h2>
<div class="outline-text-2" id="text-org419b330">
<p>
La nueva forma de mantener los <i>borradores</i> en una rama del
repositorio hace que el trabajo en el <i>blog</i> esté todo situado en el
mismo lugar. Eso, a parte de mejorar la <i>lógica</i> del sistema, también
facilita el poder trabajar en el blog desde cualquier
dispositivo. Hasta ahora, los borradores estaban sólo en el ordenador
en el que trabajo habitualmente, pero si se me ocurría alguna idea
cuando no tenía acceso a él, la debía abandonar, o iniciar un fichero
de borrador y luego pasarla al otro equipo. Esto hacía que en algún
caso terminara con el mismo fichero en un estado distinto en cada
ordenador.
</p>

<p>
Ahora, voy a probar todo lo dicho antes con este primer artículo
salido de mi rama de <code>borrador</code>.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2017/11/18/como-importar-un-fichero-de-otra-rama-en-un-repositorio-git.html</link>
  <pubDate>Sat, 18 Nov 2017 19:51:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Cómo estoy utilizando git]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-11-14</div>
<div id="outline-container-org740bc01" class="outline-2">
<h2 id="org740bc01">Git es uno de mis demonios</h2>
<div class="outline-text-2" id="text-org740bc01">
<p>
Dada mi torpeza habitual <i>git</i> es uno de esas herramientas que se me
atraviesan. Y además, no es por falta de uso o de empeño. De hecho lo
utilizo con bastante asiduidad en los proyectos que voy emprendiendo y
que se convierten en <i>vaporware</i> la mayoría. Cuando creo que tengo
dominada <i>la bestia</i> meto el cuezo en algún momento y <i>git</i> me lo
devuelve (doblado). Como muchas veces tengo que estar mirando mis
chuletas de cómo usarlo (y algunas veces no las tengo a mano) por eso,
voy a ponerlo en limpio en este artículo.
</p>

<p>
Hace tiempo que utilizo sistemas de <i>control de versiones</i>, desde el
viejuno <i>cvs</i> o su heredero <i>svn</i>, hasta que apareció <i>git</i> y se quedó
en mi ordenador.
</p>
</div>
</div>
<div id="outline-container-orgf942a0c" class="outline-2">
<h2 id="orgf942a0c">Creación de un repositorio para uso personal</h2>
<div class="outline-text-2" id="text-orgf942a0c">
<p>
Para muchos proyectos de los que empiezo se podría utilizar algún
repositorio <a href="https://github.com/">como hithub</a>, que proporcionan espacio de almacenamiento
para el código y para una página web sencilla, que no necesite bases
de datos ni mucha infraestructura detrás.
</p>

<p>
Sin embargo, como la mayoría de mis proyectos son tan sólo tentativas
o son personales, como este <i>blog</i>, yo tengo la tendencia a crear mi
repositorio en «mi nube». Tengo montado un <i>nextcloud</i> de uso personal
y lo que hago es montarlo todo en esa nube que además me sirve de
«copia de seguridad» del repositorio en caso de desastre.
</p>

<p>
Lo primero que hay que hacer es crear lo que llamo <i>repositorio
remoto</i> y una vez creado lo que hago es crear el que llamo
<i>repositorio local</i> en mi directorio de proyectos <i>clonando</i> el
remoto.
</p>

<p>
Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-nil">~/nube&gt; mkdir proyecto-nuevo.git
~/nube&gt; cd proyecto-nuevo.git
~/nube/proyecto-nuevo.git&gt; git init --bare
</pre>
</div>

<p>
Lo primero que he hecho es crear un directorio <code>proyecto-nuevo.git</code>
que de momento es una carpeta normal y corriente. Entro en ella y le
digo a <i>git</i> que inicie un repositorio. La opción <code>--bare</code> le dice a
<i>git</i> que ese repositorio no se utilizará como <i>copia local</i> sino como
<i>copia remota</i>. Es decir, no voy a trabajar con este repositorio
directamente sino que lo utilizaré como <i>almacén remoto</i> y en él no se
guardarán los ficheros de trabajo directamente sino la <i>base de datos</i>
(por llamar a como guarda <i>git</i> la información de una manera sencilla)
donde se guardan los datos. Por defecto, <i>git</i> llamará a este
repositorio <code>origin</code>, como origen de todo.
</p>

<p>
Puede parecer un enredo mantener un <i>repositorio remoto</i> en un
directorio al que puedes acceder como de forma local, pero se trata de
mantener la filosofía de red. Luego, esto que se almacena en <i>la
nube</i>, es accesible desde cualquier equipo que conecte a la misma. Y
por ello me gusta pensar en esto como <i>remoto</i>.
</p>

<p>
Pero para trabajar, necesito un repositorio local que sí pueda
modificar, y eso lo hago con:
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos&gt; git clone ~/nube/proyecto-nuevo.git
Clonando en 'proyecto-nuevo'...
warning: Pareces haber clonado un repositorio sin contenido.
hecho.
</pre>
</div>

<p>
Ese comando <i>clona</i> el repositorio <i>remoto</i> y crea el directorio
<code>proyecto-nuevo</code> en mi carpeta de <code>proyectos</code>. Eso sí, avisa de que el
repositorio que estoy clonando está vacío, algo que voy a arreglar
añadiendo contenido al mismo, así que ese aviso no me preocupa. Es el
momento oportuno para añadir, por ejemplo, un fichero <code>README</code> que
describa un poco de qué va el proyecto.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; echo "Ejemplo de repositorio para explicar cómo utilizo _git_." &gt; README.md

~/proyectos/proyecto-nuevo&gt; git status
En la rama master

No hay commits todavia

Archivos sin seguimiento:
  (usa "git add &lt;archivo&gt;..." para incluirlo a lo que se será confirmado)

        README.md

no hay nada agregado a la confirmación pero hay archivos sin seguimiento presentes (usa "git add" para hacerles seguimiento)
</pre>
</div>

<p>
<code>git status</code> es el <i>bastón del ciego</i> con ella voy dando <i>golpecitos</i>
en la acera de <i>git</i> para no tropezar. En este caso me dice que estoy
en la rama <code>master</code> (luego hablaré sobre las <i>ramas</i>), que no tiene
<i>commits</i> todavía, que hay un archivo <code>README.md</code> que está en el lugar
pero sin seguimiento (o sin sincronizar) y aconseja utilizar el
comando <code>add</code> para añadirlo al repositorio... Pues nada, voy a hacerle
caso:
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git add README.md 
~/proyectos/proyecto-nuevo&gt; git status
En la rama master

No hay commits todavia

Cambios a ser confirmados:
  (usa "git rm --cached &lt;archivo&gt;..." para sacar del area de stage)

        nuevo archivo:  README.md
</pre>
</div>

<p>
Me vuelve a repetir que estoy en la rama <code>master</code> que todavía no hay
<i>commits</i> y que tiene en la lista para añadir el fichero <code>README.md</code>,
que me puedo arrepentir con el comando <code>rm</code>. Pero como en mi caso lo
quiero confirmar para hacer el primer <i>commit</i> del repositorio, hago
lo siguiente.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git commit -m "Primer commit del repositorio añadiendo el README.md."
[master(commit-raiz) f1f91e9] Primer commit del repositorio añadiendo el README.md.
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
~/proyectos/proyecto-nuevo&gt; git status
En la rama master
tu rama esta basada en 'origin/master', pero upstream ha desaparecido.
  (usa "git branch --unset-upstream" para arreglar)

nada para hacer comit, el arbol de trabajo esta limpio
~/proyectos/proyecto-nuevo&gt; git push
Contando objetos: 3, listo.
Delta compression using up to 4 threads.
Comprimiendo objetos: 100% (2/2), listo.
Escribiendo objetos: 100% (3/3), 306 bytes | 306.00 KiB/s, listo.
Total 3 (delta 0), reused 0 (delta 0)
To /home/notxor/nube/proyecto-nuevo.git
 * [new branch]      master -&gt; master
~/proyectos/proyecto-nuevo&gt; git status
En la rama master
Tu rama está actualizada con 'origin/master'.

nada para hacer comit, el arbol de trabajo esta limpio
</pre>
</div>

<p>
En todo el código anterior he hecho un <code>commit</code> y un <code>push</code>. El
<i>commit</i> lo pienso como <i>añadirlo a la lista de cambios</i> y el <i>push</i>
como <i>subirlo al repositorio remoto</i>. Y siempre utilizo entre comando
y comando el <code>status</code>, porque es lo que me garantiza en qué estado
está el repositorio. Ya he dicho que <i>git</i> es mi bestia negra pero no
por fallos de <i>git</i> sino por precipitación mía. Así que utilizo mi
<i>bastón de ciego</i> y si encuentro algún bordillo lo arreglo (si sé)
antes de tropezar.
</p>

<p>
Hasta aquí, la creación de un repositorio básico.
</p>
</div>
</div>
<div id="outline-container-org66585ad" class="outline-2">
<h2 id="org66585ad">Mantenimiento de ramas</h2>
<div class="outline-text-2" id="text-org66585ad">
<p>
Para mantener este <i>blog</i>, estoy utilizando dos ramas del mismo
repositorio. Los ficheros <code>html</code> generados, los <code>css</code>, etc. los guardo
en la rama <code>master</code>. Sin embargo, los ficheros de texto que creo los
guardo en una rama <code>source</code>. En esa rama están todos los ficheros
<code>.org</code> pero ninguno de los generados y me mantienen la <i>lógica</i> del
sitio de forma que no se mezclen unos ficheros con otros.
</p>

<p>
Nuestro repositorio de ejemplo, sólo tiene una rama. Lo podemos
confirmar así:
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git branch
* master
</pre>
</div>
</div>
<div id="outline-container-orgea771aa" class="outline-3">
<h3 id="orgea771aa">Crear ramas</h3>
<div class="outline-text-3" id="text-orgea771aa">
<p>
Bueno, vamos a crear otra rama por ejemplo, para hacer pruebas:
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git branch prueba
~/proyectos/proyecto-nuevo&gt; git branch
* master
  prueba
</pre>
</div>

<p>
Ya tengo dos ramas: <code>master</code> y <code>prueba</code>. Además me marca con el <code>*</code>
cuál es la rama activa. Ahora cambio a la rama que he creado para
hacer pruebas. En este caso no se utiliza el comando <code>branch</code> sino el
<code>checkout</code>.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git checkout prueba 
Cambiado a rama 'prueba'
~/proyectos/proyecto-nuevo&gt; git branch
  master
* prueba
</pre>
</div>

<p>
Ya tengo una rama y me cambiado a ella ahora hago los cambios que
necesito y el proceso de <code>commit</code> y <code>push</code> de nuevo. Al tener dos
ramas y dos repositorios, tengo que contar con lo que yo llamo <i>los
diales</i>. En este caso 2 ramas por 2 repositorios me dan 4 diales:
</p>

<ul class="org-ul">
<li><code>origin/master</code> → (la rama <code>master</code> del remoto)</li>
<li><code>master</code>        → (la rama <code>master</code> del local)</li>
<li><code>origin/prueba</code> → (la rama <code>prueba</code> del remoto... bueno, esta aún no
la tengo pero hay que contar con ella. Ahora lo cuento.)</li>
<li><code>prueba</code>        → (la rama <code>prueba</code> del local)</li>
</ul>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; echo "Esto es el fichero de prueba 1." &gt; archivo1.txt
~/proyectos/proyecto-nuevo&gt; git status
En la rama prueba
Archivos sin seguimiento:
  (usa "git add &lt;archivo&gt;..." para incluirlo a lo que se será confirmado)

        archivo1.txt

no hay nada agregado a la confirmación pero hay archivos sin seguimiento presentes (usa "git add" para hacerles seguimiento)
~/proyectos/proyecto-nuevo&gt; echo "Esto es el fichero de prueba 2." &gt; archivo2.txt
~/proyectos/proyecto-nuevo&gt; git status
En la rama prueba
Archivos sin seguimiento:
  (usa "git add &lt;archivo&gt;..." para incluirlo a lo que se será confirmado)

        archivo1.txt
        archivo2.txt

no hay nada agregado a la confirmación pero hay archivos sin seguimiento presentes (usa "git add" para hacerles seguimiento)
~/proyectos/proyecto-nuevo&gt; git add archivo1.txt 
~/proyectos/proyecto-nuevo&gt; git commit -m "Añadir el archivo1.txt a la rama de pruebas."
[prueba ee63815] Añadir el archivo1.txt a la rama de pruebas.
 1 file changed, 1 insertion(+)
 create mode 100644 archivo1.txt
~/proyectos/proyecto-nuevo&gt; git add archivo2.txt
~/proyectos/proyecto-nuevo&gt; git commit -m "Añadir el archivo2.txt a la rama de pruebas."
[prueba a60c91a] Añadir el archivo2.txt a la rama de pruebas.
 1 file changed, 1 insertion(+)
 create mode 100644 archivo2.txt
~/proyectos/proyecto-nuevo&gt; git push
fatal: La rama actual prueba no tiene una rama upstream.
Para realizar un push de la rama actual y configurar el remoto como upstream, use

        git push --set-upstream origin prueba
</pre>
</div>

<p>
Todo ha ido como se esperaba, excepto cuando hemos intentado hacer el
<code>push</code> que se queja de que el repositorio remoto no tiene ninguna rama
que se llame <code>prueba</code> y me sugiere que la cree con el comando
correspondiente.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git push --set-upstream origin prueba
Contando objetos: 6, listo.
Delta compression using up to 4 threads.
Comprimiendo objetos: 100% (4/4), listo.
Escribiendo objetos: 100% (6/6), 608 bytes | 608.00 KiB/s, listo.
Total 6 (delta 1), reused 0 (delta 0)
To /home/notxor/nube/proyecto-nuevo.git
 * [new branch]      prueba -&gt; prueba
Rama 'prueba' configurada para hacer seguimiento a la rama remota 'prueba' de 'origin'.
</pre>
</div>

<p>
Pues ya tengo la rama prueba tanto en local como en remoto. Ahora
mismo tengo los siguientes ficheros en la rama.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; ls
archivo1.txt  archivo2.txt  README.md
</pre>
</div>

<p>
Al cambiar de rama, también cambian los ficheros que hay en el
directorio de trabajo.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git checkout master 
Cambiado a rama 'master'
Tu rama está actualizada con 'origin/master'.
~/proyectos/proyecto-nuevo&gt; ls
README.md
</pre>
</div>

<p>
Han desaparecido los dos ficheros <code>txt</code> que están en el seguimiento de
la rama <code>prueba</code>. Se puede ver más detalladamente el repositorio con
el comando <code>log</code>, que mostrará una salida de texto con el mismo estilo
que el comando <code>less</code> del sistema operativo. Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-nil">git log --oneline
</pre>
</div>

<p>
Muestra una salida del estilo:
</p>
<div class="org-src-container">
<pre class="src src-nil">a60c91a (HEAD -&gt; prueba, origin/prueba) Añadir el archivo2.txt a la rama de pruebas.
ee63815 Añadir el archivo1.txt a la rama de pruebas.
f1f91e9 (origin/master, master) Primer commit del repositorio añadiendo el README.md.
</pre>
</div>

<p>
<code>HEAD</code> me marca dónde estoy, es el <i>dial</i> que muestra cuál es mi
rama. En este caso en la rama <code>prueba</code> del repositorio local y además
me marca que tengo sincronizada también la rama remota
correspondiente. Ambas ramas <code>prueba</code> están en la posición (o
<i>commit</i>) <code>a60c91a</code>, mientras que ambas ramas <code>master</code> se encuentran
sincronizadas en la posición <code>f1f91e9</code>.
</p>

<p>
Si todavía quiero más detalles, quito el <code>--oneline</code> y si quiero algo
más gráfico añado el comando <code>--graph</code>.
</p>
</div>
</div>
<div id="outline-container-org24daed2" class="outline-3">
<h3 id="org24daed2">Mezclar ramas</h3>
<div class="outline-text-3" id="text-org24daed2">
<p>
Para mezclar ramas primero hay que moverse a la rama en la que vas a
recibir los cambios hechos en la otra.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git checkout master                                                        
Cambiado a rama 'master'                                                                                             
Tu rama está actualizada con 'origin/master'.
</pre>
</div>

<p>
Al cambiar de rama avisa de que la tenemos sincronizada con el
servidor remoto. Ese mensaje es importante, sobre todo cuando trabajo
en un repositorio compartido en el que colaboran varias personas. Es
importante que se compruebe y se actualice el repositorio local con
los cambios que haya en el remoto antes de subir los cambios locales.
</p>

<p>
En este caso y una vez comprobado todo el estado del repositorio,
mezclo las dos ramas con el comando <code>merge</code>.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git merge prueba
Actualizando f1f91e9..a60c91a
Fast-forward
 archivo1.txt | 1 +
 archivo2.txt | 1 +
 2 files changed, 2 insertions(+)
 create mode 100644 archivo1.txt
 create mode 100644 archivo2.txt
~/proyectos/proyecto-nuevo&gt; ls
archivo1.txt  archivo2.txt  README.md
~/proyectos/proyecto-nuevo&gt; git branch
* master
  prueba
</pre>
</div>

<p>
Como se ve, ha añadido el par de ficheros <code>txt</code> a la rama <code>master</code>,
como muestra el listado del directorio. Al mirar en qué rama estoy,
efectivamente el respositorio tiene activa la rama <code>master</code>. Al
principio, cuando empezaba a utilizar <i>git</i>, esperaba que
desapareciera la rama al mezclarla, sin embargo, <i>git</i> mantiene la
rama <code>prueba</code> lo que ha ocurrido es que se han <i>mezclado</i> y ahora
mismo las dos ramas tiene <i>el mismo estado</i>, como podemos apreciar con
un <i>log</i>.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git log --oneline

a60c91a (HEAD -&gt; master, origin/prueba, prueba) Añadir el archivo2.txt a la rama de pruebas.
ee63815 Añadir el archivo1.txt a la rama de pruebas.
f1f91e9 (origin/master) Primer commit del repositorio añadiendo el README.md.
</pre>
</div>

<p>
En la línea que comienza como <code>a60c91a</code> vemos que la rama en la que
estamos, <code>HEAD -&gt; master</code>, la remota <code>origin/prueba</code> y la local
<code>prueba</code> están apuntando al mismo estado o <i>commit</i>. Sin embargo, la
rama remota <code>origin/master</code> se encuentra en el <i>commit</i> <code>f1f91e9</code>
todavía.
</p>

<p>
Para terminar la mezcla hay que sincronizar con el remoto. Los cambios
están hechos en el local, como se ve si le pregunto el estatus.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git status
En la rama master
Tu rama está adelantada a 'origin/master' por 2 confirmaciones.
  (usa "git push" para publicar tus confirmaciones locales)

nada para hacer comit, el arbol de trabajo esta limpio
~/proyectos/proyecto-nuevo&gt; git push
Total 0 (delta 0), reused 0 (delta 0)
To /home/notxor/nube/proyecto-nuevo.git
   f1f91e9..a60c91a  master -&gt; master
</pre>
</div>

<p>
Y si lo compruebo ahora, el resultado es:
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git log --oneline

a60c91a (HEAD -&gt; master, origin/prueba, origin/master, prueba) Añadir el archivo2.txt a la rama de pruebas.
ee63815 Añadir el archivo1.txt a la rama de pruebas.
f1f91e9 Primer commit del repositorio añadiendo el README.md.
</pre>
</div>

<p>
Y ya se aprecian los <i>cuatro diales</i> en el mismo <i>commit</i>.
</p>

<p>
Y como me está saliendo un chorizo muy largo de post, dejo el resto
para otro día.
</p>
</div>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/git/index.html">git</a> <a href="/tags/varios/index.html">varios</a> <a href="/tags/programación/index.html">programación</a> ]]></description>
  <category><![CDATA[git]]></category>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[programación]]></category>
  <link>https://notxor.nueva-actitud.org/2017/11/14/como-estoy-utilizando-git.html</link>
  <pubDate>Tue, 14 Nov 2017 16:25:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Cómo estoy utilizando git (II)]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-11-14</div>
<p>
Hoy voy con la segunda parte, que no entró en el artículo de ayer. El
tema iba con las ramas y los repositorios. Hasta ahora todo ha ido
bien, entre otras cosas porque sólo se han hecho las modificaciones
desde un repositorio y así nunca hay conflictos, pero ¿qué ocurre si
hay un conflicto al hacer un <code>commit</code>?
</p>
<div id="outline-container-orgb3703d7" class="outline-2">
<h2 id="orgb3703d7">Conflictos en el repositorio</h2>
<div class="outline-text-2" id="text-orgb3703d7">
<p>
Para simularlo he modificado en otro ordenador, con otra copia del
repositorio el <code>archivo2.txt</code> y para generar el conflicto modificaré
el mismo fichero en la copia local. De momento, mi repositorio local
no se ha enterado de los cambios.
</p>

<div class="org-src-container">
<pre class="src src-bash">~/proyectos/proyecto-nuevo&gt; git status
En la rama master
Tu rama est&#225; actualizada con <span style="color: #f1fa8c;">'origin/master'</span>.

nada para hacer comit, el arbol de trabajo esta limpio
~/proyectos/proyecto-nuevo&gt; git checkout prueba 
Cambiado a rama <span style="color: #f1fa8c;">'prueba'</span>
Tu rama est&#225; actualizada con <span style="color: #f1fa8c;">'origin/prueba'</span>.
~/proyectos/proyecto-nuevo&gt; git status
En la rama prueba
Tu rama est&#225; actualizada con <span style="color: #f1fa8c;">'origin/prueba'</span>.

nada para hacer comit, el arbol de trabajo esta limpio
</pre>
</div>

<p>
Ninguna de las dos ramas se han dado cuenta que el remoto ha
cambiado. Si hago modificaciones terminaré encontrando el problema.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; echo "Cambios en el repositorio local." &gt;&gt; archivo2.txt 
~/proyectos/proyecto-nuevo&gt; git status                                                                 
En la rama prueba                                                                                                    
Tu rama está actualizada con 'origin/prueba'.                                                                        

Cambios no rastreados para el commit:                                                                                
  (usa "git add &lt;archivo&gt;..." para actualizar lo que será confirmado)                                                
  (usa "git checkout -- &lt;archivo&gt;..." para descartar los cambios en el directorio de trabajo)                        

        modificado:     archivo2.txt                                                                                 

sin cambios agregados a la confirmación (usa "git add" y/o "git commit -a")                                          
~/proyectos/proyecto-nuevo&gt; git add archivo2.txt                                                       
~/proyectos/proyecto-nuevo&gt; git commit -m "Cambios en local pretendiendo que haya conflictos."         
[prueba 8f8437c] Cambios en local pretendiendo que haya conflictos.                                                  
 1 file changed, 1 insertion(+)                                                                                      
~/proyectos/proyecto-nuevo&gt; git push                                                                   
To /ruta/a-la/nube/proyecto-nuevo.git                                                                              
 ! [rejected]        prueba -&gt; prueba (fetch first)
error: fallo el push de algunas referencias a '/ruta/a-la/nube/proyecto-nuevo.git'
ayuda: Actualizaciones fueron rechazadas porque el remoto contiene trabajo que
ayuda: no existe localmente. Esto es causado usuallmente por otro repositorio 
ayuda: realizando push a la misma ref. Quizás quiera integrar primero los cambios
ayuda: remotos (ejem. 'git pull ...') antes de volver a hacer push.
ayuda: Vea 'Notes about fast-forwards0 en 'git push --help' para detalles.
</pre>
</div>

<p>
Bien, todo parecía ir bien y al hacer el <code>push</code> para subir los cambios
al <i>remoto</i>, se queja. Rechaza el cambio que he hecho, me dice que hay
cambios que no están en el <i>local</i> y me recomienda que primero
actualice mi copia de trabajo con esos cambios. <i>Sus deseos son
órdenes</i>.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git fetch origin
remote: Contando objetos: 3, listo.
remote: Comprimiendo objetos: 100% (3/3), listo.
remote: Total 3 (delta 1), reused 0 (delta 0)
Desempaquetando objetos: 100% (3/3), listo.
Desde /ruta/a-la/nube/proyecto-nuevo
   a60c91a..bf825fc  prueba     -&gt; origin/prueba
~/proyectos/proyecto-nuevo&gt; git status
En la rama prueba
Tu rama y 'origin/prueba' han divergido,
y tienen 1 y 1 commits diferentes cada una respectivamente.
  (usa "git pull" para fusionar la rama remota en la tuya)

nada para hacer comit, el arbol de trabajo esta limpio
</pre>
</div>

<p>
He utilizado el comando habitual de actualizar el repositorio local:
<code>fetch</code>. Sin embargo, tras hacerlo <code>git</code> sigue pidiéndome que fusione
la rama remota con la local haciendo un <code>git pull</code>.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git pull
Auto-fusionando archivo2.txt
CONFLICTO (contenido): Conflicto de fusión en archivo2.txt
Fusión automática falló; arregle los conflictos y luego realice un commit con el resultado.
~/proyectos/proyecto-nuevo&gt; git status
En la rama prueba
Tu rama y 'origin/prueba' han divergido,
y tienen 1 y 1 commits diferentes cada una respectivamente.
  (usa "git pull" para fusionar la rama remota en la tuya)

tienes rutas no fusionadas
  (arregla los conflictos y corre "git commit"
  (usa "git merge --abort" para abortar la fusion)

rutas no fusionadas:
  (usa "git add &lt;archivo&gt;..." para marcar una resolucion)

        ambos modificados:     archivo2.txt

sin cambios agregados a la confirmación (usa "git add" y/o "git commit -a")
</pre>
</div>

<p>
El conflicto se ha manifestado. Podemos volvernos atrás y renunciar al
<code>merge</code>, en ese caso perderemos nuestros cambios. Lo habitual en estos
casos es <i>mediar</i> en el conflicto de los dos repositorios.
</p>
</div>
</div>
<div id="outline-container-org2451d6b" class="outline-2">
<h2 id="org2451d6b">Arreglar conflictos a mano</h2>
<div class="outline-text-2" id="text-org2451d6b">
<p>
Todo conflicto me pone nervioso y me hace preguntarme si seré capaz de
arreglarlo. Luego recuerdo que todo tiene solución y la solución
habitual es enfrentarse al problema: abrimos el archivo en conflicto
con nuestro editor favorito (en mi caso utilizo <i>emacs</i>).
</p>


<figure id="orgd8220a2">
<img src="./captura-conflicto-emacs.png" alt="captura-conflicto-emacs image" title="emacs">

<figcaption><span class="figure-number">Figure 1: </span>Editando el fichero <i>conflictivo</i> con emacs.</figcaption>
</figure>

<p>
Como se puede ver en la imagen. Se marcan los cambios entre dos
líneas, la primera marcada como <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD</code> y la última comienza
con una serie de caracteres <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt;</code>. Esas dos líneas marcan la
amplitud del conflicto. Lo situado entre la primera y otra línea
marcada con una serie de caracteres «=» son los cambios que tengo en
local y lo que está entre los «=» y la última es lo que está en el
remoto. El <i>hash</i> que muestra es el identificador del <code>commit</code> donde
están los cambios.
</p>

<p>
Vale, pero ¿cómo arreglo el conflicto?. En este caso es fácil, todo el
texto estaría correcto, por lo que bastaría con borrar las líneas
<i>especiales</i> para generar tener el fichero corregido. Cuando es
código, podemos elegir una versión u otra o incluso generar código
nuevo mezclando las dos versiones, si es necesario.
</p>

<p>
Después de realizar los cambios necesarios miro a ver cómo está el
repositorio.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git status
En la rama prueba
Tu rama y 'origin/prueba' han divergido,
y tienen 1 y 1 commits diferentes cada una respectivamente.
  (usa "git pull" para fusionar la rama remota en la tuya)

Todos los conflictos resueltos pero sigues fusionando.
  (usa "git commit" para concluir la fusion)

Cambios a ser confirmados:

        modificado:     archivo2.txt

~/proyectos/proyecto-nuevo&gt;
</pre>
</div>

<p>
Pues termino la fusión.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git commit
[prueba 8753c00] Merge branch 'prueba' of /home/notxor/nube/proyecto-nuevo into prueba
~/proyectos/proyecto-nuevo&gt; git status
En la rama prueba
Tu rama está adelantada a 'origin/prueba' por 2 confirmaciones.
  (usa "git push" para publicar tus confirmaciones locales)

nada para hacer comit, el arbol de trabajo esta limpio
~/proyectos/proyecto-nuevo&gt; git push
Contando objetos: 6, listo.
Delta compression using up to 4 threads.
Comprimiendo objetos: 100% (6/6), listo.
Escribiendo objetos: 100% (6/6), 659 bytes | 659.00 KiB/s, listo.
Total 6 (delta 3), reused 0 (delta 0)
To /path/a-la/nube/proyecto-nuevo.git
   bf825fc..8753c00  prueba -&gt; prueba
~/proyectos/proyecto-nuevo&gt; git status
En la rama prueba
Tu rama está actualizada con 'origin/prueba'.

nada para hacer comit, el arbol de trabajo esta limpio
</pre>
</div>

<p>
Bien. Ya está solucionado el conflicto.
</p>

<pre class="example" id="orgb6cd3a3">
*   8753c00 (HEAD -&gt; prueba, origin/prueba) Merge branch 'prueba' of /home/notxor/nube/proyecto-nuevo into prueba
|\  
| * bf825fc Añadido desde otro ordenador.
* | 8f8437c Cambios en local pretendiendo que haya conflictos.
|/  
* a60c91a (origin/master, master) Añadir el archivo2.txt a la rama de pruebas.
* ee63815 Añadir el archivo1.txt a la rama de pruebas.
* f1f91e9 Primer commit del repositorio añadiendo el README.md.
</pre>

<p>
Así nos queda el repositorio después de los cambios.
</p>
</div>
</div>
<div id="outline-container-org7992b04" class="outline-2">
<h2 id="org7992b04">Revertir cambios</h2>
<div class="outline-text-2" id="text-org7992b04">
<p>
Hay ocasiones en las que acabo de subir un cambio y me doy cuenta de
que falta algo o habría que corregir algún tema. Hay dos opciones. La
primera es hacer un nuevo <i>commit</i> arreglando el entuerto o, la
segunda, revertir los cambios.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; echo "Añadir nueva línea para revertir cambios." &gt;&gt; archivo2.txt 
notxor@oldulo:~/proyectos/proyecto-nuevo&gt; cat archivo2.txt 
Esto es el fichero de prueba 2.
Cambios en el repositorio local.
Esto es una línea creada por otro usuario.
Añadir nueva línea para revertir cambios.
~/proyectos/proyecto-nuevo&gt; git add archivo2.txt 
~/proyectos/proyecto-nuevo&gt; git commit -m "Añadir cambios para revertirlos después."
[prueba b1120fe] Añadir cambios para revertirlos después.
 1 file changed, 1 insertion(+)
</pre>
</div>

<p>
He añadido un <i>commit</i> a la línea del repositorio, pero quiero volver
atrás. Si es el último <i>commit</i> es sencillo puedo utilizar la opción
<code>--amend</code> del comando <code>commit</code> o puedo utilizar el comando <code>revert</code>.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git commit --amend
[prueba 4a0256f] Añadir cambios para revertirlos después.
 Date: Wed Nov 15 10:05:17 2017 +0100
 1 file changed, 1 insertion(+)
</pre>
</div>

<p>
Nuestro repositorio a estas alturas tendrá la siguiente forma:
</p>

<pre class="example" id="org0a173ee">
* 4a0256f (HEAD -&gt; prueba) Añadir cambios para revertirlos después.
*   8753c00 (origin/prueba) Merge branch 'prueba' of /home/notxor/nube/proyecto-nuevo into prueba
|\  
| * bf825fc Añadido desde otro ordenador.
* | 8f8437c Cambios en local pretendiendo que haya conflictos.
|/  
* a60c91a (origin/master, master) Añadir el archivo2.txt a la rama de pruebas.
* ee63815 Añadir el archivo1.txt a la rama de pruebas.
* f1f91e9 Primer commit del repositorio añadiendo el README.md.
</pre>

<p>
Bien, vale, no se ve que haya borrado nada. ¿Cómo borro el <i>commit</i>
para hacer como si nunca hubiera existido?
</p>

<p>
Para eso utilizo el comando <code>reset</code> bien con una opción <code>--soft</code> si no
quiero perder los cambios locales o con una opción <code>--hard</code> si quiero
quedarme en el mismo estado que estaba el <code>commit</code> al que quiero ir.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git reset 8753c00 --soft
~/proyectos/proyecto-nuevo&gt; git status
En la rama prueba
Tu rama está actualizada con 'origin/prueba'.

Cambios a ser confirmados:
  (usa "git reset HEAD &lt;archivo&gt;..." para sacar del area de stage)

        modificado:     archivo2.txt

~/proyectos/proyecto-nuevo&gt;
</pre>
</div>

<p>
En el caso del <code>reset --soft</code> conservo los cambios que hice en el
repositorio local.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git reset 8753c00 --hard
HEAD está ahora en 8753c00 Merge branch 'prueba' of /home/notxor/nube/proyecto-nuevo into prueba
~/proyectos/proyecto-nuevo&gt; git status
En la rama prueba
Tu rama está actualizada con 'origin/prueba'.

nada para hacer comit, el arbol de trabajo esta limpio
</pre>
</div>

<p>
En este caso, desaparecen todos los cambios que haya hecho en el
repositorio local y lo deja en el estado en el que estaba en el
<i>commit</i> marcado como <code>8753c00</code>.
</p>
</div>
</div>
<div id="outline-container-org9c7b8fc" class="outline-2">
<h2 id="org9c7b8fc">Borrar rama</h2>
<div class="outline-text-2" id="text-org9c7b8fc">
<p>
Algunas veces utilizo una rama sólo para hacer unas pruebas y hechas
esas pruebas según el resultado haremos un <code>merge</code> o no, con la rama
principal. El caso es que cuando ya no me interesa utilizar esa rama
la quiero borrar.
</p>

<p>
Primero me voy a la rama principal, no se puede borrar una rama cuando
la tiene activa (como si intentas cortar una rama de un árbol, en la
que estás sentado).
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git checkout master 
Cambiado a rama 'master'
Tu rama está actualizada con 'origin/master'.
~/proyectos/proyecto-nuevo&gt; git branch -d prueba 
warning: borrando la rama 'prueba' que ha sido fusionada en
         'refs/remotes/origin/prueba', pero aún no ha sido fusionada a HEAD.
Eliminada la rama prueba (era 8753c00)..
</pre>
</div>

<p>
La rama ya la fusionamos... ahora vamos a colocar nuestro <code>HEAD</code> en el
sitio correcto.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git reset 8753c00 --hard
HEAD está ahora en 8753c00 Merge branch 'prueba' of /path/a-la/nube/proyecto-nuevo into prueba
~/proyectos/proyecto-nuevo&gt; git push
Total 0 (delta 0), reused 0 (delta 0)
To /path/a-la/nube/proyecto-nuevo.git
   a60c91a..8753c00  master -&gt; master
</pre>
</div>

<p>
Ahora mismo tenemos todos los diales apuntando al mismo lugar o
<i>commit</i>. Lo podemos ver haciendo un <code>log</code>.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git log --oneline --graph --all
*   8753c00 (HEAD -&gt; master, origin/prueba, origin/master) Merge branch 'prueba' of /home/notxor/nube/proyecto-nuevo into prueba
|\  
| * bf825fc Añadido desde otro ordenador.
* | 8f8437c Cambios en local pretendiendo que haya conflictos.
|/  
* a60c91a Añadir el archivo2.txt a la rama de pruebas.
* ee63815 Añadir el archivo1.txt a la rama de pruebas.
* f1f91e9 Primer commit del repositorio añadiendo el README.md.
</pre>
</div>

<p>
¿Cómo? Sigue habiendo una rama <code>origin/prueba</code>... ¿no la había
borrado? Bueno, sí y no. Había borrado la rama <i>local</i> pero la remota
aún no la he tocado. Falta hacer un <code>push</code> para <i>normalizar</i> las ramas
en el remoto también.
</p>

<div class="org-src-container">
<pre class="src src-nil">~/proyectos/proyecto-nuevo&gt; git push origin --delete prueba
To /path/a-la/nube/proyecto-nuevo.git
 - [deleted]         prueba
</pre>
</div>
</div>
</div>
<div id="outline-container-orgb7abe77" class="outline-2">
<h2 id="orgb7abe77">Conclusión</h2>
<div class="outline-text-2" id="text-orgb7abe77">
<p>
<code>git</code> es una herramienta con una potencia que apenas he empezado a
rascar superficialmente y merece la pena el esfuerzo en aprender sus
modos y maneras. Venir de otros sistemas de control de versiones
hicieron que me costara al principio. Algunos comandos coinciden en
nombre, pero su función es distinta.
</p>

<p>
Estos dos artículos son en realidad el pasar a limpio <i>mis</i> apuntes
sobre <code>git</code> y cómo he entendido yo las cosas. Quiero decir, que puedo
estar equivocado y que algo no sea exactamente como cuento en ellos. Y
que iré actualizando el contenido, para corregirlo o para ampliarlo si
es necesario.
</p>

<p>
De las cosas que hablo en los dos artículos, la mayoría se pueden
hacer con el comando <code>gitk --all</code> que muestra un entorno gráfico <code>tk</code>
con el estado de nuestro repositorio y con el <code>gui</code> (que es otro
entorno gráfico <code>tk</code>) que nos auxilia en las acciones de actualizar la
información entre los repositorios. Sin embargo, me parece importante
saber qué estás haciendo en cada momento y cómo funciona la
herramienta que hay por debajo.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/git/index.html">git</a> <a href="/tags/programación/index.html">programación</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[git]]></category>
  <category><![CDATA[programación]]></category>
  <link>https://notxor.nueva-actitud.org/2017/11/14/como-estoy-utilizando-git-ii.html</link>
  <pubDate>Tue, 14 Nov 2017 16:21:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Quizá]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-11-13</div>
<p>
Oigo una tórtola llamando a su pareja en el jardín. O quizá esté
dándome la razón. O quizá se la esté dando a esa nube rojiza que
arrastra el viento. Quizá morimos cuando despertamos y la vida es eso
que pasa mientras dormimos. O quizá seamos el inquieto sueño de un
dios con flatulencias. Quizá.
</p>

<p>
Tengo que salir a comprar el pan, como casi todas las mañanas y
enfrentarme a la calle pensando que soy un pedo en el culo de dios me
anima un poco, quizá. Tengo que reirme, el humor básico, pueril y
escatológico siempre da resultado. Aunque en este caso quizá lo
podríamos catalogar de <i>divino</i> también.
</p>

<p>
Estoy dejando que mi pensamiento fluya entre las rendijas, grietas
llenas de flatulencias que afloran a la superficie y vuelvo a lo
escatológico, quizá porque es lo único que me viene a la mente. Quizá
porque mis pensamientos negros se están volviendo marrones por el
desgaste. O quizá porque ya no puedo pensar nada sólido y me afloran
tan sólo gases y vapores.
</p>

<p>
Oigo la mañana pasar como un susurro en mis oídos, zumban de
aburrimiento. Soy capaz de acallar ese ruidillo introduciéndoles unos
cascos y poniendo <i>rock'nd roll</i> a todo volumen. Pero el zumbido
seguro continuaría inmutable, como las tripas de nuestro flatulento
dios, haciendo fluir los gases, cambiando para que nada cambie. Pero
cuando intento escuchar su ruido, que es el mío, huye. Cuando le
presto atención se para y se aleja y sólo vuelve cuando dejo de
buscarlo. Está jugando conmigo, quizá. Quizá encontrar la realidad en
lo incontable, en lo imaginado, no es posible. O lo imaginado es tan
real que detiene los flujos místicos. Quizá la nube que ha pasado no
se ha enterado de nada, ocupada en sus propios gases. O quizá es el
sueño vivo de otro dios colgando en el vacío aire y lo ve todo.
</p>

<p>
La tórtola sigue con su cantinela y se me está haciendo ya un poco
pesada: <i>cu-cuu-cu</i>, <i>cu-cuu-cu</i>. Se sentirá sola y abandonada,
quizá. O quizá no soporta su flatulento fluir en las tripas de dios.
Quizá necesita decir algo para huir de su zumbido. Quizá. Me gustaría
mostrarle mi escatológico pensamiento de ateo, quizá su monótona
llamada se tornara en carcajada. Quizá.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/escritos/index.html">escritos</a> <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[escritos]]></category>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2017/11/13/quiza.html</link>
  <pubDate>Mon, 13 Nov 2017 00:01:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Simplificaciones]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-11-12</div>
<div id="outline-container-org4d2c64c" class="outline-2">
<h2 id="org4d2c64c">Los atajos de la mente</h2>
<div class="outline-text-2" id="text-org4d2c64c">
<p>
El órgano humano<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> que más energía consume es el cerebro. La
evolución ha seleccionado a aquellos organismos que han llegado a las
mismas conclusiones con el menos gasto de pensamiento. La naturaleza
misma nos proporciona el mecanismo esencial y primigenio para ello:
<i>las emociones</i>.
</p>

<p>
Las emociones intervienen en todas las acciones humanas<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> de forma
inmediata y nada tienen que ver con la inteligencia o la resolución de
problemas. El <i>miedo</i> por ejemplo, tan denostado por la literatura
épica, es un mecanismo de defensa que hace que seamos más cautos, y
dispara nuestra fisiología para preparar a nuestro cuerpo para la
acción (ya sea ésta enfrentarse al peligro o huir).
</p>

<p>
Nuestro cerebro comienza ahorrando en el proceso de percibir nuestro
entorno. Algo que ya estudió a principios del siglo pasado la
<a href="https://es.wikipedia.org/wiki/Psicolog%C3%ADa_de_la_Gestalt">Psicología de la Gestalt</a> y sus leyes de la percepción. Podemos resumir
todas esas leyes diciendo que al final son atajos perceptivos que
utiliza nuestra mente para ahorrar proceso de cálculo. Además, como
una parte importante de nuestra vida se relaciona con la relación con
nuestros semejantes, estamos programados para percibir caras,
emociones, otros humanos, así, podemos ver casi en cualquier mancha
una cara, un ojo, una sonrisa, etc.
</p>

<p>
Pero también, nuestro cerebro ahorra en el procesamiento de la
información. A base de realizar ciertos procesos, nuestro cerebro
acelera ciertas conexiones, lo que con cierta experiencia en cualquier
actividad mental, alcanzamos la solución casi sin pensarlo. Por
ejemplo, si practicamos una determinada lengua, tendremos más fácil
encontrar la palabra que buscamos o expresar lo que queremos decir. Si
habitualmente realizamos cálculos mentales, los realizaremos cada vez
más rápidamente y con menos errores. Pero hay algunos atajos que vamos
a comentar más despacio.
</p>

<p>
Una forma de disminuir el pensamiento, que ya he dicho que es muy caro
en gasto energético, es no utilizarlo. Para ello disponemos de algunos
mecanismos inconscientes (como los prejuicios) o conscientes (como los
argumentarios).
</p>
</div>
<div id="outline-container-org061c466" class="outline-3">
<h3 id="org061c466">Prejuicios</h3>
<div class="outline-text-3" id="text-org061c466">
<p>
Los <i>prejuicios</i> son un conjunto de creencias que todos tenemos antes
incluso de enfrentarnos al objeto en sí. Los <i>prejuicios</i> que más nos
suenan son los consabidos <i>nacionales</i> o <i>regionales</i>: Los <i>ingleses</i>
son..., los <i>andaluces</i> son...
</p>

<p>
Pero no sólo los nacionales, también los profesionales, los
ideológicos o cualquier otra <i>etiqueta</i> que pueda resumir a un
colectivo. El otro día leía en una red social alguien que recomendaba
un libro escrito por <i>un soldado</i> y claro <i>hay que perdonarle faltas
de ortografía y gramaticales</i>, porque es <i>soldado</i> y ya se sabe lo
incultos e iletrados que son... cuando la culpa sería de la editorial
y los correctores profesionales que tiene contratados. Y también
habría que recordarle al autor de dicho comentario que la obra culmen
de la literatura española, el Quijote, fue escrita por un
<i>soldado</i>. Sin embargo, su prejuicio contra (sí, los prejuicios son
siempre <i>contra</i>) un colectivo hace que achaque los errores a ese
colectivo, porque no necesita pensar en qué momento del proceso se
producen los errores <i>sabe</i> que se deben a la <i>incultura</i> del
<i>violento</i> soldado (aunque seguramente ese <i>inculto soldado</i> tiene, al
menos, un libro publicado más que él).
</p>

<p>
Lo vemos en todos los <i>nazi-onalismos</i>, siempre el <i>hecho diferencial</i>
coincide en lo mismo. Los <i>otros</i> son siempre <i>sucios</i>, <i>incultos</i>,
<i>violentos</i>, <i>autoritarios</i> y <i>nosotros</i> somos mejores en todos los
aspectos, más <i>cultos</i>, más <i>educados</i>, más <i>dialogantes</i>. El error,
el defecto, siempre es colectivo y del <i>otro</i>. Es más fácil
<i>deshumanizar</i> al que no es de <i>mi tribu</i>, al que no es de <i>mi
religión</i>, al que no es de <i>mi tendencia política</i>, al que no es de
<i>mi lo que sea</i> (las excusas son infinitas).
</p>

<p>
Este tipo de creencias me ahorran el esfuerzo de pensar o incluso de
gastar tiempo en conocer al otro. Cuando sé que alguien está en un
determinado grupo o le puedo asignar una etiqueta conocida
previamente, no necesito pensar: le asigno las características
asociadas con la etiqueta en cuestión y ya está. Así funciona la gente
que cree en los horóscopos, por ejemplo: eres <i>aries</i>, ya no tienes
que hacer o decir nada más, eres de tal o cual manera: ¡lo que nos
ahorramos en psicólogos!
</p>
</div>
</div>
<div id="outline-container-org4fce078" class="outline-3">
<h3 id="org4fce078">Argumentarios</h3>
<div class="outline-text-3" id="text-org4fce078">
<p>
Esta forma de ahorrar esfuerzos es más elaborada. La suelen utilizar
partidos políticos, asociaciones y otras entidades que no quieren un
<i>verso suelto</i> en sus filas. Los seguidores los abrazan casi con
alegría. Ya saben lo que tienen que contestar sin necesidad de gastar
energía en pensar o de contrastar la información que están soltando
por su boca. En general suponen que <i>alguien</i> la ha comprobado antes y
por tanto la repiten como una <i>verdad indiscutible</i>.
</p>

<p>
Si a un miembro de tal o cual partido le hablas de corrupción
automáticamente saltará una ristra de casos de corrupción del <i>máximo</i>
enemigo. Sin pestañear. Si le hablas de cualquier tema, sobre todo si
es actualidad, te soltará la repetición de las cuatro ideas básicas.
</p>

<p>
El <i>argumentario</i> como tal aparece en el mundo de las ventas. Se trata
de hacer un documento donde se cuentan todas las virtudes de un
producto. Se utilizaba para que los vendedores fueran capaces de
comunicar todas las virtudes y enfrentarse a todos los <i>peros</i> que
pudiera poner un posible cliente.
</p>

<p>
Sin embargo, <i>argumentar</i> no tiene nada que ver con un
<i>argumentario</i>. En los argumentarios modernos todo se reduce a repetir
frases y ondear banderas gritando consignas que en la mayoría de los
casos no son solo de dudosa veracidad, son mentiras descaradas. Joseph
Goebbels (sí, el mismo que dijo que <i>una mentira repetida mil veces se
convierte en verdad</i>) dijo una vez:
</p>

<blockquote>
<p>
«Toda propaganda debe ser popular, adaptando su nivel al menos
inteligente de los individuos a los que va dirigida. Cuanto más grande
sea la masa a convencer, más pequeño ha de ser el esfuerzo mental a
realizar. La capacidad receptiva de las masas es limitada y su
comprensión escasa; además, tienen gran facilidad para olvidar.»
</p>
</blockquote>

<p>
Se trata, por tanto, de seleccionar la población objetivo y evitarles
pensar dándoles las soluciones para que no se hagan las preguntas.
</p>
</div>
</div>
<div id="outline-container-org2c97695" class="outline-3">
<h3 id="org2c97695">Creencias</h3>
<div class="outline-text-3" id="text-org2c97695">
<p>
La forma más habitual de ahorrar energía pensando es la
<i>creencia</i>. Porque en realidad, no necesitamos <i>saber</i> cómo es algo,
sólo necesitamos <i>creer</i> que lo sabemos. La curiosidad humana consume
mucha energía, hace que busquemos respuestas y por ello necesitamos el
ahorro que supone no tenerla. Las que arrastramos históricamente son
las religiosas. No necesitas plantearte lo que es bueno o es malo, por
qué el mundo es como es: la religión te da las respuestas. Pero no
sólo hay creencias religiosas.
</p>

<p>
Sin embargo, este ahorro de energía es al final contraproducente. Es
el mayor despilfarro de recursos humanos que hay. La mayoría de las
guerras, o al menos las más sangrientas se derivan del ahorro de
proceso de pensamiento. Y no sólo las religiosas. Las dos grandes
guerras en Europa se han producido y alimentado de las creencias
<i>nazi-onalistas</i>.
</p>

<p>
Las creencias sirven también para <i>deshumanizar</i> a los otros, esos que
no son de <i>otra tribu</i>, esos <i>infieles</i>... <i>sucios</i>, <i>incultos</i>,
<i>violentos</i> e <i>intolerantes</i> (ya, bueno, las excusas de siempre).
</p>

<p>
Además, las creencias se ordenan en su propio universo. Si nos
plantean un hecho que choca con alguna de nuestras creencias,
directamente los obviamos. No existe, no tiene lugar en nuestro
universo, no encaja. Muchas veces ni lo percibimos y si nos llaman la
atención sobre ello no lo tomaremos en cuenta o le quitaremos
importancia.
</p>

<p>
Las creencias nos pueden llevar a vivir en la irrealidad. Lo que nos
rodea deja de tener importancia para nosotros. Así, el mecanismo que
nos ahorra energía, se vuelve contra nosotros.
</p>
</div>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Digo <i>humano</i> pero es extensible a los vertebrados en general.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Digo <i>humanas</i> como antes, pero vuelvo a repetir que es
extensible a todos los animales denominados <i>superiores</i> en general.
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/psicología/index.html">psicología</a> <a href="/tags/varios/index.html">varios</a> ]]></description>
  <category><![CDATA[psicología]]></category>
  <category><![CDATA[varios]]></category>
  <link>https://notxor.nueva-actitud.org/2017/11/12/simplificaciones.html</link>
  <pubDate>Sun, 12 Nov 2017 09:39:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Mia eta vojaĝo]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-11-10</div>
<div id="outline-container-orgcf6de2c" class="outline-2">
<h2 id="orgcf6de2c">Antaŭparolo</h2>
<div class="outline-text-2" id="text-orgcf6de2c">
<p>
Por la dua ekzerco oni devas verki rakonton pri vojaĝo farita. Sed nur
200 vortoj por vojaĝo estas tre malmultaj. Neniu vojaĝo rakontebla per
200 vortoj estas rakontinda. Sed bone, mi devas provi ĝin.
</p>
</div>
</div>
<div id="outline-container-org478a1a4" class="outline-2">
<h2 id="org478a1a4">Laciganta vojaĝo ĝis la ripozo</h2>
<div class="outline-text-2" id="text-org478a1a4">
<p>
Tiu friska mateno malvarmiĝis dum la mateniĝa horo, ankaŭ malluma sed
pli kaj pli hela. Mi vekiĝis kiam la steloj komencis kaŝiĝi por iri
ripozi al siaj tagaj lokoj. Mia matena purigado estis malvarma, la
glacia akvo frapis mian vizaĝon rekte tiel, kiel mian menson. Mi ne
restis antaŭ la spegulo longe, nenio rigardinda estas tie kaj tempo
por kombado estas superflua.
</p>

<p>
Mi eliris el mia dormoĉambro al la ŝtuparo kaj malrapide, miaj
klakantaj ostoj bezonas varmiĝi antaŭ ol ili bone kuniĝas por mia
moviĝado. Ŝtupo post ŝtupo mi gajnis fidon pri miaj propraj paŝoj kaj
mi atingis la malsupran etaĝon. Lacigita per tiel granda peno mi
apogiĝis ĉe la manrelo de la ŝtuparo kaj mi rigardis mian ĉirkaŭan
salonon. Frue la sofo alvokis mian atenton. La kompatinda meblo
bezonis senti sin utila. Mi pene marŝis ĝis la rando de la sidloko,
kay tie turnante mian dorson al ĝi, mi lasis mian korpon cedi al
gravita leĝo por sidigi min per mola kusena frapo.
</p>

<p>
Fine mi ripozis, kiel mi meritas. Tiu dimanĉo mi ne plu iris eĉ por
vespermanĝi. Trankvila mi restis duonkuŝanta inter la kusenoj, leganta
la interretajn ĵurnalojn, kaj mi ĝuis la <i>«dolĉa fari nenion»</i>.
</p>
</div>
</div>
<div id="outline-container-org8746ca9" class="outline-2">
<h2 id="org8746ca9">Kvanto da vortoj</h2>
<div class="outline-text-2" id="text-org8746ca9">
<table>


<colgroup>
<col  class="org-left">

<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Parto</th>
<th scope="col" class="org-right">Vortoj</th>
<th scope="col" class="org-right">Literoj</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">Sen antaŭparolo</td>
<td class="org-right">202</td>
<td class="org-right">1188</td>
</tr>

<tr>
<td class="org-left">Kun antaŭparolo</td>
<td class="org-right">237</td>
<td class="org-right">1405</td>
</tr>

<tr>
<td class="org-left">Totalaj</td>
<td class="org-right">254</td>
<td class="org-right">1621</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/esperanto/index.html">esperanto</a> ]]></description>
  <category><![CDATA[esperanto]]></category>
  <link>https://notxor.nueva-actitud.org/2017/11/10/mia-eta-vojaĝo.html</link>
  <pubDate>Fri, 10 Nov 2017 15:27:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Sobre toki pona]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-11-07</div>
<p>
Estos días he andado buscando información y datos para la realización
del juego, del que ya he venido hablando. En concreto lo que necesito
es un lenguaje que <i>suene primitivo</i> para algunos personajes que
aparecerán en él. Y, en un momento, apareció <i>toki pona</i>. Una lengua
inventada sobre la que había oído hablar muchas veces pero nunca me
había molestado en profundizar.
</p>

<p>
Como ya he dicho, es una lengua <i>inventada</i> y además nace con una idea
o vocación minimalista. Su intención es expresar mucho con pocos
elementos, de hecho sólo cuenta con 118 palabras y cualquier otro
concepto se debe alcanzar juntando esas pocas palabras.
</p>

<p>
Su simplicidad es tal que obliga al hablante a pensar de una forma
distinta a lo habitual. La mayoría de los conceptos deben crearse
juntando las palabras de forma creativa y obliga, por tanto, a
alcanzar la síntesis del concepto. Por ejemplo, si quiero decir
<i>amigo</i>, palabra que no existe en <i>toki pona</i> debo juntar otras, como
podría ser <i>jan pona</i>, que sería algo así como <i>persona buena</i> o
<i>persona agradable</i>.
</p>
<div id="outline-container-org1cc05a8" class="outline-2">
<h2 id="org1cc05a8">¿Cómo es <i>toki pona</i>?</h2>
<div class="outline-text-2" id="text-org1cc05a8">
<p>
La traducción directa sería <i>lengua buena</i> o <i>habla buena</i> o <i>lenguaje
del bien</i> (como algunos lo traducen) o <i>hablar es bueno</i>...
</p>

<p>
Como se puede apreciar es una lengua un tanto <i>imprecisa</i> y eso se
debe a que una determinada palabra puede funcionar en unas situaciones
como verbo, en otras como sustantivo o como adjetivo. Los verbos
tampoco se conjugan, no hay tiempos estrictamente. Tampoco hay género
o número en los nombres; el plural y el singular, por tanto, no
existen. Incluso el contar con números es muy complicado: existe el 0
(o ninguno), <i>ala</i>; existe el 1, <i>wan</i>; existe el 2, <i>tu</i>; y también
el 5, <i>luka</i> ... pero el tres es <i>tu wan</i> o el cuatro es <i>tu tu</i> o el
seis es <i>luka wan</i>. Así los números grandes quedan casi descartados de
las conversaciones.
</p>

<p>
La sílaba tónica siempre recae sobre la primera sílaba de la palabra
por lo que no necesita tildes para marcarla.
</p>

<p>
Su estructura también es simple <i>Sujeto + verbo + predicado</i> y cada
palabra modifica a lo anterior, por lo que a parte de darle
importancia al orden, y también hay que utilizar alguna partícula para
separar conceptos. Por ejemplo: existe la palabra <i>telo</i> que significa
agua o líquido en general. Así <i>telo jelo</i> será <i>agua amarilla</i> u
orina; <i>telo loje</i> es <i>agua roja</i> o sangre; <i>telo nasa</i> es <i>agua loca</i>
o bebida alcohólica.
</p>

<p>
Si digo <i>mi lukin pona</i> quiere decir que <i>yo veo bien</i>, pero si cambio
el orden <i>mi pona lukin</i> quiere decir que <i>yo soy guapo</i> pues <i>pona
lukin</i> se traduciría como <i>agradable a la vista</i> literalmente y es la
forma de decir <i>guapo</i> o <i>bello</i>.
</p>

<p>
Para escribirlo se han adaptado, pero también, creado algunos
alfabetos. El más habitual es el <i>latino</i> habitual. En <i>toki
pona</i> existen los cinco sonidos vocales <i>a</i>, <i>e</i>, <i>i</i>, <i>o</i> y <i>u</i>, pero
los consonantes sólo son <i>k</i>, <i>l</i>, <i>m</i>, <i>n</i>, <i>p</i>, <i>s</i> y <i>t</i>. Además
también existen dos sonidos de vocal <i>diptongada</i> la «i», para la que
se emplea la <i>j</i> y la «u» para la que se emplea la <i>w</i>. De las
consonante, todas suenan como en español, excepto la <i>k</i> que puede
sonar como <i>k</i> o como <i>g</i>.
</p>
</div>
</div>
<div id="outline-container-orgc9edd73" class="outline-2">
<h2 id="orgc9edd73">¿Para qué sirve?</h2>
<div class="outline-text-2" id="text-orgc9edd73">
<p>
Es curioso que, como he leído por algún sitio, en el MIT se den cursos
de <i>toki pona</i>. No sé si será útil o no. Lo que está claro es que
obliga a centrarse en lo esencial y además te obliga a ser
absolutamente lógico y formal (como los lenguajes de programación),
donde el orden y la estructura de las <i>frases</i> generan resultados
distintos, no es lo mismo decir <i>jan utala pona</i> que <i>jan pona utala</i>:
</p>

<p>
((jan utala) pona)  =&gt;  buen guerrero (persona combatiente buena)
</p>

<p>
((jan pona) utala)  =&gt;  amigo guerrero (persona buena combatiente)
</p>

<p>
En teoría, aprender <i>toki pona</i> es muy fácil, tienes poco vocabulario
que aprender y las normas gramaticales no son muchas.
</p>

<p>
Por algunos sitios se refieren a esta lengua como <i>el yoga de la
mente</i> y fundamentan conceptos del lenguaje, como puede ser el
minimalismo, en corrientes filosóficas orientales como el <i>taoísmo</i> o
el <i>zen</i>.
</p>
</div>
</div>
<div id="outline-container-org8f4c3eb" class="outline-2">
<h2 id="org8f4c3eb">Conclusiones</h2>
<div class="outline-text-2" id="text-org8f4c3eb">
<p>
Como concepto de lengua es chocante, pues en principio todas las
lenguas deberían servir para comunicarse. Sin embargo, en este caso la
precisión en la comunicación parece quedar relegada por otras
características como la creatividad para alcanzar los conceptos, la
capacidad de síntesis y el estricto <i>formalismo</i> al crear las frases.
</p>

<p>
Esas características parecen ser muy útiles para programadores
informáticos que deben ser capaces de expresar conceptos y procesos
complejos con unas pocas reglas muy estrictas.
</p>

<p>
Tiene muy buena pinta el lenguaje y parece sencillo, aunque para
practicarlo hay que encontrar material gráfico, escrito, vídeos o algo
que permita asentar conceptos y ampliarlos. Porque un idioma que no se
practica se pierde, y eso es una limitación importante.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/idiomas/index.html">idiomas</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[idiomas]]></category>
  <link>https://notxor.nueva-actitud.org/2017/11/07/sobre-toki-pona.html</link>
  <pubDate>Tue, 07 Nov 2017 10:22:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Montar un servidor http local para pruebas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-11-03</div>
<div id="outline-container-orgadb87ea" class="outline-2">
<h2 id="orgadb87ea">La necesidad</h2>
<div class="outline-text-2" id="text-orgadb87ea">
<p>
A vueltas con la nueva solución para mi blog estático, me encuentro
que no es <i>tan</i> estático como debería ser. No sólo por haberle puesto
algún <i>script</i> para gestionar los comentarios.
</p>

<p>
El problema que me he encontrado es que los <i>paths</i> que utiliza
<code>org-page</code> para los enlaces a cosas internas, como las imágenes o los
ficheros de otros artículos, comienzan todos por «/» y son, por tanto,
absolutos dentro del servidor. No sé si eso se podría configurar, no
encuentro ninguna opción que me lo permita. Con el sistema anterior,
aún no teniendo un servidor en marcha, era capaz de <i>navegar</i> el
blog. Con este sistema, una vez generados los ficheros del blog, no se
pueden <i>navegar</i>, no funcionan los enlaces.
</p>

<p>
Al principio, utilizaba el mismo sistema de <i>emacs</i>: lanzaba desde el
mismo <i>emacs</i> con <code>M-x op/do-publication-and-preview-site</code> el servidor
interno y lo detenía con <code>M-x httpd-stop</code>. <code>org-page</code> generaba
directamente una estructura de ficheros y cada artículo lo guarda en
un fichero <code>index.html</code> dentro de un chorizo de directorios del
estilo:
</p>

<pre class="example">
/tema/año/mes/día/título-del-artículo/
</pre>


<p>
El sistema anterior generaba sólo un fichero con un nombre del estilo
<code>título-del-artículo.html</code> y los guardaba todos en el mismo
directorio. El problema que me encontré es que para <code>org-page</code> el
directorio <code>./</code> para generar los enlaces de las imágenes, por ejemplo,
es <code>/tema/año/mes/día/</code>. Sin embargo, para el resto de los servidores
ese directorio es el mismo donde se encuentra el fichero <code>index.html</code>.
</p>

<p>
En resumen, si pongo la imagen donde se ve con el servidor de <i>emacs</i>
no se verá en el servidor remoto cuando suba el blog. Si lo pongo
donde se ve en el servidor remoto, en local no veo correctamente la
página para hacerme una idea de cómo quedará, por si hubiera que hacer
algún cambio antes de subirlo.
</p>

<p>
¿Cómo solucionar esto? Pues montando un servidor de pruebas.
</p>
</div>
</div>
<div id="outline-container-orga995d2b" class="outline-2">
<h2 id="orga995d2b">Montando un servidor</h2>
<div class="outline-text-2" id="text-orga995d2b">
<p>
Montar un servidor como <i>Apache</i> o cualquier otro me parecía una
salvajada. En recursos y en quebraderos de cabeza. Así que me puse a
recordar que había otros sistemas locales montados sobre algunos
módulos o paquetes como <i>Python</i> o <i>PHP</i>, dos lenguajes que se
utilizan para el desarrollo <i>web</i>. Supongo que habrá otros sistemas,
pero me centraré en los que conozco y que he empezado a utilizar.
</p>
</div>
<div id="outline-container-orge0fe391" class="outline-3">
<h3 id="orge0fe391">La opción de Python</h3>
<div class="outline-text-3" id="text-orge0fe391">
<p>
<i>Python</i> es uno de mis lenguajes favoritos y el que más utilizo
normalmente para mis cosas. Aunque en la actualidad estoy sufriendo
una <i>invasión</i> en todos los ámbitos de <i>emacs</i> y éste trae de fábrica
el <i>Lisp</i>. Supongo que si sigue con el rumbo actual, terminaré
moviéndome más hacia <i>elisp</i> o incluso me estoy mirando seriamente
<i>guile</i> como alternativa a mis <i>scripts</i>.
</p>

<p>
Pero vamos al tema: necesito un servidor de pruebas y me acordé del
que viene instalado con el propio <i>Python</i>. Bueno, de <i>los</i> que vienen
con dicho lenguaje según tengamos instalado una versión de <i>Python</i> u
otra.
</p>

<p>
¿No sabes que versión tienes instalada? Pues teclea lo siguiente:
</p>

<pre class="example">
python -V
</pre>


<p>
Y mira qué responde. Si la respuesta es del tipo 2.x o del tipo 3.x es
importante pues el comando variará de una a otra versión:
</p>

<pre class="example">
python -m SimpleHTTPServer [puerto]      # Para Python 2.x
python -m http.server [puerto]           # Para Python 3.x
</pre>


<p>
Hacerlo funcionar es muy sencillo: ir al directorio donde se ha hecho
el <i>deploy</i> del blog y lanza el sistema con el comando
correspondiente.
</p>
</div>
</div>
<div id="outline-container-org2a215b0" class="outline-3">
<h3 id="org2a215b0">La opción PHP</h3>
<div class="outline-text-3" id="text-org2a215b0">
<p>
En realidad, mi primera opción fue <i>Python</i>, pero también he probado
con <i>PHP</i>, más con la esperanza de que el <i>plugin</i> de los comentarios,
ya que utiliza este lenguaje para trabajar, funcionase. Si hubiera
sido así, seguramente seguiría utilizándolo. El comando que se utiliza
es:
</p>

<pre class="example">
php -S host:puerto
</pre>


<p>
Y se emplea de forma similar a los de <i>Python</i>.
</p>
</div>
</div>
</div>
<div id="outline-container-org39df7ea" class="outline-2">
<h2 id="org39df7ea">Conclusión</h2>
<div class="outline-text-2" id="text-org39df7ea">
<p>
Mi forma de trabajar ha variado un poco para afinar todos esos
detalles. Por ejemplo, antes guardaba todas las imágenes en un
directorio <code>images</code> y tenía que arreglar problemas de <i>colisión de
nombres</i> de basura que quedaba si eliminaba un artículo y no me
preocupaba de qué ficheros enlazaba. Con el sistema actual, guardo en
el mismo directorio el artículo y sus enlazados, como imágenes y otros
ficheros adjuntos. Si borro un artículo, desaparecerá todo y no tendré
que estar buscando en un directorio enorme una o dos imágenes. Además,
si me apeteciera (que no es lo habitual), llamar a las imágenes
<code>imagen01.png</code>, <code>imagen02.png</code>, estaré seguro de que no habrá ningún
conflicto de nombres porque estos sólo tendrán sentido dentro de cada
artículo.
</p>

<p>
También ha cambiado, en que lanzo el servidor desde una consola
externa y la mantengo abierta:
</p>

<pre class="example">
notxor:~&gt; cd ~/public_html
notxor:~/public_html&gt; python http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080) ...
</pre>


<p>
Cuando hago cambios los subo al directorio <code>public_html</code> con el
comando <code>op/do-publication</code>, abro el navegador, o si lo tengo abierto,
refresco el contenido y así trabajo.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/linux/index.html">linux</a> <a href="/tags/web/index.html">web</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[linux]]></category>
  <category><![CDATA[web]]></category>
  <link>https://notxor.nueva-actitud.org/2017/11/03/montar-un-servidor-http-local-para-pruebas.html</link>
  <pubDate>Fri, 03 Nov 2017 00:25:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Viaje a una isla imaginaria]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-11-02</div>

<figure id="orga411246">
<img src="./imagen/captura-isla.png" alt="captura-isla.png">

<figcaption><span class="figure-number">Figure 1: </span>Captura del juego en su estado actual.</figcaption>
</figure>

<p>
Bueno, pues seguimos con el proyecto de mezclar <i>aventuras
conversacionales</i> y 3D. Somos así de lanzados o <i>inconscientes</i>, según
se mire. Será una aventura corta, porque no podemos realizar un
escenario infinito. Por eso hemos elegido una isla, (casi) todo
sucederá en ella.
</p>

<p>
No quiero contar más para no hacer <i>spoilers</i>, como lo llaman los
modernos, que parece que ahora si no está en inglés ya no mola la
expresión. Pero en mis tiempos nos referíamos a los <i>spoilers</i> como
«destripar la cosa» (destripar el final de la película, destripar el
juego, destripar la novela...). Y hablando de <i>destripar</i>: antes de
escribir el guión casi definitivo estoy escribiendo un relato en
<i>primera persona</i> contando toda la aventura. No sé si alguien lo
querrá leer antes, por aquello de que puede contener varios
<i>destripamientos</i> de puzles y situaciones que recreará el juego, pero
en todo caso, prometo ponerlo por aquí (o por lo menos, enlazarlo)
para los curiosos a los que les dé lo mismo el <i>destripamiento</i>.
</p>

<p>
Ya sé que este post es corto, pero sólo tenía tres objetivos:
</p>

<ol class="org-ol">
<li>Automotivarme. Esta tarde tenía que hacer más cosas en el
proyecto. Modelar alguna de las zonas e ir terminando
otras. Modelar árboles y plantas... Pero por un motivo u otro no he
podido, cuando me concentraba me han interrumpido (no hay nada como
una suegra para hacer eso) y ahora que podría no me concentro.</li>
<li>Enseñar lo que se está haciendo... bueno, con la esperanza de que
alguien conocido te dé una palmadita en la espalda. Aunque en
realidad estoy casi convencido de que este blog no lo lee nadie (o
casi nadie, «...que no es lo mismo pero es igual»). Sirva también
para afirmar que es un proyecto <i>en marcha</i> y que se hacen cosas en
él casi todos los días. Pero según avanza aparecen más y más
requisitos, detalles y <i>pichorros</i> en general que hace que cada vez
parezca que el fin está más lejos. Cada vez que lo abro me gusta y
me convence más.</li>
<li>Escribir un post nuevo con el nuevo sistema de blog que he
adoptado. Poner imágenes (bueno, imagen) y ver si me encuentro
cómodo con el git, el emacs y demás yerbas.</li>
</ol>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/juegos/index.html">juegos</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[juegos]]></category>
  <link>https://notxor.nueva-actitud.org/2017/11/02/viaje-a-una-isla-imaginaria.html</link>
  <pubDate>Thu, 02 Nov 2017 22:39:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Esto es un desastre]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-10-30</div>
<div id="outline-container-org89dc205" class="outline-2">
<h2 id="org89dc205">Empezamos con decepción</h2>
<div class="outline-text-2" id="text-org89dc205">
<p>
Esto es un desastre. Mi blog se ha ido por el sumidero... bueno eso es
una exageración, pero casi.
</p>

<p>
Tuve un problema con el ordenador. Casualidades de la vida, a la
batería le dio por fallar en medio de una actualización del sistema y
todo se quedó <i>negro</i>. Pude llegar a abrir una consola y ver qué podía
haber pasado. La conclusión después de darle varias vueltas fue que la
instalación quedó a medias y seguramente habría que reiniciarla.
</p>

<p>
Mi primera intención fue hacer una actualización total:
</p>

<div class="org-src-container">
<pre class="src src-shell">sudo zypper dup --no-allow-vendor-change
</pre>
</div>

<p>
Lo más seguro es que todo hubiera funcionado de nuevo sin más problema
que tener un portátil sin batería y estar obligado a tenerlo enchufado
siempre. Sin embargo, yo <i>que soy muy listo</i>, decidí hacer otra cosa:
Instalar de cero <i>OpenSuse Tumbreweed</i>, ajustando algunos parámetros
de la anterior instalación --hecha sobre una previa de no me acuerdo
qué <i>distro</i>-- que no terminaban de gustarme, como la estructura de
las particiones en disco.
</p>

<p>
Me puse a ello, sabiendo que tenía copia de seguridad de todos mis
datos y no pasaba nada, porque lo demás son aplicaciones que funcionan
sobre los datos.
</p>

<p>
El error que me daba <i>pelican</i> era que había ficheros en las fuentes
que no era correcto y no generaba los <code>html</code> como debería. Revisé
todos los ficheros y todos estaban en correcto <i>markdown</i>. Es más,
hasta el día anterior los había estado procesando sin
problema. Después de muchas pruebas y desesperación, instalando la
versión para <i>python 2.x</i>, volviendo a la versión para <i>python 3.x</i>,
volviendo a probar, repasar los ficheros, quitando las carpetas
<i>estáticas</i>, volviéndolas a poner, repasando una y otra vez el fichero
de configuración <code>pelicanconf.py</code>... Al final desistí. Después de
haber intentado todo, incluso generar un blog nuevo y copiar los
archivos (para seguir recibiendo el mismo error), desistí y busqué
alternativas.
</p>

<p>
Las alternativas que encontré en los repositorios de OpenSuse, a parte
de <i>pelican</i>, eran <i>jekyll</i> y <i>nikola</i>. Probé los dos. No sé si fue
por falta de paciencia a esas alturas; por falta de documentación, o
quizá mi torpeza habitual, el caso es que fui incapaz de iniciar
ningún proyecto de los dos.
</p>
</div>
</div>
<div id="outline-container-orgc785f4f" class="outline-2">
<h2 id="orgc785f4f">Emacs al rescate: probando <code>org-page</code></h2>
<div class="outline-text-2" id="text-orgc785f4f">
<p>
Poco después recordé haber mirado por encima alguna vez la posibilidad
de hacer el blog única y exclusivamente con <i>emacs</i> y tropecé con el
paquete <i>org-page</i>. Por probar no perdía nada.
</p>

<p>
Y bueno, de momento parece funcionar correctamente. O al menos hace lo
que se espera de él mientras escribo esta primera entrada. Pero vamos
por partes a ver si me puedo explicar todo lo que me gustaría.
</p>
</div>
<div id="outline-container-orge0555d6" class="outline-3">
<h3 id="orge0555d6">Instalación de <code>org-page</code></h3>
<div class="outline-text-3" id="text-orge0555d6">
<p>
Esa es la parte más fácil: Primero accedí a <code>M-x list-packages</code> y
busqué por toda la lista paquetes de blog. Primero vi que había un
paquete prometedor que se llama <code>hexo-mode</code>, así que intenté a ver si
tenía suerte y podía instalar «hexo» un creador de sitios estáticos
hecho con <i>javascript</i>, pero tuve la misma suerte con el agravante de
que no está en los repositorios de OpenSuse y seguro que algo de
basurilla me ha quedado por el disco... pero bueno, hay que probarlo
todo (o casi todo).
</p>

<p>
Decía que una vez instalado el paquete había que configurarlo, así que
siguiendo las instrucciones del sitio de <code>org-page</code> añadí a mi fichero
<code>.emacs</code> las siguientes lineas.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">org-page</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/repository-directory <span style="color: #f1fa8c;">"~/proyectos/blog-org-page/"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/site-domain <span style="color: #f1fa8c;">"https://notxor.nueva-actitud.org"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/site-main-title <span style="color: #f1fa8c;">"Notxor tiene un blog"</span>)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> op/site-sub-title <span style="color: #f1fa8c;">"Defenestrando la vida"</span>)
</pre>
</div>

<p>
Además, se puede cambiar la apariencia con distintos <code>themes</code> que
proporcionan los <code>css</code> correspondientes... de momento no he hecho
modificaciones a la apariencia más allá elegir uno de ellos. Para
cambiar de tema para la visualización se utiliza la variable
<code>op/theme</code>. De momento estoy utilizando el tema que elige por defecto
cuando no le dices ninguno (<code>mdo</code>). Las opciones para elegir son:
<code>emacs_love</code>, <code>kactus</code>, <code>kd_mdo</code>, <code>mdo</code>, <code>phaer</code> y <code>wy</code>
</p>

<p>
De todas formas, después de haberlas visto todas, me ha quedado claro
que ningún diseñador gráfico le ha echado un ojo a este paquete.
</p>
</div>
</div>
<div id="outline-container-org40db57f" class="outline-3">
<h3 id="org40db57f">Primeros problemas, apareció <code>git</code></h3>
<div class="outline-text-3" id="text-org40db57f">
<p>
La gestión de todo el blog lo lleva <code>org-page</code> acoplándose sobre
<code>git</code>... y <code>git</code> es una de mis bestias negras. Tengo una tendencia,
casi <i>enfermiza</i> diría yo, a cagarla con <code>git</code>, meter la pata y
cargarme los repositorios. Aquel de vosotros que lea esto que haya
trabajado conmigo en algún proyecto utilizando <code>git</code> daréis fe de mi
torpeza con esa herramienta. Espero que el uso extensivo de esta
herramienta para el blog consiga que por fin me aclare con esta
maravilla y comience a entenderla poco a poco.
</p>

<p>
<code>org-page</code> utiliza dos ramas, los ficheros <code>.org</code> las guarda por
defecto en la rama <code>source</code> y los html generados en la
<code>master</code>. Pero otra vez vamos por partes. Primero hay que crear un
repositorio y mi costumbre de crearlo en la nube tiene sus
peculiaridades:
</p>
</div>
<div id="outline-container-org2e5149d" class="outline-4">
<h4 id="org2e5149d">Crear repositorio en <code>Nextcloud</code></h4>
<div class="outline-text-4" id="text-org2e5149d">
<p>
Tengo una nube particular que la uso para mis cosas y para tener,
básicamente, sincronizadas todas las cosas con las que trabajo de
forma normal, en varios ordenadores, en varios aparatos (teléfono
móvil, <i>tablet</i>). Así que el <i>origen</i> del blog lo he creado en él.
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #8be9fd; font-style: italic;">cd</span> nube
mkdir blog-org-page.git
<span style="color: #8be9fd; font-style: italic;">cd</span> blog-org-page.git
git init --bare
</pre>
</div>

<p>
Por lo que sé, la opción <code>bare</code> genera un repositorio que contiene
toda la información pero no los ficheros para modificarla, es decir,
actuará de «repositorio remoto» del que descargar información y al que
subir cambios. Después hay que crear el «repositorio local»
</p>

<div class="org-src-container">
<pre class="src src-shell"><span style="color: #8be9fd; font-style: italic;">cd</span> ~/proyectos
git clone ~/nube/blog-org-page.git
</pre>
</div>

<p>
Con esto nos crea, después de avisarnos de que hemos «clonado» un
repositorio vacío, un directorio que se llama «blog-org-page». Éste es
el directorio que debemos establecer en la variable
<code>op/repository-directory</code> como vimos antes.
</p>

<p>
Ahora necesitamos una rama que se llame <code>source</code>... aunque bueno, la
podemos llamar como queramos y luego se puede configurar en las
opciones. Sin embargo, para no liarme he llamado a esa rama como dice
la documentación.
</p>

<div class="org-src-container">
<pre class="src src-shell">git branch source
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-org21d04ba" class="outline-3">
<h3 id="org21d04ba">Creando el esqueleto del blog y comenzando a escribir</h3>
<div class="outline-text-3" id="text-org21d04ba">
<p>
Una vez tenemos creado el repositorio hay que crear el esqueleto del
blog. Algo tan sencillo como hacer los siguientes pasos:
</p>

<ol class="org-ol">
<li><p>
Asegurarnos de que estamos en la rama <code>source</code>, fuera de emacs
podemos llamar al comando:
</p>

<div class="org-src-container">
<pre class="src src-shell">git checkout source
</pre>
</div>

<p>
Si tenemos instalado en <i>emacs</i> <code>magit</code> también podemos hacer sin
salirnos de nuestro editor <code>M-x magit-checkout</code> y seleccionar la
rama <code>source</code>.
</p></li>

<li>Generar el esqueleto con el comando correspondiente de <code>org-page</code>:
<code>M-x op/new-repository</code>.</li>
</ol>

<p>
Si vamos al directorio del proyecto, veremos que nos ha creado un
directorio llamado <code>blog</code> y los ficheros <code>README</code>, <code>about.org</code> e
<code>index.org</code>... Y ya lo tenemos todo listo para comenzar.
</p>

<p>
Esta primera entrada la he creado en el dentro del directorio <code>blog</code>
con el nombre de fichero <code>inicio-nuevo-blog.org</code>... Bueno, en realidad
no lo he creado a mano. En realidad lo que hice fue abrir <i>emacs</i> y
lanzar <code>M-x op/new-post</code> y contestar a las preguntas que hace. Eso ya
genera la cabecera que tiene la siguiente pinta:
</p>

<div class="org-src-container">
<pre class="src src-org-mode">#+TITLE:       Esto es un desastre
#+AUTHOR:      Notxor
#+EMAIL:       notxor «en» nueva-actitud «punto» org
#+DATE:        2017-10-30 lun
#+URI:         /blog/%y/%m/%d/esto-es-un-desastre
#+KEYWORDS:    varios
#+TAGS:        varios, blog
#+LANGUAGE:    es
#+OPTIONS:     H:3 num:nil toc:nil \n:nil ::t |:t ^:nil -:nil f:t *:t &lt;:t
#+DESCRIPTION: Artículo inicial del nuevo blog
</pre>
</div>
</div>
</div>
<div id="outline-container-org5310a8c" class="outline-3">
<h3 id="org5310a8c">Publicando lo hecho</h3>
<div class="outline-text-3" id="text-org5310a8c">
<p>
Una vez de haber escrito todo este chorizo (bueno, en realidad lo hice
de varias veces y probando que funcionaba todo), guardas tus cambios y
tienes que generar el blog. He ido haciendo cambios y subiéndolos poco
a poco. ¿Cómo? poco a poco y empezando con <code>git</code>:
</p>

<p>
Por ejemplo, para subir los cambios en el los ficheros que crea por
defecto <code>about.org</code> e <code>index.org</code>. Los he modificado y subido de la
siguiente manera:
</p>

<div class="org-src-container">
<pre class="src src-shell">git add about.org index.org
git commit -m <span style="color: #f1fa8c;">"Establecer los estados iniciales del blog."</span>
git push
</pre>
</div>

<p>
Por separado subiré el primer post de este blog con comandos similares
a lo anterior, por lo que no voy repetir ese proceso. Pero además,
teniendo todos los cambios guardados y seguros en el repositorio, el
siguiente paso es <i>publicar</i> lo hecho. Lo que se hace es <code>M-x
op/do-publication</code> o si se quiere tener una visión previa de cómo está
quedando lo que vamos escribiendo se puede utilizar el comando
<code>M-x op/do-publication-and-preview-site</code>, que guarda los ficheros
generados en el directorio <code>~/.op-tmp/</code>.
</p>
</div>
</div>
</div>
<div id="outline-container-org56987d3" class="outline-2">
<h2 id="org56987d3">Conclusión</h2>
<div class="outline-text-2" id="text-org56987d3">
<p>
Y poco más puedo contar después de dos días de trastear con el
«chismático» éste. Sólo que de momento me permite volver a tener el
blog y aunque me lío con bastante frecuencia con el tema de <code>git</code>,
espero que esto me sirva para arrancar con ello.
</p>

<p>
Por otro lado un punto a favor es que utiliza directamente <code>org-mode</code>,
no necesito convertir ni romper nada, ni insertar código <code>html</code> «a
pelo» como había que hacer con el <i>Markdown</i>.
</p>

<p>
Veremos si esto me hace escribir un poco más en mi blog.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/org-mode/index.html">org-mode</a> <a href="/tags/blog/index.html">blog</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[org-mode]]></category>
  <category><![CDATA[blog]]></category>
  <link>https://notxor.nueva-actitud.org/2017/10/30/esto-es-un-desastre.html</link>
  <pubDate>Mon, 30 Oct 2017 20:02:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Biografio de Santiago Ramón y Cajal]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-10-25</div>
<div id="outline-container-orgc1a985f" class="outline-2">
<h2 id="orgc1a985f">Santiago Ramón y Cajal</h2>
<div class="outline-text-2" id="text-orgc1a985f">
</div>
<div id="outline-container-org0cda365" class="outline-3">
<h3 id="org0cda365">Antaŭparolo</h3>
<div class="outline-text-3" id="text-org0cda365">
<p>
Kiam mi ricevis la taskon verki biografion de gravulo mi pensis fari
ĝin pri S-ro. Mariano Yela Granizo, eminenta hispana psikologo, kiu
estis mia profesoro pri <i>Teorio de Testoj</i>. Poste, mi memoris la
instrukcion pri <i>konata gravulo</i>. Tiel, kvankam mi bone konas la
eminentulon S-ro. Mariano, mi pensis ke la cetera klaso kaj nia
instruisto, eble ne sciis eĉ lian ekzistadon.
</p>

<p>
Finfine, mi elektis alian eminentulon, tiu aragona kaj fama homo kaj
pro tio mi pensas, li povas esti ripetota de alia kamarado. Por paroli
de S-ro. Ramón, mi faros tion precipe de la vidpunkto de la psikologio
kaj de lia scienca laboro.
</p>
</div>
</div>
<div id="outline-container-org59dd7d5" class="outline-3">
<h3 id="org59dd7d5">Biografio</h3>
<div class="outline-text-3" id="text-org59dd7d5">
<p>
S-ro. Santiago Ramón y Cajal naskiĝis en la unua de majo de 1852 en
<i>Petilla de Aragón</i>, tiu estas navara enklavo en la provinco de
Zaragozo. Sed ambaŭ gepatroj alvenis de <i>Larrés</i>, Osko. De la infaneco
li montris korinklinon por la belartoj, precipe por la desegno, kiun
li bone uzis por sia tuta scienca laboro.
</p>

<p>
Li sukcesis siajn studojn pri medicino je la jaro 1873 kaj li iris al
militservo, kie proponis sin al laborkonkurso al Milita Sana Korpo,
akiranta la 6-a numeron. Kun la rango de <i>Dua Kuracisto</i>
(t.e. leŭtenanto) li estis sendita al Regimento <i>Burgos</i>, lokita en
Ilerdo. Je 1874 li iris, kun la rango de Kapitano, al Havano. Tie la
30-an de majo de 1875 la armeo deklaris lin «senutiligita en
kampanjo». Denove en Hispanio, la flegadoj, kiujn li ricevis de sia
patrino kaj siaj, fratinoj resanigis lin kaj li aplikis siajn
klopodojn al la reserĉado kaj la instruado.
</p>

<p>
Li geedziĝis kun Dña. Silveria Fañanás García la 19-an de julio
de 1879. Ili havis sep gefilojn: Santiago, Felina (Fe), Pabla Vicenta,
Jorge, Enriqueta, Pilar kaj Luis.
</p>

<p>
Je 1882 li gajnis la katedron de Priskriba Anatomio en la Valencia
Universitato. Tie li ankaŭ kreis la <i>komitaton por la reserĉado de la
homa penso</i>. Tiu komitato komencis siajn studojn kaj baldaŭ la
onidiroj pri la <i>mirakloj</i>, kiujn ili faris, disvastiĝis tra la tuta
Hispanio kaj la <i>svarmo de nestabiluloj kaj eĉ de «ligindaj
frenezuloj»</i> devigis Ramón y Cajal fermi tiun laboron, kiun ili faris
senkoste. Ili uzis la hipnoton kiel ilon por sia laboro, kaj ankaŭ por
malaperigi la dolorojn de la akuŝo. Tion li praktikis kun sia propra
edzino kun tre bonaj rezultoj.
</p>

<p>
Je 1888 li trovis la konekton inter la diversaj nervaj ĉeloj. Lia
teorio estis akceptita je la 1889-a en la Kongreso de la Germana
Anatomia Socio, en Berlino; la bazo por akiri la Nobelan Premion
je 1906. Li ricevis multajn aliajn premiojn kaj lia verkado estis tre
ampleksa por detali ĉi tie. Sed mi volas mencii la mallongan eseon
<i>Psikologio de D. Kiĥoto kaj la donkiĥotismo</i>, pro ĝia implico kun la
psikologio.
</p>

<p>
Li mortis je la 17-a de oktobro de 1934. (Pace ripozu! Kaj li atendos
nin multaj jaroj).
</p>
</div>
</div>
<div id="outline-container-org7af60c2" class="outline-3">
<h3 id="org7af60c2">Bibliografio</h3>
<div class="outline-text-3" id="text-org7af60c2">
<ul class="org-ul">
<li><a href="https://es.wikipedia.org/wiki/Santiago_Ram%C3%B3n_y_Cajal">Artikolo pri Santiago Ramón y Cajal. <i>Hispana Vikipedio</i>.</a></li>

<li>Albarracín, A. (1987). «El Dr. Simarro y la escuela histológica
española» <i>Investigaciones Psicológicas: orígenes de la Psicología
científica en España: El Dr. Simarro</i> (coord. J.J. Campos y
R. Llavona).</li>

<li>Ramón y Cajal, S. (1889). «Dolores del parto considerablemente
atenuados por la sugestión hipnótica». <i>Gaceta Médica Catalana</i>, XII,
292, 485-486.</li>

<li>Ramón y Cajal, S. (1923), <i>Recuerdos de mi vida, 3a ed.</i>, Madrid, p
192 (citado en Albarracín, 1987).</li>
</ul>
</div>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/varios/index.html">varios</a> <a href="/tags/esperanto/index.html">esperanto</a> ]]></description>
  <category><![CDATA[varios]]></category>
  <category><![CDATA[esperanto]]></category>
  <link>https://notxor.nueva-actitud.org/2017/10/25/biografio-de-santiago-ramon-y-cajal.html</link>
  <pubDate>Wed, 25 Oct 2017 00:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Creí haber terminado con el MiniMult]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-03-02</div>
<p>
Hace unos días creí haber terminado el experimento con <i>Emacs</i>, la
programación con <i>Lisp</i> (concretamente <i>elisp</i>), el <i>MiniMult</i> y todas
esas cosas sobre las que hice una serie días atrás. Sin embargo, me
surgió una pregunta que necesitaba contestar: ¿Todo ese trabajo
servirá para <i>android</i>?
</p>

<p>
Pues tenía que probar y aquí van mis experimentos.
</p>
<div id="outline-container-org24e17ae" class="outline-2">
<h2 id="org24e17ae">Emacs en la tablet</h2>
<div class="outline-text-2" id="text-org24e17ae">
<p>
Tengo una <i>tablet</i> muy maja. Barata, que uso con una frecuencia
relativa porque para conectarse a internet necesita siempre algún
<i>wifi</i> y sólo me fío del de casa. El primer paso era tener un <i>Emacs</i>
en la <i>tablet</i>.
</p>

<p>
En los repositorios de la <i>Gran G</i> existe una <i>app</i> de <i>Emacs</i>, pero
en mi <i>tablet</i> no funciona. Da un error y ni siquiera arranca. Así que
aparqué el tema durante unos días.
</p>

<p>
Sin embargo, en <a href="https://f-droid.org">los repositorios de f-droid</a> encontré una aplicación
que en principio no relacioné con el tema y que usaba como <i>nostalgia
linuxera</i>: <a href="https://termux.com/">termux</a>. Es una aplicación de terminal clásico, con <i>bash</i> y
otras características.  Tiene varios paquetes interesantes, como mi
calculadora favorita (<i>bc</i>) o la aplicación de redes <i>nmap</i>; lenguajes
de programación interpretados: Python, Ruby, Lua, erlang...
</p>

<p>
Haciendo un repaso de los paquetes que se pueden instalar desde ese
terminal encontré un paquete <i>emacs</i> que instalé con el comando:
</p>

<div class="org-src-container">
<pre class="src src-shell">apt install emacs
</pre>
</div>

<p>
Después adapté el fichero <code>.emacs</code> que utilizo normalmente para
despojarlo de todos los paquetes que carga y que en la <i>tablet</i> no
tienen sentido.
</p>
</div>
</div>
<div id="outline-container-org93b2605" class="outline-2">
<h2 id="org93b2605">El MiniMult en la tablet</h2>
<div class="outline-text-2" id="text-org93b2605">
<p>
El siguiente paso era pasar mi <i>script</i> a la tablet y hacer las
pruebas.  En el siguiente <i>pantallazo</i> se puede ver en la ventana
derecha el código de <code>minimult.el</code> cargado. En la ventana izquierda
está funcionando <code>minimul-pasar-prueba</code>. La ventana inferior es un
teclado <a href="http://www.exideas.com/ME/index.php">MessagEase</a>, que es un teclado más pensado para utilizar con
móviles a una mano y que con gestos permite utilizar combinaciones de
<i>Ctrl</i> y <i>Alt</i>.
</p>


<figure id="org4834c78">
<img src="./imagen/2017-03-02-minimult-tablet.png" alt="2017-03-02-minimult-tablet.png">

</figure>

<p>
¡Bien! Parece que todo funciona. Se pasa la prueba correctamente,
guarda las contestaciones e incluso corrige las puntuaciones. Sin
embargo, lanzado el comando <code>minimult-ver-grafica</code> la ventana que abre
es sólo de texto, como se ven en la siguiente imagen.
</p>


<figure id="org3d0e7f2">
<img src="./imagen/2017-03-02-corregido-tablet.png" alt="2017-03-02-corregido-tablet.png">

</figure>

<p>
Como podemos ver, <i>Emacs</i>, genera y abre el fichero <code>.svg</code> con el
gráfico de perfil. Sin embargo, no lo visualiza. Lo que hice fue
buscar en <a href="https://f-droid.org">los repositorios de f-droid</a> alguna aplicación que pudiera
visualizar ficheros SVG y encontré <a href="https://f-droid.org/repository/browse/?fdfilter=svg&amp;fdid=biz.codefuture.svgviewer">un visor de gráficos vectoriales</a>
bastante sencillo pero funcional, como se puede ver en la imagen.
</p>


<figure id="org16362b7">
<img src="./imagen/2017-03-02-minimult-grafico-tablet.png" alt="2017-03-02-minimult-grafico-tablet.png">

</figure>
</div>
</div>
<div id="outline-container-org03d1786" class="outline-2">
<h2 id="org03d1786">Conclusiones</h2>
<div class="outline-text-2" id="text-org03d1786">
<p>
Si la pregunta genérica es si funciona en <i>android</i>, tanto <i>Emacs</i>
como las funciones programadas para corregir el <i>MiniMult</i> la
respuesta es «Sí, funciona». Pero tendríamos que plantearnos también
si es cómodo. Y en ese caso la respuesta es que «No, no es cómodo».
</p>

<p>
Durante todas las pruebas he echado de menos un teclado normal y un
sistema <i>GNU/linux</i> en lugar de un teclado táctil de pantalla y un
sistema <i>android/linux</i>.
</p>

<p>
Se podría utilizar un teclado externo, de esos que se conectan por
<i>bluetooth</i>, por ejemplo. Quizá así sea más cómodo de utilizar
<i>Emacs</i>.  Desde luego, con el teclado por pantalla no se escribe de
forma cómoda, ni código ni ningún texto largo. Se echan de menos
teclas cuando tienes que dar dos pulsaciones para conseguir un <code>Ctrl</code>
o un <code>Alt</code>.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/programación/index.html">programación</a> <a href="/tags/tests/index.html">tests</a> <a href="/tags/psicología/index.html">psicología</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[programación]]></category>
  <category><![CDATA[tests]]></category>
  <category><![CDATA[psicología]]></category>
  <link>https://notxor.nueva-actitud.org/2017/03/02/crei-haber-terminado-con-el-minimult.html</link>
  <pubDate>Thu, 02 Mar 2017 16:55:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Gráfico de perfil en el MiniMult]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-02-10</div>
<p>
El último paso de la corrección del <i>test</i>:
</p>


<figure id="org918f41a">
<img src="./imagen/MiniMult-Grafico.png" alt="MiniMult-Grafico.png">

</figure>

<p>
Como se puede ver, el experimento ha terminado. <i>Emacs</i> aún siendo un
editor de texto tiene ciertas capacidades gráficas cuando no lo lanzamos
para la consola.
</p>
<div id="outline-container-orgf8969e2" class="outline-2">
<h2 id="orgf8969e2">El gráfico</h2>
<div class="outline-text-2" id="text-orgf8969e2">
<p>
En el pasado «articulillo» un poco de las capacidades gráficas de
<i>Emacs</i> aunque me guardé la parte sobre SVG para hablarlo cuando
terminara el experimento con la generación del gráfico final. Cuando
pensé originalmente esta parte utilizaba siempre <i>Emacs</i> en consola con
la opción <code>-nw</code>, y no me percaté de esas capacidades hasta más
adelante... una grata sorpresa.
</p>

<p>
Mi primera idea fue que el programa lo dibujara todo, pero me pareció un
poco chapuza reiterativa y opté por coger un gráfico SVG y ponerle en su
interior algo que permitiera dibujar la línea de forma automática en
base a los datos. A base de utilizarlo sólo para texto y en consola
desconocía las capacidades gráficas de <i>Emacs</i> y había pensado que al
fin y al cabo un SVG es un archivo XML. Pensé en lo sencillo que sería
abrir un fichero de texto (XML en este caso) modificar los valores
oportunos y guardarlo para abrirlo con otra aplicación o visor. Se
pondrían etiquetas del estilo <code>{{etiqueta}}</code> en los lugares adecuados y
con una simple regla de tres se calcula la coordenada <i>Y</i> de cada punto
en la línea.
</p>

<p>
Sin embargo, he tenido algunos problemas para hacerlo. Las coordenadas
de los puntos y los ejes me han obligado a repasar varias veces los
algoritmos de cálculo y cómo procesarlos. En este caso no me ha servido
la socorrida regla de tres que esperaba hacer, ha sido todo algo más
complejo aunque no lo suficiente para desanimarme.
</p>

<p>
Os cuento los pasos uno por uno:
</p>
</div>
<div id="outline-container-org2e6cd85" class="outline-3">
<h3 id="org2e6cd85">Cargando datos</h3>
<div class="outline-text-3" id="text-org2e6cd85">
<p>
La primera parte de la función se ocupa de cargar datos y preparar
variables que luego se utilizarán en los cálculos. Carga la plantilla en
un <i>buffer</i> y lo renombra creando un fichero nuevo.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">minimult-ver-grafica</span> ()
  <span style="color: #6272a4;">"Dibuja la gr&#225;fica del MiniMult."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Guardamos el estado del buffer actual
</span>  (<span style="color: #ff79c6; font-weight: bold;">save-excursion</span>
    (<span style="color: #ff79c6; font-weight: bold;">let</span> ((nombre (concat <span style="color: #f1fa8c;">"MiniMult-"</span>
              (org-entry-get (point) <span style="color: #f1fa8c;">"Nombre"</span> t) <span style="color: #f1fa8c;">".svg"</span>))
      (sexo (org-entry-get (point) <span style="color: #f1fa8c;">"Sexo"</span> t))
      (L    (org-entry-get (point)    <span style="color: #f1fa8c;">"L"</span> t))
      (F    (org-entry-get (point)    <span style="color: #f1fa8c;">"F"</span> t))
      (K    (org-entry-get (point)    <span style="color: #f1fa8c;">"K"</span> t))
      (Hs   (org-entry-get (point)   <span style="color: #f1fa8c;">"Hs"</span> t))
      (D    (org-entry-get (point)    <span style="color: #f1fa8c;">"D"</span> t))
      (Hy   (org-entry-get (point)   <span style="color: #f1fa8c;">"Hy"</span> t))
      (Pd   (org-entry-get (point)   <span style="color: #f1fa8c;">"Pd"</span> t))
      (Pa   (org-entry-get (point)   <span style="color: #f1fa8c;">"Pa"</span> t))
      (Pt   (org-entry-get (point)   <span style="color: #f1fa8c;">"Pt"</span> t))
      (Sc   (org-entry-get (point)   <span style="color: #f1fa8c;">"Sc"</span> t))
      (Ma   (org-entry-get (point)   <span style="color: #f1fa8c;">"Ma"</span> t))
      (Si   (org-entry-get (point)   <span style="color: #f1fa8c;">"Si"</span> t))
      (delta-control 0)
      (valor-antes   0)
      (buffer (find-file-noselect <span style="color: #f1fa8c;">"~/proyectos/minimult/plantilla.svg"</span>)))
      (set-buffer buffer)
      <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Activamos escritura en el buffer
</span>      (<span style="color: #ff79c6; font-weight: bold;">setq</span> inhibit-read-only t)
      <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Guardar la plantilla con otro nombre
</span>      (set-visited-file-name nombre)
      <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Ir al principio del buffer
</span>      (goto-char (point-min))
      <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Hacer las sustituciones
</span>      (<span style="color: #ff79c6; font-weight: bold;">if</span> (search-forward <span style="color: #f1fa8c;">"{{sexo}}"</span>)
      (replace-match sexo))
      (<span style="color: #ff79c6; font-weight: bold;">if</span> (search-forward <span style="color: #f1fa8c;">"{{L}}"</span>)
          (replace-match L))

      ...

      (<span style="color: #ff79c6; font-weight: bold;">if</span> (search-forward <span style="color: #f1fa8c;">"{{Si}}"</span>)
          (replace-match Si))
      ...)
</pre>
</div>

<p>
Lo primero que hace la función es guardar la posición del punto en el
fichero <i>org</i> que estamos trabajando con <code>save-excursion</code> por si se
mueve. Luego, en el <code>let</code> se cargan las variables obteniéndolas de las
propiedades del <i>org</i>. También carga un fichero de plantilla desde el
disco. Resumo la parte de reemplazar los números que aparecen abajo en
el gráfico con los valores de las escalas. La etiqueta <code>{{L}}</code> se
sustituye con el valor de la variable <code>L</code> que hemos cargado en el <code>let</code>;
y se hace de forma directa porque <code>L</code> es un <code>string</code>.
</p>
</div>
</div>
<div id="outline-container-orgc11ee82" class="outline-3">
<h3 id="orgc11ee82">Coordenadas <i>Y</i> de los puntos del perfil</h3>
<div class="outline-text-3" id="text-orgc11ee82">
<p>
La conversión del valor que cada escala ha alcanzado en las
coordenadas era ─en principio─ una aplicación más de la fórmula para
ajustar intervalos que ya vimos en <a href="./minimult-corregido.html">otro artículo anterior</a>. Pero puede
parecer más complicado porque el eje <i>Y</i> interno del SVG gráfico crece
hacia abajo, mientras que los valores representados en él crecen hacia
arriba. Es decir, están invertidos uno respecto al otro.
</p>

<p>
Por ejemplo, la cota de la puntuación 20 de una escala estará en el
495.5 y la cota de la puntuación 120 en el 31.5. Aún así se podría haber
utilizado la misma función para hacer los cálculo aunque hubiéramos
pasado al parámetro <code>min-t</code> el valor 495.5 y al parámetro <code>max-t</code> el
valor 31.5.
</p>

<p>
Para ahorrar tiempo de cálculo y como todos los datos son siempre los
mismos decidí resumir la función a otra más sencilla:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">minimult-calcular-perfil</span> (puntos)
  <span style="color: #6272a4;">"Calcula la posici&#243;n en el gr&#225;fico de una puntuaci&#243;n."</span>
  (+ 495.5 (* -4.641 (- puntos 20.0))))
</pre>
</div>

<p>
Después de devolver el punto al principio del <i>buffer</i> para realizar una
nueva búsqueda se realizan los cálculos y sustituciones. Pongo sólo los
de las tres escalas de control para no eternizarme con un churro de
código, pero con ello puedo explicar uno de los muchos fiascos que me he
llevado haciendo el gráfico.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Ir al principio del buffer
</span>(goto-char (point-min))
<span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Calcular la posicion de las escalas de control
</span>(<span style="color: #ff79c6; font-weight: bold;">setq</span> delta-control (minimult-calcular-perfil (string-to-number L)))
(<span style="color: #ff79c6; font-weight: bold;">if</span> (search-forward <span style="color: #f1fa8c;">"{{dL}}"</span>)
    (replace-match (number-to-string delta-control)))
(<span style="color: #ff79c6; font-weight: bold;">setq</span> valor-antes delta-control)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> delta-control (minimult-calcular-perfil (string-to-number F)))
(<span style="color: #ff79c6; font-weight: bold;">if</span> (search-forward <span style="color: #f1fa8c;">"{{dF}}"</span>)
    (replace-match (number-to-string (- delta-control valor-antes))))
(<span style="color: #ff79c6; font-weight: bold;">setq</span> valor-antes delta-control)
(<span style="color: #ff79c6; font-weight: bold;">setq</span> delta-control (minimult-calcular-perfil (string-to-number K)))
(<span style="color: #ff79c6; font-weight: bold;">if</span> (search-forward <span style="color: #f1fa8c;">"{{dK}}"</span>)
    (replace-match (number-to-string (- delta-control valor-antes))))
</pre>
</div>

<p>
Como se puede apreciar, los cálculos que se realizan para unas escalas
no sirven para otras. Eso depende de si el punto que queremos calcular
es el que inicia la línea o es una continuación. <i>¿Por qué?</i> Pues porque
los valores de esos puntos no son absolutos sino relativos. El primer
punto de la línea (y hay tres que debemos calcular en el gráfico) tiene
un valor absoluto. Por eso, una vez calculada su coordenada <i>Y</i>
guardándola en la variable <code>delta-control</code> la reemplazamos directamente.
Bueno directamente tampoco, recordemos que los datos que se cargaban
desde el <i>org</i> son cadenas y necesitamos convertirlos en números para
operar con ellos, para eso utilizo <code>string-to-number</code> y cuando los
queremos escribir tenemos que devolverlos como <code>number-to-string</code>.
</p>

<p>
Como decía, el primer punto de cada línea tiene unas coordenadas <code>(x,y)</code>
absolutas. El siguiente punto en la línea, sin embargo, se define
utilizando el anterior como si fuera el origen de las coordenadas. Esto
me obliga a calcular la posición de cada punto guardando el valor
anterior (<code>valor-antes</code>) para restarlo a la posición calculada en
<code>delta-control</code>. Este proceso se repite también para las otras dos
líneas. La idea de pasarle a una función una lista con los valores y que
los fuera calculando y sustituyendo se truncó y el código ha quedado
hecho un <i>chorizo</i> que necesita una refactorización de manera urgente.
</p>

<p>
La última chapuza es el refresco del <i>buffer</i> del SVG. Cuando cargo la
plantilla la imagen se dibuja sin las líneas del perfil y sin los textos
cambiados. He estado haciendo un búsqueda de cómo hacer un refresco
gráfico. Como no encontré nada lo que hago es un refresco a las bravas
(o a lo tonto)... llamo dos veces seguidas a <code>image-toggle-display</code> la
primera cambia el <i>buffer</i> a modo texto y la segunda lo devuelve a modo
gráfico y después cambio al <i>buffer</i> del gráfico en otra ventana:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Reseteamos el buffer pas&#225;ndolo a modo texto y de nuevo a gr&#225;fico
</span>(image-toggle-display)   <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">es un poco chapuza pero no encuentro
</span>(image-toggle-display)   <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">c&#243;mo hacer el refresco de otro modo
</span><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Mostramos el buffer en otra ventana
</span>(switch-to-buffer-other-window buffer)
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-orgc13ad49" class="outline-2">
<h2 id="orgc13ad49">Conclusiones</h2>
<div class="outline-text-2" id="text-orgc13ad49">
<p>
La verdad es que he estado aprendiendo mucho. El programa en sí es una
chapuza (siendo suave con la terminología), aunque funciona como versión
pre-pre-pre-alfa de lo que debería ser.
</p>

<p>
Acabo de decir que <i>funciona</i> pero no lo hará salvo en momentos
controlados. Porque no se ha hecho prácticamente ninguna comprobación
para que todo funcione correctamente. Por ejemplo, no se puede saber qué
ocurriría si se llamara a la función de corrección sin tener una
variable de respuestas completa. Tampoco se han tenido en cuenta los
límites de las escalas. ¿Qué ocurriría si llegara un valor por debajo
del mínimo calculado para una escala? ¿o por encima del máximo? Esto
último puede pasar en varias escalas que se ajustan mediante <i>K</i>. Se
puede dar el caso de una puntuación alta en la escala en cuestión se
junta con una puntuación alta en <i>K</i> y el valor puede sobrepasar el
límite máximo (vale, en la vida real sería un caso excepcional, pero
podría darse).
</p>

<p>
Seguramente, si empezara a hacerlo ahora, lo plantearía de otra manera.
<i>Lisp</i> es un lenguaje sencillo de entender: (casi) todo es una <i>lista</i>
encerrada entre paréntesis, <i>Lisp</i> intenta <i>evaluar</i> el primer elemento
de una lista con los demás como parámetros, a no ser que tenga una
comilla (<i>quote</i>) delante. Eso lo pillas en medio minuto pero luego la
forma de pensar los algoritmos es completamente distinta a los lenguajes
en los que me encuentro más cómodo. La POO debe de haber anquilosado mis
neuronas. Las ha dejado rígidas y <i>sin cintura</i> para flexibilizar mi
razonamiento al programar.
</p>

<p>
Pero creo que poco a poco me iré acostumbrando a los usos y costumbres
de <i>Lisp</i>. De hecho, me parece un lenguaje bonito e interesante. Si
reflexiono un poco sobre los lenguajes que más me gustan lo pondría en
segundo lugar, justo después de <i>smalltalk</i>. Los dos primeros de la
lista son pues lenguajes <i>muy</i> «viejunos». No sé si será por la edad o
no, pero tienen <i>chispa</i>. En <i>smalltalk</i> todo es un objeto y en <i>lisp</i>
todo es una lista y sobre ese supuesto se montan todo un sistema
completo sin necesitar una interminable lista de <i>palabras reservadas</i>
del lenguaje, sólo un supuesto y sus consecuencias lógicas.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/programación/index.html">programación</a> <a href="/tags/tests/index.html">tests</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[programación]]></category>
  <category><![CDATA[tests]]></category>
  <link>https://notxor.nueva-actitud.org/2017/02/10/gráfico-de-perfil-en-el-minimult.html</link>
  <pubDate>Fri, 10 Feb 2017 21:31:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[MiniMult corregido]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-02-05</div>
<p>
He estado estos días trabajando un poco en el tema de corregir el
<i>MiniMult</i> de forma automática con resultados irregulares. De momento me
encuentro con ese regustillo a <i>chapuza</i> cuando no haces las cosas como
piensas que se deberían hacer. Pero al final <i>funciona</i>, que era de
momento el objetivo. Me voy a explicar por partes, comenzando por el
final y luego dando saltos como es mi costumbre últimamente (es lo que
tiene este cerebro que me ha tocado).
</p>
<div id="outline-container-org3562aa8" class="outline-2">
<h2 id="org3562aa8">Funcionar, funciona</h2>
<div class="outline-text-2" id="text-org3562aa8">

<figure id="org5b48f92">
<img src="./imagen/MiniMultCorregido.png" alt="MiniMultCorregido.png">

</figure>

<p>
Como se puede ver en la imagen anterior el sistema devuelve las
puntuaciones T del <i>MiniMult</i> corregidas. Ahora explicaré cómo lo he ido
haciendo y las chapuzas que he tenido que hacer por el camino.
</p>
</div>
</div>
<div id="outline-container-org73cf7b8" class="outline-2">
<h2 id="org73cf7b8">Obtener las puntuaciones directas</h2>
<div class="outline-text-2" id="text-org73cf7b8">
<p>
Para obtener las puntuaciones directas lo que debemos hacer primero es
contar con unas plantillas que nos permitan saber si cada contestación
del sujeto puntúa en una determinada escala. Como ya hablé de cómo había
pensado guardarlas en formato de lista sólo voy a repasarlo un poco por
encima:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">minimult-plantilla</span>
  '(
    (<span style="color: #f1fa8c;">"L"</span>  11 <span style="color: #f1fa8c;">"F"</span> 1) ... (<span style="color: #f1fa8c;">"L"</span>  53 <span style="color: #f1fa8c;">"F"</span> 1)
    (<span style="color: #f1fa8c;">"F"</span>   9 <span style="color: #f1fa8c;">"V"</span> 1) ... (<span style="color: #f1fa8c;">"F"</span>  71 <span style="color: #f1fa8c;">"V"</span> 1)
    (<span style="color: #f1fa8c;">"K"</span>  11 <span style="color: #f1fa8c;">"F"</span> 1) ... (<span style="color: #f1fa8c;">"K"</span>  70 <span style="color: #f1fa8c;">"F"</span> 1)
    (<span style="color: #f1fa8c;">"Hs"</span>  1 <span style="color: #f1fa8c;">"F"</span> 1) ... (<span style="color: #f1fa8c;">"Hs"</span> 62 <span style="color: #f1fa8c;">"F"</span> 1)
    (<span style="color: #f1fa8c;">"D"</span>   1 <span style="color: #f1fa8c;">"F"</span> 1) ... (<span style="color: #f1fa8c;">"D"</span>  65 <span style="color: #f1fa8c;">"F"</span> 1)
    (<span style="color: #f1fa8c;">"Hy"</span>  1 <span style="color: #f1fa8c;">"F"</span> 1) ... (<span style="color: #f1fa8c;">"Hy"</span> 62 <span style="color: #f1fa8c;">"F"</span> 1)
    (<span style="color: #f1fa8c;">"Pd"</span>  3 <span style="color: #f1fa8c;">"F"</span> 1) ... (<span style="color: #f1fa8c;">"Pd"</span> 71 <span style="color: #f1fa8c;">"V"</span> 1)
    (<span style="color: #f1fa8c;">"Pa"</span>  5 <span style="color: #f1fa8c;">"V"</span> 1) ... (<span style="color: #f1fa8c;">"Pa"</span> 68 <span style="color: #f1fa8c;">"V"</span> 1)
    (<span style="color: #f1fa8c;">"Pt"</span>  2 <span style="color: #f1fa8c;">"F"</span> 1) ... (<span style="color: #f1fa8c;">"Pt"</span> 68 <span style="color: #f1fa8c;">"V"</span> 1)
    (<span style="color: #f1fa8c;">"Sc"</span>  3 <span style="color: #f1fa8c;">"F"</span> 1) ... (<span style="color: #f1fa8c;">"Sc"</span> 66 <span style="color: #f1fa8c;">"V"</span> 1)
    (<span style="color: #f1fa8c;">"Ma"</span>  4 <span style="color: #f1fa8c;">"V"</span> 1) ... (<span style="color: #f1fa8c;">"Ma"</span> 60 <span style="color: #f1fa8c;">"V"</span> 1)
    (<span style="color: #f1fa8c;">"Si"</span> 13 <span style="color: #f1fa8c;">"V"</span> 1) ... (<span style="color: #f1fa8c;">"Si"</span> 70 <span style="color: #f1fa8c;">"V"</span> 1)
    )
  <span style="color: #6272a4;">"Plantilla de correcci&#243;n con valores posicionales.
1. Nombre de escala
2. N&#250;mero de pregunta
3. Valor puntuable
4. Cantidad de puntos si coincide la respuestas con el valor puntuable."</span>)
</pre>
</div>

<p>
En el código de la definición de la variable <code>minimult-plantilla</code> he
puesto sólo la primera y la última de las respuestas de cada escala.
Ponerlo todo sería confuso y no aportaría nada. Para saber el resto
basta con repasar la serie sobre el <i>MiniMult</i> y se encontrará una tabla
con la plantilla. Luego el código que corrige el <i>test</i> recorrerá esta
variable de principio a fin comprobando y guardando las coincidencias
para obtener las puntuaciones directas.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Recorrer toda la plantilla en un bucle while
</span>(<span style="color: #ff79c6; font-weight: bold;">let</span> ((contador 0)
  (largo-plantilla (length minimult-plantilla))
  (escala <span style="color: #f1fa8c;">""</span>)
  (pregunta 0)
  (respuesta <span style="color: #f1fa8c;">"-"</span>)
  (valor 0)
  (elemento '()))
  (<span style="color: #ff79c6; font-weight: bold;">while</span> (&lt; contador largo-plantilla)
    <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Obtener la plantilla y sus valores
</span>    (<span style="color: #ff79c6; font-weight: bold;">setq</span> elemento (nth contador minimult-plantilla))
    (<span style="color: #ff79c6; font-weight: bold;">setq</span> escala (nth 0 elemento))
    (<span style="color: #ff79c6; font-weight: bold;">setq</span> pregunta (nth 1 elemento))
    (<span style="color: #ff79c6; font-weight: bold;">setq</span> respuesta (nth 2 elemento))
    (<span style="color: #ff79c6; font-weight: bold;">setq</span> valor (nth 3 elemento))
    <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Poner el contador de la escala a 0
</span>    (<span style="color: #ff79c6; font-weight: bold;">if</span> (null (lax-plist-get minimult-resultados escala))
       (<span style="color: #ff79c6; font-weight: bold;">setq</span> minimult-resultados (lax-plist-put minimult-resultados escala 0)))
    <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Sumar el VALOR a los resultados para ESCALA si procede
</span>    (<span style="color: #ff79c6; font-weight: bold;">if</span> (equal (substring minimult-respuestas (1- pregunta) pregunta) respuesta)
       (lax-plist-put minimult-resultados escala
           (+ (lax-plist-get minimult-resultados escala) valor)))
    <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Avanzar a la siguiente entrada de la plantilla
</span>    (<span style="color: #ff79c6; font-weight: bold;">setq</span> contador (1+ contador)))
  ...)
</pre>
</div>

<p>
Básicamente el bucle <code>while</code> recorre toda la plantilla, comprueba si hay
un valor para la <i>escala</i> en los resultados, comprueba si la respuesta
del sujeto en la posición que dice esa entrada de la plantilla coincide
con la plantilla y si es así, le suma el <code>valor</code> que dice la plantilla a
la <code>escala</code>. Todo lo guarda en una lista de propiedades (<code>plist</code>) que se
llama <code>minimult-resultados</code>.
</p>

<p>
Esta parte del código creo que fácilmente entendible por cualquiera que
lo lea y no le daré más vueltas.
</p>
</div>
</div>
<div id="outline-container-orgd7efbf4" class="outline-2">
<h2 id="orgd7efbf4">Convertir puntuaciones directas</h2>
<div class="outline-text-2" id="text-orgd7efbf4">
<p>
Uno de los problemas del <i>MiniMult</i> resulta de resumir el número de
preguntas que hay para cada escala. Eso hace que haya que convertir las
puntuaciones directas obtenidas en él, a las puntuaciones directas que
se hubieran obtenido en el MMPI-2 para poder continuar con la corrección
normal del <i>test</i>.
</p>

<p>
Cuando se corrige el <i>MiniMult</i> a mano, encontramos una tabla de
conversión entre puntuaciones. En lugar de utilizar esa tabla me he
decidido por hacer un cálculo. Sabiendo el máximo de puntos que se
pueden obtener en la escala reducida y en la escala completa se aplica
una sencilla fórmula:
</p>

<p>
Nf = Nt<sub>max</sub> × ( Nd /
Nd<sub>max</sub> )
</p>

<p>
donde la <i>Nf</i> es la nota estimada en el <i>test</i>,
<i>Nt<sub>max</sub></i> es la máxima nota que se podría
obtener en el <i>test</i>, <i>Nd</i> es la puntuación obtenida por el sujeto y
<i>Nd<sub>max</sub></i> la máxima que podría obtener en el
<i>MiniMult</i>. Los valores sobre los que se ha calculado la prueba (creo
que ya la he puesto otra vez por aquí) son los siguientes:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Escala</th>
<th scope="col" class="org-right">Nt<sub>max</sub></th>
<th scope="col" class="org-right">Nd<sub>max</sub></th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">L</td>
<td class="org-right">15</td>
<td class="org-right">4</td>
</tr>

<tr>
<td class="org-left">F</td>
<td class="org-right">60</td>
<td class="org-right">13</td>
</tr>

<tr>
<td class="org-left">K</td>
<td class="org-right">30</td>
<td class="org-right">16</td>
</tr>

<tr>
<td class="org-left">Hs</td>
<td class="org-right">32</td>
<td class="org-right">12</td>
</tr>

<tr>
<td class="org-left">D</td>
<td class="org-right">57</td>
<td class="org-right">19</td>
</tr>

<tr>
<td class="org-left">Hy</td>
<td class="org-right">60</td>
<td class="org-right">22</td>
</tr>

<tr>
<td class="org-left">Pd</td>
<td class="org-right">50</td>
<td class="org-right">18</td>
</tr>

<tr>
<td class="org-left">Pa</td>
<td class="org-right">40</td>
<td class="org-right">14</td>
</tr>

<tr>
<td class="org-left">Pt</td>
<td class="org-right">48</td>
<td class="org-right">15</td>
</tr>

<tr>
<td class="org-left">Sc</td>
<td class="org-right">78</td>
<td class="org-right">17</td>
</tr>

<tr>
<td class="org-left">Ma</td>
<td class="org-right">46</td>
<td class="org-right">11</td>
</tr>

<tr>
<td class="org-left">Si</td>
<td class="org-right">67</td>
<td class="org-right">9</td>
</tr>
</tbody>
</table>

<p>
Esta parte del código la he dividido en dos partes, una que aplica la
fórmula y otra que la va llamando para convertir cada puntuación.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">minimult-convertir-MMPI</span> (puntos mmpi minimult)
  <span style="color: #6272a4;">"Convierte PUNTOS a puntuaciones directas del MMPI-2."</span>
  (fround (* mmpi (/ puntos minimult))))

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">minimult-convertir-directas</span> ()
  <span style="color: #6272a4;">"Convierte las puntuaciones directas de las escalas."</span>
    (lax-plist-put minimult-resultados <span style="color: #f1fa8c;">"L"</span>
           (minimult-convertir-MMPI (lax-plist-get minimult-resultados <span style="color: #f1fa8c;">"L"</span>)
                               15.0 4.0))
    ...
           (minimult-convertir-MMPI (lax-plist-get minimult-resultados <span style="color: #f1fa8c;">"Si"</span>)
                               67.0 9.0)))
</pre>
</div>

<p>
Para convertir las puntuaciones directas hago una llamada para cada
escala. Me hubiera gustado hacer algo más presentable, como guardar las
puntuaciones en un <i>diccionario</i> pero me he encontrado con algunos
problemas y <i>bugs</i> por mis actuales carencias con <i>Lisp</i>. Al final opté
por lo más fácil, pero lo menos flexible y lo más chapucero.
</p>

<p>
Como se puede apreciar las llamadas las realizo añadiendo a los valores
una parte decimal. <i>Lisp</i> tiene por costumbre mantener el tipo de las
variables cuando realiza cálculos. Si le pasas a la división enteros
sólo devolverá la parte entera de la división, pero en este caso
necesitamos que realice los cálculos con decimales y luego redondee a
entero con <code>fround</code>.
</p>
</div>
</div>
<div id="outline-container-org25e048e" class="outline-2">
<h2 id="org25e048e">Ajustar las escalas con <i>K</i></h2>
<div class="outline-text-2" id="text-org25e048e">
<p>
Una vez obtenidas las puntuaciones directas <i>estimadas</i> se realiza el
<i>ajuste K</i> de las puntuaciones de las escalas que lo necesitan, que son
las siguientes:
</p>

<p>
Hs → 0.5 K<br>
Pd → 0.4 K<br>
Pt → 1 K<br>
Sc → 1 K
</p>

<p>
El código queda así:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">minimult-corregir-K</span> (factor-K)
  <span style="color: #6272a4;">"A&#241;ade factor de correcci&#243;n K a las escalas que lo necesitan."</span>
  (lax-plist-put minimult-resultados <span style="color: #f1fa8c;">"Hs"</span>
         (fround (+ (lax-plist-get minimult-resultados <span style="color: #f1fa8c;">"Hs"</span>)
                (* 0.5 factor-K))))
  (lax-plist-put minimult-resultados <span style="color: #f1fa8c;">"Pd"</span>
         (fround (+ (lax-plist-get minimult-resultados <span style="color: #f1fa8c;">"Pd"</span>)
                (* 0.4 factor-K))))
  (lax-plist-put minimult-resultados <span style="color: #f1fa8c;">"Pt"</span>
         (fround (+ (lax-plist-get minimult-resultados <span style="color: #f1fa8c;">"Pt"</span>)
                 factor-K)))
  (lax-plist-put minimult-resultados <span style="color: #f1fa8c;">"Sc"</span>
         (fround (+ (lax-plist-get minimult-resultados <span style="color: #f1fa8c;">"Sc"</span>)
                 factor-K))))
</pre>
</div>

<p>
La llamada a corregir las puntuaciones directas con el factor <i>K</i> se
realiza de la siguiente forma:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(minimult-corregir-K (lax-plist-get minimult-resultados <span style="color: #f1fa8c;">"K"</span>))
</pre>
</div>

<p>
Y con estos pasos ya hemos obtenido las puntuaciones directas
<i>estimadas</i> en el <i>test</i>.
</p>
</div>
</div>
<div id="outline-container-org063689e" class="outline-2">
<h2 id="org063689e">Calcular las puntuaciones <i>T</i></h2>
<div class="outline-text-2" id="text-org063689e">
<p>
Al final hay que calcular las puntuaciones <i>T</i>, pero teniendo en cuenta
que las puntuaciones se agrupan de forma distinta para hombres y
mujeres. Para ello he hecho dos funciones distintas, aunque
originalmente estaba pensado una sola que tomara los valores
correspondientes de una variable u otra teniendo en cuenta el sexo.
</p>

<p>
El código es el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">if</span> (equal (org-entry-get (point) <span style="color: #f1fa8c;">"Sexo"</span> t) <span style="color: #f1fa8c;">"Hombre"</span>)
    (minimult-calcular-T-hombre)
  (minimult-calcular-T-mujer))
</pre>
</div>

<p>
Igual que hice para convertir las puntuaciones de <i>MiniMult</i> se aplica
la fórmula
</p>

<p>
Nt = Nt<sub>min</sub> +
(Nt<sub>max</sub> -
Nt<sub>min</sub>) × (Nd -
Nd<sub>min</sub>) /
(Nd<sub>max</sub> -
Nd<sub>min</sub>)
</p>

<p>
Donde <i>Nt</i> son las puntuaciones <i>T</i> y las <i>Nd</i> son las puntuaciones
directas. El cálculo se realiza en la función siguiente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">minimult-calcular-T</span> (puntos max-t min-t max-d min-d)
  <span style="color: #6272a4;">"Convierte PUNTOS a puntuaciones T."</span>
  (fround (+ min-t (* (- max-t min-t) (/ (- puntos min-d) (- max-d min-d))))))
</pre>
</div>

<p>
y luego se le llama desde otras funciones para convertir las
puntuaciones de mujeres y hombres similares a como hice la función
<code>minimult-convertir-directas</code>, con los valores que se explican en el
siguiente punto.
</p>
</div>
</div>
<div id="outline-container-orgc23cb61" class="outline-2">
<h2 id="orgc23cb61">Tablas, sexo y <i>rock'and roll</i></h2>
<div class="outline-text-2" id="text-orgc23cb61">
<p>
Cuando corriges a mano el MMPI manejas muchas tablas que convierten las
puntuaciones. Tablas de corrección de <i>K</i>, tablas de conversión de
puntuaciones directas → <i>T</i> para hombres y mujeres.
</p>

<p>
Observando esas tablas se observa que la distribución de las
puntuaciones es homogénea. Sin embargo, están limitadas y en el manual
de corrección sólo figuran las puntuaciones entre <i>30T</i> y <i>120T</i> y no
siempre la puntuación mínima es 0. Y tampoco siempre la puntuación
máxima que se puede obtener en la escala está por debajo de 120. Por
eso, me decanté en calcular la puntuación en lugar de crear unas
larguísimas tablas.
</p>

<p>
La primera fórmula que he puesto en este <i>post</i> es un caso particular de
la fórmula que he mostrado en el punto anterior. El caso particular de
que las dos puntuaciones mínimas son 0.
</p>

<p>
Mirando las puntuaciones en las tablas del manual del MMPI-2, los
valores serían los siguientes:
</p>

<p>
Para varones:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Escala</th>
<th scope="col" class="org-right">máx.T</th>
<th scope="col" class="org-right">min.T</th>
<th scope="col" class="org-right">máx.D</th>
<th scope="col" class="org-right">min.D</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">L</td>
<td class="org-right">92</td>
<td class="org-right">30</td>
<td class="org-right">15</td>
<td class="org-right">0</td>
</tr>

<tr>
<td class="org-left">F</td>
<td class="org-right">120</td>
<td class="org-right">36</td>
<td class="org-right">47</td>
<td class="org-right">0</td>
</tr>

<tr>
<td class="org-left">K</td>
<td class="org-right">83</td>
<td class="org-right">31</td>
<td class="org-right">30</td>
<td class="org-right">6</td>
</tr>

<tr>
<td class="org-left">Hs</td>
<td class="org-right">102</td>
<td class="org-right">31</td>
<td class="org-right">38</td>
<td class="org-right">6</td>
</tr>

<tr>
<td class="org-left">D</td>
<td class="org-right">120</td>
<td class="org-right">30</td>
<td class="org-right">57</td>
<td class="org-right">12</td>
</tr>

<tr>
<td class="org-left">Hy</td>
<td class="org-right">119</td>
<td class="org-right">31</td>
<td class="org-right">56</td>
<td class="org-right">13</td>
</tr>

<tr>
<td class="org-left">Pd</td>
<td class="org-right">120</td>
<td class="org-right">31</td>
<td class="org-right">57</td>
<td class="org-right">15</td>
</tr>

<tr>
<td class="org-left">Pa</td>
<td class="org-right">118</td>
<td class="org-right">30</td>
<td class="org-right">35</td>
<td class="org-right">4</td>
</tr>

<tr>
<td class="org-left">Pt</td>
<td class="org-right">120</td>
<td class="org-right">30</td>
<td class="org-right">71</td>
<td class="org-right">18</td>
</tr>

<tr>
<td class="org-left">Sc</td>
<td class="org-right">119</td>
<td class="org-right">30</td>
<td class="org-right">84</td>
<td class="org-right">16</td>
</tr>

<tr>
<td class="org-left">Ma</td>
<td class="org-right">118</td>
<td class="org-right">31</td>
<td class="org-right">49</td>
<td class="org-right">12</td>
</tr>

<tr>
<td class="org-left">Si</td>
<td class="org-right">98</td>
<td class="org-right">30</td>
<td class="org-right">69</td>
<td class="org-right">10</td>
</tr>
</tbody>
</table>

<p>
Para mujeres:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Escala</th>
<th scope="col" class="org-right">máx.T</th>
<th scope="col" class="org-right">min.T</th>
<th scope="col" class="org-right">máx.D</th>
<th scope="col" class="org-right">min.D</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">L</td>
<td class="org-right">94</td>
<td class="org-right">30</td>
<td class="org-right">15</td>
<td class="org-right">0</td>
</tr>

<tr>
<td class="org-left">F</td>
<td class="org-right">119</td>
<td class="org-right">35</td>
<td class="org-right">38</td>
<td class="org-right">0</td>
</tr>

<tr>
<td class="org-left">K</td>
<td class="org-right">86</td>
<td class="org-right">31</td>
<td class="org-right">30</td>
<td class="org-right">6</td>
</tr>

<tr>
<td class="org-left">Hs</td>
<td class="org-right">100</td>
<td class="org-right">30</td>
<td class="org-right">38</td>
<td class="org-right">7</td>
</tr>

<tr>
<td class="org-left">D</td>
<td class="org-right">113</td>
<td class="org-right">30</td>
<td class="org-right">57</td>
<td class="org-right">14</td>
</tr>

<tr>
<td class="org-left">Hy</td>
<td class="org-right">119</td>
<td class="org-right">31</td>
<td class="org-right">57</td>
<td class="org-right">14</td>
</tr>

<tr>
<td class="org-left">Pd</td>
<td class="org-right">120</td>
<td class="org-right">31</td>
<td class="org-right">56</td>
<td class="org-right">15</td>
</tr>

<tr>
<td class="org-left">Pa</td>
<td class="org-right">119</td>
<td class="org-right">32</td>
<td class="org-right">36</td>
<td class="org-right">5</td>
</tr>

<tr>
<td class="org-left">Pt</td>
<td class="org-right">119</td>
<td class="org-right">31</td>
<td class="org-right">74</td>
<td class="org-right">20</td>
</tr>

<tr>
<td class="org-left">Sc</td>
<td class="org-right">120</td>
<td class="org-right">30</td>
<td class="org-right">83</td>
<td class="org-right">17</td>
</tr>

<tr>
<td class="org-left">Ma</td>
<td class="org-right">120</td>
<td class="org-right">31</td>
<td class="org-right">50</td>
<td class="org-right">11</td>
</tr>

<tr>
<td class="org-left">Si</td>
<td class="org-right">97</td>
<td class="org-right">30</td>
<td class="org-right">69</td>
<td class="org-right">11</td>
</tr>
</tbody>
</table>

<p>
Si comparamos las dos tablas vemos que las puntuaciones son muy
parecidas pero no iguales.
</p>

<p>
Al final, y como todas las puntuaciones que se manejan son siempre en
forma de enteros, aunque todos los cálculos se han realizado en con
decimales, se han ido redondeando al entero más cercano siempre y al
final al convertirlas en cadena para guardarlas en la lista de
propiedades del <i>org</i> se utiliza la siguiente instrucción:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">minimult-guardar-resultados</span> (lista-escalas)
  <span style="color: #6272a4;">"Guarda la LISTA-ESCALAS por pares (propiedad valor)."</span>
  (<span style="color: #ff79c6; font-weight: bold;">when</span> lista-escalas
    (org-entry-put (point) (<span style="color: #ff79c6; font-weight: bold;">pop</span> lista-escalas) (format <span style="color: #f1fa8c;">" %d"</span> (<span style="color: #ff79c6; font-weight: bold;">pop</span> lista-escalas)))
    (minimult-guardar-resultados lista-escalas)))
</pre>
</div>

<p>
En entrada <i>org</i> se guarda la <i>escala</i> y con una cadena de formato
<code>" %d"</code> se convierte la puntuación a cadena truncando la parte decimal
(que en todos los casos, dado el redondeo que se ha venido haciendo, es
<code>.0</code>).
</p>
</div>
</div>
<div id="outline-container-org49482f6" class="outline-2">
<h2 id="org49482f6">Cosas mejorables y dificultades</h2>
<div class="outline-text-2" id="text-org49482f6">
<p>
No soy nada productivo con el código en <i>elisp</i>. Aún no domino el
lenguaje, ni sus usos y costumbres. Su forma de guardar variables
temporales, el que muchas veces se me olvida el <i>quote</i> al definir
listas y que los cálculos matemáticos utilizan notación prefija me
dificultan muchas veces avanzar. Cometo muchos errores aún y todavía
cuando salta el error y me muestra el depurador la pila de llamadas, me
cuesta un momento comprender cuál es el error y dónde debo buscarlo.
</p>

<p>
Cuando me encuentre más <i>suelto</i> con el lenguaje y el entorno, quizá
haría las cosas de otras formas más <i>elegantes</i>.
</p>

<p>
Por algún sitio he leído eso de que <i>Lisp</i> es un <i>lenguaje de
programación programable</i> y que puede simular ser otra cosa. En este
caso con <i>Emacs</i> estaría simulando que es un editor cuya <i>interface</i>,
datos y acciones se enfocan en el texto. Algunos dirían algo parecido
sobre <i>AutoCAD</i> y el dibujo técnico.
</p>

<p>
Llegados a este punto vamos a ver cómo avanza el proyecto: ¿seré capaz
de hacer que <i>Emacs</i>, que básicamente es texto, dibuje el perfil
<i>gráfico</i> del test? ... Alguna idea llevo de cómo se podría hacer y voy
a ver si consigo hacerlo. A pesar de todas mis dificultades y carencias,
cada vez me encuentro más cómodo con el lenguaje y el entorno.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/programación/index.html">programación</a> <a href="/tags/tests/index.html">tests</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[programación]]></category>
  <category><![CDATA[tests]]></category>
  <link>https://notxor.nueva-actitud.org/2017/02/05/minimult-corregido.html</link>
  <pubDate>Sun, 05 Feb 2017 21:27:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Escalas, plantillas y corrección]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-01-30</div>
<p>
Para continuar con la serie del <i>MiniMult</i>, prueba que ya podemos pasar
por pantalla, necesitamos primero hacer algunas reflexiones sobre cómo
funciona la corrección manual.
</p>

<p>
Antiguamente se corregía con papel y lápiz. Las plantillas eran
cartulinas horadadas o metacrilatos transparentes que se situaban sobre
la hoja de papel y se iban contando las contestaciones que coincidían
con los orificios o huecos. Cada plantilla, cada hoja, correspondía a
una escala. Así se sumaban ─con los inevitables errores que de vez en
cuando se comenían─ la totalidad y se anotaban para posteriores
cálculos.
</p>
<div id="outline-container-orgd345b2f" class="outline-2">
<h2 id="orgd345b2f">Escalas</h2>
<div class="outline-text-2" id="text-orgd345b2f">
<p>
Una <i>escala</i> se resume al final como un número. Las escalas aglutinan
respuestas concretas y empíricamente se ha determinado que quienes
suelen puntuar alto (o bajo) en la misma cumple con unas características
personales que nos permite <i>predecir</i> el tipo de conducta que el sujeto
tendrá.
</p>

<p>
La psicología no es una ciencia exacta. Se basa en la estadística para
llegar a esas conclusiones y todo resultado debe ser tomado con la
suficiente <i>precaución</i>. No me voy a extender en teoría de tests, ni a
hacer puntualizaciones sobre fiabilidad y validez, ni todos los
constructos teóricos que se hayan detrás de del concepto <i>escala</i>. Baste
decir que no estamos hablando de un <i>test del Cosmopolitan</i>.
</p>

<p>
Pero a efectos del <i>programa</i> que estamos haciendo: nos quedamos con que
una escala será en último caso un <i>número</i>; generalmente un entero.
</p>

<p>
El MMPI Y su secuela el MMPI-2 con sus más de 500 preguntas se han
utilizado ampliamente en investigación. De forma que se han utilizado
sus ítem para muchas escalas distintas a las clínicas. De hecho en la
corrección de esas pruebas se contempla la corrección de otras escalas
secundarias. Por tanto, el sistema debería tener en cuenta que se puedan
extender las escalas de forma sencilla.
</p>

<p>
Por esto, debemos tener en cuenta cómo vamos a <i>implementar</i> las
plantillas para corregir.
</p>
</div>
</div>
<div id="outline-container-org8ba7bb2" class="outline-2">
<h2 id="org8ba7bb2">Plantillas</h2>
<div class="outline-text-2" id="text-org8ba7bb2">
<p>
La primera idea que se nos puede pasar por la cabeza es hacer algo
similar a como se haría en la vida real: crear para cada <i>escala</i> su
<i>plantilla</i>. Si tienes otra escala, deberías crear su plantilla y luego
añadirla al programa para que la tenga en cuenta.
</p>

<p>
Pero entiendo que <i>Lisp</i>, y por tanto, su derivado <i>elisp</i> es un
lenguaje especializado en gestionar listas: listas de escalas con sus
correspondientes plantillas.
</p>

<p>
Podríamos pensar que podemos recorrer desde la primera respuesta hasta
el final las contestaciones del sujeto e ir añadiendo a cada escala su
valor. Pero la coincidencia de <i>preguntas</i> con <i>escalas</i> no es exacta.
Es decir, una pregunta puede estar en varias escalas. En el caso del
MMPI o el <i>MiniMult</i> es lo habitual. No solo eso, sino que además un
valor de «V» puede puntuar en una escala y un valor de «F» en otra. Por
tanto, el sistema debería ser flexible para poder hacerlo.
</p>
</div>
</div>
<div id="outline-container-org636b097" class="outline-2">
<h2 id="org636b097">Corrección</h2>
<div class="outline-text-2" id="text-org636b097">
<p>
Las listas en <i>Lisp</i> pueden contener valores de cualquier tipo. Para la
corrección de necesitamos varios datos:
</p>

<ol class="org-ol">
<li><i>Escala</i>. Nombre de la escala.</li>
<li><i>Número de pregunta</i>.</li>
<li><i>Alternativa</i>. Qué debe contener la respuesta para que se sume
<i>valor</i> a la escala.</li>
<li><i>Valor</i>. Qué cantidad se suma si la <i>alternativa</i> coincide con la
respuesta del sujeto.</li>
</ol>

<p>
En el caso del <i>MiniMult</i> el <i>valor</i> para todas las respuestas es 1.
Pero en otros test no siempre es así. Y puede aparecer una escala de
<i>investigación</i> nueva que sume valores diferentes para las preguntas.
</p>

<p>
Por ejemplo:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #f1fa8c;">"Hs"</span> 9 <span style="color: #f1fa8c;">"V"</span> 1)
</pre>
</div>

<p>
Si lo estuviera haciendo en <i>python</i>, por ejemplo, la opción sería ir
guardando los resultados en un diccionario cuyas <i>claves</i> serían los
nombres de escalas y el valor asociado la puntuación en la escala. Al
ser un lenguaje interpretado, si añadimos a la plantilla entradas que
corrijan otras escalas, el sistema automáticamente creará una nueva
escala en el diccionario.
</p>

<p>
En <i>Lisp</i> por lo que he visto existen constructos similares que se
pueden utilizar y que nos dejarían el resultado con un aspecto similar
al siguiente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">((<span style="color: #f1fa8c;">"L"</span> . 3) (<span style="color: #f1fa8c;">"F"</span> . 25) ... (<span style="color: #f1fa8c;">"Si"</span> . 45))
</pre>
</div>

<p>
Si posteriormente se añade una nueva escala a la <i>plantilla</i> el sistema
debería añadir un valor a esta <i>lista de escalas</i>.
</p>

<p>
El estar aprendiendo el lenguaje según voy necesitando las cosas me
parece que quizá le sacaría más rendimiento más adelante. Cuando esté
más familiarizado con la forma de trabajar de <i>Lisp</i>. Supongo que más
adelante todo lo haría de otra forma, por ejemplo teniendo en cuenta
la cantidad de memoria gastada, o la velocidad y optimización de la
ejecución del programa. Supongo que algún <i>Gurú</i> de <i>Lisp</i> se llevará
las manos a la cabeza por el código que genera mi extraña cabeza de
psicólogo, pero es lo que hay y me atengo a la máxima: <i>si funciona
está bien</i>.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/tests/index.html">tests</a> <a href="/tags/programación/index.html">programación</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[tests]]></category>
  <category><![CDATA[programación]]></category>
  <link>https://notxor.nueva-actitud.org/2017/01/30/escalas-plantillas-y-correccion.html</link>
  <pubDate>Mon, 30 Jan 2017 19:18:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Código para pasar prueba por pantalla]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-01-28</div>
<p>
Bueno, para seguir con la serie sobre la corrección de pruebas
psicológicas por pantalla, ya tengo algunas cosillas hechas y lo muestro
por aquí. En las entradas anteriores solté un ladrillo sobre cómo iba a
hacer las cosas y bla, bla, bla. Todo mentira: realmente sabes cómo van
a ir las cosas cuando las haces, las pruebas, no funcionan, corriges y
las haces funcionar... En fin, de lo pensado a lo hecho hay algunos
cambios, así pues: voy a ver si me explico con claridad. El código
(casi) completo de lo que hay hecho hasta ahora en el proyecto está
guardado en un fichero <code>minimult.el</code> y lo pondré al final de esta
entrada.
</p>
<div id="outline-container-org58516de" class="outline-2">
<h2 id="org58516de">Depurar con <i>edebug</i></h2>
<div class="outline-text-2" id="text-org58516de">
<p>
Una de las cosas que he tenido que aprender sobre la marcha es la
depuración de los errores que he ido cometiendo por el camino. Algo tan
importante a la hora de programar como el escribir código.
</p>

<p>
<i>Emacs</i> lleva incorporado su depurador. En realidad y porque la gente de
<i>Emacs</i> es así, trae varios. Como estoy acostumbrado a depuradores más
visuales, me decidí a utilizar <i>edebug</i>. En el manual están todos los
comandos que admite, aunque básicamente he utilizado tres:
</p>

<ul class="org-ul">
<li><code>edebug-defun</code>: En cualquier posición de la definición de la función
llamas a <code>M-x edebug-defun</code> y cuando se ejecuta la misma comienza la
depuración.</li>
<li><code>n</code>: Avanza la ejecución de instrucción en instrucción.</li>
<li><ESP>: pulsando la tecla del espacio hace más paradas entre
las expresiones de una misma instrucción. La ventaja es que va
mostrando en el área de eco el resultado de evaluar la expresión o
variable y puedes ir viendo cómo cambian sus valores.</li>
</ul>

<p>
También puedes poner puntos de parada (<i>breakpoint</i>) con el comando <code>b</code>
y hacer que termine todo el proceso con el comando <code>g</code> (<i>go</i>).
Básicamente para poner un punto de parada más adelante y hacer que todo
se ejecute hasta que llegue allí.
</p>

<p>
Como impresión general <i>edebug</i> me ha dejado una buena sensación. Me
llamó la atención lo de <i>preparar</i> la función para ser depurada.
Acostumbrado a poner puntos de parada en el sitio que quieres depurar y
lanzar el programa, me lo tomé como «poner punto de parada al inicio de
la función». Ahora, después de llevar utilizándolo una semana, me parece
hasta natural.
</p>

<p>
Pero no seré yo el que le puede poner «peros» a nada. Yo soy psicólogo y
lo de la programación es una afición. Sin embargo, creo que es una buena
herramienta, que merece no una, sino varias entradas en un blog como
éste. De momento, a la documentación me remito.
</p>
</div>
</div>
<div id="outline-container-org750b2ed" class="outline-2">
<h2 id="org750b2ed">Analizando un poco lo que he hecho</h2>
<div class="outline-text-2" id="text-org750b2ed">
<p>
Es complicado hablar detalladamente de todo el proceso hasta llegar al
código y seguro que cualquier informático le encontrará diez fallos a
cada línea que he escrito.
</p>

<p>
Lo primero que he tenido que hacer es acostumbrarme a la sintaxis de
<i>Lisp</i>, que en diez minutos la aprendes pero al final la falta de
costumbre te hace cometer errores. Parece que siempre te faltan
paréntesis (aún siendo cuidadoso como es mi caso).
</p>

<p>
De primeras las respuestas podían ser «V», «F» y « ». Sin embargo, los
espacios son un problema. Cuando se guardan las respuestas en una cadena
y se meten en una «propiedad» dentro del árbol del fichero <i>org</i> resulta
que se guarda sin nada que indique dónde empieza y dónde acaba.
</p>

<p>
De lo primero me di cuenta después. Primero me di cuenta de que si
guardaba la prueba a medias se ignoraban los espacios en blanco
posteriores. Lo intenté solventar comprobando cuándo se acaban las
respuestas, pero el problema es aún más grave cuando las primeras
preguntas se dejan en blanco: esos caracteres son ignorados y por tanto
el resto de las respuestas son asignadas a preguntas que no
corresponden. Por esto, decidí utilizar el carácter «-» en lugar del
espacio en blanco.
</p>

<p>
La forma de presentar las preguntas en pantalla estuve a punto de
decidirme por hacerlo de forma recursiva con la lista de preguntas (sólo
por probar), pero al final me decidí por un bucle <code>while</code> cuyo meollo es
el siguiente:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">setq</span> lista-widgets <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Crear un lista de widgets para las respuestas
</span> (cons         <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Estar&#225; en orden inverso
</span>  (widget-create 'editable-field
         <span style="color: #8be9fd; font-style: italic;">:tag</span> (concat <span style="color: #f1fa8c;">"P"</span> (number-to-string (+ contador 1)))
         <span style="color: #8be9fd; font-style: italic;">:size</span> 1
         <span style="color: #8be9fd; font-style: italic;">:value</span> (<span style="color: #ff79c6; font-weight: bold;">if</span> (<span style="color: #ff79c6; font-weight: bold;">and</span> minimult-respuestas (&lt; contador (length minimult-respuestas)))
                (char-to-string (elt minimult-respuestas contador))
            <span style="color: #f1fa8c;">"-"</span>))
   lista-widgets))
(widget-insert <span style="color: #f1fa8c;">" "</span>)
(widget-insert (elt minimult-preguntas contador)) <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">extraer la pregunta de CONTADOR</span>
</pre>
</div>

<p>
Esa parte del código repetida tantas veces como preguntas hay que
presentar hace el trabajo de presentar por pantalla la pregunta asociada
a un <i>widget</i> (mostrando una posible respuesta anterior).
</p>

<p>
El proceso de corrección sería el siguiente:
</p>

<ol class="org-ol">
<li><b>Cargar el código</b>. Ahora mismo lo tengo en un directorio externo a
<i>Emacs</i>. Por eso lo cargo con el comando
<code>M-: (load    "path/completo/al/fichero.el")</code> que es una de las
posibles formas de añadir código al entorno.</li>
<li><p>
<b>Lanzar el proceso</b>. Como la función está declarada como interactiva
se la llama con el comando <code>M-x minimult-pasar-prueba</code>. Como se puede
ver en la siguiente imagen
</p>


<figure id="orge71aab8">
<img src="./imagen/minimult-lanzado.png" alt="minimult-lanzado.png">

</figure>

<p>
Al llamar a la función se inserta en <code>:PROPERTIES:</code> una entrada para
<code>:Test:</code> con el valor <i>MiniMult</i>.
</p></li>

<li><p>
<b>Contestar prueba</b>. La prueba se puede contestar pulsando apenas
tres teclas <TAB> para pasar a la siguiente, <code>v</code> y <code>f</code>. Se
puede hacer en minúsculas porque cuando se guardan se pasan a
mayúsculas.  Como se puede ver en la siguiente imagen.
</p>


<figure id="orgf4d8178">
<img src="./imagen/minimult-contestando.png" alt="minimult-contestando.png">

</figure></li>

<li><p>
<b>Guardar respuestas</b>. Una vez se termina de contestar sólo hay que
pulsar el botón que se puede ver en la imagen anterior: <i>[Guardar
respuestas]</i>. Esto hará que aparezca otra entrada en <code>:PROPERTIES:</code>
para <code>:Respuestas:</code> con la cadena formada por las respuestas.
</p>


<figure id="org510b302">
<img src="./imagen/minimult-respuestas.png" alt="minimult-respuestas.png">

</figure>

<p>
Cuando se guardan las respuestas, automáticamente se cierra el
<i>buffer</i> y vuelve a la <i>historia clínica</i>.
</p></li>
</ol>
</div>
</div>
<div id="outline-container-org5359283" class="outline-2">
<h2 id="org5359283">Algunos puntos mejorables</h2>
<div class="outline-text-2" id="text-org5359283">
<p>
Uno de los puntos mejorables es la presentación de la prueba. Quizá no
consistiría más que en introducir algún salto de línea y algunos
espacios para que las preguntas largas no se escapen por la derecha de
la ventana.
</p>

<p>
Otro que cuando acaba de cargar la prueba el <i>punto</i> de edición se queda
al final del <i>buffer</i>. Sólo con pulsar <TAB> regresa al espacio
reservado para el primer ítem.
</p>

<p>
Una de las limitaciones del sistema que me he encontrado es que aunque
se dibujan los <i>widgets</i> con tamaño 1, si se escriben más caracteres el
campo se expande. En la mayoría de los casos será el comportamiento
deseado, pero en este ejercicio sólo queremos un carácter. Por eso,
cuando se lee el contenido del mismo lo que se hace es cortar el primer
carácter.
</p>

<p>
Otra mejora que se podría hacer es que también entendiera los caracteres
<code>S</code> y <code>N</code> como respuesta (y no se descarta hacerlo más adelante).
</p>
</div>
</div>
<div id="outline-container-orgfb33b0e" class="outline-2">
<h2 id="orgfb33b0e">Código</h2>
<div class="outline-text-2" id="text-orgfb33b0e">
<p>
Antes dije que estaría <i>casi</i> todo el código. Lo que falta es que la
variable que guarda las preguntas, como ya la puse en
<a href="./minimult-2.html">otra entrada</a>, pondré la primera y última un unos
puntos suspensivos.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">
(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">widget</span>)

(<span style="color: #ff79c6; font-weight: bold;">eval-when-compile</span>
  (<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">wid-edit</span>))

(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">lista-widgets</span>)

(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">buffer-original</span>)

(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">minimult-respuestas</span>)

(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">minimult-preguntas</span>
  '(<span style="color: #f1fa8c;">"Tengo buen apetito."</span>
  ....
    <span style="color: #f1fa8c;">"He abusado del alcohol."</span>)
  <span style="color: #6272a4;">"Listado de preguntas del MiniMult."</span>)

(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">minimult-pasar-prueba</span> ()
  <span style="color: #6272a4;">"Muestra la prueba MiniMult por pantalla y guarda las respuestas."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (<span style="color: #ff79c6; font-weight: bold;">setq</span> minimult-respuestas                   <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">variable que guardar&#225; las respuestas
</span>    (org-entry-get (point) <span style="color: #f1fa8c;">"Respuestas"</span>)) <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">si no hay respuestas anteriores ser&#225; nil.
</span>  (org-entry-put (point) <span style="color: #f1fa8c;">"Test"</span> <span style="color: #f1fa8c;">"MiniMult"</span>)   <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">en la historia hace figurar un test MiniMult
</span>  (<span style="color: #ff79c6; font-weight: bold;">setq</span> lista-widgets '())
  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Guardar el buffer viejo
</span>  (<span style="color: #ff79c6; font-weight: bold;">setq</span> buffer-original (current-buffer))
  (<span style="color: #ff79c6; font-weight: bold;">let</span> ((contador 0))
    <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Crear buffer temporal
</span>    (switch-to-buffer <span style="color: #f1fa8c;">"*MiniMult*"</span>)
    (kill-all-local-variables)
    (overwrite-mode)
    <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">(setq inhibit-read-only t)
</span>    (erase-buffer)
    (remove-overlays)
    <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Iniciar el formulario con unas breves instrucciones
</span>    (widget-insert <span style="color: #f1fa8c;">"Responda sinceramente a estas preguntas. No hay tiempo, leealas despacio\n"</span>)
    (widget-insert <span style="color: #f1fa8c;">"y no se preocupe por el tiempo. Habr&#225; ocasiones en que no pueda decidirse\n"</span>)
    (widget-insert <span style="color: #f1fa8c;">"por una u otra opci&#243;n. En estos casos la primera que llegue a nuestra mente\n"</span>)
    (widget-insert <span style="color: #f1fa8c;">"es la que deber&#237;amos consignar. Ante cualquier duda pregunte al evaluador.\n\n"</span>)

    <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Rellenar el buffer con las preguntas
</span>    (<span style="color: #ff79c6; font-weight: bold;">while</span> (&lt; contador (length minimult-preguntas))
      (<span style="color: #ff79c6; font-weight: bold;">if</span> (&lt; contador 9)        <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Hay que recordar que el contador se inicia en 0
</span>      (widget-insert <span style="color: #f1fa8c;">" "</span>))  <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">por eso alineamos con un espacio las primeras 9 preguntas
</span>      (widget-insert (number-to-string (+ contador 1))) <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">y sumamos 1 a CONTADOR para poner el n&#250;mero
</span>      (widget-insert <span style="color: #f1fa8c;">".-"</span>)
      (<span style="color: #ff79c6; font-weight: bold;">setq</span> lista-widgets <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Crear un lista de widgets para las respuestas
</span>        (cons         <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Estar&#225; en orden inverso
</span>         (widget-create 'editable-field
                <span style="color: #8be9fd; font-style: italic;">:tag</span> (concat <span style="color: #f1fa8c;">"P"</span> (number-to-string (+ contador 1)))
                <span style="color: #8be9fd; font-style: italic;">:size</span> 1
                <span style="color: #8be9fd; font-style: italic;">:value</span> (<span style="color: #ff79c6; font-weight: bold;">if</span> (<span style="color: #ff79c6; font-weight: bold;">and</span> minimult-respuestas (&lt; contador (length minimult-respuestas)))
                       (char-to-string (elt minimult-respuestas contador))
                     <span style="color: #f1fa8c;">"-"</span>))
         lista-widgets))
      (widget-insert <span style="color: #f1fa8c;">" "</span>)
      (widget-insert (elt minimult-preguntas contador)) <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">extraer la pregunta de CONTADOR
</span>      (widget-insert <span style="color: #f1fa8c;">"\n"</span>)
      (<span style="color: #ff79c6; font-weight: bold;">setq</span> contador (1+ contador)))
    (widget-create 'push-button
           <span style="color: #8be9fd; font-style: italic;">:notify</span> (<span style="color: #ff79c6; font-weight: bold;">lambda</span> (<span style="color: #8be9fd; font-style: italic;">&amp;rest</span> ignore)
                 (<span style="color: #ff79c6; font-weight: bold;">let</span> ((contador 0)
                       (total (length lista-widgets))
                   (respuestas <span style="color: #f1fa8c;">""</span>)
                   (item <span style="color: #f1fa8c;">""</span>))
                   (<span style="color: #ff79c6; font-weight: bold;">while</span> (&lt; contador total)
                     <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Obtener el primer car&#225;cter del campo
</span>                     (<span style="color: #ff79c6; font-weight: bold;">setq</span> item
                       <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Comprobar que hay un valor
</span>                       (<span style="color: #ff79c6; font-weight: bold;">if</span> (widget-value (car lista-widgets))
                           <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Eliminar el widget de la lista obteniendo su valoro
</span>                           (substring (widget-value (<span style="color: #ff79c6; font-weight: bold;">pop</span> lista-widgets)) 0 1)
                         <span style="color: #f1fa8c;">"-"</span>))
                     <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Encadenamos cada respuesta en una cadena
</span>                     (<span style="color: #ff79c6; font-weight: bold;">setq</span> respuestas (concat (upcase item) respuestas))
                     <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Actualizamos contador
</span>                     (<span style="color: #ff79c6; font-weight: bold;">setq</span> contador (1+ contador)))
                   <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Cambiamos al buffer anterior
</span>                   (set-buffer buffer-original)
                   <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Guardamos respuestas
</span>                   (org-entry-put (point) <span style="color: #f1fa8c;">"Respuestas"</span> respuestas)
                   <span style="color: #6272a4;">;; </span><span style="color: #6272a4;">Destruimos el buffer temporal
</span>                   (kill-buffer <span style="color: #f1fa8c;">"*MiniMult*"</span>)))
           <span style="color: #f1fa8c;">"Guardar respuestas"</span>)
    (use-local-map widget-keymap)
    (widget-setup)
  ))
</pre>
</div>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/programación/index.html">programación</a> <a href="/tags/tests/index.html">tests</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[programación]]></category>
  <category><![CDATA[tests]]></category>
  <link>https://notxor.nueva-actitud.org/2017/01/28/codigo-para-pasar-prueba-por-pantalla.html</link>
  <pubDate>Sat, 28 Jan 2017 16:15:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Pasar el MiniMult por pantalla]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-01-24</div>
<p>
Cuando pensé los pasos que debería dar para corregir el <i>MiniMult</i> en
<a href="./minimult.html">esta entrada</a> Especificaba que la primera parte sería la elección de
ítem para la prueba. Algo que intenté explicar en la <a href="./minimult-2.html">siguiente</a> pero
que creo que no me quedó suficientemente bien explicada. Como ya está
publicada no sé si volver a ella y retocarla porque releyéndola me
parece farragosa y confusa. Pero el caso es que allí podemos ver qué
preguntas vamos a utilizar y cuáles son sus valores de plantilla (que
aún no utilizamos). Con eso cumplimos el paso uno.
</p>

<p>
¡Bien! Ya tenemos decidido todo el <i>test</i> (preguntas, plantillas,
escalas, etc.) y ahora queremos que nuestro <i>Emacs</i> lo pase por
pantalla. Para ello vamos a ver lo que necesitamos.
</p>

<p>
A <i>grosso modo</i> lo que necesitamos para pasar la prueba por pantalla
lo podemos resumir en los siguientes pasos:
</p>

<ol class="org-ol">
<li>Crear un <i>buffer</i> donde mostrar la prueba:

<ul class="org-ul">
<li>Generar los <i>widgets</i> en un <i>buffer</i> nuevo.</li>
</ul></li>

<li>Cambiar el foco al nuevo <i>buffer</i>.</li>
<li>Al terminar la prueba devolver el foco al <i>buffer</i> anterior y
devolver las respuestas.</li>
</ol>
<div id="outline-container-org102f279" class="outline-2">
<h2 id="org102f279">Crear un <i>buffer</i></h2>
<div class="outline-text-2" id="text-org102f279">
<p>
Lo primero que tenemos que tener en cuenta es que al cambiar de
<i>buffer</i> resultan inalcanzables las variables y valores del <i>buffer</i>
que abandonamos. Si necesitamos cualquier valor lo debemos guardar
para poder utilizarlo. Entre esos valores debemos guardar el <i>buffer</i>
donde está la historia de nuestro paciente, entre otras cosas para
poder volver.
</p>

<p>
Mirando la documentación de <i>Emacs</i> encontré un paquete que se llama
<i>widget</i> y que viene con un ejemplo que resulta esclarecedor. Que
comienza así:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">widget</span>)

(<span style="color: #ff79c6; font-weight: bold;">eval-when-compile</span>
  (<span style="color: #ff79c6; font-weight: bold;">require</span> '<span style="color: #bd93f9;">wid-edit</span>))
</pre>
</div>

<p>
Por lo que veo ahí existen dos paquetes que incluir. El primero es
<code>widget</code> que lo cargará siempre y otro <code>wid-edit</code> sólo se cargará cuando
se compile el módulo gracias al <i>macro</i> <code>eval-when-compile</code>.
</p>
</div>
<div id="outline-container-orgce03609" class="outline-3">
<h3 id="orgce03609">Consideraciones antes de crear el <i>buffer</i></h3>
<div class="outline-text-3" id="text-orgce03609">
<p>
En el <i>MiniMult</i> hay pocas preguntas y es casi seguro que se contestarán
en una sola sesión. Pero pensando en pruebas más largas que se podrían
contestar en varias sesiones me he planteado ser lo más <i>conservador</i>
posible con las respuestas del cliente. Es decir, si hay respuestas
previas al test el sistema debería tomarlas y colocarlas en su sitio
para que el sujeto pueda continuar o incluso modificar alguna si así lo
considera oportuno.
</p>

<p>
Después de hacer algunas pruebas he visto que obtener y establecer
información guardada en un bloque de propiedades es sencillo utilizando
las funciones <code>org-entry-get</code> y <code>org-entry-put</code>. Para obtener, por
tanto, los valores de las respuestas utilizaremos una línea que diga
algo así como:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">minimul-respuestas</span>)

 ...

(<span style="color: #ff79c6; font-weight: bold;">setq</span> minimult-respuestas (org-entry-get (point) <span style="color: #f1fa8c;">"Respuestas"</span>))
</pre>
</div>

<p>
El formato en el que vamos a guardar las respuestas es muy simple. Una
cadena de caracteres donde cada posición marca la respuesta para un
ítem. Cada carácter puede tener tres valores posibles para cada uno «V»,
«F» o un espacio en blanco. El hacerlo así es por simplicidad: la
respuesta al ítem 14 será el valor de la posición 14 de la cadena. Se
guardan todas las respuestas en una sola variable y además ese formato
es idéntico a lo que se generaría en una lectora de marcas, por ejemplo.
Lo que serviría también para los casos en que las pruebas se hicieran
con una hoja de respuestas mecanizada.
</p>
</div>
</div>
<div id="outline-container-orgdcee623" class="outline-3">
<h3 id="orgdcee623">Crear un <i>buffer</i> y cambiar a él</h3>
<div class="outline-text-3" id="text-orgdcee623">
<p>
En el mismo ejemplo de la documentación del paquete <code>widget</code> aparece
cómo hacer para crear un <i>buffer</i> y cambiar a él y luego una serie de
operaciones antes de ponerse a añadir <i>widgets</i>.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defun</span> <span style="color: #50fa7b; font-weight: bold;">widget-example</span> ()
  <span style="color: #6272a4;">"Create the widgets from the Widget manual."</span>
  (<span style="color: #ff79c6; font-weight: bold;">interactive</span>)
  (switch-to-buffer <span style="color: #f1fa8c;">"*Widget Example*"</span>)
  (kill-all-local-variables)
  (make-local-variable 'widget-example-repeat)
  (<span style="color: #ff79c6; font-weight: bold;">let</span> ((inhibit-read-only t))
    (erase-buffer))
  (remove-overlays)
  (widget-insert
  ...
  (widget-setup))
</pre>
</div>

<p>
En ese código podemos ver cómo se cambia con la función
<code>switch-to-buffer</code> a un nuevo <i>buffer</i>. Limpia variables, le pone una
variable local <code>widget-example-repeat</code>, inhibe el modo de <i>solo lectura</i>
y limpia el <i>buffer</i> y los límites si los hubiera.
</p>

<p>
El declarar la función como <code>interactive</code> hace que se pueda llamar desde
la combinación de teclas <code>M-x</code>.
</p>
</div>
</div>
</div>
<div id="outline-container-org4af75c2" class="outline-2">
<h2 id="org4af75c2">Pasos que tendrá que hacer el código</h2>
<div class="outline-text-2" id="text-org4af75c2">
<p>
Después de todas las consideraciones creo que los pasos que tendría que
hacer el sistema sería algo así:
</p>

<ol class="org-ol">
<li>Guardar el <i>buffer</i> donde están los datos.</li>
<li>Obtener las <i>respuestas</i> anteriores si las hay.</li>
<li>Cambiar al nuevo <i>buffer</i> creado.</li>
<li><i>Mostrar</i> en pantalla cada pregunta. Si hay respuestas debería
mostrar también el valor actual.</li>
<li>Guardar el contenido de los <i>widgets</i> de respuesta en una sola
cadena.</li>
<li>Cambiar el foco al <i>buffer</i> antiguo y guardar las respuestas.</li>
<li>Destruir el <i>buffer</i> temporal.</li>
</ol>

<p>
Antes he dicho <i>creo</i> porque recuerdo que de lo que yo entiendo
verdaderamente es de psicología. No soy informático aunque hago algunas
veces mis pequeñas herramientas que me ayudan a hacer mi trabajo.
Supongo que un informático ya habría terminado todo el proyecto que a mí
me cuesta investigar día a día en ratos libres y lo tendría funcionando
incluso habría hecho ya algunas mejoras.
</p>

<p>
Pero es lo que hay y mi filosofía última es «si funciona, vale». No
entro en consideraciones de <i>elegancia</i> del código. Un concepto que
nunca he entendido, porque lo que alguien encuentra elegante otro lo
considera zafio o carente de estilo.
</p>

<p>
Ahora me pondré a codificar lo pensado hasta aquí y pondré en futuras
entradas del <i>blog</i> lo que me vaya encontrando por el camino y los
cambios que tenga que hacer. Como por ejemplo, en el código que ya hay
he cambiado el nombre de la variable que guarda los textos de las
preguntas por <code>minimult-preguntas</code>. Eso hace que no haya colisiones de
nombres si por ejemplo existiera otro futuro programa de corrección de
<i>test</i> que no fuese el <i>MiniMult</i>.
</p>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/psicología/index.html">psicología</a> <a href="/tags/tests/index.html">tests</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[psicología]]></category>
  <category><![CDATA[tests]]></category>
  <link>https://notxor.nueva-actitud.org/2017/01/24/pasar-el-minimult-por-pantalla.html</link>
  <pubDate>Tue, 24 Jan 2017 22:44:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[MiniMult 2]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-01-22</div>
<p>
Unas pocas disquisiciones más que nos quedan antes de ponernos con el
código. Quizá quede un post muy largo porque voy a poner todos los datos
de los 71 ítem.
</p>
<div id="outline-container-org2cb2d1e" class="outline-2">
<h2 id="org2cb2d1e">Sobre las preguntas</h2>
<div class="outline-text-2" id="text-org2cb2d1e">
<p>
Pues vamos a seguir con algunas consideraciones del proyecto, empezando
por lo básico y lo más básico de un <i>test</i> son sus preguntas.
</p>

<p>
Lo primero que he hecho es buscar las equivalencias en las cuestiones
entre las correspondientes al <i>MiniMult</i> original y el MMPI-2. Para ello
he tenido que ir recorriendo el cuadernillo de preguntas buscando la que
más se parecía.
</p>

<p>
El primer problema que me he encontrado es que no tengo el MMPI-2, me he
bajado de internet un cuadernillo, pero es su versión argentina (que por
ejemplo, llama <i>constipado</i> al estreñimiento y algunas peculiaridades
más que tenido que solventar como he podido). Así he tenido que redactar
algunos ítem para hacerlos <i>normales</i> para el lector español.
</p>
</div>
</div>
<div id="outline-container-org3cea2b4" class="outline-2">
<h2 id="org3cea2b4">Plantillas de corrección</h2>
<div class="outline-text-2" id="text-org3cea2b4">
<p>
Una vez establecidas las equivalencias entre los ítem del <i>MiniMult</i> y
el MMPI-2. Nos interesa establecer las plantillas de corrección. Para
entenderme, me he hecho la siguiente tabla.
</p>

<table>


<colgroup>
<col  class="org-right">

<col  class="org-right">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-right">MM</th>
<th scope="col" class="org-right">MMPI-2</th>
<th scope="col" class="org-left">L</th>
<th scope="col" class="org-left">F</th>
<th scope="col" class="org-left">K</th>
<th scope="col" class="org-left">Hs</th>
<th scope="col" class="org-left">D</th>
<th scope="col" class="org-left">Hy</th>
<th scope="col" class="org-left">Pd</th>
<th scope="col" class="org-left">Pa</th>
<th scope="col" class="org-left">Pt</th>
<th scope="col" class="org-left">Sc</th>
<th scope="col" class="org-left">Ma</th>
<th scope="col" class="org-left">Si</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-right">1</td>
<td class="org-right">2</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">2</td>
<td class="org-right">3</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">3</td>
<td class="org-right">9</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">4</td>
<td class="org-right">15</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">5</td>
<td class="org-right">16</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">6</td>
<td class="org-right">20</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">7</td>
<td class="org-right">21</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">8</td>
<td class="org-right">23</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">9</td>
<td class="org-right">18</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">10</td>
<td class="org-right">22</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">11</td>
<td class="org-right">29</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">12</td>
<td class="org-right">30</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">13</td>
<td class="org-right">31</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
</tr>

<tr>
<td class="org-right">14</td>
<td class="org-right">32</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
</tr>

<tr>
<td class="org-right">15</td>
<td class="org-right">42</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">16</td>
<td class="org-right">35</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">17</td>
<td class="org-right">38</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">18</td>
<td class="org-right">39</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">19</td>
<td class="org-right">60</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">20</td>
<td class="org-right">78</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">21</td>
<td class="org-right">50</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">22</td>
<td class="org-right">56</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
</tr>

<tr>
<td class="org-right">23</td>
<td class="org-right">58</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">24</td>
<td class="org-right">102</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">25</td>
<td class="org-right">73</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">26</td>
<td class="org-right">91</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">27</td>
<td class="org-right">94</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">28</td>
<td class="org-right">95</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">29</td>
<td class="org-right">98</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">30</td>
<td class="org-right">99</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">31</td>
<td class="org-right">110</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
</tr>

<tr>
<td class="org-right">32</td>
<td class="org-right">111</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">33</td>
<td class="org-right">116</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">34</td>
<td class="org-right">122</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">35</td>
<td class="org-right">125</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">36</td>
<td class="org-right">130</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">37</td>
<td class="org-right">141</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">38</td>
<td class="org-right">168</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">39</td>
<td class="org-right">145</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">40</td>
<td class="org-right">148</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">41</td>
<td class="org-right">157</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">42</td>
<td class="org-right">165</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">43</td>
<td class="org-right">167</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">V</td>
</tr>

<tr>
<td class="org-right">44</td>
<td class="org-right">175</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">45</td>
<td class="org-right">176</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">46</td>
<td class="org-right">179</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">47</td>
<td class="org-right">183</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">48</td>
<td class="org-right">228</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">49</td>
<td class="org-right">185</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
</tr>

<tr>
<td class="org-right">50</td>
<td class="org-right">246</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">51</td>
<td class="org-right">196</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">52</td>
<td class="org-right">202</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">53</td>
<td class="org-right">203</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">54</td>
<td class="org-right">206</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">55</td>
<td class="org-right">208</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">56</td>
<td class="org-right">213</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">57</td>
<td class="org-right">218</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">58</td>
<td class="org-right">288</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">59</td>
<td class="org-right">306</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">60</td>
<td class="org-right">248</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">61</td>
<td class="org-right">330</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">62</td>
<td class="org-right">249</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">63</td>
<td class="org-right">255</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
</tr>

<tr>
<td class="org-right">64</td>
<td class="org-right">355</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">65</td>
<td class="org-right">267</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
</tr>

<tr>
<td class="org-right">66</td>
<td class="org-right">277</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">67</td>
<td class="org-right">284</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">68</td>
<td class="org-right">285</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">69</td>
<td class="org-right">341</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-right">70</td>
<td class="org-right">338</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
</tr>

<tr>
<td class="org-right">71</td>
<td class="org-right">264</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">V</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="outline-container-org524f757" class="outline-2">
<h2 id="org524f757">Equivalencias de puntuación</h2>
<div class="outline-text-2" id="text-org524f757">
<p>
Esto nos deja una equivalencia de valores máximos como muestra la tabla
siguiente.
</p>

<table>


<colgroup>
<col  class="org-right">

<col  class="org-left">

<col  class="org-right">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-right">N</th>
<th scope="col" class="org-left">Escala</th>
<th scope="col" class="org-right">MMPI-2</th>
<th scope="col" class="org-right">MiniMult</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-right">&#xa0;</td>
<td class="org-left">L</td>
<td class="org-right">15</td>
<td class="org-right">4</td>
</tr>

<tr>
<td class="org-right">&#xa0;</td>
<td class="org-left">F</td>
<td class="org-right">60</td>
<td class="org-right">13</td>
</tr>

<tr>
<td class="org-right">&#xa0;</td>
<td class="org-left">K</td>
<td class="org-right">30</td>
<td class="org-right">16</td>
</tr>

<tr>
<td class="org-right">1</td>
<td class="org-left">Hs</td>
<td class="org-right">32</td>
<td class="org-right">12</td>
</tr>

<tr>
<td class="org-right">2</td>
<td class="org-left">D</td>
<td class="org-right">57</td>
<td class="org-right">19</td>
</tr>

<tr>
<td class="org-right">3</td>
<td class="org-left">Hy</td>
<td class="org-right">60</td>
<td class="org-right">22</td>
</tr>

<tr>
<td class="org-right">4</td>
<td class="org-left">Pd</td>
<td class="org-right">50</td>
<td class="org-right">18</td>
</tr>

<tr>
<td class="org-right">6</td>
<td class="org-left">Pa</td>
<td class="org-right">40</td>
<td class="org-right">14</td>
</tr>

<tr>
<td class="org-right">7</td>
<td class="org-left">Pt</td>
<td class="org-right">48</td>
<td class="org-right">15</td>
</tr>

<tr>
<td class="org-right">8</td>
<td class="org-left">Sc</td>
<td class="org-right">78</td>
<td class="org-right">17</td>
</tr>

<tr>
<td class="org-right">9</td>
<td class="org-left">Ma</td>
<td class="org-right">46</td>
<td class="org-right">11</td>
</tr>

<tr>
<td class="org-right">0</td>
<td class="org-left">Si</td>
<td class="org-right">67</td>
<td class="org-right">9</td>
</tr>
</tbody>
</table>

<p>
Las escalas que nos interesan y que tienen puntuaciones aquí son las
históricas tres de sinceridad: <i>L</i>, <i>F</i> y <i>K</i>; y las clínicas más
utilizadas: <i>Hs</i> (Hipocondría), <i>D</i> (Depresión), <i>Hy</i> (Histeria), <i>Pd</i>
(Psicopatía), <i>Pa</i> (Paranoia), <i>Pt</i> (Psicastenia), <i>Sc</i> (Esquizofrenia),
<i>Ma</i> (Hipomanía) y <i>Si</i> (Introversión Social).
</p>

<p>
A las escalas clínicas también se les suele asignar un número entre el 0
y el 9. Algunos verán que falta el 5 (que está asociada a la escala
<i>masculinidad</i> ─ <i>feminidad</i> que no la tendremos en cuenta). La de
<i>Introversión Social</i> tiene el 0 porque, como sabrán los psicólogos, se
comenzó a evaluar posteriormente, cuando ya estaban asignadas las
escalas entre 1 y 9, así podríamos considerarlo un «10» y no un «0».
</p>

<p>
Haré otro capítulo sobre la corrección de la prueba. En este primer paso
sólo he pensado un poquito sobre los ítem y he creado un poco de código
para tenerlo agrupados en una lista de cadenas como veremos a
continuación. Pero como avance, lo que debemos tener en cuenta es que
todas las instrucciones de corrección están pensadas para puntuaciones
del rango que vemos en la columna MMPI-2 de la tabla. Luego lo primero
que deberíamos tener es una conversión entre la puntuación directa dada
por el sujeto y la estimación que nos diga cuál sería la puntuación en
la prueba larga. Pero básicamente vemos que una regla de tres nos
permitiría hacerlo, así que no avanzamos más.
</p>
</div>
</div>
<div id="outline-container-org7857f20" class="outline-2">
<h2 id="org7857f20">Código</h2>
<div class="outline-text-2" id="text-org7857f20">
<p>
Pondré el código entero, con todas los ítem aunque soy consciente que un
listado largo, pero lo pongo fundamentalmente por si alguien quiere
«cortar-pegar» a su propio proyecto... Aunque debo recordar que todo
esto es «una prueba de concepto», esta prueba así presentada, no tiene
ningún tipo de validez (ni fiabilidad).
</p>

<p>
De momento, es lo único que contiene el fichero <code>minimult.el</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #ff79c6; font-weight: bold;">defvar</span> <span style="color: #f8f8f2; font-weight: bold;">preguntas</span>
  '(<span style="color: #f1fa8c;">"Tengo buen apetito."</span>
    <span style="color: #f1fa8c;">"Casi siempre me levanto por las ma&#241;anas descansado y como nuevo."</span>
    <span style="color: #f1fa8c;">"En mi vida diaria hay muchas cosas que me resultan interesantes."</span>
    <span style="color: #f1fa8c;">"Trabajo bajo una tensi&#243;n muy grande."</span>
    <span style="color: #f1fa8c;">"De vez en cuando pienso en cosas demasiado malas como para hablar de ellas."</span>
    <span style="color: #f1fa8c;">"Muy rara vez sufro de estre&#241;imiento."</span>
    <span style="color: #f1fa8c;">"A veces he deseado much&#237;simo abandonar el hogar."</span>
    <span style="color: #f1fa8c;">"A veces tengo accesos de risa y llanto que no puedo controlar."</span>
    <span style="color: #f1fa8c;">"Sufro ataques de n&#225;useas y v&#243;mitos."</span>
    <span style="color: #f1fa8c;">"Nadie parece comprenderme."</span>
    <span style="color: #f1fa8c;">"A veces siento deseos de maldecir."</span>
    <span style="color: #f1fa8c;">"A menudo tengo pesadillas."</span>
    <span style="color: #f1fa8c;">"Me cuesta bastante concentrarme en una tarea o trabajo."</span>
    <span style="color: #f1fa8c;">"He tenido experiencias muy peculiares y extra&#241;as."</span>
    <span style="color: #f1fa8c;">"Si los dem&#225;s no se la hubieran tomado conmigo, hubiese tenido m&#225;s &#233;xito."</span>
    <span style="color: #f1fa8c;">"Durante alg&#250;n tiempo, cuado era joven, particip&#233; en peque&#241;os robos."</span>
    <span style="color: #f1fa8c;">"He tenido per&#237;odos de d&#237;as, semanas o meses en los que no pod&#237;a preocuparme por las cosas, porque no ten&#237;a &#225;nimo para nada."</span>
    <span style="color: #f1fa8c;">"Mi sue&#241;o es irregular, inquieto."</span>
    <span style="color: #f1fa8c;">"Cuando estoy con gente escucho cosas extra&#241;as."</span>
    <span style="color: #f1fa8c;">"Le agrado a la mayor parte de la gente que me conoce."</span>
    <span style="color: #f1fa8c;">"A menudo he recibido &#243;rdenes de alguien que no sab&#237;a tanto como yo."</span>
    <span style="color: #f1fa8c;">"Me gustar&#237;a ser tan feliz como parecen ser los otros."</span>
    <span style="color: #f1fa8c;">"Pienso que una gran mayor&#237;a de gente exagera sus desgracias para lograr la simpat&#237;a y ayuda de los dem&#225;s."</span>
    <span style="color: #f1fa8c;">"Alguna vez me enojo."</span>
    <span style="color: #f1fa8c;">"Definitivamente no tengo confianza en m&#237; mismo."</span>
    <span style="color: #f1fa8c;">"Tengo pocas o ninguna molestia a causa de espasmos o contracciones musculares."</span>
    <span style="color: #f1fa8c;">"La mayor parte del tiempo me parece haber hecho algo malo o equivocado."</span>
    <span style="color: #f1fa8c;">"Soy feliz la mayor tiempo del tiempo."</span>
    <span style="color: #f1fa8c;">"Hay algunas personas tan mandonas que me dan ganas de hacer lo contrario de lo que quieren, aunque sepa que tienen raz&#243;n."</span>
    <span style="color: #f1fa8c;">"Alguien me la tiene jurada."</span>
    <span style="color: #f1fa8c;">"Para no perder un beneficio o ventaja, la mayor&#237;a de la gente est&#225; dispuesta a hacer cualquier cosa."</span>
    <span style="color: #f1fa8c;">"Tengo bastantes trastornos digestivos."</span>
    <span style="color: #f1fa8c;">"Frecuentemente no puedo comprender por qu&#233; he estado tan gru&#241;&#243;n y malhumorado."</span>
    <span style="color: #f1fa8c;">"A veces mi pensamiento ha ido m&#225;s r&#225;pido y delante de mis palabras."</span>
    <span style="color: #f1fa8c;">"Creo que mi vida hogare&#241;a es tan agradable como la de mucha gente que conozco."</span>
    <span style="color: #f1fa8c;">"A veces siento que verdaderamente soy un in&#250;til."</span>
    <span style="color: #f1fa8c;">"Durante los &#250;ltimos a&#241;os he estado sano casi siempre."</span>
    <span style="color: #f1fa8c;">"He tenido &#233;pocas durante las cuales ha realizado actividades que luego no recordaba haber hecho."</span>
    <span style="color: #f1fa8c;">"Creo que frecuentemente he sido castigado sin causa."</span>
    <span style="color: #f1fa8c;">"Nunca me he sentido mejor que ahora."</span>
    <span style="color: #f1fa8c;">"Me siento inc&#243;modo cuando tengo que hacer una payasada en una reuni&#243;n, incluso aunque otros la est&#233;n haciendo."</span>
    <span style="color: #f1fa8c;">"Mi memoria parece ser normal."</span>
    <span style="color: #f1fa8c;">"Me es dif&#237;cil entablar una conversaci&#243;n cuando acabo de conocer a alguien."</span>
    <span style="color: #f1fa8c;">"Siento debilidad general la mayor parte del tiempo."</span>
    <span style="color: #f1fa8c;">"Muy pocas veces me duele la cabeza."</span>
    <span style="color: #f1fa8c;">"No he tenido dificultades para mantener el equilibrio al caminar."</span>
    <span style="color: #f1fa8c;">"Me desagradan algunas personas que conozco."</span>
    <span style="color: #f1fa8c;">"Hay personas que est&#225;n intentando apoderarse de mis ideas y proyectos."</span>
    <span style="color: #f1fa8c;">"Me gustar&#237;a ser menos t&#237;mido."</span>
    <span style="color: #f1fa8c;">"Creo que mis pecados son imperdonables."</span>
    <span style="color: #f1fa8c;">"Con frecuencia, estoy preocupado por algo."</span>
    <span style="color: #f1fa8c;">"A menudo a mis padres les molest&#243; el tipo de amigos que ten&#237;a."</span>
    <span style="color: #f1fa8c;">"A veces soy un poco chismoso."</span>
    <span style="color: #f1fa8c;">"A veces me siento capaz de tomar decisiones con extraordinaria facilidad."</span>
    <span style="color: #f1fa8c;">"Raramente noto los latidos de mi coraz&#243;n y pocas veces se me corta la respiraci&#243;n."</span>
    <span style="color: #f1fa8c;">"Me enojo f&#225;cilmente, pero se me pasa pronto."</span>
    <span style="color: #f1fa8c;">"Hay momentos en que estoy tan nervioso que no puedo estar sentado mucho tiempo."</span>
    <span style="color: #f1fa8c;">"Mis padres y familiares encuentra en m&#237; m&#225;s defectos de los que deber&#237;an."</span>
    <span style="color: #f1fa8c;">"Nadie se preocupa mucho por lo que le suceda a otro."</span>
    <span style="color: #f1fa8c;">"No culpo a aquel que se aprovecha de otro que deja que se aprovechen de &#233;l."</span>
    <span style="color: #f1fa8c;">"A veces siento que se sobran energ&#237;as."</span>
    <span style="color: #f1fa8c;">"Mi vista es tan buena como lo ha sido durante a&#241;os."</span>
    <span style="color: #f1fa8c;">"No noto que me zumben los o&#237;dos frecuentemente."</span>
    <span style="color: #f1fa8c;">"Una o m&#225;s veces en mi vida sent&#237; que alguien me oblig&#243; a hacer cosas hipnotiz&#225;ndome."</span>
    <span style="color: #f1fa8c;">"Tengo &#233;pocas en las que me he sentido m&#225;s animado que de costumbre sin que exista una raz&#243;n especial."</span>
    <span style="color: #f1fa8c;">"Incluso cuando estoy con gente, me siento solo la mayor parte del tiempo."</span>
    <span style="color: #f1fa8c;">"Pienso que casi todo el mundo dir&#237;a una mentira para evitar problemas."</span>
    <span style="color: #f1fa8c;">"Soy m&#225;s sensible que la mayor&#237;a de la gente."</span>
    <span style="color: #f1fa8c;">"Durante ciertos per&#237;odos mi mente parece trabajar m&#225;s despacio que de costumbre."</span>
    <span style="color: #f1fa8c;">"La gente me decepciona con frecuencia."</span>
    <span style="color: #f1fa8c;">"He abusado del alcohol."</span>)
  <span style="color: #6272a4;">"Listado de preguntas del MiniMult."</span>)
</pre>
</div>
</div>
</div>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/psicología/index.html">psicología</a> <a href="/tags/tests/index.html">tests</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[psicología]]></category>
  <category><![CDATA[tests]]></category>
  <link>https://notxor.nueva-actitud.org/2017/01/22/minimult-2.html</link>
  <pubDate>Sun, 22 Jan 2017 21:24:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[MiniMult]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-01-20</div>
<div id="outline-container-org3aaff35" class="outline-2">
<h2 id="org3aaff35">Sobre el MMPI<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup></h2>
<div class="outline-text-2" id="text-org3aaff35">
<p>
Estos últimos <i>posts</i> que he ido haciendo casi por completo han versado
sobre <i>Emacs</i>. Éste sólo lo hará de manera tangencial. En realidad, el
título avanza que va sobre un <i>test</i>: El <i>MiniMult</i>.
</p>

<p>
Algunos conocerán un <i>test</i> de personalidad famoso en el gremio como es
el MMPI. Dicha prueba es una de las mejores que se pueden utilizar en
psicodiagnóstico. Las escalas de fiabilidad son increíbles y te aseguran
que la evaluación es pertinente o que no lo es. Pero a estas alturas
tiene algunos inconvenientes ─que se han intentado ir solucionando─.
Por ejemplo, uno de los inconvenientes es que ya tiene unos años, la
redacción de los ítem es anticuada, pasada de moda, sexista, etc. Para
solucionar esto, se hizo un lavado de cara con el MMPI-2, donde se
reformaron muchos ítem para modernizarlos o incluso se eliminaron
bastantes y se crearon nuevos.
</p>
</div>
</div>
<div id="outline-container-org37184ff" class="outline-2">
<h2 id="org37184ff">El MiniMult</h2>
<div class="outline-text-2" id="text-org37184ff">
<p>
Otro de los problemas que presenta el MMPI es su longitud: son más de
quinientas cuestiones formuladas como afirmaciones que el sujeto debe
calificar como <i>verdadero</i> ─o aplicado a mí eso es cierto, pienso así,
etc.─ <i>falso</i> ─o eso no se puede aplicar a mí, no pienso así, etc.─
procurando no dejar respuestas en blanco.
</p>

<p>
Hay ocasiones en que las 500 y pico preguntas son demasiadas para una
sola sesión. El paciente de veras tiene que ser <i>paciente</i>. Y se hace
insufrible cuando las preguntas deben ser leídas por el administrador de
la prueba porque el paciente esté limitado para leerlo él.
</p>

<p>
Así nació el llamado <i>MiniMult</i> que resume la prueba a 71 reactivos.
Para recortar tan drásticamente la cantidad de preguntas se eliminan
todas las escalas no clínicas, una clínica (secundaria a todos los
efectos, la de másculinidad-feminidad, que a estas alturas de partido,
no tiene realmente peso clínico) y reduciendo el número de reactivos que
quedan. Para ello se eligen las preguntas que puntúan en varias escalas
clínicas y las más significativas dentro de cada una.
</p>

<p>
Este resumen presenta una <i>fiabilidad</i> «test-retest» de entre 0.63 y
0.88, que es bastante alta. y una <i>validez</i> correlacionando con las
puntuaciones estándar de entre 0.20 y 0.96 (según estudios). Hay
diferencias en las correlaciones en varios colectivos. Sin embargo, en
el colectivo de pacientes clínicos, la correlación es bastante alta, que
es en lo que se supone que se utilizaría.
</p>

<p>
Hay otros resúmenes, como el <i>MidiMult</i> que tiene 86 reactivos o como el
<i>MaxiMult</i> que tiene 94 o también el <i>MMPI abreviado</i> que tiene 166.
</p>
</div>
</div>
<div id="outline-container-org62ce728" class="outline-2">
<h2 id="org62ce728">El proyecto</h2>
<div class="outline-text-2" id="text-org62ce728">
<p>
Si has llegado hasta aquí, después de todo ese ladrillo te estarás
preguntando y ¿a qué viene todo esto?
</p>

<p>
Pues básicamente comento todo esto porque he pensado en ver hasta dónde
llego con el famoso <i>elisp</i>. La idea es utilizar el modo <i>org</i> de
<i>Emacs</i> para gestionar <i>historias clínicas</i>. Una de las cosas que me
gustaría que se pudiera hacer no sólo guardar los resultados, sino que
se pudiera utilizar para pasar las pruebas por pantalla y corregirlas.
</p>

<p>
El MMPI es uno de los <i>tests</i> más complejos de corregir. Escalas que
modifican puntuaciones de otras escalas. Conversión de puntuaciones
crudas en puntuaciones <i>T</i>. Vamos, que lo he elegido porque no es algo
sencillo de hacer. ¿Qué misterio tendría hacer lo fácil? ¿Qué
aprendería?
</p>

<p>
Sin embargo, he elegido una versión reducida, porque ya me vale con 71
ítem para hacer una «prueba de concepto». Soy vago (bueno, <i>contenido en
esfuerzos</i> me gusta más ;-) y no quería eternizarme pasando al código
más de quinientas preguntas.
</p>

<p>
El <i>MiniMult</i> está basado en el MMPI original y yo lo que voy a hacer es
coger los ítem correspondientes al MMPI-2. Por lo que el resultado lo
podríamos llamar <i>MiniMult-2</i>. Evidentemente, harían falta pruebas de
<i>fiabilidad</i> y <i>validez</i> para poder utilizar el resultado de modo
clínico, pero como digo lo que estoy haciendo es una «prueba de
concepto» y determinar si puedo gestionar toda la información que se
necesita en una <i>historia clínica</i> con el famoso <i>org-mode</i> de <i>Emacs</i>.
Así que vamos a probar con algo difícil, porque manejar fechas de
visitas es algo que el sistema lo hará sin pestañear.
</p>

<p>
He pensado que las fases del proyecto podrían ser las siguientes:
</p>

<ol class="org-ol">
<li>Elección de los ítem correspondientes al test que queremos hacer.</li>
<li>Pasar la prueba por pantalla. Esto me permitirá aprender algunas
cosas sobre el sistema, por ejemplo:

<ul class="org-ul">
<li>Crear <i>buffer</i> temporal.</li>
<li>Trabajo con formularios.</li>
<li>Intercambio de información entre <i>buffers</i> para guardar las
respuestas en el de <i>historia clínica</i>.</li>
</ul></li>

<li>Corrección. Partiendo de los resultados de la fase anterior realizar
todos los cálculos encaminados a obtener los resultados finales:

<ul class="org-ul">
<li>Obtención de las puntuaciones crudas.</li>
<li>Ajustar esas puntuaciones en base a la escala <i>K</i>.</li>
<li>Convertir las puntuaciones finales en puntuaciones <i>T</i> para
cada escala.</li>
<li>Guardarlo en la <i>historia clínica</i>.</li>
</ul></li>

<li>Gráfico. Una de las cosas que más nos ayuda a la interpretación del
test a los profesionales es el gráfico. El sistema debería coger las
puntuaciones en las escalas y dibujar un gráfico.</li>
</ol>
</div>
</div>
<div id="outline-container-org149aa6f" class="outline-2">
<h2 id="org149aa6f">Conclusión</h2>
<div class="outline-text-2" id="text-org149aa6f">
<p>
En general es un proyecto complejo. Será lo primero serio que haré en
<i>Lisp</i>, lenguaje que conocí hace muchos años y que trasteé al principio
cuando empezaba en esto de la informática, pero que dejé de lado por
otros lenguajes como <i>Smalltalk</i> y C (sí ya, viejuno soy).
</p>

<p>
Iré poniendo mis avances (y retrocesos) por aquí. Por si alguien quiere
ir avanzando conmigo. También pondré el código y así alguien podrá
descubrir el porqué me dedico a la psicología y no a la programación.
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Inventario Multifásico de la Personalidad de Minnesota (por sus
siglas en inglés).
</p></div></div>


</div>
</div><div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/psicología/index.html">psicología</a> <a href="/tags/tests/index.html">tests</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[psicología]]></category>
  <category><![CDATA[tests]]></category>
  <link>https://notxor.nueva-actitud.org/2017/01/20/minimult.html</link>
  <pubDate>Fri, 20 Jan 2017 22:03:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[Utilizando org-mode para otras cosas]]></title>
  <description><![CDATA[
<div class="post-author">Notxor</div>
<div class="post-date">2017-01-09</div>
<p>
Una cosa que llevo tiempo buscando y/o pensando en que al final tendré
que hacerlo yo es algo que me permita llevar una serie de registros a
modo de <i>historia clínica</i>, de los casos que trabajo.
</p>

<p>
Hasta ahora el caos se ha adueñado de un directorio, lleno de ficheros
inconexos en formatos totalmente distintos: escritos, cartas, <i>tests</i>,
notas...
</p>

<p>
Mirando el modo <code>org-mode</code> de Emacs he visto que permite mantener
estructuras con propiedades añadidas. Hasta ahora no he probado cómo
funcionan pero quizá sea una herramienta a tener en cuenta. Además, dada
la posibilidad de aumentar las capacidades añadiendo código, me pregunto
si no sería un buen entorno para <i>pasar</i>, <i>corregir</i> y <i>consultar</i> los
tests, pruebas y visitas.
</p>

<p>
Por ejemplo, cada fichero de cada paciente podría empezar con una lista
de propiedades donde guardar los datos más básicos :
</p>

<pre class="example" id="orgf9d0f85">
* Historia Clínica
** Datos Personales
   :PROPERTIES:
   :NOMBRE:
   :APELLIDOS:
   :FECHA-NAC:
   :DNI:
   :DOMICILIO:
   :COD-POSTAL:
   :POBLACION:
   :TELEF-MOVIL:
   :TELEF-FIJO:
   :CORREO-E:
   :END:

** Anotaciones...
** Pruebas...
** Sesiones...
</pre>

<p>
<i>Lisp</i> sería un buen lenguaje de programación para gestionar tanto las
anotaciones como las sesiones, así como los <i>tests</i> que se puedan
realizar. Las sesiones son una lista de visitas con fechas donde se
puede hacer un resumen de qué tema se ha trabajado en ella. Las
anotaciones son una serie de aspectos que hay que trabajar o se han
trabajado, hay que insistir, se han superado, en fin, son listas de
cosas.
</p>

<p>
Más claro es el ejemplo de los tests. Un tests, generalmente es una
lista de <i>preguntas</i> que una vez contestado genera una lista de
<i>respuestas</i>, a las que se aplica una serie de cálculos ─algunas veces
complejos─ para conseguir una lista de valores o puntuaciones agrupadas
en <i>factores</i> o <i>escalas</i>, que en muchas ocasiones se emplean para
dibujar gráficos de perfil. Dicho de otra manera, creo que sería muy
factible el utilizar <i>elisp</i> para automatizar algunas de estas tareas.
Incluso utilizar las capacidades de <i>widgets</i> de texto que tiene
<code>org-mode</code> para pasar las pruebas por pantalla.
</p>

<p>
El tema de la confidencialidad de los datos sería otro de los puntos a
tratar. Los ficheros de texto plano estarían abiertos. La facilidad que
proporciona Emacs para abrir ficheros encriptados con GPG, cargarlos en
un <i>buffer</i> y guardarlo encriptado de nuevo sería una forma de tener los
datos salvaguardados sin mucho esfuerzo.
</p>

<p>
Lo siguiente será, por tanto, ponerme a repasar <i>Lisp</i>, y en concreto
<i>elisp</i>, para probar a crear el <i>corrector</i> de algún tipo de test.
</p>
<div class="taglist"><a href="/etiquetas.html">Categoría</a>: <a href="/tags/emacs/index.html">emacs</a> <a href="/tags/psicología/index.html">psicología</a> <a href="/tags/org-mode/index.html">org-mode</a> ]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[psicología]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://notxor.nueva-actitud.org/2017/01/09/utilizando-org-mode-para-otras-cosas.html</link>
  <pubDate>Mon, 09 Jan 2017 10:33:00 +0100</pubDate>
</item>
</channel>
</rss>
