Earmark.Transform (Earmark v1.4.14) View Source

Transformations

Structure Conserving Transformers

For the convenience of processing the output of EarmarkParser.as_ast we expose two structure conserving mappers.

map_ast

takes a function that will be called for each node of the AST, where a leaf node is either a quadruple like {"code", [{"class", "inline"}], ["some code"], %{}} or a text leaf like "some code"

The result of the function call must be

  • for nodes → a quadruple of which the third element will be ignored -- that might change in future, and will therefore classically be nil. The other elements replace the node

  • for strings → strings

A third parameter ignore_strings which defaults to false can be used to avoid invocation of the mapper function for text nodes

As an example let us transform an ast to have symbol keys

  iex(0)> input = [
  ...(0)> {"h1", [], ["Hello"], %{title: true}},
  ...(0)> {"ul", [], [{"li", [], ["alpha"], %{}}, {"li", [], ["beta"], %{}}], %{}}] 
  ...(0)> map_ast(input, fn {t, a, _, m} -> {String.to_atom(t), a, nil, m} end, true)
  [ {:h1, [], ["Hello"], %{title: true}},
    {:ul, [], [{:li, [], ["alpha"], %{}}, {:li, [], ["beta"], %{}}], %{}} ]

N.B. If this returning convention is not respected map_ast might not complain, but the resulting transformation might not be suitable for Earmark.Transform.transform anymore. From this follows that any function passed in as value of the postprocessor: option must obey to these conventions.

map_ast_with

this is like map_ast but like a reducer an accumulator can also be passed through.

For that reason the function is called with two arguments, the first element being the same value as in map_ast and the second the accumulator. The return values need to be equally augmented tuples.

A simple example, annotating traversal order in the meta map's :count key, as we are not interested in text nodes we use the fourth parameter ignore_strings which defaults to false

   iex(0)>  input = [
   ...(0)>  {"ul", [], [{"li", [], ["one"], %{}}, {"li", [], ["two"], %{}}], %{}},
   ...(0)>  {"p", [], ["hello"], %{}}]
   ...(0)>  counter = fn {t, a, _, m}, c -> {{t, a, nil, Map.put(m, :count, c)}, c+1} end
   ...(0)>  map_ast_with(input, 0, counter, true) 
   {[ {"ul", [], [{"li", [], ["one"], %{count: 1}}, {"li", [], ["two"], %{count: 2}}], %{count: 0}},
     {"p", [], ["hello"], %{count: 3}}], 4}

Structure Modifying Transformers

For structure modifications a tree traversal is needed and no clear pattern of how to assist this task with tools has emerged yet.

Link to this section Summary

Link to this section Functions

Link to this function

map_ast(ast, fun, ignore_strings \\ false)

View Source

Coming soon

Link to this function

map_ast_with(ast, value, fun, ignore_strings \\ false)

View Source

Coming soon