As one of the less popular languages, it's difficult to find literature on the avant garde of postscript hackery. So what discoveries have the golfers here made to exploit the stack model (or other features) to overcome Postscript's inherent verbosity?
A Postscript program has a unique(?) ability to read it's own program text as data. This is normally used by the
A simple PS interpreter in PS:
Binary Operator String Decoder
Since I can't seem to get raw binary tokens to work for me (see other answer), I've made use of the "embedded decoding" idea to exploit the binary token mechanism to pack code into 8-bit strings, and then manipulate and parse the commands from the string on the fly.
More compactly, these procedures look like this:
So, 55 chars buys binary token strings. Or, for 6 (maybe 7, if you terminate it with a space) chars, you can load the G library with
Further illustrated in my crossword puzzle answer.
When generating graphical output and console output does not matter, use
Replace hexstrings with ASCII85
Probably old news, but I just learned it. :)
You can do it using the postscript interpreter interactively with an encoding filter and cut-and-paste. But I'm going to show how to use
So, here's a hex string. We split it into 4-byte chunks.
Firing up dc, we input these as 32-bit (unsigned) big-endian-byte-order numbers. Then mod-off base-85 digits (there should be 5 until you get to 0).
0> dc 16i 95206ED8 Ai d85%n85/ 82 d85%n85/ 83 d85%n85/ 82 d85%n85/ 78 d85%n85/ 47 d85%n85/ 0
Padding the last chunk with
Add 33 to shift into the printable range of ASCII and poof! ASCII85.
Wrap it in
Here's a quickie: wrap multiple definitions in
So remember: more than
While most postscript operators are syntactically identifiers (and therefore must be space- (or otherwise-) delimited), the names
In order to redefine these names, which cannot be mentioned by name, we can use strings which are implicitly converted to names when used as keys in a dictionary (convenient!).
This example illustrates abusing these operators to perform arithmetic.
Factor-out repeated uses of long operator names
If you're already using a
Setting this formula equal to 0 gives the equation of the break-even point. From this we can solve for each variable in terms of the other, yielding
No we can answer questions like, "For how many uses of 'print' is it worthwhile to abbreviate?" n = 5, so N = 9/4. Take the ceiling, since you can't effectively call print 1/4 times. So, 3. 3 uses. And indeed,
(assuming you've already paid the overhead of
Of course, binary tokens makes this kind of moot, giving you the first 255 names from the system name table as 2-bytes: 0x92, 0x??. And binary tokens are also self-delimiting, requiring no whitespace before or after, since the high-bit of the first byte is outside of the ascii range.
For the ultimate zip-up of a PostScript program that final frontier is binary tokens which allows you to remove long operator names completely, at the cost of no longer having an ASCII-clean program.
So starting with a compacted block of postscript code
We look up all the names in the back of the PLRM (Appendix F, pp. 795-797)
And then type them in prefixed by a
Then in vim, the condensed file can be typed directly, so:
... you have to enter a space here to terminate the
... have to enter a space here to terminate the
... 3rd digit of 3-digit code terminates the byte-entry so the following
Which will look like this on screen (in vim):
This one can often be omitted entirely if the aim is just to show a picture. Ghostscript paints most things to the screen without needing
[This actually isn't working. Ghostscript's giving me
Change negative rolls to positive
Negative rolls can always be changed to positive rolls.
Use my G library
It's a text file. No extension, for the shortest possible syntax to load it.
It permits this 203-char Sierpinksi Triangle program
to be rewritten in 151 bytes as
Using the abbreviated system names feature,
Use the PLRM Appendix F for the standard table of operator names.
And the feature of Operator Strings is available even if the abbreviated names is not selected. The bare library has a "base-level" selected by adding simply
The base level includes a new function
The new function
A new function
A new function
Two new functions