Skip to content

Commit d6cf782

Browse files
committed
nix: generate postscript file from include files
Generates the committed postscript and runs diff to make sure that the reconstruction was faithful. Currently this simply reproduces the existing code, though it autogenerates the numbers to make it easier to rearrange things and/or add blank pages. Later PRs will abstract out the setup code, improve best practices (e.g. wrapping every page in "10 dict ... end") and add additional targets which produce e.g. individual worksheets in their own postscript. We will also use the Nix mechanism to add illustrations, rather than using PHP.
1 parent 4e05e6e commit d6cf782

14 files changed

+2531
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
reference/rust-codex32/Cargo.lock
22
reference/rust-codex32/target/
3+
result

default.nix

+222
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
{ pkgs ? import <nixpkgs> { }
2+
, stdenv ? pkgs.stdenv
3+
, lib ? pkgs.lib
4+
, ghostscript ? pkgs.ghostscript
5+
, ref ? null
6+
, doPdfGeneration ? true
7+
# Checks whether the generated output matches the checked-in SSS32.ps.
8+
# When doing development you may want to shut this off to obtain the
9+
# output file that you need to check in.
10+
, doOutputDiff ? true
11+
}:
12+
13+
let
14+
src =
15+
if isNull ref
16+
then lib.sourceFilesBySuffices ./. [ ".ps" ".inc" ]
17+
else
18+
fetchGit {
19+
url = ./.;
20+
inherit ref;
21+
};
22+
shortId = lib.optionalString (! isNull ref) ("-" + builtins.substring 0 8 src.rev);
23+
24+
25+
setup = rec {
26+
# Will be broken into multiple sub-files in a later PR.
27+
fullSetup = {
28+
content = builtins.readFile "${src}/include/setup.ps.inc";
29+
dependencies = [ ];
30+
};
31+
};
32+
# Dependencies that every page has
33+
standardDependencies = [ setup.fullSetup ];
34+
35+
allPages = {
36+
title = {
37+
sourceHeader = "Title Page";
38+
content = builtins.readFile "${src}/include/title.ps.inc";
39+
dependencies = [ ];
40+
};
41+
license = {
42+
sourceHeader = "License Information";
43+
drawPageContent = true;
44+
content = builtins.readFile "${src}/include/license.ps.inc";
45+
dependencies = [ ];
46+
};
47+
reference = {
48+
sourceHeader = "Reference Sheet";
49+
drawPageContent = true;
50+
content = builtins.readFile "${src}/include/reference.ps.inc";
51+
dependencies = [ ];
52+
};
53+
principalTables = {
54+
sourceHeader = "Arithmetic Tables";
55+
content = builtins.readFile "${src}/include/principal-tables.ps.inc";
56+
dependencies = [ ];
57+
};
58+
59+
additionBottom = {
60+
content = "{xor} (Addition) code dup perm drawBottomWheelPage\n";
61+
dependencies = [ ];
62+
};
63+
additionTop = {
64+
content = "showTopWheelPage\n";
65+
dependencies = [ ];
66+
};
67+
recovery = {
68+
content = builtins.readFile "${src}/include/volvelle-recovery.ps.inc";
69+
dependencies = [ ];
70+
};
71+
fusionInner = {
72+
content = builtins.readFile "${src}/include/volvelle-fusion-1.ps.inc";
73+
dependencies = [ ];
74+
};
75+
fusionOuter = {
76+
content = builtins.readFile "${src}/include/volvelle-fusion-2.ps.inc";
77+
dependencies = [ ];
78+
};
79+
80+
generationInstructions = {
81+
content = builtins.readFile "${src}/include/page7.ps.inc";
82+
dependencies = [ ];
83+
};
84+
85+
checksumTable1 = {
86+
content = builtins.readFile "${src}/include/checksum-table-1.ps.inc";
87+
isLandscape = true;
88+
dependencies = [ ];
89+
};
90+
checksumTable2 = {
91+
content = builtins.readFile "${src}/include/checksum-table-2.ps.inc";
92+
isLandscape = true;
93+
dependencies = [ ];
94+
};
95+
checksumWorksheet = {
96+
content = builtins.readFile "${src}/include/checksum-worksheet.ps.inc";
97+
isLandscape = true;
98+
dependencies = [ ];
99+
};
100+
101+
shareTable = a: b: c: d: {
102+
content = "${toString a} ${toString b} ${toString c} ${toString d} showShareTablePage\n";
103+
dependencies = [ ];
104+
};
105+
};
106+
107+
fullBooklet = {
108+
name = "SSS32.ps";
109+
pages = with allPages; [
110+
title
111+
license
112+
reference
113+
principalTables
114+
additionBottom
115+
additionTop
116+
generationInstructions
117+
(shareTable 29 24 13 25)
118+
(shareTable 9 8 23 18)
119+
(shareTable 22 31 27 19)
120+
(shareTable 1 0 3 16)
121+
(shareTable 11 28 12 14)
122+
(shareTable 6 4 2 15)
123+
(shareTable 10 17 21 20)
124+
(shareTable 26 30 7 5)
125+
recovery
126+
fusionInner
127+
fusionOuter
128+
checksumTable1
129+
checksumTable2
130+
checksumWorksheet
131+
];
132+
};
133+
134+
dependencyContentRecur = content: builtins.concatMap
135+
(item: (dependencyContentRecur item.dependencies) ++ [ item.content ])
136+
content;
137+
dependencyContent = pages: lib.lists.unique (
138+
(map (dep: dep.content) standardDependencies) ++
139+
(builtins.concatMap (page: dependencyContentRecur page.dependencies) pages)
140+
);
141+
142+
renderBooklet = booklet:
143+
let
144+
addPage = content: pageData: {
145+
content = content.content + lib.optionalString (pageData ? sourceHeader) ''
146+
%****************************************************************
147+
%*
148+
%* ${pageData.sourceHeader}
149+
%*
150+
%****************************************************************
151+
'' + ''
152+
%%Page: ${toString content.nextPgIdx} ${toString content.nextPgIdx}
153+
${lib.optionalString (pageData ? isLandscape) "%%PageOrientation: Landscape\n"}%%BeginPageSetup
154+
/pgsave save def
155+
%%EndPageSetup
156+
'' + (
157+
if pageData ? drawPageContent
158+
then
159+
if pageData ? isLandscape
160+
then "landscapePage begin ${toString content.nextCtIdx} drawPageContent\n"
161+
else "portraitPage begin ${toString content.nextCtIdx} drawPageContent\n"
162+
else
163+
if pageData ? isLandscape
164+
then "90 rotate\n"
165+
else ""
166+
) + ''
167+
${pageData.content}
168+
${lib.optionalString (pageData ? drawPageContent) "end\n"}pgsave restore
169+
showpage
170+
'';
171+
nextCtIdx = content.nextCtIdx + (if pageData ? drawPageContent then 1 else 0);
172+
nextPgIdx = content.nextPgIdx + 1;
173+
};
174+
initialContent = {
175+
content = ''
176+
%!PS-Adobe-3.0
177+
%%Orientation: Portrait
178+
%%Pages: ${toString (builtins.length booklet.pages)}
179+
%%EndComments
180+
%%BeginSetup
181+
${toString (dependencyContent (booklet.pages))}%%EndSetup
182+
183+
%************************************************************************
184+
%************************************************************************
185+
%*
186+
%* Section Three: Page Rendering
187+
%*
188+
%************************************************************************
189+
%************************************************************************
190+
191+
'';
192+
nextPgIdx = 1;
193+
nextCtIdx = 1;
194+
};
195+
finalContent = builtins.foldl' addPage initialContent booklet.pages;
196+
in
197+
pkgs.writeTextFile {
198+
name = booklet.name;
199+
text = finalContent.content + ''
200+
%%EOF
201+
'';
202+
};
203+
in
204+
stdenv.mkDerivation {
205+
name = "codex32${shortId}";
206+
207+
buildInputs = if doPdfGeneration then [ ghostscript ] else [ ];
208+
209+
phases = [ "buildPhase" ];
210+
buildPhase = ''
211+
set -e
212+
213+
mkdir "$out"
214+
cd "$out"
215+
cp ${renderBooklet fullBooklet} SSS32.ps
216+
217+
${lib.optionalString doOutputDiff "diff -C 5 ${src}/SSS32.ps SSS32.ps"}
218+
sed -i 's/(revision \(.*\))/(revision \1${shortId})/' ./SSS32.ps
219+
${lib.optionalString doPdfGeneration "ps2pdf -dPDFSETTINGS=/prepress SSS32.ps"}
220+
'';
221+
}
222+

include/checksum-table-1.ps.inc

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
10 dict begin
2+
pgsize aload pop
3+
/pageW exch def
4+
/pageH exch def
5+
6+
0 pageH neg translate
7+
8+
/Helvetica-Bold findfont 10 scalefont setfont
9+
pageW 2 div pageH 48 sub moveto (MS32 Checksum Table) centreshow
10+
11+
/Courier findfont 8.5 scalefont setfont
12+
36 pageH 64 sub % x y
13+
pageW 64 sub pageH 144 sub 2 div % w h
14+
0 drawChecksumTable
15+
16+
36 pageH 2 div 16 sub % x y
17+
pageW 64 sub pageH 144 sub 2 div % w h
18+
8 drawChecksumTable
19+
end

include/checksum-table-2.ps.inc

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
10 dict begin
2+
pgsize aload pop
3+
/pageW exch def
4+
/pageH exch def
5+
6+
0 pageH neg translate
7+
8+
/Helvetica-Bold findfont 10 scalefont setfont
9+
pageW 2 div pageH 48 sub moveto (MS32 Checksum Table) centreshow
10+
11+
/Courier findfont 8.5 scalefont setfont
12+
36 pageH 64 sub % x y
13+
pageW 64 sub pageH 144 sub 2 div % w h
14+
16 drawChecksumTable
15+
16+
36 pageH 2 div 16 sub % x y
17+
pageW 64 sub pageH 144 sub 2 div % w h
18+
24 drawChecksumTable
19+
end

include/checksum-worksheet.ps.inc

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
% 0 pgsize aload pop pop neg translate
2+
0 -750 translate
3+
4+
/Helvetica-Bold findfont 10 scalefont setfont
5+
pgsize aload pop exch pop 2 div 700
6+
moveto (ms32 Checksum Worksheet) centreshow
7+
8+
gsave
9+
50 680 translate
10+
ladder begin
11+
drawgrid
12+
% (2NAMES5GS8YDXGMLUW34LEN0PRDAK9GLF307N04SN6SKL) fillgrid
13+
% (2NAMES5GS8YDXGMLUW34LEN0PRDAK9GL ) fillgrid
14+
end
15+
grestore
16+
17+
100 420 moveto
18+
/Helvetica-Bold findfont 10 scalefont setfont
19+
(Verifying Checksums) show
20+
100 400 moveto
21+
/Helvetica findfont 9 scalefont setfont
22+
(Write out the 45 character data portion in the) show
23+
100 390 moveto
24+
(bold boxes, two at a time, starting on the top) show
25+
100 380 moveto
26+
(row. Working from the top row down, look up) show
27+
100 370 moveto
28+
(the first two characters of each odd row in the) show
29+
100 360 moveto
30+
(ms32 Checksum Table and write the ) polymodulus length 10 string cvs concatstrings show
31+
100 350 moveto
32+
(character word into the even row below it. Fill) show
33+
100 340 moveto
34+
(in the odd rows by adding the two characters) show
35+
100 330 moveto
36+
(above each cell. You may use either the) show
37+
100 320 moveto
38+
(addition wheel table. The first few boxes are) show
39+
100 310 moveto
40+
(already filled in for you. The last row will sum) show
41+
100 300 moveto
42+
(to ) show checksumstring {glyphshow} forall ( if the checksum is valid.) show
43+
100 260 moveto
44+
/Helvetica-Bold findfont 10 scalefont setfont
45+
(Creating Checksums) show
46+
100 240 moveto
47+
/Helvetica findfont 9 scalefont setfont
48+
(Follow the "Verifying Checksums" instructions) show
49+
100 230 moveto
50+
(to fill in everything but the shaded cells. To fill in) show
51+
100 220 moveto
52+
(the shaded cells, write ) show checksumstring {glyphshow} forall ( into the bottom) show
53+
100 210 moveto
54+
(row. Working from the bottom up, fill in the) show
55+
100 200 moveto
56+
(shaded cells by adding the two characters below) show
57+
100 190 moveto
58+
(each cell. The ) polymodulus length 10 string cvs ( characters in the bold shaded) concatstrings concatstrings show
59+
100 180 moveto
60+
(boxes will be the checksum.) show
61+
62+
450 650
63+
/offsety exch def
64+
/offsetx exch def
65+
/Courier findfont 10 scalefont setfont
66+
20 offsetx add offsety moveto (Addition Table) show
67+
/Courier-Bold findfont 8 scalefont setfont
68+
0 1 31 {
69+
dup 2 add 7 mul offsetx add offsety 10 sub moveto
70+
perm exch get
71+
code exch get glyphshow
72+
} for
73+
74+
0 1 31 {
75+
/Courier-Bold findfont 8 scalefont setfont
76+
offsetx 34.5 7 mul add offsety 20 sub 2 index 8 mul sub moveto
77+
dup code exch perm exch get get glyphshow
78+
/Courier findfont 8 scalefont setfont
79+
dup 1 31 {
80+
dup 2 add 7 mul offsetx add offsety 20 sub 3 index 8 mul sub moveto
81+
perm exch get
82+
perm 2 index get gf32add code exch get glyphshow
83+
} for pop } for

include/license.ps.inc

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/Helvetica findfont 6 scalefont setfont
2+
marginX1 marginY1 16 sub moveto
3+
MIT {gsave ((c)) search {show pop /copyright glyphshow} if show grestore 0 -8 rmoveto} forall
4+
/Helvetica findfont 6 scalefont setfont
5+
warning {gsave show grestore 0 -7 rmoveto} forall
6+
0 -16 rmoveto
7+
/Helvetica findfont 8 scalefont setfont
8+
README {gsave show grestore 0 -10 rmoveto} forall

0 commit comments

Comments
 (0)