Text-Sprintf-Zenkaku
view release on metacpan or search on metacpan
lib/Text/Sprintf/Zenkaku.pm view on Meta::CPAN
package Text::Sprintf::Zenkaku;
use 5.008001;
use strict;
use warnings;
use utf8;
use Carp;
use Encode;
our $VERSION = "0.09";
use Exporter 'import';
our @EXPORT_OK = qw(sprintf);
our $cp932 = Encode::find_encoding("cp932");
our $conversions = qr/\A[cduoxefgXEGbBpnaA]\Z/;
$conversions = qr/\A[cduoxefgXEGbBpn]\Z/ if $] lt 5.022000;
$conversions = qr/\A[cduoxefgXEGbpn]\Z/ if $] lt 5.010000;
sub calc_width {
my ($w, $s) = @_;
my $ofs;
if ($w >= 0) {
$ofs = $w - ((length $cp932->encode($s)) - (length $s));
} else {
$ofs = (abs $w) - ((length $cp932->encode($s)) - (length $s));
$ofs *= -1;
}
return $ofs;
}
sub sprintf {
my @argv = @_;
my $fmt = defined $argv[0] ? $argv[0] : "";
my $ofs = 0;
my $state = "IDL";
my $index = 1;
my $tmp = "";
my $fmt_new = "";
my $length = length $fmt;
my $is_uniq = {};
while ($ofs < $length) {
my $s = substr $fmt, $ofs, 1;
if ($state eq "IDL") {
if ($s eq "%") {
$tmp = $s;
$state = "READ_FORMAT";
} else {
$fmt_new .= $s;
}
} elsif ($state eq "READ_FORMAT") {
if ($s eq "%") {
# 'a percent sign' literal
$fmt_new .= $tmp . $s;
$tmp = "";
$state = "IDL";
} elsif ($s eq "s") {
# %s
$tmp .= $s;
if ($tmp =~ /^%([1-9][0-9]*)\$( *)\*([1-9][0-9]*)\$s$/) {
my $s_index = int $1;
my $space = $2;
my $w_index = int $3;
my $s = $_[$s_index];
my $w = $_[$w_index];
my $width = calc_width($w, $s);
if (not exists $is_uniq->{$w_index}) {
$argv[$w_index] = $width;
$is_uniq->{$w_index}++;
( run in 3.034 seconds using v1.01-cache-2.11-cpan-a49fcb8fa48 )