mirror of
https://github.com/erkin/ponysay.git
synced 2024-11-22 20:38:00 +01:00
move documentation to be below the declaration and not above, this makes it parsable by python's help command, althought it is not as pretty, but hay, help() is awesome
Signed-off-by: Mattias Andrée <maandree@operamail.com>
This commit is contained in:
parent
a18804002b
commit
ecdac1b6a1
12 changed files with 583 additions and 579 deletions
|
@ -33,25 +33,29 @@ from common import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ARGUMENTLESS = 0
|
||||||
'''
|
'''
|
||||||
Option takes no arguments
|
Option takes no arguments
|
||||||
'''
|
'''
|
||||||
ARGUMENTLESS = 0
|
|
||||||
|
|
||||||
|
ARGUMENTED = 1
|
||||||
'''
|
'''
|
||||||
Option takes one argument per instance
|
Option takes one argument per instance
|
||||||
'''
|
'''
|
||||||
ARGUMENTED = 1
|
|
||||||
|
|
||||||
|
VARIADIC = 2
|
||||||
'''
|
'''
|
||||||
Option consumes all following arguments
|
Option consumes all following arguments
|
||||||
'''
|
'''
|
||||||
VARIADIC = 2
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ArgParser():
|
||||||
'''
|
'''
|
||||||
Simple argument parser
|
Simple argument parser
|
||||||
'''
|
'''
|
||||||
class ArgParser():
|
|
||||||
|
def __init__(self, program, description, usage, longdescription = None):
|
||||||
'''
|
'''
|
||||||
Constructor.
|
Constructor.
|
||||||
The short description is printed on same line as the program name
|
The short description is printed on same line as the program name
|
||||||
|
@ -61,7 +65,6 @@ class ArgParser():
|
||||||
@param usage:str Formated, multi-line, usage text
|
@param usage:str Formated, multi-line, usage text
|
||||||
@param longdescription:str Long, multi-line, description of the program, may be `None`
|
@param longdescription:str Long, multi-line, description of the program, may be `None`
|
||||||
'''
|
'''
|
||||||
def __init__(self, program, description, usage, longdescription = None):
|
|
||||||
self.linuxvt = ('TERM' in os.environ) and (os.environ['TERM'] == 'linux')
|
self.linuxvt = ('TERM' in os.environ) and (os.environ['TERM'] == 'linux')
|
||||||
self.__program = program
|
self.__program = program
|
||||||
self.__description = description
|
self.__description = description
|
||||||
|
@ -72,19 +75,20 @@ class ArgParser():
|
||||||
self.optmap = {}
|
self.optmap = {}
|
||||||
|
|
||||||
|
|
||||||
|
def add_argumentless(self, alternatives, help = None):
|
||||||
'''
|
'''
|
||||||
Add option that takes no arguments
|
Add option that takes no arguments
|
||||||
|
|
||||||
@param alternatives:list<str> Option names
|
@param alternatives:list<str> Option names
|
||||||
@param help:str Short description, use `None` to hide the option
|
@param help:str Short description, use `None` to hide the option
|
||||||
'''
|
'''
|
||||||
def add_argumentless(self, alternatives, help = None):
|
|
||||||
self.__arguments.append((ARGUMENTLESS, alternatives, None, help))
|
self.__arguments.append((ARGUMENTLESS, alternatives, None, help))
|
||||||
stdalt = alternatives[0]
|
stdalt = alternatives[0]
|
||||||
self.opts[stdalt] = None
|
self.opts[stdalt] = None
|
||||||
for alt in alternatives:
|
for alt in alternatives:
|
||||||
self.optmap[alt] = (stdalt, ARGUMENTLESS)
|
self.optmap[alt] = (stdalt, ARGUMENTLESS)
|
||||||
|
|
||||||
|
def add_argumented(self, alternatives, arg, help = None):
|
||||||
'''
|
'''
|
||||||
Add option that takes one argument
|
Add option that takes one argument
|
||||||
|
|
||||||
|
@ -92,13 +96,13 @@ class ArgParser():
|
||||||
@param arg:str The name of the takes argument, one word
|
@param arg:str The name of the takes argument, one word
|
||||||
@param help:str Short description, use `None` to hide the option
|
@param help:str Short description, use `None` to hide the option
|
||||||
'''
|
'''
|
||||||
def add_argumented(self, alternatives, arg, help = None):
|
|
||||||
self.__arguments.append((ARGUMENTED, alternatives, arg, help))
|
self.__arguments.append((ARGUMENTED, alternatives, arg, help))
|
||||||
stdalt = alternatives[0]
|
stdalt = alternatives[0]
|
||||||
self.opts[stdalt] = None
|
self.opts[stdalt] = None
|
||||||
for alt in alternatives:
|
for alt in alternatives:
|
||||||
self.optmap[alt] = (stdalt, ARGUMENTED)
|
self.optmap[alt] = (stdalt, ARGUMENTED)
|
||||||
|
|
||||||
|
def add_variadic(self, alternatives, arg, help = None):
|
||||||
'''
|
'''
|
||||||
Add option that takes all following argument
|
Add option that takes all following argument
|
||||||
|
|
||||||
|
@ -106,7 +110,6 @@ class ArgParser():
|
||||||
@param arg:str The name of the takes arguments, one word
|
@param arg:str The name of the takes arguments, one word
|
||||||
@param help:str Short description, use `None` to hide the option
|
@param help:str Short description, use `None` to hide the option
|
||||||
'''
|
'''
|
||||||
def add_variadic(self, alternatives, arg, help = None):
|
|
||||||
self.__arguments.append((VARIADIC, alternatives, arg, help))
|
self.__arguments.append((VARIADIC, alternatives, arg, help))
|
||||||
stdalt = alternatives[0]
|
stdalt = alternatives[0]
|
||||||
self.opts[stdalt] = None
|
self.opts[stdalt] = None
|
||||||
|
@ -114,13 +117,13 @@ class ArgParser():
|
||||||
self.optmap[alt] = (stdalt, VARIADIC)
|
self.optmap[alt] = (stdalt, VARIADIC)
|
||||||
|
|
||||||
|
|
||||||
|
def parse(self, argv = sys.argv):
|
||||||
'''
|
'''
|
||||||
Parse arguments
|
Parse arguments
|
||||||
|
|
||||||
@param args:list<str> The command line arguments, should include the execute file at index 0, `sys.argv` is default
|
@param args:list<str> The command line arguments, should include the execute file at index 0, `sys.argv` is default
|
||||||
@return :bool Whether no unrecognised option is used
|
@return :bool Whether no unrecognised option is used
|
||||||
'''
|
'''
|
||||||
def parse(self, argv = sys.argv):
|
|
||||||
self.argcount = len(argv) - 1
|
self.argcount = len(argv) - 1
|
||||||
self.files = []
|
self.files = []
|
||||||
|
|
||||||
|
@ -242,10 +245,10 @@ class ArgParser():
|
||||||
return self.rc
|
return self.rc
|
||||||
|
|
||||||
|
|
||||||
|
def help(self):
|
||||||
'''
|
'''
|
||||||
Prints a colourful help message
|
Prints a colourful help message
|
||||||
'''
|
'''
|
||||||
def help(self):
|
|
||||||
print('\033[1m%s\033[21m %s %s' % (self.__program, '-' if self.linuxvt else '—', self.__description))
|
print('\033[1m%s\033[21m %s %s' % (self.__program, '-' if self.linuxvt else '—', self.__description))
|
||||||
print()
|
print()
|
||||||
if self.__longdescription is not None:
|
if self.__longdescription is not None:
|
||||||
|
|
|
@ -36,10 +36,12 @@ from ucs import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Backend():
|
||||||
'''
|
'''
|
||||||
Super-ultra-extreme-awesomazing replacement for cowsay
|
Super-ultra-extreme-awesomazing replacement for cowsay
|
||||||
'''
|
'''
|
||||||
class Backend():
|
|
||||||
|
def __init__(self, message, ponyfile, wrapcolumn, width, balloon, hyphen, linkcolour, ballooncolour, mode, infolevel):
|
||||||
'''
|
'''
|
||||||
Constructor
|
Constructor
|
||||||
|
|
||||||
|
@ -54,7 +56,6 @@ class Backend():
|
||||||
@param mode:str Mode string for the pony
|
@param mode:str Mode string for the pony
|
||||||
@parma infolevel:int 2 if ++info is used, 1 if --info is used and 0 otherwise
|
@parma infolevel:int 2 if ++info is used, 1 if --info is used and 0 otherwise
|
||||||
'''
|
'''
|
||||||
def __init__(self, message, ponyfile, wrapcolumn, width, balloon, hyphen, linkcolour, ballooncolour, mode, infolevel):
|
|
||||||
self.message = message
|
self.message = message
|
||||||
self.ponyfile = ponyfile
|
self.ponyfile = ponyfile
|
||||||
self.wrapcolumn = None if wrapcolumn is None else wrapcolumn - (0 if balloon is None else balloon.minwidth)
|
self.wrapcolumn = None if wrapcolumn is None else wrapcolumn - (0 if balloon is None else balloon.minwidth)
|
||||||
|
@ -78,10 +79,10 @@ class Backend():
|
||||||
self.pony = None
|
self.pony = None
|
||||||
|
|
||||||
|
|
||||||
|
def parse(self):
|
||||||
'''
|
'''
|
||||||
Process all data
|
Process all data
|
||||||
'''
|
'''
|
||||||
def parse(self):
|
|
||||||
self.__loadFile()
|
self.__loadFile()
|
||||||
|
|
||||||
if self.pony.startswith('$$$\n'):
|
if self.pony.startswith('$$$\n'):
|
||||||
|
@ -126,14 +127,14 @@ class Backend():
|
||||||
self.__truncate()
|
self.__truncate()
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def formatInfo(info):
|
||||||
'''
|
'''
|
||||||
Format metadata to be nicely printed, this include bold keys
|
Format metadata to be nicely printed, this include bold keys
|
||||||
|
|
||||||
@param info:str The metadata
|
@param info:str The metadata
|
||||||
@return :str The metadata nicely formated
|
@return :str The metadata nicely formated
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
|
||||||
def formatInfo(info):
|
|
||||||
info = info.split('\n')
|
info = info.split('\n')
|
||||||
tags = ''
|
tags = ''
|
||||||
comment = ''
|
comment = ''
|
||||||
|
@ -156,10 +157,10 @@ class Backend():
|
||||||
return tags + comment
|
return tags + comment
|
||||||
|
|
||||||
|
|
||||||
|
def __unpadMessage(self):
|
||||||
'''
|
'''
|
||||||
Remove padding spaces fortune cookies are padded with whitespace (damn featherbrains)
|
Remove padding spaces fortune cookies are padded with whitespace (damn featherbrains)
|
||||||
'''
|
'''
|
||||||
def __unpadMessage(self):
|
|
||||||
lines = self.message.split('\n')
|
lines = self.message.split('\n')
|
||||||
for spaces in (128, 64, 32, 16, 8, 4, 2, 1):
|
for spaces in (128, 64, 32, 16, 8, 4, 2, 1):
|
||||||
padded = True
|
padded = True
|
||||||
|
@ -176,10 +177,10 @@ class Backend():
|
||||||
self.message = '\n'.join(lines)
|
self.message = '\n'.join(lines)
|
||||||
|
|
||||||
|
|
||||||
|
def __expandMessage(self):
|
||||||
'''
|
'''
|
||||||
Converts all tabs in the message to spaces by expanding
|
Converts all tabs in the message to spaces by expanding
|
||||||
'''
|
'''
|
||||||
def __expandMessage(self):
|
|
||||||
lines = self.message.split('\n')
|
lines = self.message.split('\n')
|
||||||
buf = ''
|
buf = ''
|
||||||
for line in lines:
|
for line in lines:
|
||||||
|
@ -203,18 +204,18 @@ class Backend():
|
||||||
self.message = buf[:-1]
|
self.message = buf[:-1]
|
||||||
|
|
||||||
|
|
||||||
|
def __loadFile(self):
|
||||||
'''
|
'''
|
||||||
Loads the pony file
|
Loads the pony file
|
||||||
'''
|
'''
|
||||||
def __loadFile(self):
|
|
||||||
with open(self.ponyfile, 'rb') as ponystream:
|
with open(self.ponyfile, 'rb') as ponystream:
|
||||||
self.pony = ponystream.read().decode('utf8', 'replace')
|
self.pony = ponystream.read().decode('utf8', 'replace')
|
||||||
|
|
||||||
|
|
||||||
|
def __truncate(self):
|
||||||
'''
|
'''
|
||||||
Truncate output to the width of the screen
|
Truncate output to the width of the screen
|
||||||
'''
|
'''
|
||||||
def __truncate(self):
|
|
||||||
if self.width is None:
|
if self.width is None:
|
||||||
return
|
return
|
||||||
lines = self.output.split('\n')
|
lines = self.output.split('\n')
|
||||||
|
@ -237,10 +238,10 @@ class Backend():
|
||||||
self.output = self.output[:-1]
|
self.output = self.output[:-1]
|
||||||
|
|
||||||
|
|
||||||
|
def __processPony(self):
|
||||||
'''
|
'''
|
||||||
Process the pony file and generate output to self.output
|
Process the pony file and generate output to self.output
|
||||||
'''
|
'''
|
||||||
def __processPony(self):
|
|
||||||
self.output = ''
|
self.output = ''
|
||||||
|
|
||||||
AUTO_PUSH = '\033[01010~'
|
AUTO_PUSH = '\033[01010~'
|
||||||
|
@ -307,7 +308,7 @@ class Backend():
|
||||||
w -= x;
|
w -= x;
|
||||||
else:
|
else:
|
||||||
w = int(w)
|
w = int(w)
|
||||||
balloon = self.__getballoon(w, h, x, justify, indent)
|
balloon = self.__getBalloon(w, h, x, justify, indent)
|
||||||
balloon = balloon.split('\n')
|
balloon = balloon.split('\n')
|
||||||
balloon = [AUTO_PUSH + self.ballooncolour + item + AUTO_POP for item in balloon]
|
balloon = [AUTO_PUSH + self.ballooncolour + item + AUTO_POP for item in balloon]
|
||||||
for b in balloon[0]:
|
for b in balloon[0]:
|
||||||
|
@ -383,6 +384,8 @@ class Backend():
|
||||||
self.output = '\n'.join(self.output)
|
self.output = '\n'.join(self.output)
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getColour(input, offset):
|
||||||
'''
|
'''
|
||||||
Gets colour code att the currect offset in a buffer
|
Gets colour code att the currect offset in a buffer
|
||||||
|
|
||||||
|
@ -390,8 +393,6 @@ class Backend():
|
||||||
@param offset:int The offset at where to start reading, a escape must begin here
|
@param offset:int The offset at where to start reading, a escape must begin here
|
||||||
@return :str The escape sequence
|
@return :str The escape sequence
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
|
||||||
def getColour(input, offset):
|
|
||||||
(i, n) = (offset, len(input))
|
(i, n) = (offset, len(input))
|
||||||
rc = input[i]
|
rc = input[i]
|
||||||
i += 1
|
i += 1
|
||||||
|
@ -439,14 +440,14 @@ class Backend():
|
||||||
return rc
|
return rc
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def len(input):
|
||||||
'''
|
'''
|
||||||
Calculates the number of visible characters in a text
|
Calculates the number of visible characters in a text
|
||||||
|
|
||||||
@param input:str The input buffer
|
@param input:str The input buffer
|
||||||
@return :int The number of visible characters
|
@return :int The number of visible characters
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
|
||||||
def len(input):
|
|
||||||
(rc, i, n) = (0, 0, len(input))
|
(rc, i, n) = (0, 0, len(input))
|
||||||
while i < n:
|
while i < n:
|
||||||
c = input[i]
|
c = input[i]
|
||||||
|
@ -459,6 +460,7 @@ class Backend():
|
||||||
return rc
|
return rc
|
||||||
|
|
||||||
|
|
||||||
|
def __getBalloon(self, width, height, innerleft, justify, left):
|
||||||
'''
|
'''
|
||||||
Generates a balloon with the message
|
Generates a balloon with the message
|
||||||
|
|
||||||
|
@ -470,7 +472,6 @@ class Backend():
|
||||||
@param left:int The column where the balloon starts
|
@param left:int The column where the balloon starts
|
||||||
@return :str The balloon the the message as a string
|
@return :str The balloon the the message as a string
|
||||||
'''
|
'''
|
||||||
def __getballoon(self, width, height, innerleft, justify, left):
|
|
||||||
wrap = None
|
wrap = None
|
||||||
if self.wrapcolumn is not None:
|
if self.wrapcolumn is not None:
|
||||||
wrap = self.wrapcolumn - left
|
wrap = self.wrapcolumn - left
|
||||||
|
@ -508,6 +509,7 @@ class Backend():
|
||||||
return rc
|
return rc
|
||||||
|
|
||||||
|
|
||||||
|
def __wrapMessage(self, message, wrap):
|
||||||
'''
|
'''
|
||||||
Wraps the message
|
Wraps the message
|
||||||
|
|
||||||
|
@ -515,7 +517,6 @@ class Backend():
|
||||||
@param wrap:int The width at where to force wrapping
|
@param wrap:int The width at where to force wrapping
|
||||||
@return :str The message wrapped
|
@return :str The message wrapped
|
||||||
'''
|
'''
|
||||||
def __wrapMessage(self, message, wrap):
|
|
||||||
wraplimit = os.environ['PONYSAY_WRAP_LIMIT'] if 'PONYSAY_WRAP_LIMIT' in os.environ else ''
|
wraplimit = os.environ['PONYSAY_WRAP_LIMIT'] if 'PONYSAY_WRAP_LIMIT' in os.environ else ''
|
||||||
wraplimit = 8 if len(wraplimit) == 0 else int(wraplimit)
|
wraplimit = 8 if len(wraplimit) == 0 else int(wraplimit)
|
||||||
|
|
||||||
|
@ -579,11 +580,11 @@ class Backend():
|
||||||
nbsp = b[map[mm + x]] == ' ' # nbsp
|
nbsp = b[map[mm + x]] == ' ' # nbsp
|
||||||
m = map[mm + x]
|
m = map[mm + x]
|
||||||
|
|
||||||
if ('' in b[bisub : m]) and not nbsp: # sort hyphen
|
if ('' in b[bisub : m]) and not nbsp: # soft hyphen
|
||||||
hyphen = m - 1
|
hyphen = m - 1
|
||||||
while b[hyphen] != '': # sort hyphen
|
while b[hyphen] != '': # soft hyphen
|
||||||
hyphen -= 1
|
hyphen -= 1
|
||||||
while map[mm + x] > hyphen: ## Only looking backward, if foreward is required the word is probabily not hyphenated correctly
|
while map[mm + x] > hyphen: ## Only looking backward, if forward is required the word is probabily not hyphenated correctly
|
||||||
x -= 1
|
x -= 1
|
||||||
x += 1
|
x += 1
|
||||||
m = map[mm + x]
|
m = map[mm + x]
|
||||||
|
|
|
@ -34,10 +34,12 @@ from ucs import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Balloon():
|
||||||
'''
|
'''
|
||||||
Balloon format class
|
Balloon format class
|
||||||
'''
|
'''
|
||||||
class Balloon():
|
|
||||||
|
def __init__(self, link, linkmirror, linkcross, ww, ee, nw, nnw, n, nne, ne, nee, e, see, se, sse, s, ssw, sw, sww, w, nww):
|
||||||
'''
|
'''
|
||||||
Constructor
|
Constructor
|
||||||
|
|
||||||
|
@ -63,7 +65,6 @@ class Balloon():
|
||||||
@param w:str See the info manual
|
@param w:str See the info manual
|
||||||
@param nww:str See the info manual
|
@param nww:str See the info manual
|
||||||
'''
|
'''
|
||||||
def __init__(self, link, linkmirror, linkcross, ww, ee, nw, nnw, n, nne, ne, nee, e, see, se, sse, s, ssw, sw, sww, w, nww):
|
|
||||||
(self.link, self.linkmirror, self.linkcross) = (link, linkmirror, linkcross)
|
(self.link, self.linkmirror, self.linkcross) = (link, linkmirror, linkcross)
|
||||||
(self.ww, self.ee) = (ww, ee)
|
(self.ww, self.ee) = (ww, ee)
|
||||||
(self.nw, self.ne, self.se, self.sw) = (nw, ne, se, sw)
|
(self.nw, self.ne, self.se, self.sw) = (nw, ne, se, sw)
|
||||||
|
@ -86,6 +87,7 @@ class Balloon():
|
||||||
self.minheight = minN + minS
|
self.minheight = minN + minS
|
||||||
|
|
||||||
|
|
||||||
|
def get(self, minw, minh, lines, lencalc):
|
||||||
'''
|
'''
|
||||||
Generates a balloon with a message
|
Generates a balloon with a message
|
||||||
|
|
||||||
|
@ -95,7 +97,6 @@ class Balloon():
|
||||||
@param lencalc:int(str) Function used to compute the length of a text line
|
@param lencalc:int(str) Function used to compute the length of a text line
|
||||||
@return :str The balloon as a formated string
|
@return :str The balloon as a formated string
|
||||||
'''
|
'''
|
||||||
def get(self, minw, minh, lines, lencalc):
|
|
||||||
## Get dimension
|
## Get dimension
|
||||||
h = self.minheight + len(lines)
|
h = self.minheight + len(lines)
|
||||||
w = self.minwidth + lencalc(max(lines, key = lencalc))
|
w = self.minwidth + lencalc(max(lines, key = lencalc))
|
||||||
|
@ -138,6 +139,8 @@ class Balloon():
|
||||||
return '\n'.join(rc)
|
return '\n'.join(rc)
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def fromFile(balloonfile, isthink):
|
||||||
'''
|
'''
|
||||||
Creates the balloon style object
|
Creates the balloon style object
|
||||||
|
|
||||||
|
@ -145,8 +148,6 @@ class Balloon():
|
||||||
@param isthink:bool Whether the ponythink command is used
|
@param isthink:bool Whether the ponythink command is used
|
||||||
@return :Balloon Instance describing the balloon's style
|
@return :Balloon Instance describing the balloon's style
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
|
||||||
def fromFile(balloonfile, isthink):
|
|
||||||
## Use default balloon if none is specified
|
## Use default balloon if none is specified
|
||||||
if balloonfile is None:
|
if balloonfile is None:
|
||||||
if isthink:
|
if isthink:
|
||||||
|
|
|
@ -33,19 +33,20 @@ from common import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ColourStack():
|
||||||
'''
|
'''
|
||||||
ANSI colour stack
|
ANSI colour stack
|
||||||
|
|
||||||
This is used to make layers with independent coloursations
|
This is used to make layers with independent coloursations
|
||||||
'''
|
'''
|
||||||
class ColourStack():
|
|
||||||
|
def __init__(self, autopush, autopop):
|
||||||
'''
|
'''
|
||||||
Constructor
|
Constructor
|
||||||
|
|
||||||
@param autopush:str String that, when used, will create a new independently colourised layer
|
@param autopush:str String that, when used, will create a new independently colourised layer
|
||||||
@param autopop:str String that, when used, will end the current layer and continue of the previous layer
|
@param autopop:str String that, when used, will end the current layer and continue of the previous layer
|
||||||
'''
|
'''
|
||||||
def __init__(self, autopush, autopop):
|
|
||||||
self.autopush = autopush
|
self.autopush = autopush
|
||||||
self.autopop = autopop
|
self.autopop = autopop
|
||||||
self.lenpush = len(autopush)
|
self.lenpush = len(autopush)
|
||||||
|
@ -56,24 +57,24 @@ class ColourStack():
|
||||||
self.seq = None
|
self.seq = None
|
||||||
|
|
||||||
|
|
||||||
|
def push(self):
|
||||||
'''
|
'''
|
||||||
Create a new independently colourised layer
|
Create a new independently colourised layer
|
||||||
|
|
||||||
@return :str String that should be inserted into your buffer
|
@return :str String that should be inserted into your buffer
|
||||||
'''
|
'''
|
||||||
def push(self):
|
|
||||||
self.stack.insert(0, [self.bufproto, None, None, [False] * 9])
|
self.stack.insert(0, [self.bufproto, None, None, [False] * 9])
|
||||||
if len(self.stack) == 1:
|
if len(self.stack) == 1:
|
||||||
return None
|
return None
|
||||||
return '\033[0m'
|
return '\033[0m'
|
||||||
|
|
||||||
|
|
||||||
|
def pop(self):
|
||||||
'''
|
'''
|
||||||
End the current layer and continue of the previous layer
|
End the current layer and continue of the previous layer
|
||||||
|
|
||||||
@return :str String that should be inserted into your buffer
|
@return :str String that should be inserted into your buffer
|
||||||
'''
|
'''
|
||||||
def pop(self):
|
|
||||||
old = self.stack.pop(0)
|
old = self.stack.pop(0)
|
||||||
rc = '\033[0;'
|
rc = '\033[0;'
|
||||||
if len(self.stack) == 0: # last resort in case something made it pop too mush
|
if len(self.stack) == 0: # last resort in case something made it pop too mush
|
||||||
|
@ -87,6 +88,7 @@ class ColourStack():
|
||||||
return rc[:-1] + 'm'
|
return rc[:-1] + 'm'
|
||||||
|
|
||||||
|
|
||||||
|
def feed(self, char):
|
||||||
'''
|
'''
|
||||||
Use this, in sequence, for which character in your buffer that contains yor autopush and autopop
|
Use this, in sequence, for which character in your buffer that contains yor autopush and autopop
|
||||||
string, the automatically get push and pop string to insert after each character
|
string, the automatically get push and pop string to insert after each character
|
||||||
|
@ -94,7 +96,6 @@ class ColourStack():
|
||||||
@param :chr One character in your buffer
|
@param :chr One character in your buffer
|
||||||
@return :str The text to insert after the input character
|
@return :str The text to insert after the input character
|
||||||
'''
|
'''
|
||||||
def feed(self, char):
|
|
||||||
if self.seq is not None:
|
if self.seq is not None:
|
||||||
self.seq += char
|
self.seq += char
|
||||||
if (char == '~') or (('a' <= char) and (char <= 'z')) or (('A' <= char) and (char <= 'Z')):
|
if (char == '~') or (('a' <= char) and (char <= 'z')) or (('A' <= char) and (char <= 'Z')):
|
||||||
|
|
|
@ -38,13 +38,14 @@ from subprocess import Popen, PIPE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
VERSION = 'dev' # this line should not be edited, it is fixed by the build system
|
||||||
'''
|
'''
|
||||||
The version of ponysay
|
The version of ponysay
|
||||||
'''
|
'''
|
||||||
VERSION = 'dev' # this line should not be edited, it is fixed by the build system
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def print(text = '', end = '\n'):
|
||||||
'''
|
'''
|
||||||
Hack to enforce UTF-8 in output (in the future, if you see anypony not using utf-8 in
|
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)
|
programs by default, report them to Princess Celestia so she can banish them to the moon)
|
||||||
|
@ -52,26 +53,25 @@ programs by default, report them to Princess Celestia so she can banish them to
|
||||||
@param text:str The text to print (empty string is default)
|
@param text:str The text to print (empty string is default)
|
||||||
@param end:str The appendix to the text to print (line breaking is default)
|
@param end:str The appendix to the text to print (line breaking is default)
|
||||||
'''
|
'''
|
||||||
def print(text = '', end = '\n'):
|
|
||||||
sys.stdout.buffer.write((str(text) + end).encode('utf-8'))
|
sys.stdout.buffer.write((str(text) + end).encode('utf-8'))
|
||||||
|
|
||||||
|
def printerr(text = '', end = '\n'):
|
||||||
'''
|
'''
|
||||||
stderr equivalent to print()
|
stderr equivalent to print()
|
||||||
|
|
||||||
@param text:str The text to print (empty string is default)
|
@param text:str The text to print (empty string is default)
|
||||||
@param end:str The appendix to the text to print (line breaking is default)
|
@param end:str The appendix to the text to print (line breaking is default)
|
||||||
'''
|
'''
|
||||||
def printerr(text = '', end = '\n'):
|
|
||||||
sys.stderr.buffer.write((str(text) + end).encode('utf-8'))
|
sys.stderr.buffer.write((str(text) + end).encode('utf-8'))
|
||||||
|
|
||||||
fd3 = None
|
fd3 = None
|
||||||
|
def printinfo(text = '', end = '\n'):
|
||||||
'''
|
'''
|
||||||
/proc/self/fd/3 equivalent to print()
|
/proc/self/fd/3 equivalent to print()
|
||||||
|
|
||||||
@param text:str The text to print (empty string is default)
|
@param text:str The text to print (empty string is default)
|
||||||
@param end:str The appendix to the text to print (line breaking is default)
|
@param end:str The appendix to the text to print (line breaking is default)
|
||||||
'''
|
'''
|
||||||
def printinfo(text = '', end = '\n'):
|
|
||||||
global fd3
|
global fd3
|
||||||
if os.path.exists('/proc/self/fd/3') and not os.path.isdir(os.path.realpath('/proc/self/fd/3')):
|
if os.path.exists('/proc/self/fd/3') and not os.path.isdir(os.path.realpath('/proc/self/fd/3')):
|
||||||
if fd3 is None:
|
if fd3 is None:
|
||||||
|
@ -80,6 +80,7 @@ def printinfo(text = '', end = '\n'):
|
||||||
fd3.write(str(text) + end)
|
fd3.write(str(text) + end)
|
||||||
|
|
||||||
|
|
||||||
|
def endswith(text, ending):
|
||||||
'''
|
'''
|
||||||
Checks whether a text ends with a specific text, but has more
|
Checks whether a text ends with a specific text, but has more
|
||||||
|
|
||||||
|
@ -87,16 +88,15 @@ Checks whether a text ends with a specific text, but has more
|
||||||
@param ending:str The desired end of the text
|
@param ending:str The desired end of the text
|
||||||
@return :bool The result of the test
|
@return :bool The result of the test
|
||||||
'''
|
'''
|
||||||
def endswith(text, ending):
|
|
||||||
return text.endswith(ending) and not (text == ending)
|
return text.endswith(ending) and not (text == ending)
|
||||||
|
|
||||||
|
|
||||||
|
def gettermsize():
|
||||||
'''
|
'''
|
||||||
Gets the size of the terminal in (rows, columns)
|
Gets the size of the terminal in (rows, columns)
|
||||||
|
|
||||||
@return (rows, columns):(int, int) The number or lines and the number of columns in the terminal's display area
|
@return (rows, columns):(int, int) The number or lines and the number of columns in the terminal's display area
|
||||||
'''
|
'''
|
||||||
def gettermsize():
|
|
||||||
## Call `stty` to determine the size of the terminal, this way is better than using python's ncurses
|
## Call `stty` to determine the size of the terminal, this way is better than using python's ncurses
|
||||||
for channel in (sys.stderr, sys.stdout, sys.stdin):
|
for channel in (sys.stderr, sys.stdout, sys.stdin):
|
||||||
termsize = Popen(['stty', 'size'], stdout=PIPE, stdin=channel, stderr=PIPE).communicate()[0]
|
termsize = Popen(['stty', 'size'], stdout=PIPE, stdin=channel, stderr=PIPE).communicate()[0]
|
||||||
|
|
11
src/kms.py
11
src/kms.py
|
@ -33,18 +33,19 @@ from common import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class KMS():
|
||||||
'''
|
'''
|
||||||
KMS support utilisation
|
KMS support utilisation
|
||||||
'''
|
'''
|
||||||
class KMS():
|
|
||||||
|
@staticmethod
|
||||||
|
def usingkms(linuxvt):
|
||||||
'''
|
'''
|
||||||
Identifies whether KMS support is utilised
|
Identifies whether KMS support is utilised
|
||||||
|
|
||||||
@param linuxvt:bool Whether Linux VT is used
|
@param linuxvt:bool Whether Linux VT is used
|
||||||
@return :bool Whether KMS support is utilised
|
@return :bool Whether KMS support is utilised
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
|
||||||
def usingkms(linuxvt):
|
|
||||||
## KMS is not utilised if Linux VT is not used
|
## KMS is not utilised if Linux VT is not used
|
||||||
if not linuxvt:
|
if not linuxvt:
|
||||||
return False
|
return False
|
||||||
|
@ -64,6 +65,8 @@ class KMS():
|
||||||
return env_kms != ''
|
return env_kms != ''
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def kms(pony, home, linuxvt):
|
||||||
'''
|
'''
|
||||||
Returns the file name of the input pony converted to a KMS pony, or if KMS is not used, the input pony itself
|
Returns the file name of the input pony converted to a KMS pony, or if KMS is not used, the input pony itself
|
||||||
|
|
||||||
|
@ -72,8 +75,6 @@ class KMS():
|
||||||
@param linuxvt:bool Whether Linux VT is used
|
@param linuxvt:bool Whether Linux VT is used
|
||||||
@return :str Pony file to display
|
@return :str Pony file to display
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
|
||||||
def kms(pony, home, linuxvt):
|
|
||||||
## If not in Linux VT, return the pony as is
|
## If not in Linux VT, return the pony as is
|
||||||
if not linuxvt:
|
if not linuxvt:
|
||||||
return pony
|
return pony
|
||||||
|
|
23
src/list.py
23
src/list.py
|
@ -34,17 +34,18 @@ from ucs import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class List():
|
||||||
'''
|
'''
|
||||||
File listing functions
|
File listing functions
|
||||||
'''
|
'''
|
||||||
class List():
|
|
||||||
|
@staticmethod
|
||||||
|
def __columnise(ponies):
|
||||||
'''
|
'''
|
||||||
Columnise a list and prints it
|
Columnise a list and prints it
|
||||||
|
|
||||||
@param ponies:list<(str, str)> All items to list, each item should have to elements: unformated name, formated name
|
@param ponies:list<(str, str)> All items to list, each item should have to elements: unformated name, formated name
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
|
||||||
def __columnise(ponies):
|
|
||||||
## Get terminal width, and a 2 which is the space between columns
|
## Get terminal width, and a 2 which is the space between columns
|
||||||
termwidth = gettermsize()[1] + 2
|
termwidth = gettermsize()[1] + 2
|
||||||
## Sort the ponies, and get the cells' widths, and the largest width + 2
|
## Sort the ponies, and get the cells' widths, and the largest width + 2
|
||||||
|
@ -92,6 +93,8 @@ class List():
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def simplelist(ponydirs, quoters = [], ucsiser = None):
|
||||||
'''
|
'''
|
||||||
Lists the available ponies
|
Lists the available ponies
|
||||||
|
|
||||||
|
@ -99,8 +102,6 @@ class List():
|
||||||
@param quoters:__in__(str)→bool Set of ponies that of quotes
|
@param quoters:__in__(str)→bool Set of ponies that of quotes
|
||||||
@param ucsiser:(list<str>)?→void Function used to UCS:ise names
|
@param ucsiser:(list<str>)?→void Function used to UCS:ise names
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
|
||||||
def simplelist(ponydirs, quoters = [], ucsiser = None):
|
|
||||||
for ponydir in ponydirs: # Loop ponydirs
|
for ponydir in ponydirs: # Loop ponydirs
|
||||||
## Get all ponies in the directory
|
## Get all ponies in the directory
|
||||||
_ponies = os.listdir(ponydir)
|
_ponies = os.listdir(ponydir)
|
||||||
|
@ -122,6 +123,8 @@ class List():
|
||||||
List.__columnise([(pony, '\033[1m' + pony + '\033[21m' if pony in quoters else pony) for pony in ponies])
|
List.__columnise([(pony, '\033[1m' + pony + '\033[21m' if pony in quoters else pony) for pony in ponies])
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def linklist(ponydirs = None, quoters = [], ucsiser = None):
|
||||||
'''
|
'''
|
||||||
Lists the available ponies with alternatives inside brackets
|
Lists the available ponies with alternatives inside brackets
|
||||||
|
|
||||||
|
@ -129,8 +132,6 @@ class List():
|
||||||
@param quoters:__in__(str)→bool Set of ponies that of quotes
|
@param quoters:__in__(str)→bool Set of ponies that of quotes
|
||||||
@param ucsiser:(list<str>, map<str, str>)?→void Function used to UCS:ise names
|
@param ucsiser:(list<str>, map<str, str>)?→void Function used to UCS:ise names
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
|
||||||
def linklist(ponydirs = None, quoters = [], ucsiser = None):
|
|
||||||
## Get the size of the terminal
|
## Get the size of the terminal
|
||||||
termsize = gettermsize()
|
termsize = gettermsize()
|
||||||
|
|
||||||
|
@ -200,6 +201,8 @@ class List():
|
||||||
List.__columnise(list(ponies))
|
List.__columnise(list(ponies))
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def onelist(standarddirs, extradirs = None, ucsiser = None):
|
||||||
'''
|
'''
|
||||||
Lists the available ponies on one column without anything bold or otherwise formated
|
Lists the available ponies on one column without anything bold or otherwise formated
|
||||||
|
|
||||||
|
@ -207,8 +210,6 @@ class List():
|
||||||
@param extra:itr<str>? Include extra ponies
|
@param extra:itr<str>? Include extra ponies
|
||||||
@param ucsiser:(list<str>)?→void Function used to UCS:ise names
|
@param ucsiser:(list<str>)?→void Function used to UCS:ise names
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
|
||||||
def onelist(standarddirs, extradirs = None, ucsiser = None):
|
|
||||||
## Get all pony files
|
## Get all pony files
|
||||||
_ponies = []
|
_ponies = []
|
||||||
if standarddirs is not None:
|
if standarddirs is not None:
|
||||||
|
@ -237,14 +238,14 @@ class List():
|
||||||
print(pony)
|
print(pony)
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def balloonlist(balloondirs, isthink):
|
||||||
'''
|
'''
|
||||||
Prints a list of all balloons
|
Prints a list of all balloons
|
||||||
|
|
||||||
@param balloondirs:itr<str> The balloon directories to use
|
@param balloondirs:itr<str> The balloon directories to use
|
||||||
@param isthink:bool Whether the ponythink command is used
|
@param isthink:bool Whether the ponythink command is used
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
|
||||||
def balloonlist(balloondirs, isthink):
|
|
||||||
## Get the size of the terminal
|
## Get the size of the terminal
|
||||||
termsize = gettermsize()
|
termsize = gettermsize()
|
||||||
|
|
||||||
|
|
|
@ -33,18 +33,19 @@ from common import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Metadata():
|
||||||
'''
|
'''
|
||||||
Metadata functions
|
Metadata functions
|
||||||
'''
|
'''
|
||||||
class Metadata():
|
|
||||||
|
@staticmethod
|
||||||
|
def makeRestrictionLogic(restriction):
|
||||||
'''
|
'''
|
||||||
Make restriction test logic function
|
Make restriction test logic function
|
||||||
|
|
||||||
@param restriction:list<string> Metadata based restrictions
|
@param restriction:list<string> Metadata based restrictions
|
||||||
@return :dict<str, str>→bool Test function
|
@return :dict<str, str>→bool Test function
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
|
||||||
def makeRestrictionLogic(restriction):
|
|
||||||
def get_test(cell):
|
def get_test(cell):
|
||||||
strict = cell[0][-1] != '?'
|
strict = cell[0][-1] != '?'
|
||||||
key = cell[0]
|
key = cell[0]
|
||||||
|
@ -109,6 +110,8 @@ class Metadata():
|
||||||
return Logic(table)
|
return Logic(table)
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def restrictedPonies(ponydir, logic):
|
||||||
'''
|
'''
|
||||||
Get ponies that pass restriction
|
Get ponies that pass restriction
|
||||||
|
|
||||||
|
@ -116,8 +119,6 @@ class Metadata():
|
||||||
@param logic:(str)→bool Restriction test functor
|
@param logic:(str)→bool Restriction test functor
|
||||||
@return :list<str> Passed ponies
|
@return :list<str> Passed ponies
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
|
||||||
def restrictedPonies(ponydir, logic):
|
|
||||||
import pickle
|
import pickle
|
||||||
passed = []
|
passed = []
|
||||||
if os.path.exists(ponydir + 'metadata'):
|
if os.path.exists(ponydir + 'metadata'):
|
||||||
|
@ -131,6 +132,8 @@ class Metadata():
|
||||||
return passed
|
return passed
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getfitting(fitting, requirement, file):
|
||||||
'''
|
'''
|
||||||
Get ponies that fit the terminal
|
Get ponies that fit the terminal
|
||||||
|
|
||||||
|
@ -138,8 +141,6 @@ class Metadata():
|
||||||
@param requirement:int The maximum allowed value
|
@param requirement:int The maximum allowed value
|
||||||
@param file:istream The file with all data
|
@param file:istream The file with all data
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
|
||||||
def getfitting(fitting, requirement, file):
|
|
||||||
data = file.read() # not too much data, can load everything at once
|
data = file.read() # not too much data, can load everything at once
|
||||||
ptr = 0
|
ptr = 0
|
||||||
while data[ptr] != 47: # 47 == ord('/')
|
while data[ptr] != 47: # 47 == ord('/')
|
||||||
|
|
130
src/ponysay.py
130
src/ponysay.py
|
@ -3,13 +3,31 @@
|
||||||
|
|
||||||
'''
|
'''
|
||||||
ponysay - Ponysay, cowsay reimplementation for ponies
|
ponysay - Ponysay, cowsay reimplementation for ponies
|
||||||
|
|
||||||
Copyright (C) 2012, 2013 Erkin Batu Altunbaş et al.
|
Copyright (C) 2012, 2013 Erkin Batu Altunbaş et al.
|
||||||
|
|
||||||
This program is free software. It comes without any warranty, to
|
|
||||||
the extent permitted by applicable law. You can redistribute it
|
This program is free software: you can redistribute it and/or modify
|
||||||
and/or modify it under the terms of the Do What The Fuck You Want
|
it under the terms of the GNU General Public License as published by
|
||||||
To Public License, Version 2, as published by Sam Hocevar. See
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
http://sam.zoy.org/wtfpl/COPYING for more details.
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
If you intend to redistribute ponysay or a fork of it commercially,
|
||||||
|
it contains aggregated images, some of which may not be commercially
|
||||||
|
redistribute, you would be required to remove those. To determine
|
||||||
|
whether or not you may commercially redistribute an image make use
|
||||||
|
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 common import *
|
||||||
from backend import *
|
from backend import *
|
||||||
|
@ -22,29 +40,29 @@ from metadata import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Ponysay():
|
||||||
'''
|
'''
|
||||||
This is the mane class of ponysay
|
This is the mane class of ponysay
|
||||||
'''
|
'''
|
||||||
class Ponysay():
|
|
||||||
|
def __init__(self):
|
||||||
'''
|
'''
|
||||||
Constructor
|
Constructor
|
||||||
'''
|
'''
|
||||||
def __init__(self):
|
|
||||||
'''
|
# The user's home directory
|
||||||
The user's home directory
|
|
||||||
'''
|
|
||||||
self.HOME = os.environ['HOME'] if 'HOME' in os.environ else ''
|
self.HOME = os.environ['HOME'] if 'HOME' in os.environ else ''
|
||||||
if len(self.HOME) == 0:
|
if len(self.HOME) == 0:
|
||||||
os.environ['HOME'] = self.HOME = os.path.expanduser('~')
|
os.environ['HOME'] = self.HOME = os.path.expanduser('~')
|
||||||
|
|
||||||
|
|
||||||
|
def parsefile(file):
|
||||||
'''
|
'''
|
||||||
Parse a file name encoded with environment variables
|
Parse a file name encoded with environment variables
|
||||||
|
|
||||||
@param file The encoded file name
|
@param file The encoded file name
|
||||||
@return The target file name, None if the environment variables are not declared
|
@return The target file name, None if the environment variables are not declared
|
||||||
'''
|
'''
|
||||||
def parsefile(file):
|
|
||||||
if '$' in file:
|
if '$' in file:
|
||||||
buf = ''
|
buf = ''
|
||||||
esc = False
|
esc = False
|
||||||
|
@ -88,21 +106,15 @@ class Ponysay():
|
||||||
os.environ['HOME'] = self.HOME = os.path.expanduser('~')
|
os.environ['HOME'] = self.HOME = os.path.expanduser('~')
|
||||||
|
|
||||||
|
|
||||||
'''
|
# Whether any unrecognised options was parsed, this should be set by the invoker before run()
|
||||||
Whether any unrecognised options was parsed, this should be set by the invoker before run()
|
|
||||||
'''
|
|
||||||
self.unrecognised = False
|
self.unrecognised = False
|
||||||
|
|
||||||
|
|
||||||
'''
|
# Whether the program is execute in Linux VT (TTY)
|
||||||
Whether the program is execute in Linux VT (TTY)
|
|
||||||
'''
|
|
||||||
self.linuxvt = ('TERM' in os.environ) and (os.environ['TERM'] == 'linux')
|
self.linuxvt = ('TERM' in os.environ) and (os.environ['TERM'] == 'linux')
|
||||||
|
|
||||||
|
|
||||||
'''
|
# Whether the script is executed as ponythink
|
||||||
Whether the script is executed as ponythink
|
|
||||||
'''
|
|
||||||
self.isthink = sys.argv[0]
|
self.isthink = sys.argv[0]
|
||||||
if os.sep in self.isthink:
|
if os.sep in self.isthink:
|
||||||
self.isthink = self.isthink[self.isthink.rfind(os.sep) + 1:]
|
self.isthink = self.isthink[self.isthink.rfind(os.sep) + 1:]
|
||||||
|
@ -111,31 +123,21 @@ class Ponysay():
|
||||||
self.isthink = self.isthink.endswith('think')
|
self.isthink = self.isthink.endswith('think')
|
||||||
|
|
||||||
|
|
||||||
'''
|
# Whether stdin is piped
|
||||||
Whether stdin is piped
|
|
||||||
'''
|
|
||||||
self.pipelinein = not sys.stdin.isatty()
|
self.pipelinein = not sys.stdin.isatty()
|
||||||
|
|
||||||
'''
|
# Whether stdout is piped
|
||||||
Whether stdout is piped
|
|
||||||
'''
|
|
||||||
self.pipelineout = not sys.stdout.isatty()
|
self.pipelineout = not sys.stdout.isatty()
|
||||||
|
|
||||||
'''
|
# Whether stderr is piped
|
||||||
Whether stderr is piped
|
|
||||||
'''
|
|
||||||
self.pipelineerr = not sys.stderr.isatty()
|
self.pipelineerr = not sys.stderr.isatty()
|
||||||
|
|
||||||
|
|
||||||
'''
|
# Whether KMS is used
|
||||||
Whether KMS is used
|
|
||||||
'''
|
|
||||||
self.usekms = KMS.usingkms(self.linuxvt)
|
self.usekms = KMS.usingkms(self.linuxvt)
|
||||||
|
|
||||||
|
|
||||||
'''
|
# Mode string that modifies or adds $ variables in the pony image
|
||||||
Mode string that modifies or adds $ variables in the pony image
|
|
||||||
'''
|
|
||||||
self.mode = ''
|
self.mode = ''
|
||||||
|
|
||||||
|
|
||||||
|
@ -152,9 +154,7 @@ class Ponysay():
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
|
||||||
'''
|
# The directories where pony files are stored, ttyponies/ are used if the terminal is Linux VT (also known as TTY) and not with KMS
|
||||||
The directories where pony files are stored, ttyponies/ are used if the terminal is Linux VT (also known as TTY) and not with KMS
|
|
||||||
'''
|
|
||||||
appendset = set()
|
appendset = set()
|
||||||
self.xponydirs = []
|
self.xponydirs = []
|
||||||
_ponydirs = share('ponies/')
|
_ponydirs = share('ponies/')
|
||||||
|
@ -171,9 +171,7 @@ class Ponysay():
|
||||||
appendset.add(ponydir)
|
appendset.add(ponydir)
|
||||||
|
|
||||||
|
|
||||||
'''
|
# The directories where pony files are stored, extrattyponies/ are used if the terminal is Linux VT (also known as TTY) and not with KMS
|
||||||
The directories where pony files are stored, extrattyponies/ are used if the terminal is Linux VT (also known as TTY) and not with KMS
|
|
||||||
'''
|
|
||||||
appendset = set()
|
appendset = set()
|
||||||
self.extraxponydirs = []
|
self.extraxponydirs = []
|
||||||
_extraponydirs = share('extraponies/')
|
_extraponydirs = share('extraponies/')
|
||||||
|
@ -190,9 +188,7 @@ class Ponysay():
|
||||||
appendset.add(extraponydir)
|
appendset.add(extraponydir)
|
||||||
|
|
||||||
|
|
||||||
'''
|
# The directories where quotes files are stored
|
||||||
The directories where quotes files are stored
|
|
||||||
'''
|
|
||||||
appendset = set()
|
appendset = set()
|
||||||
self.quotedirs = []
|
self.quotedirs = []
|
||||||
_quotedirs = share('quotes/')
|
_quotedirs = share('quotes/')
|
||||||
|
@ -202,9 +198,7 @@ class Ponysay():
|
||||||
appendset.add(quotedir)
|
appendset.add(quotedir)
|
||||||
|
|
||||||
|
|
||||||
'''
|
# The directories where balloon style files are stored
|
||||||
The directories where balloon style files are stored
|
|
||||||
'''
|
|
||||||
appendset = set()
|
appendset = set()
|
||||||
self.balloondirs = []
|
self.balloondirs = []
|
||||||
_balloondirs = share('balloons/')
|
_balloondirs = share('balloons/')
|
||||||
|
@ -214,9 +208,7 @@ class Ponysay():
|
||||||
appendset.add(balloondir)
|
appendset.add(balloondir)
|
||||||
|
|
||||||
|
|
||||||
'''
|
# ucsmap files
|
||||||
ucsmap files
|
|
||||||
'''
|
|
||||||
appendset = set()
|
appendset = set()
|
||||||
self.ucsmaps = []
|
self.ucsmaps = []
|
||||||
_ucsmaps = share('ucsmap/')
|
_ucsmaps = share('ucsmap/')
|
||||||
|
@ -227,24 +219,24 @@ class Ponysay():
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def run(self, args):
|
||||||
'''
|
'''
|
||||||
Starts the part of the program the arguments indicate
|
Starts the part of the program the arguments indicate
|
||||||
|
|
||||||
@param args:ArgParser Parsed command line arguments
|
@param args:ArgParser Parsed command line arguments
|
||||||
'''
|
'''
|
||||||
def run(self, args):
|
|
||||||
if (args.argcount == 0) and not self.pipelinein:
|
if (args.argcount == 0) and not self.pipelinein:
|
||||||
args.help()
|
args.help()
|
||||||
exit(254)
|
exit(254)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def test(*keys):
|
||||||
'''
|
'''
|
||||||
Test arguments written in negation-free disjunctive normal form
|
Test arguments written in negation-free disjunctive normal form
|
||||||
|
|
||||||
@param keys:*str|itr<str> A list of keys and set of keys, any of which must exists, a set of keys only passes if all of those exists
|
@param keys:*str|itr<str> A list of keys and set of keys, any of which must exists, a set of keys only passes if all of those exists
|
||||||
@return :bool Whether the check passed
|
@return :bool Whether the check passed
|
||||||
'''
|
'''
|
||||||
def test(*keys):
|
|
||||||
for key in keys:
|
for key in keys:
|
||||||
if isinstance(key, str):
|
if isinstance(key, str):
|
||||||
if args.opts[key] is not None:
|
if args.opts[key] is not None:
|
||||||
|
@ -328,21 +320,21 @@ class Ponysay():
|
||||||
## Methods that run before the mane methods ##
|
## Methods that run before the mane methods ##
|
||||||
##############################################
|
##############################################
|
||||||
|
|
||||||
|
def __extraponies(self):
|
||||||
'''
|
'''
|
||||||
Use extra ponies
|
Use extra ponies
|
||||||
'''
|
'''
|
||||||
def __extraponies(self):
|
|
||||||
## Change ponydir to extraponydir
|
## Change ponydir to extraponydir
|
||||||
self.ponydirs[:] = self.extraponydirs
|
self.ponydirs[:] = self.extraponydirs
|
||||||
self.quotedirs[:] = [] ## TODO +q
|
self.quotedirs[:] = [] ## TODO +q
|
||||||
|
|
||||||
|
|
||||||
|
def __bestpony(self, args):
|
||||||
'''
|
'''
|
||||||
Use best.pony if nothing else is set
|
Use best.pony if nothing else is set
|
||||||
|
|
||||||
@param args:ArgParser Parsed command line arguments
|
@param args:ArgParser Parsed command line arguments
|
||||||
'''
|
'''
|
||||||
def __bestpony(self, args):
|
|
||||||
## Set best.pony as the pony to display if none is selected
|
## Set best.pony as the pony to display if none is selected
|
||||||
def test(keys, strict):
|
def test(keys, strict):
|
||||||
if strict:
|
if strict:
|
||||||
|
@ -368,12 +360,12 @@ class Ponysay():
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def __ucsremap(self, args):
|
||||||
'''
|
'''
|
||||||
Apply pony name remapping to args according to UCS settings
|
Apply pony name remapping to args according to UCS settings
|
||||||
|
|
||||||
@param args:ArgParser Parsed command line arguments
|
@param args:ArgParser Parsed command line arguments
|
||||||
'''
|
'''
|
||||||
def __ucsremap(self, args):
|
|
||||||
## Read UCS configurations
|
## Read UCS configurations
|
||||||
env_ucs = os.environ['PONYSAY_UCS_ME'] if 'PONYSAY_UCS_ME' in os.environ else ''
|
env_ucs = os.environ['PONYSAY_UCS_ME'] if 'PONYSAY_UCS_ME' in os.environ else ''
|
||||||
ucs_conf = 0
|
ucs_conf = 0
|
||||||
|
@ -413,13 +405,13 @@ class Ponysay():
|
||||||
## Auxiliary methods ##
|
## Auxiliary methods ##
|
||||||
#######################
|
#######################
|
||||||
|
|
||||||
|
def __ucsise(self, ponies, links = None):
|
||||||
'''
|
'''
|
||||||
Apply UCS:ise pony names according to UCS settings
|
Apply UCS:ise pony names according to UCS settings
|
||||||
|
|
||||||
@param ponies:list<str> List of all ponies (of interrest)
|
@param ponies:list<str> List of all ponies (of interrest)
|
||||||
@param links:map<str, str>? Map to fill with simulated symlink ponies, may be `None`
|
@param links:map<str, str>? Map to fill with simulated symlink ponies, may be `None`
|
||||||
'''
|
'''
|
||||||
def __ucsise(self, ponies, links = None):
|
|
||||||
## Read UCS configurations
|
## Read UCS configurations
|
||||||
env_ucs = os.environ['PONYSAY_UCS_ME'] if 'PONYSAY_UCS_ME' in os.environ else ''
|
env_ucs = os.environ['PONYSAY_UCS_ME'] if 'PONYSAY_UCS_ME' in os.environ else ''
|
||||||
ucs_conf = 0
|
ucs_conf = 0
|
||||||
|
@ -460,6 +452,7 @@ class Ponysay():
|
||||||
ponies[j] = map[ponies[j]]
|
ponies[j] = map[ponies[j]]
|
||||||
|
|
||||||
|
|
||||||
|
def __getpony(self, selection, args, alt = False):
|
||||||
'''
|
'''
|
||||||
Returns one file with full path and ponyquote that should be used, names is filter for names, also accepts filepaths
|
Returns one file with full path and ponyquote that should be used, names is filter for names, also accepts filepaths
|
||||||
|
|
||||||
|
@ -471,7 +464,6 @@ class Ponysay():
|
||||||
@param alt:bool For method internal use...
|
@param alt:bool For method internal use...
|
||||||
@return (path, quote):(str, str?) The file name of a pony, and the ponyquote that should be used if any
|
@return (path, quote):(str, str?) The file name of a pony, and the ponyquote that should be used if any
|
||||||
'''
|
'''
|
||||||
def __getpony(self, selection, args, alt = False):
|
|
||||||
## If there is no selected ponies, choose all of them
|
## If there is no selected ponies, choose all of them
|
||||||
if (selection is None) or (len(selection) == 0):
|
if (selection is None) or (len(selection) == 0):
|
||||||
quote = args.opts['-q'] is not None ## TODO +q -Q
|
quote = args.opts['-q'] is not None ## TODO +q -Q
|
||||||
|
@ -570,6 +562,7 @@ class Ponysay():
|
||||||
return (file, self.__getquote(pony[0], file) if pony[2] else None)
|
return (file, self.__getquote(pony[0], file) if pony[2] else None)
|
||||||
|
|
||||||
|
|
||||||
|
def __getquote(self, pony, file):
|
||||||
'''
|
'''
|
||||||
Select a quote for a pony
|
Select a quote for a pony
|
||||||
|
|
||||||
|
@ -577,7 +570,6 @@ class Ponysay():
|
||||||
@param file:str The pony's file name
|
@param file:str The pony's file name
|
||||||
@return :str A quote from the pony, with a failure fall back message
|
@return :str A quote from the pony, with a failure fall back message
|
||||||
'''
|
'''
|
||||||
def __getquote(self, pony, file):
|
|
||||||
quote = []
|
quote = []
|
||||||
if (os.path.dirname(file) + os.sep).replace(os.sep + os.sep, os.sep) in self.ponydirs:
|
if (os.path.dirname(file) + os.sep).replace(os.sep + os.sep, os.sep) in self.ponydirs:
|
||||||
realpony = pony
|
realpony = pony
|
||||||
|
@ -596,6 +588,7 @@ class Ponysay():
|
||||||
return quote
|
return quote
|
||||||
|
|
||||||
|
|
||||||
|
def __quoters(self, ponydirs = None, quotedirs = None):
|
||||||
'''
|
'''
|
||||||
Returns a set with all ponies that have quotes and are displayable
|
Returns a set with all ponies that have quotes and are displayable
|
||||||
|
|
||||||
|
@ -603,7 +596,6 @@ class Ponysay():
|
||||||
@param quotedirs:itr<str>? The quote directories to use
|
@param quotedirs:itr<str>? The quote directories to use
|
||||||
@return :set<str> All ponies that have quotes and are displayable
|
@return :set<str> All ponies that have quotes and are displayable
|
||||||
'''
|
'''
|
||||||
def __quoters(self, ponydirs = None, quotedirs = None):
|
|
||||||
if ponydirs is None: ponydirs = self.ponydirs
|
if ponydirs is None: ponydirs = self.ponydirs
|
||||||
if quotedirs is None: quotedirs = self.quotedirs
|
if quotedirs is None: quotedirs = self.quotedirs
|
||||||
|
|
||||||
|
@ -633,6 +625,7 @@ class Ponysay():
|
||||||
return ponies
|
return ponies
|
||||||
|
|
||||||
|
|
||||||
|
def __quotes(self, ponydirs = None, quotedirs = None, ponies = None):
|
||||||
'''
|
'''
|
||||||
Returns a list with all (pony, quote file) pairs
|
Returns a list with all (pony, quote file) pairs
|
||||||
|
|
||||||
|
@ -641,7 +634,6 @@ class Ponysay():
|
||||||
@param ponies:itr<str>? The ponies to use
|
@param ponies:itr<str>? The ponies to use
|
||||||
@return (pony, quote):(str, str) All ponies–quote file-pairs
|
@return (pony, quote):(str, str) All ponies–quote file-pairs
|
||||||
'''
|
'''
|
||||||
def __quotes(self, ponydirs = None, quotedirs = None, ponies = None):
|
|
||||||
if ponydirs is None: ponydirs = self.ponydirs
|
if ponydirs is None: ponydirs = self.ponydirs
|
||||||
if quotedirs is None: quotedirs = self.quotedirs
|
if quotedirs is None: quotedirs = self.quotedirs
|
||||||
|
|
||||||
|
@ -678,45 +670,45 @@ class Ponysay():
|
||||||
## Listing methods ##
|
## Listing methods ##
|
||||||
#####################
|
#####################
|
||||||
|
|
||||||
|
def list(self, ponydirs = None):
|
||||||
'''
|
'''
|
||||||
Lists the available ponies
|
Lists the available ponies
|
||||||
|
|
||||||
@param ponydirs:itr<str>? The pony directories to use
|
@param ponydirs:itr<str>? The pony directories to use
|
||||||
'''
|
'''
|
||||||
def list(self, ponydirs = None):
|
|
||||||
List.simplelist(self.ponydirs if ponydirs is None else ponydirs,
|
List.simplelist(self.ponydirs if ponydirs is None else ponydirs,
|
||||||
self.__quoters(), lambda x : self.__ucsise(x))
|
self.__quoters(), lambda x : self.__ucsise(x))
|
||||||
|
|
||||||
|
|
||||||
|
def linklist(self, ponydirs = None):
|
||||||
'''
|
'''
|
||||||
Lists the available ponies with alternatives inside brackets
|
Lists the available ponies with alternatives inside brackets
|
||||||
|
|
||||||
@param ponydirs:itr<str> The pony directories to use
|
@param ponydirs:itr<str> The pony directories to use
|
||||||
'''
|
'''
|
||||||
def linklist(self, ponydirs = None):
|
|
||||||
List.linklist(self.ponydirs if ponydirs is None else ponydirs,
|
List.linklist(self.ponydirs if ponydirs is None else ponydirs,
|
||||||
self.__quoters(), lambda x, y : self.__ucsise(x, y))
|
self.__quoters(), lambda x, y : self.__ucsise(x, y))
|
||||||
|
|
||||||
|
|
||||||
|
def onelist(self, standard = True, extra = False):
|
||||||
'''
|
'''
|
||||||
Lists the available ponies on one column without anything bold or otherwise formated
|
Lists the available ponies on one column without anything bold or otherwise formated
|
||||||
|
|
||||||
@param standard:bool Include standard ponies
|
@param standard:bool Include standard ponies
|
||||||
@param extra:bool Include extra ponies
|
@param extra:bool Include extra ponies
|
||||||
'''
|
'''
|
||||||
def onelist(self, standard = True, extra = False):
|
|
||||||
List.onelist(self.ponydirs if standard else None,
|
List.onelist(self.ponydirs if standard else None,
|
||||||
self.extraponydirs if extra else None,
|
self.extraponydirs if extra else None,
|
||||||
lambda x : self.__ucsise(x))
|
lambda x : self.__ucsise(x))
|
||||||
|
|
||||||
|
|
||||||
|
def quoters(self, standard = True, extra = False):
|
||||||
'''
|
'''
|
||||||
Lists with all ponies that have quotes and are displayable, on one column without anything bold or otherwise formated
|
Lists with all ponies that have quotes and are displayable, on one column without anything bold or otherwise formated
|
||||||
|
|
||||||
@param standard:bool Include standard ponies
|
@param standard:bool Include standard ponies
|
||||||
@param extra:bool Include extra ponies
|
@param extra:bool Include extra ponies
|
||||||
'''
|
'''
|
||||||
def quoters(self, standard = True, extra = False):
|
|
||||||
## Get all quoters
|
## Get all quoters
|
||||||
ponies = list(self.__quoters()) if standard else []
|
ponies = list(self.__quoters()) if standard else []
|
||||||
|
|
||||||
|
@ -742,13 +734,14 @@ class Ponysay():
|
||||||
## Balloon methods ##
|
## Balloon methods ##
|
||||||
#####################
|
#####################
|
||||||
|
|
||||||
|
def balloonlist(self):
|
||||||
'''
|
'''
|
||||||
Prints a list of all balloons
|
Prints a list of all balloons
|
||||||
'''
|
'''
|
||||||
def balloonlist(self):
|
|
||||||
List.balloonlist(self.balloondirs, self.isthink)
|
List.balloonlist(self.balloondirs, self.isthink)
|
||||||
|
|
||||||
|
|
||||||
|
def __getballoonpath(self, names, alt = False):
|
||||||
'''
|
'''
|
||||||
Returns one file with full path, names is filter for style names, also accepts filepaths
|
Returns one file with full path, names is filter for style names, also accepts filepaths
|
||||||
|
|
||||||
|
@ -756,7 +749,6 @@ class Ponysay():
|
||||||
@param alt:bool For method internal use
|
@param alt:bool For method internal use
|
||||||
@param :str The file name of the balloon, will be `None` iff `names` is `None`
|
@param :str The file name of the balloon, will be `None` iff `names` is `None`
|
||||||
'''
|
'''
|
||||||
def __getballoonpath(self, names, alt = False):
|
|
||||||
## Stop if their is no choosen balloon
|
## Stop if their is no choosen balloon
|
||||||
if names is None:
|
if names is None:
|
||||||
return None
|
return None
|
||||||
|
@ -799,13 +791,13 @@ class Ponysay():
|
||||||
return balloons[balloon]
|
return balloons[balloon]
|
||||||
|
|
||||||
|
|
||||||
|
def __getballoon(self, balloonfile):
|
||||||
'''
|
'''
|
||||||
Creates the balloon style object
|
Creates the balloon style object
|
||||||
|
|
||||||
@param balloonfile:str The file with the balloon style, may be `None`
|
@param balloonfile:str The file with the balloon style, may be `None`
|
||||||
@return :Balloon Instance describing the balloon's style
|
@return :Balloon Instance describing the balloon's style
|
||||||
'''
|
'''
|
||||||
def __getballoon(self, balloonfile):
|
|
||||||
return Balloon.fromFile(balloonfile, self.isthink)
|
return Balloon.fromFile(balloonfile, self.isthink)
|
||||||
|
|
||||||
|
|
||||||
|
@ -814,20 +806,20 @@ class Ponysay():
|
||||||
## Displaying methods ##
|
## Displaying methods ##
|
||||||
########################
|
########################
|
||||||
|
|
||||||
|
def version(self):
|
||||||
'''
|
'''
|
||||||
Prints the name of the program and the version of the program
|
Prints the name of the program and the version of the program
|
||||||
'''
|
'''
|
||||||
def version(self):
|
|
||||||
## Prints the "ponysay $VERSION", if this is modified, ./dev/dist.sh must be modified accordingly
|
## Prints the "ponysay $VERSION", if this is modified, ./dev/dist.sh must be modified accordingly
|
||||||
print('%s %s' % ('ponysay', VERSION))
|
print('%s %s' % ('ponysay', VERSION))
|
||||||
|
|
||||||
|
|
||||||
|
def print_pony(self, args):
|
||||||
'''
|
'''
|
||||||
Print the pony with a speech or though bubble. message, pony and wrap from args are used.
|
Print the pony with a speech or though bubble. message, pony and wrap from args are used.
|
||||||
|
|
||||||
@param args:ArgParser Parsed command line arguments
|
@param args:ArgParser Parsed command line arguments
|
||||||
'''
|
'''
|
||||||
def print_pony(self, args):
|
|
||||||
## Get the pony
|
## Get the pony
|
||||||
(selection, standard, extra) = ([], [], [])
|
(selection, standard, extra) = ([], [], [])
|
||||||
for ponydir in self.ponydirs:
|
for ponydir in self.ponydirs:
|
||||||
|
|
|
@ -39,13 +39,14 @@ from ponysay import *
|
||||||
from metadata import *
|
from metadata import *
|
||||||
|
|
||||||
|
|
||||||
|
VERSION = 'dev' # this line should not be edited, it is fixed by the build system
|
||||||
'''
|
'''
|
||||||
The version of ponysay
|
The version of ponysay
|
||||||
'''
|
'''
|
||||||
VERSION = 'dev' # this line should not be edited, it is fixed by the build system
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def print(text = '', end = '\n'):
|
||||||
'''
|
'''
|
||||||
Hack to enforce UTF-8 in output (in the future, if you see anypony not using utf-8 in
|
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)
|
programs by default, report them to Princess Celestia so she can banish them to the moon)
|
||||||
|
@ -53,30 +54,30 @@ programs by default, report them to Princess Celestia so she can banish them to
|
||||||
@param text:str The text to print (empty string is default)
|
@param text:str The text to print (empty string is default)
|
||||||
@param end:str The appendix to the text to print (line breaking is default)
|
@param end:str The appendix to the text to print (line breaking is default)
|
||||||
'''
|
'''
|
||||||
def print(text = '', end = '\n'):
|
|
||||||
sys.stdout.buffer.write((str(text) + end).encode('utf-8'))
|
sys.stdout.buffer.write((str(text) + end).encode('utf-8'))
|
||||||
|
|
||||||
|
def printerr(text = '', end = '\n'):
|
||||||
'''
|
'''
|
||||||
stderr equivalent to print()
|
stderr equivalent to print()
|
||||||
|
|
||||||
@param text:str The text to print (empty string is default)
|
@param text:str The text to print (empty string is default)
|
||||||
@param end:str The appendix to the text to print (line breaking is default)
|
@param end:str The appendix to the text to print (line breaking is default)
|
||||||
'''
|
'''
|
||||||
def printerr(text = '', end = '\n'):
|
|
||||||
sys.stderr.buffer.write((str(text) + end).encode('utf-8'))
|
sys.stderr.buffer.write((str(text) + end).encode('utf-8'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class PonysayTool():
|
||||||
'''
|
'''
|
||||||
This is the mane class of ponysay-tool
|
This is the mane class of ponysay-tool
|
||||||
'''
|
'''
|
||||||
class PonysayTool():
|
|
||||||
|
def __init__(self, args):
|
||||||
'''
|
'''
|
||||||
Starts the part of the program the arguments indicate
|
Starts the part of the program the arguments indicate
|
||||||
|
|
||||||
@param args:ArgParser Parsed command line arguments
|
@param args:ArgParser Parsed command line arguments
|
||||||
'''
|
'''
|
||||||
def __init__(self, args):
|
|
||||||
if args.argcount == 0:
|
if args.argcount == 0:
|
||||||
args.help()
|
args.help()
|
||||||
exit(255)
|
exit(255)
|
||||||
|
@ -194,13 +195,13 @@ class PonysayTool():
|
||||||
exit(253)
|
exit(253)
|
||||||
|
|
||||||
|
|
||||||
|
def execPonysay(self, args, message = ''):
|
||||||
'''
|
'''
|
||||||
Execute ponysay!
|
Execute ponysay!
|
||||||
|
|
||||||
@param args Arguments
|
@param args Arguments
|
||||||
@param message Message
|
@param message Message
|
||||||
'''
|
'''
|
||||||
def execPonysay(self, args, message = ''):
|
|
||||||
class PhonyArgParser():
|
class PhonyArgParser():
|
||||||
def __init__(self, args, message):
|
def __init__(self, args, message):
|
||||||
self.argcount = len(args) + (0 if message is None else 1)
|
self.argcount = len(args) + (0 if message is None else 1)
|
||||||
|
@ -239,13 +240,13 @@ class PonysayTool():
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def browse(self, ponydir, restriction):
|
||||||
'''
|
'''
|
||||||
Browse ponies
|
Browse ponies
|
||||||
|
|
||||||
@param ponydir:str The pony directory to browse
|
@param ponydir:str The pony directory to browse
|
||||||
@param restriction:list<str> Restrictions on listed ponies, may be None
|
@param restriction:list<str> Restrictions on listed ponies, may be None
|
||||||
'''
|
'''
|
||||||
def browse(self, ponydir, restriction):
|
|
||||||
## Call `stty` to determine the size of the terminal, this way is better than using python's ncurses
|
## Call `stty` to determine the size of the terminal, this way is better than using python's ncurses
|
||||||
termsize = None
|
termsize = None
|
||||||
for channel in (sys.stdout, sys.stdin, sys.stderr):
|
for channel in (sys.stdout, sys.stdin, sys.stderr):
|
||||||
|
@ -431,10 +432,10 @@ class PonysayTool():
|
||||||
(x, y) = (0, 0)
|
(x, y) = (0, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def generateKMS(self):
|
||||||
'''
|
'''
|
||||||
Generate all kmsponies for the current TTY palette
|
Generate all kmsponies for the current TTY palette
|
||||||
'''
|
'''
|
||||||
def generateKMS(self):
|
|
||||||
class PhonyArgParser():
|
class PhonyArgParser():
|
||||||
def __init__(self, key, value):
|
def __init__(self, key, value):
|
||||||
self.argcount = 3
|
self.argcount = 3
|
||||||
|
@ -495,13 +496,13 @@ class PonysayTool():
|
||||||
sys.stdout = stdout
|
sys.stdout = stdout
|
||||||
|
|
||||||
|
|
||||||
|
def generateDimensions(self, ponydir, ponies = None):
|
||||||
'''
|
'''
|
||||||
Generate pony dimension file for a directory
|
Generate pony dimension file for a directory
|
||||||
|
|
||||||
@param ponydir:str The directory
|
@param ponydir:str The directory
|
||||||
@param ponies:itr<str>? Ponies to which to limit
|
@param ponies:itr<str>? Ponies to which to limit
|
||||||
'''
|
'''
|
||||||
def generateDimensions(self, ponydir, ponies = None):
|
|
||||||
dimensions = []
|
dimensions = []
|
||||||
ponyset = None if (ponies is None) or (len(ponies) == 0) else set(ponies)
|
ponyset = None if (ponies is None) or (len(ponies) == 0) else set(ponies)
|
||||||
for ponyfile in os.listdir(ponydir):
|
for ponyfile in os.listdir(ponydir):
|
||||||
|
@ -581,13 +582,13 @@ class PonysayTool():
|
||||||
file.flush()
|
file.flush()
|
||||||
|
|
||||||
|
|
||||||
|
def generateMetadata(self, ponydir, ponies = None):
|
||||||
'''
|
'''
|
||||||
Generate pony metadata collection file for a directory
|
Generate pony metadata collection file for a directory
|
||||||
|
|
||||||
@param ponydir:str The directory
|
@param ponydir:str The directory
|
||||||
@param ponies:itr<str>? Ponies to which to limit
|
@param ponies:itr<str>? Ponies to which to limit
|
||||||
'''
|
'''
|
||||||
def generateMetadata(self, ponydir, ponies = None):
|
|
||||||
if not ponydir.endswith('/'):
|
if not ponydir.endswith('/'):
|
||||||
ponydir += '/'
|
ponydir += '/'
|
||||||
def makeset(value):
|
def makeset(value):
|
||||||
|
@ -663,12 +664,12 @@ class PonysayTool():
|
||||||
file.flush()
|
file.flush()
|
||||||
|
|
||||||
|
|
||||||
|
def editmeta(self, ponyfile):
|
||||||
'''
|
'''
|
||||||
Edit a pony file's metadata
|
Edit a pony file's metadata
|
||||||
|
|
||||||
@param ponyfile:str A pony file to edit
|
@param ponyfile:str A pony file to edit
|
||||||
'''
|
'''
|
||||||
def editmeta(self, ponyfile):
|
|
||||||
(data, meta, image) = 3 * [None]
|
(data, meta, image) = 3 * [None]
|
||||||
|
|
||||||
with open(ponyfile, 'rb') as file:
|
with open(ponyfile, 'rb') as file:
|
||||||
|
@ -838,10 +839,11 @@ class PonysayTool():
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class TextArea(): # TODO support small screens (This is being work on in GNU-Pony/featherweight)
|
||||||
'''
|
'''
|
||||||
GNU Emacs alike text area
|
GNU Emacs alike text area
|
||||||
'''
|
'''
|
||||||
class TextArea(): # TODO support small screens
|
def __init__(self, fields, datamap, left, top, width, height, termsize):
|
||||||
'''
|
'''
|
||||||
Constructor
|
Constructor
|
||||||
|
|
||||||
|
@ -853,17 +855,16 @@ class TextArea(): # TODO support small screens
|
||||||
@param height:int Height of the component
|
@param height:int Height of the component
|
||||||
@param termsize:(int,int) The height and width of the terminal
|
@param termsize:(int,int) The height and width of the terminal
|
||||||
'''
|
'''
|
||||||
def __init__(self, fields, datamap, left, top, width, height, termsize):
|
|
||||||
(self.fields, self.datamap, self.left, self.top, self.width, self.height, self.termsize) \
|
(self.fields, self.datamap, self.left, self.top, self.width, self.height, self.termsize) \
|
||||||
= (fields, datamap, left, top, width - 1, height, termsize)
|
= (fields, datamap, left, top, width - 1, height, termsize)
|
||||||
|
|
||||||
|
|
||||||
|
def run(self, saver):
|
||||||
'''
|
'''
|
||||||
Execute text reading
|
Execute text reading
|
||||||
|
|
||||||
@param saver Save method
|
@param saver Save method
|
||||||
'''
|
'''
|
||||||
def run(self, saver):
|
|
||||||
innerleft = UCS.dispLen(max(self.fields, key = UCS.dispLen)) + self.left + 3
|
innerleft = UCS.dispLen(max(self.fields, key = UCS.dispLen)) + self.left + 3
|
||||||
|
|
||||||
leftlines = []
|
leftlines = []
|
||||||
|
@ -1183,25 +1184,25 @@ class TextArea(): # TODO support small screens
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
HOME = os.environ['HOME'] if 'HOME' in os.environ else os.path.expanduser('~')
|
||||||
'''
|
'''
|
||||||
The user's home directory
|
The user's home directory
|
||||||
'''
|
'''
|
||||||
HOME = os.environ['HOME'] if 'HOME' in os.environ else os.path.expanduser('~')
|
|
||||||
|
|
||||||
|
pipelinein = not sys.stdin.isatty()
|
||||||
'''
|
'''
|
||||||
Whether stdin is piped
|
Whether stdin is piped
|
||||||
'''
|
'''
|
||||||
pipelinein = not sys.stdin.isatty()
|
|
||||||
|
|
||||||
|
pipelineout = not sys.stdout.isatty()
|
||||||
'''
|
'''
|
||||||
Whether stdout is piped
|
Whether stdout is piped
|
||||||
'''
|
'''
|
||||||
pipelineout = not sys.stdout.isatty()
|
|
||||||
|
|
||||||
|
pipelineerr = not sys.stderr.isatty()
|
||||||
'''
|
'''
|
||||||
Whether stderr is piped
|
Whether stderr is piped
|
||||||
'''
|
'''
|
||||||
pipelineerr = not sys.stderr.isatty()
|
|
||||||
|
|
||||||
|
|
||||||
usage_program = '\033[34;1mponysay-tool\033[21;39m'
|
usage_program = '\033[34;1mponysay-tool\033[21;39m'
|
||||||
|
@ -1241,10 +1242,10 @@ opts.add_argumented( ['--edit-rm'], arg = 'PONY-FILE', help = 'Remove
|
||||||
opts.add_argumented( ['--edit-apply'], arg = 'PONY-FILE', help = 'Apply metadata from stdin to a pony file')
|
opts.add_argumented( ['--edit-apply'], arg = 'PONY-FILE', help = 'Apply metadata from stdin to a pony file')
|
||||||
opts.add_argumented( ['--edit-stash'], arg = 'PONY-FILE', help = 'Print applyable metadata from a pony file')
|
opts.add_argumented( ['--edit-stash'], arg = 'PONY-FILE', help = 'Print applyable metadata from a pony file')
|
||||||
|
|
||||||
|
unrecognised = not opts.parse()
|
||||||
'''
|
'''
|
||||||
Whether at least one unrecognised option was used
|
Whether at least one unrecognised option was used
|
||||||
'''
|
'''
|
||||||
unrecognised = not opts.parse()
|
|
||||||
|
|
||||||
PonysayTool(args = opts)
|
PonysayTool(args = opts)
|
||||||
|
|
||||||
|
|
|
@ -33,13 +33,15 @@ from common import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimised Java, may not be the nicest, or even fast, Python code
|
||||||
'''
|
'''
|
||||||
Class used for correcting spellos and typos,
|
Class used for correcting spellos and typos,
|
||||||
|
|
||||||
Note that this implementation will not find that correctly spelled word are correct faster than it corrects words.
|
Note that this implementation will not find that correctly spelled word are correct faster than it corrects words.
|
||||||
It is also limited to words of size 0 to 127 (inclusive)
|
It is also limited to words of size 0 to 127 (inclusive)
|
||||||
'''
|
'''
|
||||||
class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimised Java, may not be the nicest, or even fast, Python code
|
|
||||||
|
def __init__(self, directories, ending = None):
|
||||||
'''
|
'''
|
||||||
Constructor
|
Constructor
|
||||||
|
|
||||||
|
@ -50,7 +52,6 @@ class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimise
|
||||||
|
|
||||||
@param directories:list<str> The file names with the correct spelling
|
@param directories:list<str> The file names with the correct spelling
|
||||||
'''
|
'''
|
||||||
def __init__(self, directories, ending = None):
|
|
||||||
self.weights = {'k' : {'c' : 0.25, 'g' : 0.75, 'q' : 0.125},
|
self.weights = {'k' : {'c' : 0.25, 'g' : 0.75, 'q' : 0.125},
|
||||||
'c' : {'k' : 0.25, 'g' : 0.75, 's' : 0.5, 'z' : 0.5, 'q' : 0.125},
|
'c' : {'k' : 0.25, 'g' : 0.75, 's' : 0.5, 'z' : 0.5, 'q' : 0.125},
|
||||||
's' : {'z' : 0.25, 'c' : 0.5},
|
's' : {'z' : 0.25, 'c' : 0.5},
|
||||||
|
@ -145,13 +146,13 @@ class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimise
|
||||||
# index -= 1;
|
# index -= 1;
|
||||||
|
|
||||||
|
|
||||||
|
def correct(self, used):
|
||||||
'''
|
'''
|
||||||
Finds the closests correct spelled word
|
Finds the closests correct spelled word
|
||||||
|
|
||||||
@param used:str The word to correct
|
@param used:str The word to correct
|
||||||
@return (words, distance):(list<string>, int) A list the closest spellings and the weighted distance
|
@return (words, distance):(list<string>, int) A list the closest spellings and the weighted distance
|
||||||
'''
|
'''
|
||||||
def correct(self, used):
|
|
||||||
if len(used) > 127:
|
if len(used) > 127:
|
||||||
return ([used], 0)
|
return ([used], 0)
|
||||||
|
|
||||||
|
@ -159,12 +160,12 @@ class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimise
|
||||||
return (self.corrections, self.closestDistance)
|
return (self.corrections, self.closestDistance)
|
||||||
|
|
||||||
|
|
||||||
|
def __correct(self, used):
|
||||||
'''
|
'''
|
||||||
Finds the closests correct spelled word
|
Finds the closests correct spelled word
|
||||||
|
|
||||||
@param used:str The word to correct, it must satisfy all restrictions
|
@param used:str The word to correct, it must satisfy all restrictions
|
||||||
'''
|
'''
|
||||||
def __correct(self, used):
|
|
||||||
self.closestDistance = 0x7FFFFFFF
|
self.closestDistance = 0x7FFFFFFF
|
||||||
previous = self.dictionary[-1]
|
previous = self.dictionary[-1]
|
||||||
prevLen = 0
|
prevLen = 0
|
||||||
|
@ -217,6 +218,7 @@ class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimise
|
||||||
prevLen = len(proper)
|
prevLen = len(proper)
|
||||||
|
|
||||||
|
|
||||||
|
def __distance(self, proper, y0, yn, used, x0, xn):
|
||||||
'''
|
'''
|
||||||
Calculate the distance between a correct word and a incorrect word
|
Calculate the distance between a correct word and a incorrect word
|
||||||
|
|
||||||
|
@ -228,7 +230,6 @@ class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimise
|
||||||
@param xn:int The length, before applying `x0`, of `used`
|
@param xn:int The length, before applying `x0`, of `used`
|
||||||
@return :float The distance between the words
|
@return :float The distance between the words
|
||||||
'''
|
'''
|
||||||
def __distance(self, proper, y0, yn, used, x0, xn):
|
|
||||||
my = self.M[y0]
|
my = self.M[y0]
|
||||||
for y in range(y0, yn):
|
for y in range(y0, yn):
|
||||||
best = 0x7FFFFFFF
|
best = 0x7FFFFFFF
|
||||||
|
|
15
src/ucs.py
15
src/ucs.py
|
@ -33,18 +33,19 @@ from common import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class UCS():
|
||||||
'''
|
'''
|
||||||
UCS utility class
|
UCS utility class
|
||||||
'''
|
'''
|
||||||
class UCS():
|
|
||||||
|
@staticmethod
|
||||||
|
def isCombining(char):
|
||||||
'''
|
'''
|
||||||
Checks whether a character is a combining character
|
Checks whether a character is a combining character
|
||||||
|
|
||||||
@param char:chr The character to test
|
@param char:chr The character to test
|
||||||
@return :bool Whether the character is a combining character
|
@return :bool Whether the character is a combining character
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
|
||||||
def isCombining(char):
|
|
||||||
o = ord(char)
|
o = ord(char)
|
||||||
if (0x0300 <= o) and (o <= 0x036F): return True
|
if (0x0300 <= o) and (o <= 0x036F): return True
|
||||||
if (0x20D0 <= o) and (o <= 0x20FF): return True
|
if (0x20D0 <= o) and (o <= 0x20FF): return True
|
||||||
|
@ -53,14 +54,14 @@ class UCS():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def countCombining(string):
|
||||||
'''
|
'''
|
||||||
Gets the number of combining characters in a string
|
Gets the number of combining characters in a string
|
||||||
|
|
||||||
@param string:str A text to count combining characters in
|
@param string:str A text to count combining characters in
|
||||||
@return :int The number of combining characters in the string
|
@return :int The number of combining characters in the string
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
|
||||||
def countCombining(string):
|
|
||||||
rc = 0
|
rc = 0
|
||||||
for char in string:
|
for char in string:
|
||||||
if UCS.isCombining(char):
|
if UCS.isCombining(char):
|
||||||
|
@ -68,13 +69,13 @@ class UCS():
|
||||||
return rc
|
return rc
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def dispLen(string):
|
||||||
'''
|
'''
|
||||||
Gets length of a string not counting combining characters
|
Gets length of a string not counting combining characters
|
||||||
|
|
||||||
@param string:str The text of which to determine the monospaced width
|
@param string:str The text of which to determine the monospaced width
|
||||||
@return The determine the monospaced width of the text, provided it does not have escape sequnces
|
@return The determine the monospaced width of the text, provided it does not have escape sequnces
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
|
||||||
def dispLen(string):
|
|
||||||
return len(string) - UCS.countCombining(string)
|
return len(string) - UCS.countCombining(string)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue