From 99ddfe9cd38bdfd6ba9f66d69dbf92cbb0afb627 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Tue, 21 Aug 2012 03:51:34 +0200
Subject: separate colouring for pony, balloon and link

---
 ponysay | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 58 insertions(+), 9 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index 3a4efa3..a843572 100755
--- a/ponysay
+++ b/ponysay
@@ -1092,27 +1092,76 @@ class ColourStack():
         self.bufproto = ' ' * (self.lenpush if self.lenpush > self.lenpop else self.lenpop)
         self.stack = []
         self.push()
+        self.seq = None
     
     
     def push(self):
-        self.stack = [[self.bufproto]] + self.stack
+        self.stack = [[self.bufproto, None, None, [False] * 9]] + self.stack
         if len(self.stack) == 1:
-            return ''
-        return ''
+            return None
+        old = self.stack[1]
+        rc = '\033['
+        if old[1] is not None:  rc += '39;'
+        if old[2] is not None:  rc += '49;'
+        for i in range(0, 9):
+            if old[3][i]:
+                rc += '2%i;' % (i + 1)
+        return '' if len(rc) == 2 else (rc[:-1] + 'm')
     
     
     def pop(self):
-        return ''
+        old = self.stack[0]
+        self.stack = self.stack[1:]
+        rc = '\033['
+        if old[1] is not None:  rc += '39;'
+        if old[2] is not None:  rc += '49;'
+        for i in range(0, 9):
+            if old[3][i]:
+                rc += str(i + 21) + ';'
+        new = self.stack[0]
+        if new[1] is not None:  rc += new[1] + ';'
+        if new[2] is not None:  rc += new[2] + ';'
+        for i in range(0, 9):
+            if new[3][i]:
+                rc += str(i + 1) + ';'
+        return '' if len(rc) == 2 else (rc[:-1] + 'm')
     
     
     def feed(self, char):
+        if self.seq is not None:
+            self.seq += char
+            if (char == '~') or (('a' <= char) and (char <= 'z')) or (('A' <= char) and (char <= 'Z')):
+                if (self.seq[0] == '[') and (self.seq[-1] == 'm'):
+                    self.seq = self.seq[1:-1].split(';')
+                    (i, n) = (0, len(self.seq))
+                    while i < n:
+                        part = self.seq[i]
+                        p = 0 if part == '' else int(part)
+                        i += 1
+                        if p == '':                      self.stack[0][1:] = [None, None, [False] * 9]
+                        elif (1 <= p) and (p <= 9):      self.stack[0][3][p - 1] = True
+                        elif (21 <= p) and (p <= 29):    self.stack[0][3][p - 21] = False
+                        elif p == 39:                    self.stack[0][1] = None
+                        elif p == 40:                    self.stack[0][2] = None
+                        elif (30 <= p) and (p <= 37):    self.stack[0][1] = part
+                        elif (90 <= p) and (p <= 97):    self.stack[0][1] = part
+                        elif (40 <= p) and (p <= 47):    self.stack[0][2] = part
+                        elif (100 <= p) and (p <= 107):  self.stack[0][2] = part
+                        elif p == 38:
+                            self.stack[0][1] = '%s;%s;%s' % (part, self.seq[i], self.seq[i + 1])
+                            i += 2
+                        elif p == 48:
+                            self.stack[0][2] = '%s;%s;%s' % (part, self.seq[i], self.seq[i + 1])
+                            i += 2
+                self.seq = None
+        elif char == '\033':
+            self.seq = ''
         buf = self.stack[0][0]
+        buf = buf[1:] + char
         rc = ''
-        if buf[:-self.lenpush] == self.autopush:
-            rc = self.push()
-        elif buf[:-self.lenpop] == self.autopop:
-            rc = self.pop()
-        self.stack[0][0] = buf[1:] + char
+        if buf[-self.lenpush:] == self.autopush:  rc = self.push()
+        elif buf[-self.lenpop:] == self.autopop:  rc = self.pop()
+        self.stack[0][0] = buf
         return rc
 
 
-- 
cgit 


From 6088f793691f22c5308e9435f91a12c4c3869f7e Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Tue, 21 Aug 2012 04:45:05 +0200
Subject: never wrap less than 8

---
 ponysay | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index a843572..1f99579 100755
--- a/ponysay
+++ b/ponysay
@@ -958,6 +958,8 @@ class Backend():
         wrap = None
         if self.wrapcolumn is not None:
             wrap = self.wrapcolumn - left
+            if wrap < 8:
+                wrap = 8
         
         msg = self.message
         if wrap is not None:
-- 
cgit 


From 16763d07d3296afb651adc524ded365dc3efa005 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Tue, 21 Aug 2012 14:36:01 +0200
Subject: balloon class used for balloon style customisation

---
 ponysay | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 52 insertions(+), 13 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index 1f99579..a5b6030 100755
--- a/ponysay
+++ b/ponysay
@@ -683,6 +683,51 @@ class ArgParser():
 
 
 
+'''
+Balloon format class
+'''
+class Balloon():
+    '''
+    Constructor
+    '''
+    def __init__(self, link, linkmirror, ww, ee, nw, nnw, n, nne, ne, nee, e, see, se, sse, s, ssw, sw, sww, w, nww):
+        (self.link, self.linkmirror) = (link, linkmirror)
+        (self.ww, self.ee) = (ww, ee)
+        (self.nw, self.ne, self.se, self.sw) = (nw, ne, se, sw)
+        (self.nnw, self.n, self.nne) = (nnw, n, nne)
+        (self.nee, self.e, self.see) = (nee, e, see)
+        (self.sse, self.s, self.ssw) = (sse, s, ssw)
+        (self.sww, self.w, self.nww) = (sww, w, nww)
+        
+        minE = len(max([ne, nee, e, see, se, ee], key = len))
+        minW = len(max([nw, nww, e, sww, sw, ww], key = len))
+        minN = len(max([ne, nne, n, nnw, nw], key = len))
+        minS = len(max([se, sse, s, ssw, sw], key = len))
+        
+        self.minwidth = minE + minE
+        self.minheight = minN + minS
+    
+    
+    '''
+    Generates a balloon with a message
+    '''
+    def get(self, minw, minh, lines, lencalc):
+        h = 4 + lencalc(lines)
+        w = 6 + lencalc(max(lines, key = lencalc))
+        if w < minw:  w = minw
+        if h < minh:  h = minh
+        
+        rc = '/' + '-' * (w - 2) + '\\\n'
+        rc += '|' + ' ' * (w - 2) + '|\n'
+        for line in lines:
+            rc += '|  ' + line + ' ' * (w - lencalc(line) - 6) + '  |\n'
+        rc += '|' + ' ' * (w - 2) + '|\n'
+        rc += '\\' + '-' * (w - 2) + '/'
+        
+        return rc
+
+
+
 '''
 Replacement for cowsay
 '''
@@ -697,7 +742,12 @@ class Backend():
         self.wrapcolumn = wrapcolumn
         self.width = width
         
-        self.link = {'\\' : '\\', '/' : '/'} if not isthink else {'\\' : 'o', '/' : 'o'}
+        if isthink:
+            self.balloon = Balloon('o', 'o', '( ', ' )', [' _'], ['_'], ['_'], ['_'], ['_ '], ' )', ' )', ' )', ['- '], ['-'], ['-'], ['-'], ['- '], '( ', '( ', '( ')
+        else:
+            self.balloon = Balloon('\\', '/', '< ', ' >', [' _'], ['_'], ['_'], ['_'], ['_ '], ' \\', ' |', ' //', ['- '], ['-'], ['-'], ['-'], ['- '], '\\ ', '| ', '/ ')
+        
+        self.link = {'\\' : self.balloon.link, '/' : self.balloon.linkmirror}
         
         self.output = ''
         self.pony = None
@@ -965,19 +1015,8 @@ class Backend():
         if wrap is not None:
             msg = self.__wrapMessage(msg, wrap)
         lines = msg.split('\n')
-        h = 4 + len(lines)
-        w = 6 + len(max(lines, key = len))
-        if w < width:   w = width
-        if h < height:  h = height
         
-        rc = '/' + '-' * (w - 2) + '\\\n'
-        rc += '|' + ' ' * (w - 2) + '|\n'
-        for line in lines:
-            rc += '|  ' + line + ' ' * (w - len(line) - 6) + '  |\n'
-        rc += '|' + ' ' * (w - 2) + '|\n'
-        rc += '\\' + '-' * (w - 2) + '/'
-        
-        return rc
+        return self.balloon.get(width, height, lines, self.__len)
     
     
     '''
-- 
cgit 


From 3f137a105514d1ae12374d0b4475438c31b21983 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Tue, 21 Aug 2012 14:55:09 +0200
Subject: balloons are customisable (but there is not yet a way to do that)

---
 ponysay | 43 ++++++++++++++++++++++++++++++-------------
 1 file changed, 30 insertions(+), 13 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index a5b6030..b1fbd27 100755
--- a/ponysay
+++ b/ponysay
@@ -699,8 +699,13 @@ class Balloon():
         (self.sse, self.s, self.ssw) = (sse, s, ssw)
         (self.sww, self.w, self.nww) = (sww, w, nww)
         
-        minE = len(max([ne, nee, e, see, se, ee], key = len))
-        minW = len(max([nw, nww, e, sww, sw, ww], key = len))
+        _ne = max(ne, key = len)
+        _nw = max(nw, key = len)
+        _se = max(se, key = len)
+        _sw = max(sw, key = len)
+        
+        minE = len(max([_ne, nee, e, see, _se, ee], key = len))
+        minW = len(max([_nw, nww, e, sww, _sw, ww], key = len))
         minN = len(max([ne, nne, n, nnw, nw], key = len))
         minS = len(max([se, sse, s, ssw, sw], key = len))
         
@@ -712,19 +717,31 @@ class Balloon():
     Generates a balloon with a message
     '''
     def get(self, minw, minh, lines, lencalc):
-        h = 4 + lencalc(lines)
-        w = 6 + lencalc(max(lines, key = lencalc))
+        h = self.minheight + len(lines)
+        w = self.minwidth + lencalc(max(lines, key = lencalc))
         if w < minw:  w = minw
         if h < minh:  h = minh
         
-        rc = '/' + '-' * (w - 2) + '\\\n'
-        rc += '|' + ' ' * (w - 2) + '|\n'
-        for line in lines:
-            rc += '|  ' + line + ' ' * (w - lencalc(line) - 6) + '  |\n'
-        rc += '|' + ' ' * (w - 2) + '|\n'
-        rc += '\\' + '-' * (w - 2) + '/'
+        rc = []
         
-        return rc
+        for j in range(0, len(self.n)):
+            rc.append(self.nw[j] + self.n[j] * (w - len(self.nw[j]) - len(self.ne[j])) + self.ne[j])
+    
+        if len(lines) > 1:
+            (ws, es) = ({0 : self.nww, len(lines) - 1 : self.sww}, {0 : self.nee, len(lines) - 1 : self.see})
+            for j in range(1, len(lines) - 1):
+                ws[j] = self.w
+                es[j] = self.e
+        else:
+            (ws, es) = ({0 : self.ww}, {0 : self.ee})
+        
+        for j in range(0, len(lines)):
+            rc.append(ws[j] + lines[j] + ' ' * (w - lencalc(lines[j]) - len(self.w) - len(self.e)) + es[j])
+        
+        for j in range(0, len(self.s)):
+            rc.append(self.sw[j] + self.s[j] * (w - len(self.sw[j]) - len(self.se[j])) + self.se[j])
+        
+        return '\n'.join(rc)
 
 
 
@@ -743,9 +760,9 @@ class Backend():
         self.width = width
         
         if isthink:
-            self.balloon = Balloon('o', 'o', '( ', ' )', [' _'], ['_'], ['_'], ['_'], ['_ '], ' )', ' )', ' )', ['- '], ['-'], ['-'], ['-'], ['- '], '( ', '( ', '( ')
+            self.balloon = Balloon('o', 'o', '( ', ' )', [' _'], ['_'], ['_'], ['_'], ['_ '], ' )', ' )', ' )', ['- '], ['-'], ['-'], ['-'], [' -'], '( ', '( ', '( ')
         else:
-            self.balloon = Balloon('\\', '/', '< ', ' >', [' _'], ['_'], ['_'], ['_'], ['_ '], ' \\', ' |', ' //', ['- '], ['-'], ['-'], ['-'], ['- '], '\\ ', '| ', '/ ')
+            self.balloon = Balloon('\\', '/', '< ', ' >', [' _'], ['_'], ['_'], ['_'], ['_ '], ' \\', ' |', ' /', ['- '], ['-'], ['-'], ['-'], [' -'], '\\ ', '| ', '/ ')
         
         self.link = {'\\' : self.balloon.link, '/' : self.balloon.linkmirror}
         
-- 
cgit 


From ef624440a8acbbbdb8ec33612aba36619b636140 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Tue, 21 Aug 2012 15:03:34 +0200
Subject: improved balloon customisation

---
 ponysay | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index b1fbd27..a29a8e7 100755
--- a/ponysay
+++ b/ponysay
@@ -722,11 +722,6 @@ class Balloon():
         if w < minw:  w = minw
         if h < minh:  h = minh
         
-        rc = []
-        
-        for j in range(0, len(self.n)):
-            rc.append(self.nw[j] + self.n[j] * (w - len(self.nw[j]) - len(self.ne[j])) + self.ne[j])
-    
         if len(lines) > 1:
             (ws, es) = ({0 : self.nww, len(lines) - 1 : self.sww}, {0 : self.nee, len(lines) - 1 : self.see})
             for j in range(1, len(lines) - 1):
@@ -735,11 +730,26 @@ class Balloon():
         else:
             (ws, es) = ({0 : self.ww}, {0 : self.ee})
         
+        rc = []
+        
+        for j in range(0, len(self.n)):
+            outer = len(self.nw[j]) + len(self.ne[j])
+            inner = len(self.nnw[j]) + len(self.nne[j])
+            if outer + inner >= w:
+                rc.append(self.nw[j] + self.nnw[j] + self.n[j] * (w - outer - inner) + self.nne[j] + self.ne[j])
+            else:
+                rc.append(self.nw[j] + self.n[j] * (w - outer) + self.ne[j])
+        
         for j in range(0, len(lines)):
             rc.append(ws[j] + lines[j] + ' ' * (w - lencalc(lines[j]) - len(self.w) - len(self.e)) + es[j])
         
         for j in range(0, len(self.s)):
-            rc.append(self.sw[j] + self.s[j] * (w - len(self.sw[j]) - len(self.se[j])) + self.se[j])
+            outer = len(self.sw[j]) + len(self.se[j])
+            inner = len(self.ssw[j]) + len(self.sse[j])
+            if outer + inner >= w:
+                rc.append(self.sw[j] + self.ssw[j] + self.s[j] * (w - outer - inner) + self.sse[j] + self.se[j])
+            else:
+                rc.append(self.sw[j] + self.s[j] * (w - outer) + self.se[j])
         
         return '\n'.join(rc)
 
-- 
cgit 


From a033501244ae238055f309d0edc3769ee6cbbf14 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Tue, 21 Aug 2012 15:57:48 +0200
Subject: balloon style parsing

---
 ponysay | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 51 insertions(+), 13 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index a29a8e7..708e34d 100755
--- a/ponysay
+++ b/ponysay
@@ -283,6 +283,48 @@ class Ponysay():
                 print(pony)
     
     
+    
+    ##
+    ## Balloon methods
+    ##
+    
+    '''
+    Creates the balloon style object
+    '''
+    def __getballoon(self, balloonfile):
+        if balloonfile is None:
+            if isthink:
+                return Balloon('o', 'o', '( ', ' )', [' _'], ['_'], ['_'], ['_'], ['_ '], ' )', ' )', ' )', ['- '], ['-'], ['-'], ['-'], [' -'], '( ', '( ', '( ')
+            return Balloon('\\', '/', '< ', ' >', [' _'], ['_'], ['_'], ['_'], ['_ '], ' \\', ' |', ' /', ['- '], ['-'], ['-'], ['-'], [' -'], '\\ ', '| ', '/ ')
+        
+        map = {}
+        for elem in ('\\', '/', 'ww', 'ee', 'nw', 'nnw', 'n', 'nne', 'ne', 'nee', 'e', 'see', 'se', 'sse', 's', 'ssw', 'sw', 'sww', 'w', 'nww'):
+            map[elem] = []
+        
+        balloonstream = None
+        try:
+            balloonstream = open(balloonfile, 'r')
+            data = [line.replace('\n', '') for line in balloonstream.readlines()]
+        finally:
+            if balloonstream is not None:
+                balloonstream.close()
+        
+        last = None
+        for line in data:
+            if len(line) > 0:
+                if line[0] == ':':
+                    map[last].append(line[1:])
+                else:
+                    last = line[:line.index(':')]
+                    value = line[len(last) + 1:]
+                    map[last].append(value)
+        
+        return Balloon(map['\\'][0], map['/'][0], map['ww'][0], map['ee'][0], map['nw'], map['nnw'], map['n'],
+                       map['nne'], map['ne'], map['nee'][0], map['e'][0], map['see'][0], map['se'], map['sse'],
+                       map['s'], map['ssw'], map['sw'], map['sww'][0], map['w'][0], map['nww'][0])
+    
+    
+    
     ##
     ## Displaying methods
     ##
@@ -323,7 +365,7 @@ class Ponysay():
         widthtruncation = self.__gettermsize()[1] if env_width not in ('yes', 'y', '1') else None
         messagewrap = int(args.opts['-W'][0]) if args.opts['-W'] is not None else None
         
-        backend = Backend(message = msg, ponyfile = pony, wrapcolumn = messagewrap if messagewrap is not None else 40, width = widthtruncation)
+        backend = Backend(message = msg, ponyfile = pony, wrapcolumn = messagewrap if messagewrap is not None else 40, width = widthtruncation, balloon = self.__getballoon(None))
         backend.parse()
         output = backend.output
         if (len(output) > 0) and (output[-1] == '\n'):
@@ -649,7 +691,7 @@ class ArgParser():
             if first:
                 first = False
             else:
-                print('    or', end="")
+                print('    or', end='')
             print('\t%s' % (line))
         print()
         
@@ -761,18 +803,14 @@ Replacement for cowsay
 class Backend():
     '''
     Constructor
-    Takes message [string], ponyfile [filename string], wrapcolumn [None or an int] and width [None or an int]
+    Takes message [string], ponyfile [filename string], wrapcolumn [None or an int], width [None or an int] and balloon [Balloon object]
     '''
-    def __init__(self, message, ponyfile, wrapcolumn, width):
+    def __init__(self, message, ponyfile, wrapcolumn, width, balloon):
         self.message = message
         self.ponyfile = ponyfile
         self.wrapcolumn = wrapcolumn
         self.width = width
-        
-        if isthink:
-            self.balloon = Balloon('o', 'o', '( ', ' )', [' _'], ['_'], ['_'], ['_'], ['_ '], ' )', ' )', ' )', ['- '], ['-'], ['-'], ['-'], [' -'], '( ', '( ', '( ')
-        else:
-            self.balloon = Balloon('\\', '/', '< ', ' >', [' _'], ['_'], ['_'], ['_'], ['_ '], ' \\', ' |', ' /', ['- '], ['-'], ['-'], ['-'], [' -'], '\\ ', '| ', '/ ')
+        self.balloon = balloon
         
         self.link = {'\\' : self.balloon.link, '/' : self.balloon.linkmirror}
         
@@ -955,7 +993,7 @@ class Backend():
                     datalen = self.__len(data)
                     skip += datalen
                     nonskip += datalen
-                    data = data.replace("$", '$$')
+                    data = data.replace('$', '$$')
                     n += len(data)
                     self.pony = self.pony[:i] + data + self.pony[i:]
                     balloonLines[balloonLine] = None
@@ -1325,9 +1363,9 @@ opts.add_argumentless(['-h', '--help'],                      help = 'Print this
 opts.add_argumentless(['-v', '--version'],                   help = 'Print the version of the program.')
 opts.add_argumentless(['-l', '--list'],                      help = 'List pony files.')
 opts.add_argumentless(['-L', '--altlist'],                   help = 'List pony files with alternatives.')
-opts.add_argumented(  ['-W', '--wrap'],     arg = "COLUMN",  help = 'Specify the column when the message should be wrapped.')
-opts.add_argumented(  ['-f', '--pony'],     arg = "PONY",    help = 'Select a pony.\nEither a file name or a pony name.')
-opts.add_variadic(    ['-q', '--quote'],    arg = "PONY",    help = 'Select a ponies which will quote themself.')
+opts.add_argumented(  ['-W', '--wrap'],     arg = 'COLUMN',  help = 'Specify the column when the message should be wrapped.')
+opts.add_argumented(  ['-f', '--pony'],     arg = 'PONY',    help = 'Select a pony.\nEither a file name or a pony name.')
+opts.add_variadic(    ['-q', '--quote'],    arg = 'PONY',    help = 'Select a ponies which will quote themself.')
 
 opts.parse()
 
-- 
cgit 


From 504a6bd5f5a13d19fee54fcbec537bdab983e2ba Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Tue, 21 Aug 2012 16:20:29 +0200
Subject: balloon stuff + pony names supersedes file names

---
 ponysay | 41 +++++++++++++++++++++++++++++++++++------
 1 file changed, 35 insertions(+), 6 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index 708e34d..36b4ca3 100755
--- a/ponysay
+++ b/ponysay
@@ -70,17 +70,17 @@ class Ponysay():
     def __getponypath(self, names = None):
         ponies = {}
         
-        if not names == None:
-            for name in names:
-                if os.path.isfile(name):
-                    ponies[name] = name
-        
         for ponydir in ponydirs:
             for ponyfile in os.listdir(ponydir):
                 pony = ponyfile[:-5]
                 if pony not in ponies:
                     ponies[pony] = ponydir + ponyfile
         
+        if not names == None:
+            for name in names:
+                if os.path.isfile(name):
+                    ponies[name] = name
+        
         if names == None:
             names = list(ponies.keys())
         
@@ -288,6 +288,35 @@ class Ponysay():
     ## Balloon methods
     ##
     
+    '''
+    Returns one file with full path, names is filter for names, also accepts filepaths
+    '''
+    def __getballoonpath(self, names):
+        if names is None:
+            return None
+        balloons = {}
+        
+        for balloondir in balloondirs:
+            for balloonfile in os.listdir(balloondir):
+                balloon = balloonfile[:-5]
+                if balloon not in balloons:
+                    balloons[balloon] = balloondir + balloonfile
+        
+        for name in names:
+            if os.path.isfile(name):
+                balloons[name] = name
+        
+        if names == None:
+            names = list(balloons.keys())
+        
+        balloon = names[random.randrange(0, len(names))]
+        if balloon not in balloons:
+            sys.stderr.write('That balloon style %s does not exist\n' % (balloon));
+            exit(1)
+        else:
+            return balloons[balloon]
+    
+    
     '''
     Creates the balloon style object
     '''
@@ -1299,7 +1328,7 @@ pipelinein = not sys.stdin.isatty()
 '''
 Whether stdout is piped
 '''
-pipelineout = False #not sys.stdout.isatty()  # currently impossible, we need to get rid of the little shell script first
+pipelineout = not sys.stdout.isatty()
 
 '''
 Whether stderr is piped
-- 
cgit 


From b66b3b5bfc842b1224c5b6bcd2f0c6737f2f0f8b Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Tue, 21 Aug 2012 16:21:35 +0200
Subject: in case you want to run `ponysay -l | less -r`

---
 ponysay | 4 ----
 1 file changed, 4 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index 36b4ca3..a329fd5 100755
--- a/ponysay
+++ b/ponysay
@@ -46,10 +46,6 @@ class Ponysay():
             args.help()
             return
         
-        if (args.opts['-l'] is not None) and pipelineout:
-            args.opts['--onelist'] = args.opts['-l']
-            args.opts['-l'] = None
-        
         if   args.opts['-h']        is not None:  args.help()
         elif args.opts['--quoters'] is not None:  self.quoters()
         elif args.opts['--onelist'] is not None:  self.onelist()
-- 
cgit 


From 66cbb352ebc7717f9bbd816b6e76bdcc347fdcb7 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Tue, 21 Aug 2012 17:26:21 +0200
Subject: balloon styles: -b and -B options are implemented

---
 ponysay | 129 ++++++++++++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 98 insertions(+), 31 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index a329fd5..fedaab6 100755
--- a/ponysay
+++ b/ponysay
@@ -52,6 +52,7 @@ class Ponysay():
         elif args.opts['-v']        is not None:  self.version()
         elif args.opts['-l']        is not None:  self.list()
         elif args.opts['-L']        is not None:  self.linklist()
+        elif args.opts['-B']        is not None:  self.balloonlist()
         elif args.opts['-q']        is not None:  self.quote(args)
         else:                                     self.print_pony(args)
     
@@ -61,7 +62,7 @@ class Ponysay():
     ##
     
     '''
-    Returns one file with full path, names is filter for names, also accepts filepaths.
+    Returns one file with full path, names is filter for names, also accepts filepaths
     '''
     def __getponypath(self, names = None):
         ponies = {}
@@ -160,10 +161,13 @@ class Ponysay():
         quoters = self.__quoters()
         
         for ponydir in ponydirs: # Loop ponydirs
-            print('\033[1mponyfiles located in ' + ponydir + '\033[21m')
+            print('\033[1mponies located in ' + ponydir + '\033[21m')
             
-            ponies = os.listdir(ponydir)
-            ponies = [item[:-5] for item in ponies] # remove .pony from file name
+            _ponies = os.listdir(ponydir)
+            ponies = []
+            for pony in _ponies:
+                if (len(pony) > 5) and (pony[-5:] == '.pony'):
+                    ponies.append(pony[:-5])
             ponies.sort()
             
             width = len(max(ponies, key = len)) + 2 # Get the longest ponyfilename lenght + 2 spaces
@@ -176,7 +180,7 @@ class Ponysay():
                 if x > (termsize[1] - width): # If too wide, make new line
                     print()
                     x = 0
-                    
+            
             print('\n');
     
     
@@ -188,12 +192,15 @@ class Ponysay():
         quoters = self.__quoters()
         
         for ponydir in ponydirs: # Loop ponydirs
-            print('\033[1mponyfiles located in ' + ponydir + '\033[21m')
+            print('\033[1mponies located in ' + ponydir + '\033[21m')
             
-            files = os.listdir(ponydir)
-            files = [item[:-5] for item in files] # remove .pony from file name
-            files.sort()
-            pairs = [(item, os.readlink(ponydir + item + '.pony') if os.path.islink(ponydir + item + '.pony') else '') for item in files]
+            _ponies = os.listdir(ponydir)
+            ponies = []
+            for pony in _ponies:
+                if (len(pony) > 5) and (pony[-5:] == '.pony'):
+                    ponies.append(pony[:-5])
+            ponies.sort()
+            pairs = [(pony, os.readlink(ponydir + pony + '.pony') if os.path.islink(ponydir + pony + '.pony') else '') for pony in ponies]
             
             ponymap = {}
             for pair in pairs:
@@ -239,7 +246,7 @@ class Ponysay():
             for pony in ponies:
                 spacing = ' ' * (width - widths[index])
                 index += 1
-                print(pony + spacing, end='') # Print ponyfilename
+                print(pony + spacing, end='') # Print pony file name
                 x += width
                 if x > (termsize[1] - width): # If too wide, make new line
                     print()
@@ -268,10 +275,13 @@ class Ponysay():
     '''
     def onelist(self):
         last = ''
-        ponies = []
+        _ponies = []
         for ponydir in ponydirs: # Loop ponydirs
-            ponies += os.listdir(ponydir)
-        ponies = [item[:-5] for item in ponies] # remove .pony from file name
+            _ponies += os.listdir(ponydir)
+        ponies = []
+        for pony in _ponies:
+            if (len(pony) > 5) and (pony[-5:] == '.pony'):
+                ponies.append(pony[:-5])
         ponies.sort()
         for pony in ponies:
             if not pony == last:
@@ -285,7 +295,42 @@ class Ponysay():
     ##
     
     '''
-    Returns one file with full path, names is filter for names, also accepts filepaths
+    Prints a list of all balloons
+    '''
+    def balloonlist(self):
+        termsize = self.__gettermsize()
+        balloonset = set()
+        
+        for balloondir in balloondirs:
+            for balloon in os.listdir(balloondir):
+                if isthink and (len(balloon) > 6) and (balloon[-6:] == '.think'):
+                    balloon = balloon[:-6]
+                elif (not isthink) and (len(balloon) > 4) and (balloon[-4:] == '.say'):
+                    balloon = balloon[:-4]
+                else:
+                    continue
+                if balloon not in balloonset:
+                    balloonset.add(balloon)
+        
+        balloons = list(balloonset)
+        balloons.sort()
+        
+        width = len(max(balloons, key = len)) + 2
+        
+        x = 0
+        for balloon in balloons:
+            spacing = ' ' * (width - len(balloon))
+            print(balloon + spacing, end='')
+            x += width
+            if x > (termsize[1] - width):
+                print()
+                x = 0
+        
+        print();
+    
+    
+    '''
+    Returns one file with full path, names is filter for style names, also accepts filepaths
     '''
     def __getballoonpath(self, names):
         if names is None:
@@ -293,8 +338,14 @@ class Ponysay():
         balloons = {}
         
         for balloondir in balloondirs:
-            for balloonfile in os.listdir(balloondir):
-                balloon = balloonfile[:-5]
+            for balloon in os.listdir(balloondir):
+                balloonfile = balloon
+                if isthink and (len(balloon) > 6) and (balloon[-6:] == '.think'):
+                    balloon = balloon[:-6]
+                elif (not isthink) and (len(balloon) > 4) and (balloon[-4:] == '.say'):
+                    balloon = balloon[:-4]
+                else:
+                    continue
                 if balloon not in balloons:
                     balloons[balloon] = balloondir + balloonfile
         
@@ -390,7 +441,9 @@ class Ponysay():
         widthtruncation = self.__gettermsize()[1] if env_width not in ('yes', 'y', '1') else None
         messagewrap = int(args.opts['-W'][0]) if args.opts['-W'] is not None else None
         
-        backend = Backend(message = msg, ponyfile = pony, wrapcolumn = messagewrap if messagewrap is not None else 40, width = widthtruncation, balloon = self.__getballoon(None))
+        balloon = self.__getballoon(self.__getballoonpath(args.opts['-b']))
+        
+        backend = Backend(message = msg, ponyfile = pony, wrapcolumn = messagewrap if messagewrap is not None else 40, width = widthtruncation, balloon = balloon)
         backend.parse()
         output = backend.output
         if (len(output) > 0) and (output[-1] == '\n'):
@@ -1269,7 +1322,7 @@ class ColourStack():
                         part = self.seq[i]
                         p = 0 if part == '' else int(part)
                         i += 1
-                        if p == '':                      self.stack[0][1:] = [None, None, [False] * 9]
+                        if p == 0:                       self.stack[0][1:] = [None, None, [False] * 9]
                         elif (1 <= p) and (p <= 9):      self.stack[0][3][p - 1] = True
                         elif (21 <= p) and (p <= 29):    self.stack[0][3][p - 21] = False
                         elif p == 39:                    self.stack[0][1] = None
@@ -1313,7 +1366,8 @@ linuxvt = os.environ['TERM'] == 'linux'
 '''
 Whether the script is executed as ponythink
 '''
-isthink = (len(__file__) >= 8) and (__file__[-8:] == 'think.py')
+isthink =  (len(__file__) >= 5) and (__file__[-5:] == 'think')
+isthink = ((len(__file__) >= 8) and (__file__[-8:] == 'think.py')) or isthink
 
 
 '''
@@ -1354,15 +1408,26 @@ for quotedir in _quotedirs:
         quotedirs.append(quotedir)
 
 
+'''
+The directories where balloon style files are stored
+'''
+balloondirs = []
+_balloondirs = [HOME + '/.local/share/ponysay/balloons/',  INSTALLDIR + '/share/ponysay/balloons/']
+for balloondir in _balloondirs:
+    if os.path.isdir(balloondir):
+        balloondirs.append(balloondir)
+
+
 usage_saythink = '\033[34;1m(ponysay | ponythink)\033[21;39m'
 usage_wrap     = '--wrap \033[4mCOLUMN\033[24m'
-usage_listhelp = '(--list | ---altlist | --version | --help)'
+usage_balloon  = '--balloon \033[4mSTYLE\033[24m'
+usage_listhelp = '(--list | --altlist | --balloonlist | --version | --help)'
 usage_file     = '[--pony \033[4mPONY\033[24m]... ([--] \033[4mmessage\033[24m | <<<\033[4mmessage\033[24m)'
 usage_quote    = '--quote [\033[4mPONY\033[24m...]'
 
-usage = '%s %s\n%s [%s] %s\n%s [%s] %s' % (usage_saythink, usage_listhelp,
-                                           usage_saythink, usage_wrap, usage_file,
-                                           usage_saythink, usage_wrap, usage_quote)
+usage = '%s %s\n%s [%s] [%s] %s\n%s [%s] [%s] %s' % (usage_saythink, usage_listhelp,
+                                                     usage_saythink, usage_wrap, usage_balloon, usage_file,
+                                                     usage_saythink, usage_wrap, usage_balloon, usage_quote)
 
 usage = usage.replace('\033[', '\0')
 for sym in ('[', ']', '(', ')', '|', '...'):
@@ -1384,13 +1449,15 @@ run `man ponysay`. Ponysay has so much more to offer than described here.''')
 opts.add_argumentless(['--quoters'])
 opts.add_argumentless(['--onelist'])
 
-opts.add_argumentless(['-h', '--help'],                      help = 'Print this help message.')
-opts.add_argumentless(['-v', '--version'],                   help = 'Print the version of the program.')
-opts.add_argumentless(['-l', '--list'],                      help = 'List pony files.')
-opts.add_argumentless(['-L', '--altlist'],                   help = 'List pony files with alternatives.')
-opts.add_argumented(  ['-W', '--wrap'],     arg = 'COLUMN',  help = 'Specify the column when the message should be wrapped.')
-opts.add_argumented(  ['-f', '--pony'],     arg = 'PONY',    help = 'Select a pony.\nEither a file name or a pony name.')
-opts.add_variadic(    ['-q', '--quote'],    arg = 'PONY',    help = 'Select a ponies which will quote themself.')
+opts.add_argumentless(['-h', '--help'],                                   help = 'Print this help message.')
+opts.add_argumentless(['-v', '--version'],                                help = 'Print the version of the program.')
+opts.add_argumentless(['-l', '--list'],                                   help = 'List pony names.')
+opts.add_argumentless(['-L', '--altlist'],                                help = 'List pony names with alternatives.')
+opts.add_argumentless(['-B', '--balloonlist'],                            help = 'list balloon styles.')
+opts.add_argumented(  ['-W', '--wrap'],                  arg = 'COLUMN',  help = 'Specify the column when the message should be wrapped.')
+opts.add_argumented(  ['-b', '--bubble', '--balloon'],   arg = 'STYLE',   help = 'Select a balloon style.')
+opts.add_argumented(  ['-f', '--file', '--pony'],        arg = 'PONY',    help = 'Select a pony.\nEither a file name or a pony name.')
+opts.add_variadic(    ['-q', '--quote'],                 arg = 'PONY',    help = 'Select a ponies which will quote themself.')
 
 opts.parse()
 
-- 
cgit 


From c13ce26768e760908078244e251c7b3c19b26a8f Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Tue, 21 Aug 2012 19:35:55 +0200
Subject: automatic cache clean

---
 ponysay | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index fedaab6..7eb6dd5 100755
--- a/ponysay
+++ b/ponysay
@@ -24,7 +24,7 @@ from subprocess import Popen, PIPE
 '''
 The version of ponysay
 '''
-VERSION = '2.2'
+VERSION = '2.3'
 
 
 '''
@@ -533,6 +533,8 @@ class Ponysay():
         if not linuxvt:
             return pony
         
+        KMS_VERSION = '1'
+        
         env_kms = os.environ['PONYSAY_KMS_PALETTE'] if 'PONYSAY_KMS_PALETTE' in os.environ else None
         if env_kms is None:  env_kms = ''
         
@@ -554,6 +556,28 @@ class Ponysay():
             if not os.path.isdir(cachedir):
                 os.makedirs(cachedir)
         
+        newversion = False
+        if not os.path.isfile(cachedir + '/.version'):
+            newversion = True
+        else:
+            cachev = None
+            try:
+                cachev = open(cachedir + '/.version', 'r')
+                if ''.join(cachev.readlines()) == KMS_VERSION:
+                    newversion = True
+            finally:
+                if cachev is not None:
+                    cachev.close()
+        if newversion:
+            for cached in os.listdir(ponydir):
+                shutil.rmtree(cachedir + '/' + cached, False)
+            try:
+                cachev = open(cachedir + '/.version', 'w+')
+                cachev.write(KMS_VERSION)
+            finally:
+                if cachev is not None:
+                    cachev.close()
+        
         kmsponies = cachedir + '/kmsponies/' + palettefile
         kmspony = (kmsponies + pony).replace('//', '/')
         
-- 
cgit 


From 49e7ad42ebc79462d6827c8a5316adeeade43fcb Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Tue, 21 Aug 2012 19:37:51 +0200
Subject: forgot import

---
 ponysay | 1 +
 1 file changed, 1 insertion(+)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index 7eb6dd5..175fa63 100755
--- a/ponysay
+++ b/ponysay
@@ -16,6 +16,7 @@ License: WTFPL
 '''
 
 import os
+import shutil
 import sys
 import random
 from subprocess import Popen, PIPE
-- 
cgit 


From 8ac0aceadcadb4241d04ab65897a47b9e817d4b4 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Tue, 21 Aug 2012 19:45:35 +0200
Subject: derp

---
 ponysay | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index 175fa63..82f16b9 100755
--- a/ponysay
+++ b/ponysay
@@ -570,8 +570,13 @@ class Ponysay():
                 if cachev is not None:
                     cachev.close()
         if newversion:
-            for cached in os.listdir(ponydir):
-                shutil.rmtree(cachedir + '/' + cached, False)
+            for cached in os.listdir(cachedir):
+                cached = cachedir + '/' + cached
+                if os.path.isdir(cached) and not os.path.islink(cached):
+                    shutil.rmtree(cached, False)
+                else:
+                    os.remove(cached)
+            cachev = None
             try:
                 cachev = open(cachedir + '/.version', 'w+')
                 cachev.write(KMS_VERSION)
-- 
cgit 


From b6dfc3bd2ed4e69beaafb750c868c4200ac84223 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Tue, 21 Aug 2012 19:48:24 +0200
Subject: typo in code make e.g fillycadance draw incorrectly

---
 ponysay | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index 82f16b9..96ce9e6 100755
--- a/ponysay
+++ b/ponysay
@@ -1356,7 +1356,7 @@ class ColourStack():
                         elif (1 <= p) and (p <= 9):      self.stack[0][3][p - 1] = True
                         elif (21 <= p) and (p <= 29):    self.stack[0][3][p - 21] = False
                         elif p == 39:                    self.stack[0][1] = None
-                        elif p == 40:                    self.stack[0][2] = None
+                        elif p == 49:                    self.stack[0][2] = None
                         elif (30 <= p) and (p <= 37):    self.stack[0][1] = part
                         elif (90 <= p) and (p <= 97):    self.stack[0][1] = part
                         elif (40 <= p) and (p <= 47):    self.stack[0][2] = part
-- 
cgit 


From 2eb9342b864725d301a3dbc25423da6fcb174c13 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Tue, 21 Aug 2012 21:29:24 +0200
Subject: support for best.pony

---
 ponysay | 30 ++++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index 96ce9e6..a550578 100755
--- a/ponysay
+++ b/ponysay
@@ -47,6 +47,7 @@ class Ponysay():
             args.help()
             return
         
+        
         if   args.opts['-h']        is not None:  args.help()
         elif args.opts['--quoters'] is not None:  self.quoters()
         elif args.opts['--onelist'] is not None:  self.onelist()
@@ -54,8 +55,17 @@ class Ponysay():
         elif args.opts['-l']        is not None:  self.list()
         elif args.opts['-L']        is not None:  self.linklist()
         elif args.opts['-B']        is not None:  self.balloonlist()
-        elif args.opts['-q']        is not None:  self.quote(args)
-        else:                                     self.print_pony(args)
+        else:
+            if (args.opts['-f'] is None) or (args.opts['-q'] is None) or (len(args.opts['-q']) == 0):
+                for ponydir in ponydirs:
+                    if os.path.isfile(ponydir + 'best.pony') or os.path.islink(ponydir + 'best.pony'):
+                        pony = os.path.realpath(ponydir + 'best.pony') # Canonical path
+                        if args.opts['-q'] is not None:  args.opts['-q'] = [pony]
+                        else:                            args.opts['-f'] = [pony]
+                        break
+            
+            if args.opts['-q'] is not None:  self.quote(args)
+            else:                            self.print_pony(args)
     
     
     ##
@@ -480,11 +490,19 @@ class Ponysay():
     def quote(self, args):
         pairs = self.__quotes()
         if len(args.opts['-q']) > 0:
-            ponyset = set(args.opts['-q'])
+            ponyset = {}
+            for pony in args.opts['-q']:
+                if (len(pony) > 5) and (pony[-5:] == '.pony'):
+                    ponyname = pony[:-5]
+                    if '/' in ponyname:
+                        ponyname = ponyname[ponyname.rindex('/') + 1:]
+                    ponyset[ponyname] = pony
+                else:
+                    ponyset[pony] = pony
             alts = []
             for pair in pairs:
                 if pair[0] in ponyset:
-                    alts.append(pair)
+                    alts.append((ponyset[pair[0]], pair[1]))
             pairs = alts
             
         if not len(pairs) == 0:
@@ -498,11 +516,11 @@ class Ponysay():
                     qfile.close()
             args.opts['-f'] = [pair[0]]
         elif len(args.opts['-q']) == 0:
-            sys.stderr.write('All the ponies are mute! Call the Princess!\n')
+            sys.stderr.write('Princess Celestia! All the ponies are mute!\n')
             exit(1)
         else:
             args.opts['-f'] = [args.opts['-q'][random.randrange(0, len(args.opts['-q']))]]
-            args.message = 'I got nuthin\' good to say :('
+            args.message = 'Zecora! Help me, I am mute!'
         
         self.print_pony(args)
     
-- 
cgit 


From f76bef8facffab5eda3b9faefe76591f8d1a163a Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Wed, 22 Aug 2012 00:09:07 +0200
Subject: accepts ucs in -f and -q

---
 ponysay | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 70 insertions(+), 14 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index a550578..afcc595 100755
--- a/ponysay
+++ b/ponysay
@@ -56,14 +56,8 @@ class Ponysay():
         elif args.opts['-L']        is not None:  self.linklist()
         elif args.opts['-B']        is not None:  self.balloonlist()
         else:
-            if (args.opts['-f'] is None) or (args.opts['-q'] is None) or (len(args.opts['-q']) == 0):
-                for ponydir in ponydirs:
-                    if os.path.isfile(ponydir + 'best.pony') or os.path.islink(ponydir + 'best.pony'):
-                        pony = os.path.realpath(ponydir + 'best.pony') # Canonical path
-                        if args.opts['-q'] is not None:  args.opts['-q'] = [pony]
-                        else:                            args.opts['-f'] = [pony]
-                        break
-            
+            self.__bestpony(args)
+            self.__ucsremap(args)
             if args.opts['-q'] is not None:  self.quote(args)
             else:                            self.print_pony(args)
     
@@ -72,6 +66,58 @@ class Ponysay():
     ## Auxiliary methods
     ##
     
+    '''
+    Use best.pony if nothing else is set
+    '''
+    def __bestpony(self, args):
+        if (args.opts['-f'] is None) or (args.opts['-q'] is None) or (len(args.opts['-q']) == 0):
+            for ponydir in ponydirs:
+                if os.path.isfile(ponydir + 'best.pony') or os.path.islink(ponydir + 'best.pony'):
+                    pony = os.path.realpath(ponydir + 'best.pony') # Canonical path
+                    if args.opts['-q'] is not None:  args.opts['-q'] = [pony]
+                    else:                            args.opts['-f'] = [pony]
+                    break
+    
+    
+    '''
+    Apply pony name remapping to args according to UCS settings
+    '''
+    def __ucsremap(self, args):
+        env_ucs = os.environ['PONYSAY_UCS_ME'] if 'PONYSAY_UCS_ME' in os.environ else ''
+        ucs_conf = 0
+        if   env_ucs in ('yes',    'y', '1'):  ucs_conf = 1
+        elif env_ucs in ('harder', 'h', '2'):  ucs_conf = 2
+        
+        if ucs_conf == 0:
+            return
+        
+        maplines = []
+        for sharedir in sharedirs:
+            if os.path.isfile(sharedir + 'ucsmap'):
+                mapfile = None
+                try:
+                    mapfile = open(sharedir + 'ucsmap', 'r')
+                    maplines += [line.replace('\n', '') for line in mapfile.readlines()]
+                finally:
+                    if mapfile is not None:
+                        mapfile.close()
+        
+        map = {}
+        stripset = ' \t' # must be string, wtf! and way doesn't python's doc say so
+        for line in maplines:
+            if (len(line) > 0) and not (line[0] == '#'):
+                s = line.index('→')
+                ucs   = line[:s]    .strip(stripset)
+                ascii = line[s + 1:].strip(stripset)
+                map[ucs] = ascii
+        
+        for flag in ('-f', '-q'):
+            if args.opts[flag] is not None:
+                for i in range(0, len(args.opts[flag])):
+                    if args.opts[flag][i] in map:
+                        args.opts[flag][i] = map[args.opts[flag][i]]
+    
+    
     '''
     Returns one file with full path, names is filter for names, also accepts filepaths
     '''
@@ -1402,13 +1448,13 @@ class ColourStack():
 '''
 The user's home directory
 '''
-HOME = os.environ['HOME']
+HOME = os.environ['HOME'] if 'HOME' in os.environ else os.path.expanduser('~')
 
 
 '''
 Whether the program is execute in Linux VT (TTY)
 '''
-linuxvt = os.environ['TERM'] == 'linux'
+linuxvt = ('TERM' in os.environ) and (os.environ['TERM'] == 'linux')
 
 
 '''
@@ -1434,13 +1480,23 @@ Whether stderr is piped
 pipelineerr = not sys.stderr.isatty()
 
 
+'''
+Root share/ directories
+'''
+sharedirs = []
+_sharedirs = [HOME + '/.local/share/ponysay/',  INSTALLDIR + '/share/ponysay/']
+for sharedir in _sharedirs:
+    if os.path.isdir(sharedir):
+        sharedirs.append(sharedir)
+
+
 '''
 The directories where pony files are stored, ttyponies/ are used if the terminal is Linux VT (also known as TTY)
 '''
 ponydirs = []
 _kms = Ponysay.isUsingKMS()
-if linuxvt and not _kms:  _ponydirs = [HOME + '/.local/share/ponysay/ttyponies/',  INSTALLDIR + '/share/ponysay/ttyponies/']
-else:                     _ponydirs = [HOME + '/.local/share/ponysay/ponies/',     INSTALLDIR + '/share/ponysay/ponies/'   ]
+if linuxvt and not _kms:  _ponydirs = [d + 'ttyponies/' for d in sharedirs]
+else:                     _ponydirs = [d + 'ponies/' for d in sharedirs]
 for ponydir in _ponydirs:
     if os.path.isdir(ponydir):
         ponydirs.append(ponydir)
@@ -1450,7 +1506,7 @@ for ponydir in _ponydirs:
 The directories where quotes files are stored
 '''
 quotedirs = []
-_quotedirs = [HOME + '/.local/share/ponysay/quotes/',  INSTALLDIR + '/share/ponysay/quotes/']
+_quotedirs = [d + 'quotes/' for d in sharedirs]
 for quotedir in _quotedirs:
     if os.path.isdir(quotedir):
         quotedirs.append(quotedir)
@@ -1460,7 +1516,7 @@ for quotedir in _quotedirs:
 The directories where balloon style files are stored
 '''
 balloondirs = []
-_balloondirs = [HOME + '/.local/share/ponysay/balloons/',  INSTALLDIR + '/share/ponysay/balloons/']
+_balloondirs = [d + 'balloons/' for d in sharedirs]
 for balloondir in _balloondirs:
     if os.path.isdir(balloondir):
         balloondirs.append(balloondir)
-- 
cgit 


From 5744c13146e3401e479e58cca87d872423b046e2 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Wed, 22 Aug 2012 00:11:10 +0200
Subject: I think readlink only follows one level, this should get the
 canonical path (absolute and to the last level)

---
 ponysay | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index afcc595..f177ad3 100755
--- a/ponysay
+++ b/ponysay
@@ -257,7 +257,7 @@ class Ponysay():
                 if (len(pony) > 5) and (pony[-5:] == '.pony'):
                     ponies.append(pony[:-5])
             ponies.sort()
-            pairs = [(pony, os.readlink(ponydir + pony + '.pony') if os.path.islink(ponydir + pony + '.pony') else '') for pony in ponies]
+            pairs = [(pony, os.path.realpath(ponydir + pony + '.pony') if os.path.islink(ponydir + pony + '.pony') else '') for pony in ponies]
             
             ponymap = {}
             for pair in pairs:
-- 
cgit 


From 2227c0c5b780343e501a82cc0faff900bedd8e8f Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Wed, 22 Aug 2012 00:48:18 +0200
Subject: some work needed on UCS, otherwise complete

---
 ponysay | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index f177ad3..88ab9aa 100755
--- a/ponysay
+++ b/ponysay
@@ -118,6 +118,49 @@ class Ponysay():
                         args.opts[flag][i] = map[args.opts[flag][i]]
     
     
+    '''
+    Apply USC:ise pony names according to UCS settings
+    '''
+    def __ucsise(self, ponies, links = None):
+        env_ucs = os.environ['PONYSAY_UCS_ME'] if 'PONYSAY_UCS_ME' in os.environ else ''
+        ucs_conf = 0
+        if   env_ucs in ('yes',    'y', '1'):  ucs_conf = 1
+        elif env_ucs in ('harder', 'h', '2'):  ucs_conf = 2
+        
+        if ucs_conf == 0:
+            return
+        
+        maplines = []
+        for sharedir in sharedirs:
+            if os.path.isfile(sharedir + 'ucsmap'):
+                mapfile = None
+                try:
+                    mapfile = open(sharedir + 'ucsmap', 'r')
+                    maplines += [line.replace('\n', '') for line in mapfile.readlines()]
+                finally:
+                    if mapfile is not None:
+                        mapfile.close()
+        
+        map = {}
+        stripset = ' \t' # must be string, wtf! and way doesn't python's doc say so
+        for line in maplines:
+            if (len(line) > 0) and not (line[0] == '#'):
+                s = line.index('→')
+                ucs   = line[:s]    .strip(stripset)
+                ascii = line[s + 1:].strip(stripset)
+                map[ascii] = ucs
+        
+        if ucs_conf == 1:
+            for pony in ponies:
+                if pony in map:
+                    ponies.append(map[pony])
+        else:
+            for j in range(0, len(ponies)):
+                if ponies[j] in map:
+                    ponies[j] = map[ponies[j]]
+    
+    
+    
     '''
     Returns one file with full path, names is filter for names, also accepts filepaths
     '''
@@ -225,6 +268,7 @@ class Ponysay():
             for pony in _ponies:
                 if (len(pony) > 5) and (pony[-5:] == '.pony'):
                     ponies.append(pony[:-5])
+            self.__ucsise(ponies)
             ponies.sort()
             
             width = len(max(ponies, key = len)) + 2 # Get the longest ponyfilename lenght + 2 spaces
@@ -256,6 +300,8 @@ class Ponysay():
             for pony in _ponies:
                 if (len(pony) > 5) and (pony[-5:] == '.pony'):
                     ponies.append(pony[:-5])
+            pseudolinkmap = []
+            self.__ucsise(ponies, pseudolinkmap) ##TODO
             ponies.sort()
             pairs = [(pony, os.path.realpath(ponydir + pony + '.pony') if os.path.islink(ponydir + pony + '.pony') else '') for pony in ponies]
             
@@ -320,6 +366,7 @@ class Ponysay():
         ponies = []
         for pony in self.__quoters():
             ponies.append(pony)
+        self.__ucsise(ponies)
         ponies.sort()
         for pony in ponies:
             if not pony == last:
@@ -339,6 +386,7 @@ class Ponysay():
         for pony in _ponies:
             if (len(pony) > 5) and (pony[-5:] == '.pony'):
                 ponies.append(pony[:-5])
+        self.__ucsise(ponies)
         ponies.sort()
         for pony in ponies:
             if not pony == last:
-- 
cgit 


From 08fb7cc7e66f4cc5917b4b15a61b111abe94cc27 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Wed, 22 Aug 2012 01:34:06 +0200
Subject: support for combining characters (now we have full unicode support)

---
 ponysay | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 53 insertions(+), 14 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index 88ab9aa..a727aab 100755
--- a/ponysay
+++ b/ponysay
@@ -271,11 +271,11 @@ class Ponysay():
             self.__ucsise(ponies)
             ponies.sort()
             
-            width = len(max(ponies, key = len)) + 2 # Get the longest ponyfilename lenght + 2 spaces
+            width = UCS.dispLen(max(ponies, key = UCS.dispLen)) + 2 # Get the longest ponyfilename lenght + 2 spaces
             
             x = 0
             for pony in ponies:
-                spacing = ' ' * (width - len(pony))
+                spacing = ' ' * (width - UCS.dispLen(pony))
                 print(('\033[1m' + pony + '\033[21m' if (pony in quoters) else pony) + spacing, end='') # Print ponyfilename
                 x += width
                 if x > (termsize[1] - width): # If too wide, make new line
@@ -323,7 +323,7 @@ class Ponysay():
             ponies = []
             widths = []
             for pony in ponymap:
-                w = len(pony)
+                w = UCS.dispLen(pony)
                 item = '\033[1m' + pony + '\033[21m' if (pony in quoters) else pony
                 syms = ponymap[pony]
                 if len(syms) > 0:
@@ -331,7 +331,7 @@ class Ponysay():
                     item += ' ('
                     first = True
                     for sym in syms:
-                        w += len(sym)
+                        w += UCS.dispLen(sym)
                         if not first:
                             item += ' '
                         else:
@@ -420,11 +420,11 @@ class Ponysay():
         balloons = list(balloonset)
         balloons.sort()
         
-        width = len(max(balloons, key = len)) + 2
+        width = UCS.dispLen(max(balloons, key = UCS.dispLen)) + 2
         
         x = 0
         for balloon in balloons:
-            spacing = ' ' * (width - len(balloon))
+            spacing = ' ' * (width - UCS.dispLen(balloon))
             print(balloon + spacing, end='')
             x += width
             if x > (termsize[1] - width):
@@ -961,13 +961,13 @@ class Balloon():
         (self.sse, self.s, self.ssw) = (sse, s, ssw)
         (self.sww, self.w, self.nww) = (sww, w, nww)
         
-        _ne = max(ne, key = len)
-        _nw = max(nw, key = len)
-        _se = max(se, key = len)
-        _sw = max(sw, key = len)
+        _ne = max(ne, key = UCS.dispLen)
+        _nw = max(nw, key = UCS.dispLen)
+        _se = max(se, key = UCS.dispLen)
+        _sw = max(sw, key = UCS.dispLen)
         
-        minE = len(max([_ne, nee, e, see, _se, ee], key = len))
-        minW = len(max([_nw, nww, e, sww, _sw, ww], key = len))
+        minE = UCS.dispLen(max([_ne, nee, e, see, _se, ee], key = UCS.dispLen))
+        minW = UCS.dispLen(max([_nw, nww, e, sww, _sw, ww], key = UCS.dispLen))
         minN = len(max([ne, nne, n, nnw, nw], key = len))
         minS = len(max([se, sse, s, ssw, sw], key = len))
         
@@ -1282,7 +1282,8 @@ class Backend():
                 i += len(self.__getcolour(input, i))
             else:
                 i += 1
-                rc += 1
+                if not UCS.isCombining(c):
+                    rc += 1
         return rc
     
     
@@ -1355,7 +1356,8 @@ class Backend():
                                 indentc += 1
                     b[bi] = d
                     bi += 1
-                    cols += 1
+                    if not UCS.isCombining(d):
+                        cols += 1
                     map[cols] = bi
                 else:
                     mm = 0
@@ -1492,6 +1494,43 @@ class ColourStack():
 
 
 
+'''
+UCS utility class
+'''
+class UCS():
+    '''
+    Checks whether a character is a combining character
+    '''
+    @staticmethod
+    def isCombining(char):
+        o = ord(char)
+        if (0x0300 <= o) and (o <= 0x036F):  return True
+        if (0x20D0 <= o) and (o <= 0x20FF):  return True
+        if (0x1DC0 <= o) and (o <= 0x1DFF):  return True
+        if (0xFE20 <= o) and (o <= 0xFE2F):  return True
+        return False
+    
+    
+    '''
+    Gets the number of combining characters in a string
+    '''
+    @staticmethod
+    def countCombining(string):
+        rc = 0
+        for char in string:
+            if UCS.isCombining(char):
+                rc += 1
+        return rc
+    
+    
+    '''
+    Gets length of a string not counting combining characters
+    '''
+    @staticmethod
+    def dispLen(string):
+        return len(string) - UCS.countCombining(string)
+
+
 
 '''
 The user's home directory
-- 
cgit 


From 22d7318624f834254ecdb0c6bdf9536dee3cae37 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Wed, 22 Aug 2012 01:55:50 +0200
Subject: warping error with combining characters

---
 ponysay | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index a727aab..6086352 100755
--- a/ponysay
+++ b/ponysay
@@ -995,19 +995,19 @@ class Balloon():
         rc = []
         
         for j in range(0, len(self.n)):
-            outer = len(self.nw[j]) + len(self.ne[j])
-            inner = len(self.nnw[j]) + len(self.nne[j])
+            outer = UCS.dispLen(self.nw[j]) + UCS.dispLen(self.ne[j])
+            inner = UCS.dispLen(self.nnw[j]) + UCS.dispLen(self.nne[j])
             if outer + inner >= w:
                 rc.append(self.nw[j] + self.nnw[j] + self.n[j] * (w - outer - inner) + self.nne[j] + self.ne[j])
             else:
                 rc.append(self.nw[j] + self.n[j] * (w - outer) + self.ne[j])
         
         for j in range(0, len(lines)):
-            rc.append(ws[j] + lines[j] + ' ' * (w - lencalc(lines[j]) - len(self.w) - len(self.e)) + es[j])
+            rc.append(ws[j] + lines[j] + ' ' * (w - lencalc(lines[j]) - UCS.dispLen(self.w) - UCS.dispLen(self.e)) + es[j])
         
         for j in range(0, len(self.s)):
-            outer = len(self.sw[j]) + len(self.se[j])
-            inner = len(self.ssw[j]) + len(self.sse[j])
+            outer = UCS.dispLen(self.sw[j]) + UCS.dispLen(self.se[j])
+            inner = UCS.dispLen(self.ssw[j]) + UCS.dispLen(self.sse[j])
             if outer + inner >= w:
                 rc.append(self.sw[j] + self.ssw[j] + self.s[j] * (w - outer - inner) + self.sse[j] + self.se[j])
             else:
@@ -1069,7 +1069,8 @@ class Backend():
                     x += nx
                 else:
                     buf += c
-                    x += 1
+                    if not UCS.isCombining(c):
+                        x += 1
             buf += '\n'
         self.message = buf[:-1]
     
@@ -1107,7 +1108,8 @@ class Backend():
                 else:
                     if x < self.width:
                         self.output += c
-                        x += 1
+                        if not UCS.isCombining(c):
+                            x += 1
             self.output += '\n'
         self.output = self.output[:-1]
     
@@ -1222,7 +1224,8 @@ class Backend():
                         if nonskip > 0:
                             nonskip -= 1
                         self.output += c + colourstack.feed(c);
-                        indent += 1
+                        if not UCS.isCombining(c):
+                            indent += 1
                     else:
                         skip -= 1
         
@@ -1302,7 +1305,7 @@ class Backend():
             msg = self.__wrapMessage(msg, wrap)
         lines = msg.split('\n')
         
-        return self.balloon.get(width, height, lines, self.__len)
+        return self.balloon.get(width, height, lines, lambda text : self.__len(text) - UCS.countCombining(text))
     
     
     '''
-- 
cgit 


From beeed62f49f98fc2b29b8f057fd3499a22cad22b Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Wed, 22 Aug 2012 01:59:06 +0200
Subject: support pipes and sockets as ponyfiles and balloon files

---
 ponysay | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index 6086352..50e19b2 100755
--- a/ponysay
+++ b/ponysay
@@ -175,7 +175,7 @@ class Ponysay():
         
         if not names == None:
             for name in names:
-                if os.path.isfile(name):
+                if os.path.exists(name):
                     ponies[name] = name
         
         if names == None:
@@ -455,7 +455,7 @@ class Ponysay():
                     balloons[balloon] = balloondir + balloonfile
         
         for name in names:
-            if os.path.isfile(name):
+            if os.path.exists(name):
                 balloons[name] = name
         
         if names == None:
-- 
cgit 


From a9c0dedfbc908be9bef30101737f9e0a1a5112d1 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Wed, 22 Aug 2012 02:50:35 +0200
Subject: wrap correction

---
 ponysay | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index 50e19b2..1a69e01 100755
--- a/ponysay
+++ b/ponysay
@@ -1305,7 +1305,7 @@ class Backend():
             msg = self.__wrapMessage(msg, wrap)
         lines = msg.split('\n')
         
-        return self.balloon.get(width, height, lines, lambda text : self.__len(text) - UCS.countCombining(text))
+        return self.balloon.get(width, height, lines, self.__len)
     
     
     '''
-- 
cgit 


From 860919ddd4f367c9be70b6e746b02695dfa3767a Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Wed, 22 Aug 2012 03:23:11 +0200
Subject: sorting -L

---
 ponysay | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index 1a69e01..8426fc4 100755
--- a/ponysay
+++ b/ponysay
@@ -154,6 +154,8 @@ class Ponysay():
             for pony in ponies:
                 if pony in map:
                     ponies.append(map[pony])
+                    if links is not None:
+                        links[map[pony]] = pony + '.pony'
         else:
             for j in range(0, len(ponies)):
                 if ponies[j] in map:
@@ -282,7 +284,7 @@ class Ponysay():
                     print()
                     x = 0
             
-            print('\n');
+            print('' if x == 0 else '\n');
     
     
     '''
@@ -300,14 +302,13 @@ class Ponysay():
             for pony in _ponies:
                 if (len(pony) > 5) and (pony[-5:] == '.pony'):
                     ponies.append(pony[:-5])
-            pseudolinkmap = []
+            pseudolinkmap = {}
             self.__ucsise(ponies, pseudolinkmap) ##TODO
-            ponies.sort()
-            pairs = [(pony, os.path.realpath(ponydir + pony + '.pony') if os.path.islink(ponydir + pony + '.pony') else '') for pony in ponies]
+            pairs = [(pony, os.path.realpath(ponydir + pony + '.pony') if os.path.islink(ponydir + pony + '.pony') else None) for pony in ponies]
             
             ponymap = {}
             for pair in pairs:
-                if pair[1] == '':
+                if (pair[1] is None) or (pair[1] == ''):
                     if pair[0] not in ponymap:
                         ponymap[pair[0]] = []
                 else:
@@ -320,8 +321,7 @@ class Ponysay():
                         ponymap[target] = [pair[0]]
             
             width = 0
-            ponies = []
-            widths = []
+            ponies = {}
             for pony in ponymap:
                 w = UCS.dispLen(pony)
                 item = '\033[1m' + pony + '\033[21m' if (pony in quoters) else pony
@@ -338,24 +338,25 @@ class Ponysay():
                             first = False
                         item += '\033[1m' + sym + '\033[21m' if (sym in quoters) else sym
                     item += ')'
-                ponies.append(item)
-                widths.append(w)
+                ponies[item] = w
                 if width < w:
                     width = w
             
             width += 2;
             x = 0
             index = 0
-            for pony in ponies:
-                spacing = ' ' * (width - widths[index])
+            ponylist = list(ponies)
+            ponylist.sort(key = lambda pony : pony.split(' ')[0].replace('\033[1m', '').replace('\033[21m', ''))
+            for pony in ponylist:
+                spacing = ' ' * (width - ponies[pony])
                 index += 1
                 print(pony + spacing, end='') # Print pony file name
                 x += width
-                if x > (termsize[1] - width): # If too wide, make new line
+                if x > termsize[1] - width: # If too wide, make new line
                     print()
                     x = 0
             
-            print('\n');
+            print('' if x == 0 else '\n');
     
     
     '''
-- 
cgit 


From d179b3c18007d5e7c7326d3d2ae3b5f43cd88a70 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Wed, 22 Aug 2012 03:28:21 +0200
Subject: sorting the symlinks in -L

---
 ponysay | 1 +
 1 file changed, 1 insertion(+)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index 8426fc4..b1911ce 100755
--- a/ponysay
+++ b/ponysay
@@ -326,6 +326,7 @@ class Ponysay():
                 w = UCS.dispLen(pony)
                 item = '\033[1m' + pony + '\033[21m' if (pony in quoters) else pony
                 syms = ponymap[pony]
+                syms.sort()
                 if len(syms) > 0:
                     w += 2 + len(syms)
                     item += ' ('
-- 
cgit 


From 44a3fbca3b9ed1a2504a3f297682e74891bea1ba Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Wed, 22 Aug 2012 03:48:25 +0200
Subject: ucs name support complete

---
 ponysay | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index b1911ce..c120ca3 100755
--- a/ponysay
+++ b/ponysay
@@ -155,14 +155,13 @@ class Ponysay():
                 if pony in map:
                     ponies.append(map[pony])
                     if links is not None:
-                        links[map[pony]] = pony + '.pony'
+                        links[map[pony]] = pony
         else:
             for j in range(0, len(ponies)):
                 if ponies[j] in map:
                     ponies[j] = map[ponies[j]]
     
     
-    
     '''
     Returns one file with full path, names is filter for names, also accepts filepaths
     '''
@@ -251,6 +250,7 @@ class Ponysay():
         return termsize
     
     
+    
     ##
     ## Listing methods
     ##
@@ -304,7 +304,12 @@ class Ponysay():
                     ponies.append(pony[:-5])
             pseudolinkmap = {}
             self.__ucsise(ponies, pseudolinkmap) ##TODO
-            pairs = [(pony, os.path.realpath(ponydir + pony + '.pony') if os.path.islink(ponydir + pony + '.pony') else None) for pony in ponies]
+            pairs = []
+            for pony in ponies:
+                if pony in pseudolinkmap:
+                    pairs.append((pony, pseudolinkmap[pony] + '.pony'));
+                else:
+                    pairs.append((pony, os.path.realpath(ponydir + pony + '.pony') if os.path.islink(ponydir + pony + '.pony') else None))
             
             ponymap = {}
             for pair in pairs:
-- 
cgit 


From 9c6aeee703b821c78dd7ea6dd96359cc3a90c669 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Wed, 22 Aug 2012 04:35:07 +0200
Subject: message stuff

---
 ponysay | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index c120ca3..6b33005 100755
--- a/ponysay
+++ b/ponysay
@@ -533,6 +533,25 @@ class Ponysay():
         else:
             msg = args.message
         
+        if args.opts['-c'] is not None: ## This algorithm should give some result as cowsay's (according to tests)
+            buf = ''
+            last = ' '
+            CHARS = '\t \n'
+            for c in msg:
+                if (c in CHARS) and (last in CHARS):
+                    if last == '\n':
+                        buf += last
+                    last = c
+                else:
+                    buf += c
+                    last = c
+            msg = buf.strip(CHARS)
+            buf = ''
+            for c in msg:
+                if (c != '\n') or (last != '\n'):
+                    buf += c
+                    last = c
+            msg = buf.replace('\n', '\n\n')
         
         pony = self.__getponypath(args.opts['-f'])
         
@@ -1412,7 +1431,7 @@ class Backend():
                                 w -= indentc
             
             buf += '\n'
-        return buf[:-1]
+        return '\n'.join(line.rstrip() for line in buf[:-1].split('\n'))
 
 
 '''
@@ -1654,7 +1673,8 @@ opts.add_argumentless(['-h', '--help'],                                   help =
 opts.add_argumentless(['-v', '--version'],                                help = 'Print the version of the program.')
 opts.add_argumentless(['-l', '--list'],                                   help = 'List pony names.')
 opts.add_argumentless(['-L', '--altlist'],                                help = 'List pony names with alternatives.')
-opts.add_argumentless(['-B', '--balloonlist'],                            help = 'list balloon styles.')
+opts.add_argumentless(['-B', '--balloonlist'],                            help = 'List balloon styles.')
+opts.add_argumentless(['-c', '--compact'],                                help = 'Compress messages.')
 opts.add_argumented(  ['-W', '--wrap'],                  arg = 'COLUMN',  help = 'Specify the column when the message should be wrapped.')
 opts.add_argumented(  ['-b', '--bubble', '--balloon'],   arg = 'STYLE',   help = 'Select a balloon style.')
 opts.add_argumented(  ['-f', '--file', '--pony'],        arg = 'PONY',    help = 'Select a pony.\nEither a file name or a pony name.')
-- 
cgit 


From 607fafbc3a40a615750e817f5e8b443b062579d8 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Wed, 22 Aug 2012 05:16:32 +0200
Subject: manual update

---
 ponysay | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index 6b33005..9fc8c70 100755
--- a/ponysay
+++ b/ponysay
@@ -1639,15 +1639,14 @@ for balloondir in _balloondirs:
 
 
 usage_saythink = '\033[34;1m(ponysay | ponythink)\033[21;39m'
-usage_wrap     = '--wrap \033[4mCOLUMN\033[24m'
-usage_balloon  = '--balloon \033[4mSTYLE\033[24m'
-usage_listhelp = '(--list | --altlist | --balloonlist | --version | --help)'
-usage_file     = '[--pony \033[4mPONY\033[24m]... ([--] \033[4mmessage\033[24m | <<<\033[4mmessage\033[24m)'
-usage_quote    = '--quote [\033[4mPONY\033[24m...]'
+usage_common   = '[-c] [-W \033[4mCOLUMN\033[24m] [-b \033[4mSTYLE\033[24m]'
+usage_listhelp = '(-l | -L | -B | -v | -h)'
+usage_file     = '[-f \033[4mPONY\033[24m]... ([--] \033[4mmessage\033[24m | <<<\033[4mmessage\033[24m)'
+usage_quote    = '-q [\033[4mPONY\033[24m...]'
 
-usage = '%s %s\n%s [%s] [%s] %s\n%s [%s] [%s] %s' % (usage_saythink, usage_listhelp,
-                                                     usage_saythink, usage_wrap, usage_balloon, usage_file,
-                                                     usage_saythink, usage_wrap, usage_balloon, usage_quote)
+usage = '%s %s\n%s %s %s\n%s %s %s' % (usage_saythink, usage_listhelp,
+                                       usage_saythink, usage_common, usage_file,
+                                       usage_saythink, usage_common, usage_quote)
 
 usage = usage.replace('\033[', '\0')
 for sym in ('[', ']', '(', ')', '|', '...'):
-- 
cgit 


From cbbb9be76c7ab4d7bec9c7f7afea3dda8fd949b6 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Wed, 22 Aug 2012 15:50:42 +0200
Subject: Non-TV ponies

---
 ponysay | 51 +++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 41 insertions(+), 10 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index 9fc8c70..62f6834 100755
--- a/ponysay
+++ b/ponysay
@@ -58,14 +58,24 @@ class Ponysay():
         else:
             self.__bestpony(args)
             self.__ucsremap(args)
+            self.__extraponies(args)
             if args.opts['-q'] is not None:  self.quote(args)
             else:                            self.print_pony(args)
     
     
     ##
-    ## Auxiliary methods
+    ## Methods that run in the beginning of non-listing and non-help stuff
     ##
     
+    '''
+    Use best.pony if nothing else is set
+    '''
+    def __bestpony(self, args):
+        if args.opts['-F'] is not None:
+            args.opts['-f'] = args.opts['-F']
+            ponydirs = extraponydirs
+    
+    
     '''
     Use best.pony if nothing else is set
     '''
@@ -118,6 +128,10 @@ class Ponysay():
                         args.opts[flag][i] = map[args.opts[flag][i]]
     
     
+    ##
+    ## Auxiliary methods
+    ##
+    
     '''
     Apply USC:ise pony names according to UCS settings
     '''
@@ -1596,6 +1610,12 @@ Whether stderr is piped
 pipelineerr = not sys.stderr.isatty()
 
 
+'''
+Whether KMS is used
+'''
+usekms = Ponysay.isUsingKMS()
+
+
 '''
 Root share/ directories
 '''
@@ -1607,17 +1627,27 @@ for sharedir in _sharedirs:
 
 
 '''
-The directories where pony files are stored, ttyponies/ are used if the terminal is Linux VT (also known as TTY)
+The directories where pony files are stored, ttyponies/ are used if the terminal is Linux VT (also known as TTY) and not with KMS
 '''
 ponydirs = []
-_kms = Ponysay.isUsingKMS()
-if linuxvt and not _kms:  _ponydirs = [d + 'ttyponies/' for d in sharedirs]
-else:                     _ponydirs = [d + 'ponies/' for d in sharedirs]
+if linuxvt and not usekms:  _ponydirs = [d + 'ttyponies/' for d in sharedirs]
+else:                       _ponydirs = [d + 'ponies/'    for d in sharedirs]
 for ponydir in _ponydirs:
     if os.path.isdir(ponydir):
         ponydirs.append(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
+'''
+extraponydirs = []
+if linuxvt and not usekms:  _extraponydirs = [d + 'extrattyponies/' for d in sharedirs]
+else:                       _extraponydirs = [d + 'extraponies/'    for d in sharedirs]
+for extraponydir in _extraponydirs:
+    if os.path.isdir(extraponydir):
+        extraponydirs.append(extraponydir)
+
+
 '''
 The directories where quotes files are stored
 '''
@@ -1638,11 +1668,11 @@ for balloondir in _balloondirs:
         balloondirs.append(balloondir)
 
 
-usage_saythink = '\033[34;1m(ponysay | ponythink)\033[21;39m'
-usage_common   = '[-c] [-W \033[4mCOLUMN\033[24m] [-b \033[4mSTYLE\033[24m]'
-usage_listhelp = '(-l | -L | -B | -v | -h)'
-usage_file     = '[-f \033[4mPONY\033[24m]... ([--] \033[4mmessage\033[24m | <<<\033[4mmessage\033[24m)'
-usage_quote    = '-q [\033[4mPONY\033[24m...]'
+usage_saythink  = '\033[34;1m(ponysay | ponythink)\033[21;39m'
+usage_common    = '[-c] [-W \033[4mCOLUMN\033[24m] [-b \033[4mSTYLE\033[24m]'
+usage_listhelp  = '(-l | -L | -B | -v | -h)'
+usage_file      = '[(-f | -F) \033[4mPONY\033[24m]... ([--] \033[4mmessage\033[24m | <<<\033[4mmessage\033[24m)'
+usage_quote     = '-q [\033[4mPONY\033[24m...]'
 
 usage = '%s %s\n%s %s %s\n%s %s %s' % (usage_saythink, usage_listhelp,
                                        usage_saythink, usage_common, usage_file,
@@ -1677,6 +1707,7 @@ opts.add_argumentless(['-c', '--compact'],                                help =
 opts.add_argumented(  ['-W', '--wrap'],                  arg = 'COLUMN',  help = 'Specify the column when the message should be wrapped.')
 opts.add_argumented(  ['-b', '--bubble', '--balloon'],   arg = 'STYLE',   help = 'Select a balloon style.')
 opts.add_argumented(  ['-f', '--file', '--pony'],        arg = 'PONY',    help = 'Select a pony.\nEither a file name or a pony name.')
+opts.add_argumented(  ['-F', '++file', '++pony'],        arg = 'PONY',    help = 'Select a non-MLP:FiM pony.')
 opts.add_variadic(    ['-q', '--quote'],                 arg = 'PONY',    help = 'Select a ponies which will quote themself.')
 
 opts.parse()
-- 
cgit 


From 243612379e077eb46159cb64df51de2489b5c67f Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Wed, 22 Aug 2012 15:56:48 +0200
Subject: Non-TV ponies fix

---
 ponysay | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index 62f6834..f4480c0 100755
--- a/ponysay
+++ b/ponysay
@@ -56,24 +56,24 @@ class Ponysay():
         elif args.opts['-L']        is not None:  self.linklist()
         elif args.opts['-B']        is not None:  self.balloonlist()
         else:
+            self.__extraponies(args)
             self.__bestpony(args)
             self.__ucsremap(args)
-            self.__extraponies(args)
             if args.opts['-q'] is not None:  self.quote(args)
             else:                            self.print_pony(args)
     
     
     ##
-    ## Methods that run in the beginning of non-listing and non-help stuff
+    ## Methods that run before the mane methods
     ##
     
     '''
-    Use best.pony if nothing else is set
+    Use extra ponies
     '''
-    def __bestpony(self, args):
+    def __extraponies(self, args):
         if args.opts['-F'] is not None:
             args.opts['-f'] = args.opts['-F']
-            ponydirs = extraponydirs
+            ponydirs[:] = extraponydirs
     
     
     '''
@@ -1668,11 +1668,11 @@ for balloondir in _balloondirs:
         balloondirs.append(balloondir)
 
 
-usage_saythink  = '\033[34;1m(ponysay | ponythink)\033[21;39m'
-usage_common    = '[-c] [-W \033[4mCOLUMN\033[24m] [-b \033[4mSTYLE\033[24m]'
-usage_listhelp  = '(-l | -L | -B | -v | -h)'
-usage_file      = '[(-f | -F) \033[4mPONY\033[24m]... ([--] \033[4mmessage\033[24m | <<<\033[4mmessage\033[24m)'
-usage_quote     = '-q [\033[4mPONY\033[24m...]'
+usage_saythink = '\033[34;1m(ponysay | ponythink)\033[21;39m'
+usage_common   = '[-c] [-W \033[4mCOLUMN\033[24m] [-b \033[4mSTYLE\033[24m]'
+usage_listhelp = '(-l | -L | -B | -v | -h)'
+usage_file     = '[(-f | -F) \033[4mPONY\033[24m]... ([--] \033[4mmessage\033[24m | <<<\033[4mmessage\033[24m)'
+usage_quote    = '-q [\033[4mPONY\033[24m...]'
 
 usage = '%s %s\n%s %s %s\n%s %s %s' % (usage_saythink, usage_listhelp,
                                        usage_saythink, usage_common, usage_file,
-- 
cgit 


From a84f1d6534515e3264b6e87d9f13568de98feade Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Wed, 22 Aug 2012 16:01:37 +0200
Subject: listing extra ponies

---
 ponysay | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index f4480c0..baea15c 100755
--- a/ponysay
+++ b/ponysay
@@ -55,6 +55,9 @@ class Ponysay():
         elif args.opts['-l']        is not None:  self.list()
         elif args.opts['-L']        is not None:  self.linklist()
         elif args.opts['-B']        is not None:  self.balloonlist()
+        elif args.opts['++onelist'] is not None:  self.__extraponies(); self.onelist()
+        elif args.opts['+l']        is not None:  self.__extraponies(); self.list()
+        elif args.opts['+L']        is not None:  self.__extraponies(); self.linklist()
         else:
             self.__extraponies(args)
             self.__bestpony(args)
@@ -70,8 +73,10 @@ class Ponysay():
     '''
     Use extra ponies
     '''
-    def __extraponies(self, args):
-        if args.opts['-F'] is not None:
+    def __extraponies(self, args = None):
+        if args is None:
+            ponydirs[:] = extraponydirs
+        elif args.opts['-F'] is not None:
             args.opts['-f'] = args.opts['-F']
             ponydirs[:] = extraponydirs
     
@@ -1697,11 +1702,14 @@ run `man ponysay`. Ponysay has so much more to offer than described here.''')
 
 opts.add_argumentless(['--quoters'])
 opts.add_argumentless(['--onelist'])
+opts.add_argumentless(['++onelist'])
 
 opts.add_argumentless(['-h', '--help'],                                   help = 'Print this help message.')
 opts.add_argumentless(['-v', '--version'],                                help = 'Print the version of the program.')
 opts.add_argumentless(['-l', '--list'],                                   help = 'List pony names.')
 opts.add_argumentless(['-L', '--altlist'],                                help = 'List pony names with alternatives.')
+opts.add_argumentless(['+l', '++list'],                                   help = 'List non-MLP:FiM pony names.')
+opts.add_argumentless(['+L', '++altlist'],                                help = 'List non-MLP:FiM pony names with alternatives.')
 opts.add_argumentless(['-B', '--balloonlist'],                            help = 'List balloon styles.')
 opts.add_argumentless(['-c', '--compact'],                                help = 'Compress messages.')
 opts.add_argumented(  ['-W', '--wrap'],                  arg = 'COLUMN',  help = 'Specify the column when the message should be wrapped.')
-- 
cgit 


From f830ba4cf7b21b50406fbccf32535ebda11c2ed9 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Wed, 22 Aug 2012 16:25:35 +0200
Subject: misc

---
 ponysay | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index baea15c..67a7d2e 100755
--- a/ponysay
+++ b/ponysay
@@ -1675,7 +1675,7 @@ for balloondir in _balloondirs:
 
 usage_saythink = '\033[34;1m(ponysay | ponythink)\033[21;39m'
 usage_common   = '[-c] [-W \033[4mCOLUMN\033[24m] [-b \033[4mSTYLE\033[24m]'
-usage_listhelp = '(-l | -L | -B | -v | -h)'
+usage_listhelp = '(-l | -L | -B | +l | +L | -v | -h)'
 usage_file     = '[(-f | -F) \033[4mPONY\033[24m]... ([--] \033[4mmessage\033[24m | <<<\033[4mmessage\033[24m)'
 usage_quote    = '-q [\033[4mPONY\033[24m...]'
 
-- 
cgit 


From d3ddf64433b38558a4dc83eba36469a971dd9640 Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@operamail.com>
Date: Wed, 22 Aug 2012 16:36:47 +0200
Subject: final touches on extra ponies

---
 ponysay | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

(limited to 'ponysay')

diff --git a/ponysay b/ponysay
index 67a7d2e..faca1d3 100755
--- a/ponysay
+++ b/ponysay
@@ -282,8 +282,6 @@ class Ponysay():
         quoters = self.__quoters()
         
         for ponydir in ponydirs: # Loop ponydirs
-            print('\033[1mponies located in ' + ponydir + '\033[21m')
-            
             _ponies = os.listdir(ponydir)
             ponies = []
             for pony in _ponies:
@@ -292,6 +290,10 @@ class Ponysay():
             self.__ucsise(ponies)
             ponies.sort()
             
+            if len(ponies) == 0:
+                continue
+            print('\033[1mponies located in ' + ponydir + '\033[21m')
+            
             width = UCS.dispLen(max(ponies, key = UCS.dispLen)) + 2 # Get the longest ponyfilename lenght + 2 spaces
             
             x = 0
@@ -314,13 +316,16 @@ class Ponysay():
         quoters = self.__quoters()
         
         for ponydir in ponydirs: # Loop ponydirs
-            print('\033[1mponies located in ' + ponydir + '\033[21m')
-            
             _ponies = os.listdir(ponydir)
             ponies = []
             for pony in _ponies:
                 if (len(pony) > 5) and (pony[-5:] == '.pony'):
                     ponies.append(pony[:-5])
+            
+            if len(ponies) == 0:
+                continue
+            print('\033[1mponies located in ' + ponydir + '\033[21m')
+            
             pseudolinkmap = {}
             self.__ucsise(ponies, pseudolinkmap) ##TODO
             pairs = []
-- 
cgit