Hello! I use (and am one of the maintainers of) a bibliography auto-generation command-line tool called Autobib. Essentially, given a list of citation keys in a specific format, Autobib generates a .bib file containing exactly those citation keys, with data either from a local cache or retrieved from a remote API.
The most convenient option is for Autobib to be able to automatically retrieve all citation keys directly from a file. However, I am struggling to understand how to best integrate this with Typst.
In this PR I implemented very basic support using the typst-syntax crate to find all explicit #cite function calls and to extract label text. This works, but it is somewhat fragile:
It misses custom citation syntax #let c = cite and #c(<ref>), label text generated by another function, etc.
It does not handle @ref at all: I do not know how to distinguish existing internal links, undefined internal links, and genuine citation keys.
I also tried typst query file.typ cite --field key, but undefined citation keys result in an error, and the whole point of Autobib is to programmatically retrieve the data for undefined citation keys.
Finally, I looked a bit into implementing this as a plugin. An ideal solution would be to define a special function, say #autocite, such that one can call #autocite(<ref>) and then this calls back into Autobib to generate the bibliographic data and then inserts a #cite(<ref>) in-place, before bibliography parsing occurs. But it seems that calling into external code is not really a supported use-case for plugins, and moreover the above pattern might not compatible with the Typst compilation model.
I am curious if there are any suggestions for the best way to integrate Autobib into Typst? I appreciate any thoughts about this, thank you!
Well, I don’t quite understand your situation, but you can wrap the original *.typ with some hacks and then typst query will work fine.
// Convert (possibly broken) citations to metadata.
#show ref: it => {
if it.element == none {
[#metadata(it)<hack>]
} else {
it
}
}
#show cite: it => [#metadata(it)<hack>]
// -----------------------
// Start of the original *.typ
#set heading(numbering: "1.1")
= Internal <internal>
Ignored internal: @internal.
@zbl:1337.28015
#cite(label("doi:10.4007/annals.2014.180.2.7"))
@mr:3224722[p.~7]
`#cite(<raw>)`
// End of the original *.typ
// -----------------------
#bibliography(bytes("")) // Create an empty bibliography source
$ typst query a.typ '<hack>' --format yaml
- func: metadata
value:
func: ref
target: <zbl:1337.28015>
supplement: auto
form: normal
citation:
func: cite
key: <zbl:1337.28015>
supplement: null
element: null
label: <hack>
- func: metadata
value:
func: cite
key: label("doi:10.4007/annals.2014.180.2.7")
supplement: null
form: normal
style: auto
label: <hack>
- func: metadata
value:
func: ref
target: <mr:3224722>
supplement:
func: sequence
children:
- func: text
text: p.
- func: symbol
text:
- func: text
text: '7'
form: normal
citation:
func: cite
key: <mr:3224722>
supplement:
func: sequence
children:
- func: text
text: p.
- func: symbol
text:
- func: text
text: '7'
element: null
label: <hack>
Thank you for the detailed response! This solution using typst query works very well. Thanks for the heads up about typst eval as well.
To rephrase my original question in case someone else looks at this, I was wondering about the best way to extract all bibliographic citation keys from a Typst file, whether or not they are defined in a bibliography.