4

I’m writing a macro to output Unicode codepoints in the U+1F642 🙂 SLIGHTLY SMILING FACE format. To do this, I need to print an argument as a hex number as well as pass it to \symbol.

Minimal non-working example:

\newcommand{\unicode}[3][]
    {\texttt{U+#1} {#3 \symbol{"#1}} \texttt{#2}}

I think some \expandafter or counter magic is required, but I’m not exactly sure where to go.

I can assume the codepoint will always be in upper-case hexadecimal, so multiple number-formats don’t need to be accounted for.

If it makes a difference, I’m using XeLaTeX.

The error is unsurprising:

! Missing number, treated as zero.
<to be read again>
                   {
\\unicode [#1]#2#3->\texttt {U+#1} \symbol {"#1}
                                                 \texttt {#2}
  • Your error message doesn't match up with the definition you've given: please post a full example. – Joseph Wright Apr 6 '17 at 15:44
  • @JosephWright OK, done; the definition includes a third optional argument for switching the symbol font, in case a special font is needed for a particular codepoint. – 9999years Apr 6 '17 at 15:46
8

\char is a TeX primitive that takes as argument a <number> and doesn't want braces as delimiters of the argument.

LaTeX provides \symbol as a wrapper around it.

\newcommand{\unicode}[2]{%
  \texttt{U+#1} \symbol{"#1} \texttt{#2}%
}

With \char it should be

\newcommand{\unicode}[2]{%
  \texttt{U+#1} \char"#1\space\space\texttt{#2}%
}

(the first \space is gobbled as the <number> terminator, the second one is typeset).

Minimal example:

\documentclass{article}
\usepackage{fontspec}
\setmainfont{CMU Serif}

\newcommand{\unicode}[2]{%
  \texttt{U+#1} \symbol{"#1} \texttt{#2}%
}

\begin{document}

\unicode{0180}{LATIN SMALL LETTER B WITH STROKE}

\unicode{04AF}{CYRILLIC SMALL LETTER STRAIGHT U}

\end{document}

However, if you want to be able to specify a different font for some character, the definition can be as follows. Note the order of the arguments.

\documentclass{article}
\usepackage{fontspec}
\setmainfont{CMU Serif}
\newfontfamily{\djvusans}{DejaVu Sans}

\newcommand{\unicode}[3][]{%
  \texttt{U+#2} {#1\symbol{"#2}} \texttt{#3}%
}

\begin{document}

\unicode{0180}{LATIN SMALL LETTER B WITH STROKE}

\unicode{04AF}{CYRILLIC SMALL LETTER STRAIGHT U}

\unicode[\djvusans]{1F0CA}{PLAYING CARD TEN OF DIAMONDS}

\end{document}

enter image description here

If you want the optional argument to be last (but I don't recommend it), you can use \NewDocumentCommand, provided by xparse which is loaded by fontspec.

\documentclass{article}
\usepackage{fontspec}
\setmainfont{CMU Serif}
\newfontfamily{\djvusans}{DejaVu Sans}

\NewDocumentCommand{\unicode}{mmO{}}{%
  \texttt{U+#1} {#3\symbol{"#1}} \texttt{#2}%
}

\begin{document}

\unicode{0180}{LATIN SMALL LETTER B WITH STROKE}

\unicode{04AF}{CYRILLIC SMALL LETTER STRAIGHT U}

\unicode{1F0CA}{PLAYING CARD TEN OF DIAMONDS}[\djvusans]

\end{document}
  • While I do appreciate your prompt response, this doesn’t actually work — the issue is with the expansion order (i.e. \char/\symbol not actually receiving a number), rather than syntax. I’ve revised the question to match, however. – 9999years Apr 6 '17 at 15:42
  • @9999years You are numbering arguments in the wrong order. – egreg Apr 6 '17 at 15:53
  • Ah, shoot! Should’ve looked at the argument order. Sorry for the terseness, I appreciate the help. – 9999years Apr 6 '17 at 15:55

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.