# Vertical rule at the left of a listing

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....")

-

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

-
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