mirror of
https://github.com/erkin/ponysay.git
synced 2024-11-29 07:27:59 +01:00
Merge branch 'master' of http://github.com/erkin/ponysay
This commit is contained in:
commit
ed4e30e3f5
7 changed files with 377 additions and 180 deletions
13
CHANGELOG
13
CHANGELOG
|
@ -2,6 +2,19 @@ Version 2.9
|
||||||
|
|
||||||
New extraponies: molestia (Tumblr)
|
New extraponies: molestia (Tumblr)
|
||||||
|
|
||||||
|
The option -q works like -f and -F, it takes one argument, and may be used multiple
|
||||||
|
times for more arguments.
|
||||||
|
|
||||||
|
The old option -q is renamed to --q.
|
||||||
|
|
||||||
|
The options --f and --F has been added.
|
||||||
|
|
||||||
|
Weighted distance for autocorrection on pony names and boolean style name is set to 5, rather
|
||||||
|
than unlimited. Currently this cannot be modified (without editing the source code.)
|
||||||
|
|
||||||
|
If file descriptor 3 is definied when ponysay is executed, extra information is printed to it.
|
||||||
|
|
||||||
|
|
||||||
Version 2.8
|
Version 2.8
|
||||||
|
|
||||||
New ponies: airheart, bastionyorsets, gustavelegrand, milkyway, peppermoon, pinkacopter, pinkiefly,
|
New ponies: airheart, bastionyorsets, gustavelegrand, milkyway, peppermoon, pinkacopter, pinkiefly,
|
||||||
|
|
|
@ -53,8 +53,8 @@ Now every time you open a terminal a pony should give your fortune
|
||||||
|
|
||||||
### Pony quotes
|
### Pony quotes
|
||||||
|
|
||||||
Running `ponysay -q` will give you a random pony saying one it its quote from MLP:FiM. Add one or more argument after `-q` to sepecify a
|
Running `ponysay -q` will give you a random pony saying one it its quote from MLP:FiM.
|
||||||
set of ponies from which one will be selected randomly.
|
Just as with `-`f, `-q` can be used multiple time to to sepecify a set of ponies from which one will be selected randomly.
|
||||||
|
|
||||||
When running `ponysay -l` or `ponysay -L` the ponies which have quotes will be printed bold or bright (depending on terminal).
|
When running `ponysay -l` or `ponysay -L` the ponies which have quotes will be printed bold or bright (depending on terminal).
|
||||||
|
|
||||||
|
|
|
@ -23,13 +23,14 @@ ro=0
|
||||||
(hash makeinfo 2>/dev/null) || (bo=1 ; echo 'Missing makeinfo, install texinfo [build optional]')
|
(hash makeinfo 2>/dev/null) || (bo=1 ; echo 'Missing makeinfo, install texinfo [build optional]')
|
||||||
(hash install-info 2>/dev/null) || (bo=1 ; echo 'Missing install-info, install info [build optional]')
|
(hash install-info 2>/dev/null) || (bo=1 ; echo 'Missing install-info, install info [build optional]')
|
||||||
|
|
||||||
(hash stty 2>/dev/null) || (rr=1 ; echo 'Missing stty, install coreutils [runtime required]')
|
(hash python 2>/dev/null) || (rr=1 ; echo 'Missing python, install python>=3 [build+runtime required]')
|
||||||
(hash python 2>/dev/null) || (rr=1 ; echo 'Missing python, install python>=3 [runtime required]')
|
|
||||||
|
|
||||||
(hash cut 2>/dev/null) && (hash python 2>/dev/null) &&
|
(hash cut 2>/dev/null) && (hash python 2>/dev/null) &&
|
||||||
(test ! $(env python --version 2>&1 | cut -d ' ' -f 2 | cut -d '.' -f 1) = 3) && (
|
(test ! $(env python --version 2>&1 | cut -d ' ' -f 2 | cut -d '.' -f 1) = 3) && (
|
||||||
(hash python3 2>/dev/null) ||
|
(hash python3 2>/dev/null) ||
|
||||||
(rr=1 ; echo 'Missing python>=3, install python (may be named python3) [runtime required]'))
|
(rr=1 ; echo 'Missing python>=3, install python (may be named python3) [build+runtime required]'))
|
||||||
|
|
||||||
|
(hash stty 2>/dev/null) || (rr=1 ; echo 'Missing stty, install coreutils [runtime required]')
|
||||||
|
|
||||||
(hash tty2colourfultty 2>/dev/null) || (ro=1 ; echo 'Missing tty2colourfultty, install util-say [runtime optional]')
|
(hash tty2colourfultty 2>/dev/null) || (ro=1 ; echo 'Missing tty2colourfultty, install util-say [runtime optional]')
|
||||||
(hash ponysay2ttyponysay 2>/dev/null) || (ro=1 ; echo 'Missing ponysay2ttyponysay, install util-say [runtime optional]')
|
(hash ponysay2ttyponysay 2>/dev/null) || (ro=1 ; echo 'Missing ponysay2ttyponysay, install util-say [runtime optional]')
|
||||||
|
|
|
@ -76,8 +76,8 @@ multiple times, and one of the will be selected randomly.
|
||||||
.B \-q, \-\-quote [\fIname\fP...]
|
.B \-q, \-\-quote [\fIname\fP...]
|
||||||
By using this option, a pony will be printed with quotes from her in My Little Pony:
|
By using this option, a pony will be printed with quotes from her in My Little Pony:
|
||||||
Friendship is Magic. The pony will be selected randomly, unless at least one pony
|
Friendship is Magic. The pony will be selected randomly, unless at least one pony
|
||||||
is added as an argument after \fI-q\fP. If one or more ponies are added after \fI-q\fP
|
is added as an argument to \fI-q\fP. If one or more ponies are added as an argument
|
||||||
the pony will be selected randomly from that set of ponies.
|
to \fI-q\fP the pony will be selected randomly from that set of ponies.
|
||||||
.TP
|
.TP
|
||||||
.B \-W, \-\-wrap \fIcolumn\fP
|
.B \-W, \-\-wrap \fIcolumn\fP
|
||||||
The screen column where the message should be wrapped.
|
The screen column where the message should be wrapped.
|
||||||
|
|
|
@ -116,7 +116,7 @@ way over e-mail.
|
||||||
@cindex invoking
|
@cindex invoking
|
||||||
@cindex options
|
@cindex options
|
||||||
@cindex arguments
|
@cindex arguments
|
||||||
@pindex ponythink
|
@pindex @command{ponythink}
|
||||||
|
|
||||||
The format for running the @command{ponysay} program is:
|
The format for running the @command{ponysay} program is:
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ In versions earlier than version 2.0, the if the pony were a file name it had to
|
||||||
include a `@code{/}'. This is not longer required and any existing pony name
|
include a `@code{/}'. This is not longer required and any existing pony name
|
||||||
supersedes file names.
|
supersedes file names.
|
||||||
|
|
||||||
@item -F
|
@item -F PONY
|
||||||
@itemx ++file PONY
|
@itemx ++file PONY
|
||||||
@itemx ++pony PONY
|
@itemx ++pony PONY
|
||||||
@opindex @option{-F}
|
@opindex @option{-F}
|
||||||
|
@ -181,6 +181,54 @@ supersedes file names.
|
||||||
Just as @option{-F}, but it uses extra (non-MLP:FiM) ponies instead of standard
|
Just as @option{-F}, but it uses extra (non-MLP:FiM) ponies instead of standard
|
||||||
(MLP:FiM) ponies
|
(MLP:FiM) ponies
|
||||||
|
|
||||||
|
@item -q PONY
|
||||||
|
@itemx --quote PONY
|
||||||
|
@opindex @option{-q}
|
||||||
|
@opindex @option{--quote}
|
||||||
|
@cindex quotes
|
||||||
|
@cindex pony quotes
|
||||||
|
By using this option, a pony will be printed with quotes from her in My Little Pony:
|
||||||
|
Friendship is Magic. The pony will be selected randomly, unless at least one pony
|
||||||
|
is added as an argument to @option{-q}. If one or more ponies are added as an argument
|
||||||
|
to @option{-q}, the pony will be selected randomly from that set of ponies.
|
||||||
|
This option requires the extension @command{ponyquotes4ponysay}, which is included
|
||||||
|
by default since version 1.2.
|
||||||
|
|
||||||
|
The argument can be a file name, but only if it ends with @file{.pony}.
|
||||||
|
|
||||||
|
@item --f [PONY...]
|
||||||
|
@itemx --files [PONY...]
|
||||||
|
@itemx --ponies [PONY...]
|
||||||
|
@opindex @option{--f}
|
||||||
|
@opindex @option{--files}
|
||||||
|
@opindex @option{--ponies}
|
||||||
|
Variadic variant of @option{-f}, meaning that all arguments added after this one
|
||||||
|
will parsed as an argument to this option. Additionally, those options are added
|
||||||
|
to @option{-f}.
|
||||||
|
|
||||||
|
@item --F [PONY...]
|
||||||
|
@itemx ++files [PONY...]
|
||||||
|
@itemx ++ponies [PONY...]
|
||||||
|
@opindex @option{--F}
|
||||||
|
@opindex @option{++files}
|
||||||
|
@opindex @option{++ponies}
|
||||||
|
Variadic variant of @option{-F}, meaning that all arguments added after this one
|
||||||
|
will parsed as an argument to this option. Additionally, those options are added
|
||||||
|
to @option{-F}.
|
||||||
|
|
||||||
|
@item --q [PONY...]
|
||||||
|
@itemx --quotes [PONY...]
|
||||||
|
@opindex @option{--q}
|
||||||
|
@opindex @option{--quotes}
|
||||||
|
@cindex quotes
|
||||||
|
@cindex pony quotes
|
||||||
|
Variadic variant of @option{-q}, meaning that all arguments added after this one
|
||||||
|
will parsed as an argument to this option. Additionally, those options are added
|
||||||
|
to @option{-q}.
|
||||||
|
|
||||||
|
An important feature of this options, is that you can but it in the end of the
|
||||||
|
command line, without any argument to get a quote from any pony with a quote.
|
||||||
|
|
||||||
@item -b STYLE
|
@item -b STYLE
|
||||||
@itemx --bubble STYLE
|
@itemx --bubble STYLE
|
||||||
@itemx --balloon STYLE
|
@itemx --balloon STYLE
|
||||||
|
@ -192,19 +240,6 @@ balloon name printed by @option{ponysay -B}. This option can be used multiple
|
||||||
times to specify a set of styles from which one will be selected randomly. If no
|
times to specify a set of styles from which one will be selected randomly. If no
|
||||||
balloon style is specified a fallback style will be used.
|
balloon style is specified a fallback style will be used.
|
||||||
|
|
||||||
@item -q [PONY...]
|
|
||||||
@itemx --quote [PONY...]
|
|
||||||
@opindex @option{-q}
|
|
||||||
@opindex @option{--quote}
|
|
||||||
By using this option, a pony will be printed with quotes from her in My Little Pony:
|
|
||||||
Friendship is Magic. The pony will be selected randomly, unless at least one pony
|
|
||||||
is added as an argument after @option{-q}. If one or more ponies are added after
|
|
||||||
@option{-q}, the pony will be selected randomly from that set of ponies.
|
|
||||||
This option requires the extension @command{ponyquotes4ponysay}, which is included
|
|
||||||
by default since version 1.2.
|
|
||||||
|
|
||||||
The argument can be a file name, but only if it ends with @file{.pony}.
|
|
||||||
|
|
||||||
@item -W COLUMN
|
@item -W COLUMN
|
||||||
@itemx --wrap COLUMN
|
@itemx --wrap COLUMN
|
||||||
@opindex @option{-W}
|
@opindex @option{-W}
|
||||||
|
@ -289,7 +324,8 @@ The first list are the MLP:FiM and the second one are non-MLP:FiM.
|
||||||
@opindex @option{-o}
|
@opindex @option{-o}
|
||||||
@opindex @option{--pony-only}
|
@opindex @option{--pony-only}
|
||||||
@opindex @option{--ponyonly}
|
@opindex @option{--ponyonly}
|
||||||
Print just the pony, nothing else like the speech balloon.
|
Print just the pony, nothing else like the speech balloon. Naturally the
|
||||||
|
@command{ponysay} will not wait for a message from stdin.
|
||||||
|
|
||||||
@item -X
|
@item -X
|
||||||
@itemx --256-colours
|
@itemx --256-colours
|
||||||
|
@ -376,11 +412,13 @@ this file should be a symbolic link to the pony you want as a default. If it is
|
||||||
a symbolic link, @option{-q} cannot determine which quotes to use.
|
a symbolic link, @option{-q} cannot determine which quotes to use.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@node Advanced usage
|
@node Advanced usage
|
||||||
@chapter Advanced usage of @command{ponysay}.
|
@chapter Advanced usage of @command{ponysay}.
|
||||||
@cindex advanced usage
|
@cindex advanced usage
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
|
* Extra information:: Displaying extra information.
|
||||||
* Fortune cookies:: Displaying with fortune cookies.
|
* Fortune cookies:: Displaying with fortune cookies.
|
||||||
* Ponification:: Ponify your fortune cookies.
|
* Ponification:: Ponify your fortune cookies.
|
||||||
* Running on TTY:: Running on TTY (Linux VT).
|
* Running on TTY:: Running on TTY (Linux VT).
|
||||||
|
@ -388,9 +426,28 @@ a symbolic link, @option{-q} cannot determine which quotes to use.
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@node Extra information
|
||||||
|
@section Extra information
|
||||||
|
@cindex file descriptor 3
|
||||||
|
@cindex extra information
|
||||||
|
@cindex verbose mode
|
||||||
|
@pindex @command{tee}
|
||||||
|
If file descriptor 3 is definied when @command{ponysay} is executed, extra information
|
||||||
|
is printed to it. The printed information includes the name of the pony file, the name
|
||||||
|
of the balloon style file, and if definied in the pony file, file meta data and comment.
|
||||||
|
|
||||||
|
In most shells, a file descriptor 3 can defined using @command{3> FILE}, and linked to
|
||||||
|
stderr using @command{3>&2}. For example, you can print the information to @file{~/info}
|
||||||
|
by running @command{ponysay I\'m just the cutest pony! | 3> ~/info}.
|
||||||
|
|
||||||
|
The message is not stored this way, for that you can use @command{tee}. However, if you
|
||||||
|
use @option{-q} the quote file is printed to file descriptor 3.
|
||||||
|
|
||||||
|
|
||||||
@node Fortune cookies
|
@node Fortune cookies
|
||||||
@section Fortune cookies
|
@section Fortune cookies
|
||||||
@pindex fortune
|
@pindex @command{fortune}
|
||||||
@cindex startup
|
@cindex startup
|
||||||
@cindex on startup
|
@cindex on startup
|
||||||
@cindex @file{.bashrc}
|
@cindex @file{.bashrc}
|
||||||
|
@ -410,7 +467,7 @@ described in the previous paragraph every time you open a terminal.
|
||||||
@section Ponification
|
@section Ponification
|
||||||
@cindex ponification
|
@cindex ponification
|
||||||
@cindex text ponification
|
@cindex text ponification
|
||||||
@pindex ponypipe
|
@pindex @command{ponypipe}
|
||||||
|
|
||||||
You can ponify messages (i.e. replaces words search as `everyone' with `everypony') by
|
You can ponify messages (i.e. replaces words search as `everyone' with `everypony') by
|
||||||
using @code{fortune | ponypipe} instead of using @command{fortune}. @command{ponypipe}
|
using @code{fortune | ponypipe} instead of using @command{fortune}. @command{ponypipe}
|
||||||
|
@ -447,7 +504,7 @@ You should read more about this in @ref{KMS ponies}.
|
||||||
|
|
||||||
@node Running on screen
|
@node Running on screen
|
||||||
@section Running on @command{screen}
|
@section Running on @command{screen}
|
||||||
@pindex screen
|
@pindex @command{screen}
|
||||||
@cindex @file{.bashrc}
|
@cindex @file{.bashrc}
|
||||||
@cindex @file{~/.bashrc}
|
@cindex @file{~/.bashrc}
|
||||||
|
|
||||||
|
@ -667,7 +724,7 @@ run on it.
|
||||||
|
|
||||||
@node Cowsay
|
@node Cowsay
|
||||||
@section Cowsay
|
@section Cowsay
|
||||||
@pindex cowsay
|
@pindex @command{cowsay}
|
||||||
|
|
||||||
This section describes the limitation of @command{cowsay}, but since version 2.1
|
This section describes the limitation of @command{cowsay}, but since version 2.1
|
||||||
@command{cowsay} is no longer used because of it. So none of the following limitations
|
@command{cowsay} is no longer used because of it. So none of the following limitations
|
||||||
|
@ -1951,8 +2008,22 @@ sequences.
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
New extraponies: @file{molestia} (Tumblr)
|
New extraponies: @file{molestia} (Tumblr)
|
||||||
|
@item
|
||||||
|
The option @option{-q} works like @option{-f} and @option{-F}, it takes one argument, and
|
||||||
|
may be used multiple times for more arguments.
|
||||||
|
@item
|
||||||
|
The old option @option{-q} is renamed to @option{--q}.
|
||||||
|
@item
|
||||||
|
The options @option{--f} and @option{--F} has been added.
|
||||||
|
@item
|
||||||
|
Weighted distance for autocorrection on pony names and boolean style name is set to 5, rather
|
||||||
|
than unlimited. Currently this cannot be modified (without editing the source code.)
|
||||||
|
@item
|
||||||
|
If file descriptor 3 is definied when @command{ponysay} is executed, extra information is
|
||||||
|
printed to it.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
|
|
||||||
@heading Version 2.8
|
@heading Version 2.8
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
|
|
184
ponysay.py
184
ponysay.py
|
@ -47,6 +47,29 @@ programs by default, report them to Princess Celestia so she can banish them to
|
||||||
def print(text = '', end = '\n'):
|
def print(text = '', end = '\n'):
|
||||||
sys.stdout.buffer.write((str(text) + end).encode('utf-8'))
|
sys.stdout.buffer.write((str(text) + end).encode('utf-8'))
|
||||||
|
|
||||||
|
'''
|
||||||
|
stderr equivalent to print()
|
||||||
|
|
||||||
|
@param text:str The text to print (empty string is default)
|
||||||
|
@param end:str The appendix to the text to print (line breaking is default)
|
||||||
|
'''
|
||||||
|
def printerr(text = '', end = '\n'):
|
||||||
|
sys.stderr.buffer.write((str(text) + end).encode('utf-8'))
|
||||||
|
|
||||||
|
fd3 = None
|
||||||
|
'''
|
||||||
|
/proc/self/fd/3 equivalent to print()
|
||||||
|
|
||||||
|
@param text:str The text to print (empty string is default)
|
||||||
|
@param end:str The appendix to the text to print (line breaking is default)
|
||||||
|
'''
|
||||||
|
def printinfo(text = '', end = '\n'):
|
||||||
|
global fd3
|
||||||
|
if os.path.exists('/proc/self/fd/3'):
|
||||||
|
if fd3 is None:
|
||||||
|
fd3 = os.fdopen(3, 'w')
|
||||||
|
fd3.write(str(text) + end)
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Checks whether a text ends with a specific text, but has more
|
Checks whether a text ends with a specific text, but has more
|
||||||
|
@ -56,7 +79,7 @@ Checks whether a text ends with a specific text, but has more
|
||||||
@return :bool The result of the test
|
@return :bool The result of the test
|
||||||
'''
|
'''
|
||||||
def endswith(text, ending):
|
def endswith(text, ending):
|
||||||
return text.endswith(ending) and not (text == ending);
|
return text.endswith(ending) and not (text == ending)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,6 +95,7 @@ class Ponysay():
|
||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
if (args.argcount == 0) and not pipelinein:
|
if (args.argcount == 0) and not pipelinein:
|
||||||
args.help()
|
args.help()
|
||||||
|
exit(254)
|
||||||
return
|
return
|
||||||
|
|
||||||
## Modifyable global variables
|
## Modifyable global variables
|
||||||
|
@ -82,18 +106,23 @@ class Ponysay():
|
||||||
global extraponydirs
|
global extraponydirs
|
||||||
|
|
||||||
## Emulate termial capabilities
|
## Emulate termial capabilities
|
||||||
if args.opts['-X'] is not None:
|
if args.opts['-X'] is not None: (linuxvt, usekms) = (False, False)
|
||||||
linuxvt = False
|
elif args.opts['-V'] is not None: (linuxvt, usekms) = (True, False)
|
||||||
usekms = False
|
elif args.opts['-K'] is not None: (linuxvt, usekms) = (True, True)
|
||||||
elif args.opts['-V'] is not None:
|
|
||||||
linuxvt = True
|
|
||||||
usekms = False
|
|
||||||
elif args.opts['-K'] is not None:
|
|
||||||
linuxvt = True
|
|
||||||
usekms = True
|
|
||||||
ponydirs = vtponydirs if linuxvt and not usekms else xponydirs
|
ponydirs = vtponydirs if linuxvt and not usekms else xponydirs
|
||||||
extraponydirs = extravtponydirs if linuxvt and not usekms else extraxponydirs
|
extraponydirs = extravtponydirs if linuxvt and not usekms else extraxponydirs
|
||||||
|
|
||||||
|
## Variadic variants of -f, -F and -q
|
||||||
|
if args.opts['--f'] is not None:
|
||||||
|
if args.opts['-f'] is not None: args.opts['-f'] += args.opts['--f']
|
||||||
|
else: args.opts['-f'] = args.opts['--f']
|
||||||
|
if args.opts['--F'] is not None:
|
||||||
|
if args.opts['-F'] is not None: args.opts['-F'] += args.opts['--F']
|
||||||
|
else: args.opts['-F'] = args.opts['--F']
|
||||||
|
if args.opts['--q'] is not None:
|
||||||
|
if args.opts['-q'] is not None: args.opts['-q'] += args.opts['--q']
|
||||||
|
else: args.opts['-q'] = args.opts['--q']
|
||||||
|
|
||||||
## Run modes
|
## Run modes
|
||||||
if args.opts['-h'] is not None: args.help()
|
if args.opts['-h'] is not None: args.help()
|
||||||
elif args.opts['--quoters'] is not None: self.quoters()
|
elif args.opts['--quoters'] is not None: self.quoters()
|
||||||
|
@ -124,10 +153,26 @@ class Ponysay():
|
||||||
self.__ucsremap(args)
|
self.__ucsremap(args)
|
||||||
if args.opts['-o'] is not None:
|
if args.opts['-o'] is not None:
|
||||||
mode += '$/= $$\\= $'
|
mode += '$/= $$\\= $'
|
||||||
|
args.message = ''
|
||||||
|
|
||||||
## The stuff
|
## The stuff
|
||||||
if args.opts['-q'] is not None: self.quote(args)
|
if args.opts['-q'] is not None:
|
||||||
else: self.print_pony(args)
|
warn = (args.opts['-f'] is not None) or (args.opts['-F'] is not None)
|
||||||
|
if (len(args.opts['-q']) == 1) and ((args.opts['-q'][0] == '-f') or (args.opts['-q'][0] == '-F')):
|
||||||
|
warn = True
|
||||||
|
if args.opts['-q'][0] == '-f':
|
||||||
|
args.opts['-q'] = args.files
|
||||||
|
if args.opts['-f'] is not None:
|
||||||
|
args.opts['-q'] += args.opts['-f']
|
||||||
|
self.quote(args)
|
||||||
|
if warn:
|
||||||
|
printerr('-q cannot be used at the same time as -f or -F.')
|
||||||
|
elif not unrecognised:
|
||||||
|
self.print_pony(args)
|
||||||
|
else:
|
||||||
|
args.help()
|
||||||
|
exit(255)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
##############################################
|
##############################################
|
||||||
|
@ -289,7 +334,7 @@ class Ponysay():
|
||||||
if not alt:
|
if not alt:
|
||||||
autocorrect = SpelloCorrecter(ponydirs, '.pony')
|
autocorrect = SpelloCorrecter(ponydirs, '.pony')
|
||||||
(alternatives, dist) = autocorrect.correct(pony)
|
(alternatives, dist) = autocorrect.correct(pony)
|
||||||
if len(alternatives) > 0:
|
if (len(alternatives) > 0) and (dist <= 5): # TODO the limit `dist` should be configureable
|
||||||
return self.__getponypath(alternatives, True)
|
return self.__getponypath(alternatives, True)
|
||||||
sys.stderr.write('I have never heard of anypony named %s\n' % (pony));
|
sys.stderr.write('I have never heard of anypony named %s\n' % (pony));
|
||||||
exit(1)
|
exit(1)
|
||||||
|
@ -362,10 +407,13 @@ class Ponysay():
|
||||||
'''
|
'''
|
||||||
def __gettermsize(self):
|
def __gettermsize(self):
|
||||||
## Call `stty` to determine the size of the terminal, this way is better then using python's ncurses
|
## Call `stty` to determine the size of the terminal, this way is better then using python's ncurses
|
||||||
termsize = Popen(['stty', 'size'], stdout=PIPE, stdin=sys.stderr).communicate()[0]
|
for channel in (sys.stderr, sys.stdout, sys.stdin):
|
||||||
|
termsize = Popen(['stty', 'size'], stdout=PIPE, stdin=channel, stderr=PIPE).communicate()[0]
|
||||||
|
if len(termsize) > 0:
|
||||||
termsize = termsize.decode('utf8', 'replace')[:-1].split(' ') # [:-1] removes a \n
|
termsize = termsize.decode('utf8', 'replace')[:-1].split(' ') # [:-1] removes a \n
|
||||||
termsize = [int(item) for item in termsize]
|
termsize = [int(item) for item in termsize]
|
||||||
return termsize
|
return termsize
|
||||||
|
return (24, 80) # fall back to minimal sane size
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -642,9 +690,9 @@ class Ponysay():
|
||||||
if balloon not in balloons:
|
if balloon not in balloons:
|
||||||
if not alt:
|
if not alt:
|
||||||
autocorrect = SpelloCorrecter(balloondirs, '.think' if isthink else '.say')
|
autocorrect = SpelloCorrecter(balloondirs, '.think' if isthink else '.say')
|
||||||
alternatives = autocorrect.correct(balloon)[0]
|
(alternatives, dist) = autocorrect.correct(balloon)
|
||||||
if len(alternatives) > 0:
|
if (len(alternatives) > 0) and (dist <= 5): # TODO the limit `dist` should be configureable
|
||||||
return self.__getponypath(alternatives, True)
|
return self.__getballoonpath(alternatives, True)
|
||||||
sys.stderr.write('That balloon style %s does not exist\n' % (balloon));
|
sys.stderr.write('That balloon style %s does not exist\n' % (balloon));
|
||||||
exit(1)
|
exit(1)
|
||||||
else:
|
else:
|
||||||
|
@ -671,7 +719,8 @@ class Ponysay():
|
||||||
|
|
||||||
## Read all lines in the balloon file
|
## Read all lines in the balloon file
|
||||||
with open(balloonfile, 'rb') as balloonstream:
|
with open(balloonfile, 'rb') as balloonstream:
|
||||||
data = [line.replace('\n', '') for line in balloonstream.read().decode('utf8', 'replace').split('\n')]
|
data = balloonstream.read().decode('utf8', 'replace')
|
||||||
|
data = [line.replace('\n', '') for line in data.split('\n')]
|
||||||
|
|
||||||
## Parse the balloon file, and fill the map
|
## Parse the balloon file, and fill the map
|
||||||
last = None
|
last = None
|
||||||
|
@ -740,6 +789,7 @@ class Ponysay():
|
||||||
|
|
||||||
## Get the pony
|
## Get the pony
|
||||||
pony = self.__getponypath(args.opts['-f'])
|
pony = self.__getponypath(args.opts['-f'])
|
||||||
|
printinfo('pony file: ' + pony)
|
||||||
|
|
||||||
## Use PNG file as pony file
|
## Use PNG file as pony file
|
||||||
if endswith(pony.lower(), '.png'):
|
if endswith(pony.lower(), '.png'):
|
||||||
|
@ -763,7 +813,9 @@ class Ponysay():
|
||||||
messagewrap = int(args.opts['-W'][0]) if args.opts['-W'] is not None else None
|
messagewrap = int(args.opts['-W'][0]) if args.opts['-W'] is not None else None
|
||||||
|
|
||||||
## Get balloon object
|
## Get balloon object
|
||||||
balloon = self.__getballoon(self.__getballoonpath(args.opts['-b'])) if args.opts['-o'] is None else None
|
balloonfile = self.__getballoonpath(args.opts['-b'])
|
||||||
|
printinfo('balloon style file: ' + str(balloonfile))
|
||||||
|
balloon = self.__getballoon(balloonfile) if args.opts['-o'] is None else None
|
||||||
|
|
||||||
## Get hyphen style
|
## Get hyphen style
|
||||||
hyphencolour = ''
|
hyphencolour = ''
|
||||||
|
@ -839,6 +891,7 @@ class Ponysay():
|
||||||
## Select a random pony–quote-pair, load it and print it
|
## Select a random pony–quote-pair, load it and print it
|
||||||
if not len(pairs) == 0:
|
if not len(pairs) == 0:
|
||||||
pair = pairs[random.randrange(0, len(pairs))]
|
pair = pairs[random.randrange(0, len(pairs))]
|
||||||
|
printinfo('quote file: ' + pair[1])
|
||||||
with open(pair[1], 'rb') as qfile:
|
with open(pair[1], 'rb') as qfile:
|
||||||
args.message = qfile.read().decode('utf8', 'replace').strip()
|
args.message = qfile.read().decode('utf8', 'replace').strip()
|
||||||
args.opts['-f'] = [pair[0]]
|
args.opts['-f'] = [pair[0]]
|
||||||
|
@ -1068,6 +1121,7 @@ class ArgParser():
|
||||||
Parse arguments
|
Parse arguments
|
||||||
|
|
||||||
@param args:list<str> The command line arguments, should include the execute file at index 0, `sys.argv` is default
|
@param args:list<str> The command line arguments, should include the execute file at index 0, `sys.argv` is default
|
||||||
|
@return :bool Whether no unrecognised option is used
|
||||||
'''
|
'''
|
||||||
def parse(self, argv = sys.argv):
|
def parse(self, argv = sys.argv):
|
||||||
self.argcount = len(argv) - 1
|
self.argcount = len(argv) - 1
|
||||||
|
@ -1083,9 +1137,11 @@ class ArgParser():
|
||||||
tmpdashed = False
|
tmpdashed = False
|
||||||
get = 0
|
get = 0
|
||||||
dontget = 0
|
dontget = 0
|
||||||
|
self.rc = True
|
||||||
|
|
||||||
def unrecognised(arg):
|
def unrecognised(arg):
|
||||||
sys.stderr.write('%s: warning: unrecognised option %s\n' % (self.__program, arg))
|
sys.stderr.write('%s: warning: unrecognised option %s\n' % (self.__program, arg))
|
||||||
|
self.rc = False
|
||||||
|
|
||||||
while len(deque) != 0:
|
while len(deque) != 0:
|
||||||
arg = deque[0]
|
arg = deque[0]
|
||||||
|
@ -1179,6 +1235,8 @@ class ArgParser():
|
||||||
|
|
||||||
self.message = ' '.join(self.files) if len(self.files) > 0 else None
|
self.message = ' '.join(self.files) if len(self.files) > 0 else None
|
||||||
|
|
||||||
|
return self.rc
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Prints a colourful help message
|
Prints a colourful help message
|
||||||
|
@ -1326,7 +1384,7 @@ class Balloon():
|
||||||
for j in range(0, len(self.n)):
|
for j in range(0, len(self.n)):
|
||||||
outer = UCS.dispLen(self.nw[j]) + UCS.dispLen(self.ne[j])
|
outer = UCS.dispLen(self.nw[j]) + UCS.dispLen(self.ne[j])
|
||||||
inner = UCS.dispLen(self.nnw[j]) + UCS.dispLen(self.nne[j])
|
inner = UCS.dispLen(self.nnw[j]) + UCS.dispLen(self.nne[j])
|
||||||
if outer + inner >= w:
|
if outer + inner <= w:
|
||||||
rc.append(self.nw[j] + self.nnw[j] + self.n[j] * (w - outer - inner) + self.nne[j] + self.ne[j])
|
rc.append(self.nw[j] + self.nnw[j] + self.n[j] * (w - outer - inner) + self.nne[j] + self.ne[j])
|
||||||
else:
|
else:
|
||||||
rc.append(self.nw[j] + self.n[j] * (w - outer) + self.ne[j])
|
rc.append(self.nw[j] + self.n[j] * (w - outer) + self.ne[j])
|
||||||
|
@ -1337,7 +1395,7 @@ class Balloon():
|
||||||
for j in range(0, len(self.s)):
|
for j in range(0, len(self.s)):
|
||||||
outer = UCS.dispLen(self.sw[j]) + UCS.dispLen(self.se[j])
|
outer = UCS.dispLen(self.sw[j]) + UCS.dispLen(self.se[j])
|
||||||
inner = UCS.dispLen(self.ssw[j]) + UCS.dispLen(self.sse[j])
|
inner = UCS.dispLen(self.ssw[j]) + UCS.dispLen(self.sse[j])
|
||||||
if outer + inner >= w:
|
if outer + inner <= w:
|
||||||
rc.append(self.sw[j] + self.ssw[j] + self.s[j] * (w - outer - inner) + self.sse[j] + self.se[j])
|
rc.append(self.sw[j] + self.ssw[j] + self.s[j] * (w - outer - inner) + self.sse[j] + self.se[j])
|
||||||
else:
|
else:
|
||||||
rc.append(self.sw[j] + self.s[j] * (w - outer) + self.se[j])
|
rc.append(self.sw[j] + self.s[j] * (w - outer) + self.se[j])
|
||||||
|
@ -1365,7 +1423,7 @@ class Backend():
|
||||||
def __init__(self, message, ponyfile, wrapcolumn, width, balloon, hyphen, linkcolour, ballooncolour):
|
def __init__(self, message, ponyfile, wrapcolumn, width, balloon, hyphen, linkcolour, ballooncolour):
|
||||||
self.message = message
|
self.message = message
|
||||||
self.ponyfile = ponyfile
|
self.ponyfile = ponyfile
|
||||||
self.wrapcolumn = wrapcolumn
|
self.wrapcolumn = None if wrapcolumn is None else wrapcolumn - balloon.minwidth
|
||||||
self.width = width
|
self.width = width
|
||||||
self.balloon = balloon
|
self.balloon = balloon
|
||||||
self.hyphen = hyphen
|
self.hyphen = hyphen
|
||||||
|
@ -1386,12 +1444,41 @@ class Backend():
|
||||||
'''
|
'''
|
||||||
def parse(self):
|
def parse(self):
|
||||||
self.__expandMessage()
|
self.__expandMessage()
|
||||||
|
self.__unpadMessage()
|
||||||
self.__loadFile()
|
self.__loadFile()
|
||||||
|
|
||||||
|
if self.pony.startswith('$$$\n'):
|
||||||
|
self.pony = self.pony[4:]
|
||||||
|
infoend = self.pony.index('\n$$$\n')
|
||||||
|
printinfo(self.pony[:infoend])
|
||||||
|
self.pony = self.pony[infoend + 5:]
|
||||||
self.pony = mode + self.pony
|
self.pony = mode + self.pony
|
||||||
|
|
||||||
self.__processPony()
|
self.__processPony()
|
||||||
self.__truncate()
|
self.__truncate()
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
Remove padding spaces fortune cookies are padded with whitespace (damn featherbrains)
|
||||||
|
'''
|
||||||
|
def __unpadMessage(self):
|
||||||
|
lines = self.message.split('\n')
|
||||||
|
for spaces in (8, 4, 2, 1):
|
||||||
|
padded = True
|
||||||
|
for line in lines:
|
||||||
|
if not line.startswith(' ' * spaces):
|
||||||
|
padded = False
|
||||||
|
break
|
||||||
|
if padded:
|
||||||
|
for i in range(0, len(lines)):
|
||||||
|
line = lines[i]
|
||||||
|
while line.startswith(' ' * spaces):
|
||||||
|
line = line[spaces:]
|
||||||
|
lines[i] = line
|
||||||
|
lines = [line.rstrip(' ') for line in lines]
|
||||||
|
self.message = '\n'.join(lines)
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Converts all tabs in the message to spaces by expanding
|
Converts all tabs in the message to spaces by expanding
|
||||||
'''
|
'''
|
||||||
|
@ -1475,10 +1562,10 @@ class Backend():
|
||||||
while i < n:
|
while i < n:
|
||||||
c = self.pony[i]
|
c = self.pony[i]
|
||||||
if c == '\t':
|
if c == '\t':
|
||||||
n += 8 - (indent & 7)
|
n += 7 - (indent & 7)
|
||||||
ed = ' ' * (7 - (indent & 7))
|
ed = ' ' * (8 - (indent & 7))
|
||||||
c = ' '
|
c = ' '
|
||||||
self.pony = self.pony[:i] + ed + self.pony[i:]
|
self.pony = self.pony[:i] + ed + self.pony[i + 1:]
|
||||||
i += 1
|
i += 1
|
||||||
if c == '$':
|
if c == '$':
|
||||||
if dollar is not None:
|
if dollar is not None:
|
||||||
|
@ -1669,18 +1756,20 @@ class Backend():
|
||||||
@return :str The message wrapped
|
@return :str The message wrapped
|
||||||
'''
|
'''
|
||||||
def __wrapMessage(self, message, wrap):
|
def __wrapMessage(self, message, wrap):
|
||||||
AUTO_PUSH = '\033[0101y0~'
|
buf = ''
|
||||||
|
try:
|
||||||
|
AUTO_PUSH = '\033[01010~'
|
||||||
AUTO_POP = '\033[10101~'
|
AUTO_POP = '\033[10101~'
|
||||||
msg = message.replace('\n', AUTO_PUSH + '\n' + AUTO_POP);
|
msg = message.replace('\n', AUTO_PUSH + '\n' + AUTO_POP);
|
||||||
cstack = ColourStack(AUTO_PUSH, AUTO_POP)
|
cstack = ColourStack(AUTO_PUSH, AUTO_POP)
|
||||||
buf = ''
|
|
||||||
for c in msg:
|
for c in msg:
|
||||||
buf += c + cstack.feed(c)
|
buf += c + cstack.feed(c)
|
||||||
lines = buf.replace(AUTO_PUSH, '').replace(AUTO_POP, '').split('\n')
|
lines = buf.replace(AUTO_PUSH, '').replace(AUTO_POP, '').split('\n')
|
||||||
buf = ''
|
buf = ''
|
||||||
|
|
||||||
for line in lines:
|
for line in lines:
|
||||||
b = [None] * len(line)
|
b = [None] * len(line)
|
||||||
map = {}
|
map = {0 : 0}
|
||||||
(bi, cols, w) = (0, 0, wrap)
|
(bi, cols, w) = (0, 0, wrap)
|
||||||
(indent, indentc) = (-1, 0)
|
(indent, indentc) = (-1, 0)
|
||||||
|
|
||||||
|
@ -1737,6 +1826,9 @@ class Backend():
|
||||||
while ((w > 8) and (cols > w + 5)) or (cols > iwrap): # TODO make configurable
|
while ((w > 8) and (cols > w + 5)) or (cols > iwrap): # TODO make configurable
|
||||||
## wrap
|
## wrap
|
||||||
x = w;
|
x = w;
|
||||||
|
if mm + x not in map: # Too much whitespace ?
|
||||||
|
cols = 0
|
||||||
|
break
|
||||||
nbsp = b[map[mm + x]] == ' '
|
nbsp = b[map[mm + x]] == ' '
|
||||||
m = map[mm + x]
|
m = map[mm + x]
|
||||||
|
|
||||||
|
@ -1794,6 +1886,19 @@ class Backend():
|
||||||
rc = rc.replace('', ''); # remove soft hyphens
|
rc = rc.replace('', ''); # remove soft hyphens
|
||||||
rc = rc.replace('\0', '%s%s%s' % (AUTO_PUSH, self.hyphen, AUTO_POP))
|
rc = rc.replace('\0', '%s%s%s' % (AUTO_PUSH, self.hyphen, AUTO_POP))
|
||||||
return rc
|
return rc
|
||||||
|
except Exception as err:
|
||||||
|
import traceback
|
||||||
|
errormessage = ''.join(traceback.format_exception(type(err), err, None))
|
||||||
|
rc = '\n'.join(line.rstrip() for line in buf.split('\n'));
|
||||||
|
rc = rc.replace('\0', '%s%s%s' % (AUTO_PUSH, self.hyphen, AUTO_POP))
|
||||||
|
errormessage += '\n---- WRAPPING BUFFER ----\n\n' + rc
|
||||||
|
try:
|
||||||
|
if os.readlink('/proc/self/fd/2') != os.readlink('/proc/self/fd/1'):
|
||||||
|
printerr(errormessage, end='')
|
||||||
|
return message
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return message + '\n\n\033[0;1;31m---- EXCEPTION IN PONYSAY WHILE WRAPPING ----\033[0m\n\n' + errormessage
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
@ -1825,7 +1930,7 @@ class ColourStack():
|
||||||
@return :str String that should be inserted into your buffer
|
@return :str String that should be inserted into your buffer
|
||||||
'''
|
'''
|
||||||
def push(self):
|
def push(self):
|
||||||
self.stack = [[self.bufproto, None, None, [False] * 9]] + self.stack
|
self.stack.insert(0, [self.bufproto, None, None, [False] * 9])
|
||||||
if len(self.stack) == 1:
|
if len(self.stack) == 1:
|
||||||
return None
|
return None
|
||||||
return '\033[0m'
|
return '\033[0m'
|
||||||
|
@ -1837,9 +1942,10 @@ class ColourStack():
|
||||||
@return :str String that should be inserted into your buffer
|
@return :str String that should be inserted into your buffer
|
||||||
'''
|
'''
|
||||||
def pop(self):
|
def pop(self):
|
||||||
old = self.stack[0]
|
old = self.stack.pop(0)
|
||||||
self.stack = self.stack[1:]
|
|
||||||
rc = '\033[0;'
|
rc = '\033[0;'
|
||||||
|
if len(self.stack) == 0: # last resort in case something made it pop too mush
|
||||||
|
push()
|
||||||
new = self.stack[0]
|
new = self.stack[0]
|
||||||
if new[1] is not None: rc += new[1] + ';'
|
if new[1] is not None: rc += new[1] + ';'
|
||||||
if new[2] is not None: rc += new[2] + ';'
|
if new[2] is not None: rc += new[2] + ';'
|
||||||
|
@ -1984,7 +2090,7 @@ class SpelloCorrecter(): # Naïvely and quickly proted and adapted from optimise
|
||||||
m0[x] = x
|
m0[x] = x
|
||||||
x -= 1
|
x -= 1
|
||||||
|
|
||||||
previous = ""
|
previous = ''
|
||||||
self.dictionary[-1] = previous;
|
self.dictionary[-1] = previous;
|
||||||
|
|
||||||
for directory in directories:
|
for directory in directories:
|
||||||
|
@ -2270,8 +2376,8 @@ usage_saythink = '\033[34;1m(ponysay | ponythink)\033[21;39m'
|
||||||
usage_common = '[-c] [-W\033[4mCOLUMN\033[24m] [-b\033[4mSTYLE\033[24m]'
|
usage_common = '[-c] [-W\033[4mCOLUMN\033[24m] [-b\033[4mSTYLE\033[24m]'
|
||||||
usage_listhelp = '(-l | -L | -B | +l | +L | -v | -h)'
|
usage_listhelp = '(-l | -L | -B | +l | +L | -v | -h)'
|
||||||
usage_file = '[-f\033[4mPONY\033[24m]* [[--] \033[4mmessage\033[24m]'
|
usage_file = '[-f\033[4mPONY\033[24m]* [[--] \033[4mmessage\033[24m]'
|
||||||
usage_xfile = '[-F\033[4mPONY\033[24m]* [[--] \033[4mmessage\033[24m]'
|
usage_xfile = '(-F\033[4mPONY\033[24m)* [[--] \033[4mmessage\033[24m]'
|
||||||
usage_quote = '-q [\033[4mPONY\033[24m*]'
|
usage_quote = '(-q \033[4mPONY\033[24m)*'
|
||||||
|
|
||||||
usage = '%s %s\n%s %s %s\n%s %s %s\n%s %s %s' % (usage_saythink, usage_listhelp,
|
usage = '%s %s\n%s %s %s\n%s %s %s\n%s %s %s' % (usage_saythink, usage_listhelp,
|
||||||
usage_saythink, usage_common, usage_file,
|
usage_saythink, usage_common, usage_file,
|
||||||
|
@ -2325,9 +2431,15 @@ opts.add_argumented( ['-W', '--wrap'], arg = 'COLUMN', help =
|
||||||
opts.add_argumented( ['-b', '--bubble', '--balloon'], arg = 'STYLE', help = 'Select a balloon style.')
|
opts.add_argumented( ['-b', '--bubble', '--balloon'], arg = 'STYLE', help = 'Select a balloon style.')
|
||||||
opts.add_argumented( ['-f', '--file', '--pony'], arg = 'PONY', help = 'Select a pony.\nEither a file name or a pony name.')
|
opts.add_argumented( ['-f', '--file', '--pony'], arg = 'PONY', help = 'Select a pony.\nEither a file name or a pony name.')
|
||||||
opts.add_argumented( ['-F', '++file', '++pony'], arg = 'PONY', help = 'Select a non-MLP:FiM pony.')
|
opts.add_argumented( ['-F', '++file', '++pony'], arg = 'PONY', help = 'Select a non-MLP:FiM pony.')
|
||||||
opts.add_variadic( ['-q', '--quote'], arg = 'PONY', help = 'Select a ponies which will quote themself.')
|
opts.add_argumented( ['-q', '--quote'], arg = 'PONY', help = 'Select a pony which will quote herself.')
|
||||||
|
opts.add_variadic( ['--f', '--files', '--ponies'], arg = 'PONY')
|
||||||
|
opts.add_variadic( ['--F', '++files', '++ponies'], arg = 'PONY')
|
||||||
|
opts.add_variadic( ['--q', '--quotes'], arg = 'PONY')
|
||||||
|
|
||||||
opts.parse()
|
'''
|
||||||
|
Whether at least one unrecognised option was used
|
||||||
|
'''
|
||||||
|
unrecognised = not opts.parse()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue