Commits

Jonathan Eunice committed a1437c0

text replace and textlines largely working

  • Participants
  • Parent commits da0b883

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