-
-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add hfill-command parameter to TOC #1650
Draft
raphCode
wants to merge
1
commit into
sile-typesetter:master
Choose a base branch
from
raphCode:toc_improvement
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is the right approach to solve this problem. I understand why it works for your use case, but I don't think it generalizes very well. Trying to setup a TOC style that does different things at different levels is going to be a messy fiasco.
That being said part of the problem in my view in the original TOC :item commands (
\tableofcontents:level1item
and friends) were incorrectly setup as "pre" commands that run before an item but don't actually output the item itself and hence are limited in the amount of reconfiguring they can do.By comparison the TOC implementation I use is the one in CaSILE (code here)) makes those commands responsible for actually outputting the line. The fill is part of the line, but since the point where it is output is in the per-level commands, each level can have different default options for whether to turn dotfill on or off.
For example a book project may run something like this:
I think it would be worth reworking this PR as part of a complete TOC package overhaul that –one way or another– allows for more complete styling hooks all the way through. I believe @Omikhleia also has another TOC implementation that handles styling better. We probably need to pair up and fine some best-of approach to styling.
In the mean time I'm kind of hesitant to just stuff hacks on the current implementation that aren't going to scale well in the long run for most users. This implementation wouldn't be too hard to copy into a library of your own to include in any projects you want to use it in, but since it doesn't handle multiple levels very well I don't think we should make it the default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very experimental. Revisiting "generic" styling is a long due task in my todos... I am not satisfied with its API. The "old" way can be consulted here, p. 40 §1.2.1 and is used on p. 3-5. I insist this is considered experimental and that my eventual implementation might differ (though it likely will keep the core concept of splitting styling decisions from implementation and using some king of "lite CSS" approach to style definition templates)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, I was completely unaware of command defaults. I agree this is a good idea if it works*
It is a bit unconventional in the programming sense where all arguments / options are traditionally passed at the call site. So by just inspecting the
SILE.call("level1item")
it is not clear howoptions.dotfill
can ever be populated, but once you are aware of the concept it's fine.Also the implementation of
SILE.call
doesn't hint at the possibility of additional options being passed, sinceSILE.setCommandDefaults
just creates a new closure that applies the defaults.*In my understandung your casile TOC doesn't work this way - the
level1item
function doesn't even use itsoptions
argument. To make it work, it would have to pass on the argument to thecontent
. And since that is a closure fromtableofcontents:item
it needs to take anoption
argument as well. Currently, theoptions
in the closure body there is just an upvalue to the options from tableofcontents:item` .If my understanding is correct I think this hints more to a general problem in SILE with nesting content closures which makes it very hard to pass arguments to a specific content function. I am happy to elaborate on that or discuss solutions if that is desired.
This is also why I settled for a SILE setting in this PR - it seemed to me with the current architecture it is the most elegant solution to access a "global" - while it is still ugly from a programming perspective.
I am perfectly okay with this, I don't want anything merged that doesn't serve the project well in the long run.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, but we're talking about document markup here. One cannot expect a document to modify every call to a tag to pass the same options over and over every time. That would be absurdly complex for large projects and get in the way of the content. Instead we allow documents to redefine commands and people to write their own libraries that replace the functions used to typeset the markup.
One of the most common use cases turned out to be using the same typesetting function but changing the default options—using some non-default option by default. Hence I added a programming shortcut for it. It's just syntax sugar for creating a wrapper function that calls the original function with some options by default, but it's a lot less cumbersome than making everybody write their own stub functions.
If you need something other than a different
{ options }
table you'll still need to write your own function of course...You can pass a table op options like so:
SILE.call("command", { options_here }, ...)
, and that doesn't change when a command has been wrapped withsetCommandDefaults()
. You can still override options that are passed in, only the default options are changed.It's a little bit obtuse, but it does yet used ;-) The
\tableofcontents:level1item
function doesn't reference it directly, but it does process the content it is passed. The content it is passed in this situation is actually a lambda function sent from the body of\tableofcontents:item
. That then eventually gets evaluated and spots the option. I would code that up a lot cleaner if I were to do it again today, but at the time I figured it out it got the job done right for the books I was printing.Yes. There are actually a lot of ways to do it using Lua features, but few/none that are intuitive and well documented.
Ya I understand why you reached for it. I think settings though are better scoped to situations when more than one command would be affected: i.g. changing the behavior of an entire package or module (or multiple modules). When just one command is in play we probably need something else. A standardized way of options inheritance would help.
Also note another way to deal with this would be to write a
\dotfill
replacement that uses bread crumbs to give different output depending on what other commands it was nested in.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I am still not convinced. I even made up a little test document to prove it, something along the lines:
(I hacked your cabook-commands file (gist is here) to make it work with this minimal document outside casile, especially calling
registerCommands()
again frominit()
to overwrite the TOC commands the book class pulls in.)I then replaced this line with
pl.pretty.dump(options)
to dump what options the lambda function you mentioned sees.As expected, it sees the upvalue from
tableofcontents:item
, and no amount ofSILE.setCommandDefaults("tableofcontents:level1item", { dotfill = false })
changes that.SILE.setCommandDefaults("tableofcontents:item", { dotfill = false })
is the only command that changes it, which doesn't enable per-level customisation.The problem is that
content
is already a closure when it is passed totableofcontents:level1item
and no options can be passed into it anymore.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Embarrassingly (for me) you might be right. I made the assertion based on looking at a book project that used CaSILE and had mix-matched dotfills and I could see it was responding ... but it turns out that book has its own forked copy of the TOC code from CaSILE that I made some other changes to and apparently fixed the option scoping bug without upstreaming it even to CaSILE much less SILE. Gaveraboglesplitişlöbğ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious to see how you addressed the problem! I am happy to discuss in a dedicated issue or PR