2

I'm building an application in PostScript that needs to take input fom the user at a prompt (I will be using the GhostScript executive, and the file won't be sent to the printer). I can't see anything in my PostScript Language Reference Manual that suggests this is possible, and I don't want to drop back to the executive, so is this possible?

Jashank Jeremy
  • 360
  • 1
  • 4
  • 14

2 Answers2

3

It's not that hopeless! But it ain't exactly easy, either. There are two other special files besides %stdin that you can read from. (%lineedit)(r)file dup bytesavailable string readstring pop will read a line from stdin into a string. There is also the (%statementedit) file which will read until a syntactically valid postscript fragment is typed (plus newline). This will match parentheses and curlies, but not square brackets. Before reading, you should issue a prompt like (> )print flush.

One more thing, you can catch ^D by wrapping all this in a stopped context.

{ %stopped
    (> )print flush
    (%lineedit)(r)file
    dup bytesavailable string readstring pop
} stopped not {
    (successfully read: )print
    print
}{
    (received EOF indication)print
}ifelse

Instead of popping that bool after readstring, you could use it to cheaply detect an empty input line. Note also, that the stop that triggers on EOF is from an error in file (ghostscript calls it /invalidfilename), but although file is defined as an operator, and operators are supposed to push their arguments back on the stack when signaling an error, I've noticed ghostscript doesn't necessarily do this (I forget what it leaves, but it's not 2 strings like you'd expect), so you might want to put mark in front and cleartomark pop after this whole block.

The special files (%lineedit) and (%statementedit), if available, will successfully process backspaces and control-U and possibly other control. I believe real Adobe printers will respond to ^T with some kind of status message. But I've never seen it.

PS. :!

I've got a more extensive example of interactive postscript in my postscript debugger. Here's a better version of the debugger, but it's probably less useable as an example.

luser droog
  • 18,988
  • 3
  • 53
  • 105
  • @Jashank I've got a more fun example in my [Mandelbrot explorer](http://code.google.com/p/xpost/downloads/detail?name=mandel2.ps). It just issues a menu and an internal PS> prompt, and defines single-letter procedures as commands. – luser droog Jan 22 '13 at 06:30
  • May I suggest: `(%lineedit) (r) file dup bytesavailable 1 max string readstring pop` so that it also works for the empty line, i.e., if you simply press RET! – mat Aug 06 '18 at 08:18
2

PostScript isn't designed as an interactive language, so there is no great provision for user input.

You can read input from stdin, and you cat write to stdout or stderr, so if those are wired up to a console then you can theoretically prompt the user for input by writing to stdout, and read the input back from stdin.

Note that reading from stdin won't allow the user to do things like backspace over errors. At least not visually, the data will be sent to your PostScript program which could process the backspace characters.

That's about the only way to achieve this that I can think of though.

KenS
  • 30,202
  • 3
  • 34
  • 51
  • Looks like I'm going to have to take that approach. – Jashank Jeremy Sep 06 '11 at 07:08
  • On the other hand, since you are running on an itneractive computer, the other way to do that would be running an interactive program in another language, and the data to a postscript program (command line/file, or even templating the postscript file)? – jsbueno Sep 06 '11 at 14:19
  • I'd like to implement the entire solution in PostScript, to learn a bit more about the language, but also so I'm not having to pass things around between programs. – Jashank Jeremy Sep 09 '11 at 11:46