Annotation of researchv10dc/cmd/postscript/grabit/grabit.ps, revision 1.1

1.1     ! root        1: %
        !             2: % Dump a PostScript object, occasionally in a form that can be sent back
        !             3: % through the interpreter. Similiar to Adobe's == procedure, but output
        !             4: % is usually easier to read. No binding so operators like rcheck and exec
        !             5: % can be conviently redefined.
        !             6: %
        !             7: 
        !             8: /GrabitDict 100 dict dup begin
        !             9: 
        !            10: /recursive true def
        !            11: /scratchstring 200 string def
        !            12: /slowdown 100 def
        !            13: 
        !            14: /column 0 def
        !            15: /lastcolumn 80 def
        !            16: /level 0 def
        !            17: /multiline 100 array def
        !            18: /nextname 0 def
        !            19: /arraylength 0 def
        !            20: /lengthonly false def
        !            21: 
        !            22: /GrabitSetup {
        !            23:        counttomark {OmitNames exch true put} repeat pop
        !            24:        0 0 moveto              % for hardcopy output
        !            25: } def
        !            26: 
        !            27: /OmitNames 30 dict def         % ignore these names
        !            28: /OtherDicts 200 dict def       % unrecognized dictionaries
        !            29: 
        !            30: %
        !            31: % All strings returned to the host go through Print. First pass through an
        !            32: % array has lengthonly set to true.
        !            33: %
        !            34: 
        !            35: /Print {
        !            36:        dup type /stringtype ne {scratchstring cvs} if
        !            37:        lengthonly {
        !            38:                length arraylength add /arraylength exch def
        !            39:        }{
        !            40:                dup length column add /column exch def
        !            41:                print flush
        !            42:                slowdown {1 pop} repeat
        !            43:        } ifelse
        !            44: } def
        !            45: 
        !            46: /Indent {level {(    ) Print} repeat} def
        !            47: /Newline {(\n) Print lengthonly not {/column 0 def} if} def
        !            48: 
        !            49: /NextLevel {/level level 1 add def multiline level 0 put} def
        !            50: /LastLevel {/level level 1 sub def} def
        !            51: 
        !            52: %
        !            53: % Make a unique name for each unrecognized dictionary and remember the name
        !            54: % and dictionary in OtherDicts.
        !            55: %
        !            56: 
        !            57: /Register {
        !            58:        dup type /dicttype eq {
        !            59:                /nextname nextname 1 add def
        !            60:                dup (UnknownDict   ) dup
        !            61:                (UnknownDict) length nextname (   ) cvs putinterval
        !            62:                0 (UnknownDict) length nextname (   ) cvs length add getinterval cvn
        !            63:                exch OtherDicts 3 1 roll put
        !            64:        } if
        !            65: } def
        !            66: 
        !            67: %
        !            68: % Replace array or dictionary values by known names. Lookups are in the
        !            69: % standard PostScript dictionaries and in OtherDicts. If found replace
        !            70: % the value by the name and make it executable so nametype omits the
        !            71: % leading /.
        !            72: %
        !            73: 
        !            74: /Replace {
        !            75:        false
        !            76:        1 index type /dicttype eq {pop true} if
        !            77:        1 index type /arraytype eq 2 index xcheck not and {pop true} if
        !            78:        {
        !            79:                false
        !            80:                [userdict systemdict statusdict serverdict OtherDicts] {
        !            81:                        {
        !            82:                                3 index eq
        !            83:                                        {exch pop exch pop cvx true exit}
        !            84:                                        {pop}
        !            85:                                ifelse
        !            86:                        } forall
        !            87:                        dup {exit} if
        !            88:                } forall
        !            89:                pop
        !            90:        } if
        !            91: } def
        !            92: 
        !            93: %
        !            94: % Simple type handlers. In some cases (e.g. savetype) what's returned can't
        !            95: % be sent back through the interpreter.
        !            96: %
        !            97: 
        !            98: /booleantype {{(true )}{(false )} ifelse Print} def
        !            99: /marktype {pop (mark ) Print} def
        !           100: /nulltype {pop (null ) Print} def
        !           101: /integertype {Print ( ) Print} def
        !           102: /realtype {Print ( ) Print} def
        !           103: /filetype {pop (-file- ) Print} def
        !           104: /fonttype {pop (-fontID- ) Print} def
        !           105: /savetype {pop (-saveobj- ) Print} def
        !           106: 
        !           107: %
        !           108: % Special formatting for operators is enabled if the flag in multiline
        !           109: % (for the current level) is set to 1. In that case each operator, after
        !           110: % being printed, is looked up in OperatorDict. If found the value is used
        !           111: % as an index into the OperatorProcs array and the object at that index
        !           112: % is retrieved and executed. Currently only used to choose the operators
        !           113: % that end a line.
        !           114: %
        !           115: 
        !           116: /operatortype {
        !           117:        dup Print ( ) Print
        !           118:        multiline level get 1 eq {
        !           119:                scratchstring cvs cvn dup OperatorDict exch known {
        !           120:                        OperatorDict exch get
        !           121:                        OperatorProcs exch get exec
        !           122:                }{
        !           123:                        pop
        !           124:                        column lastcolumn gt {Newline Indent} if
        !           125:                } ifelse
        !           126:        }{pop} ifelse
        !           127: } def
        !           128: 
        !           129: %
        !           130: % Executable names are passed to operatortype. Non-executable names get a
        !           131: % leading /.
        !           132: %
        !           133: 
        !           134: /nametype {
        !           135:        dup xcheck {
        !           136:                operatortype
        !           137:        }{
        !           138:                (/) Print Print ( ) Print
        !           139:        } ifelse
        !           140: } def
        !           141: 
        !           142: %
        !           143: % Arrays are processed in two passes. The first computes the length of the
        !           144: % string returned to the host without any special formatting. If it extends
        !           145: % past the last column special formatting is enabled by setting a flag in
        !           146: % array multiline. Arrays are processed in a for loop so the last element
        !           147: % easily recognized. At that point special fortmatting is disabled.
        !           148: %
        !           149: 
        !           150: /packedarraytype {arraytype} def
        !           151: 
        !           152: /arraytype {
        !           153:        NextLevel
        !           154:        lengthonly not {
        !           155:                /lengthonly true def
        !           156:                /arraylength 0 def
        !           157:                dup dup type exec
        !           158:                arraylength 20 gt arraylength column add lastcolumn gt and {
        !           159:                        multiline level 1 put
        !           160:                } if
        !           161:                /lengthonly false def
        !           162:        } if
        !           163: 
        !           164:        dup rcheck not {
        !           165:                (-array- ) Print pop
        !           166:        }{
        !           167:                dup xcheck {({)}{([)} ifelse Print
        !           168:                multiline level get 0 ne {Newline Indent}{( ) Print} ifelse
        !           169:                0 1 2 index length 1 sub {
        !           170:                        2 copy exch length 1 sub eq multiline level get 1 eq and {
        !           171:                                multiline level 2 put
        !           172:                        } if
        !           173:                        2 copy get exch pop
        !           174:                        dup type /dicttype eq {
        !           175:                                Replace
        !           176:                                dup type /dicttype eq {
        !           177:                                        dup Register Replace
        !           178:                                        recursive {
        !           179:                                                2 copy cvlit
        !           180:                                                /def load 3 1 roll
        !           181:                                                count 3 roll
        !           182:                                        } if
        !           183:                                        exch pop
        !           184:                                } if
        !           185:                        } if
        !           186:                        dup type exec
        !           187:                        dup xcheck not multiline level get 1 eq and {
        !           188:                                0 index type /arraytype eq
        !           189:                                1 index type /packedarray eq or
        !           190:                                1 index type /stringtype eq or {Newline Indent} if
        !           191:                        } if
        !           192:                } for
        !           193:                multiline level get 0 ne {Newline LastLevel Indent NextLevel} if
        !           194:                xcheck {(} )}{(] )} ifelse Print
        !           195:        } ifelse
        !           196:        LastLevel
        !           197: } def
        !           198: 
        !           199: %
        !           200: % Dictionary handler. Try to replace the value by a name before processing
        !           201: % the dictionary.
        !           202: %
        !           203: 
        !           204: /dicttype {
        !           205:        dup
        !           206:        rcheck not {
        !           207:                (-dictionary- ) Print pop
        !           208:        }{
        !           209:                dup maxlength Print ( dict dup begin) Print Newline
        !           210:                NextLevel
        !           211:                {
        !           212:                        1 index OmitNames exch known {
        !           213:                                pop pop
        !           214:                        }{
        !           215:                                Indent
        !           216:                                Replace         % arrays and dicts by known names
        !           217:                                Register        % new dictionaries in OtherDicts
        !           218:                                exch
        !           219:                                cvlit dup type exec     % key first - force a /
        !           220:                                dup type exec           % then the value
        !           221:                                (def) Print Newline
        !           222:                        } ifelse
        !           223:                } forall
        !           224:                LastLevel
        !           225:                Indent
        !           226:                (end ) Print
        !           227:        } ifelse
        !           228: } def
        !           229: 
        !           230: %
        !           231: % Strings containing characters not in AsciiDict are returned in hex. All
        !           232: % others are ASCII strings and use AsciiDict for character mapping.
        !           233: %
        !           234: 
        !           235: /onecharstring ( ) def
        !           236: /twocharstring (  ) def
        !           237: 
        !           238: /stringtype {
        !           239:        dup
        !           240:        rcheck not {
        !           241:                (-string- ) Print
        !           242:        }{
        !           243:                /hexit false def
        !           244:                dup {
        !           245:                        onecharstring 0 3 -1 roll put
        !           246:                        AsciiDict onecharstring cvn known not {
        !           247:                                /hexit true def exit
        !           248:                        } if
        !           249:                } forall
        !           250: 
        !           251:                hexit {(<)}{(\()} ifelse Print
        !           252:                0 1 2 index length 1 sub {
        !           253:                        2 copy 1 getinterval exch pop
        !           254:                        hexit {
        !           255:                                0 get /n exch def
        !           256:                                n -4 bitshift 16#F and 16 twocharstring cvrs pop
        !           257:                                n 16#F and twocharstring 1 1 getinterval 16 exch cvrs pop
        !           258:                                twocharstring
        !           259:                        }{cvn AsciiDict exch get} ifelse
        !           260:                        Print
        !           261:                        column lastcolumn gt {
        !           262:                                hexit not {(\\) Print} if
        !           263:                                Newline
        !           264:                        } if
        !           265:                } for
        !           266:                hexit {(> )}{(\) )} ifelse Print
        !           267:        } ifelse
        !           268:        pop
        !           269: } def
        !           270: 
        !           271: %
        !           272: % ASCII characters and replacement strings. Ensures the returned string will
        !           273: % reproduce the original when passed through the scanner. Strings containing
        !           274: % characters not in this list should be returned as hex strings.
        !           275: %
        !           276: 
        !           277: /AsciiDict 128 dict dup begin
        !           278:        (\n) cvn (\\n) def
        !           279:        (\r) cvn (\\r) def
        !           280:        (\t) cvn (\\t) def
        !           281:        (\b) cvn (\\b) def
        !           282:        (\f) cvn (\\f) def
        !           283:        ( ) cvn ( ) def
        !           284:        (!) cvn (!) def
        !           285:        (") cvn (") def
        !           286:        (#) cvn (#) def
        !           287:        ($) cvn ($) def
        !           288:        (%) cvn (\\%) def
        !           289:        (&) cvn (&) def
        !           290:        (') cvn (') def
        !           291:        (\() cvn (\\\() def
        !           292:        (\)) cvn (\\\)) def
        !           293:        (*) cvn (*) def
        !           294:        (+) cvn (+) def
        !           295:        (,) cvn (,) def
        !           296:        (-) cvn (-) def
        !           297:        (.) cvn (.) def
        !           298:        (/) cvn (/) def
        !           299:        (0) cvn (0) def
        !           300:        (1) cvn (1) def
        !           301:        (2) cvn (2) def
        !           302:        (3) cvn (3) def
        !           303:        (4) cvn (4) def
        !           304:        (5) cvn (5) def
        !           305:        (6) cvn (6) def
        !           306:        (7) cvn (7) def
        !           307:        (8) cvn (8) def
        !           308:        (9) cvn (9) def
        !           309:        (:) cvn (:) def
        !           310:        (;) cvn (;) def
        !           311:        (<) cvn (<) def
        !           312:        (=) cvn (=) def
        !           313:        (>) cvn (>) def
        !           314:        (?) cvn (?) def
        !           315:        (@) cvn (@) def
        !           316:        (A) cvn (A) def
        !           317:        (B) cvn (B) def
        !           318:        (C) cvn (C) def
        !           319:        (D) cvn (D) def
        !           320:        (E) cvn (E) def
        !           321:        (F) cvn (F) def
        !           322:        (G) cvn (G) def
        !           323:        (H) cvn (H) def
        !           324:        (I) cvn (I) def
        !           325:        (J) cvn (J) def
        !           326:        (K) cvn (K) def
        !           327:        (L) cvn (L) def
        !           328:        (M) cvn (M) def
        !           329:        (N) cvn (N) def
        !           330:        (O) cvn (O) def
        !           331:        (P) cvn (P) def
        !           332:        (Q) cvn (Q) def
        !           333:        (R) cvn (R) def
        !           334:        (S) cvn (S) def
        !           335:        (T) cvn (T) def
        !           336:        (U) cvn (U) def
        !           337:        (V) cvn (V) def
        !           338:        (W) cvn (W) def
        !           339:        (X) cvn (X) def
        !           340:        (Y) cvn (Y) def
        !           341:        (Z) cvn (Z) def
        !           342:        ([) cvn ([) def
        !           343:        (\\) cvn (\\\\) def
        !           344:        (]) cvn (]) def
        !           345:        (^) cvn (^) def
        !           346:        (_) cvn (_) def
        !           347:        (`) cvn (`) def
        !           348:        (a) cvn (a) def
        !           349:        (b) cvn (b) def
        !           350:        (c) cvn (c) def
        !           351:        (d) cvn (d) def
        !           352:        (e) cvn (e) def
        !           353:        (f) cvn (f) def
        !           354:        (g) cvn (g) def
        !           355:        (h) cvn (h) def
        !           356:        (i) cvn (i) def
        !           357:        (j) cvn (j) def
        !           358:        (k) cvn (k) def
        !           359:        (l) cvn (l) def
        !           360:        (m) cvn (m) def
        !           361:        (n) cvn (n) def
        !           362:        (o) cvn (o) def
        !           363:        (p) cvn (p) def
        !           364:        (q) cvn (q) def
        !           365:        (r) cvn (r) def
        !           366:        (s) cvn (s) def
        !           367:        (t) cvn (t) def
        !           368:        (u) cvn (u) def
        !           369:        (v) cvn (v) def
        !           370:        (w) cvn (w) def
        !           371:        (x) cvn (x) def
        !           372:        (y) cvn (y) def
        !           373:        (z) cvn (z) def
        !           374:        ({) cvn ({) def
        !           375:        (|) cvn (|) def
        !           376:        (}) cvn (}) def
        !           377:        (~) cvn (~) def
        !           378: end def
        !           379: 
        !           380: %
        !           381: % OperatorDict can help format procedure listings. The value assigned to each
        !           382: % name is used as an index into the OperatorProcs array. The procedure at that
        !           383: % index is fetched and executed after the named operator is printed. What's in
        !           384: % OperatorDict is a matter of taste rather than correctness. The default list
        !           385: % represents our choice of which of Adobe's operators should end a line.
        !           386: %
        !           387: 
        !           388: /OperatorProcs [{} {Newline Indent}] def
        !           389: 
        !           390: /OperatorDict 250 dict def
        !           391: 
        !           392: OperatorDict   /arc                    1 put
        !           393: OperatorDict   /arcn                   1 put
        !           394: OperatorDict   /ashow                  1 put
        !           395: OperatorDict   /awidthshow             1 put
        !           396: OperatorDict   /banddevice             1 put
        !           397: OperatorDict   /begin                  1 put
        !           398: OperatorDict   /charpath               1 put
        !           399: OperatorDict   /clear                  1 put
        !           400: OperatorDict   /cleardictstack         1 put
        !           401: OperatorDict   /cleartomark            1 put
        !           402: OperatorDict   /clip                   1 put
        !           403: OperatorDict   /clippath               1 put
        !           404: OperatorDict   /closefile              1 put
        !           405: OperatorDict   /closepath              1 put
        !           406: OperatorDict   /concat                 1 put
        !           407: OperatorDict   /copypage               1 put
        !           408: OperatorDict   /curveto                1 put
        !           409: OperatorDict   /def                    1 put
        !           410: OperatorDict   /end                    1 put
        !           411: OperatorDict   /eoclip                 1 put
        !           412: OperatorDict   /eofill                 1 put
        !           413: OperatorDict   /erasepage              1 put
        !           414: OperatorDict   /exec                   1 put
        !           415: OperatorDict   /exit                   1 put
        !           416: OperatorDict   /fill                   1 put
        !           417: OperatorDict   /flattenpath            1 put
        !           418: OperatorDict   /flush                  1 put
        !           419: OperatorDict   /flushfile              1 put
        !           420: OperatorDict   /for                    1 put
        !           421: OperatorDict   /forall                 1 put
        !           422: OperatorDict   /framedevice            1 put
        !           423: OperatorDict   /grestore               1 put
        !           424: OperatorDict   /grestoreall            1 put
        !           425: OperatorDict   /gsave                  1 put
        !           426: OperatorDict   /handleerror            1 put
        !           427: OperatorDict   /if                     1 put
        !           428: OperatorDict   /ifelse                 1 put
        !           429: OperatorDict   /image                  1 put
        !           430: OperatorDict   /imagemask              1 put
        !           431: OperatorDict   /initclip               1 put
        !           432: OperatorDict   /initgraphics           1 put
        !           433: OperatorDict   /initmatrix             1 put
        !           434: OperatorDict   /kshow                  1 put
        !           435: OperatorDict   /lineto                 1 put
        !           436: OperatorDict   /loop                   1 put
        !           437: OperatorDict   /moveto                 1 put
        !           438: OperatorDict   /newpath                1 put
        !           439: OperatorDict   /nulldevice             1 put
        !           440: OperatorDict   /pathforall             1 put
        !           441: OperatorDict   /print                  1 put
        !           442: OperatorDict   /prompt                 1 put
        !           443: OperatorDict   /put                    1 put
        !           444: OperatorDict   /putinterval            1 put
        !           445: OperatorDict   /quit                   1 put
        !           446: OperatorDict   /rcurveto               1 put
        !           447: OperatorDict   /renderbands            1 put
        !           448: OperatorDict   /repeat                 1 put
        !           449: OperatorDict   /resetfile              1 put
        !           450: OperatorDict   /restore                1 put
        !           451: OperatorDict   /reversepath            1 put
        !           452: OperatorDict   /rlineto                1 put
        !           453: OperatorDict   /rmoveto                1 put
        !           454: OperatorDict   /rotate                 1 put
        !           455: OperatorDict   /run                    1 put
        !           456: OperatorDict   /scale                  1 put
        !           457: OperatorDict   /setcachedevice         1 put
        !           458: OperatorDict   /setcachelimit          1 put
        !           459: OperatorDict   /setcacheparams         1 put
        !           460: OperatorDict   /setcharwidth           1 put
        !           461: OperatorDict   /setdash                1 put
        !           462: OperatorDict   /setdefaulttimeouts     1 put
        !           463: OperatorDict   /setdostartpage         1 put
        !           464: OperatorDict   /seteescratch           1 put
        !           465: OperatorDict   /setflat                1 put
        !           466: OperatorDict   /setfont                1 put
        !           467: OperatorDict   /setgray                1 put
        !           468: OperatorDict   /sethsbcolor            1 put
        !           469: OperatorDict   /setidlefonts           1 put
        !           470: OperatorDict   /setjobtimeout          1 put
        !           471: OperatorDict   /setlinecap             1 put
        !           472: OperatorDict   /setlinejoin            1 put
        !           473: OperatorDict   /setlinewidth           1 put
        !           474: OperatorDict   /setmargins             1 put
        !           475: OperatorDict   /setmatrix              1 put
        !           476: OperatorDict   /setmiterlimit          1 put
        !           477: OperatorDict   /setpacking             1 put
        !           478: OperatorDict   /setpagetype            1 put
        !           479: OperatorDict   /setprintname           1 put
        !           480: OperatorDict   /setrgbcolor            1 put
        !           481: OperatorDict   /setsccbatch            1 put
        !           482: OperatorDict   /setsccinteractive      1 put
        !           483: OperatorDict   /setscreen              1 put
        !           484: OperatorDict   /settransfer            1 put
        !           485: OperatorDict   /show                   1 put
        !           486: OperatorDict   /showpage               1 put
        !           487: OperatorDict   /start                  1 put
        !           488: OperatorDict   /stop                   1 put
        !           489: OperatorDict   /store                  1 put
        !           490: OperatorDict   /stroke                 1 put
        !           491: OperatorDict   /strokepath             1 put
        !           492: OperatorDict   /translate              1 put
        !           493: OperatorDict   /widthshow              1 put
        !           494: OperatorDict   /write                  1 put
        !           495: OperatorDict   /writehexstring         1 put
        !           496: OperatorDict   /writestring            1 put
        !           497: 
        !           498: end def
        !           499: 
        !           500: %
        !           501: % Put an object on the stack and call Grabit. Output continues until stack
        !           502: % is empty. For example,
        !           503: %
        !           504: %              /letter load Grabit
        !           505: %
        !           506: % prints a listing of the letter procedure.
        !           507: %
        !           508: 
        !           509: /Grabit {
        !           510:        /saveobj save def
        !           511:        GrabitDict begin
        !           512:                {
        !           513:                        count 0 eq {exit} if
        !           514:                        count {dup type exec} repeat
        !           515:                        (\n) print flush
        !           516:                } loop
        !           517:        end
        !           518:        currentpoint                    % for hardcopy output
        !           519:        saveobj restore
        !           520:        moveto
        !           521: } def
        !           522: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.