Yapp (yet another pretty print)
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> May 19, 2003
- 436 views
I've just cleaned up my version of pretty print. If anyone wants to give it a whirl let me know if there is anything you don't like: There's not much benefit if you throw it a short string, it needs a big table type thing to shine. Pete -- -- Yapp. Yet another pretty print -- Author Pete Lomax -- -- usage(1): prnt(object,nest) outputs to screen, breaks lines longer -- than 78 characters, pauses every 23=20 -- lines. See examples for use of "nest". -- -- usage(2): prntEx(file,object,maxlen,pause,format,nest) -- -- where file specifies the output, typically 1 to screen, or a file -- opened by the calling application, or if 0 is passed,=20 -- the result is left (with embedded \n characters) in=20 -- the global sequence pres, -- object is the item to be printed, -- maxlen is the line length to split long lines, typically 78=20 -- (the default if 0 is passed) -- pause is the number of lines displayed between pauses,=20 -- typically 23, or if 0 is passed it never pauses, and -- format 0 prints strings as is, 1 number only, 3 number&text. -- eg "abc" {97, 98, 99} {97a, 98b, 99c} -- nest indicates nesting levels to force new lines eg: -- -- obj=3D{1,{2,{3,3},2},1} -- nest=3D0 -- prnt(obj,nest) gives:=20 --=20 -- {1, {2, {3, 3}, 2}, 1} -- -- same, with nest=3D1 gives: -- -- { 1, -- { 2, { 3, 3}, 2}, -- 1} -- -- same, with nest=3D2 gives: -- -- { 1, -- { 2, -- { 3, 3}, -- 2}, -- 1} -- -- nest may also be passed as a sequence of {indent,nest_level}. -- In the above examples, note how the 1, {, and 1 display in the=20 -- same column. If an indent level is specified, spaces are inserted=20 -- in the "{1" to maintain alignment. -- -- eg same, with nest=3D{3,2} gives: -- -- { 1, -- { 2, -- { 3, 3}, -- 2}, -- 1} -- -- same, with nest=3D{1,2} gives: -- -- {1, -- {2, -- {3, 3}, -- 2}, -- 1} -- -- The default indent level is 2, unless the atom 0 is passed -- it is one (see the first example) -- -- Also, specifying a nest-level of -1 suppresses the trailing \n -- without trace integer maxlen -- break lines longer than this integer nindent -- indent increment when nesting integer pause -- pause display after this many lines integer format -- 0=3Dtext as strings,=20 -- 1 as numbers,=20 -- 3 as txt&number sequence pline -- output line, as built by sput() integer plen plen=3D0 -- used part of pline; rest is garbage integer sline sline=3D0 -- counter for screen line -- -- bundle "puts(1," calls together and output one line at a time... -- integer ofile global sequence pres -- print result if file is passed as 0 procedure spurge() if ofile then puts(ofile,pline[1..plen]) else pres&=3Dpline[1..plen] end if plen=3D0 end procedure procedure sput(object txt) integer p p=3Dplen+1 if atom(txt) then plen+=3D1 else plen+=3Dlength(txt) end if if plen>length(pline) then pline&=3Drepeat(0,plen-length(pline)) end if pline[p..plen]=3Dtxt if pline[plen]=3D'\n' then spurge() sline+=3D1+(plen>maxlen) if pause and sline >=3D pause then if getc(0) then end if sline=3D0 end if end if end procedure without warning -- suppress short-circuit warning function prnf(object cl, integer col, integer indent, integer prnt, integer break) integer len integer aschar sequence sep,txt if sequence(cl) then if format=3D0 then aschar=3Dlength(cl) for i=3D1 to length(cl) do if sequence(cl[i]) or cl[i]<' ' or cl[i]>'~' then=20 aschar=3D0=20 exit=20 end if end for if aschar then if prnt then sput('\"'&cl&'\"') end if return length(cl)+2 end if end if len=3Dnindent=09 if prnt then sput('{'&repeat(' ',nindent-1)) end if sep=3D"" for i=3D1 to length(cl) do if (i>1 and break>0) or prnf(cl[i],col+len,col+nindent,0,break-1)+ col+len+length(sep)+2>=3Dmaxlen then if not prnt then return maxlen+1 end if sput(",\n") sput(repeat(' ',indent+nindent)) len=3Dnindent col=3Dindent sep=3D"" end if if prnt then sput(sep) end if len+=3Dlength(sep) len+=3Dprnf(cl[i],col+len,col+nindent,prnt,break-1) sep=3D", " end for if prnt then sput('}') end if return len+1 end if if integer(cl) then if format=3D3 and cl>=3D' ' and cl<=3D'~' then txt=3Dsprintf("%d%s",{cl,cl}) else txt=3Dsprintf("%d",cl) end if else txt=3Dsprintf("%3.2f",cl) end if if prnt then sput(txt) end if return length(txt) end function with warning global procedure prntEx(integer file, object o, integer maxln,=20 integer pauze, integer fmt, object nest) -- file: 1 for screen, 0 leaves result in global sequence 'pres'. -- o is the object to be printed -- maxln (defaults to 78 if 0 is passed) for splitting long lines -- pauze (suggested 23, or 0 for no pausing) prompts every n lines -- fmt 0 prints text strings as eg "abc",=20 -- 1 as {97, 98, 99},=20 -- 3 as {97a, 98b, 99c} -- nest indicates nesting levels to force new lines, -- or can be passed as {indent, nest_level} -- ofile=3Dfile if maxln=3D0 then maxln=3D78 end if maxlen=3Dmaxln pline=3Drepeat(9,maxlen+1) -- space for \n pause=3Dpauze format=3Dfmt pres=3D"" nindent=3D2 if sequence(nest) then nindent=3Dnest[1] nest=3Dnest[2] elsif nest=3D0 then nindent=3D1 end if if prnf(o,0,0,1,nest) then end if if nest>=3D0 then=20 sput("\n") elsif plen then spurge() end if end procedure =09 global procedure prnt(object o, object nest) prntEx(1,o,78,23,0,nest) end procedure