Skip to content

Custom AST elements in pandoc Lua; smooth like butter in a pan.

License

Notifications You must be signed in to change notification settings

tarleb/castiron

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

castiron – cook with your own Custom AST elements

Define custom pandoc Block or Inline* elements to be used in Lua scripts; supports filtering and transparent conversion to and from pandoc's native format.

Important

This package relies on unpublished pandoc features. Castiron currently requires a nightly pandoc build.

Note

This package is developed on Codeberg, so this repo might be slightly out of date at times. However, please do feel free to raise issues or open PRs here on GitHub if you want to, we will then merge them back into the main branch.

Usage

Enable support for custom elements by calling the module's init function.

local castiron = require 'castiron'
castiron.init()

This will patch pandoc modules and types to make them work with custom elements.

Each element type must be registered with

castiron.define_block_element(MyCustomElementMetatable)

where MyCustomElementMetatable is the metatable that should be used for the custom elements. It must have a __name string, a __toblock function, and a __fromblock filter-like constructor table.

Example

Below is the Lua code for the Example type.

--- Metatable for custom `Example` Block elements
local Example = {}

--- The custom element's name.
Example.__name = 'Example'

--- Creates a string representation
function Example:__tostring ()
  return table.concat{
    'Example {\n',
    '\tcontents = ',
    tostring(self.content),
    '\n}'
  }
end

--- Constructs a new custom element.
function Example:__call(obj)
  local exm = {tag = self.__name, content = obj.content}
  return setmetatable(exm, self)
end

--- Converts the custom element back into a default Block.
function Example:__toblock ()
  return pandoc.Div(self.content, {'', {'Example'}})
end

--- Converters from pandoc Block values in a filter-like structure.
-- Keys must be the tags of standard Block elements, and the values
-- are functions that take the default AST element and return a
-- custom AST element.
Example.__fromblock = {
  Div = function (div)
    if div.classes == List{'Example'} then
      return Example {content = div.content}
    end
  end
}

--- Make Example a metatable of itself so we can use it as
-- a function.
setmetatable(Example, Example)

The new Block type is registered with define_block_element.

castiron.init()
castiron.define_block_element(Example)

We can now use the objects of this type like Block elements:

local exm = Example{content = pandoc.Blocks('Testing.')}
local blocks = pandoc.Blocks{'other', exm}
local filtered = blocks:walk {
  Example = function (e) --[[ ... ]] end
}

About

Custom AST elements in pandoc Lua; smooth like butter in a pan.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

 

Packages

No packages published

Languages