fix(typst): left-align cross-ref callouts#14130
Conversation
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
|
If this PR seems good, I will add tests to check alignment using the new tools in the test suite. |
|
LGTM! I am not sure if |
|
I've tested locally, but did not want yet to spend time on trying to make a test if the proposed two fixes were not suitable. edit: also missing changelog entry(ies) |
| })) | ||
|
|
||
| block_with_new_content(old_callout, | ||
| align(left, block_with_new_content(old_callout, |
There was a problem hiding this comment.
The hardcoding to left here is a little concerning, because it means that in general it won't be possible to affirmatively choose to center figure content. Or am I missing something?
There was a problem hiding this comment.
This is just for callouts? Do we support non-left callout content?
There was a problem hiding this comment.
Yes, I'm fiddling to see another approach that would let users define something that would allow changing the alignment while keeping cross-ref callouts/ non cross-ref consistent.
not directly.
There was a problem hiding this comment.
Let me scope the align() to allow figure show rule like the one from Andrew to work.
There was a problem hiding this comment.
So, here are the results:
Setting align() inside the show rule either as I did or adding a new rule, like the one from Andrew will forbid any change by the users.
One alternative if we want to set align and allow users to change it would be to use state context variable, but this only change cross-ref callouts.
+ #let quarto-callout-align = state("quarto-callout-align", left)
// callout rendering
// this is a figure show rule because callouts are crossreferenceable
#show figure: it => {
...
- align(left, block_with_new_content(old_callout, block_with_new_content(old_callout,
+ context align(quarto-callout-align.get(), block_with_new_content(old_callout,
block(below: 0pt, new_title_block) +
old_callout.body.children.at(1)))
}Then users can do:
---
format:
typst:
include-in-header:
- text: |
#quarto-callout-align.update(right)
---
::: {.callout-tip #tip-abc}
## Tip with Title
This is an example of a callout with a title.
This is an example of a 'folded' caution callout that can be expanded by the user. You can use `collapse="true"` to collapse it by default or `collapse="false"` to make a collapsible callout that is expanded by default.
:::
::: {.callout-tip}
## Tip with Title
This is an example of a callout with a title.
This is an example of a 'folded' caution callout that can be expanded by the user. You can use `collapse="true"` to collapse it by default or `collapse="false"` to make a collapsible callout that is expanded by default.
:::There was a problem hiding this comment.
If we want this customisation of alignement to work also for non-crossref, it would require more changes: either in Lua to surround calls to callouts with #context align(quarto-callout-align.get(), [, ], or create a wrapper which contains this, then update the Lua filter to call the wrapper.
-> The current #callout() has no selector that would allow changing alignment from a show rule.
There was a problem hiding this comment.
I don't see a (easy) way to keep cross-ref/non cross-ref consistent in all scenarios.
Blocks inherit from the context in which they are called.
- In cross-ref, "callout" will inherit from "figure" alignment (center)
- Non cross-ref in most cases will inherits from the page alignement (left)
As stated before, if we set set align(left), align(left)[..., or set a show rule, it means the alignment is hardcoded and cannot be changed unless removed by users.
----
format:
typst:
keep-typ: true
---
```{=typst}
#show figure: it => {
if type(it.kind) != str { return it }
if it.kind.starts-with("quarto-callout-") {
return align(left, it)
}
it
}
// See that the second rule does not work
#show figure: it => {
if type(it.kind) != str { return it }
if it.kind.starts-with("quarto-callout-") {
return align(right, it)
}
it
}
#align(right)[
```
::: {.callout-tip #tip-abc}
## Tip with Title
This is an example of a callout with a title.
This is an example of a 'folded' caution callout that can be expanded by the user. You can use `collapse="true"` to collapse it by default or `collapse="false"` to make a collapsible callout that is expanded by default.
:::
::: {.callout-tip}
## Tip with Title
This is an example of a callout with a title.
This is an example of a 'folded' caution callout that can be expanded by the user. You can use `collapse="true"` to collapse it by default or `collapse="false"` to make a collapsible callout that is expanded by default.
:::
```{=typst}
]
```There was a problem hiding this comment.
I have the changes ready with the state variable.
This will makes callouts no longer inherit from context (page, column, etc.)
Screen.Recording.2026-02-27.at.21.56.05.mov
There was a problem hiding this comment.
Sorry, I should have qualified my "little concerning" more strongly. I'm actually happy with the original PR as it was. This state business is pretty cool, but I think it's a bigger change than I'm ready to put into 1.9 at this stage.
There was a problem hiding this comment.
The state variable is really good when you want to control the state of something across context changes.
The main use in Typst is usually for counters.
For reference, the code from the screencast:
-
-- Wrap in state-based alignment for consistency with crossref callouts local result = pandoc.Blocks({}) result:insert(pandoc.RawBlock("typst", '#context align(quarto-callout-align.get(), [')) result:extend(quarto.utils.as_blocks(typst_callout_basic)) result:insert(pandoc.RawBlock("typst", '])')) return result
-
#context align(quarto-callout-align.get(), block_with_new_content(old_callout,
And this in definitions.typ or anywhere before content:
#let quarto-callout-align = state("quarto-callout-align", left)|
Okay, I've pushed a test and changelog. |
|
Ok, let's merge this. Thank you, @andrewheiss! |
Corrects the text alignment issue in typst format's callouts when using a prefix. The text was previously centred, and this change ensures it is left-aligned as expected. Fixes #12803
This also fix the warning arising inside cross-reference callouts because the discarded element was not caught thus the explicit call to
return.