mirror of
https://0xacab.org/anarsec/anarsec.guide.git
synced 2025-06-08 06:42:56 -04:00
250 lines
7.1 KiB
Typst
250 lines
7.1 KiB
Typst
#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)
|
||
]
|
||
]
|
||
]
|
||
|