typst

How to get height or width of content and layout in Typst as a length type?


How to get widths of content and layout as a number (length type in Typst).


What I tried is to use layout() and measure() as suggested by Typst doc. Using these functions, I can show the width, for example 453.54pt, on the pdf file, but the data type of 453.54pt is content, and I cannot convert it to length type.

More specifically, I tried the following code:

#let layoutwidth = layout(size => {return size.width})
#let textwidthof(body) = context { return measure(body).width} // a function
#let atextwidth = textwidthof[Hello World]

Although we can print the two widths layoutwidth and atextwidth on the pdf file, it is of type content, not length. I also tried to convert it to string str() and then eval(), but it does not work! Any ideas?


Solution

  • I've been facing the exact same problem today, and finally found that it's due to the context.

    In the measure doc page they say it has to be used in a given context because it depends on where it is in the document.

    The thing is you have to be in a context to access the fields of width and height :

    #let authors = ("John One", "John Two", "John Three")
    #let org = "University"
    
    #let auths = text(style: "italic")[#authors.join(", ")]
    
    #context {
        let authsize = measure(auths).width
        let orgsize = measure(org).width
        set page(
            footer: [
                #text(size: 11pt)[#auths] #h(100% -authsize -orgsize -1pt) #text(style: "italic")[#org]
            ]
        )
    }
    

    However this would not work because the variable only exist in the context :

    #context {
        let authsize = measure(auths).width
        let orgsize = measure(org).width
    }
    
    #set page(
        footer: [
            #text(size: 11pt)[#auths] #h(100% -authsize -orgsize -1pt) #text(style: "italic")[#org]
        ]
    )
    

    And the following is what returns a content that we can't use, I'm not sure of the reason but I would guess that the content type comes from the context keyword :

    #let authsize = context measure(auths).width
    #let orgsize = context measure(org).width
    
    #set page(
        footer: [
            #text(size: 11pt)[#auths] #h(100% -authsize -orgsize -1pt) #text(style: "italic")[#org]
        ]
    )
    

    Edit : If the goal is to spread text across the page, it's better to use fr instead of context and measure.

    footer: [
        #text(size: 11pt)[#auths] #h(1fr) #text(style: "italic")[#org]
    ]