TransWikia.com

Drawing an old punched card using tikz

TeX - LaTeX Asked by Cristian Koliver on July 23, 2021

I am trying to draw a punch card using tikz. The card is a 8 x 80 matrix. A card "stores" a sentence (e.g. a line from a program’s source code) printed in the card header via an encoding scheme (e.g., ASCII).
Each column represents a sentence char by its binary code: column 0 represents 1st char, column 1 the 2nd and so on. Obviously, a sentence cannot be longer than 80 characters. A hole in a row represents that the corresponding code bit is 1; a "non-hole" represents 0. For example, if the 11th position char is ‘A’ (65 or 01000001 in binary), in column 10 a hole in row 0 and row 6.

Using the binhex library nbinary macro, I can get the 1’s and 0’s string corresponding to a decimal number; with the StrChar macro from the xstring package, I can get these "bits", but from left to right, which makes the holes appear in the wrong positions of the card (for example, in the case of ‘A’, the hole appears on line 7 and 5).

My other problem is that I can’t get position by position of the sentence (the printed character is the same for all columns).

Above, a partial view with the first 4 columns of what I want to get.
Partial view of the punshed card

My code:

documentclass[16pt,a4paper, openright,twoside, fleqn]{book}
usepackage{tikz}
usetikzlibrary{arrows, arrows.meta, backgrounds,calc, chains, calligraphy,  decorations.pathreplacing, decorations.markings, external, fit,positioning, scopes, ,shapes.arrows, shapes.multipart, shapes.symbols, shapes.geometric, shapes.callouts, shadows, shadows.blur, tikzmark}
usepackage{xstring}
usepackage{ifthen}
usepackage{stix}

begin{document}
input binhex   
defword{nbinary{8}{0}} % Fixed ASCII
       
   
begin{tikzpicture}[scale=.4, transform shape]  
   node[rectangle, draw, rounded corners=1ex, fit={(-1,1) (37, -11)}, line width = 0.4mm, ] (card) {};
   node[text centered, below right = 3mm and 1cm of card.north west] {{huge texttt{IF WS-NUM1 IS GREATER THAN OR EQUAL TO WS-NUM2 THEN}}};
   foreach x  [count = yi] in {0, ..., 79} {
       node[text centered] at (x*.45,-11) {x};
   }
   
   foreach x  [count = xi] in {0, 1, 2, ..., 79}{   
       foreach k  [count = ki] in {1, ..., 8}{  
           StrChar{word}{k}[bit]
           ifthenelse{equal{bit}{1}}{
               node[text centered, minimum size=2mm, text width=2mm] at (x*.45,k *-1.2) {{huge $talloblong$}}; 
           }
           {
               node[text centered, minimum size=2mm, text width=2mm] at (x*.45,k *-1.2) {numbernumexpr 1-k relax};
           }
       }
   }
end{tikzpicture}       
end{document}

Thanks in advance!

2 Answers

The Hollerith cards I remember looked more like

hollerith

The text was printed above the holes, and the coding was probably EBCDIC (at least with IBM card punchers). I think the ninth row was a parity bit.

Answered by John Kormylo on July 23, 2021

Here is some function that converts a binary in a list and prepends enough zeros so that the list has a fixed length. You can then loop over this list to draw the column entries. I just used random binaries for the test. I am not old enough to know how the punch cards really looked.

documentclass[tikz,border=3mm]{standalone}
usetikzlibrary{fit,positioning}
makeatletter
pgfmathdeclarefunction{Split}{2}{%
  begingroup%
    pgfmath@count0%
    expandafterpgfmath@split@i#1pgfmath@token@stop
    pgfutil@loop
        ifnumpgfmath@count<#2relax
          advancepgfmath@count by1relax 
          edefpgfmathresult{0,pgfmathresult}%   
    pgfutil@repeat
    pgfmathsmugglepgfmathresult%
  endgroup}
defpgfmath@split@i#1{%
    ifxpgfmath@token@stop#1%
    else
      ifnumpgfmath@count=0relax
        edefpgfmathresult{#1}%
      else
        edefpgfmathresult{pgfmathresult,#1}%
      fi
      advancepgfmath@count by1%
      expandafterpgfmath@split@i
    fi}  
makeatother
begin{document}
begin{tikzpicture}[scale=.4, transform shape]  
   node[rectangle, draw, rounded corners=1ex, fit={(-1,1) (37, -11)}, line width = 0.4mm, ] (card) {};
   node[text centered, below right = 3mm and 1cm of card.north west,
    font=hugettfamily] 
    {IF WS-NUM1 IS GREATER THAN OR EQUAL TO WS-NUM2 THEN};
   foreach x  [count = yi] in {0, ..., 79} {
       node[text centered] at (x*.45,-11) {x};
   }
   
   foreach x  [count = xi] in {0, 1, 2, ..., 79}{  
       % generate a random integer between 0 and 255
       pgfmathtruncatemacro{myrnd}{random(256)-1}
       % convert it to a binary
       pgfmathtruncatemacro{myword}{bin(myrnd)}
       % convert the binary to a list and prepend zeros till it has 8 entries
       pgfmathsetmacro{mysplitword}{Split("myword",8)}  
       foreach k  [count = ki] in mysplitword {  
           ifnumk=1
             path (x*.45,-1.2*ki) 
             node[text height=1.1em,draw,inner sep=0pt,minimum width={width("0")}] {}; 
           else
              path (x*.45,-1.2*ki) 
              node (tmp)[text height=1.1em,inner sep=0pt] {ki}
              (tikzlastnode.north west) edge (tikzlastnode.north east);
           fi            
       }
   }
end{tikzpicture}       
end{document}

enter image description here

Answered by user227987 on July 23, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP