mirror of
https://github.com/erkin/ponysay.git
synced 2025-02-14 16:44:23 +01:00
kuroko port
This commit is contained in:
parent
8a2c71416e
commit
2a32fed223
14 changed files with 592 additions and 531 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -39,7 +39,6 @@ _/
|
||||||
/*ponies/onlyheights
|
/*ponies/onlyheights
|
||||||
/*ponies/widths
|
/*ponies/widths
|
||||||
/*ponies/metadata
|
/*ponies/metadata
|
||||||
/ponysay
|
|
||||||
/bin/
|
/bin/
|
||||||
/obj/
|
/obj/
|
||||||
|
|
||||||
|
|
|
@ -39,56 +39,57 @@ Authors:
|
||||||
Jan Alexander "heftig" Steffens: Major contributor of the first implementation
|
Jan Alexander "heftig" Steffens: Major contributor of the first implementation
|
||||||
Kyah "L-four" Rindlisbacher: Patched the first implementation
|
Kyah "L-four" Rindlisbacher: Patched the first implementation
|
||||||
'''
|
'''
|
||||||
from common import *
|
from ponysay.common import printerr, printinfo, gettermsize, endswith
|
||||||
from argparser import *
|
from ponysay.argparser import ArgParser
|
||||||
from ponysay import *
|
from ponysay.ponysay import Ponysay
|
||||||
|
import os
|
||||||
|
import kuroko
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Start the program
|
Start the program
|
||||||
'''
|
'''
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
istool = sys.argv[0]
|
let istool = kuroko.argv[0]
|
||||||
if os.sep in istool:
|
if os.sep in istool:
|
||||||
istool = istool[istool.rfind(os.sep) + 1:]
|
istool = istool[istool.rfind(os.sep) + 1:]
|
||||||
if os.extsep in istool:
|
if os.extsep in istool:
|
||||||
istool = istool[:istool.find(os.extsep)]
|
istool = istool[:istool.find(os.extsep)]
|
||||||
istool = istool.endswith('-tool')
|
istool = istool.endswith('-tool')
|
||||||
if istool:
|
if istool:
|
||||||
from ponysaytool import * ## will start ponysay-tool
|
import ponysaytool
|
||||||
exit(0)
|
os.exit(0)
|
||||||
|
|
||||||
isthink = sys.argv[0]
|
let isthink = kuroko.argv[0]
|
||||||
if os.sep in isthink:
|
if os.sep in isthink:
|
||||||
isthink = isthink[isthink.rfind(os.sep) + 1:]
|
isthink = isthink[isthink.rfind(os.sep) + 1:]
|
||||||
if os.extsep in isthink:
|
if os.extsep in isthink:
|
||||||
isthink = isthink[:isthink.find(os.extsep)]
|
isthink = isthink[:isthink.find(os.extsep)]
|
||||||
isthink = isthink.endswith('think')
|
isthink = isthink.endswith('think')
|
||||||
|
|
||||||
usage_saythink = '\033[34;1m(ponysay | ponythink)\033[21;39m'
|
let usage_saythink = '\033[34;1m(ponysay | ponythink)\033[22;39m'
|
||||||
usage_common = '[-c] [-W\033[33mCOLUMN\033[39m] [-b\033[33mSTYLE\033[39m]'
|
let usage_common = '[-c] [-W\033[33mCOLUMN\033[39m] [-b\033[33mSTYLE\033[39m]'
|
||||||
usage_listhelp = '(-l | -L | -B | +l | +L | -A | + A | -v | -h)'
|
let usage_listhelp = '(-l | -L | -B | +l | +L | -A | + A | -v | -h)'
|
||||||
usage_file = '[-f\033[33mPONY\033[39m]* [[--] \033[33mmessage\033[39m]'
|
let usage_file = '[-f\033[33mPONY\033[39m]* [[--] \033[33mmessage\033[39m]'
|
||||||
usage_xfile = '(+f\033[33mPONY\033[39m)* [[--] \033[33mmessage\033[39m]'
|
let usage_xfile = '(+f\033[33mPONY\033[39m)* [[--] \033[33mmessage\033[39m]'
|
||||||
usage_afile = '(-F\033[33mPONY\033[39m)* [[--] \033[33mmessage\033[39m]'
|
let usage_afile = '(-F\033[33mPONY\033[39m)* [[--] \033[33mmessage\033[39m]'
|
||||||
usage_quote = '(-q\033[33mPONY\033[39m)*'
|
let usage_quote = '(-q\033[33mPONY\033[39m)*'
|
||||||
|
|
||||||
usage = ('%s %s' + 4 * '\n%s %s %s') % (usage_saythink, usage_listhelp,
|
let usage = ('{} {}' + 4 * '\n{} {} {}') .format (usage_saythink, usage_listhelp,
|
||||||
usage_saythink, usage_common, usage_file,
|
usage_saythink, usage_common, usage_file,
|
||||||
usage_saythink, usage_common, usage_xfile,
|
usage_saythink, usage_common, usage_xfile,
|
||||||
usage_saythink, usage_common, usage_afile,
|
usage_saythink, usage_common, usage_afile,
|
||||||
usage_saythink, usage_common, usage_quote)
|
usage_saythink, usage_common, usage_quote)
|
||||||
|
|
||||||
usage = usage.replace('\033[', '\0')
|
usage = usage.replace('\033[', 'あ')
|
||||||
for sym in ('[', ']', '(', ')', '|', '...', '*'):
|
for sym in ('[', ']', '(', ')', '|', '...', '*'):
|
||||||
usage = usage.replace(sym, '\033[2m' + sym + '\033[22m')
|
usage = usage.replace(sym, '\033[2m' + sym + '\033[22m')
|
||||||
usage = usage.replace('\0', '\033[')
|
usage = usage.replace('あ', '\033[')
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Argument parsing
|
Argument parsing
|
||||||
'''
|
'''
|
||||||
opts = ArgParser(program = 'ponythink' if isthink else 'ponysay',
|
let opts = ArgParser(program = 'ponythink' if isthink else 'ponysay',
|
||||||
description = 'cowsay reimplemention for ponies',
|
description = 'cowsay reimplemention for ponies',
|
||||||
usage = usage,
|
usage = usage,
|
||||||
longdescription =
|
longdescription =
|
||||||
|
@ -117,8 +118,8 @@ run `man ponysay`. Ponysay has so much more to offer than described here.''')
|
||||||
opts.add_argumented( ['--colour-pony'], arg = 'COLOUR')
|
opts.add_argumented( ['--colour-pony'], arg = 'COLOUR')
|
||||||
opts.add_argumented( ['--colour-wrap', '--colour-hyphen'], arg = 'COLOUR')
|
opts.add_argumented( ['--colour-wrap', '--colour-hyphen'], arg = 'COLOUR')
|
||||||
|
|
||||||
_F = ['--any-file', '--anyfile', '--any-pony', '--anypony']
|
let _F = ['--any-file', '--anyfile', '--any-pony', '--anypony']
|
||||||
__F = [_.replace("pony", "ponie") + 's' for _ in _F]
|
let __F = [_.replace("pony", "ponie") + 's' for _ in _F]
|
||||||
opts.add_argumentless(['-h', '--help'], help = 'Print this help message.')
|
opts.add_argumentless(['-h', '--help'], help = 'Print this help message.')
|
||||||
opts.add_argumentless(['+h', '++help', '--help-colour'], help = 'Print this help message with colours even if piped.')
|
opts.add_argumentless(['+h', '++help', '--help-colour'], help = 'Print this help message with colours even if piped.')
|
||||||
opts.add_argumentless(['-v', '--version'], help = 'Print the version of the program.')
|
opts.add_argumentless(['-v', '--version'], help = 'Print the version of the program.')
|
||||||
|
@ -145,10 +146,10 @@ run `man ponysay`. Ponysay has so much more to offer than described here.''')
|
||||||
'''
|
'''
|
||||||
Whether at least one unrecognised option was used
|
Whether at least one unrecognised option was used
|
||||||
'''
|
'''
|
||||||
unrecognised = not opts.parse()
|
let unrecognised = not opts.parse()
|
||||||
|
|
||||||
|
|
||||||
## Start
|
## Start
|
||||||
ponysay = Ponysay()
|
let ponysay = Ponysay()
|
||||||
ponysay.unrecognised = unrecognised
|
ponysay.unrecognised = unrecognised
|
||||||
ponysay.run(opts)
|
ponysay.run(opts)
|
|
@ -29,21 +29,23 @@ that line ‘FREE: yes’, is included inside the image between two ‘$$$’
|
||||||
lines and the ‘FREE’ is and upper case and directly followed by
|
lines and the ‘FREE’ is and upper case and directly followed by
|
||||||
the colon.
|
the colon.
|
||||||
'''
|
'''
|
||||||
from common import *
|
from ponysay.common import printerr, printinfo, gettermsize, endswith
|
||||||
|
import os
|
||||||
|
import kuroko
|
||||||
|
import fileio
|
||||||
|
|
||||||
|
|
||||||
|
let ARGUMENTLESS = 0
|
||||||
ARGUMENTLESS = 0
|
|
||||||
'''
|
'''
|
||||||
Option takes no arguments
|
Option takes no arguments
|
||||||
'''
|
'''
|
||||||
|
|
||||||
ARGUMENTED = 1
|
let ARGUMENTED = 1
|
||||||
'''
|
'''
|
||||||
Option takes one argument per instance
|
Option takes one argument per instance
|
||||||
'''
|
'''
|
||||||
|
|
||||||
VARIADIC = 2
|
let VARIADIC = 2
|
||||||
'''
|
'''
|
||||||
Option consumes all following arguments
|
Option consumes all following arguments
|
||||||
'''
|
'''
|
||||||
|
@ -83,7 +85,7 @@ class ArgParser():
|
||||||
@param help:str Short description, use `None` to hide the option
|
@param help:str Short description, use `None` to hide the option
|
||||||
'''
|
'''
|
||||||
self.__arguments.append((ARGUMENTLESS, alternatives, None, help))
|
self.__arguments.append((ARGUMENTLESS, alternatives, None, help))
|
||||||
stdalt = alternatives[0]
|
let stdalt = alternatives[0]
|
||||||
self.opts[stdalt] = None
|
self.opts[stdalt] = None
|
||||||
for alt in alternatives:
|
for alt in alternatives:
|
||||||
self.optmap[alt] = (stdalt, ARGUMENTLESS)
|
self.optmap[alt] = (stdalt, ARGUMENTLESS)
|
||||||
|
@ -97,7 +99,7 @@ class ArgParser():
|
||||||
@param help:str Short description, use `None` to hide the option
|
@param help:str Short description, use `None` to hide the option
|
||||||
'''
|
'''
|
||||||
self.__arguments.append((ARGUMENTED, alternatives, arg, help))
|
self.__arguments.append((ARGUMENTED, alternatives, arg, help))
|
||||||
stdalt = alternatives[0]
|
let stdalt = alternatives[0]
|
||||||
self.opts[stdalt] = None
|
self.opts[stdalt] = None
|
||||||
for alt in alternatives:
|
for alt in alternatives:
|
||||||
self.optmap[alt] = (stdalt, ARGUMENTED)
|
self.optmap[alt] = (stdalt, ARGUMENTED)
|
||||||
|
@ -111,13 +113,13 @@ class ArgParser():
|
||||||
@param help:str Short description, use `None` to hide the option
|
@param help:str Short description, use `None` to hide the option
|
||||||
'''
|
'''
|
||||||
self.__arguments.append((VARIADIC, alternatives, arg, help))
|
self.__arguments.append((VARIADIC, alternatives, arg, help))
|
||||||
stdalt = alternatives[0]
|
let stdalt = alternatives[0]
|
||||||
self.opts[stdalt] = None
|
self.opts[stdalt] = None
|
||||||
for alt in alternatives:
|
for alt in alternatives:
|
||||||
self.optmap[alt] = (stdalt, VARIADIC)
|
self.optmap[alt] = (stdalt, VARIADIC)
|
||||||
|
|
||||||
|
|
||||||
def parse(self, argv = sys.argv):
|
def parse(self, argv = kuroko.argv):
|
||||||
'''
|
'''
|
||||||
Parse arguments
|
Parse arguments
|
||||||
|
|
||||||
|
@ -127,23 +129,24 @@ class ArgParser():
|
||||||
self.argcount = len(argv) - 1
|
self.argcount = len(argv) - 1
|
||||||
self.files = []
|
self.files = []
|
||||||
|
|
||||||
argqueue = []
|
let arg, i, n, opt, varopt
|
||||||
optqueue = []
|
let argqueue = []
|
||||||
deque = []
|
let optqueue = []
|
||||||
|
let deque = []
|
||||||
for arg in argv[1:]:
|
for arg in argv[1:]:
|
||||||
deque.append(arg)
|
deque.append(arg)
|
||||||
|
|
||||||
dashed = False
|
let dashed = False
|
||||||
tmpdashed = False
|
let tmpdashed = False
|
||||||
get = 0
|
let get = 0
|
||||||
dontget = 0
|
let dontget = 0
|
||||||
self.rc = True
|
self.rc = True
|
||||||
|
|
||||||
self.unrecognisedCount = 0
|
self.unrecognisedCount = 0
|
||||||
def unrecognised(arg):
|
def unrecognised(arg):
|
||||||
self.unrecognisedCount += 1
|
self.unrecognisedCount += 1
|
||||||
if self.unrecognisedCount <= 5:
|
if self.unrecognisedCount <= 5:
|
||||||
sys.stderr.write('%s: warning: unrecognised option %s\n' % (self.__program, arg))
|
fileio.stderr.write('{}: warning: unrecognised option {}\n' .format (self.__program, arg))
|
||||||
self.rc = False
|
self.rc = False
|
||||||
|
|
||||||
while len(deque) != 0:
|
while len(deque) != 0:
|
||||||
|
@ -184,11 +187,11 @@ class ArgParser():
|
||||||
else:
|
else:
|
||||||
unrecognised(arg)
|
unrecognised(arg)
|
||||||
else:
|
else:
|
||||||
sign = arg[0]
|
let sign = arg[0]
|
||||||
i = 1
|
let i = 1
|
||||||
n = len(arg)
|
let n = len(arg)
|
||||||
while i < n:
|
while i < n:
|
||||||
narg = sign + arg[i]
|
let narg = sign + arg[i]
|
||||||
i += 1
|
i += 1
|
||||||
if (narg in self.optmap):
|
if (narg in self.optmap):
|
||||||
if self.optmap[narg][1] == ARGUMENTLESS:
|
if self.optmap[narg][1] == ARGUMENTLESS:
|
||||||
|
@ -196,7 +199,7 @@ class ArgParser():
|
||||||
argqueue.append(None)
|
argqueue.append(None)
|
||||||
elif self.optmap[narg][1] == ARGUMENTED:
|
elif self.optmap[narg][1] == ARGUMENTED:
|
||||||
optqueue.append(narg)
|
optqueue.append(narg)
|
||||||
nargarg = arg[i:]
|
let nargarg = arg[i:]
|
||||||
if len(nargarg) == 0:
|
if len(nargarg) == 0:
|
||||||
get += 1
|
get += 1
|
||||||
else:
|
else:
|
||||||
|
@ -204,7 +207,7 @@ class ArgParser():
|
||||||
break
|
break
|
||||||
elif self.optmap[narg][1] == VARIADIC:
|
elif self.optmap[narg][1] == VARIADIC:
|
||||||
optqueue.append(narg)
|
optqueue.append(narg)
|
||||||
nargarg = arg[i:]
|
let nargarg = arg[i:]
|
||||||
argqueue.append(nargarg if len(nargarg) > 0 else None)
|
argqueue.append(nargarg if len(nargarg) > 0 else None)
|
||||||
dashed = True
|
dashed = True
|
||||||
break
|
break
|
||||||
|
@ -240,7 +243,7 @@ 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
|
||||||
|
|
||||||
if self.unrecognisedCount > 5:
|
if self.unrecognisedCount > 5:
|
||||||
sys.stderr.write('%s: warning: %i more unrecognised %s\n' % (self.unrecognisedCount - 5, 'options' if self.unrecognisedCount == 6 else 'options'))
|
fileio.stderr.write('{}: warning: {} more unrecognised {}\n' .format (self.unrecognisedCount - 5, 'options' if self.unrecognisedCount == 6 else 'options'))
|
||||||
|
|
||||||
return self.rc
|
return self.rc
|
||||||
|
|
||||||
|
@ -252,94 +255,102 @@ class ArgParser():
|
||||||
@param use_colours:bool? Whether to use colours, `None` if stdout is not piped
|
@param use_colours:bool? Whether to use colours, `None` if stdout is not piped
|
||||||
'''
|
'''
|
||||||
if use_colours is None:
|
if use_colours is None:
|
||||||
use_colours = sys.stdout.isatty()
|
use_colours = True # os.isatty(1)
|
||||||
|
|
||||||
print(('\033[1m%s\033[21m %s %s' if use_colours else '%s %s %s') % (self.__program, '-' if self.linuxvt else '—', self.__description))
|
print(('\[[1m{}\[[22m {} {}' if use_colours else '{} {} {}').format(self.__program, '-' if self.linuxvt else '—', self.__description))
|
||||||
print()
|
print()
|
||||||
if self.__longdescription is not None:
|
if self.__longdescription is not None:
|
||||||
desc = self.__longdescription
|
let desc = self.__longdescription
|
||||||
if not use_colours:
|
if not use_colours:
|
||||||
while '\033' in desc:
|
while '\[' in desc:
|
||||||
esc = desc.find('\033')
|
esc = desc.find('\[')
|
||||||
desc = desc[:esc] + desc[desc.find('m', esc) + 1:]
|
desc = desc[:esc] + desc[desc.find('m', esc) + 1:]
|
||||||
print(desc)
|
print(desc)
|
||||||
print()
|
print()
|
||||||
|
|
||||||
print('\033[1mUSAGE:\033[21m' if use_colours else 'USAGE:', end='')
|
print('\[[1mUSAGE:\[[22m' if use_colours else 'USAGE:', end='')
|
||||||
first = True
|
let first = True
|
||||||
for line in self.__usage.split('\n'):
|
for line in self.__usage.split('\n'):
|
||||||
if first:
|
if first:
|
||||||
first = False
|
first = False
|
||||||
else:
|
else:
|
||||||
print(' or', end='')
|
print(' or', end='')
|
||||||
if not use_colours:
|
if not use_colours:
|
||||||
while '\033' in line:
|
while '\[' in line:
|
||||||
esc = line.find('\033')
|
esc = line.find('\[')
|
||||||
line = line[:esc] + line[line.find('m', esc) + 1:]
|
line = line[:esc] + line[line.find('m', esc) + 1:]
|
||||||
print('\t%s' % line)
|
print('\t{}'.format(line))
|
||||||
print()
|
print()
|
||||||
|
|
||||||
maxfirstlen = []
|
let maxfirstlen = []
|
||||||
for opt in self.__arguments:
|
for opt in self.__arguments:
|
||||||
opt_alts = opt[1]
|
let opt_alts = opt[1]
|
||||||
opt_help = opt[3]
|
let opt_help = opt[3]
|
||||||
if opt_help is None:
|
if opt_help is None:
|
||||||
continue
|
continue
|
||||||
first = opt_alts[0]
|
first = opt_alts[0]
|
||||||
last = opt_alts[-1]
|
let last = opt_alts[-1]
|
||||||
if first is not last:
|
if first is not last:
|
||||||
maxfirstlen.append(first)
|
maxfirstlen.append(first)
|
||||||
maxfirstlen = len(max(maxfirstlen, key = len))
|
maxfirstlen = len(max(maxfirstlen, key = len))
|
||||||
|
|
||||||
print('\033[1mSYNOPSIS:\033[21m' if use_colours else 'SYNOPSIS')
|
print('\[[1mSYNOPSIS:\[[22m' if use_colours else 'SYNOPSIS')
|
||||||
(lines, lens) = ([], [])
|
let lines, lens = [], []
|
||||||
for opt in self.__arguments:
|
for opt in self.__arguments:
|
||||||
opt_type = opt[0]
|
let opt_type = opt[0]
|
||||||
opt_alts = opt[1]
|
let opt_alts = opt[1]
|
||||||
opt_arg = opt[2]
|
let opt_arg = opt[2]
|
||||||
opt_help = opt[3]
|
let opt_help = opt[3]
|
||||||
if opt_help is None:
|
if opt_help is None:
|
||||||
continue
|
continue
|
||||||
(line, l) = ('', 0)
|
let line, l = '', 0
|
||||||
first = opt_alts[0]
|
first = opt_alts[0]
|
||||||
last = opt_alts[-1]
|
let last = opt_alts[-1]
|
||||||
alts = ['', last] if first is last else [first, last]
|
let alts = ['', last] if first is last else [first, last]
|
||||||
alts[0] += ' ' * (maxfirstlen - len(alts[0]))
|
alts[0] += ' ' * (maxfirstlen - len(alts[0]))
|
||||||
for opt_alt in alts:
|
for opt_alt in alts:
|
||||||
if opt_alt is alts[-1]:
|
if opt_alt is alts[-1]:
|
||||||
line += '%colour%' + opt_alt
|
line += '%colour%' + opt_alt
|
||||||
l += len(opt_alt)
|
l += len(opt_alt)
|
||||||
if use_colours:
|
if use_colours:
|
||||||
if opt_type == ARGUMENTED: line += ' \033[4m%s\033[24m' % (opt_arg); l += len(opt_arg) + 1
|
if opt_type == ARGUMENTED:
|
||||||
elif opt_type == VARIADIC: line += ' [\033[4m%s\033[24m...]' % (opt_arg); l += len(opt_arg) + 6
|
line += ' \[[4m{}\[[24m' .format (opt_arg)
|
||||||
|
l += len(opt_arg) + 1
|
||||||
|
elif opt_type == VARIADIC:
|
||||||
|
line += ' [\[[4m{}\[[24m...]' .format (opt_arg)
|
||||||
|
l += len(opt_arg) + 6
|
||||||
else:
|
else:
|
||||||
if opt_type == ARGUMENTED: line += ' %s' % (opt_arg); l += len(opt_arg) + 1
|
if opt_type == ARGUMENTED:
|
||||||
elif opt_type == VARIADIC: line += ' [%s...]' % (opt_arg); l += len(opt_arg) + 6
|
line += ' {}' .format (opt_arg)
|
||||||
|
l += len(opt_arg) + 1
|
||||||
|
elif opt_type == VARIADIC:
|
||||||
|
line += ' [{}...]' .format (opt_arg)
|
||||||
|
l += len(opt_arg) + 6
|
||||||
else:
|
else:
|
||||||
if use_colours:
|
if use_colours:
|
||||||
line += ' \033[2m%s\033[22m ' % (opt_alt)
|
line += ' \[[2m{}\[[22m ' .format (opt_alt)
|
||||||
else:
|
else:
|
||||||
line += ' %s ' % (opt_alt)
|
line += ' {} ' .format (opt_alt)
|
||||||
l += len(opt_alt) + 6
|
l += len(opt_alt) + 6
|
||||||
lines.append(line)
|
lines.append(line)
|
||||||
lens.append(l)
|
lens.append(l)
|
||||||
|
|
||||||
col = max(lens)
|
let col = max(lens)
|
||||||
col += 8 - ((col - 4) & 7)
|
col += 8 - ((col - 4) & 7)
|
||||||
index = 0
|
let index = 0
|
||||||
for opt in self.__arguments:
|
for opt in self.__arguments:
|
||||||
opt_help = opt[3]
|
let opt_help = opt[3]
|
||||||
if opt_help is None:
|
if opt_help is None:
|
||||||
continue
|
continue
|
||||||
first = True
|
first = True
|
||||||
colour = ('36' if (index & 1) == 0 else '34') if use_colours else ''
|
let colour = ('36' if (index & 1) == 0 else '34') if use_colours else ''
|
||||||
print(lines[index].replace('%colour%', ('\033[%s;1m' % colour) if use_colours else ''), end=' ' * (col - lens[index]))
|
print(lines[index].replace('%colour%', ('\[[{};1m' .format (colour)) if use_colours else ''), end=' ' * (col - lens[index]))
|
||||||
for line in opt_help.split('\n'):
|
for line in opt_help.split('\n'):
|
||||||
if first:
|
if first:
|
||||||
first = False
|
first = False
|
||||||
print('%s' % (line), end='\033[21;39m\n' if use_colours else '\n')
|
print(line, end='\[[22;39m\n' if use_colours else '\n')
|
||||||
else:
|
else:
|
||||||
print(('%s\033[%sm%s\033[39m' if use_colours else '%s%s%s') % (' ' * col, colour, line))
|
print(('{}\[[{}m{}\[[39m' if use_colours else '{}{}{}').format (' ' * col, colour, line))
|
||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
print()
|
print()
|
|
@ -29,14 +29,14 @@ that line ‘FREE: yes’, is included inside the image between two ‘$$$’
|
||||||
lines and the ‘FREE’ is and upper case and directly followed by
|
lines and the ‘FREE’ is and upper case and directly followed by
|
||||||
the colon.
|
the colon.
|
||||||
'''
|
'''
|
||||||
from common import *
|
from ponysay.common import printerr, printinfo, gettermsize, endswith
|
||||||
from balloon import *
|
from ponysay.balloon import Balloon
|
||||||
from colourstack import *
|
from ponysay.colourstack import ColourStack
|
||||||
from ucs import *
|
from ponysay.ucs import UCS
|
||||||
|
|
||||||
import unicodedata
|
|
||||||
|
|
||||||
|
|
||||||
|
from wcwidth import wcwidth
|
||||||
|
import fileio
|
||||||
|
import os
|
||||||
|
|
||||||
class Backend():
|
class Backend():
|
||||||
'''
|
'''
|
||||||
|
@ -89,6 +89,7 @@ class Backend():
|
||||||
|
|
||||||
if self.pony.startswith('$$$\n'):
|
if self.pony.startswith('$$$\n'):
|
||||||
self.pony = self.pony[4:]
|
self.pony = self.pony[4:]
|
||||||
|
let infoend, info
|
||||||
if self.pony.startswith('$$$\n'):
|
if self.pony.startswith('$$$\n'):
|
||||||
infoend = 4
|
infoend = 4
|
||||||
info = ''
|
info = ''
|
||||||
|
@ -104,21 +105,21 @@ class Backend():
|
||||||
else:
|
else:
|
||||||
info = info.split('\n')
|
info = info.split('\n')
|
||||||
for line in info:
|
for line in info:
|
||||||
sep = line.find(':')
|
let sep = line.find(':')
|
||||||
if sep > 0:
|
if sep > 0:
|
||||||
key = line[:sep].strip()
|
let key = line[:sep].strip()
|
||||||
if key == 'BALLOON TOP':
|
if key == 'BALLOON TOP':
|
||||||
value = line[sep + 1:].strip()
|
let value = line[sep + 1:].strip()
|
||||||
if len(value) > 0:
|
if len(value) > 0:
|
||||||
self.balloontop = int(value)
|
self.balloontop = int(value)
|
||||||
if key == 'BALLOON BOTTOM':
|
if key == 'BALLOON BOTTOM':
|
||||||
value = line[sep + 1:].strip()
|
let value = line[sep + 1:].strip()
|
||||||
if len(value) > 0:
|
if len(value) > 0:
|
||||||
self.balloonbottom = int(value)
|
self.balloonbottom = int(value)
|
||||||
printinfo(info)
|
printinfo(info)
|
||||||
self.pony = self.pony[infoend:]
|
self.pony = self.pony[infoend:]
|
||||||
elif self.infolevel == 2:
|
elif self.infolevel == 2:
|
||||||
self.message = '\033[01;31mI am the mysterious mare...\033[21;39m'
|
self.message = '\033[01;31mI am the mysterious mare...\033[22;39m'
|
||||||
elif self.infolevel == 1:
|
elif self.infolevel == 1:
|
||||||
self.pony = 'There is not metadata for this pony file'
|
self.pony = 'There is not metadata for this pony file'
|
||||||
self.pony = self.mode + self.pony
|
self.pony = self.mode + self.pony
|
||||||
|
@ -149,7 +150,7 @@ class Backend():
|
||||||
test = test.replace(c, '')
|
test = test.replace(c, '')
|
||||||
if (len(test) == 0) and (len(key.replace(' ', '')) > 0):
|
if (len(test) == 0) and (len(key.replace(' ', '')) > 0):
|
||||||
value = line[sep + 1:].strip()
|
value = line[sep + 1:].strip()
|
||||||
line = '\033[1m%s\033[21m: %s\n' % (key.strip(), value)
|
line = '\033[1m{}\033[22m: {}\n' .format (key.strip(), value)
|
||||||
tags += line
|
tags += line
|
||||||
continue
|
continue
|
||||||
comment += '\n' + line
|
comment += '\n' + line
|
||||||
|
@ -163,16 +164,16 @@ class Backend():
|
||||||
'''
|
'''
|
||||||
Remove padding spaces fortune cookies are padded with whitespace (damn featherbrains)
|
Remove padding spaces fortune cookies are padded with whitespace (damn featherbrains)
|
||||||
'''
|
'''
|
||||||
lines = self.message.split('\n')
|
let lines = self.message.split('\n')
|
||||||
for spaces in (128, 64, 32, 16, 8, 4, 2, 1):
|
for spaces in (128, 64, 32, 16, 8, 4, 2, 1):
|
||||||
padded = True
|
let padded = True
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if not line.startswith(' ' * spaces):
|
if not line.startswith(' ' * spaces):
|
||||||
padded = False
|
padded = False
|
||||||
break
|
break
|
||||||
if padded:
|
if padded:
|
||||||
for i in range(0, len(lines)):
|
for i in range(0, len(lines)):
|
||||||
line = lines[i]
|
let line = lines[i]
|
||||||
line = line[spaces:]
|
line = line[spaces:]
|
||||||
lines[i] = line
|
lines[i] = line
|
||||||
lines = [line.rstrip(' ') for line in lines]
|
lines = [line.rstrip(' ') for line in lines]
|
||||||
|
@ -183,19 +184,19 @@ class Backend():
|
||||||
'''
|
'''
|
||||||
Converts all tabs in the message to spaces by expanding
|
Converts all tabs in the message to spaces by expanding
|
||||||
'''
|
'''
|
||||||
lines = self.message.split('\n')
|
let lines = self.message.split('\n')
|
||||||
buf = ''
|
let buf = ''
|
||||||
for line in lines:
|
for line in lines:
|
||||||
(i, n, x) = (0, len(line), 0)
|
let i, n, x = (0, len(line), 0)
|
||||||
while i < n:
|
while i < n:
|
||||||
c = line[i]
|
let c = line[i]
|
||||||
i += 1
|
i += 1
|
||||||
if c == '\033':
|
if c == '\033':
|
||||||
colour = Backend.getColour(line, i - 1)
|
let colour = Backend.getColour(line, i - 1)
|
||||||
i += len(colour) - 1
|
i += len(colour) - 1
|
||||||
buf += colour
|
buf += colour
|
||||||
elif c == '\t':
|
elif c == '\t':
|
||||||
nx = 8 - (x & 7)
|
let nx = 8 - (x & 7)
|
||||||
buf += ' ' * nx
|
buf += ' ' * nx
|
||||||
x += nx
|
x += nx
|
||||||
else:
|
else:
|
||||||
|
@ -210,8 +211,8 @@ class Backend():
|
||||||
'''
|
'''
|
||||||
Loads the pony file
|
Loads the pony file
|
||||||
'''
|
'''
|
||||||
with open(self.ponyfile, 'rb') as ponystream:
|
with fileio.open(self.ponyfile, 'rb') as ponystream:
|
||||||
self.pony = ponystream.read().decode('utf8', 'replace')
|
self.pony = ponystream.read().decode()
|
||||||
|
|
||||||
|
|
||||||
def __truncate(self):
|
def __truncate(self):
|
||||||
|
@ -220,15 +221,15 @@ class Backend():
|
||||||
'''
|
'''
|
||||||
if self.width is None:
|
if self.width is None:
|
||||||
return
|
return
|
||||||
lines = self.output.split('\n')
|
let lines = self.output.split('\n')
|
||||||
self.output = ''
|
self.output = ''
|
||||||
for line in lines:
|
for line in lines:
|
||||||
(i, n, x) = (0, len(line), 0)
|
let i, n, x = (0, len(line), 0)
|
||||||
while i < n:
|
while i < n:
|
||||||
c = line[i]
|
let c = line[i]
|
||||||
i += 1
|
i += 1
|
||||||
if c == '\033':
|
if c == '\033':
|
||||||
colour = Backend.getColour(line, i - 1)
|
let colour = Backend.getColour(line, i - 1)
|
||||||
i += len(colour) - 1
|
i += len(colour) - 1
|
||||||
self.output += colour
|
self.output += colour
|
||||||
else:
|
else:
|
||||||
|
@ -246,35 +247,36 @@ class Backend():
|
||||||
'''
|
'''
|
||||||
self.output = ''
|
self.output = ''
|
||||||
|
|
||||||
AUTO_PUSH = '\033[01010~'
|
let AUTO_PUSH = '\033[01010~'
|
||||||
AUTO_POP = '\033[10101~'
|
let AUTO_POP = '\033[10101~'
|
||||||
|
|
||||||
variables = {'' : '$'}
|
let variables = {'' : '$'}
|
||||||
for key in self.link:
|
for key in self.link:
|
||||||
variables[key] = AUTO_PUSH + self.link[key] + AUTO_POP
|
variables[key] = AUTO_PUSH + self.link[key] + AUTO_POP
|
||||||
|
|
||||||
indent = 0
|
let indent = 0
|
||||||
dollar = None
|
let dollar = None
|
||||||
balloonLines = None
|
let balloonLines = None
|
||||||
colourstack = ColourStack(AUTO_PUSH, AUTO_POP)
|
let balloonLine, balloonIndent
|
||||||
|
let colourstack = ColourStack(AUTO_PUSH, AUTO_POP)
|
||||||
|
|
||||||
(i, n, lineindex, skip, nonskip) = (0, len(self.pony), 0, 0, 0)
|
let i, n, lineindex, skip, nonskip = (0, len(self.pony), 0, 0, 0)
|
||||||
while i < n:
|
while i < n:
|
||||||
c = self.pony[i]
|
let c = self.pony[i]
|
||||||
if c == '\t':
|
if c == '\t':
|
||||||
n += 7 - (indent & 7)
|
n += 7 - (indent & 7)
|
||||||
ed = ' ' * (8 - (indent & 7))
|
let ed = ' ' * (8 - (indent & 7))
|
||||||
c = ' '
|
c = ' '
|
||||||
self.pony = self.pony[:i] + ed + self.pony[i + 1:]
|
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:
|
||||||
if '=' in dollar:
|
if '=' in dollar:
|
||||||
name = dollar[:dollar.find('=')]
|
let name = dollar[:dollar.find('=')]
|
||||||
value = dollar[dollar.find('=') + 1:]
|
let value = dollar[dollar.find('=') + 1:]
|
||||||
variables[name] = value
|
variables[name] = value
|
||||||
elif not dollar.startswith('balloon'):
|
elif not dollar.startswith('balloon'):
|
||||||
data = variables[dollar].replace('$', '$$')
|
let data = variables[dollar].replace('$', '$$')
|
||||||
if data == '$$': # if not handled specially we will get an infinity loop
|
if data == '$$': # if not handled specially we will get an infinity loop
|
||||||
if (skip == 0) or (nonskip > 0):
|
if (skip == 0) or (nonskip > 0):
|
||||||
if nonskip > 0:
|
if nonskip > 0:
|
||||||
|
@ -287,8 +289,8 @@ class Backend():
|
||||||
n += len(data)
|
n += len(data)
|
||||||
self.pony = self.pony[:i] + data + self.pony[i:]
|
self.pony = self.pony[:i] + data + self.pony[i:]
|
||||||
elif self.balloon is not None:
|
elif self.balloon is not None:
|
||||||
(w, h, x, justify) = ('0', 0, 0, None)
|
let w, h, x, justify = ('0', 0, 0, None)
|
||||||
props = dollar[7:]
|
let props = dollar[7:]
|
||||||
if len(props) > 0:
|
if len(props) > 0:
|
||||||
if ',' in props:
|
if ',' in props:
|
||||||
if props[0] != ',':
|
if props[0] != ',':
|
||||||
|
@ -299,28 +301,28 @@ class Backend():
|
||||||
if 'l' in w:
|
if 'l' in w:
|
||||||
(x, w) = (int(w[:w.find('l')]), int(w[w.find('l') + 1:]))
|
(x, w) = (int(w[:w.find('l')]), int(w[w.find('l') + 1:]))
|
||||||
justify = 'l'
|
justify = 'l'
|
||||||
w -= x;
|
w -= x
|
||||||
elif 'c' in w:
|
elif 'c' in w:
|
||||||
(x, w) = (int(w[:w.find('c')]), int(w[w.find('c') + 1:]))
|
(x, w) = (int(w[:w.find('c')]), int(w[w.find('c') + 1:]))
|
||||||
justify = 'c'
|
justify = 'c'
|
||||||
w -= x;
|
w -= x
|
||||||
elif 'r' in w:
|
elif 'r' in w:
|
||||||
(x, w) = (int(w[:w.find('r')]), int(w[w.find('r') + 1:]))
|
(x, w) = (int(w[:w.find('r')]), int(w[w.find('r') + 1:]))
|
||||||
justify = 'r'
|
justify = 'r'
|
||||||
w -= x;
|
w -= x
|
||||||
else:
|
else:
|
||||||
w = int(w)
|
w = int(w)
|
||||||
balloon = self.__getBalloon(w, h, x, justify, indent)
|
let balloon = self.__getBalloon(w, h, x, justify, indent)
|
||||||
balloon = balloon.split('\n')
|
balloon = balloon.split('\n')
|
||||||
balloon = [AUTO_PUSH + self.ballooncolour + item + AUTO_POP for item in balloon]
|
balloon = [AUTO_PUSH + self.ballooncolour + item + AUTO_POP for item in balloon]
|
||||||
for b in balloon[0]:
|
for b in balloon[0]:
|
||||||
self.output += b + colourstack.feed(b)
|
self.output += b + colourstack.feed(b)
|
||||||
if lineindex == 0:
|
if lineindex == 0:
|
||||||
balloonpre = '\n' + (' ' * indent)
|
let balloonpre = '\n' + (' ' * indent)
|
||||||
for line in balloon[1:]:
|
for line in balloon[1:]:
|
||||||
self.output += balloonpre;
|
self.output += balloonpre
|
||||||
for b in line:
|
for b in line:
|
||||||
self.output += b + colourstack.feed(b);
|
self.output += b + colourstack.feed(b)
|
||||||
indent = 0
|
indent = 0
|
||||||
elif len(balloon) > 1:
|
elif len(balloon) > 1:
|
||||||
balloonLines = balloon
|
balloonLines = balloon
|
||||||
|
@ -337,9 +339,9 @@ class Backend():
|
||||||
i += 1
|
i += 1
|
||||||
dollar += c
|
dollar += c
|
||||||
elif c == '\033':
|
elif c == '\033':
|
||||||
colour = Backend.getColour(self.pony, i - 1)
|
let colour = Backend.getColour(self.pony, i - 1)
|
||||||
for b in colour:
|
for b in colour:
|
||||||
self.output += b + colourstack.feed(b);
|
self.output += b + colourstack.feed(b)
|
||||||
i += len(colour) - 1
|
i += len(colour) - 1
|
||||||
elif c == '\n':
|
elif c == '\n':
|
||||||
self.output += c
|
self.output += c
|
||||||
|
@ -364,7 +366,7 @@ class Backend():
|
||||||
if (skip == 0) or (nonskip > 0):
|
if (skip == 0) or (nonskip > 0):
|
||||||
if nonskip > 0:
|
if nonskip > 0:
|
||||||
nonskip -= 1
|
nonskip -= 1
|
||||||
self.output += c + colourstack.feed(c);
|
self.output += c + colourstack.feed(c)
|
||||||
if not UCS.isCombining(c):
|
if not UCS.isCombining(c):
|
||||||
indent += 1
|
indent += 1
|
||||||
else:
|
else:
|
||||||
|
@ -374,7 +376,7 @@ class Backend():
|
||||||
for line in balloonLines[balloonLine:]:
|
for line in balloonLines[balloonLine:]:
|
||||||
data = ' ' * (balloonIndent - indent) + line + '\n'
|
data = ' ' * (balloonIndent - indent) + line + '\n'
|
||||||
for b in data:
|
for b in data:
|
||||||
self.output += b + colourstack.feed(b);
|
self.output += b + colourstack.feed(b)
|
||||||
indent = 0
|
indent = 0
|
||||||
|
|
||||||
self.output = self.output.replace(AUTO_PUSH, '').replace(AUTO_POP, '')
|
self.output = self.output.replace(AUTO_PUSH, '').replace(AUTO_POP, '')
|
||||||
|
@ -395,11 +397,11 @@ class Backend():
|
||||||
@param offset:int The offset at where to start reading, a escape must begin here
|
@param offset:int The offset at where to start reading, a escape must begin here
|
||||||
@return :str The escape sequence
|
@return :str The escape sequence
|
||||||
'''
|
'''
|
||||||
(i, n) = (offset, len(input))
|
let i, n = (offset, len(input))
|
||||||
rc = input[i]
|
let rc = input[i]
|
||||||
i += 1
|
i += 1
|
||||||
if i == n: return rc
|
if i == n: return rc
|
||||||
c = input[i]
|
let c = input[i]
|
||||||
i += 1
|
i += 1
|
||||||
rc += c
|
rc += c
|
||||||
|
|
||||||
|
@ -450,16 +452,16 @@ class Backend():
|
||||||
@param input:str The input buffer
|
@param input:str The input buffer
|
||||||
@return :int The number of visible characters
|
@return :int The number of visible characters
|
||||||
'''
|
'''
|
||||||
(rc, i, n) = (0, 0, len(input))
|
let rc, i, n = 0, 0, len(input)
|
||||||
while i < n:
|
while i < n:
|
||||||
c = input[i]
|
let c = input[i]
|
||||||
if c == '\033':
|
if c == '\033':
|
||||||
i += len(Backend.getColour(input, i))
|
i += len(Backend.getColour(input, i))
|
||||||
else:
|
else:
|
||||||
i += 1
|
i += 1
|
||||||
if not UCS.isCombining(c):
|
if not UCS.isCombining(c):
|
||||||
rc += 1
|
rc += 1
|
||||||
if unicodedata.east_asian_width(c) in ('F', 'W'):
|
if wcwidth(ord(c)) in ('F', 'W'):
|
||||||
rc += 1
|
rc += 1
|
||||||
return rc
|
return rc
|
||||||
|
|
||||||
|
@ -476,22 +478,22 @@ class Backend():
|
||||||
@param left:int The column where the balloon starts
|
@param left:int The column where the balloon starts
|
||||||
@return :str The balloon the the message as a string
|
@return :str The balloon the the message as a string
|
||||||
'''
|
'''
|
||||||
wrap = None
|
let wrap = None
|
||||||
if self.wrapcolumn is not None:
|
if self.wrapcolumn is not None:
|
||||||
wrap = self.wrapcolumn - left
|
wrap = self.wrapcolumn - left
|
||||||
if wrap < 8:
|
if wrap < 8:
|
||||||
wrap = 8
|
wrap = 8
|
||||||
|
|
||||||
msg = self.message
|
let msg = self.message
|
||||||
if wrap is not None:
|
if wrap is not None:
|
||||||
msg = self.__wrapMessage(msg, wrap)
|
msg = self.__wrapMessage(msg, wrap)
|
||||||
|
|
||||||
msg = msg.replace('\n', '\033[0m%s\n' % (self.ballooncolour)) + '\033[0m' + self.ballooncolour
|
msg = msg.replace('\n', '\033[0m{}\n' .format (self.ballooncolour)) + '\033[0m' + self.ballooncolour
|
||||||
msg = msg.split('\n')
|
msg = msg.split('\n')
|
||||||
|
|
||||||
extraleft = 0
|
let extraleft = 0
|
||||||
if justify is not None:
|
if justify is not None:
|
||||||
msgwidth = self.len(max(msg, key = self.len)) + self.balloon.minwidth
|
let msgwidth = self.len(max(msg, key = self.len)) + self.balloon.minwidth
|
||||||
extraleft = innerleft
|
extraleft = innerleft
|
||||||
if msgwidth > width:
|
if msgwidth > width:
|
||||||
if (justify == 'l') and (wrap is not None):
|
if (justify == 'l') and (wrap is not None):
|
||||||
|
@ -507,7 +509,7 @@ class Backend():
|
||||||
if extraleft + msgwidth > wrap:
|
if extraleft + msgwidth > wrap:
|
||||||
extraleft -= msgwidth - wrap
|
extraleft -= msgwidth - wrap
|
||||||
|
|
||||||
rc = self.balloon.get(width, height, msg, Backend.len);
|
let rc = self.balloon.get(width, height, msg, Backend.len)
|
||||||
if extraleft > 0:
|
if extraleft > 0:
|
||||||
rc = ' ' * extraleft + rc.replace('\n', '\n' + ' ' * extraleft)
|
rc = ' ' * extraleft + rc.replace('\n', '\n' + ' ' * extraleft)
|
||||||
return rc
|
return rc
|
||||||
|
@ -521,39 +523,39 @@ class Backend():
|
||||||
@param wrap:int The width at where to force wrapping
|
@param wrap:int The width at where to force wrapping
|
||||||
@return :str The message wrapped
|
@return :str The message wrapped
|
||||||
'''
|
'''
|
||||||
wraplimit = os.environ['PONYSAY_WRAP_LIMIT'] if 'PONYSAY_WRAP_LIMIT' in os.environ else ''
|
let wraplimit = os.environ['PONYSAY_WRAP_LIMIT'] if 'PONYSAY_WRAP_LIMIT' in os.environ else ''
|
||||||
wraplimit = 8 if len(wraplimit) == 0 else int(wraplimit)
|
wraplimit = 8 if len(wraplimit) == 0 else int(wraplimit)
|
||||||
|
|
||||||
wrapexceed = os.environ['PONYSAY_WRAP_EXCEED'] if 'PONYSAY_WRAP_EXCEED' in os.environ else ''
|
let wrapexceed = os.environ['PONYSAY_WRAP_EXCEED'] if 'PONYSAY_WRAP_EXCEED' in os.environ else ''
|
||||||
wrapexceed = 5 if len(wrapexceed) == 0 else int(wrapexceed)
|
wrapexceed = 5 if len(wrapexceed) == 0 else int(wrapexceed)
|
||||||
|
|
||||||
buf = ''
|
let buf = ''
|
||||||
|
let AUTO_PUSH = '\033[01010~'
|
||||||
|
let AUTO_POP = '\033[10101~'
|
||||||
try:
|
try:
|
||||||
AUTO_PUSH = '\033[01010~'
|
let msg = message.replace('\n', AUTO_PUSH + '\n' + AUTO_POP)
|
||||||
AUTO_POP = '\033[10101~'
|
let cstack = ColourStack(AUTO_PUSH, AUTO_POP)
|
||||||
msg = message.replace('\n', AUTO_PUSH + '\n' + AUTO_POP)
|
|
||||||
cstack = ColourStack(AUTO_PUSH, AUTO_POP)
|
|
||||||
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')
|
let lines = buf.replace(AUTO_PUSH, '').replace(AUTO_POP, '').split('\n')
|
||||||
buf = ''
|
buf = ''
|
||||||
|
|
||||||
for line in lines:
|
for line in lines:
|
||||||
b = [None] * len(line)
|
let b = [None] * len(line)
|
||||||
map = {0 : 0}
|
let map = {0 : 0}
|
||||||
(bi, cols, w) = (0, 0, wrap)
|
let bi, cols, w = (0, 0, wrap)
|
||||||
(indent, indentc) = (-1, 0)
|
let indent, indentc = (-1, 0)
|
||||||
|
|
||||||
(i, n) = (0, len(line))
|
let i, n = (0, len(line))
|
||||||
while i <= n:
|
while i <= n:
|
||||||
d = None
|
let d = None
|
||||||
if i < n:
|
if i < n:
|
||||||
d = line[i]
|
d = line[i]
|
||||||
i += 1
|
i += 1
|
||||||
if d == '\033':
|
if d == '\033':
|
||||||
## Invisible stuff
|
## Invisible stuff
|
||||||
i -= 1
|
i -= 1
|
||||||
colourseq = Backend.getColour(line, i)
|
let colourseq = Backend.getColour(line, i)
|
||||||
b[bi : bi + len(colourseq)] = colourseq
|
b[bi : bi + len(colourseq)] = colourseq
|
||||||
i += len(colourseq)
|
i += len(colourseq)
|
||||||
bi += len(colourseq)
|
bi += len(colourseq)
|
||||||
|
@ -571,18 +573,18 @@ class Backend():
|
||||||
map[cols] = bi
|
map[cols] = bi
|
||||||
else:
|
else:
|
||||||
## Wrap?
|
## Wrap?
|
||||||
mm = 0
|
let mm = 0
|
||||||
bisub = 0
|
let bisub = 0
|
||||||
iwrap = wrap - (0 if indent == 1 else indentc)
|
let iwrap = wrap - (0 if indent == 1 else indentc)
|
||||||
|
|
||||||
while ((w > wraplimit) and (cols > w + wrapexceed)) or (cols > iwrap):
|
while ((w > wraplimit) and (cols > w + wrapexceed)) or (cols > iwrap):
|
||||||
## wrap
|
## wrap
|
||||||
x = w;
|
let x = w
|
||||||
if mm + x not in map: # Too much whitespace?
|
if mm + x not in map: # Too much whitespace?
|
||||||
cols = 0
|
cols = 0
|
||||||
break
|
break
|
||||||
nbsp = b[map[mm + x]] == ' ' # nbsp
|
let nbsp = b[map[mm + x]] == ' ' # nbsp
|
||||||
m = map[mm + x]
|
let m = map[mm + x]
|
||||||
|
|
||||||
if ('' in b[bisub : m]) and not nbsp: # soft hyphen
|
if ('' in b[bisub : m]) and not nbsp: # soft hyphen
|
||||||
hyphen = m - 1
|
hyphen = m - 1
|
||||||
|
@ -597,7 +599,7 @@ class Backend():
|
||||||
|
|
||||||
for bb in b[bisub : m]:
|
for bb in b[bisub : m]:
|
||||||
buf += bb
|
buf += bb
|
||||||
buf += '\n' if nbsp else '\0\n'
|
buf += '\n' if nbsp else 'あ\n'
|
||||||
cols -= x - (0 if nbsp else 1)
|
cols -= x - (0 if nbsp else 1)
|
||||||
bisub = m
|
bisub = m
|
||||||
|
|
||||||
|
@ -635,21 +637,15 @@ class Backend():
|
||||||
w -= indentc
|
w -= indentc
|
||||||
buf += '\n'
|
buf += '\n'
|
||||||
|
|
||||||
rc = '\n'.join(line.rstrip(' ') for line in buf[:-1].split('\n'));
|
let rc = '\n'.join(line.rstrip(' ') for line in buf[:-1].split('\n'))
|
||||||
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('あ', '{}{}{}' .format (AUTO_PUSH, self.hyphen, AUTO_POP))
|
||||||
return rc
|
return rc
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
import traceback
|
let errormessage = str(err)
|
||||||
errormessage = ''.join(traceback.format_exception(type(err), err, None))
|
let rc = '\n'.join(line.rstrip(' ') for line in buf.split('\n'))
|
||||||
rc = '\n'.join(line.rstrip(' ') for line in buf.split('\n'));
|
rc = rc.replace('あ', '{}{}{}' .format (AUTO_PUSH, self.hyphen, AUTO_POP))
|
||||||
rc = rc.replace('\0', '%s%s%s' % (AUTO_PUSH, self.hyphen, AUTO_POP))
|
|
||||||
errormessage += '\n---- WRAPPING BUFFER ----\n\n' + rc
|
errormessage += '\n---- WRAPPING BUFFER ----\n\n' + rc
|
||||||
try:
|
printerr(errormessage, end='')
|
||||||
if os.readlink('/proc/self/fd/2') != os.readlink('/proc/self/fd/1'):
|
return message
|
||||||
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
|
|
||||||
|
|
|
@ -29,10 +29,18 @@ that line ‘FREE: yes’, is included inside the image between two ‘$$$’
|
||||||
lines and the ‘FREE’ is and upper case and directly followed by
|
lines and the ‘FREE’ is and upper case and directly followed by
|
||||||
the colon.
|
the colon.
|
||||||
'''
|
'''
|
||||||
from common import *
|
from ponysay.common import printerr, printinfo, gettermsize, endswith
|
||||||
from ucs import *
|
from ponysay.ucs import UCS
|
||||||
|
|
||||||
|
import fileio
|
||||||
|
|
||||||
|
def fmax(lst,key):
|
||||||
|
if not lst: return None
|
||||||
|
let best = lst[0]
|
||||||
|
for i in lst[1:]:
|
||||||
|
if key(best) < key(i):
|
||||||
|
best = i
|
||||||
|
return best
|
||||||
|
|
||||||
class Balloon():
|
class Balloon():
|
||||||
'''
|
'''
|
||||||
|
@ -73,15 +81,15 @@ class Balloon():
|
||||||
(self.sse, self.s, self.ssw) = (sse, s, ssw)
|
(self.sse, self.s, self.ssw) = (sse, s, ssw)
|
||||||
(self.sww, self.w, self.nww) = (sww, w, nww)
|
(self.sww, self.w, self.nww) = (sww, w, nww)
|
||||||
|
|
||||||
_ne = max(ne, key = UCS.dispLen)
|
let _ne = fmax(ne, key = UCS.dispLen)
|
||||||
_nw = max(nw, key = UCS.dispLen)
|
let _nw = fmax(nw, key = UCS.dispLen)
|
||||||
_se = max(se, key = UCS.dispLen)
|
let _se = fmax(se, key = UCS.dispLen)
|
||||||
_sw = max(sw, key = UCS.dispLen)
|
let _sw = fmax(sw, key = UCS.dispLen)
|
||||||
|
|
||||||
minE = UCS.dispLen(max([_ne, nee, e, see, _se, ee], key = UCS.dispLen))
|
let minE = UCS.dispLen(fmax([_ne, nee, e, see, _se, ee], key = UCS.dispLen))
|
||||||
minW = UCS.dispLen(max([_nw, nww, e, sww, _sw, ww], key = UCS.dispLen))
|
let minW = UCS.dispLen(fmax([_nw, nww, e, sww, _sw, ww], key = UCS.dispLen))
|
||||||
minN = len(max([ne, nne, n, nnw, nw], key = len))
|
let minN = len(fmax([ne, nne, n, nnw, nw], key = len))
|
||||||
minS = len(max([se, sse, s, ssw, sw], key = len))
|
let minS = len(fmax([se, sse, s, ssw, sw], key = len))
|
||||||
|
|
||||||
self.minwidth = minE + minE
|
self.minwidth = minE + minE
|
||||||
self.minheight = minN + minS
|
self.minheight = minN + minS
|
||||||
|
@ -98,26 +106,27 @@ class Balloon():
|
||||||
@return :str The balloon as a formated string
|
@return :str The balloon as a formated string
|
||||||
'''
|
'''
|
||||||
## Get dimension
|
## Get dimension
|
||||||
h = self.minheight + len(lines)
|
let h = self.minheight + len(lines)
|
||||||
w = self.minwidth + lencalc(max(lines, key = lencalc))
|
let w = self.minwidth + lencalc(fmax(lines, key = lencalc))
|
||||||
if w < minw: w = minw
|
if w < minw: w = minw
|
||||||
if h < minh: h = minh
|
if h < minh: h = minh
|
||||||
|
|
||||||
## Create edges
|
## Create edges
|
||||||
|
let ws, es
|
||||||
if len(lines) > 1:
|
if len(lines) > 1:
|
||||||
(ws, es) = ({0 : self.nww, len(lines) - 1 : self.sww}, {0 : self.nee, len(lines) - 1 : self.see})
|
ws, es = ({0 : self.nww, len(lines) - 1 : self.sww}, {0 : self.nee, len(lines) - 1 : self.see})
|
||||||
for j in range(1, len(lines) - 1):
|
for j in range(1, len(lines) - 1):
|
||||||
ws[j] = self.w
|
ws[j] = self.w
|
||||||
es[j] = self.e
|
es[j] = self.e
|
||||||
else:
|
else:
|
||||||
(ws, es) = ({0 : self.ww}, {0 : self.ee})
|
ws, es = ({0 : self.ww}, {0 : self.ee})
|
||||||
|
|
||||||
rc = []
|
let rc = []
|
||||||
|
|
||||||
## Create the upper part of the balloon
|
## Create the upper part of the 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])
|
let outer = UCS.dispLen(self.nw[j]) + UCS.dispLen(self.ne[j])
|
||||||
inner = UCS.dispLen(self.nnw[j]) + UCS.dispLen(self.nne[j])
|
let 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:
|
||||||
|
@ -129,8 +138,8 @@ class Balloon():
|
||||||
|
|
||||||
## Create the lower part of the balloon
|
## Create the lower part of the 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])
|
let outer = UCS.dispLen(self.sw[j]) + UCS.dispLen(self.se[j])
|
||||||
inner = UCS.dispLen(self.ssw[j]) + UCS.dispLen(self.sse[j])
|
let 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:
|
||||||
|
@ -155,24 +164,25 @@ class Balloon():
|
||||||
return Balloon('\\', '/', 'X', '< ', ' >', [' _'], ['_'], ['_'], ['_'], ['_ '], ' \\', ' |', ' /', ['- '], ['-'], ['-'], ['-'], [' -'], '\\ ', '| ', '/ ')
|
return Balloon('\\', '/', 'X', '< ', ' >', [' _'], ['_'], ['_'], ['_'], ['_ '], ' \\', ' |', ' /', ['- '], ['-'], ['-'], ['-'], [' -'], '\\ ', '| ', '/ ')
|
||||||
|
|
||||||
## Initialise map for balloon parts
|
## Initialise map for balloon parts
|
||||||
map = {}
|
let map = {}
|
||||||
for elem in ('\\', '/', 'X', 'ww', 'ee', 'nw', 'nnw', 'n', 'nne', 'ne', 'nee', 'e', 'see', 'se', 'sse', 's', 'ssw', 'sw', 'sww', 'w', 'nww'):
|
for elem in ('\\', '/', 'X', 'ww', 'ee', 'nw', 'nnw', 'n', 'nne', 'ne', 'nee', 'e', 'see', 'se', 'sse', 's', 'ssw', 'sw', 'sww', 'w', 'nww'):
|
||||||
map[elem] = []
|
map[elem] = []
|
||||||
|
|
||||||
## Read all lines in the balloon file
|
## Read all lines in the balloon file
|
||||||
with open(balloonfile, 'rb') as balloonstream:
|
let data
|
||||||
data = balloonstream.read().decode('utf8', 'replace')
|
with fileio.open(balloonfile, 'rb') as balloonstream:
|
||||||
|
data = balloonstream.read().decode()
|
||||||
data = [line.replace('\n', '') for line in data.split('\n')]
|
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
|
let last = None
|
||||||
for line in data:
|
for line in data:
|
||||||
if len(line) > 0:
|
if len(line) > 0:
|
||||||
if line[0] == ':':
|
if line[0] == ':':
|
||||||
map[last].append(line[1:])
|
map[last].append(line[1:])
|
||||||
else:
|
else:
|
||||||
last = line[:line.index(':')]
|
last = line[:line.index(':')]
|
||||||
value = line[len(last) + 1:]
|
let value = line[len(last) + 1:]
|
||||||
map[last].append(value)
|
map[last].append(value)
|
||||||
|
|
||||||
## Return the balloon
|
## Return the balloon
|
|
@ -29,7 +29,7 @@ that line ‘FREE: yes’, is included inside the image between two ‘$$$’
|
||||||
lines and the ‘FREE’ is and upper case and directly followed by
|
lines and the ‘FREE’ is and upper case and directly followed by
|
||||||
the colon.
|
the colon.
|
||||||
'''
|
'''
|
||||||
from common import *
|
from ponysay.common import printerr, printinfo, gettermsize, endswith
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,7 +63,10 @@ class ColourStack():
|
||||||
|
|
||||||
@return :str String that should be inserted into your buffer
|
@return :str String that should be inserted into your buffer
|
||||||
'''
|
'''
|
||||||
self.stack.insert(0, [self.bufproto, None, None, [False] * 9])
|
if self.stack:
|
||||||
|
self.stack.insert(0, [self.bufproto, None, None, [False] * 9])
|
||||||
|
else:
|
||||||
|
self.stack.append([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'
|
||||||
|
@ -75,11 +78,11 @@ class ColourStack():
|
||||||
|
|
||||||
@return :str String that should be inserted into your buffer
|
@return :str String that should be inserted into your buffer
|
||||||
'''
|
'''
|
||||||
old = self.stack.pop(0)
|
let old = self.stack.pop(0)
|
||||||
rc = '\033[0;'
|
let rc = '\033[0;'
|
||||||
if len(self.stack) == 0: # last resort in case something made it pop too mush
|
if len(self.stack) == 0: # last resort in case something made it pop too mush
|
||||||
push()
|
push()
|
||||||
new = self.stack[0]
|
let 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] + ';'
|
||||||
for i in range(0, 9):
|
for i in range(0, 9):
|
||||||
|
@ -101,10 +104,10 @@ class ColourStack():
|
||||||
if (char == '~') or (('a' <= char) and (char <= 'z')) or (('A' <= char) and (char <= 'Z')):
|
if (char == '~') or (('a' <= char) and (char <= 'z')) or (('A' <= char) and (char <= 'Z')):
|
||||||
if (self.seq[0] == '[') and (self.seq[-1] == 'm'):
|
if (self.seq[0] == '[') and (self.seq[-1] == 'm'):
|
||||||
self.seq = self.seq[1:-1].split(';')
|
self.seq = self.seq[1:-1].split(';')
|
||||||
(i, n) = (0, len(self.seq))
|
let i, n = (0, len(self.seq))
|
||||||
while i < n:
|
while i < n:
|
||||||
part = self.seq[i]
|
let part = self.seq[i]
|
||||||
p = 0 if part == '' else int(part)
|
let p = 0 if part == '' else int(part)
|
||||||
i += 1
|
i += 1
|
||||||
if p == 0: self.stack[0][1:] = [None, None, [False] * 9]
|
if p == 0: self.stack[0][1:] = [None, None, [False] * 9]
|
||||||
elif 1 <= p <= 9: self.stack[0][3][p - 1] = True
|
elif 1 <= p <= 9: self.stack[0][3][p - 1] = True
|
||||||
|
@ -116,17 +119,17 @@ class ColourStack():
|
||||||
elif 40 <= p <= 47: self.stack[0][2] = part
|
elif 40 <= p <= 47: self.stack[0][2] = part
|
||||||
elif 100 <= p <= 107: self.stack[0][2] = part
|
elif 100 <= p <= 107: self.stack[0][2] = part
|
||||||
elif p == 38:
|
elif p == 38:
|
||||||
self.stack[0][1] = '%s;%s;%s' % (part, self.seq[i], self.seq[i + 1])
|
self.stack[0][1] = '{};{};{}' .format (part, self.seq[i], self.seq[i + 1])
|
||||||
i += 2
|
i += 2
|
||||||
elif p == 48:
|
elif p == 48:
|
||||||
self.stack[0][2] = '%s;%s;%s' % (part, self.seq[i], self.seq[i + 1])
|
self.stack[0][2] = '{};{};{}' .format (part, self.seq[i], self.seq[i + 1])
|
||||||
i += 2
|
i += 2
|
||||||
self.seq = None
|
self.seq = None
|
||||||
elif char == '\033':
|
elif char == '\033':
|
||||||
self.seq = ''
|
self.seq = ''
|
||||||
buf = self.stack[0][0]
|
let buf = self.stack[0][0]
|
||||||
buf = buf[1:] + char
|
buf = buf[1:] + char
|
||||||
rc = ''
|
let rc = ''
|
||||||
if buf[-self.lenpush:] == self.autopush: rc = self.push()
|
if buf[-self.lenpush:] == self.autopush: rc = self.push()
|
||||||
elif buf[-self.lenpop:] == self.autopop: rc = self.pop()
|
elif buf[-self.lenpop:] == self.autopop: rc = self.pop()
|
||||||
self.stack[0][0] = buf
|
self.stack[0][0] = buf
|
|
@ -30,30 +30,8 @@ lines and the ‘FREE’ is and upper case and directly followed by
|
||||||
the colon.
|
the colon.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
import fileio
|
||||||
import os
|
import os
|
||||||
import shutil
|
|
||||||
import sys
|
|
||||||
import random
|
|
||||||
from subprocess import Popen, PIPE
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
VERSION = 'dev' # this line should not be edited, it is fixed by the build system
|
|
||||||
'''
|
|
||||||
The version of ponysay
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def print(text = '', end = '\n'):
|
|
||||||
'''
|
|
||||||
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)
|
|
||||||
'''
|
|
||||||
sys.stdout.buffer.write((str(text) + end).encode('utf-8'))
|
|
||||||
|
|
||||||
def printerr(text = '', end = '\n'):
|
def printerr(text = '', end = '\n'):
|
||||||
'''
|
'''
|
||||||
|
@ -62,9 +40,8 @@ def printerr(text = '', end = '\n'):
|
||||||
@param text:str The text to print (empty string is default)
|
@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)
|
@param end:str The appendix to the text to print (line breaking is default)
|
||||||
'''
|
'''
|
||||||
sys.stderr.buffer.write((str(text) + end).encode('utf-8'))
|
fileio.stderr.write((str(text) + end))
|
||||||
|
|
||||||
fd3 = None
|
|
||||||
def printinfo(text = '', end = '\n'):
|
def printinfo(text = '', end = '\n'):
|
||||||
'''
|
'''
|
||||||
/proc/self/fd/3 equivalent to print()
|
/proc/self/fd/3 equivalent to print()
|
||||||
|
@ -72,12 +49,8 @@ def printinfo(text = '', end = '\n'):
|
||||||
@param text:str The text to print (empty string is default)
|
@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)
|
@param end:str The appendix to the text to print (line breaking is default)
|
||||||
'''
|
'''
|
||||||
global fd3
|
pass
|
||||||
if os.path.exists('/proc/self/fd/3') and not os.path.isdir(os.path.realpath('/proc/self/fd/3')):
|
#os.write(2, (str(text) + end).encode())
|
||||||
if fd3 is None:
|
|
||||||
fd3 = os.fdopen(3, 'w')
|
|
||||||
if fd3 is not None:
|
|
||||||
fd3.write(str(text) + end)
|
|
||||||
|
|
||||||
|
|
||||||
def endswith(text, ending):
|
def endswith(text, ending):
|
||||||
|
@ -97,12 +70,12 @@ def gettermsize():
|
||||||
|
|
||||||
@return (rows, columns):(int, int) The number or lines and the number of columns in the terminal's display area
|
@return (rows, columns):(int, int) The number or lines and the number of columns in the terminal's display area
|
||||||
'''
|
'''
|
||||||
## Call `stty` to determine the size of the terminal, this way is better than using python's ncurses
|
# TODO we don't have a thing for this??
|
||||||
for channel in (sys.stderr, sys.stdout, sys.stdin):
|
try:
|
||||||
termsize = Popen(['stty', 'size'], stdout=PIPE, stdin=channel, stderr=PIPE).communicate()[0]
|
os.system("stty size > /tmp/.ponysaysize")
|
||||||
if len(termsize) > 0:
|
with fileio.open("/tmp/.ponysaysize") as f:
|
||||||
termsize = termsize.decode('utf8', 'replace')[:-1].split(' ') # [:-1] removes a \n
|
let tmp = f.read().strip()
|
||||||
termsize = [int(item) for item in termsize]
|
return tuple(int(x) for x in tmp.split(' '))
|
||||||
return termsize
|
except:
|
||||||
return (24, 80) # fall back to minimal sane size
|
return (24, 80) # fall back to minimal sane size
|
||||||
|
|
|
@ -29,7 +29,7 @@ that line ‘FREE: yes’, is included inside the image between two ‘$$$’
|
||||||
lines and the ‘FREE’ is and upper case and directly followed by
|
lines and the ‘FREE’ is and upper case and directly followed by
|
||||||
the colon.
|
the colon.
|
||||||
'''
|
'''
|
||||||
from common import *
|
from ponysay.common import *
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,11 +34,17 @@ File listing functions.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
from ucs import *
|
from ponysay.common import endswith, gettermsize
|
||||||
import itertools
|
from ponysay.ucs import UCS
|
||||||
|
import os
|
||||||
|
|
||||||
|
def _range(min,max,step):
|
||||||
|
let i = min
|
||||||
|
while i < max:
|
||||||
|
yield i
|
||||||
|
i += step
|
||||||
|
|
||||||
def _columnise_list(items: list, available_width: int, length_fn: callable, separation : int = 2):
|
def _columnise_list(items: list, available_width: int, length_fn: function, separation : int = 2):
|
||||||
"""
|
"""
|
||||||
From a list of items, produce a list of columns. Each columns is a list of tuples. Each tuple contains the element and a an int, specifying how much shorter the element is compared to the column width.
|
From a list of items, produce a list of columns. Each columns is a list of tuples. Each tuple contains the element and a an int, specifying how much shorter the element is compared to the column width.
|
||||||
|
|
||||||
|
@ -48,18 +54,27 @@ def _columnise_list(items: list, available_width: int, length_fn: callable, sepa
|
||||||
:param separation: Amount of space to insert between columns.
|
:param separation: Amount of space to insert between columns.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
num_items = len(items)
|
let num_items = len(items)
|
||||||
items_with_length = [(i, length_fn(i)) for i in items]
|
let items_with_length = [(i, length_fn(i)) for i in items]
|
||||||
max_item_length = max(i for _, i in items_with_length)
|
let max_item_length = max(i for _, i in items_with_length)
|
||||||
|
|
||||||
# Make at least one column to handle very narrow terminals.
|
# Make at least one column to handle very narrow terminals.
|
||||||
num_columns = max((available_width + separation) // (max_item_length + separation), 1)
|
let num_columns = max((available_width + separation) // (max_item_length + separation), 1)
|
||||||
column_length = (num_items - 1) // num_columns + 1
|
let column_length = (num_items - 1) // num_columns + 1
|
||||||
|
|
||||||
items_with_spacing = [(i, max_item_length - l + separation) for i, l in items_with_length]
|
let items_with_spacing = [(i, max_item_length - l + separation) for i, l in items_with_length]
|
||||||
|
|
||||||
return [items_with_spacing[i:i + column_length] for i in range(0, num_items, column_length)]
|
return [items_with_spacing[i:(i + column_length)] for i in _range(0, num_items, column_length)]
|
||||||
|
|
||||||
|
def _sorted(lst, key):
|
||||||
|
class Sortable():
|
||||||
|
def __init__(self, thing):
|
||||||
|
self.thing = thing
|
||||||
|
def __lt__(self, other):
|
||||||
|
return key(self.thing) < key(other.thing)
|
||||||
|
let out = [Sortable(l) for l in lst]
|
||||||
|
out.sort()
|
||||||
|
return [l.thing for l in out]
|
||||||
|
|
||||||
def _print_columnised(items):
|
def _print_columnised(items):
|
||||||
'''
|
'''
|
||||||
|
@ -68,26 +83,24 @@ def _print_columnised(items):
|
||||||
@param ponies:list<(str, str)> All items to list, each item should have to elements: unformatted name, formatted name.
|
@param ponies:list<(str, str)> All items to list, each item should have to elements: unformatted name, formatted name.
|
||||||
'''
|
'''
|
||||||
## Get terminal width
|
## Get terminal width
|
||||||
_, term_width = gettermsize()
|
let _, term_width = gettermsize()
|
||||||
|
|
||||||
columns = _columnise_list(
|
let columns = _columnise_list(
|
||||||
sorted(items, key = lambda x: x[0]),
|
_sorted(items, key = lambda x: x[0]),
|
||||||
term_width,
|
term_width,
|
||||||
lambda x: UCS.dispLen(x[0]))
|
lambda x: UCS.dispLen(x[0]))
|
||||||
|
|
||||||
for row in itertools.zip_longest(*columns):
|
for row in zip(*columns):
|
||||||
def iter_parts():
|
def iter_parts():
|
||||||
spacing = 0
|
let spacing = 0
|
||||||
|
|
||||||
for cell in row:
|
for cell in row:
|
||||||
if cell:
|
if cell:
|
||||||
# Yield this here to prevent whitespace to be printed after the last column.
|
# Yield this here to prevent whitespace to be printed after the last column.
|
||||||
yield ' ' * spacing
|
yield ' ' * spacing
|
||||||
|
let item, _, inner
|
||||||
(_, item), spacing = cell
|
inner, spacing = cell
|
||||||
|
_, item = inner
|
||||||
yield item
|
yield item
|
||||||
|
|
||||||
print(''.join(iter_parts()))
|
print(''.join(iter_parts()))
|
||||||
|
|
||||||
print()
|
print()
|
||||||
|
@ -114,7 +127,7 @@ def simplelist(ponydirs, quoters = [], ucsiser = None):
|
||||||
'''
|
'''
|
||||||
for ponydir in ponydirs: # Loop ponydirs
|
for ponydir in ponydirs: # Loop ponydirs
|
||||||
## Get all ponies in the directory
|
## Get all ponies in the directory
|
||||||
ponies = _get_file_list(ponydir, '.pony')
|
let ponies = _get_file_list(ponydir, '.pony')
|
||||||
|
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
@ -125,8 +138,8 @@ def simplelist(ponydirs, quoters = [], ucsiser = None):
|
||||||
## If ther directory is not empty print its name and all ponies, columnised
|
## If ther directory is not empty print its name and all ponies, columnised
|
||||||
if len(ponies) == 0:
|
if len(ponies) == 0:
|
||||||
continue
|
continue
|
||||||
print('\033[1mponies located in ' + ponydir + '\033[21m')
|
print('\033[1mponies located in ' + ponydir + '\033[22m')
|
||||||
_print_columnised([(pony, '\033[1m' + pony + '\033[21m' if pony in quoters else pony) for pony in ponies])
|
_print_columnised([(pony, '\033[1m' + pony + '\033[22m' if pony in quoters else pony) for pony in ponies])
|
||||||
|
|
||||||
|
|
||||||
def linklist(ponydirs = None, quoters = [], ucsiser = None):
|
def linklist(ponydirs = None, quoters = [], ucsiser = None):
|
||||||
|
@ -145,7 +158,7 @@ def linklist(ponydirs = None, quoters = [], ucsiser = None):
|
||||||
## If there are no ponies in the directory skip to next directory, otherwise, print the directories name
|
## If there are no ponies in the directory skip to next directory, otherwise, print the directories name
|
||||||
if len(ponies) == 0:
|
if len(ponies) == 0:
|
||||||
continue
|
continue
|
||||||
print('\033[1mponies located in ' + ponydir + '\033[21m')
|
print('\033[1mponies located in ' + ponydir + '\033[22m')
|
||||||
|
|
||||||
## UCS:ise pony names
|
## UCS:ise pony names
|
||||||
pseudolinkmap = {}
|
pseudolinkmap = {}
|
||||||
|
@ -156,7 +169,7 @@ def linklist(ponydirs = None, quoters = [], ucsiser = None):
|
||||||
pairs = []
|
pairs = []
|
||||||
for pony in ponies:
|
for pony in ponies:
|
||||||
if pony in pseudolinkmap:
|
if pony in pseudolinkmap:
|
||||||
pairs.append((pony, pseudolinkmap[pony] + '.pony'));
|
pairs.append((pony, pseudolinkmap[pony] + '.pony'))
|
||||||
else:
|
else:
|
||||||
pairs.append((pony, os.path.realpath(ponydir + pony + '.pony') if os.path.islink(ponydir + pony + '.pony') else None))
|
pairs.append((pony, os.path.realpath(ponydir + pony + '.pony') if os.path.islink(ponydir + pony + '.pony') else None))
|
||||||
|
|
||||||
|
@ -179,7 +192,7 @@ def linklist(ponydirs = None, quoters = [], ucsiser = None):
|
||||||
ponies = {}
|
ponies = {}
|
||||||
for pony in ponymap:
|
for pony in ponymap:
|
||||||
w = UCS.dispLen(pony)
|
w = UCS.dispLen(pony)
|
||||||
item = '\033[1m' + pony + '\033[21m' if (pony in quoters) else pony
|
item = '\033[1m' + pony + '\033[22m' if (pony in quoters) else pony
|
||||||
syms = ponymap[pony]
|
syms = ponymap[pony]
|
||||||
syms.sort()
|
syms.sort()
|
||||||
if len(syms) > 0:
|
if len(syms) > 0:
|
||||||
|
@ -190,9 +203,9 @@ def linklist(ponydirs = None, quoters = [], ucsiser = None):
|
||||||
w += UCS.dispLen(sym)
|
w += UCS.dispLen(sym)
|
||||||
if first: first = False
|
if first: first = False
|
||||||
else: item += ' '
|
else: item += ' '
|
||||||
item += '\033[1m' + sym + '\033[21m' if (sym in quoters) else sym
|
item += '\033[1m' + sym + '\033[22m' if (sym in quoters) else sym
|
||||||
item += ')'
|
item += ')'
|
||||||
ponies[(item.replace('\033[1m', '').replace('\033[21m', ''), item)] = w
|
ponies[(item.replace('\033[1m', '').replace('\033[22m', ''), item)] = w
|
||||||
|
|
||||||
## Print the ponies, columnised
|
## Print the ponies, columnised
|
||||||
_print_columnised(list(ponies))
|
_print_columnised(list(ponies))
|
||||||
|
@ -206,14 +219,14 @@ def onelist(pony_dirs, ucsiser):
|
||||||
@param ucsiser:(list<str>)→void Function used to UCS:ise names
|
@param ucsiser:(list<str>)→void Function used to UCS:ise names
|
||||||
'''
|
'''
|
||||||
## Get all pony files
|
## Get all pony files
|
||||||
ponies = [name for dir in pony_dirs for name in _get_file_list(dir, '.pony')]
|
let ponies = [name for dir in pony_dirs for name in _get_file_list(dir, '.pony')]
|
||||||
|
|
||||||
## UCS:ise and sort
|
## UCS:ise and sort
|
||||||
ucsiser(ponies)
|
ucsiser(ponies)
|
||||||
ponies.sort()
|
ponies.sort()
|
||||||
|
|
||||||
## Print each one on a seperate line, but skip duplicates
|
## Print each one on a seperate line, but skip duplicates
|
||||||
last = ''
|
let last = ''
|
||||||
for pony in ponies:
|
for pony in ponies:
|
||||||
if not pony == last:
|
if not pony == last:
|
||||||
last = pony
|
last = pony
|
|
@ -29,7 +29,7 @@ that line ‘FREE: yes’, is included inside the image between two ‘$$$’
|
||||||
lines and the ‘FREE’ is and upper case and directly followed by
|
lines and the ‘FREE’ is and upper case and directly followed by
|
||||||
the colon.
|
the colon.
|
||||||
'''
|
'''
|
||||||
from common import *
|
from ponysay.common import printerr, printinfo, gettermsize, endswith
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,16 +29,72 @@ that line ‘FREE: yes’, is included inside the image between two ‘$$$’
|
||||||
lines and the ‘FREE’ is and upper case and directly followed by
|
lines and the ‘FREE’ is and upper case and directly followed by
|
||||||
the colon.
|
the colon.
|
||||||
'''
|
'''
|
||||||
from common import *
|
from ponysay.common import printerr, printinfo, gettermsize, endswith
|
||||||
from backend import *
|
from ponysay.backend import Backend
|
||||||
from balloon import *
|
from ponysay.balloon import Balloon
|
||||||
from spellocorrecter import *
|
from ponysay.spellocorrecter import SpelloCorrecter
|
||||||
from ucs import *
|
from ponysay.ucs import UCS
|
||||||
from kms import *
|
import ponysay.lists as lists
|
||||||
import lists
|
from ponysay.metadata import Metadata
|
||||||
from metadata import *
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
import kuroko
|
||||||
|
import fileio
|
||||||
|
import stat
|
||||||
|
|
||||||
|
import random
|
||||||
|
|
||||||
|
def randrange(low,high):
|
||||||
|
with fileio.open('/dev/urandom','rb') as f:
|
||||||
|
let b = f.read(4)
|
||||||
|
let val = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]
|
||||||
|
let flt = val / 0xFFFFFFFF
|
||||||
|
return int(flt*(high-low)+low)
|
||||||
|
|
||||||
|
def rfind(self, sub):
|
||||||
|
let last = self.find(sub)
|
||||||
|
while True:
|
||||||
|
let next = self.find(sub,last+1)
|
||||||
|
if next == -1: break
|
||||||
|
last = next
|
||||||
|
return last
|
||||||
|
|
||||||
|
str.rfind = rfind
|
||||||
|
|
||||||
|
random.randrange = randrange
|
||||||
|
|
||||||
|
class OSExtensions():
|
||||||
|
def exists(self, p):
|
||||||
|
try:
|
||||||
|
os.stat(p)
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
def isdir(self, p):
|
||||||
|
try:
|
||||||
|
let res = os.stat(p)
|
||||||
|
return stat.S_ISDIR(res.st_mode)
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
def isfile(self, p):
|
||||||
|
try:
|
||||||
|
let res = os.stat(p)
|
||||||
|
return stat.S_ISREG(res.st_mode)
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
def islink(self, p):
|
||||||
|
try:
|
||||||
|
let res = os.stat(p)
|
||||||
|
return stat.S_ISLNK(res.st_mode)
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
os.path = OSExtensions()
|
||||||
|
let exit = os.exit
|
||||||
|
|
||||||
|
def listdir(p):
|
||||||
|
return [c['name'] for c in fileio.opendir(p)]
|
||||||
|
os.listdir = listdir
|
||||||
|
|
||||||
class Ponysay():
|
class Ponysay():
|
||||||
'''
|
'''
|
||||||
|
@ -55,7 +111,6 @@ class Ponysay():
|
||||||
if len(self.HOME) == 0:
|
if len(self.HOME) == 0:
|
||||||
os.environ['HOME'] = self.HOME = os.path.expanduser('~')
|
os.environ['HOME'] = self.HOME = os.path.expanduser('~')
|
||||||
|
|
||||||
|
|
||||||
## Load extension and configurations via ponysayrc
|
## Load extension and configurations via ponysayrc
|
||||||
for file in ('$XDG_CONFIG_HOME/ponysay/ponysayrc', '$HOME/.config/ponysay/ponysayrc', '$HOME/.ponysayrc', '/etc/ponysayrc'):
|
for file in ('$XDG_CONFIG_HOME/ponysay/ponysayrc', '$HOME/.config/ponysay/ponysayrc', '$HOME/.ponysayrc', '/etc/ponysayrc'):
|
||||||
file = self.__parseFile(file)
|
file = self.__parseFile(file)
|
||||||
|
@ -84,17 +139,17 @@ class Ponysay():
|
||||||
|
|
||||||
|
|
||||||
# Whether stdin is piped
|
# Whether stdin is piped
|
||||||
self.pipelinein = not sys.stdin.isatty()
|
self.pipelinein = not os.isatty(0) #sys.stdin.isatty()
|
||||||
|
|
||||||
# Whether stdout is piped
|
# Whether stdout is piped
|
||||||
self.pipelineout = not sys.stdout.isatty()
|
self.pipelineout = not os.isatty(1) #sys.stdout.isatty()
|
||||||
|
|
||||||
# Whether stderr is piped
|
# Whether stderr is piped
|
||||||
self.pipelineerr = not sys.stderr.isatty()
|
self.pipelineerr = not os.isatty(2) #sys.stderr.isatty()
|
||||||
|
|
||||||
|
|
||||||
# Whether KMS is used
|
# Whether KMS is used
|
||||||
self.usekms = KMS.usingKMS(self.linuxvt)
|
self.usekms = False #KMS.usingKMS(self.linuxvt)
|
||||||
|
|
||||||
|
|
||||||
# Mode string that modifies or adds $ variables in the pony image
|
# Mode string that modifies or adds $ variables in the pony image
|
||||||
|
@ -128,9 +183,9 @@ class Ponysay():
|
||||||
@return The target file name, None if the environment variables are not declared
|
@return The target file name, None if the environment variables are not declared
|
||||||
'''
|
'''
|
||||||
if '$' in file:
|
if '$' in file:
|
||||||
buf = ''
|
let buf = ''
|
||||||
esc = False
|
let esc = False
|
||||||
var = None
|
let var = None
|
||||||
for c in file:
|
for c in file:
|
||||||
if esc:
|
if esc:
|
||||||
buf += c
|
buf += c
|
||||||
|
@ -162,9 +217,9 @@ class Ponysay():
|
||||||
@param directory:str The directory base name
|
@param directory:str The directory base name
|
||||||
@return :list<str> Absolute directory names
|
@return :list<str> Absolute directory names
|
||||||
'''
|
'''
|
||||||
appendset = set()
|
let appendset = set()
|
||||||
rc = []
|
let rc = []
|
||||||
_ponydirs = cls.__share(directory)
|
let _ponydirs = cls.__share(directory)
|
||||||
for ponydir in _ponydirs:
|
for ponydir in _ponydirs:
|
||||||
if (ponydir is not None) and os.path.isdir(ponydir) and (ponydir not in appendset):
|
if (ponydir is not None) and os.path.isdir(ponydir) and (ponydir not in appendset):
|
||||||
rc.append(ponydir)
|
rc.append(ponydir)
|
||||||
|
@ -188,7 +243,8 @@ class Ponysay():
|
||||||
return [cat(cls.__parseFile(item), file) for item in [
|
return [cat(cls.__parseFile(item), file) for item in [
|
||||||
'$XDG_DATA_HOME/ponysay/',
|
'$XDG_DATA_HOME/ponysay/',
|
||||||
'$HOME/.local/share/ponysay/',
|
'$HOME/.local/share/ponysay/',
|
||||||
'/usr/share/ponysay/'
|
'/usr/share/ponysay/',
|
||||||
|
'./'
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
|
||||||
|
@ -197,7 +253,7 @@ class Ponysay():
|
||||||
'''
|
'''
|
||||||
Check if ponythink is executed
|
Check if ponythink is executed
|
||||||
'''
|
'''
|
||||||
isthink = sys.argv[0]
|
let isthink = kuroko.argv[0]
|
||||||
if os.sep in isthink:
|
if os.sep in isthink:
|
||||||
isthink = isthink[isthink.rfind(os.sep) + 1:]
|
isthink = isthink[isthink.rfind(os.sep) + 1:]
|
||||||
if os.extsep in isthink:
|
if os.extsep in isthink:
|
||||||
|
@ -217,7 +273,7 @@ class Ponysay():
|
||||||
args.help()
|
args.help()
|
||||||
exit(254)
|
exit(254)
|
||||||
return
|
return
|
||||||
self.args = args;
|
self.args = args
|
||||||
|
|
||||||
## Emulate termial capabilities
|
## Emulate termial capabilities
|
||||||
if self.__test_nfdnf('-X'): (self.linuxvt, self.usekms) = (False, False)
|
if self.__test_nfdnf('-X'): (self.linuxvt, self.usekms) = (False, False)
|
||||||
|
@ -229,8 +285,8 @@ class Ponysay():
|
||||||
## Variadic variants of -f, -q &c
|
## Variadic variants of -f, -q &c
|
||||||
for sign in ('-', '+'):
|
for sign in ('-', '+'):
|
||||||
for letter in ('f', 'F', 'q', 'Q'):
|
for letter in ('f', 'F', 'q', 'Q'):
|
||||||
ssl = sign + sign + letter
|
let ssl = sign + sign + letter
|
||||||
sl = sign + letter
|
let sl = sign + letter
|
||||||
if (ssl in args.opts) and (args.opts[ssl] is not None):
|
if (ssl in args.opts) and (args.opts[ssl] is not None):
|
||||||
if args.opts[sl] is not None: args.opts[sl] += args.opts[ssl]
|
if args.opts[sl] is not None: args.opts[sl] += args.opts[ssl]
|
||||||
else: args.opts[sl] = args.opts[ssl]
|
else: args.opts[sl] = args.opts[ssl]
|
||||||
|
@ -343,11 +399,11 @@ class Ponysay():
|
||||||
if args.opts[key] is not None:
|
if args.opts[key] is not None:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
keys = ['-f', '+f', '-F', '-q'] ## TODO +q -Q
|
let keys = ['-f', '+f', '-F', '-q'] ## TODO +q -Q
|
||||||
if test(keys, False):
|
if test(keys, False):
|
||||||
for ponydir in self.ponydirs:
|
for ponydir in self.ponydirs:
|
||||||
if os.path.isfile(ponydir + 'best.pony') or os.path.islink(ponydir + 'best.pony'):
|
if os.path.isfile(ponydir + 'best.pony') or os.path.islink(ponydir + 'best.pony'):
|
||||||
pony = os.path.realpath(ponydir + 'best.pony') # Canonical path
|
let pony = os.path.realpath(ponydir + 'best.pony') # Canonical path
|
||||||
if test(keys, True):
|
if test(keys, True):
|
||||||
args.opts['-f'] = [pony]
|
args.opts['-f'] = [pony]
|
||||||
else:
|
else:
|
||||||
|
@ -364,8 +420,8 @@ class Ponysay():
|
||||||
@param args:ArgParser Parsed command line arguments
|
@param args:ArgParser Parsed command line arguments
|
||||||
'''
|
'''
|
||||||
## Read UCS configurations
|
## Read UCS configurations
|
||||||
env_ucs = os.environ['PONYSAY_UCS_ME'] if 'PONYSAY_UCS_ME' in os.environ else ''
|
let env_ucs = os.environ['PONYSAY_UCS_ME'] if 'PONYSAY_UCS_ME' in os.environ else ''
|
||||||
ucs_conf = 0
|
let ucs_conf = 0
|
||||||
if env_ucs in ('yes', 'y', '1'): ucs_conf = 1
|
if env_ucs in ('yes', 'y', '1'): ucs_conf = 1
|
||||||
elif env_ucs in ('harder', 'h', '2'): ucs_conf = 2
|
elif env_ucs in ('harder', 'h', '2'): ucs_conf = 2
|
||||||
|
|
||||||
|
@ -410,8 +466,8 @@ class Ponysay():
|
||||||
@param links:map<str, str>? Map to fill with simulated symlink ponies, may be `None`
|
@param links:map<str, str>? Map to fill with simulated symlink ponies, may be `None`
|
||||||
'''
|
'''
|
||||||
## Read UCS configurations
|
## Read UCS configurations
|
||||||
env_ucs = os.environ['PONYSAY_UCS_ME'] if 'PONYSAY_UCS_ME' in os.environ else ''
|
let env_ucs = os.environ['PONYSAY_UCS_ME'] if 'PONYSAY_UCS_ME' in os.environ else ''
|
||||||
ucs_conf = 0
|
let ucs_conf = 0
|
||||||
if env_ucs in ('yes', 'y', '1'): ucs_conf = 1
|
if env_ucs in ('yes', 'y', '1'): ucs_conf = 1
|
||||||
elif env_ucs in ('harder', 'h', '2'): ucs_conf = 2
|
elif env_ucs in ('harder', 'h', '2'): ucs_conf = 2
|
||||||
|
|
||||||
|
@ -420,20 +476,20 @@ class Ponysay():
|
||||||
return
|
return
|
||||||
|
|
||||||
## Read all lines in all UCS → ASCII map files
|
## Read all lines in all UCS → ASCII map files
|
||||||
maplines = []
|
let maplines = []
|
||||||
for ucsmap in self.ucsmaps:
|
for ucsmap in self.ucsmaps:
|
||||||
if os.path.isfile(ucsmap):
|
if os.path.isfile(ucsmap):
|
||||||
with open(ucsmap, 'rb') as mapfile:
|
with open(ucsmap, 'rb') as mapfile:
|
||||||
maplines += [line.replace('\n', '') for line in mapfile.read().decode('utf8', 'replace').split('\n')]
|
maplines += [line.replace('\n', '') for line in mapfile.read().decode('utf8', 'replace').split('\n')]
|
||||||
|
|
||||||
## Create UCS → ASCII mapping from read lines
|
## Create UCS → ASCII mapping from read lines
|
||||||
map = {}
|
let map = {}
|
||||||
stripset = ' \t' # must be string, wtf! and way doesn't python's doc say so
|
let stripset = ' \t' # must be string, wtf! and way doesn't python's doc say so
|
||||||
for line in maplines:
|
for line in maplines:
|
||||||
if not line.startswith('#'):
|
if not line.startswith('#'):
|
||||||
s = line.index('→')
|
let s = line.index('→')
|
||||||
ucs = line[:s] .strip(stripset)
|
let ucs = line[:s] .strip(stripset)
|
||||||
ascii = line[s + 1:].strip(stripset)
|
let ascii = line[s + 1:].strip(stripset)
|
||||||
map[ascii] = ucs
|
map[ascii] = ucs
|
||||||
|
|
||||||
## Apply UCS → ASCII mapping to ponies, by alias if weak settings
|
## Apply UCS → ASCII mapping to ponies, by alias if weak settings
|
||||||
|
@ -466,31 +522,31 @@ class Ponysay():
|
||||||
selection = [self.__selectAnypony(args)]
|
selection = [self.__selectAnypony(args)]
|
||||||
|
|
||||||
## Select a random pony of the choosen ones
|
## Select a random pony of the choosen ones
|
||||||
pony = selection[random.randrange(0, len(selection))]
|
let pony = selection[random.randrange(0, len(selection))]
|
||||||
if os.path.exists(pony[0]):
|
if os.path.exists(pony[0]):
|
||||||
ponyname = pony[0].split(os.sep)[-1]
|
let ponyname = pony[0].split(os.sep)[-1]
|
||||||
if os.extsep in ponyname:
|
if os.extsep in ponyname:
|
||||||
ponyname = ponyname[:ponyname.rfind(os.extsep)]
|
ponyname = ponyname[:ponyname.rfind(os.extsep)]
|
||||||
return (pony[0], self.__getQuote(ponyname, pony[0]) if pony[2] else None)
|
return (pony[0], self.__getQuote(ponyname, pony[0]) if pony[2] else None)
|
||||||
else:
|
else:
|
||||||
possibilities = [f.split(os.sep)[-1][:-5] for f in pony[1]]
|
let possibilities = [f.split(os.sep)[-1][:-5] for f in pony[1]]
|
||||||
if pony[0] not in possibilities:
|
if pony[0] not in possibilities:
|
||||||
if not alt:
|
if not alt:
|
||||||
autocorrect = SpelloCorrecter(possibilities)
|
let autocorrect = SpelloCorrecter(possibilities)
|
||||||
(alternatives, dist) = autocorrect.correct(pony[0])
|
let alternatives, dist = autocorrect.correct(pony[0])
|
||||||
limit = os.environ['PONYSAY_TYPO_LIMIT'] if 'PONYSAY_TYPO_LIMIT' in os.environ else ''
|
let limit = os.environ['PONYSAY_TYPO_LIMIT'] if 'PONYSAY_TYPO_LIMIT' in os.environ else ''
|
||||||
limit = 5 if len(limit) == 0 else int(limit)
|
limit = 5 if len(limit) == 0 else int(limit)
|
||||||
if (len(alternatives) > 0) and (dist <= limit):
|
if (len(alternatives) > 0) and (dist <= limit):
|
||||||
(_, files, quote) = pony
|
let _, files, quote = pony
|
||||||
return self.__getPony([(a, files, quote) for a in alternatives], True)
|
return self.__getPony([(a, files, quote) for a in alternatives], True)
|
||||||
printerr('I have never heard of anypony named %s' % pony[0]);
|
printerr('I have never heard of anypony named %s' % pony[0])
|
||||||
if not self.usingstandard:
|
if not self.usingstandard:
|
||||||
printerr('Use -f/-q or -F if it a MLP:FiM pony');
|
printerr('Use -f/-q or -F if it a MLP:FiM pony')
|
||||||
if not self.usingextra:
|
if not self.usingextra:
|
||||||
printerr('Have you tested +f or -F?');
|
printerr('Have you tested +f or -F?')
|
||||||
exit(252)
|
exit(252)
|
||||||
else:
|
else:
|
||||||
file = pony[1][possibilities.index(pony[0])]
|
let file = pony[1][possibilities.index(pony[0])]
|
||||||
return (file, self.__getQuote(pony[0], file) if pony[2] else None)
|
return (file, self.__getQuote(pony[0], file) if pony[2] else None)
|
||||||
|
|
||||||
|
|
||||||
|
@ -501,30 +557,30 @@ class Ponysay():
|
||||||
@param args:ArgParser Parsed command line arguments
|
@param args:ArgParser Parsed command line arguments
|
||||||
@return (name, dirfile, quote):(str, list<str>, bool) The pony name, pony file with the directory, and whether to use ponyquotes
|
@return (name, dirfile, quote):(str, list<str>, bool) The pony name, pony file with the directory, and whether to use ponyquotes
|
||||||
'''
|
'''
|
||||||
quote = args.opts['-q'] is not None ## TODO +q -Q
|
let quote = args.opts['-q'] is not None ## TODO +q -Q
|
||||||
standard = (args.opts['-f'] is not None) or (args.opts['-F'] is not None) or (args.opts['-q'] is not None) ## TODO -Q
|
let standard = (args.opts['-f'] is not None) or (args.opts['-F'] is not None) or (args.opts['-q'] is not None) ## TODO -Q
|
||||||
extra = (args.opts['+f'] is not None) or (args.opts['-F'] is not None) ## TODO +q -Q
|
let extra = (args.opts['+f'] is not None) or (args.opts['-F'] is not None) ## TODO +q -Q
|
||||||
if not (standard or extra):
|
if not (standard or extra):
|
||||||
standard = True
|
standard = True
|
||||||
ponydirs = (self.ponydirs if standard else []) + (self.extraponydirs if extra else []);
|
let ponydirs = (self.ponydirs if standard else []) + (self.extraponydirs if extra else [])
|
||||||
quoters = self.__quoters() if standard and quote else None ## TODO +q -Q
|
let quoters = self.__quoters() if standard and quote else None ## TODO +q -Q
|
||||||
if (quoters is not None) and (len(quoters) == 0):
|
if (quoters is not None) and (len(quoters) == 0):
|
||||||
printerr('Princess Celestia! All the ponies are mute!')
|
printerr('Princess Celestia! All the ponies are mute!')
|
||||||
exit(250)
|
exit(250)
|
||||||
|
|
||||||
## Get all ponies, with quotes
|
## Get all ponies, with quotes
|
||||||
oldponies = {}
|
let oldponies = {}
|
||||||
self.__getAllPonies(standard, extra, oldponies, quoters)
|
self.__getAllPonies(standard, extra, oldponies, quoters)
|
||||||
|
|
||||||
## Apply restriction
|
## Apply restriction
|
||||||
ponies = self.__applyRestriction(oldponies, ponydirs)
|
let ponies = self.__applyRestriction(oldponies, ponydirs)
|
||||||
|
|
||||||
## Select one pony and set all information
|
## Select one pony and set all information
|
||||||
names = list(ponies.keys())
|
let names = list(ponies.keys())
|
||||||
if len(names) == 0:
|
if len(names) == 0:
|
||||||
printerr('All the ponies are missing, call the Princess!')
|
printerr('All the ponies are missing, call the Princess!')
|
||||||
exit(249)
|
exit(249)
|
||||||
pony = names[random.randrange(0, len(names))]
|
let pony = names[random.randrange(0, len(names))]
|
||||||
return (pony, [ponies[pony]], quote)
|
return (pony, [ponies[pony]], quote)
|
||||||
|
|
||||||
|
|
||||||
|
@ -554,7 +610,7 @@ class Ponysay():
|
||||||
for ponydir in directories:
|
for ponydir in directories:
|
||||||
for ponyfile in os.listdir(ponydir):
|
for ponyfile in os.listdir(ponydir):
|
||||||
if endswith(ponyfile, '.pony'):
|
if endswith(ponyfile, '.pony'):
|
||||||
pony = ponyfile[:-5]
|
let pony = ponyfile[:-5]
|
||||||
if (pony not in collection) and ((quoters is None) or (pony in quoters)):
|
if (pony not in collection) and ((quoters is None) or (pony in quoters)):
|
||||||
collection[pony] = ponydir + ponyfile
|
collection[pony] = ponydir + ponyfile
|
||||||
|
|
||||||
|
@ -575,7 +631,7 @@ class Ponysay():
|
||||||
oldponies = ponies
|
oldponies = ponies
|
||||||
|
|
||||||
## Apply dimension restriction
|
## Apply dimension restriction
|
||||||
ponies = {}
|
let ponies = {}
|
||||||
self.__applyDimensionRestriction(ponies, oldponies, ponydirs)
|
self.__applyDimensionRestriction(ponies, oldponies, ponydirs)
|
||||||
if len(ponies) > 0:
|
if len(ponies) > 0:
|
||||||
oldponies = ponies
|
oldponies = ponies
|
||||||
|
@ -606,9 +662,9 @@ class Ponysay():
|
||||||
@param oldponies:dict<str, str> Collection of original ponies, maps to pony file
|
@param oldponies:dict<str, str> Collection of original ponies, maps to pony file
|
||||||
@param ponydirs:list<sr> List of pony directories
|
@param ponydirs:list<sr> List of pony directories
|
||||||
'''
|
'''
|
||||||
(termh, termw) = gettermsize()
|
let termh, termw = gettermsize()
|
||||||
for ponydir in ponydirs:
|
for ponydir in ponydirs:
|
||||||
(fitw, fith) = (None, None)
|
let fitw, fith = (None, None)
|
||||||
if os.path.exists(ponydir + 'widths'):
|
if os.path.exists(ponydir + 'widths'):
|
||||||
fitw = set()
|
fitw = set()
|
||||||
with open(ponydir + 'widths', 'rb') as file:
|
with open(ponydir + 'widths', 'rb') as file:
|
||||||
|
@ -619,7 +675,7 @@ class Ponysay():
|
||||||
Metadata.getFitting(fith, termh, file)
|
Metadata.getFitting(fith, termh, file)
|
||||||
for ponyfile in oldponies.values():
|
for ponyfile in oldponies.values():
|
||||||
if ponyfile.startswith(ponydir):
|
if ponyfile.startswith(ponydir):
|
||||||
pony = ponyfile[len(ponydir) : -5]
|
let pony = ponyfile[len(ponydir) : -5]
|
||||||
if (fitw is None) or (pony in fitw):
|
if (fitw is None) or (pony in fitw):
|
||||||
if (fith is None) or (pony in fith):
|
if (fith is None) or (pony in fith):
|
||||||
ponies[pony] = ponyfile
|
ponies[pony] = ponyfile
|
||||||
|
@ -663,9 +719,9 @@ class Ponysay():
|
||||||
if quotedirs is None: quotedirs = self.quotedirs
|
if quotedirs is None: quotedirs = self.quotedirs
|
||||||
|
|
||||||
## List all unique quote files
|
## List all unique quote files
|
||||||
quotes = []
|
let quotes = []
|
||||||
quoteshash = set()
|
let quoteshash = set()
|
||||||
_quotes = []
|
let _quotes = []
|
||||||
for quotedir in quotedirs:
|
for quotedir in quotedirs:
|
||||||
_quotes += [item[:item.index('.')] for item in os.listdir(quotedir)]
|
_quotes += [item[:item.index('.')] for item in os.listdir(quotedir)]
|
||||||
for quote in _quotes:
|
for quote in _quotes:
|
||||||
|
@ -675,11 +731,11 @@ class Ponysay():
|
||||||
quotes.append(quote)
|
quotes.append(quote)
|
||||||
|
|
||||||
## Create a set of all ponies that have quotes
|
## Create a set of all ponies that have quotes
|
||||||
ponies = set()
|
let ponies = set()
|
||||||
for ponydir in ponydirs:
|
for ponydir in ponydirs:
|
||||||
for pony in os.listdir(ponydir):
|
for pony in os.listdir(ponydir):
|
||||||
if not pony[0] == '.':
|
if not pony[0] == '.':
|
||||||
p = pony[:-5] # remove .pony
|
let p = pony[:-5] # remove .pony
|
||||||
for quote in quotes:
|
for quote in quotes:
|
||||||
if ('+' + p + '+') in ('+' + quote + '+'):
|
if ('+' + p + '+') in ('+' + quote + '+'):
|
||||||
if not p in ponies:
|
if not p in ponies:
|
||||||
|
@ -760,8 +816,7 @@ class Ponysay():
|
||||||
@param standard:bool Include standard ponies
|
@param standard:bool Include standard ponies
|
||||||
@param extra:bool Include extra ponies
|
@param extra:bool Include extra ponies
|
||||||
'''
|
'''
|
||||||
|
let pony_dirs = (self.ponydirs if standard else []) + (self.extraponydirs if extra else [])
|
||||||
pony_dirs = (self.ponydirs if standard else []) + (self.extraponydirs if extra else [])
|
|
||||||
|
|
||||||
lists.onelist(pony_dirs, self.__ucsise)
|
lists.onelist(pony_dirs, self.__ucsise)
|
||||||
|
|
||||||
|
@ -774,7 +829,7 @@ class Ponysay():
|
||||||
@param extra:bool Include extra ponies
|
@param extra:bool Include extra ponies
|
||||||
'''
|
'''
|
||||||
## Get all quoters
|
## Get all quoters
|
||||||
ponies = list(self.__quoters()) if standard else []
|
let ponies = list(self.__quoters()) if standard else []
|
||||||
|
|
||||||
## And now the extra ponies
|
## And now the extra ponies
|
||||||
if extra:
|
if extra:
|
||||||
|
@ -818,10 +873,10 @@ class Ponysay():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
## Get all balloons
|
## Get all balloons
|
||||||
balloons = {}
|
let balloons = {}
|
||||||
for balloondir in self.balloondirs:
|
for balloondir in self.balloondirs:
|
||||||
for balloon in os.listdir(balloondir):
|
for balloon in os.listdir(balloondir):
|
||||||
balloonfile = balloon
|
let balloonfile = balloon
|
||||||
## Use .think if running ponythink, otherwise .say
|
## Use .think if running ponythink, otherwise .say
|
||||||
if self.isthink and endswith(balloon, '.think'):
|
if self.isthink and endswith(balloon, '.think'):
|
||||||
balloon = balloon[:-6]
|
balloon = balloon[:-6]
|
||||||
|
@ -840,12 +895,12 @@ class Ponysay():
|
||||||
balloons[name] = name
|
balloons[name] = name
|
||||||
|
|
||||||
## Select a random balloon of the choosen ones
|
## Select a random balloon of the choosen ones
|
||||||
balloon = names[random.randrange(0, len(names))]
|
let balloon = names[random.randrange(0, len(names))]
|
||||||
if balloon not in balloons:
|
if balloon not in balloons:
|
||||||
if not alt:
|
if not alt:
|
||||||
autocorrect = SpelloCorrecter(self.balloondirs, '.think' if self.isthink else '.say')
|
let autocorrect = SpelloCorrecter(self.balloondirs, '.think' if self.isthink else '.say')
|
||||||
(alternatives, dist) = autocorrect.correct(balloon)
|
let alternatives, dist = autocorrect.correct(balloon)
|
||||||
limit = os.environ['PONYSAY_TYPO_LIMIT'] if 'PONYSAY_TYPO_LIMIT' in os.environ else ''
|
let limit = os.environ['PONYSAY_TYPO_LIMIT'] if 'PONYSAY_TYPO_LIMIT' in os.environ else ''
|
||||||
limit = 5 if len(limit) == 0 else int(limit)
|
limit = 5 if len(limit) == 0 else int(limit)
|
||||||
if (len(alternatives) > 0) and (dist <= limit):
|
if (len(alternatives) > 0) and (dist <= limit):
|
||||||
return self.__getBalloonPath(alternatives, True)
|
return self.__getBalloonPath(alternatives, True)
|
||||||
|
@ -885,12 +940,12 @@ class Ponysay():
|
||||||
@param args:ArgParser Parsed command line arguments
|
@param args:ArgParser Parsed command line arguments
|
||||||
'''
|
'''
|
||||||
## Get the pony
|
## Get the pony
|
||||||
selection = []
|
let selection = []
|
||||||
self.__getSelectedPonies(args, selection)
|
self.__getSelectedPonies(args, selection)
|
||||||
(pony, quote) = self.__getPony(selection, args)
|
let pony, quote = self.__getPony(selection, args)
|
||||||
|
|
||||||
## Get message and manipulate it
|
## Get message and manipulate it
|
||||||
msg = self.__getMessage(args, quote)
|
let msg = self.__getMessage(args, quote)
|
||||||
msg = self.__colouriseMessage(args, msg)
|
msg = self.__colouriseMessage(args, msg)
|
||||||
msg = self.__compressMessage(args, msg)
|
msg = self.__compressMessage(args, msg)
|
||||||
|
|
||||||
|
@ -901,38 +956,38 @@ class Ponysay():
|
||||||
pony = self.__useImage(pony)
|
pony = self.__useImage(pony)
|
||||||
|
|
||||||
## If KMS is utilies, select a KMS pony file and create it if necessary
|
## If KMS is utilies, select a KMS pony file and create it if necessary
|
||||||
pony = KMS.kms(pony, self.HOME, self.linuxvt)
|
#pony = KMS.kms(pony, self.HOME, self.linuxvt)
|
||||||
|
|
||||||
## If in Linux VT clean the terminal (See info/pdf-manual [Printing in TTY with KMS])
|
## If in Linux VT clean the terminal (See info/pdf-manual [Printing in TTY with KMS])
|
||||||
if self.linuxvt:
|
if self.linuxvt:
|
||||||
print('\033[H\033[2J', end='')
|
print('\033[H\033[2J', end='')
|
||||||
|
|
||||||
## Get width truncation and wrapping
|
## Get width truncation and wrapping
|
||||||
widthtruncation = self.__getWidthTruncation()
|
let widthtruncation = self.__getWidthTruncation()
|
||||||
messagewrap = self.__getMessageWrap(args)
|
let messagewrap = self.__getMessageWrap(args)
|
||||||
|
|
||||||
## Get balloon object
|
## Get balloon object
|
||||||
balloonfile = self.__getBalloonPath(args.opts['-b'] if args.opts['-b'] is not None else None)
|
let balloonfile = self.__getBalloonPath(args.opts['-b'] if args.opts['-b'] is not None else None)
|
||||||
printinfo('balloon style file: ' + str(balloonfile))
|
printinfo('balloon style file: ' + str(balloonfile))
|
||||||
balloon = self.__getBalloon(balloonfile) if args.opts['-o'] is None else None
|
let balloon = self.__getBalloon(balloonfile) if args.opts['-o'] is None else None
|
||||||
|
|
||||||
## Get hyphen style
|
## Get hyphen style
|
||||||
hyphen = self.__getHyphen(args)
|
let hyphen = self.__getHyphen(args)
|
||||||
|
|
||||||
## Link and balloon colouring
|
## Link and balloon colouring
|
||||||
linkcolour = self.__getLinkColour(args)
|
let linkcolour = self.__getLinkColour(args)
|
||||||
ballooncolour = self.__getBalloonColour(args)
|
let ballooncolour = self.__getBalloonColour(args)
|
||||||
|
|
||||||
## Determine --info/++info settings
|
## Determine --info/++info settings
|
||||||
minusinfo = args.opts['-i'] is not None
|
let minusinfo = args.opts['-i'] is not None
|
||||||
plusinfo = args.opts['+i'] is not None
|
let plusinfo = args.opts['+i'] is not None
|
||||||
|
|
||||||
## Run cowsay replacement
|
## Run cowsay replacement
|
||||||
backend = Backend(message = msg, ponyfile = pony, wrapcolumn = messagewrap, width = widthtruncation, balloon = balloon,
|
let backend = Backend(message = msg, ponyfile = pony, wrapcolumn = messagewrap, width = widthtruncation, balloon = balloon,
|
||||||
hyphen = hyphen, linkcolour = linkcolour, ballooncolour = ballooncolour, mode = self.mode,
|
hyphen = hyphen, linkcolour = linkcolour, ballooncolour = ballooncolour, mode = self.mode,
|
||||||
infolevel = 2 if plusinfo else (1 if minusinfo else 0))
|
infolevel = 2 if plusinfo else (1 if minusinfo else 0))
|
||||||
backend.parse()
|
backend.parse()
|
||||||
output = backend.output
|
let output = backend.output
|
||||||
if output.endswith('\n'):
|
if output.endswith('\n'):
|
||||||
output = output[:-1]
|
output = output[:-1]
|
||||||
|
|
||||||
|
@ -947,7 +1002,7 @@ class Ponysay():
|
||||||
@param args:ArgParser Command line options
|
@param args:ArgParser Command line options
|
||||||
@param selection:list<(name:str, file:str, quotes:bool)> List to fill with tuples of selected pony names, pony files and whether quotes are used
|
@param selection:list<(name:str, file:str, quotes:bool)> List to fill with tuples of selected pony names, pony files and whether quotes are used
|
||||||
'''
|
'''
|
||||||
(standard, extra) = ([], [])
|
let standard, extra = [], []
|
||||||
for ponydir in self.ponydirs:
|
for ponydir in self.ponydirs:
|
||||||
for pony in os.listdir(ponydir):
|
for pony in os.listdir(ponydir):
|
||||||
if endswith(pony, '.pony'):
|
if endswith(pony, '.pony'):
|
||||||
|
@ -956,8 +1011,8 @@ class Ponysay():
|
||||||
for pony in os.listdir(ponydir):
|
for pony in os.listdir(ponydir):
|
||||||
if endswith(pony, '.pony'):
|
if endswith(pony, '.pony'):
|
||||||
extra.append(ponydir + pony)
|
extra.append(ponydir + pony)
|
||||||
both = standard + extra
|
let both = standard + extra
|
||||||
for (opt, ponies, quotes) in [('-f', standard, False), ('+f', extra, False), ('-F', both, False), ('-q', standard, True)]: ## TODO +q -Q
|
for opt, ponies, quotes in [('-f', standard, False), ('+f', extra, False), ('-F', both, False), ('-q', standard, True)]: ## TODO +q -Q
|
||||||
if args.opts[opt] is not None:
|
if args.opts[opt] is not None:
|
||||||
for pony in args.opts[opt]:
|
for pony in args.opts[opt]:
|
||||||
selection.append((pony, ponies, quotes))
|
selection.append((pony, ponies, quotes))
|
||||||
|
@ -974,7 +1029,7 @@ class Ponysay():
|
||||||
if quote is not None:
|
if quote is not None:
|
||||||
return quote
|
return quote
|
||||||
if args.message is None:
|
if args.message is None:
|
||||||
return ''.join(sys.stdin.readlines()).rstrip()
|
return ''.join(fileio.stdin.readlines()).rstrip()
|
||||||
return args.message
|
return args.message
|
||||||
|
|
||||||
|
|
||||||
|
@ -1044,7 +1099,7 @@ class Ponysay():
|
||||||
|
|
||||||
@return :int? The column the truncate the output at, or `None` to not truncate it
|
@return :int? The column the truncate the output at, or `None` to not truncate it
|
||||||
'''
|
'''
|
||||||
env_width = os.environ['PONYSAY_FULL_WIDTH'] if 'PONYSAY_FULL_WIDTH' in os.environ else None
|
let env_width = os.environ['PONYSAY_FULL_WIDTH'] if 'PONYSAY_FULL_WIDTH' in os.environ else None
|
||||||
if env_width is None: env_width = 'auto'
|
if env_width is None: env_width = 'auto'
|
||||||
return gettermsize()[1] if env_width not in ('yes', 'y', '1') else None
|
return gettermsize()[1] if env_width not in ('yes', 'y', '1') else None
|
||||||
|
|
||||||
|
@ -1056,7 +1111,7 @@ class Ponysay():
|
||||||
@param args:ArgParser Command line options
|
@param args:ArgParser Command line options
|
||||||
@return :int? The message balloon wrapping column, or `None` if disabled
|
@return :int? The message balloon wrapping column, or `None` if disabled
|
||||||
'''
|
'''
|
||||||
messagewrap = 65
|
let messagewrap = 65
|
||||||
if (args.opts['-W'] is not None) and (len(args.opts['-W'][0]) > 0):
|
if (args.opts['-W'] is not None) and (len(args.opts['-W'][0]) > 0):
|
||||||
messagewrap = args.opts['-W'][0]
|
messagewrap = args.opts['-W'][0]
|
||||||
if messagewrap[0] in 'nmsNMS': # m is left to n on QWERTY and s is left to n on Dvorak
|
if messagewrap[0] in 'nmsNMS': # m is left to n on QWERTY and s is left to n on Dvorak
|
||||||
|
@ -1075,10 +1130,10 @@ class Ponysay():
|
||||||
@param args:ArgParser Command line options
|
@param args:ArgParser Command line options
|
||||||
@return :str The hyphen string to use at hyphenation
|
@return :str The hyphen string to use at hyphenation
|
||||||
'''
|
'''
|
||||||
hyphen = os.environ['PONYSAY_WRAP_HYPHEN'] if 'PONYSAY_WRAP_HYPHEN' in os.environ else None
|
let hyphen = os.environ['PONYSAY_WRAP_HYPHEN'] if 'PONYSAY_WRAP_HYPHEN' in os.environ else None
|
||||||
if (hyphen is None) or (len(hyphen) == 0):
|
if (hyphen is None) or (len(hyphen) == 0):
|
||||||
hyphen = '-'
|
hyphen = '-'
|
||||||
hyphencolour = ''
|
let hyphencolour = ''
|
||||||
if args.opts['--colour-wrap'] is not None:
|
if args.opts['--colour-wrap'] is not None:
|
||||||
hyphencolour = '\033[' + ';'.join(args.opts['--colour-wrap']) + 'm'
|
hyphencolour = '\033[' + ';'.join(args.opts['--colour-wrap']) + 'm'
|
||||||
return '\033[31m' + hyphencolour + hyphen
|
return '\033[31m' + hyphencolour + hyphen
|
||||||
|
@ -1091,7 +1146,7 @@ class Ponysay():
|
||||||
@param args:ArgParser Command line options
|
@param args:ArgParser Command line options
|
||||||
@return :str The colour of balloon links
|
@return :str The colour of balloon links
|
||||||
'''
|
'''
|
||||||
linkcolour = ''
|
let linkcolour = ''
|
||||||
if args.opts['--colour-link'] is not None:
|
if args.opts['--colour-link'] is not None:
|
||||||
linkcolour = '\033[' + ';'.join(args.opts['--colour-link']) + 'm'
|
linkcolour = '\033[' + ';'.join(args.opts['--colour-link']) + 'm'
|
||||||
return linkcolour
|
return linkcolour
|
||||||
|
@ -1104,7 +1159,7 @@ class Ponysay():
|
||||||
@param args:ArgParser Command line options
|
@param args:ArgParser Command line options
|
||||||
@return :str The colour of balloons
|
@return :str The colour of balloons
|
||||||
'''
|
'''
|
||||||
ballooncolour = ''
|
let ballooncolour = ''
|
||||||
if args.opts['--colour-bubble'] is not None:
|
if args.opts['--colour-bubble'] is not None:
|
||||||
ballooncolour = '\033[' + ';'.join(args.opts['--colour-bubble']) + 'm'
|
ballooncolour = '\033[' + ';'.join(args.opts['--colour-bubble']) + 'm'
|
||||||
return ballooncolour
|
return ballooncolour
|
||||||
|
@ -1117,17 +1172,17 @@ class Ponysay():
|
||||||
@param output:str The output truncated on the width but not on the height
|
@param output:str The output truncated on the width but not on the height
|
||||||
'''
|
'''
|
||||||
## Load height trunction settings
|
## Load height trunction settings
|
||||||
env_bottom = os.environ['PONYSAY_BOTTOM'] if 'PONYSAY_BOTTOM' in os.environ else None
|
let env_bottom = os.environ['PONYSAY_BOTTOM'] if 'PONYSAY_BOTTOM' in os.environ else None
|
||||||
if env_bottom is None: env_bottom = ''
|
if env_bottom is None: env_bottom = ''
|
||||||
|
|
||||||
env_height = os.environ['PONYSAY_TRUNCATE_HEIGHT'] if 'PONYSAY_TRUNCATE_HEIGHT' in os.environ else None
|
let env_height = os.environ['PONYSAY_TRUNCATE_HEIGHT'] if 'PONYSAY_TRUNCATE_HEIGHT' in os.environ else None
|
||||||
if env_height is None: env_height = ''
|
if env_height is None: env_height = ''
|
||||||
|
|
||||||
env_lines = os.environ['PONYSAY_SHELL_LINES'] if 'PONYSAY_SHELL_LINES' in os.environ else None
|
let env_lines = os.environ['PONYSAY_SHELL_LINES'] if 'PONYSAY_SHELL_LINES' in os.environ else None
|
||||||
if (env_lines is None) or (env_lines == ''): env_lines = '2'
|
if (env_lines is None) or (env_lines == ''): env_lines = '2'
|
||||||
|
|
||||||
## Print the output, truncated on height if so set
|
## Print the output, truncated on height if so set
|
||||||
lines = gettermsize()[0] - int(env_lines)
|
let lines = gettermsize()[0] - int(env_lines)
|
||||||
if self.linuxvt or (env_height in ('yes', 'y', '1')):
|
if self.linuxvt or (env_height in ('yes', 'y', '1')):
|
||||||
if env_bottom in ('yes', 'y', '1'):
|
if env_bottom in ('yes', 'y', '1'):
|
||||||
for line in output.split('\n')[: -lines]:
|
for line in output.split('\n')[: -lines]:
|
|
@ -31,15 +31,16 @@ the colon.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import kuroko
|
||||||
from subprocess import Popen, PIPE
|
import fileio
|
||||||
|
|
||||||
from argparser import *
|
from ponysay.argparser import ArgParser
|
||||||
from ponysay import *
|
from ponysay.ponysay import Ponysay
|
||||||
from metadata import *
|
from ponysay.metadata import Metadata
|
||||||
|
|
||||||
|
|
||||||
VERSION = 'dev' # this line should not be edited, it is fixed by the build system
|
|
||||||
|
let VERSION = 'dev' # this line should not be edited, it is fixed by the build system
|
||||||
'''
|
'''
|
||||||
The version of ponysay
|
The version of ponysay
|
||||||
'''
|
'''
|
||||||
|
@ -54,7 +55,7 @@ def print(text = '', end = '\n'):
|
||||||
@param text:str The text to print (empty string is default)
|
@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)
|
@param end:str The appendix to the text to print (line breaking is default)
|
||||||
'''
|
'''
|
||||||
sys.stdout.buffer.write((str(text) + end).encode('utf-8'))
|
fileio.stdout.buffer.write((str(text) + end).encode('utf-8'))
|
||||||
|
|
||||||
def printerr(text = '', end = '\n'):
|
def printerr(text = '', end = '\n'):
|
||||||
'''
|
'''
|
||||||
|
@ -63,7 +64,7 @@ def printerr(text = '', end = '\n'):
|
||||||
@param text:str The text to print (empty string is default)
|
@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)
|
@param end:str The appendix to the text to print (line breaking is default)
|
||||||
'''
|
'''
|
||||||
sys.stderr.buffer.write((str(text) + end).encode('utf-8'))
|
fileio.stderr.buffer.write((str(text) + end).encode('utf-8'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,7 +81,7 @@ class PonysayTool():
|
||||||
'''
|
'''
|
||||||
if args.argcount == 0:
|
if args.argcount == 0:
|
||||||
args.help()
|
args.help()
|
||||||
exit(255)
|
os.exit(255)
|
||||||
return
|
return
|
||||||
|
|
||||||
opts = args.opts
|
opts = args.opts
|
||||||
|
@ -88,7 +89,7 @@ class PonysayTool():
|
||||||
if unrecognised or (opts['-h'] is not None) or (opts['+h'] is not None):
|
if unrecognised or (opts['-h'] is not None) or (opts['+h'] is not None):
|
||||||
args.help(True if opts['+h'] is not None else None)
|
args.help(True if opts['+h'] is not None else None)
|
||||||
if unrecognised:
|
if unrecognised:
|
||||||
exit(254)
|
os.exit(254)
|
||||||
|
|
||||||
elif opts['-v'] is not None:
|
elif opts['-v'] is not None:
|
||||||
print('%s %s' % ('ponysay-tool', VERSION))
|
print('%s %s' % ('ponysay-tool', VERSION))
|
||||||
|
@ -105,33 +106,33 @@ class PonysayTool():
|
||||||
elif (opts['-b'] is not None) and (len(opts['-b']) == 1):
|
elif (opts['-b'] is not None) and (len(opts['-b']) == 1):
|
||||||
try:
|
try:
|
||||||
if opts['--no-term-init'] is None:
|
if opts['--no-term-init'] is None:
|
||||||
print('\033[?1049h', end='') # initialise terminal
|
print('\[[?1049h', end='') # initialise terminal
|
||||||
cmd = 'stty %s < %s > /dev/null 2> /dev/null'
|
cmd = 'stty %s < %s > /dev/null 2> /dev/null'
|
||||||
cmd %= ('-echo -icanon -echo -isig -ixoff -ixon', os.path.realpath('/dev/stdout'))
|
cmd %= ('-echo -icanon -echo -isig -ixoff -ixon', os.path.realpath('/dev/stdout'))
|
||||||
Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).wait()
|
Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).wait()
|
||||||
print('\033[?25l', end='') # hide cursor
|
print('\[[?25l', end='') # hide cursor
|
||||||
dir = opts['-b'][0]
|
dir = opts['-b'][0]
|
||||||
if not dir.endswith(os.sep):
|
if not dir.endswith(os.sep):
|
||||||
dir += os.sep
|
dir += os.sep
|
||||||
self.browse(dir, opts['-r'])
|
self.browse(dir, opts['-r'])
|
||||||
finally:
|
finally:
|
||||||
print('\033[?25h', end='') # show cursor
|
print('\[[?25h', end='') # show cursor
|
||||||
cmd = 'stty %s < %s > /dev/null 2> /dev/null'
|
cmd = 'stty %s < %s > /dev/null 2> /dev/null'
|
||||||
cmd %= ('echo icanon echo isig ixoff ixon', os.path.realpath('/dev/stdout'))
|
cmd %= ('echo icanon echo isig ixoff ixon', os.path.realpath('/dev/stdout'))
|
||||||
Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).wait()
|
Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).wait()
|
||||||
if opts['--no-term-init'] is None:
|
if opts['--no-term-init'] is None:
|
||||||
print('\033[?1049l', end='') # terminate terminal
|
print('\[[?1049l', end='') # terminate terminal
|
||||||
|
|
||||||
elif (opts['--edit'] is not None) and (len(opts['--edit']) == 1):
|
elif (opts['--edit'] is not None) and (len(opts['--edit']) == 1):
|
||||||
pony = opts['--edit'][0]
|
pony = opts['--edit'][0]
|
||||||
if not os.path.isfile(pony):
|
if not os.path.isfile(pony):
|
||||||
printerr('%s is not an existing regular file' % pony)
|
printerr('%s is not an existing regular file' % pony)
|
||||||
exit(252)
|
os.exit(252)
|
||||||
linuxvt = ('TERM' in os.environ) and (os.environ['TERM'] == 'linux')
|
linuxvt = ('TERM' in os.environ) and (os.environ['TERM'] == 'linux')
|
||||||
try:
|
try:
|
||||||
if opts['--no-term-init'] is None:
|
if opts['--no-term-init'] is None:
|
||||||
print('\033[?1049h', end='') # initialise terminal
|
print('\[[?1049h', end='') # initialise terminal
|
||||||
if linuxvt: print('\033[?8c', end='') # use full block for cursor (_ is used by default in linux vt)
|
if linuxvt: print('\[[?8c', end='') # use full block for cursor (_ is used by default in linux vt)
|
||||||
cmd = 'stty %s < %s > /dev/null 2> /dev/null'
|
cmd = 'stty %s < %s > /dev/null 2> /dev/null'
|
||||||
cmd %= ('-echo -icanon -echo -isig -ixoff -ixon', os.path.realpath('/dev/stdout'))
|
cmd %= ('-echo -icanon -echo -isig -ixoff -ixon', os.path.realpath('/dev/stdout'))
|
||||||
Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).wait()
|
Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).wait()
|
||||||
|
@ -140,9 +141,9 @@ class PonysayTool():
|
||||||
cmd = 'stty %s < %s > /dev/null 2> /dev/null'
|
cmd = 'stty %s < %s > /dev/null 2> /dev/null'
|
||||||
cmd %= ('echo icanon echo isig ixoff ixon', os.path.realpath('/dev/stdout'))
|
cmd %= ('echo icanon echo isig ixoff ixon', os.path.realpath('/dev/stdout'))
|
||||||
Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).wait()
|
Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).wait()
|
||||||
if linuxvt: print('\033[?0c', end='') # restore cursor
|
if linuxvt: print('\[[?0c', end='') # restore cursor
|
||||||
if opts['--no-term-init'] is None:
|
if opts['--no-term-init'] is None:
|
||||||
print('\033[?1049l', end='') # terminate terminal
|
print('\[[?1049l', end='') # terminate terminal
|
||||||
|
|
||||||
elif (opts['--edit-rm'] is not None) and (len(opts['--edit-rm']) == 1):
|
elif (opts['--edit-rm'] is not None) and (len(opts['--edit-rm']) == 1):
|
||||||
ponyfile = opts['--edit-rm'][0]
|
ponyfile = opts['--edit-rm'][0]
|
||||||
|
@ -174,7 +175,7 @@ class PonysayTool():
|
||||||
if data == '':
|
if data == '':
|
||||||
if line != '$$$':
|
if line != '$$$':
|
||||||
printerr('Bad stash')
|
printerr('Bad stash')
|
||||||
exit(251)
|
os.exit(251)
|
||||||
data += '$$$\n'
|
data += '$$$\n'
|
||||||
else:
|
else:
|
||||||
data += line + '\n'
|
data += line + '\n'
|
||||||
|
@ -192,7 +193,7 @@ class PonysayTool():
|
||||||
|
|
||||||
else:
|
else:
|
||||||
args.help()
|
args.help()
|
||||||
exit(253)
|
os.exit(253)
|
||||||
|
|
||||||
|
|
||||||
def execPonysay(self, args, message = ''):
|
def execPonysay(self, args, message = ''):
|
||||||
|
@ -214,9 +215,9 @@ class PonysayTool():
|
||||||
return args[key] if (args[key] is not None) and isinstance(args[key], list) else [args[key]]
|
return args[key] if (args[key] is not None) and isinstance(args[key], list) else [args[key]]
|
||||||
return None
|
return None
|
||||||
def __contains__(self, key):
|
def __contains__(self, key):
|
||||||
return key in args;
|
return key in args
|
||||||
|
|
||||||
stdout = sys.stdout
|
stdout = fileio.stdout
|
||||||
class StringInputStream():
|
class StringInputStream():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.buf = ''
|
self.buf = ''
|
||||||
|
@ -232,11 +233,11 @@ class PonysayTool():
|
||||||
pass
|
pass
|
||||||
def isatty(self):
|
def isatty(self):
|
||||||
return True
|
return True
|
||||||
sys.stdout = StringInputStream()
|
fileio.stdout = StringInputStream()
|
||||||
ponysay = Ponysay()
|
ponysay = Ponysay()
|
||||||
ponysay.run(PhonyArgParser(args, message))
|
ponysay.run(PhonyArgParser(args, message))
|
||||||
out = sys.stdout.buf[:-1]
|
out = fileio.stdout.buf[:-1]
|
||||||
sys.stdout = stdout
|
fileio.stdout = stdout
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
@ -249,7 +250,7 @@ class PonysayTool():
|
||||||
'''
|
'''
|
||||||
## Call `stty` to determine the size of the terminal, this way is better than using python's ncurses
|
## Call `stty` to determine the size of the terminal, this way is better than using python's ncurses
|
||||||
termsize = None
|
termsize = None
|
||||||
for channel in (sys.stdout, sys.stdin, sys.stderr):
|
for channel in (fileio.stdout, fileio.stdin, fileio.stderr):
|
||||||
termsize = Popen(['stty', 'size'], stdout=PIPE, stdin=channel, stderr=PIPE).communicate()[0]
|
termsize = Popen(['stty', 'size'], stdout=PIPE, stdin=channel, stderr=PIPE).communicate()[0]
|
||||||
if len(termsize) > 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
|
||||||
|
@ -275,7 +276,7 @@ class PonysayTool():
|
||||||
ponies.sort()
|
ponies.sort()
|
||||||
|
|
||||||
if len(ponies) == 0:
|
if len(ponies) == 0:
|
||||||
print('\033[1;31m%s\033[21m;39m' % 'No ponies... press Enter to exit.')
|
print('\[[1;31m%s\[[22m;39m' % 'No ponies... press Enter to exit.')
|
||||||
input()
|
input()
|
||||||
|
|
||||||
panelw = Backend.len(max(ponies, key = Backend.len))
|
panelw = Backend.len(max(ponies, key = Backend.len))
|
||||||
|
@ -300,14 +301,14 @@ class PonysayTool():
|
||||||
ponyfile = (ponydir + '/' + ponies[ponyindex] + '.pony').replace('//', '/')
|
ponyfile = (ponydir + '/' + ponies[ponyindex] + '.pony').replace('//', '/')
|
||||||
pony = self.execPonysay({'-f' : ponyfile, '-W' : 'none', '-o' : None}).split('\n')
|
pony = self.execPonysay({'-f' : ponyfile, '-W' : 'none', '-o' : None}).split('\n')
|
||||||
|
|
||||||
preprint = '\033[H\033[2J'
|
preprint = '\[[H\[[2J'
|
||||||
if pony[0].startswith(preprint):
|
if pony[0].startswith(preprint):
|
||||||
pony[0] = pony[0][len(preprint):]
|
pony[0] = pony[0][len(preprint):]
|
||||||
ponyheight = len(pony)
|
ponyheight = len(pony)
|
||||||
ponywidth = Backend.len(max(pony, key = Backend.len))
|
ponywidth = Backend.len(max(pony, key = Backend.len))
|
||||||
|
|
||||||
AUTO_PUSH = '\033[01010~'
|
AUTO_PUSH = '\[[01010~'
|
||||||
AUTO_POP = '\033[10101~'
|
AUTO_POP = '\[[10101~'
|
||||||
pony = '\n'.join(pony).replace('\n', AUTO_PUSH + '\n' + AUTO_POP)
|
pony = '\n'.join(pony).replace('\n', AUTO_PUSH + '\n' + AUTO_POP)
|
||||||
colourstack = ColourStack(AUTO_PUSH, AUTO_POP)
|
colourstack = ColourStack(AUTO_PUSH, AUTO_POP)
|
||||||
buf = ''
|
buf = ''
|
||||||
|
@ -317,7 +318,7 @@ class PonysayTool():
|
||||||
|
|
||||||
if (oldx != x) or (oldy != y):
|
if (oldx != x) or (oldy != y):
|
||||||
(oldx, oldy) = (x, y)
|
(oldx, oldy) = (x, y)
|
||||||
print('\033[H\033[2J', end='')
|
print('\[[H\[[2J', end='')
|
||||||
|
|
||||||
def getprint(pony, ponywidth, ponyheight, termw, termh, px, py):
|
def getprint(pony, ponywidth, ponyheight, termw, termh, px, py):
|
||||||
ponyprint = pony
|
ponyprint = pony
|
||||||
|
@ -338,7 +339,7 @@ class PonysayTool():
|
||||||
elif px > 0:
|
elif px > 0:
|
||||||
ponyprint = [px * ' ' + line for line in ponyprint]
|
ponyprint = [px * ' ' + line for line in ponyprint]
|
||||||
ponyprint = [(line if Backend.len(line) <= termw else line[:findcolumn(line, termw)]) for line in ponyprint]
|
ponyprint = [(line if Backend.len(line) <= termw else line[:findcolumn(line, termw)]) for line in ponyprint]
|
||||||
ponyprint = ['\033[21;39;49;0m%s\033[21;39;49;0m' % line for line in ponyprint]
|
ponyprint = ['\[[22;39;49;0m%s\[[22;39;49;0m' % line for line in ponyprint]
|
||||||
return '\n'.join(ponyprint)
|
return '\n'.join(ponyprint)
|
||||||
|
|
||||||
if quotes:
|
if quotes:
|
||||||
|
@ -361,24 +362,24 @@ class PonysayTool():
|
||||||
for line in ponies[panely:]:
|
for line in ponies[panely:]:
|
||||||
cury += 1
|
cury += 1
|
||||||
if os.path.islink((ponydir + '/' + line + '.pony').replace('//', '/')):
|
if os.path.islink((ponydir + '/' + line + '.pony').replace('//', '/')):
|
||||||
line = '\033[34m%s\033[39m' % ((line + ' ' * panelw)[:panelw])
|
line = '\[[34m%s\[[39m' % ((line + ' ' * panelw)[:panelw])
|
||||||
else:
|
else:
|
||||||
line = (line + ' ' * panelw)[:panelw]
|
line = (line + ' ' * panelw)[:panelw]
|
||||||
print('\033[%i;%iH\033[%im%s\033[0m' % (cury, panelx + 1, 1 if panely + cury - 1 == ponyindex else 0, line), end='')
|
print('\[[%i;%iH\[[%im%s\[[0m' % (cury, panelx + 1, 1 if panely + cury - 1 == ponyindex else 0, line), end='')
|
||||||
elif printpanel >= 0:
|
elif printpanel >= 0:
|
||||||
for index in (printpanel, ponyindex):
|
for index in (printpanel, ponyindex):
|
||||||
cury = index - panely
|
cury = index - panely
|
||||||
if (0 <= cury) and (cury < termh):
|
if (0 <= cury) and (cury < termh):
|
||||||
line = ponies[cury + panely]
|
line = ponies[cury + panely]
|
||||||
if os.path.islink((ponydir + '/' + line + '.pony').replace('//', '/')):
|
if os.path.islink((ponydir + '/' + line + '.pony').replace('//', '/')):
|
||||||
line = '\033[34m%s\033[39m' % ((line + ' ' * panelw)[:panelw])
|
line = '\[[34m%s\[[39m' % ((line + ' ' * panelw)[:panelw])
|
||||||
else:
|
else:
|
||||||
line = (line + ' ' * panelw)[:panelw]
|
line = (line + ' ' * panelw)[:panelw]
|
||||||
print('\033[%i;%iH\033[%im%s\033[0m' % (cury, panelx + 1, 1 if panely + cury - 1 == ponyindex else 0, line), end='')
|
print('\[[%i;%iH\[[%im%s\[[0m' % (cury, panelx + 1, 1 if panely + cury - 1 == ponyindex else 0, line), end='')
|
||||||
|
|
||||||
sys.stdout.buffer.flush()
|
fileios.stdout.buffer.flush()
|
||||||
if stored is None:
|
if stored is None:
|
||||||
d = sys.stdin.read(1)
|
d = fileio.stdin.read(1)
|
||||||
else:
|
else:
|
||||||
d = stored
|
d = stored
|
||||||
stored = None
|
stored = None
|
||||||
|
@ -409,20 +410,20 @@ class PonysayTool():
|
||||||
elif ord(d) == ord('Q') - ord('@'):
|
elif ord(d) == ord('Q') - ord('@'):
|
||||||
break
|
break
|
||||||
elif ord(d) == ord('X') - ord('@'):
|
elif ord(d) == ord('X') - ord('@'):
|
||||||
if ord(sys.stdin.read(1)) == ord('C') - ord('@'):
|
if ord(fileio.stdin.read(1)) == ord('C') - ord('@'):
|
||||||
break
|
break
|
||||||
elif d == '\033':
|
elif d == '\[':
|
||||||
d = sys.stdin.read(1)
|
d = fileio.stdin.read(1)
|
||||||
if d == '[':
|
if d == '[':
|
||||||
d = sys.stdin.read(1)
|
d = fileio.stdin.read(1)
|
||||||
if d == 'A': stored = chr(ord('P') - ord('@')) if (not quotes) and (not info) else 'W'
|
if d == 'A': stored = chr(ord('P') - ord('@')) if (not quotes) and (not info) else 'W'
|
||||||
elif d == 'B': stored = chr(ord('N') - ord('@')) if (not quotes) and (not info) else 'S'
|
elif d == 'B': stored = chr(ord('N') - ord('@')) if (not quotes) and (not info) else 'S'
|
||||||
elif d == 'C': stored = chr(ord('N') - ord('@')) if (not quotes) and (not info) else 'D'
|
elif d == 'C': stored = chr(ord('N') - ord('@')) if (not quotes) and (not info) else 'D'
|
||||||
elif d == 'D': stored = chr(ord('P') - ord('@')) if (not quotes) and (not info) else 'A'
|
elif d == 'D': stored = chr(ord('P') - ord('@')) if (not quotes) and (not info) else 'A'
|
||||||
elif d == '1':
|
elif d == '1':
|
||||||
if sys.stdin.read(1) == ';':
|
if fileio.stdin.read(1) == ';':
|
||||||
if sys.stdin.read(1) == '5':
|
if fileio.stdin.read(1) == '5':
|
||||||
d = sys.stdin.read(1)
|
d = fileio.stdin.read(1)
|
||||||
if d == 'A': stored = 'W'
|
if d == 'A': stored = 'W'
|
||||||
elif d == 'B': stored = 'S'
|
elif d == 'B': stored = 'S'
|
||||||
elif d == 'C': stored = 'D'
|
elif d == 'C': stored = 'D'
|
||||||
|
@ -446,7 +447,7 @@ class PonysayTool():
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
return [self.value] if key == self.key else None
|
return [self.value] if key == self.key else None
|
||||||
def __contains__(self, key):
|
def __contains__(self, key):
|
||||||
return key == self.key;
|
return key == self.key
|
||||||
|
|
||||||
class StringInputStream():
|
class StringInputStream():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -464,36 +465,36 @@ class PonysayTool():
|
||||||
def isatty(self):
|
def isatty(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
stdout = sys.stdout
|
stdout = fileio.stdout
|
||||||
term = os.environ['TERM']
|
term = os.environ['TERM']
|
||||||
os.environ['TERM'] = 'linux'
|
os.environ['TERM'] = 'linux'
|
||||||
|
|
||||||
sys.stdout = StringInputStream()
|
fileio.stdout = StringInputStream()
|
||||||
ponysay = Ponysay()
|
ponysay = Ponysay()
|
||||||
ponysay.run(PhonyArgParser('--onelist', None))
|
ponysay.run(PhonyArgParser('--onelist', None))
|
||||||
stdponies = sys.stdout.buf[:-1].split('\n')
|
stdponies = fileio.stdout.buf[:-1].split('\n')
|
||||||
|
|
||||||
sys.stdout = StringInputStream()
|
fileio.stdout = StringInputStream()
|
||||||
ponysay = Ponysay()
|
ponysay = Ponysay()
|
||||||
ponysay.run(PhonyArgParser('++onelist', None))
|
ponysay.run(PhonyArgParser('++onelist', None))
|
||||||
extraponies = sys.stdout.buf[:-1].split('\n')
|
extraponies = fileio.stdout.buf[:-1].split('\n')
|
||||||
|
|
||||||
for pony in stdponies:
|
for pony in stdponies:
|
||||||
printerr('Genering standard kmspony: %s' % pony)
|
printerr('Genering standard kmspony: %s' % pony)
|
||||||
sys.stderr.buffer.flush();
|
fileio.stderr.buffer.flush()
|
||||||
sys.stdout = StringInputStream()
|
fileio.stdout = StringInputStream()
|
||||||
ponysay = Ponysay()
|
ponysay = Ponysay()
|
||||||
ponysay.run(PhonyArgParser('--pony', pony))
|
ponysay.run(PhonyArgParser('--pony', pony))
|
||||||
|
|
||||||
for pony in extraponies:
|
for pony in extraponies:
|
||||||
printerr('Genering extra kmspony: %s' % pony)
|
printerr('Genering extra kmspony: %s' % pony)
|
||||||
sys.stderr.buffer.flush();
|
fileio.stderr.buffer.flush()
|
||||||
sys.stdout = StringInputStream()
|
fileio.stdout = StringInputStream()
|
||||||
ponysay = Ponysay()
|
ponysay = Ponysay()
|
||||||
ponysay.run(PhonyArgParser('++pony', pony))
|
ponysay.run(PhonyArgParser('++pony', pony))
|
||||||
|
|
||||||
os.environ['TERM'] = term
|
os.environ['TERM'] = term
|
||||||
sys.stdout = stdout
|
fileio.stdout = stdout
|
||||||
|
|
||||||
|
|
||||||
def generateDimensions(self, ponydir, ponies = None):
|
def generateDimensions(self, ponydir, ponies = None):
|
||||||
|
@ -523,8 +524,8 @@ class PonysayTool():
|
||||||
return [('none' if self.balloon else None)]
|
return [('none' if self.balloon else None)]
|
||||||
return None
|
return None
|
||||||
def __contains__(self, key):
|
def __contains__(self, key):
|
||||||
return key in ('-f', '-W', '-b');
|
return key in ('-f', '-W', '-b')
|
||||||
stdout = sys.stdout
|
stdout = fileio.stdout
|
||||||
class StringInputStream():
|
class StringInputStream():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.buf = ''
|
self.buf = ''
|
||||||
|
@ -540,7 +541,7 @@ class PonysayTool():
|
||||||
pass
|
pass
|
||||||
def isatty(self):
|
def isatty(self):
|
||||||
return True
|
return True
|
||||||
sys.stdout = StringInputStream()
|
fileio.stdout = StringInputStream()
|
||||||
ponysay = Ponysay()
|
ponysay = Ponysay()
|
||||||
ponysay.run(PhonyArgParser(True))
|
ponysay.run(PhonyArgParser(True))
|
||||||
printpony = sys.stdout.buf[:-1].split('\n')
|
printpony = sys.stdout.buf[:-1].split('\n')
|
||||||
|
@ -697,7 +698,7 @@ class PonysayTool():
|
||||||
if key == '-W': return ['n']
|
if key == '-W': return ['n']
|
||||||
return None
|
return None
|
||||||
def __contains__(self, key):
|
def __contains__(self, key):
|
||||||
return key in ('-f', '-W');
|
return key in ('-f', '-W')
|
||||||
|
|
||||||
|
|
||||||
data = {}
|
data = {}
|
||||||
|
@ -750,7 +751,7 @@ class PonysayTool():
|
||||||
printpony = sys.stdout.buf[:-1].split('\n')
|
printpony = sys.stdout.buf[:-1].split('\n')
|
||||||
sys.stdout = stdout
|
sys.stdout = stdout
|
||||||
|
|
||||||
preprint = '\033[H\033[2J'
|
preprint = '\[[H\[[2J'
|
||||||
if printpony[0].startswith(preprint):
|
if printpony[0].startswith(preprint):
|
||||||
printpony[0] = printpony[0][len(preprint):]
|
printpony[0] = printpony[0][len(preprint):]
|
||||||
ponyheight = len(printpony) - len(ponyfile.split('\n')) + 1 - 2 # using fallback balloon
|
ponyheight = len(printpony) - len(ponyfile.split('\n')) + 1 - 2 # using fallback balloon
|
||||||
|
@ -765,8 +766,8 @@ class PonysayTool():
|
||||||
termsize = [int(item) for item in termsize]
|
termsize = [int(item) for item in termsize]
|
||||||
break
|
break
|
||||||
|
|
||||||
AUTO_PUSH = '\033[01010~'
|
AUTO_PUSH = '\[[01010~'
|
||||||
AUTO_POP = '\033[10101~'
|
AUTO_POP = '\[[10101~'
|
||||||
modprintpony = '\n'.join(printpony).replace('\n', AUTO_PUSH + '\n' + AUTO_POP)
|
modprintpony = '\n'.join(printpony).replace('\n', AUTO_PUSH + '\n' + AUTO_POP)
|
||||||
colourstack = ColourStack(AUTO_PUSH, AUTO_POP)
|
colourstack = ColourStack(AUTO_PUSH, AUTO_POP)
|
||||||
buf = ''
|
buf = ''
|
||||||
|
@ -774,12 +775,12 @@ class PonysayTool():
|
||||||
buf += c + colourstack.feed(c)
|
buf += c + colourstack.feed(c)
|
||||||
modprintpony = buf.replace(AUTO_PUSH, '').replace(AUTO_POP, '')
|
modprintpony = buf.replace(AUTO_PUSH, '').replace(AUTO_POP, '')
|
||||||
|
|
||||||
printpony = [('\033[21;39;49;0m%s%s\033[21;39;49;0m' % (' ' * (termsize[1] - ponywidth), line)) for line in modprintpony.split('\n')]
|
printpony = [('\[[22;39;49;0m%s%s\[[22;39;49;0m' % (' ' * (termsize[1] - ponywidth), line)) for line in modprintpony.split('\n')]
|
||||||
|
|
||||||
|
|
||||||
print(preprint, end='')
|
print(preprint, end='')
|
||||||
print('\n'.join(printpony), end='')
|
print('\n'.join(printpony), end='')
|
||||||
print('\033[H', end='')
|
print('\[[H', end='')
|
||||||
print('Please see the info manual for details on how to fill out this form')
|
print('Please see the info manual for details on how to fill out this form')
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
@ -885,17 +886,17 @@ class TextArea(): # TODO support small screens (This is being work on in GNU-Po
|
||||||
killptr = None
|
killptr = None
|
||||||
|
|
||||||
def status(text):
|
def status(text):
|
||||||
print('\033[%i;%iH\033[7m%s\033[27m\033[%i;%iH' % (termh - 1, 1, ' (' + text + ') ' + '-' * (termw - len(' (' + text + ') ')), self.top + y, innerleft + x), end='')
|
print('\[[%i;%iH\[[7m%s\[[27m\[[%i;%iH' % (termh - 1, 1, ' (' + text + ') ' + '-' * (termw - len(' (' + text + ') ')), self.top + y, innerleft + x), end='')
|
||||||
|
|
||||||
status('unmodified')
|
status('unmodified')
|
||||||
|
|
||||||
print('\033[%i;%iH' % (self.top, innerleft), end='')
|
print('\[[%i;%iH' % (self.top, innerleft), end='')
|
||||||
|
|
||||||
def alert(text):
|
def alert(text):
|
||||||
if text is None:
|
if text is None:
|
||||||
alert('')
|
alert('')
|
||||||
else:
|
else:
|
||||||
print('\033[%i;%iH\033[2K%s\033[%i;%iH' % (termh, 1, text, self.top + y, innerleft + x), end='')
|
print('\[[%i;%iH\[[2K%s\[[%i;%iH' % (termh, 1, text, self.top + y, innerleft + x), end='')
|
||||||
|
|
||||||
modified = False
|
modified = False
|
||||||
override = False
|
override = False
|
||||||
|
@ -904,28 +905,28 @@ class TextArea(): # TODO support small screens (This is being work on in GNU-Po
|
||||||
stored = chr(ord('L') - ord('@'))
|
stored = chr(ord('L') - ord('@'))
|
||||||
alerted = False
|
alerted = False
|
||||||
edited = False
|
edited = False
|
||||||
print('\033[%i;%iH' % (self.top + y, innerleft + x), end='')
|
print('\[[%i;%iH' % (self.top + y, innerleft + x), end='')
|
||||||
while True:
|
while True:
|
||||||
if (oldmark is not None) and (oldmark >= 0):
|
if (oldmark is not None) and (oldmark >= 0):
|
||||||
if oldmark < oldx:
|
if oldmark < oldx:
|
||||||
print('\033[%i;%iH\033[49m%s\033[%i;%iH' % (self.top + oldy, innerleft + oldmark, datalines[oldy][oldmark : oldx], self.top + y, innerleft + x), end='')
|
print('\[[%i;%iH\[[49m%s\[[%i;%iH' % (self.top + oldy, innerleft + oldmark, datalines[oldy][oldmark : oldx], self.top + y, innerleft + x), end='')
|
||||||
elif oldmark > oldx:
|
elif oldmark > oldx:
|
||||||
print('\033[%i;%iH\033[49m%s\033[%i;%iH' % (self.top + oldy, innerleft + oldx, datalines[oldy][oldx : oldmark], self.top + y, innerleft + x), end='')
|
print('\[[%i;%iH\[[49m%s\[[%i;%iH' % (self.top + oldy, innerleft + oldx, datalines[oldy][oldx : oldmark], self.top + y, innerleft + x), end='')
|
||||||
if (mark is not None) and (mark >= 0):
|
if (mark is not None) and (mark >= 0):
|
||||||
if mark < x:
|
if mark < x:
|
||||||
print('\033[%i;%iH\033[44;37m%s\033[49;39m\033[%i;%iH' % (self.top + y, innerleft + mark, datalines[y][mark : x], self.top + y, innerleft + x), end='')
|
print('\[[%i;%iH\[[44;37m%s\[[49;39m\[[%i;%iH' % (self.top + y, innerleft + mark, datalines[y][mark : x], self.top + y, innerleft + x), end='')
|
||||||
elif mark > x:
|
elif mark > x:
|
||||||
print('\033[%i;%iH\033[44;37m%s\033[49;39m\033[%i;%iH' % (self.top + y, innerleft + x, datalines[y][x : mark], self.top + y, innerleft + x), end='')
|
print('\[[%i;%iH\[[44;37m%s\[[49;39m\[[%i;%iH' % (self.top + y, innerleft + x, datalines[y][x : mark], self.top + y, innerleft + x), end='')
|
||||||
if y != oldy:
|
if y != oldy:
|
||||||
if (oldy > 0) and (leftlines[oldy - 1] == leftlines[oldy]) and (leftlines[oldy] == leftlines[-1]):
|
if (oldy > 0) and (leftlines[oldy - 1] == leftlines[oldy]) and (leftlines[oldy] == leftlines[-1]):
|
||||||
print('\033[%i;%iH\033[34m%s\033[39m' % (self.top + oldy, self.left, '>'), end='')
|
print('\[[%i;%iH\[[34m%s\[[39m' % (self.top + oldy, self.left, '>'), end='')
|
||||||
else:
|
else:
|
||||||
print('\033[%i;%iH\033[34m%s:\033[39m' % (self.top + oldy, self.left, leftlines[oldy]), end='')
|
print('\[[%i;%iH\[[34m%s:\[[39m' % (self.top + oldy, self.left, leftlines[oldy]), end='')
|
||||||
if (y > 0) and (leftlines[y - 1] == leftlines[y]) and (leftlines[y] == leftlines[-1]):
|
if (y > 0) and (leftlines[y - 1] == leftlines[y]) and (leftlines[y] == leftlines[-1]):
|
||||||
print('\033[%i;%iH\033[1;34m%s\033[21;39m' % (self.top + y, self.left, '>'), end='')
|
print('\[[%i;%iH\[[1;34m%s\[[22;39m' % (self.top + y, self.left, '>'), end='')
|
||||||
else:
|
else:
|
||||||
print('\033[%i;%iH\033[1;34m%s:\033[21;39m' % (self.top + y, self.left, leftlines[y]), end='')
|
print('\[[%i;%iH\[[1;34m%s:\[[22;39m' % (self.top + y, self.left, leftlines[y]), end='')
|
||||||
print('\033[%i;%iH' % (self.top + y, innerleft + x), end='')
|
print('\[[%i;%iH' % (self.top + y, innerleft + x), end='')
|
||||||
(oldy, oldx, oldmark) = (y, x, mark)
|
(oldy, oldx, oldmark) = (y, x, mark)
|
||||||
if edited:
|
if edited:
|
||||||
edited = False
|
edited = False
|
||||||
|
@ -980,10 +981,10 @@ class TextArea(): # TODO support small screens (This is being work on in GNU-Po
|
||||||
mark = None
|
mark = None
|
||||||
killptr = len(killring) - 1
|
killptr = len(killring) - 1
|
||||||
yanked = killring[killptr]
|
yanked = killring[killptr]
|
||||||
print('\033[%i;%iH%s' % (self.top + y, innerleft + x, yanked + datalines[y][x:]), end='')
|
print('\[[%i;%iH%s' % (self.top + y, innerleft + x, yanked + datalines[y][x:]), end='')
|
||||||
datalines[y] = datalines[y][:x] + yanked + datalines[y][x:]
|
datalines[y] = datalines[y][:x] + yanked + datalines[y][x:]
|
||||||
x += len(yanked)
|
x += len(yanked)
|
||||||
print('\033[%i;%iH' % (self.top + y, innerleft + x), end='')
|
print('\[[%i;%iH' % (self.top + y, innerleft + x), end='')
|
||||||
elif ord(d) == ord('X') - ord('@'):
|
elif ord(d) == ord('X') - ord('@'):
|
||||||
alert('C-x')
|
alert('C-x')
|
||||||
alerted = True
|
alerted = True
|
||||||
|
@ -1034,7 +1035,7 @@ class TextArea(): # TODO support small screens (This is being work on in GNU-Po
|
||||||
datalines[y] = dataline = dataline[:x - removed] + dataline[x:]
|
datalines[y] = dataline = dataline[:x - removed] + dataline[x:]
|
||||||
x -= removed
|
x -= removed
|
||||||
mark = None
|
mark = None
|
||||||
print('\033[%i;%iH%s%s\033[%i;%iH' % (self.top + y, innerleft, dataline, ' ' * removed, self.top + y, innerleft + x), end='')
|
print('\[[%i;%iH%s%s\[[%i;%iH' % (self.top + y, innerleft, dataline, ' ' * removed, self.top + y, innerleft + x), end='')
|
||||||
edited = True
|
edited = True
|
||||||
elif ord(d) < ord(' '):
|
elif ord(d) < ord(' '):
|
||||||
if ord(d) == ord('P') - ord('@'):
|
if ord(d) == ord('P') - ord('@'):
|
||||||
|
@ -1055,14 +1056,14 @@ class TextArea(): # TODO support small screens (This is being work on in GNU-Po
|
||||||
elif ord(d) == ord('F') - ord('@'):
|
elif ord(d) == ord('F') - ord('@'):
|
||||||
if x < len(datalines[y]):
|
if x < len(datalines[y]):
|
||||||
x += 1
|
x += 1
|
||||||
print('\033[C', end='')
|
print('\[[C', end='')
|
||||||
else:
|
else:
|
||||||
alert('At end')
|
alert('At end')
|
||||||
alerted = True
|
alerted = True
|
||||||
elif ord(d) == ord('B') - ord('@'):
|
elif ord(d) == ord('B') - ord('@'):
|
||||||
if x > 0:
|
if x > 0:
|
||||||
x -= 1
|
x -= 1
|
||||||
print('\033[D', end='')
|
print('\[[D', end='')
|
||||||
else:
|
else:
|
||||||
alert('At beginning')
|
alert('At beginning')
|
||||||
alerted = True
|
alerted = True
|
||||||
|
@ -1074,17 +1075,17 @@ class TextArea(): # TODO support small screens (This is being work on in GNU-Po
|
||||||
x = 0
|
x = 0
|
||||||
stored = chr(ord('L') - ord('@'))
|
stored = chr(ord('L') - ord('@'))
|
||||||
elif ord(d) == ord('L') - ord('@'):
|
elif ord(d) == ord('L') - ord('@'):
|
||||||
empty = '\033[0m' + (' ' * self.width + '\n') * len(datalines)
|
empty = '\[[0m' + (' ' * self.width + '\n') * len(datalines)
|
||||||
print('\033[%i;%iH%s' % (self.top, self.left, empty), end='')
|
print('\[[%i;%iH%s' % (self.top, self.left, empty), end='')
|
||||||
for row in range(0, len(leftlines)):
|
for row in range(0, len(leftlines)):
|
||||||
leftline = leftlines[row] + ':'
|
leftline = leftlines[row] + ':'
|
||||||
if (leftlines[row - 1] == leftlines[row]) and (leftlines[row] == leftlines[-1]):
|
if (leftlines[row - 1] == leftlines[row]) and (leftlines[row] == leftlines[-1]):
|
||||||
leftline = '>'
|
leftline = '>'
|
||||||
print('\033[%i;%iH\033[%s34m%s\033[%s39m' % (self.top + row, self.left, '1;' if row == y else '', leftline, '21;' if row == y else ''), end='')
|
print('\[[%i;%iH\[[%s34m%s\[[%s39m' % (self.top + row, self.left, '1;' if row == y else '', leftline, '22;' if row == y else ''), end='')
|
||||||
for row in range(0, len(datalines)):
|
for row in range(0, len(datalines)):
|
||||||
print('\033[%i;%iH%s\033[49m' % (self.top + row, innerleft, datalines[row]), end='')
|
print('\[[%i;%iH%s\[[49m' % (self.top + row, innerleft, datalines[row]), end='')
|
||||||
print('\033[%i;%iH' % (self.top + y, innerleft + x), end='')
|
print('\[[%i;%iH' % (self.top + y, innerleft + x), end='')
|
||||||
elif d == '\033':
|
elif d == '\[':
|
||||||
d = sys.stdin.read(1)
|
d = sys.stdin.read(1)
|
||||||
if d == '[':
|
if d == '[':
|
||||||
d = sys.stdin.read(1)
|
d = sys.stdin.read(1)
|
||||||
|
@ -1119,7 +1120,7 @@ class TextArea(): # TODO support small screens (This is being work on in GNU-Po
|
||||||
alerted = True
|
alerted = True
|
||||||
continue
|
continue
|
||||||
datalines[y] = dataline = dataline[:x] + dataline[x + removed:]
|
datalines[y] = dataline = dataline[:x] + dataline[x + removed:]
|
||||||
print('\033[%i;%iH%s%s\033[%i;%iH' % (self.top + y, innerleft, dataline, ' ' * removed, self.top + y, innerleft + x), end='')
|
print('\[[%i;%iH%s%s\[[%i;%iH' % (self.top + y, innerleft, dataline, ' ' * removed, self.top + y, innerleft + x), end='')
|
||||||
mark = None
|
mark = None
|
||||||
edited = True
|
edited = True
|
||||||
else:
|
else:
|
||||||
|
@ -1150,18 +1151,18 @@ class TextArea(): # TODO support small screens (This is being work on in GNU-Po
|
||||||
additional = len(killring[killptr]) - len(yanked)
|
additional = len(killring[killptr]) - len(yanked)
|
||||||
x += additional
|
x += additional
|
||||||
datalines[y] = dataline
|
datalines[y] = dataline
|
||||||
print('\033[%i;%iH%s%s\033[%i;%iH' % (self.top + y, innerleft, dataline, ' ' * max(0, -additional), self.top + y, innerleft + x), end='')
|
print('\[[%i;%iH%s%s\[[%i;%iH' % (self.top + y, innerleft, dataline, ' ' * max(0, -additional), self.top + y, innerleft + x), end='')
|
||||||
else:
|
else:
|
||||||
stored = chr(ord('Y') - ord('@'))
|
stored = chr(ord('Y') - ord('@'))
|
||||||
else:
|
else:
|
||||||
stored = chr(ord('Y') - ord('@'))
|
stored = chr(ord('Y') - ord('@'))
|
||||||
elif d == 'O':
|
elif d == 'O':
|
||||||
d = sys.stdin.read(1)
|
d = fileio.stdin.read(1)
|
||||||
if d == 'H':
|
if d == 'H':
|
||||||
x = 0
|
x = 0
|
||||||
elif d == 'F':
|
elif d == 'F':
|
||||||
x = len(datalines[y])
|
x = len(datalines[y])
|
||||||
print('\033[%i;%iH' % (self.top + y, innerleft + x), end='')
|
print('\[[%i;%iH' % (self.top + y, innerleft + x), end='')
|
||||||
elif d == '\n':
|
elif d == '\n':
|
||||||
stored = chr(ord('N') - ord('@'))
|
stored = chr(ord('N') - ord('@'))
|
||||||
else:
|
else:
|
||||||
|
@ -1172,7 +1173,7 @@ class TextArea(): # TODO support small screens (This is being work on in GNU-Po
|
||||||
if (not override) or (x == len(dataline)):
|
if (not override) or (x == len(dataline)):
|
||||||
print(insert + dataline[x:], end='')
|
print(insert + dataline[x:], end='')
|
||||||
if len(dataline) - x > 0:
|
if len(dataline) - x > 0:
|
||||||
print('\033[%iD' % (len(dataline) - x), end='')
|
print('\[[%iD' % (len(dataline) - x), end='')
|
||||||
datalines[y] = dataline[:x] + insert + dataline[x:]
|
datalines[y] = dataline[:x] + insert + dataline[x:]
|
||||||
if (mark is not None) and (mark >= 0):
|
if (mark is not None) and (mark >= 0):
|
||||||
if mark >= x:
|
if mark >= x:
|
||||||
|
@ -1185,46 +1186,46 @@ class TextArea(): # TODO support small screens (This is being work on in GNU-Po
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
HOME = os.environ['HOME'] if 'HOME' in os.environ else os.path.expanduser('~')
|
let HOME = os.environ['HOME'] if 'HOME' in os.environ else os.path.expanduser('~')
|
||||||
'''
|
'''
|
||||||
The user's home directory
|
The user's home directory
|
||||||
'''
|
'''
|
||||||
|
|
||||||
pipelinein = not sys.stdin.isatty()
|
let pipelinein = not os.isatty(0)
|
||||||
'''
|
'''
|
||||||
Whether stdin is piped
|
Whether stdin is piped
|
||||||
'''
|
'''
|
||||||
|
|
||||||
pipelineout = not sys.stdout.isatty()
|
let pipelineout = not os.isatty(1)
|
||||||
'''
|
'''
|
||||||
Whether stdout is piped
|
Whether stdout is piped
|
||||||
'''
|
'''
|
||||||
|
|
||||||
pipelineerr = not sys.stderr.isatty()
|
let pipelineerr = not os.isatty(2)
|
||||||
'''
|
'''
|
||||||
Whether stderr is piped
|
Whether stderr is piped
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
usage_program = '\033[34;1mponysay-tool\033[21;39m'
|
let usage_program = '\[[34;1mponysay-tool\[[22;39m'
|
||||||
|
|
||||||
usage = '\n'.join(['%s %s' % (usage_program, '(--help | --version | --kms)'),
|
let usage = '\n'.join([' '.join((usage_program, '(--help | --version | --kms)')),
|
||||||
'%s %s' % (usage_program, '(--edit | --edit-rm) \033[33mPONY-FILE\033[39m'),
|
' '.join((usage_program, '(--edit | --edit-rm) \[[33mPONY-FILE\[[39m')),
|
||||||
'%s %s' % (usage_program, '--edit-stash \033[33mPONY-FILE\033[39m > \033[33mSTASH-FILE\033[39m'),
|
' '.join((usage_program, '--edit-stash \[[33mPONY-FILE\[[39m > \[[33mSTASH-FILE\[[39m')),
|
||||||
'%s %s' % (usage_program, '--edit-apply \033[33mPONY-FILE\033[39m < \033[33mSTASH-FILE\033[39m'),
|
' '.join((usage_program, '--edit-apply \[[33mPONY-FILE\[[39m < \[[33mSTASH-FILE\[[39m')),
|
||||||
'%s %s' % (usage_program, '(--dimensions | --metadata) \033[33mPONY-DIR\033[39m'),
|
' '.join((usage_program, '(--dimensions | --metadata) \[[33mPONY-DIR\[[39m')),
|
||||||
'%s %s' % (usage_program, '--browse \033[33mPONY-DIR\033[39m [-r \033[33mRESTRICTION\033[39m]*'),
|
' '.join((usage_program, '--browse \[[33mPONY-DIR\[[39m [-r \[[33mRESTRICTION\[[39m]*')),
|
||||||
])
|
])
|
||||||
|
|
||||||
usage = usage.replace('\033[', '\0')
|
usage = usage.replace('\[[', 'あ')
|
||||||
for sym in ('[', ']', '(', ')', '|', '...', '*'):
|
for sym in ('[', ']', '(', ')', '|', '...', '*'):
|
||||||
usage = usage.replace(sym, '\033[2m' + sym + '\033[22m')
|
usage = usage.replace(sym, '\[[2m' + sym + '\[[22m')
|
||||||
usage = usage.replace('\0', '\033[')
|
usage = usage.replace('あ', '\[[')
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Argument parsing
|
Argument parsing
|
||||||
'''
|
'''
|
||||||
opts = ArgParser(program = 'ponysay-tool',
|
let opts = ArgParser(program = 'ponysay-tool',
|
||||||
description = 'Tool chest for ponysay',
|
description = 'Tool chest for ponysay',
|
||||||
usage = usage,
|
usage = usage,
|
||||||
longdescription = None)
|
longdescription = None)
|
||||||
|
@ -1244,7 +1245,7 @@ opts.add_argumented( ['--edit-rm'], arg = 'PONY-FILE', help = 'Remove
|
||||||
opts.add_argumented( ['--edit-apply'], arg = 'PONY-FILE', help = 'Apply metadata from stdin to a pony file')
|
opts.add_argumented( ['--edit-apply'], arg = 'PONY-FILE', help = 'Apply metadata from stdin to a pony file')
|
||||||
opts.add_argumented( ['--edit-stash'], arg = 'PONY-FILE', help = 'Print applyable metadata from a pony file')
|
opts.add_argumented( ['--edit-stash'], arg = 'PONY-FILE', help = 'Print applyable metadata from a pony file')
|
||||||
|
|
||||||
unrecognised = not opts.parse()
|
let unrecognised = not opts.parse()
|
||||||
'''
|
'''
|
||||||
Whether at least one unrecognised option was used
|
Whether at least one unrecognised option was used
|
||||||
'''
|
'''
|
|
@ -29,8 +29,7 @@ that line ‘FREE: yes’, is included inside the image between two ‘$$$’
|
||||||
lines and the ‘FREE’ is and upper case and directly followed by
|
lines and the ‘FREE’ is and upper case and directly followed by
|
||||||
the colon.
|
the colon.
|
||||||
'''
|
'''
|
||||||
from common import *
|
from ponysay.common import printerr, printinfo, gettermsize, endswith
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimised Java, may not be the nicest, or even fast, Python code
|
class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimised Java, may not be the nicest, or even fast, Python code
|
||||||
|
@ -74,18 +73,18 @@ class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimise
|
||||||
for y in range(0, 128):
|
for y in range(0, 128):
|
||||||
self.M[y] = [0] * 128
|
self.M[y] = [0] * 128
|
||||||
self.M[y][0] = y
|
self.M[y][0] = y
|
||||||
m0 = self.M[0]
|
let m0 = self.M[0]
|
||||||
x = 127
|
let x = 127
|
||||||
while x > -1:
|
while x > -1:
|
||||||
m0[x] = x
|
m0[x] = x
|
||||||
x -= 1
|
x -= 1
|
||||||
|
|
||||||
previous = ''
|
let previous = ''
|
||||||
self.dictionary[-1] = previous;
|
self.dictionary[-1] = previous
|
||||||
|
|
||||||
if ending is not None:
|
if ending is not None:
|
||||||
for directory in directories:
|
for directory in directories:
|
||||||
files = os.listdir(directory)
|
let files = os.listdir(directory)
|
||||||
files.sort()
|
files.sort()
|
||||||
for filename in files:
|
for filename in files:
|
||||||
if (not endswith(filename, ending)) or (len(filename) - len(ending) > 127):
|
if (not endswith(filename, ending)) or (len(filename) - len(ending) > 127):
|
||||||
|
@ -108,7 +107,7 @@ class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimise
|
||||||
previous = proper
|
previous = proper
|
||||||
self.reusable[self.dictionaryEnd] = prevCommon
|
self.reusable[self.dictionaryEnd] = prevCommon
|
||||||
else:
|
else:
|
||||||
files = directories
|
let files = directories
|
||||||
files.sort()
|
files.sort()
|
||||||
for proper in files:
|
for proper in files:
|
||||||
if len(proper) > 127:
|
if len(proper) > 127:
|
||||||
|
@ -167,20 +166,20 @@ class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimise
|
||||||
@param used:str The word to correct, it must satisfy all restrictions
|
@param used:str The word to correct, it must satisfy all restrictions
|
||||||
'''
|
'''
|
||||||
self.closestDistance = 0x7FFFFFFF
|
self.closestDistance = 0x7FFFFFFF
|
||||||
previous = self.dictionary[-1]
|
let previous = self.dictionary[-1]
|
||||||
prevLen = 0
|
let prevLen = 0
|
||||||
usedLen = len(used)
|
let usedLen = len(used)
|
||||||
|
|
||||||
proper = None
|
let proper = None
|
||||||
prevCommon = 0
|
let prevCommon = 0
|
||||||
|
|
||||||
d = len(self.dictionary) - 1
|
let d = len(self.dictionary) - 1
|
||||||
while d > self.dictionaryEnd:
|
while d > self.dictionaryEnd:
|
||||||
d -= 1
|
d -= 1
|
||||||
proper = self.dictionary[d]
|
proper = self.dictionary[d]
|
||||||
if abs(len(proper) - usedLen) <= self.closestDistance:
|
if abs(len(proper) - usedLen) <= self.closestDistance:
|
||||||
if previous == self.dictionary[d + 1]:
|
if previous == self.dictionary[d + 1]:
|
||||||
prevCommon = self.reusable[d];
|
prevCommon = self.reusable[d]
|
||||||
else:
|
else:
|
||||||
prevCommon = min(prevLen, len(proper))
|
prevCommon = min(prevLen, len(proper))
|
||||||
for i in range(0, prevCommon):
|
for i in range(0, prevCommon):
|
||||||
|
@ -188,8 +187,8 @@ class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimise
|
||||||
prevCommon = i
|
prevCommon = i
|
||||||
break
|
break
|
||||||
|
|
||||||
skip = min(prevLen, len(proper))
|
let skip = min(prevLen, len(proper))
|
||||||
i = prevCommon
|
let i = prevCommon
|
||||||
while i < skip:
|
while i < skip:
|
||||||
for u in range(0, usedLen):
|
for u in range(0, usedLen):
|
||||||
if (used[u] == previous[i]) or (used[u] == proper[i]):
|
if (used[u] == previous[i]) or (used[u] == proper[i]):
|
||||||
|
@ -197,13 +196,13 @@ class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimise
|
||||||
break
|
break
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
common = min(skip, min(usedLen, len(proper)))
|
let common = min(skip, min(usedLen, len(proper)))
|
||||||
for i in range(0, common):
|
for i in range(0, common):
|
||||||
if used[i] != proper[i]:
|
if used[i] != proper[i]:
|
||||||
common = i
|
common = i
|
||||||
break
|
break
|
||||||
|
|
||||||
distance = self.__distance(proper, skip, len(proper), used, common, usedLen)
|
let distance = self.__distance(proper, skip, len(proper), used, common, usedLen)
|
||||||
|
|
||||||
if self.closestDistance > distance:
|
if self.closestDistance > distance:
|
||||||
self.closestDistance = distance
|
self.closestDistance = distance
|
||||||
|
@ -211,7 +210,7 @@ class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimise
|
||||||
elif self.closestDistance == distance:
|
elif self.closestDistance == distance:
|
||||||
self.corrections.append(proper)
|
self.corrections.append(proper)
|
||||||
|
|
||||||
previous = proper;
|
previous = proper
|
||||||
if distance >= 0x7FFFFF00:
|
if distance >= 0x7FFFFF00:
|
||||||
prevLen = distance & 255
|
prevLen = distance & 255
|
||||||
else:
|
else:
|
|
@ -29,7 +29,7 @@ that line ‘FREE: yes’, is included inside the image between two ‘$$$’
|
||||||
lines and the ‘FREE’ is and upper case and directly followed by
|
lines and the ‘FREE’ is and upper case and directly followed by
|
||||||
the colon.
|
the colon.
|
||||||
'''
|
'''
|
||||||
from common import *
|
from ponysay.common import printerr, printinfo, gettermsize, endswith
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ class UCS():
|
||||||
@param char:chr The character to test
|
@param char:chr The character to test
|
||||||
@return :bool Whether the character is a combining character
|
@return :bool Whether the character is a combining character
|
||||||
'''
|
'''
|
||||||
o = ord(char)
|
let o = ord(char)
|
||||||
if (0x0300 <= o) and (o <= 0x036F): return True
|
if (0x0300 <= o) and (o <= 0x036F): return True
|
||||||
if (0x20D0 <= o) and (o <= 0x20FF): return True
|
if (0x20D0 <= o) and (o <= 0x20FF): return True
|
||||||
if (0x1DC0 <= o) and (o <= 0x1DFF): return True
|
if (0x1DC0 <= o) and (o <= 0x1DFF): return True
|
||||||
|
@ -62,7 +62,7 @@ class UCS():
|
||||||
@param string:str A text to count combining characters in
|
@param string:str A text to count combining characters in
|
||||||
@return :int The number of combining characters in the string
|
@return :int The number of combining characters in the string
|
||||||
'''
|
'''
|
||||||
rc = 0
|
let rc = 0
|
||||||
for char in string:
|
for char in string:
|
||||||
if UCS.isCombining(char):
|
if UCS.isCombining(char):
|
||||||
rc += 1
|
rc += 1
|
Loading…
Reference in a new issue