How to find out whether raw text or a table is passed as a parameter?

Basically the title.
Before passing a parameter to figure(...) I`d like to know whether the parameter contains raw text or a table.
It doesn’t look like raw or table are locatable. How can I approach this?
I want to know the data type (raw, table, image) before I call figure(...).

1 Like

I’ve found that you can recursively search for a raw element by exploring children and body. Content elements have children, while other elements such as table and block have a body field.

I’m not sure if it’s enough to explore children and body to cover all cases. The following example searches for a raw element, though it can easily be extended to also check for table.

#let contains-raw(elem) = {
  if elem.func() == raw {
    true
  }
  else if elem.has("children") {
    elem.children.any(contains-raw)
  }
  else if elem.has("body") {
    contains-raw(elem.body)
  }
  else {
    false
  }
}

#let test-1 = [
  Does not contain raw
  #block[
    Not here
  ]
  #block[
    nor here
  ]
]

#let test-2 = `is directly raw`

#let test-3 = [
  #table(
    columns: (auto, auto),
    [here], [`raw inside table`]
  )
]

#let test-4 = [
  #block[
    `raw stuff`
  ]
]

#contains-raw(test-1)
#contains-raw(test-2)
#contains-raw(test-3)
#contains-raw(test-4)
Output
false true true true
1 Like

Thank you for the inspiration. I modified it and so far it seems to be working:

#let TYPE_IMG = 0
#let TYPE_RAW = 1
#let TYPE_TBL = 2

#let get_type(elem) = {
  if elem.func() == raw {
    TYPE_RAW
  } 
  else if elem.func() == table {
    TYPE_TBL
  }
  else if elem.has("children") {
    let t1 = elem.children.position(it => get_type(it) == TYPE_RAW)
    let t2 = elem.children.position(it => get_type(it) == TYPE_TBL)
    
    if t1 != none and t2 == none {TYPE_RAW}
    else if t1 == none and t2 != none {TYPE_TBL}
    else if t1 == none and t2 == none {TYPE_IMG}
    else {
      if t1 < t2 {TYPE_RAW}
      else {TYPE_TBL}
    }
  }
  else if elem.has("body") {
    get_type(elem.body)
  }
  else {
    TYPE_IMG
  }
}
1 Like

I have a hunch that you just want to use #show figure.where(kind: ...) instead (Figure Function – Typst Documentation). Can you share why you need to get the type of the parameter and how you then use this information? There is a good change, this can be drastically simplified (but not 100%). :)