% !TEX spellcheck = en_GB \documentclass{article} \usepackage{fontspec} \usepackage[backend=biber]{biblatex} \addbibresource{literatur.bib} \usepackage{codeanatomy} \usepackage{listings} \lstset { basicstyle=\small\ttfamily% ,language=% ,escapeinside={!}{!}% ,resetmargins=true% ,columns=flexible% ,literate={-}{-}1% ,keepspaces=true } % command from ltxdoc \newcommand{\pkg}[1]{\textsf{#1}} % others shortcuts \newcommand{\slsh}{\textbackslash{}} \newcommand{\TikZ}{Ti\textit{k}Z} \newcommand{\inputlisting}[1]{% \lstinputlisting[% basicstyle=\footnotesize\ttfamily% ,xleftmargin=-40pt% ,resetmargins=true% ,firstline=5% ,language=% ,columns=flexible% ,escapeinside={}{}% ,keepspaces=true ]{#1}% } \def\thinmargin{\list{}{\rightmargin-30pt\leftmargin-40pt}\item[]} \let\endthinmargin=\endlist %\newenvironment{thinmargin}{}{} \usepackage{readprov} % need for \GetFileInfo{} \usepackage{hyperref} \title{ \pkg{codeanatomy} -- Draw Code Anatomy% \thanks{This file describes \fileversion, last revised \filedate.}\\\vspace*{2ex} \normalsize{Usage with \pkg{listings}} } \author{ Hồng-Phúc Bùi% \thanks{ E-mail: \href{mailto:Hồng-Phúc Bùi} {hong-phuc.bui (at) htwsaar dot de} } } \date{Released \filedate} \newsavebox\codelst \newsavebox\mycodebox \begin{document} \GetFileInfo{codeanatomy.sty} \maketitle \tableofcontents \section{General Usage with Package \pkg{listings}} \subsection{Setup Package \pkg{listings}} The most important setup for the package \pkg{listings} is the delimiter to escape \LaTeX{} commands in Listing. With this escape delimiter we can mark a piece of code as with \verb|\cPart|. In this example we use \verb|!| and \verb|!| as delimiter. Code between \verb|!| and \verb|!| is evaluated as \LaTeX{}-code. \lstset { escapeinside={+}{+} } \begin{lrbox}{\codelst} \begin{lstlisting} \usepackage{codeanatomy} \usepackage{listings} \lstset { basicstyle=\small\ttfamily ,escapeinside=+\cPart{delimiter}{\{!\}\{!\}}+ } +\cPart{declareBox}{\slsh{}newsavebox\{\slsh{}mycodebox\}}+ \end{lstlisting} \end{lrbox} \begin{thinmargin} \begin{tikzpicture}[remember picture] % {[on background layer]\draw[code grid debug] (-3.5,-0.5) grid (5.5,4.5);} \node(code) [anatomy] at (0,0){\usebox\codelst};% \codeAnnotation{delimiterText} (6,1.152) {Setup \texttt{!} and \texttt{!}\\as delimiter} \codeAnnotation{declareBoxText}(-2.5,0.2) {Savebox to typeset \\ \texttt{lstlisting}\\ inside TikZ-Node} \draw[->, annotation] (delimiterText) -- (delimiter); \draw[->, annotation] (declareBoxText) -- (declareBox); \end{tikzpicture} \end{thinmargin} Delimiter can also be reset in \verb|document|-Environment, typical just before a new \verb:\begin{lstlisting}: environment so each anatomy can have different delimiter. The fact is, in this document I use \verb|+| and \verb|+| for the above listing, so that I can typeset \verb|!| in this listing. You may also want to set option \verb|keepspaces| to \verb|true|, so that your reader can easy copy past your example code. \subsection{Typeset Code} % ----------------------- The command \verb|\codeBlock| does not work if the environment \verb|lstlisting| is passed to its argument. So instead of \verb|\codeBlock| we must use the \TikZ{} command \verb|\node|: \begin{lrbox}{\codelst} \begin{lstlisting} +\mtPoint{lstsMT}+\begin{lrbox}{\mycodebox}+\extremPoint{lstsML}+ +\slsh{}begin\{lstlisting\}\vspace{6pt}\mbPoint{lstsMB}+ +\mtPoint{mostLeft}+function gcd(p,q) { if(q === 0) { return q; } else { const r = p % q; return gcd(q, r);+\extremPoint{mostRight}+ } }+\mbPoint{mostBottom}\vspace{6pt}+ +\mtPoint{lsteMT}\slsh{}end\{lstlisting\}\extremPoint{lsteML}+ \end{lrbox}+\mbPoint{lsteMB}+ \begin{tikzpicture}[remember picture] +\cPart{tikzNode}{\slsh{}node(code) [anatomy] at (0,0)\{\slsh{}usebox\slsh{}mycodebox\}}\cPart{semiColon}{;}+ \end{tikzpicture} \end{lstlisting} \end{lrbox} \begin{thinmargin} \begin{tikzpicture}[remember picture] \node(code) [anatomy] at (0,0) {\usebox\codelst}; \fitExtrem{listingBegin}{(lstsMT) (lstsML) (lstsMB)} \fitExtrem{listingEnd}{ (lsteMT) (lsteML) (lsteMB)} \fitExtrem{listingContent}{(mostLeft) (mostRight) (mostBottom)} % Annotations \codeAnnotation{tikzNodeText} (-2, 0) {use \texttt{\slsh{}node}\\instead of\\\texttt{\slsh{}codeBlock}} \codeAnnotation{listingText} (-2, 4) {typeset code in\\\texttt{lrbox} / \texttt{lstlisting}\\environment} \codeAnnotation{listingContentText} (6.5, 3) {whitespaces\\in code\\are kept} \codeAnnotation{semiColonText} (8.5, -0.5) {don't forget\\semicolon} % Arrows from labels to code parts \draw[->,annotation] (tikzNodeText) -- (tikzNode.west); \draw[->,annotation] (listingText) -- (listingBegin.west); \draw[->,annotation] (listingText) -- (listingEnd.west); \draw[->,annotation] (listingContentText) -- (listingContent); \draw[->,annotation] (semiColonText) -- (semiColon); \end{tikzpicture} \end{thinmargin} Figure~\ref{fig:full-formatted-code} shows result of the above code. \begin{figure}[ht] \begin{lrbox}{\codelst} \begin{lstlisting} function gcd(p,q) { if (q === 0) { return q; } else { const r = p % q; return gcd(q, r) } } \end{lstlisting} \end{lrbox} \begin{tikzpicture}[remember picture] \node(code) [anatomy] at (0,0) {\usebox\codelst}; \end{tikzpicture} \caption{Formatted Code Listing\label{fig:full-formatted-code}} \end{figure} \subsection{Mark Code} % -------------------- The command \verb|\cPart| can be used to mark single-line code parts. For multiple-line code parts once can use \verb|\xxxPoint| family to mark the outer most points of code parts and \verb|\fitExtrem| to cover extreme points of a code part. These commands must be put between escape delimiter, here \verb|!| and \verb|!|. \begin{lrbox}{\codelst} \begin{lstlisting} \begin{lrbox}{\mycodebox} +\slsh{}begin\{lstlisting\}+ !\cPart{fnHead}{function \cPart{fnName}{gcd} \cPart{paramList}{(p,q)}}\vspace{3pt}!{ +\cPart{ep1}{!\slsh{}mtPoint\{mostLeft\}!}+if (q === 0) { return q; }else{ +\cPart{cp}{!\slsh{}cPart\{localVar\}\{const r\}!}+ = p % q; return gcd(q, r);+\cPart{ep2}{!\slsh{}extremPoint\{mostRight\}!}+ }+\cPart{ep3}{!\slsh{}mbPoint\{mostBottom\}!}+ } +\slsh{}end\{lstlisting\}+ \end{lrbox} \begin{tikzpicture} \node(code) [anatomy] at (0,0) {\usebox\mycodebox}; \fitExtrem{fnBody}{(mostLeft) (mostRight) (mostBottom)} \end{tikzpicture} \end{lstlisting} \end{lrbox} \begin{thinmargin} \begin{tikzpicture}[remember picture] \node(code) [anatomy] {\usebox\codelst}; % Annotations \codeAnnotation{epText} (12,2.75) {xxx\texttt{Point}-s mark\\outer most\\of the function body} \codeAnnotation{cpText} (-1,3.25) {\texttt{cPart} marks a\\single line\\code part} % Arrows \draw[->,annotation] (epText) -- (ep1.south east); \draw[->,annotation] (epText) -- (ep2.east); \draw[->,annotation] (epText) -- (ep3.south east); \draw[->,annotation] (cpText) -- (cp.west); \end{tikzpicture} \end{thinmargin} Figure~\ref{fig:listing-code-parts} shows the result of the above code. \begin{figure}[ht] \begin{lrbox}{\codelst} \lstset{escapeinside={!}{!}} \begin{lstlisting} !\cPart{fnHead}{function \cPart{fnName}{gcd} \cPart{paramList}{(p,q)}}\vspace{3pt}! { !\mtPoint{mostLeft}!if (q === 0) { return q; } else { !\cPart{localVar}{const r}! = p % q; return gcd(q, r);!\extremPoint{mostRight}! }!\mbPoint{mostBottom}! } \end{lstlisting} \end{lrbox} \begin{tikzpicture}[remember picture] \node(code) [anatomy] at (0,0) {\usebox\codelst}; \fitExtrem{fnBody}{(mostLeft) (mostRight) (mostBottom)} \end{tikzpicture} \caption{Code Listing with mark of code parts\label{fig:listing-code-parts}} \end{figure} \subsection{Add Annotations to Listing} % ------------------------------------- This step is the same as the description in the usage document of package \pkg{codeanatomy}. Readers can typeset annotations to the above listing like an exercise. \subsection{Highlight some tokens} \LaTeX-Code: \begin{thinmargin} \inputlisting{demo-recursive-with-bug.tex} \end{thinmargin} Result: \input{demo-recursive-with-bug.tex} \section{Some examples} % ==================== Most of examples in this section are redrawn from the textbook~\autocite{sedgewick-wayne-2016}. \subsection{Anatomy of a Java Program~\autocite[5]{sedgewick-wayne-2016}} % ----------------------------------- \begin{thinmargin} \inputlisting{demo-java-program.tex} \end{thinmargin} \input{demo-java-program.tex} \subsection{Anatomy of an expression~\autocite[17]{sedgewick-wayne-2016}} % ----------------------------------- \begin{thinmargin} \inputlisting{demo-java-expression.tex} \end{thinmargin} \input{demo-java-expression.tex} \subsection{Using a primitive Data Type~\autocite[17]{sedgewick-wayne-2016}} % ------------------------------------- \begin{thinmargin} \inputlisting{demo-using-a-primitive-data-type.tex} \end{thinmargin} \input{demo-using-a-primitive-data-type.tex} \subsection{Anatomy of a method signature~\autocite[30]{sedgewick-wayne-2016}} % --------------------------------------- \begin{thinmargin} \inputlisting{demo-anatomy-of-a-method-signature.tex} \end{thinmargin} \input{demo-anatomy-of-a-method-signature.tex} \subsection{Using a library method~\autocite[30]{sedgewick-wayne-2016}} % -------------------------------- \begin{thinmargin} \inputlisting{demo-using-a-library-method.tex} \end{thinmargin} \input{demo-using-a-library-method.tex} \subsection{Anatomy of an \texttt{if} statement~\autocite[51]{sedgewick-wayne-2016}} % --------------------------------------------- \begin{thinmargin} \inputlisting{demo-anatomy-of-an-if-statement.tex} \end{thinmargin} \input{demo-anatomy-of-an-if-statement.tex} \subsection{Anatomy of a \texttt{while} loop~\autocite[54]{sedgewick-wayne-2016}} % ------------------------------------------ \begin{thinmargin} \inputlisting{demo-anatomy-of-a-while-loop.tex} \end{thinmargin} \input{demo-anatomy-of-a-while-loop.tex} \subsection{Anatomy of a \texttt{for} loop~\autocite[59]{sedgewick-wayne-2016}} % ---------------------------------------- \begin{thinmargin} \inputlisting{demo-anatomy-of-a-for-loop.tex} \end{thinmargin} \input{demo-anatomy-of-a-for-loop.tex} \subsection{Anatomy of a static method~\autocite[196]{sedgewick-wayne-2016}} % ---------------------------------------- \begin{thinmargin} \inputlisting{demo-anatomy-of-a-static-method.tex} \end{thinmargin} \input{demo-anatomy-of-a-static-method.tex} \printbibliography \end{document}