Jonathan Eunice avatar Jonathan Eunice committed a1437c0

text replace and textlines largely working

Comments (0)

Files changed (6)

 automatically remove blank starting and ending lines, and any whitespace prefix
 that is common to all of the lines.
 
+``Text`` objects, unlike strings, are mutable. The ``replace(x, y)`` method will
+replace all instances of ``x`` with ``y`` *in situ*. If given just one argument,
+a ``dict``, all the keys will be replaced with their corresponding values.
+
 ``Text`` doesn't have the full set of text-onboarding options seen in `textdata
 <http://pypi.python.org/pypi/textdata>`_, but it should suit many cirumstances.
 If you need more, ``textdata`` can be used alongside ``Text``.
 from say.core import fmt
 import inspect
 import sys, os, re
+from simplere import Re
 
 _PY3 = sys.version_info[0] > 2
 if _PY3:
         newt._lines = self._lines[:]
         return newt
 
-    def replace(self, target, replacement):
+    def replace(self, target, replacement=None):
         """
         Replace all instances of the target string with the replacement string.
         Works in situ, contra str.replace().
         """
-        for i, line in enumerate(self._lines):
-            self._lines[i] = line.replace(target, replacement)
+        if target and isinstance(target, dict) and replacement is None:
+            for (targ, repl) in target.items():
+                self.replace(targ, repl)
+        else:
+            for i, line in enumerate(self._lines):
+                self._lines[i] = line.replace(target, replacement)
             
         # TODO: should lines be recalibrated, if there are any \n in replacement? or just assume there won't be?
     
         function that takes re match object as a parameter and returns replacement
         string.
         """
-        if isinstance(target, basestring):
-            target = re.compile(target)
+        target = Re(target) if not isinstance(target, Re) else target
         for i, line in enumerate(self._lines):
             self._lines[i] = target.sub(replacement, line)
+            
+    # TODO: for some reason, replacement not getting to be a simplere.ReMatch obj
+    # TODO: extend dict-style invocation to re_replace
     
     def read_from(self, filepath, interpolate=True, dedent=True):
         """
 from say import Text
 import inspect
 import sys, re
+from simplere import Re
 
 _PY3 = sys.version_info[0] > 2
 if _PY3:
     def __repr__(self):
         return 'TextRange({0}, {1}:{2} of {3})'.format(id(self),
                 self._indices.start, self._indices.stop, id(self._text))
-    
-    def replace(self, target, replacement):
+
+    def replace(self, target, replacement=None):
         """
         Replace all instances of the target string with the replacement string.
         Works in situ, contra str.replace().
         """
-        for i, line in enumerate(self._text._lines[self._indices], start=self._indices.start):
-            self._text._lines[i] = line.replace(target, replacement)
+        if target and isinstance(target, dict) and replacement is None:
+            for (targ, repl) in target.items():
+                self.replace(targ, repl)
+        else:
+            for i, line in enumerate(self._text._lines[self._indices], start=self._indices.start):
+                self._text._lines[i] = line.replace(target, replacement)
             
         # TODO: should lines be recalibrated, if there are any \n in replacement?
 
+
     def re_replace(self, target, replacement):
         """
         Regular expression replacement. Target is either compiled re object or
         string that will be compiled into one. Replacement is either string or
         function that takes re match object as a parameter and returns replacement
-        string.
+        string. Intead of Python's stock ``_sre.SRE_Match`` objects, returns a
+        ``ReMatch``, which adds the ability to directly access via indices 
         """
-        if isinstance(target, basestring):
-            target = re.compile(target)
+        target = Re(target) if not isinstance(target, Re) else target
         for i, line in enumerate(self._text._lines[self._indices], start=self._indices.start):
             self._text._lines[i] = target.sub(replacement, line)
     
 
 setup(
     name='say',
-    version=verno("0.932"),
+    version=verno("0.954"),
     author='Jonathan Eunice',
     author_email='jonathan.eunice@gmail.com',
     description='Super-simple templated printing. E.g.: say("Hello, {whoever}!", indent=1)',
     long_description=open('README.rst').read(),
     url='https://bitbucket.org/jeunice/say',
     packages=['say'],
-    install_requires=['six', 'options>=0.426', 'stuf>=0.9.10'],
+    install_requires=['six', 'options>=0.426', 'stuf>=0.9.10', 'simplere>=0.25'],
     tests_require = ['tox', 'pytest', 'six'],
     zip_safe = True,
     keywords='print format template interpolate say',

test/test_text.py

    t.replace('d', 'D')
    assert t.lines ==  'a B c D'.split()
    
+def test_replace_many():
+   t = Text('a\nb\nc\nd')
+   assert t.lines == 'a b c d'.split()
+   
+   t.replace({'b': 'BEE', 'd': 'DEE'})
+   assert t.lines ==  'a BEE c DEE'.split()
+   
 def test_re_replace():
    t = Text('a\nb\nc\nd')
    assert t.lines == 'a b c d'.split()
    t.re_replace(r'[b]', 'B')
    t.re_replace(r'd', lambda m: m.group(0).upper())
    assert t.lines ==  'a B c D'.split()
+   
+   t1 = Text('and then there were none'.split())
+   t1.re_replace(r'(?P<art>the)', lambda m: '*' + m.art.upper() + '*')
+   assert t1.lines == 'and *THE*n *THE*re were none'.split()
     
 def test_set_text():
     t = Text()

test/test_textrange.py

    tr.replace('a', 'A')
    assert tr.lines == 'A b'.split()
    assert t.lines == 'a a A b a'.split()
-
+   
+def test_replace_many():
+   t = Text('a\na\na\nb\na')
+   assert t.lines == 'a a a b a'.split()
+   
+   tr = TextRange(t, 2, 4)
+   assert tr.lines == 'a b'.split()
+   
+   tr.replace({'a': 'A', 'b': 'BEE'})
+   assert tr.lines == 'A BEE'.split()
+   assert t.lines == 'a a A BEE a'.split()
+   
 def test_re_replace():
    t = Text('a\na\na\nb\na')
    assert t.lines == 'a a a b a'.split()
    tr.re_replace(r'[b]', 'B')
    tr.re_replace(r'a', lambda m: m.group(0).upper())
    assert t.lines == 'a a A B a'.split()
-
+   
       
 def test_interpolation():
    x = 21
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.