% \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-common.dtx} % %\NeedsTeXFormat{LaTeX2e}[2022-06-01] % %<*driver> \begin{document} \DocInput{\jobname.dtx} \PrintChanges \PrintIndex \end{document} % % \changes{v0.0.0}{2026-05-13}{First draft} % % % \fi % % \iffalse %<*package> %<@@=hexdumptikz_common> % \fi % % \maketitle % % \begin{abstract} % Defines helpers and variables which are use throughout the whole project. % \end{abstract} % % Identify the package and give the over all version information. % \begin{macrocode} \ProvidesExplPackage {hexdumptikz-common} {2026-06-20} {1.0.1} {Common functionality for working with hexdumps and (large) addresses} % \end{macrocode} % \subsection{Conventions of this (sub-)package} % None of the function defined in this (sub-)package makes use of the expl3 scratch-variables. % % The idea behind this is that this (sub-)package only defines small helper functions. % If they would clobber expl3 scratch-variables functions calling the helpers would not be able to use the normal expl3 scratch-variables anymore. % Thus, this (sub-)package defines its own scratch-variables if functions need them. % % \subsection{Implemenation} % \subsubsection{pgfkeys} % Set up common pgf-keys / the space where all pgfkeys will live in % \begin{macrocode} \RequirePackage { pgfkeys } \pgfkeys { % \end{macrocode} % Make it a real \enquote{directory}. % \texttt{/tikz} should also be searched to allow easily setting tikz-options. % \begin{macrocode} /hexdumptikz/.is~family, /hexdumptikz/.search~also = { /tikz }, % \end{macrocode} % Not all tikz-options work natively. % Thus, this option allows setting options on the next \texttt{scope}. % % Note: All tikz drawings are wrapped in a \texttt{scope}. % \begin{pgfkey}{/hexdumptikz/tikz} % \begin{macrocode} /hexdumptikz/next~scope/.style = { }, /hexdumptikz/tikz/.style = { /hexdumptikz/next~scope/.append~style = { #1 } }, % \end{macrocode} % \end{pgfkey} % \begin{macrocode} } % \end{macrocode} % \subsection{Regexes} % Set up regexes commonly used throught the whole package % % \begin{var}{\c_hexdumptikz_common_hex_regex} % Matches an hexadecimal number % \begin{macrocode} \regex_const:Nn \c_hexdumptikz_common_hex_regex { \A 0x[0-9a-fA-F]+ \Z } % \end{macrocode} % \end{var} % % \begin{var}{\c_hexdumptikz_common_hex_x_regex} % Matches a hexadecimal number which is (optionally) accompanied by a specification of the x-index. % \begin{macrocode} \regex_const:Nn \c_hexdumptikz_common_hex_x_regex { \A 0x[0-9a-fA-F]+ (?: / [0-9]+ )? \Z } % \end{macrocode} % \end{var} % % \begin{var}{\c_hexdumptikz_common_idx_regex} % Matches an index specification. % Can (optionally) be accompanied by a specification of the x-index. % \begin{macrocode} \regex_const:Nn \c_hexdumptikz_common_idx_regex { \A [0-9]+ (?: / [0-9]+ )? \Z } % \end{macrocode} % \end{var} % % \begin{var}{\c_hexdumptikz_common_leading_hex_base_regex} % Matches a \emph{leading} hexadecimal-base specifier. % \begin{macrocode} \regex_const:Nn \c_hexdumptikz_common_leading_hex_base_regex { \A 0x } % \end{macrocode} % \end{var} % % Generate variants of expl functions which are used often (having this in % hexdumptikz\_common means this only runs once) % \begin{macrocode} \cs_generate_variant:Nn \int_from_hex:n { f } \cs_generate_variant:Nn \msg_critical:nnn { nnV } \cs_generate_variant:Nn \msg_critical:nnnn { nnVV , nneV } \cs_generate_variant:Nn \msg_critical:nnnnn { nnVeV } \cs_generate_variant:Nn \msg_warning:nnn { nnV } % \end{macrocode} % % \subsection{Variables used by multiple other (sub-)packages} % Define the variables only once here. % Note that this does not mean the variables are global. % % \begin{var}{\l_hexdumptikz_common_nodename_prefix_tl} % Prefix for nodenames generated % \begin{macrocode} \tl_new:N \l_hexdumptikz_common_nodename_prefix_tl % \end{macrocode} % \end{var} % % \begin{var}{\l_hexdumptikz_common_input_file_str} % Path to the input file from which to read the hexdump from % \begin{macrocode} \str_new:N \l_hexdumptikz_common_input_file_str % \end{macrocode} % \end{var} % % \begin{var}{\l_hexdumptikz_common_bytes_per_row_int} % Number of bytes shown in one row. % (optionally) enforced by the parser and used at some other locations too. % \begin{macrocode} \int_new:N \l_hexdumptikz_common_bytes_per_row_int % \end{macrocode} % \end{var} % % \begin{var}{\l_hexdumptikz_common_addr_len_int} % padd addresses to this length (only refers to the hex-digits without the leading 0x) % \begin{macrocode} \int_new:N \l_hexdumptikz_common_addr_len_int % \end{macrocode} % \end{var} % % \begin{var}{\g_hexdumptikz_common_cur_offsets_prop} % Stores a mapping \emph{addr/offset} to \emph{out-index}. % Required to draw from one row to the row above/below since this package avoids calculating on the addresses. % needs to be global since the assignment happens inside a tikz-scope so % otherwise the assignment is gone when the prop is needed % \begin{macrocode} \prop_new:N \g_hexdumptikz_common_cur_offsets_prop % \end{macrocode} % \end{var} % % \subsection{Functions} % \begin{fn}{\hexdumptikz_common_pad_left:Nnn} % \begin{sideeffects} % \sclobber & \sdir & \texttt{l\_tmpb\_int} \\ % \end{sideeffects} % \begin{args} % 1 & \ain/\aout & tl variable to work on \\ % 2 & \ain & target length (int expression) \\ % 3 & \ain & padding token (should have length 1) \\ % \end{args} % \begin{macrocode} \cs_new_protected:Npn \hexdumptikz_common_pad_left:Nnn #1 #2 #3 { % \end{macrocode} % calculate the needed padding (target - current length) % \begin{macrocode} \int_set:Nn \l_tmpb_int { #2 - \tl_count:N #1 } % \end{macrocode} % perform the padding % \begin{macrocode} \int_compare:nNnT { \l_tmpb_int } > { 0 } { \tl_put_left:Ne #1 { \prg_replicate:nn { \l_tmpb_int } { #3 } } } } % \end{macrocode} % \end{fn} % % \begin{fn}{\hexdumptikz_common_pad_address:N} % \begin{sideeffects} % \sclobber & \sindir & \texttt{l\_tmpa\_int} \\ % \sclobber & \sindir & \texttt{l\_tmpb\_int} \\ % \end{sideeffects} % \begin{args} % 1 & \ain/\aout & address (tl) \\ % - & \ain & \texttt{l\_hexdumptikz\_common\_addr\_len\_int} \\ % \end{args} % \begin{macrocode} \cs_new_protected:Npn \hexdumptikz_common_pad_address:N #1 { % \end{macrocode} % Remove leading \texttt{0x} (hex base indicator) % \begin{macrocode} \regex_replace_once:NnNTF \c_hexdumptikz_common_leading_hex_base_regex { } #1 { % \end{macrocode} % Pad the address and place back the hex base indicator % \begin{macrocode} \hexdumptikz_common_pad_left:Nnn #1 { \l_hexdumptikz_common_addr_len_int } { 0 } \tl_put_left:Nn #1 { 0x } } { % \end{macrocode} % Pad the address (no base-indicator present before -> none present after) % \begin{macrocode} \hexdumptikz_common_pad_left:Nnn #1 { \l_hexdumptikz_common_addr_len_int } { 0 } } } % \end{macrocode} % \end{fn} % % \begin{fn}{\hexdumptikz_common_parse_bool:Nn} % \begin{sideeffects} % \end{sideeffects} % \begin{args} % 1 & \aout & bool var (bool) \\ % 2 & \ain & user input \\ % \end{args} % \begin{macrocode} \cs_new_protected:Npn \hexdumptikz_common_parse_bool:Nn #1 #2 { \str_case:enF { \tl_trim_spaces:n { #2 } } { { true } { \bool_set_true:N #1 } { false } { \bool_set_false:N #1 } } { \msg_critical:nne { hexdumptikz } { invalid-boolean } { #2 } } } % \end{macrocode} % \end{fn} % \iffalse % % \fi % % \Finale