7

I would like to use the catchfilebetweentags package to grab code snippets from a source file and use minted to highlight them.

Imagine I have the following in program.scala:

//<a
def someFunctionA = {
  // some code
}
//a>

def aFunctionIDontCareAbout = {
  // irrelevant stuff
}

//<b
def someFunctionB = {
  // important code!
}
//b>

and the following LaTeX document:

\documentclass{article}
\usepackage{minted}
\usepackage{catchfilebetweentags}

\begin{document}

% Nicely formatted snippet:
\begin{minted}{scala}
  def someNicelyHighlightedFunction = {
    // not from the file
  }
\end{minted}

% Expanding, but unformatted snippet:
\CatchFileBetweenDelims{\a}{program.scala}{<a}{//a>}
\a

% Non-expanding snippet inside minted environment:
\CatchFileBetweenDelims{\b}{program.scala}{<b}{//b>}
\begin{minted}{scala}
  \b
\end{minted}

\end{document}

Is there any way I can get \b to expand inside the verbatim environment used by minted?

(I am not committed to catchfilebetweentags or to minted in particular, but I do need Pygments highlighting on extracted code fragments.)

1

1 Answer 1

6

catchfilebetweentags will get tricky with catcodes. Since you already have fancyvrb loaded, already have \write18 enabled (shell escape), and have Python (to use Pygments), I would suggest a pure Python solution. This is designed for tags that don't need to be escaped by either LaTeX or Python, though it could be adapted.

The basic idea is to use fancyvrb's VerbatimOut to create a Python script that will read your code and save the relevant portion in a temporary file. This script is executed automatically via \write18. Then the temporary file is read in via minted's \inputminted.

enter image description here

\documentclass{article}
\usepackage{minted}

\begin{VerbatimOut}{minted_delim.py}
import sys
codefile = sys.argv[1]
delim1 = sys.argv[2]
delim2 = sys.argv[3]
f = open(codefile)
code = f.read()
f.close()
f = open(codefile + '.snippet', 'w')
try:
    f.write(code.split(delim1, 1)[1].split(delim2, 1)[0])
except:
    f.write('MINTED DELIM ERROR')
f.close()
\end{VerbatimOut}

\newcommand{\inputmintedbetweendelims}[5][]{%
  \immediate\write18{python minted_delim.py "#3" "#4" "#5"}%
  \inputminted[#1]{#2}{#3.snippet}%
}

\begin{document}

\begin{minted}{scala}
  def someNicelyHighlightedFunction = {
    // not from the file
  }
\end{minted}

\inputmintedbetweendelims{scala}{program.scala}{<b}{//b>}


\end{document}
3
  • Question, though: what's the fifth argument to \inputmintedbetweendelims for? #5 is passed to the python script, but the latter doesn't seem to use sys.argv[4] anywhere... ? Aug 30, 2013 at 15:40
  • @NicolasPayette The script receives the name of the code file (#3), the opening delim (#4), and the closing delim (#5). sys.argv[0] is the script name, so #3 becomes sys.argv[1], #4 becomes sys.argv[2], and #5 becomes sys.argv[3].
    – G. Poore
    Aug 30, 2013 at 15:50
  • Oh, right, I see now. What confused me is the fact that it's the first arg of a LaTeX command that can be optional (#1, which in this case becomes the options arg to \inputminted). I also was not aware that sys.argv[0] is passed as the script name in Python. Anyway, thanks for the clarification! Aug 30, 2013 at 15:59

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.