How should i do, can change lib's component func by lib's input?

/*****************
*      lib       *
*****************/
#let mylib(fill: none, body) = {
  body
}

#let lib-component-func(content) = {
  // this box's fill will changed by mylib input
  box()[#content]
}

/*****************
*      User      *
*****************/
// case1: draw a red box
#show: mylib.with(fill: red)
#lib-component-func("hello")

// case2: draw a green box
#show: mylib.with(fill: green)
#lib-component-func("world")
1 Like

The basic idea here is that everything in the function is definite (for the same input the function should generate the same result). So there are 2 ways to achieve this:

  • Use a context block (The function generates the same context content, the color is determined after it is inserted into the document according to the “context”)
  • (Recommended) Let users customize the function by themselves (The function accepts a color parameter and the user can set it easily)

Context solution

If you wrap it with a context block:

#let global-color = state("my-box-color", blue.lighten(40%))
#let set-color(c) = global-color.update(c)
#let smart-box(cont) = context {
  box(cont, fill: global-color.get())
}

And make sure to add the global-color.update content into the document in your main show function to make sure the state updates correctly.

.with solution

Using context immoderately would cause disasters, for example, if you would like to modify the smart-box above, you may find that the type of its return value has been content, which is hard to customize further.

I would like to define a function like this:

#let stupid-box(cont, fill: blue.lighten(40%)) = box(cont, fill: fill)

And in the main file add the following code:

#import "somewhere/lib.typ": stupid-box
#let my-box = stupid-box.with(fill: red)

which is much more simple and steerable.

Conclusion

state and context allow you to make it work like a “global variable”, but this usually get into a mess when the global context become more and more complicated. Using the recommended way would make sure users know what they are getting from the function.

1 Like