>From gr@ Tue, 2 Apr 2002 17:35:10 -0500 Date: Tue, 2 Apr 2002 17:35:10 -0500 >From: gabriel rosenkoetter gr@ Subject: Other April 1st stuff. --3D7yMlnunRPwJqC7 Content-Type: multipart/mixed; boundary="oplxJGu+Ee5xywIT" Content-Disposition: inline --oplxJGu+Ee5xywIT Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable So, since the Phoenix has gone to digital print with it: http://www.sccs.swarthmore.edu/org/phoenix/2002/2002-03-28/news/printing.php I might as well explain how I made the printers leave out irritating Swarthmore words, and teach the interested a little bit about PostScript in the process. For what it's worth, what happened was not exactly what I wanted. I wanted, rather than to leave words out, to censor words (that is, replace them with a black box the width and height of the words). I know how to do that now ("(string) FontBBox get"), but I couldn't find it in the documentation I had handy Sunday night. Also, it was never my intention to pick specifically on Macintosh computers. In fact, the ITS's statement "only Macintoshes were affected" is wrong. It should be, "only computers printing through the Windows print server were unaffected". This is either because the print server communicates with the printers by way of NetBIOS (or similar) or because it does it's own redefinition of the PostScript's show commands. (I'm not sure.) The point is, any computer that was pointed directly at the printer was affected (so, Unix/Linux machines too, at the least). Also, any mac running software to run through the Windows print server (which is possible) would have not been affected. Note that none of the public area macs presently do this, despite it supposedly being ITS policy that everyone prints through the print server. Go fig. (I'm certain I could have found a way to deal with the print server too, but I put coding this off till Sunday evening, so it ended up being even more of a hack job than it needed to be.) Note that it was possible to remove the settings I made by simply power-cycling the printer, which people gradually noticed over the course of the day. I (well, an accomplice) did issue another PostScript file in the evening to clear off any printers that were plossibly still screwed up. (It just resets the printer's state, so it didn't cause any harm if the printer had already been rebooted.) Now then... how did I make the printers skip words? Simple, I just printed a file. I didn't crack into anyone's computer. I certainly didn't compromise ITS's ghosted image that they'd just installed on all the macs. (That would have been ridiculously more work, far more difficult for them to clean up--though I understand they went down that path anyway, sorry, Mr. Kane--, and I certainly would have done more than play around with your printing.) The main thing to keep in mind is that PostScript is not just a markup language (like TeX, HTML, SGML, so forth), but a full-fledged programming language. It's kind of a weird programming language, but it's fun to play with once you get used to it. It keeps state on a variety of stacks and a couple of state tables. The state tables are mostly for graphics (which is more what most people do with PostScript); the stacks are mostly what we're interested in here. Specifically, we're interested in the dictionary stack and the operator stack. The dictionary stack stores mappings between names and values, and the operator stack stores just values. When an operator is executed, it pulls as many things as it needs to execute off the top of the operator stack (so they'd better be there, and had better be in the right order too). Beyond the stacks, the syntax of the language is quite simple. There are only a few reserved characters. / makes the following token be a name rather than its being evaluated (this is important). Anything enclosed by ()s is a string, anything enclosed by [] is an array, anything enclosed by {}s is a procedure (which is a special kind of array), <>s also do something special, though I forget what, and % is the comment character (making PostScript ignore everything after it on the line, closed by a newline; comments cannot span lines). By convention, %! on the first line of the file is used to designate it as a PostScript file, and some printers may act more intelligently if a the level (by which PostScript means version) of PS being used is stated afterwards. (Something like %!PS-Adobe-2.0, for PostScript level 2.) PS keeps track of a few types of variables. It distinguishes between strings (text enclosed by ()s), booleans, integers, and real numbers. Real numbers can be expressed in decimal form. Both integers and reals (I *think*) can be expressed in (computer-style) scientific notation (that is, 1E10). PS also includes a really cool radix notation... that is, if you say 16#AB, you're saying 171 (16 for hexadecimal). This works for any base. (I don't use it here, but I think it's pretty neat.) So PostScript has very little syntax. But, oh boy, does it have a lot of built-in operators. They are what live on the dictionary stack. In particular, there are four that are interesting: show, ashow, widthshow, and awidthshow. show eats a string from the stack and adds it to the image that will be drawn when the showpage command is issued. The variations do similar things, taking progressively more arguments about spacing. (In the output of, say, Microsoft word documents, pretty much only show and awdithshow is used, the latter for justified text.) Recall that these operators are stored on the dictionary stack. When I call a procedure, that stack is traversed from top to bottom to find the name I have called and execute the associated procedure. So if I would like show to do something other than what PostScript intended, I need only create a new show, and it will get used first. But since I don't want to do the hardwork of drawing fonts on screen, I'd like to keep the old show around. Though I could also have gone to a lot more effort and gotten the justification right for the other varieties of show, I opted to save coding time and just lose justification. There are a few specific PS operators I should describe before I explain how we make words disappear. I'll define operators as , with a - meaning "nothing" for both and . load Looks for name in the dictionary stack and pushes its value (in the case of /show, this will be an operator's array... that is, some commands inside a set of {}s) onto the operator stack. def - Pushes : onto the dictionary stack (so that executing or loading later gets ). n m roll (rearranged) Performs a rotate of m moves on the top n items of the stack. That is, (a) (b) (c) 3 1 roll yields (b) (c) (a) on the stack. Note that m IS allowed to be negative. pop - Removes from the stack (and forgets about it entirely!) So then, to start things out I store the old definition for show as realshow and redifine the show variations so that they all call the name "show" (which I'm about to redefine). /realshow /show load def /ashow { 3 1 roll pop pop show } def /widthshow { 4 1 roll pop pop pop show } def /awdithshow { 6 1 roll pop pop pop show } def The rolls and pops are necessary to get rid of the extraneous sizing information with the show variants want but show does not. (You wouldn't want to leave extraneous stuff on the stack, it'll almost definitely bite you later.) Now we need a way to make a string we'd like to censor go away, which means we need a few more operators: dup Just makes a copy of the top element of the stack. eq true | false Compares the top to elements of the stack. ("How" depends on what kind of things they are. We'll be comparing strings, which works pretty much the way you'd expect it to. Yes, it's case-sensitive.) not Exactly what you'd expect. stringwidth Initially, I thought that this would have better been named stringsize... except that it doesn't seem to work as you might expect. It really does only mean width, it's just that after a rotate, that width may be a vector that requires two values. This does NOT give you the height of the string, which was what kept me from censoring words as I'd hoped. (There's another way to do what I wanted involving font bounding boxes.) rmoveto - Move the drawing point pixels to the right and pixels up relative to the current point. (strings are drawn with their lower left corner at the current point.) So then, we have my function, censor, which presumes it will be called like this:
 censor -

where  is a string that we would like to censor and 
 and
 are strings to be printed each before and after .

/censor {
	realshow
	stringwidth pop 0 rmoveto
	show
}

So we show the part of the string before our censored word (making
sure we use PostScript's real show function; you'll see why we don't
need to recur over this string in a moment), then move the width
of the second string to the right, then pass the part after our
match to whatever's behind the show name.

Finally, and here's the tricky bit, we define a list of words we'd
like to censor (yes, this was a much longer list when I sent it to
the printer, but we're talking about less than a kilobyte here;
certainly far far less than a modern printer's memory) and create a
new definition for show. There are a few more built-in operators
used here:

  exch  
Just swap the top two elements of the stack.

  if -
Executes procedure  if  is true.

 not 
Inverts the value of the boolean. (This can also be used on
integers, in which case its a bitwise 1's complement. That's mostly
handy for graphics stuff.)

  search   
 true |  false
Searches for str2 in str1, and either pushes str1 and the boolean
false back (if it doesn't find str2) or pushes the part of str1
after the match,  (it's an exact match, not a regular expression
match; implementing a regexp version of search would be non-trivial,
though very cool), the part of str1 before the match, and the
boolean true.

[list]  forall -
Pushes each item of list (which can also be a procedure or a single
string--forall on a string does so character-wise) sequentially onto
the stack, performing  after each.

- exit -
Breaks completely out of the innermost-nested loop. (There are other
kinds than foralls.)

/censorwords [(Your) (list) (here.)] def
/show {
	/found false def
	censorwords {
		search { censor /found true def exit } if
	} forall
	found not { realshow } if
} def

So we set a state variable about whether we've already found a match
(so that we don't forget to show the string regularly if it didn't
have any censored words in it), and then we get fancy.

For each of the strings in our list, we search through the input
string... until we find a single match. After that, we hand things
off to censor (which will realshow 
, censor , and
recursively call show on ). If none of our strings was found
anywhere in the input, we just show the input. (Note how the input
string stays on the stack throughout the above; either search puts
it back or we've handed business off to censor. Things like this
make me *really* like programming with stacks. I never have to store
my string in a named variable, that's what the stack is for.)

There you have it. If you want to see it in action, make a
PostScript document however you like (dvips -o foo.ps, or print to a
file out of MS Word), then open the file in a good text editor
(BBEdit should do it on the mac) and insert the defs above
immediately after the %! line and before anything else. Then either
view (gv, ghostview, not sure outside of Unix) or print your file.
(If you do this on a Unix machine, please use lpr. lp will interpret
your file as a text file rather than a postscript file, which will
make for a lot of wasted paper.)

The detail I'm purposely leaving out is how to load this into the
printer to happen before *everyone's* print job. I figure that if
you take the time to do the research about that, your more likely to
behave responsibly with the knowledge. Suffice to say that it's
significantly easier to figure out than how to elegantly censor
words.

If you're interested in learning more about PostScript, I recommend
the two books in the Sun Lab (but please read them there rather than
making off with them; I'm not sure these are still in print, and
they're rather useful), as well as a few websites:

http://www.cs.indiana.edu/docproject/programming/postscript/postscript.html
  (Jim Marshall's alma mater, for those who remember him.)
http://atrey.karlin.mff.cuni.cz/~milanek/PostScript/Reference/
http://www.mdwconsulting.com/ps/
http://www.jwz.org/hacks/audio-tape.ps

(That last is Jamie Zawinski's massive audio/video-tape label
creator. It's got lots of comments. Jamie's the one who gave me the
idea for this hack, by describing having once done it but not
bothered to keep his file around.)

For the curious, my word list is attached.

--=20
gabriel rosenkoetter
gr@

--oplxJGu+Ee5xywIT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=word-list

Afghanistan
B. F. Skinner
Beethoven
Chomsky
Congress
Constitution
Continental
Creationism
Darwin
Engel
Foucault
Hegel
Homer
Joyce
Kuhn
Marx
NAFTA
NASA
Other
Philadelphia
Phoenix
Plato
Pope
Proust
SAC
SBC
SCCS
SCF
SQU
Sartre
Shakespeare
Umberto Eco
WTO
War
Wittgenstein
administration
annihilate
artistic
astronomy
attribute
attribution
bibliography
biological
biology
bloc
budget
capitalism
cell
censorship
censor
characteristic
chemical
citation
civil
classist
classism
classic
complex
computer
conclusion
conflict
confrontation
consequence
constant
contextualize
cultural
death
debate
deconstruction
deconstruct
degree
delineate
description
descriptive
destruction
dialog
dichotomy
digital
discourse
dogma
dollar
domain
dominant
element
engineering
environment
espionage
etc.
exclusion
existentialist
existentialism
existential
fabricate
fabrication
factor
female
feminism
feminist
film
force
frequency
fundamentally
fundamental
gender
gentrification
globalization
graduate
hegemony
historical
history
hyperbole
hypertext
identity
industrial
infrastructure
intelligence
intelligent
international
interpretation
interpret
intrinsic
introduction
lexicographic
liberate
liberating
libertarian
liberties
liberty
mathematics
memory
mental
meter
military
moreover
Moreover
musician
music
nationalism
nation
natural
nihilism
notable
objective
online
oppression
oppressive
oppress
paradigm
paradox
patriarchy
patriarch
phallic
phallus
phenomena
phenomenological
phenomenology
phenomenon
philosophy
policy
politics
post-modern
postmodern
modern
power
preemptive
process
proletariat
race
racism
reconsider
representation
representative
represent
repress
reproduction
result
rights
right
science
scientific
selection
self
sexuality
sexual
sex
simulacra
simulacrum
source
stress
structure
subjective
subversive
subvert
symbolic
symbolism
symbol
tension
text
theme
theorist
theory
therefore
transcend
transform
understanding
vaginal
vagina
validate
validation
verify
viable
violence
violent
pants

--oplxJGu+Ee5xywIT--

--3D7yMlnunRPwJqC7
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (NetBSD)
Comment: For info see http://www.gnupg.org

iEYEARECAAYFAjyqMh4ACgkQ9ehacAz5CRqTMQCgoV5nM/jMn6+GCqjRG3mYRBnh
0SgAoIEbjB3yKrMuDx5ce5Y1BsCw8BX0
=EVf7
-----END PGP SIGNATURE-----

--3D7yMlnunRPwJqC7--





>From branen@ Tue, 2 Apr 2002 19:22:09 -0500 (EST)
Date: Tue, 2 Apr 2002 19:22:09 -0500 (EST)
>From: branen salmon branen@
Subject: Other April 1st stuff.

spoke Gabe:
> In fact, the ITS's statement "only Macintoshes were affected" is
> wrong.  It should be, "only computers printing through the Windows
> print server were unaffected". This is either because the print server
> communicates with the printers by way of NetBIOS (or similar) or
> because it does it's own redefinition of the PostScript's show
> commands. (I'm not sure.)

> The point is, any computer that was pointed directly at the printer
> was affected. Also, any mac running software to run through the
> Windows print server would have not been affected.


I'm going to offer some alternate explanations.

I seriously doubt that the print server actually mucks with the
postscript.  I could be totally wrong here, but I imagine that ITS is
using Win2000's vanilla print server, which is probably far too dumb to do
anything that involved.  This is not to say that the print server was
totally irrelevant, but more on that in a second.

Looking at postscript from an affected Mac, text is output like this:
  250 331 :M (graduate)S

Postscript print drivers generally generate prologs which they send with
each print job.  This prolog does preliminary setup stuff so that the
printer can interpret the rest of the actual print job, deal with errors
in a friendly fashion, etc.

The LaserWriter 8 prolog contains this:
  /S/show ld

I don't have a reference handy, but I'll venture to say that this creates
an operator "S" which maps to the operator "show," which is what Gabe
redefined.

Thus,
  250 331 :M (graduate)S       equates to
  250 331 :M (graduate)show    and Gabe's code is invoked:

  250 331 :M (graduate)
        /found false def
        censorwords {
                search { censor /found true def exit } if
        } forall
        found not { realshow } if


(graduate) matches a word in the censor list, and is handed off to
"censor" instead of "realshow."


Looking at the output from a Win2000 machine, though, we get this:
  642 842 M (SCCS)[55 60 60 0]xS

And in the pscript.dll v5 prolog, we find
  /xS/xshow

(Yes, I am missing an operator.  "/xS/xshow" is surrounded by a bunch of
muck, but the assignment does eventually happen.)

So 
  642 842 M (SCCS)[55 60 60 0]xS      equates to
  642 842 M (SCCS)[55 60 60 0]xshow


Aha!  Gabe's code hooks "show," not "xshow."  Thus, it's never invoked,
and (SCCS) passes through unperturbed.


So that's my guess-- that the difference was in the operators invoked, not
in the presence or absence of a print server.


BUT, if the print server did matter, here's my guess why:

One other significant difference between the Mac/Unix print jobs and
those from Windows:  the presence of a PJL header.

Here's what you get from a Mac:
%!PS-Adobe-3.0 
%%Title: (Microsoft Word - Document1) 
%%Creator: (Microsoft Word: LaserWriter 8 8.7.1)  
%%CreationDate: (1:35 PM Monday, April 1, 2002) 

Here's what you get from Win2000:
%-12345X@PJL JOB 
@PJL SET RESOLUTION = 600 
@PJL SET BITSPERPIXEL = 2 
@PJL SET ECONOMODE = OFF 
@PJL ENTER LANGUAGE = POSTSCRIPT 
%!PS-Adobe-3.0 
%%Title: Document 
%%Creator: Pscript.dll Version 5.0 
%%CreationDate: 4/1/2002 13:32:32 


Gah!  What's that ugliness?  It's sure as hell not postscript.

"PJL" stands for "Printer Job Language."  Hewlett-Packard introduced it
with the LaserJet 4, and it's been present in every subsequent HP
laser.  Its primary purpose is configuration of printer-specific options--
things like resolution enhancement, duplex setup, language escapes, stuff
like that.  Most of what PJL does can also be done in Postscript, but
whatever; it's still there.

  %-12345X@PJL JOB
is the PJL universal language escape-- no matter what the printer's been
reading, this string pops it out into PJL.

  @PJL SET blah = blah
is configuring things for this print job.  (I think replacing SET with
ENTER makes the configurations default, but don't quote me on that.)

  @PJL ENTER LANGUAGE = POSTSCRIPT
tells the printer to start acting as a Postscript interpreter, and

  %!PS-Adobe-3.0 
is postscript-- the beginning of a Level 3 job.


HPs ship with two personalities-- Postscript and PCL (Plotter Control
Language).  Thus, this PJL command to switch between languages.  Again,
this isn't necessary--the printer can autodetect--but it's still there.


Conceivably, an @PJL ENTER LANGUAGE command could change the state of the
global VM, rendering Gabe's code irrelevant.  And conceivably, the Win2000
print server could simply "wrap" each submitted job in PJL, thus making it
important, but I seriously doubt it.


So I think that the difference was in show and xshow.  I doubt that the
print server had anything to do with it, but if it did, I'd gamble that it
was due to submitted Postscript jobs being wrapped in PJL, rather than
having their actual code modified.



I tip my hat to you, Gabe.  That was fucking inspired.


--b


----
branen salmon











>From gr@ Tue, 2 Apr 2002 22:11:48 -0500
Date: Tue, 2 Apr 2002 22:11:48 -0500
>From: gabriel rosenkoetter gr@
Subject: Other April 1st stuff.

--mojUlQ0s9EVzWg2t
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Tue, Apr 02, 2002 at 07:22:09PM -0500, branen salmon wrote:
>   250 331 :M (graduate)S
[...]
> The LaserWriter 8 prolog contains this:
>   /S/show ld
>=20
> I don't have a reference handy, but I'll venture to say that this creates
> an operator "S" which maps to the operator "show," which is what Gabe
> redefined.

Yep, exactly. (:M is a moveto in mac MS Word output, if memory
serves. If you're at screen resolution--72 dpi--then that's about
three inches in and four inches up. Centered?)

Most software that spits out PostScript does this ellision of
commands it uses frequently. (Yes, this really is worth it: S is one
byte, show is four; think about how many times you save three bytes.)

Fwiw, J in mac Word's output is an awidthshow with settings
appropriate to the font defined for that file (J for justify).

> Looking at the output from a Win2000 machine, though, we get this:

=2E.. which I didn't have an opportunity to do.

>   642 842 M (SCCS)[55 60 60 0]xS
>=20
> And in the pscript.dll v5 prolog, we find
>   /xS/xshow
>=20
> (Yes, I am missing an operator.  "/xS/xshow" is surrounded by a bunch of
> muck, but the assignment does eventually happen.)

Ewwww... xshow is, I think, Level 3 evilness. Bastards. Judging by
the arguments it takes, xshow is a version of awidthshow that looks
something like this:

 [cx cy ax ay] xshow -

=2E.. where cx and cy are presumed to apply to the space character, and
ax and ay are applied to every character. These will be offsets from
the font-defined char size to enable justification (and also
line-spacing... apparently MS Word presumes you want 1.5-height
lines by default; cute).

Note that this saves (logical) stack space (by making the command
need only two items on the stack rather than five) and saves stack
space memory (by presuming you want the char-specific modifications
done to space, because people almost never use the generality of
awidthshow).

> Aha!  Gabe's code hooks "show," not "xshow."  Thus, it's never invoked,
> and (SCCS) passes through unperturbed.

Right, because my references were only for Level 2 (if that...
actually, I think the texts in the CS Lab describe Level 1.3), so I
hadn't a clue it existed.

You have to pay Adobe for references on Level 3, btw. I think they
were free briefly (and may be mirrored elsewhere... I haven't gone
through the Adobe docs I got from another source that aren't
available from Adobe without buying a developer license these days),
but Adobe decided they wanted to milk developers for more cash.
Silly dot-bomb survivor.

(You always had to pay for the books, but it's possible to find
Level 1 and Level 2 references completely free online. I could find
no Level 3 references.)

> So that's my guess-- that the difference was in the operators invoked, not
> in the presence or absence of a print server.

You're definitely correct.

> "PJL" stands for "Printer Job Language."  Hewlett-Packard introduced it
> with the LaserJet 4, and it's been present in every subsequent HP
> laser.  Its primary purpose is configuration of printer-specific options--
> things like resolution enhancement, duplex setup, language escapes, stuff
> like that.  Most of what PJL does can also be done in Postscript, but
> whatever; it's still there.

Sure, but that's no big deal. That's very printer-specific, and
wouldn't affect its PostScript interpretation (well, except to turn
it on, I suppose). That'll just be the Windows driver specific to
the HP printers in question doing some (unnecessary) chatting with
the printer.

Also, it means that a suggestion Adam Preset made (that if the macs
were going through the windows print server there wouldn't have been
a problem) is untrue, since it's the original PS document coming
from the Win2k Word that caused this, nothing the print server did.

> Conceivably, an @PJL ENTER LANGUAGE command could change the state of the
> global VM, rendering Gabe's code irrelevant.  And conceivably, the Win2000
> print server could simply "wrap" each submitted job in PJL, thus making it
> important, but I seriously doubt it.

If this affected the printer's PostScript stacks (that is, cleared
out the dictionary stack and reloaded systemdict, which is what
you have to do to clear my stuff out, hint hint), then any time a
PC printed, the problem would have gone away for macs. That didn't
happen.

If the rest of that Win2k MS Word doc also redefined, using the
literal draw commands, show and friends, then it would have worked
right and things after it still would have been broken, because not
even MS would be foolish enough to leave their redefined shows on
the dictionary stack, since that would quickly run the printer out
of memory; rather, they'd create a new dictionary on top of the
stack, do their stuff there, and close it when they were done.

But redefining show using PostScript draw commands would be totally
insane... or, at least, it would mean that you knew were using an
exactly half-broken PostScript interpretter (one whose draw commands
worked flawlessly but whose show commands were broken). That doesn't
make a lot of sense.

> So I think that the difference was in show and xshow.  I doubt that the
> print server had anything to do with it, but if it did, I'd gamble that it
> was due to submitted Postscript jobs being wrapped in PJL, rather than
> having their actual code modified.

As I said, you're surely correct. If I'd done the code for this
three weeks ago as I should have rather than on Sunday night, I'd
definitely have caught that.

> I tip my hat to you, Gabe.  That was fucking inspired.

I do what I can to keep Swarthmore from taking itself too seriously.
I'm glad it was appreciated by some. (Some apparently doesn't
include much of ITS. Alas.)

Thanks for the great analysis!

(See, full disclosure is fun, kids!)

--=20
gabriel rosenkoetter
gr@

--mojUlQ0s9EVzWg2t
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (NetBSD)
Comment: For info see http://www.gnupg.org

iEYEARECAAYFAjyqcvQACgkQ9ehacAz5CRoFXwCeKc+iJBulczzztnTFNi/gyogD
B0AAniLvm4BJYdfKhQgYMUQw9NzK7l2X
=h+Ju
-----END PGP SIGNATURE-----

--mojUlQ0s9EVzWg2t--





>From branen@ Tue, 2 Apr 2002 23:38:16 -0500 (EST)
Date: Tue, 2 Apr 2002 23:38:16 -0500 (EST)
>From: branen salmon branen@
Subject: Other April 1st stuff.

spoke Gabe:
> Judging by the arguments it takes, xshow is a version of awidthshow
> that looks something like this:
>  [cx cy ax ay] xshow -

Oops.  I picked a bad example.
  (Graduate)[65 28 46 46 46 46 23  0]xS
might be a better one.  There's one number for each glyph.

> Right, because my references were only for Level 2 (if that...
> actually, I think the texts in the CS Lab describe Level 1.3), so I
> hadn't a clue it existed.

As it turns out, xshow is a part of Level 2, which was defined in
1990.  (Time for the department to buy a new book?)

You were right on about xshow being similar to awidthshow.  The Reference
Manual says:
    string numarray|numstring xshow
    Paint glyphs for string using x-widths in numarray|numstring

There's also an xyshow and a yshow-- the x & y are the same as in ashow,
and the arrays hold width information per glyph.


Incidentally, you -don't- have to pay Adobe for references on Level 3.  
(You don't have to pay Amazon, either, though they have all of the books
in stock.)

http://partners.adobe.com/asn/developer/technotes/postscript.html has a
wealth of goodies in PDF, including the complete second and third editions
of the Postscript Language Reference.  (xshow is on page 521 of the
latter.)

There are a couple of "tutorial"-style books that Adobe published back in
the mid-to-late 80s, the Postscript Language Tutorial and Cookbook (aka 
the Blue Book) and Postscript Language Program Design (aka the
Green Book).  They aren't listed on the Adobe Technotes page, but you can
find them at

http://www-cdf.fnal.gov/offline/PostScript/BLUEBOOK.PDF
http://www-cdf.fnal.gov/offline/PostScript/GREENBK.PDF


There'll also be copies at
http://www.sccs.swarthmore.edu/users/03/branen/postscript/
for the next few weeks just for the hell of it.



Damn, Postscript is so cool.


--b


----
branen salmon







>From gr@ Wed, 3 Apr 2002 01:02:38 -0500
Date: Wed, 3 Apr 2002 01:02:38 -0500
>From: gabriel rosenkoetter gr@
Subject: Other April 1st stuff.

--w2JjAQZceEVGylhD
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Tue, Apr 02, 2002 at 11:38:16PM -0500, branen salmon wrote:
> Oops.  I picked a bad example.
>   (Graduate)[65 28 46 46 46 46 23  0]xS
> might be a better one.  There's one number for each glyph.

Not a bad example, just only one example.

Wow, the implementation of xshow must be really evil. It's *hard* to
count characters in PS. (Erm... well, but forall does it for you, so
maybe they just use that.)

> As it turns out, xshow is a part of Level 2, which was defined in
> 1990.  (Time for the department to buy a new book?)

Well, much of the new stuff is pretty extraneous. That is, it's
clearly possible to get the same results out of awidthshow that they
do out of xshow in most cases. But it does seem that xshow is
actually more general.

> Incidentally, you -don't- have to pay Adobe for references on Level 3. =
=20
> (You don't have to pay Amazon, either, though they have all of the books
> in stock.)

Well, ftp.adobe.com/pub/adobe/Documentation definitely doesn't exist
any more and the correlative portion of their website asks for you
to register (annually, to the tune of $100, minimum).

> http://partners.adobe.com/asn/developer/technotes/postscript.html has a
> wealth of goodies in PDF, including the complete second and third editions
> of the Postscript Language Reference.  (xshow is on page 521 of the
> latter.)

Hrm. I recall foo.adobe.com asking me to buy a license. But maybe
foo wasn't partners. (Recall that I did all of this in one six hour
sitting, so my memory's going to be a bit fogged... ;^>)

> http://www-cdf.fnal.gov/offline/PostScript/BLUEBOOK.PDF
> http://www-cdf.fnal.gov/offline/PostScript/GREENBK.PDF

Huh. No redbook there? The Sun lab has the blue book and the red
book. (The red book is the language reference, what I got the most
use out of.)

> Damn, Postscript is so cool.

My feelings exactly. :^>

--=20
gabriel rosenkoetter
gr@

--w2JjAQZceEVGylhD
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (NetBSD)
Comment: For info see http://www.gnupg.org

iEYEARECAAYFAjyqmv4ACgkQ9ehacAz5CRrG4wCeKKk7gx5IQlRVfdd/2CmgMwrJ
MAAAmwVX7dhboQ3lK2QevbVh05z5x4Ap
=rvWf
-----END PGP SIGNATURE-----

--w2JjAQZceEVGylhD--