State length error in place coordinate

#let cursor = state(“cursor”, 0.1em)
#let placeNeume(gabcneume) = {

let dx = context cursor.get()
[#dx]
[#pitches.at(pitch)]
place(dx:dx,dy:-pitches.at(pitch),neumentypes.at(“g”))

dx and pitches show me both a length (e.g. 0.1em)
for the dy the placing works fine, but dx throws an error:
error: expected relative length, found content
┌─ lib.typ:54:11

54 │ place(dx:dx,dy:-pitches.at(pitch),neumentypes.at(“g”))
│ ^^

why is it content and not relative length ?!

Hello @Julian, welcome to the forum and thank you for your question.

You will notice it is not easy to view the code snippet you have posted. If you could please edit your post to follow the guidance provided in:

This way your code will look like:

#let cursor = state(“cursor”, 0.1em)
...

It is easier to copy and paste and to read all along.

Could you please ensure that the code snippet compiles without any other modification, this in order to help you best.

To understand why dx is of type content , see Why is the value I receive from context always content? for more details.

Thanks, that was helpful :slight_smile:

I have now a similar issue, I get the error:

error: cannot add length and content
    ┌─ lib.typ:239:4
    │
239 │     currentWidth += w

But my groupTokens fct need to be off context, I need a conversion from content to length.

#let groupTokens(tokens) = {
  let groups = ()
  let currentGroup = ()

  let currentWidth = 0pt
  // let currentWidth = state("currentWidth", 0pt)

  let maxWidth = 800pt

  for token in tokens {
    currentGroup.push(token)

    let tokenType = determineTokenType(token)
    let w = if tokenType == "separation" {horizontalspacing}
    else if tokenType == "item" {
      let parts = token.split("(")
      let text = parts.at(0)
      let neume = parts.at(1).slice(0, parts.at(1).len() - 1)
      calculateItemWidth(text, neume)
    }
    else {horizontalspacing}
    currentWidth += w
    if currentWidth > maxWidth {
      groups.push(currentGroup)
      currentGroup = ()
      currentWidth.set(0pt)
    }
  }

On the other hand this fuction needs to be in context, at least for the measuring (so far my understanding).

#let calculateItemWidth(text, notes) = context {
  // let spacing = horizontalspacing
  let hasMora = notes.last() == "."
  let base = if hasMora {notes.slice(0, notes.len() - 1)}
  else {notes}
  let neumetype = detectNeumeType(base)
  // context{
  let neumeWidth = measure(neumetype).width
  let textWidth = measure(text).width/2
  let spacing = calc.max(neumeWidth, textWidth, horizontalspacing)
  spacing
  }
}

how can I convert content to length. Or at which point I can swtich from off context to in context ?

Try moving the context outwards to avoid using content:

#let groupTokens(tokens) = {
  …
  for token in tokens context { // To here 
    currentGroup.push(token)

    let tokenType = determineTokenType(token)
    let w = if tokenType == "separation" {horizontalspacing}
    else if tokenType == "item" {
      let parts = token.split("(")
      let text = parts.at(0)
      let neume = parts.at(1).slice(0, parts.at(1).len() - 1)
      calculateItemWidth(text, neume)

  …
  }

#let calculateItemWidth(text, notes) = { //From here
  // let spacing = horizontalspacing
  let hasMora = notes.last() == "."
…
#let groupTokens(tokens) = {
  let groups = ()
  let currentGroup = ()

  let currentWidth = 0pt
  let maxWidth = 200pt

  for token in tokens {
    context{
    currentGroup.push(token)

    let tokenType = determineTokenType(token)
    let w = if tokenType == "separation" {horizontalspacing}
    else if tokenType == "item" {
      let parts = token.split("(")
      let text = parts.at(0)
      let neume = parts.at(1).slice(0, parts.at(1).len() - 1)
      calculateItemWidth(text, neume)
    }
    else {horizontalspacing}
    currentWidth += w
    if currentWidth > maxWidth {
      groups.push(currentGroup)
      currentGroup = ()
      currentWidth.set(0pt)
    }
  }}
  groups
}

ok, but now I cannot return the array :/

error: cannot join content with array

and with

return groups

The content get discarded

warning: this return unconditionally discards the content before it
    ┌─ lib.typ:239:2
    │
239 │   return groups
    │   ^^^^^^^^^^^^^
    │
    = hint: try omitting the `return` to automatically join all values

You won’t be. It is the same answer as the precedent one. You will need to move context outwards until everything needed is within that same context scope.

I suggest you read again the first post I have referred to. It may take a few times to realize it, but trying to extract values from content is usually not the good solution.

Same problem as this How to convert content to length

1 Like