5

Is there any way in LaTeX to define an environment, say,

\begin{markdown}
  This will be *processed* as
  [Markdown](http://daringfireball.net/projects/markdown/)!
\end{markdown}

which passes the contents of the environment through an external command (such as pandoc), then substitutes the processed results back into the document? Essentially, is it possible to replicate the filter ConTeXt module? I've tried various tricks with bashful and \directlua but with no success.

  • Did you check out the posting Is there any package with Markdown support? – Mico May 26 '15 at 6:06
  • AFAIK, the closest analog of filter module in LaTeX is the pythontex. In principle, you should be able to replicate the functionality of the filter module by an appropriate python script (and then wrap around that using pythontex). – Aditya May 27 '15 at 5:12
3

If you're willing and able to use LuaLaTeX, an extension to an earlier answer given to the posting Use Markdown-style formatting for bold and italic may work for you. It doesn't call an external routine (e.g, pandoc), though. Instead, it converts selected Markdown-type code into LaTeX-based code.

The code (a) defines a LaTeX environment named markdown and (b) sets up a Lua function named process_simple_markdown to handle very simple cases of markdown-type code. The Lua function is activated inside -- and only inside -- markdown environments. Lua "captures" are used to process what's inside pairs of parentheses and brackets and pairs of triple, double, and single asterisks. The Lua function is assigned to the so-called process_input_buffer callback; it therefore operates on the input file at a very early stage, before TeX itself does any typesetting-related work.

A strong caveat: Syntax checking is currently somewhere between rudimentary and non-existent. E.g., if you have pairs of asterisks inside a URL string, I have no idea what may happen.

enter image description here

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage[colorlinks=true,urlcolor=blue]{hyperref} % for "\href" macro

\usepackage{luacode,luatexbase}

%% Lua-side code
\begin{luacode}
   function process_simple_markdown (line)
      line = string.gsub( line, "%[(.-)%]%((.-)%)", "\\href{%2}{%1}" )
      line = string.gsub( line, "%*%*%*(.-)%*%*%*", "\\textbf{\\textit{%1}}")
      line = string.gsub( line, "%*%*(.-)%*%*",     "\\textbf{%1}" )
      line = string.gsub( line, "%*(.-)%*",         "\\textit{%1}" )
      return line
   end
\end{luacode}

%% TeX-side code
\newcommand\markdownon{%
   \directlua{luatexbase.add_to_callback( "process_input_buffer", process_simple_markdown, "process_simple_markdown" )}}
\newcommand\markdownoff{%
   \directlua{luatexbase.remove_from_callback( "process_input_buffer", "process_simple_markdown" )}}
\newenvironment{markdown}{\markdownon}{\markdownoff}

\begin{document}

\begin{markdown}
  This will be *processed* as [Markdown](http://daringfireball.net/projects/markdown/)!
\end{markdown}

\end{document}
  • 1
    Markdown was actually merely an example of a possible filter, unfortunately - my actual use-case is processing PlantUML source and embedding the resulting images. However, the process_input_buffer callback appears to be an extremely viable way to capture buffer contents regardless of what they're being used for, so this was a great pointer! Thanks. – 00dani May 26 '15 at 6:37
  • @00Davo: For a slow filter such as PlantUML, you may also want to consider caching the result. In the filter module, I compute the MD5 hash of the entire environment and compare it with previously stored value (stored in the auxiliary file), and re-run the filter only if this value has changed. – Aditya May 27 '15 at 5:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.