Having recently fallen in love with Typst, I wish to dive deap and learn as much as I can : )
The other day I got my first package submitted to Typst Universe, latex-lookalike.
Today I started to play around with internationalization support, and realized that one line in latex-lookalike which changes the default title of the outline from “Contents” to “Table of contets”, unfortunately also makes this change for all other languages, not just English.
set outline(title: [Table of contents])
If tried messing around with different options to resolve this issue, but so far I haven’t found a solution.
set outline(title: context {
if text.lang == "en" [ Table of contents ]
else {
// how can I get the `auto` output for other languages here?
}
})
Hello. Since show is not literal if, this won’t work:
#show text.where(lang: "en"): set outline(title: "this")
But literal if still won’t work, since you can’t mix context with set rules directly.
#context set outline(title: "Table of contents") if text.lang == "en"
This will work
#show: it => context {
set outline(title: "Table of contents") if text.lang == "en"
it
}
but only if the language is set before the context, so it’s not great. So the only other way would be to use show rules, since you can’t ask Typst to use auto if you override it with something.
#show outline: it => {
show heading: it => {
show "Contents": "Table of contents"
it
}
it
}
#outline()
= Heading
#set text(lang: "ru")
#outline()
= Heading
Thanks, I had a look at linguify and will probably use it for some of my documents.
But I don’t want to introduce dependencies in the latex-lookalike package, since I don’t know what internationalisation primitives the end users of the package will be using.
Wonderful, thanks for the detailed reply Andrew! I will have to give it some time to consider the different options. A text-substitute show rules works, but feels a little bit like a hack ^^
It’s hardly a hack, since you only have this outline title for exactly one language. It’s almost exactly the same as directly checking the language, but with less steps and complications.
To still use text.lang/text.region and be able to set them anywhere, you can make a wrapper:
#let outline(..args) = context {
set std.outline(title: "Table of contents") if text.lang == "en"
std.outline(..args)
}
#outline()
= Heading
#set text(lang: "ru")
#outline()
= Heading
However, the arguments completion no longer will work, and no docs. To mostly fix that, you would have to fully copy everything from the original function, like this:
/// A table of contents, figures, or other elements.
///
/// This function generates a list of all occurrences of an element in the
/// document, up to a given [`depth`](https://typst.app/docs/reference/model/outline/#parameters-depth). The element's numbering
/// and page number will be displayed in the outline alongside its title or
/// caption.
///
/// = Example
/// ```typ
/// #set heading(numbering: "1.")
/// #outline()
///
/// = Introduction
/// #lorem(5)
///
/// = Methods
/// == Setup
/// #lorem(10)
/// ```
///
/// = Alternative outlines
/// In its default configuration, this function generates a table of contents.
/// By setting the `target` parameter, the outline can be used to generate a
/// list of other kinds of elements than headings.
/// ...
#let outline(
depth: none,
indent: auto,
target: heading,
title: auto,
) = context {
set std.outline(title: "Table of contents") if text.lang == "en"
std.outline(
depth: depth,
indent: indent,
target: target,
title: title,
)
}