Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/docs.typ
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#import "@preview/gentle-clues:0.7.1": abstract, quote as _quote

#let l = [_linguify_]
#let L = [_Linguify_]

#show raw.where(block: false): it => {
box(fill: luma(240), radius: 5pt, inset: (x: 3pt), outset: (y: 3pt), it)
Expand Down Expand Up @@ -96,6 +97,18 @@ Test: #linguify("test")
The content of the `lang.toml` file, used in the example above looks like this.
#raw(lang: "toml", read("lang.toml"))

== Handling outlines

#L looks up translations in the _currently active_ database. This is a problem with outlines, because outline entries are rendered at a different location than the elements they refer to (headings, figures). In this case, an unexpected database may be used.

If you use multiple databases for different parts of your document, and also use translations for your heading or figure captions, you can add the following show rule to ensure correct database lookup:

```typ
#show outline.entry: it => database-at(it.element.location(), it)
```

See the #ref-fn("database-at()") function for more details.

== Information for package authors.<4pck>

As the database is stored in a typst state, it can be overwritten. This leads to the following problem. If you use #l inside your package and use the #ref-fn("set-database()") function it will probably work like you expect. But if a user imports your package and uses #l for their own document as well, he will overwrite the your database by using #ref-fn("set-database()"). Therefore it is recommend to use the `from` argument in the #ref-fn("linguify()") function to specify your database directly.
Expand Down
Binary file modified manual.pdf
Binary file not shown.
2 changes: 1 addition & 1 deletion src/lib.typ
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#import "linguify.typ" as lflib: set-database, reset-database, linguify
#import "linguify.typ" as lflib: set-database, reset-database, database-at, linguify
#import "fluent.typ": load-ftl-data
#import "utils.typ" as utils: if-auto-then
44 changes: 43 additions & 1 deletion src/linguify.typ
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,45 @@
/// - ...
#let database = state("linguify-database", none)

/// A stack (array) of `location`s to use instead of `here()` when looking up the current database.
/// This is used internally to support looking up translations in e.g. outlines relative to a
/// heading's or figure's location, instead of the outline's.
///
/// When the stack is empty, the current location is used.
#let location-stack = state("linguify-location-stack", ())

/// Temporarily overrides the location at which the translation database is looked up.
/// This is typically used to change the lookup inside outlines. Consider this:
///
/// ```typ
/// #set-database(toml("a.toml"))
/// #outline()
/// = linguify("foo")
///
/// #set-database(toml("b.toml"))
/// = linguify("bar")
/// ```
///
/// In this example, the `foo` translation should be loaded from `a.toml` and `bar` from `b.toml`.
/// However, the outline is covered by `a.toml` -- including the entry for the `bar` heading!
///
/// Adding the following show rule at the beginning fixes this:
///
/// ```typ
/// #show outline.entry: it => database-at(it.element.location(), it)
/// ```
///
/// This will make linguify look up the translations for each outline entry at the location the
/// referenced element (heading) is located.
#let database-at(
loc,
body,
) = {
location-stack.update(it => (..it, loc))
body
location-stack.update(((..it, _)) => it)
}

/// Set the default linguify database
///
/// The data must contain at least a lang section like described at @@database.
Expand Down Expand Up @@ -91,7 +130,10 @@
lang: auto,
args: auto,
) = {
let database = if-auto-then(from, () => database.get())
let database = if-auto-then(from, () => {
let location = location-stack.get().at(-1, default: here())
database.at(location)
})

// check if database is not empty. Means no data dictionary was specified.
if database == none { return error("linguify database is empty.") }
Expand Down
5 changes: 5 additions & 0 deletions tests/outline-location/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# generated by tytanic, do not edit

diff/**
out/**
ref/**
9 changes: 9 additions & 0 deletions tests/outline-location/a.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[conf]
default-lang = "en"

[lang.en]
apple = "Apple"
pear = "Pear"
banana = "Banana"

red = "different red"
7 changes: 7 additions & 0 deletions tests/outline-location/b.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[conf]
default-lang = "en"

[lang.en]
red = "red"
green = "green"
yellow = "yellow"
9 changes: 9 additions & 0 deletions tests/outline-location/ref.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#import "/src/lib.typ": *

= Apple
= Pear

#outline()

= red
green
23 changes: 23 additions & 0 deletions tests/outline-location/test.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#import "/src/lib.typ": *

#show outline.entry: it => database-at(it.element.location(), it)

// Initial database for cover page
#let database = toml("a.toml")
#set-database(database)

// These keys are found in the initial database
= #linguify("apple")
= #linguify("pear")

// Generate the outline
#outline()

// Switch to the main translation database
#let database = toml("b.toml")
#set-database(database)

// This key is NOT found in the header!
= #linguify("red")
// This key IS found in regular text
#linguify("green")