0

Instead of using firstline= and lastline=, is it possible to include code within a certain, user-defined key? That way, if I wanted to include only one definition of a long file, for example, I would not need to worry about typing above the definition, since that would change the first line.

2
  • Yes, this is possible. There is a script contained in TeXLive, called listings-ext.sh to do something like that (take a look at texdoc listings-ext). But I personally didn't like the fact that one doesn't get named entries but that they are numbered automatically, so I created a Python script (which should also work on Windows), that does something similar to listings-ext.sh but with names, that one isn't publish yet: gitlass.de/jonathan/listings-extx.py
    – Skillmon
    Oct 15 '19 at 18:00
  • That is very cool, nice work. I was considering making a Python script to simply make new files by scanning the text, extracting text between tags, and generating a new Python file to be used, and using pythontex to automatically run the script when I compile my document. Only downside I can think of is I would lose line numbering capabilities if I wanted to present and excerpt within a large block. Oct 15 '19 at 23:23
3

listings provides an experimental feature to include parts of code based on certain begin and end markers (see section 5.7 "Arbitrary linerange markers" of the listings guide).

The options

rangeprefix = <prefix>,
rangesuffix = <suffix>,
linerange   = <startmarker>-<endmarker>

would look in the included code for lines

... some boring code ...
<prefix><startmarker><suffix>
... interesting code ...
<prefix><endmarker><suffix>
... more boring code ...

and include only the interesting parts of the code in the listing (including the start/end markers, unless includerangemarker=false). Several marker pairs can be used with linerange, all separated by commas. Special characters in the prefix, suffix or markers need to be escaped by \.

The disadvantage of this method is that you need to annotate the input code with start and end markers.

Usage example:

\documentclass{article}
\usepackage{listings}
\usepackage{xcolor}

\begin{filecontents*}{\jobname.hs}
{- begin map -}
map :: (a -> b) -> [a] -> [b]
map f []     = []
map f (x:xs) = f x : map f xs
{- end map -}

{- begin head -}
head :: [a] -> a
head (x:_) = x
head []    = error "Prelude.head: empty list"
{- end head -}

{- begin tail -}
tail :: [a] -> [a]
tail (_:xs) = xs
tail []     = error "Prelude.tail: empty list"
{- end tail -}
\end{filecontents*}

\lstset{
    language=Haskell,
    basicstyle=\ttfamily,
    backgroundcolor=\color{black!5}
}

\begin{document}
\lstinputlisting[
    linerange=8-10
]{\jobname.hs}

\lstinputlisting[
    rangeprefix=\{-\ ,
    rangesuffix=\ -\},
    includerangemarker=false,
    linerange=begin\ head-end\ head
]{\jobname.hs}
\end{document}

outputs

enter image description here

2
  • Very nice. I will have to experiment with this. Do you know if there is a character that will hide text from being shown. Similar to escapechar, maybe a hidechar? Also, do you know if you can choose to begin numbering at 1 or the number corresponding to the source code? Oct 16 '19 at 16:49
  • @likethevegetable You can set firstnumber if you want to start counting from a specific value. I can't come up with a way to hide text right away, maybe you want to ask that as a separate question.
    – siracusa
    Oct 17 '19 at 0:11

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.