8

I would like to print a number of 256-bit long hashes in hexadecimal (so 64 characters, I'm skipping the usual "0x" without white spaces or punctuation) in line and using a monospaced font.

So, I first went for \texttt, which does not hyphenate my strings. I saw some questions with interesting answers, such as How to get long \texttt sections to break and Automatic linebreak on specific character but those both define linebreak for a specific character and I would find ugly to use their trick for each of the 16 characters of hexadecimal without some sort of natural loop.

Is there a way to define a command such that the text inside will be typed as texttt but break on any character or, even better, a standard way to typeset long hexadecimal strings that takes this issue into account?

MWE:

\documentclass{article}

\newcommand{\hash}[1]{\texttt{#1}}%In a perfect world, this would be changed to allow linebreaks anywhere in #1

\begin{document}
SHA-256 is a hash function with a 256-bit long output: \hash{d270f747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15}
\end{document}

4 Answers 4

12

There is already a package for this:

\documentclass{article}
\usepackage{seqsplit}

\newcommand{\hash}[1]{{\ttfamily\seqsplit{#1}}}

\begin{document}

SHA-256 is a hash function with a 256-bit long output:
\hash{d270f747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15}

\end{document}

enter image description here

Without packages:

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand{\hash}{O{\ttfamily}m}
 {
  \group_begin:
  #1 % font choice, default \ttfamily
  \tl_map_function:nN { #2 } \__anab_hash_char:n
  \group_end:
 }
\cs_new:Nn \__anab_hash_char:n { #1 \skip_horizontal:n { 0pt plus 0.2pt } }
\ExplSyntaxOff

\begin{document}

SHA-256 is a hash function with a 256-bit long output:
\hash{d270f747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15}

\noindent\parbox[t]{0.4\textwidth}{%
  SHA-256 is a hash function with a 256-bit long output:
  \hash{d270f747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15}
}\quad
\parbox[t]{0.4\textwidth}{%
  SHA-256 is a hash function with a 256-bit long output:
  \hash[\sffamily]{d270f747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15}
}

\end{document}

enter image description here

5
  • David's answer is nice because it shows how stuff works but I have to admit - yours is even more elegant.
    – Anab
    Commented Aug 9, 2016 at 19:51
  • @Anab disaster! :-) Commented Aug 9, 2016 at 20:10
  • This method doesn't keep whitespace. It is used for display sequence without whitespace.
    – Tokubara
    Commented Apr 8, 2023 at 9:21
  • @Tokubara That's what the OP wants. If you have further needs, please ask a new question with the details.
    – egreg
    Commented Apr 8, 2023 at 9:32
  • @egreg I find that with backslash like \hash{this\ a\ word}, whitespace will be keeped.
    – Tokubara
    Commented Apr 8, 2023 at 9:39
7

You can add a penalty after each character

enter image description here

\documentclass{article}

\newcommand{\hash}[1]{\texttt{\zz#1\zz}}%In a perfect world, this would be changed to allow linebreaks anywhere in #1

\def\zz#1{%
 \ifx\zz#1\else
   #1\linebreak[1]\expandafter\zz
 \fi}

\begin{document}
SHA-256 is a hash function with a 256-bit long output: \hash{d270f747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15}
\end{document}
9
  • Thanks, this does exactly what I wanted! I am just a bit curious as to how that works: is it a recursion that does nothing if #1 is empty (stopping condition) or else suggests a line break at the current position?
    – Anab
    Commented Aug 9, 2016 at 18:39
  • 1
    @Anab it recurses through each character adding a potential breakpoint stopping when it sees the \zz that is placed at the end. Commented Aug 9, 2016 at 18:44
  • Thanks, that's what I thought was going on but my TeX was not nearly good enough for me to be sure of it without asking. :)
    – Anab
    Commented Aug 9, 2016 at 18:49
  • @DavidCarlisle Nice. But this \hash{\char"02C6} (or \hash{\char"02C6{}}) breaks it. Is there a way to modify your code to cope with hexidecimal/octal/substitution-denoted characters? Commented Mar 22, 2018 at 12:18
  • 1
    @JonathanKomar ^^^^02c6 is the hex representation of the character, it is a single character token that can be used anywhere a character can be used eg \^^^^02c6 would be a command token with that name. \char"02C6 is completely different it is 6 tokens invoking a non-expandable sequence of instructions which if used in a typesetting context will access the the glyph from the font with number hex 02C6. Commented Mar 22, 2018 at 13:00
3

Solution Making TeX Treat Characters like Words

This works, but has the limitation that denoted characters do not work. e.g. using hexidecimal (\char"02C6) or octal notation.

\documentclass{article}

\def\hash#1{\xscan#1\relax}% calls xscan which looks ahead one token, #1
\def\xscan{\afterassignment\xxscan\let\token= }% assign single token to \token and call \xxscan
\def\xxscan{%
\ttfamily% set font style
\ifx\token\relax\ttfamily\else%test for end-of-line or end of group and switch to ttfamily
  \ifcat\token\space%
    \token% token is catcode 10
    \spaceskip=.5em% remove glue from space for fixed-width space
    \xspaceskip=.5em% remove glue from space for fixed-width space
  \else%
    \token\hskip 0pt plus 1sp minus 1sp % add glue to any non-catcode 10 (space)
   \fi
   \spaceskip=0pt% reset space skip
\expandafter\xscan% feed next token to \xscan, which is effectively a recursive call
\fi}

\begin{document}
SHA-256 is a hash function with a 256-bit long output: \hash{d270f747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15}
%SHA-256 is a hash function with a 256-bit long output: \hash{d270f\char"02C6\relax747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15}% \char" denoted char syntax not supported
\end{document}

Related: How can I make LaTeX to recognize spaces in my macro (catcode 10)?

Solution Using Intercharacter Tokens

\XeTeXinterchartokenstate=1                     % turn them on
\XeTeXinterchartoks 0 0 = {\penalty0\relax}#1}  % use insert token

This is my preferred solution if using TeX Live 2017 and using xelatex. This has the advantage that it supports the original capabilities of \texttt-it should-like denoted characters (see comments under David Carlisle's answer).

\documentclass{article}

\newcommand{\hash}[1]{\texttt{\XeTeXinterchartokenstate=1\XeTeXinterchartoks 0 0 = {\penalty0\relax}#1}}%In a perfect world, this would be changed to allow linebreaks anywhere in #1

\begin{document}
SHA-256 is a hash function with a 256-bit long output: \hash{d270f747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15}
SHA-256 is a hash function with a 256-bit long output: `\hash{d270f\char"02C6\relax747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15}`

\end{document}
1
  • I've adapted the initial macro since when using it with text that has space it would add recursively more space. Just in case somebody would like to use this macro.
    – LeO
    Commented Jan 18 at 11:59
2

Configure it as a URL. EDITED to do it inside a group as \hexdump{}, so that \url remains unaffected by the redefinitions.

\documentclass{article}
\usepackage{url,lipsum}
\urlstyle{rm}
\newcommand\hexdump[1]{%
  \begingroup\urlstyle{tt}%
  \def\UrlBreaks{%
    \do\1\do\2\do\3\do\4\do\5\do\6\do\7\do\8\do\9\do\0\do\A\do\B\do\C\do\D\do\E\do\F}%
  \url{#1}\endgroup%
}
\textwidth3.34in
\parskip 1ex
\begin{document}
\noindent\hexdump{5A0FF349ABC5A0FF349ABC5A0FF349ABC5A0FF349ABC5A0FF349ABC5A0FF349ABC5A0FF349ABC5%
A0FF349ABC5A0FF349ABC5A0FF349ABC5A0FF349ABC5A0FF349ABC5A0FF349ABC5A0FF349ABC}

\lipsum[1]

URLs should be unaffected: \url{www.xyz.com}
\end{document}

enter image description here

5
  • Thanks, but I have two small issues with that: though it does the job and listing all the characters is not that long, it still require to do it, and modifies the url command that I use at several other occasions in my document (which, granted, was not specified in my question).
    – Anab
    Commented Aug 9, 2016 at 18:46
  • @Anab I can (and will) resolve the 2nd issue easily enough. I'm not sure what you mean by the first issue. Commented Aug 9, 2016 at 18:56
  • What I mean is that, compared to David Carlisle's answer, that I accepted, yours require to a long list of \do (line 5) which, though not that hard to do for 16 characters, feels a bit blunt to me. That's however just a feeling and I've done way uglier at several occasions when I couldn't find an elegant solution quickly enough. ;)
    – Anab
    Commented Aug 9, 2016 at 19:21
  • @Anab I agree David's answer is very elegant. Nonetheless, I have revised to not interfere with underlying \url configuration. Commented Aug 9, 2016 at 19:31
  • 1
    I'm sticking with the accepted answer for its elegance but I like seeing different ways to do stuff so you got my upvote now that it the rest of my document unaffected.
    – Anab
    Commented Aug 9, 2016 at 19:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .