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:
Mattias Andrée 2013-08-12 07:54:31 +02:00
parent a18804002b
commit ecdac1b6a1
12 changed files with 583 additions and 579 deletions

View file

@ -33,35 +33,38 @@ from common import *
ARGUMENTLESS = 0
'''
Option takes no arguments
'''
ARGUMENTLESS = 0
ARGUMENTED = 1
'''
Option takes one argument per instance
'''
ARGUMENTED = 1
VARIADIC = 2
'''
Option consumes all following arguments
'''
VARIADIC = 2
'''
Simple argument parser
'''
class ArgParser():
'''
Constructor.
The short description is printed on same line as the program name
@param program:str The name of the program
@param description:str Short, single-line, description of the program
@param usage:str Formated, multi-line, usage text
@param longdescription:str Long, multi-line, description of the program, may be `None`
Simple argument parser
'''
def __init__(self, program, description, usage, longdescription = None):
'''
Constructor.
The short description is printed on same line as the program name
@param program:str The name of the program
@param description:str Short, single-line, description of the program
@param usage:str Formated, multi-line, usage text
@param longdescription:str Long, multi-line, description of the program, may be `None`
'''
self.linuxvt = ('TERM' in os.environ) and (os.environ['TERM'] == 'linux')
self.__program = program
self.__description = description
@ -72,41 +75,41 @@ class ArgParser():
self.optmap = {}
'''
Add option that takes no arguments
@param alternatives:list<str> Option names
@param help:str Short description, use `None` to hide the option
'''
def add_argumentless(self, alternatives, help = None):
'''
Add option that takes no arguments
@param alternatives:list<str> Option names
@param help:str Short description, use `None` to hide the option
'''
self.__arguments.append((ARGUMENTLESS, alternatives, None, help))
stdalt = alternatives[0]
self.opts[stdalt] = None
for alt in alternatives:
self.optmap[alt] = (stdalt, ARGUMENTLESS)
'''
Add option that takes one argument
@param alternatives:list<str> Option names
@param arg:str The name of the takes argument, one word
@param help:str Short description, use `None` to hide the option
'''
def add_argumented(self, alternatives, arg, help = None):
'''
Add option that takes one argument
@param alternatives:list<str> Option names
@param arg:str The name of the takes argument, one word
@param help:str Short description, use `None` to hide the option
'''
self.__arguments.append((ARGUMENTED, alternatives, arg, help))
stdalt = alternatives[0]
self.opts[stdalt] = None
for alt in alternatives:
self.optmap[alt] = (stdalt, ARGUMENTED)
'''
Add option that takes all following argument
@param alternatives:list<str> Option names
@param arg:str The name of the takes arguments, one word
@param help:str Short description, use `None` to hide the option
'''
def add_variadic(self, alternatives, arg, help = None):
'''
Add option that takes all following argument
@param alternatives:list<str> Option names
@param arg:str The name of the takes arguments, one word
@param help:str Short description, use `None` to hide the option
'''
self.__arguments.append((VARIADIC, alternatives, arg, help))
stdalt = alternatives[0]
self.opts[stdalt] = None
@ -114,13 +117,13 @@ class ArgParser():
self.optmap[alt] = (stdalt, VARIADIC)
'''
Parse arguments
@param args:list<str> The command line arguments, should include the execute file at index 0, `sys.argv` is default
@return :bool Whether no unrecognised option is used
'''
def parse(self, argv = sys.argv):
'''
Parse arguments
@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
'''
self.argcount = len(argv) - 1
self.files = []
@ -242,10 +245,10 @@ class ArgParser():
return self.rc
'''
Prints a colourful help message
'''
def help(self):
'''
Prints a colourful help message
'''
print('\033[1m%s\033[21m %s %s' % (self.__program, '-' if self.linuxvt else '', self.__description))
print()
if self.__longdescription is not None:

View file

@ -36,25 +36,26 @@ from ucs import *
'''
Super-ultra-extreme-awesomazing replacement for cowsay
'''
class Backend():
'''
Constructor
@param message:str The message spoken by the pony
@param ponyfile:str The pony file
@param wrapcolumn:int The column at where to wrap the message, `None` for no wrapping
@param width:int The width of the screen, `None` if truncation should not be applied
@param balloon:Balloon The balloon style object, `None` if only the pony should be printed
@param hyphen:str How hyphens added by the wordwrapper should be printed
@param linkcolour:str How to colour the link character, empty string if none
@param ballooncolour:str How to colour the balloon, empty string if none
@param mode:str Mode string for the pony
@parma infolevel:int 2 if ++info is used, 1 if --info is used and 0 otherwise
Super-ultra-extreme-awesomazing replacement for cowsay
'''
def __init__(self, message, ponyfile, wrapcolumn, width, balloon, hyphen, linkcolour, ballooncolour, mode, infolevel):
'''
Constructor
@param message:str The message spoken by the pony
@param ponyfile:str The pony file
@param wrapcolumn:int The column at where to wrap the message, `None` for no wrapping
@param width:int The width of the screen, `None` if truncation should not be applied
@param balloon:Balloon The balloon style object, `None` if only the pony should be printed
@param hyphen:str How hyphens added by the wordwrapper should be printed
@param linkcolour:str How to colour the link character, empty string if none
@param ballooncolour:str How to colour the balloon, empty string if none
@param mode:str Mode string for the pony
@parma infolevel:int 2 if ++info is used, 1 if --info is used and 0 otherwise
'''
self.message = message
self.ponyfile = ponyfile
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
'''
Process all data
'''
def parse(self):
'''
Process all data
'''
self.__loadFile()
if self.pony.startswith('$$$\n'):
@ -126,14 +127,14 @@ class Backend():
self.__truncate()
'''
Format metadata to be nicely printed, this include bold keys
@param info:str The metadata
@return :str The metadata nicely formated
'''
@staticmethod
def formatInfo(info):
'''
Format metadata to be nicely printed, this include bold keys
@param info:str The metadata
@return :str The metadata nicely formated
'''
info = info.split('\n')
tags = ''
comment = ''
@ -156,10 +157,10 @@ class Backend():
return tags + comment
'''
Remove padding spaces fortune cookies are padded with whitespace (damn featherbrains)
'''
def __unpadMessage(self):
'''
Remove padding spaces fortune cookies are padded with whitespace (damn featherbrains)
'''
lines = self.message.split('\n')
for spaces in (128, 64, 32, 16, 8, 4, 2, 1):
padded = True
@ -176,10 +177,10 @@ class Backend():
self.message = '\n'.join(lines)
'''
Converts all tabs in the message to spaces by expanding
'''
def __expandMessage(self):
'''
Converts all tabs in the message to spaces by expanding
'''
lines = self.message.split('\n')
buf = ''
for line in lines:
@ -203,18 +204,18 @@ class Backend():
self.message = buf[:-1]
'''
Loads the pony file
'''
def __loadFile(self):
'''
Loads the pony file
'''
with open(self.ponyfile, 'rb') as ponystream:
self.pony = ponystream.read().decode('utf8', 'replace')
'''
Truncate output to the width of the screen
'''
def __truncate(self):
'''
Truncate output to the width of the screen
'''
if self.width is None:
return
lines = self.output.split('\n')
@ -237,10 +238,10 @@ class Backend():
self.output = self.output[:-1]
'''
Process the pony file and generate output to self.output
'''
def __processPony(self):
'''
Process the pony file and generate output to self.output
'''
self.output = ''
AUTO_PUSH = '\033[01010~'
@ -307,7 +308,7 @@ class Backend():
w -= x;
else:
w = int(w)
balloon = self.__getballoon(w, h, x, justify, indent)
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]:
@ -383,15 +384,15 @@ class Backend():
self.output = '\n'.join(self.output)
'''
Gets colour code att the currect offset in a buffer
@param input:str The input buffer
@param offset:int The offset at where to start reading, a escape must begin here
@return :str The escape sequence
'''
@staticmethod
def getColour(input, offset):
'''
Gets colour code att the currect offset in a buffer
@param input:str The input buffer
@param offset:int The offset at where to start reading, a escape must begin here
@return :str The escape sequence
'''
(i, n) = (offset, len(input))
rc = input[i]
i += 1
@ -439,14 +440,14 @@ class Backend():
return rc
'''
Calculates the number of visible characters in a text
@param input:str The input buffer
@return :int The number of visible characters
'''
@staticmethod
def len(input):
'''
Calculates the number of visible characters in a text
@param input:str The input buffer
@return :int The number of visible characters
'''
(rc, i, n) = (0, 0, len(input))
while i < n:
c = input[i]
@ -459,18 +460,18 @@ class Backend():
return rc
'''
Generates a balloon with the message
@param width:int The minimum width of the balloon
@param height:int The minimum height of the balloon
@param innerleft:int The left column of the required span, excluding that of `left`
@param justify:str Balloon placement justification, 'c' centered,
'l' left (expand to right), 'r' right (expand to left)
@param left:int The column where the balloon starts
@return :str The balloon the the message as a string
'''
def __getballoon(self, width, height, innerleft, justify, left):
def __getBalloon(self, width, height, innerleft, justify, left):
'''
Generates a balloon with the message
@param width:int The minimum width of the balloon
@param height:int The minimum height of the balloon
@param innerleft:int The left column of the required span, excluding that of `left`
@param justify:str Balloon placement justification, 'c' centered,
'l' left (expand to right), 'r' right (expand to left)
@param left:int The column where the balloon starts
@return :str The balloon the the message as a string
'''
wrap = None
if self.wrapcolumn is not None:
wrap = self.wrapcolumn - left
@ -508,14 +509,14 @@ class Backend():
return rc
'''
Wraps the message
@param message:str The message to wrap
@param wrap:int The width at where to force wrapping
@return :str The message wrapped
'''
def __wrapMessage(self, message, wrap):
'''
Wraps the message
@param message:str The message to wrap
@param wrap:int The width at where to force wrapping
@return :str The message wrapped
'''
wraplimit = os.environ['PONYSAY_WRAP_LIMIT'] if 'PONYSAY_WRAP_LIMIT' in os.environ else ''
wraplimit = 8 if len(wraplimit) == 0 else int(wraplimit)
@ -579,11 +580,11 @@ class Backend():
nbsp = b[map[mm + x]] == ' ' # nbsp
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
while b[hyphen] != '­': # sort hyphen
while b[hyphen] != '­': # soft hyphen
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
m = map[mm + x]

View file

@ -34,36 +34,37 @@ from ucs import *
'''
Balloon format class
'''
class Balloon():
'''
Constructor
@param link:str The \-directional balloon line character
@param linkmirror:str The /-directional balloon line character
@param linkcross:str The /-directional balloon crossing a \-directional ballonon line character
@param ww:str See the info manual
@param ee:str See the info manual
@param nw:list<str> See the info manual
@param nnw:list<str> See the info manual
@param n:list<str> See the info manual
@param nne:list<str> See the info manual
@param ne:list<str> See the info manual
@param nee:str See the info manual
@param e:str See the info manual
@param see:str See the info manual
@param se:list<str> See the info manual
@param sse:list<str> See the info manual
@param s:list<str> See the info manual
@param ssw:list<str> See the info manual
@param sw:list<str> See the info manual
@param sww:str See the info manual
@param w:str See the info manual
@param nww:str See the info manual
Balloon format class
'''
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
@param link:str The \-directional balloon line character
@param linkmirror:str The /-directional balloon line character
@param linkcross:str The /-directional balloon crossing a \-directional ballonon line character
@param ww:str See the info manual
@param ee:str See the info manual
@param nw:list<str> See the info manual
@param nnw:list<str> See the info manual
@param n:list<str> See the info manual
@param nne:list<str> See the info manual
@param ne:list<str> See the info manual
@param nee:str See the info manual
@param e:str See the info manual
@param see:str See the info manual
@param se:list<str> See the info manual
@param sse:list<str> See the info manual
@param s:list<str> See the info manual
@param ssw:list<str> See the info manual
@param sw:list<str> See the info manual
@param sww:str See the info manual
@param w:str See the info manual
@param nww:str See the info manual
'''
(self.link, self.linkmirror, self.linkcross) = (link, linkmirror, linkcross)
(self.ww, self.ee) = (ww, ee)
(self.nw, self.ne, self.se, self.sw) = (nw, ne, se, sw)
@ -86,16 +87,16 @@ class Balloon():
self.minheight = minN + minS
'''
Generates a balloon with a message
@param minw:int The minimum number of columns of the balloon
@param minh:int The minimum number of lines of the balloon
@param lines:list<str> The text lines to display
@param lencalc:int(str) Function used to compute the length of a text line
@return :str The balloon as a formated string
'''
def get(self, minw, minh, lines, lencalc):
'''
Generates a balloon with a message
@param minw:int The minimum number of columns of the balloon
@param minh:int The minimum number of lines of the balloon
@param lines:list<str> The text lines to display
@param lencalc:int(str) Function used to compute the length of a text line
@return :str The balloon as a formated string
'''
## Get dimension
h = self.minheight + len(lines)
w = self.minwidth + lencalc(max(lines, key = lencalc))
@ -138,15 +139,15 @@ class Balloon():
return '\n'.join(rc)
'''
Creates the balloon style object
@param balloonfile:str The file with the balloon style, may be `None`
@param isthink:bool Whether the ponythink command is used
@return :Balloon Instance describing the balloon's style
'''
@staticmethod
def fromFile(balloonfile, isthink):
'''
Creates the balloon style object
@param balloonfile:str The file with the balloon style, may be `None`
@param isthink:bool Whether the ponythink command is used
@return :Balloon Instance describing the balloon's style
'''
## Use default balloon if none is specified
if balloonfile is None:
if isthink:

View file

@ -33,19 +33,20 @@ from common import *
'''
ANSI colour stack
This is used to make layers with independent coloursations
'''
class ColourStack():
'''
Constructor
ANSI colour stack
@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
This is used to make layers with independent coloursations
'''
def __init__(self, autopush, autopop):
'''
Constructor
@param autopush:str String that, when used, will create a new independently colourised layer
@param autopop:str String that, when used, will end the current layer and continue of the previous layer
'''
self.autopush = autopush
self.autopop = autopop
self.lenpush = len(autopush)
@ -56,24 +57,24 @@ class ColourStack():
self.seq = None
'''
Create a new independently colourised layer
@return :str String that should be inserted into your buffer
'''
def push(self):
'''
Create a new independently colourised layer
@return :str String that should be inserted into your buffer
'''
self.stack.insert(0, [self.bufproto, None, None, [False] * 9])
if len(self.stack) == 1:
return None
return '\033[0m'
'''
End the current layer and continue of the previous layer
@return :str String that should be inserted into your buffer
'''
def pop(self):
'''
End the current layer and continue of the previous layer
@return :str String that should be inserted into your buffer
'''
old = self.stack.pop(0)
rc = '\033[0;'
if len(self.stack) == 0: # last resort in case something made it pop too mush
@ -87,14 +88,14 @@ class ColourStack():
return rc[:-1] + 'm'
'''
Use this, in sequence, for which character in your buffer that contains yor autopush and autopop
string, the automatically get push and pop string to insert after each character
@param :chr One character in your buffer
@return :str The text to insert after the input character
'''
def feed(self, char):
'''
Use this, in sequence, for which character in your buffer that contains yor autopush and autopop
string, the automatically get push and pop string to insert after each character
@param :chr One character in your buffer
@return :str The text to insert after the input character
'''
if self.seq is not None:
self.seq += char
if (char == '~') or (('a' <= char) and (char <= 'z')) or (('A' <= char) and (char <= 'Z')):

View file

@ -38,40 +38,40 @@ from subprocess import Popen, PIPE
VERSION = 'dev' # this line should not be edited, it is fixed by the build system
'''
The version of ponysay
'''
VERSION = 'dev' # this line should not be edited, it is fixed by the build system
'''
Hack to enforce UTF-8 in output (in the future, if you see anypony not using utf-8 in
programs by default, report them to Princess Celestia so she can banish them to the moon)
@param text:str The text to print (empty string is default)
@param end:str The appendix to the text to print (line breaking is default)
'''
def print(text = '', end = '\n'):
'''
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'))
'''
stderr equivalent to print()
@param text:str The text to print (empty string is default)
@param end:str The appendix to the text to print (line breaking is default)
'''
def printerr(text = '', end = '\n'):
'''
stderr equivalent to print()
@param text:str The text to print (empty string is default)
@param end:str The appendix to the text to print (line breaking is default)
'''
sys.stderr.buffer.write((str(text) + end).encode('utf-8'))
fd3 = None
'''
/proc/self/fd/3 equivalent to print()
@param text:str The text to print (empty string is default)
@param end:str The appendix to the text to print (line breaking is default)
'''
def printinfo(text = '', end = '\n'):
'''
/proc/self/fd/3 equivalent to print()
@param text:str The text to print (empty string is default)
@param end:str The appendix to the text to print (line breaking is default)
'''
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:
@ -80,23 +80,23 @@ def printinfo(text = '', end = '\n'):
fd3.write(str(text) + end)
'''
Checks whether a text ends with a specific text, but has more
@param text:str The text to test
@param ending:str The desired end of the text
@return :bool The result of the test
'''
def endswith(text, ending):
'''
Checks whether a text ends with a specific text, but has more
@param text:str The text to test
@param ending:str The desired end of the text
@return :bool The result of the test
'''
return text.endswith(ending) and not (text == ending)
'''
Gets the size of the terminal in (rows, columns)
@return (rows, columns):(int, int) The number or lines and the number of columns in the terminal's display area
'''
def gettermsize():
'''
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
'''
## 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]

View file

@ -33,18 +33,19 @@ from common import *
'''
KMS support utilisation
'''
class KMS():
'''
Identifies whether KMS support is utilised
@param linuxvt:bool Whether Linux VT is used
@return :bool Whether KMS support is utilised
KMS support utilisation
'''
@staticmethod
def usingkms(linuxvt):
'''
Identifies whether KMS support is utilised
@param linuxvt:bool Whether Linux VT is used
@return :bool Whether KMS support is utilised
'''
## KMS is not utilised if Linux VT is not used
if not linuxvt:
return False
@ -64,16 +65,16 @@ class KMS():
return env_kms != ''
'''
Returns the file name of the input pony converted to a KMS pony, or if KMS is not used, the input pony itself
@param pony:str Choosen pony file
@param home:str The home directory
@param linuxvt:bool Whether Linux VT is used
@return :str Pony file to display
'''
@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
@param pony:str Choosen pony file
@param home:str The home directory
@param linuxvt:bool Whether Linux VT is used
@return :str Pony file to display
'''
## If not in Linux VT, return the pony as is
if not linuxvt:
return pony

View file

@ -34,17 +34,18 @@ from ucs import *
'''
File listing functions
'''
class List():
'''
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
File listing functions
'''
@staticmethod
def __columnise(ponies):
'''
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
'''
## Get terminal width, and a 2 which is the space between columns
termwidth = gettermsize()[1] + 2
## Sort the ponies, and get the cells' widths, and the largest width + 2
@ -90,17 +91,17 @@ class List():
## Print the matrix, with one extra blank row
print('\n'.join([''.join(line)[:-2] for line in lines]))
print()
'''
Lists the available ponies
@param ponydirs:itr<str> The pony directories to use
@param quoters:__in__(str)bool Set of ponies that of quotes
@param ucsiser:(list<str>)?void Function used to UCS:ise names
'''
@staticmethod
def simplelist(ponydirs, quoters = [], ucsiser = None):
'''
Lists the available ponies
@param ponydirs:itr<str> The pony directories to use
@param quoters:__in__(str)bool Set of ponies that of quotes
@param ucsiser:(list<str>)?void Function used to UCS:ise names
'''
for ponydir in ponydirs: # Loop ponydirs
## Get all ponies in the directory
_ponies = os.listdir(ponydir)
@ -122,15 +123,15 @@ class List():
List.__columnise([(pony, '\033[1m' + pony + '\033[21m' if pony in quoters else pony) for pony in ponies])
'''
Lists the available ponies with alternatives inside brackets
@param ponydirs:itr<str> The pony directories to use
@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
'''
@staticmethod
def linklist(ponydirs = None, quoters = [], ucsiser = None):
'''
Lists the available ponies with alternatives inside brackets
@param ponydirs:itr<str> The pony directories to use
@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
'''
## Get the size of the terminal
termsize = gettermsize()
@ -200,15 +201,15 @@ class List():
List.__columnise(list(ponies))
'''
Lists the available ponies on one column without anything bold or otherwise formated
@param standard:itr<str>? Include standard ponies
@param extra:itr<str>? Include extra ponies
@param ucsiser:(list<str>)?void Function used to UCS:ise names
'''
@staticmethod
def onelist(standarddirs, extradirs = None, ucsiser = None):
'''
Lists the available ponies on one column without anything bold or otherwise formated
@param standard:itr<str>? Include standard ponies
@param extra:itr<str>? Include extra ponies
@param ucsiser:(list<str>)?void Function used to UCS:ise names
'''
## Get all pony files
_ponies = []
if standarddirs is not None:
@ -237,14 +238,14 @@ class List():
print(pony)
'''
Prints a list of all balloons
@param balloondirs:itr<str> The balloon directories to use
@param isthink:bool Whether the ponythink command is used
'''
@staticmethod
def balloonlist(balloondirs, isthink):
'''
Prints a list of all balloons
@param balloondirs:itr<str> The balloon directories to use
@param isthink:bool Whether the ponythink command is used
'''
## Get the size of the terminal
termsize = gettermsize()

View file

@ -33,18 +33,19 @@ from common import *
'''
Metadata functions
'''
class Metadata():
'''
Make restriction test logic function
@param restriction:list<string> Metadata based restrictions
@return :dict<str, str>bool Test function
Metadata functions
'''
@staticmethod
def makeRestrictionLogic(restriction):
'''
Make restriction test logic function
@param restriction:list<string> Metadata based restrictions
@return :dict<str, str>bool Test function
'''
def get_test(cell):
strict = cell[0][-1] != '?'
key = cell[0]
@ -109,15 +110,15 @@ class Metadata():
return Logic(table)
'''
Get ponies that pass restriction
@param ponydir:str Pony directory, must end with `os.sep`
@param logic:(str)bool Restriction test functor
@return :list<str> Passed ponies
'''
@staticmethod
def restrictedPonies(ponydir, logic):
'''
Get ponies that pass restriction
@param ponydir:str Pony directory, must end with `os.sep`
@param logic:(str)bool Restriction test functor
@return :list<str> Passed ponies
'''
import pickle
passed = []
if os.path.exists(ponydir + 'metadata'):
@ -131,15 +132,15 @@ class Metadata():
return passed
'''
Get ponies that fit the terminal
@param fitting:add(str)void The set to fill
@param requirement:int The maximum allowed value
@param file:istream The file with all data
'''
@staticmethod
def getfitting(fitting, requirement, file):
'''
Get ponies that fit the terminal
@param fitting:add(str)void The set to fill
@param requirement:int The maximum allowed value
@param file:istream The file with all data
'''
data = file.read() # not too much data, can load everything at once
ptr = 0
while data[ptr] != 47: # 47 == ord('/')

View file

@ -3,13 +3,31 @@
'''
ponysay - Ponysay, cowsay reimplementation for ponies
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
and/or modify it under the terms of the Do What The Fuck You Want
To Public License, Version 2, as published by Sam Hocevar. See
http://sam.zoy.org/wtfpl/COPYING for more details.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(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 backend import *
@ -22,29 +40,29 @@ from metadata import *
'''
This is the mane class of ponysay
'''
class Ponysay():
'''
Constructor
This is the mane class of ponysay
'''
def __init__(self):
'''
The user's home directory
Constructor
'''
# The user's home directory
self.HOME = os.environ['HOME'] if 'HOME' in os.environ else ''
if len(self.HOME) == 0:
os.environ['HOME'] = self.HOME = os.path.expanduser('~')
'''
Parse a file name encoded with environment variables
@param file The encoded file name
@return The target file name, None if the environment variables are not declared
'''
def parsefile(file):
'''
Parse a file name encoded with environment variables
@param file The encoded file name
@return The target file name, None if the environment variables are not declared
'''
if '$' in file:
buf = ''
esc = False
@ -88,21 +106,15 @@ class Ponysay():
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
'''
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')
'''
Whether the script is executed as ponythink
'''
# Whether the script is executed as ponythink
self.isthink = sys.argv[0]
if os.sep in self.isthink:
self.isthink = self.isthink[self.isthink.rfind(os.sep) + 1:]
@ -111,31 +123,21 @@ class Ponysay():
self.isthink = self.isthink.endswith('think')
'''
Whether stdin is piped
'''
# Whether stdin is piped
self.pipelinein = not sys.stdin.isatty()
'''
Whether stdout is piped
'''
# Whether stdout is piped
self.pipelineout = not sys.stdout.isatty()
'''
Whether stderr is piped
'''
# Whether stderr is piped
self.pipelineerr = not sys.stderr.isatty()
'''
Whether KMS is used
'''
# Whether KMS is used
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 = ''
@ -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()
self.xponydirs = []
_ponydirs = share('ponies/')
@ -171,9 +171,7 @@ class Ponysay():
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()
self.extraxponydirs = []
_extraponydirs = share('extraponies/')
@ -190,9 +188,7 @@ class Ponysay():
appendset.add(extraponydir)
'''
The directories where quotes files are stored
'''
# The directories where quotes files are stored
appendset = set()
self.quotedirs = []
_quotedirs = share('quotes/')
@ -202,9 +198,7 @@ class Ponysay():
appendset.add(quotedir)
'''
The directories where balloon style files are stored
'''
# The directories where balloon style files are stored
appendset = set()
self.balloondirs = []
_balloondirs = share('balloons/')
@ -214,9 +208,7 @@ class Ponysay():
appendset.add(balloondir)
'''
ucsmap files
'''
# ucsmap files
appendset = set()
self.ucsmaps = []
_ucsmaps = share('ucsmap/')
@ -227,24 +219,24 @@ class Ponysay():
'''
Starts the part of the program the arguments indicate
@param args:ArgParser Parsed command line arguments
'''
def run(self, args):
'''
Starts the part of the program the arguments indicate
@param args:ArgParser Parsed command line arguments
'''
if (args.argcount == 0) and not self.pipelinein:
args.help()
exit(254)
return
'''
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
@return :bool Whether the check passed
'''
def test(*keys):
'''
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
@return :bool Whether the check passed
'''
for key in keys:
if isinstance(key, str):
if args.opts[key] is not None:
@ -328,21 +320,21 @@ class Ponysay():
## Methods that run before the mane methods ##
##############################################
'''
Use extra ponies
'''
def __extraponies(self):
'''
Use extra ponies
'''
## Change ponydir to extraponydir
self.ponydirs[:] = self.extraponydirs
self.quotedirs[:] = [] ## TODO +q
'''
Use best.pony if nothing else is set
@param args:ArgParser Parsed command line arguments
'''
def __bestpony(self, args):
'''
Use best.pony if nothing else is set
@param args:ArgParser Parsed command line arguments
'''
## Set best.pony as the pony to display if none is selected
def test(keys, strict):
if strict:
@ -368,12 +360,12 @@ class Ponysay():
break
'''
Apply pony name remapping to args according to UCS settings
@param args:ArgParser Parsed command line arguments
'''
def __ucsremap(self, args):
'''
Apply pony name remapping to args according to UCS settings
@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
@ -413,13 +405,13 @@ class Ponysay():
## Auxiliary methods ##
#######################
'''
Apply UCS:ise pony names according to UCS settings
@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`
'''
def __ucsise(self, ponies, links = None):
'''
Apply UCS:ise pony names according to UCS settings
@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`
'''
## Read UCS configurations
env_ucs = os.environ['PONYSAY_UCS_ME'] if 'PONYSAY_UCS_ME' in os.environ else ''
ucs_conf = 0
@ -460,18 +452,18 @@ class Ponysay():
ponies[j] = map[ponies[j]]
'''
Returns one file with full path and ponyquote that should be used, names is filter for names, also accepts filepaths
@param selection:(name:str, dirs:itr<str>, quote:bool)? Parsed command line arguments as namedirectoriesquoting tubles:
name: The pony name
dirfiles: Files, with the directory, in the pony directories
quote: Whether to use ponyquotes
@param args:ArgParser Parsed command line arguments
@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
'''
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
@param selection:(name:str, dirs:itr<str>, quote:bool)? Parsed command line arguments as namedirectoriesquoting tubles:
name: The pony name
dirfiles: Files, with the directory, in the pony directories
quote: Whether to use ponyquotes
@param args:ArgParser Parsed command line arguments
@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
'''
## If there is no selected ponies, choose all of them
if (selection is None) or (len(selection) == 0):
quote = args.opts['-q'] is not None ## TODO +q -Q
@ -570,14 +562,14 @@ class Ponysay():
return (file, self.__getquote(pony[0], file) if pony[2] else None)
'''
Select a quote for a pony
@param pony:str The pony name
@param file:str The pony's file name
@return :str A quote from the pony, with a failure fall back message
'''
def __getquote(self, pony, file):
'''
Select a quote for a pony
@param pony:str The pony name
@param file:str The pony's file name
@return :str A quote from the pony, with a failure fall back message
'''
quote = []
if (os.path.dirname(file) + os.sep).replace(os.sep + os.sep, os.sep) in self.ponydirs:
realpony = pony
@ -596,14 +588,14 @@ class Ponysay():
return quote
'''
Returns a set with all ponies that have quotes and are displayable
@param ponydirs:itr<str>? The pony directories to use
@param quotedirs:itr<str>? The quote directories to use
@return :set<str> All ponies that have quotes and are displayable
'''
def __quoters(self, ponydirs = None, quotedirs = None):
'''
Returns a set with all ponies that have quotes and are displayable
@param ponydirs:itr<str>? The pony directories to use
@param quotedirs:itr<str>? The quote directories to use
@return :set<str> All ponies that have quotes and are displayable
'''
if ponydirs is None: ponydirs = self.ponydirs
if quotedirs is None: quotedirs = self.quotedirs
@ -633,15 +625,15 @@ class Ponysay():
return ponies
'''
Returns a list with all (pony, quote file) pairs
@param ponydirs:itr<str>? The pony directories to use
@param quotedirs:itr<str>? The quote directories to use
@param ponies:itr<str>? The ponies to use
@return (pony, quote):(str, str) All poniesquote file-pairs
'''
def __quotes(self, ponydirs = None, quotedirs = None, ponies = None):
'''
Returns a list with all (pony, quote file) pairs
@param ponydirs:itr<str>? The pony directories to use
@param quotedirs:itr<str>? The quote directories to use
@param ponies:itr<str>? The ponies to use
@return (pony, quote):(str, str) All poniesquote file-pairs
'''
if ponydirs is None: ponydirs = self.ponydirs
if quotedirs is None: quotedirs = self.quotedirs
@ -678,45 +670,45 @@ class Ponysay():
## Listing methods ##
#####################
'''
Lists the available ponies
@param ponydirs:itr<str>? The pony directories to use
'''
def list(self, ponydirs = None):
'''
Lists the available ponies
@param ponydirs:itr<str>? The pony directories to use
'''
List.simplelist(self.ponydirs if ponydirs is None else ponydirs,
self.__quoters(), lambda x : self.__ucsise(x))
'''
Lists the available ponies with alternatives inside brackets
@param ponydirs:itr<str> The pony directories to use
'''
def linklist(self, ponydirs = None):
'''
Lists the available ponies with alternatives inside brackets
@param ponydirs:itr<str> The pony directories to use
'''
List.linklist(self.ponydirs if ponydirs is None else ponydirs,
self.__quoters(), lambda x, y : self.__ucsise(x, y))
'''
Lists the available ponies on one column without anything bold or otherwise formated
@param standard:bool Include standard ponies
@param extra:bool Include extra ponies
'''
def onelist(self, standard = True, extra = False):
'''
Lists the available ponies on one column without anything bold or otherwise formated
@param standard:bool Include standard ponies
@param extra:bool Include extra ponies
'''
List.onelist(self.ponydirs if standard else None,
self.extraponydirs if extra else None,
lambda x : self.__ucsise(x))
'''
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 extra:bool Include extra ponies
'''
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
@param standard:bool Include standard ponies
@param extra:bool Include extra ponies
'''
## Get all quoters
ponies = list(self.__quoters()) if standard else []
@ -742,21 +734,21 @@ class Ponysay():
## Balloon methods ##
#####################
'''
Prints a list of all balloons
'''
def balloonlist(self):
'''
Prints a list of all balloons
'''
List.balloonlist(self.balloondirs, self.isthink)
'''
Returns one file with full path, names is filter for style names, also accepts filepaths
@param names:list<str> Balloons to choose from, may be `None`
@param alt:bool For method internal use
@param :str The file name of the balloon, will be `None` iff `names` is `None`
'''
def __getballoonpath(self, names, alt = False):
'''
Returns one file with full path, names is filter for style names, also accepts filepaths
@param names:list<str> Balloons to choose from, may be `None`
@param alt:bool For method internal use
@param :str The file name of the balloon, will be `None` iff `names` is `None`
'''
## Stop if their is no choosen balloon
if names is None:
return None
@ -799,13 +791,13 @@ class Ponysay():
return balloons[balloon]
'''
Creates the balloon style object
@param balloonfile:str The file with the balloon style, may be `None`
@return :Balloon Instance describing the balloon's style
'''
def __getballoon(self, balloonfile):
'''
Creates the balloon style object
@param balloonfile:str The file with the balloon style, may be `None`
@return :Balloon Instance describing the balloon's style
'''
return Balloon.fromFile(balloonfile, self.isthink)
@ -814,20 +806,20 @@ class Ponysay():
## Displaying methods ##
########################
'''
Prints the name of the program and the version of the program
'''
def version(self):
'''
Prints the name of the program and the version of the program
'''
## Prints the "ponysay $VERSION", if this is modified, ./dev/dist.sh must be modified accordingly
print('%s %s' % ('ponysay', VERSION))
'''
Print the pony with a speech or though bubble. message, pony and wrap from args are used.
@param args:ArgParser Parsed command line arguments
'''
def print_pony(self, args):
'''
Print the pony with a speech or though bubble. message, pony and wrap from args are used.
@param args:ArgParser Parsed command line arguments
'''
## Get the pony
(selection, standard, extra) = ([], [], [])
for ponydir in self.ponydirs:

View file

@ -39,44 +39,45 @@ from ponysay import *
from metadata import *
VERSION = 'dev' # this line should not be edited, it is fixed by the build system
'''
The version of ponysay
'''
VERSION = 'dev' # this line should not be edited, it is fixed by the build system
'''
Hack to enforce UTF-8 in output (in the future, if you see anypony not using utf-8 in
programs by default, report them to Princess Celestia so she can banish them to the moon)
@param text:str The text to print (empty string is default)
@param end:str The appendix to the text to print (line breaking is default)
'''
def print(text = '', end = '\n'):
'''
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'))
'''
stderr equivalent to print()
@param text:str The text to print (empty string is default)
@param end:str The appendix to the text to print (line breaking is default)
'''
def printerr(text = '', end = '\n'):
'''
stderr equivalent to print()
@param text:str The text to print (empty string is default)
@param end:str The appendix to the text to print (line breaking is default)
'''
sys.stderr.buffer.write((str(text) + end).encode('utf-8'))
'''
This is the mane class of ponysay-tool
'''
class PonysayTool():
'''
Starts the part of the program the arguments indicate
@param args:ArgParser Parsed command line arguments
This is the mane class of ponysay-tool
'''
def __init__(self, args):
'''
Starts the part of the program the arguments indicate
@param args:ArgParser Parsed command line arguments
'''
if args.argcount == 0:
args.help()
exit(255)
@ -194,13 +195,13 @@ class PonysayTool():
exit(253)
'''
Execute ponysay!
@param args Arguments
@param message Message
'''
def execPonysay(self, args, message = ''):
'''
Execute ponysay!
@param args Arguments
@param message Message
'''
class PhonyArgParser():
def __init__(self, args, message):
self.argcount = len(args) + (0 if message is None else 1)
@ -239,13 +240,13 @@ class PonysayTool():
return out
'''
Browse ponies
@param ponydir:str The pony directory to browse
@param restriction:list<str> Restrictions on listed ponies, may be None
'''
def browse(self, ponydir, restriction):
'''
Browse ponies
@param ponydir:str The pony directory to browse
@param restriction:list<str> Restrictions on listed ponies, may be None
'''
## 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):
@ -431,10 +432,10 @@ class PonysayTool():
(x, y) = (0, 0)
'''
Generate all kmsponies for the current TTY palette
'''
def generateKMS(self):
'''
Generate all kmsponies for the current TTY palette
'''
class PhonyArgParser():
def __init__(self, key, value):
self.argcount = 3
@ -495,13 +496,13 @@ class PonysayTool():
sys.stdout = stdout
'''
Generate pony dimension file for a directory
@param ponydir:str The directory
@param ponies:itr<str>? Ponies to which to limit
'''
def generateDimensions(self, ponydir, ponies = None):
'''
Generate pony dimension file for a directory
@param ponydir:str The directory
@param ponies:itr<str>? Ponies to which to limit
'''
dimensions = []
ponyset = None if (ponies is None) or (len(ponies) == 0) else set(ponies)
for ponyfile in os.listdir(ponydir):
@ -581,13 +582,13 @@ class PonysayTool():
file.flush()
'''
Generate pony metadata collection file for a directory
@param ponydir:str The directory
@param ponies:itr<str>? Ponies to which to limit
'''
def generateMetadata(self, ponydir, ponies = None):
'''
Generate pony metadata collection file for a directory
@param ponydir:str The directory
@param ponies:itr<str>? Ponies to which to limit
'''
if not ponydir.endswith('/'):
ponydir += '/'
def makeset(value):
@ -663,12 +664,12 @@ class PonysayTool():
file.flush()
'''
Edit a pony file's metadata
@param ponyfile:str A pony file to edit
'''
def editmeta(self, ponyfile):
'''
Edit a pony file's metadata
@param ponyfile:str A pony file to edit
'''
(data, meta, image) = 3 * [None]
with open(ponyfile, 'rb') as file:
@ -838,32 +839,32 @@ class PonysayTool():
'''
GNU Emacs alike text area
'''
class TextArea(): # TODO support small screens
class TextArea(): # TODO support small screens (This is being work on in GNU-Pony/featherweight)
'''
Constructor
@param fields:list<str> Field names
@param datamap:dist<str,str> Data map
@param left:int Left position of the component
@param top:int Top position of the component
@param width:int Width of the component
@param height:int Height of the component
@param termsize:(int,int) The height and width of the terminal
GNU Emacs alike text area
'''
def __init__(self, fields, datamap, left, top, width, height, termsize):
'''
Constructor
@param fields:list<str> Field names
@param datamap:dist<str,str> Data map
@param left:int Left position of the component
@param top:int Top position of the component
@param width:int Width of the component
@param height:int Height of the component
@param termsize:(int,int) The height and width of the terminal
'''
(self.fields, self.datamap, self.left, self.top, self.width, self.height, self.termsize) \
= (fields, datamap, left, top, width - 1, height, termsize)
'''
Execute text reading
@param saver Save method
'''
def run(self, saver):
'''
Execute text reading
@param saver Save method
'''
innerleft = UCS.dispLen(max(self.fields, key = UCS.dispLen)) + self.left + 3
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
'''
HOME = os.environ['HOME'] if 'HOME' in os.environ else os.path.expanduser('~')
pipelinein = not sys.stdin.isatty()
'''
Whether stdin is piped
'''
pipelinein = not sys.stdin.isatty()
pipelineout = not sys.stdout.isatty()
'''
Whether stdout is piped
'''
pipelineout = not sys.stdout.isatty()
pipelineerr = not sys.stderr.isatty()
'''
Whether stderr is piped
'''
pipelineerr = not sys.stderr.isatty()
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-stash'], arg = 'PONY-FILE', help = 'Print applyable metadata from a pony file')
unrecognised = not opts.parse()
'''
Whether at least one unrecognised option was used
'''
unrecognised = not opts.parse()
PonysayTool(args = opts)

View file

@ -33,24 +33,25 @@ from common import *
'''
Class used for correcting spellos and typos,
Note that this implementation will not find that correctly spelled word are correct faster than it corrects words.
It is also limited to words of size 0 to 127 (inclusive)
'''
class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimised Java, may not be the nicest, or even fast, Python code
'''
Constructor
Class used for correcting spellos and typos,
@param directories:list<str> List of directories that contains the file names with the correct spelling
@param ending:str The file name ending of the correctly spelled file names, this is removed for the name
-- OR -- (emulated overloading [overloading is absent in Python])
@param directories:list<str> The file names with the correct spelling
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)
'''
def __init__(self, directories, ending = None):
'''
Constructor
@param directories:list<str> List of directories that contains the file names with the correct spelling
@param ending:str The file name ending of the correctly spelled file names, this is removed for the name
-- OR -- (emulated overloading [overloading is absent in Python])
@param directories:list<str> The file names with the correct spelling
'''
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},
's' : {'z' : 0.25, 'c' : 0.5},
@ -145,13 +146,13 @@ class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimise
# index -= 1;
'''
Finds the closests correct spelled word
@param used:str The word to correct
@return (words, distance):(list<string>, int) A list the closest spellings and the weighted distance
'''
def correct(self, used):
'''
Finds the closests correct spelled word
@param used:str The word to correct
@return (words, distance):(list<string>, int) A list the closest spellings and the weighted distance
'''
if len(used) > 127:
return ([used], 0)
@ -159,12 +160,12 @@ class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimise
return (self.corrections, self.closestDistance)
'''
Finds the closests correct spelled word
@param used:str The word to correct, it must satisfy all restrictions
'''
def __correct(self, used):
'''
Finds the closests correct spelled word
@param used:str The word to correct, it must satisfy all restrictions
'''
self.closestDistance = 0x7FFFFFFF
previous = self.dictionary[-1]
prevLen = 0
@ -217,18 +218,18 @@ class SpelloCorrecter(): # Naïvely and quickly ported and adapted from optimise
prevLen = len(proper)
'''
Calculate the distance between a correct word and a incorrect word
@param proper:str The correct word
@param y0:int The offset for `proper`
@param yn:int The length, before applying `y0`, of `proper`
@param used:str The incorrect word
@param x0:int The offset for `used`
@param xn:int The length, before applying `x0`, of `used`
@return :float The distance between the words
'''
def __distance(self, proper, y0, yn, used, x0, xn):
'''
Calculate the distance between a correct word and a incorrect word
@param proper:str The correct word
@param y0:int The offset for `proper`
@param yn:int The length, before applying `y0`, of `proper`
@param used:str The incorrect word
@param x0:int The offset for `used`
@param xn:int The length, before applying `x0`, of `used`
@return :float The distance between the words
'''
my = self.M[y0]
for y in range(y0, yn):
best = 0x7FFFFFFF

View file

@ -33,18 +33,19 @@ from common import *
'''
UCS utility class
'''
class UCS():
'''
Checks whether a character is a combining character
@param char:chr The character to test
@return :bool Whether the character is a combining character
UCS utility class
'''
@staticmethod
def isCombining(char):
'''
Checks whether a character is a combining character
@param char:chr The character to test
@return :bool Whether the character is a combining character
'''
o = ord(char)
if (0x0300 <= o) and (o <= 0x036F): return True
if (0x20D0 <= o) and (o <= 0x20FF): return True
@ -53,14 +54,14 @@ class UCS():
return False
'''
Gets the number of combining characters in a string
@param string:str A text to count combining characters in
@return :int The number of combining characters in the string
'''
@staticmethod
def countCombining(string):
'''
Gets the number of combining characters in a string
@param string:str A text to count combining characters in
@return :int The number of combining characters in the string
'''
rc = 0
for char in string:
if UCS.isCombining(char):
@ -68,13 +69,13 @@ class UCS():
return rc
'''
Gets length of a string not counting combining characters
@param string:str The text of which to determine the monospaced width
@return The determine the monospaced width of the text, provided it does not have escape sequnces
'''
@staticmethod
def dispLen(string):
'''
Gets length of a string not counting combining characters
@param string:str The text of which to determine the monospaced width
@return The determine the monospaced width of the text, provided it does not have escape sequnces
'''
return len(string) - UCS.countCombining(string)