Yapp (yet another pretty print)

new topic     » topic index » view thread      » older message » newer message

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

new topic     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu