Skip to content

Instantly share code, notes, and snippets.

@lxl66566
Created December 23, 2023 02:34
Show Gist options
  • Save lxl66566/30e309e696169829524ee04503b526db to your computer and use it in GitHub Desktop.
Save lxl66566/30e309e696169829524ee04503b526db to your computer and use it in GitHub Desktop.
typst content.at() will always check 'default' even if the given field exists
#let get_text(knt) = {
let temp = knt.at("body", default: false)
if temp == false { temp = knt.at("text") }
temp
}
#let get_text2(knt) = {
knt.at("body", default: knt.at("text", default: "anything"))
}
#let get_text3(knt) = {
knt.at("body", default: knt.at("text"))
// error: content does not contain field "text" and no default value was specified
}
#get_text([*20*])
#get_text([20])
#get_text2([*20*])
#get_text2([20])
#get_text3([*20*])
#get_text3([20])
@lxl66566
Copy link
Author

❯ typst --version
typst 0.10.0 (70ca0d25)

@lxl66566
Copy link
Author

lxl66566 commented Dec 23, 2023

#[func]
pub fn at(
    &self,
    /// The field to access.
    field: Str,
    /// A default value to return if the field does not exist.
    #[named]
    default: Option<Value>,
) -> StrResult<Value> {
    let Some(id) = self.elem().field_id(&field) else {
        return default.ok_or_else(|| missing_field_no_default(&field));
    };
    self.get(id)
        .or(default)
        .ok_or_else(|| missing_field_no_default(&field))
}

There may be no simple way to fix that because default has been calculated into a Value before the function at is called.
I think knt.at("body").or(something_default) (actually or_else) is "the rust way", and it can avoid this problem caused by evaluation strategy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment