I have a series of "charts" I created with Excel (before discovering LaTeX) to show the ROM character patterns for an old computer for inclusion in a book on retrocomputing.

enter image description here

My dilemma is how to approach inserting these into the book. I'm assuming each should be a separate image so I can allow LaTeX to format them properly in a grid pattern, but I'm also wondering if TikZ or even Inkscape would be a better approach.

I need 128 characters total. The character in the lower-left is from a TTF font. I'm using XeTeX so the inclusion of that font is no problem.

What would be the "best" approach in terms of learning curve, convenience, and appearance in the final document?

  • 1
    Can you obtain the huge characters by TTF scaling, or must be a different approach to obtain the same look that this example? All these details are needed? An approach could be tex.stackexchange.com/questions/44806/…. Another, make a tabular environment model and fill cells as needed.
    – Fran
    Aug 6, 2013 at 19:49
  • I believe I could scale the TTF, but I'd prefer to reproduce the charts exactly as they are because of the information they convey (bit patterns, data, ASCII code, screen code, and appearance). The grid represents the pixels on screen (each character is 8 x 8). Aug 6, 2013 at 19:52
  • 1
    Related: tex.stackexchange.com/questions/116869/…. Also: Excel can save selections as pdf, which you can crop with pdfcrop and insert as graphics. Aug 6, 2013 at 20:10

3 Answers 3


Please note the symbol node style which should have the right font setup for the special font. My positioning-plus has been used for the keys west below which can be replaced with original positioning and TikZ keys: west below=<distance> of node is the same as below=<distance> of node.south west, anchor=north west.


  /handlers/.append tikz/.code=\pgfkeys{\pgfkeyscurrentpath/.append code=\tikzset{#1}},%
  /handlers/.prefix tikz/.code=\pgfkeys{\pgfkeyscurrentpath/.prefix code=\tikzset{#1}}}
  @int/start chain/.style={start chain=ch#1 going right},
  column width/.initial=+.5cm,
  row height/.initial=+.6cm,
  every letter picture/.tikz={
    node distance=+0pt,
    every node/.append style={
      minimum width=\pgfkeysvalueof{/letter/column width},
      minimum height=\pgfkeysvalueof{/letter/row height},
      text depth=+0pt,
      outer sep=+0pt,
  every header label/.tikz={font=\tiny,rotate=90,inner sep=+0pt,outer sep=+0pt},
  every cell node/.tikz={draw=gray, ultra thin},
  every 1 node/.tikz={fill=black},
  every 0 node/.tikz={},
  data column node/.tikz={
    text width=\widthof{000}
  symbol node/.tikz={
    font=\ttfamily}% Here should stand the command for the XeTeX font
    \tikzpicture[/letter/every letter picture/.try, /letter/@int/start chain/.list/.expanded={0,1,...,\letter@Columns}]
      \node[anchor=west,/letter/head node/.try] (letter@head) {Bit Values of Pixels};
        \foreach \letter@Power in {1,...,\letter@Columns} {
          \ifnum\letter@Power=1\tikzset{/letter/@int/first node/.tikz={west below=of letter@head}}\fi
          \node[on chain=ch0,/letter/@int/first node/.try,/letter/header node/.try,label={[/letter/every header label/.try]center:\pgfmathprint{int(2^(\letter@Columns-\letter@Power))}}] {};
        \foreach \letter@Row[count=\c@prevRow from 0, count=\c@Row] in \letter@Rows {%
          \foreach \letter@Digit[count=\c@Col] in \letter@Digits{
            \ifnum\c@Col=1\tikzset{/letter/@int/first node/.tikz={below=of ch\c@prevRow-begin}}\fi
            \node[on chain=ch\c@Row,/letter/@int/first node/.try,/letter/every cell node/.try, /letter/every \letter@Digit\space node/.try] {};
          \node[/letter/data column node/.try, right=\pgfkeysvalueof{/letter/column width} of ch\c@Row-end] (letter@datacolumn) {\letter@Row};
        \node[anchor=base east, /letter/head node/.try] at ([email protected]|[email protected]) {Data};

        \node[below=\pgfkeysvalueof{/letter/row height} of letter@datacolumn, /letter/data column node/.try] (letter@ascii) {#3};
        \node[mid left=of letter@ascii] {ASCII Code:};
        \node[below=of letter@ascii, /letter/data column node/.try] (letter@screen) {#4};
        \node[mid left=of letter@screen] {Screen Code:};

        \node[anchor=base west, /letter/symbol node/.try] at ([email protected]|[email protected] west) {#2};

  every letter picture/.append tikz={node distance=+3pt},
  /tikz/nodes={minimum width=\pgfkeysvalueof{/letter/column width}-3pt,
        minimum height=\pgfkeysvalueof{/letter/row height}-3pt},
  every cell node/.append tikz={shape=circle,draw=none},
  column width/.initial=+.5cm,
  row height/.initial=+.5cm}



enter image description here enter image description here enter image description here

enter image description here enter image description here enter image description here

  • Really nice. Exactly what i was looking for. I'm not familiar enough with TikZ to know exactly what this is doing, but it appears that it's actually calculating which cells are filled from the data? Aug 7, 2013 at 20:50
  • I got this to work, but I noticed that each character grid takes up an entire page. I didn't notice any errors when compiling, but was wondering if this is the expected behaviour or something that I've done wrong. Is it possible to arrange each character grid onto a page in a (for example) 8 x 10 grid whilst maintaining the headings I've used for my template? Aug 9, 2013 at 12:12
  • 1
    @KevinP.Kilburn That is the work of the standalone class, you usually don’t use that class for your real document (or only to include PDFs created by it). With a class like article you get your usual TikZ picture which can be placed as everything else. If you replace the \tikzpicture with \scope (and the same for \endtikzpicture) you can use \letterChart inside a TikZ picture (for example a \matrix). Aug 9, 2013 at 16:07

As suggested by Ethan Bolker, I would export them directly from Excel as a pdf. Place all the pdf files in a single folder. Then you can use the following loop to crop all the pdfs:

for img in *.pdf
    convert -quality 100 -crop 300x100+20+50 "$img" "new_$img"
    echo $img

where: 300 is the width, 100 is the height, 20 is the cropped portion on x axis, 50 is the cropped portion on y axis.

--> (20,50) is the top left corner of your image.

If you have problems with the scale, you can add -scale 100% to the command.

Note: for this loop to be useful, all the characters you are going to export must be the same size.

  • 1
    Why wouldn't you just use pdfcrop (pdfcrop.sourceforge.net)?
    – rainer
    Aug 7, 2013 at 7:06
  • I guess pdfcrop should work as well. I do not know the exact syntax though...
    – Nicolas
    Aug 7, 2013 at 15:25
  • 1
    Why would the PDF files need to be cropped? Are the values here only for illustrative purposes? Aug 7, 2013 at 20:54
  • 1
    @KevinP.Kilburn: The values given for the cropping are indeed for illustrative purposes, as well as the values given for the repositioning of the new image. The files are cropped in the case where the entire page is exported from Excel as a pdf.
    – Nicolas
    Aug 7, 2013 at 21:26
  • 1
    @KevinP.Kilburn Exactly, so when you are done exporting all the images, you can crop them with the above routine with the right values (width, height and position of the top left corner)
    – Nicolas
    Aug 9, 2013 at 14:04

An attempt only with LaTeX from the scratch:


\multicolumn{9}{l}{Bit values of Pixels} &
\multicolumn{1}{c}{\begin{sideways}\small 128\end{sideways}} & 
\multicolumn{1}{c}{\begin{sideways}\small 64\end{sideways}} & 
\multicolumn{1}{c}{\begin{sideways}\small 32\end{sideways}} & 
\multicolumn{1}{c}{\begin{sideways}\small 16\end{sideways}} & 
\multicolumn{1}{c}{\begin{sideways}\small 8\end{sideways}} & 
\multicolumn{1}{c}{\begin{sideways}\small 4\end{sideways}} & 
\multicolumn{1}{c}{\begin{sideways}\small 2\end{sideways}} & 
\multicolumn{1}{c}{\begin{sideways}\small 1\end{sideways}} & 
\CR &    &    & \X & \X &    &    &  &  & 24\\
\CR &    & \X & \X & \X & \X &    &  &  & 60\\
\CR & \X & \X &    &    & \X & \X &  &  & 102\\
\CR & \X & \X &    &    & \X & \X &  &  & 102\\
\CR & \X & \X & \X & \X & \X & \X &  &  & 126\\
\CR & \X & \X &    &    & \X & \X &  &  & 102\\
\CR & \X & \X &    &    & \X & \X &  &  & 102\\
\CR &    &    &    &    &    &    &  &  & 0\\

\multicolumn{1}{c}{} & \multicolumn{1}{c}{} & \multicolumn{1}{c}{} & \multicolumn{1}{c}{} & \multicolumn{1}{c}{} & \multicolumn{1}{c}{} & \multicolumn{1}{c}{} & \multicolumn{1}{>{\centering}p{1cm}}{} & \multicolumn{1}{c}{} & \multicolumn{1}{c}{}\\
\cline{1-1} \cline{10-10} 
A & \multicolumn{8}{r|}{ASCII Code:} & 64\\
\cline{1-1} \cline{10-10} 
\multicolumn{1}{c}{} & \multicolumn{8}{r|}{Screen Code:} & \\

You must log in to answer this question.

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