2

I wish to annotate a hex text block with matrix. and the matrix output should be similar to listings output. so I add a listings above for compare.

\documentclass{article}
\usepackage[margin=1mm]{geometry}
\usepackage{tikz}
\usepackage{listings}
\usetikzlibrary{positioning}
\usepackage{pgfplots}
\pgfplotsset{compat=1.6}
\usetikzlibrary{matrix}
\lstset{frame=tb,
    aboveskip=3mm,
    belowskip=3mm,
    showstringspaces=false,
    columns=flexible,
    basicstyle={\small\ttfamily},
    numbers=none,
    breaklines=true,
    breakatwhitespace=true,
}
\begin{document}
    \small\ttfamily\begin{lstlisting}
00000000: ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01  ......JFIF......
00000010: 00 01 00 00 ff db 00 43 00 03 02 02 03 02 02 03  .......C........
00000020: 03 03 03 04 03 03 04 05 08 05 05 04 04 05 0a 07  ................
00000030: 07 06 08 0c 0a 0c 0c 0b 0a 0b 0b 0d 0e 12 10 0d  ................ 
    \end{lstlisting}
    \begin{tikzpicture}[>=latex]
 \matrix (m) [
matrix of nodes,nodes in empty cells,
row sep =-\pgflinewidth,
column sep = -\pgflinewidth,
nodes={anchor=center,minimum width=1ex,text width=2ex,inner sep=0,outer sep=0},
] 
{
0&0&0&0&0&0&0&0&:& &f&f& &d&8& &f&f& &e&0& &0&0& &1&0& &4&a& &4&6& &4&9& &4&6& &0&0& &0&1& &0&1& &0&0& &0&0& &0&1& & &.&.&.&.&.&.&J&F&I&F&.&.&.&.&.&.\\
0&0&0&0&0&0&1&0&:& &0&0& &0&1& &0&0& &0&0& &f&f& &d&b& &0&0& &4&3& &0&0& &0&3& &0&2& &0&2& &0&3& &0&2& &0&2& &0&3& & &.&.&.&.&.&.&.&C&.&.&.&.&.&.&.&.\\
0&0&0&0&0&0&2&0&:& &0&3& &0&3& &0&3& &0&4& &0&3& &0&3& &0&4& &0&5& &0&8& &0&5& &0&5& &0&4& &0&4& &0&5& &0&a& &0&7& & &.&.&.&.&.&.&.&.&.&.&.&.&.&.&.&.\\
0&0&0&0&0&0&3&0&:& &0&7& &0&6& &0&8& &0&c& &0&a& &0&c& &0&c& &0&b& &0&a& &0&b& &0&b& &0&d& &0&e& &1&2& &1&0& &0&d& & &.&.&.&.&.&.&.&.&.&.&.&.&.&.&.&.\\
};  
   \draw[red,line width=1pt] (m-1-11.south west) rectangle (m-1-16.north east);
   \draw[red,<-] (m-1-16.north east) -- ++(1,0.2) -- ++(5,0) node[pos=1,right] {ISO};
    \end{tikzpicture}
\end{document}

How can I adjust the parameters to get similar result between matrix output and listings output? Or any other choice for such annotation purpose? enter image description here

5
  • You can use tikzmark to annotate the listing.
    – user194703
    Dec 10 '19 at 19:58
  • @Schrödinger'scat Good suggestion, but I prefer to use table cell to access the elements.
    – lucky1928
    Dec 10 '19 at 20:21
  • If you are open to something that allows you to annotate the code without actually changing it, see e.g. here. This allows you to have the code in a separate file even, and still to access everything.
    – user194703
    Dec 10 '19 at 21:13
  • @Schrödinger'scat Great information, is it for matlab code only, when I try it with my text, the position sounds weird.would you please give a modify for my specific text. (annotate the ff 48 ff part.
    – lucky1928
    Dec 10 '19 at 21:30
  • 1
    You have already an accepted answer... so if you are happy with what you got, I am not going to add an answer.
    – user194703
    Dec 10 '19 at 21:52
2

Like this?

screenshot

\documentclass{article}
\usepackage[margin=1mm]{geometry}
\usepackage{tikz}
\usepackage{listings}
\usetikzlibrary{positioning,fit}
\usepackage{pgfplots}
\pgfplotsset{compat=1.6}
\usetikzlibrary{matrix}
\lstset{frame=tb,
    aboveskip=3mm,
    belowskip=3mm,
    showstringspaces=false,
    columns=flexible,
    basicstyle={\small\ttfamily},
    numbers=none,
    breaklines=true,
    breakatwhitespace=true,
}
\begin{document}
    \small\ttfamily\begin{lstlisting}
00000000: ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01  ......JFIF......
00000010: 00 01 00 00 ff db 00 43 00 03 02 02 03 02 02 03  .......C........
00000020: 03 03 03 04 03 03 04 05 08 05 05 04 04 05 0a 07  ................
00000030: 07 06 08 0c 0a 0c 0c 0b 0a 0b 0b 0d 0e 12 10 0d  ................ 
    \end{lstlisting}
    \begin{tikzpicture}[>=latex]
 \matrix (m) [
matrix of nodes,nodes in empty cells,
row sep =15\pgflinewidth,
column sep = -7.5\pgflinewidth,
nodes={anchor=center,minimum width=1ex,text width=2ex,inner sep=0pt,outer sep=0pt},
] 
{
0&0&0&0&0&0&0&0&:& &f&f& &d&8& &f&f& &e&0& &0&0& &1&0& &4&a& &4&6& &4&9& &4&6& &0&0& &0&1& &0&1& &0&0& &0&0& &0&1& & &.&.&.&.&.&.&J&F&I&F&.&.&.&.&.&.\\
0&0&0&0&0&0&1&0&:& &0&0& &0&1& &0&0& &0&0& &f&f& &d&b& &0&0& &4&3& &0&0& &0&3& &0&2& &0&2& &0&3& &0&2& &0&2& &0&3& & &.&.&.&.&.&.&.&C&.&.&.&.&.&.&.&.\\
0&0&0&0&0&0&2&0&:& &0&3& &0&3& &0&3& &0&4& &0&3& &0&3& &0&4& &0&5& &0&8& &0&5& &0&5& &0&4& &0&4& &0&5& &0&a& &0&7& & &.&.&.&.&.&.&.&.&.&.&.&.&.&.&.&.\\
0&0&0&0&0&0&3&0&:& &0&7& &0&6& &0&8& &0&c& &0&a& &0&c& &0&c& &0&b& &0&a& &0&b& &0&b& &0&d& &0&e& &1&2& &1&0& &0&d& & &.&.&.&.&.&.&.&.&.&.&.&.&.&.&.&.\\
};  
   \node[fit= (m-1-11)(m-1-17),draw,red]{};
   \draw[red,<-] (m-1-16.north east) -- ++(1,0.2) -- ++(5,0) node[pos=1,right] {ISO};
    \end{tikzpicture}
\end{document}
3
  • 1
    Great, thanks, but the red rectangle a little bit weird. it should cover the four char's but sounds like only half is covered.
    – lucky1928
    Dec 10 '19 at 20:20
  • Look at my updated answer. Otherwise, specify exactly what you want about this red frame.
    – AndréC
    Dec 10 '19 at 20:30
  • 1
    Great, fits done good job! it's exactly what I want. many thanks.
    – lucky1928
    Dec 10 '19 at 20:40
2

refer to this SO, I modify it with hardcode hex numbers. it's a little bit long but now sure if any regrex support for listings keyword define! Maybe someone can help improve it.

\documentclass{article}
\usepackage[margin=1cm]{geometry}
\usepackage{listings}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\usetikzlibrary{fit,calc,shadows,decorations.pathreplacing}
\makeatletter
\newif\iflst@linemark
\lst@AddToHook{EveryLine}{%
    \begingroup
    \advance\c@lstnumber by 1\relax
    \pgfmark{line-\lst@name-\the\c@lstnumber-start}%
    \endgroup
}
\lst@AddToHook{EOL}{\pgfmark{line-\lst@name-\the\c@lstnumber-end}%
    \global\lst@linemarktrue
}
\lst@AddToHook{OutputBox}{%
    \iflst@linemark
    \pgfmark{line-\lst@name-\the\c@lstnumber-first}%
    \global\lst@linemarkfalse
    \fi
}
\def\tkzlst@fnum#1\relax#2\@STOP{%
    \def\@test{#2}%
    \ifx\@test\@empty
    \def\tkzlst@start{0}%
    \else
    \@tempcnta=#1\relax
    \advance\@tempcnta by -1\relax
    \def\tkzlst@start{\the\@tempcnta}%
    \fi
}
\lst@AddToHook{Init}{%
    \expandafter\tkzlst@fnum\lst@firstnumber\relax\@STOP
    \pgfmark{line-\lst@name-\tkzlst@start-start}%
}
\newcommand\balloon[4]{%
    \pgfmathtruncatemacro\pgf@temp{%
        #3-1
    }%
    \iftikzmark{line-#2-\pgf@temp-start}{%
        \iftikzmark{line-#2-#3-first}{%
            %\xdef\b@lines{({pic cs:line-#2-\pgf@temp-start} -| {pic cs:line-#2-#3-first})}%
            \xdef\b@lines{($({pic cs:line-#2-\pgf@temp-start} -| {pic cs:line-#2-#3-first})!.5!({pic cs:line-#2-#3-first})$)}
        }{%
            \iftikzmark{line-#2-#3-start}{%
                %\xdef\b@lines{({pic cs:line-#2-\pgf@temp-start} -| {pic cs:line-#2-#3-start})}%
                \xdef\b@lines{($({pic cs:line-#2-\pgf@temp-start} -| {pic cs:line-#2-#3-first})!.5!({pic cs:line-#2-#3-first}) $)}
            }{%
                \xdef\b@lines{(pic cs:line-#2-\pgf@temp-start)}%
            }%
        }%
    }{%
        \xdef\b@lines{}%
    }%
    \foreach \k in {#3,...,#4} {%
        \iftikzmark{line-#2-\k-first}{%
            \xdef\b@lines{\b@lines (pic cs:line-#2-\k-first) }
        }{}
        \iftikzmark{line-#2-\k-end}{%
            \xdef\b@lines{\b@lines (pic cs:line-#2-\k-end) }
        }{}
    }%
    \ifx\b@lines\pgfutil@empty
    \else
    \edef\pgf@temp{\noexpand\tikz[remember picture,overlay]\noexpand\node[fit={\b@lines},balloon] (#1) {};}%
    \pgf@temp
    \fi
}
\makeatother
% Define styles for balloons, lines and marked code areas
\tikzset{
    balloon/.style={
        draw,
        fill=blue!20,
        opacity=0.4,
        inner sep=2pt,
        rounded corners=2pt
    },
}
\newcounter{tmlistings}
\newcommand\makenode[2]{%
    \tikz[baseline=0pt, remember picture] { \node[anchor=base,#1/.try,inner sep=0] (m-\the\value{tmlistings}) {#2}; }%
    \stepcounter{tmlistings}%
}
\lstdefinelanguage{HEX}{
    alsoletter=0123456789,
    keywords={
        00,01,02,03,04,05,06,07,08,09,0a,0b,0c,0d,0e,0f,
        10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f,
        20,21,22,23,24,25,26,27,28,29,2a,2b,2c,2d,2e,2f,
        30,31,32,33,34,35,36,37,38,39,3a,3b,3c,3d,3e,3f,
        40,41,42,43,44,45,46,47,48,49,4a,4b,4c,4d,4e,4f,
        50,51,52,53,54,55,56,57,58,59,5a,5b,5c,5d,5e,5f,
        60,61,62,63,64,65,66,67,68,69,6a,6b,6c,6d,6e,6f,
        70,71,72,73,74,75,76,77,78,79,7a,7b,7c,7d,7e,7f,
        80,81,82,83,84,85,86,87,88,89,8a,8b,8c,8d,8e,8f,
        90,91,92,93,94,95,96,97,98,99,9a,9b,9c,9d,9e,9f,
        a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,aa,ab,ac,ad,ae,af,
        b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf,
        c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,ca,cb,cc,cd,ce,cf,
        d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,da,db,dc,dd,de,df,
        e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,ea,eb,ec,ed,ee,ef,
        f0,f1,f2,f3,f4,f5,f6,f7,f8,f9,fa,fb,fc,fd,fe,ff
    },
    keywordstyle=\makenode{keyword},
    sensitive=false, %not case-sensitive
} %
% Command to draw a balloon over two anchors
\newcommand*{\ann}[4][]{%[red]{from}{to}{desc}
    \draw [decoration={brace,amplitude=0.5em,raise=2pt},decorate,ultra thick,#1]
    (#2) -- node [align=center,anchor=west,right=5pt] {#4} (#3);
}%
\begin{document}
    \begin{lstlisting}[language=HEX,name=list1,numbers=left,firstnumber=1]
00000000: ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01  ......JFIF......
00000010: 00 01 00 00 ff db 00 43 00 03 02 02 03 02 02 03  .......C........
00000020: 03 03 03 04 03 03 04 05 08 05 05 04 04 05 0a 07  ................
00000030: 07 06 08 0c 0a 0c 0c 0b 0a 0b 0b 0d 0e 12 10 0d  ................ 
00000000: ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01  ......JFIF......
00000010: 00 01 00 00 ff db 00 43 00 03 02 02 03 02 02 03  .......C........
00000020: 03 03 03 04 03 03 04 05 08 05 05 04 04 05 0a 07  ................
00000030: 07 06 08 0c 0a 0c 0c 0b 0a 0b 0b 0d 0e 12 10 0d  ................ 
    \end{lstlisting}
    \balloon{comment}{list1}{3}{3}
    \balloon{comment}{list1}{4}{4}
    \balloon{comment}{list1}{7}{7}
    \begin{tikzpicture}[remember picture,overlay]
        \draw[->] (0,0) -- (pic cs:line-list1-5-first);
        \draw[->] (0,0) -- (pic cs:line-list1-5-start);
        \draw[->] (0,0) -- (pic cs:line-list1-5-end);
        \node[above] at (0,0) {Line 5};
        \node[fit=(m-0)(m-2),draw,red]{};
        \draw[red,<-] (m-2.north east) -- ++(1,0.2) -- ++(12,0) node[pos=1,right] {ISO};
        \node[fit=(m-32)(m-34),draw,red]{};
        \draw[red,<-] (m-34.north east) -- ++(1,0.2) -- ++(12,0) node[pos=1,right] {ISO};
        \ann[red]{pic cs:line-list1-4-end}{pic cs:line-list1-7-end}{hello}
\end{tikzpicture}
\end{document}

Now it looks like: enter image description here

1

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.