Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like to draw vertical rules at a specific location in the left margin of a listing in a listings environment. Is it possible ?

======= PSEUDO EXAMPLE =======

for i in range(5):
# One comment
    if i == 2:
# One comment
        print(i)

print("Finished....")

======= OUTPUT WISHED (this is ASCII art ! ) =======

   for i in range(5):
    # One comment
|      if i == 2:
|   # One comment
|          print(i)

    print("Finished....")   
share|improve this question
add comment

1 Answer

up vote 8 down vote accepted

You may use TikZ and it’s overlay function …

Here’s my solution.

Code

\documentclass{article}

\usepackage{xparse}
\usepackage{listings}
    \lstset{%
        escapechar=§% or what fits to your code
    }
\usepackage{tikz}
    \usetikzlibrary{calc}
    \tikzstyle{every lst line}=[line width=3pt, gray]
    % command for setting a TikZ anchor
    \newcommand{\tanc}[1]{%
        \begin{tikzpicture}[remember picture]
            \coordinate (#1) at (0,0);
%           \fill circle (0.5pt);% this line is for testing only
        \end{tikzpicture}%
    }
    % some parameters
    \def\DeltaX{4cm}
    \def\DeltaYi{6pt}
    \def\DeltaYii{0pt}
    % command for drawing the lines
    \NewDocumentCommand{\makeline}{O{0pt} m m O{}}{%
        \begin{tikzpicture}[remember picture, overlay, transform canvas={xshift=#1}]
            \draw [every lst line,#4] %
                let\p1=(#2), \p2=(#3), \p3=(current page.west) in%
                (\x3+\DeltaX,\y1+\DeltaYi) -- (\x3+\DeltaX,\y2+\DeltaYii);
            ;
        \end{tikzpicture}%
    }

\usepackage{lipsum}% for testing

\begin{document}
\lipsum[1]
%
\begin{lstlisting}
for i in range(5):
# Pu§\tanc{one}§t the anchor somewhere in the line
if i == 2:
# One comment §\tanc{two}§
    print(i) §\tanc{three}§
print("Finished....")§\tanc{four}§
\end{lstlisting}
\makeline{one}{two}\makeline{three}{four}[red]
\makeline[-7pt]{one}{four}[blue]
%
\lipsum[2]
\end{document}

Settings

  • Choose an escape character that is never part of your listings. I choosed §.
  • Adjust the every lst line style to fit your taste. This is the style applied to each line drawn with \makeline
  • Adjust the parameters to fit you font and layout. \DeltaX = distance to left page border, \DeltaYi = shift between baseline of the anchored row in your listing an the start of the line and \DeltaYii same for second row.

Usage

  • Put an anchor somewhere in the row you want the line to start with \tanc{<name 1>}
    # Pu§\tanc{one}§t the anchor somewhere in the line

  • Put a second anchor with \tanc{<name 2>}. The names should be unique at least for on listing.
    print(i) §\tanc{two}§

  • Draw the line with \makeline{<name 1>}{<name 2>}.
    \makeline{one}{two}

    You may change the line style of the line using the second optional argument and shift the line horizontally using the first one:
    \makeline[<x shift>]{<name 1>}{<name 2>}[<style>]
    \makeline[-7pt]{one}{four}[blue]

    If you load a decoration library you can also add big curly braces or whatever by using the <style> argument.

  • run LaTeX twice otherwise TikZ can’t get the right positions of the remember picture nodes.

Result

result

share|improve this answer
    
Thanks for this... I will start soon how to use TiKz for enhancing my documents. –  projetmbc Feb 5 '12 at 23:03
    
@projetmbc: I improved my answer and extend the code. If you want to learn TikZ you may consider the pgfmanual containing some great tutorials. –  Tobi Feb 6 '12 at 13:52
    
Thanks for the possibilty to indicate two lines, or more. That will help for producing documents to start programmation. PS : could you remove \start{fold} et \end{fold} in the example because they don't belong to the listing ? –  projetmbc Feb 6 '12 at 18:44
    
@projetmbc I removed them. Don’t know why they where there … I also added a not that the example needs two latex runs –  Tobi Feb 6 '12 at 18:58
    
Indeed I've puted \start{fold} et \end{fold} to materialze where I wanted to place the LaTeX commands to draw the rules. This corresponds to your §\tanc{...}§. –  projetmbc Feb 6 '12 at 19:40
show 3 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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