mirror of
https://github.com/erkin/ponysay.git
synced 2025-02-12 07:46:44 +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/widths
|
||||
/*ponies/metadata
|
||||
/ponysay
|
||||
/bin/
|
||||
/obj/
|
||||
|
||||
|
|
|
@ -39,56 +39,57 @@ Authors:
|
|||
Jan Alexander "heftig" Steffens: Major contributor of the first implementation
|
||||
Kyah "L-four" Rindlisbacher: Patched the first implementation
|
||||
'''
|
||||
from common import *
|
||||
from argparser import *
|
||||
from ponysay import *
|
||||
|
||||
from ponysay.common import printerr, printinfo, gettermsize, endswith
|
||||
from ponysay.argparser import ArgParser
|
||||
from ponysay.ponysay import Ponysay
|
||||
import os
|
||||
import kuroko
|
||||
|
||||
|
||||
'''
|
||||
Start the program
|
||||
'''
|
||||
if __name__ == '__main__':
|
||||
istool = sys.argv[0]
|
||||
let istool = kuroko.argv[0]
|
||||
if os.sep in istool:
|
||||
istool = istool[istool.rfind(os.sep) + 1:]
|
||||
if os.extsep in istool:
|
||||
istool = istool[:istool.find(os.extsep)]
|
||||
istool = istool.endswith('-tool')
|
||||
if istool:
|
||||
from ponysaytool import * ## will start ponysay-tool
|
||||
exit(0)
|
||||
import ponysaytool
|
||||
os.exit(0)
|
||||
|
||||
isthink = sys.argv[0]
|
||||
let isthink = kuroko.argv[0]
|
||||
if os.sep in isthink:
|
||||
isthink = isthink[isthink.rfind(os.sep) + 1:]
|
||||
if os.extsep in isthink:
|
||||
isthink = isthink[:isthink.find(os.extsep)]
|
||||
isthink = isthink.endswith('think')
|
||||
|
||||
usage_saythink = '\033[34;1m(ponysay | ponythink)\033[21;39m'
|
||||
usage_common = '[-c] [-W\033[33mCOLUMN\033[39m] [-b\033[33mSTYLE\033[39m]'
|
||||
usage_listhelp = '(-l | -L | -B | +l | +L | -A | + A | -v | -h)'
|
||||
usage_file = '[-f\033[33mPONY\033[39m]* [[--] \033[33mmessage\033[39m]'
|
||||
usage_xfile = '(+f\033[33mPONY\033[39m)* [[--] \033[33mmessage\033[39m]'
|
||||
usage_afile = '(-F\033[33mPONY\033[39m)* [[--] \033[33mmessage\033[39m]'
|
||||
usage_quote = '(-q\033[33mPONY\033[39m)*'
|
||||
let usage_saythink = '\033[34;1m(ponysay | ponythink)\033[22;39m'
|
||||
let usage_common = '[-c] [-W\033[33mCOLUMN\033[39m] [-b\033[33mSTYLE\033[39m]'
|
||||
let usage_listhelp = '(-l | -L | -B | +l | +L | -A | + A | -v | -h)'
|
||||
let usage_file = '[-f\033[33mPONY\033[39m]* [[--] \033[33mmessage\033[39m]'
|
||||
let usage_xfile = '(+f\033[33mPONY\033[39m)* [[--] \033[33mmessage\033[39m]'
|
||||
let usage_afile = '(-F\033[33mPONY\033[39m)* [[--] \033[33mmessage\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_xfile,
|
||||
usage_saythink, usage_common, usage_afile,
|
||||
usage_saythink, usage_common, usage_quote)
|
||||
|
||||
usage = usage.replace('\033[', '\0')
|
||||
usage = usage.replace('\033[', 'あ')
|
||||
for sym in ('[', ']', '(', ')', '|', '...', '*'):
|
||||
usage = usage.replace(sym, '\033[2m' + sym + '\033[22m')
|
||||
usage = usage.replace('\0', '\033[')
|
||||
usage = usage.replace('あ', '\033[')
|
||||
|
||||
'''
|
||||
Argument parsing
|
||||
'''
|
||||
opts = ArgParser(program = 'ponythink' if isthink else 'ponysay',
|
||||
let opts = ArgParser(program = 'ponythink' if isthink else 'ponysay',
|
||||
description = 'cowsay reimplemention for ponies',
|
||||
usage = usage,
|
||||
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-wrap', '--colour-hyphen'], arg = 'COLOUR')
|
||||
|
||||
_F = ['--any-file', '--anyfile', '--any-pony', '--anypony']
|
||||
__F = [_.replace("pony", "ponie") + 's' for _ in _F]
|
||||
let _F = ['--any-file', '--anyfile', '--any-pony', '--anypony']
|
||||
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-colour'], help = 'Print this help message with colours even if piped.')
|
||||
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
|
||||
'''
|
||||
unrecognised = not opts.parse()
|
||||
let unrecognised = not opts.parse()
|
||||
|
||||
|
||||
## Start
|
||||
ponysay = Ponysay()
|
||||
let ponysay = Ponysay()
|
||||
ponysay.unrecognised = unrecognised
|
||||
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
|
||||
the colon.
|
||||
'''
|
||||
from common import *
|
||||
from ponysay.common import printerr, printinfo, gettermsize, endswith
|
||||
import os
|
||||
import kuroko
|
||||
import fileio
|
||||
|
||||
|
||||
|
||||
ARGUMENTLESS = 0
|
||||
let ARGUMENTLESS = 0
|
||||
'''
|
||||
Option takes no arguments
|
||||
'''
|
||||
|
||||
ARGUMENTED = 1
|
||||
let ARGUMENTED = 1
|
||||
'''
|
||||
Option takes one argument per instance
|
||||
'''
|
||||
|
||||
VARIADIC = 2
|
||||
let VARIADIC = 2
|
||||
'''
|
||||
Option consumes all following arguments
|
||||
'''
|
||||
|
@ -83,7 +85,7 @@ class ArgParser():
|
|||
@param help:str Short description, use `None` to hide the option
|
||||
'''
|
||||
self.__arguments.append((ARGUMENTLESS, alternatives, None, help))
|
||||
stdalt = alternatives[0]
|
||||
let stdalt = alternatives[0]
|
||||
self.opts[stdalt] = None
|
||||
for alt in alternatives:
|
||||
self.optmap[alt] = (stdalt, ARGUMENTLESS)
|
||||
|
@ -97,7 +99,7 @@ class ArgParser():
|
|||
@param help:str Short description, use `None` to hide the option
|
||||
'''
|
||||
self.__arguments.append((ARGUMENTED, alternatives, arg, help))
|
||||
stdalt = alternatives[0]
|
||||
let stdalt = alternatives[0]
|
||||
self.opts[stdalt] = None
|
||||
for alt in alternatives:
|
||||
self.optmap[alt] = (stdalt, ARGUMENTED)
|
||||
|
@ -111,13 +113,13 @@ class ArgParser():
|
|||
@param help:str Short description, use `None` to hide the option
|
||||
'''
|
||||
self.__arguments.append((VARIADIC, alternatives, arg, help))
|
||||
stdalt = alternatives[0]
|
||||
let stdalt = alternatives[0]
|
||||
self.opts[stdalt] = None
|
||||
for alt in alternatives:
|
||||
self.optmap[alt] = (stdalt, VARIADIC)
|
||||
|
||||
|
||||
def parse(self, argv = sys.argv):
|
||||
def parse(self, argv = kuroko.argv):
|
||||
'''
|
||||
Parse arguments
|
||||
|
||||
|
@ -127,23 +129,24 @@ class ArgParser():
|
|||
self.argcount = len(argv) - 1
|
||||
self.files = []
|
||||
|
||||
argqueue = []
|
||||
optqueue = []
|
||||
deque = []
|
||||
let arg, i, n, opt, varopt
|
||||
let argqueue = []
|
||||
let optqueue = []
|
||||
let deque = []
|
||||
for arg in argv[1:]:
|
||||
deque.append(arg)
|
||||
|
||||
dashed = False
|
||||
tmpdashed = False
|
||||
get = 0
|
||||
dontget = 0
|
||||
let dashed = False
|
||||
let tmpdashed = False
|
||||
let get = 0
|
||||
let dontget = 0
|
||||
self.rc = True
|
||||
|
||||
self.unrecognisedCount = 0
|
||||
def unrecognised(arg):
|
||||
self.unrecognisedCount += 1
|
||||
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
|
||||
|
||||
while len(deque) != 0:
|
||||
|
@ -184,11 +187,11 @@ class ArgParser():
|
|||
else:
|
||||
unrecognised(arg)
|
||||
else:
|
||||
sign = arg[0]
|
||||
i = 1
|
||||
n = len(arg)
|
||||
let sign = arg[0]
|
||||
let i = 1
|
||||
let n = len(arg)
|
||||
while i < n:
|
||||
narg = sign + arg[i]
|
||||
let narg = sign + arg[i]
|
||||
i += 1
|
||||
if (narg in self.optmap):
|
||||
if self.optmap[narg][1] == ARGUMENTLESS:
|
||||
|
@ -196,7 +199,7 @@ class ArgParser():
|
|||
argqueue.append(None)
|
||||
elif self.optmap[narg][1] == ARGUMENTED:
|
||||
optqueue.append(narg)
|
||||
nargarg = arg[i:]
|
||||
let nargarg = arg[i:]
|
||||
if len(nargarg) == 0:
|
||||
get += 1
|
||||
else:
|
||||
|
@ -204,7 +207,7 @@ class ArgParser():
|
|||
break
|
||||
elif self.optmap[narg][1] == VARIADIC:
|
||||
optqueue.append(narg)
|
||||
nargarg = arg[i:]
|
||||
let nargarg = arg[i:]
|
||||
argqueue.append(nargarg if len(nargarg) > 0 else None)
|
||||
dashed = True
|
||||
break
|
||||
|
@ -240,7 +243,7 @@ class ArgParser():
|
|||
self.message = ' '.join(self.files) if len(self.files) > 0 else None
|
||||
|
||||
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
|
||||
|
||||
|
@ -252,94 +255,102 @@ class ArgParser():
|
|||
@param use_colours:bool? Whether to use colours, `None` if stdout is not piped
|
||||
'''
|
||||
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()
|
||||
if self.__longdescription is not None:
|
||||
desc = self.__longdescription
|
||||
let desc = self.__longdescription
|
||||
if not use_colours:
|
||||
while '\033' in desc:
|
||||
esc = desc.find('\033')
|
||||
while '\[' in desc:
|
||||
esc = desc.find('\[')
|
||||
desc = desc[:esc] + desc[desc.find('m', esc) + 1:]
|
||||
print(desc)
|
||||
print()
|
||||
|
||||
print('\033[1mUSAGE:\033[21m' if use_colours else 'USAGE:', end='')
|
||||
first = True
|
||||
print('\[[1mUSAGE:\[[22m' if use_colours else 'USAGE:', end='')
|
||||
let first = True
|
||||
for line in self.__usage.split('\n'):
|
||||
if first:
|
||||
first = False
|
||||
else:
|
||||
print(' or', end='')
|
||||
if not use_colours:
|
||||
while '\033' in line:
|
||||
esc = line.find('\033')
|
||||
while '\[' in line:
|
||||
esc = line.find('\[')
|
||||
line = line[:esc] + line[line.find('m', esc) + 1:]
|
||||
print('\t%s' % line)
|
||||
print('\t{}'.format(line))
|
||||
print()
|
||||
|
||||
maxfirstlen = []
|
||||
let maxfirstlen = []
|
||||
for opt in self.__arguments:
|
||||
opt_alts = opt[1]
|
||||
opt_help = opt[3]
|
||||
let opt_alts = opt[1]
|
||||
let opt_help = opt[3]
|
||||
if opt_help is None:
|
||||
continue
|
||||
first = opt_alts[0]
|
||||
last = opt_alts[-1]
|
||||
let last = opt_alts[-1]
|
||||
if first is not last:
|
||||
maxfirstlen.append(first)
|
||||
maxfirstlen = len(max(maxfirstlen, key = len))
|
||||
|
||||
print('\033[1mSYNOPSIS:\033[21m' if use_colours else 'SYNOPSIS')
|
||||
(lines, lens) = ([], [])
|
||||
print('\[[1mSYNOPSIS:\[[22m' if use_colours else 'SYNOPSIS')
|
||||
let lines, lens = [], []
|
||||
for opt in self.__arguments:
|
||||
opt_type = opt[0]
|
||||
opt_alts = opt[1]
|
||||
opt_arg = opt[2]
|
||||
opt_help = opt[3]
|
||||
let opt_type = opt[0]
|
||||
let opt_alts = opt[1]
|
||||
let opt_arg = opt[2]
|
||||
let opt_help = opt[3]
|
||||
if opt_help is None:
|
||||
continue
|
||||
(line, l) = ('', 0)
|
||||
let line, l = '', 0
|
||||
first = opt_alts[0]
|
||||
last = opt_alts[-1]
|
||||
alts = ['', last] if first is last else [first, last]
|
||||
let last = opt_alts[-1]
|
||||
let alts = ['', last] if first is last else [first, last]
|
||||
alts[0] += ' ' * (maxfirstlen - len(alts[0]))
|
||||
for opt_alt in alts:
|
||||
if opt_alt is alts[-1]:
|
||||
line += '%colour%' + opt_alt
|
||||
l += len(opt_alt)
|
||||
if use_colours:
|
||||
if opt_type == ARGUMENTED: line += ' \033[4m%s\033[24m' % (opt_arg); l += len(opt_arg) + 1
|
||||
elif opt_type == VARIADIC: line += ' [\033[4m%s\033[24m...]' % (opt_arg); l += len(opt_arg) + 6
|
||||
if opt_type == ARGUMENTED:
|
||||
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:
|
||||
if opt_type == ARGUMENTED: line += ' %s' % (opt_arg); l += len(opt_arg) + 1
|
||||
elif opt_type == VARIADIC: line += ' [%s...]' % (opt_arg); l += len(opt_arg) + 6
|
||||
if opt_type == ARGUMENTED:
|
||||
line += ' {}' .format (opt_arg)
|
||||
l += len(opt_arg) + 1
|
||||
elif opt_type == VARIADIC:
|
||||
line += ' [{}...]' .format (opt_arg)
|
||||
l += len(opt_arg) + 6
|
||||
else:
|
||||
if use_colours:
|
||||
line += ' \033[2m%s\033[22m ' % (opt_alt)
|
||||
line += ' \[[2m{}\[[22m ' .format (opt_alt)
|
||||
else:
|
||||
line += ' %s ' % (opt_alt)
|
||||
line += ' {} ' .format (opt_alt)
|
||||
l += len(opt_alt) + 6
|
||||
lines.append(line)
|
||||
lens.append(l)
|
||||
|
||||
col = max(lens)
|
||||
let col = max(lens)
|
||||
col += 8 - ((col - 4) & 7)
|
||||
index = 0
|
||||
let index = 0
|
||||
for opt in self.__arguments:
|
||||
opt_help = opt[3]
|
||||
let opt_help = opt[3]
|
||||
if opt_help is None:
|
||||
continue
|
||||
first = True
|
||||
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]))
|
||||
let colour = ('36' if (index & 1) == 0 else '34') if use_colours else ''
|
||||
print(lines[index].replace('%colour%', ('\[[{};1m' .format (colour)) if use_colours else ''), end=' ' * (col - lens[index]))
|
||||
for line in opt_help.split('\n'):
|
||||
if first:
|
||||
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:
|
||||
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
|
||||
|
||||
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
|
||||
the colon.
|
||||
'''
|
||||
from common import *
|
||||
from balloon import *
|
||||
from colourstack import *
|
||||
from ucs import *
|
||||
|
||||
import unicodedata
|
||||
|
||||
from ponysay.common import printerr, printinfo, gettermsize, endswith
|
||||
from ponysay.balloon import Balloon
|
||||
from ponysay.colourstack import ColourStack
|
||||
from ponysay.ucs import UCS
|
||||
|
||||
from wcwidth import wcwidth
|
||||
import fileio
|
||||
import os
|
||||
|
||||
class Backend():
|
||||
'''
|
||||
|
@ -89,6 +89,7 @@ class Backend():
|
|||
|
||||
if self.pony.startswith('$$$\n'):
|
||||
self.pony = self.pony[4:]
|
||||
let infoend, info
|
||||
if self.pony.startswith('$$$\n'):
|
||||
infoend = 4
|
||||
info = ''
|
||||
|
@ -104,21 +105,21 @@ class Backend():
|
|||
else:
|
||||
info = info.split('\n')
|
||||
for line in info:
|
||||
sep = line.find(':')
|
||||
let sep = line.find(':')
|
||||
if sep > 0:
|
||||
key = line[:sep].strip()
|
||||
let key = line[:sep].strip()
|
||||
if key == 'BALLOON TOP':
|
||||
value = line[sep + 1:].strip()
|
||||
let value = line[sep + 1:].strip()
|
||||
if len(value) > 0:
|
||||
self.balloontop = int(value)
|
||||
if key == 'BALLOON BOTTOM':
|
||||
value = line[sep + 1:].strip()
|
||||
let value = line[sep + 1:].strip()
|
||||
if len(value) > 0:
|
||||
self.balloonbottom = int(value)
|
||||
printinfo(info)
|
||||
self.pony = self.pony[infoend:]
|
||||
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:
|
||||
self.pony = 'There is not metadata for this pony file'
|
||||
self.pony = self.mode + self.pony
|
||||
|
@ -149,7 +150,7 @@ class Backend():
|
|||
test = test.replace(c, '')
|
||||
if (len(test) == 0) and (len(key.replace(' ', '')) > 0):
|
||||
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
|
||||
continue
|
||||
comment += '\n' + line
|
||||
|
@ -163,16 +164,16 @@ class Backend():
|
|||
'''
|
||||
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):
|
||||
padded = True
|
||||
let padded = True
|
||||
for line in lines:
|
||||
if not line.startswith(' ' * spaces):
|
||||
padded = False
|
||||
break
|
||||
if padded:
|
||||
for i in range(0, len(lines)):
|
||||
line = lines[i]
|
||||
let line = lines[i]
|
||||
line = line[spaces:]
|
||||
lines[i] = line
|
||||
lines = [line.rstrip(' ') for line in lines]
|
||||
|
@ -183,19 +184,19 @@ class Backend():
|
|||
'''
|
||||
Converts all tabs in the message to spaces by expanding
|
||||
'''
|
||||
lines = self.message.split('\n')
|
||||
buf = ''
|
||||
let lines = self.message.split('\n')
|
||||
let buf = ''
|
||||
for line in lines:
|
||||
(i, n, x) = (0, len(line), 0)
|
||||
let i, n, x = (0, len(line), 0)
|
||||
while i < n:
|
||||
c = line[i]
|
||||
let c = line[i]
|
||||
i += 1
|
||||
if c == '\033':
|
||||
colour = Backend.getColour(line, i - 1)
|
||||
let colour = Backend.getColour(line, i - 1)
|
||||
i += len(colour) - 1
|
||||
buf += colour
|
||||
elif c == '\t':
|
||||
nx = 8 - (x & 7)
|
||||
let nx = 8 - (x & 7)
|
||||
buf += ' ' * nx
|
||||
x += nx
|
||||
else:
|
||||
|
@ -210,8 +211,8 @@ class Backend():
|
|||
'''
|
||||
Loads the pony file
|
||||
'''
|
||||
with open(self.ponyfile, 'rb') as ponystream:
|
||||
self.pony = ponystream.read().decode('utf8', 'replace')
|
||||
with fileio.open(self.ponyfile, 'rb') as ponystream:
|
||||
self.pony = ponystream.read().decode()
|
||||
|
||||
|
||||
def __truncate(self):
|
||||
|
@ -220,15 +221,15 @@ class Backend():
|
|||
'''
|
||||
if self.width is None:
|
||||
return
|
||||
lines = self.output.split('\n')
|
||||
let lines = self.output.split('\n')
|
||||
self.output = ''
|
||||
for line in lines:
|
||||
(i, n, x) = (0, len(line), 0)
|
||||
let i, n, x = (0, len(line), 0)
|
||||
while i < n:
|
||||
c = line[i]
|
||||
let c = line[i]
|
||||
i += 1
|
||||
if c == '\033':
|
||||
colour = Backend.getColour(line, i - 1)
|
||||
let colour = Backend.getColour(line, i - 1)
|
||||
i += len(colour) - 1
|
||||
self.output += colour
|
||||
else:
|
||||
|
@ -246,35 +247,36 @@ class Backend():
|
|||
'''
|
||||
self.output = ''
|
||||
|
||||
AUTO_PUSH = '\033[01010~'
|
||||
AUTO_POP = '\033[10101~'
|
||||
let AUTO_PUSH = '\033[01010~'
|
||||
let AUTO_POP = '\033[10101~'
|
||||
|
||||
variables = {'' : '$'}
|
||||
let variables = {'' : '$'}
|
||||
for key in self.link:
|
||||
variables[key] = AUTO_PUSH + self.link[key] + AUTO_POP
|
||||
|
||||
indent = 0
|
||||
dollar = None
|
||||
balloonLines = None
|
||||
colourstack = ColourStack(AUTO_PUSH, AUTO_POP)
|
||||
let indent = 0
|
||||
let dollar = None
|
||||
let balloonLines = None
|
||||
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:
|
||||
c = self.pony[i]
|
||||
let c = self.pony[i]
|
||||
if c == '\t':
|
||||
n += 7 - (indent & 7)
|
||||
ed = ' ' * (8 - (indent & 7))
|
||||
let ed = ' ' * (8 - (indent & 7))
|
||||
c = ' '
|
||||
self.pony = self.pony[:i] + ed + self.pony[i + 1:]
|
||||
i += 1
|
||||
if c == '$':
|
||||
if dollar is not None:
|
||||
if '=' in dollar:
|
||||
name = dollar[:dollar.find('=')]
|
||||
value = dollar[dollar.find('=') + 1:]
|
||||
let name = dollar[:dollar.find('=')]
|
||||
let value = dollar[dollar.find('=') + 1:]
|
||||
variables[name] = value
|
||||
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 (skip == 0) or (nonskip > 0):
|
||||
if nonskip > 0:
|
||||
|
@ -287,8 +289,8 @@ class Backend():
|
|||
n += len(data)
|
||||
self.pony = self.pony[:i] + data + self.pony[i:]
|
||||
elif self.balloon is not None:
|
||||
(w, h, x, justify) = ('0', 0, 0, None)
|
||||
props = dollar[7:]
|
||||
let w, h, x, justify = ('0', 0, 0, None)
|
||||
let props = dollar[7:]
|
||||
if len(props) > 0:
|
||||
if ',' in props:
|
||||
if props[0] != ',':
|
||||
|
@ -299,28 +301,28 @@ class Backend():
|
|||
if 'l' in w:
|
||||
(x, w) = (int(w[:w.find('l')]), int(w[w.find('l') + 1:]))
|
||||
justify = 'l'
|
||||
w -= x;
|
||||
w -= x
|
||||
elif 'c' in w:
|
||||
(x, w) = (int(w[:w.find('c')]), int(w[w.find('c') + 1:]))
|
||||
justify = 'c'
|
||||
w -= x;
|
||||
w -= x
|
||||
elif 'r' in w:
|
||||
(x, w) = (int(w[:w.find('r')]), int(w[w.find('r') + 1:]))
|
||||
justify = 'r'
|
||||
w -= x;
|
||||
w -= x
|
||||
else:
|
||||
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 = [AUTO_PUSH + self.ballooncolour + item + AUTO_POP for item in balloon]
|
||||
for b in balloon[0]:
|
||||
self.output += b + colourstack.feed(b)
|
||||
if lineindex == 0:
|
||||
balloonpre = '\n' + (' ' * indent)
|
||||
let balloonpre = '\n' + (' ' * indent)
|
||||
for line in balloon[1:]:
|
||||
self.output += balloonpre;
|
||||
self.output += balloonpre
|
||||
for b in line:
|
||||
self.output += b + colourstack.feed(b);
|
||||
self.output += b + colourstack.feed(b)
|
||||
indent = 0
|
||||
elif len(balloon) > 1:
|
||||
balloonLines = balloon
|
||||
|
@ -337,9 +339,9 @@ class Backend():
|
|||
i += 1
|
||||
dollar += c
|
||||
elif c == '\033':
|
||||
colour = Backend.getColour(self.pony, i - 1)
|
||||
let colour = Backend.getColour(self.pony, i - 1)
|
||||
for b in colour:
|
||||
self.output += b + colourstack.feed(b);
|
||||
self.output += b + colourstack.feed(b)
|
||||
i += len(colour) - 1
|
||||
elif c == '\n':
|
||||
self.output += c
|
||||
|
@ -364,7 +366,7 @@ class Backend():
|
|||
if (skip == 0) or (nonskip > 0):
|
||||
if nonskip > 0:
|
||||
nonskip -= 1
|
||||
self.output += c + colourstack.feed(c);
|
||||
self.output += c + colourstack.feed(c)
|
||||
if not UCS.isCombining(c):
|
||||
indent += 1
|
||||
else:
|
||||
|
@ -374,7 +376,7 @@ class Backend():
|
|||
for line in balloonLines[balloonLine:]:
|
||||
data = ' ' * (balloonIndent - indent) + line + '\n'
|
||||
for b in data:
|
||||
self.output += b + colourstack.feed(b);
|
||||
self.output += b + colourstack.feed(b)
|
||||
indent = 0
|
||||
|
||||
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
|
||||
@return :str The escape sequence
|
||||
'''
|
||||
(i, n) = (offset, len(input))
|
||||
rc = input[i]
|
||||
let i, n = (offset, len(input))
|
||||
let rc = input[i]
|
||||
i += 1
|
||||
if i == n: return rc
|
||||
c = input[i]
|
||||
let c = input[i]
|
||||
i += 1
|
||||
rc += c
|
||||
|
||||
|
@ -450,16 +452,16 @@ class Backend():
|
|||
@param input:str The input buffer
|
||||
@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:
|
||||
c = input[i]
|
||||
let c = input[i]
|
||||
if c == '\033':
|
||||
i += len(Backend.getColour(input, i))
|
||||
else:
|
||||
i += 1
|
||||
if not UCS.isCombining(c):
|
||||
rc += 1
|
||||
if unicodedata.east_asian_width(c) in ('F', 'W'):
|
||||
if wcwidth(ord(c)) in ('F', 'W'):
|
||||
rc += 1
|
||||
return rc
|
||||
|
||||
|
@ -476,22 +478,22 @@ class Backend():
|
|||
@param left:int The column where the balloon starts
|
||||
@return :str The balloon the the message as a string
|
||||
'''
|
||||
wrap = None
|
||||
let wrap = None
|
||||
if self.wrapcolumn is not None:
|
||||
wrap = self.wrapcolumn - left
|
||||
if wrap < 8:
|
||||
wrap = 8
|
||||
|
||||
msg = self.message
|
||||
let msg = self.message
|
||||
if wrap is not None:
|
||||
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')
|
||||
|
||||
extraleft = 0
|
||||
let extraleft = 0
|
||||
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
|
||||
if msgwidth > width:
|
||||
if (justify == 'l') and (wrap is not None):
|
||||
|
@ -507,7 +509,7 @@ class Backend():
|
|||
if 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:
|
||||
rc = ' ' * extraleft + rc.replace('\n', '\n' + ' ' * extraleft)
|
||||
return rc
|
||||
|
@ -521,39 +523,39 @@ class Backend():
|
|||
@param wrap:int The width at where to force wrapping
|
||||
@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)
|
||||
|
||||
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)
|
||||
|
||||
buf = ''
|
||||
let buf = ''
|
||||
let AUTO_PUSH = '\033[01010~'
|
||||
let AUTO_POP = '\033[10101~'
|
||||
try:
|
||||
AUTO_PUSH = '\033[01010~'
|
||||
AUTO_POP = '\033[10101~'
|
||||
msg = message.replace('\n', AUTO_PUSH + '\n' + AUTO_POP)
|
||||
cstack = ColourStack(AUTO_PUSH, AUTO_POP)
|
||||
let msg = message.replace('\n', AUTO_PUSH + '\n' + AUTO_POP)
|
||||
let cstack = ColourStack(AUTO_PUSH, AUTO_POP)
|
||||
for c in msg:
|
||||
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 = ''
|
||||
|
||||
for line in lines:
|
||||
b = [None] * len(line)
|
||||
map = {0 : 0}
|
||||
(bi, cols, w) = (0, 0, wrap)
|
||||
(indent, indentc) = (-1, 0)
|
||||
let b = [None] * len(line)
|
||||
let map = {0 : 0}
|
||||
let bi, cols, w = (0, 0, wrap)
|
||||
let indent, indentc = (-1, 0)
|
||||
|
||||
(i, n) = (0, len(line))
|
||||
let i, n = (0, len(line))
|
||||
while i <= n:
|
||||
d = None
|
||||
let d = None
|
||||
if i < n:
|
||||
d = line[i]
|
||||
i += 1
|
||||
if d == '\033':
|
||||
## Invisible stuff
|
||||
i -= 1
|
||||
colourseq = Backend.getColour(line, i)
|
||||
let colourseq = Backend.getColour(line, i)
|
||||
b[bi : bi + len(colourseq)] = colourseq
|
||||
i += len(colourseq)
|
||||
bi += len(colourseq)
|
||||
|
@ -571,18 +573,18 @@ class Backend():
|
|||
map[cols] = bi
|
||||
else:
|
||||
## Wrap?
|
||||
mm = 0
|
||||
bisub = 0
|
||||
iwrap = wrap - (0 if indent == 1 else indentc)
|
||||
let mm = 0
|
||||
let bisub = 0
|
||||
let iwrap = wrap - (0 if indent == 1 else indentc)
|
||||
|
||||
while ((w > wraplimit) and (cols > w + wrapexceed)) or (cols > iwrap):
|
||||
## wrap
|
||||
x = w;
|
||||
let x = w
|
||||
if mm + x not in map: # Too much whitespace?
|
||||
cols = 0
|
||||
break
|
||||
nbsp = b[map[mm + x]] == ' ' # nbsp
|
||||
m = map[mm + x]
|
||||
let nbsp = b[map[mm + x]] == ' ' # nbsp
|
||||
let m = map[mm + x]
|
||||
|
||||
if ('' in b[bisub : m]) and not nbsp: # soft hyphen
|
||||
hyphen = m - 1
|
||||
|
@ -597,7 +599,7 @@ class Backend():
|
|||
|
||||
for bb in b[bisub : m]:
|
||||
buf += bb
|
||||
buf += '\n' if nbsp else '\0\n'
|
||||
buf += '\n' if nbsp else 'あ\n'
|
||||
cols -= x - (0 if nbsp else 1)
|
||||
bisub = m
|
||||
|
||||
|
@ -635,21 +637,15 @@ class Backend():
|
|||
w -= indentc
|
||||
buf += '\n'
|
||||
|
||||
rc = '\n'.join(line.rstrip(' ') for line in buf[:-1].split('\n'));
|
||||
rc = rc.replace('', ''); # remove soft hyphens
|
||||
rc = rc.replace('\0', '%s%s%s' % (AUTO_PUSH, self.hyphen, AUTO_POP))
|
||||
let rc = '\n'.join(line.rstrip(' ') for line in buf[:-1].split('\n'))
|
||||
rc = rc.replace('', '') # remove soft hyphens
|
||||
rc = rc.replace('あ', '{}{}{}' .format (AUTO_PUSH, self.hyphen, AUTO_POP))
|
||||
return rc
|
||||
except Exception as err:
|
||||
import traceback
|
||||
errormessage = ''.join(traceback.format_exception(type(err), err, None))
|
||||
rc = '\n'.join(line.rstrip(' ') for line in buf.split('\n'));
|
||||
rc = rc.replace('\0', '%s%s%s' % (AUTO_PUSH, self.hyphen, AUTO_POP))
|
||||
let errormessage = str(err)
|
||||
let rc = '\n'.join(line.rstrip(' ') for line in buf.split('\n'))
|
||||
rc = rc.replace('あ', '{}{}{}' .format (AUTO_PUSH, self.hyphen, AUTO_POP))
|
||||
errormessage += '\n---- WRAPPING BUFFER ----\n\n' + rc
|
||||
try:
|
||||
if os.readlink('/proc/self/fd/2') != os.readlink('/proc/self/fd/1'):
|
||||
printerr(errormessage, end='')
|
||||
return message
|
||||
except:
|
||||
pass
|
||||
return message + '\n\n\033[0;1;31m---- EXCEPTION IN PONYSAY WHILE WRAPPING ----\033[0m\n\n' + errormessage
|
||||
|
|
@ -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
|
||||
the colon.
|
||||
'''
|
||||
from common import *
|
||||
from ucs import *
|
||||
from ponysay.common import printerr, printinfo, gettermsize, endswith
|
||||
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():
|
||||
'''
|
||||
|
@ -73,15 +81,15 @@ class Balloon():
|
|||
(self.sse, self.s, self.ssw) = (sse, s, ssw)
|
||||
(self.sww, self.w, self.nww) = (sww, w, nww)
|
||||
|
||||
_ne = max(ne, key = UCS.dispLen)
|
||||
_nw = max(nw, key = UCS.dispLen)
|
||||
_se = max(se, key = UCS.dispLen)
|
||||
_sw = max(sw, key = UCS.dispLen)
|
||||
let _ne = fmax(ne, key = UCS.dispLen)
|
||||
let _nw = fmax(nw, key = UCS.dispLen)
|
||||
let _se = fmax(se, key = UCS.dispLen)
|
||||
let _sw = fmax(sw, key = UCS.dispLen)
|
||||
|
||||
minE = UCS.dispLen(max([_ne, nee, e, see, _se, ee], key = UCS.dispLen))
|
||||
minW = UCS.dispLen(max([_nw, nww, e, sww, _sw, ww], key = UCS.dispLen))
|
||||
minN = len(max([ne, nne, n, nnw, nw], key = len))
|
||||
minS = len(max([se, sse, s, ssw, sw], key = len))
|
||||
let minE = UCS.dispLen(fmax([_ne, nee, e, see, _se, ee], key = UCS.dispLen))
|
||||
let minW = UCS.dispLen(fmax([_nw, nww, e, sww, _sw, ww], key = UCS.dispLen))
|
||||
let minN = len(fmax([ne, nne, n, nnw, nw], key = len))
|
||||
let minS = len(fmax([se, sse, s, ssw, sw], key = len))
|
||||
|
||||
self.minwidth = minE + minE
|
||||
self.minheight = minN + minS
|
||||
|
@ -98,26 +106,27 @@ class Balloon():
|
|||
@return :str The balloon as a formated string
|
||||
'''
|
||||
## Get dimension
|
||||
h = self.minheight + len(lines)
|
||||
w = self.minwidth + lencalc(max(lines, key = lencalc))
|
||||
let h = self.minheight + len(lines)
|
||||
let w = self.minwidth + lencalc(fmax(lines, key = lencalc))
|
||||
if w < minw: w = minw
|
||||
if h < minh: h = minh
|
||||
|
||||
## Create edges
|
||||
let ws, es
|
||||
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):
|
||||
ws[j] = self.w
|
||||
es[j] = self.e
|
||||
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
|
||||
for j in range(0, len(self.n)):
|
||||
outer = UCS.dispLen(self.nw[j]) + UCS.dispLen(self.ne[j])
|
||||
inner = UCS.dispLen(self.nnw[j]) + UCS.dispLen(self.nne[j])
|
||||
let outer = UCS.dispLen(self.nw[j]) + UCS.dispLen(self.ne[j])
|
||||
let inner = UCS.dispLen(self.nnw[j]) + UCS.dispLen(self.nne[j])
|
||||
if outer + inner <= w:
|
||||
rc.append(self.nw[j] + self.nnw[j] + self.n[j] * (w - outer - inner) + self.nne[j] + self.ne[j])
|
||||
else:
|
||||
|
@ -129,8 +138,8 @@ class Balloon():
|
|||
|
||||
## Create the lower part of the balloon
|
||||
for j in range(0, len(self.s)):
|
||||
outer = UCS.dispLen(self.sw[j]) + UCS.dispLen(self.se[j])
|
||||
inner = UCS.dispLen(self.ssw[j]) + UCS.dispLen(self.sse[j])
|
||||
let outer = UCS.dispLen(self.sw[j]) + UCS.dispLen(self.se[j])
|
||||
let inner = UCS.dispLen(self.ssw[j]) + UCS.dispLen(self.sse[j])
|
||||
if outer + inner <= w:
|
||||
rc.append(self.sw[j] + self.ssw[j] + self.s[j] * (w - outer - inner) + self.sse[j] + self.se[j])
|
||||
else:
|
||||
|
@ -155,24 +164,25 @@ class Balloon():
|
|||
return Balloon('\\', '/', 'X', '< ', ' >', [' _'], ['_'], ['_'], ['_'], ['_ '], ' \\', ' |', ' /', ['- '], ['-'], ['-'], ['-'], [' -'], '\\ ', '| ', '/ ')
|
||||
|
||||
## 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'):
|
||||
map[elem] = []
|
||||
|
||||
## Read all lines in the balloon file
|
||||
with open(balloonfile, 'rb') as balloonstream:
|
||||
data = balloonstream.read().decode('utf8', 'replace')
|
||||
let data
|
||||
with fileio.open(balloonfile, 'rb') as balloonstream:
|
||||
data = balloonstream.read().decode()
|
||||
data = [line.replace('\n', '') for line in data.split('\n')]
|
||||
|
||||
## Parse the balloon file, and fill the map
|
||||
last = None
|
||||
let last = None
|
||||
for line in data:
|
||||
if len(line) > 0:
|
||||
if line[0] == ':':
|
||||
map[last].append(line[1:])
|
||||
else:
|
||||
last = line[:line.index(':')]
|
||||
value = line[len(last) + 1:]
|
||||
let value = line[len(last) + 1:]
|
||||
map[last].append(value)
|
||||
|
||||
## 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
|
||||
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
|
||||
'''
|
||||
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:
|
||||
return None
|
||||
return '\033[0m'
|
||||
|
@ -75,11 +78,11 @@ class ColourStack():
|
|||
|
||||
@return :str String that should be inserted into your buffer
|
||||
'''
|
||||
old = self.stack.pop(0)
|
||||
rc = '\033[0;'
|
||||
let old = self.stack.pop(0)
|
||||
let rc = '\033[0;'
|
||||
if len(self.stack) == 0: # last resort in case something made it pop too mush
|
||||
push()
|
||||
new = self.stack[0]
|
||||
let new = self.stack[0]
|
||||
if new[1] is not None: rc += new[1] + ';'
|
||||
if new[2] is not None: rc += new[2] + ';'
|
||||
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 (self.seq[0] == '[') and (self.seq[-1] == 'm'):
|
||||
self.seq = self.seq[1:-1].split(';')
|
||||
(i, n) = (0, len(self.seq))
|
||||
let i, n = (0, len(self.seq))
|
||||
while i < n:
|
||||
part = self.seq[i]
|
||||
p = 0 if part == '' else int(part)
|
||||
let part = self.seq[i]
|
||||
let p = 0 if part == '' else int(part)
|
||||
i += 1
|
||||
if p == 0: self.stack[0][1:] = [None, None, [False] * 9]
|
||||
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 100 <= p <= 107: self.stack[0][2] = part
|
||||
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
|
||||
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
|
||||
self.seq = None
|
||||
elif char == '\033':
|
||||
self.seq = ''
|
||||
buf = self.stack[0][0]
|
||||
let buf = self.stack[0][0]
|
||||
buf = buf[1:] + char
|
||||
rc = ''
|
||||
let rc = ''
|
||||
if buf[-self.lenpush:] == self.autopush: rc = self.push()
|
||||
elif buf[-self.lenpop:] == self.autopop: rc = self.pop()
|
||||
self.stack[0][0] = buf
|
|
@ -30,30 +30,8 @@ lines and the ‘FREE’ is and upper case and directly followed by
|
|||
the colon.
|
||||
'''
|
||||
|
||||
import fileio
|
||||
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'):
|
||||
'''
|
||||
|
@ -62,9 +40,8 @@ def printerr(text = '', end = '\n'):
|
|||
@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.stderr.buffer.write((str(text) + end).encode('utf-8'))
|
||||
fileio.stderr.write((str(text) + end))
|
||||
|
||||
fd3 = None
|
||||
def printinfo(text = '', end = '\n'):
|
||||
'''
|
||||
/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 end:str The appendix to the text to print (line breaking is default)
|
||||
'''
|
||||
global fd3
|
||||
if os.path.exists('/proc/self/fd/3') and not os.path.isdir(os.path.realpath('/proc/self/fd/3')):
|
||||
if fd3 is None:
|
||||
fd3 = os.fdopen(3, 'w')
|
||||
if fd3 is not None:
|
||||
fd3.write(str(text) + end)
|
||||
pass
|
||||
#os.write(2, (str(text) + end).encode())
|
||||
|
||||
|
||||
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
|
||||
'''
|
||||
## Call `stty` to determine the size of the terminal, this way is better than using python's ncurses
|
||||
for channel in (sys.stderr, sys.stdout, sys.stdin):
|
||||
termsize = Popen(['stty', 'size'], stdout=PIPE, stdin=channel, stderr=PIPE).communicate()[0]
|
||||
if len(termsize) > 0:
|
||||
termsize = termsize.decode('utf8', 'replace')[:-1].split(' ') # [:-1] removes a \n
|
||||
termsize = [int(item) for item in termsize]
|
||||
return termsize
|
||||
# TODO we don't have a thing for this??
|
||||
try:
|
||||
os.system("stty size > /tmp/.ponysaysize")
|
||||
with fileio.open("/tmp/.ponysaysize") as f:
|
||||
let tmp = f.read().strip()
|
||||
return tuple(int(x) for x in tmp.split(' '))
|
||||
except:
|
||||
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
|
||||
the colon.
|
||||
'''
|
||||
from common import *
|
||||
from ponysay.common import *
|
||||
|
||||
|
||||
|
|
@ -34,11 +34,17 @@ File listing functions.
|
|||
'''
|
||||
|
||||
|
||||
from ucs import *
|
||||
import itertools
|
||||
from ponysay.common import endswith, gettermsize
|
||||
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.
|
||||
|
||||
|
@ -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.
|
||||
"""
|
||||
|
||||
num_items = len(items)
|
||||
items_with_length = [(i, length_fn(i)) for i in items]
|
||||
max_item_length = max(i for _, i in items_with_length)
|
||||
let num_items = len(items)
|
||||
let items_with_length = [(i, length_fn(i)) for i in items]
|
||||
let max_item_length = max(i for _, i in items_with_length)
|
||||
|
||||
# Make at least one column to handle very narrow terminals.
|
||||
num_columns = max((available_width + separation) // (max_item_length + separation), 1)
|
||||
column_length = (num_items - 1) // num_columns + 1
|
||||
let num_columns = max((available_width + separation) // (max_item_length + separation), 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):
|
||||
'''
|
||||
|
@ -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.
|
||||
'''
|
||||
## Get terminal width
|
||||
_, term_width = gettermsize()
|
||||
let _, term_width = gettermsize()
|
||||
|
||||
columns = _columnise_list(
|
||||
sorted(items, key = lambda x: x[0]),
|
||||
let columns = _columnise_list(
|
||||
_sorted(items, key = lambda x: x[0]),
|
||||
term_width,
|
||||
lambda x: UCS.dispLen(x[0]))
|
||||
|
||||
for row in itertools.zip_longest(*columns):
|
||||
for row in zip(*columns):
|
||||
def iter_parts():
|
||||
spacing = 0
|
||||
|
||||
let spacing = 0
|
||||
for cell in row:
|
||||
if cell:
|
||||
# Yield this here to prevent whitespace to be printed after the last column.
|
||||
yield ' ' * spacing
|
||||
|
||||
(_, item), spacing = cell
|
||||
|
||||
let item, _, inner
|
||||
inner, spacing = cell
|
||||
_, item = inner
|
||||
yield item
|
||||
|
||||
print(''.join(iter_parts()))
|
||||
|
||||
print()
|
||||
|
@ -114,7 +127,7 @@ def simplelist(ponydirs, quoters = [], ucsiser = None):
|
|||
'''
|
||||
for ponydir in ponydirs: # Loop ponydirs
|
||||
## Get all ponies in the directory
|
||||
ponies = _get_file_list(ponydir, '.pony')
|
||||
let ponies = _get_file_list(ponydir, '.pony')
|
||||
|
||||
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 len(ponies) == 0:
|
||||
continue
|
||||
print('\033[1mponies located in ' + ponydir + '\033[21m')
|
||||
_print_columnised([(pony, '\033[1m' + pony + '\033[21m' if pony in quoters else pony) for pony in ponies])
|
||||
print('\033[1mponies located in ' + ponydir + '\033[22m')
|
||||
_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):
|
||||
|
@ -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 len(ponies) == 0:
|
||||
continue
|
||||
print('\033[1mponies located in ' + ponydir + '\033[21m')
|
||||
print('\033[1mponies located in ' + ponydir + '\033[22m')
|
||||
|
||||
## UCS:ise pony names
|
||||
pseudolinkmap = {}
|
||||
|
@ -156,7 +169,7 @@ def linklist(ponydirs = None, quoters = [], ucsiser = None):
|
|||
pairs = []
|
||||
for pony in ponies:
|
||||
if pony in pseudolinkmap:
|
||||
pairs.append((pony, pseudolinkmap[pony] + '.pony'));
|
||||
pairs.append((pony, pseudolinkmap[pony] + '.pony'))
|
||||
else:
|
||||
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 = {}
|
||||
for pony in ponymap:
|
||||
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.sort()
|
||||
if len(syms) > 0:
|
||||
|
@ -190,9 +203,9 @@ def linklist(ponydirs = None, quoters = [], ucsiser = None):
|
|||
w += UCS.dispLen(sym)
|
||||
if first: first = False
|
||||
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 += ')'
|
||||
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_columnised(list(ponies))
|
||||
|
@ -206,14 +219,14 @@ def onelist(pony_dirs, ucsiser):
|
|||
@param ucsiser:(list<str>)→void Function used to UCS:ise names
|
||||
'''
|
||||
## 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
|
||||
ucsiser(ponies)
|
||||
ponies.sort()
|
||||
|
||||
## Print each one on a seperate line, but skip duplicates
|
||||
last = ''
|
||||
let last = ''
|
||||
for pony in ponies:
|
||||
if not pony == last:
|
||||
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
|
||||
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
|
||||
the colon.
|
||||
'''
|
||||
from common import *
|
||||
from backend import *
|
||||
from balloon import *
|
||||
from spellocorrecter import *
|
||||
from ucs import *
|
||||
from kms import *
|
||||
import lists
|
||||
from metadata import *
|
||||
from ponysay.common import printerr, printinfo, gettermsize, endswith
|
||||
from ponysay.backend import Backend
|
||||
from ponysay.balloon import Balloon
|
||||
from ponysay.spellocorrecter import SpelloCorrecter
|
||||
from ponysay.ucs import UCS
|
||||
import ponysay.lists as lists
|
||||
from ponysay.metadata import Metadata
|
||||
|
||||
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():
|
||||
'''
|
||||
|
@ -55,7 +111,6 @@ class Ponysay():
|
|||
if len(self.HOME) == 0:
|
||||
os.environ['HOME'] = self.HOME = os.path.expanduser('~')
|
||||
|
||||
|
||||
## Load extension and configurations via ponysayrc
|
||||
for file in ('$XDG_CONFIG_HOME/ponysay/ponysayrc', '$HOME/.config/ponysay/ponysayrc', '$HOME/.ponysayrc', '/etc/ponysayrc'):
|
||||
file = self.__parseFile(file)
|
||||
|
@ -84,17 +139,17 @@ class Ponysay():
|
|||
|
||||
|
||||
# Whether stdin is piped
|
||||
self.pipelinein = not sys.stdin.isatty()
|
||||
self.pipelinein = not os.isatty(0) #sys.stdin.isatty()
|
||||
|
||||
# Whether stdout is piped
|
||||
self.pipelineout = not sys.stdout.isatty()
|
||||
self.pipelineout = not os.isatty(1) #sys.stdout.isatty()
|
||||
|
||||
# Whether stderr is piped
|
||||
self.pipelineerr = not sys.stderr.isatty()
|
||||
self.pipelineerr = not os.isatty(2) #sys.stderr.isatty()
|
||||
|
||||
|
||||
# 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
|
||||
|
@ -128,9 +183,9 @@ class Ponysay():
|
|||
@return The target file name, None if the environment variables are not declared
|
||||
'''
|
||||
if '$' in file:
|
||||
buf = ''
|
||||
esc = False
|
||||
var = None
|
||||
let buf = ''
|
||||
let esc = False
|
||||
let var = None
|
||||
for c in file:
|
||||
if esc:
|
||||
buf += c
|
||||
|
@ -162,9 +217,9 @@ class Ponysay():
|
|||
@param directory:str The directory base name
|
||||
@return :list<str> Absolute directory names
|
||||
'''
|
||||
appendset = set()
|
||||
rc = []
|
||||
_ponydirs = cls.__share(directory)
|
||||
let appendset = set()
|
||||
let rc = []
|
||||
let _ponydirs = cls.__share(directory)
|
||||
for ponydir in _ponydirs:
|
||||
if (ponydir is not None) and os.path.isdir(ponydir) and (ponydir not in appendset):
|
||||
rc.append(ponydir)
|
||||
|
@ -188,7 +243,8 @@ class Ponysay():
|
|||
return [cat(cls.__parseFile(item), file) for item in [
|
||||
'$XDG_DATA_HOME/ponysay/',
|
||||
'$HOME/.local/share/ponysay/',
|
||||
'/usr/share/ponysay/'
|
||||
'/usr/share/ponysay/',
|
||||
'./'
|
||||
]]
|
||||
|
||||
|
||||
|
@ -197,7 +253,7 @@ class Ponysay():
|
|||
'''
|
||||
Check if ponythink is executed
|
||||
'''
|
||||
isthink = sys.argv[0]
|
||||
let isthink = kuroko.argv[0]
|
||||
if os.sep in isthink:
|
||||
isthink = isthink[isthink.rfind(os.sep) + 1:]
|
||||
if os.extsep in isthink:
|
||||
|
@ -217,7 +273,7 @@ class Ponysay():
|
|||
args.help()
|
||||
exit(254)
|
||||
return
|
||||
self.args = args;
|
||||
self.args = args
|
||||
|
||||
## Emulate termial capabilities
|
||||
if self.__test_nfdnf('-X'): (self.linuxvt, self.usekms) = (False, False)
|
||||
|
@ -229,8 +285,8 @@ class Ponysay():
|
|||
## Variadic variants of -f, -q &c
|
||||
for sign in ('-', '+'):
|
||||
for letter in ('f', 'F', 'q', 'Q'):
|
||||
ssl = sign + sign + letter
|
||||
sl = sign + letter
|
||||
let ssl = sign + sign + letter
|
||||
let sl = sign + letter
|
||||
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]
|
||||
else: args.opts[sl] = args.opts[ssl]
|
||||
|
@ -343,11 +399,11 @@ class Ponysay():
|
|||
if args.opts[key] is not None:
|
||||
return False
|
||||
return True
|
||||
keys = ['-f', '+f', '-F', '-q'] ## TODO +q -Q
|
||||
let keys = ['-f', '+f', '-F', '-q'] ## TODO +q -Q
|
||||
if test(keys, False):
|
||||
for ponydir in self.ponydirs:
|
||||
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):
|
||||
args.opts['-f'] = [pony]
|
||||
else:
|
||||
|
@ -364,8 +420,8 @@ class Ponysay():
|
|||
@param args:ArgParser Parsed command line arguments
|
||||
'''
|
||||
## Read UCS configurations
|
||||
env_ucs = os.environ['PONYSAY_UCS_ME'] if 'PONYSAY_UCS_ME' in os.environ else ''
|
||||
ucs_conf = 0
|
||||
let env_ucs = os.environ['PONYSAY_UCS_ME'] if 'PONYSAY_UCS_ME' in os.environ else ''
|
||||
let ucs_conf = 0
|
||||
if env_ucs in ('yes', 'y', '1'): ucs_conf = 1
|
||||
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`
|
||||
'''
|
||||
## Read UCS configurations
|
||||
env_ucs = os.environ['PONYSAY_UCS_ME'] if 'PONYSAY_UCS_ME' in os.environ else ''
|
||||
ucs_conf = 0
|
||||
let env_ucs = os.environ['PONYSAY_UCS_ME'] if 'PONYSAY_UCS_ME' in os.environ else ''
|
||||
let ucs_conf = 0
|
||||
if env_ucs in ('yes', 'y', '1'): ucs_conf = 1
|
||||
elif env_ucs in ('harder', 'h', '2'): ucs_conf = 2
|
||||
|
||||
|
@ -420,20 +476,20 @@ class Ponysay():
|
|||
return
|
||||
|
||||
## Read all lines in all UCS → ASCII map files
|
||||
maplines = []
|
||||
let maplines = []
|
||||
for ucsmap in self.ucsmaps:
|
||||
if os.path.isfile(ucsmap):
|
||||
with open(ucsmap, 'rb') as mapfile:
|
||||
maplines += [line.replace('\n', '') for line in mapfile.read().decode('utf8', 'replace').split('\n')]
|
||||
|
||||
## Create UCS → ASCII mapping from read lines
|
||||
map = {}
|
||||
stripset = ' \t' # must be string, wtf! and way doesn't python's doc say so
|
||||
let map = {}
|
||||
let stripset = ' \t' # must be string, wtf! and way doesn't python's doc say so
|
||||
for line in maplines:
|
||||
if not line.startswith('#'):
|
||||
s = line.index('→')
|
||||
ucs = line[:s] .strip(stripset)
|
||||
ascii = line[s + 1:].strip(stripset)
|
||||
let s = line.index('→')
|
||||
let ucs = line[:s] .strip(stripset)
|
||||
let ascii = line[s + 1:].strip(stripset)
|
||||
map[ascii] = ucs
|
||||
|
||||
## Apply UCS → ASCII mapping to ponies, by alias if weak settings
|
||||
|
@ -466,31 +522,31 @@ class Ponysay():
|
|||
selection = [self.__selectAnypony(args)]
|
||||
|
||||
## 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]):
|
||||
ponyname = pony[0].split(os.sep)[-1]
|
||||
let ponyname = pony[0].split(os.sep)[-1]
|
||||
if os.extsep in ponyname:
|
||||
ponyname = ponyname[:ponyname.rfind(os.extsep)]
|
||||
return (pony[0], self.__getQuote(ponyname, pony[0]) if pony[2] else None)
|
||||
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 not alt:
|
||||
autocorrect = SpelloCorrecter(possibilities)
|
||||
(alternatives, dist) = autocorrect.correct(pony[0])
|
||||
limit = os.environ['PONYSAY_TYPO_LIMIT'] if 'PONYSAY_TYPO_LIMIT' in os.environ else ''
|
||||
let autocorrect = SpelloCorrecter(possibilities)
|
||||
let alternatives, dist = autocorrect.correct(pony[0])
|
||||
let limit = os.environ['PONYSAY_TYPO_LIMIT'] if 'PONYSAY_TYPO_LIMIT' in os.environ else ''
|
||||
limit = 5 if len(limit) == 0 else int(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)
|
||||
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:
|
||||
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:
|
||||
printerr('Have you tested +f or -F?');
|
||||
printerr('Have you tested +f or -F?')
|
||||
exit(252)
|
||||
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)
|
||||
|
||||
|
||||
|
@ -501,30 +557,30 @@ class Ponysay():
|
|||
@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
|
||||
'''
|
||||
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
|
||||
extra = (args.opts['+f'] is not None) or (args.opts['-F'] is not None) ## TODO +q -Q
|
||||
let quote = args.opts['-q'] is not None ## TODO +q -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
|
||||
let extra = (args.opts['+f'] is not None) or (args.opts['-F'] is not None) ## TODO +q -Q
|
||||
if not (standard or extra):
|
||||
standard = True
|
||||
ponydirs = (self.ponydirs if standard else []) + (self.extraponydirs if extra else []);
|
||||
quoters = self.__quoters() if standard and quote else None ## TODO +q -Q
|
||||
let ponydirs = (self.ponydirs if standard else []) + (self.extraponydirs if extra else [])
|
||||
let quoters = self.__quoters() if standard and quote else None ## TODO +q -Q
|
||||
if (quoters is not None) and (len(quoters) == 0):
|
||||
printerr('Princess Celestia! All the ponies are mute!')
|
||||
exit(250)
|
||||
|
||||
## Get all ponies, with quotes
|
||||
oldponies = {}
|
||||
let oldponies = {}
|
||||
self.__getAllPonies(standard, extra, oldponies, quoters)
|
||||
|
||||
## Apply restriction
|
||||
ponies = self.__applyRestriction(oldponies, ponydirs)
|
||||
let ponies = self.__applyRestriction(oldponies, ponydirs)
|
||||
|
||||
## Select one pony and set all information
|
||||
names = list(ponies.keys())
|
||||
let names = list(ponies.keys())
|
||||
if len(names) == 0:
|
||||
printerr('All the ponies are missing, call the Princess!')
|
||||
exit(249)
|
||||
pony = names[random.randrange(0, len(names))]
|
||||
let pony = names[random.randrange(0, len(names))]
|
||||
return (pony, [ponies[pony]], quote)
|
||||
|
||||
|
||||
|
@ -554,7 +610,7 @@ class Ponysay():
|
|||
for ponydir in directories:
|
||||
for ponyfile in os.listdir(ponydir):
|
||||
if endswith(ponyfile, '.pony'):
|
||||
pony = ponyfile[:-5]
|
||||
let pony = ponyfile[:-5]
|
||||
if (pony not in collection) and ((quoters is None) or (pony in quoters)):
|
||||
collection[pony] = ponydir + ponyfile
|
||||
|
||||
|
@ -575,7 +631,7 @@ class Ponysay():
|
|||
oldponies = ponies
|
||||
|
||||
## Apply dimension restriction
|
||||
ponies = {}
|
||||
let ponies = {}
|
||||
self.__applyDimensionRestriction(ponies, oldponies, ponydirs)
|
||||
if len(ponies) > 0:
|
||||
oldponies = ponies
|
||||
|
@ -606,9 +662,9 @@ class Ponysay():
|
|||
@param oldponies:dict<str, str> Collection of original ponies, maps to pony file
|
||||
@param ponydirs:list<sr> List of pony directories
|
||||
'''
|
||||
(termh, termw) = gettermsize()
|
||||
let termh, termw = gettermsize()
|
||||
for ponydir in ponydirs:
|
||||
(fitw, fith) = (None, None)
|
||||
let fitw, fith = (None, None)
|
||||
if os.path.exists(ponydir + 'widths'):
|
||||
fitw = set()
|
||||
with open(ponydir + 'widths', 'rb') as file:
|
||||
|
@ -619,7 +675,7 @@ class Ponysay():
|
|||
Metadata.getFitting(fith, termh, file)
|
||||
for ponyfile in oldponies.values():
|
||||
if ponyfile.startswith(ponydir):
|
||||
pony = ponyfile[len(ponydir) : -5]
|
||||
let pony = ponyfile[len(ponydir) : -5]
|
||||
if (fitw is None) or (pony in fitw):
|
||||
if (fith is None) or (pony in fith):
|
||||
ponies[pony] = ponyfile
|
||||
|
@ -663,9 +719,9 @@ class Ponysay():
|
|||
if quotedirs is None: quotedirs = self.quotedirs
|
||||
|
||||
## List all unique quote files
|
||||
quotes = []
|
||||
quoteshash = set()
|
||||
_quotes = []
|
||||
let quotes = []
|
||||
let quoteshash = set()
|
||||
let _quotes = []
|
||||
for quotedir in quotedirs:
|
||||
_quotes += [item[:item.index('.')] for item in os.listdir(quotedir)]
|
||||
for quote in _quotes:
|
||||
|
@ -675,11 +731,11 @@ class Ponysay():
|
|||
quotes.append(quote)
|
||||
|
||||
## Create a set of all ponies that have quotes
|
||||
ponies = set()
|
||||
let ponies = set()
|
||||
for ponydir in ponydirs:
|
||||
for pony in os.listdir(ponydir):
|
||||
if not pony[0] == '.':
|
||||
p = pony[:-5] # remove .pony
|
||||
let p = pony[:-5] # remove .pony
|
||||
for quote in quotes:
|
||||
if ('+' + p + '+') in ('+' + quote + '+'):
|
||||
if not p in ponies:
|
||||
|
@ -760,8 +816,7 @@ class Ponysay():
|
|||
@param standard:bool Include standard ponies
|
||||
@param extra:bool Include extra ponies
|
||||
'''
|
||||
|
||||
pony_dirs = (self.ponydirs if standard else []) + (self.extraponydirs if extra else [])
|
||||
let pony_dirs = (self.ponydirs if standard else []) + (self.extraponydirs if extra else [])
|
||||
|
||||
lists.onelist(pony_dirs, self.__ucsise)
|
||||
|
||||
|
@ -774,7 +829,7 @@ class Ponysay():
|
|||
@param extra:bool Include extra ponies
|
||||
'''
|
||||
## Get all quoters
|
||||
ponies = list(self.__quoters()) if standard else []
|
||||
let ponies = list(self.__quoters()) if standard else []
|
||||
|
||||
## And now the extra ponies
|
||||
if extra:
|
||||
|
@ -818,10 +873,10 @@ class Ponysay():
|
|||
return None
|
||||
|
||||
## Get all balloons
|
||||
balloons = {}
|
||||
let balloons = {}
|
||||
for balloondir in self.balloondirs:
|
||||
for balloon in os.listdir(balloondir):
|
||||
balloonfile = balloon
|
||||
let balloonfile = balloon
|
||||
## Use .think if running ponythink, otherwise .say
|
||||
if self.isthink and endswith(balloon, '.think'):
|
||||
balloon = balloon[:-6]
|
||||
|
@ -840,12 +895,12 @@ class Ponysay():
|
|||
balloons[name] = name
|
||||
|
||||
## 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 not alt:
|
||||
autocorrect = SpelloCorrecter(self.balloondirs, '.think' if self.isthink else '.say')
|
||||
(alternatives, dist) = autocorrect.correct(balloon)
|
||||
limit = os.environ['PONYSAY_TYPO_LIMIT'] if 'PONYSAY_TYPO_LIMIT' in os.environ else ''
|
||||
let autocorrect = SpelloCorrecter(self.balloondirs, '.think' if self.isthink else '.say')
|
||||
let alternatives, dist = autocorrect.correct(balloon)
|
||||
let limit = os.environ['PONYSAY_TYPO_LIMIT'] if 'PONYSAY_TYPO_LIMIT' in os.environ else ''
|
||||
limit = 5 if len(limit) == 0 else int(limit)
|
||||
if (len(alternatives) > 0) and (dist <= limit):
|
||||
return self.__getBalloonPath(alternatives, True)
|
||||
|
@ -885,12 +940,12 @@ class Ponysay():
|
|||
@param args:ArgParser Parsed command line arguments
|
||||
'''
|
||||
## Get the pony
|
||||
selection = []
|
||||
let selection = []
|
||||
self.__getSelectedPonies(args, selection)
|
||||
(pony, quote) = self.__getPony(selection, args)
|
||||
let pony, quote = self.__getPony(selection, args)
|
||||
|
||||
## Get message and manipulate it
|
||||
msg = self.__getMessage(args, quote)
|
||||
let msg = self.__getMessage(args, quote)
|
||||
msg = self.__colouriseMessage(args, msg)
|
||||
msg = self.__compressMessage(args, msg)
|
||||
|
||||
|
@ -901,38 +956,38 @@ class Ponysay():
|
|||
pony = self.__useImage(pony)
|
||||
|
||||
## 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 self.linuxvt:
|
||||
print('\033[H\033[2J', end='')
|
||||
|
||||
## Get width truncation and wrapping
|
||||
widthtruncation = self.__getWidthTruncation()
|
||||
messagewrap = self.__getMessageWrap(args)
|
||||
let widthtruncation = self.__getWidthTruncation()
|
||||
let messagewrap = self.__getMessageWrap(args)
|
||||
|
||||
## 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))
|
||||
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
|
||||
hyphen = self.__getHyphen(args)
|
||||
let hyphen = self.__getHyphen(args)
|
||||
|
||||
## Link and balloon colouring
|
||||
linkcolour = self.__getLinkColour(args)
|
||||
ballooncolour = self.__getBalloonColour(args)
|
||||
let linkcolour = self.__getLinkColour(args)
|
||||
let ballooncolour = self.__getBalloonColour(args)
|
||||
|
||||
## Determine --info/++info settings
|
||||
minusinfo = args.opts['-i'] is not None
|
||||
plusinfo = args.opts['+i'] is not None
|
||||
let minusinfo = args.opts['-i'] is not None
|
||||
let plusinfo = args.opts['+i'] is not None
|
||||
|
||||
## 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,
|
||||
infolevel = 2 if plusinfo else (1 if minusinfo else 0))
|
||||
backend.parse()
|
||||
output = backend.output
|
||||
let output = backend.output
|
||||
if output.endswith('\n'):
|
||||
output = output[:-1]
|
||||
|
||||
|
@ -947,7 +1002,7 @@ class Ponysay():
|
|||
@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
|
||||
'''
|
||||
(standard, extra) = ([], [])
|
||||
let standard, extra = [], []
|
||||
for ponydir in self.ponydirs:
|
||||
for pony in os.listdir(ponydir):
|
||||
if endswith(pony, '.pony'):
|
||||
|
@ -956,8 +1011,8 @@ class Ponysay():
|
|||
for pony in os.listdir(ponydir):
|
||||
if endswith(pony, '.pony'):
|
||||
extra.append(ponydir + pony)
|
||||
both = standard + extra
|
||||
for (opt, ponies, quotes) in [('-f', standard, False), ('+f', extra, False), ('-F', both, False), ('-q', standard, True)]: ## TODO +q -Q
|
||||
let both = standard + extra
|
||||
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:
|
||||
for pony in args.opts[opt]:
|
||||
selection.append((pony, ponies, quotes))
|
||||
|
@ -974,7 +1029,7 @@ class Ponysay():
|
|||
if quote is not None:
|
||||
return quote
|
||||
if args.message is None:
|
||||
return ''.join(sys.stdin.readlines()).rstrip()
|
||||
return ''.join(fileio.stdin.readlines()).rstrip()
|
||||
return args.message
|
||||
|
||||
|
||||
|
@ -1044,7 +1099,7 @@ class Ponysay():
|
|||
|
||||
@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'
|
||||
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
|
||||
@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):
|
||||
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
|
||||
|
@ -1075,10 +1130,10 @@ class Ponysay():
|
|||
@param args:ArgParser Command line options
|
||||
@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):
|
||||
hyphen = '-'
|
||||
hyphencolour = ''
|
||||
let hyphencolour = ''
|
||||
if args.opts['--colour-wrap'] is not None:
|
||||
hyphencolour = '\033[' + ';'.join(args.opts['--colour-wrap']) + 'm'
|
||||
return '\033[31m' + hyphencolour + hyphen
|
||||
|
@ -1091,7 +1146,7 @@ class Ponysay():
|
|||
@param args:ArgParser Command line options
|
||||
@return :str The colour of balloon links
|
||||
'''
|
||||
linkcolour = ''
|
||||
let linkcolour = ''
|
||||
if args.opts['--colour-link'] is not None:
|
||||
linkcolour = '\033[' + ';'.join(args.opts['--colour-link']) + 'm'
|
||||
return linkcolour
|
||||
|
@ -1104,7 +1159,7 @@ class Ponysay():
|
|||
@param args:ArgParser Command line options
|
||||
@return :str The colour of balloons
|
||||
'''
|
||||
ballooncolour = ''
|
||||
let ballooncolour = ''
|
||||
if args.opts['--colour-bubble'] is not None:
|
||||
ballooncolour = '\033[' + ';'.join(args.opts['--colour-bubble']) + 'm'
|
||||
return ballooncolour
|
||||
|
@ -1117,17 +1172,17 @@ class Ponysay():
|
|||
@param output:str The output truncated on the width but not on the height
|
||||
'''
|
||||
## 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 = ''
|
||||
|
||||
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 = ''
|
||||
|
||||
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'
|
||||
|
||||
## 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 env_bottom in ('yes', 'y', '1'):
|
||||
for line in output.split('\n')[: -lines]:
|
|
@ -31,15 +31,16 @@ the colon.
|
|||
'''
|
||||
|
||||
import os
|
||||
import sys
|
||||
from subprocess import Popen, PIPE
|
||||
import kuroko
|
||||
import fileio
|
||||
|
||||
from argparser import *
|
||||
from ponysay import *
|
||||
from metadata import *
|
||||
from ponysay.argparser import ArgParser
|
||||
from ponysay.ponysay import Ponysay
|
||||
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
|
||||
'''
|
||||
|
@ -54,7 +55,7 @@ def print(text = '', end = '\n'):
|
|||
@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'))
|
||||
fileio.stdout.buffer.write((str(text) + end).encode('utf-8'))
|
||||
|
||||
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 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:
|
||||
args.help()
|
||||
exit(255)
|
||||
os.exit(255)
|
||||
return
|
||||
|
||||
opts = args.opts
|
||||
|
@ -88,7 +89,7 @@ class PonysayTool():
|
|||
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)
|
||||
if unrecognised:
|
||||
exit(254)
|
||||
os.exit(254)
|
||||
|
||||
elif opts['-v'] is not None:
|
||||
print('%s %s' % ('ponysay-tool', VERSION))
|
||||
|
@ -105,33 +106,33 @@ class PonysayTool():
|
|||
elif (opts['-b'] is not None) and (len(opts['-b']) == 1):
|
||||
try:
|
||||
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 %= ('-echo -icanon -echo -isig -ixoff -ixon', os.path.realpath('/dev/stdout'))
|
||||
Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).wait()
|
||||
print('\033[?25l', end='') # hide cursor
|
||||
print('\[[?25l', end='') # hide cursor
|
||||
dir = opts['-b'][0]
|
||||
if not dir.endswith(os.sep):
|
||||
dir += os.sep
|
||||
self.browse(dir, opts['-r'])
|
||||
finally:
|
||||
print('\033[?25h', end='') # show cursor
|
||||
print('\[[?25h', end='') # show cursor
|
||||
cmd = 'stty %s < %s > /dev/null 2> /dev/null'
|
||||
cmd %= ('echo icanon echo isig ixoff ixon', os.path.realpath('/dev/stdout'))
|
||||
Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).wait()
|
||||
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):
|
||||
pony = opts['--edit'][0]
|
||||
if not os.path.isfile(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')
|
||||
try:
|
||||
if opts['--no-term-init'] is None:
|
||||
print('\033[?1049h', end='') # initialise terminal
|
||||
if linuxvt: print('\033[?8c', end='') # use full block for cursor (_ is used by default in linux vt)
|
||||
print('\[[?1049h', end='') # initialise terminal
|
||||
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 %= ('-echo -icanon -echo -isig -ixoff -ixon', os.path.realpath('/dev/stdout'))
|
||||
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 %= ('echo icanon echo isig ixoff ixon', os.path.realpath('/dev/stdout'))
|
||||
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:
|
||||
print('\033[?1049l', end='') # terminate terminal
|
||||
print('\[[?1049l', end='') # terminate terminal
|
||||
|
||||
elif (opts['--edit-rm'] is not None) and (len(opts['--edit-rm']) == 1):
|
||||
ponyfile = opts['--edit-rm'][0]
|
||||
|
@ -174,7 +175,7 @@ class PonysayTool():
|
|||
if data == '':
|
||||
if line != '$$$':
|
||||
printerr('Bad stash')
|
||||
exit(251)
|
||||
os.exit(251)
|
||||
data += '$$$\n'
|
||||
else:
|
||||
data += line + '\n'
|
||||
|
@ -192,7 +193,7 @@ class PonysayTool():
|
|||
|
||||
else:
|
||||
args.help()
|
||||
exit(253)
|
||||
os.exit(253)
|
||||
|
||||
|
||||
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 None
|
||||
def __contains__(self, key):
|
||||
return key in args;
|
||||
return key in args
|
||||
|
||||
stdout = sys.stdout
|
||||
stdout = fileio.stdout
|
||||
class StringInputStream():
|
||||
def __init__(self):
|
||||
self.buf = ''
|
||||
|
@ -232,11 +233,11 @@ class PonysayTool():
|
|||
pass
|
||||
def isatty(self):
|
||||
return True
|
||||
sys.stdout = StringInputStream()
|
||||
fileio.stdout = StringInputStream()
|
||||
ponysay = Ponysay()
|
||||
ponysay.run(PhonyArgParser(args, message))
|
||||
out = sys.stdout.buf[:-1]
|
||||
sys.stdout = stdout
|
||||
out = fileio.stdout.buf[:-1]
|
||||
fileio.stdout = stdout
|
||||
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
|
||||
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]
|
||||
if len(termsize) > 0:
|
||||
termsize = termsize.decode('utf8', 'replace')[:-1].split(' ') # [:-1] removes a \n
|
||||
|
@ -275,7 +276,7 @@ class PonysayTool():
|
|||
ponies.sort()
|
||||
|
||||
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()
|
||||
|
||||
panelw = Backend.len(max(ponies, key = Backend.len))
|
||||
|
@ -300,14 +301,14 @@ class PonysayTool():
|
|||
ponyfile = (ponydir + '/' + ponies[ponyindex] + '.pony').replace('//', '/')
|
||||
pony = self.execPonysay({'-f' : ponyfile, '-W' : 'none', '-o' : None}).split('\n')
|
||||
|
||||
preprint = '\033[H\033[2J'
|
||||
preprint = '\[[H\[[2J'
|
||||
if pony[0].startswith(preprint):
|
||||
pony[0] = pony[0][len(preprint):]
|
||||
ponyheight = len(pony)
|
||||
ponywidth = Backend.len(max(pony, key = Backend.len))
|
||||
|
||||
AUTO_PUSH = '\033[01010~'
|
||||
AUTO_POP = '\033[10101~'
|
||||
AUTO_PUSH = '\[[01010~'
|
||||
AUTO_POP = '\[[10101~'
|
||||
pony = '\n'.join(pony).replace('\n', AUTO_PUSH + '\n' + AUTO_POP)
|
||||
colourstack = ColourStack(AUTO_PUSH, AUTO_POP)
|
||||
buf = ''
|
||||
|
@ -317,7 +318,7 @@ class PonysayTool():
|
|||
|
||||
if (oldx != x) or (oldy != y):
|
||||
(oldx, oldy) = (x, y)
|
||||
print('\033[H\033[2J', end='')
|
||||
print('\[[H\[[2J', end='')
|
||||
|
||||
def getprint(pony, ponywidth, ponyheight, termw, termh, px, py):
|
||||
ponyprint = pony
|
||||
|
@ -338,7 +339,7 @@ class PonysayTool():
|
|||
elif px > 0:
|
||||
ponyprint = [px * ' ' + line 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)
|
||||
|
||||
if quotes:
|
||||
|
@ -361,24 +362,24 @@ class PonysayTool():
|
|||
for line in ponies[panely:]:
|
||||
cury += 1
|
||||
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:
|
||||
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:
|
||||
for index in (printpanel, ponyindex):
|
||||
cury = index - panely
|
||||
if (0 <= cury) and (cury < termh):
|
||||
line = ponies[cury + panely]
|
||||
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:
|
||||
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:
|
||||
d = sys.stdin.read(1)
|
||||
d = fileio.stdin.read(1)
|
||||
else:
|
||||
d = stored
|
||||
stored = None
|
||||
|
@ -409,20 +410,20 @@ class PonysayTool():
|
|||
elif ord(d) == ord('Q') - ord('@'):
|
||||
break
|
||||
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
|
||||
elif d == '\033':
|
||||
d = sys.stdin.read(1)
|
||||
elif d == '\[':
|
||||
d = fileio.stdin.read(1)
|
||||
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'
|
||||
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 == 'D': stored = chr(ord('P') - ord('@')) if (not quotes) and (not info) else 'A'
|
||||
elif d == '1':
|
||||
if sys.stdin.read(1) == ';':
|
||||
if sys.stdin.read(1) == '5':
|
||||
d = sys.stdin.read(1)
|
||||
if fileio.stdin.read(1) == ';':
|
||||
if fileio.stdin.read(1) == '5':
|
||||
d = fileio.stdin.read(1)
|
||||
if d == 'A': stored = 'W'
|
||||
elif d == 'B': stored = 'S'
|
||||
elif d == 'C': stored = 'D'
|
||||
|
@ -446,7 +447,7 @@ class PonysayTool():
|
|||
def __getitem__(self, key):
|
||||
return [self.value] if key == self.key else None
|
||||
def __contains__(self, key):
|
||||
return key == self.key;
|
||||
return key == self.key
|
||||
|
||||
class StringInputStream():
|
||||
def __init__(self):
|
||||
|
@ -464,36 +465,36 @@ class PonysayTool():
|
|||
def isatty(self):
|
||||
return True
|
||||
|
||||
stdout = sys.stdout
|
||||
stdout = fileio.stdout
|
||||
term = os.environ['TERM']
|
||||
os.environ['TERM'] = 'linux'
|
||||
|
||||
sys.stdout = StringInputStream()
|
||||
fileio.stdout = StringInputStream()
|
||||
ponysay = Ponysay()
|
||||
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.run(PhonyArgParser('++onelist', None))
|
||||
extraponies = sys.stdout.buf[:-1].split('\n')
|
||||
extraponies = fileio.stdout.buf[:-1].split('\n')
|
||||
|
||||
for pony in stdponies:
|
||||
printerr('Genering standard kmspony: %s' % pony)
|
||||
sys.stderr.buffer.flush();
|
||||
sys.stdout = StringInputStream()
|
||||
fileio.stderr.buffer.flush()
|
||||
fileio.stdout = StringInputStream()
|
||||
ponysay = Ponysay()
|
||||
ponysay.run(PhonyArgParser('--pony', pony))
|
||||
|
||||
for pony in extraponies:
|
||||
printerr('Genering extra kmspony: %s' % pony)
|
||||
sys.stderr.buffer.flush();
|
||||
sys.stdout = StringInputStream()
|
||||
fileio.stderr.buffer.flush()
|
||||
fileio.stdout = StringInputStream()
|
||||
ponysay = Ponysay()
|
||||
ponysay.run(PhonyArgParser('++pony', pony))
|
||||
|
||||
os.environ['TERM'] = term
|
||||
sys.stdout = stdout
|
||||
fileio.stdout = stdout
|
||||
|
||||
|
||||
def generateDimensions(self, ponydir, ponies = None):
|
||||
|
@ -523,8 +524,8 @@ class PonysayTool():
|
|||
return [('none' if self.balloon else None)]
|
||||
return None
|
||||
def __contains__(self, key):
|
||||
return key in ('-f', '-W', '-b');
|
||||
stdout = sys.stdout
|
||||
return key in ('-f', '-W', '-b')
|
||||
stdout = fileio.stdout
|
||||
class StringInputStream():
|
||||
def __init__(self):
|
||||
self.buf = ''
|
||||
|
@ -540,7 +541,7 @@ class PonysayTool():
|
|||
pass
|
||||
def isatty(self):
|
||||
return True
|
||||
sys.stdout = StringInputStream()
|
||||
fileio.stdout = StringInputStream()
|
||||
ponysay = Ponysay()
|
||||
ponysay.run(PhonyArgParser(True))
|
||||
printpony = sys.stdout.buf[:-1].split('\n')
|
||||
|
@ -697,7 +698,7 @@ class PonysayTool():
|
|||
if key == '-W': return ['n']
|
||||
return None
|
||||
def __contains__(self, key):
|
||||
return key in ('-f', '-W');
|
||||
return key in ('-f', '-W')
|
||||
|
||||
|
||||
data = {}
|
||||
|
@ -750,7 +751,7 @@ class PonysayTool():
|
|||
printpony = sys.stdout.buf[:-1].split('\n')
|
||||
sys.stdout = stdout
|
||||
|
||||
preprint = '\033[H\033[2J'
|
||||
preprint = '\[[H\[[2J'
|
||||
if printpony[0].startswith(preprint):
|
||||
printpony[0] = printpony[0][len(preprint):]
|
||||
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]
|
||||
break
|
||||
|
||||
AUTO_PUSH = '\033[01010~'
|
||||
AUTO_POP = '\033[10101~'
|
||||
AUTO_PUSH = '\[[01010~'
|
||||
AUTO_POP = '\[[10101~'
|
||||
modprintpony = '\n'.join(printpony).replace('\n', AUTO_PUSH + '\n' + AUTO_POP)
|
||||
colourstack = ColourStack(AUTO_PUSH, AUTO_POP)
|
||||
buf = ''
|
||||
|
@ -774,12 +775,12 @@ class PonysayTool():
|
|||
buf += c + colourstack.feed(c)
|
||||
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('\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()
|
||||
|
||||
|
@ -885,17 +886,17 @@ class TextArea(): # TODO support small screens (This is being work on in GNU-Po
|
|||
killptr = None
|
||||
|
||||
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')
|
||||
|
||||
print('\033[%i;%iH' % (self.top, innerleft), end='')
|
||||
print('\[[%i;%iH' % (self.top, innerleft), end='')
|
||||
|
||||
def alert(text):
|
||||
if text is None:
|
||||
alert('')
|
||||
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
|
||||
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('@'))
|
||||
alerted = False
|
||||
edited = False
|
||||
print('\033[%i;%iH' % (self.top + y, innerleft + x), end='')
|
||||
print('\[[%i;%iH' % (self.top + y, innerleft + x), end='')
|
||||
while True:
|
||||
if (oldmark is not None) and (oldmark >= 0):
|
||||
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:
|
||||
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 < 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:
|
||||
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 (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:
|
||||
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]):
|
||||
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:
|
||||
print('\033[%i;%iH\033[1;34m%s:\033[21;39m' % (self.top + y, self.left, leftlines[y]), end='')
|
||||
print('\033[%i;%iH' % (self.top + y, innerleft + x), end='')
|
||||
print('\[[%i;%iH\[[1;34m%s:\[[22;39m' % (self.top + y, self.left, leftlines[y]), end='')
|
||||
print('\[[%i;%iH' % (self.top + y, innerleft + x), end='')
|
||||
(oldy, oldx, oldmark) = (y, x, mark)
|
||||
if edited:
|
||||
edited = False
|
||||
|
@ -980,10 +981,10 @@ class TextArea(): # TODO support small screens (This is being work on in GNU-Po
|
|||
mark = None
|
||||
killptr = len(killring) - 1
|
||||
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:]
|
||||
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('@'):
|
||||
alert('C-x')
|
||||
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:]
|
||||
x -= removed
|
||||
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
|
||||
elif ord(d) < 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('@'):
|
||||
if x < len(datalines[y]):
|
||||
x += 1
|
||||
print('\033[C', end='')
|
||||
print('\[[C', end='')
|
||||
else:
|
||||
alert('At end')
|
||||
alerted = True
|
||||
elif ord(d) == ord('B') - ord('@'):
|
||||
if x > 0:
|
||||
x -= 1
|
||||
print('\033[D', end='')
|
||||
print('\[[D', end='')
|
||||
else:
|
||||
alert('At beginning')
|
||||
alerted = True
|
||||
|
@ -1074,17 +1075,17 @@ class TextArea(): # TODO support small screens (This is being work on in GNU-Po
|
|||
x = 0
|
||||
stored = chr(ord('L') - ord('@'))
|
||||
elif ord(d) == ord('L') - ord('@'):
|
||||
empty = '\033[0m' + (' ' * self.width + '\n') * len(datalines)
|
||||
print('\033[%i;%iH%s' % (self.top, self.left, empty), end='')
|
||||
empty = '\[[0m' + (' ' * self.width + '\n') * len(datalines)
|
||||
print('\[[%i;%iH%s' % (self.top, self.left, empty), end='')
|
||||
for row in range(0, len(leftlines)):
|
||||
leftline = leftlines[row] + ':'
|
||||
if (leftlines[row - 1] == leftlines[row]) and (leftlines[row] == leftlines[-1]):
|
||||
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)):
|
||||
print('\033[%i;%iH%s\033[49m' % (self.top + row, innerleft, datalines[row]), end='')
|
||||
print('\033[%i;%iH' % (self.top + y, innerleft + x), end='')
|
||||
elif d == '\033':
|
||||
print('\[[%i;%iH%s\[[49m' % (self.top + row, innerleft, datalines[row]), end='')
|
||||
print('\[[%i;%iH' % (self.top + y, innerleft + x), end='')
|
||||
elif d == '\[':
|
||||
d = sys.stdin.read(1)
|
||||
if d == '[':
|
||||
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
|
||||
continue
|
||||
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
|
||||
edited = True
|
||||
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)
|
||||
x += additional
|
||||
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:
|
||||
stored = chr(ord('Y') - ord('@'))
|
||||
else:
|
||||
stored = chr(ord('Y') - ord('@'))
|
||||
elif d == 'O':
|
||||
d = sys.stdin.read(1)
|
||||
d = fileio.stdin.read(1)
|
||||
if d == 'H':
|
||||
x = 0
|
||||
elif d == 'F':
|
||||
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':
|
||||
stored = chr(ord('N') - ord('@'))
|
||||
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)):
|
||||
print(insert + dataline[x:], end='')
|
||||
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:]
|
||||
if (mark is not None) and (mark >= 0):
|
||||
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
|
||||
'''
|
||||
|
||||
pipelinein = not sys.stdin.isatty()
|
||||
let pipelinein = not os.isatty(0)
|
||||
'''
|
||||
Whether stdin is piped
|
||||
'''
|
||||
|
||||
pipelineout = not sys.stdout.isatty()
|
||||
let pipelineout = not os.isatty(1)
|
||||
'''
|
||||
Whether stdout is piped
|
||||
'''
|
||||
|
||||
pipelineerr = not sys.stderr.isatty()
|
||||
let pipelineerr = not os.isatty(2)
|
||||
'''
|
||||
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)'),
|
||||
'%s %s' % (usage_program, '(--edit | --edit-rm) \033[33mPONY-FILE\033[39m'),
|
||||
'%s %s' % (usage_program, '--edit-stash \033[33mPONY-FILE\033[39m > \033[33mSTASH-FILE\033[39m'),
|
||||
'%s %s' % (usage_program, '--edit-apply \033[33mPONY-FILE\033[39m < \033[33mSTASH-FILE\033[39m'),
|
||||
'%s %s' % (usage_program, '(--dimensions | --metadata) \033[33mPONY-DIR\033[39m'),
|
||||
'%s %s' % (usage_program, '--browse \033[33mPONY-DIR\033[39m [-r \033[33mRESTRICTION\033[39m]*'),
|
||||
let usage = '\n'.join([' '.join((usage_program, '(--help | --version | --kms)')),
|
||||
' '.join((usage_program, '(--edit | --edit-rm) \[[33mPONY-FILE\[[39m')),
|
||||
' '.join((usage_program, '--edit-stash \[[33mPONY-FILE\[[39m > \[[33mSTASH-FILE\[[39m')),
|
||||
' '.join((usage_program, '--edit-apply \[[33mPONY-FILE\[[39m < \[[33mSTASH-FILE\[[39m')),
|
||||
' '.join((usage_program, '(--dimensions | --metadata) \[[33mPONY-DIR\[[39m')),
|
||||
' '.join((usage_program, '--browse \[[33mPONY-DIR\[[39m [-r \[[33mRESTRICTION\[[39m]*')),
|
||||
])
|
||||
|
||||
usage = usage.replace('\033[', '\0')
|
||||
usage = usage.replace('\[[', 'あ')
|
||||
for sym in ('[', ']', '(', ')', '|', '...', '*'):
|
||||
usage = usage.replace(sym, '\033[2m' + sym + '\033[22m')
|
||||
usage = usage.replace('\0', '\033[')
|
||||
usage = usage.replace(sym, '\[[2m' + sym + '\[[22m')
|
||||
usage = usage.replace('あ', '\[[')
|
||||
|
||||
'''
|
||||
Argument parsing
|
||||
'''
|
||||
opts = ArgParser(program = 'ponysay-tool',
|
||||
let opts = ArgParser(program = 'ponysay-tool',
|
||||
description = 'Tool chest for ponysay',
|
||||
usage = usage,
|
||||
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-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
|
||||
'''
|
|
@ -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
|
||||
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
|
||||
|
@ -74,18 +73,18 @@ class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimise
|
|||
for y in range(0, 128):
|
||||
self.M[y] = [0] * 128
|
||||
self.M[y][0] = y
|
||||
m0 = self.M[0]
|
||||
x = 127
|
||||
let m0 = self.M[0]
|
||||
let x = 127
|
||||
while x > -1:
|
||||
m0[x] = x
|
||||
x -= 1
|
||||
|
||||
previous = ''
|
||||
self.dictionary[-1] = previous;
|
||||
let previous = ''
|
||||
self.dictionary[-1] = previous
|
||||
|
||||
if ending is not None:
|
||||
for directory in directories:
|
||||
files = os.listdir(directory)
|
||||
let files = os.listdir(directory)
|
||||
files.sort()
|
||||
for filename in files:
|
||||
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
|
||||
self.reusable[self.dictionaryEnd] = prevCommon
|
||||
else:
|
||||
files = directories
|
||||
let files = directories
|
||||
files.sort()
|
||||
for proper in files:
|
||||
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
|
||||
'''
|
||||
self.closestDistance = 0x7FFFFFFF
|
||||
previous = self.dictionary[-1]
|
||||
prevLen = 0
|
||||
usedLen = len(used)
|
||||
let previous = self.dictionary[-1]
|
||||
let prevLen = 0
|
||||
let usedLen = len(used)
|
||||
|
||||
proper = None
|
||||
prevCommon = 0
|
||||
let proper = None
|
||||
let prevCommon = 0
|
||||
|
||||
d = len(self.dictionary) - 1
|
||||
let d = len(self.dictionary) - 1
|
||||
while d > self.dictionaryEnd:
|
||||
d -= 1
|
||||
proper = self.dictionary[d]
|
||||
if abs(len(proper) - usedLen) <= self.closestDistance:
|
||||
if previous == self.dictionary[d + 1]:
|
||||
prevCommon = self.reusable[d];
|
||||
prevCommon = self.reusable[d]
|
||||
else:
|
||||
prevCommon = min(prevLen, len(proper))
|
||||
for i in range(0, prevCommon):
|
||||
|
@ -188,8 +187,8 @@ class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimise
|
|||
prevCommon = i
|
||||
break
|
||||
|
||||
skip = min(prevLen, len(proper))
|
||||
i = prevCommon
|
||||
let skip = min(prevLen, len(proper))
|
||||
let i = prevCommon
|
||||
while i < skip:
|
||||
for u in range(0, usedLen):
|
||||
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
|
||||
i += 1
|
||||
|
||||
common = min(skip, min(usedLen, len(proper)))
|
||||
let common = min(skip, min(usedLen, len(proper)))
|
||||
for i in range(0, common):
|
||||
if used[i] != proper[i]:
|
||||
common = i
|
||||
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:
|
||||
self.closestDistance = distance
|
||||
|
@ -211,7 +210,7 @@ class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimise
|
|||
elif self.closestDistance == distance:
|
||||
self.corrections.append(proper)
|
||||
|
||||
previous = proper;
|
||||
previous = proper
|
||||
if distance >= 0x7FFFFF00:
|
||||
prevLen = distance & 255
|
||||
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
|
||||
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
|
||||
@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 (0x20D0 <= o) and (o <= 0x20FF): 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
|
||||
@return :int The number of combining characters in the string
|
||||
'''
|
||||
rc = 0
|
||||
let rc = 0
|
||||
for char in string:
|
||||
if UCS.isCombining(char):
|
||||
rc += 1
|
Loading…
Reference in a new issue