Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to centrally justify in printf function in Perl

Tags:

perl

I know the printf function by default uses right-justification. - will make it left justify. But is it possible to make it centrally justify the format?

like image 459
Qiang Li Avatar asked May 13 '11 00:05

Qiang Li


4 Answers

The printf function cannot center text.

However, there is a very old, and almost forgotten mechanism that can do this. You can create format statements in Perl that tells write statements how to print. By using format and write, you can center justify text.

This was something sort of done back in the days of Perl 3.x back in 1989, but sort of abandoned by the time Perl 4 came out. Perl 5, with its stronger variable scoping really put a crimp in the use of formats since using them would violate the way Perl 5 likes to scope variables (formats are global in nature).

You can learn more about it by looking at perldoc perlform. I haven't seen them used in years.

like image 64
David W. Avatar answered Nov 17 '22 23:11

David W.


my @lines = (
  "It is true that printf and sprintf",
  "do not have a conversion to center-justify text.",
  "However, you can achieve the same effect",
  "by padding left-justified text",
  "with an appropriate number of spaces."
);

my $max_length = 0;
foreach my $line (@lines) {
  $max_length = (length $line > $max_length) ? length $line : $max_length;
}

foreach my $line (@lines) {
  printf "%s%-${max_length}s\n", ' ' x int(($max_length - length $line)/2), $line;
}
like image 20
Sam Choukri Avatar answered Nov 17 '22 21:11

Sam Choukri


You need to use two variables for each value you'd like to print and dynamically set the width of each around the value width. The problem becomes a little trickier if you want consistent total widths when your value has an odd/even string length. The following seems to do the trick!

use POSIX;
printf( "<%*s%*s>\n",
   ((10+length($_))/2), $_,
   ceil((10-length($_))/2), "" )
      for( qw( four five5 six666 7seven7 ) );

which prints

<   four   >
<  five5   >
<  six666  >
< 7seven7  >
like image 4
errant.info Avatar answered Nov 17 '22 22:11

errant.info


You need to know the line width for this. For example, printing centered lines to the terminal:

perl -lne 'BEGIN {$cols=`tput cols`} print " " x (($cols-length)/2),$_;' /etc/passwd

Of course, this is not a printf formatting tag.

like image 2
jm666 Avatar answered Nov 17 '22 21:11

jm666