BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
KevinViel
Pyrite | Level 9

How can I avoid having a word broken instead of the breaking on the white space before it?

 

I thought about writing a PRXCHANGE function to substitute the first space before the non-space characters that exceed a certain length but that would probably challenge me and it would like have to be in a loop, since my Regex skills are functions, not superb 🙂

 

I would appreciate any suggestions or references.

 

Thank you,


Kevin

 

PS  I note that the documentation specifies:

 

FLOW

wraps the value of a character variable in its column. The FLOW option honors the split character. If the text contains no split character, then PROC REPORT tries to split text at a blank.
Restriction This option only affects the LISTING output. It has no affect on other ODS output.
1 ACCEPTED SOLUTION

Accepted Solutions
Cynthia_sas
SAS Super FREQ

Hi:

  I'm just not sure why you are worrying so much about the length or the wrapping. I would not bother. If INDENT= is not what you want and you DO want the wrapped text to be indented, then the LEFTMARGIN= attribute does that, as shown below.

 

more_indent.png

 

 Before you go into template land, you can experiment with CELLPADDING values and fonts in PROC REPORT and THEN, after you find the values that give you  the report you want, you can move them to a style template. The TABLE element will apply to the PROC  REPORT table. I like to start with the PROC REPORT attributes in the PROC REPORT code, so I can experiment to see which values I want to use and then, after that I move into template land.

 

  Here's my paper about tiptoeing through the templates: https://support.sas.com/resources/papers/proceedings09/227-2009.pdf  and the one on style templates: https://support.sas.com/resources/papers/proceedings10/033-2010.pdf .

 

  And, here's an example of wrapping long text along with using INDENT or LEFTMARGIN:

longtext.png

 

I did turn on the border lines and interior table lines in the long text example so you could be assured that the INDENT and LEFTMARGIN were working as designed.

 

I find that ODS and SAS do a good job of not splitting words at a bad place such that I do not need to over-control the text strings by inserting my own line breaks. The only time I really insert line breaks is when I want to "stack" information in one cell and control exactly where the line break will occur, such as:

data newclass;
  set sashelp.class(obs=2);
  length newvar1 newvar2 $200;
  newvar1 = cat('Name: ',name,'~{newline 1}','Sex: ',sex,'~{newline 1}','Age: ',put(age,2.0));
  newvar2 = cat('Height:',put(height,5.1),'~{newline 1}','Weight: ',put(weight,5.1));
run;

ods escapechar='~';
proc report data=newclass;
column newvar1 newvar2;
run;

  Perhaps I am missing the big picture, but you're not showing all your code and all your data, but based on what you've indicated so far, I don't think you need to go down the REGEX road or insert your own NEWLINE characters.

 

cynthia

View solution in original post

4 REPLIES 4
art297
Opal | Level 21

Kevin,

 

Is there a chance that you have "asis=on" within your style?

 

Art, CEO, AnalystFinder.com

 

Cynthia_sas
SAS Super FREQ

Hi:

  Are you using INDENT= to do your indent or did you pad the sentence with blanks. I found that INDENT= worked for me. I tried fiddling with the WIDTH= value quite a bit and could not make it split "the" or "completed" as you experienced.

 

  Also not sure why you included the doc reference on FLOW -- it is a LISTING only option and irrelevant to ODS PDF and other ODS destinations (sort of like HEADLINE, HEADSKIP, SPACING and SKIP -- just not used by any destination except LISTING).

 

cynthia

 

width_indent.png

KevinViel
Pyrite | Level 9

Cynthia,

 

  I included the documentation on Flow to let reader know that I was aware of this option and that, as you observed, is for the LISTING destination.

 

  I should have given more details: Times New Roman, 10 pt, with

 

class table from output

/ frame = hsides

rules = groups

cellpadding = 2.0pt

cellspacing = 0.5pt

borderwidth = 1.0pt

background = color_list( "BGT" )

;

 

  I am still weak on TEMPLATEs, so I am not sure if the above applies to report.  It is legacy code that I obtained and 2.0 pt padding seems undesirable.

 

 I padded the variable value with blank spaces (PDF and RTF destinations).  I  found that when wrapping occurs, then the INDENT does not apply to the subsequent lines (as you show below). Instead, I manually inserted:

 

if row_1 = " Subject had a clinically significant protocol deviation during the induction phase"

then row_1 = " Subject had a clinically significant protocol deviation during^n the induction phase" ;

 

 

Note that my ODS ESCAPECHAR = "^" and three spaces follow "^n". The issue is that we might have listings of hundreds of pages.  I stumbled onto http://www.pharmasug.org/proceedings/2012/CC/PharmaSUG-2012-CC22.pdf

 

"A Macro to Indent and Hyphenate Lengthy Text in PROC REPORT" by Stanley Yuen

 

Note that Regex can get us pretty far:

 

12528 data _null_ ;

12529 length x $ 200 ;

12530 x = " three little pigs" ;

12531 x = prxchange( "s/(.*)(?:\s+)([\S]*)$/$1^n%sysfunc(repeat( %str( ) , 2 ))$2/o" , 1 , trim( x )) ;

12532 put x $char40. ;

12533 run ;

three little^n pigs

 

(With some flexibility, with the number of spaces ready to be replaced by a macro variable, complicating the code.)

 

Bummer, as you observed in a previous post, we'd need to use &nbsp since we are in HTML land so the leading three spaces are gone...

 

The macro would to break on spaces, or if we allow, in words (using a hyphen), would not be that complicated.

 

The big issue is length.  I spent some time reading about fonts because some asked me to predict how many characters would fit in a given column/table.  Fascinating, if you can believe it, but I like books and did not mind reading about printing presses (carrying over from my childhood when I found an old newpaper in New Hampshire that had those "funny" s's that look similar to f's with a base and no line in the middle.  The only thing that I can think of at the moment is to use the least narrow and the widest (M?) characters to find a conservative length, but we have not guarantee other bytes, like symbols will not appear in the value.

 

Thank you,

 

Kevin

Cynthia_sas
SAS Super FREQ

Hi:

  I'm just not sure why you are worrying so much about the length or the wrapping. I would not bother. If INDENT= is not what you want and you DO want the wrapped text to be indented, then the LEFTMARGIN= attribute does that, as shown below.

 

more_indent.png

 

 Before you go into template land, you can experiment with CELLPADDING values and fonts in PROC REPORT and THEN, after you find the values that give you  the report you want, you can move them to a style template. The TABLE element will apply to the PROC  REPORT table. I like to start with the PROC REPORT attributes in the PROC REPORT code, so I can experiment to see which values I want to use and then, after that I move into template land.

 

  Here's my paper about tiptoeing through the templates: https://support.sas.com/resources/papers/proceedings09/227-2009.pdf  and the one on style templates: https://support.sas.com/resources/papers/proceedings10/033-2010.pdf .

 

  And, here's an example of wrapping long text along with using INDENT or LEFTMARGIN:

longtext.png

 

I did turn on the border lines and interior table lines in the long text example so you could be assured that the INDENT and LEFTMARGIN were working as designed.

 

I find that ODS and SAS do a good job of not splitting words at a bad place such that I do not need to over-control the text strings by inserting my own line breaks. The only time I really insert line breaks is when I want to "stack" information in one cell and control exactly where the line break will occur, such as:

data newclass;
  set sashelp.class(obs=2);
  length newvar1 newvar2 $200;
  newvar1 = cat('Name: ',name,'~{newline 1}','Sex: ',sex,'~{newline 1}','Age: ',put(age,2.0));
  newvar2 = cat('Height:',put(height,5.1),'~{newline 1}','Weight: ',put(weight,5.1));
run;

ods escapechar='~';
proc report data=newclass;
column newvar1 newvar2;
run;

  Perhaps I am missing the big picture, but you're not showing all your code and all your data, but based on what you've indicated so far, I don't think you need to go down the REGEX road or insert your own NEWLINE characters.

 

cynthia

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 4 replies
  • 2953 views
  • 0 likes
  • 3 in conversation