*
; /* From - Mon Apr 22 15:37:36 1996 Comments: Gated by NETNEWS@AUVM.AMERICAN.EDU Newsgroups: comp.soft-sys.sas Date: Thu, 18 Apr 1996 15:03:00 +0000 Reply-To: wood-st@cityscape.co.uk Sender: "SAS(r) Discussion";Comments: Authenticated sender is From: Philip & Esther Mason Subject: SUGI Programmers Toolkit Update For those who attended SUGI and got the Programmers Toolkit, Ian Whitlock has kindly provided a correction to a macro in the SUGI Programmers Toolkit. Here is the complete version in a working form. Phil */ %macro wordwrap ( inray= , /* input array name */ inlen=200, /* length of variables in input array */ outray= , /* output array name */ outlen= , /* length of variables in output array */ debug= *** /* null value for debugging */ ) ; %* All parameters null by default are required ; %local p q plen qlen blank ; %let p = %upcase(&inray) ; %let q = %upcase(&outray) ; %let plen = &inlen ; %let qlen = &outlen ; %let blank = %str( ) ; %*----------------------------------------------------------------- *; %* Purpose: *; %* Text stored in &inray from a long character string (over 200 *; %* bytes. Array elements are not word boundaries. The text is *; %* moved to &outray with space filling at the end so that no word *; %* crosses an array element in &outray. *; %* *; %* Assumptions: *; %* Parameters null by default are required *; %* When a word in &inray is longer than &outlen abort *; %* *; %* Working variables: *; %* begin __p when associated with &inray and __q for &outray *; %* __px, __qx - index to respective arrays *; %* __rpb , __rqb - relative begin pointers within array element *; %* __rpe - relative end pointer within array element *; %* __pb , __pe - absolute (full string) begin and end *; %* pointers to substring of &inray *; %* __pc - one byte character value from &inray *; %* __sublen - length of substring within an array element *; %* *; %* Basic algorithm: *; %* initialize __pe = 0 *; %* loop over index of &outray until finished *; %* __pb = __pe + 1 *; %* set __pe to maxium that will fit in &outray *; %* back up to space when next character is not a space *; %* move substring to &outray (will require two moves when *; %* substring begins and ends on different elements *; %* end loop *; %* ---------------------------------------------------------------- *; drop __: ; __pe = 0 ; do __qx = lbound(&q) to hbound(&q) until ( __pe >= &plen * dim(&p) ) ; __pb = __pe + 1 ; &debug put __qx= __pb= ; if &p ( %px(__pb) ) = " " then do ; __qx = __qx - 1 ; leave ; end ; else do ; __pe = min ( &plen * dim ( &p ) , __pb + &qlen - 1 ) ; /* skip backup test when pe is at the end of full string */ if __pe = &plen * dim ( &p ) then ; else if substr ( &p ( %px(__pe+1) ), %pp(__pe+1), 1 ) ^= "&blank" then do ; /* back up to first blank */ do __pe = __pe to __pb by - 1 until ( __pc = "&blank" or __pe < __pb ) ; &debug __px = %px(__pe) ; &debug __rpe = %pp(__pe) ; __pc = substr ( &p(%px(__pe)) , %pp(__pe) , 1 ) ; &debug put 'backup ' __pe= __pc= __px= __rpe= &p(__px)=; end ; if __pe < __pb then do ; /* token to long to process */ __px = %px ( __pb ) ; put 'WORDRAP: token too long - aborting ' / "input: &p(" __px +(-1) ')=' &p ( __px ) $char&plen.. ; __px = __px + 1 ; put "input: &p(" __px +(-1) ')=' &p ( __px ) $char&plen.. ; abort 99 ; end ; end ; /* move substring to q array */ __rqb = 1 ; do while ( %px(__pb) ^= %px(__pe) ) ; __px = %px(__pb) ; __rpb = %pp(__pb) ; __sublen = &plen - __rpb + 1 ; &debug put 'partial move ' __px= __rpb= __sublen= ; substr ( &q ( __qx ) , __rqb ) = substr ( &p(%px(__pb)), __rpb, __sublen ) ; &debug put &q(__qx)= ' incomplete' ; __rqb = __sublen + 1 ; __pb = ( __px ) * &plen + 1 ; &debug put 'after partial move ' __pb= __rqb= ; end ; /* move part on end elelement */ &debug __rpb = %pp(__pb) ; &debug __sublen = __pe - __pb + 1 ; &debug __px = %px(__pe) ; &debug put 'completed move ' __px= __pb= __pe= __rqb= __rpb= __sublen= ; substr ( &q ( __qx ) , __rqb ) = substr ( &p(%px(__pe)) , %pp(__pb) , __pe - __pb + 1 ) ; &debug put &q ( __qx ) = ; end ; end ; do __qx = __qx + 1 to dim ( &q ) ; &q ( __qx ) = ' ' ; end ; %mend wordwrap ; %macro pp ( ptr ) ; /* relative pointer to the p array element */ mod ( ( &ptr - 1 ) , &plen ) + 1 %mend pp ; %macro px ( ptr ) ; /* index to the p array */ int ( ( &ptr - 1 ) / &plen ) + 1 %mend px ; /*-----------------------------------------------------------+ ! Philip Mason Email: wood-st@cityscape.co.uk ! ! Freelance SAS Consultant ! ! & SUGI-22 Applications Development co-chair ! +----------------------------------------------------------+ ! 16 Wood Street, Wallingford, OXON., OX10 0AY, England ! ! Phone/Fax: +44 1491 824905 ! -----------------------------------------------------------+*/ *