Search code examples
luayamlquarto

how to access meta data from quarto YAML in lua script


I'm encountering an issue with a Quarto extension where I'm trying to use a shortcode to extract and display an ORCID number from the YAML metadata in my Quarto document. I've defined a shortcode in my document as {{< orcid >}}, expecting it to be replaced with a hyperlink containing the ORCID number from the YAML metadata.

Here's an example of my YAML metadata:

---
author:
  - name: Your Name
    orcid: 0000-0000-0000-0000
---

And here's my Lua script:

return {
  ['orcid'] = function(meta)
    local authors = meta.authors or meta['by-author']

    if authors then
      for _, author in ipairs(authors) do
        if author.orcid then
          local orcid_link = "<a href=\"https://orcid.org/" .. pandoc.utils.stringify(author.orcid) .. "\">orcid</a>"
          return pandoc.Para(pandoc.RawInline("html", orcid_link))
        end
      end
    end

    return pandoc.Para(pandoc.Str("ORCID not found"))
  end
}

However, despite having the ORCID number in the YAML header, the shortcode always returns "ORCID not found." I've noticed that the meta fields for the author are empty in Lua.

Could someone help me understand how to correctly extract the ORCID number from the YAML header using Lua? Any assistance would be greatly appreciated!


Solution

  • From the Programming In Lua book,

    The parameter passing mechanism in Lua is positional: When we call a function, arguments match parameters by their positions. The first argument gives the value to the first parameter, and so on.

    And from the Quarto shortcodes documentation, shortcodes function signature is function(args, kwargs, meta). So in your implementation, meta is matched with args, instead of meta. And that's why meta.authors returns nil and you are getting "ORCID not found.".

    The following implementation returns the orcid link as expected. Note that, I have added a shortcode argument so that it works in case of multiple authors.

    test-shortcodes.lua

    local str = pandoc.utils.stringify
    
    return {
      ['orcid'] = function(args, kwargs, meta)
        local author_id = str(args[1])
        local authors = meta.authors or meta['by-author']
    
        if authors then
          for _, author in ipairs(authors) do
            if author.id == author_id then
              if author.orcid then
                local orcid_value = str(author.orcid)
                local orcid_link = "<a href=\"https://orcid.org/" .. orcid_value .. "\">orcid</a>"
                return pandoc.Para(pandoc.RawInline("html", orcid_link))
              end
              return pandoc.Para(pandoc.Str("ORCID not found"))
            end
          end
        end
    
      end
    }
    
    ---
    Title: Lua Test
    format: html
    author:
      - name: First Author
        orcid: 0000-0000-0000-0000
      - name: Second Author
        orcid: 0000-0000-0000-0001
    shortcodes: 
      - test-shortcodes.lua
    ---
    
    
    First Author {{< orcid 1 >}}
    
    Second Author {{< orcid 2 >}}
    

    enter image description here