Tutoriales

Presentaciones en Markdown con MARP

Juan Vera - juanvvc@gmail.com

Hoy hablamos de...

  1. Introducción a MARP
  2. Jugar con los estilos
  3. Tema personalizado
  4. En el día a día
  5. Notas adicionales

Introducción a MARP

¡Escribe presentaciones en Markdown!

## Marp Next

Presentaciones HTML, PDF y PPTX en Markdown

[![center width:20em](https://raw.githubusercontent.com/marp-team/marp/master/marp.png)](https://marp.app/)

- *marpit*: mini núcleo del sistema y sintaxis: <https://marpit.marp.app/>
- *marp-core*: API para Marpit: <https://github.com/marp-team/marp-core>
- *marp-vscode*: plugin para VSCode

<!--
El Marp original era una aplicación con editor incluido.
Marp Next uriliza VSCode con un plugin como editor.
-->

Mira el resultado en la siguiente transparencia

Marp Next

Presentaciones HTML, PDF y PPTX en Markdown

center

Edición en VSCode

center

Plugin: "Marp for VS Code". Previsualización con CMD+k+v

Compilación desde línea de comandos

# This command only works if you have marp-cli: npm install -g @marp-team/marp-cli
# You need chrome/chromium in your system for the PDF
MARP=marp
# This command needs "marp-cli" from docker: docker pull marpteam/marp-cli
#MARP=docker run --rm --init -v "$(PWD)":/home/marp/app/ marpteam/marp-cli

# You can overwrite these from the command line
# For example: make -e THEME=marp-upc
THEME=marp-viu
THEME_SET=themes
THEME_OPTS=--theme $(THEME) --theme-set "$(THEME_SET)"

# Convert all .md files in this directory
SRCS=$(shell find . -name '*.md')
OBJS=$(patsubst %.md,%.html,$(SRCS))

all: $(OBJS)

%.pdf: %.md
	$(MARP) "$<" -o "$@" --no-config $(THEME_OPTS) --pdf --allow-local-files --html --pdf-notes

%.html: %.md
	$(MARP) "$<" -o "$@" --no-config $(THEME_OPTS) --bespoke.progress true --html
	#--bespoke.transition

clean:
	/bin/rm -rf *.html *.pdf

.PHONY: all clean

Separación entre transparencias

Por defecto, la separación se hace con una línea de tres guiones ---

headingDivider: 2 en YAML: usa cabeceras para separar transparencias

Si necesitas una transparencia sin título siempre puedes usar las tres líneas ---

Listas

Las listas con guiones - o con 1. son estáticas

  • Uno
  • Dos
  • Tres

Las listas con asteriscos * o con 1) son animadas, pero solo en el HTML

  • Uno
  • Dos
  • Tres

Modo speaker

Pulsa p para entrar en el modo speaker: comentarios, hora, siguiente transparencia...

center

Imágenes en el interior

center

![center width:15em](https://raw.githubusercontent.com/marp-team/marp/master/marp.png)
![width:50px](https://raw.githubusercontent.com/marp-team/marp/master/marp.png)
![w:5em](https://raw.githubusercontent.com/marp-team/marp/master/marp.png)

Tamaños: pixeles y em, pero no porcentajes

Hay muchos atributos disponibles

Imágenes en el fondo: atributo bg

![bg saturate:0.9 contrast:0.3 brightness:1.5](https://picsum.photos/720?image=27)

También se puede hacer con directivas (lo veremos)

Imágenes en el fondo: bg right o bg left

![bg left:30% w:80%](https://freepngimg.com/...)

Si no se dice nada, la imagen ocupa todo el alto

Puede limitarse el ancho con w:VALOR%

Nota que con bg sí se pueden usar porcentajes

Imágenes en el fondo: múltiples

![bg left hue-rotate:240deg](https://freepngimg.com/...)
![bg left hue-rotate:320deg](https://freepngimg.com/...)
![bg left:50%](https://freepngimg.com/...)

No pueden combinarse left y right

Fíjate que la última tiene el total que ocuparán todas

GIFs, videos...

Esta transparencia también es un ejemplo de nueva transparencia sin título

<iframe width="400" height="300" src="https://www.youtube.com/watch?v=dQw4w9WgXcQ"> </iframe>

Jugar con los estilos

Uso de directivas

Controla el estilo de una transparencia con directivas justo después del título

Por ejemplo, añadir imagen de fondo:

<!--
backgroundImage: url('themes/back-starline.jpg')
_backgroundImage: url('themes/back-starline.jpg')
-->
  • En la cabecera YAML, activo para todas las transparencias
  • Sin guion bajo, activo a partir de ahora en todas las transparencias
  • Con guion bajo, solo activo en la transparencia actual

Background: Designed by starline / Freepik.

Cabecera con imagen

Otros ejemplos

# <!-- fit --> Otros ejemplos

<!--
_header: 'Cabecera con imagen ![width:5em grayscale invert brightness:2](themes/viu/logo-viu.png)'
_footer: 'Pie personalizado con [enlace](https://www.universidadviu.com/es/)'
_backgroundImage: "linear-gradient(to bottom, #67b8e3, #F288d1)"
_color: #fff
-->

Si quieres personalización total...

<style scoped>
    .mycustomspan {
        border: solid 1px orange;
        background-color: red;
        color: white;
    }
    /* segundo párrafo verde y centrado */
    p:nth-of-type(2) { text-align: center; margin: 0 2em 0 2em; color: green; }
    /* sin logo */
    section::before{ background-image:  none;}
</style>

Esto es un párrafo <span class="mycustomspan">y esto unas cuantas palabras</span>.

Esto es un párrafo <span class="mycustomspan">y esto unas cuantas palabras</span>.

Para que funcione el span se tiene que activar --html en las opciones del compilador Marp o en la sección Marp de VSCode. Es un riesgo si abres presentaciones de atacantes, porque pueden incluir cualquier script

  • Con scoped puedes por ejemplo cambiar completamente el estilo de las listas
  • ...mostrar las frases poco a poco...
  • ...paso a paso
  • ...una a una
  • imagino que ya entiendes la idea

Ejemplo sencillo de imágenes que aparecen en el centro

Tema personalizado

Tema personalizado

theme: marp-XXX en el preámbulo. Están disponibles:

  • marp-viu
  • marp-upc
  • marp-incide

En opciones de VSCode -> Marp, hay que incluir el path al tema. Fíjate en el archivo workspace

Idea principal: que todo sea Markdown, y solo cambiar "la clase" (el layout) de la transparencia

Clases / layouts especiales

  • lead / lead2 / first-slide | last-slide: inicio de sección. Ya hemos visto ejemplos
  • cool-list / cool-list2 para listas especiales
  • two-columns / two-columns-33: transparencia con dos columnas
  • two-columns-list: lista en dos o más columnas
  • smaller-font / smallest-font: transparencia con letra más pequeña
  • center: centra el contenido de texto en la transparencia
  • with-info / with-success / with-warning: el último párrafo es una caja info / success / warning

Utiliza blockquote para "notas a pie de página"
También incluye pequeños ajustes: muestra página actual, logotipo, atributo center para imágenes...

cool-list

  1. Uno
    • Uno y medio
    • y tres cuartos
  2. Dos
    1. Dos y medio
    2. Dos y un poco más
  3. Tres

Basado en: https://catalin.red/css3-ordered-list-styles/

cool-list2

Un estilo alternativo de lista

  1. Seis (nota que podemos empezar en cualquier número)
    • <style scoped>ol { counter-reset: li 5; }</style>
    • y tres cuartos
  2. Siete
    1. y medio
    2. y un poco más
  3. Ocho

Basado en: https://catalin.red/css3-ordered-list-styles/

two-columns

Uno Dos Tres Cuatro Cinco
1 2 3 4 5
1 2 3 4 5
  • <!-- _class: two-columns -->
  • La columna de la izquierda tiene que ser una lista, código, tabla, párrafo o imagen. Es decir, un elemento único.
  • La columna de la derecha también

El siguiente elemento único va después de todo y se extiende hasta el final de la transparencia.

Header de ejemplo

two-columns-33

  • Lo mismo que two-columns, pero la izquierda es más estrecha
  • Fíjate que aunque este elemento es una lista, puedes desactivar los puntos con <style scoped>ul {list-style-type: none;}</style>

Si tienes un header, añade la clase with-header como en este ejemplo

Footer de ejemplo, con link

two-columns-list

Listas largas que se organizan en dos o más columnas. Mira el código de esta transparencia para configuración

  1. Uno, uno, uno y uno y uno y uno y uno y uno
    • Uno
    • Dos
  2. Dos
  3. Tres
  4. Cuatro
    • Uno
  5. Cinco
  6. Seis
    • Uno
    • Dos
  7. Siete
  8. Ocho
  9. Nueve
    • Uno
    • Dos
  10. Diez
    • Uno
    • Dos
  11. Once
  12. Doce
  13. Trece
    • Uno
    • Dos

La lista externa es ol, la interna es ul. Al revés no funciona

two-columns-list y cool-list

Puedes combinar two-columns-list y cool-list

  1. Uno, uno, uno y uno y uno y uno y uno y uno
    • y otro
    • y otro
  2. Dos
  3. Tres
    • y otro
    • y otro
  4. Cuatro uno
    • y otro
    • y otro
  5. Cinco
    • uno, uno y uno y uno y uno y uno y uno y uno y uno, uno y uno y uno y uno y uno y uno

En este caso no puedes usar listas ol internas

smallest-font

(y también ejemplo de título fit y clase center y with-info)

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vel quam lobortis, egestas ex eu, dictum nisi. Nullam accumsan magna augue, vitae tempor arcu porttitor quis. Nam sit amet turpis sit amet tellus lacinia convallis. Nam suscipit sollicitudin orci, quis vehicula velit. Pellentesque viverra lacus nec velit fermentum suscipit sit amet eu erat. Mauris finibus massa eu eros luctus, nec congue velit lobortis. Quisque rhoncus velit porta tristique consectetur. Praesent sagittis facilisis ex in facilisis. Curabitur vel vulputate libero. Sed leo metus, maximus non lectus non, vestibulum scelerisque ipsum. Nunc convallis, felis vitae commodo iaculis, tellus nisl sollicitudin ligula, quis consectetur sem tellus vitae lorem. Duis rhoncus tristique volutpat. Nunc erat ante, pellentesque non ligula id, gravida vehicula lacus.

Tambien está la clase smaller-font, que es un poco más grande.

Cajas: success

<!-- _class: with-success -->

c1c2=(kgm1)(kgm2)=kgm1kgm2=kgkgm1m2=(kgkg)(m1m2)=({000000})(m1m2)=m1m2 \begin{aligned} c_1 \oplus c_2 &= (k_{\text{g}} \oplus m_1) \oplus (k_{\text{g}} \oplus m_2) \\ &= k_{\text{g}} \oplus m_1 \oplus k_{\text{g}} \oplus m_2 \\ &= k_{\text{g}} \oplus k_{\text{g}} \oplus m_1 \oplus m_2 \\ &= (k_{\text{g}} \oplus k_{\text{g}}) \oplus (m_1 \oplus m_2) \\ &= (\{000\cdots000\}) \oplus (m_1 \oplus m_2) \\ &= m_1 \oplus m_2 \end{aligned}

Por supuesto, puedes añadir fórmulas matemáticas, tanto en párrafos como inline 2×2=42 \times 2 = 4 y también utilizar emojis 🙆 🏃 💓 y símbolos ⇛ ❤ ⚝

Cajas: warning

<!-- _class: with-warning -->

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vel quam lobortis, egestas ex eu, dictum nisi. Nullam accumsan magna augue, vitae tempor arcu porttitor quis.

⚠ Solo puede haber una caja warning, info o success por transparencia. Solo el último párrafo se mete en una caja.

En el día a día

En el día a día

Sí, puedes añadir fondos personalizados a los inicios de secciones

En el día a día

Comparando con RevealJS

  • Marp no ofrece animaciones entre transparencias, RevealJS sí
    • Esto puede cambiar cuanto se adopte la Element Transition API en los navegadores. La versión 1.4.0 (2021) de Marp ya incluye animaciones pero solo en Chrome
  • HackMD no soporta directamente Marp, pero sí RevealJS
  • El plugin para VSCode de Marp es muy superior y eso convierte a Marp (¡opinión!) en más productivo: exportación a PDF perfecta, preview más rápido
  • RevealJS tiene ayudas espectaculares durante la presentación: alarmas, modo pizarra, movimiento en dos dimensiones...
  • RevealJS es mucho más flexible con el layout de una transparencia, a cambio de escribir más HTML
  • Los temas Marp los tengo mucho más desarrollados

Mi opinión: es mucho más rápido ESCRIBIR una presentación tradicional en Marp, pero es más fácil y dinámico PRESENTAR con RevealJS.

En el día a día

Convertir de RevealJS a Marp y viceversa

  • Casi todas las transparencias podrán copiarse sin más
  • Sintaxis diferente, pero similar, en imágenes y clases especiales
  • Las transparencias que utilicen cosas específicas como animaciones tendrán que repensarse

Ejemplo de two-columns con imagen, alternativa a bg right

En el día a día

Ejemplos de conversiones

RevealJS:

< !-- .slide:data-state="lead" -->
# Título

![](imagen.jpg){width=70%}

Marp:

# Título
< !-- _class: lead -->

![width:20em](imagen.jpg){}
Notas adicionales

Notas adicionales

Notas adicionales
  • En 2022, las transparencias son simples, sin sombras, sin animaciones...
  • No luches contra el sistema de presentaciones: si no puedes hacer algo, no pierdas demasiado tiempo buscando cómo
  • Puedes usar header: Título de sección como directiva en las transparencias de sección y aparecerá a partir de ese momento. Mira el header de esta transparencia
  • http://www.jilles.net/perma/2020/06/05/presentation-rules.html
Notas adicionales

Pizarra

Puede añadirse JavaScript genérico en la última transparencia

<script src="whiteboard.js"></script>

Por ejemplo, modo pizarra (experimental):

  • n: activa pizarra transparente
  • k: activa pizarra negra
  • c: vuelve al modo normal
  • 1, 2, 3, 4, 5: colores
Notas adicionales

¡Gracias!

<script src="whiteboard.js"></script>

Esta misma presentación sirve como ejemplo de qué se puede hacer Esto es una nota de orador. Aparecen pulsando P... pero solo si el HTML no se ha abierto con protocolo file://. También aparecen en el PDF como annotations. Algunos visores PDF como pympress o el PDF de OSX aceptan anotaciones, pero otros como Okular no.

MARP utiliza Common Markdown, el dialecto con mayor compatibilidad y por tanto menos características de Markdown

El Marp original era una aplicación con editor incluido. Marp Next utiliza VSCode con un plugin como editor.

El plugin permite: - Previsualización instantánea - Compilación a PDF, HTML o PPTX. PDF y PPTX necesitan tener instalado Chrome

Además, la opción -p abre una ventana de navegador, y la opción -s un servidor que se queda escuchando para cambios.

Fíjate también: los textos se centran verticalmente en los temas por defecto En esta presentación de ejemplo se utilizan los títulos para separar transparencias porque me parece más cómodo. Fíjate en el headingDivider de la cabecera YAML de esta presentación

Es decir, los asteriscos no mostrarán los items de la lista uno a uno ni en la previsualización ni en el PDF Puedes combinar - y * en la misma lista, y así algunos items aparecen siempre, si quieres.

Esto es un comentario visible en el modo presentación Desde línea de comandos, `--bespoke.progress true` añade una barra de progreso. Mira en la parte de arriba de la transparencia

En Marp, la parte entre corchetes [] puede contener atributos adicionales: clases para aplicar sobre la imagen, tamaños, posiciones... Nota que esto es una diferencia con respecto a otros dialectos como HackMD o RevealJS, que usan llaves {} para los atributos adicionales. Puedes usar width o w, height o h

El orden de los filtros gráficos importa. No es lo mismo desaturar y después contrastar que al revés

Nota: VSCode no soporta previsualización de GIFs cuando están en el background Los vídeos necesitan la activación del código HTML en VSCode o en línea de comandos (mira el Makefile). En local, pueden no funcionar si abres la presentación con protocolo file:// También puedes usar etiqueda <video> para vídeos en local

Solo lo pongo como ejemplo, la idea de los temas personalizados en no necesitar (casi nunca) esto

Fíjate: el primer item es un guion para que aparezca desde el principio

ejemplo de qué puede hacerse pero no recomiendo su uso

Hay que meter obligatoriamente los items entre asteriscos o enlaces Se puede usar en el índice

- Cualquier elemento después del último volverá a estar en formato columnas - Para poner párrafos en las columnas, usa listas pero oculta los puntos: <style scoped> ul { list-style-type: none; } li {margin-bottom: 1em} </style>

La diferencia entre emojis y símbolos es operativa de editores de texto: mientras que los emojis se entrar escribiendo :emoji:, los símbolos se copianpegan de alún sitio como https://unicode-table.com. En realidad, todo es unicode. En la lista anterior he usado adrede símbolos que la fuente por defecto no tiene instalada, para probar cómo salen

Las animaciones entre transparencias las tiene que ofrecer "una librería de alto nivel" que use Marp: https://github.com/marp-team/marp-core/issues/110

Para que funcione la pizarra tienes que activar el código HTML. Mira el Makefile