Search code examples
pandocquarto

Quarto make a shortcode that reads content from the document


I want to make a Quarto extension that extracts some information from the existing document, and dumps it when the user places a shortcode. For example, let's say I want to count the number of images in the document and then output it when the user adds {{< imgcount >}}.

However, Quarto shortcodes don't seem to have the capacity to access the rest of the document. Quarto Filters can access the document content, by defining element filters. However, they can't define shortcodes. You can define a Quarto extension with both a filter and a shortcode, but it's not clear to me if these can communicate with each other.

Is there an elegant way to therefore solve this problem?


Solution

  • You can communicate using the meta variable, which is accessible for the Meta filter and for shortcodes. The meta filter is run after the element filters, so you can count the images first and set the meta value after that.

    Filter countimages.lua:

    nrimgs = 0
    
    function Meta(m)
      m.totalimgs = nrimgs
      return m
    end
    
    function Image (elem)
      nrimgs = nrimgs + 1
      return elem
    end
    

    Shortcode imgcount.lua:

    return {
      ['imgcount'] = function(args, kwargs, meta) 
        return pandoc.Str(meta.totalimgs)
      end
    }
    

    Quarto document:

    ---
    title: "Count images"
    filters:
      - countimages.lua
    ---
    
    This document has {{< imgcount >}} images.
    
    ![Elephant](elephant_small.png)
    
    ![Lion](lion_small.png)
    

    Result:

    enter image description here