#How to get heading text from label?

31 messages ยท Page 1 of 1 (latest)

sour edge
#

Is there a way to get the text of the heading associated with a label?

e.g.,

  str(l) 
}

== The Heading Text <test>

#header_text(<test>)```
Looking for `#header_text(<test>)` to output `The Heading Text` and not `test`

Thanks in advance.
woeful depot
#

indeed, str(x) will stringify what you gave to it, in this case the label itself

sour edge
#

Thanks @woeful depot , I've got the following working, but I'm wondering if there's some simplification that can be done?

  locate(loc => {
    let elems = query(
      selector(heading).before(l),
      loc
    )
    elems.last().body
  })
}

In particular the part that puzzles me is the loc seems to be required by query but it shouldn't be relevant as I'm looking for l?

woeful depot
#

yeah, it was only required before to force you to use locate

#

because this kind of thing cant be done within normal code, code is run before the document is laid out

#

so you use an element (locate) which is placed into the document and then, during layout, runs your code with layout info

#

then you can query

#

but this approach has been superseded by the context { } syntax

#

which does the same thing but hides it conveniently enough

#

so now you can write

#let header_text(l) = context {
  let elems = query(
    selector(heading).before(l)
  )
  elems.last().body
}
#

just note that, due to what I explained above, you wont be able to access the actual returned value there

#

that is, you wont be able to reason about what header_text(l) returns

#

since the evaluation of your contextual code is deferred , your code is only run later, during layout
so non-contextual code wont be able to interact with that piece of code

sour edge
#

Ah got it, that makes sense.

#

I don't need to reason about the text returned in this case, but that's good to know for the future.

#

The other question is whether there's a way to optimize the query, as it seems inefficient (at least theoretically, I'm not sure if it's already optimized in some way under the hood), to query all headings before the label and just get the last one.

But I'm guessing, based on what I'm learning above from the layout pass needed, that a label doesn't actually "associate" with anything, but just a position in the document? So there's no way to say select 'heading' associated with 'label'?

woeful depot
#

oh, i didnt notice that in your code

#

indeed, you can just query(l).first().body

sour edge
#

Oh haha that's perfect, thank you.

#

Feels cleaner now ๐Ÿ˜Š

woeful depot
#

np ๐Ÿ‘

sour edge
#
  locate(loc => {
    query(l, loc).first().body
  })
}```
woeful depot
#

i'd suggest using context from now on

#

as locate (at least with that particular usage) is now deprecated

#

basically just context { ... } and then query(l) (no loc)

#

one advantage of using context is that there's a convenient way to sidestep the "not being able to reason about" problem

sour edge
#

I guess I can now, I just got the Typst 0.11 update in VS Code. ๐Ÿ˜Š

woeful depot
# woeful depot one advantage of using `context` is that there's a convenient way to sidestep th...

with the simple fact that you can just omit the context keyword from your function
that is , it'd look like #let header_text(l) = query(l).first().body

that means that calling it normally will error, so you will have to type #context header_text(l)

but if you're already within a context block, you'll be able to do something like

#context {
  let x = header_text(l)
  [Stuff #x etc]
}

without a problem

#

so, yeah, keep an eye on these tricks โ„ข๏ธ (this is a new thing from 0.11, it's pretty dope)

sour edge
#

Ok thanks for all the information ๐Ÿ˜Š