Why does 'set' not affect the output of a user defined function?

Hi, folks!

I’m trying to understand set with user defined functions and I’m confused about this behavour as I’m not able to use set to alter the width of the block created in the function opening.

Any ideas? Thanks in advance, Simon

#let opening(txt)=block(width:400pt, text(size: 40pt,txt))

//sets on document level
#set text(size: 20pt) //as expected, changes only font size of document scoped block
#set block(width:200pt) //as expected, changes only width of document scoped block

//function call
#opening([
//sets in the scope of the function
#set text(size: 10pt) //as expected, changes only font size of functional created text 
#set block(width:800pt) //not working, does not change width of functional created block
#lorem(30)]
)

//a block created in document scope
#block(
  inset: 12pt,
  radius: 4pt,
  lorem(30),
)


Please give some more information on the problem at hand. What outcome do you expect and how does the actual output differ from that?

[ To me everything seems to be working es expected. ]

PS: you should probably adjust your title according to the guidlines of this forum. Therefore please reformulate it as a question. Thanks ;)

Maybe you should have a look at this slightly changed example. Here I added strokes to the three different calls to block to clarify where you use all of them.

#let opening(txt)=block(width:200pt, stroke: black, text(size: 40pt,txt))

//sets on document level
#set text(size: 20pt) //as expected, changes only font size of document scoped block
#set block(width:300pt, stroke: blue) //as expected, changes only width of document scoped block

//function call
#opening(
  [
    //sets in the scope of the function
    #set text(size: 10pt) //as expected, changes only font size of functional created text 
    #set block(width:400pt) //not working, does not change width of functional created block
    
    #lorem(30)
    #block(stroke: red, lorem(50))
    #lorem(30)
  ]
)

//a block created in document scope
#block(
  inset: 12pt,
  radius: 4pt,
  lorem(30),
)

This is the output:

If you want to see the affected text sequences of your calls to text more clearly (e.g. where the size is actually adjusted) you can also use the color parameter for text.

1 Like

Hi there,

okay, you pass a new block to the opening function. So now two blocks are nested. Its interesting for me that now #set block inside the call of opening is effecting only the most nested block.

My main question is: why can I change the text size by including a set text(size: …) in the content of the opening function call, but I can not change the width of the block created in that function by using a identical set block(width: …)?

Regards Simon

The width of the block is indeed changed by the your set block ... statement. See the red block, it has width 400 instead of 300. (if you remove the set block() the red block will have width 300.

It works the same as the text size.

You are defining a function opening which creates a block with a specific size. Why would instructions inside the body of this block affect the outer block ??? (think about it for a second, this would be an absolute nightmare … xD)

but set text(size …) on line 11 in your example inside the opening function does change the font size in the red AND the black surrounded block…

Hi @Simon,
as @Xodarap already showed with the blocks, set rules do only affect elements after the rule and inside the same or a nested scope. It does not change the surrounding elements.
Maybe this makes it clear for you, I have inlined your opening(txt) function:

//sets on document level
#set text(size: 20pt)
#set block(width:200pt) 

// Inlined "opening(txt)" function
#block(
  width:400pt, 
  text(
    size: 40pt, 
    [
      This is some text // Added additional text
      //sets in the scope of the function
      #set text(size: 10pt)
      #set block(width:800pt) ) // There is no block below, that can be affected by the set rule

      #lorem(40) // Effected by the above text set rule
      // Equal to #text(lorem(40)) 
      // Equal to #text(size: 10pt, lorem(40)) with the above set rule applied
    ]
  )
)

//a block created in document scope
#block(
  inset: 12pt,
  radius: 4pt,
  lorem(30),
)
Output

1 Like

thanks,

There is no block below, that can be affected by the set rule

now its clear

Hey @Simon, welcome to the forum! I’ve changed your question post’s title to better fit our guidelines: How to post in the Questions category

For future posts, make sure your title is a question you’d ask to a friend about Typst. :wink:

1 Like