pax_global_header 0000666 0000000 0000000 00000000064 13041231401 0014477 g ustar 00root root 0000000 0000000 52 comment=ba3650c987147f1191e7c23fe3fb6f2eb2d39e26
cadubi-1.3.4/ 0000775 0000000 0000000 00000000000 13041231401 0012733 5 ustar 00root root 0000000 0000000 cadubi-1.3.4/LICENSE 0000664 0000000 0000000 00000002070 13041231401 0013737 0 ustar 00root root 0000000 0000000 The MIT License (MIT)
Copyright (c) 2015 Ian Langworth
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
cadubi-1.3.4/README.md 0000664 0000000 0000000 00000013271 13041231401 0014216 0 ustar 00root root 0000000 0000000 # CADUBI - Creative ASCII Drawing Utility By Ian
This Perl program was written sometime around 1997 -- many years before I knew
anything about Perl or Unix -- and the code hasn't changed much since then. It
has, however, become very widely adopted and is available as a package on most
Linux distributions.
CADUBI is an application written in Perl that allows you to draw
text-based images that are viewable on typical unix-based consoles.
Usually the applications that emulate these consoles support various
text modes, such as background and foreground colors, bold, and
inverse. This text art, commonly called "ASCII art," is used in
various places such as online BBSes, email and login prompts.
## Screen shots
## Installation
* [Homebrew](http://brew.sh/): `brew install cadubi`
* [Debian](https://packages.debian.org/wheezy/cadubi) and [Ubuntu](http://packages.ubuntu.com/precise/cadubi): `apt-get install cadubi`
* From source:
* Perl 5.002 or later
* `Term::ReadKey` Perl module
## Usage
CADUBI has a 'pen' which describes the current mode. Properties of
the pen are the painting character, foreground color, background
color, bold, inverse, and blink. Whenever you paint or use the text
mode, the characters drawn on the screen will have the properties of
the pen. The current mode of the pen is shown at the bottom of the
console and is what will be drawn on screen when you paint.
Move around the cursor with the i, j, k and l keys. Holding
down shift and typing these keys will move the cursor five spaces
instead of one. Pressing return/enter will move the cursor down one
line and all the way to the left of the console.
To paint the current pen on the screen, press the space bar. To
delete a character, press the delete/backspace key. You'll notice
that editing is much like common text editors, such as pico or joe.
You can also delete with the tilde key, which makes moving & painting
(right hand) and erasing (left hand) much easier.
The pen character is the character that is drawn when you paint using
the space bar. To change the character, press p and then the
character you would like it to be.
To set the foreground or background colors for the cursor, press f
for foreground or b for background, and then a corresponding color
code. The color codes are case-insensitive and are listed below:
0 or N Normal (standard text)
1 or W White
2 or R Red
3 or G Green
4 or Y Yellow
5 or B Blue
6 or M Magenta
7 or C Cyan
8 or K Black
If you can't remember the codes above, you can always hit Ctrl-h
to view the Quick Help which will display a summary of all the keys,
color codes and examples of how they look.
Typically, foreground text colors are the same as background colors,
unless the text is bold. If the text is bold, foreground colors are
usually lighter than the background color, making text easier to read
when the text has the same foreground and background color. Refer to
the Quick Help (Ctrl-h) to see what the colors look like on your
console.
Bold and inverse are two widely-supported modes. Bold is toggled with
the g key, and inverse is toggled with the v key. Blink, though
regarded as highly annoying, can be toggled with by pressing
Shift-w.
Text mode is an extremely useful feature. Once in the text mode you
can type as if you were using a normal text editor, and all the
characters drawn onscreen will use the same mode as the pen. To enter
text mode, press the t key. To exit, press escape.
To exit the CADUBI application, press Ctrl-x. Quick help can be
accessed by pressing Ctrl-h. In case it is needed, pressing
Ctrl-w will refresh the entire screen by redrawing each
character.
### Reading and writing files
To read a file and use it with CADUBI, type Ctrl-r. To write
a file, type Ctrl-o. You will be prompted for a filename.
When CADUBI reads a file, it will only read as much that will fit in
the workspace (the area of the console minus the bottom row [status
bar]). To gain more workspace, see the `-s` operator in 'COMMAND LINE
USAGE' below.
CADUBI optimizes its output files to display properly and take up as
little space as possible. All CADUBI output can be viewed with the
'cat' utility.
## Command line usage
Usage: cadubi [OPTIONS] [FILE]
Available options:
-h, --help what you're looking at now
-m, --mute turn off beeping
-s, --size [W] [H] sets the size of the console for use with
CADUBI, where W is number of columns and H
is number of rows.
-v, --version show CADUBI version
Example:
Will make the cadubi workspace 160 columns wide, 48 rows high,
disable beeping, and open the file 'bacon.txt':
cadubi --mute --size 160 48 bacon.txt
Will display the version of CADUBI, copyright and author:
cadubi -v
## Tips
Whenever you are prompted to type in information, such as the name of
a file to read/write to, you can hit escape to cancel. You can also
hit escape to get out of text mode.
When using the `-s` or `--size` command line option, make sure your
console actually _is_ that size or the text won't wrap properly and
CADUBI will look funny.
cadubi-1.3.4/cadubi 0000775 0000000 0000000 00000074145 13041231401 0014123 0 ustar 00root root 0000000 0000000 #!/usr/bin/perl
eval 'case $# in 0) exec /usr/bin/perl -S "$0";; *) exec /usr/bin/perl -S "$0" "$@";; esac'
if 0;
$VERSION = '1.3.4';
########################################################################
# MAIN LOOP
# kludge to make this easier (?) for package maintainers
# (sorry guys, i wrote this years before i had the remotest clue as to
# what the hell i was doing)
use FindBin qw($Bin);
$HELPFILE = "$Bin/help.txt";
# other stuff
$DEBUG = 0;
$CADUBI_VERSION = $VERSION;
use Term::ReadKey;
use lib "$Bin/../lib";
# global variables
$ESC = "\x1b"; # our most important var
$AUDIBLE = 1; # beep unless -m, --mute, or configured in 'cadubi'
@pos = (1,1); # position of cursor (x,y)
@totalspan = undef; # width & height of console (x,y)
@workspan = undef; # same as $totalspace, but y-1
$charmap = undef; # a 3D array:
# [col] [row] [(0 => char to paint with
# 1 => bg color
# 2 => fg color
# 3 => bold
# 4 => inverse
# 5 => blink
# 6 => special char command
# )]
@charmode = ('x',0,0,0,0,0,'');
$status_changed = 1; # used with &status so we don't constantly redraw.
$current_filename = undef; # name of file we're working with
$cadubi_done = 0; # main loop var
# runtime statements
&initKeys(); # setup %controlkeys and %keymap
&initANSI(); # setup %ansi_mode
&setspan(); # setup span of terminal (default 24x80)
&get_args; # read in command line parameters
&clear; # clear screen
&debug_open(); # open debug file
ReadMode raw; # set terminal getchar mode
if ($current_filename) {
# file has been specified via command line, open it
&user_readfile($current_filename);
} else {
# draw default status bar
&status();
}
do {
&status if &HandleKeystroke(ReadKey(0)); # handle the key
} until ($cadubi_done);
&clear; # clear screen
&cleanup; # cleanup code
sub cleanup {
ReadMode restore; # restore previous terminal getchar mode
&debug_close(); # close debug file
print $ESC.'[0m'; # return to normal ansi mode if anything has messed up
}
########################################################################
# ANSI MODES
sub initANSI {
%ansi_mode = ( 'escape' => "\x1b",
'normal' => 0,
'bold' => 1,
'blink' => 5,
'inverse ' => 7,
'invisible' => 8,
'fg_black' => 30,
'fg_red' => 31,
'fg_green' => 32,
'fg_yellow' => 33,
'fg_blue' => 34,
'fg_magenta' => 35,
'fg_cyan' => 36,
'fg_white' => 37,
'bg_black' => 40,
'bg_red' => 41,
'bg_green' => 42,
'bg_yellow' => 43,
'bg_blue' => 44,
'bg_magenta' => 45,
'bg_cyan' => 46,
'bg_white' => 47 );
# color codes is used strictly for interface purposes
%color_codes = qw( N normal 0 normal
W white 1 white
R red 2 red
G green 3 green
Y yellow 4 yellow
B blue 5 blue
M magenta 6 magenta
C cyan 7 cyan
K black 8 black
);
}
########################################################################
# CONSOLE ROUTINES
sub curs_move {
# accepts coordinates ((x,y) or (column, row))
if (($_[0] >= 1) && ($_[0] <= $totalspan[0]) && ($_[1] >= 1) && ($_[1] <= $totalspan[1])) {
print $ESC.'['.$_[1].';'.$_[0].'H';
@pos = ($_[0], $_[1]);
} else {
#&debug('&curs_move out of range: ('.$_[0].','.$_[1].')');
#&debug(' >> @totalspan = ('.$totalspan[0].','.$totalspan[1].')');
#&debug(' >> @workspan = ('.$workspan[0].','.$workspan[1].')');
#&debug(' >> @pos = ('.$pos[0].','.$pos[1].')');
return 0;
}
1;
}
sub curs_move_up {
if ($pos[1] > 1) {
print $ESC.'[1A';
$pos[1]--;
} else {
&beep;
return 0;
}
1;
}
sub curs_move_dn {
if ($pos[1] < $workspan[1]) {
print $ESC.'[1B';
$pos[1]++;
} else {
&beep;
return 0;
}
1;
}
sub curs_move_rt {
if ($pos[0] < $workspan[0]) {
print $ESC.'[1C';
$pos[0]++;
} else {
&beep;
return 0;
}
1;
}
sub curs_move_lt {
if ($pos[0] > 1) {
print $ESC.'[1D';
$pos[0]--;
} else {
&beep;
return 0;
}
1;
}
sub clear {
print $ESC.'[2J';
&curs_move(1,1);
}
# set the size of our workspace
sub setspan {
if (@_) {
@totalspan = ($_[0],$_[1]);
@workspan = ($_[0],$_[1]-1);
&debug("\&setspan (specified): $_[0], $_[1]");
} elsif (GetTerminalSize) { #Term::ReadKey
my ($w, $h, @x) = GetTerminalSize; #Term::ReadKey
@totalspan = ($w,$h);
@workspan = ($w,$h-1);
&debug("\&setspan (using Term::ReadKey): $w, $h");
} else { # we must assume, even though it makes an ass of u and me
@totalspan = (80,24);
@workspan = (80,23);
&debug("\&setspan (assumed): 80, 24");
}
}
# our status bar
# if no parameters, erases if status has changed
# if string is first argument, fills entire status bar with string
# if string begins with '>', only replace 'CADUBI v1.x' in status bar with string
# if second argument is true, leave the cursor at the end of the status text...
# (good for prompts, see &user_writefile().
sub status {
my $msg = shift;
my $leave_cursor = shift;
my $out = undef;
if ($msg && (substr($msg,0,1) ne '>')) {
$out = ''.$ESC.'[0m'.$ESC.'[7m '.
pack('A'.($totalspan[0]-1), $msg).$ESC.'[0m';
$status_changed = 1;
} else {
if ($status_changed || $msg) {
my $out_vers;
if ($msg) {
$out_vers = pack('A34',' '.substr($msg,1).' ');
$status_changed = 1;
} else {
$out_vers = pack('A34',' cadubi '.$CADUBI_VERSION.' ');
$status_changed = 0;
}
my $out_help = ' Type ^H for Help ';
my $out_char = ' Pen: '.&printchar(@charmode).' ';
$out = $ESC.'[0m'.$ESC.'[7m'.$out_vers.
$ESC.'[0m'.$out_char.$ESC.'[7m'.
(' ' x ($totalspan[0]-
length($out_vers)-
length($out_help)-
8)
).
$out_help.$ESC.'[0m';
}
}
my @oldpos = @pos;
&curs_move(1,$totalspan[1]);
print $out;
&curs_move(@oldpos) unless $leave_cursor;
}
# this promps the user with the first argument given, and waits for a string.
# pass it a maximum string length for second argument. if no second argument,
# user's allowed to fill the width between prompt & right edge with text.
# a third argument is treated as a default answer, already filled in the field
sub get_user_string {
my $msg = shift;
my $max = shift;
my $out = shift;
my @oldpos = @pos;
my $char = undef;
&curs_move(1,$totalspan[1]);
# notice we don't print a normal mode sequence (\x1b[0m) because we
# want to keep writing in inverse. we print a normal mode right before
# we do a return.
print $ESC.'[7m '.pack('A'.($workspan[0]-2),$msg)." ";
$max = $workspan[0]-length($msg)-3 unless $max;
&curs_move(length($msg)+3,$totalspan[1]);
print $out;
while (not $char =~ /[\n\x1b]/) {
$char = ReadKey(0);
# no chars < space
if ($char =~ /[\x00-\x1f]/) {
&beep;
}
# delete, but don't delete past starting x position
elsif (ord($char) == $keymap{'del'}) {
if ($out) {
# print a backspace...the same as move left one char, print
# a space (which moves the cursor right one char), then move
# back one char again
print $ESC.'[1D '.$ESC.'[1D';
$out = substr($out,0,-1);
} else {
&beep;
}
}
else {
if (length($out) >= $max) {
&beep;
} else {
$out .= $char;
print $char;
}
}
}
&curs_move(@oldpos);
print $ESC.'[0m';
# refresh status bar
$status_changed = 1;
&status();
# user hit enter
return $out if ($char eq "\n");
# user hit cancel
return undef;
}
########################################################################
# SUPPORT SUBROUTINES
sub beep {
print "\x07" if $AUDIBLE;
}
sub refresh {
my @oldpos = @pos;
&clear();
my ($x, $y);
for ($y=1; $y<=$workspan[1]; $y++) {
for ($x=1; $x<=$workspan[0]; $x++) {
if ($charmap->[$x][$y]) {
print &printchar(@{$charmap->[$x][$y]});
} else {
print ' ';
}
}
&curs_move($x--,$y);
}
&curs_move(@oldpos);
}
sub printchar { # returns a string with the current ANSI mode and the character
my $out = undef;
my @desc = @_;
my $char = shift(@desc); #key to draw
pop(@desc); #remove special char command
$out.= $ESC.'['; #print properties
foreach (@desc) {
$out.= $_.';' if ($_);
}
$out = substr($out,0,-1).'m';
$out = undef if ($out eq $ESC.'m');
if (defined($char)) { #print char or space if there's no char
$out.= $char;
} else {
$out.= ' ';
}
$out.= $ESC.'[0m';
return $out;
}
sub paintchar { # prints the char on screen and saves it to $charmap
$charmap->[$pos[0]][$pos[1]] = [@charmode];
print &printchar(@charmode);
&curs_move(@pos); #print moves to the right on us, without asking. the nerve!
}
sub erasechar { # saves blank char to $charmap, prints
$charmap->[$pos[0]][$pos[1]] = undef;
print &printchar({$charmap->[$pos[0]][$pos[1]]});
&curs_move(@pos); #print moves to the right on us, without asking. the nerve!
}
sub usage {
if ($_[0]) {
print $_[0]."\n";
}
print <> printed &usage');
&usage();
&cleanup;
exit(1);
}
elsif (($option eq '-v') || ($option eq '--version')) {
&debug('>> printed &version');
&version;
&cleanup;
exit(1);
}
elsif (($option eq '-m') || ($option eq '--mute')) {
&debug('>> disabled audio');
$AUDIBLE = 0;
}
elsif (($option eq '-s') || ($option eq '--size')) {
($param1, $param2) = (shift(@ARGS), shift(@ARGS));
&debug('>> grabbing setspan variables, raw:');
&debug('>> $param1 = '.$param1);
&debug('>> $param2 = '.$param2);
$param1 = 80 unless $param1;
$param2 = 24 unless $param2;
&debug('>> processed setspan vars:');
&debug('>> $param1 = '.$param1);
&debug('>> $param2 = '.$param2);
&setspan($param1, $param2);
}
elsif ($option =~ /^-/) {
&usage('Unknown option: '.$option);
&cleanup;
exit(1);
}
elsif (not $got_filename) {
$got_filename = 1;
$current_filename = $option;
}
else {
&usage('Unknown argument: '.$option);
&cleanup;
exit(1);
}
}
}
########################################################################
# DEBUGGING
sub debug {
print DEBUGFH $_[0]."\n" if ($DEBUG && DEBUGFH);
}
sub debug_open {
open(DEBUGFH, '>cadubi_debug.txt') if $DEBUG;
&debug('Debug file opened '.(localtime));
}
sub debug_close {
&debug('Debug file closed '.(localtime));
close(DEBUGFH) if DEBUGFH;
}
########################################################################
# KEY HANDLING
sub initKeys {
%controlkeys = GetControlChars; #Term::ReadKey
# DISCARD
# DSUSPEND
# EOF
# EOL
# EOL2
# ERASE
# ERASEWORD
# INTERRUPT
# KILL
# MIN
# QUIT
# QUOTENEXT
# REPRINT
# START
# STATUS
# STOP
# SUSPEND
# SWITCH
# TIME
%keymap = ( '^a' => 1,
'^b' => 2,
'^d' => 4,
'^e' => 5,
'^f' => 6,
'^g' => 7, #bell
'^h' => 8,
'^i' => 9,
'^k' => 11,
'^o' => 15,
'^p' => 16,
'^r' => 18,
'^t' => 20,
'^u' => 21,
'^v' => 22,
'^w' => 23,
'^x' => 24,
'^y' => 25,
'esc' => 27,
'del' => 127,
'up' => 30,
'dn' => 31,
'lt' => 28,
'rt' => 29,
'space' => 32,
'cr' => 13,
'lf' => 10);
}
sub HandleKeystroke {
my $key = shift;
# ansi escape chars, like arrow keys
if ($key eq $ESC) {
if (ReadKey(0) eq '[') {
my $newkey = ReadKey(0);
if ($newkey eq 'A') {&curs_move_up; return 1;}
elsif ($newkey eq 'B') {&curs_move_dn; return 1;}
elsif ($newkey eq 'C') {&curs_move_rt; return 1;}
elsif ($newkey eq 'D') {&curs_move_lt; return 1;}
else {
&status("Unknown escape sequence: '".$newkey."'");
return 0;
}
} else {
&status("Unknown escape sequence.");
return 0;
}
}
# moving around keys (ijkl, IJKL, arrow keys)
if ($key eq 'i') {&curs_move_up; return 1;}
if ($key eq 'j') {&curs_move_lt; return 1;}
if ($key eq 'k') {&curs_move_dn; return 1;}
if ($key eq 'l') {&curs_move_rt; return 1;}
if ($key eq 'I') {for (1 .. 5) {&curs_move_up}; return 1;}
if ($key eq 'J') {for (1 .. 5) {&curs_move_lt}; return 1;}
if ($key eq 'K') {for (1 .. 5) {&curs_move_dn}; return 1;}
if ($key eq 'L') {for (1 .. 5) {&curs_move_rt}; return 1;}
# exit
if (ord($key) == $keymap{'^x'}) {
$cadubi_done = 1;
return 1;
}
# carrage return
if ($key eq "\n") {
# if we're at the bottom of the workspace, don't return
if ($pos[1] >= $workspan[1]) {
&curs_move(1, $pos[1]);
} else {
&curs_move(1, $pos[1]);
&curs_move_dn;
}
return 1;
}
# paint
if ($key eq ' ') {
&paintchar;
&curs_move_rt if ($pos[0] < $workspan[0]);
return 1;
}
# erase
if ((ord($key) == $keymap{'del'}) || ($key eq '`')) {
&curs_move_lt;
&erasechar;
return 1;
}
# text mode
if ($key eq 't') {
my $char = undef;
my $oldchar = $charmode[0];
my $startingx = $pos[0];
&status('Text mode (escape key exits)');
while ($char ne "\x1b") {
$char = ReadKey(0);
# if user hit return, move down a line to starting point
if ($char eq "\n") {
# if we're at the bottom of the workspace, don't return
if ($pos[1] >= $workspan[1]) {
&beep;
} else {
&curs_move($startingx, $pos[1]);
&curs_move_dn;
}
}
# no chars < space
elsif ($char =~ /[\x00-\x1a\x1c-\x1f]/) {
&beep;
}
# delete, but don't delete past starting x position
elsif (ord($char) == $keymap{'del'}) {
if ($pos[0] > $startingx) {
&curs_move_lt;
} else {
&beep;
}
&erasechar;
}
elsif ($char ne $ESC) {
$charmode[0] = $char;
&paintchar(@charmode);
&curs_move_rt;
}
}
$charmode[0] = $oldchar;
return 1;
}
# paint modes
if ($key eq 'p') { # pen character
&status('Set pen character:');
my $newkey = ReadKey(0);
if ($newkey =~ /[\x00-\x1f\x7f]/) {
&beep;
&status('Unusable pen selection');
} else {
$charmode[0] = $newkey;
&status(">Pen char now: '".$newkey."'");
}
return 0;
}
if ($key eq 'g') { # bold
$charmode[3] = ($charmode[3]) ? 0 : 1;
&status(">Bold enabled") if $charmode[3];
&status(">Bold disabled") unless $charmode[3];
return 0;
}
if ($key eq 'v') { # inverse
$charmode[4] = ($charmode[4]) ? 0 : 7;
&status(">Inverse enabled") if $charmode[4];
&status(">Inverse disabled") unless $charmode[4];
return 0;
}
if ($key eq 'W') { # blink (that's W for "why?")
$charmode[5] = ($charmode[5]) ? 0 : 5;
&status(">Blink enabled") if $charmode[5];
&status(">Blink disabled") unless $charmode[5];
return 0;
}
if ($key eq 'f') {
&status('Set pen foreground color:');
my $newkey = ReadKey(0);
if ($newkey =~ /[nN0]/) {$charmode[2] = $ansi_mode{'normal'}}
elsif ($newkey =~ /[wW1]/) {$charmode[2] = $ansi_mode{'fg_white'}}
elsif ($newkey =~ /[rR2]/) {$charmode[2] = $ansi_mode{'fg_red'}}
elsif ($newkey =~ /[gG3]/) {$charmode[2] = $ansi_mode{'fg_green'}}
elsif ($newkey =~ /[yY4]/) {$charmode[2] = $ansi_mode{'fg_yellow'}}
elsif ($newkey =~ /[bB5]/) {$charmode[2] = $ansi_mode{'fg_blue'}}
elsif ($newkey =~ /[mM6]/) {$charmode[2] = $ansi_mode{'fg_magenta'}}
elsif ($newkey =~ /[cC7]/) {$charmode[2] = $ansi_mode{'fg_cyan'}}
elsif ($newkey =~ /[kK8]/) {$charmode[2] = $ansi_mode{'fg_black'}}
if ($newkey =~ /[NWRGYBMCK012345678]/i) {
&status(">Foreground: ".$color_codes{uc($newkey)});
} else {
&beep;
&status("Unknown color selection: '".$newkey."'")
}
return 0;
}
if ($key eq 'b') {
&status('Set pen background color:');
my $newkey = ReadKey(0);
if ($newkey =~ /[nN0]/) {$charmode[1] = $ansi_mode{'normal'}}
elsif ($newkey =~ /[wW1]/) {$charmode[1] = $ansi_mode{'bg_white'}}
elsif ($newkey =~ /[rR2]/) {$charmode[1] = $ansi_mode{'bg_red'}}
elsif ($newkey =~ /[gG3]/) {$charmode[1] = $ansi_mode{'bg_green'}}
elsif ($newkey =~ /[yY4]/) {$charmode[1] = $ansi_mode{'bg_yellow'}}
elsif ($newkey =~ /[bB5]/) {$charmode[1] = $ansi_mode{'bg_blue'}}
elsif ($newkey =~ /[mM6]/) {$charmode[1] = $ansi_mode{'bg_magenta'}}
elsif ($newkey =~ /[cC7]/) {$charmode[1] = $ansi_mode{'bg_cyan'}}
elsif ($newkey =~ /[kK8]/) {$charmode[1] = $ansi_mode{'bg_black'}}
if ($newkey =~ /[NWRGYBMCK012345678]/i) {
&status(">Background: ".$color_codes{uc($newkey)});
} else {
&beep;
&status("Unknown color selection: '".$newkey."'")
}
return 0;
}
# file i/o
if (ord($key) == $keymap{'^r'}) {
return &user_readfile;
}
if (ord($key) == $keymap{'^o'}) {
return &user_writefile;
}
# refresh
if (ord($key) == $keymap{'^w'}) { #refresh
&refresh();
&status('Workspace refreshed');
return 1;
}
# help
if (ord($key) == $keymap{'^h'}) { #Help
if (-e $HELPFILE) {
my $oldmap = $charmap;
my @oldpos = @pos;
&readfile($HELPFILE);
&status('Press a key to continue...', 1);
my $temp = ReadKey(0);
$charmap = $oldmap;
$oldmap = undef;
&curs_move(@oldpos);
&refresh;
&status;
} else {
&beep;
&status("$HELPFILE not available");
}
return 0;
}
# other
if (ord($key) == $keymap{'^t'}) { # TEST
&beep;
return 0;
}
# no cigar!
&beep;
return 0;
}
########################################################################
# FILE SUBROUTINES
sub readfile {
# pass it a filename as first argument, reads a file into
# the $charmap array
my $filepath = shift;
my @oldpos = @pos;
my @oldcharmode = @charmode;
my ($char, $buf, $command, @nums);
my $x = 1;
my $y = 1;
open(IN, '<'.$filepath);
unless (IN) {
return 0;
}
$charmap = undef;
&debug('&readfile parsing:');
PARSE: while (not eof(IN)) {
# MAGICAL ANSI ESCAPE SEQUENCE PARSER
# This parses almost all the escape sequences I could get documentation on.
# Even though, other than the mode change sequences, they will hardly ever
# appear in an ascii art file, it's good to be prepared.
#
# I've parsed all EXCEPT this format:
# ESC[#;"string";#p
#
$char = ReadKey(0, IN);
&debug('>> "'.$char.'"');
# exit if we've found more lines than max
if ($y > $workspan[1]) {
&debug('>> '.$y.' is greater than '.$workspan[1]);
last PARSE;
}
# if we've hit a newline in the file
if ($char eq "\n") {
&debug('>> newline');
$y++;
$x = 1;
}
# if we've found more chars on the line than max
elsif ($x > $workspan[0]) {
&debug('>> maximum chars hit');
$y++;
$x = 1;
# read until newline
do {
$char = ReadKey(0, IN);
} until ($char eq "\n");
}
elsif ($char eq $ESC) { # escape sequence
$char = ReadKey(0, IN);
if ($char eq '[') {
$char = ReadKey(0, IN);
# These escape sequence types don't need support
if ($char =~ /[usK]/) {
# example: ESC[u
}
# Double-char unsupported escape sequences
elsif ($char =~ /[2]/) {
# example: ESC[2J
$char = ReadKey(0, IN);
}
# Multi-numbered wierd with digits
elsif ($char =~ /[\=\?]/) {
# example: ESC[=21;29h
do {
$char = ReadKey(0, IN);
} until (not ($char =~ /[\d\;]/));
}
# Eeek! Keyboard reassignment!
elsif ($char eq '"') {
# example: ESC["string"p
$char = ReadKey(0, IN); # get first "
do {
$char = ReadKey(0, IN); # get string"
} until ($char eq '"');
$char = ReadKey(0, IN); # get final p
}
# Oh great. We've hit digits.
elsif ($char =~ /\d/) {
# example: ESC[31;7m
$buf = $char;
# read until we hit a non-digit or non-; char
do {
$char = ReadKey(0, IN);
$buf .= $char;
} until (not ($char =~ /[\d\;]/));
# $command is the letter following the number series
$command = substr($buf,-1,1);
# $buf ends up being a ; delimeted list of numbers
$buf = substr($buf,0,-1);
# @nums is a list the numbers
@nums = split(/\;/, $buf);
&debug(">> Sequence:");
&debug(">> -> \$command = $command");
&debug(">> -> \$buf = $bug");
&debug(">> -> \@nums = ");
foreach (@nums) {&debug(">> -> !- $_")}
# make sure these numbers are a mode change
if ($command eq 'm') {
# did we get a set-to-normal mode? (ESC[0m])
if (grep(/0/, @nums)) {
@charmode = (' ',0,0,0,0,0,'');
# no, we got a regular mode change
} else {
foreach (@nums) {
$charmode[1] = $_ if (($_ >= 40) && ($_ <= 47));
$charmode[2] = $_ if (($_ >= 30) && ($_ <= 37));
$charmode[3] = $_ if ($_ == 1);
$charmode[4] = $_ if ($_ == 7);
$charmode[5] = $_ if ($_ == 5);
}
}
}
}
}
}
else {
$charmode[0] = $char;
$charmap->[$x][$y] = [@charmode];
$x++;
}
}
close(IN);
&refresh;
&curs_move(@oldpos);
@charmode = @oldcharmode;
return 1;
}
sub writefile {
# pass it a filename, writes the entire $charmap to file, readable by
# cat, more, less, whatever.
my $filepath = shift;
my $out = undef;
my ($thisline, $thischar);
my $inital_space = 1;
my ($x, $y, $i, $d, $max, @newmode, @oldmode, @outlines);
for ($y=1; $y<=$workspan[1]; $y++) {
# fresh new line to work with
@oldmode = qw(99 99 99 99 99 99);
$thisline = undef;
for ($x=1; $x<=$workspan[0]; $x++) {
# set @newmode to the mode of the char we're about to write
@newmode = @{$charmap->[$x][$y]};
# is our new char mode different from our old one?
$d = 0;
$max = ($#oldmode > $#newmode) ? $#oldmode : $#newmode;
for($i=1; $i<=$max; $i++) {
# notice $i starts at one so we skip the character
$d++ if ($oldmode[$i] != $newmode[$i]);
}
# if our new char mode is indeed different, add a normal
# mode sequence and our new mode and char. else, just add
# the char.
if ($d) {
$thisline .= $ESC.'[0m'.substr(&printchar(@{$charmap->[$x][$y]}),0,-4);
} else {
# make sure it's not just a space
if ($charmap->[$x][$y]) {
$thisline .= $newmode[0];
} else {
$thisline .= ' ';
}
}
# now make @newmode our @oldmode
@oldmode = @newmode;
}
# kill trailing whitespace on single lines
$thisline =~ s/(\s+)$//;
# make sure each line ends with a normal mode sequence
push(@outlines, $thisline.$ESC."[0m\n");
}
open(OUT, ">$filepath") or return 0;
# kill trailing lines
$x = 0;
for ($i=$#outlines; $i>=0; $i--) {
unless (($outlines[$i] eq $ESC.'[0m'.$ESC."[0m\n") && (not $x)) {
$out = $outlines[$i].$out;
$x++;
}
}
print OUT $out;
close(OUT);
if ($out) {
return length($out);
} else {
# if no bytes were written, we'll return 'zero'
return 'zero';
}
}
sub user_writefile {
my ($filename, $reply, $bytes_written);
my $file_exists = 1;
my @oldpos = @pos;
while ($file_exists) {
$filename = &get_user_string('File name to write:', undef, $current_filename);
# user canceled
return 1 unless defined($filename);
# check if file exists
if (-e $filename) {
&status('File already exists. Overwrite? (y/n)',1);
$reply = uc(ReadKey(0));
$file_exists = 0 if ($reply eq 'Y');
return 1 if ($reply eq $ESC);
&status();
} else {
$file_exists = 0;
}
}
$current_filename = $filename;
$bytes_written = &writefile($filename);
if ($bytes_written) {
&status("Wrote '".$filename."' (".$bytes_written.' bytes)');
} else {
&beep;
&status("Couldn't write file '".$filename."': ".$!);
}
&curs_move(@oldpos);
return 0;
}
sub user_readfile {
my $filename;
if ($_[0]) {
$filename = $_[0];
} else {
$filename = &get_user_string('File name to read:', undef, $current_filename);
}
# user canceled
return 1 unless defined($filename);
if (-e $filename) {
if (&readfile($filename)) {
&status("Read file '".$filename."'");
} else {
&status("Couldn't read file '".$filename."': ".$!);
}
} else {
&status("File '".$filename."' doesn't exist.");
}
return 0;
}
########################################################################
# EOF
1;
cadubi-1.3.4/cadubi.1 0000664 0000000 0000000 00000011204 13041231401 0014242 0 ustar 00root root 0000000 0000000 .\" created by Abel Daniel for the Debian Gnu/Linux version, but may be used by
others.
.TH "cadubi" "1" "1.3.4" "Abel Daniel" "User commands"
.SH "NAME"
cadubi \- Creative ASCII Drawing Utility By Ian
.SH "DESCRIPTION"
cadubi is an application written in Perl that allows you to draw text\-based
images that are viewable on typical UNIX\-based consoles. Usually the
applications
that emulate these consoles support various text modes, such as background and
foreground colors, bold, and inverse. This text art, commonly called
"ASCII art", is used in various places such as online BBSes, email and
login prompts.
.SH "OPTIONS"
.TP
.B \-h \-\-help
display some documentation
.TP
.BI \-m \-\-mute
turn off beeping
.TP
.BI "\-s ["W "] ["H ]
.TP
.BI "\-\-size ["W "] ["H ]
sets the size of the console for use with cadubi, where W is number of columns
and H is number of rows.
.TP
.B \-v \-\-version
show cadubi's version
.SH "CONFIGURING"
Beeping and command line options can be also set in /usr/bin/cadubi.
.SH "KEYBOARD"
.TP
.B i j k l
Move the cursor around. Holding down shift and typing these keys will move the
ursor five spaces instead of one.
.TP
.B space
Paint the current pen on the screen.
.TP
.B return/enter
Move the cursor down one line and all the way to the left of the console.
.TP
.BI "delete " "or " "backspace " "or "`
Delete the character before the cursor.
.TP
.B p
Prompt for a pen character
.TP
.B f
Prompt for foreground color (see section colors).
.TP
.B b
Prompt for background color (see section colors).
.TP
.B g
Toggle bold mode.
.TP
.B v
Toggle inverse mode.
.TP
.B shift-w
Toggle blink (highly annoying).
.TP
.B t
Enter text mode. This allows you to type like as if you were using a normal
text editor, and all the characters drawn onscreen will use the same mode
as the pen
.
Pressing Esc will exit text mode.
.TP
.B control-w
Refresh the entire screen by redrawing each character.
.TP
.B control-r
Open a file.
.TP
.B control-o
Save the file.
.TP
.B control-h
Show the quick help screen.
.TP
.B control-x
Exit cadubi.
.SH "USING"
Cadubi has a 'pen' which describes the current mode. Properties of the pen are
the painting character, foreground color, background color, bold, inverse, and
blink. Whenever you paint or use the text mode, the characters drawn on the
screen will have the properties of the pen. The current mode of the pen is
shown at the bottom of the console and is what will be drawn on screen
when you paint.
.
Typically, foreground text colors are the same as background colors, unless
the text is bold. If the text is bold, foreground colors are usually lighter
than
the background color, making text easier to read when the text has the same
foreground and background color. Refer to the Quick Help (control-'h') to see
what the colors look like on your console.
Text mode is an extremely useful feature. Once in the text mode you can type
as if you were using a normal text editor, and all the characters drawn
onscreen will use the same mode as the pen. To enter text mode,
press the 't' key. To exit, press escape.
When cadubi reads a file, it will only read as much that will fit in the
workspace (the area of the console minus the bottom row [status bar]). To gain
more workspace, see the '-s' operator in section "options".
Cadubi optimizes its output files to display properly and take up as little
space as possible. All cadubi output can be viewed with the 'cat' utility.
.SH "COLORS"
The color codes are case-insensitive.
The following color codes can be chosen as fore- or background colors:
.IP
0 or N \- Normal (standard text)
.IP
1 or W \- White
.IP
2 or R \- Red
.IP
3 or G \- Green
.IP
4 or Y \- Yellow
.IP
5 or B \- Blue
.IP
6 or M \- Magenta
.IP
7 or C \- Cyan
.IP
8 or K \- Black
.SH "WARNING"
Cadubi uses escape sequences for things like color. These may differ from
system to system. This means that the file generated by cadubi may
trash your console when viewed with for example cat.
It is generally safe to use the files on the
same type of console as they were generated on.
.SH "AUTHORS"
Cadubi was created and is currently being maintained by Ian Langworth. Please
send all questions, comments, hate mail and bug reports to cadubi@logicallemon.
com
.SH "SEE ALSO"
The "Keyboard and Console HOWTO" and the "Text Terminal HOWTO" from the
Linuxdoc project (www.linuxdoc.org). Both are available in a Debian GNU/Linux
system by installing the doc-linux-text package at
.B /usr/share/doc/HOWTO/en-txt/Keyboard-and-Console-HOWTO.gz
and
.B /usr/share/doc/HOWTO/en-txt/Text-Terminal-HOWTO.gz
respectively.
This man page was copy-pasted from other documentation by Abel Daniel (abli@mai
lbox.hu) for the Debian GNU/Linux distributions, but can be used by
others.
cadubi-1.3.4/extras/ 0000775 0000000 0000000 00000000000 13041231401 0014241 5 ustar 00root root 0000000 0000000 cadubi-1.3.4/extras/ansi_term_codes.txt 0000664 0000000 0000000 00000010267 13041231401 0020146 0 ustar 00root root 0000000 0000000 ANSI TERMINAL CODES
------------------------------------------------------------------------
From the "Castle Perilous Manual"
Original text Copyright (c) 1998 CircleWorld
Converted to text & updated by Ian L. (1/23/00)
------------------------------------------------------------------------
ANSI is a standard for screen displays. Here is a listing of ANSI codes for color. Not available for game play, but is handy for coders.
Wherever you see '#', that should be replaced by the appropriate number. The ESC char is usually hexidecimal 1B (ASCII 27, Octal 033) on most computers. To clarify this, in the example 'ESC[#B', to move the cursor down two lines you would print "\x1b[2B" in perl or in C.
ESC code sequence Function
------------------------------------------------------------------------
>> Cursor Controls:
ESC[#;#H or ESC[#;#f Moves cusor to line #, column #
ESC[#A Moves cursor up # lines
ESC[#B Moves cursor down # lines
ESC[#C Moves cursor forward # spaces
ESC[#D Moves cursor back # spaces
ESC[#;#R Reports current cursor line & column
ESC[s Saves cursor position for recall later
ESC[u Return to saved cursor position
------------------------------------------------------------------------
>> Erase Functions:
ESC[2J Clear screen and home cursor
ESC[K Clear to end of line
------------------------------------------------------------------------
>> Set Graphics Rendition:
ESC[#m Set single display attribute
ESC[#;#;...;#m Set multiple display attributes where # is:
0 for normal display
1 for bold on
4 underline (mono only)
5 blink on
7 reverse video on
8 nondisplayed (invisible)
30 black foreground
31 red foreground
32 green foreground
33 yellow foreground
34 blue foreground
35 magenta foreground
36 cyan foreground
37 white foreground
40 black background
41 red background
42 green background
43 yellow background
44 blue background
45 magenta background
46 cyan background
47 white background
ESC[=#;7h or..
ESC[=h or..
ESC[=0h or..
ESC[?7h Put screen in indicated mode where # is
0 for 40 x 25 black & white
1 for 40 x 25 color
2 for 80 x 25 b&w
3 for 80 x 25 color
4 for 320 x 200 color graphics
5 for 320 x 200 b & w graphics
6 for 640 x 200 b & w graphics
7 to wrap at end of line
ESC[=#;7l or..
ESC[=l or..
ESC[=0l or..
ESC[?7l Resets mode # set with above command
------------------------------------------------------------------------
>> Keyboard Reassignments:
ESC[#;#;...p or..
ESC["string"p or..
ESC[#;"string";#;
Using: #;"string";#p
The first ASCII code defines which code is to be changed. The remaining codes define what it is to be changed to.
Example: Reassign the Q and q keys to the A and a keys (and vice versa).
ESC[65;81p --> A becomes Q
ESC[97;113p --> a becomes q
ESC[81;65p --> Q becomes A
ESC[113;97p --> q becomes a
Example: Reassign the F10 key to a DIR command.
ESC [0;68;"dir";13p
The 0;68 is the extended ASCII code for the F10 key and 13 is the ASCII
code for a carriage return.
Other function key codes:
F1=59
F2=60
F3=61
F4=62
F5=63
F6=64
F7=65
F8=66
F9=67
F10=68
------------------------------------------------------------------------
Eat snacky smores!
cadubi-1.3.4/help.txt 0000664 0000000 0000000 00000007310 13041231401 0014425 0 ustar 00root root 0000000 0000000 [0m[44;34;1moooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo[0m
[0m[44;34;1mo[0m [0m[31;1mcadubi Keys[0m [0m[44;34;1mo[0m [0m[31;1mColor Codes[0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[44;34;1mo[0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[1mijkl[0m Move [0m[44;34;1mo[0m [0m[1mKey FG BG Bold All[0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[1mIJKL[0m Move Quick [0m[44;34;1mo[0m n / 0 X [0m[1mX[0m [0m[1mXXX[0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[1mspace[0m Paint with Pen [0m[44;34;1mo[0m w / 1 [0m[37mX[0m [0m[47;37m [0m [0m[37;1mX[0m [0m[47;37;1mXXX[0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[1mdel[0m Erase [0m[44;34;1mo[0m r / 2 [0m[31mX[0m [0m[41;31m [0m [0m[31;1mX[0m [0m[41;31;1mXXX[0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[1mp[0m Set Pen Character [0m[44;34;1mo[0m g / 3 [0m[32mX[0m [0m[42;32m [0m [0m[32;1mX[0m [0m[42;32;1mXXX[0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[1m g[0m Toggle Pen Bold [0m[44;34;1mo[0m y / 4 [0m[33mX[0m [0m[43m [0m [0m[33;1mX[0m [0m[43;33;1mXXX[0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[1m v[0m Toggle Pen Inverse [0m[44;34;1mo[0m b / 5 [0m[34mX[0m [0m[44m [0m [0m[34;1mX[0m [0m[44;34;1mXXX[0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[1m f[0m Set Pen Foreground [0m[44;34;1mo[0m m / 6 [0m[35mX[0m [0m[45m [0m [0m[35;1mX[0m [0m[45;35;1mXXX[0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[1m b[0m Set Pen Background [0m[44;34;1mo[0m c / 7 [0m[36mX[0m [0m[46m [0m [0m[36;1mX[0m [0m[46;36;1mXXX[0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[1m t[0m Text Mode [0m[44;34;1mo[0m k / 8 [0m[30mX[0m [0m[40m [0m [0m[30;1mX[0m [0m[40;30;1mXXX[0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[1m W[0m Toggle Pen Blink [0m[44;34;1mo[0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[1m^r[0m Read File In [0m[44;34;1mooooooooooooooooooooooooooooooooooooooooooooooooo[0m
[0m[44;34;1mo[0m [0m[1m^o[0m Write File Out [0m[44;34;1mo[0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[1m^x[0m Exit [0m[44;34;1mo[0m [0m[31;1mWebsite:[0m https://github.com/statico/cadubi [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[1m^w[0m Refresh Screen [0m[44;34;1mo[0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[1m `[0m Erase (also) [0m[44;34;1mo[0m [0m[31;1m [0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[44;34;1mo[0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[44;34;1mo[0m [0m[44;34;1mo[0m
[0m[44;34;1mo[0m [0m[44;34;1mo[0m [0m[44;34;1mo[0m
[0m[44;34;1moooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo[0m
cadubi-1.3.4/logo.txt 0000664 0000000 0000000 00000001655 13041231401 0014443 0 ustar 00root root 0000000 0000000 [0m [0m[46;36;1mcccc[0m [0m[41;31;1mrrrr[0m [0m[43;33;1myyy[0m [0m[42;32;1mg[0m [0m[42;32;1mg[0m [0m[44;34;1mbbb[0m [0m[45;35;1mm[0m[0m
[0m [0m[46;36;1mc[0m [0m[41;31;1mr[0m [0m[41;31;1mr[0m [0m[43;33;1my[0m [0m[43;33;1my[0m [0m[42;32;1mg[0m [0m[42;32;1mg[0m [0m[44;34;1mb[0m [0m[44;34;1mb[0m [0m[45;35;1mm[0m[0m
[0m [0m[46;36;1mc[0m [0m[41;31;1mrrrr[0m [0m[43;33;1my[0m [0m[43;33;1my[0m [0m[42;32;1mg[0m [0m[42;32;1mg[0m [0m[44;34;1mbbb[0m [0m[45;35;1mm[0m[0m
[0m [0m[46;36;1mc[0m [0m[41;31;1mr[0m [0m[41;31;1mr[0m [0m[43;33;1my[0m [0m[43;33;1my[0m [0m[42;32;1mg[0m [0m[42;32;1mg[0m [0m[44;34;1mb[0m [0m[44;34;1mb[0m [0m[45;35;1mm[0m[0m
[0m [0m[46;36;1mcccc[0m [0m[41;31;1mr[0m [0m[41;31;1mr[0m [0m[43;33;1myyy[0m [0m[42;32;1mgggg[0m [0m[44;34;1mbbb[0m [0m[45;35;1mm[0m[0m
cadubi-1.3.4/screenshots/ 0000775 0000000 0000000 00000000000 13041231401 0015273 5 ustar 00root root 0000000 0000000 cadubi-1.3.4/screenshots/catfile.png 0000664 0000000 0000000 00000040007 13041231401 0017411 0 ustar 00root root 0000000 0000000 PNG
IHDR j 8 .H pHYs
!d tIME"JaS IDATxyXWO-@ ( WNL8ɨ4qI:ļ8a%q̈q8Q hPAh qą}ŲjyxxnuoW֡>ڐ vr.a7 9WNa[ b/