anarsec.guide/layout/anarsec_article.typ
2025-01-04 00:26:12 -05:00

250 lines
7.1 KiB
Typst
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#let anarsec_article(
title: none,
frontimage: none,
backimage: none,
lastediteddate: none,
description: none,
subtitle: none,
category: none,
backcoverinsidecontent: none,
lang: none,
content
) = {
set document(date: none)
set text(lang: lang)
set text(hyphenate: true)
// format lists
set list(marker: ([], [--]))
// front cover
page()[
#place(
center + top,
dy: 250pt,
image(frontimage)
)
#place(
center + top,
dy: 100pt,
)[
#set text(hyphenate: false, font: "Jost")
#text(35pt, title)
#{
if subtitle != "None" {
text(18pt, subtitle)
}
}
]
#place(
center + bottom,
dy: -20pt,
)[
#set text(hyphenate: false, font: "Jost")
#if lang == "en" [
#text(18pt)[Series: #category]
]
#if lang == "fr" [
#text(18pt)[Série: #category]
]
#if lang == "el" [
#text(18pt)[Σειρά: #category]
]
#if lang == "ru" [
#text(18pt)[Серии: #category]
]
#if lang == "pt" [
#text(18pt)[Séries: #category]
]
]
]
// inside cover
page()[
#if lang == "en" [
#set align(center + bottom)
#text()[This version of the zine was last edited on #lastediteddate. Visit anarsec.guide to see whether it has been updated since.]
#text()[The dagger symbol #super[] on a word means that there is a glossary entry for it. Ai ferri corti.]
]
#if lang == "fr" [
#set align(center + bottom)
#text()[Cette version de la brochure a été modifiée pour la dernière fois le #lastediteddate. Visitez anarsec.guide/fr pour savoir si elle a été mise à jour depuis.]
#text()[Le symbole de dague #super[] près d'un mot indique qu'une entrée existe dans le glossaire pour ce mot. Ai ferri corti.]
]
#if lang == "el" [
#set align(center + bottom)
#text()[Αυτή η έκδοση της μπροσούρας τροποποιήθηκε τελευταία φορά στις #lastediteddate. Επισκέψου το anarsec.guide/el για να δεις εάν έχει ενημερωθεί από τότε.]
#text()[Το σύμβολο στιλέτο #super[] σε μια λέξη σημαίνει ότι υπάρχει μια καταχώριση στο γλωσσάρι για αυτήν. Ai ferri corti.]
]
#if lang == "ru" [
#set align(center + bottom)
#text()[Эта версия зина была последний раз обновлена #lastediteddate. Зайдите на сайт anarsec.guide/ru и посмотрите, нет ли более поздних редакций.]
#text()[Символ #super[] означает, что этот термин есть в словаре. Ai ferri corti.]
]
#if lang == "pt" [
#set align(center + bottom)
#text()[Essa versão do zine foi editada por último em #lastediteddate. Visite anarsec.guide/pt para consultar possíveis atualizações.]
#text()[O símbolo de adaga #super[] significa que ela tem uma entrada no glossário. Ai ferri corti.]
]
]
// set headings
show heading.where(level: 1): it => {
block(width: 100%)[
#set align(center)
#set text(hyphenate: false, size: 22pt, font: "Jost")
#text(underline(it.body))
#v(10pt)
]
}
show heading.where(level: 2): it => block(width: 100%)[
#set text(hyphenate: false, size: 16pt, font: "Jost")
#text(it.body)
#v(10pt)
]
show heading.where(level: 3): it => block(width: 100%)[
#set text(hyphenate: false, size: 13pt, font: "Jost", style: "italic")
#text(it.body)
#v(10pt)
]
show heading.where(level: 4): it => block(width: 100%)[
#set text(hyphenate: false, size: 11pt, font: "Jost")
#text(underline(it.body))
#v(10pt)
]
// table of contents
outline(indent: 20pt, depth: 2)
// format links
let before = ""
let after = ""
let rec = ""
if lang != "en" {
before = "/" + lang
after = lang + "/"
}
if lang == "en" {
rec = "Appendix: Recommendations"
}
else if lang == "fr" {
rec = "Annexe: Recommendations"
}
else if lang == "el" {
rec = "Παράρτημα: Προτάσεις"
}
else if lang == "ru" {
rec = "Приложение: Рекомендации"
}
else if lang == "pt" {
rec = "Apêndice: Recomendações"
}
let glossaryFootnote = state("x", [#footnote[anarsec.guide/glossary]<glossary-footnote>])
show link: it => {
it.body
if type(it.dest) == "string" {
if it.dest == ("https://anarsec.guide/" + after + "recommendations") or it.dest == (before + "/recommendations") {
text[ (#emph()[rec])]
}
else if it.dest.starts-with(before + "/recommendations#") or it.dest.starts-with(before + "/recommendations/#") {
context {
let elements = query(label(it.dest.trim(before + "/recommendations#", at: start).trim(before + "/recommendations/#", at: start)))
text[ (#emph()[rec])]
}
}
else if it.dest.starts-with("https://") or it.dest.starts-with("http://") {
footnote[#it.dest.trim("https://", at: start).trim("http://", at: start).trim("www.", at: start)]
}
else if it.dest.starts-with(before + "/glossary#") or it.dest.starts-with(before + "/glossary/#") {
context {
let elements = query(heading.where(label: label(it.dest.trim(before + "/glossary#", at: start).trim(before + "/glossary/#", at: start))))
if elements.len() != 0 {
text[#super[]]
}
else {
context glossaryFootnote.get()
glossaryFootnote.update(x => footnote(<glossary-footnote>))
}
}
}
else if it.dest.starts-with("/") {
footnote({text[anarsec.guide] + it.dest})
}
}
else if type(it.dest) == "label" {
locate(location => {
let elements = query(it.dest, location)
text[ (#emph(elements.first().body))]
})
}
}
// content
set page(numbering: "1")
set align(left)
pagebreak(weak: true)
content
set page(numbering: none)
set heading(outlined: false)
// back cover inside
page()[
// set headings
#show heading.where(level: 1): it => {
block(width: 100%)[
#set align(center)
#set text(size: 22pt, font: "Jost")
#text(it.body)
#v(10pt)
]
}
// format links
#show link: it => {
it.body
}
#backcoverinsidecontent
]
// back cover
page()[
#text()[
#place(center + horizon, dy: -100pt, block(width: 100%, align(left, par(justify: true, description))))
#place(center + bottom, dy: 20pt, image(height: 250pt, backimage))
]
]
}
// blockquote function ; TODO: remove when typst has a native blockquote function (see https://github.com/typst/typst/issues/105)
#let blockquote(
content
) = align(center)[
#block(width: 92%, fill: rgb(230, 230, 230), radius: 4pt, inset: 8pt)[
#align(left)[
#text(content)
]
]
]