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.
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!
The Hollerith cards I remember looked more like
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}
Answered by user227987 on July 23, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP