From 024ca3965e8aa776d2457974b616e58a0e213c5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Thu, 11 Oct 2012 22:29:26 +0200 Subject: [PATCH 01/19] add --symall and --altall as alternatives to +A + m manual fix + -X, -V, -K options --- manuals/manpage.0 | 8 ++++---- manuals/manpage.es.0 | 8 ++++---- manuals/ponysay.texinfo | 16 +++++++++------- ponysay.py | 20 +++++++++++++++++++- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/manuals/manpage.0 b/manuals/manpage.0 index 229ad108..cb653f84 100644 --- a/manuals/manpage.0 +++ b/manuals/manpage.0 @@ -82,12 +82,12 @@ the pony will be selected randomly from that set of ponies. .B \-W, \-\-wrap \fIcolumn\fP The screen column where the message should be wrapped. .TP -.B \-A, \-\-all \fIcolumn\fP -Show all ponies, MLP-FiM and non-MLP-FiM, in this case the first list are MLP:FiM +.B \-A, \-\-all +List all pony files, MLP-FiM and non-MLP-FiM, in this case the first list are MLP:FiM and the second are non-MLP-FiM. .TP -.B \+A, \+\+all \fIcolumn\fP -Show both ponies names, including alternatives, these from MLP:FiM and non-MLP:FiM +.B \+A, \+\+all, \-\-symall, \-\-altall +List all pony files, including alternatives names inside brackets, these from MLP:FiM and non-MLP:FiM the first list are the MLP:FiM and the second one are non-MLP:FiM. .SH ENVIRONMENT .TP diff --git a/manuals/manpage.es.0 b/manuals/manpage.es.0 index f4156eea..5f42fdf4 100644 --- a/manuals/manpage.es.0 +++ b/manuals/manpage.es.0 @@ -84,12 +84,12 @@ aleatoriamente uno de este conjunto. .B \-W, \-\-wrap \fIcolumna\fP El numero de columnas en el que será impreso el mensaje. .TP -.B \-A. \-\-all \fIcolumn\fP -Muestra todos los ponis, tanto pertenecientes a MLP:FiM cono no pertenecientes a esta +.B \-A. \-\-all +Lista todos los ponis, tanto pertenecientes a MLP:FiM cono no pertenecientes a esta la primera lista son los pertenecientes a esta y la subsiguente los no pertenecientes. .TP -.B \+A, \+\+all \fIcolumn\fP -Muestra todos los ponies incluyendo sus nombres alternativos, estos pertenecientes a +.B \+A, \+\+all, \-\-symall, \-\-altall +Lista todos los ponis incluyendo sus nombres alternativos, estos pertenecientes a MLP:FiM cono no pertenecientes, la primera lista seran los pertenecientes y la subsiguente los no pertenecientes. .SH ENTORNO diff --git a/manuals/ponysay.texinfo b/manuals/ponysay.texinfo index 16ce53c5..931f8536 100644 --- a/manuals/ponysay.texinfo +++ b/manuals/ponysay.texinfo @@ -266,19 +266,21 @@ Just as @option{-L}, except it lists extra (non-MLP:FiM) ponies instead of stand Prints a list of all balloon styles. @item -A -@itemx --balloonlist +@itemx --all @opindex @option{-A} @opindex @option{--all} -@opindex @option{--all} -Show all ponies, MLP-FiM and non-MLP-FiM, in this case the first list are MLP:FiM -and the second are non-MLP-FiM. +List all ponies, MLP:FiM and non-MLP:FiM, in this case the first list are MLP:FiM +and the second are non-MLP:FiM. @item +A -@itemx --balloonlist +@itemx ++all +@itemx --symall +@itemx --altall @opindex @option{+A} @opindex @option{++all} -@opindex @option{++all} -Show both ponies names, including alternatives, these from MLP:FiM and non-MLP:FiM +@opindex @option{--symall} +@opindex @option{--altall} +List all ponies names, including alternatives, these from MLP:FiM and non-MLP:FiM the first list are the MLP:FiM and the second one are non-MLP:FiM. @end table diff --git a/ponysay.py b/ponysay.py index 85e4cbd5..cb701bf4 100755 --- a/ponysay.py +++ b/ponysay.py @@ -78,9 +78,23 @@ class Ponysay(): elif args.opts['-A'] is not None: self.list(); self.__extraponies(); self.list() elif args.opts['+A'] is not None: self.linklist(); self.__extraponies(); self.linklist() else: + ## Emulate termial capabilities + if args.opts['-X'] is not None: + linuxvt = False + usekms = False + elif args.opts['-V'] is not None: + linuxvt = True + usekms = False + elif args.opts['-K'] is not None: + linuxvt = True + usekms = True + + ## Other extra features self.__extraponies(args) self.__bestpony(args) self.__ucsremap(args) + + ## The stuff if args.opts['-q'] is not None: self.quote(args) else: self.print_pony(args) @@ -2022,6 +2036,10 @@ opts.add_argumentless(['--quoters']) opts.add_argumentless(['--onelist']) opts.add_argumentless(['++onelist']) +opts.add_argumentless(['-X', '--256-colours', '--256colours', '--x-colours']) +opts.add_argumentless(['-V', '--tty-colours', '--ttycolours', '--vt-colours']) +opts.add_argumentless(['-K', '--kms-colours', '--kmscolours']) + opts.add_argumentless(['-h', '--help'], help = 'Print this help message.') opts.add_argumentless(['-v', '--version'], help = 'Print the version of the program.') opts.add_argumentless(['-l', '--list'], help = 'List pony names.') @@ -2029,7 +2047,7 @@ opts.add_argumentless(['-L', '--symlist', '--altlist'], help = opts.add_argumentless(['+l', '++list'], help = 'List non-MLP:FiM pony names.') opts.add_argumentless(['+L', '++symlist', '++altlist'], help = 'List non-MLP:FiM pony names with alternatives.') opts.add_argumentless(['-A', '--all'], help = 'List all pony names.') -opts.add_argumentless(['+A', '++all'], help = 'List all pony names with alternatives.') +opts.add_argumentless(['+A', '++all', '--symall', '--altall'], help = 'List all pony names with alternatives.') opts.add_argumentless(['-B', '--bubblelist', '--balloonlist'], help = 'List balloon styles.') opts.add_argumentless(['-c', '--compact'], help = 'Compress messages.') opts.add_argumented( ['-W', '--wrap'], arg = 'COLUMN', help = 'Specify column where the message should be wrapped.') From 8285ce9a0f8eb43777cf1d37d58c94b9b9a56f48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Thu, 11 Oct 2012 22:39:50 +0200 Subject: [PATCH 02/19] document -X, -V and -K in info manual (I am not sure if the manpage should document this, it is not too useful) --- manuals/ponysay.texinfo | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/manuals/ponysay.texinfo b/manuals/ponysay.texinfo index 931f8536..2954af58 100644 --- a/manuals/ponysay.texinfo +++ b/manuals/ponysay.texinfo @@ -282,6 +282,38 @@ and the second are non-MLP:FiM. @opindex @option{--altall} List all ponies names, including alternatives, these from MLP:FiM and non-MLP:FiM the first list are the MLP:FiM and the second one are non-MLP:FiM. + +@item -X +@itemx --256-colours +@itemx --256colours +@itemx --x-colours +@opindex @option{-X} +@opindex @option{--256-colours} +@opindex @option{--256colours} +@opindex @option{--x-colours} +Use @command{xterm}'s 256-colour support (supported by most X11 terminals), despite +your terminal's actual compatibilies. + +@item -V +@itemx --tty-colours +@itemx --ttycolours +@itemx --vt-colours +@opindex @option{-V} +@opindex @option{--tty-colours} +@opindex @option{--ttycolours} +@opindex @option{--vt-colours} +Use Linux VT's compatbilies without KMS utilisation, despite your terminal's actual +compatibilies. + +@item -K +@itemx --kms-colours +@itemx --kmscolours +@opindex @option{-K} +@opindex @option{--kms-colours} +@opindex @option{--kmscolours} +Use Linux VT's compatbilies with KMS utilisation, despite your terminal's actual +compatibilies. + @end table @opindex @var{message} From bb5e26b8d84d83b64cd4f63bb7009ecb6d55c582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Thu, 11 Oct 2012 22:43:55 +0200 Subject: [PATCH 03/19] changelog update --- CHANGELOG | 2 ++ manuals/ponysay.texinfo | 2 ++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 1dce8697..4552ce44 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -10,6 +10,8 @@ Version 2.8 The word wrapper colours the inserted hyphens in red. + Support for terminal capabilities emulation with the flags -X, -V and -K. + Version 2.7 diff --git a/manuals/ponysay.texinfo b/manuals/ponysay.texinfo index 2954af58..e3f2a5c2 100644 --- a/manuals/ponysay.texinfo +++ b/manuals/ponysay.texinfo @@ -1913,6 +1913,8 @@ Support for explicit hypthenation using soft hyphens had been added to the word Support for explicit non-word wrapping using non-breaking space had been added to the word wrapper. @item The word wrapper colours the inserted hyphens in red. +@item +Support for terminal capabilities emulation with the flags @option{-X}, @option{-V} and @option{-K}. @end itemize From 30dfacb70b99f758bc4bc3a61b1501fa0ef29aac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Thu, 11 Oct 2012 22:47:39 +0200 Subject: [PATCH 04/19] shell completion update --- completion/bash-completion.sh | 3 ++- completion/fish-completion.fish | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/completion/bash-completion.sh b/completion/bash-completion.sh index 4f59a4aa..e9c284c1 100644 --- a/completion/bash-completion.sh +++ b/completion/bash-completion.sh @@ -5,7 +5,8 @@ _ponysay() local cur prev words cword _init_completion -n = || return - options='--version --help --list --altlist --pony --wrap --quote --balloonlist --balloon --file ++file ++pony ++list ++altlist' + options="--version --help --list --altlist --pony --wrap --quote --balloonlist --balloon --file ++file ++pony ++list ++altlist --all ++all" + options="$options --256-colours --tty-colours --kms-colours" COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) if [ $prev = "-f" ] || [ $prev = "--pony" ] || [ $prev = "--file" ]; then diff --git a/completion/fish-completion.fish b/completion/fish-completion.fish index 68e013ae..044dd784 100644 --- a/completion/fish-completion.fish +++ b/completion/fish-completion.fish @@ -9,7 +9,7 @@ set -g quoters ('/usr/bin/ponysay' --quoters) set -g balloons ('/usr/bin/ponysay' --balloonlist) -## TODO: update with options [see info manual]: +l +L ++list ++altlist ++file --file ++pony +## TODO: update with options [see info manual]: +l +L ++list ++altlist ++file --file ++pony {-A, +A, -V, -K, -X}(with alternative) complete --command ponysay --short-option h --long-option help --description 'help of ponysay' complete --command ponysay --short-option v --long-option version --description 'version of ponysay' complete --command ponysay --short-option l --long-option list --description 'list pony names' From 6892c51ba65bccfb06fef3cf0413bd87185b0aa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Thu, 11 Oct 2012 23:09:14 +0200 Subject: [PATCH 05/19] fix for -V, -K and -X, and beginning of --pony-only --- ponysay.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ponysay.py b/ponysay.py index cb701bf4..270bc7fa 100755 --- a/ponysay.py +++ b/ponysay.py @@ -78,6 +78,10 @@ class Ponysay(): elif args.opts['-A'] is not None: self.list(); self.__extraponies(); self.list() elif args.opts['+A'] is not None: self.linklist(); self.__extraponies(); self.linklist() else: + global linuxvt + global usekms + global mode + ## Emulate termial capabilities if args.opts['-X'] is not None: linuxvt = False @@ -93,6 +97,8 @@ class Ponysay(): self.__extraponies(args) self.__bestpony(args) self.__ucsremap(args) + if args.opts['-o'] is not None: + mode += '$/= $$\\= $' ## The stuff if args.opts['-q'] is not None: self.quote(args) @@ -1223,6 +1229,7 @@ class Backend(): def parse(self): self.__expandMessage() self.__loadFile() + self.pony = mode + self.pony self.__processPony() self.__truncate() @@ -1940,6 +1947,12 @@ Whether KMS is used usekms = Ponysay.isUsingKMS() +''' +Mode string that modifies or adds $ variables in the pony image +''' +mode = '' + + ''' The directories where pony files are stored, ttyponies/ are used if the terminal is Linux VT (also known as TTY) and not with KMS ''' @@ -2050,6 +2063,7 @@ opts.add_argumentless(['-A', '--all'], help = opts.add_argumentless(['+A', '++all', '--symall', '--altall'], help = 'List all pony names with alternatives.') opts.add_argumentless(['-B', '--bubblelist', '--balloonlist'], help = 'List balloon styles.') opts.add_argumentless(['-c', '--compact'], help = 'Compress messages.') +opts.add_argumentless(['-o', '--pony-only', '--ponyonly'], help = 'Print only the pony.') opts.add_argumented( ['-W', '--wrap'], arg = 'COLUMN', help = 'Specify column where the message should be wrapped.') 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.') From f214a9f59bc397cfd1db6626b9491c3ec9dc5762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Thu, 11 Oct 2012 23:24:40 +0200 Subject: [PATCH 06/19] terminal capatily emulation fix --- ponysay.py | 66 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/ponysay.py b/ponysay.py index 90520ec0..3534e5ed 100755 --- a/ponysay.py +++ b/ponysay.py @@ -65,6 +65,27 @@ class Ponysay(): args.help() return + ## Modifyable global variables + global linuxvt + global usekms + global mode + global ponydirs + global extraponydirs + + ## Emulate termial capabilities + if args.opts['-X'] is not None: + linuxvt = False + usekms = False + 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 + extraponydirs = extravtponydirs if linuxvt and not usekms else extraxponydirs + + ## Run modes if args.opts['-h'] is not None: args.help() elif args.opts['--quoters'] is not None: self.quoters() elif args.opts['--onelist'] is not None: self.onelist() @@ -78,21 +99,6 @@ class Ponysay(): elif args.opts['-A'] is not None: self.list(); self.__extraponies(); self.list() elif args.opts['+A'] is not None: self.linklist(); self.__extraponies(); self.linklist() else: - global linuxvt - global usekms - global mode - - ## Emulate termial capabilities - if args.opts['-X'] is not None: - linuxvt = False - usekms = False - elif args.opts['-V'] is not None: - linuxvt = True - usekms = False - elif args.opts['-K'] is not None: - linuxvt = True - usekms = True - ## Other extra features self.__extraponies(args) self.__bestpony(args) @@ -1957,25 +1963,37 @@ mode = '' The directories where pony files are stored, ttyponies/ are used if the terminal is Linux VT (also known as TTY) and not with KMS ''' appendset = set() -ponydirs = [] -if linuxvt and not usekms: _ponydirs = [HOME + '/.local/share/ponysay/ttyponies/', '/usr/share/ponysay/ttyponies/'] -else: _ponydirs = [HOME + '/.local/share/ponysay/ponies/', '/usr/share/ponysay/ponies/'] +xponydirs = [] +_ponydirs = [HOME + '/.local/share/ponysay/ponies/', '/usr/share/ponysay/ponies/'] for ponydir in _ponydirs: if os.path.isdir(ponydir) and (ponydir not in appendset): - ponydirs.append(ponydir) + xponydirs.append(ponydir) + appendset.add(ponydir) +appendset = set() +vtponydirs = [] +_ponydirs = [HOME + '/.local/share/ponysay/ttyponies/', '/usr/share/ponysay/ttyponies/'] +for ponydir in _ponydirs: + if os.path.isdir(ponydir) and (ponydir not in appendset): + vtponydirs.append(ponydir) appendset.add(ponydir) ''' The directories where pony files are stored, extrattyponies/ are used if the terminal is Linux VT (also known as TTY) and not with KMS ''' -appendsetset = set() -extraponydirs = [] -if linuxvt and not usekms: _extraponydirs = [HOME + '/.local/share/ponysay/extrattyponies/', '/usr/share/ponysay/extrattyponies/'] -else: _extraponydirs = [HOME + '/.local/share/ponysay/extraponies/', '/usr/share/ponysay/extraponies/'] +appendset = set() +extraxponydirs = [] +_extraponydirs = [HOME + '/.local/share/ponysay/extraponies/', '/usr/share/ponysay/extraponies/'] for extraponydir in _extraponydirs: if os.path.isdir(extraponydir) and (extraponydir not in appendset): - extraponydirs.append(extraponydir) + extraxponydirs.append(extraponydir) + appendset.add(extraponydir) +appendset = set() +extravtponydirs = [] +_extraponydirs = [HOME + '/.local/share/ponysay/extrattyponies/', '/usr/share/ponysay/extrattyponies/'] +for extraponydir in _extraponydirs: + if os.path.isdir(extraponydir) and (extraponydir not in appendset): + extravtponydirs.append(extraponydir) appendset.add(extraponydir) From bf619ffa24a5b3323f53f8eaeb56ce3b4475d7d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Thu, 11 Oct 2012 23:35:51 +0200 Subject: [PATCH 07/19] printing just the pony --- ponysay.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ponysay.py b/ponysay.py index 3534e5ed..1649402f 100755 --- a/ponysay.py +++ b/ponysay.py @@ -703,7 +703,7 @@ class Ponysay(): messagewrap = int(args.opts['-W'][0]) if args.opts['-W'] is not None else None ## Get balloon object - balloon = self.__getballoon(self.__getballoonpath(args.opts['-b'])) + balloon = self.__getballoon(self.__getballoonpath(args.opts['-b'])) if args.opts['-o'] is None else None ## Run cowsay replacement backend = Backend(message = msg, ponyfile = pony, wrapcolumn = messagewrap if messagewrap is not None else 40, width = widthtruncation, balloon = balloon) @@ -1214,7 +1214,8 @@ Replacement for cowsay class Backend(): ''' Constructor - Takes message [string], ponyfile [filename string], wrapcolumn [None or an int], width [None or an int] and balloon [Balloon object] + Takes message [string], ponyfile [filename string], wrapcolumn [None or an int], + width [None or an int] and balloon [None or Balloon object] ''' def __init__(self, message, ponyfile, wrapcolumn, width, balloon): self.message = message @@ -1223,7 +1224,10 @@ class Backend(): self.width = width self.balloon = balloon - self.link = {'\\' : self.balloon.link, '/' : self.balloon.linkmirror} + if self.balloon is not None: + self.link = {'\\' : self.balloon.link, '/' : self.balloon.linkmirror} + else: + self.link = {} self.output = '' self.pony = None @@ -1347,7 +1351,7 @@ class Backend(): else: n += len(data) self.pony = self.pony[:i] + data + self.pony[i:] - else: + elif self.balloon is not None: (w, h) = (0, 0) props = dollar[7:] if len(props) > 0: From 6b49c9412820479cc114204b580fe33801b1bd28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Thu, 11 Oct 2012 23:40:11 +0200 Subject: [PATCH 08/19] document the -o flag and update the change log --- CHANGELOG | 2 ++ manuals/manpage.0 | 3 +++ manuals/ponysay.texinfo | 10 ++++++++++ 3 files changed, 15 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index d73a4bc4..892416b3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -13,6 +13,8 @@ Version 2.8 Support for terminal capabilities emulation with the flags -X, -V and -K. + Support for printing just the pony, using the flag -o. + Version 2.7 diff --git a/manuals/manpage.0 b/manuals/manpage.0 index cb653f84..5162a504 100644 --- a/manuals/manpage.0 +++ b/manuals/manpage.0 @@ -89,6 +89,9 @@ and the second are non-MLP-FiM. .B \+A, \+\+all, \-\-symall, \-\-altall List all pony files, including alternatives names inside brackets, these from MLP:FiM and non-MLP:FiM the first list are the MLP:FiM and the second one are non-MLP:FiM. +.TP +.B \-o, \-\-pony\-only, \-\-ponyonly +Just print the pony, nothing else like the speech balloon. .SH ENVIRONMENT .TP .B PONYSAY_BOTTOM diff --git a/manuals/ponysay.texinfo b/manuals/ponysay.texinfo index d2f2f6fb..5df4fd29 100644 --- a/manuals/ponysay.texinfo +++ b/manuals/ponysay.texinfo @@ -283,6 +283,14 @@ and the second are non-MLP:FiM. List all ponies names, including alternatives, these from MLP:FiM and non-MLP:FiM the first list are the MLP:FiM and the second one are non-MLP:FiM. +@item -o +@itemx --pony-only +@itemx --ponyonly +@opindex @option{-o} +@opindex @option{--pony-only} +@opindex @option{--ponyonly} +Print just the pony, nothing else like the speech balloon. + @item -X @itemx --256-colours @itemx --256colours @@ -1916,6 +1924,8 @@ Support for explicit non-word wrapping using non-breaking space had been added t The word wrapper colours the inserted hyphens in red. @item Support for terminal capabilities emulation with the flags @option{-X}, @option{-V} and @option{-K}. +@item +Support for printing just the pony, using the flag @option{-o}. @end itemize From dc38ab4e6d6302cf278df6e6adfcefe0afd841fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Fri, 12 Oct 2012 01:56:08 +0200 Subject: [PATCH 09/19] colour options are almost fully functional, inplace balloons are problematic --- .gitignore | 1 + CHANGELOG | 2 ++ manuals/manpage.0 | 6 ++++ manuals/ponysay.texinfo | 41 ++++++++++++++++++++++ ponysay.py | 76 +++++++++++++++++++++++++++++------------ 5 files changed, 104 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 0f3a1fc8..cbbd8750 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ ## Private workspace directory /_/ +/*.pony ## Backup files diff --git a/CHANGELOG b/CHANGELOG index 892416b3..ab03820d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -15,6 +15,8 @@ Version 2.8 Support for printing just the pony, using the flag -o. + Colouring option flags are added. + Version 2.7 diff --git a/manuals/manpage.0 b/manuals/manpage.0 index 5162a504..9627f62e 100644 --- a/manuals/manpage.0 +++ b/manuals/manpage.0 @@ -92,6 +92,12 @@ the first list are the MLP:FiM and the second one are non-MLP:FiM. .TP .B \-o, \-\-pony\-only, \-\-ponyonly Just print the pony, nothing else like the speech balloon. +.TP +.B \+c, \-\-colour [\fIansi-colour\fP] +Colour the balloon, including link and message. For more colouring features, se the \fIinfo\fP +manual. The argument, \fIansi-colour\fP, should be a ANSI colour sequence without leading CSI +and without a tailing \fIm\fP, for example \fI1;31\fP will make it in red and bold (or bright +depending on the terminal.) .SH ENVIRONMENT .TP .B PONYSAY_BOTTOM diff --git a/manuals/ponysay.texinfo b/manuals/ponysay.texinfo index 5df4fd29..a43a781c 100644 --- a/manuals/ponysay.texinfo +++ b/manuals/ponysay.texinfo @@ -322,6 +322,45 @@ compatibilies. Use Linux VT's compatbilies with KMS utilisation, despite your terminal's actual compatibilies. +@item +c +@itemx --colour ANSI-COLOUR +@opindex @option{+c} +@opindex @option{--colour} +Colour the balloon, including link and message (the parts that are not individually +specified.) The argument, should be a ANSI colour sequence without leading CSI and +without a tailing ‘m’, for example @code{1;31} will make it in red and bold (or bright +depending on the terminal.) + +@item --colour-bubble +@itemx --colour-balloon ANSI-COLOUR +@opindex @option{--colour-bubble} +@opindex @option{--colour-balloon} +Just like @option{--colour}, but it only colours the balloon, without the message +or link. + +@item --colour-link ANSI-COLOUR +@opindex @option{--colour-link} +Just like @option{--colour}, but it only colours the balloon link. + +@item --colour-msg +@itemx --colour-message ANSI-COLOUR +@opindex @option{--colour-msg} +@opindex @option{--colour-message} +Just like @option{--colour}, but it only colours the message. + +@item --colour-pony ANSI-COLOUR +@opindex @option{--colour-pony} +Just like @option{--colour}, but it colours the pony. This colouring has no +effect ony regular pony files, as it has its own colouring. + +@item --colour-wrap +@itemx --colour-hyphen ANSI-COLOUR +@opindex @option{--colour-wrap} +@opindex @option{--colour-hyphen} +Just like @option{--colour}, but it colours hyphen added by the word wrapping. +By default this is red (@code{31}), if you want uncoloured use @code{0}, +without @code{0} or @code{39}, the default @code{31} is presistent. + @end table @opindex @var{message} @@ -1926,6 +1965,8 @@ The word wrapper colours the inserted hyphens in red. Support for terminal capabilities emulation with the flags @option{-X}, @option{-V} and @option{-K}. @item Support for printing just the pony, using the flag @option{-o}. +@item +Colouring option flags are added. @end itemize diff --git a/ponysay.py b/ponysay.py index 1649402f..2bad694d 100755 --- a/ponysay.py +++ b/ponysay.py @@ -20,7 +20,6 @@ Authors of ponysay.py: Sven-Hendrik "svenstaro" Haase: Major contributor of the first implementation Jan Alexander "heftig" Steffens: Major contributor of the first implementation Kyah "L-four" Rindlisbacher: Patched the first implementation - ''' import os @@ -99,6 +98,16 @@ class Ponysay(): elif args.opts['-A'] is not None: self.list(); self.__extraponies(); self.list() elif args.opts['+A'] is not None: self.linklist(); self.__extraponies(); self.linklist() else: + ## Colouring features + if args.opts['--colour-pony'] is not None: + mode += '\033[' + ';'.join(args.opts['--colour-pony']) + 'm' + else: + mode += '\033[0m' + if args.opts['+c'] is not None: + if args.opts['--colour-msg'] is None: args.opts['--colour-msg'] = args.opts['+c'] + if args.opts['--colour-link'] is None: args.opts['--colour-link'] = args.opts['+c'] + if args.opts['--colour-bubble'] is None: args.opts['--colour-bubble'] = args.opts['+c'] + ## Other extra features self.__extraponies(args) self.__bestpony(args) @@ -656,6 +665,8 @@ class Ponysay(): msg = ''.join(sys.stdin.readlines()).rstrip() else: msg = args.message + if args.opts['--colour-msg'] is not None: + msg = '\033[' + ';'.join(args.opts['--colour-msg']) + 'm' + msg ## This algorithm should give some result as cowsay's (according to tests) if args.opts['-c'] is not None: @@ -705,8 +716,24 @@ class Ponysay(): ## Get balloon object balloon = self.__getballoon(self.__getballoonpath(args.opts['-b'])) if args.opts['-o'] is None else None + ## Get hyphen style + hyphencolour = '' + if args.opts['--colour-wrap'] is not None: + hyphencolour = '\033[' + ';'.join(args.opts['--colour-wrap']) + 'm' + hyphen = '\033[31m' + hyphencolour + '-' + + ## Link and balloon colouring + linkcolour = '' + if args.opts['--colour-link'] is not None: + linkcolour = '\033[' + ';'.join(args.opts['--colour-link']) + 'm' + ballooncolour = '' + if args.opts['--colour-bubble'] is not None: + ballooncolour = '\033[' + ';'.join(args.opts['--colour-bubble']) + 'm' + + ## Run cowsay replacement - backend = Backend(message = msg, ponyfile = pony, wrapcolumn = messagewrap if messagewrap is not None else 40, width = widthtruncation, balloon = balloon) + backend = Backend(message = msg, ponyfile = pony, wrapcolumn = messagewrap if messagewrap is not None else 40, + width = widthtruncation, balloon = balloon, hyphen = hyphen, linkcolour = linkcolour, ballooncolour = ballooncolour) backend.parse() output = backend.output if output.endswith('\n'): @@ -1215,17 +1242,21 @@ class Backend(): ''' Constructor Takes message [string], ponyfile [filename string], wrapcolumn [None or an int], - width [None or an int] and balloon [None or Balloon object] + width [None or an int], balloon [None or Balloon object], hyphen [string], + linkcolour [string] and ballooncolour [string] ''' - def __init__(self, message, ponyfile, wrapcolumn, width, balloon): + def __init__(self, message, ponyfile, wrapcolumn, width, balloon, hyphen, linkcolour, ballooncolour): self.message = message self.ponyfile = ponyfile self.wrapcolumn = wrapcolumn self.width = width self.balloon = balloon + self.hyphen = hyphen + self.ballooncolour = ballooncolour if self.balloon is not None: - self.link = {'\\' : self.balloon.link, '/' : self.balloon.linkmirror} + self.link = {'\\' : linkcolour + self.balloon.link, + '/' : linkcolour + self.balloon.linkmirror} else: self.link = {} @@ -1363,6 +1394,7 @@ class Backend(): w = int(props) balloon = self.__getballoon(w, h, indent) balloon = balloon.split('\n') + balloon = [AUTO_PUSH + self.ballooncolour + item + AUTO_POP for item in balloon] for b in balloon[0]: self.output += b + colourstack.feed(b) if lineindex == 0: @@ -1495,22 +1527,15 @@ class Backend(): if wrap is not None: msg = self.__wrapMessage(msg, wrap) - if '\033' in msg: - AUTO_PUSH = '\033[01010~' - AUTO_POP = '\033[10101~' - cstack = ColourStack(AUTO_PUSH, AUTO_POP) - buf = '' - for c in msg: - if c == '\n': - for cc in ('%s\n%s' % (AUTO_PUSH, AUTO_POP)): - buf += cc - buf += cstack.feed(cc) - else: - buf += c - buf += cstack.feed(c) - msg = buf + AUTO_PUSH = '\033[01010~' + AUTO_POP = '\033[10101~' + cstack = ColourStack(AUTO_PUSH, AUTO_POP) + buf = '' + for c in msg.replace('\n', AUTO_PUSH + self.ballooncolour + '\n' + AUTO_POP) + self.ballooncolour: + buf += c + buf += cstack.feed(c) - return self.balloon.get(width, height, msg.split('\n'), self.__len) + return self.balloon.get(width, height, buf.split('\n'), self.__len) ''' @@ -1587,7 +1612,7 @@ class Backend(): hyphen = m - 1 while b[hyphen] != '­': hyphen -= 1 - while map[mm + x] > hyphen: ## Only looking backward, if foreward is required the word is probabily not hythenated correctly + while map[mm + x] > hyphen: ## Only looking backward, if foreward is required the word is probabily not hyphenated correctly x -= 1 x += 1 m = map[mm + x] @@ -1635,7 +1660,7 @@ class Backend(): rc = '\n'.join(line.rstrip() for line in buf[:-1].split('\n')); rc = rc.replace('­', ''); # remove soft hyphens - rc = rc.replace('\0', '%s%s%s' % (AUTO_PUSH, '\033[31m-', AUTO_POP)) # TODO make configurable + rc = rc.replace('\0', '%s%s%s' % (AUTO_PUSH, self.hyphen, AUTO_POP)) # TODO make configurable return rc @@ -2075,6 +2100,13 @@ opts.add_argumentless(['-X', '--256-colours', '--256colours', '--x-colours']) opts.add_argumentless(['-V', '--tty-colours', '--ttycolours', '--vt-colours']) opts.add_argumentless(['-K', '--kms-colours', '--kmscolours']) +opts.add_argumented(['+c', '--colour'], arg = 'COLOUR') +opts.add_argumented(['--colour-bubble', '--colour-balloon'], arg = 'COLOUR') +opts.add_argumented(['--colour-link'], arg = 'COLOUR') +opts.add_argumented(['--colour-msg', '--colour-message'], arg = 'COLOUR') +opts.add_argumented(['--colour-pony'], arg = 'COLOUR') +opts.add_argumented(['--colour-wrap', '--colour-hyphen'], arg = 'COLOUR') + opts.add_argumentless(['-h', '--help'], help = 'Print this help message.') opts.add_argumentless(['-v', '--version'], help = 'Print the version of the program.') opts.add_argumentless(['-l', '--list'], help = 'List pony names.') From e74b16297e4ab932236a8a9eb71c545a1d70eb49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Fri, 12 Oct 2012 02:59:43 +0200 Subject: [PATCH 10/19] colouring is fully functional --- ponysay.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/ponysay.py b/ponysay.py index 2bad694d..52629643 100755 --- a/ponysay.py +++ b/ponysay.py @@ -720,7 +720,7 @@ class Ponysay(): hyphencolour = '' if args.opts['--colour-wrap'] is not None: hyphencolour = '\033[' + ';'.join(args.opts['--colour-wrap']) + 'm' - hyphen = '\033[31m' + hyphencolour + '-' + hyphen = '\033[31m' + hyphencolour + '-' # TODO make configurable ## Link and balloon colouring linkcolour = '' @@ -1527,15 +1527,9 @@ class Backend(): if wrap is not None: msg = self.__wrapMessage(msg, wrap) - AUTO_PUSH = '\033[01010~' - AUTO_POP = '\033[10101~' - cstack = ColourStack(AUTO_PUSH, AUTO_POP) - buf = '' - for c in msg.replace('\n', AUTO_PUSH + self.ballooncolour + '\n' + AUTO_POP) + self.ballooncolour: - buf += c - buf += cstack.feed(c) + msg = msg.replace('\n', '\033[0m%s\n' % (self.ballooncolour)) + '\033[0m' + self.ballooncolour - return self.balloon.get(width, height, buf.split('\n'), self.__len) + return self.balloon.get(width, height, msg.split('\n'), self.__len); ''' @@ -1544,7 +1538,12 @@ class Backend(): def __wrapMessage(self, message, wrap): AUTO_PUSH = '\033[01010~' AUTO_POP = '\033[10101~' - lines = message.split('\n') + msg = message.replace('\n', AUTO_PUSH + '\n' + AUTO_POP); + cstack = ColourStack(AUTO_PUSH, AUTO_POP) + buf = '' + for c in msg: + buf += c + cstack.feed(c) + lines = buf.replace(AUTO_PUSH, '').replace(AUTO_POP, '').split('\n') buf = '' for line in lines: b = [None] * len(line) @@ -1660,7 +1659,7 @@ class Backend(): rc = '\n'.join(line.rstrip() for line in buf[:-1].split('\n')); rc = rc.replace('­', ''); # remove soft hyphens - rc = rc.replace('\0', '%s%s%s' % (AUTO_PUSH, self.hyphen, AUTO_POP)) # TODO make configurable + rc = rc.replace('\0', '%s%s%s' % (AUTO_PUSH, self.hyphen, AUTO_POP)) return rc From d62f6d495e586287a28e061891f8e2da1c8574ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Fri, 12 Oct 2012 12:11:24 +0200 Subject: [PATCH 11/19] more detailed method documentation --- ponysay.py | 142 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 124 insertions(+), 18 deletions(-) diff --git a/ponysay.py b/ponysay.py index 52629643..3693cd13 100755 --- a/ponysay.py +++ b/ponysay.py @@ -38,7 +38,11 @@ VERSION = 'dev' # this line should not be edited, it is fixed by the build syst ''' -Hack to enforce UTF-8 in output (in the future, if you see anypony not using utf-8 in programs by default, report them to Princess Celestia so she can banish them to the moon) +Hack to enforce UTF-8 in output (in the future, if you see anypony not using utf-8 in +programs by default, report them to Princess Celestia so she can banish them to the moon) + +@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 print(text = '', end = '\n'): sys.stdout.buffer.write((str(text) + end).encode('utf-8')) @@ -46,6 +50,10 @@ def print(text = '', end = '\n'): ''' Checks whether a text ends with a specific text, but has more + +@param text The text to test +@param ending The desired end of the text +@return :bool The result of the test ''' def endswith(text, ending): return text.endswith(ending) and not (text == ending); @@ -58,6 +66,8 @@ This is the mane class of ponysay class Ponysay(): ''' Starts the part of the program the arguments indicate + + @param args:ArgParser Parsed command line arguments ''' def __init__(self, args): if (args.argcount == 0) and not pipelinein: @@ -120,12 +130,14 @@ class Ponysay(): else: self.print_pony(args) - ## - ## Methods that run before the mane methods - ## + ############################################## + ## Methods that run before the mane methods ## + ############################################## ''' Use extra ponies + + @param args:ArgParser Parsed command line arguments, may be `None` ''' def __extraponies(self, args = None): ## If extraponies are used, change ponydir to extraponydir @@ -138,6 +150,8 @@ class Ponysay(): ''' Use best.pony if nothing else is set + + @param args:ArgParser Parsed command line arguments ''' def __bestpony(self, args): ## Set best.pony as the pony to display if none is selected @@ -151,6 +165,8 @@ class Ponysay(): ''' Apply pony name remapping to args according to UCS settings + + @param args:ArgParser Parsed command line arguments ''' def __ucsremap(self, args): ## Read UCS configurations @@ -188,12 +204,15 @@ class Ponysay(): args.opts[flag][i] = map[args.opts[flag][i]] - ## - ## Auxiliary methods - ## + ####################### + ## Auxiliary methods ## + ####################### ''' Apply USC:ise pony names according to UCS settings + + @param ponies:list List of all ponies (of interrest) + @param links:map Map to fill with simulated symlink ponies, may be `None` ''' def __ucsise(self, ponies, links = None): ## Read UCS configurations @@ -238,6 +257,9 @@ class Ponysay(): ''' Returns one file with full path, names is filter for names, also accepts filepaths + + @param names:list Ponies to choose from, may be `None` + @return :str The file name of a pony ''' def __getponypath(self, names = None): ponies = {} @@ -270,6 +292,8 @@ class Ponysay(): ''' Returns a set with all ponies that have quotes and are displayable + + @return :set All ponies that have quotes and are displayable ''' def __quoters(self): ## List all unique quote files @@ -300,6 +324,8 @@ class Ponysay(): ''' Returns a list with all (pony, quote file) pairs + + @return (pony, quote):(str, str) All ponies–quote file-pairs ''' def __quotes(self): ## Get all ponyquote files @@ -324,6 +350,8 @@ class Ponysay(): ''' Gets the size of the terminal in (rows, columns) + + @return (rows, columns):(int, int) The number or lines and the number of columns in the terminal's display area ''' def __gettermsize(self): ## Call `stty` to determine the size of the terminal, this way is better then using python's ncurses @@ -334,12 +362,14 @@ class Ponysay(): - ## - ## Listing methods - ## + ##################### + ## Listing methods ## + ##################### ''' Columnise a list and prints it + + @param ponies:list<(str, str)> All items to list, each item should have to elements: unformated name, formated name ''' def __columnise(self, ponies): ## Get terminal width, and a 2 which is the space between columns @@ -536,10 +566,9 @@ class Ponysay(): print(pony) - - ## - ## Balloon methods - ## + ##################### + ## Balloon methods ## + ##################### ''' Prints a list of all balloons @@ -570,6 +599,9 @@ class Ponysay(): ''' Returns one file with full path, names is filter for style names, also accepts filepaths + + @param names:list Balloons to choose from, may be `None` + @param :str The file name of the balloon, will be `None` iff `names` is `None` ''' def __getballoonpath(self, names): ## Stop if their is no choosen balloon @@ -609,6 +641,9 @@ class Ponysay(): ''' Creates the balloon style object + + @param balloonfile:str The file with the balloon style, may be `None` + @return :Balloon Instance describing the balloon's style ''' def __getballoon(self, balloonfile): ## Use default balloon if none is specified @@ -644,9 +679,9 @@ class Ponysay(): - ## - ## Displaying methods - ## + ######################## + ## Displaying methods ## + ######################## ''' Prints the name of the program and the version of the program @@ -658,6 +693,8 @@ class Ponysay(): ''' Print the pony with a speech or though bubble. message, pony and wrap from args are used. + + @param args:ArgParser Parsed command line arguments ''' def print_pony(self, args): ## Get message and remove tailing whitespace from stdin (but not for each line) @@ -765,6 +802,8 @@ class Ponysay(): ''' Print the pony with a speech or though bubble and a self quote + + @param args:ArgParser Parsed command line arguments ''' def quote(self, args): ## Get all quotes, and if any pony is choosen just keep them @@ -827,6 +866,9 @@ class Ponysay(): ''' Returns the file name of the input pony converted to a KMS pony, or if KMS is not used, the input pony itself + + @param pony:str Choosen pony file + @return :str Pony file to display ''' def __kms(self, pony): ## If not in Linux VT, return the pony as is @@ -929,9 +971,21 @@ class Ponysay(): +''' +Option takes no arguments +''' ARGUMENTLESS = 0 + +''' +Option takes one argument per instance +''' ARGUMENTED = 1 + +''' +Option consumes all following arguments +''' VARIADIC = 2 + ''' Simple argument parser ''' @@ -939,6 +993,11 @@ class ArgParser(): ''' Constructor. The short description is printed on same line as the program name + + @param program:str The name of the program + @param description:str Short, single-line, description of the program + @param usage:str Formated, multi-line, usage text + @param longdescription:str Long, multi-line, description of the program, may be `None` ''' def __init__(self, program, description, usage, longdescription = None): self.__program = program @@ -952,6 +1011,9 @@ class ArgParser(): ''' Add option that takes no arguments + + @param alternatives:list Option names + @param help:str Short description, use `None` to hide the option ''' def add_argumentless(self, alternatives, help = None): ARGUMENTLESS @@ -963,6 +1025,10 @@ class ArgParser(): ''' Add option that takes one argument + + @param alternatives:list Option names + @param arg:str The name of the takes argument, one word + @param help:str Short description, use `None` to hide the option ''' def add_argumented(self, alternatives, arg, help = None): self.__arguments.append((ARGUMENTED, alternatives, arg, help)) @@ -973,6 +1039,10 @@ class ArgParser(): ''' Add option that takes all following argument + + @param alternatives:list Option names + @param arg:str The name of the takes arguments, one word + @param help:str Short description, use `None` to hide the option ''' def add_variadic(self, alternatives, arg, help = None): self.__arguments.append((VARIADIC, alternatives, arg, help)) @@ -984,6 +1054,8 @@ class ArgParser(): ''' Parse arguments + + @param args:list The command line arguments, should include the execute file at index 0, `sys.argv` is default ''' def parse(self, argv = sys.argv): self.argcount = len(argv) - 1 @@ -1169,6 +1241,27 @@ Balloon format class class Balloon(): ''' Constructor + + @param link:str The \-directional balloon line character + @param linkmirror:str The /-directional balloon line character + @param ww:str See the info manual + @param ee:str See the info manual + @param nw:list See the info manual + @param nnw:list See the info manual + @param n:list See the info manual + @param nne:list See the info manual + @param ne:list See the info manual + @param nee:str See the info manual + @param e:str See the info manual + @param see:str See the info manual + @param se:list See the info manual + @param sse:list See the info manual + @param s:list See the info manual + @param ssw:list See the info manual + @param sw:list See the info manual + @param sww:str See the info manual + @param w:str See the info manual + @param nww:str See the info manual ''' def __init__(self, link, linkmirror, ww, ee, nw, nnw, n, nne, ne, nee, e, see, se, sse, s, ssw, sw, sww, w, nww): (self.link, self.linkmirror) = (link, linkmirror) @@ -1195,6 +1288,12 @@ class Balloon(): ''' Generates a balloon with a message + + @param minw:int The minimum number of columns of the balloon + @param minh:int The minimum number of lines of the balloon + @param lines:list The text lines to display + @param lencalc:int(str) Function used to compute the length of a text line + @return :str The balloon as a formated string ''' def get(self, minw, minh, lines, lencalc): h = self.minheight + len(lines) @@ -1464,6 +1563,10 @@ class Backend(): ''' Gets colour code att the currect offset in a buffer + + @param input:str The input buffer + @param offset:int The offset at where to start reading, a escape must begin here + @return :str The escape sequence ''' def __getcolour(self, input, offset): (i, n) = (offset, len(input)) @@ -1499,6 +1602,9 @@ class Backend(): ''' Calculates the number of visible characters in a text + + @param input:str The input buffer + @return :int The number of visible characters ''' def __len(self, input): (rc, i, n) = (0, 0, len(input)) @@ -1784,7 +1890,7 @@ Class used for correcting spellos and typos, Note that this implementation will not find that correctly spelled word are correct faster than it corrects words. It is also limited to words of size 0 to 127 (inclusive) ''' -class SpelloCorrecter: # Naïvely and quickly proted and adapted from optimised Java, may not be the nicest, or even fast, Python code +class SpelloCorrecter(): # Naïvely and quickly proted and adapted from optimised Java, may not be the nicest, or even fast, Python code def __init__(self, directories, ending): self.weights = {'k' : {'c' : 0.25, 'g' : 0.75, 'q' : 0.125}, 'c' : {'k' : 0.25, 'g' : 0.75, 's' : 0.5, 'z' : 0.5, 'q' : 0.125}, From 9cd7e26542e83becb9abd05502f1bca0be5439a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Fri, 12 Oct 2012 16:46:27 +0200 Subject: [PATCH 12/19] document code --- ponysay.py | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 5 deletions(-) diff --git a/ponysay.py b/ponysay.py index 3693cd13..1a726574 100755 --- a/ponysay.py +++ b/ponysay.py @@ -1340,9 +1340,18 @@ Replacement for cowsay class Backend(): ''' Constructor - Takes message [string], ponyfile [filename string], wrapcolumn [None or an int], + Takes wrapcolumn [None or an int], width [None or an int], balloon [None or Balloon object], hyphen [string], linkcolour [string] and ballooncolour [string] + + @param message:str The message spoken by the pony + @param ponyfile:str The pony file + @param wrapcolumn:int The column at where to wrap the message, `None` for no wrapping + @param width:int The width of the screen, `None` if truncation should not be applied + @param balloon:Balloon The balloon style object, `None` if only the pony should be printed + @param hyphen:str How hyphens added by the wordwrapper should be printed + @param linkcolour:str How to colour the link character, empty string if none + @param ballooncolour:str How to colour the balloon, empty string if none ''' def __init__(self, message, ponyfile, wrapcolumn, width, balloon, hyphen, linkcolour, ballooncolour): self.message = message @@ -1621,6 +1630,11 @@ class Backend(): ''' Generates a balloon with the message + + @param width:int The minimum width of the balloon + @param height:int The minimum height of the balloon + @param left:int The column where the balloon starts + @return :str The balloon the the message as a string ''' def __getballoon(self, width, height, left): wrap = None @@ -1640,9 +1654,13 @@ class Backend(): ''' Wraps the message + + @param message:str The message to wrap + @param wrap:int The width at where to force wrapping + @return :str The message wrapped ''' def __wrapMessage(self, message, wrap): - AUTO_PUSH = '\033[01010~' + AUTO_PUSH = '\033[0101y0~' AUTO_POP = '\033[10101~' msg = message.replace('\n', AUTO_PUSH + '\n' + AUTO_POP); cstack = ColourStack(AUTO_PUSH, AUTO_POP) @@ -1771,10 +1789,15 @@ class Backend(): ''' ANSI colour stack + +This is used to make layers with independent coloursations ''' class ColourStack(): ''' Constructor + + @param autopush:str String that, when used, will create a new independently colourised layer + @param autopop:str String that, when used, will end the current layer and continue of the previous layer ''' def __init__(self, autopush, autopop): self.autopush = autopush @@ -1787,6 +1810,11 @@ class ColourStack(): self.seq = None + ''' + Create a new independently colourised layer + + @return :str String that should be inserted into your buffer + ''' def push(self): self.stack = [[self.bufproto, None, None, [False] * 9]] + self.stack if len(self.stack) == 1: @@ -1794,6 +1822,11 @@ class ColourStack(): return '\033[0m' + ''' + End the current layer and continue of the previous layer + + @return :str String that should be inserted into your buffer + ''' def pop(self): old = self.stack[0] self.stack = self.stack[1:] @@ -1807,6 +1840,13 @@ class ColourStack(): return rc[:-1] + 'm' + ''' + Use this, in sequence, for which character in your buffer that contains yor autopush and autopop + string, the automatically get push and pop string to insert after each character + + @param :chr One character in your buffer + @return :str The text to insert after the input character + ''' def feed(self, char): if self.seq is not None: self.seq += char @@ -1852,6 +1892,9 @@ UCS utility class class UCS(): ''' Checks whether a character is a combining character + + @param char:chr The character to test + @return :bool Whether the character is a combining character ''' @staticmethod def isCombining(char): @@ -1865,6 +1908,9 @@ class UCS(): ''' Gets the number of combining characters in a string + + @param string:str A text to count combining characters in + @return :int The number of combining characters in the string ''' @staticmethod def countCombining(string): @@ -1877,6 +1923,9 @@ class UCS(): ''' Gets length of a string not counting combining characters + + @param string:str The text of which to determine the monospaced width + @return The determine the monospaced width of the text, provided it does not have escape sequnces ''' @staticmethod def dispLen(string): @@ -1891,6 +1940,12 @@ Note that this implementation will not find that correctly spelled word are corr It is also limited to words of size 0 to 127 (inclusive) ''' class SpelloCorrecter(): # Naïvely and quickly proted and adapted from optimised Java, may not be the nicest, or even fast, Python code + ''' + Constructor + + @param directories:list List of directories that contains the file names with the correct spelling + @param ending:str The file name ending of the correctly spelled file names, this is removed for the name + ''' def __init__(self, directories, ending): self.weights = {'k' : {'c' : 0.25, 'g' : 0.75, 'q' : 0.125}, 'c' : {'k' : 0.25, 'g' : 0.75, 's' : 0.5, 'z' : 0.5, 'q' : 0.125}, @@ -1946,9 +2001,10 @@ class SpelloCorrecter(): # Naïvely and quickly proted and adapted from optimise ''' - Finds the closests correct spelled word. - The input is just one word, and the output is tuple - with a list of the closest spellings, and the weigthed distance. + Finds the closests correct spelled word + + @param used:str The word to correct + @return (words, distance):(list, int) A list the closest spellings and the weighted distance ''' def correct(self, used): if len(used) < 127: @@ -1958,6 +2014,11 @@ class SpelloCorrecter(): # Naïvely and quickly proted and adapted from optimise return (seld.corrections, self.closestDistance) + ''' + Finds the closests correct spelled word + + @param used:str The word to correct, it must satisfy all restrictions + ''' def __correct(self, used): self.closestDistance = 0x7FFFFFFF previous = self.dictionary[-1] @@ -2011,6 +2072,17 @@ class SpelloCorrecter(): # Naïvely and quickly proted and adapted from optimise prevLen = len(proper) + ''' + Calculate the distance between a correct word and a incorrect word + + @param proper:str The correct word + @param y0:int The offset for `proper` + @param yn:int The length, before applying `y0`, of `proper` + @param used:str The incorrect word + @param x0:int The offset for `used` + @param xn:int The length, before applying `x0`, of `used` + @return :float The distance between the words + ''' def __distance(self, proper, y0, yn, used, x0, xn): my = self.M[y0] for y in range(y0, yn): From 5aa773ef93e1571cc1a10bb9a2c5bcdf56484466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Fri, 12 Oct 2012 18:47:19 +0200 Subject: [PATCH 13/19] m doc --- ponysay.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ponysay.py b/ponysay.py index 1a726574..90de92d8 100755 --- a/ponysay.py +++ b/ponysay.py @@ -1335,14 +1335,11 @@ class Balloon(): ''' -Replacement for cowsay +Super-ultra-extreme-awesomazing replacement for cowsay ''' class Backend(): ''' Constructor - Takes wrapcolumn [None or an int], - width [None or an int], balloon [None or Balloon object], hyphen [string], - linkcolour [string] and ballooncolour [string] @param message:str The message spoken by the pony @param ponyfile:str The pony file From 45c3d2a1aa8f68525317933689541274926942f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Mon, 22 Oct 2012 12:25:01 +0200 Subject: [PATCH 14/19] m --- ponysay.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ponysay.py b/ponysay.py index 90de92d8..6e8b82c3 100755 --- a/ponysay.py +++ b/ponysay.py @@ -2130,8 +2130,8 @@ linuxvt = ('TERM' in os.environ) and (os.environ['TERM'] == 'linux') ''' Whether the script is executed as ponythink ''' -isthink = (len(__file__) >= 5) and (__file__[-5:] == 'think') -isthink = ((len(__file__) >= 8) and (__file__[-8:] == 'think.py')) or isthink +isthink = (len(__file__) >= len('think')) and (__file__.endswith('think')) +isthink = ((len(__file__) >= len('think.py')) and (__file__.endswith('think.py'))) or isthink ''' From 10b55d4def70d8dcb3e0c667c1e38747580e73f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Mon, 22 Oct 2012 12:26:17 +0200 Subject: [PATCH 15/19] doc typo --- ponysay.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ponysay.py b/ponysay.py index 6e8b82c3..34674579 100755 --- a/ponysay.py +++ b/ponysay.py @@ -175,7 +175,7 @@ class Ponysay(): if env_ucs in ('yes', 'y', '1'): ucs_conf = 1 elif env_ucs in ('harder', 'h', '2'): ucs_conf = 2 - ## Stop USC is not used + ## Stop UCS is not used if ucs_conf == 0: return @@ -186,7 +186,7 @@ class Ponysay(): with open(ucsmap, 'rb') as mapfile: maplines += [line.replace('\n', '') for line in mapfile.read().decode('utf8', 'replace').split('\n')] - ## Create USC → ASCII mapping from read lines + ## Create UCS → ASCII mapping from read lines map = {} stripset = ' \t' # must be string, wtf! and way doesn't python's doc say so for line in maplines: @@ -196,7 +196,7 @@ class Ponysay(): ascii = line[s + 1:].strip(stripset) map[ucs] = ascii - ## Apply USC → ASCII mapping to -f and -q arguments + ## Apply UCS → ASCII mapping to -f and -q arguments for flag in ('-f', '-q'): if args.opts[flag] is not None: for i in range(0, len(args.opts[flag])): @@ -209,7 +209,7 @@ class Ponysay(): ####################### ''' - Apply USC:ise pony names according to UCS settings + Apply UCS:ise pony names according to UCS settings @param ponies:list List of all ponies (of interrest) @param links:map Map to fill with simulated symlink ponies, may be `None` @@ -221,7 +221,7 @@ class Ponysay(): if env_ucs in ('yes', 'y', '1'): ucs_conf = 1 elif env_ucs in ('harder', 'h', '2'): ucs_conf = 2 - ## Stop USC is not used + ## Stop UCS is not used if ucs_conf == 0: return @@ -232,7 +232,7 @@ class Ponysay(): with open(ucsmap, 'rb') as mapfile: maplines += [line.replace('\n', '') for line in mapfile.read().decode('utf8', 'replace').split('\n')] - ## Create USC → ASCII mapping from read lines + ## Create UCS → ASCII mapping from read lines map = {} stripset = ' \t' # must be string, wtf! and way doesn't python's doc say so for line in maplines: @@ -242,7 +242,7 @@ class Ponysay(): ascii = line[s + 1:].strip(stripset) map[ascii] = ucs - ## Apply USC → ACII mapping to ponies, by alias if weak settings + ## Apply UCS → ACII mapping to ponies, by alias if weak settings if ucs_conf == 1: for pony in ponies: if pony in map: @@ -527,7 +527,7 @@ class Ponysay(): ## Get all quoters ponies = self.__quoters() - ## USC:ise and sort + ## UCS:ise and sort self.__ucsise(ponies) ponies.sort() @@ -554,7 +554,7 @@ class Ponysay(): if endswith(pony, '.pony'): ponies.append(pony[:-5]) - ## USC:ise and sort + ## UCS:ise and sort self.__ucsise(ponies) ponies.sort() From 78fc2bda35591530231ffe374f0c6523a2220caa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Mon, 22 Oct 2012 12:31:32 +0200 Subject: [PATCH 16/19] minor dependency update (chmod in coreutils is used) --- dependency-test.sh | 2 ++ manuals/ponysay.texinfo | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/dependency-test.sh b/dependency-test.sh index 770873c5..3c5301bd 100755 --- a/dependency-test.sh +++ b/dependency-test.sh @@ -15,6 +15,7 @@ ro=0 (hash mkdir 2>/dev/null) || (br=1 ; echo 'Missing mkdir, install coreutils [build required]') (hash cp 2>/dev/null) || (br=1 ; echo 'Missing cp, install coreutils [build required]') (hash cut 2>/dev/null) || (br=1 ; echo 'Missing cut, install coreutils [build required]') +(hash chmod 2>/dev/null) || (br=1 ; echo 'Missing chmod, install coreutils [build required]') (hash bash 2>/dev/null) || (bs=1 ; echo 'Missing bash, install bash [build recommended]') @@ -32,6 +33,7 @@ ro=0 (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 chmod 2>/dev/null) || (rr=1 ; echo 'Missing chmod, install coreutils [runtime optional]') ( (test $br = 1) || (test $rr = 1) || (test $ro = 1) ) && echo diff --git a/manuals/ponysay.texinfo b/manuals/ponysay.texinfo index a43a781c..d2c5165c 100644 --- a/manuals/ponysay.texinfo +++ b/manuals/ponysay.texinfo @@ -754,12 +754,14 @@ We have provided a script that should run one most, if not all shells, named @table @command @item util-say>=2 -@cindex @command{util-say} +@pindex @command{util-say} @cindex kms @cindex tty @pindex linux vt For improved TTY support for user with custom colour palette and KMS support. -It can be downloaded at @url{https://github.com/maandree/util-say}. +It can be downloaded at @url{https://github.com/maandree/util-say}. If this is +used @command{chmod} from @command{coreutils} is also required. + @cindex .png @cindex png images From de0813f5233bb45cc196d59fbc3f0ce30dba2c8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Mon, 22 Oct 2012 13:17:42 +0200 Subject: [PATCH 17/19] automatic pony name and balloon style name spelling correction --- ponysay.py | 75 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 23 deletions(-) diff --git a/ponysay.py b/ponysay.py index 34674579..b7abe7f9 100755 --- a/ponysay.py +++ b/ponysay.py @@ -259,17 +259,19 @@ class Ponysay(): Returns one file with full path, names is filter for names, also accepts filepaths @param names:list Ponies to choose from, may be `None` + @param alt:bool For method internal use... @return :str The file name of a pony ''' - def __getponypath(self, names = None): + def __getponypath(self, names = None, alt = False): ponies = {} ## List all pony files, without the .pony ending for ponydir in ponydirs: for ponyfile in os.listdir(ponydir): - pony = ponyfile[:-5] - if pony not in ponies: - ponies[pony] = ponydir + ponyfile + if endswith(ponyfile, ".pony"): + pony = ponyfile[:-5] + if pony not in ponies: + ponies[pony] = ponydir + ponyfile ## Support for explicit pony file names if not names == None: @@ -284,6 +286,11 @@ class Ponysay(): ## Select a random pony of the choosen onles pony = names[random.randrange(0, len(names))] if pony not in ponies: + if not alt: + autocorrect = SpelloCorrecter(ponydirs, '.pony') + (alternatives, dist) = autocorrect.correct(pony) + if len(alternatives) > 0: + return self.__getponypath(alternatives, True) sys.stderr.write('I have never heard of anypony named %s\n' % (pony)); exit(1) else: @@ -405,7 +412,6 @@ class Ponysay(): c -= 1 columns[c] = columns[c][:-diff] diff -= 1 - pass ## Create rows from columns lines = [] @@ -601,9 +607,10 @@ class Ponysay(): Returns one file with full path, names is filter for style names, also accepts filepaths @param names:list Balloons to choose from, may be `None` + @param alt:bool For method internal use @param :str The file name of the balloon, will be `None` iff `names` is `None` ''' - def __getballoonpath(self, names): + def __getballoonpath(self, names, alt = False): ## Stop if their is no choosen balloon if names is None: return None @@ -633,6 +640,11 @@ class Ponysay(): ## Select a random balloon of the choosen ones balloon = names[random.randrange(0, len(names))] if balloon not in balloons: + if not alt: + autocorrect = SpelloCorrecter(balloondirs, '.think' if isthink else '.say') + alternatives = autocorrect.correct(balloon)[0] + if len(alternatives) > 0: + return self.__getponypath(alternatives, True) sys.stderr.write('That balloon style %s does not exist\n' % (balloon)); exit(1) else: @@ -1981,20 +1993,36 @@ class SpelloCorrecter(): # Naïvely and quickly proted and adapted from optimise continue proper = filename[:-len(ending)] - if dictionaryEnd == 0: - dictionaryEnd = len(self.dictionary) - self.reusable = [0] * dictionaryEnd + self.reusable - self.dictionary = [None] * dictionaryEnd + self.dictionary + if self.dictionaryEnd == 0: + self.dictionaryEnd = len(self.dictionary) + self.reusable = [0] * self.dictionaryEnd + self.reusable + self.dictionary = [None] * self.dictionaryEnd + self.dictionary + + self.dictionaryEnd -= 1 + self.dictionary[self.dictionaryEnd] = proper - dictionaryEnd -= 1 - dictionary[dictionaryEnd] = proper prevCommon = min(len(previous), len(proper)) for i in range(0, prevCommon): if previous[i] != proper[i]: prevCommon = i break - previous = dictionary[dictionaryEnd] - reusable[dictionaryEnd] = prevCommon + previous = proper + self.reusable[self.dictionaryEnd] = prevCommon + #part = self.dictionary[self.dictionaryEnd : len(self.dictionary) - 1] + #part.sort() + #self.dictionary[self.dictionaryEnd : len(self.dictionary) - 1] = part + # + #index = len(self.dictionary) - 1 + #while index >= self.dictionaryEnd: + # proper = self.dictionary[index] + # prevCommon = min(len(previous), len(proper)) + # for i in range(0, prevCommon): + # if previous[i] != proper[i]: + # prevCommon = i + # break + # previous = proper + # self.reusable[self.dictionaryEnd] = prevCommon + # index -= 1; ''' @@ -2004,11 +2032,11 @@ class SpelloCorrecter(): # Naïvely and quickly proted and adapted from optimise @return (words, distance):(list, int) A list the closest spellings and the weighted distance ''' def correct(self, used): - if len(used) < 127: + if len(used) > 127: return ([used], 0) - __correct(used) - return (seld.corrections, self.closestDistance) + self.__correct(used) + return (self.corrections, self.closestDistance) ''' @@ -2025,7 +2053,7 @@ class SpelloCorrecter(): # Naïvely and quickly proted and adapted from optimise proper = None prevCommon = 0 - d = len(self.dictionary) + d = len(self.dictionary) - 1 while d > self.dictionaryEnd: d -= 1 proper = self.dictionary[d] @@ -2041,7 +2069,7 @@ class SpelloCorrecter(): # Naïvely and quickly proted and adapted from optimise skip = min(prevLen, len(proper)) i = prevCommon - while i < skip: + while i < skip: for u in range(0, usedLen): if (used[u] == previous[i]) or (used[u] == proper[i]): skip = i @@ -2054,13 +2082,13 @@ class SpelloCorrecter(): # Naïvely and quickly proted and adapted from optimise common = i break - distance = self.__distance(proper, skip, proper.length, used, common, usedLen) + distance = self.__distance(proper, skip, len(proper), used, common, usedLen) if self.closestDistance > distance: self.closestDistance = distance - corrections = [proper] + self.corrections = [proper] elif self.closestDistance == distance: - corrections.append(proper) + self.corrections.append(proper) previous = proper; if distance >= 0x7FFFFF00: @@ -2102,13 +2130,14 @@ class SpelloCorrecter(): # Naïvely and quickly proted and adapted from optimise if my[x] in self.weights: if p in self.weights[u]: cw = self.weights[u][p] + x += 1 myy[x] = min(cw + change, 1 + min(remove, add)) if best > myy[x]: best = myy[x] if best > self.closestDistance: - return 0x7FFFFFFF | y + return 0x7FFFFF00 | y my = myy return my[xn] From bed638b035bbda4ddd4d9f64f9a0ffbd0000643a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Mon, 22 Oct 2012 13:19:34 +0200 Subject: [PATCH 18/19] change log update according to last commit --- CHANGELOG | 2 ++ manuals/ponysay.texinfo | 2 ++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index ab03820d..ed8663f4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -17,6 +17,8 @@ Version 2.8 Colouring option flags are added. + Automatic correction of incorrectly spelled pony names and balloon style names added. + Version 2.7 diff --git a/manuals/ponysay.texinfo b/manuals/ponysay.texinfo index d2c5165c..67108297 100644 --- a/manuals/ponysay.texinfo +++ b/manuals/ponysay.texinfo @@ -1969,6 +1969,8 @@ Support for terminal capabilities emulation with the flags @option{-X}, @option{ Support for printing just the pony, using the flag @option{-o}. @item Colouring option flags are added. +@item +Automatic correction of incorrectly spelled pony names and balloon style names added. @end itemize From a07dadb81348b61b19f9ca9760fcb1a7696c4d06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Mon, 22 Oct 2012 13:34:41 +0200 Subject: [PATCH 19/19] changelog typo --- manuals/ponysay.texinfo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manuals/ponysay.texinfo b/manuals/ponysay.texinfo index 67108297..3bd4fe41 100644 --- a/manuals/ponysay.texinfo +++ b/manuals/ponysay.texinfo @@ -1958,7 +1958,7 @@ Pony symlink added: @item @file{georgewashingtony} @arrow{} @file{bastionyorsets} @end itemize @item -Support for explicit hypthenation using soft hyphens had been added to the word wrapper. +Support for explicit hyphenation using soft hyphens had been added to the word wrapper. @item Support for explicit non-word wrapping using non-breaking space had been added to the word wrapper. @item