-
Notifications
You must be signed in to change notification settings - Fork 0
/
ch_directivas.rst
582 lines (308 loc) · 19.8 KB
/
ch_directivas.rst
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
Directivas
==========
Las directivas son instrucciones especiales de reStructuredText que comienzan por ``..`` y un espacio, seguido del nombre de la directiva, que terminan con ``::``, y cualquier argumento que se reciba. Es decir:
.. code-block:: rst
.. directiva:: argumentos
Además, pueden tener opciones, mismas que se delimitan por ``:`` al inicio y al final, además del contenido. Por lo tanto, la "forma completa" de una directiva es:
.. code-block:: rst
.. directiva:: argumentos
:opcion1:
:opcion2:
contenido
Antes de empezar este capítulo es necesario informarte que no podrás probar varias de las directivas aquí mencionadas. Esto es porque requieren de archivos locales ubicados en la misma carpeta que tu archivo de reST. Y, no, los editores en línea no cuentan con esa facilidad.
Una vez hecha la advertencia, la primer directiva que veremos es ``image``.
Imágenes
--------
La directiva ``image`` se utiliza con un argumento obligatorio: el directorio o dirección donde se ubica la imagen. Por ejemplo, aquí debajo incluyo mi logo personal, alojado en mi dominio:
.. code-block:: rst
.. image:: http://ramoscarlos.com/logo.png
Con eso basta para que reST pueda ir por la imagen y colocarla en el HTML final. No obstante, y dependiendo del ancho de tu pantalla, el editor en línea puede mostrar el contenido desbordado.
Esto pasa porque reST no le hace ningún tipo de procesamiento o escalado a la imagen. Para este libro, aunque aún no se ha especificado ninguna opción, la imagen aparece del ancho de la línea (magia de LaTeX):
.. image:: http://ramoscarlos.com/logo.png
Dado que el desbordamiento es molesto, te muestro las opciones que permiten darle formato a la imagen:
:height: es el alto de la imagen, utilizado para reservar espacio vertical para la imagen. Cuando se utiliza en conjunto con la opción de ``scale``, ambos se aplican (por ejemplo, escala al 40% de 100px da 40px).
:width: es el ancho de la imagen, y puede ser en términos absolutos o en porcentaje. De manera análoga a la altura, se combina con la opción de escala.
:scale: es un factor de escalamiento, en porcentaje, que se aplicará a la imagen (el símbolo de porcentaje puede omitirse). El valor predeterminado es 100% (sin escalamiento).
:align: la alineación de la imagen, puede tener los siguientes valores: ``top``, ``middle``, ``bottom``, ``left``, ``center``, o ``right``. Los primero tres valores hacen referencia a la alineación vertical, mientras que los últimos tres hacen referencia a su posición horizontal.
:alt: es un texto alternativo a utilizar en caso de que no se pueda desplegar la imagen. También es texto que se lee por aplicaciones de asistencia visual.
:target: convierte la imagen en un enlace hacia la URL especificada.
Después de haber visto las opciones, lo primero que probaremos es el uso de ``alt`` sobre una imagen inexistente. Por ejemplo:
.. code-block:: rst
.. image:: http://yo-no-existo.com/ni-existire.gif
:alt: Referencia a imagen inexistente.
Al colocar el código de la imagen, lo único que se desplegará es el texto:
.. raw:: latex
\begin{sphinxVerbatim}
Referencia a imagen inexistente.
\end{sphinxVerbatim}
.. image:: http://yo-no-existo.com/ni-existire.gif
:alt: Referencia a imagen inexistente.
Para resolver el problema de la imagen que desborda los márgenes usamos la opción ``width``, con un valor del 60% del ancho, y no más. Como no estamos especificando la alineación, la imagen se mostrará a la izquierda. Como buena práctica, trata de siempre colocar un texto alternativo:
.. code-block:: rst
.. image:: http://ramoscarlos.com/logo.png
:width: 60%
:alt: Logo de ramoscarlos.com
.. image:: http://ramoscarlos.com/logo.png
:width: 60%
:alt: Logo de ramoscarlos.com
Imágenes locales
^^^^^^^^^^^^^^^^
La directiva ``image`` no sirve únicamente para colocar imágenes provenientes de Internet. Por supuesto, esto no es algo que se pueda probar en el editor en línea. No obstante, haciendo uso de Sphinx podrías incluir cualquier imagen dentro de tu disco duro, con la trayectoria completa (empezando desde ``C:/``, si fuera Windows) o, lo más común, desde un directorio relativo a tu proyecto.
En caso de trabajar localmente, lo más común es guardar las imágenes en el subdirectorio ``img`` (o algo por el estilo) relativo a tu archivo reST. Y ya, automáticamente reStructuredText sabe en qué lugar ir a buscar el archivo de tu imagen. Una muestra de tal sintaxis sería:
.. code-block:: rst
.. image:: img/nombre-de-imagen.png
Figuras
-------
Una figura es una imagen con una leyenda debajo. Su sintaxis es similar a la directiva ``image``, y acepta sus opciones, solo que agrega el contenido de la directiva, que corresponde a la leyenda que se colocará debajo de la imagen:
.. code-block:: rst
.. figure:: img/nombre-de-imagen.png
Leyenda de la figura.
Podemos tomar uno de los ejemplos anteriores, y duplicar el texto de la opción ``alt`` para usarla como el contenido de la directiva (leyenda):
.. code-block:: rst
.. figure:: http://ramoscarlos.com/logo.png
:width: 60%
:alt: Logo de ramoscarlos.com
Logo de ramoscarlos.com (con leyenda)
Y listo, tenemos una imagen con leyenda:
.. figure:: http://ramoscarlos.com/logo.png
:width: 60%
:alt: Logo de ramoscarlos.com
Logo de ramoscarlos.com (con leyenda)
Código fuente (embebido)
------------------------
No solamente podemos incluir código como :ref:`texto preformateado <texto-preformateado>` sino que podemos colocar código fuente formalmente, con resaltado de sintaxis, gracias a la directiva ``code``, que recibe como argumento el lenguaje en que el código está escrito.
Dado que el código se resalta con la librería Pygments_, los lenguajes disponibles son los mismos de esta librería... que son bastantes.
Pongamos por ejemplo un fragmento de código C:
.. code:: c
int main() {
return 0;
}
Ese código se muestra con la sintaxis adecuada gracias a su argumento:
.. code-block:: rst
.. code:: c
int main() {
return 0;
}
Incluso podemos resaltar reStructuredText:
.. code:: rst
Esto está en *italicas* y esto en **negritas**.
Donde el código detrás es:
.. code-block:: rst
.. code:: rst
Esto está en *italicas* y esto en **negritas**.
.. note::
El editor en línea no carga las sintaxis debido a que esto implica más procesamiento y es un poco más difícil de lograr. Lo sé, es un tanto frustrante. Pero, ¿no te deja con ganas de probar Sphinx?
Opción ``number-lines``
^^^^^^^^^^^^^^^^^^^^^^^
La directiva ``code`` tiene la opción ``number-lines``, la cual nos permite colocar números de línea. Volviendo al ejemplo de C, podemos agregar los números de línea con:
.. code-block:: rst
.. code:: c
:number-lines:
int main() {
return 0;
}
Lo que ahora muestra el código como:
.. code:: c
:number-lines:
int main() {
return 0;
}
También podemos cambiar el número inicial agregando el argumento después de los dos puntos de la opción:
.. code-block:: rst
.. code:: c
:number-lines: 50
int main() {
return 0;
}
Lo que ahora despliega la primera línea como la 50:
.. code:: c
:number-lines: 50
int main() {
return 0;
}
Es importante colocar al menos un espacio entre el número inicial y ``number-lines``, de lo contrario tendrás una advertencia sobre exceder el número de argumentos y tu código no se verá:
.. code-block:: none
WARNING: Error in "code" directive:
maximum 1 argument(s) allowed, 2 supplied.
.. code:: c
:number-lines:50
int main() {
return 0;
}
Código fuente (archivo externo)
-------------------------------
Si prefieres insertar código de un archivo fuente en lugar de copiar y pegar fragmentos entonces la directiva ``include`` es lo que buscas. Sí, lo sé, esto no lo puedes probar en línea.
Su sintaxis es similar a la directiva ``image``, en el sentido de que su argumento requerido es la trayectoria del archivo relativo al archivo fuente (aunque aquí no se permiten recursos en línea).
Recomiendo guardar el código fuente en un subdirectorio. En este libro se hace referencia al directorio ``src``. Para esta demostración tomé el código fuente de un ejemplo de alcance de la `documentación oficial de Python <https://docs.python.org/3/tutorial/classes.html#scopes-and-namespaces-example>`_ y lo guardé como ``demo.py`` en la carpeta antes mencionada. Para incluir el archivo usamos la directiva ``include`` con la trayectoria relativa al archivo:
.. code-block:: rst
.. include:: src/demo.py
Lo que nos incluye el código:
.. include:: src/demo.py
Yo sé que eso que está justo arriba no tiene sentido. Se imprime el código, o un intento de, pero no hay resaltado de sintaxis, y también se eliminaron bastantes saltos de línea. Esto fue porque el interprete creyó que el texto seguía las reglas de reStructuredText (claro, no le hemos dicho lo contrario).
La verdad es que la directiva ``include`` se puede utilizar para hacer un gran documento de reST en base a otros, y quizá esa era su intención, pero el uso más común de la directiva viene siendo incluir código (pido perdón a los diseñadores). Esto es, sin especificarle a ``include`` que estamos incluyendo código, el compilador cree que es más contenido reST que debe procesar.
Opción ``code``
^^^^^^^^^^^^^^^
Los errores de visualización del ejemplo anterior se pueden arreglar con la opción ``code`` (que vendría a trasformar la directiva ``include`` en una directiva ``code``, básicamente), que toma como argumento el lenguaje con el cual resaltar el archivo incluído. Recordemos que el resaltado se realiza gracias a Pygments, así que cualquier lenguaje que funciona para la directiva ``code`` funciona con la opción ``code`` del ``include``. Reescribiendo:
.. code-block:: rst
.. include:: src/demo.py
:code: python
Con esto ya podemos ver nuestro archivo como código Python (puedes comprobar, si así lo deseas, que el código que se muestra debajo es similar al código que parece no tener sentido):
.. include:: src/demo.py
:code: python
Opción ``number-lines``
^^^^^^^^^^^^^^^^^^^^^^^
También acepta el número de línea inicial a mostrarse, similar al entorno ``code``, con la opción ``number-lines``:
.. include:: src/demo.py
:code: python
:number-lines:
No obstante, aquí se aprecia una diferencia contra ``code``: el resaltado de sintaxis se pierde, y la selección del texto incluye los números de línea.
La lección: usar ``code`` si se requieren números de línea.
Opciones ``start-line`` y ``end-line``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
También podemos incluir un fragmento, especificando de qué a qué línea. Por ejemplo, si solo queremos ver la función ``do_global``, que se encuentra de las líneas 9 a 11, usamos la opción ``start-line`` con un valor de 8, porque el conteo empieza en 0, y ``end-line`` con 12, dado que el número de línea que recibe como argumento no se imprime:
.. code-block:: rst
.. include:: src/demo.py
:code: python
:start-line: 8
:end-line: 12
Lo que nos muestra el código de la función como deseamos:
.. include:: src/demo.py
:code: python
:start-line: 8
:end-line: 12
Lamentablemente, el resaltado de sintaxis se pierde al usar estos parámetros debido a que no sabe qué hacer con los diferentes niveles de indentación. Es decir, este método no es tan confiable para mostrar ciertas líneas y a la vez colorearlas. Ugh.
Opciones ``start-after`` y ``end-after``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Pero si queremos siempre imprimir la función ``do_global``, independientemente del número de línea, ¿cómo le hacemos?
Existe otra opción que incluye código en base a cadenas de texto, llamada ``start-after``, así podemos usar ``:start-after: "non-local spam"`` para empezar en nuestra línea de función:
.. code-block:: rst
.. include:: src/demo.py
:code: python
:start-after: "nonlocal spam"
Aunque también perdemos el coloreado, aunque el código es correcto:
.. include:: src/demo.py
:code: python
:start-after: "nonlocal spam"
Podemos aplicar la misma lógica para definir el contenido hasta la línea que ya no queremos imprimir, en este caso ``spam = "test spam"``:
.. code-block:: rst
.. include:: src/demo.py
:code: python
:start-after: "nonlocal spam"
:end-before: spam = "test spam"
Y el resultado es similar a haber utilizado los números de línea:
.. include:: src/demo.py
:code: python
:start-after: "nonlocal spam"
:end-before: spam = "test spam"
Opción ``tab-width``
--------------------
La opción ``tab-width`` nos permite establecer el ancho de las tabulaciones, que de manera predeterminada es de ocho espacios (como en el código incluido previamente). Por ejemplo, para establecer la tabulación a dos espacios usaríamos:
.. code-block:: rst
.. include:: src/demo.py
:code: python
:tab-width: 2
Incluyendo el mismo archivo, se nota la diferencia de reducir los espacios:
.. include:: src/demo.py
:code: python
:tab-width: 2
En caso de que este ajuste parezca no funcionar habrá que revisar si el archivo en realidad contiene tabulaciones... y si es así, ¡usa espacios! Es broma, es broma.
HTML o LaTeX con ``raw``
------------------------
Si sientes la imperiosa necesidad de colocar HTML en tu documento de reST, no es así de simple. Probemos con una regla horizontal en HTML:
<hr>
Sí, no funciona. Para insertar HTML directo se puede utilizar la directiva ``raw``, con el argumento del lenguaje que se utilizará para interpretar el contenido, que en este caso es ``html``:
.. code-block:: rst
.. raw:: html
<hr>
Y ahora sí, eso da como resultado la regla horizontal:
.. raw:: html
<hr>
... por supuesto, para los lectores del PDF no hay nada entre el párrafo anterior y este. Eso es porque el PDF compila LaTeX, no HTML (razón para no usar HTML directo). Pero si queremos una línea horizontal en el PDF podemos usar ``\rule`` en un entorno LaTeX:
.. code-block:: rst
.. raw:: latex
\noindent{\rule{\linewidth}{0.4pt}}
Y eso nos da una línea horizontal en el PDF, pero no en la página web de HTML:
.. raw:: latex
\noindent{\rule{\linewidth}{0.4pt}}
De esta manera podemos incluir tanto HTML y LaTeX como nuestro corazón desee. Por supuesto, si se desea compilar tanto en HTML como en LaTeX, habrá que proveer ambas opciones, en cada lenguaje. Por ejemplo, podríamos poner las dos instrucciones seguidas:
.. code-block:: rst
.. raw:: html
<hr>
.. raw:: latex
\noindent{\rule{\linewidth}{0.4pt}}
De esta manera, tanto en HTML como en LaTeX tenmos nuestra regla debajo:
.. raw:: html
<hr>
.. raw:: latex
\noindent{\rule{\linewidth}{0.4pt}}
Amonestaciones
--------------
Las amonestaciones son notas o temas especiales que aparecen marcados a lo largo del texto. En el caso de HTML, puedes imaginar cajas de colores: roja para errores, amarilla para advertencias, azules para información. En el caso de libros, puedes pensar en pequeños textos como en las series "Para Dummies", que incluyen consejos, advertencias, o simples notas a considerar.
La amonestación no es una sola directiva, son un conjunto formado por las siguientes: ``attention``, ``caution``, ``danger``, ``error``, ``hint``, ``important``, ``note``, ``tip``, y ``warning``.
Dependiendo de tu tema en HTML, cada una de estas amonestaciones tiene un estilo diferente, y se mandan llamar de la siguiente forma:
.. code-block:: rst
.. nombre-del-tipo-de-amonestación::
Contenido de la amonestación.
Por ejemplo, para crear un cuadro de atención, usamos su nombre como directiva:
.. code-block:: rst
.. attention::
Contenido de la amonestación.
Y ahora veremos el estilo que cada una de estas diferentes amonestaciones puede tener (que, de nuevo, varían según tu tema):
.. attention::
Contenido de la amonestación ``attention``.
.. caution::
Contenido de la amonestación ``caution``.
.. danger::
Contenido de la amonestación ``danger``.
.. error::
Contenido de la amonestación ``error``.
.. hint::
Contenido de la amonestación ``hint``.
.. important::
Contenido de la amonestación ``important``.
.. note::
Contenido de la amonestación ``note``.
.. tip::
Contenido de la amonestación ``tip``.
.. warning::
Contenido de la amonestación ``warning``.
Ahora bien, cada una de las amonestaciones anteriores colocan el título y un estilo predeterminado. No obstante, nos queda una última amonestación, la cual es genérica. ¿Qué quiere decir? Que no contiene un título, por lo que recibe el título de la amonestación como parámetro requerido:
.. code-block:: rst
.. admonition:: Título de la amonestación.
Contenido de la amonestación ``admonition``.
Lo que da como resultado:
.. admonition:: Título de la amonestación.
Contenido de la amonestación ``admonition``.
Matemáticas
-----------
Sí, reStructuredText también sirve para lidiar con complejas ecuaciones matemáticas... bueno, más o menos. Para ello hace uso de LaTeX. Así que, si conoces LaTeX, estás salvado y solo tienes que saber que puedes incluir ecuaciones con la directiva ``math``:
.. code-block:: rst
.. math::
\frac{1}{2} + \frac{1}{4} + \ldots = \sum_{n=1}^{\infty} \left(\frac{1}{2}\right)^n = 1
Lo que, por supuesto, se resuelve a:
.. math::
\frac{1}{2} + \frac{1}{4} + \ldots = \sum_{n=1}^{\infty} \left(\frac{1}{2}\right)^n = 1
Si desconoces LaTeX, `escribí un libro que podría ayudarte con ello`_.
Extensibilidad
--------------
En los primeros capítulos se hablo de la extensibilidad de reST pero no ahondamos mucho en ese tema. Como vimos al inicio de este capítulo, una directiva es algún nombre entre ``..`` y ``::``. En teoría, podemos hacer una directiva para mostrar una lista de asistencia de tres semanas:
.. code-block:: rst
.. lista-de-asistencia::
:grado: 5
:grupo: G
Juanito Pérez
Marianita López
Y, de alguna manera mística, que eso se convierta en una tabla con fechas y todo, ¿por qué no? Bueno... porque esto sí implica saber programar en Python y ser capaz de poder seguir la gúia de `Creating reStructuredText Directives`_ (sí, en inglés).
Entonces, mientras que Markdown lograba más funcionalidad debido a sus sabores y adiciones por terceros, reST cuenta con un sistema para ser extendido. Incluso hay formas de que tus contribuciones se añadan a un repositorio oficial, y que lo instale quien necesita.
Claro, para eso ya hablamos más de Sphinx, y la mayoría de las extensiones están en inglés, pero hay bastantes disponibles. Puedes encontrar lo que la comunidad ha cooperado en `sphinx-contrib`_.
Resumen
-------
En este capítulo vimos las directivas de reST, que resultan no ser solo instrucciones más potentes sino que son la base del mecanismo de extensibilidad del lenguaje.
Aunque en esta obra nos limitamos a las directivas definidas en la especificación de reST, nada nos detiene de ir a husmear qué es lo que otras personas han considerado pertinente agregar a este lenguaje.
.. #######################################################################
.. ### Enlaces externos ##################################################
.. #######################################################################
.. _Pygments: https://pygments.org/languages/
.. _escribí un libro que podría ayudarte con ello: https://leanpub.com/tesis-en-latex/
.. _Creating reStructuredText Directives: https://docutils.sourceforge.io/docs/howto/rst-directives.html
.. _sphinx-contrib: https://github.com/sphinx-contrib/