pandoc-lua-filters/margin-notes
..
test
Makefile
README.md
margin-notes.lua
sample.md

README.md

Marginal notes in Pandoc for semantically marked spans of text

margin-notes enables you to create unnumbered marginal notes from spans with user-defined class and properties. It currently only works with LaTeX, ConTeXt and, to a limited extent, DOCX (using tooltips instead of marginal notes) and ODT (using annotations).

Defining the renderings

This filter does not provide a predefined class for marginal notes. Instead, it lets the user choose what classes it will handle and how. This way, it is possible to define appropriate renderings of spans marked with different, semantically meaningful classes.

Here is an example. Please note that it is necessary to surround the values both with single quotes and backsticks to force Pandoc to pass them unchanged to margin-notes.lua.

mrgnn-define-renderings:
- class: term
  body-text: '`**§content§**`'
  note-text: '`§attr.lem§: *§attr.def§*`'
- class: warning
  body-text: '`**!**`'
  note-text: '`**§content§**`'

The values of note-text and body-text are markdown templates. Inside it, you have access to the content and the attributes of the span with the variables §content§ and §attr.X§. The special character § should be escaped with a backslash if you want it to be treated literally.

Mardown in the content and the attributes of the span is taken into account whenever possible. Otherwise (e.g. when used in the target of a link or the path of an image), the values of §content§ and §attr.X§ are converted to a plain string without any formatting.

The preceding configuration can be applied to the following sample:

[Important!]{.warning}You can use LaTeX to include
[BibTeX]{.term
  lem=BibTeX
  def="A program designed to format bibliographical entries"
} citations. Note that in LaTeX environments,
the material between the begin and end tags will be interpreted
as [raw LaTeX]{.term
  lem="Raw code"
  def="Code inserted **untouched** in the output."
}, not as Markdown.

For DOCX output, the note is set as the content of a tooltip attached to an asterisk following the body text. Since this does not always produce good results, notably because tooltips only display plain strings, DOCX output is deactivated by default. However, you can activate it for individual classes by setting the variables docx-body-text and docx-note-text:

mrgnn-define-renderings:
- class: term
  body-text: '`**§content§**`'
  note-text: '`§attr.lem§: *§attr.def§*`'
  docx-body-text: '`**§content§**`'
  docx-note-text: '`§attr.lem§: §attr.def§`'

With ODT, the marginal notes are always converted to annotations. By default, the values of body-text and note-text are used. However, since LibreOffice (at least) does not support all kinds of formatting in annotations, you can define specific values for odt-body-text and odt-note-text as well.

Tips and tricks

Simplify your markdown file

So as not to overload your markdown file, you may wish to pre-process your spans with a custom filter. For instance, the sample above could be simplified like this:

[Important!]{.warning}You can use LaTeX to include [BibTeX]{.term}
citations. Note that in LaTeX environments,
the material between the begin and end tags will be interpreted
as [raw LaTeX]{.term lem="Raw code"}, not as Markdown.

The following filter, to be applied before margin-notes.lua, adds the required attributes to the spans with class term.

local definitions = {
  BibTeX = 'A program designed to format bibliographical entries.',
  ['Raw code'] = 'Code inserted untouched in the output.'
}

function Span(span)
  if span.classes:includes('term') then
    attr = span.attributes
    if not attr.lem then
      attr.lem = pandoc.utils.stringify(span.content)
    end
    if not attr.def then
      attr.def = definitions[attr.lem]
    end
    return span
  end
end

Further customization of the marginal notes

By default, all marginal notes are rendered by the macro \mrgnn, which is defined as follows:

  • LaTeX:
\newcommand{\mrgnn}[1]{%
  \marginpar{{\footnotesize #1}}%
}
\define\placeMrgnn{%
  \inoutermargin{\vtop{%
    \placelocalnotes[mrgnn][before=,after=]%
  }}%
}

\definenote
  [mrgnn]
  [location=text,
   bodyfont=x,
   next=\placeMrgnn]

\setupnotation
  [mrgnn]
  [number=no,
   alternative=serried]

However, you can associate different macros with individual classes by setting the variable csname:

mrgnn-define-renderings:
- class: term
  body-text: '`**§content§**`'
  note-text: '`§attr.lem§: *§attr.def§*`'
  csname: mrgnnTerm

In that case, you will have to define \mrgnnTerm in your LaTeX or ConTeXt template. This macro takes one argument, which is the result of the processing of note-text.

The position of the instructions about the marginal note in the output file can be set via the variable position. They can be placed after (default) or before the in-text content.