I’m sure many of us have tried to write something like this:
<span style.color=<<colour muted-foreground>>>...</span>
only to find that it does take effect due to the fact that the macro call is not wikified.
The value you get for the style.color attribute is actually:
\whitespace trim <$transclude $tiddler={{$:/palette}} $index=`$(name)$`> <$transclude $tiddler="$:/palettes/Vanilla" $index=`$(name)$`> <$transclude $tiddler=`$:/config/DefaultColourMappings/$(name)$`/> </$transclude> </$transclude>
(Or, if you use <<color>>
instead of <<colour>>
, you will get <$macrocall $name=colour name=`$(name)$`/>
.)
Instead of a macro, it would be nice to have a function that does the same thing, since functions are evaluated (\function
under the same link above in the text not wikified
).
Well, by looking at the macro definition, we can see it is just transcluding a tiddler index (from the palette), transcluding the same index from the vanilla palette as a backup, and finally transcluding the text from a default config tiddler for the given color as a final backup. We can do the same with a custom function:
\function getColor(c) [{$:/palette}getindex<c>!is[blank]] ~[[$:/palettes/Vanilla]getindex<c>!is[blank]] ~[[$:/config/DefaultColourMappings/]addsuffix<c>get[text]]
There is actually one little problem with this approach: sometimes the value in the palette is another call to the colour macro! This won’t be automatically wikified to the final value if called in a widget attribute.
To fix this, we can use regular expressions to detect if the value is another call to the colour macro, and recursively call the getColor
function again if it is.
I bet someone with better regex and filter skills could write a cleaner or more efficient version, but this is how I implemented it (originally for another topic):
\define colorRegexp() <<colou?r .*>>
\define removeRegex() <<colou?r |"|'|>>
\function getColor(c) [{$:/palette}getindex<c>!is[blank]] ~[[$:/palettes/Vanilla]getindex<c>!is[blank]] ~[[$:/config/DefaultColourMappings/]addsuffix<c>get[text]] :map[function[recolor],<currentTiddler>]
\function recolor(c) [<c>regexp<colorRegexp>] :then[<c>search-replace:g:regexp<removeRegex>,[]split[ ]!is[blank]first[]] :map[function[getColor],<currentTiddler>] :else[<c>]
This allows you to do things like this:
<div style.color=<<getColor foreground>> style.background-color=<<getColor table-header-background>> >
(contents)
</div>
I’m American, so I used the American spelling “color” in the name of my implementation of the “getColor” function, but you can name the functions whatever you like.