.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.28) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Term::Sk 3pm" .TH Term::Sk 3pm "2015-11-01" "perl v5.20.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Term::Sk \- Perl extension for displaying a progress indicator on a terminal. .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use Term::Sk; \& \& my $ctr = Term::Sk\->new(\*(Aq%d Elapsed: %8t %21b %4p %2d (%8c of %11m)\*(Aq, \& {quiet => 0, freq => 10, base => 0, target => 100, pdisp => \*(Aq!\*(Aq}); \& \& $ctr\->up for (1..100); \& \& $ctr\->down for (1..100); \& \& $ctr\->whisper(\*(Aqabc\*(Aq); \& \& my last_line = $ctr\->get_line; \& \& $ctr\->close; \& \& print "Number of ticks: ", $ctr\->ticks, "\en"; .Ve .SH "EXAMPLES" .IX Header "EXAMPLES" Term::Sk is a class to implement a progress indicator (\*(L"Sk\*(R" is a short form for \*(L"Show Key\*(R"). This is used to provide immediate feedback for long running processes. .PP A sample code fragment that uses Term::Sk: .PP .Vb 1 \& use Term::Sk; \& \& print qq{This is a test of "Term::Sk"\en\en}; \& \& my $target = 2_845; \& my $format = \*(Aq%2d Elapsed: %8t %21b %4p %2d (%8c of %11m)\*(Aq; \& \& my $ctr = Term::Sk\->new($format, \& {freq => 10, base => 0, target => $target, pdisp => \*(Aq!\*(Aq}); \& \& for (1..$target) { \& $ctr\->up; \& do_something(); \& } \& \& $ctr\->close; \& \& sub do_something { \& my $test = 0; \& for my $i (0..10_000) { \& $test += sin($i) * cos($i); \& } \& } .Ve .PP Another example that counts upwards: .PP .Vb 1 \& use Term::Sk; \& \& my $format = \*(Aq%21b %4p\*(Aq; \& \& my $ctr = Term::Sk\->new($format, {freq => \*(Aqs\*(Aq, base => 0, target => 70}); \& \& for (1..10) { \& $ctr\->up(7); \& sleep 1; \& } \& \& $ctr\->close; .Ve .PP At any time, after Term::Sk\->\fInew()\fR, you can query the number of ticks (i.e. number of calls to \&\f(CW$ctr\fR\->up or \f(CW$ctr\fR\->down) using the method 'ticks': .PP .Vb 1 \& use Term::Sk; \& \& my $ctr = Term::Sk\->new(\*(Aq%6c\*(Aq, {freq => \*(Aqs\*(Aq, base => 0, target => 70}); \& \& for (1..4288) { \& $ctr\->up; \& } \& \& $ctr\->close; \& \& print "Number of ticks: ", $ctr\->ticks, "\en"; .Ve .PP This example uses a simple progress bar in quiet mode (nothing is printed to \s-1STDOUT\s0), but instead, the content of what would have been printed can now be extracted using the \fIget_line()\fR method: .PP .Vb 1 \& use Term::Sk; \& \& my $format = \*(AqCtr %4c\*(Aq; \& \& my $ctr = Term::Sk\->new($format, {freq => 2, base => 0, target => 10, quiet => 1}); \& \& my $line = $ctr\->get_line; \& $line =~ s/\e010/up; \& \& $line = $ctr\->get_line; \& $line =~ s/\e010/close; \& \& $line = $ctr\->get_line; \& $line =~ s/\e010/ ...} .PP .Vb 1 \& my $format = \*(Aqact %c max %m\*(Aq; \& \& my $ctr1 = Term::Sk\->new($format, {base => 1234567, target => 2345678}); \& # The following numbers are shown: act 1_234_567 max 2_345_678 \& \& my $ctr2 = Term::Sk\->new($format, {base => 1234567, target => 2345678, num => q{9,999}}); \& # The following numbers are shown: act 1,234,567 max 2,345,678 \& \& my $ctr3 = Term::Sk\->new($format, {base => 1234567, target => 2345678, num => q{9\*(Aq99}}); \& # The following numbers are shown: act 1\*(Aq23\*(Aq45\*(Aq67 max 2\*(Aq34\*(Aq56\*(Aq78 \& \& my $ctr4 = Term::Sk\->new($format, {base => 1234567, target => 2345678, num => q{9}}); \& # The following numbers are shown: act 1234567 max 2345678 \& \& my $ctr5 = Term::Sk\->new($format, {base => 1234567, target => 2345678, \& commify => sub{ join \*(Aq!\*(Aq, split m{}xms, $_[0]; }}); \& # The following numbers are shown: act 1!2!3!4!5!6!7 max 2!3!4!5!6!7!8 .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" .SS "Format strings" .IX Subsection "Format strings" The first parameter to \fInew()\fR is the format string which contains the following special characters: .IP "characters '%d'" 4 .IX Item "characters '%d'" a revolving dash, format '/\-\e|' .IP "characters '%t'" 4 .IX Item "characters '%t'" time elapsed, format 'hh:mm:ss' .IP "characters '%b'" 4 .IX Item "characters '%b'" progress bar, format '#####_\|_\|_\|_\|_' .IP "characters '%p'" 4 .IX Item "characters '%p'" Progress in percentage, format '999%' .IP "characters '%c'" 4 .IX Item "characters '%c'" Actual counter value (commified by '_'), format '99_999_999' .IP "characters '%m'" 4 .IX Item "characters '%m'" Target maximum value (commified by '_'), format '99_999_999' .IP "characters '%k'" 4 .IX Item "characters '%k'" Token which updates its value before being displayed. An example use of this would be a loop wherein every step of the loop could be identified by a particular string. For example: .Sp .Vb 10 \& my $ctr = Term::Sk\->new(\*(AqProcessing %k counter %c\*(Aq, \& {base => 0, token => \*(AqAlbania\*(Aq}); \& foreach my $country (@list_of_european_nations) { \& $ctr\->token($country); \& for (1..500) { \& $ctr\->up; \& ## do something... \& } \& }; \& $ctr\->close; .Ve .Sp You can also have more than one token on a single line. Here is an example: .Sp .Vb 10 \& my $ctr = Term::Sk\->new(\*(AqProcessing %k Region %k counter %c\*(Aq, \& {base => 0, token => [\*(AqAlbania\*(Aq, \*(AqSouth\*(Aq]}); \& foreach my $country (@list_of_european_nations) { \& $ctr\->token([$country, \*(AqNorth\*(Aq]); \& for (1..500) { \& $ctr\->up; \& ## do something... \& } \& }; \& $ctr\->close; .Ve .Sp The \f(CW\*(C`token\*(C'\fR method is used to update the token value immediately on the screen. .Sp The \f(CW\*(C`tok_maybe\*(C'\fR method is used to set the token value, but the screen is not refreshed immediately. .Sp If '%k' is used, then the counter must be instantiated with an initial value for the token. .IP "characters '%P'" 4 .IX Item "characters '%P'" The '%' character itself .SS "Options" .IX Subsection "Options" The second parameter are the following options: .IP "option {freq => 999}" 4 .IX Item "option {freq => 999}" This option sets the refresh-frequency on \s-1STDOUT\s0 to every 999 \fIup()\fR or \&\fIdown()\fR calls. If {freq => 999} is not specified at all, then the refresh-frequency is set by default to every \fIup()\fR or \fIdown()\fR call. .IP "option {freq => 's'}" 4 .IX Item "option {freq => 's'}" This is a special case whereby the refresh-frequency on \s-1STDOUT \s0 is set to every second. .IP "option {freq => 'd'}" 4 .IX Item "option {freq => 'd'}" This is a special case whereby the refresh-frequency on \s-1STDOUT \s0 is set to every 1/10th of a second. .IP "option {base => 0}" 4 .IX Item "option {base => 0}" This specifies the base value from which to count. The default is 0 .IP "option {target => 10_000}" 4 .IX Item "option {target => 10_000}" This specifies the maximum value to which to count. The default is 10_000. .IP "option {pdisp => '!'}" 4 .IX Item "option {pdisp => '!'}" This option (with the exclamation mark) is obsolete and has no effect whatsoever. The progressbar will always be displayed using the hash-symbol \*(L"#\*(R". .IP "option {quiet => 1}" 4 .IX Item "option {quiet => 1}" This option disables most printing to \s-1STDOUT,\s0 but the content of the would be printed line is still available using the method \fIget_line()\fR. The whisper-method, however, still shows its output. .Sp The default is in fact {quiet => !\-t \s-1STDOUT\s0} .IP "option {num => '9_999'}" 4 .IX Item "option {num => '9_999'}" This option configures the output number format for the counters. .IP "option {commify => sub{...}}" 4 .IX Item "option {commify => sub{...}}" This option allows one to register a subroutine that formats the counters. .IP "option {test => 1}" 4 .IX Item "option {test => 1}" This option is used for testing purposes only, it disables all printing to \s-1STDOUT,\s0 even the whisper shows no output. But again, the content of the would be printed line is still available using the method \fIget_line()\fR. .SS "Processing" .IX Subsection "Processing" The \fInew()\fR method immediately displays the initial values on screen. From now on, nothing must be printed to \s-1STDOUT\s0 and/or \s-1STDERR.\s0 However, you can write to \s-1STDOUT\s0 during the operation using the method \fIwhisper()\fR. .PP We can either count upwards, \f(CW$ctr\fR\->up, or downwards, \f(CW$ctr\fR\->down. Everytime we do so, the value is either incremented or decremented and the new value is replaced on \s-1STDOUT.\s0 We should do so regularly during the process. Both methods, \f(CW$ctr\fR\->up(99) and \f(CW$ctr\fR\->down(99) can take an optional argument, in which case the value is incremented/decremented by the specified amount. .PP When our process has finished, we must close the counter ($ctr\->close). By doing so, the last displayed value is removed from \s-1STDOUT,\s0 as if nothing had happened. Now we are allowed to print again to \s-1STDOUT\s0 and/or \s-1STDERR.\s0 .SS "Post hoc transformation" .IX Subsection "Post hoc transformation" In some cases it makes sense to redirected \s-1STDOUT\s0 to a flat file. In this case, the backspace characters remain in the flat file. .PP There is a function \*(L"\fIrem_backspace()\fR\*(R" that removes the backspaces (including the characters that they are supposed to remove) from a redirected file. .PP Here is a simplified example: .PP .Vb 1 \& use Term::Sk qw(rem_backspace); \& \& my $flatfile = "Test hijabc\e010\e010\e010xyzklmttt\e010\e010yzz"; \& \& printf "before (len=%3d): \*(Aq%s\*(Aq\en", length($flatfile), $flatfile; \& \& rem_backspace(\e$flatfile); \& \& printf "after (len=%3d): \*(Aq%s\*(Aq\en", length($flatfile), $flatfile; .Ve .SH "AUTHOR" .IX Header "AUTHOR" Klaus Eichner, January 2008 .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" Copyright (C) 2008\-2011 by Klaus Eichner .PP This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.