How Can I Create Image Examples Like In The Documentation Within a Typst Document?

I’m making my own collection of typst samples in a document. I’d like to generate images to show with the samples the same way the documentation does. I saw a post from 2023 in the discord that sounded like the code to do that was closed source. Is that still the case?

(I’ve also seen the tidy package but that has a lot more output than I’m looking for. I’d like to have what amounts to an image of a single page with the output from the example source)

Hello @Alan and welcome!
I have changed your post to Questions, don’t hesitate to also add relevant tags!

For the image, it is more or less reproducible like this

#set page(width: 8cm, height: auto, margin: .5cm)
#set heading(numbering: "I.")
#set text(font: "New Computer Modern")

= Introduction
With set rules, you can style your document.

image

If you’re looking for a way to show both the code and the output automatically within a typst document, you can do so like this:


#let makedocs(dic) = context [
  #let b1 = block(stroke: 1pt + luma(220), outset: 3pt, radius: 5pt)[
    #dic
  ]  
  #let b2 = block(stroke: 5pt + luma(220), outset: 5pt)[
    #eval(dic.text, mode: "markup")
  ]
  #let s1 = measure(b1).width
  #let s2 = measure(b2).width

  #set block(width: calc.max(s1, s2))
  
  #b1
  #b2
]



#makedocs(```typst
#set text(fill: blue)
I am blue!
```)

image

1 Like

This is great!

Can this also do things like show examples of adding page headers. (For example, like the “Add headers and footers” of the page setup guide)

I currently get a page configuration is not allowed inside containers error if I try that. For example, this

#makedocs(```typst
#set page(header: [Here i am])
#set text(fill: blue)
= DO I SHOW UP IN THE OUTLINE
I am blue!
```)

Results in this:

Yeah this is a bit trickier. AFAIK, Typst doesn’t really support nesting pages inside a document, so the only way to display the entire page is to render it in a new page.

#let makedocs(dic) = context [
  #if "#set page" in dic.text [
    #let b1 = block(stroke: 1pt + luma(220), outset: 3pt, radius: 5pt)[
      #dic
    ]
    #let b2 = eval(dic.text, mode: "markup")
    #b1
    #set page(paper: "a5") // comment out if you want
    #b2
    #return
  ]
  // else
  #let b1 = block(stroke: 1pt + luma(220), outset: 3pt, radius: 5pt)[
    #dic
  ]  
  
  #let b2 = block(stroke: 5pt + luma(220), outset: 5pt)[
    #eval(dic.text, mode: "markup")
  ]
  #let s1 = measure(b1).width
  #let s2 = measure(b2).width

  #set block(width: calc.max(s1, s2))
  
  #b1
  #b2
  
]

#makedocs(```typst
#set page(header: [Here i am])
#set text(fill: blue)
= DO I SHOW UP IN THE OUTLINE
I am blue!
```)


#makedocs(```typst
#set text(fill: blue)
I am blue!
```)
```

Maybe someone else can come up with a more elegant solution

There are two projects I know of that allow compiling Typst inside Typst. They are not available on Typst Universe due to their size. Unfortunately, I don’t know how easy they are to use or their current state.

One project by @Myriad-Dreamin was showcased on Discord here and is used to write a Chinese Typst tutorial. There are precompiled files available, as well as the source.

The other project is typst-matryoshka which was also showcased on Discord here.

right on. I’ll check those out.

thanks!

As a follow up, the approach I’m moving to looks like this:

  • write the snippets I’d like to show in their own files
  • set up an external process to watch those files and output them to png whenever the change
  • write a typst function that lets me include the original text and the png in my main document with a single call

for the process that outputs the pngs I expect I’ll end up adding a way to apply some styling to the snippet that isn’t displayed in the text output in the main file. I’ll do this by adding a comment line that let’s me split the text so I can put any formatting above it and then only show what’s below it in the output.