是否有"Postscript for Dummies中的文件IO"?

dmc*_*kee 1 io file postscript

在Stack Overflow上播放的大部分涉及到ASCII数字,而codegolf.SE正在以同样的方式形成.

这一切都很好,但我想在输出中注入一些变化,并编写了我最近的问题输出一个可玩的填字游戏网格,以鼓励图形格式条目.

为了表示愿意,我开始尝试将后记中的参考实现破解.唉,我对语言完全不熟悉,并且在执行基本文件IO时遇到了麻烦.有谁知道涵盖这个主题的基本资源?

我知道

  • file
  • (%stdin)
  • token
  • readstring
  • readline

但是我很清楚到底是什么后三个回归以及在你得到之后如何操纵它.

已经发现有几个返回一<value> <boolean>对,我可以if用来测试布尔值.那又怎样?

小智 10

一本关于附言的好书是Gleen Reid的"后记思考".您曾经可以从他的网站上免费获取该书供个人使用,但它已经失效.您仍然可以从http://replay.waybackmachine.org/20090621100720/http://www.rightbrain.com/pages/books.html下载它

第14章介绍了文件io并提供了示例代码.


lus*_*oog 6

在postscript中有一些文件IO的技巧和快捷方式,这些技巧通常在postscript书籍的介绍部分中没有提到.其中最保守的秘密是"令牌"操作符.它允许您借用解释器自己的扫描程序来读取一个裸字(生成一个名称类型对象),一个数字(产生一个integertype或realtype对象),或者这些数组的数组(但只有当你使用可执行数组表示法时,即.花括号,否则你只需要一个代表左方括号的marktype对象.

举个简单的例子,我经常使用这个单行程序在postscript程序中嵌入一个扩展的评论部分:

%!
{ currentfile token pop /END-COMMENT eq {exit} if } loop
Each word here is read from the current file and converted
into a name object and compared to "/END-COMMENT".
It can have but does not need a preceeding slash.

This program produces an image of a snowman in a blizzard,
suitable for use as stationary.
END-COMMENT

showpage
Run Code Online (Sandbox Code Playgroud)

编辑:我现在意识到这是一个非常可怕的答案......到目前为止.

我上面的例子不过是:

(Some
multi-line
text)
pop
Run Code Online (Sandbox Code Playgroud)

所以,这次真实.

首先,你需要一个loop.

{
} loop
Run Code Online (Sandbox Code Playgroud)

在这个循环中,你读了一些数据.

/src (datafile) (r) file def
{
    src readline
} loop
Run Code Online (Sandbox Code Playgroud)

正如您所观察到的,文件读取操作符都在堆栈顶部返回一个布尔值.完善!

/src (datafile) (r) file def
{
    src readline {
    }{
        exit
    } ifelse
} loop
Run Code Online (Sandbox Code Playgroud)

因此,布尔值true将执行某些操作并保持循环,但布尔值为false(无更多数据)会导致循环终止.但readline需要一个字符串来放入其数据.它甚至在false的情况下返回字符串.

/src (datafile) (r) file def
/str 80 string def
{
    src str readline {
        processline
    }{
        pop exit
    } ifelse
} loop
Run Code Online (Sandbox Code Playgroud)

现在我们有一个字符串,其中包含来自文件的一行(最多80个字符)数据.如果它完全类似于Postscript语法,你可以token在循环中使用(就像我的第一个例子;它从文件中读取每个单词,将其转换为可执行文件名,然后将其与文字名称进行比较;如果名称匹配,则退出环).或者您可以get在循环(或forall循环)中使用将每个字节提取为整数.但最酷的事情是search.

此过程扫描字符串以查找以空格分隔的单词,并将每个单词打印到stdout各自的行.

/processline { % (line)
     ( ) { % (line) ( )
         search { % (post) ( ) (pre)
             =
         }{ % (no-match)
             =
             exit
         } ifelse
     } loop
} def
Run Code Online (Sandbox Code Playgroud)

在这里复制案例通常更容易,当你想对所有其他案件做同样的事情时.你可以做一些棘手的事情来处理最顶层的字符串,然后测试布尔值; 但这并不值得麻烦.很酷的search是它返回结果的方便顺序.它将字符串的开头放在顶部,以便您可以使用它.然后它给你"匹配"(这与你最初给出的"搜索"相同(尽管它现在引用了工作字符串))和余数; 并且它们已经按照正确的顺序进行下一轮循环.

那么你想用从外部文件中读取的提取的,以空格分隔的单词做什么?

如果它们代表数字,你可以cvicvr他们做算术.如果它们是字母数字,你可以printshow他们; 或者cvn他们并将它们用作原子符号.


小智 5

听起来您想要将简单的文本文件(表示填字游戏布局)转换为在页面上绘制填字游戏的PostScript代码.虽然PostScript确实是Turing-complete,因此可以编程来实现这一点,但我认为在PostScript中编写整个程序并不是一个好方法.

PostScript是一种难以编程的语言,特别是如果你想搞乱任意数据.当我想要PostScript输出时,我首先将一些样本的PostScript混合在一起,绘制出我想要的东西,所有参数都是硬编码的.然后我用其他语言编写代码,输出PostScript代码,根据输入根据需要改变相应的部分.

我看到它读得不太好,所以这是一个例子.如果我有一个包含圆的半径的输入文件,那么我将在Python中编写一个读取该半径的程序,然后编写PostScript代码以绘制圆,并在PostScript中对半径进行硬编码.

几年前我开始从事填字游戏项目.没有走得太远,但附加的PostScript代码将绘制一个小填字游戏.请注意,"正确的"PostScript遵循一些我没有打扰的文档约定; 我有一些关于他们的粗略笔记,我可以发布.

这个PostScript代码确实做了一些计算.通常我会在PostScript中编写我希望做的事情,或者需要只有PostScript解释器会有数据的东西,比如当前字体中字符串的宽度,以便居中.

我没有清理过这个.随意要求澄清.HTH.

%!

% "Example"
% by (author)
% Generated 16 Apr 2005 22:19 by (program name)

% should really be eps

% unit conversions

/inch {72 mul} bind def
/cm {inch 2.54 div} bind def



%%%%%% start of adjustable parameters

% these may be fiddled with, within reason
% be careful not to change the syntax

% paper size
/page_width 8.5 inch def
/page_height 11 inch def

% page margins
/top_margin 1 inch def
/left_margin 1 inch def

% how many "cells" wide and high
/puzzle_width 9 def
/puzzle_height 9 def

% cell_size: height and width of a one-letter square, in points
/cell_size .25 inch def

% line width, in points. 1 is about maximum.
/line_width .375 def

% font and size for the numbers
/cell_font {/Helvetica 5} bind def

% top/left margin for numbers within a cell
/num_margin 1.5 def

%%%%%% end of adjustable parameters



<< /PageSize [page_width page_height] >> setpagedevice


/w_pts puzzle_width cell_size mul def
/h_pts puzzle_height cell_size mul def

/ulx left_margin def
/uly page_height top_margin sub def
/lrx ulx w_pts add def
/lry uly h_pts sub def


% draw grid

line_width setlinewidth
0 setgray

newpath ulx uly w_pts h_pts neg rectstroke

lry cell_size uly {
  newpath ulx exch moveto w_pts 0 rlineto stroke
} for

ulx cell_size lrx {
  newpath lry moveto 0 h_pts rlineto stroke
} for


% fill in black spaces

% ulx uly width height blackrect
% all in terms of cells; upper-left-most is 0,0
/blackrect
{
  << >> begin
  /h exch def /w exch def /y exch def /x exch def
  newpath
  ulx x cell_size mul add
  uly y cell_size mul sub
  w cell_size mul
  h cell_size mul neg
  rectfill
  end
} bind def

0 setgray
0 0 1 1 blackrect
3 0 2 1 blackrect
8 0 1 1 blackrect
4 1 1 1 blackrect
2 2 1 1 blackrect
6 2 1 1 blackrect
8 3 1 1 blackrect
0 4 2 1 blackrect
7 4 2 1 blackrect
0 5 1 1 blackrect
2 6 1 1 blackrect
6 6 1 1 blackrect
4 7 1 1 blackrect
0 8 1 1 blackrect
4 8 2 1 blackrect
8 8 1 1 blackrect


% draw numbers

% x y h s drawnum
% x and y in terms of cells; upper-left-most is 0,0. s is string.
% h is height of numbers. should never change, so compute once before any calls.
/drawnum
{
  << >> begin
  /s exch def /h exch def /y exch def /x exch def
  newpath
  ulx x cell_size mul add num_margin add
  uly y cell_size mul sub num_margin sub h sub
  moveto s show
  end
} bind def

0 setgray
cell_font selectfont

% compute font height
mark
newpath 0 0 moveto
(0) false charpath flattenpath pathbbox
/fh exch def
cleartomark newpath

1 0 fh (1) drawnum
2 0 fh (2) drawnum
5 0 fh (3) drawnum
6 0 fh (4) drawnum
7 0 fh (5) drawnum
0 1 fh (6) drawnum
3 1 fh (7) drawnum
5 1 fh (8) drawnum
8 1 fh (9) drawnum
0 2 fh (10) drawnum
3 2 fh (11) drawnum
4 2 fh (12) drawnum
7 2 fh (13) drawnum
0 3 fh (14) drawnum
2 3 fh (15) drawnum
6 3 fh (16) drawnum
2 4 fh (17) drawnum
1 5 fh (18) drawnum
7 5 fh (19) drawnum
8 5 fh (20) drawnum
0 6 fh (21) drawnum
3 6 fh (22) drawnum
7 6 fh (23) drawnum
0 7 fh (24) drawnum
2 7 fh (25) drawnum
5 7 fh (26) drawnum
6 7 fh (27) drawnum
1 8 fh (28) drawnum
6 8 fh (29) drawnum


showpage
Run Code Online (Sandbox Code Playgroud)