% \iffalse % vim: set expandtab: % vim: set shiftwidth=2: % vim: set tabstop=2: % \fi % \iffalse meta-comment % % Copyright (C) 2026 by Lukas Heindl % --------------------------------------------------------------------------- % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3c or later is part of all distributions of LaTeX % version 2008/05/04 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Lukas Heindl. % % This work consists of all files listed in manifest.txt. % % \fi % % \iffalse %<*driver> \ProvidesFile{hexdumptikz-code.dtx} % %\NeedsTeXFormat{LaTeX2e}[2022-06-01] % %<*driver> \documentclass{ltxdoc} \usepackage[numbered]{hypdoc} \usepackage{hexdumptikz} \usepackage{csquotes} \usepackage{xspace} \usepackage{array} \usepackage{amsmath} \usepackage{tikz} \usetikzlibrary{positioning,arrows.meta} \tikzset{ >={Stealth[scale=1.5]}, } \NewDocumentEnvironment{sideeffects}{+b}{% \par \def\sclobber{\texttt{clobbered}\xspace}% \def\sdir{\texttt{ dir}\xspace}% \def\sindir{\texttt{indir}\xspace}% \noindent Sideeffects:\\ \begin{tabular}{rrl} #1 \end{tabular} }{\par} \NewDocumentEnvironment{args}{+b}{% \par \def\ain{\texttt{in}}% \def\aout{\texttt{out}}% \noindent Arguments:\\ \begin{tabular}{>{\#}ccl} #1 \end{tabular} }{\par} \def\MakePrivateLetters{% \makeatletter \catcode`\_11 \catcode`\:11} \NewDocElement[% macrolike, idxtype=fn., idxgroup=expl3 functions, printtype=\textit{fn.}, ]{Fn}{fn} \NewDocElement[% macrolike, idxtype=var, idxgroup=expl3 variables, printtype=\textit{var.}, ]{Var}{var} \NewDocElement[% idxtype=pgfkey, idxgroup=pgfkeys, printtype=\textit{pgfkey}, ]{Pgfkey}{pgfkey} \NewDocElement[% idxtype=error, idxgroup=error, printtype=\textit{error}, ]{Error}{error} \EnableCrossrefs \CodelineIndex \RecordChanges \setcounter{IndexColumns}{2} \setlength\IndexMin{100pt} % see https://tex.stackexchange.com/questions/95882/avoid-multicol-error-error-saving-partial-page \begin{document} \DocInput{\jobname.dtx} \PrintChanges \PrintIndex \end{document} % % \changes{v0.0.0}{2026-05-14}{First draft} % % % \fi % % \GetFileInfo{hexdumptikz.sty} % % \title{\textsf{hexdumptikz-code} -- \fileinfo} % \author{Lukas Heindl\thanks{% % E-Mail: \href{oss.heindl+latex@protonmail.com}{oss.heindl+latex@protonmail.com}\\% % Issue tracker: \href{https://codeberg.org/atticus-sullivan/hexdumptikz/issues}{codeberg.org/atticus-sullivan/hexdumptikz/issues}\\% % Codeberg (mirror): \href{https://codeberg.org/atticus-sullivan/hexdumptikz}{codeberg.org/atticus-sullivan/hexdumptikz}\\% % \\% % }} % \date{\fileversion~from \filedate} % \maketitle % \iffalse %<*package> %<@@=hexdumptikz> % \fi % % High-level overview of how the different modules / sub-packages work together: % % \begin{tikzpicture}[every node/.style={align=center,font=\sffamily}] % \node[] (user) {User}; % \node[right=of user] (draw-hd) {draw(-hd)}; % \node[below right=of draw-hd] (parser) {parser}; % \node[above=of draw-hd] (sel-row) {selector\\row}; % \node[above right=of draw-hd] (sel-sty) {selector\\style}; % \node[below=14ex of user] (draw-label) {annotate}; % % % \path[every edge/.style={->,draw}] % (user) edge[] node[above,sloped] {1} (draw-hd) % (draw-hd) edge[bend left] node[above,sloped] {2} (parser) % (parser) edge[bend left] node[below,sloped] {3} (draw-hd) % (draw-hd) edge[] node[above,sloped] {4} (sel-row) % (draw-hd) edge[] node[above,sloped] {5} (sel-sty) % (user) edge[] node[below,sloped] {(6)} node[above,sloped] {labeling} (draw-label) % ; % \node[rotate=45,anchor=south] at (parser.north west) {loop}; % \end{tikzpicture} % % \part{Implementation} % \phantomsection % \refstepcounter{section} % \addcontentsline{toc}{section}{\mdseries\pkg{hexdumptikz}}% % % \makeatletter % \let\origmaketitle\maketitle % \NewDocumentCommand \pkginput {O{#2}m}{% % \begingroup % \def\maketitle{% % \GetFileInfo{hexdumptikz-#1.sty} % \ifx\@title\@empty % \def\@title{\pkg{hexdumptikz-#1}}% % \fi % \ifx\@author\@empty % \def\@author{Lukas Heindl}% % \fi % \def\@date{\fileversion~from \filedate}% % \let\saved@title\@title % \origmaketitle % \phantomsection % \refstepcounter{section} % \addcontentsline{toc}{section}{\mdseries\pkg{\saved@title}}% % }% % \let\Finale\relax % \let\PrintIndex\relax % \let\PrintChanges\relax % \input{hexdumptikz-#2.dtx}% % \endgroup % } % \makeatother % % Identify the package and give the over all version information. % \begin{macrocode} \ProvidesExplPackage {hexdumptikz} {2026-06-20} {1.0.1} {Printing and annotating hexdumps with TikZ} % \end{macrocode} % % Load external dependencies % \begin{macrocode} \RequirePackage { tikz } \ExplSyntaxOff \usetikzlibrary{chains} \ExplSyntaxOn % \end{macrocode} % % Load internal (sub-)packages % \begin{macrocode} \RequirePackage { hexdumptikz-common } \RequirePackage { hexdumptikz-draw } \RequirePackage { hexdumptikz-annotate } \RequirePackage { hexdumptikz-addrcalc } % \end{macrocode} % % % \subsection{Errors} % \begin{error}{unknown-row} % \begin{macrocode} \msg_new:nnn { hexdumptikz } { unknown-row } { The~(#2)~row~with~the~id~#1~is~unknown. } % \end{macrocode} % \end{error} % % \begin{error}{invalid-address} % \begin{macrocode} \msg_new:nnn { hexdumptikz } { invalid-address } { #1~is~not~a~valid~address. } % \end{macrocode} % \end{error} % % \begin{error}{address-too-short} % \begin{macrocode} \msg_new:nnn { hexdumptikz } { address-too-short } { Address~'#1'~is~too~short.~Must~be~at~least~#2~long. } % \end{macrocode} % \end{error} % % \begin{error}{invalid-boolean} % \begin{macrocode} \msg_new:nnn { hexdumptikz } { invalid-boolean } { '#1'~cannot~be~parsed~as~boolean. } % \end{macrocode} % \end{error} % % \begin{error}{weird-num-bytes-per-row} % \begin{macrocode} \msg_new:nnn { hexdumptikz } { weird-num-bytes-per-row } { '#1'~is~a~weird~num~bytes~per~row. } % \end{macrocode} % \end{error} % % \subsection{Main/Public functions/Macros} % \begin{fn}{\@@_begin:nn} % Begin-code when a new hexdumptikz environment is started % \begin{args} % 1 & \ain & pgfkeys \\ % 2 & \ain & filename from which to read the hexdump from \\ % \end{args} % \begin{macrocode} \cs_new_protected:Npn \@@_begin:nn #1 #2 { \pgfkeys { /hexdumptikz, #1 } \str_set:Ne \l_hexdumptikz_common_input_file_str { #2 } \begin { scope }[/hexdumptikz/next~scope] \pgfkeys { /hexdumptikz/next~scope/.style = { } } } % \end{macrocode} % \end{fn} % % \begin{fn}{\@@_end:} % End-code when a hexdumptikz environment stops -- doing come cleanup % \begin{args} % \end{args} % \begin{macrocode} \cs_new_protected:Nn \@@_end: { \prop_gclear:N \g_hexdumptikz_common_cur_offsets_prop \end { scope } } % \end{macrocode} % \end{fn} % % \begin{environment}{hexdumptikz} % Define an environment which wraps the hexdumptikz related operations. % SHOULD be placed inside a tikz-environment. % TODO % \begin{macrocode} \NewDocumentEnvironment { hexdumptikz } { O { } m } { \@@_begin:nn { #1 } { #2 } } { \@@_end: } % \end{macrocode} % \end{environment} % % \begin{macro}{\hexdumptikzPrint} % Define a macro which prints the hexdump which was previously specified (via its filename). % SHOULD be placed inside a hexdumptikz-environment % TODO % \begin{macrocode} \NewDocumentCommand{ \hexdumptikzPrint } { O { } m } { \hexdumptikz_draw_print:nn { #1 } { #2 } } % \end{macrocode} % \end{macro} % % \begin{macro}{\hexdumptikzLabelBytes} % Define a macro which labels a sequence of bytes in the printed hexdump. % SHOULD be placed inside a hexdumptikz-environment % TODO % Should be placed after the hexdump was printed. % \begin{macrocode} \NewDocumentCommand{ \hexdumptikzLabelBytes } { O { } mm } { \__hexdumptikz_annotate_label_bytes:nnn { #1 } { #2 } { #3 } } % \end{macrocode} % \end{macro} % \begin{macro}{\hexdumptikzLabelBytesFallback} % Define a macro which labels a sequence of bytes in the printed hexdump. % Also works without the data gathered while printing the dump (outside of the environment). % But the output does look a little bit less good compared to the normal annotation. % \begin{macrocode} \NewDocumentCommand{ \hexdumptikzLabelBytesFallback } { O { } mm } { \__hexdumptikz_annotate_label_bytes_fallback:nnn { #1 } { #2 } { #3 } } % \end{macrocode} % \end{macro} % % \begin{macro}{\hexdumptikzAddrToNodename} % Define a helper macro which converts a full address to its nodename in the hexdump. % Can be used by the user for custom drawings. % \begin{macrocode} \NewDocumentCommand{ \hexdumptikzAddrToNodename } { m } { \__hexdumptikz_addrcalc_address_to_nodename:e { #1 } } % \end{macrocode} % \end{macro} % % \begin{macro}{\hexdumptikzAddrToRow} % Define a helper macro which converts a full address to the row in which the byte is placed. % Can be used by the user for custom drawings. % \begin{macrocode} \NewDocumentCommand{ \hexdumptikzAddrToRow } { m } { \__hexdumptikz_addrcalc_address_to_row:e { #1 } } % \end{macrocode} % \end{macro} % % \begin{macro}{\hexdumptikzAddrToCol} % Define a helper macro which converts a full address to the column in which the byte is placed. % Can be used by the user for custom drawings. % \begin{macrocode} \NewDocumentCommand{ \hexdumptikzAddrToCol } { m } { \__hexdumptikz_addrcalc_address_to_col:e { #1 } } % \end{macrocode} % \end{macro} % % \pkginput{common} % \pkginput{draw} % \pkginput{addrcalc} % \pkginput{annotate} % \pkginput{parser} % \pkginput{parser-hd} % \pkginput{selector} % \pkginput{selector-parser} % \pkginput{selector-matcher} % % \iffalse % % \fi % % \Finale