changeset 34:88a69d587326

round1 of commands
author Jeff Hammel <k0scist@gmail.com>
date Sun, 02 Mar 2014 15:33:07 -0800
parents de3148412191
children 5ffa0dbcb7fe
files textshaper/commands.py textshaper/decorator.py textshaper/indent.py textshaper/main.py
diffstat 4 files changed, 84 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/textshaper/commands.py	Sun Feb 23 16:48:09 2014 -0800
+++ b/textshaper/commands.py	Sun Mar 02 15:33:07 2014 -0800
@@ -1,23 +1,53 @@
-#!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
 """
 CLI commands for textshaper
 """
 
+import inspect
+
 class Shaper(object):
-    """individual text shaper component"""
+    """
+    individual text shaper component
+    (function wrapper)
+    """
 
     def __init__(self, function):
         self.function = function
+        self.func_name = function.func_name
+
+    def __call__(self, text, **kwargs):
+        return self.function(text, **kwargs)
+
+    def __str__(self):
+        return self.func_name
+
 
 class Commands(object):
 
     def __init__(self):
         self.shapers = []
         self.keys = {}
+        self.display_keys = []
 
     def add(self, function, key=None):
         self.shapers.append(Shaper(function))
-        if key:
-            self.keys[key] = self.shapers[-1]
+        if not key:
+            key = str(self.shapers[-1])
+        key = key.lower()
+        self.keys[key] = self.shapers[-1]
+        name = str(self.shapers[-1]).lower()
+        if name.startswith(key):
+            display_name = '{}{}'.format(key, name[len(key):].upper())
+        else:
+            display_name = '{}:{}'.format(key, name.upper())
+        self.display_keys.append(display_name)
+
+    def call(self, key, text, **kwargs):
+        if key in self.keys:
+            return self.keys[key](text, **kwargs)
+
+    __call__ = call
+
+    def display(self):
+        return ' '.join(self.display_keys)
--- a/textshaper/decorator.py	Sun Feb 23 16:48:09 2014 -0800
+++ b/textshaper/decorator.py	Sun Mar 02 15:33:07 2014 -0800
@@ -16,6 +16,9 @@
         self.function = function
         self.line_separator = line_separator
 
+        # record function information from function object
+        self.func_name = function.func_name
+
     def __call__(self, text, *args, **kwargs):
         is_string = False
         if isinstance(text, string):
--- a/textshaper/indent.py	Sun Feb 23 16:48:09 2014 -0800
+++ b/textshaper/indent.py	Sun Mar 02 15:33:07 2014 -0800
@@ -43,6 +43,12 @@
 
     return retval
 
+@lines
+def deindent(text):
+    """strip lines"""
+    return [line.strip() for line in text]
+
+### CLI
 
 def add_arguments(parser):
     parser.add_argument('infile', nargs='?', type=argparse.FileType('r'),
@@ -52,6 +58,7 @@
 
 
 def main(args=sys.argv[1:]):
+    """CLI"""
 
     # parse command line
     description = """indent files or stdin if no files given"""
--- a/textshaper/main.py	Sun Feb 23 16:48:09 2014 -0800
+++ b/textshaper/main.py	Sun Mar 02 15:33:07 2014 -0800
@@ -10,8 +10,11 @@
 import subprocess
 import sys
 import time
+from .commands import Commands
+from .indent import deindent, indent
 from which import which
 
+HR = '--'
 
 def info(content):
     """gathers info about the content and returns a dict"""
@@ -22,7 +25,7 @@
             'columns': max([len(line) for line in lines])}
 
 
-def display(content, keys=('lines', 'chars', 'columns'), hr='--'):
+def display(content, keys=('lines', 'chars', 'columns'), hr=HR):
     """displays the content"""
     print (content)
     if keys:
@@ -31,6 +34,13 @@
     print ('; '.join(['{}: {}'.format(key, _info[key])
                       for key in keys]))
 
+def add_commands():
+    # TODO: do this dynamically
+    commands = Commands()
+    commands.add(indent, 'i')
+    commands.add(deindent, 'd')
+    return commands
+
 def add_options(parser):
     """add options to the parser instance"""
 
@@ -42,13 +52,16 @@
                         help="do not strip whitespace before processing")
 
     if which('xclip'): # TODO: support e.g. xsel or python native
-        parser.add_argument('-c', '--clip', '--copy', dest='copy_to_clipboard',
+        parser.add_argument('-c', '-o', '--clip', '--copy', dest='copy_to_clipboard',
                             action='store_true', default=False,
                             help="copy to clipboard")
-
+        parser.add_argument('-i', dest='input_from_clipboard',
+                            action='store_true', default=False,
+                            help="copy from clipboard")
 
 
 def main(args=sys.argv[1:]):
+    """CLI"""
 
     # TODO: read ~/.textshaper
 
@@ -58,24 +71,38 @@
     options = parser.parse_args(args)
 
     # read input
-    content = options.input.read()
+    if getattr(options, 'input_from_clipboard', False):
+        content = subprocess.check_output(['xclip', '-o'])
+    else:
+        content = options.input.read()
+
+    # get formatting commands
+    commands = add_commands()
 
     # pre-process output
     if options.strip:
         content = content.strip()
 
-    # print formatted content
-    display(content)
-
     # main display loop
     # TODO: read input + commands
-    while True:
-        time.sleep(1) # XXX
+    try:
+        while True:
+            # print formatted content
+            display(content)
+            print (commands.display())
+            choice = raw_input('? ')
+            new_content = commands(choice, content)
+            if new_content is None:
+                print ("Choice '{}' not recognized".format(choice))
+                continue
+            content = new_content
 
-    if options.copy_to_clipboard:
-        # copy content to X clipboard
-        process = subprocess.Popen(['xclip', '-i'], stdin=subprocess.PIPE)
-        _, _ = process.communicate(content)
+            if options.copy_to_clipboard:
+                # copy content to X clipboard
+                process = subprocess.Popen(['xclip', '-i'], stdin=subprocess.PIPE)
+                _, _ = process.communicate(content)
+    except KeyboardInterrupt:
+        sys.exit(0)
 
 if __name__ == '__main__':
   main()