Open tavareshugo opened 2 years ago
@dragonstyle I just stumble upon this, is it not closed by "Quarto Callouts Custom Node API" added in 1.3 release (https://quarto.org/docs/prerelease/1.3/custom-ast-nodes/callout.html)?
I don't think one can create yet any arbitrary callout. The new AST node is for existing callout. @cscheid can confirm (or not)
What @mcanouil is suggesting, I think, is for users to use a different div class (like .callout-custom
, which we don't pick up on callout ourselves), but then write a Lua filter that does, and creates a callout programmatically. That should be possible with our current API. See callout_constructor.lua
in tests/docs/smoke-all/2022/11/29/callout-constructor.qmd
for a minimal example. We should properly document all of this, of course.
You read my mind @cscheid π
π I felt that what I said was required an approval or correction π
I was under the impression it needed to be with a known type only, but if one can use any custom type I was indeed wrong. I remembered trying and something was not working (like icon or else)
Anyhow, quarto.Callout()
in Lua is a good solution ! As @mcanouil said, probably issue closed then ?
I think it's currently possible, but not easy. I want to leave this open in case we eventually design a more convenient fix.
Hi all. Thanks for picking up on this.
From a user perspective, who doesn't know Lua and is just trying to hack around (i.e. me), having explicit docs for this would indeed be great.
I've played around a bit (including trying to make a custom Lua filter, but failed), and for now I've settled on specifying something like .callout-exercise
, .callout-answer
, .callout-hint
and then style them up with some CSS.
It works, but does seem like a workaround.
Rendered example here if you're interested.
I love the example, @tavareshugo!
Would be great if in some future the callouts could be cross referenced. I've made a Lua filter (custom-numbered-blocks) that shows what I mean.
@ute we're tracking that here: https://github.com/quarto-dev/quarto-cli/issues/4863
Just wanted to say: thank you for custom-AST-Nodes, @cscheid & all quarto-team. Very cool :-) I was somehow stuck in quarto 1.2..,
@tavareshugo Thank you for sharing the rendered example from UoC, it looks great! I suppose the custom .callout-exercise doesn't render in pdf?
@tavareshugo Thank you for sharing the rendered example from UoC, it looks great! I suppose the custom .callout-exercise doesn't render in pdf?
We haven't worked on a PDF template (yet), so they show as generic callout boxes without any styling applied (basically grey boxes, with no associated icons). I imagine it might be possible to customise these somehow, based on the quarto docs, but haven't looked at how this works in practice. If anyone has any tips on how to convert CSS styling to be applied to the PDF output, they are very welcome! :)
This seems to be working only with v1.2. not current version which I am using. As I like this feature, would downgrading to v1.2 be a possible workaround?? @cscheid
Thanks
This seems to be working only with v1.2
@bsalehe What "this" refers to exactly?
Currently and as stated there are no easy way to do it, thus the issue being opened. Some examples were shared by community members, but those are not made/supported by Quarto.
@mcanouil, I believe @bsalehe was referring to our strategy of using ::: {.callout-exercise}
for our custom "exercise" box. In v1.2 Quarto converted this to a generic box with class callout-exercise
and so we could style it with CSS to make it appear as we wanted. But this doesn't seem to be the behaviour for v1.3 anymore.
I guess an alternative is that we specify it as ::: {.callout .exercise}
so it renders as the generic box but with an additional exercise
class.
But the custom AST nodes feature seems more promising. Can you give us some clues of how to implement a custom callout with this feature?
I have looked at the example mentioned above, but I couldn't quite figure out how to make it work.
Of course part of the issue is that I don't know how Lua filters work, and couldn't understand how to get there from the current docs, so I'm blindly trialing things out. π Namely, two issues at the moment:
::: {.callout-div}
in my markdown?If you have some quick suggestions, that would be great. Otherwise, we appreciate this may not be your highest priority and we can work around it.
@tavareshugo You need to learn a bit more about lua
This would help you understand the code you copied.
function Pandoc(doc) -- <- applies on the docment
-- create a callout
local c = quarto.Callout({
type = "exercise",
content = { pandoc.Div(pandoc.Plain("This is an exercise")) },
title = "Exercise with Lua"
})
-- insert the callout at the end of the document
doc.blocks:insert(c)
-- return the whole document
return doc
end
Here is how you could replace you div by the callout you created
function Div(div)
if div.classes:includes("callout-exercise") then
return quarto.Callout({
type = "exercise",
content = { pandoc.Div(pandoc.Plain("This is an exercise")) },
title = "Exercise with Lua"
})
end
end
I think you can understand the difference. Now you could mimic part of the behavior of callout with more complex handling
---
format: html
filters:
- custom-callout.lua
---
This box comes with Quarto and works fine:
:::{.callout-tip}
## This is the title
Native quarto callout.
:::
This was intended to be our custom box
:::{.callout-exercise}
## This is the title
Custom exercise callout content.
:::
function Div(div)
-- process only specific div
if div.classes:includes("callout-exercise") then
-- default title
local title = "Exercice"
-- Use first element of div as title is this is a header
if div.content[1] ~= nil and div.content[1].t == "Header" then
title = div.content[1]
div.content:remove(1)
end
-- return a callout instead of the Div
return quarto.Callout({
type = "exercise",
content = div,
title = title
})
end
end
Hopefully this give you enough example to build your own
@cderv I just wanted to say a huge thank you again for your code. I've finally implemented it (here) and it worked, with only a couple of tweaks:
title = div.content[1]
I changed to title = pandoc.utils.stringify(div.content[1])
content = div
I changed to content = { pandoc.Div(div) }
I really appreciate your input - the focus of our team is on course material development in the field of bioinformatics/statistics/machine learning, and while Python/R are staples for us, Pandoc/Lua development is beyond our current scope. But I'm really happy that we managed to get this one working with your help!
fwiw, I've been able to get custom callouts working with just a bit of CSS and inline styling for the custom {color, icon}
relvant lines in the index.qmd
::: {.callout-tip icon=false title="[{{< fa solid person-chalkboard size=fa-lg >}}]{style='color:var(--dim-text);'} $\hspace{1pt}$ [Recent Talks]{.dim-text}" collapse="false" style="text-align: left!important; width:100%; border-color: var(--dim-color)!important; background-color: var(--bg-transparent);"}
You can get a live view of some of my recent talks [here {{< iconify line-md external-link >}}](./qmd/slides.qmd)
:::
::: {.callout-tip icon=false title="[{{< iconify logos spotify-icon >}} $\hspace{1pt}$ Now Playing:]{style='color: #1ED760;'}" collapse="true" style="width:100%; border: 1px solid #1ED760!important;"}
[[![](https://spotify-github-profile.vercel.app/api/view?uid=saforem2&cover_image=true&theme=novatorem&bar_color=53b14f&bar_color_cover=true)](https://spotify-github-profile.vercel.app/api/view?uid=saforem2&redirect=true)]{.stretch}
:::
where the .callout-tip
is coming from .callout-tip
callouts.css
From my personal website:
Some more examples if you're interested:
interestingly, this this seems broken (e.g. the icons fail to load when embedded in the callout title) in quarto-1.4.{357, 398, 415, 446, 448}
but works in quarto-1.3.450
I tried playing around with it briefly, but couldn't quite get it working.
I'm guessing it would be best for me to create a new issue for this??
I'm guessing it would be best for me to create a new issue for this??
Yes, pleas.e
I'd also be keen to create my own bespoke callouts. It sounds like there is a workround, but this seems pretty complex.
For those who stumble upon this, I've written up a quick {quarto-custom-callout}
filter extension that allows you to define new callouts effortlessly from within the document's YAML.
For example, take the original ask, we could specify it as:
---
title: "Custom Callouts Rock!"
format: html
custom-callout:
exercise:
title: "Exercise"
color: "purple"
icon: "fa-question"
collapse: "false"
answer:
title: "Answer"
color: "green"
icon: "fa-pen"
collapse: "true"
filters:
- custom-callout
---
From there, we could just use:
:::{.exercise}
This is an exercise callout.
:::
:::{.answer}
This is an answer callout.
:::
:::{.answer title="Custom Answer Title"}
This is an answer callout with a custom title.
:::
[!NOTE] Only
color
cannot be used as an attribute on the Callout itself.
Website: https://quarto.thecoatlessprofessor.com/custom-callout/ Repository: https://github.com/coatless-quarto/custom-callout
Firstly, many thanks for the fantastic package you are developing!
I am following from @athulsudheesh's comment in #556, to request a new feature for custom callout boxes.
One use case I have in mind is for exercises in books or course materials, for example:
I guess these would have to be defined somewhere following a template (on the front matter? or on a separate YAML, that is then referenced on the front-matter?).
Alternatively maybe this could be done through a generic callout with a couple of extra options, such as:
The disadvantage here is that there is more typing involved.