Open TimeTravelPenguin opened 3 weeks ago
Hi @TimeTravelPenguin
It is true that the provided themes are not very customizable, that is why you can make your own themes too. Especially the example rendering has proven to be a little tricky. There have been plans to redesign how themes and customization work in tidy but they require the long-awaited custom types in Typst and I don't want to break everything twice.
This is just for the background, however - for show-example
we can totally find a good solution for now. Let me look at the issue.
PS: Nice color themes by the way :)
Okay, so the thing is that we could of course add parameters for all these hard-coded values to show-example()
but then you'd sortof have to provide these arguments every time you call example
in the documentation. This can be overcome by adding some #example = example.with(...)
to the preamble
argument in parse-module()
but that's all not very clean and satisfying.
Again, ideally example
would be a type so one can do set
and show
rules like
#set tidy.example(fill: black, spacing: 1em)
or similar. Unfortunately, they're not there yet.
One thing you can do now is copying the default theme and insert your own modified implementation of show-example
. As you pointed out, there are so many hard-coded details of the implementation of show-example
that in the end you might want to change even more.
Modifying a theme does not actually require copying everything, you can write
#import "/src/styles/default.typ"
#let show-example(..args) = {} // your own implementation of show-example
#let my-theme = dictionary(default)
#{my-theme.show-example = show-example}
#show-module(docs, style: styles.default, colors: styles.default.colors-dark)
because styles
also accepts a dictionary and since recently it is possible to turn a module into a dictionary.
Still, if you can think of another (elegant) solution to solve this issue, let me know!
PS: Nice color themes by the way :)
Haha thanks, but I can't take credit for the Catppuccin themes. I am just a random community member implementing it in Typst to save my poor eyes from a white screen!
Okay, so the thing is that we could of course add parameters for all these hard-coded values to
show-example()
but then you'd sortof have to provide these arguments every time you callexample
in the documentation.
There are a few ways to get around this. Or at least, to make it a bit easier to work with, as I will shortly discuss.
There have been plans to redesign how themes and customization work in tidy but they require the long-awaited custom types in Typst and I don't want to break everything twice.
Yes, I am very excited about custom types. For a temporary workaround, I personally like using the Valkyrie package for schema validation.
What I am doing in my project is having some
#import "@preview/valkyrie:0.2.1" as z
#let config-schema = z.dictionary(( ... ))
#let my-func(config: (:)) = {
let config-defaults = (...)
config = config-defaults + config
let valid-config = z.parse(config, config-schema)
}
You don't need Valkyrie for the main point here, but it shows how it can be used. So, the approach I take is that the default user-provided config is empty. I then use the +
behaviour on dictionaries to update the functions local default (e.g., setting the fill to white). Then, if the user provides a fill
entry, it overwrites your function's defaults.
Then, Valkyrie is helpful because you can assert that the provided dictionary configuration contains only the expected values for the thing you're plugging it into. But like I said, it isn't the necessary part of this. I just wanted to mention it as I am a personal fan.
Ultimately, a redesign is certainly looking like the way to go, but depending on how you want to go about it, the complexity can greatly differ.
Just off the top of my head, I would probably take a kind of functional approach, seeing as there are no object/types. The tidy show-module
function would need to be dependent on the remaining other functions. Either these are given as arguments, found through introspection/parsing of a module, or be the result of another function who, itself, if provided the required components to build show-module
.
One other approach, which would be much harder to implement and would require some big planning would be to work with functions that give and take contexts (not the typst context
), similar to how CeTZ does.
This is just some spitballing of ideas I had while studying your library :)
Haha thanks, but I can't take credit for the Catppuccin themes. I am just a random community member implementing it in Typst to save my poor eyes from a white screen!
Ah okay haha. Still good work porting it to Typst 👍
You don't need Valkyrie for the main point here, but it shows how it can be used. So, the approach I take is that the default user-provided config is empty. I then use the + behaviour on dictionaries to update the functions local default (e.g., setting the fill to white). Then, if the user provides a fill entry, it overwrites your function's defaults.
Yes, I use the same approach in other packages as well.
Just off the top of my head, I would probably take a kind of functional approach, seeing as there are no object/types. The tidy show-module function would need to be dependent on the remaining other functions. Either these are given as arguments, found through introspection/parsing of a module, or be the result of another function who, itself, if provided the required components to build show-module.
Indeed, the dependance is one of the main issues. For example implementations of show-function
call show-type
etc. Another issue is passing lots of data and settings down to the different styling functions.
I really want to go for user-defined types in the long run because they allow for composable, flexible rules. Additionally, methods on types will allow outsourcing common transformations/preprocessing of the content.
Alas, the different ways that other packages currently deal with this problem are all a bit clunky and have disadvantages of their own. For me it does not make too much sense rebuilding the framework now and then changing it up yet again so I will wait for custom types since everything is possible (I think/I hope) now by building your own themes.
I would still keep this issue open so we can check that this is treated with the needed care once the time has come :)
If you need help defining or modifying a style/theme come back to me.
Ah okay haha. Still good work porting it to Typst 👍
I have so much to do still, but the package is slowly coming together.
For me it does not make too much sense rebuilding the framework now and then changing it up yet again so I will wait for custom types since everything is possible (I think/I hope) now by building your own themes.
That's perfectly valid. There is a lot of potential opportunity depending on what kinds of features get added in the future. Any changes you do now should probably only complement the future, in the event you don't start from the ground up.
If you need help defining or modifying a style/theme come back to me.
Thanks! I have been having some issues with a slightly hacked version of the default show-example
, but it is partly due to my own package's configuration and styling. I need to chip away at yours some more when I have the time. I will certainly reach out if I need help.
One thing that I do want to mention is that one place to perhaps introduce where the user may be able to configure their docs would be by making this code an external dependency.
Just wanted to leave this here as a future consideration. A builder pattern would be very useful.
Yes, this will definitely be customizable at some point!
Hi, I am working on the package Catppuccin and I am currently writing up the documentation, where I am using the theme that the library provides.
Currently, Tidy makes it very difficult to render examples that adhere to theming. For example, this line makes it impossible to set the preview theme, even if using the preamble argument in
parse-module
.Could you please revise this function and remove any such defaults? I do not feel that explicitly setting the fill to white is necessary.
Thanks :)