2

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

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

  • David's answer is nice because it shows how stuff works but I have to admit - yours is even more elegant. – Anab Aug 9 '16 at 19:51
  • @Anab disaster! :-) – David Carlisle Aug 9 '16 at 20:10
6

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}
  • 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 Aug 9 '16 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. – David Carlisle Aug 9 '16 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 Aug 9 '16 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? – Jonathan Komar Mar 22 '18 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. – David Carlisle Mar 22 '18 at 13:00
1

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

  • 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 Aug 9 '16 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. – Steven B. Segletes Aug 9 '16 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 Aug 9 '16 at 19:21
  • @Anab I agree David's answer is very elegant. Nonetheless, I have revised to not interfere with underlying \url configuration. – Steven B. Segletes Aug 9 '16 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 Aug 9 '16 at 19:40
0

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
\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}

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.