7

Consider the below unicode table. Some slots are undefined by the Unicode Consortium and appear empty in the table (slot 7,8,15 &16 in second row). How can I detect these and replace the characters with a symbol?

enter image description here

Minimal:

\documentclass{article}
\usepackage{fontspec}
\newfontfamily\greek{Times New Roman}
\makeatletter
%puts the unicode label (removes last char and adds x)
\def\putunicode@label#1#2;{%
  \def\reformat@unicode@string##1{%
  \bgroup%
  \ttfamily
  U+%
  \edef\z{}%
  \expandafter\@tfor\expandafter\i\expandafter:\expandafter=#2;\do{%
  \if\i;x\space
     \else\z\fi%
  \edef\z{\i}%
 }%
\egroup
}%
 \makebox[5em]{\reformat@unicode@string{#2}}%
}

\def\putchar@cx#1{%
   \char\n$_{\the\r}$
  }

\def\urow@cx#1{%
    \parindent0pt%
    \n=#1% 
    \r=1%
    \expandafter\putunicode@label#1;%
    \loop%
        \ifnum\n<\numexpr#1+16%
        \makebox[2.1em]{\expandafter\putchar@cx{#1}}%
        \advance\r by1%  
        \ifnum\r>16\r=1\relax\else\fi
        \advance\n by1%
    \repeat
    \par
}

\def\typeseturows@cx#1{%
\@for\next:=#1\do{%
  \urow@cx\next\vskip3pt}}


\newcommand\unicodetable[2]{%
  \par\leavevmode
  \bgroup%
   \parindent0pt%
   \newcount\n%
   \newcount\r%
   \r=1%
   \raggedright%
   \@nameuse{#1}%
   \r=1%
   {\ttfamily\makebox[3.1em]{}}%
   \loop%
    \ifnum\r<17%
    \makebox[2.1em]{\hfill\texttt{\the\r}\hfill}%
    \advance\r by1%  
   \repeat
   \vskip3pt
   \typeseturows@cx{#2}%
\egroup%
}

\makeatother

\begin{document}

\unicodetable{greek}{"1F00,"1F10,"1F20,"1F60}

\end{document}

1 Answer 1

7

Use \iffontchar:

\def\putchar@cx#1{%
   \iffontchar\font\n
     \char\n$_{\the\r}$%
   \else
     *%
   \fi
  }

The conditional \iffontchar\font<number> is true if a character is present in the slot <number>, false otherwise.

enter image description here


I've also removed a spurious space after $, but there are other glitches in your code. I'll refer to line numbers in your original code.

  1. Line 27 should be \parindent=0pt (no trailing %)

  2. Line 32 should be \ifnum\n<\numexpr#1+16\relax

  3. Lines 34 and 36 should be \advance\r by1 (no trailing %) or \advance\r by\@ne

  4. Line 35 should be \ifnum\r>16 \r=1 \else\fi

  5. Lines 50 and 51, that is \newcount\n and \newcount\r should be outside the definition of \unicodetable. Using \r is not really a good choice.

  6. Lines 52 and 55 should be \r=1 (no trailing %)

  7. Line 58 should be \ifnum\r<17 (no trailing %)

  8. Line 60 should be \advance\r by1 (no trailing %)

The % characters I suggest to remove may cause untimely expansions. Allocating registers in the definition of a macro should be done only if the assigned names depend on the macro arguments: at any call of \unicodetable you'd be wasting two counter registers.

4
  • @YiannisLazarides I noted other glitches. Besides them there are several redundant %, which are innocuous, though.
    – egreg
    Commented Sep 21, 2014 at 19:27
  • Thanks once more. It is still buggy, I need to test it a bit more.
    – yannisl
    Commented Sep 21, 2014 at 19:55
  • But this handles just characters not covered by the font which might or might not be assigned Unicode characters. Commented Sep 22, 2014 at 8:06
  • @KhaledHosny For the "unassigned slots" there's no primitive that I know of. Maybe a read only table with the status of a slot (unassigned/assigned in version x.y of Unicode) could be a solution.
    – egreg
    Commented Sep 22, 2014 at 8:59

You must log in to answer this question.

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