Saltar al contenido principal

Typst

Instalación​

Binario global​

  • Arch Linux: sudo pacman -S typst
  • macOS: brew install typst
  • Windows: winget install --id Typst.Typst

Editores de código​

  • Visual Studio Code: instalar la extensión myriad-dreamin.tinymist

Notas​

  • Los archivos usan la extensión .typ
  • Exportar documentos básicos a Word con Pandoc pandoc tarea.typ -o tarea.docx

Texto​

  • Negrita: *Negrita*
  • Cursiva: _Cursiva_
  • Código inline: encerrar entre acentos graves simples. Ejemplo: `fn main() {}`
  • Salto de línea:
Contenido separado
\
en varias
\ \ \
líneas
  • Texto personalizado:
#text(size: 15pt, weight: "bold")[Texto o contenido con estilo personalizado]

#align(center)[
#text(size: 22pt, weight: "bold")[Ejemplo básico de Typst]
#v(0.3em)
_Un documento corto sobre lenguajes de programación_
]
  • Alineación:
#align(center)[
#text(size: 16pt, weight: "bold")[Contenido o título centrado]
]

Estructura​

  • Títulos:
= Título Nivel 1
== Título Nivel 2
=== Título Nivel 3
==== Título Nivel 4
===== Título Nivel 5
====== Título Nivel 6
  • Lista desordenada:
- Elemento 1
- Subelemento 1.1
- Subelemento 1.2
- Subelemento 1.2.1
- Subelemento 1.2.2
- Elemento 2
- Elemento 3
  • Lista ordenada:
+ Elemento 1
+ Subelemento
+ Subelemento
+ Subelemento del subelemento
+ Subelemento del subelemento
+ Elemento 2
+ Elemento 3

Bloques de código​

Encerrar el código entre tres acentos graves, igual que en Markdown:

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

Estilos

#show raw: set text(size: 10pt)
#show raw.where(block: true): it => {
block(
fill: luma(210),
inset: 8pt,
radius: 4pt,
width: 100%,
it,
)
}

Imagen​

La imagen ocupa su tamaño original.

#image("img/zero.svg")

La imagen ocupa todo el alto disponible, pero si el ancho de la imagen es mayor que el ancho disponible, se recortará, por lo que se corrige con el parámetro "fit: contain" para que la imagen se ajuste al contenedor sin recortarse y manteniendo su proporción original.

#image("img/zero.svg", height: 100%, fit: "contain")

La imagen ocupa todo el ancho disponible.

#image("img/zero.svg", width: 100%)

Tablas​

Dependiendo la forma en que se definan las columnas pueden adaptarse al contenido u ocupar todo el ancho de la página:

  • columns: 3 se adaptará al contenido de cada columna y puede que no ocupe todo el ancho de la página.
  • columns: (auto, 1fr) con auto las columnas se adaptarán al contenido de la columna, pero las columnas definidas con fr pueden ocupar mucho más que su contenido lo que puede hacer que ocupen todo el ancho de la página.

Para la fila header de la tabla se puede utilizar table.header que muestra automáticamente los encabezados en la siguiente página si se corta la tabla. Pero si es una tabla sencilla, la primera fila se puede definir como cualquier otra fila.

#table(
columns: 2,

[*Crate*], [*Descripción*],

[serde], [Serialización y deserialización de datos],
[tokio], [Runtime asíncrono para Rust],
[reqwest], [Cliente HTTP fácil de usar],
)
#table(

columns: (auto, 1fr, 1fr),

align: (left, center, center),

fill: (x, y) => if x == 0 or y == 0 {
luma(210)
},

table.header([*Tipo*], [*Descripción*], [*Ejemplo*]),

[i32], [Entero de 32 bits con signo], [let x: i32 = 42;],
[f64], [Flotante de 64 bits], [let y: f64 = 3.14;],
[bool], [Booleano], [let is_active: bool = true;],
[char], [Carácter Unicode], [let letter: char = 'A';],
)

Figuras​

  • Al utilizar #figure para las imágenes o tablas agrega automáticamente la numeración y las etiquetas o notas.
  • También centra en la página la imagen o tabla.
// Imágen
#figure(
image("assets/image1.png"),
caption: [Descripción descripción],
)

// Imagen con medidas específicas
#figure(
image("img/ferris.svg", height: 5cm),
caption: [Ferris, la mascota de Rust],
)

// Tablas
#figure(
table(
columns: 2,
fill: (x, y) => if y == 0 {
luma(210)
},
align: left,
table.header([*Crate*], [*Descripción*]),
[serde], [Serialización y deserialización de datos],
[tokio], [Runtime asíncrono para Rust],
[reqwest], [Cliente HTTP fácil de usar],
),
caption: [Crates populares en Rust],
)

Ajustes

// Solo cambia el estilo de la descripción a cursiva
#show figure.caption: emph

// Cambia la posición del texto a sobre la imagen o tabla
#set figure.caption(position: top)

// Numeración en negrita y descripción en cursiva
#show figure.caption: it => context [
*#it.supplement~#it.counter.display()#it.separator*#emph(it.body)
]

Grid​

#grid(
columns: (40%, 60%),

gutter: 1em, // Espacio vertical y horizontal entre cuadros

[#figure(image("img/rust.png"), caption: "Logo de Rust")],
[#figure(image("img/ferris.svg"), caption: "Ferris, la mascota de Rust")],

[#figure(image("img/rust.png"), caption: "Logo de Rust")],
[#figure(image("img/ferris.svg"), caption: "Ferris, la mascota de Rust")],
)

Numeración de títulos y subtítulos​

proyecto.typ
// Numeración automática
#set heading(numbering: "1.")

= Capitulo Uno
Agregará en automático la numeración de los captiulos.

Ejemplo de salida:
- 1. Capítulo Uno
- 2. Capítulo Dos

== Subtítulos y otros niveles
También agrega en automático la numeración de los demás subtitulos y niveles.

Ejemplo de salida:
- 1.1. Subtítulo
- 1.2. Subtítulo

Esto afecta a todos los títulos y subtítulos como =, ==, ===, etc. pero si no queremos que marque la numeración en algunas secciones, por ejemplo para que se vea Apéndice y no 10. Apéndice

apendice.typ
// Se cancela la numeración automática
#set heading(numbering: none)

= Apéndice
+ Item uno
+ Item dos

Numeración de páginas​

La numeración comienza a mostrarse dependiendo en qué posición del documento se coloque la directiva #set page(numbering: 1) pero el número si sigue la cantidad de las páginas, es decir, el número mostrado comienza desde n y no desde 1 aunque se coloque a mitad del documento.

Entonces si no se desea mostrar la numeración desde la portada, índice u otras páginas del inicio, solo se coloca después de esas secciones y ya comienza a mostrarse la numeración de forma normal, desde n y no desde 1.

#include "portada.typ"
#pagebreak()

#outline()
#pagebreak()

#set page(
numbering: "1",
number-align: top + right,
)

#include "capitulo_i.typ"
#pagebreak()

#include "capitulo_ii.typ"
#pagebreak()

Referencias​

Se debe crear un archivo o mini base de datos donde guardar todas las referencias a las que se harán referencia desde los archivos .typ

  • yaml el formato recomendado para Typst pero no soportado por Pandoc si se planea exportar a Docx
  • bib formato utilizado por LaTex pero soportado también por Typst de forma nativa y también soportando por Pandoc para exportar a Docx

Si sólo se exportará a PDF entonces es recomendable utilizar yaml.

Hay varios tipos de referencias como artículos, libros, web, leyes, etc. y cada tipo se muestra de diferente manera aunque tengan los mismos campos o metadatos, por ejemplo:

  • Usando el tipo Legislation de yaml muestra Título + Año
(Código Penal de Guatemala, 1973)

Código Penal de Guatemala, Legis. Nos. Decreto Número 17–73 (1973). https://
www.tse.org.gt/images/UECFFPP/leyes/Codigo_Penal.pdf
  • Usando el tipo Book en yaml muestra el Autor + Año
(Congreso de la República de Guatemala, 1973)

Congreso de la República de Guatemala. (1973). Código Penal de Guatemala
(Nos. Decreto Número 17–73). Diario de Centro América. https://www.tse.
org.gt/images/UECFFPP/leyes/Codigo_Penal.pdf
  • Usando el tipo Misc en bib
(Congreso de la República de Guatemala, 1973)

Congreso de la República de Guatemala. (1973,). Código Penal de Guatema-
la [Decreto Número 17-73]. https://www.tse.org.gt/images/UECFFPP/leyes/
Codigo_Penal.pdf
  1. Referencias
referencias.yaml
codigo_penal_1973:
type: Legislation
title: Código Penal de Guatemala
serial-number: Decreto Número 17-73
author:
- name: Congreso de la República de Guatemala
date: 1973
publisher: Diario de Centro América
url:
{
value: "https://www.tse.org.gt/images/UECFFPP/leyes/Codigo_Penal.pdf",
date: 2026-10-20,
}
language: es
note: "Hay reformas posteriores a 2012 (p. ej., Decreto 8-2023); verificar la versión consultada."

prensa_libre_2026:
type: Article
title: Guatemala enfrenta ciberataques cada vez más sofisticados sin un marco legal sólido
author: González, Ana Lucía
date: 2026-03-22
url:
{
value: "https://www.prensalibre.com/guatemala/justicia/guatemala-enfrenta-ciberataques-cada-vez-mas-sofisticados-sin-un-marco-legal-solido/",
date: 2026-10-20,
}
language: es
parent:
type: Web
title: Prensa Libre

iso_27001_2022:
type: Misc
title: "Information security, cybersecurity and privacy protection — Information security management systems — Requirements"
genre: International standard
serial-number: "ISO/IEC 27001:2022"
author:
- name: International Organization for Standardization (ISO)
date: 2022
language: en
referencias.bib
@misc{codigo_penal_1973,
author = {{Congreso de la República de Guatemala}},
title = {Código Penal de Guatemala},
type = {Decreto Número 17-73},
date = {1973},
howpublished = {Diario de Centro América},
url = {https://www.tse.org.gt/images/UECFFPP/leyes/Codigo_Penal.pdf},
urldate = {2026-10-20},
langid = {spanish},
note = {Hay reformas posteriores a 2012 (p.\,ej., Decreto 8-2023); verificar la versión consultada}
}

@article{prensa_libre_2026,
author = {González, Ana Lucía},
title = {Guatemala enfrenta ciberataques cada vez más sofisticados sin un marco legal sólido},
journaltitle = {Prensa Libre},
date = {2026-03-22},
url = {https://www.prensalibre.com/guatemala/justicia/guatemala-enfrenta-ciberataques-cada-vez-mas-sofisticados-sin-un-marco-legal-solido/},
urldate = {2026-10-20},
langid = {spanish}
}

@standard{iso_27001_2022,
author = {{International Organization for Standardization}},
title = {Information security, cybersecurity and privacy protection --- Information security management systems --- Requirements},
type = {International standard},
number = {{ISO/IEC} 27001:2022},
date = {2022-10},
langid = {english}
}
  1. Agregar las referencias al proyecto
// bib
#bibliography("referencias.bib", style: "apa", title: "Referencias")

// yaml
#bibliography("referencias.yaml", style: "apa", title: "Referencias")
  1. Utilizar referencias
Aunque en 1996 se incorporaron algunas adiciones específicas para sancionar conductas informáticas básicas y en 2012 se reformó parcialmente la destrucción de registros informáticos @codigo_penal_1973, este andamiaje normativo resulta totalmente obsoleto frente al comportamiento técnico del cibercrimen moderno @prensa_libre_2026.

// ...

3. *Adopción de Medidas Técnicas de Resiliencia:* El proveedor cumpla con estándares mínimos de seguridad de la información, tales como la implementación de los controles de la norma *ISO/IEC 27001* @iso_27001_2022.
  1. Exportar a Docx usando Pandoc
  • Descargar el archivo apa.csl y colocarlo en la raíz del proyecto
  • Para exportar a PDF con o sin referencias yaml o bib no es necesario el archivo cls o Pandoc u otras configuraciones que las por defecto de Typst
pandoc proyecto.typ --citeproc --csl=apa.csl --bibliography=referencias.bib -o proyecto.docx

Ejemplos​

Por defecto + Básico​

#set page(paper: "us-letter", margin: 2.54cm)
#set text(lang: "es", font: "Inter", size: 12pt)
#set heading(numbering: "1.")

#show raw: set text(size: 10pt)
#show raw.where(block: true): it => {
block(
fill: luma(210),
inset: 8pt,
radius: 4pt,
width: 100%,
it,
)
}

= Título
Contenido contenido contenido.

== Subtítulo
Contenido contenido contenido.

Documento extenso​

/// ==================================================================
/// DISEÑO DEL DOCUMENTO
/// ==================================================================

/// Ajustes generales de la página y del texto

#set page(
paper: "us-letter",
margin: (left: 3.5cm, right: 2.5cm, y: 3cm),
)
#set text(
lang: "es",
font: "Inter",
size: 12pt,
)
#set heading(numbering: "1.")
#show heading.where(level: 1): set text(size: 12pt)
#show heading.where(level: 2): set text(size: 12pt)
#show heading.where(level: 3): set text(style: "italic")
#set par(
first-line-indent: (amount: 1.27cm, all: true),
justify: true,
)
#set list(indent: 1.27cm)
#set enum(indent: 1.27cm)
// Comillas estándar (" ") en lugar de comillas tipográficas francesas (« »)
#set smartquote(enabled: false)
#show raw: set text(size: 10pt)
#show raw.where(block: true): it => {
block(
fill: luma(210),
inset: 8pt,
radius: 4pt,
width: 100%,
it,
)
}
#set figure.caption(position: top)
#show figure.caption: it => context [
*#it.supplement~#it.counter.display()#it.separator*#emph(it.body)
]

/// Interlineado y espaciado entre bloques, títulos y párrafos

// 0em, sin espacio
// 0.5em, sencillo
// 1em, doble
#let spacing = 0.5em

// Espacio entre líneas del párrafo y entre párrafos
// Se hace un ajuste de los márgenes superior e inferior del texto
// para que el interlineado y el espaciado entre párrafos se vea correctamente.
#set text(
top-edge: 0.8em,
bottom-edge: -0.2em,
)
#set par(
leading: spacing, // Espacio entre líneas del párrafo
spacing: spacing, // Espacio entre párrafos
)
// Espacio entre titulos y párrafos
#show heading: set block(above: spacing, below: spacing)
// Espacio entre bloques (indice, listas, ....)
#set block(spacing: spacing)

/// ==================================================================
/// CONTENIDO DEL DOCUMENTO
/// ==================================================================

#include "portada.typ"
#pagebreak()

#outline()
#pagebreak()

#set page(
numbering: "1",
number-align: top + right,
)

#include "capitulo_i.typ"
#pagebreak()

#include "capitulo_ii.typ"
#pagebreak()

#bibliography("referencias.bib", style: "apa", title: "Referencias")
#pagebreak()

#include "apendice.typ"