<commit_before>=head1 NAME

Gfat::Cmd::Base - Base modules that used for build commands

=head1 SYNOPSIS

  use Gfat::Cmd::Base qw(get_fh close_fh get_options);

  # For simple options with only input, output and help
  my $cmd = shift @ARGV;
  my ($in_fh, $out_fh) = get_fh($cmd);
  my ($in_fh, $out_fh, $options) = get_fh($cmd, "hello" => "Print hello world")
  my $hello = $options{hello};
  print "Hello world!\n" if $hello;
  ...
  close_fh($in_fh, $out_fh);

=head1 DESCRIPTION

Subroutines that assist defining commands for scripts

=head1 FEEDBACK

Create an issue in GitHub <https://github.com/lileiting/gfatk/issues>

=head1 AUTHOR

<NAME>, Email: <EMAIL>

=head1 APPENDIX

The rest of the documentation details each of the subroutine.

=cut

package Gfat::Cmd::Base;
use warnings;
use strict;
use FindBin;
use Gfat::Base qw(GetInFh GetOutFh);
use Getopt::Long qw(:config gnu_getopt);
use Getopt::Long;
use List::Util qw/max/;
use vars qw(@EXPORT @EXPORT_OK);
use base qw(Exporter);
@EXPORT = ();
@EXPORT_OK = qw(get_fh close_fh get_options base_main base_usage load_listfile);

=head2 base_usage

  Title   : base_usage
  Usage   : my $actions_hash_ref = {-description => 'print hello world',
                                    hello => [\&hello, "Print hello"],
                                    world => [\&world, "Print world"]};
            base_usage($actions_hash_ref);

  Function: Resolve the information in the actions hash and 
            print the base usage information. Description is optional.

  Returns : Exit the program

  Args    : The subroutine reference for functions defination
            and the base usage subroutine reference

=cut

sub _multi_line{
    my ($str, $maxlen) = @_;
    my $space = $maxlen + 4 + 3;
    my $line_len = 60 - $space;
    my $newstr = '';
    for (my $i = 0; $i < length($str); $i += $line_len){
        my $part = substr($str, $i, $line_len);
        $newstr = $newstr ?  "$newstr\n"." " x $space.$part : $part;
    }
    return $newstr;
}

sub _desc_format{
    my $str = shift;
    my $line_len = 60 - 4;
    my $newstr = 'Description: ';
    for (my $i = 0; $i < length($str); $i += $line_len){
        $newstr .= "\n    ".substr($str, $i, $line_len);
    }
    return "\n$newstr\n";
}

sub base_usage{
    my $actions_hash_ref = shift;
    my %actions = %$actions_hash_ref;
    my $description = $actions{"-description"} ? 
        _desc_format($actions{"-description"}) : '';
    delete $actions{"-description"} if $actions{"-description"};
    print <<USAGE;

Usage:
    $FindBin::Script ACTION
$description
Available ACTIONS:
USAGE

    my $maxlen = max(map{length($_)}keys %actions);
    die "CATUTION: Maximum action name length is greater than 20!: $maxlen\n"
        if $maxlen > 20;
    for my $action (sort{$a cmp $b}keys %actions){
        my $usage = _multi_line($actions{$action}->[1], $maxlen);
        printf "    %${maxlen}s | %s\n", $action, $usage;
    }
    print "\n";
    exit;
}

<commit_msg>fix the bug in display action usage<commit_after>=head1 NAME

Gfat::Cmd::Base - Base modules that used for build commands

=head1 SYNOPSIS

  use Gfat::Cmd::Base qw(get_fh close_fh get_options);

  # For simple options with only input, output and help
  my $cmd = shift @ARGV;
  my ($in_fh, $out_fh) = get_fh($cmd);
  my ($in_fh, $out_fh, $options) = get_fh($cmd, "hello" => "Print hello world")
  my $hello = $options{hello};
  print "Hello world!\n" if $hello;
  ...
  close_fh($in_fh, $out_fh);

=head1 DESCRIPTION

Subroutines that assist defining commands for scripts

=head1 FEEDBACK

Create an issue in GitHub <https://github.com/lileiting/gfatk/issues>

=head1 AUTHOR

<NAME>, Email: <EMAIL>

=head1 APPENDIX

The rest of the documentation details each of the subroutine.

=cut

package Gfat::Cmd::Base;
use warnings;
use strict;
use FindBin;
use Gfat::Base qw(GetInFh GetOutFh);
use Getopt::Long qw(:config gnu_getopt);
use Getopt::Long;
use List::Util qw/max/;
use vars qw(@EXPORT @EXPORT_OK);
use base qw(Exporter);
@EXPORT = ();
@EXPORT_OK = qw(get_fh close_fh get_options base_main base_usage load_listfile);

=head2 base_usage

  Title   : base_usage
  Usage   : my $actions_hash_ref = {-description => 'print hello world',
                                    hello => [\&hello, "Print hello"],
                                    world => [\&world, "Print world"]};
            base_usage($actions_hash_ref);

  Function: Resolve the information in the actions hash and 
            print the base usage information. Description is optional.

  Returns : Exit the program

  Args    : The subroutine reference for functions defination
            and the base usage subroutine reference

=cut

sub _multi_line{
    my ($str, $indent) = @_;
    my $line_maxlen = 60 - $indent;

    my $space  = ' ' x $indent;
    my $newstr = '';
    my @words  = split / /, $str;
    my $line_len;
    for my $word (@words){
        if($newstr eq ''){ 
            $newstr = $word;
            $line_len = length($word);
        }elsif($line_len + length(" $word") <= $line_maxlen){
            $newstr .= " $word";
            $line_len += length(" $word");
        }else{
            $newstr .= "\n$space$word";
            $line_len = 0;
        }
    }
    return $newstr;
}

sub _desc_format{
    my $str = shift;
    my $line_len = 60 - 4;
    my $newstr = 'Description: ';
    for (my $i = 0; $i < length($str); $i += $line_len){
        $newstr .= "\n    ".substr($str, $i, $line_len);
    }
    return "\n$newstr\n";
}

sub base_usage{
    my $actions_hash_ref = shift;
    my %actions = %$actions_hash_ref;
    my $description = $actions{"-description"} ? 
        _desc_format($actions{"-description"}) : '';
    delete $actions{"-description"} if $actions{"-description"};
    print <<USAGE;

Usage:
    $FindBin::Script ACTION
$description
Available ACTIONS:
USAGE

    my $maxlen = max(map{length($_)}keys %actions);
    die "CATUTION: Maximum action name length is greater than 20!: $maxlen\n"
        if $maxlen > 20;
    for my $action (sort{$a cmp $b}keys %actions){
        my $usage = _multi_line($actions{$action}->[1], $maxlen + 4 + 3);
        printf "    %${maxlen}s | %s\n", $action, $usage;
    }
    print "\n";
    exit;
}


{'fraction_non_alphanumeric': 0.1414141414141414, 'fraction_numerical': 0.006734006734006734, 'mean_word_length': 2.8890274314214466, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 21, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2089321', 'n_tokens_mistral': 2239, 'n_tokens_neox': 2103, 'n_words': 628}