Quester, thank you for your reply. Basically, I was trying to insert \137 in various places along line 29 to see what effect it would have. I got underlines before the column headings and I forget where else, but not where I wanted. Because the Perl program that I have does miraculous things, I just assumed I could underline the columns. I wondered why I couldn’t find a regex or a double-quoted string representation. | [reply] |
I have been able to underline the column headings using Term::ANSIColor but I am not satisfied with the result. There can be twenty six columns depending on the data, so I want to keep my output width to a minimum. The column header consists of one or two digits (the count of the letter) followed by the letter followed by one or two digits called flank in the code (the count of how many times the letter contacts a different letter). The headers vary in width from five to three characters.
The line (32) in question is:
push @line, sprintf('%2d%s%-2d', scalar @{$trigraphs{$k}}, $k, scalar keys %{$flanks{$k}});
When I use colored in the format portion of sprintf(), like this:
sprintf(colored('%2d%s%-2d', 'underline'),
I always get an underline that is five characters wide, which is good when my column header is five characters wide; not so good when the header is only three characters wide. I was forced to go that route because even though I got the correct results with the letter part of the header, like this:
colored($k, 'underline'),
I was unable to get around the fact that I couldn’t use the %d identifier when I tried to underline what I thought would be numerical values from the scalar part of my code (it still sees $k as letters). If I changed %d to %s and used:
colored(scalar @{$trigraphs{$k}}, 'underline'), and
colored(scalar keys %{$flanks{$k}}, 'underline'));
Note: the last ) is to match the ( in sprintf().
I could get the underline I want, but the headers no longer lined up with the letter above it’s corresponding letter in the columns. The columns print as they should with three spaces between them.
That is my problem, can anyone help? Should anyone want to run the code
#! /usr/bin/perl
use strict;
use warnings;
use Term::ANSIColor;
# get cipherText
my $txt = do{local $/; <DATA>};
$txt =~ s/\s//go;
my @letters = split '', $txt;
# create trigraphs
my (%trigraphs, %flanks);
add_trigraph('-', @letters[0..1]);
while(@letters > 2){
add_trigraph(@letters[0..2]);
shift @letters;
}
add_trigraph(@letters[0..1], '-');
# sort by most seen middle character
my @sorted_keys = sort{
@{$trigraphs{$b}} <=> @{$trigraphs{$a}} || $a cmp $b
} keys %trigraphs;
# create columns/lines
for(my $i = -1;$i < @{$trigraphs{$sorted_keys[0]}};++$i){
my @line;
for my $k (@sorted_keys){
unless($i > -1){ # create header
@{$trigraphs{$k}} = sort @{$trigraphs{$k}};
push @line, sprintf('%2d%s%-2d', scalar @{$tri
+graphs{$k}}, $k, scalar keys %{$flanks{$k}});
next;
}
next unless defined $trigraphs{$k}->[$i];
push @line, sprintf(' %s ', $trigraphs{$k}->[$i]);
}
print "@line\n";
}
sub add_trigraph {
++$flanks{$_[1]}->{$_} for @_[0,2];
push(@{$trigraphs{$_[1]}}, join('', @_));
}
__DATA__ # elcy pg.73 in P format
FDRJN UHVXX URDMD SKVSO PJRKZ DYFZJ
XGSRR VTQYR WDARW DFVRK VDRKV TDFSZ
ZDYFR DNNVO VTSXS AWVZR
| [reply] [d/l] [select] |
The colored(...) function wants a character string argument, so you must call sprintf first to convert your numbers to strings, then colored. This fix works (at least on Linux):
push @line, colored(sprintf('%2d', scalar @{$trigraphs{$k}}), 'und
+erline') . $k .
colored(sprintf('%-2d',scalar keys %{$flanks{$k}}), 'underline')
+;
| [reply] [d/l] |
Quester, thank you, your solution helped.
I have tried everything I could think of to get a proper variable width underline with no success so I will have to settle for what I’ve got. I get 5 underlines under each heading, but at least the columns line up properly when I use:
push @line, colored(sprintf('%2d', scalar @{$trigraphs{$k}}), 'underli
+ne') . colored(sprintf('%s', $k), 'underline') . colored(sprintf('%-2
+d', scalar keys
%{$flanks{$k}}), 'underline');
What puzzles me is that It’s possible to get the variable width underline that I want when I use:
push @line, sprintf('%2s%s%-2s', colored(scalar @{$trigraphs{$k}}, 'un
+derline'), colored($k, 'underline'), colored(scalar keys %{$flanks{$k
+}}, 'underline')
);
I just don’t know how to get it with the columns lining up. | [reply] [d/l] [select] |