##// END OF EJS Templates
FIX: Update vi bindings to work with nav auttosuggestion....
FIX: Update vi bindings to work with nav auttosuggestion. 1) dismiss the autosuggest on cursor motion 2) in vi mode, escape already dismiss autosuggestions closes #13901

File last commit:

r27639:c55dbf99
r28050:a885b478
Show More
text.py
752 lines | 22.3 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 """
import os
import re
Blazej Michalik
Refactor strip_email_quotes...
r26615 import string
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
Thomas Kluyver
Simplify some pathlib imports
r24258 from pathlib import Path
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 #
#
Hugo
Replace simplegeneric.generic with functools.singledispatch
r24687 # print_lsstring = result_display.register(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 ""
Srinivas Reddy Thatiparthy
convert string_types to str
r23037 if isinstance(pattern, str):
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 #
Hugo
Replace simplegeneric.generic with functools.singledispatch
r24687 # print_slist = result_display.register(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
----------
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
-------
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']
"""
Srinivas Reddy Thatiparthy
convert string_types to str
r23037 if isinstance(arg, str):
return [arg]
else:
return arg
Brian Granger
Work to address the review comments on Fernando's branch....
r2498
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
-------
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 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
Blazej Michalik
Refactor strip_email_quotes...
r26615 So if any line has no quote marks ('>'), then none are stripped from any
Fernando Perez
Add full docstring to strip_email_quotes
r7719 of them ::
Blazej Michalik
Refactor strip_email_quotes...
r26615
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()
Blazej Michalik
Refactor strip_email_quotes...
r26615 strip_len = 0
for characters in zip(*lines):
# Check if all characters in this position are the same
if len(set(characters)) > 1:
break
Blazej Michalik
Update IPython/utils/text.py...
r26619 prefix_char = characters[0]
Blazej Michalik
Refactor strip_email_quotes...
r26615
if prefix_char in string.whitespace or prefix_char == ">":
strip_len += 1
Fernando Perez
Add robust email-quote-stripping function to text utilities.
r7713 else:
break
Blazej Michalik
Refactor strip_email_quotes...
r26615
text = "\n".join([ln[strip_len:] for ln in lines])
Fernando Perez
Add robust email-quote-stripping function to text utilities.
r7713 return text
Blazej Michalik
Refactor strip_email_quotes...
r26615
Thomas Kluyver
Move strip_ansi function to utils
r16980 def strip_ansi(source):
"""
Remove ansi escape codes from text.
Matthias Bussonnier
reformat docstring in IPython utils
r26419
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.
Matthias Bussonnier
typo and reformat
r27639
Matthias Bussonnier
doc parssing issue
r27531 Note that this version interprets a `:` as specifying a format string (as per
Thomas Kluyver
Copy EvalFormatter and FullEvalFormatter from prompt-manager branch.
r5353 standard string formatting), so if slicing is required, you must explicitly
create a slice.
Matthias Bussonnier
typo and reformat
r27639
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
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)
Paul Ivanov
don't skip doctest
r22976 Out[2]: '2'
Thomas Kluyver
Fix docstrings in utils.text
r13807
In [3]: f.format('{list(range(5))[2:4]}')
Paul Ivanov
don't skip doctest
r22976 Out[3]: '[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}')
Paul Ivanov
don't skip doctest
r22976 Out[4]: '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
Matthias Bussonnier
remove cast_unicode and add some typings
r25343 def vformat(self, format_string:str, args, kwargs)->str:
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
Matthias Bussonnier
remove cast_unicode and add some typings
r25343 return ''.join(result)
MinRK
update EvalFormatter to allow arbitrary expressions...
r4654
Fernando Perez
Add full docstring to strip_email_quotes
r7719
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)
Paul Ivanov
don't skip doctest
r22976 Out[2]: '2'
Thomas Kluyver
Fix docstrings in utils.text
r13807
In [3]: f.format('23 * 76 is $result', result=23*76)
Paul Ivanov
don't skip doctest
r22976 Out[3]: '23 * 76 is 1748'
Thomas Kluyver
Fix docstrings in utils.text
r13807
In [4]: f.format('$a or {b}', a=1, b=2)
Paul Ivanov
don't skip doctest
r22976 Out[4]: '1 or 2'
Thomas Kluyver
Add DollarFormatter and tests.
r5354 """
Matthias Bussonnier
Use raw string when invalid escape sequence present....
r24451 _dollar_pattern_ignore_single_quote = re.compile(r"(.*?)\$(\$?[\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 = ""
ICanWaitAndFishAllDay
ignore the single quotes string when parsing
r23620 for m in self._dollar_pattern_ignore_single_quote.finditer(literal_txt):
Thomas Kluyver
Add DollarFormatter and tests.
r5354 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
A few modification to fix docs passing....
r27136 def __repr__(self):
return "<DollarFormatter>"
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)
Srinivas Reddy Thatiparthy
Change functions,...
r23036 for i in range(ncols):
yield [l[j] for j in range(i, len(l), ncols)]
naught101
Row-first option for columnize
r21613 else:
Srinivas Reddy Thatiparthy
Change functions,...
r23036 for i in range(0, len(l), max_rows):
naught101
rename num_rows etc to max_rows for clarity...
r21618 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,
Paul Ivanov
fix compute_item_matrix doctest
r22980 '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
----------
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)
luz.paz
Fix documentation typos...
r24322 How much characters will be used as a separation between each columns.
Matthias BUSSONNIER
fix docstring, and debug leftover
r7388 displaywidth : int (default=80)
luzpaz
Misc. typo fixes...
r24084 The width of the area onto which the columns should enter
Matthias BUSSONNIER
fix docstring, and debug leftover
r7388
Thomas Kluyver
Miscellaneous docs fixes
r9244 Returns
-------
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
luzpaz
Misc. typo fixes...
r24084 rows, the innermost lists have each as many element as columns. If the
Matthias BUSSONNIER
fix docstring, and debug leftover
r7388 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']
Paul Ivanov
fix compute_item_matrix doctest
r22980 In [2]: list, info = compute_item_matrix(l, displaywidth=12)
In [3]: list
Out[3]: [['aaa', 'f', 'k'], ['b', 'g', 'l'], ['cc', 'h', None], ['d', 'i', None], ['eeeee', 'j', None]]
In [4]: ideal = {'num_columns': 3, 'column_widths': [5, 1, 1], 'optimal_separator_width': 2, 'max_rows': 5}
In [5]: all((info[k] == ideal[k] for k in ideal.keys()))
Out[5]: True
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
Matthias Bussonnier
typo and reformat
r27639 def columnize(items, row_first=False, separator=" ", displaywidth=80, spread=False):
"""Transform a list of strings into a single string with columns.
Fernando Perez
Move columnization code out of GUI code so we can test it better.
r4537
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])