##// END OF EJS Templates
remove another py2 only test
remove another py2 only test

File last commit:

r22960:cf0d4930
r22962:c05c1799
Show More
text.py
783 lines | 22.9 KiB | text/x-python | PythonLexer
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 # encoding: utf-8
"""
Utilities for working with strings and text.
Thomas Kluyver
Only include inheritance diagram where it's useful.
r8795
Inheritance diagram:
.. inheritance-diagram:: IPython.utils.text
:parts: 3
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 """
Marin Gilles
Re-added fix without whitespace mess
r21542 from __future__ import absolute_import
Brian Granger
Work to address the review comments on Fernando's branch....
r2498
import os
import re
Jonathan Frederic
Moved format date into common space
r12399 import sys
MinRK
wrap helpstring output to 80 cols
r4020 import textwrap
MinRK
add EvalFormatter for batch system (PBS) launcher templates...
r4004 from string import Formatter
Min RK
use pathlib for utils.text.paths...
r22249 try:
from pathlib import Path
except ImportError:
# Python 2 backport
from pathlib2 import Path
Brian Granger
Work to address the review comments on Fernando's branch....
r2498
Paul Ivanov
remove Python2/3 specific decorators
r22960 from IPython.testing.skipdoctest import skip_doctest
Thomas Kluyver
More Python 3 compatibility fixes.
r4732 from IPython.utils import py3compat
Brian Granger
Work to address the review comments on Fernando's branch....
r2498
Jonathan Frederic
Function -> variable
r12402 # datetime.strftime date format for ipython
if sys.platform == 'win32':
Jonathan Frederic
Woops, removed old function call
r12403 date_format = "%B %d, %Y"
Jonathan Frederic
Function -> variable
r12402 else:
Jonathan Frederic
Woops, removed old function call
r12403 date_format = "%B %-d, %Y"
Jonathan Frederic
Function -> variable
r12402
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 class LSString(str):
"""String derivative with a special access attributes.
These are normal strings, but with the special attributes:
.l (or .list) : value as list (split on newlines).
.n (or .nlstr): original value (the string itself).
.s (or .spstr): value as whitespace-separated string.
MinRK
remove path from external
r20811 .p (or .paths): list of path objects (requires path.py package)
Brian Granger
Work to address the review comments on Fernando's branch....
r2498
Any values which require transformations are computed only once and
cached.
Such strings are very useful to efficiently interact with the shell, which
typically only understands whitespace-separated options for commands."""
def get_list(self):
try:
return self.__list
except AttributeError:
self.__list = self.split('\n')
return self.__list
l = list = property(get_list)
def get_spstr(self):
try:
return self.__spstr
except AttributeError:
self.__spstr = self.replace('\n',' ')
return self.__spstr
s = spstr = property(get_spstr)
def get_nlstr(self):
return self
n = nlstr = property(get_nlstr)
def get_paths(self):
try:
return self.__paths
except AttributeError:
Min RK
use pathlib for utils.text.paths...
r22249 self.__paths = [Path(p) for p in self.split('\n') if os.path.exists(p)]
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 return self.__paths
p = paths = property(get_paths)
Brian Granger
Refactor of prompts and the displayhook....
r2781 # FIXME: We need to reimplement type specific displayhook and then add this
# back as a custom printer. This should also be moved outside utils into the
# core.
Brian Granger
Work to address the review comments on Fernando's branch....
r2498
Brian Granger
Refactor of prompts and the displayhook....
r2781 # def print_lsstring(arg):
# """ Prettier (non-repr-like) and more informative printer for LSString """
# print "LSString (.p, .n, .l, .s available). Value:"
# print arg
Bernardo B. Marques
remove all trailling spaces
r4872 #
#
Brian Granger
Refactor of prompts and the displayhook....
r2781 # print_lsstring = result_display.when_type(LSString)(print_lsstring)
Brian Granger
Work to address the review comments on Fernando's branch....
r2498
class SList(list):
"""List derivative with a special access attributes.
These are normal lists, but with the special attributes:
Thomas Kluyver
Various minor docs fixes
r13592 * .l (or .list) : value as list (the list itself).
* .n (or .nlstr): value as a string, joined on newlines.
* .s (or .spstr): value as a string, joined on spaces.
MinRK
remove path from external
r20811 * .p (or .paths): list of path objects (requires path.py package)
Brian Granger
Work to address the review comments on Fernando's branch....
r2498
Any values which require transformations are computed only once and
cached."""
def get_list(self):
return self
l = list = property(get_list)
def get_spstr(self):
try:
return self.__spstr
except AttributeError:
self.__spstr = ' '.join(self)
return self.__spstr
s = spstr = property(get_spstr)
def get_nlstr(self):
try:
return self.__nlstr
except AttributeError:
self.__nlstr = '\n'.join(self)
return self.__nlstr
n = nlstr = property(get_nlstr)
def get_paths(self):
try:
return self.__paths
except AttributeError:
Min RK
use pathlib for utils.text.paths...
r22249 self.__paths = [Path(p) for p in self if os.path.exists(p)]
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 return self.__paths
p = paths = property(get_paths)
def grep(self, pattern, prune = False, field = None):
""" Return all strings matching 'pattern' (a regex or callable)
This is case-insensitive. If prune is true, return all items
NOT matching the pattern.
If field is specified, the match must occur in the specified
whitespace-separated field.
Examples::
a.grep( lambda x: x.startswith('C') )
a.grep('Cha.*log', prune=1)
a.grep('chm', field=-1)
"""
def match_target(s):
if field is None:
return s
parts = s.split()
try:
tgt = parts[field]
return tgt
except IndexError:
return ""
Thomas Kluyver
Replace references to unicode and basestring
r13353 if isinstance(pattern, py3compat.string_types):
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 pred = lambda x : re.search(pattern, x, re.IGNORECASE)
else:
pred = pattern
if not prune:
return SList([el for el in self if pred(match_target(el))])
else:
return SList([el for el in self if not pred(match_target(el))])
def fields(self, *fields):
""" Collect whitespace-separated fields from string list
Allows quick awk-like usage of string lists.
Example data (in var a, created by 'a = !ls -l')::
Thomas Kluyver
Various minor docs fixes
r13592
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 -rwxrwxrwx 1 ville None 18 Dec 14 2006 ChangeLog
drwxrwxrwx+ 6 ville None 0 Oct 24 18:05 IPython
Thomas Kluyver
Various minor docs fixes
r13592 * ``a.fields(0)`` is ``['-rwxrwxrwx', 'drwxrwxrwx+']``
* ``a.fields(1,0)`` is ``['1 -rwxrwxrwx', '6 drwxrwxrwx+']``
(note the joining by space).
* ``a.fields(-1)`` is ``['ChangeLog', 'IPython']``
Brian Granger
Work to address the review comments on Fernando's branch....
r2498
IndexErrors are ignored.
Without args, fields() just split()'s the strings.
"""
if len(fields) == 0:
return [el.split() for el in self]
res = SList()
for el in [f.split() for f in self]:
lineparts = []
for fd in fields:
try:
lineparts.append(el[fd])
except IndexError:
pass
if lineparts:
res.append(" ".join(lineparts))
return res
def sort(self,field= None, nums = False):
""" sort by specified fields (see fields())
Example::
Thomas Kluyver
Fix docstrings in utils.text
r13807
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 a.sort(1, nums = True)
Sorts a by second field, in numerical order (so that 21 > 3)
"""
#decorate, sort, undecorate
if field is not None:
dsu = [[SList([line]).fields(field), line] for line in self]
else:
dsu = [[line, line] for line in self]
if nums:
for i in range(len(dsu)):
numstr = "".join([ch for ch in dsu[i][0] if ch.isdigit()])
try:
n = int(numstr)
except ValueError:
Rémy Léone
Remove useless semicolon
r21782 n = 0
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 dsu[i][0] = n
dsu.sort()
return SList([t[1] for t in dsu])
Brian Granger
Refactor of prompts and the displayhook....
r2781 # FIXME: We need to reimplement type specific displayhook and then add this
# back as a custom printer. This should also be moved outside utils into the
# core.
# def print_slist(arg):
# """ Prettier (non-repr-like) and more informative printer for SList """
# print "SList (.p, .n, .l, .s, .grep(), .fields(), sort() available):"
# if hasattr(arg, 'hideonce') and arg.hideonce:
# arg.hideonce = False
# return
Bernardo B. Marques
remove all trailling spaces
r4872 #
Thomas Kluyver
Remove utils.io.nlprint
r9474 # nlprint(arg) # This was a nested list printer, now removed.
Bernardo B. Marques
remove all trailling spaces
r4872 #
Brian Granger
Refactor of prompts and the displayhook....
r2781 # print_slist = result_display.when_type(SList)(print_slist)
Brian Granger
Work to address the review comments on Fernando's branch....
r2498
MinRK
allow utils.text.indent to [optionally] flatten existing indentation.
r3943 def indent(instr,nspaces=4, ntabs=0, flatten=False):
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 """Indent a string a given number of spaces or tabstops.
indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
allow utils.text.indent to [optionally] flatten existing indentation.
r3943 Parameters
----------
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
allow utils.text.indent to [optionally] flatten existing indentation.
r3943 instr : basestring
The string to be indented.
nspaces : int (default: 4)
The number of spaces to be indented.
ntabs : int (default: 0)
The number of tabs to be indented.
flatten : bool (default: False)
Whether to scrub existing indentation. If True, all lines will be
aligned to the same indentation. If False, existing indentation will
be strictly increased.
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
allow utils.text.indent to [optionally] flatten existing indentation.
r3943 Returns
-------
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
allow utils.text.indent to [optionally] flatten existing indentation.
r3943 str|unicode : string indented by ntabs and nspaces.
Bernardo B. Marques
remove all trailling spaces
r4872
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 """
MinRK
allow utils.text.indent to [optionally] flatten existing indentation.
r3943 if instr is None:
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 return
ind = '\t'*ntabs+' '*nspaces
MinRK
allow utils.text.indent to [optionally] flatten existing indentation.
r3943 if flatten:
pat = re.compile(r'^\s*', re.MULTILINE)
else:
pat = re.compile(r'^', re.MULTILINE)
outstr = re.sub(pat, ind, instr)
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 if outstr.endswith(os.linesep+ind):
return outstr[:-len(ind)]
else:
return outstr
def list_strings(arg):
"""Always return a list of strings, given a string or list of strings
as input.
Thomas Kluyver
Squash a couple more Sphinx warnings
r13914 Examples
--------
Thomas Kluyver
Fix docstrings in utils.text
r13807 ::
Brian Granger
Work to address the review comments on Fernando's branch....
r2498
In [7]: list_strings('A single string')
Out[7]: ['A single string']
In [8]: list_strings(['A single string in a list'])
Out[8]: ['A single string in a list']
In [9]: list_strings(['A','list','of','strings'])
Out[9]: ['A', 'list', 'of', 'strings']
"""
Thomas Kluyver
Replace references to unicode and basestring
r13353 if isinstance(arg, py3compat.string_types): return [arg]
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 else: return arg
def marquee(txt='',width=78,mark='*'):
"""Return the input string centered in a 'marquee'.
Thomas Kluyver
Squash a couple more Sphinx warnings
r13914 Examples
--------
Thomas Kluyver
Fix docstrings in utils.text
r13807 ::
Brian Granger
Work to address the review comments on Fernando's branch....
r2498
In [16]: marquee('A test',40)
Out[16]: '**************** A test ****************'
In [17]: marquee('A test',40,'-')
Out[17]: '---------------- A test ----------------'
In [18]: marquee('A test',40,' ')
Out[18]: ' A test '
"""
if not txt:
return (mark*width)[:width]
Thomas Kluyver
More Python 3 compatibility fixes.
r4732 nmark = (width-len(txt)-2)//len(mark)//2
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 if nmark < 0: nmark =0
marks = mark*nmark
return '%s %s %s' % (marks,txt,marks)
Brian Granger
Complete reorganization of InteractiveShell....
r2761 ini_spaces_re = re.compile(r'^(\s+)')
def num_ini_spaces(strng):
"""Return the number of initial spaces in a string"""
ini_spaces = ini_spaces_re.match(strng)
if ini_spaces:
return ini_spaces.end()
else:
return 0
Fernando Perez
Continue restructuring info system, move some standalone code to utils.
r2929
def format_screen(strng):
"""Format a string for screen printing.
This removes some latex-type format codes."""
# Paragraph continue
par_re = re.compile(r'\\$',re.MULTILINE)
strng = par_re.sub('',strng)
return strng
Fernando Perez
Add robust email-quote-stripping function to text utilities.
r7713
MinRK
wrap helpstring output to 80 cols
r4020 def dedent(text):
"""Equivalent of textwrap.dedent that ignores unindented first line.
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
wrap helpstring output to 80 cols
r4020 This means it will still dedent strings like:
'''foo
is a bar
'''
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
wrap helpstring output to 80 cols
r4020 For use in wrap_paragraphs.
"""
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
wrap helpstring output to 80 cols
r4020 if text.startswith('\n'):
# text starts with blank line, don't ignore the first line
return textwrap.dedent(text)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
wrap helpstring output to 80 cols
r4020 # split first line
splits = text.split('\n',1)
if len(splits) == 1:
# only one line
return textwrap.dedent(text)
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
wrap helpstring output to 80 cols
r4020 first, rest = splits
# dedent everything but the first line
rest = textwrap.dedent(rest)
return '\n'.join([first, rest])
Fernando Perez
Add robust email-quote-stripping function to text utilities.
r7713
MinRK
wrap helpstring output to 80 cols
r4020 def wrap_paragraphs(text, ncols=80):
"""Wrap multiple paragraphs to fit a specified width.
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
wrap helpstring output to 80 cols
r4020 This is equivalent to textwrap.wrap, but with support for multiple
paragraphs, as separated by empty lines.
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
wrap helpstring output to 80 cols
r4020 Returns
-------
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
wrap helpstring output to 80 cols
r4020 list of complete paragraphs, wrapped to fill `ncols` columns.
"""
paragraph_re = re.compile(r'\n(\s*\n)+', re.MULTILINE)
text = dedent(text).strip()
paragraphs = paragraph_re.split(text)[::2] # every other entry is space
out_ps = []
indent_re = re.compile(r'\n\s+', re.MULTILINE)
for p in paragraphs:
Bernardo B. Marques
remove all trailling spaces
r4872 # presume indentation that survives dedent is meaningful formatting,
MinRK
wrap helpstring output to 80 cols
r4020 # so don't fill unless text is flush.
if indent_re.search(p) is None:
# wrap paragraph
p = textwrap.fill(p, ncols)
out_ps.append(p)
return out_ps
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
wrap helpstring output to 80 cols
r4020
Fernando Perez
Add robust email-quote-stripping function to text utilities.
r7713 def long_substr(data):
"""Return the longest common substring in a list of strings.
Marin Gilles
Revert "added absolute_import to utils.text module + test"...
r21541
Fernando Perez
Add robust email-quote-stripping function to text utilities.
r7713 Credit: http://stackoverflow.com/questions/2892931/longest-common-substring-from-more-than-two-strings-python
"""
substr = ''
if len(data) > 1 and len(data[0]) > 0:
for i in range(len(data[0])):
for j in range(len(data[0])-i+1):
if j > len(substr) and all(data[0][i:i+j] in x for x in data):
substr = data[0][i:i+j]
Bradley M. Froehle
Fix: longest_substr([]) -> ''...
r8147 elif len(data) == 1:
Fernando Perez
Fix logic for longest_substring when only one input....
r7715 substr = data[0]
Fernando Perez
Add robust email-quote-stripping function to text utilities.
r7713 return substr
def strip_email_quotes(text):
"""Strip leading email quotation characters ('>').
Fernando Perez
Add full docstring to strip_email_quotes
r7719
Removes any combination of leading '>' interspersed with whitespace that
appears *identically* in all lines of the input text.
Parameters
----------
text : str
Examples
--------
Simple uses::
In [2]: strip_email_quotes('> > text')
Out[2]: 'text'
Fernando Perez
Fix newlines embedded in docstring for correct display and doctests.
r7720 In [3]: strip_email_quotes('> > text\\n> > more')
Out[3]: 'text\\nmore'
Fernando Perez
Add full docstring to strip_email_quotes
r7719
Note how only the common prefix that appears in all lines is stripped::
Fernando Perez
Fix newlines embedded in docstring for correct display and doctests.
r7720 In [4]: strip_email_quotes('> > text\\n> > more\\n> more...')
Out[4]: '> text\\n> more\\nmore...'
Fernando Perez
Add full docstring to strip_email_quotes
r7719
So if any line has no quote marks ('>') , then none are stripped from any
of them ::
Marin Gilles
Revert "added absolute_import to utils.text module + test"...
r21541
Fernando Perez
Fix newlines embedded in docstring for correct display and doctests.
r7720 In [5]: strip_email_quotes('> > text\\n> > more\\nlast different')
Out[5]: '> > text\\n> > more\\nlast different'
Fernando Perez
Add robust email-quote-stripping function to text utilities.
r7713 """
lines = text.splitlines()
matches = set()
for line in lines:
prefix = re.match(r'^(\s*>[ >]*)', line)
if prefix:
matches.add(prefix.group(1))
else:
break
else:
prefix = long_substr(list(matches))
if prefix:
strip = len(prefix)
text = '\n'.join([ ln[strip:] for ln in lines])
return text
Thomas Kluyver
Move strip_ansi function to utils
r16980 def strip_ansi(source):
"""
Remove ansi escape codes from text.
Marin Gilles
Revert "added absolute_import to utils.text module + test"...
r21541
Thomas Kluyver
Move strip_ansi function to utils
r16980 Parameters
----------
source : str
Source to remove the ansi from
"""
return re.sub(r'\033\[(\d|;)+?m', '', source)
Fernando Perez
Add robust email-quote-stripping function to text utilities.
r7713
MinRK
add EvalFormatter for batch system (PBS) launcher templates...
r4004 class EvalFormatter(Formatter):
"""A String Formatter that allows evaluation of simple expressions.
Marin Gilles
Revert "added absolute_import to utils.text module + test"...
r21541
Thomas Kluyver
Copy EvalFormatter and FullEvalFormatter from prompt-manager branch.
r5353 Note that this version interprets a : as specifying a format string (as per
standard string formatting), so if slicing is required, you must explicitly
create a slice.
Marin Gilles
Revert "added absolute_import to utils.text module + test"...
r21541
MinRK
add EvalFormatter for batch system (PBS) launcher templates...
r4004 This is to be used in templating cases, such as the parallel batch
script templates, where simple arithmetic on arguments is useful.
Bernardo B. Marques
remove all trailling spaces
r4872
MinRK
add EvalFormatter for batch system (PBS) launcher templates...
r4004 Examples
--------
Thomas Kluyver
Fix docstrings in utils.text
r13807 ::
In [1]: f = EvalFormatter()
In [2]: f.format('{n//4}', n=8)
Out[2]: '2'
In [3]: f.format("{greeting[slice(2,4)]}", greeting="Hello")
Out[3]: 'll'
Thomas Kluyver
Copy EvalFormatter and FullEvalFormatter from prompt-manager branch.
r5353 """
def get_field(self, name, args, kwargs):
v = eval(name, kwargs)
return v, name
Bernardo B. Marques
remove all trailling spaces
r4872
Thomas Kluyver
Add comment about string formatting changes in Python 3.4
r14002 #XXX: As of Python 3.4, the format string parsing no longer splits on a colon
# inside [], so EvalFormatter can handle slicing. Once we only support 3.4 and
# above, it should be possible to remove FullEvalFormatter.
Fernando Perez
Add full docstring to strip_email_quotes
r7719
Paul Ivanov
remove Python2/3 specific decorators
r22960 @skip_doctest
Thomas Kluyver
Copy EvalFormatter and FullEvalFormatter from prompt-manager branch.
r5353 class FullEvalFormatter(Formatter):
"""A String Formatter that allows evaluation of simple expressions.
Marin Gilles
Revert "added absolute_import to utils.text module + test"...
r21541
Thomas Kluyver
Copy EvalFormatter and FullEvalFormatter from prompt-manager branch.
r5353 Any time a format key is not found in the kwargs,
it will be tried as an expression in the kwargs namespace.
Marin Gilles
Revert "added absolute_import to utils.text module + test"...
r21541
Thomas Kluyver
Copy EvalFormatter and FullEvalFormatter from prompt-manager branch.
r5353 Note that this version allows slicing using [1:2], so you cannot specify
a format string. Use :class:`EvalFormatter` to permit format strings.
Marin Gilles
Revert "added absolute_import to utils.text module + test"...
r21541
Thomas Kluyver
Copy EvalFormatter and FullEvalFormatter from prompt-manager branch.
r5353 Examples
--------
Thomas Kluyver
Fix docstrings in utils.text
r13807 ::
In [1]: f = FullEvalFormatter()
In [2]: f.format('{n//4}', n=8)
Out[2]: u'2'
In [3]: f.format('{list(range(5))[2:4]}')
Out[3]: u'[2, 3]'
MinRK
add EvalFormatter for batch system (PBS) launcher templates...
r4004
Thomas Kluyver
Fix docstrings in utils.text
r13807 In [4]: f.format('{3*2}')
Out[4]: u'6'
MinRK
add EvalFormatter for batch system (PBS) launcher templates...
r4004 """
MinRK
update EvalFormatter to allow arbitrary expressions...
r4654 # copied from Formatter._vformat with minor changes to allow eval
# and replace the format_spec code with slicing
Min RK
override vformat instead of _vformat...
r21798 def vformat(self, format_string, args, kwargs):
MinRK
update EvalFormatter to allow arbitrary expressions...
r4654 result = []
for literal_text, field_name, format_spec, conversion in \
self.parse(format_string):
# output the literal text
if literal_text:
result.append(literal_text)
# if there's a field, output it
if field_name is not None:
# this is some markup, find the object and do
Thomas Kluyver
Copy EvalFormatter and FullEvalFormatter from prompt-manager branch.
r5353 # the formatting
MinRK
update EvalFormatter to allow arbitrary expressions...
r4654
Thomas Kluyver
Copy EvalFormatter and FullEvalFormatter from prompt-manager branch.
r5353 if format_spec:
MinRK
update EvalFormatter to allow arbitrary expressions...
r4654 # override format spec, to allow slicing:
field_name = ':'.join([field_name, format_spec])
# eval the contents of the field for the object
# to be formatted
obj = eval(field_name, kwargs)
# do any conversion on the resulting object
obj = self.convert_field(obj, conversion)
# format the object and append to the result
Thomas Kluyver
Copy EvalFormatter and FullEvalFormatter from prompt-manager branch.
r5353 result.append(self.format_field(obj, ''))
MinRK
update EvalFormatter to allow arbitrary expressions...
r4654
Thomas Kluyver
Use DollarFormatter to fill in names in ! shell calls....
r5355 return u''.join(py3compat.cast_unicode(s) for s in result)
MinRK
update EvalFormatter to allow arbitrary expressions...
r4654
Fernando Perez
Add full docstring to strip_email_quotes
r7719
Paul Ivanov
remove Python2/3 specific decorators
r22960 @skip_doctest
Thomas Kluyver
Add DollarFormatter and tests.
r5354 class DollarFormatter(FullEvalFormatter):
"""Formatter allowing Itpl style $foo replacement, for names and attribute
access only. Standard {foo} replacement also works, and allows full
evaluation of its arguments.
Examples
--------
Thomas Kluyver
Fix docstrings in utils.text
r13807 ::
In [1]: f = DollarFormatter()
In [2]: f.format('{n//4}', n=8)
Out[2]: u'2'
In [3]: f.format('23 * 76 is $result', result=23*76)
Out[3]: u'23 * 76 is 1748'
In [4]: f.format('$a or {b}', a=1, b=2)
Out[4]: u'1 or 2'
Thomas Kluyver
Add DollarFormatter and tests.
r5354 """
Thomas Kluyver
Allow 2033 to get literal $ in shell commands.
r5365 _dollar_pattern = re.compile("(.*?)\$(\$?[\w\.]+)")
Thomas Kluyver
Add DollarFormatter and tests.
r5354 def parse(self, fmt_string):
for literal_txt, field_name, format_spec, conversion \
in Formatter.parse(self, fmt_string):
Marin Gilles
Revert "added absolute_import to utils.text module + test"...
r21541
Thomas Kluyver
Add DollarFormatter and tests.
r5354 # Find $foo patterns in the literal text.
continue_from = 0
Thomas Kluyver
Allow 2033 to get literal $ in shell commands.
r5365 txt = ""
Thomas Kluyver
Add DollarFormatter and tests.
r5354 for m in self._dollar_pattern.finditer(literal_txt):
new_txt, new_field = m.group(1,2)
Thomas Kluyver
Allow 2033 to get literal $ in shell commands.
r5365 # $$foo --> $foo
if new_field.startswith("$"):
txt += new_txt + new_field
else:
yield (txt + new_txt, new_field, "", None)
txt = ""
Thomas Kluyver
Add DollarFormatter and tests.
r5354 continue_from = m.end()
Marin Gilles
Revert "added absolute_import to utils.text module + test"...
r21541
Thomas Kluyver
Add DollarFormatter and tests.
r5354 # Re-yield the {foo} style pattern
Thomas Kluyver
Allow 2033 to get literal $ in shell commands.
r5365 yield (txt + literal_txt[continue_from:], field_name, format_spec, conversion)
MinRK
add EvalFormatter for batch system (PBS) launcher templates...
r4004
Matthias BUSSONNIER
re-write columnize, with intermediate step....
r7387 #-----------------------------------------------------------------------------
# Utils to columnize a list of string
#-----------------------------------------------------------------------------
Fernando Perez
Add full docstring to strip_email_quotes
r7719
naught101
rename num_rows etc to max_rows for clarity...
r21618 def _col_chunks(l, max_rows, row_first=False):
"""Yield successive max_rows-sized column chunks from l."""
naught101
Row-first option for columnize
r21613 if row_first:
naught101
rename num_rows etc to max_rows for clarity...
r21618 ncols = (len(l) // max_rows) + (len(l) % max_rows > 0)
naught101
Row-first option for columnize
r21613 for i in py3compat.xrange(ncols):
naught101
Fix loop logic
r21617 yield [l[j] for j in py3compat.xrange(i, len(l), ncols)]
naught101
Row-first option for columnize
r21613 else:
naught101
rename num_rows etc to max_rows for clarity...
r21618 for i in py3compat.xrange(0, len(l), max_rows):
yield l[i:(i + max_rows)]
Matthias BUSSONNIER
re-write columnize, with intermediate step....
r7387
Fernando Perez
Add full docstring to strip_email_quotes
r7719
naught101
Row-first option for columnize
r21613 def _find_optimal(rlist, row_first=False, separator_size=2, displaywidth=80):
Matthias BUSSONNIER
re-write columnize, with intermediate step....
r7387 """Calculate optimal info to columnize a list of string"""
naught101
rename num_rows etc to max_rows for clarity...
r21618 for max_rows in range(1, len(rlist) + 1):
col_widths = list(map(max, _col_chunks(rlist, max_rows, row_first)))
naught101
Row-first option for columnize
r21613 sumlength = sum(col_widths)
ncols = len(col_widths)
if sumlength + separator_size * (ncols - 1) <= displaywidth:
break
return {'num_columns': ncols,
'optimal_separator_width': (displaywidth - sumlength) / (ncols - 1) if (ncols - 1) else 0,
naught101
rename num_rows etc to max_rows for clarity...
r21618 'max_rows': max_rows,
naught101
Row-first option for columnize
r21613 'column_widths': col_widths
}
Matthias BUSSONNIER
re-write columnize, with intermediate step....
r7387
Fernando Perez
Add full docstring to strip_email_quotes
r7719
Matthias BUSSONNIER
re-write columnize, with intermediate step....
r7387 def _get_or_default(mylist, i, default=None):
"""return list item number, or default if don't exist"""
if i >= len(mylist):
return default
else :
return mylist[i]
Fernando Perez
Add full docstring to strip_email_quotes
r7719
naught101
Row-first option for columnize
r21613 def compute_item_matrix(items, row_first=False, empty=None, *args, **kwargs) :
Matthias BUSSONNIER
fix docstring, and debug leftover
r7388 """Returns a nested list, and info to columnize items
Thomas Kluyver
Miscellaneous docs fixes
r9244 Parameters
----------
Matthias BUSSONNIER
fix docstring, and debug leftover
r7388
Thomas Kluyver
Fix docstrings in utils.text
r13807 items
Matthias BUSSONNIER
fix docstring, and debug leftover
r7388 list of strings to columize
naught101
Row-first option for columnize
r21613 row_first : (default False)
naught101
fix help text
r21615 Whether to compute columns for a row-first matrix instead of
naught101
Row-first option for columnize
r21613 column-first (default).
Matthias BUSSONNIER
new completer for qtconsole...
r7393 empty : (default None)
default value to fill list if needed
Matthias BUSSONNIER
fix docstring, and debug leftover
r7388 separator_size : int (default=2)
How much caracters will be used as a separation between each columns.
displaywidth : int (default=80)
The width of the area onto wich the columns should enter
Thomas Kluyver
Miscellaneous docs fixes
r9244 Returns
-------
Matthias BUSSONNIER
re-write columnize, with intermediate step....
r7387
Thomas Kluyver
Fix docstrings in utils.text
r13807 strings_matrix
Matthias BUSSONNIER
fix docstring, and debug leftover
r7388
nested list of string, the outer most list contains as many list as
rows, the innermost lists have each as many element as colums. If the
total number of elements in `items` does not equal the product of
rows*columns, the last element of some lists are filled with `None`.
Thomas Kluyver
Fix docstrings in utils.text
r13807 dict_info
Matthias BUSSONNIER
fix docstring, and debug leftover
r7388 some info to make columnize easier:
naught101
Row-first option for columnize
r21613 num_columns
Thomas Kluyver
Fix docstrings in utils.text
r13807 number of columns
naught101
rename num_rows etc to max_rows for clarity...
r21618 max_rows
maximum number of rows (final number may be less)
naught101
Row-first option for columnize
r21613 column_widths
Thomas Kluyver
Fix docstrings in utils.text
r13807 list of with of each columns
optimal_separator_width
best separator width between columns
Matthias BUSSONNIER
fix docstring, and debug leftover
r7388
Thomas Kluyver
Miscellaneous docs fixes
r9244 Examples
--------
Thomas Kluyver
Fix docstrings in utils.text
r13807 ::
In [1]: l = ['aaa','b','cc','d','eeeee','f','g','h','i','j','k','l']
naught101
Row-first option for columnize
r21613 ...: compute_item_matrix(l, displaywidth=12)
Thomas Kluyver
Fix docstrings in utils.text
r13807 Out[1]:
([['aaa', 'f', 'k'],
['b', 'g', 'l'],
['cc', 'h', None],
['d', 'i', None],
['eeeee', 'j', None]],
naught101
Row-first option for columnize
r21613 {'num_columns': 3,
'column_widths': [5, 1, 1],
Thomas Kluyver
Fix docstrings in utils.text
r13807 'optimal_separator_width': 2,
naught101
rename num_rows etc to max_rows for clarity...
r21618 'max_rows': 5})
Matthias BUSSONNIER
re-write columnize, with intermediate step....
r7387 """
naught101
Row-first option for columnize
r21613 info = _find_optimal(list(map(len, items)), row_first, *args, **kwargs)
naught101
rename num_rows etc to max_rows for clarity...
r21618 nrow, ncol = info['max_rows'], info['num_columns']
naught101
Row-first option for columnize
r21613 if row_first:
naught101
Fix loop logic
r21617 return ([[_get_or_default(items, r * ncol + c, default=empty) for c in range(ncol)] for r in range(nrow)], info)
naught101
Row-first option for columnize
r21613 else:
return ([[_get_or_default(items, c * nrow + r, default=empty) for c in range(ncol)] for r in range(nrow)], info)
MinRK
add EvalFormatter for batch system (PBS) launcher templates...
r4004
Fernando Perez
Add full docstring to strip_email_quotes
r7719
naught101
Add spread option, to allow columns to fill space.
r21621 def columnize(items, row_first=False, separator=' ', displaywidth=80, spread=False):
Fernando Perez
Move columnization code out of GUI code so we can test it better.
r4537 """ Transform a list of strings into a single string with columns.
Parameters
----------
items : sequence of strings
The strings to process.
naught101
Row-first option for columnize
r21613 row_first : (default False)
naught101
fix help text
r21615 Whether to compute columns for a row-first matrix instead of
naught101
Row-first option for columnize
r21613 column-first (default).
Fernando Perez
Move columnization code out of GUI code so we can test it better.
r4537 separator : str, optional [default is two spaces]
The string that separates columns.
displaywidth : int, optional [default is 80]
Width of the display in number of characters.
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Move columnization code out of GUI code so we can test it better.
r4537 Returns
-------
The formatted string.
"""
naught101
Row-first option for columnize
r21613 if not items:
Fernando Perez
Move columnization code out of GUI code so we can test it better.
r4537 return '\n'
naught101
Row-first option for columnize
r21613 matrix, info = compute_item_matrix(items, row_first=row_first, separator_size=len(separator), displaywidth=displaywidth)
naught101
Add spread option, to allow columns to fill space.
r21621 if spread:
separator = separator.ljust(int(info['optimal_separator_width']))
Matthias BUSSONNIER
re-write columnize, with intermediate step....
r7387 fmatrix = [filter(None, x) for x in matrix]
naught101
Row-first option for columnize
r21613 sjoin = lambda x : separator.join([ y.ljust(w, ' ') for y, w in zip(x, info['column_widths'])])
Matthias BUSSONNIER
re-write columnize, with intermediate step....
r7387 return '\n'.join(map(sjoin, fmatrix))+'\n'
Martín Gaitán
adding get_text_list helper inspired in django's one
r12919
Martín Gaitán
generalizing get_text_list helper
r12925 def get_text_list(list_, last_sep=' and ', sep=", ", wrap_item_with=""):
Martín Gaitán
adding get_text_list helper inspired in django's one
r12919 """
Return a string with a natural enumeration of items
>>> get_text_list(['a', 'b', 'c', 'd'])
'a, b, c and d'
Martín Gaitán
generalizing get_text_list helper
r12925 >>> get_text_list(['a', 'b', 'c'], ' or ')
Martín Gaitán
adding get_text_list helper inspired in django's one
r12919 'a, b or c'
Martín Gaitán
generalizing get_text_list helper
r12925 >>> get_text_list(['a', 'b', 'c'], ', ')
'a, b, c'
>>> get_text_list(['a', 'b'], ' or ')
Martín Gaitán
adding get_text_list helper inspired in django's one
r12919 'a or b'
>>> get_text_list(['a'])
'a'
>>> get_text_list([])
''
>>> get_text_list(['a', 'b'], wrap_item_with="`")
'`a` and `b`'
Martín Gaitán
generalizing get_text_list helper
r12925 >>> get_text_list(['a', 'b', 'c', 'd'], " = ", sep=" + ")
'a + b + c = d'
Martín Gaitán
adding get_text_list helper inspired in django's one
r12919 """
if len(list_) == 0:
return ''
if wrap_item_with:
list_ = ['%s%s%s' % (wrap_item_with, item, wrap_item_with) for
item in list_]
if len(list_) == 1:
return list_[0]
Martín Gaitán
generalizing get_text_list helper
r12925 return '%s%s%s' % (
sep.join(i for i in list_[:-1]),
Marin Gilles
Re-added fix without whitespace mess
r21542 last_sep, list_[-1])