feat: add multi-language support

This commit is contained in:
welpo
2023-05-22 19:12:03 +02:00
parent e316dc25ab
commit fa9229377d
49 changed files with 1314 additions and 88 deletions

View File

@@ -0,0 +1,8 @@
+++
paginate_by = 5
path = "/blog"
title = "Blog"
sort_by = "date"
template = "section.html"
insert_anchor_links = "left"
+++

View File

@@ -0,0 +1,8 @@
+++
paginate_by = 5
path = "/blog"
title = "Blog"
sort_by = "date"
template = "section.html"
insert_anchor_links = "left"
+++

View File

@@ -0,0 +1,17 @@
+++
title = "Gairebé sense JavaScript"
date = 2023-01-06
updated = 2023-04-28
description = "JavaScript només s'utilitza quan HTML i CSS no són suficients."
[taxonomies]
tags = ["funcionalitat"]
+++
# JavaScript?
Aquest tema gairebé no utilitza JavaScript. Inclou uns ~900 bytes de fitxers `.js` amb la lògica per al canvi de tema clar/fosc, que es pot desactivar establint `theme_switcher = false` al fitxer `config.toml`.
La funcionalitat de KaTex, que requereix carregar un fitxer JavaScript de 274 KB, es pot activar per a publicacions específiques.
A part d'això, és un tema ràpid amb HTML i CSS. Tal i com hauria de ser (la major part de) la web :-)

View File

@@ -0,0 +1,17 @@
+++
title = "Casi sin JavaScript"
date = 2023-01-06
updated = 2023-04-28
description = "JavaScript solo se utiliza cuando HTML y CSS no son suficientes."
[taxonomies]
tags = ["funcionalidad"]
+++
# ¿JavaScript?
Este tema casi no utiliza JavaScript. Incluye ~900 bytes de código `.js` con la lógica para el interruptor de modo claro/oscuro, el cual puede ser desactivado configurando `theme_switcher = false` en el archivo `config.toml`.
El soporte de KaTeX, que requiere cargar un archivo JavaScript de 274 KB, puede ser activado para publicaciones específicas.
Aparte de esto, es un tema rápido con HTML y CSS. Como debería ser (en su mayoría) la web :-)

View File

@@ -0,0 +1,190 @@
+++
title = "Optimitza la càrrega amb un subconjunt de font personalitzat"
date = 2023-04-29
updated = 2023-05-18
description = "Aprèn com crear un subconjunt personalitzat que només inclogui els glifs necessaris."
[taxonomies]
tags = ["funcionalitat", "tutorial"]
+++
## El problema
Les fonts personalitzades causen parpelleig de text a Firefox. Per veure un gif i més detalls, mira [aquesta issue](https://github.com/welpo/tabi/issues/75).
## La solució
Per solucionar això, tabi carrega un subconjunt de glifs per a l'encapçalament. Donat que això augmenta lleugerament el temps de càrrega inicial, és una bona idea intentar minimitzar la mida d'aquest subconjunt.
Per defecte, tabi inclou fitxers de subconjunts per a caràcters en anglès i espanyol (amb alguns símbols). Aquests fitxers es carreguen quan la pàgina o el lloc web de Zola està en aquest idioma.
Per a una optimització addicional, pots crear un subconjunt de fonts personalitzat que només inclogui els caràcters utilitzats en el teu encapçalament.
## Requisits
Instal·la aquestes eines:
- [fonttools](https://github.com/fonttools/fonttools)
- [brotli](https://github.com/google/brotli)
Executa `pip install fonttools brotli` per instal·lar totes dues.
## L'script
El següent script pren un fitxer `config.toml` i un fitxer de font com a entrada, extreu els caràcters necessaris, crea un subconjunt de la font i genera un fitxer CSS que conté el subconjunt codificat en base64.
```bash
#!/usr/bin/env bash
usage() {
echo "Usage: $0 [--config|-c CONFIG_FILE] [--font|-f FONT_FILE] [--output|-o OUTPUT_PATH]"
echo
echo "Options:"
echo " --config, -c Path to the config.toml file."
echo " --font, -f Path to the font file."
echo " --output, -o Output path for the generated subset.css file (default: current directory)"
echo " --help, -h Show this help message and exit"
}
# La sortida per defecte és el directori actual.
output_path="."
# Opcions de la línia de comandes.
while [ "$#" -gt 0 ]; do
case "$1" in
--config|-c)
config_file="$2"
shift 2
;;
--font|-f)
font_file="$2"
shift 2
;;
--output|-o)
output_path="$2"
shift 2
;;
--help|-h)
usage
exit 0
;;
*)
echo "Unknown option: $1"
usage
exit 1
;;
esac
done
# Comprova si s'han proporcionat les opcions -c i -f.
if [ -z "$config_file" ]; then
echo "Error: --config|-c option is required."
usage
exit 1
fi
if [ -z "$font_file" ]; then
echo "Error: --font|-f option is required."
usage
exit 1
fi
# Comprova si els fitxers de configuració i de font existeixen.
if [ ! -f "$config_file" ]; then
echo "Error: Config file '$config_file' not found."
exit 1
fi
if [ ! -f "$font_file" ]; then
echo "Error: Font file '$font_file' not found."
exit 1
fi
# Extreu el títol i els noms del menú del fitxer de configuració.
title=$(awk -F' = ' '/^title/{print $2}' "$config_file" | tr -d '"' | grep -v "atom feed")
menu_names=$(awk -F' = ' '/^menu/{f=1;next} /socials/{f=0} f && /name/{print $2}' "$config_file" | cut -d',' -f1 | tr -d '"' )
language_names=$(awk -F' = ' '/^language_name\./{print $2}' "$config_file" | tr -d '"' )
# Si el lloc web és multilingüe, obté les traduccions del menú.
if [ -n "$language_names" ]; then
for menu_name in $menu_names; do
# Find the line with the menu name inside a [languages.*.translations] section and get the translated menus.
menu_translation=$(awk -F' = ' "/\\[languages.*\\.translations\\]/{f=1;next} /^\\[/ {f=0} f && /$menu_name =/{print \$2}" "$config_file" | tr -d '"' )
# Add the found menu value to the translations string
menu_names+="$menu_translation"
done
fi
# Combina les cadenes extretes.
combined="$title$menu_names$language_names"
# Obté els caràcters únics.
unique_chars=$(echo "$combined" | grep -o . | sort -u | tr -d '\n')
# Crea un fitxer temporal per a subset.woff2.
temp_subset=$(mktemp)
# Executa la comanda pyftsubset amb els caràcters filtrats com a argument --text.
pyftsubset "$font_file" \
--text="$unique_chars" \
--layout-features="" --flavor="woff2" --output-file="$temp_subset" --with-zopfli
# Codifica en base64 el fitxer temporal subset.woff2 i crea el fitxer CSS.
base64_encoded_font=$(base64 -i "$temp_subset")
echo "@font-face{font-family:\"Inter Subset\";src:url(data:application/font-woff2;base64,$base64_encoded_font);}" > "$output_path/custom_subset.css"
# Elimina el fitxer temporal subset.woff2
rm "$temp_subset"
```
## Ús
Guarda l'script a algun lloc com `~/bin/subset_font`. Fes-lo executable amb `chmod +x ~/bin/subset_font`.
Ara pots executar-lo amb les opcions requerides `--config` i `--font`:
```
~/bin/subset_font --config path/to/config.toml --font path/to/font.woff2
```
De forma predeterminada, això generarà un fitxer `custom_subset.css` al directori actual. Utilitza `-o` o `--output` per especificar una ruta diferent:
```
~/bin/subset_font -c path/to/config.toml -f path/to/font.woff2 -o path/to/output
```
Col·loca aquest fitxer `custom_subset.css` dins del directori `static/` del teu projecte de Zola.
## Automatització amb un Pre-commit Hook
És possible que canviïs el títol o les opcions del menú del teu lloc web, la qual cosa faria que el subconjunt personalitzat deixés de ser útil.
Per automatitzar el procés de creació d'aquest fitxer, pots integrar l'script en un ganxo (hook) pre-commit de Git que s'activi en detectar canvis al fitxer `config.toml`, executi l'script i guardi el fitxer CSS resultant al directori `static/` del teu lloc web.
1. Crea un fitxer `.git/hooks/pre-commit` al teu projecte de Git, si encara no existeix.
2. Fes-lo executable amb `chmod +x .git/hooks/pre-commit`.
3. Afegeix el següent codi al fitxer:
```bash
# Comprova si config.toml s'ha modificat.
if git diff --cached --name-only | grep -q "config.toml"; then
echo "config.toml modified. Running subset_font…"
# Executa l'script subset_font.
~/bin/subset_font -c config.toml -f static/fonts/Inter4.woff2 -o static/
# Afegeix el fitxer subset.css generat al commit.
git add static/custom_subset.css
fi
```
Asegura't de modificar l'script perquè coincideixi amb la ruta on has guardat l'script `subset_font`. Les rutes de configuració i font haurien de funcionar correctament amb la configuració predeterminada de tabi.
Ara, cada vegada que facis canvis al teu projecte de Git i facis commit, el ganxo pre-commit verificarà les modificacions al fitxer `config.toml` i executarà automàticament l'script `subset_font` per actualitzar el fitxer `custom_subset.css`.
Per cert, si t'interessa una forma d'actualitzar automàticament la data de les teves publicacions a Zola o comprimir automàticament els teus fitxers PNG, fes un cop d'ull a [aquesta publicació](https://osc.garden/ca/blog/zola-date-git-hook/).
Si desitges utilitzar tots els scripts alhora (compressió de fitxers PNG, actualització de la data i creació del subconjunt de fonts), combina el seu codi en un sol fitxer `.git/hooks/pre-commit`.

View File

@@ -0,0 +1,191 @@
+++
title = "Optimiza la carga con un subconjunto de fuente personalizado"
date = 2023-04-29
updated = 2023-05-18
description = "Aprende cómo crear un subconjunto personalizado que solo incluya los glifos necesarios."
[taxonomies]
tags = ["funcionalidad", "tutorial"]
+++
## El problema
Las fuentes personalizadas causan parpadeo de texto en Firefox. Para ver un gif y más detalles, mira [esta issue](https://github.com/welpo/tabi/issues/75).
## La solución
Para solucionar esto, tabi carga un subconjunto de glifos para el encabezado. Dado que esto aumenta ligeramente el tiempo de carga inicial, es una buena idea tratar de minimizar el tamaño de este subconjunto.
Por defecto, tabi incluye archivos de subconjuntos para caracteres en inglés y español (con algunos símbolos). Estos archivos se cargan cuando la página o el sitio de Zola está en ese idioma.
Para una optimización adicional, puedes crear un subconjunto de fuentes personalizado que solo incluya los caracteres utilizados en tu encabezado.
## Requisitos
Instala estas herramientas:
- [fonttools](https://github.com/fonttools/fonttools)
- [brotli](https://github.com/google/brotli)
Ejecuta `pip install fonttools brotli` para instalar ambas.
## El script
El script que sigue toma un archivo `config.toml` y un archivo de fuente como entrada, extrae los caracteres necesarios, crea un subconjunto de la fuente y genera un archivo CSS que contiene el subconjunto codificado en base64.
```bash
#!/usr/bin/env bash
usage() {
echo "Usage: $0 [--config|-c CONFIG_FILE] [--font|-f FONT_FILE] [--output|-o OUTPUT_PATH]"
echo
echo "Options:"
echo " --config, -c Path to the config.toml file."
echo " --font, -f Path to the font file."
echo " --output, -o Output path for the generated subset.css file (default: current directory)"
echo " --help, -h Show this help message and exit"
}
# La salida predeterminada es el directorio actual.
output_path="."
# Analiza las opciones de la línea de comandos.
while [ "$#" -gt 0 ]; do
case "$1" in
--config|-c)
config_file="$2"
shift 2
;;
--font|-f)
font_file="$2"
shift 2
;;
--output|-o)
output_path="$2"
shift 2
;;
--help|-h)
usage
exit 0
;;
*)
echo "Unknown option: $1"
usage
exit 1
;;
esac
done
# Comprueba si se proporcionan las opciones -c y -f.
if [ -z "$config_file" ]; then
echo "Error: --config|-c option is required."
usage
exit 1
fi
if [ -z "$font_file" ]; then
echo "Error: --font|-f option is required."
usage
exit 1
fi
# Comprueba si existen los archivos de configuración y de fuentes.
if [ ! -f "$config_file" ]; then
echo "Error: Config file '$config_file' not found."
exit 1
fi
if [ ! -f "$font_file" ]; then
echo "Error: Font file '$font_file' not found."
exit 1
fi
# Extrae el título y los nombres de los menús del archivo de configuración.
title=$(awk -F' = ' '/^title/{print $2}' "$config_file" | tr -d '"' | grep -v "atom feed")
menu_names=$(awk -F' = ' '/^menu/{f=1;next} /socials/{f=0} f && /name/{print $2}' "$config_file" | cut -d',' -f1 | tr -d '"' )
language_names=$(awk -F' = ' '/^language_name\./{print $2}' "$config_file" | tr -d '"' )
# Si el sitio es multilingüe, obtiene las traducciones de los menús.
if [ -n "$language_names" ]; then
for menu_name in $menu_names; do
# Find the line with the menu name inside a [languages.*.translations] section and get the translated menus.
menu_translation=$(awk -F' = ' "/\\[languages.*\\.translations\\]/{f=1;next} /^\\[/ {f=0} f && /$menu_name =/{print \$2}" "$config_file" | tr -d '"' )
# Add the found menu value to the translations string
menu_names+="$menu_translation"
done
fi
# Combina las cadenas extraídas..
combined="$title$menu_names$language_names"
# Obtiene los caracteres únicos.
unique_chars=$(echo "$combined" | grep -o . | sort -u | tr -d '\n')
# Crea un archivo temporal para subset.woff2.
temp_subset=$(mktemp)
# Ejecuta el comando pyftsubset con los caracteres filtrados como argumento --text.
pyftsubset "$font_file" \
--text="$unique_chars" \
--layout-features="" --flavor="woff2" --output-file="$temp_subset" --with-zopfli
# Codifica en Base64 el archivo temporal subset.woff2 y crea el archivo CSS.
base64_encoded_font=$(base64 -i "$temp_subset")
echo "@font-face{font-family:\"Inter Subset\";src:url(data:application/font-woff2;base64,$base64_encoded_font);}" > "$output_path/custom_subset.css"
# Elimina el archivo temporal subset.woff2.
rm "$temp_subset"
```
## Uso
Guarda el script en algún lugar como `~/bin/subset_font`. Hazlo ejecutable con `chmod +x ~/bin/subset_font`.
Ahora puedes ejecutarlo con las opciones requeridas `--config` y `--font`:
```
~/bin/subset_font --config path/to/config.toml --font path/to/font.woff2
```
De forma predeterminada, esto generará un archivo `custom_subset.css` en el directorio actual. Usa `-o` o `--output` para especificar una ruta diferente:
```
~/bin/subset_font -c path/to/config.toml -f path/to/font.woff2 -o path/to/output
```
Coloca este archivo `custom_subset.css` dentro del directorio `static/`.
## Automatización con un Pre-commit Hook
Es posible que cambies el título o las opciones del menú de tu sitio, lo que haría que el subconjunto personalizado deje de ser útil.
Para automatizar el proceso de creación de este archivo, puedes integrar el script en un gancho (hook) pre-commit de Git que se active al detectar cambios en el archivo `config.toml`, ejecute el script y guarde el archivo CSS resultante en el directorio `static/` de tu sitio.
1. Crea un archivo `.git/hooks/pre-commit` en tu proyecto de Git, si aún no existe.
2. Hazlo ejecutable con `chmod +x .git/hooks/pre-commit`.
3. Agrega el siguiente código al archivo:
```bash
# Comprueba si config.toml se ha modificado.
if git diff --cached --name-only | grep -q "config.toml"; then
echo "config.toml modified. Running subset_font…"
# Ejecuta el script subset_font.
~/bin/subset_font -c config.toml -f static/fonts/Inter4.woff2 -o static/
# Añadie el subset.css recién generado al commit.
git add static/custom_subset.css
fi
```
Asegúrate de modificar el script para que coincida con la ruta donde has guardado el script `subset_font`. Las rutas de configuración y fuente deberían funcionar correctamente con la configuración predeterminada de tabi.
Ahora, cada vez que hagas cambios en tu proyecto de Git y los confirmes, el gancho pre-commit verificará las modificaciones en el archivo `config.toml` y ejecutará automáticamente el script `subset_font` para actualizar el archivo `custom_subset.css`.
Por cierto, si te interesa una forma de actualizar automáticamente la fecha de tus publicaciones en Zola o comprimir automáticamente tus archivos PNG, echa un vistazo a [esta publicación](https://osc.garden/es/blog/zola-date-git-hook/).
Si deseas utilizar todos los scripts a la vez (compresión de archivos PNG, actualización de la fecha y creación del subconjunto de fuentes), combina su código en un solo archivo `.git/hooks/pre-commit`.

View File

@@ -1,7 +1,7 @@
+++
title = "Optimise loading times with a custom font subset"
date = 2023-04-29
updated = 2023-05-18
updated = 2023-05-22
description = "Learn how to create a custom subset that only includes the necessary glyphs."
[taxonomies]
@@ -38,12 +38,12 @@ The script below takes a `config.toml` file and a font file as input, extracts t
#!/usr/bin/env bash
usage() {
echo "Usage: $0 [--config | -c CONFIG_FILE] [--font | -f FONT_FILE] [--output | -o OUTPUT_PATH]"
echo "Usage: $0 [--config|-c CONFIG_FILE] [--font|-f FONT_FILE] [--output|-o OUTPUT_PATH]"
echo
echo "Options:"
echo " --config, -c Path to the config.toml file."
echo " --font, -f Path to the font file."
echo " --output, -o Output path for the generated custom_subset.css file (default: current directory)"
echo " --output, -o Output path for the generated subset.css file (default: current directory)"
echo " --help, -h Show this help message and exit"
}
@@ -102,11 +102,22 @@ if [ ! -f "$font_file" ]; then
fi
# Extract the title and menu names from the config file.
title=$(awk -F' = ' '/title/{print $2}' "$config_file" | tr -d '"' | grep -v "atom feed")
menu_names=$(awk '/menu/{f=1;next} /^\S/{f=0} f{print}' "$config_file" | awk -F' = ' '/name/{print $2}' | tr -d '"' )
title=$(awk -F' = ' '/^title/{print $2}' "$config_file" | tr -d '"' | grep -v "atom feed")
menu_names=$(awk -F' = ' '/^menu/{f=1;next} /socials/{f=0} f && /name/{print $2}' "$config_file" | cut -d',' -f1 | tr -d '"' )
language_names=$(awk -F' = ' '/^language_name\./{print $2}' "$config_file" | tr -d '"' )
# If the site is multilingual, get the menu translations.
if [ -n "$language_names" ]; then
for menu_name in $menu_names; do
# Find the line with the menu name inside a [languages.*.translations] section and get the translated menus.
menu_translation=$(awk -F' = ' "/\\[languages.*\\.translations\\]/{f=1;next} /^\\[/ {f=0} f && /$menu_name =/{print \$2}" "$config_file" | tr -d '"' )
# Add the found menu value to the translations string
menu_names+="$menu_translation"
done
fi
# Combine the extracted strings.
combined="$title$menu_names"
combined="$title$menu_names$language_names"
# Get unique characters.
unique_chars=$(echo "$combined" | grep -o . | sort -u | tr -d '\n')
@@ -114,19 +125,16 @@ unique_chars=$(echo "$combined" | grep -o . | sort -u | tr -d '\n')
# Create a temporary file for subset.woff2.
temp_subset=$(mktemp)
# Create the subset.
# Run the pyftsubset command with the filtered characters as --text argument.
pyftsubset "$font_file" \
--text="$unique_chars" \
--layout-features="" --flavor="woff2" --output-file="$temp_subset" --with-zopfli
# Remove trailing slash from output path, if present.
output_path=${output_path%/}
# Base64 encode the temporary subset.woff2 file and create the CSS file.
base64_encoded_font=$(base64 -i "$temp_subset")
echo "@font-face{font-family:\"Inter Subset\";src:url(data:application/font-woff2;base64,$base64_encoded_font);}" > "$output_path/custom_subset.css"
# Remove the temporary subset.woff2 file.
# Remove the temporary subset.woff2 file
rm "$temp_subset"
```

View File

@@ -0,0 +1,60 @@
+++
title = "Exemples de Markdown"
date = 2023-01-31
updated = 2023-04-28
description = "Aquesta publicació mostra alguns exemples de format en Markdown, incloent-hi una taula, blocs de codi i etiquetes, citacions, taules i notes a peu de pàgina."
[taxonomies]
tags = ["markdown", "funcionalitat"]
[extra]
katex = true
+++
## $\KaTeX$
[$\KaTeX$](https://katex.org/) és una llibreria ràpida i fàcil d'usar que permet representar notació matemàtica mitjançant la sintaxi LaTeX.
Pots utilitzar $\KaTeX$ **en línia** embolcallant l'expressió entre `$` o entre `\\(` i `\\)`.
Per exemple, `$ \sin(x) = \sum_{n=0}^{\infty} \frac{(-1)^n}{(2n + 1)!} x^{2n + 1} $` es renderitzarà com: $ \sin(x) = \sum_{n=0}^{\infty} \frac{(-1)^n}{(2n + 1)!} x^{2n + 1} $
Per mostrar l'expressió **en una línia pròpia i centrada**, embolcalla-la amb `$$` o entre `\\[` i `\\]`.
Per exemple, `\\[ r = \frac{\sum_{i=1}^{n}(x_i - \bar{x})(y_i - \bar{y})}{\sqrt{\sum_{i=1}^{n}(x_i - \bar{x})^2}\sqrt{\sum_{i=1}^{n}(y_i - \bar{y})^2}} \\]` es renderitzarà com: \\[ r = \frac{\sum_{i=1}^{n}(x_i - \bar{x})(y_i - \bar{y})}{\sqrt{\sum_{i=1}^{n}(x_i - \bar{x})^2}\sqrt{\sum_{i=1}^{n}(y_i - \bar{y})^2}} \\]
Per activar $\KaTeX$ en una publicació, inclou `katex = true` dins de la secció `[extra]` dels metadades de la publicació. Per obtenir un millor rendiment i seguretat, els fitxers JavaScript, CSS i les tipografies s'allotgen localment.
**Nota**: Després d'activar $\KaTeX$, si vols utilitzar el caràcter \$ sense renderitzar-lo com a expressió matemàtica, escapa'l amb una barra inversa: `\$`.
## Taula
Aquí tens un exemple de taula[^1]. Els seus colors canvien en funció del tema actual.
| Símbol | Element | Nombre atòmic |
|---------|---------|---------------|
| H | Hidrogen| 1 |
| C | Carboni | 6 |
| Fe | Ferro | 26 |
| Au | Or | 79 |
## Bloc de codi
```rust
fn main() {
println!("Hola, món!") -> ();
}
```
## Etiquetes de codi
Lorem ipsum `dolor` sit amet, `consectetur adipiscing` elit.
`Lorem ipsum dolor sit amet, consectetur adipiscing elit.`
## Quote
> La vida, perquè sigui vida, s'ha de viure a poc a poc…
>
> — Mercè Rodoreda, La plaça del Diamant
[^1]: I aquí tens un exemple de nota a peu de pàgina!

View File

@@ -0,0 +1,60 @@
+++
title = "Ejemplos de Markdown"
date = 2023-01-31
updated = 2023-04-28
description = "Esta publicación muestra algunos ejemplos de formato Markdown, incluyendo una tabla, bloques de código y etiquetas, citas, tablas y notas al pie de página."
[taxonomies]
tags = ["markdown", "funcionalidad"]
[extra]
katex = true
+++
## $\KaTeX$
[$\KaTeX$](https://katex.org/) es una biblioteca rápida y fácil de usar que permite la representación de notación matemática utilizando sintaxis LaTeX.
Puedes usar $\KaTeX$ **en línea** al envolver la expresión entre `$` o entre `\\(` y `\\)`.
Por ejemplo, `$ \sin(x) = \sum_{n=0}^{\infty} \frac{(-1)^n}{(2n + 1)!} x^{2n + 1} $` se mostraría como: $ \sin(x) = \sum_{n=0}^{\infty} \frac{(-1)^n}{(2n + 1)!} x^{2n + 1} $
Para mostrar la expresión **en su propia línea y centrada**, envuélvela entre `$$` o entre `\\[` y `\\]`.
Por ejemplo, `\\[ r = \frac{\sum_{i=1}^{n}(x_i - \bar{x})(y_i - \bar{y})}{\sqrt{\sum_{i=1}^{n}(x_i - \bar{x})^2}\sqrt{\sum_{i=1}^{n}(y_i - \bar{y})^2}} \\]` se mostraría como: \\[ r = \frac{\sum_{i=1}^{n}(x_i - \bar{x})(y_i - \bar{y})}{\sqrt{\sum_{i=1}^{n}(x_i - \bar{x})^2}\sqrt{\sum_{i=1}^{n}(y_i - \bar{y})^2}} \\]
Para activar $\KaTeX$ en una publicación, incluye `katex = true` dentro de la sección `[extra]` del encabezado de la publicación. Para un mejor rendimiento y seguridad, el JavaScript, CSS y las fuentes se alojan localmente.
**Nota**: Después de habilitar $\KaTeX$, si deseas usar \$ sin representar una expresión matemática, escápalo con una sola barra invertida: `\$`.
## Tabla
Aquí tienes un ejemplo de una tabla[^1]. Los colores cambian dependiendo del tema actual.
| Símbolo | Elemento | Número atómico |
|---------|----------|----------------|
| H | Hidrógeno| 1 |
| C | Carbono | 6 |
| Fe | Hierro | 26 |
| Au | Oro | 79 |
## Bloque de código
```rust
fn main() {
println!("¡Hola, mundo!") -> ();
}
```
## Etiquetas de código
Lorem ipsum `dolor` sit amet, `consectetur adipiscing` elit.
`Lorem ipsum dolor sit amet, consectetur adipiscing elit.`
## Cita
> A mí me sobra el cuerpo, Orfeo, me sobra el cuerpo porque me falta alma.
>
> — Miguel de Unamuno, Niebla
[^1]: ¡Y aquí tienes un ejemplo de una nota al pie de página!

View File

@@ -0,0 +1,30 @@
+++
title = "Seguretat per defecte"
date = 2023-02-22
updated = 2023-04-29
description = "tabi té una Política de Seguretat de Contingut (CSP) fàcilment personalitzable amb valors segurs per defecte. Obtingues tranquil·litat i un A+ en l'Observatori de Mozilla."
[taxonomies]
tags = ["seguretat", "funcionalitat"]
+++
La configuració per defecte del tema obté una puntuació A+ a l'[Observatori de Mozilla](https://observatory.mozilla.org).[^1]
Això s'aconsegueix configurant programàticament les capçaleres de la Política de Seguretat de Contingut (CSP) basant-se en una llista de dominis permesos definida per l'usuari en el fitxer `config.toml`. Aquí tens la configuració per defecte i recomanada (pots eliminar l'última directiva si no vols inserir vídeos de YouTube):
```
[extra]
allowed_domains = [
{ directive = "font-src", domains = ["'self'", "data:"] },
{ directive = "img-src", domains = ["'self'", "https://*", "data:"] },
{ directive = "script-src", domains = ["'self'"] },
{ directive = "style-src", domains = ["'self'"] },
{ directive = "frame-src", domains = ["https://www.youtube-nocookie.com"] },
]
```
La llista `allowed_domains` especifica les URLs a les quals el lloc web hauria de poder connectar-se, i cada domini de la llista està associat amb una directiva CSP com `frame-src`, `connect-src` o `script-src`. El fitxer `templates/partials/header.html` genera dinàmicament la capçalera CSP basant-se en aquesta llista.
Aquesta funcionalitat permet personalitzar fàcilment les capçaleres de seguretat del lloc web per permetre casos d'ús específics, com ara inserir vídeos de YouTube, carregar scripts o tipografies remotes ([no recomanat](https://www.albertovarela.net/blog/2022/11/stop-using-google-fonts/)).
[^1]: Requereix una configuració adequada del servidor web (p. ex., redirigir el trànsit HTTP a HTTPS).

View File

@@ -0,0 +1,30 @@
+++
title = "Seguro por defecto"
date = 2023-02-22
updated = 2023-04-29
description = "tabi tiene una Política de Seguridad de Contenido (CSP) fácilmente personalizable con configuraciones seguras. Obtén tranquilidad y una calificación de A+ en Mozilla Observatory."
[taxonomies]
tags = ["seguridad", "funcionalidad"]
+++
La configuración predeterminada del tema obtiene una calificación de A+ en [Mozilla Observatory](https://observatory.mozilla.org).[^1]
Esto se logra configurando programáticamente las cabeceras de la Política de Seguridad de Contenido (CSP) en función de una lista de dominios permitidos definida por el usuario en el archivo `config.toml`. Aquí tienes la configuración predeterminada y recomendada (puedes eliminar la última directiva si no deseas insertar videos de YouTube):
```
[extra]
allowed_domains = [
{ directive = "font-src", domains = ["'self'", "data:"] },
{ directive = "img-src", domains = ["'self'", "https://*", "data:"] },
{ directive = "script-src", domains = ["'self'"] },
{ directive = "style-src", domains = ["'self'"] },
{ directive = "frame-src", domains = ["https://www.youtube-nocookie.com"] },
]
```
La lista `allowed_domains` especifica las URL a las que el sitio web debería poder conectarse, y cada dominio de la lista se asocia con una directiva CSP como `frame-src`, `connect-src` o `script-src`. El archivo `templates/partials/header.html` genera dinámicamente la cabecera CSP en función de esta lista.
Esta función permite personalizar fácilmente las cabeceras de seguridad del sitio web para permitir casos de uso específicos, como la incrustación de videos de YouTube, la carga de scripts o fuentes remotas ([no recomendado](https://www.albertovarela.net/blog/2022/11/stop-using-google-fonts/)).
[^1]: Requiere una configuración adecuada del servidor web (por ejemplo, redirigir el tráfico HTTP a HTTPS).

View File

@@ -0,0 +1,78 @@
+++
title = "Shortcodes personalitzats"
date = 2023-02-19
updated = 2023-04-16
description = "Aquest tema inclou alguns shortcodes personalitzats útils que pots utilitzar per millorar les teves publicacions. Ja sigui per mostrar imatges que s'adapten als temes clar i fosc, o per donar format a una secció de referències amb un aspecte professional, aquests shortcodes personalitzats t'ajudaran."
[taxonomies]
tags = ["funcionalitat", "shortcodes"]
+++
## Shortcodes d'imatge
### Imatges per a temes duals
Útil si vols utilitzar una imatge diferent pels temes clar i fosc:
{{ dual_theme_image(light_src="img/paris_day.webp", dark_src="img/paris_night.webp" alt="La Torre Eiffel") }}
#### Ús
```
{{/* dual_theme_image(light_src="img/paris_day.webp", dark_src="img/paris_night.webp" alt="La Torre Eiffel") */}}
```
### Imatge invertible
Útil per a gràfics, dibuixos de línies, diagrames… Inverteix els colors de la imatge. La imatge original s'utilitzarà per al tema clar.
{{ invertible_image(src="img/graph.webp", alt="Gràfic invertible") }}
#### Ús
```
{{/* invertible_image(src="img/graph.webp", alt="Gràfic invertible") */}}
```
### Imatge regulable
Les imatges amb massa brillantor o contrast poden ser molestes en un fons fosc. Aquí tens un exemple d'una fotografia que s'atenua quan s'activa el tema fosc.
{{ dimmable_image(src="img/desert_by_oskerwyld.webp", alt="Fotografia d'un desert, cel celestial") }}
#### Usage
```
{{/* dimmable_image(src="img/desert_by_oskerwyld.webp", alt="Fotografia d'un desert, cel celestial") */}}
```
## Referències
### Sagnat invertit
Aquest shortcode formata una secció de referència amb un sagnat invertit de la següent manera:
{% references() %}
Alderson, E. (2015). Ciberseguretat i justícia social: Una crítica a la hegemonia corporativa en un món digital. *New York Journal of Technology, 11*(2), 24-39. [https://doi.org/10.1007/s10198-022-01497-6](https://doi.org/10.1007/s10198-022-01497-6).
Funkhouser, M. (2012). Les normes socials d'indecència: Un anàlisi del comportament desviat a la societat contemporània. *Los Angeles Journal of Sociology, 16*(3), 41-58. [https://doi.org/10.1093/jmp/jhx037](https://doi.org/10.1093/jmp/jhx037).
Schrute, D. (2005). La revolució de l'agricultura de remolatxa: Un anàlisi de la innovació agrícola. *Scranton Agricultural Quarterly, 38*(3), 67-81.
Steinbrenner, G. (1997). L'anàlisi cost-benefici de George Costanza: Un anàlisi del comportament de presa de riscos en el lloc de treball. *New York Journal of Business, 12*(4), 112-125.
Winger, J. A. (2010). L'art del debat: Un examen de la retòrica en el model de les Nacions Unides del Greendale Community College. *Colorado Journal of Communication Studies, 19*(2), 73-86. [https://doi.org/10.1093/6seaons/1movie](https://doi.org/10.1093/6seaons/1movie).
{% end %}
#### Ús
```
{%/* references() */%}
Les teves referències van aquí.
Cada una en una nova línia. Es renderitzarà el Markdown (enllaços, cursiva…).
{%/* end */%}
```

View File

@@ -0,0 +1,79 @@
+++
title = "Shortcodes personalizados"
date = 2023-02-19
updated = 2023-05-21
description = "Este tema incluye algunos shortcodes personalizados útiles que puedes utilizar para mejorar tus publicaciones. Puedes mostrar imágenes que se adapten a los temas claro y oscuro, dar formato a una sección de referencias con un aspecto profesional, y más."
[taxonomies]
tags = ["funcionalidad", "shortcodes"]
+++
## Shortcodes de imágenes
### Imágenes de doble tema
Útil si deseas usar una imagen diferente para los temas claro y oscuro:
{{ dual_theme_image(light_src="img/paris_day.webp", dark_src="img/paris_night.webp" alt="La Torre Eiffel") }}
#### Uso
```
{{/* dual_theme_image(light_src="img/paris_day.webp", dark_src="img/paris_night.webp" alt="La Torre Eiffel") */}}
```
### Imagen invertible
Ideal para gráficos, dibujos lineales, diagramas... Invierte los colores de la imagen. La imagen de origen se utilizará para el tema claro.
{{ invertible_image(src="img/graph.webp", alt="Gráfico invertible") }}
#### Uso
```
{{/* invertible_image(src="img/graph.webp", alt="Gráfico invertible") */}}
```
### Imagen atenuable
Las imágenes con demasiado brillo o contraste pueden ser impactantes en un fondo oscuro. Aquí tienes un ejemplo de una fotografía que se atenúa cuando el tema oscuro está activo.
{{ dimmable_image(src="img/desert_by_oskerwyld.webp", alt="Fotografía de un desierto, cielo celestial") }}
#### Uso
```
{{/* dimmable_image(src="img/desert_by_oskerwyld.webp", alt="Fotografía de un desierto, cielo celestial") */}}
```
## Referencias
### Sangría francesa
Este shortcode formatea una sección de referencias con sangría francesa de la siguiente manera:
{% references() %}
Alderson, E. (2015). Ciberseguridad y justicia social: Una crítica a la hegemonía corporativa en un mundo digital. *New York Journal of Technology, 11*(2), 24-39. [https://doi.org/10.1007/s10198-022-01497-6](https://doi.org/10.1007/s10198-022-01497-6).
Funkhouser, M. (2012). Las normas sociales de indecencia: Un análisis del comportamiento desviado en la sociedad contemporánea. *Los Angeles Journal of Sociology, 16*(3), 41-58. [https://doi.org/10.1093/jmp/jhx037](https://doi.org/10.1093/jmp/jhx037).
Schrute, D. (2005). La revolución de la agricultura de remolacha: Un análisis de la innovación agrícola. *Scranton Agricultural Quarterly, 38*(3), 67-81.
Steinbrenner, G. (1997). El análisis costo-beneficio de George Costanza: Un examen del comportamiento de toma de riesgos en el lugar de trabajo. *New York Journal of Business, 12*(4), 112-125.
Winger, J. A. (2010). El arte del debate: Un examen de la retórica en el modelo de las Naciones Unidas del Greendale Community College. *Colorado Journal of Communication Studies, 19*(2), 73-86. [https://doi.org/10.1093/6seaons/1movie](https://doi.org/10.1093/6seaons/1movie).
{% end %}
#### Uso
```
{%/* references() */%}
Tus referencias van aquí.
Cada una en una línea nueva. Se renderizará Markdown (enlaces, cursivas…).
{%/* end */%}
```

48
content/blog/toc.ca.md Normal file
View File

@@ -0,0 +1,48 @@
+++
title = "Taula de contingut"
date = 2022-11-01
description = "Una publicació que mostra la taula de contingut opcional."
[taxonomies]
tags = ["funcionalitat", "markdown"]
[extra]
toc = true
+++
# Capçalera 1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
## Capçalera 2
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
### Capçalera 3.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
#### Capçalera 4.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
#### Capçalera 4.2
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
### Capçalera 3.2
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
#### Capçalera 4
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
#### Capçalera 4
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
---
## Capçalera 2
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
### Capçalera 3.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
#### Capçalera 4.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
#### Capçalera 4.2
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
### Capçalera 3.2
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
#### Capçalera 4.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
#### Capçalera 4.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.

48
content/blog/toc.es.md Normal file
View File

@@ -0,0 +1,48 @@
+++
title = "Tabla de contenido"
date = 2022-11-01
description = "Una publicación que muestra la tabla de contenido opcional."
[taxonomies]
tags = ["funcionalidad", "markdown"]
[extra]
toc = true
+++
# Encabezado 1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
## Encabezado 2
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
### Encabezado 3.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
#### Encabezado 4.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
#### Encabezado 4.2
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
### Encabezado 3.2
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
#### Encabezado 4
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
#### Encabezado 4
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
---
## Encabezado 2
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
### Encabezado 3.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
#### Encabezado 4.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
#### Encabezado 4.2
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
### Encabezado 3.2
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
#### Encabezado 4.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.
#### Encabezado 4.1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mollis augue, vel efficitur lacus. Pellentesque eu egestas mi. Etiam ultrices lectus sit amet aliquet ullamcorper. Praesent in erat quis est sagittis finibus. Etiam nec sapien in nulla interdum faucibus. Integer iaculis lorem quis arcu lobortis, non malesuada neque vehicula. Aenean nec tellus eu metus bibendum tempus. Sed rutrum urna ut commodo tempor. Vestibulum aliquet elit posuere turpis maximus condimentum. Sed urna libero, ornare eu tellus vitae, laoreet condimentum risus. Aenean elit lectus, mattis quis nibh nec, faucibus rutrum sapien. Sed iaculis consectetur mi, eget posuere turpis finibus et.