%macro formchar(fileref,fcstring); %local __lsold __number __fflag __pgno; /******************************************************************/ /* COPYRIGHT 1993 by Kernon M. Gibes */ /* */ /* FILESPEC: SAS$ROOT:[CUSTOM.AUTO]FORMCHAR.TPU;1 */ /* SYSTEM: VAX/VMS */ /* LANGUAGE: SAS 6.07 Macro */ /* ABSTRACT: SAS macro to replace the ASCII codes of a SAS */ /* PROC TABULATE FORMCHAR string with the DEC */ /* Special Graphic (DSG) characters and escape */ /* sequences in order to produce solid-lined */ /* tables on DEC VTxxx/LN0x equipment. */ /* VERSION: 2.0 */ /* DATE: January 1993 */ /* AUTHOR: Kernon M. Gibes */ /* */ /* INPUT: File reference (logical name) and, optionally, */ /* a FORMCHAR hex string */ /* */ /* OUTPUT: Edited file sent to procedure output destination */ /* */ /* USAGE: %FORMCHAR(fileref[,fcstring]) */ /* */ /* fileref = file reference used with PRINTTO */ /* fcstring = optional FORMCHAR string used, in */ /* format 'xxxxxxxxxxxxxxxxxxxxxx'X, */ /* if not given, defaults to global */ /* value */ /* */ /* NOTES: This macro currently only supports CC=CR */ /* carriage control, and line sizes up to 200. */ /******************************************************************/ %if &fileref=%then %do; %put ; %put ERROR: FORMCHAR macro requires a fileref (logical name); %put %str( ) No fileref was specified at invocation.; %put %str( ) Macro FORMCHAR aborted.; %end; %else %do; /* Get the current values of the LINESIZE and NUMBER */ /* global options, and the fileref that should have */ /* been specified at invocation: */ proc sql; reset noprint; select setting into :__lsold from dictionary.options where optname in ('LINESIZE'); select setting into :__number from dictionary.options where optname in ('NUMBER'); select fileref into :__fflag from dictionary.extfiles where fileref="%upcase(&fileref)" ; /* If necessary, get the FORMCHAR global option */ %if &fcstring=%then %do; select setting into :globalfc from dictionary.options where optname in ('FORMCHAR'); quit; %end; %else %do; quit; %end; %if &__fflag=%then %do; %put ; %put ERROR: FORMCHAR macro requires a fileref (logical name); %put %str( ) The given fileref, "&fileref", does not exist; %put %str( ) Macro FORMCHAR aborted.; %end; %else %do; %if &__lsold gt 200 %then %do; %put ; %put WARNING: FORMCHAR macro can only process line sizes to 200.; %put %str( ) Since the linesize is greater than 200, note; %put %str( ) that unpredictable results may occur.; %end; /* Set linesize to maximum in order to accommodate the */ /* many-to-one mapping of FORMCHAR characters to DEC escape */ /* escape sequences. */ options ls=256; /* Use a "null" data step to read in the TABULATE output, */ /* and do all FORMCHAR mappings for solid-lines: */ data _null_; length buffer $ 200 fc $ 11 char escape SI formfeed $ 1 fc1 - fc11 $ 6 firstff numflag chknum 2 ; retain firstff 1 chknum 0 %if &fcstring=%then fc "&globalfc"; %else fc &fcstring; %if &__number=NUMBER %then numflag 1; %else numflag 0; formfeed '0C'X escape '1B'X SI '0F'X ; /* Initialize the array of DEC escape sequences that each */ /* FORMCHAR character must be mapped into. */ array _fcmap {11} fc1 - fc11 ('8F78'X, 'q', '1B2B301B6F6C'X, 'w', '6B0F'X, '1B6F74'X, 'n', '750F'X, '1B6F6D'X, 'v', '6A0F'X ); file print print notitles; infile &fileref noprint length=len; input buffer $varying200. len; /* Check for new page (formfeed). Only the very first */ /* one can be ignored, otherwise start a new page, and set */ /* a flag for parsing the page number (if necessary). */ if buffer=formfeed then do; if numflag then chknum=1; if firstff then firstff=0; else put _page_; end; else do; /* If this is the first line and page numbering is */ /* on, parse out the current value so that it can be */ /* used to reset the page number later on. */ if chknum then do; do i=length(buffer) to 1 by -1 while(substr(buffer,i,1) ne ' '); end; call symput('__pgno',substr(buffer,i)); chknum=0; put buffer $varying200. len; end; else do; /* For each character in the input file, check to */ /* see if it is a FORMCHAR character. If not, just */ /* output it. If it is, output the appropriate */ /* DEC escape sequence. */ do i=1 to length(buffer); char=substr(buffer,i,1); j=index(fc,char); if j>0 then do; l=length(_fcmap[j]); put _fcmap[j] $varying6. l @; end; else put char $1. @; end; put; end; end; run; /* Reset the linesize */ options linesize=&__lsold; %if &syserr=0 %then %do; %put NOTE: FORMCHAR re-processing of TABULATE output completed.; %if &__number=NUMBER %then %do; options pageno=%eval(1+&__pgno); %put %str( ) Page numbering reset to start at %eval(1+&__pgno); %end; %else %do; %put %str( ) Page numbering not reset.; %end; %put ; %end; %else %do; %put ; %put ERROR: FORMCHAR re-processing of TABULATE output failed.; %put %str( ) Unknown error occurred during processing.; %end; %end; %end; %mend formchar;