Macro TextLine

From sasCommunity
Jump to: navigation, search

2008-Dec-19 RJF2

This is an interesting look back in time, to see how I was writing back in 2002. I have been polishing this macro this week after I mentioned in in my paper on Setting Up an Autoexec. I made several modifications and was stuck with an off-by-one error. Once I put in the testing variable and messages, the problem and solution were much easier to see and fix.

I have decided to leave the original code which I had harvested from my SAS-L post so you can see the differences.


Macro TextLine: New and Improved

 /*    name: ?:\SAS-site\macros\TextLine.sas
       is.a: macro function
description: returns set of quoted spaces
             which justify named arguments (left=, center=, right=)
             within one title or footnote statement
purpose    : control of pagination
usage: any title or footnote
%Let TextLine = %sysfunc(time(),time5.)%sysfunc(date(),weekdate29.);
%Put TextLine:&TextLine.;
Title1
%TextLine(Left   = '4:project name'
         ,Right  = "&TextLine."
         ,RM     =  4
         );*move RightMargin to left for page number;
Title3 %TextLine(Left   = 'Left'
                ,Center = 'Centered'
                ,Right  = 'Right');* closure Title;
;/* ****************************************************** */
%MACRO TextLine
(Left     = ' '
,Center   = .
,Right    = ' '
,RM       = 0  /*RightMargin: number of chars to move left
                 suggest: 4,
                 for Title1: replace SysDate w/current time+datestamp */
,LineSize = %sysfunc(getoption(linesize))
,Testing  = 0
)/ des = 'site: justify items running text: title or footnote'
 /* ** store source /* *** */
;/* ************************************
02Nov15 RJF2 written
02Dec11 RJF2 polishing for SAS-L stocking stuffer
08Dec19 RJF2 polishing for book macro, added testing
******* ***/
%let Testing  = %eval(&Testing.
                or %sysfunc(getoption(mprint)) eq MPRINT);
%local Half Len_Left Len_Center Len_Right
       SpacesLeft SpacesCntr SpacesRite;
 
%let Len_Left   = %eval(%length(&Left.)  -2);%* two quotes;
%let Len_Center = %eval(%length(&Center.)-2);
%let Len_Right  = %eval(%length(&Right.) -2);
 
%if  &Center. eq . %then %let Len_Center = 0;
 
%let Half       = %eval(&LineSize./2 -(&Len_Center./2));
 
%let SpacesLeft = %eval(&Half.    - &Len_Left. );
%let SpacesCntr = %eval(&LineSize.- &Len_Left.
                                  - &Len_Right.
                                  - &RM.       );
%let SpacesRite = %eval(&Half.    - &Len_Right.
                                  - &RM.       );
%if   &Center. eq . %then %do;
      %if %eval( &Len_Left   + &Len_Right.
           + &SpacesCntr.) gt &LineSize. %then
          %let SpacesCntr = %eval(&SpacesLeft. -1);
      %end;
%else %if %eval( &Len_Left   + &Len_Center. + &Len_Right.
               + &SpacesLeft + &SpacesRite.) gt &LineSize. %then
      %let SpacesLeft = %eval(&SpacesLeft. -1);
 
%if &Testing. %then %do;
    %put _local_;
    %put &SysMacroName: sum(left, center, right)%eval
        (&Len_Left + &Len_Center. + &Len_Right.);
    %put &SysMacroName: sum(spaces:left,  right)%eval
        (&SpacesLeft + &SpacesRite.);
    %end;
 
&Left.
%if   &Center. ne . %then %do;
      "%sysfunc(repeat(%str( ),&SpacesLeft. - 1))"
       &Center.
      "%sysfunc(repeat(%str( ),&SpacesRite. - 1))"
      %end;
%else "%sysfunc(repeat(%str( ),&SpacesCntr. - 1))";
&Right.
%Mend;

Test Data

*name: TestLine-Test;
* note: if you set linesize that constrains the log as well;
* so: use a macro variable to test and leave the log max;
%Let TestLineSize = 80;
 
options  date number
         mprint
         %*symbolgen; %* why I have testing message;
         linesize = max
         pagesize = max;
 
%*reference lines;
Title3
"%sysfunc(repeat(.   +    !,(%sysfunc(getoption(linesize))/10) -1))";
Title4
"%sysfunc(repeat(1234567890,(%sysfunc(getoption(linesize))/10) -1))";
PROC Print data = SAShelp.Class(obs = 1);
run;
Title3
%TextLine(Left   = '3:Text on left'
         ,Center = '.!.'
         ,Right  = 'Right --]'
         ,LineSize = &TestLineSize.
         );
%*Let TextLine = %cmpres(%sysfunc(time(),time5.)
               )%cmpres(%sysfunc(date(),weekdate29.));
%Let TextLine = %sysfunc(time(),time5.)%sysfunc(date(),weekdate29.);
%Put TextLine:&TextLine.;
Title4
%TextLine(Left   = '4:project name'
         ,Right  = "&TextLine."
         ,RM     =  4
         ,LineSize = &TestLineSize.
         );*move RightMargin to left for page number;
 
%Let TextLine = %sysfunc(time(),time5.)%sysfunc(date(),weekdate29.);
%Put TextLine:&TextLine.;
Title5
%TextLine(Left   = '5:34567890123456789012345678901234567890'
         ,Right  = "&TextLine."
         ,LineSize = &TestLineSize.
         );
%Let TextTime = %sysfunc(time(),timeampm7.);
%Put TextTime:&TextTime.;
%Let TextDate = %sysfunc(date(),date.);
%Put TextDate:&TextDate.;
 
Title6
%TextLine(Left   = '6:test of timeline w/2 mVars'
         ,Center = "&TextTime."
         ,Right  = "&TextDate."
         ,LineSize = &TestLineSize.
         );
%Let TextLine = %sysfunc(datetime(),datetime29.2);
%Let TextLine = %cmpres(&TextLine.);
%Put TextLine:&TextLine.;
Title7
%TextLine(Left   = '7: mvarTime centered'
         ,Center = "&TextLine."
         ,LineSize = &TestLineSize.
         );
%*Let TextLine = %sysfunc(time(),time5.)%sysfunc(date(),weekdate28.);
%*Let TextLine = %sysfunc(time(),timeampm8.)%sysfunc(date(),weekdate28.);
%Let TextLine = %sysfunc(date(),weekdate28.);
%Let TextLine = %sysfunc(time(),timeampm8.) &TextLine.;
%Put TextLine:&TextLine.;
Title8
%TextLine(Left   = '8:left'
         ,Right  = "right: &TextLine."
         ,LineSize = &TestLineSize.
         );
%Let TextLine = %sysfunc(datetime(),dateampm18.);
%Put TextLine:&TextLine.;
Title9
%TextLine(RIGHT  = "&TextLine."
         ,LineSize = &TestLineSize.
         );
%*note use of two TextLines in one Title
       linesize==div(linesize,2);
Title10
%TextLine(CENTER ='TEXT on left half'
         ,LINESIZE = %eval(&TestLineSize./2)
         )
%TextLine(CENTER ='right half TEXT'
         ,LINESIZE = %eval(&TestLineSize./2)
         );
 
Proc SQL; select Text from Dictionary.Titles;
          quit;
run;

Macro TextLine: Old

/*macro TEXTLINE macro function returns quoted strings
                       justified in(left, center, right)
usage:
TITLE
%TEXTLINE(LEFT   = 'Left'
         ,CENTER = 'Centered'
         ,RIGHT  = 'Right'
         );%*closure TITLE;
TITLE1
%TEXTLINE(LEFT   = 'project name'
         ,RIGHT  = "%sysfunc(time(),time5.)%sysfunc(date(),weekdate29.)"
         ,RM     = -4
         );%*move RightMargin to left for page number;
TITLE1
%TEXTLINE(LEFT   = 'test of mvarTime'
         ,NOCENTER = 1
         ,RIGHT
="%MVARTIME(RETURN=%nrstr(&TIMEAMPM)) %MVARTIME(RETURN=%nrstr(&WEEKDATE))"
         ,RM     = -4
         );
NOTE if placing current time and/or date in TITLE1
     remember to set options nodate
     else SAS will put &SYSDATETIME in next empty TITLE line;
see test data for use with MVARTIME
 /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
%MACRO TEXTLINE
(LEFT     = ' '
,CENTER   = ' '
,RIGHT    = ' '
,NOCENTER = 0  /*use Center?*/
,RM       = 0  /*RightMargin: move left with negative value
                 suggest: -4,
                 for TITLE1: replace SYSDATE w/current time+datestamp */
,LINESIZE = %sysfunc(getoption(linesize))
);/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -**
RJF2 02Nov15 longest day  : Wednesday,
                     month: September
     time: HH is in 1:24
hh:mm Wednesday, September 31, 2002
15:29 Monday, November 18, 2002
      123456789012345678901234567890 weekdate29.
problem: need weekdate width to vary with Month, and WeekDay
see mVars of DAY MONTH DD CCYY TIME_HH TIME_MM
note: defaults values of LEFT CENTER and RIGHT are char1.
      BUT macro %length is 3, not 1
      THEREFORE see fudge in repeat is not -1, but +1
RJF2 02Dec11 polishing for SAS-L stocking stuffer
;/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
&LEFT.
 
%IF &NOCENTER. %THEN %DO;
    "%sysfunc(repeat(%str( ),&LINESIZE.+3-%length(&LEFT. )
                                        -%length(&RIGHT.)
                                        +       (&RM.   )))"          
   %END;
%ELSE %IF not &NOCENTER. %THEN %DO;
   %local HALF LEN_CNTR;
   %LET LEN_CNTR = %length(&CENTER.);
   %LET HALF     = %eval(&LINESIZE./2 -(&LEN_CNTR./2));
   "%sysfunc(repeat(%str( ),&HALF. +1-%length(&LEFT. )))"
   &CENTER.
   "%sysfunc(repeat(%str( ),&HALF. +1-%length(&RIGHT.)
       + %eval(&LEN_CNTR. - 2*(&LEN_CNTR./2)) + (&RM.)))"             
   %END;
&RIGHT.
%Mend;

Test Data

 /*TEST DATA ********************************************************/
options symbolgen linesize = 66 nocenter;%*testing;
options symbolgen linesize = 80 nocenter;%*need this for time+date;
%*PUT LINESIZE<%sysfunc(getoption(linesize))>;
TITLE1 'test of! center';
TITLE1
%TEXTLINE(LEFT   = 'Text on left'
         ,CENTER = '.!.'
         ,RIGHT  = 'Right --]'
         );
TITLE1
%TEXTLINE(LEFT   = 'project name'
         ,RIGHT  = "%sysfunc(time(),time5.)%sysfunc(date(),weekdate29.)"
         ,RM     = -4
         );%*move RightMargin to left for page number;
TITLE2
%TEXTLINE(LEFT   = '1234567890123456789012345678901234567890'
         ,NOCENTER = 1
         ,RIGHT  = "%sysfunc(time(),time5.)%sysfunc(date(),weekdate29.)"
         );
%LET DATESTMP
= %MVARTIME(RETURN=%NRSTR(&TIMEAMPM)) %MVARTIME(RETURN=%NRSTR(&WEEKDATE));
%PUT DATESTMP<&DATESTMP.>;
 
TITLE3
%TEXTLINE(LEFT   = 'test of mvarTime w/mVar'
         ,RIGHT  = "&DATESTMP."
         );
TITLE4
%TEXTLINE(LEFT   = 'test of mvarTime'
         ,CENTER
="%MVARTIME(RETURN=%nrstr(&TIMEAMPM)) %MVARTIME(RETURN=%nrstr(&WEEKDATE))"
         );
TITLE5
%TEXTLINE(LEFT   = 'left'
       ,RIGHT  =
"%sysfunc(time(),time5.)%sysfunc(date(),weekdate28.)"
         );
TITLE6
%TEXTLINE(RIGHT  = "%sysfunc(datetime(),dateampm18.)"
         );
%*note use of two TEXTLINEs in one TITLE
       linesize==div(linesize,2);
TITLE7
%TEXTLINE(CENTER ='TEXT on left half'
         ,LINESIZE = %sysfunc(getoption(linesize))/2
         )
%TEXTLINE(CENTER ='right half TEXT'
         ,LINESIZE = %sysfunc(getoption(linesize))/2
         );
%*reference lines;
TITLE8
"%sysfunc(repeat(.    +    !,(%sysfunc(getoption(linesize))/10) -1))";
TITLE9
"%sysfunc(repeat(1234567890,(%sysfunc(getoption(linesize))/10) -1))";
 
data _NULL_;
file PRINT;
put 'TEXTLINE test';
stop;
run;
;/*********************************************************************/

References

--Ron_Fehd macromaven == the radical programmer 15:11, 5 December 2008 (EST)

--Ronald_J._Fehd macro.maven == the radical programmer 15:56, 18 January 2013 (EST)