cetz-package / cetz

CeTZ: ein Typst Zeichenpaket - A library for drawing stuff with Typst.
https://cetz-package.github.io
GNU Lesser General Public License v3.0
885 stars 36 forks source link

Generalised Styling Method #57

Closed fenjalien closed 1 year ago

fenjalien commented 1 year ago

When styling in TikZ you use key-value pairs which can be passed to draw commands using square brackets or with the \tikzset command. In typst-canvas you set the stroke and fill with the dedicated methods or for each draw command, additional styling for elements can be set with their respective draw functions.

I want to propose a new function that can set styling options for all elements in a similar manner to TikZ's key-value pairs except with dictionaries (as this is Typst's equivalent). The current stroke and fill methods can remain as short hand notation for this generalised method.

Name

Either style or styling, with a possible prefix of set-.

How it should work / Ideas

#set-style(..styling)

To set the stroke and fill of following draw methods:

// Stroke of blue and fill of red
set-style(stroke: blue, fill: red)
// Draws a red circle with a blue border
circle(())

Dictionaries should update the style, not override the option:

// Red stroke with a thickness of 5pt
set-style(stroke: (paint: red, thickness: 5pt))
// Changes the stroke to be blue but keeps the thickness of 5pt
set-style(stroke: (paint: blue))

A way to specify that the dictionary should set the value instead of updating it should be made available. Maybe update: false to keep a similar syntax to relative coordinates.

It should be possible to override and set styling for each draw method:

// Sets the global stroke to red
set-style(stroke: red)
// Sets the stroke for this line to be blue
line((1,0), (0,0), stroke: blue)

This could be done by using a styling sink argument for named parameters.

It could be possible to set specific styling for each type element:

// Sets the stroke of lines to be red and the stroke of circles to be blue. 
// All other elements have the default style.
set-style(
  line: (stroke: red),
  circle: (stroke: blue)
)

You should be able to for the styling of arrow heads on lines:

set-style(line: (mark: (begin: ">")))
line((0,0), (0,1))
// The above is equivalent to 
line((0,0), (0,1), mark-begin: ">")

A short hand for single values in nested dictionaries should also be possible:

set-style("line.mark.begin": ">")

johannes-wolf commented 1 year ago

I really like this idea :+1:.