-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add default.nix which can produce ps and pdf files #52
base: master
Are you sure you want to change the base?
Changes from all commits
7298bb2
91ad915
94e1cea
4074e0c
441f7bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
|
||
.PHONY: clean check-nix check-git | ||
.DEFAULT_GOAL = all | ||
|
||
GIT_COMMIT = $(shell git rev-parse HEAD) | ||
SOURCES = include/*.inc | ||
|
||
all: check-nix check-git ${SOURCES} | ||
@echo "Starting build with git commit ID: ${GIT_COMMIT}" | ||
nix-build --argstr ref ${GIT_COMMIT} | ||
|
||
clean: | ||
rm result || true | ||
|
||
check-git: | ||
@command -v git > /dev/null 2>&1 || (echo "Must have git installed on your system." && exit 1) | ||
@git rev-parse HEAD >/dev/null 2>&1 || (echo "Must be running inside of a git repository." && exit 1) | ||
|
||
check-nix: | ||
@command -v nix-build > /dev/null 2>&1 || (echo "Must have Nix installed on your system." && exit 1) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,251 @@ | ||
{ pkgs ? import <nixpkgs> { } | ||
, stdenv ? pkgs.stdenv | ||
, lib ? pkgs.lib | ||
, ghostscript ? pkgs.ghostscript | ||
, ref ? null | ||
, doPdfGeneration ? true | ||
# Attempts to render every page individually to make sure the dependencies | ||
# are set correctly. | ||
, doCheck ? true | ||
# Checks whether the generated output matches the checked-in SSS32.ps. | ||
# When doing development you may want to shut this off to obtain the | ||
# output file that you need to check in. | ||
# | ||
# Has no effect if doChecks is not set. | ||
, doOutputDiff ? true | ||
}: | ||
|
||
let | ||
src = | ||
if isNull ref | ||
then lib.sourceFilesBySuffices ./. [ ".ps" ".inc" ] | ||
else | ||
fetchGit { | ||
url = ./.; | ||
inherit ref; | ||
}; | ||
shortId = lib.optionalString (! isNull ref) ("-" + builtins.substring 0 8 src.rev); | ||
|
||
setup = rec { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. probably best to remove There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can remove it for now, but it will be used -- this |
||
# Will be broken into multiple sub-files in a later PR. | ||
fullSetup = { | ||
content = builtins.readFile "${src}/include/setup.ps.inc"; | ||
dependencies = [ ]; | ||
}; | ||
}; | ||
# Dependencies that every page has | ||
standardDependencies = [ setup.fullSetup ]; | ||
|
||
allPages = { | ||
title = { | ||
sourceHeader = "Title Page"; | ||
content = builtins.readFile "${src}/include/title.ps.inc"; | ||
dependencies = [ ]; | ||
skipPageNumber = true; | ||
}; | ||
license = { | ||
sourceHeader = "License Information"; | ||
content = builtins.readFile "${src}/include/license.ps.inc"; | ||
dependencies = [ ]; | ||
skipPageNumber = true; | ||
}; | ||
reference = { | ||
sourceHeader = "Reference Sheet"; | ||
content = builtins.readFile "${src}/include/reference.ps.inc"; | ||
dependencies = [ ]; | ||
drawFooter = true; | ||
}; | ||
principalTables = { | ||
sourceHeader = "Arithmetic Tables"; | ||
content = builtins.readFile "${src}/include/principal-tables.ps.inc"; | ||
dependencies = [ ]; | ||
}; | ||
|
||
additionBottom = { | ||
content = "{xor} (Addition) code dup perm drawBottomWheelPage\n"; | ||
dependencies = [ ]; | ||
}; | ||
additionTop = { | ||
content = "showTopWheelPage\n"; | ||
dependencies = [ ]; | ||
}; | ||
recovery = { | ||
content = builtins.readFile "${src}/include/volvelle-recovery.ps.inc"; | ||
dependencies = [ ]; | ||
}; | ||
fusionInner = { | ||
content = builtins.readFile "${src}/include/volvelle-fusion-1.ps.inc"; | ||
dependencies = [ ]; | ||
}; | ||
fusionOuter = { | ||
content = builtins.readFile "${src}/include/volvelle-fusion-2.ps.inc"; | ||
dependencies = [ ]; | ||
}; | ||
|
||
generationInstructions = { | ||
content = builtins.readFile "${src}/include/page7.ps.inc"; | ||
dependencies = [ ]; | ||
}; | ||
|
||
checksumTable1 = { | ||
content = builtins.readFile "${src}/include/checksum-table-1.ps.inc"; | ||
isLandscape = true; | ||
dependencies = [ ]; | ||
drawFooter = true; | ||
}; | ||
checksumTable2 = { | ||
content = builtins.readFile "${src}/include/checksum-table-2.ps.inc"; | ||
dependencies = [ ]; | ||
isLandscape = true; | ||
drawFooter = true; | ||
}; | ||
checksumWorksheet = { | ||
content = builtins.readFile "${src}/include/checksum-worksheet.ps.inc"; | ||
dependencies = [ ]; | ||
isLandscape = true; | ||
drawFooter = true; | ||
}; | ||
|
||
shareTable = a: b: c: d: { | ||
content = "${toString a} ${toString b} ${toString c} ${toString d} showShareTablePage\n"; | ||
dependencies = [ ]; | ||
drawFooter = true; | ||
}; | ||
}; | ||
|
||
fullBooklet = { | ||
name = "SSS32.ps"; | ||
pages = with allPages; [ | ||
title | ||
license | ||
reference | ||
principalTables | ||
additionBottom | ||
additionTop | ||
generationInstructions | ||
(shareTable 29 24 13 25) | ||
(shareTable 9 8 23 18) | ||
(shareTable 22 31 27 19) | ||
(shareTable 1 0 3 16) | ||
(shareTable 11 28 12 14) | ||
(shareTable 6 4 2 15) | ||
(shareTable 10 17 21 20) | ||
(shareTable 26 30 7 5) | ||
recovery | ||
fusionInner | ||
fusionOuter | ||
checksumTable1 | ||
checksumTable2 | ||
checksumWorksheet | ||
]; | ||
}; | ||
|
||
dependencyContentRecur = content: builtins.concatMap | ||
(item: (dependencyContentRecur item.dependencies) ++ [ item.content ]) | ||
content; | ||
dependencyContent = pages: lib.lists.unique ( | ||
(map (dep: dep.content) standardDependencies) ++ | ||
(builtins.concatMap (page: dependencyContentRecur page.dependencies) pages) | ||
); | ||
|
||
renderBooklet = booklet: | ||
let | ||
addPage = content: pageData: { | ||
content = content.content + lib.optionalString (pageData ? sourceHeader) '' | ||
%**************************************************************** | ||
%* | ||
%* ${pageData.sourceHeader} | ||
%* | ||
%**************************************************************** | ||
'' + '' | ||
%%Page: ${toString content.nextPgIdx} ${toString content.nextPgIdx} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps this is for a follow up PR, but if you want to get fancy with page numbering then you need to update this line. This isn't just a pair of page numbers repeated for no reason. You'll have to look up the spec, but it is something like one is the literal sequence number and the other is the displayed page number. This makes a difference for assembling a sidebar of contents on your PS viewer. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @roconnor-blockstream yep, I'll address that in a future PR. Unfortunately |
||
${lib.optionalString (pageData ? isLandscape) "%%PageOrientation: Landscape\n"} | ||
%%BeginPageSetup | ||
/pgsave save def | ||
%%EndPageSetup | ||
${if pageData ? isLandscape then "landscapePage" else "portraitPage"} begin | ||
${lib.optionalString (pageData ? drawFooter) "${toString content.nextFooterIdx} drawFooter"} | ||
${pageData.content} | ||
end | ||
pgsave restore | ||
showpage | ||
''; | ||
nextFooterIdx = content.nextFooterIdx + (if pageData ? drawFooter then 1 else 0); | ||
nextPgIdx = content.nextPgIdx + 1; | ||
}; | ||
initialContent = { | ||
content = '' | ||
%!PS-Adobe-3.0 | ||
%%Orientation: Portrait | ||
%%Pages: ${toString (builtins.length booklet.pages)} | ||
%%EndComments | ||
%%BeginSetup | ||
${toString (dependencyContent (booklet.pages))}%%EndSetup | ||
|
||
%************************************************************************ | ||
%************************************************************************ | ||
%* | ||
%* Section Three: Page Rendering | ||
%* | ||
%************************************************************************ | ||
%************************************************************************ | ||
|
||
''; | ||
nextPgIdx = 1; | ||
nextFooterIdx = 1; | ||
}; | ||
finalContent = builtins.foldl' addPage initialContent booklet.pages; | ||
in | ||
pkgs.writeTextFile { | ||
name = booklet.name; | ||
text = finalContent.content + '' | ||
%%EOF | ||
''; | ||
}; | ||
checkSinglePage = page: renderBooklet { | ||
name = "test-single-page.ps"; | ||
pages = [ page ]; | ||
}; | ||
in | ||
stdenv.mkDerivation { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not just put renderBooklet as the derivation result? Wouldn't that make it easier to check the result into git? We can do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because I eventually want to produce more than one output -- the full booklet, but also postscript files with individual worksheets, 256-bit vesrions of the worksheets, etc. And maybe a illustrated version alongside the regular version. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On further reflection, and having learned Nix better, let me explore making this derivation have multiple outputs, where the default is the fully-assembled SSS32.ps. I'm unsure if this is the right way to go still, because there are e.g. flags we want to be able to set about PDF vs PS, color vs non-color etc, and it might still be the cleanest thing to output a directory with a bunch of different files. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My experiments with git and symlinks was a failure. While we could support multiple outputs, I do not think that it worth worrying about. At least not at this time. |
||
name = "codex32${shortId}"; | ||
|
||
nativeBuildInputs = if doPdfGeneration then [ ghostscript ] else [ ]; | ||
|
||
phases = [ "buildPhase" ] ++ lib.optionals doCheck [ "checkPhase" ]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately the You should change the phases line to:
and let |
||
|
||
buildPhase = '' | ||
set -e | ||
|
||
FULL_BW="${renderBooklet fullBooklet}" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The way nix derivations work is that, more or less, every value in the derivation becomes an environment variable. Therefore, it would make more sense for you to define |
||
|
||
# Copy output Postscript into place | ||
mkdir "$out" | ||
cd "$out" | ||
cp "$FULL_BW" SSS32.ps | ||
# Patch to include version | ||
sed -i 's/(revision \(.*\))/(revision \1${shortId})/' ./SSS32.ps | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This probably needs to be more robust, but it is fine for now. |
||
# Produce PDF, if requested. | ||
${lib.optionalString doPdfGeneration "ps2pdf -dPDFSETTINGS=/prepress SSS32.ps"} | ||
''; | ||
|
||
checkPhase = toString | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately the check fails when it is actually enabled, at least in part because you try to run |
||
(map | ||
(page: "ghostscriptTest ${checkSinglePage page}") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is another issue with this design. Because Alternatively you could replace |
||
fullBooklet.pages | ||
) + '' | ||
ghostscriptTest() { | ||
echo "Ghostscript testing $1" | ||
local output; | ||
if ! output="$(gs -dNOPAUSE -dNODISPLAY "$1" < /dev/null 2>&1)"; then | ||
echo "Failed to run ghostscript on $1" | ||
echo "$output" | ||
exit 1 | ||
fi | ||
} | ||
|
||
ghostscriptTest "$FULL_BW" | ||
${lib.optionalString doOutputDiff "diff -C 5 ${src}/SSS32.ps SSS32.ps"} | ||
''; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/Helvetica-Bold findfont 10 scalefont setfont | ||
pageW 2 div pageH 48 sub moveto (MS32 Checksum Table) centreshow | ||
|
||
/Courier findfont 8.5 scalefont setfont | ||
36 pageH 64 sub % x y | ||
pageW 64 sub pageH 148 sub 2 div % w h | ||
0 drawChecksumTable | ||
|
||
36 pageH 2 div 16 sub % x y | ||
pageW 64 sub pageH 148 sub 2 div % w h | ||
8 drawChecksumTable |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/Helvetica-Bold findfont 10 scalefont setfont | ||
pageW 2 div pageH 48 sub moveto (MS32 Checksum Table) centreshow | ||
|
||
/Courier findfont 8.5 scalefont setfont | ||
36 pageH 64 sub % x y | ||
pageW 64 sub pageH 148 sub 2 div % w h | ||
16 drawChecksumTable | ||
|
||
36 pageH 2 div 16 sub % x y | ||
pageW 64 sub pageH 148 sub 2 div % w h | ||
24 drawChecksumTable |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/Helvetica-Bold findfont 10 scalefont setfont | ||
pgsize aload pop exch pop 2 div 700 | ||
moveto (ms32 Checksum Worksheet) centreshow | ||
|
||
gsave | ||
50 560 translate | ||
ladder begin | ||
drawgrid | ||
% (2NAMES5GS8YDXGMLUW34LEN0PRDAK9GLF307N04SN6SKL) fillgrid | ||
% (2NAMES5GS8YDXGMLUW34LEN0PRDAK9GL ) fillgrid | ||
end | ||
grestore | ||
|
||
100 320 moveto | ||
/Helvetica-Bold findfont 10 scalefont setfont | ||
(Verifying Checksums) show | ||
100 300 moveto | ||
/Helvetica findfont 9 scalefont setfont | ||
(Write out the 45 character data portion in the) show | ||
100 290 moveto | ||
(bold boxes, two at a time, starting on the top) show | ||
100 280 moveto | ||
(row. Working from the top row down, look up) show | ||
100 270 moveto | ||
(the first two characters of each odd row in the) show | ||
100 260 moveto | ||
(ms32 Checksum Table and write the ) polymodulus length 10 string cvs concatstrings show | ||
100 250 moveto | ||
(character word into the even row below it. Fill) show | ||
100 240 moveto | ||
(in the odd rows by adding the two characters) show | ||
100 230 moveto | ||
(above each cell. You may use either the) show | ||
100 220 moveto | ||
(addition wheel table. The first few boxes are) show | ||
100 210 moveto | ||
(already filled in for you. The last row will sum) show | ||
100 200 moveto | ||
(to ) show checksumstring {glyphshow} forall ( if the checksum is valid.) show | ||
100 160 moveto | ||
/Helvetica-Bold findfont 10 scalefont setfont | ||
(Creating Checksums) show | ||
100 140 moveto | ||
/Helvetica findfont 9 scalefont setfont | ||
(Follow the "Verifying Checksums" instructions) show | ||
100 130 moveto | ||
(to fill in everything but the shaded cells. To fill in) show | ||
100 120 moveto | ||
(the shaded cells, write ) show checksumstring {glyphshow} forall ( into the bottom) show | ||
100 110 moveto | ||
(row. Working from the bottom up, fill in the) show | ||
100 100 moveto | ||
(shaded cells by adding the two characters below) show | ||
100 90 moveto | ||
(each cell. The ) polymodulus length 10 string cvs ( characters in the bold shaded) concatstrings concatstrings show | ||
100 80 moveto | ||
(boxes will be the checksum.) show | ||
|
||
/offsety 550 def | ||
/offsetx 450 def | ||
/Courier findfont 10 scalefont setfont | ||
20 offsetx add offsety moveto (Addition Table) show | ||
/Courier-Bold findfont 8 scalefont setfont | ||
0 1 31 { | ||
dup 2 add 7 mul offsetx add offsety 10 sub moveto | ||
perm exch get | ||
code exch get glyphshow | ||
} for | ||
|
||
0 1 31 { | ||
/Courier-Bold findfont 8 scalefont setfont | ||
offsetx 34.5 7 mul add offsety 20 sub 2 index 8 mul sub moveto | ||
dup code exch perm exch get get glyphshow | ||
/Courier findfont 8 scalefont setfont | ||
dup 1 31 { | ||
dup 2 add 7 mul offsetx add offsety 20 sub 3 index 8 mul sub moveto | ||
perm exch get | ||
perm 2 index get gf32add code exch get glyphshow | ||
} for pop } for |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/Helvetica findfont 6 scalefont setfont | ||
marginX1 marginY1 16 sub moveto | ||
MIT {gsave ((c)) search {show pop /copyright glyphshow} if show grestore 0 -8 rmoveto} forall | ||
/Helvetica findfont 6 scalefont setfont | ||
warning {gsave show grestore 0 -7 rmoveto} forall | ||
0 -16 rmoveto | ||
/Helvetica findfont 8 scalefont setfont | ||
README {gsave show grestore 0 -10 rmoveto} forall |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After reviewing https://nix.dev/manual/nix/2.22/language/builtins#builtins-fetchGit I'm pretty sure you want
rev
instead ofref
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Empirically
rev
seems to want a 40-character hash, whileref
will accept short hashes, branch names, etc.