How do I create an inline element that can be referenced?

I’m trying to define a function that returns elements that can be referenced using ref. This works if the function returns a figure element and nothing else, but the figure is a block-level container and will force a paragraph break to the subsequent text:

#show heading.where(level: 3): it => [#it.body\.]

#let wp(x) =  {
  let title = context {   
    [WP #counter(figure.where(kind: "wpfigure")).display(): #x] 
  }
  figure(heading(level: 3, numbering: none, title), kind: "wpfigure", supplement: "WP")
}


#text(fill: red)[This is what it looks like:]

#wp[My work package] <wp1>
#lorem(30) @wp1


#text(fill: red)[This is what I want:]

=== WP 1: My work package
#lorem(30)

Wrapping the figure in a box will make it inline, but then the function returns a box and not a figure, and a box can’t be referenced.

I thought about breaking the figure content out of the figure through a show rule, but that just looks the same:

#show figure: it => it.body

Does anyone have advice on either styling the figure so it becomes inline, or on an inline element that I can use in place of figure? Thanks!

I know that you can work around the “box(figure) label attachment problem” with a show rule, like this:

#show figure.where(kind: "wpfigure"): box

This way the label can still attach to the figure before the figure is wrapped in a box.

Thank you! That would be an amazing solution, but if I add #show figure: box to my MWE above, it still looks the same. :/

Oh, I’m sorry about that. Then there is enough going on with the default figure show rules that we can’t seem to override its kind of placement.

My guess about what’s happening, it’s like this:

#show block: box                // yes we can make the block inline
#show block: set align(center)  // unless we have this line; impossible to make it inline now
#block[Hello]<label> world

Elembic also has not solved this problem, seeing its docs:

labelable: Set this to true to support outer label syntax: #elem(...) <label-here>. The downsides are that #show: e.prepare() becomes required to use the element, the element can no longer be inline, and show rules on the individual labels no longer have access to final fields.

This makes me think that there is no easy way to do this.

2 Likes

Oh, thanks for the pointer to elembic. That makes a lot of sense. Thank you for your answer!

The workaround elembic uses is I believe what would be let wp(x, label: none) in your case - you pass the label as a parameter.

Yes, I have used this workaround too, I was just hoping one could use the normal label syntax.

I like their recommended syntax of #wp(label: <x>)[title], as opposed to the #wp([title], label: <x>) that I was using previously. I suppose I can live with that for now.