Search code examples
typst

How to make a caption and set numbering style for a code block


The following is my demo document.

#set heading(numbering: "A.")

#show raw.where(lang:"python"): it=>{
par(justify:false,block(fill:rgb("#f0fef0"),inset:1.5em,width:99%,text(it)))}

= first section
== first.first section
#figure(
```python
print("hello,world")
```)<program-hello-world>
= second section
== second.first section
In the program (@program-hello-world), a demo program was given.

blabla

I want to add a caption for each code block above it with auto numbering, and prefer the number includes the chapter number. The results I want is

enter image description here


Solution

  • Paste this into your document after your show rule:

    #let filename(target, loc) = if target.func() == raw and target.lang == "python" {
      context {
        let hcount = counter(heading).at(loc).first()
        let figcount = counter(figure).at(loc).first()
        [Code-#numbering("A-1", hcount, figcount)\.py]
      }
    } else {
      none
    }
    
    #show figure: it => {
      let label = filename(it.body, it.location())
      
      if label != none {
        block(
          above: 20pt,
          below: 20pt,
          strong("Filename: " + label) + it.body,
        )
      } else {
        it 
      }
    }
    
    #show ref: it => {
      let target = query(it.target).last()
      let label = filename(target.body, target.location())
    
      if label != none {
        label
      } else { it }
    }
    

    This is a function that uses a figure's body and a location to query the heading and figure counters and format a file name as in your example. We pass the location separately instead of calling it on target because it will be none on it.body from the figure show rule. Instead, we pass the location from the figure (obtained through show rule and query) separately.

    Finally, we can customize the figure using #show figure and the reference through #show ref.

    The result will look like this:

    Reference to a code block by file name