%---------------------------------------------------------------------------
% Time-stamp: "2005-08-19 00:24:30 ADT" -*-coding:latin-1;-*- µ
%
% desc{ PostScript function library for dumping PostScript data structures as XML. }
% 2005 Sean M. Burke «sburke@cpan.org»
%
% Examples:
%
%
% From the shell:
%
% echo '(ps2xml.ps)run devicenames XML_dump' | gs -q - | less
%
% echo '(ps2xml.ps)run (gsdevs.xml) devicenames XML_dump_to_file' | gs -q -
%
%
% To exercise the the dumper a bit, try these from the "GS>" prompt:
%
%[ true /crunk false [[(oboy)] (stuff\n) (thingsé) (Pie) -456 ] -3543.45] XML_dump_doc
%[ (Pies\n) ] XML_dump_doc
%[ true (crunk) false [[(oboy)] (stuff\n) (thingsé) (Pie) -456 ] -3543.45] XML_dump_doc
%
%() [123] XML_dump_to_file ==
%
%() [ true cvx (crunk) executeonly false [[(oh boy!)] (stuff\n) (\000\176\177\200\201\202\203
!&"\(\)\n\tingsé) (Pie) -456 ]]
%XML_dump_to_file ==
%
% [ true cvx (crunk) executeonly false [[(oh boy!)] (stuff\n) (\000\176\177\200\201\202\203 | !&"\(\)\n\tingsé) (Pie) -456 ]] XML_dump_doc
%
%--------------------------------------------------------------------------
/!! {(ps2xml.ps) run } def
/P {XML_out_fh exch writestring} def
/i2s { 40 string cvs } bind def
/name2s { dup length string cvs } bind def
/i2hex { 16 20 string cvrs } bind def
/i2chr { 1 string dup 0 4 -1 roll put } bind def
/@ { %% string1 string2 @ => string ("@" because it ATpends strings)
2 copy length exch length add string dup 4 2 roll 2 index 0 3 index
putinterval exch length exch putinterval
} bind def
/filenamecounter 0 def
/newfilename {
(psdata_)
realtime dup 0 lt { 16#80000000 sub } if i2hex
@
(_) @
usertime i2hex @
(_) @
filenamecounter 1 add dup /filenamecounter exch def i2hex @
(.xml) @
} def
% ---------------------------------------------------------------------------
/EscForm 256 array def
16#00 1 16#ff { EscForm exch dup () exch i2s @ (;) @ put } for
/to_e0xx { EscForm exch dup () exch 16#e000 add i2hex @ (;) @ put } def
/literally { { EscForm exch dup i2chr put } } def
% Now Move fishy stuff into U+E000 - U+E00FF (e.g., U+E07f-U+E09f)
% From XML 1.1 spec: "[#x1-#x8] | [#xB-#xC] | [#xE-#x1F]
% | [#x7F-#x84] | [#x86-#x9F]"
16#00 1 16#08 { to_e0xx } for
16#0b to_e0xx
16#0c to_e0xx
16#0e 1 16#1f { to_e0xx } for
16#7f 1 16#9f { to_e0xx } for
% Now things that don't need escaping:
(!#$%=) literally forall
16#28 1 16#3b literally for
16#3f 1 16#7e literally for
% Since we declare latin-1 output encoding, we can leave these as literals too:
16#a1 1 16#ff literally for
% ---------------------------------------------------------------------------
/printEsc { { EscForm exch get P } forall } def
/IndentLevel 0 def
/++ { /IndentLevel IndentLevel 1 add def } def
/-- { /IndentLevel IndentLevel 1 sub def } def
/I { IndentLevel {( )P} repeat } def
/How 20 dict def
How /stringtype {I(\n)P } put
How /nametype {I(\n)P } put
How /integertype {I(\n)P } put
How /realtype {I(\n)P } put
How /marktype {I(\n)P pop } put
How /nulltype {I(\n)P pop } put
How /booleantype {dup I{(\n) P } put
How /operatortype {I(\n)P } put
How /arraytype {I(\n)P
++ {XML_dump} forall -- I (\n)P } put
How /packedarraytype {I(\n)P
++ {XML_dump} forall -- I (\n)P } put
How /dicttype {
I(\n)P
++
{
exch
I(\n)P ++ I(\n)P ++ XML_dump -- % key
I(\n)P I(\n)P ++ XML_dump -- % value
I(\n)P -- I(\n)P
} forall
--
I(\n)P
} put
/R { dup rcheck not {(executeonly="1" ) P pop (-)} if } def
/W { dup wcheck not {(readonly="1" ) P } if } def
/X { dup xcheck {(executable="1" ) P } if } def
%---------------------------------------------------------------------------
/XML_dump {
dup type How exch known {
dup type How exch get exec
} {
type I(\n)P
} ifelse
} def
/XML_dump_doc {
(\n) P
(\n) P
%(\n)P
XML_dump
(\n) P
} def
/XML_out_fh (%stdout) (w) file def
/XML_dump_to_file {
% filename obj XML_dump_to_file => realfilename
%
% If filename is (), output is to a uniquely named file, which you
% get as the return value.
exch
dup length 0 eq { pop newfilename } if
dup /XML_out_filename exch def
(w) file
/XML_out_fh exch def
XML_dump_doc
XML_out_fh closefile
/XML_out_fh (%stdout) (w) file def
XML_out_filename
/XML_out_filename ("-") def
} def
%End
|