There’s a video game that stores its dialogue transcript in all the languages supported by the game inside a single .csv
file. With Typst, I can turn this into a table, which helps me a lot in learning/practising some of the languages.
The .csv
file contains some game-specific markup that makes pieces of the text show up as bold or italics, or with a different size or colour in the game. Here are a few examples:
{i}This{/i} should be emphasized. {i}Another{/i} example.
{color=#3761d9}Blue{/color} coloured text.
{size=20}This{/size} should be smaller.
My end-goal would be to turn the example above into this:
#emph[This] should be emphasized. #emph[Another] example.
#text(rgb("#3761d9"), [Blue]) coloured text.
#text(0.7em, [This]) should be smaller.
Output screenshot
Here’s my attempt so far:
Source code with rules and turning the CSV into a table
#let transcript = csv("transcript.csv", row-type: dictionary)
// Italics and bold
#show regex("\{i\}.*\{/i\}"): it => {
show regex("\{i\}"): ""
show regex("\{/i\}"): ""
emph[#it]
}
#show regex("\{b\}.*\{/b\}"): it => {
show regex("\{b\}"): ""
show regex("\{/b\}"): ""
emph[#it]
}
// Size and colour
#show regex("\{size=\d+\}.*\{/size\}"): it => {
show regex("\{size=\d+\}"): ""
show regex("\{/size\}"): ""
text(rgb("#666"), it)
}
#show regex("\{color=#......\}.*\{/color\}"): it => {
show regex("\{color=#......\}"): ""
show regex("\{/color\}"): ""
text(rgb("#666"), it)
}
#table(
columns: 4,
stroke: 0.3pt,
table.header([*Key*], [*English*], [*Spanish*], [*Japanese*],),
..transcript.map(row => (row.Key, row.Standard, row.Spanish, row.Japanese)).flatten()
)
For handling the markup for colour and size changes, I believe I would need to capture the values for that (like #3761d9
and 20
), which I don’t know how to do (yet). So, for now, I’ve just made two rules that turn anything wrapped in a {color}
or {size}
into grey. (While not the ideal solution, at least this would be a clear indication that the passage in question is supposed to have some special markup.)
As for text wrapped in {i}
or {b}
, the rules mostly work. The only problem is when there are two non-consecutive pieces of text meant to be displayed in italics, everything between them is also turned into italics. (This might have something to do with how greedy the regex rule is.)
Output screenshot with the italics rule
P.S.: I’ve also thought about manipulating the .csv
file with sed
in a way that Typst’s own markup is read from there instead of relying on show rules, but I’m not sure if Typst would recognise the markup that way.