\usepackage{etoolbox}
\usepackage{fancyvrb}

\usepackage{listings}
\lstset{basicstyle=\ttfamily,fontadjust=true,basewidth=0.5em,xleftmargin=26pt}

\usepackage[strings,nohyphen]{underscore}

\usepackage{mdframed}

\newsavebox{\measurebox}
\newlength{\widestline}

% \measurewidest{line one\\line two\\...}  ->  \widestline = width of widest
\newcommand{\measurewidest}[1]{%
  \begin{lrbox}{\measurebox}%
    \begin{tabular}{@{}l@{}}#1\end{tabular}%
  \end{lrbox}%
  \setlength{\widestline}{\wd\measurebox}%
}

% \asymbox[<left pad>]{line one\\line two\\...}   other three sides: 8pt
\newcommand{\asymbox}[2][0pt]{%
  \begin{lrbox}{\measurebox}%
    \begin{tabular}{@{}l@{}}\tt #2\end{tabular}%
  \end{lrbox}%
      {\setlength{\fboxsep}{0pt}%
        \fcolorbox{black}{yellow!20}{%
          \kern#1%
          \vbox{\kern0pt\hbox{\usebox{\measurebox}}\kern0pt}%
          \kern0pt}}%
}

% ===========================================================================
% Annotated code listings.  Emitted by sks/code/code_block.py; the layout
% policy lives here so it can be tuned without touching the Python.
%
% The model: a listing is a vertical stack of BLOCKS, each block a run of
% code lines with an optional comment beside it.  There is deliberately no
% table -- comments are a fixed distance from their own block and do not
% align with each other, and each block's shaded box is as wide as that
% block's longest line.
%
% Two mechanisms carry the whole appearance:
%
%  1. Every line is a \strut'ed \makebox of the block's width.  A LaTeX
%     \strut is exactly 0.7\baselineskip high and 0.3 deep -- one full
%     \baselineskip -- so consecutive lines inside a block abut exactly,
%     with no gap and no overlap, at any point size.  Without the strut a
%     line with no descender would sit closer to its neighbour and the
%     rhythm would follow the text rather than the grid.
%
%  2. \offinterlineskip in the listing removes the interline glue BETWEEN
%     BLOCKS, so consecutive blocks abut too and a boxed block continues
%     the rhythm of the plain lines around it.  (It does not reach inside
%     a \parbox, which restores normal interline spacing -- that is why
%     the struts in point 1 are doing the work there, and why the box's
%     vertical padding comes from \fboxsep below rather than from a
%     padding line, which would be spaced off the grid.)
% ===========================================================================

\definecolor{klcodeshade}{rgb}{1,1,.6}

\newlength{\kllistingwidth}   % width of a whole unannotated listing
% How the listing is placed WITHOUT being boxed, so that it can still break
% across pages: \klshift moves it right (an :offset with :hpos left) and
% \klindent is the width taken out of \linewidth (either side's offset).
% A minipage would do both at once but cannot break -- see Code.tex in
% sks/code/code_block.py, which sets these before \begin{klcode}.
\newlength{\klshift}     \setlength{\klshift}{0pt}
\newlength{\klindent}    \setlength{\klindent}{0pt}
\newlength{\klcodewidth}      % width of the current block's box
\newlength{\klcommentwidth}   % what is left for its comment
% Horizontal inset of the code from the box's left edge.  0pt puts the
% box's left edge ON the code column, where the line's own indentation
% begins, rather than out to the left of it; a positive value moves the
% CODE right, never the box left.
\newlength{\klcodepad}   \setlength{\klcodepad}{0pt}
\newlength{\klcodegap}   \setlength{\klcodegap}{14pt}  % box to comment
\newlength{\klcodemin}   \setlength{\klcodemin}{6em}   % narrower: see below
% Clear space above and below a block that HAS a box, so that two boxed
% blocks with no unboxed lines between them read as two boxes rather than
% one.  Applied per block, never per line: the lines within a block must
% still abut, or the shading stops being a solid rectangle.
% 1.5pt is 2px at the CSS reference 96dpi, matching the html margin in
% css/code.css -- these two are meant to look the same, so change them
% together.
\newlength{\klboxgap}    \setlength{\klboxgap}{1.5pt}
% The box's own vertical margin: space INSIDE the shading, above the first
% line and below the last.  Same 2px equivalent, matching the html padding.
\newlength{\klboxpad}    \setlength{\klboxpad}{1.5pt}

% \klline{<line>} — one code line, padded and strut'ed to the block width.
\newcommand{\klline}[1]{%
  \makebox[\klcodewidth][l]{\hspace{\klcodepad}\strut\ttfamily #1}}

% \klcodebox{<lines>} — the block's lines, shaded when the block has a
% comment (\klcomment is set by \klblock).
%
% The shading is ONE \colorbox around the whole block, not one per line,
% because only a box around the whole block can have a vertical margin.
%
% That margin is \vspace* INSIDE the \parbox rather than \fboxsep: \fboxsep
% pads all four sides, and any horizontal padding would put the box's left
% edge out to the LEFT of the code column.  With \fboxsep 0 the box spans
% exactly the code's own extent, so it begins where the line's indentation
% begins and the code stays aligned with the unshaded lines around it.
\newcommand{\klcodebox}[1]{%
  \ifx\klcomment\empty
    \parbox[c]{\klcodewidth}{#1}%
  \else
    \setlength{\fboxsep}{0pt}%
    \colorbox{klcodeshade}{%
      \parbox[c]{\klcodewidth}{\vspace*{\klboxpad}#1\vspace*{\klboxpad}}}%
  \fi}

% \klblock{<widest line>}{<lines>}{<comment>}
%   <lines> is \klline/\klshaded calls separated by \\; <comment> may be
%   empty.  The comment gets what the box leaves of \linewidth (NOT
%   \textwidth: inside a list or minipage they differ, and \textwidth would
%   push the comment into the margin).  If that remainder is too narrow to
%   set prose in, the comment goes BELOW the block rather than being
%   squeezed into an overfull box.
\newcommand{\klblock}[3]{%
  \begingroup
  % A block is boxed exactly when it has a comment, so this one test also
  % decides whether the block gets the \klboxgap separation.
  \def\klcomment{#3}%
  \ifx\klcomment\empty\else\vskip\klboxgap\fi
  \settowidth{\klcodewidth}{\ttfamily #1}%
  \addtolength{\klcodewidth}{2\klcodepad}%
  % The box advances the line by exactly \klcodewidth (\fboxsep is 0 in
  % \klcodebox).  If a horizontal padding is ever reintroduced there, its
  % width must be subtracted here too: leaving it out overfills the line,
  % and \raggedright then breaks it -- dropping the comment onto the next
  % line at the margin, which looks like the narrow-comment fallback.
  \setlength{\klcommentwidth}%
    {\dimexpr\linewidth-\klindent-\klcodewidth-\klcodegap\relax}%
  \noindent
  \ifdim\klcommentwidth<\klcodemin
    \klcodebox{#2}%
    \ifx\klcomment\empty\else
      \\\parbox[t]{\linewidth}{\klcommentfont #3}%
    \fi
  \else
    \klcodebox{#2}%
    \ifx\klcomment\empty\else
      \hspace{\klcodegap}%
      \parbox[c]{\klcommentwidth}{\klcommentfont #3}%
    \fi
  \fi
  % End the block's line.  Without this every block joins ONE horizontal
  % list and the blocks are broken into lines and justified like words.
  \par
  \ifx\klcomment\empty\else\vskip\klboxgap\fi
  \endgroup}

% The annotation font.  Ragged right: a justified annotation beside a
% narrow box hyphenates badly.
\newcommand{\klcommentfont}{\sffamily\itshape\small\raggedright}

% \begin{klcode} ... \end{klcode} — the listing itself.  \offinterlineskip
% is what makes the struts the only thing setting vertical rhythm.
\newenvironment{klcode}
  {\par\addvspace{0.5\baselineskip}%
   \begingroup
   \setlength{\parindent}{0pt}%
   \setlength{\parskip}{0pt}%
   \raggedright
   % An unboxed listing is shifted with \leftskip rather than wrapped in a
   % minipage, so that it can still break across pages.
   \leftskip=\klshift
   \offinterlineskip}
  {\endgroup\par\addvspace{0.5\baselineskip}}
