Mardown-style nested quotes

Because my document contains nested quotes, I have come to the conclusion that the most effective way to portray the complexity is simply making it look like Markdown (e.g. Nested quote test · GitHub).

In fact, I am actually using Markdown to construct the PDF in the first place with cmarker.

Any tips on creating a show rule for this?

[UPDATE]

  • this looks great, but it doesn’t adapt to the amount of text

[UPDATE 2]

  • automatic adapting to text is working now: all that’s left is
  1. show rule integration
  2. graphic fine-tuning adjustments
#box(lorem(400), stroke:(left:(paint:gray)))

This does the job:

#import "lib.typ" as cmarker
#show quote: tx => {
box(tx, stroke:(left:(paint:gray)))
}
#cmarker.render(read("t.md"))

Here’s a suggestion:

#set quote(block: true)
#show quote: set block(
  spacing: 1em,
  stroke: (left: 0.15em + luma(75%)),
  outset: (left: -0.5em),
  inset: (left: 1em))
#show quote: set text(luma(20%))
#show quote.where(block: true): it => block(it.body)

Before quote.
#quote[
  Hello, world!
  #quote[
    Goodbye, world!
    
    #lorem(25)
  ]
]
After quote.

You should use block instead of box, because box joins the current paragraph (not as a separate block/paragraph). Here I had to use a show quote: it => block(it.body) rule because otherwise there are more than one block inside each quote, and styling one of them and not the other becomes impossible.

Seems like others were quicker in responding to you. Still, I completely agree with what @bluss had to add about block, so consider changing the chosen solution.

I’m being biased here, but I thought this would be the answer:

#import "@preview/cmarker:0.1.8"

#set quote(block: true)
#show quote.where(block: true): block.with(
  stroke: (left: 1pt),
  above: 1em,
  below: 1em,
)

#line(length: 100%)

One:

#quote(lorem(10))

Two:

#quote[#lorem(10) #quote(lorem(50))]

#line(length: 100%)

One:

#cmarker.render("> block")

Two:

#cmarker.render("> block \n > > block")

#line(length: 100%)
Output

I like this variant too, but there are pros and cons. First attempt: can it be done with only show-set? But we both seem to agree we don’t find a good solution there. Then we apply both show and show-set together.

The benefit demonstrated in my answer is that we still have an element, albeit not the standard quote, whose style can be further modfied using show-set. In your variant, it’s defined only once and further modifications of the block’s properties using show-set are impossible. In a small template or document the difference doesn’t matter.

The eventual best answer for Typst will hopefully be a more configurable quote element (using the fragments idea Laurenz talked about at last event?) and/or custom elements.

Sorry I was able to break this lol (or maybe Typst bug?):

#quote(block:true)[
#lorem(10)
#table(lorem(20))
]

The solution that ended up working out for me was:

#show quote: tx =>{block(tx, stroke:(left:(paint:gray, thickness: 2pt, cap:"round")))}

Thank you @hpcfzl @hpc for your guidance, your examples will continue to be valuable for me and others in the future!

Good catch, it is broken by that, and nothing using a set block rule will work with that example unfortunately. It’s a Typst limitation but not a bug (in this case we want to style one particular block but not the blocks it contains.)