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

  • @YiannisLazarides I noted other glitches. Besides them there are several redundant %, which are innocuous, though. – egreg Sep 21 '14 at 19:27
  • Thanks once more. It is still buggy, I need to test it a bit more. – Yiannis Lazarides Sep 21 '14 at 19:55
  • But this handles just characters not covered by the font which might or might not be assigned Unicode characters. – Khaled Hosny Sep 22 '14 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 Sep 22 '14 at 8:59

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.